作者 李忠强

线上

  1 +{"files":[],"license":"regular","licenseto":"10789","licensekey":"o6mJaMsK4NpyHf9q psldq2tLvR9vsAcBNF\/P7cl4cmp82g9FH9Xpm96xhYw=","domains":[],"licensecodes":[],"validations":[]}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms;
  4 +
  5 +use addons\qcloudsms\library\SmsSingleSender;
  6 +use addons\qcloudsms\library\SmsVoicePromptSender;
  7 +use addons\qcloudsms\library\SmsVoiceverifyCodeSender;
  8 +use addons\qcloudsms\library\TtsVoiceSender;
  9 +use think\Addons;
  10 +use think\Config;
  11 +
  12 +/**
  13 + * 插件
  14 + */
  15 +class Qcloudsms extends Addons
  16 +{
  17 + private $appid = null;
  18 + private $appkey = null;
  19 + private $config = null;
  20 + private $sender = null;
  21 + private $sendError = '';
  22 +
  23 + public function ConfigInit()
  24 + {
  25 + $this->config = $this->getConfig();
  26 + //如果使用语音短信 更换成语音短信模板
  27 + if ($this->config['isVoice'] == 1) {
  28 + $this->config['template'] = $this->config['voiceTemplate'];
  29 + //语音短信 需要另行设置Aappid 与Appkey
  30 + $this->appid = $this->config['voiceAppid'];
  31 + $this->appkey = $this->config['voiceAppkey'];
  32 + } else {
  33 + $this->appid = $this->config['appid'];
  34 + $this->appkey = $this->config['appkey'];
  35 + }
  36 + }
  37 +
  38 + /**
  39 + * 短信发送行为
  40 + * @param Sms $params
  41 + * @return boolean
  42 + */
  43 + public function smsSend(&$params)
  44 + {
  45 + $this->ConfigInit();
  46 + try {
  47 + if ($this->config['isTemplateSender'] == 1) {
  48 + $templateID = $this->config['template'][$params->event];
  49 + if ($this->config['isVoice'] != 1) {
  50 + //普通短信发送
  51 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  52 + $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params->code}"], $this->config['sign'], "", "");
  53 + } else {
  54 + //语音短信发送
  55 + $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
  56 + //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
  57 + $result = $this->sender->send("86", $params['mobile'], $templateID, [$params->code]);
  58 + }
  59 + } else {
  60 + //判断是否是语音短信
  61 + if ($this->config['isVoice'] != 1) {
  62 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  63 + //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
  64 + $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
  65 + } else {
  66 + $this->sender = new SmsVoiceVerifyCodeSender($this->appid, $this->appkey);
  67 + //参数:国家码、手机号、短信内容、播放次数(默认2次)、服务的原样返回的参数
  68 + $result = $this->sender->send('86', $params['mobile'], $params['msg']);
  69 + }
  70 + }
  71 +
  72 + $rsp = json_decode($result, true);
  73 + if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
  74 + return true;
  75 + } else {
  76 + //记录错误信息
  77 + $this->setError($rsp);
  78 + return false;
  79 + }
  80 + } catch (\Exception $e) {
  81 + $this->setError($e->getMessage());
  82 + }
  83 + return false;
  84 + }
  85 +
  86 + /**
  87 + * 短信发送通知
  88 + * @param array $params
  89 + * @return boolean
  90 + */
  91 + public function smsNotice(&$params)
  92 + {
  93 + $this->ConfigInit();
  94 + try {
  95 + if ($this->config['isTemplateSender'] == 1) {
  96 + $templateID = $this->config['template'][$params['template']];
  97 +
  98 + if ($this->config['isVoice'] != 1) {
  99 + //普通短信发送
  100 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  101 + $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params['msg']}"], $this->config['sign'], "", "");
  102 + } else {
  103 + //语音短信发送
  104 + $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
  105 + //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
  106 + $result = $this->sender->send("86", $params['mobile'], $templateID, [$params['msg']]);
  107 + }
  108 + } else {
  109 + //判断是否是语音短信
  110 + if ($this->config['isVoice'] != 1) {
  111 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  112 + //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
  113 + $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
  114 + } else {
  115 + $this->sender = new SmsVoicePromptSender($this->appid, $this->appkey);
  116 + //参数:国家码、手机号、语音类型(目前固定为2)、短信内容、播放次数(默认2次)、服务的原样返回的参数
  117 + $result = $this->sender->send('86', $params['mobile'], 2, $params['msg']);
  118 + }
  119 + }
  120 + $rsp = (array)json_decode($result, true);
  121 + if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
  122 + return true;
  123 + } else {
  124 + //记录错误信息
  125 + $this->setError($rsp);
  126 + return false;
  127 + }
  128 + } catch (\Exception $e) {
  129 + var_dump($e);
  130 + exit();
  131 + }
  132 + }
  133 +
  134 + /**
  135 + * 记录失败信息
  136 + * @param [type] $err [description]
  137 + */
  138 + private function setError($err)
  139 + {
  140 + $this->sendError = $err;
  141 + }
  142 +
  143 + /**
  144 + * 获取失败信息
  145 + * @return [type] [description]
  146 + */
  147 + public function getError()
  148 + {
  149 + return $this->sendError;
  150 + }
  151 +
  152 + /**
  153 + * 检测验证是否正确
  154 + * @param Sms $params
  155 + * @return boolean
  156 + */
  157 + public function smsCheck(&$params)
  158 + {
  159 + return true;
  160 + }
  161 +
  162 + /**
  163 + * 插件安装方法
  164 + * @return bool
  165 + */
  166 + public function install()
  167 + {
  168 + return true;
  169 + }
  170 +
  171 + /**
  172 + * 插件卸载方法
  173 + * @return bool
  174 + */
  175 + public function uninstall()
  176 + {
  177 + return true;
  178 + }
  179 +
  180 + /**
  181 + * 插件启用方法
  182 + * @return bool
  183 + */
  184 + public function enable()
  185 + {
  186 + return true;
  187 + }
  188 +
  189 + /**
  190 + * 插件禁用方法
  191 + * @return bool
  192 + */
  193 + public function disable()
  194 + {
  195 + return true;
  196 + }
  197 +}
  1 +<?php
  2 +
  3 +return array(
  4 + array(
  5 + 'name' => 'appid',
  6 + 'title' => '应用AppID',
  7 + 'type' => 'string',
  8 + 'content' =>
  9 + array(),
  10 + 'value' => '',
  11 + 'rule' => 'required',
  12 + 'msg' => '',
  13 + 'tip' => '',
  14 + 'ok' => '',
  15 + 'extend' => '',
  16 + ),
  17 + array(
  18 + 'name' => 'appkey',
  19 + 'title' => '应用AppKEY',
  20 + 'type' => 'string',
  21 + 'content' =>
  22 + array(),
  23 + 'value' => '',
  24 + 'rule' => 'required',
  25 + 'msg' => '',
  26 + 'tip' => '',
  27 + 'ok' => '',
  28 + 'extend' => '',
  29 + ),
  30 + array(
  31 + 'name' => 'voiceAppid',
  32 + 'title' => '语音短信AppID',
  33 + 'type' => 'string',
  34 + 'content' =>
  35 + array(),
  36 + 'value' => '',
  37 + 'rule' => 'required',
  38 + 'msg' => '使用语音短信必须设置',
  39 + 'tip' => '',
  40 + 'ok' => '',
  41 + 'extend' => '',
  42 + ),
  43 + array(
  44 + 'name' => 'voiceAppkey',
  45 + 'title' => '语音短信AppKEY',
  46 + 'type' => 'string',
  47 + 'content' =>
  48 + array(),
  49 + 'value' => '',
  50 + 'rule' => 'required',
  51 + 'msg' => '使用语音短信必须设置',
  52 + 'tip' => '',
  53 + 'ok' => '',
  54 + 'extend' => '',
  55 + ),
  56 + array(
  57 + 'name' => 'sign',
  58 + 'title' => '签名',
  59 + 'type' => 'string',
  60 + 'content' =>
  61 + array(),
  62 + 'value' => 'your sign',
  63 + 'rule' => 'required',
  64 + 'msg' => '',
  65 + 'tip' => '',
  66 + 'ok' => '',
  67 + 'extend' => '',
  68 + ),
  69 + array(
  70 + 'name' => 'isVoice',
  71 + 'title' => '是否使用语音短信',
  72 + 'type' => 'radio',
  73 + 'content' =>
  74 + array(
  75 + 0 => '否',
  76 + 1 => '是',
  77 + ),
  78 + 'value' => '0',
  79 + 'rule' => 'required',
  80 + 'msg' => '',
  81 + 'tip' => '',
  82 + 'ok' => '',
  83 + 'extend' => '',
  84 + ),
  85 + array(
  86 + 'name' => 'isTemplateSender',
  87 + 'title' => '是否使用短信模板发送',
  88 + 'type' => 'radio',
  89 + 'content' =>
  90 + array(
  91 + 0 => '否',
  92 + 1 => '是',
  93 + ),
  94 + 'value' => '1',
  95 + 'rule' => 'required',
  96 + 'msg' => '',
  97 + 'tip' => '',
  98 + 'ok' => '',
  99 + 'extend' => '',
  100 + ),
  101 + array(
  102 + 'name' => 'template',
  103 + 'title' => '短信模板',
  104 + 'type' => 'array',
  105 + 'content' =>
  106 + array(),
  107 + 'value' =>
  108 + array(
  109 + 'register' => '',
  110 + 'resetpwd' => '',
  111 + 'changepwd' => '',
  112 + 'profile' => '',
  113 + ),
  114 + 'rule' => 'required',
  115 + 'msg' => '',
  116 + 'tip' => '',
  117 + 'ok' => '',
  118 + 'extend' => '',
  119 + ),
  120 + array(
  121 + 'name' => 'voiceTemplate',
  122 + 'title' => '语音短信模板',
  123 + 'type' => 'array',
  124 + 'content' =>
  125 + array(),
  126 + 'value' =>
  127 + array(
  128 + 'register' => '',
  129 + 'resetpwd' => '',
  130 + 'changepwd' => '',
  131 + 'profile' => '',
  132 + ),
  133 + 'rule' => 'required',
  134 + 'msg' => '',
  135 + 'tip' => '',
  136 + 'ok' => '',
  137 + 'extend' => '',
  138 + ),
  139 +);
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\controller;
  4 +
  5 +use think\addons\Controller;
  6 +
  7 +class Index extends Controller
  8 +{
  9 +
  10 + public function index()
  11 + {
  12 + $this->error("当前插件暂无前台页面");
  13 + }
  14 +
  15 +}
  1 +name = qcloudsms
  2 +title = 腾讯云短信发送插件
  3 +intro = 腾讯云短信发送插件
  4 +author = Seacent
  5 +website = https://www.seacent.com
  6 +version = 1.0.3
  7 +state = 1
  8 +url = /addons/qcloudsms
  9 +license = regular
  10 +licenseto = 10789
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +
  8 +/**
  9 + * 按语音文件fid发送语音通知类
  10 + *
  11 + */
  12 +class FileVoiceSender
  13 +{
  14 + private $url;
  15 + private $appid;
  16 + private $appkey;
  17 + private $util;
  18 +
  19 + /**
  20 + * 构造函数
  21 + *
  22 + * @param string $appid sdkappid
  23 + * @param string $appkey sdkappid对应的appkey
  24 + */
  25 + public function __construct($appid, $appkey)
  26 + {
  27 + $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendfvoice";
  28 + $this->appid = $appid;
  29 + $this->appkey = $appkey;
  30 + $this->util = new SmsSenderUtil();
  31 + }
  32 +
  33 + /**
  34 + *
  35 + * 按语音文件fid发送语音通知
  36 + *
  37 + * @param string $nationCode 国家码,如 86 为中国
  38 + * @param string $phoneNumber 不带国家码的手机号
  39 + * @param string $fid 语音文件fid
  40 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  41 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  42 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  43 + */
  44 + public function send($nationCode, $phoneNumber, $fid, $playtimes = 2, $ext = "")
  45 + {
  46 + $random = $this->util->getRandom();
  47 + $curTime = time();
  48 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  49 +
  50 + // 按照协议组织 post 包体
  51 + $data = new \stdClass();
  52 + $tel = new \stdClass();
  53 + $tel->nationcode = "".$nationCode;
  54 + $tel->mobile = "".$phoneNumber;
  55 + $data->tel = $tel;
  56 + $data->fid = $fid;
  57 + $data->playtimes = $playtimes;
  58 +
  59 + // app凭证
  60 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  61 + $curTime, array($phoneNumber));
  62 +
  63 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  64 + $data->time = $curTime;
  65 + $data->ext = $ext;
  66 +
  67 + return $this->util->sendCurlPost($wholeUrl, $data);
  68 + }
  69 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 拉取单个手机短信状态类
  9 + *
  10 + */
  11 +class SmsMobileStatusPuller
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus4mobile";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 拉取回执结果
  34 + *
  35 + * @param int $type 拉取类型,0表示回执结果,1表示回复信息
  36 + * @param string $nationCode 国家码,如 86 为中国
  37 + * @param string $mobile 不带国家码的手机号
  38 + * @param int $beginTime 开始时间(unix timestamp)
  39 + * @param int $endTime 结束时间(unix timestamp)
  40 + * @param int $max 拉取最大条数,最多100
  41 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  42 + */
  43 + private function pull($type, $nationCode, $mobile, $beginTime, $endTime, $max)
  44 + {
  45 + $random = $this->util->getRandom();
  46 + $curTime = time();
  47 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  48 +
  49 + $data = new \stdClass();
  50 + $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
  51 + $data->time = $curTime;
  52 + $data->type = $type;
  53 + $data->max = $max;
  54 + $data->begin_time = $beginTime;
  55 + $data->end_time = $endTime;
  56 + $data->nationcode = $nationCode;
  57 + $data->mobile = $mobile;
  58 +
  59 + return $this->util->sendCurlPost($wholeUrl, $data);
  60 + }
  61 +
  62 + /**
  63 + * 拉取回执结果
  64 + *
  65 + * @param string $nationCode 国家码,如 86 为中国
  66 + * @param string $mobile 不带国家码的手机号
  67 + * @param int $beginTime 开始时间(unix timestamp)
  68 + * @param int $endTime 结束时间(unix timestamp)
  69 + * @param int $max 拉取最大条数,最多100
  70 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  71 + */
  72 + public function pullCallback($nationCode, $mobile, $beginTime, $endTime, $max)
  73 + {
  74 + return $this->pull(0, $nationCode, $mobile, $beginTime, $endTime, $max);
  75 + }
  76 +
  77 + /**
  78 + * 拉取回复信息
  79 + *
  80 + * @param string $nationCode 国家码,如 86 为中国
  81 + * @param string $mobile 不带国家码的手机号
  82 + * @param int $beginTime 开始时间(unix timestamp)
  83 + * @param int $endTime 结束时间(unix timestamp)
  84 + * @param int $max 拉取最大条数,最多100
  85 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  86 + */
  87 + public function pullReply($nationCode, $mobile, $beginTime, $endTime, $max)
  88 + {
  89 + return $this->pull(1, $nationCode, $mobile, $beginTime, $endTime, $max);
  90 + }
  91 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 群发短信类
  9 + *
  10 + */
  11 +class SmsMultiSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 普通群发
  34 + *
  35 + * 普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
  36 + * 否则系统将使用默认签名。
  37 + *
  38 + *
  39 + * @param int $type 短信类型,0 为普通短信,1 营销短信
  40 + * @param string $nationCode 国家码,如 86 为中国
  41 + * @param array $phoneNumbers 不带国家码的手机号列表
  42 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  43 + * @param string $extend 扩展码,可填空串
  44 + * @param string $ext 服务端原样返回的参数,可填空串
  45 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  46 + */
  47 + public function send($type, $nationCode, $phoneNumbers, $msg, $extend = "", $ext = "")
  48 + {
  49 + $random = $this->util->getRandom();
  50 + $curTime = time();
  51 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  52 +
  53 + $data = new \stdClass();
  54 + $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
  55 + $data->type = $type;
  56 + $data->msg = $msg;
  57 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  58 + $curTime, $phoneNumbers);
  59 + $data->time = $curTime;
  60 + $data->extend = $extend;
  61 + $data->ext = $ext;
  62 +
  63 + return $this->util->sendCurlPost($wholeUrl, $data);
  64 + }
  65 +
  66 + /**
  67 + * 指定模板群发
  68 + *
  69 + *
  70 + * @param string $nationCode 国家码,如 86 为中国
  71 + * @param array $phoneNumbers 不带国家码的手机号列表
  72 + * @param int $templId 模板id
  73 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
  74 + * @param string $sign 签名,如果填空串,系统会使用默认签名
  75 + * @param string $extend 扩展码,可填空串
  76 + * @param string $ext 服务端原样返回的参数,可填空串
  77 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  78 + */
  79 + public function sendWithParam($nationCode, $phoneNumbers, $templId, $params,
  80 + $sign = "", $extend = "", $ext = "")
  81 + {
  82 + $random = $this->util->getRandom();
  83 + $curTime = time();
  84 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  85 +
  86 + $data = new \stdClass();
  87 + $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
  88 + $data->sign = $sign;
  89 + $data->tpl_id = $templId;
  90 + $data->params = $params;
  91 + $data->sig = $this->util->calculateSigForTemplAndPhoneNumbers(
  92 + $this->appkey, $random, $curTime, $phoneNumbers);
  93 + $data->time = $curTime;
  94 + $data->extend = $extend;
  95 + $data->ext = $ext;
  96 +
  97 + return $this->util->sendCurlPost($wholeUrl, $data);
  98 + }
  99 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +/**
  6 + * 发送Util类
  7 + *
  8 + */
  9 +class SmsSenderUtil
  10 +{
  11 + /**
  12 + * 生成随机数
  13 + *
  14 + * @return int 随机数结果
  15 + */
  16 + public function getRandom()
  17 + {
  18 + return rand(100000, 999999);
  19 + }
  20 +
  21 + /**
  22 + * 生成签名
  23 + *
  24 + * @param string $appkey sdkappid对应的appkey
  25 + * @param string $random 随机正整数
  26 + * @param string $curTime 当前时间
  27 + * @param array $phoneNumbers 手机号码
  28 + * @return string 签名结果
  29 + */
  30 + public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
  31 + {
  32 + $phoneNumbersString = $phoneNumbers[0];
  33 + for ($i = 1; $i < count($phoneNumbers); $i++) {
  34 + $phoneNumbersString .= ("," . $phoneNumbers[$i]);
  35 + }
  36 +
  37 + return hash("sha256", "appkey=".$appkey."&random=".$random
  38 + ."&time=".$curTime."&mobile=".$phoneNumbersString);
  39 + }
  40 +
  41 + /**
  42 + * 生成签名
  43 + *
  44 + * @param string $appkey sdkappid对应的appkey
  45 + * @param string $random 随机正整数
  46 + * @param string $curTime 当前时间
  47 + * @param array $phoneNumbers 手机号码
  48 + * @return string 签名结果
  49 + */
  50 + public function calculateSigForTemplAndPhoneNumbers($appkey, $random,
  51 + $curTime, $phoneNumbers)
  52 + {
  53 + $phoneNumbersString = $phoneNumbers[0];
  54 + for ($i = 1; $i < count($phoneNumbers); $i++) {
  55 + $phoneNumbersString .= ("," . $phoneNumbers[$i]);
  56 + }
  57 +
  58 + return hash("sha256", "appkey=".$appkey."&random=".$random
  59 + ."&time=".$curTime."&mobile=".$phoneNumbersString);
  60 + }
  61 +
  62 + public function phoneNumbersToArray($nationCode, $phoneNumbers)
  63 + {
  64 + $i = 0;
  65 + $tel = array();
  66 + do {
  67 + $telElement = new \stdClass();
  68 + $telElement->nationcode = $nationCode;
  69 + $telElement->mobile = $phoneNumbers[$i];
  70 + array_push($tel, $telElement);
  71 + } while (++$i < count($phoneNumbers));
  72 +
  73 + return $tel;
  74 + }
  75 +
  76 + /**
  77 + * 生成签名
  78 + *
  79 + * @param string $appkey sdkappid对应的appkey
  80 + * @param string $random 随机正整数
  81 + * @param string $curTime 当前时间
  82 + * @param array $phoneNumber 手机号码
  83 + * @return string 签名结果
  84 + */
  85 + public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
  86 + {
  87 + $phoneNumbers = array($phoneNumber);
  88 +
  89 + return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
  90 + $curTime, $phoneNumbers);
  91 + }
  92 +
  93 + /**
  94 + * 生成签名
  95 + *
  96 + * @param string $appkey sdkappid对应的appkey
  97 + * @param string $random 随机正整数
  98 + * @param string $curTime 当前时间
  99 + * @return string 签名结果
  100 + */
  101 + public function calculateSigForPuller($appkey, $random, $curTime)
  102 + {
  103 + return hash("sha256", "appkey=".$appkey."&random=".$random
  104 + ."&time=".$curTime);
  105 + }
  106 +
  107 + /**
  108 + * 生成上传文件授权
  109 + *
  110 + * @param string $appkey sdkappid对应的appkey
  111 + * @param string $random 随机正整数
  112 + * @param string $curTime 当前时间
  113 + * @param array $fileSha1Sum 文件sha1sum
  114 + * @return string 授权结果
  115 + */
  116 + public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
  117 + {
  118 + return hash("sha256", "appkey=".$appkey."&random=".$random
  119 + ."&time=".$curTime."&content-sha1=".$fileSha1Sum);
  120 + }
  121 +
  122 + /**
  123 + * 生成sha1sum
  124 + *
  125 + * @param string $content 内容
  126 + * @return string 内容sha1散列值
  127 + */
  128 + public function sha1sum($content)
  129 + {
  130 + return hash("sha1", $content);
  131 + }
  132 +
  133 + /**
  134 + * 发送请求
  135 + *
  136 + * @param string $url 请求地址
  137 + * @param array $dataObj 请求内容
  138 + * @return string 应答json字符串
  139 + */
  140 + public function sendCurlPost($url, $dataObj)
  141 + {
  142 + $curl = curl_init();
  143 + curl_setopt($curl, CURLOPT_URL, $url);
  144 + curl_setopt($curl, CURLOPT_HEADER, 0);
  145 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  146 + curl_setopt($curl, CURLOPT_POST, 1);
  147 + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  148 + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
  149 + curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  150 + 'Content-Type: application/json; charset=utf-8',
  151 + 'Content-Length: ' . strlen(json_encode($dataObj)))
  152 + );
  153 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  154 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  155 +
  156 + $ret = curl_exec($curl);
  157 + if (false == $ret) {
  158 + // curl_exec failed
  159 + $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
  160 + } else {
  161 + $rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  162 + if (200 != $rsp) {
  163 + $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
  164 + . " " . curl_error($curl) ."\"}";
  165 + } else {
  166 + $result = $ret;
  167 + }
  168 + }
  169 +
  170 + curl_close($curl);
  171 +
  172 + return $result;
  173 + }
  174 +
  175 + /**
  176 + * 发送请求
  177 + *
  178 + * @param string $req 请求对象
  179 + * @return string 应答json字符串
  180 + */
  181 + public function fetch($req)
  182 + {
  183 + $curl = curl_init();
  184 +
  185 + curl_setopt($curl, CURLOPT_URL, $req->url);
  186 + curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
  187 + curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
  188 + curl_setopt($curl, CURLOPT_HEADER, 0);
  189 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  190 + curl_setopt($curl, CURLOPT_POST, 1);
  191 + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  192 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  193 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  194 +
  195 + $result = curl_exec($curl);
  196 +
  197 + if (false == $result) {
  198 + // curl_exec failed
  199 + $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
  200 + } else {
  201 + $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  202 + if (200 != $code) {
  203 + $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
  204 + . " " . curl_error($curl) ."\"}";
  205 + }
  206 + }
  207 + curl_close($curl);
  208 +
  209 + return $result;
  210 + }
  211 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 单发短信类
  9 + *
  10 + */
  11 +class SmsSingleSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 普通单发
  34 + *
  35 + * 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
  36 + *
  37 + * @param int $type 短信类型,0 为普通短信,1 营销短信
  38 + * @param string $nationCode 国家码,如 86 为中国
  39 + * @param string $phoneNumber 不带国家码的手机号
  40 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  41 + * @param string $extend 扩展码,可填空串
  42 + * @param string $ext 服务端原样返回的参数,可填空串
  43 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  44 + */
  45 + public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
  46 + {
  47 + $random = $this->util->getRandom();
  48 + $curTime = time();
  49 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  50 +
  51 + // 按照协议组织 post 包体
  52 + $data = new \stdClass();
  53 + $tel = new \stdClass();
  54 + $tel->nationcode = "".$nationCode;
  55 + $tel->mobile = "".$phoneNumber;
  56 +
  57 + $data->tel = $tel;
  58 + $data->type = (int)$type;
  59 + $data->msg = $msg;
  60 + $data->sig = hash("sha256",
  61 + "appkey=".$this->appkey."&random=".$random."&time="
  62 + .$curTime."&mobile=".$phoneNumber, FALSE);
  63 + $data->time = $curTime;
  64 + $data->extend = $extend;
  65 + $data->ext = $ext;
  66 +
  67 + return $this->util->sendCurlPost($wholeUrl, $data);
  68 + }
  69 +
  70 + /**
  71 + * 指定模板单发
  72 + *
  73 + * @param string $nationCode 国家码,如 86 为中国
  74 + * @param string $phoneNumber 不带国家码的手机号
  75 + * @param int $templId 模板 id
  76 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
  77 + * @param string $sign 签名,如果填空串,系统会使用默认签名
  78 + * @param string $extend 扩展码,可填空串
  79 + * @param string $ext 服务端原样返回的参数,可填空串
  80 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  81 + */
  82 + public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
  83 + $sign = "", $extend = "", $ext = "")
  84 + {
  85 + $random = $this->util->getRandom();
  86 + $curTime = time();
  87 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  88 +
  89 + // 按照协议组织 post 包体
  90 + $data = new \stdClass();
  91 + $tel = new \stdClass();
  92 + $tel->nationcode = "".$nationCode;
  93 + $tel->mobile = "".$phoneNumber;
  94 +
  95 + $data->tel = $tel;
  96 + $data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
  97 + $curTime, $phoneNumber);
  98 + $data->tpl_id = $templId;
  99 + $data->params = $params;
  100 + $data->sign = $sign;
  101 + $data->time = $curTime;
  102 + $data->extend = $extend;
  103 + $data->ext = $ext;
  104 +
  105 + return $this->util->sendCurlPost($wholeUrl, $data);
  106 + }
  107 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 拉取短信状态类
  9 + *
  10 + */
  11 +class SmsStatusPuller
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 拉取回执结果
  34 + *
  35 + * @param int $type 拉取类型,0表示回执结果,1表示回复信息
  36 + * @param int $max 最大条数,最多100
  37 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  38 + */
  39 + private function pull($type, $max)
  40 + {
  41 + $random = $this->util->getRandom();
  42 + $curTime = time();
  43 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  44 +
  45 + $data = new \stdClass();
  46 + $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
  47 + $data->time = $curTime;
  48 + $data->type = $type;
  49 + $data->max = $max;
  50 +
  51 + return $this->util->sendCurlPost($wholeUrl, $data);
  52 + }
  53 +
  54 + /**
  55 + * 拉取回执结果
  56 + *
  57 + * @param int $max 拉取最大条数,最多100
  58 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  59 + */
  60 + public function pullCallback($max)
  61 + {
  62 + return $this->pull(0, $max);
  63 + }
  64 +
  65 + /**
  66 + * 拉取回复信息
  67 + *
  68 + * @param int $max 拉取最大条数,最多100
  69 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  70 + */
  71 + public function pullReply($max)
  72 + {
  73 + return $this->pull(1, $max);
  74 + }
  75 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 发送语音通知类
  9 + *
  10 + */
  11 +class SmsVoicePromptSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoiceprompt";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + *
  34 + * 发送语音通知
  35 + *
  36 + * @param string $nationCode 国家码,如 86 为中国
  37 + * @param string $phoneNumber 不带国家码的手机号
  38 + * @param string $prompttype 语音类型,目前固定为2
  39 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  40 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  41 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  42 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  43 + */
  44 + public function send($nationCode, $phoneNumber, $prompttype, $msg, $playtimes = 2, $ext = "")
  45 + {
  46 + $random = $this->util->getRandom();
  47 + $curTime = time();
  48 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  49 +
  50 + // 按照协议组织 post 包体
  51 + $data = new \stdClass();
  52 + $tel = new \stdClass();
  53 + $tel->nationcode = "".$nationCode;
  54 + $tel->mobile = "".$phoneNumber;
  55 +
  56 + $data->tel = $tel;
  57 + // 通知内容,utf8编码,支持中文英文、数字及组合,需要和语音内容模版相匹配
  58 + $data->promptfile = $msg;
  59 + // 固定值 2
  60 + $data->prompttype = $prompttype;
  61 + $data->playtimes = $playtimes;
  62 + // app凭证
  63 + $data->sig = hash("sha256",
  64 + "appkey=".$this->appkey."&random=".$random."&time="
  65 + .$curTime."&mobile=".$phoneNumber, FALSE);
  66 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  67 + $data->time = $curTime;
  68 + $data->ext = $ext;
  69 + return $this->util->sendCurlPost($wholeUrl, $data);
  70 + }
  71 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 发送语音验证码类
  9 + *
  10 + */
  11 +class SmsVoiceVerifyCodeSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoice";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 发送语音验证码
  34 + *
  35 + * @param string $nationCode 国家码,如 86 为中国
  36 + * @param string $phoneNumber 不带国家码的手机号
  37 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  38 + * @param int $playtimes 播放次数,可选,最多3次,默认2次
  39 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  40 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  41 + */
  42 + public function send($nationCode, $phoneNumber, $msg, $playtimes = 2, $ext = "")
  43 + {
  44 + $random = $this->util->getRandom();
  45 + $curTime = time();
  46 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  47 +
  48 + // 按照协议组织 post 包体
  49 + $data = new \stdClass();
  50 + $tel = new \stdClass();
  51 + $tel->nationcode = "".$nationCode;
  52 + $tel->mobile = "".$phoneNumber;
  53 +
  54 + $data->tel = $tel;
  55 + $data->msg = $msg;
  56 + $data->playtimes = $playtimes;
  57 + // app凭证
  58 + $data->sig = hash("sha256",
  59 + "appkey=".$this->appkey."&random=".$random."&time="
  60 + .$curTime."&mobile=".$phoneNumber, FALSE);
  61 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  62 + $data->time = $curTime;
  63 + $data->ext = $ext;
  64 +
  65 + return $this->util->sendCurlPost($wholeUrl, $data);
  66 + }
  67 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +
  8 +/**
  9 + * 指定模板发送语音通知类
  10 + *
  11 + */
  12 +class TtsVoiceSender
  13 +{
  14 + private $url;
  15 + private $appid;
  16 + private $appkey;
  17 + private $util;
  18 +
  19 + /**
  20 + * 构造函数
  21 + *
  22 + * @param string $appid sdkappid
  23 + * @param string $appkey sdkappid对应的appkey
  24 + */
  25 + public function __construct($appid, $appkey)
  26 + {
  27 + $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendtvoice";
  28 + $this->appid = $appid;
  29 + $this->appkey = $appkey;
  30 + $this->util = new SmsSenderUtil();
  31 + }
  32 +
  33 + /**
  34 + *
  35 + * 指定模板发送语音短信
  36 + *
  37 + * @param string $nationCode 国家码,如 86 为中国
  38 + * @param string $phoneNumber 不带国家码的手机号
  39 + * @param int $templId 模板 id
  40 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},需要带三个参数
  41 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  42 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  43 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  44 + */
  45 + public function send($nationCode, $phoneNumber, $templId, $params, $playtimes = 2, $ext = "")
  46 + {
  47 + /*var_dump($nationCode);
  48 + var_dump($phoneNumber);
  49 + var_dump($templId);
  50 + var_dump($params);
  51 + var_dump($playtimes);
  52 + exit();*/
  53 + $random = $this->util->getRandom();
  54 + $curTime = time();
  55 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  56 +
  57 + // 按照协议组织 post 包体
  58 + $data = new \stdClass();
  59 + $tel = new \stdClass();
  60 + $tel->nationcode = "".$nationCode;
  61 + $tel->mobile = "".$phoneNumber;
  62 + $data->tel = $tel;
  63 + $data->tpl_id = $templId;
  64 + $data->params = $params;
  65 + $data->playtimes = $playtimes;
  66 +
  67 + // app凭证
  68 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  69 + $curTime, array($phoneNumber));
  70 +
  71 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  72 + $data->time = $curTime;
  73 + $data->ext = $ext;
  74 + //var_dump($data);exit();
  75 + return $this->util->sendCurlPost($wholeUrl, $data);
  76 + }
  77 +}
@@ -2,24 +2,18 @@ @@ -2,24 +2,18 @@
2 2
3 namespace app\admin\controller\litestore; 3 namespace app\admin\controller\litestore;
4 4
5 -use addons\fastexport\library\ExportLib;  
6 use app\admin\model\litestore\Litestoregoodsspec; 5 use app\admin\model\litestore\Litestoregoodsspec;
7 -use app\api\model\Goods;  
8 use app\common\controller\Backend; 6 use app\common\controller\Backend;
9 use app\admin\model\litestore\Litestorespec as SpecModel; 7 use app\admin\model\litestore\Litestorespec as SpecModel;
10 use app\admin\model\litestore\Litestorespecvalue as SpecValueModel; 8 use app\admin\model\litestore\Litestorespecvalue as SpecValueModel;
11 -use PHPExcel;  
12 -use PHPExcel_Style;  
13 -use PHPExcel_Style_Alignment;  
14 -use PHPExcel_Style_Border;  
15 -use PHPExcel_Style_Fill;  
16 -use PhpOffice\PhpSpreadsheet\Cell\DataType;  
17 -use PhpOffice\PhpSpreadsheet\Spreadsheet;  
18 -use PhpOffice\PhpSpreadsheet\Writer\Xlsx; 9 +use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  10 +use PhpOffice\PhpSpreadsheet\Reader\Csv;
  11 +use PhpOffice\PhpSpreadsheet\Reader\Xls;
  12 +use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
19 use think\Db; 13 use think\Db;
20 -use think\Exception;  
21 use think\exception\PDOException; 14 use think\exception\PDOException;
22 15
  16 +
23 /** 17 /**
24 * 18 *
25 * 19 *
@@ -34,6 +28,7 @@ class Litestoregoods extends Backend @@ -34,6 +28,7 @@ class Litestoregoods extends Backend
34 * @var \app\admin\model\litestore\Litestoregoods 28 * @var \app\admin\model\litestore\Litestoregoods
35 */ 29 */
36 protected $model = null; 30 protected $model = null;
  31 + protected $spec_model = null;
37 32
38 public function _initialize() 33 public function _initialize()
39 { 34 {
@@ -41,7 +36,8 @@ class Litestoregoods extends Backend @@ -41,7 +36,8 @@ class Litestoregoods extends Backend
41 $this->SpecModel = new SpecModel; 36 $this->SpecModel = new SpecModel;
42 $this->SpecValueModel = new SpecValueModel; 37 $this->SpecValueModel = new SpecValueModel;
43 38
44 - $this->model = new \app\admin\model\litestore\Litestoregoods; 39 + $this->model = new \app\admin\model\litestore\Litestoregoods;
  40 + $this->spec_model = new \app\admin\model\litestore\Litestoregoodsspec();
45 $this->view->assign("specTypeList", $this->model->getSpecTypeList()); 41 $this->view->assign("specTypeList", $this->model->getSpecTypeList());
46 $this->view->assign("deductStockTypeList", $this->model->getDeductStockTypeList()); 42 $this->view->assign("deductStockTypeList", $this->model->getDeductStockTypeList());
47 $this->view->assign("goodsStatusList", $this->model->getGoodsStatusList()); 43 $this->view->assign("goodsStatusList", $this->model->getGoodsStatusList());
@@ -100,6 +96,8 @@ class Litestoregoods extends Backend @@ -100,6 +96,8 @@ class Litestoregoods extends Backend
100 96
101 return json($result); 97 return json($result);
102 } 98 }
  99 + $this->assign('template', $this->request->domain() . '/static/template/商品导入模板.xlsx');
  100 +
103 return $this->view->fetch(); 101 return $this->view->fetch();
104 } 102 }
105 103
@@ -292,6 +290,7 @@ class Litestoregoods extends Backend @@ -292,6 +290,7 @@ class Litestoregoods extends Backend
292 ->select(); 290 ->select();
293 $list = collection($list)->toArray(); 291 $list = collection($list)->toArray();
294 foreach ($list as &$item) { 292 foreach ($list as &$item) {
  293 + $item['category_name'] = Db::name('litestore_category')->where('id', $item['category_id'])->value('name');
295 if (!empty($item['spec_sku_id'])) { 294 if (!empty($item['spec_sku_id'])) {
296 $sku_value = explode('_', $item['spec_sku_id']); 295 $sku_value = explode('_', $item['spec_sku_id']);
297 if (count($sku_value) > 1) { 296 if (count($sku_value) > 1) {
@@ -320,35 +319,57 @@ class Litestoregoods extends Backend @@ -320,35 +319,57 @@ class Litestoregoods extends Backend
320 $objPHPExcel->setActiveSheetIndex(0) 319 $objPHPExcel->setActiveSheetIndex(0)
321 ->setCellValue('A1', '商品ID') 320 ->setCellValue('A1', '商品ID')
322 ->setCellValue('B1', '商品名称') 321 ->setCellValue('B1', '商品名称')
323 - ->setCellValue('C1', '商品规格')  
324 - ->setCellValue('D1', '商品原价')  
325 - ->setCellValue('E1', '折扣')  
326 - ->setCellValue('F1', '商品现价')  
327 - ->setCellValue('G1', '已销数量')  
328 - ->setCellValue('H1', '导出时间'); 322 + ->setCellValue('C1', '搜索关键词')
  323 + ->setCellValue('D1', '分类名称')
  324 + ->setCellValue('E1', '活动名称(新人用户=1,限时秒杀=2,进口商品=4)')
  325 + ->setCellValue('F1', '商品规格(10=单规格,20=多规格)')
  326 + ->setCellValue('G1', '库存')
  327 + ->setCellValue('H1', '商品规格')
  328 + ->setCellValue('I1', '商品原价')
  329 + ->setCellValue('J1', '折扣')
  330 + ->setCellValue('K1', '商品现价')
  331 + ->setCellValue('L1', '已销数量')
  332 + ->setCellValue('M1', '商品状态(10=上架,20=下架)')
  333 + ->setCellValue('N1', '首页展示(0=未展示,1=已展示)')
  334 + ->setCellValue('O1', '导出时间');
329 //设置A列水平居中 335 //设置A列水平居中
330 $objPHPExcel->setActiveSheetIndex(0)->getStyle('A1')->getAlignment() 336 $objPHPExcel->setActiveSheetIndex(0)->getStyle('A1')->getAlignment()
331 ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 337 ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
332 //设置单元格宽度 338 //设置单元格宽度
333 //6.循环刚取出来的数组,将数据逐一添加到excel表格。 339 //6.循环刚取出来的数组,将数据逐一添加到excel表格。
334 - $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('B')->setWidth(10); 340 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('A')->setWidth(10);
  341 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('B')->setWidth(20);
335 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('C')->setWidth(20); 342 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('C')->setWidth(20);
336 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('D')->setWidth(20); 343 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('D')->setWidth(20);
337 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('E')->setWidth(20); 344 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('E')->setWidth(20);
338 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('F')->setWidth(20); 345 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('F')->setWidth(20);
339 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('G')->setWidth(20); 346 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('G')->setWidth(20);
340 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('H')->setWidth(20); 347 $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('H')->setWidth(20);
  348 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('I')->setWidth(20);
  349 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('J')->setWidth(20);
  350 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('K')->setWidth(20);
  351 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('L')->setWidth(20);
  352 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('M')->setWidth(20);
  353 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('N')->setWidth(20);
  354 + $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('O')->setWidth(20);
341 355
342 356
343 for ($i = 0; $i < count($list); $i++) { 357 for ($i = 0; $i < count($list); $i++) {
344 $objPHPExcel->getActiveSheet()->setCellValue('A' . ($i + 2), $list[$i]['goods_id']);//ID 358 $objPHPExcel->getActiveSheet()->setCellValue('A' . ($i + 2), $list[$i]['goods_id']);//ID
345 $objPHPExcel->getActiveSheet()->setCellValue('B' . ($i + 2), $list[$i]['goods_name']);//商品名称 359 $objPHPExcel->getActiveSheet()->setCellValue('B' . ($i + 2), $list[$i]['goods_name']);//商品名称
346 - $objPHPExcel->getActiveSheet()->setCellValue('C' . ($i + 2), $list[$i]['sku_value']);//商品规格  
347 - $objPHPExcel->getActiveSheet()->setCellValue('D' . ($i + 2), $list[$i]['line_price']);//原价  
348 - $objPHPExcel->getActiveSheet()->setCellValue('E' . ($i + 2), $list[$i]['discount']);//ID  
349 - $objPHPExcel->getActiveSheet()->setCellValue('F' . ($i + 2), $list[$i]['goods_price']);//标签码  
350 - $objPHPExcel->getActiveSheet()->setCellValue('G' . ($i + 2), $list[$i]['goods_sales']);//ID  
351 - $objPHPExcel->getActiveSheet()->setCellValue('H' . ($i + 2), datetime(time()));//标签码 360 + $objPHPExcel->getActiveSheet()->setCellValue('C' . ($i + 2), $list[$i]['keywords']);//商品规格
  361 + $objPHPExcel->getActiveSheet()->setCellValue('D' . ($i + 2), $list[$i]['category_name']);//原价
  362 + $objPHPExcel->getActiveSheet()->setCellValue('E' . ($i + 2), $list[$i]['activity_id']);//ID
  363 + $objPHPExcel->getActiveSheet()->setCellValue('F' . ($i + 2), $list[$i]['spec_type']);//标签码
  364 + $objPHPExcel->getActiveSheet()->setCellValue('G' . ($i + 2), $list[$i]['stock_num']);//ID
  365 + $objPHPExcel->getActiveSheet()->setCellValue('H' . ($i + 2), $list[$i]['sku_value']);//ID
  366 + $objPHPExcel->getActiveSheet()->setCellValue('I' . ($i + 2), $list[$i]['line_price']);//ID
  367 + $objPHPExcel->getActiveSheet()->setCellValue('J' . ($i + 2), $list[$i]['discount']);//ID
  368 + $objPHPExcel->getActiveSheet()->setCellValue('K' . ($i + 2), $list[$i]['goods_price']);//ID
  369 + $objPHPExcel->getActiveSheet()->setCellValue('L' . ($i + 2), $list[$i]['goods_sales']);//ID
  370 + $objPHPExcel->getActiveSheet()->setCellValue('M' . ($i + 2), $list[$i]['goods_status']);//ID
  371 + $objPHPExcel->getActiveSheet()->setCellValue('N' . ($i + 2), $list[$i]['is_index']);//标签码
  372 + $objPHPExcel->getActiveSheet()->setCellValue('O' . ($i + 2), datetime(time()));//标签码
352 } 373 }
353 ob_end_clean(); 374 ob_end_clean();
354 ob_start(); 375 ob_start();
@@ -366,6 +387,100 @@ class Litestoregoods extends Backend @@ -366,6 +387,100 @@ class Litestoregoods extends Backend
366 exit(); 387 exit();
367 } 388 }
368 389
  390 + /**
  391 + *导入
  392 + *
  393 + * */
  394 + public function import()
  395 + {
  396 + $file = $this->request->request('file');
  397 + if (!$file) {
  398 + $this->error(__('Parameter %s can not be empty', 'file'));
  399 + }
  400 + $filePath = ROOT_PATH . DS . 'public' . DS . $file;
  401 + if (!is_file($filePath)) {
  402 + $this->error(__('No results were found'));
  403 + }
  404 + //实例化reader
  405 + $ext = pathinfo($filePath, PATHINFO_EXTENSION);
  406 + if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
  407 + $this->error(__('Unknown data format'));
  408 + }
  409 + if ($ext === 'csv') {
  410 + $file = fopen($filePath, 'r');
  411 + $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
  412 + $fp = fopen($filePath, "w");
  413 + $n = 0;
  414 + while ($line = fgets($file)) {
  415 + $line = rtrim($line, "\n\r\0");
  416 + $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
  417 + if ($encoding != 'utf-8') {
  418 + $line = mb_convert_encoding($line, 'utf-8', $encoding);
  419 + }
  420 + if ($n == 0 || preg_match('/^".*"$/', $line)) {
  421 + fwrite($fp, $line . "\n");
  422 + } else {
  423 + fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
  424 + }
  425 + $n++;
  426 + }
  427 + fclose($file) || fclose($fp);
  428 + $reader = new Csv();
  429 + } elseif ($ext === 'xls') {
  430 + $reader = new Xls();
  431 + } else {
  432 + $reader = new Xlsx();
  433 + }
  434 + set_time_limit(0);
  435 + //加载文件
  436 + $insert = [];
  437 + try {
  438 + if (!$PHPExcel = $reader->load($filePath)) {
  439 + $this->error(__('Unknown data format'));
  440 + }
  441 + $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
  442 + $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
  443 + $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
  444 + $maxColumnNumber = Coordinate::columnIndexFromString($allColumn); // 一共多少列
  445 + for ($i = 2; $i <= $allRow; $i++) {
  446 + if (!empty($PHPExcel->getActiveSheet()->getCell("A" . $i)->getValue())) {
  447 + $insert[$i]['goods_name'] = $PHPExcel->getActiveSheet()->getCell("A" . $i)->getValue();//商品名称
  448 + $insert[$i]['keywords'] = $PHPExcel->getActiveSheet()->getCell("B" . $i)->getValue();//关键词
  449 + $category = $PHPExcel->getActiveSheet()->getCell("C" . $i)->getValue() ?? '';//类别
  450 + $insert[$i]['category_id'] = Db::name('litestore_category')->where('name', $category)->value('id') ?? '';
  451 + $insert[$i]['activity_id'] = $PHPExcel->getActiveSheet()->getCell("D" . $i)->getValue() ?? '';//活动类型
  452 + $insert[$i]['is_index'] = $PHPExcel->getActiveSheet()->getCell("I" . $i)->getValue() ?? '';//是否首页
  453 + $insert[$i]['goods_status'] = $PHPExcel->getActiveSheet()->getCell("H" . $i)->getValue() ?? '';//商品状态
  454 + $spec_insert[$i]['stock_num'] = $PHPExcel->getActiveSheet()->getCell("E" . $i)->getValue() ?? '';//库存
  455 + $spec_insert[$i]['goods_price'] = $PHPExcel->getActiveSheet()->getCell("G" . $i)->getValue() ?? '';//现价
  456 + $spec_insert[$i]['line_price'] = $PHPExcel->getActiveSheet()->getCell("F" . $i)->getValue() ?? '';//原价
  457 + }
  458 + }
  459 + } catch (\Exception $exception) {
  460 + $this->error($exception->getMessage());
  461 + }
  462 + if (!$insert) {
  463 + $this->error(__('No rows were updated'));
  464 + }
  465 + try {
  466 +
  467 + $res_goods = $this->model->saveAll($insert);
  468 + foreach ($spec_insert as $key => &$v) {
  469 + $v['goods_id'] = $res_goods[$key]['goods_id'];
  470 + }
  471 + unset($v);
  472 + $this->spec_model->saveAll($spec_insert);
  473 + } catch (PDOException $exception) {
  474 + $msg = $exception->getMessage();
  475 + if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
  476 + $msg = "导入失败,包含【{$matches[1]}】的记录已存在";
  477 + };
  478 + $this->error($msg);
  479 + } catch (\Exception $e) {
  480 + $this->error($e->getMessage());
  481 + }
  482 + $this->success();
  483 + }
369 484
370 485
371 } 486 }
@@ -17,18 +17,19 @@ @@ -17,18 +17,19 @@
17 <a href="javascript:;" 17 <a href="javascript:;"
18 class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('litestore/litestoregoods/del')?'':'hide'}" 18 class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('litestore/litestoregoods/del')?'':'hide'}"
19 title="{:__('Delete')}"><i class="fa fa-trash"></i> {:__('Delete')}</a> 19 title="{:__('Delete')}"><i class="fa fa-trash"></i> {:__('Delete')}</a>
20 - <!-- <a href="javascript:;"-->  
21 - <!-- class="btn btn-danger btn-import {:$auth->check('litestore/litestoregoods/import')?'':'hide'}"-->  
22 - <!-- title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload"-->  
23 - <!-- data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i>-->  
24 - <!-- {:__('Import')}</a>-->  
25 - <!-- <a href="javascript:;"--> 20 + <a href="javascript:;"
  21 + class="btn btn-danger btn-import {:$auth->check('litestore/litestoregoods/import')?'':'hide'}"
  22 + title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload"
  23 + data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i>
  24 + {:__('Import')}</a>
  25 + <!-- <a href="javascript:;"-->
26 <!-- class="btn btn-info btn-change btn-export btn-disable" data-params="action=export"--> 26 <!-- class="btn btn-info btn-change btn-export btn-disable" data-params="action=export"-->
27 <!-- data-url="litestore/litestoregoods/export"--> 27 <!-- data-url="litestore/litestoregoods/export"-->
28 <!-- title="{:__('批量导出')}"><i class="fa fa-download"></i>{:__('批量导出')}</a>--> 28 <!-- title="{:__('批量导出')}"><i class="fa fa-download"></i>{:__('批量导出')}</a>-->
29 <a href="javascript:;" 29 <a href="javascript:;"
30 class="btn btn-info btn-export {:$auth->check('litestore/litestoregoods/export')?'':'hide'}" 30 class="btn btn-info btn-export {:$auth->check('litestore/litestoregoods/export')?'':'hide'}"
31 title="{:__('Export')}" id="btn-export-file"><i class="fa fa-download"></i> 批量导出</a> 31 title="{:__('Export')}" id="btn-export-file"><i class="fa fa-download"></i> 批量导出</a>
  32 + <a href="{$template}" class="btn btn-info"><i class="fa fa-folder-open"></i> {:__('导入模板下载')}</a>
32 33
33 <!-- <div class="dropdown btn-group {:$auth->check('litestore/litestoregoods/multi')?'':'hide'}">--> 34 <!-- <div class="dropdown btn-group {:$auth->check('litestore/litestoregoods/multi')?'':'hide'}">-->
34 <!-- <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>--> 35 <!-- <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>-->
@@ -24,59 +24,61 @@ class Notify extends Api @@ -24,59 +24,61 @@ class Notify extends Api
24 public function orderNotify() 24 public function orderNotify()
25 { 25 {
26 $paytype = $this->request->param('type'); 26 $paytype = $this->request->param('type');
27 - $pay = Service::checkNotify($paytype); 27 + $pay = Service::checkNotify($paytype);
28 if (!$pay) { 28 if (!$pay) {
29 return '签名错误'; 29 return '签名错误';
30 } 30 }
31 $data = $pay->verify(); 31 $data = $pay->verify();
32 - if (!is_array($data)) $data = json_decode($data,true);  
33 - $model = new \app\api\model\Order();  
34 - $goodsmodel = new \app\api\model\OrderGoods();  
35 - $skumodel = new \app\api\model\GoodsSpec(); 32 + if (!is_array($data)) $data = json_decode($data, true);
  33 + $model = new \app\api\model\Order();
  34 + $goodsmodel = new \app\api\model\OrderGoods();
  35 + $skumodel = new \app\api\model\GoodsSpec();
36 $goods_model = new \app\api\model\Goods(); 36 $goods_model = new \app\api\model\Goods();
37 - $buymodel = new \app\api\model\UserBuylist(); 37 + $buymodel = new \app\api\model\UserBuylist();
38 try { 38 try {
39 $out_trade_no = $data['out_trade_no']; 39 $out_trade_no = $data['out_trade_no'];
40 - $order = $model  
41 - ->where('order_no',$out_trade_no)  
42 - ->where('pay_status','10')  
43 - ->where('order_status','10') 40 + $order = $model
  41 + ->where('order_no', $out_trade_no)
  42 + ->where('pay_status', '10')
  43 + ->where('order_status', '10')
44 ->find(); 44 ->find();
45 if (!$order) $this->error('订单不存在'); 45 if (!$order) $this->error('订单不存在');
46 - $order->pay_status = '20'; 46 + $order->pay_status = '20';
47 $order->transaction_id = $data['transaction_id']; 47 $order->transaction_id = $data['transaction_id'];
48 - $order->pay_time = time(); 48 + $order->pay_time = time();
49 $order->isUpdate()->save(); 49 $order->isUpdate()->save();
50 // 减少库存 50 // 减少库存
51 $sales_actual = 0; 51 $sales_actual = 0;
52 - $goods_ids = [];  
53 - $list = $goodsmodel->where('order_id',$order['id'])->select();  
54 - foreach ($list as $key => $value){  
55 - $goods_ids[] = $value['goods_id'];  
56 - $sales_actual+=$value['total_num'];  
57 - if ($value['deduct_stock_type'] == 20){  
58 - $skumodel->where('goods_spec_id',$value['goods_spec_id'])->setDec('stock_num',$value['total_num']); 52 + $goods_ids = [];
  53 + $list = $goodsmodel->where('order_id', $order['id'])->select();
  54 + foreach ($list as $key => $value) {
  55 + $goods_ids[] = $value['goods_id'];
  56 + $sales_actual += $value['total_num'];
  57 + if ($value['deduct_stock_type'] == 20) {
  58 + $skumodel->where('goods_spec_id', $value['goods_spec_id'])->setDec('stock_num', $value['total_num']);
  59 + //增加规格销量
  60 + $skumodel->where('goods_spec_id', $value['goods_spec_id'])->setInc('goods_sales', $value['total_num']);
59 } 61 }
60 } 62 }
61 // 增加销量 63 // 增加销量
62 - $goods_model->whereIn('goods_id',$goods_ids)->setInc('sales_actual',$sales_actual); 64 + $goods_model->whereIn('goods_id', $goods_ids)->setInc('sales_actual', $sales_actual);
63 // 判断是否邀请成功 65 // 判断是否邀请成功
64 $user = \app\api\model\User::get($order['user_id']); 66 $user = \app\api\model\User::get($order['user_id']);
65 if ($user['invite_user_id'] > 0 && $user['invite_status'] != 1) { 67 if ($user['invite_user_id'] > 0 && $user['invite_status'] != 1) {
66 $user->invite_status = '1'; 68 $user->invite_status = '1';
67 $user->isUpdate()->save(); 69 $user->isUpdate()->save();
68 - $coupon = Db::name('coupon')->where('id',1)->find();  
69 - if ($coupon['endtime'] > time()){ 70 + $coupon = Db::name('coupon')->where('id', 1)->find();
  71 + if ($coupon['endtime'] > time()) {
70 $data = []; 72 $data = [];
71 $time = time(); 73 $time = time();
72 - for ($i=1;$i<=$coupon['send_number'];$i++){ 74 + for ($i = 1; $i <= $coupon['send_number']; $i++) {
73 $data[] = [ 75 $data[] = [
74 - 'user_id' => $user->invite_user_id,  
75 - 'coupon_id' => $coupon['id'],  
76 - 'name' => $coupon['name'],  
77 - 'price' => $coupon['price'], 76 + 'user_id' => $user->invite_user_id,
  77 + 'coupon_id' => $coupon['id'],
  78 + 'name' => $coupon['name'],
  79 + 'price' => $coupon['price'],
78 'full_price' => $coupon['full_price'], 80 'full_price' => $coupon['full_price'],
79 - 'endtime' => $time+$coupon['days']*86400, 81 + 'endtime' => $time + $coupon['days'] * 86400,
80 'createtime' => $time, 82 'createtime' => $time,
81 ]; 83 ];
82 } 84 }
@@ -85,24 +87,24 @@ class Notify extends Api @@ -85,24 +87,24 @@ class Notify extends Api
85 } 87 }
86 // 加入我常买 88 // 加入我常买
87 $data = []; 89 $data = [];
88 - foreach ($list as $key => $value){ 90 + foreach ($list as $key => $value) {
89 $data[] = [ 91 $data[] = [
90 - 'user_id' => $order['user_id'], 92 + 'user_id' => $order['user_id'],
91 'goods_id' => $value['goods_id'], 93 'goods_id' => $value['goods_id'],
92 - 'sku_id' => $value['goods_spec_id'], 94 + 'sku_id' => $value['goods_spec_id'],
93 ]; 95 ];
94 } 96 }
95 $buymodel->isUpdate(false)->saveAll($data); 97 $buymodel->isUpdate(false)->saveAll($data);
96 // 给后台发送新订单提醒 98 // 给后台发送新订单提醒
97 - $client = new Client();  
98 - $domain = config('socketio.domain'); 99 + $client = new Client();
  100 + $domain = config('socketio.domain');
99 $http_port = config('socketio.http_port'); 101 $http_port = config('socketio.http_port');
100 - $client->request('POST', $domain.":{$http_port}/", [ 102 + $client->request('POST', $domain . ":{$http_port}/", [
101 'form_params' => [ 103 'form_params' => [
102 - 'type' => 'publish', 104 + 'type' => 'publish',
103 'content' => '您有新的订单,请注意查收', 105 'content' => '您有新的订单,请注意查收',
104 - 'to' => '',  
105 - ] 106 + 'to' => '',
  107 + ],
106 ]); 108 ]);
107 } catch (Exception $e) { 109 } catch (Exception $e) {
108 } 110 }
@@ -116,40 +118,40 @@ class Notify extends Api @@ -116,40 +118,40 @@ class Notify extends Api
116 public function refund() 118 public function refund()
117 { 119 {
118 $paytype = $this->request->param('type'); 120 $paytype = $this->request->param('type');
119 - $pay = Service::checkNotify($paytype,'refund'); 121 + $pay = Service::checkNotify($paytype, 'refund');
120 if (!$pay) { 122 if (!$pay) {
121 echo '签名错误'; 123 echo '签名错误';
122 return; 124 return;
123 } 125 }
124 - $data = $pay->verify();  
125 - $data = json_decode($data,true);  
126 - $model = new \app\api\model\Order();  
127 - $goodsmodel = new \app\api\model\OrderGoods();  
128 - $skumodel = new \app\api\model\GoodsSpec(); 126 + $data = $pay->verify();
  127 + $data = json_decode($data, true);
  128 + $model = new \app\api\model\Order();
  129 + $goodsmodel = new \app\api\model\OrderGoods();
  130 + $skumodel = new \app\api\model\GoodsSpec();
129 $goods_model = new \app\api\model\Goods(); 131 $goods_model = new \app\api\model\Goods();
130 try { 132 try {
131 $out_trade_no = $data['out_refund_no']; 133 $out_trade_no = $data['out_refund_no'];
132 - $order = $model  
133 - ->where('refund_no',$out_trade_no)  
134 - ->where('pay_status','20')  
135 - ->where('order_status','10') 134 + $order = $model
  135 + ->where('refund_no', $out_trade_no)
  136 + ->where('pay_status', '20')
  137 + ->where('order_status', '10')
136 ->find(); 138 ->find();
137 if (!$order) $this->error('订单不存在'); 139 if (!$order) $this->error('订单不存在');
138 - $order->refund_id = $data['refund_id'];  
139 - $order->refund_time = time(); 140 + $order->refund_id = $data['refund_id'];
  141 + $order->refund_time = time();
140 $order->order_status = '20'; 142 $order->order_status = '20';
141 $order->isUpdate()->save(); 143 $order->isUpdate()->save();
142 // 增加库存 144 // 增加库存
143 $sales_actual = 0; 145 $sales_actual = 0;
144 - $list = $goodsmodel->where('order_id',$order['id'])->select();  
145 - foreach ($list as $key => $value){  
146 - $sales_actual+=$value['total_num'];  
147 - if ($value['deduct_stock_type'] == 20){  
148 - $skumodel->where('goods_spec_id',$value['goods_spec_id'])->setInc('stock_num',$value['total_num']); 146 + $list = $goodsmodel->where('order_id', $order['id'])->select();
  147 + foreach ($list as $key => $value) {
  148 + $sales_actual += $value['total_num'];
  149 + if ($value['deduct_stock_type'] == 20) {
  150 + $skumodel->where('goods_spec_id', $value['goods_spec_id'])->setInc('stock_num', $value['total_num']);
149 } 151 }
150 } 152 }
151 // 减少销量 153 // 减少销量
152 - $goods_model->setDec('sales_actual',$sales_actual); 154 + $goods_model->setDec('sales_actual', $sales_actual);
153 //你可以在此编写订单逻辑 155 //你可以在此编写订单逻辑
154 } catch (Exception $e) { 156 } catch (Exception $e) {
155 } 157 }
@@ -18,7 +18,7 @@ return [ @@ -18,7 +18,7 @@ return [
18 // 应用命名空间 18 // 应用命名空间
19 'app_namespace' => 'app', 19 'app_namespace' => 'app',
20 // 应用调试模式 20 // 应用调试模式
21 - 'app_debug' => Env::get('app.debug', true), 21 + 'app_debug' => Env::get('app.debug', false),
22 // 应用Trace 22 // 应用Trace
23 'app_trace' => Env::get('app.trace', false), 23 'app_trace' => Env::get('app.trace', false),
24 // 应用模式状态 24 // 应用模式状态
@@ -4,7 +4,7 @@ return array ( @@ -4,7 +4,7 @@ return array (
4 'name' => '橙子优选', 4 'name' => '橙子优选',
5 'beian' => '', 5 'beian' => '',
6 'cdnurl' => '', 6 'cdnurl' => '',
7 - 'version' => '1.0.1', 7 + 'version' => '1.0.2',
8 'timezone' => 'Asia/Shanghai', 8 'timezone' => 'Asia/Shanghai',
9 'forbiddenip' => '', 9 'forbiddenip' => '',
10 'languages' => 10 'languages' =>
@@ -41,6 +41,7 @@ return array ( @@ -41,6 +41,7 @@ return array (
41 'category2' => '分类二', 41 'category2' => '分类二',
42 'custom' => '自定义', 42 'custom' => '自定义',
43 ), 43 ),
  44 +<<<<<<< HEAD
44 'user_agreement' => '<p><div><p><strong>一、序言</strong> <br /> 1、您使用简书软件和/或服务,即视为您签署了本协议,表明您自愿接受本协议全部条款的约束,本协议将构成您与上海佰集科技有限公司(以下称我公司)就“简书”软件及服务(以下统称“简书”)之间具有约束力的法律文件。无论您是进入简书浏览网页,还是在简书上发布任何内容,或者是直接或通过各类方式(如站外API引用等)间接使用简书的行为,都将被视作已无条件接受本声明所涉全部内容。</p> 45 'user_agreement' => '<p><div><p><strong>一、序言</strong> <br /> 1、您使用简书软件和/或服务,即视为您签署了本协议,表明您自愿接受本协议全部条款的约束,本协议将构成您与上海佰集科技有限公司(以下称我公司)就“简书”软件及服务(以下统称“简书”)之间具有约束力的法律文件。无论您是进入简书浏览网页,还是在简书上发布任何内容,或者是直接或通过各类方式(如站外API引用等)间接使用简书的行为,都将被视作已无条件接受本声明所涉全部内容。</p>
45 <p>2、我公司有权利对本协议进行修改,我公司将在简书相关页面公告或发送通知等方式公布修改的内容,修改后的协议一经公布即有效的代替原协议。如果您不同意本协议的修改,请立即停止访问或使用简书或取消已经获得的服务;如果您选择继续访问或使用简书,则视为您已接受本协议的修改。</p> 46 <p>2、我公司有权利对本协议进行修改,我公司将在简书相关页面公告或发送通知等方式公布修改的内容,修改后的协议一经公布即有效的代替原协议。如果您不同意本协议的修改,请立即停止访问或使用简书或取消已经获得的服务;如果您选择继续访问或使用简书,则视为您已接受本协议的修改。</p>
46 <p>3、本协议所列明的条款,并不能完全涵盖您与我公司之间所有的权利和义务。因此,我公司不定期公布的其他声明、规则、子协议等均视为本协议之补充协议,为本协议不可分割的组成部分,与本协议具有同等法律效力。</p> 47 <p>3、本协议所列明的条款,并不能完全涵盖您与我公司之间所有的权利和义务。因此,我公司不定期公布的其他声明、规则、子协议等均视为本协议之补充协议,为本协议不可分割的组成部分,与本协议具有同等法律效力。</p>
@@ -48,6 +49,15 @@ return array ( @@ -48,6 +49,15 @@ return array (
48 'privacy_agreement' => '<p><br /></p><div><p>1、帐号的取得 (1)您确认,在您开始使用简书时,已经具备中华人民共和国法律规定的与您行为相适应的民事行为能力。若您不具备前述与您行为相适应的民事行为能力,则您及您的监护人应依照法律规定承担因此而导致的一切后果。</p> 49 'privacy_agreement' => '<p><br /></p><div><p>1、帐号的取得 (1)您确认,在您开始使用简书时,已经具备中华人民共和国法律规定的与您行为相适应的民事行为能力。若您不具备前述与您行为相适应的民事行为能力,则您及您的监护人应依照法律规定承担因此而导致的一切后果。</p>
49 <p>(2)您注册成功后,即成为简书注册用户,用户须对在简书的注册信息的真实性、合法性、有效性承担全部责任。您可自行创建、修改昵称,但用户名和昵称的命名及使用应遵守相关法律法规并符合网络道德,不得冒充他人或恶意注册使人误认;不得利用他人的名义发布任何信息;不得恶意使用注册帐号导致其他用户误认;用户名和昵称中不能含有任何侮辱、诽谤、淫秽或暴力等侵害他人合法权益或违反公序良俗的词语。如您违反前述规定,简书有权随时限制或拒绝您使用该账号,甚至注销该账号。 (3)用户名的管理 1)请勿以党和国家领导人或其他名人的真实姓名、字、号、艺名、笔名、头衔等注册和使用昵称(如确为本人,需要提交相关证据并通过审核方可允许使用); 2)请勿以国家组织机构或其他组织机构的名称等注册和使用昵称(如确为该机构,需要提交相关证据并通过审核方可允许使用); 3)请勿注册和使用与其他网友相同、相仿的用户名或昵称; 4)请勿注册和使用不文明、不健康的用户名和昵称; 5)请勿注册和使用易产生歧义、引起他人误解或带有各种奇形怪状符号的用户名和昵称。 6)用户以虚假信息骗取账号名称注册,或账号头像、简介等注册信息存在违法和不良信息的,简书将暂停或注销。</p> 50 <p>(2)您注册成功后,即成为简书注册用户,用户须对在简书的注册信息的真实性、合法性、有效性承担全部责任。您可自行创建、修改昵称,但用户名和昵称的命名及使用应遵守相关法律法规并符合网络道德,不得冒充他人或恶意注册使人误认;不得利用他人的名义发布任何信息;不得恶意使用注册帐号导致其他用户误认;用户名和昵称中不能含有任何侮辱、诽谤、淫秽或暴力等侵害他人合法权益或违反公序良俗的词语。如您违反前述规定,简书有权随时限制或拒绝您使用该账号,甚至注销该账号。 (3)用户名的管理 1)请勿以党和国家领导人或其他名人的真实姓名、字、号、艺名、笔名、头衔等注册和使用昵称(如确为本人,需要提交相关证据并通过审核方可允许使用); 2)请勿以国家组织机构或其他组织机构的名称等注册和使用昵称(如确为该机构,需要提交相关证据并通过审核方可允许使用); 3)请勿注册和使用与其他网友相同、相仿的用户名或昵称; 4)请勿注册和使用不文明、不健康的用户名和昵称; 5)请勿注册和使用易产生歧义、引起他人误解或带有各种奇形怪状符号的用户名和昵称。 6)用户以虚假信息骗取账号名称注册,或账号头像、简介等注册信息存在违法和不良信息的,简书将暂停或注销。</p>
50 <p>2、请您妥善保管您注册时填写的用户帐号和密码,不要将帐号密码告知他人,因您原因导致帐号或密码泄露而造成的法律后果由用户负责。同时,您还应当对以此帐号登录进行的所有活动和事件承担全部后果与法律责任。</p> 51 <p>2、请您妥善保管您注册时填写的用户帐号和密码,不要将帐号密码告知他人,因您原因导致帐号或密码泄露而造成的法律后果由用户负责。同时,您还应当对以此帐号登录进行的所有活动和事件承担全部后果与法律责任。</p>
  52 +=======
  53 + 'user_agreement' => '<p><div><p><strong>一、序言</strong> <br /> 1、您使用简书软件和/或服务,即视为您签署了本协议,表明您自愿接受本协议全部条款的约束,本协议将构成您与上海佰集科技有限公司(以下称我公司)就“简书”软件及服务(以下统称“简书”)之间具有约束力的法律文件。无论您是进入简书浏览网页,还是在简书上发布任何内容,或者是直接或通过各类方式(如站外API引用等)间接使用简书的行为,都将被视作已无条件接受本声明所涉全部内容。</p>
  54 +<p>2、我公司有权利对本协议进行修改,我公司将在简书相关页面公告或发送通知等方式公布修改的内容,修改后的协议一经公布即有效的代替原协议。如果您不同意本协议的修改,请立即停止访问或使用简书或取消已经获得的服务;如果您选择继续访问或使用简书,则视为您已接受本协议的修改。</p>
  55 +<p>3、本协议所列明的条款,并不能完全涵盖您与我公司之间所有的权利和义务。因此,我公司不定期公布的其他声明、规则、子协议等均视为本协议之补充协议,为本协议不可分割的组成部分,与本协议具有同等法律效力。</p>
  56 +<p>4、如本协议与简书的补充协议不一致,以补充协议内容为准。</p></div></p><p><br /></p>',
  57 + 'privacy_agreement' => '<p><br /></p><div><p>1、帐号的取得 (1)您确认,在您开始使用简书时,已经具备中华人民共和国法律规定的与您行为相适应的民事行为能力。若您不具备前述与您行为相适应的民事行为能力,则您及您的监护人应依照法律规定承担因此而导致的一切后果。</p>
  58 +<p>(2)您注册成功后,即成为简书注册用户,用户须对在简书的注册信息的真实性、合法性、有效性承担全部责任。您可自行创建、修改昵称,但用户名和昵称的命名及使用应遵守相关法律法规并符合网络道德,不得冒充他人或恶意注册使人误认;不得利用他人的名义发布任何信息;不得恶意使用注册帐号导致其他用户误认;用户名和昵称中不能含有任何侮辱、诽谤、淫秽或暴力等侵害他人合法权益或违反公序良俗的词语。如您违反前述规定,简书有权随时限制或拒绝您使用该账号,甚至注销该账号。 (3)用户名的管理 1)请勿以党和国家领导人或其他名人的真实姓名、字、号、艺名、笔名、头衔等注册和使用昵称(如确为本人,需要提交相关证据并通过审核方可允许使用); 2)请勿以国家组织机构或其他组织机构的名称等注册和使用昵称(如确为该机构,需要提交相关证据并通过审核方可允许使用); 3)请勿注册和使用与其他网友相同、相仿的用户名或昵称; 4)请勿注册和使用不文明、不健康的用户名和昵称; 5)请勿注册和使用易产生歧义、引起他人误解或带有各种奇形怪状符号的用户名和昵称。 6)用户以虚假信息骗取账号名称注册,或账号头像、简介等注册信息存在违法和不良信息的,简书将暂停或注销。</p>
  59 +<p>2、请您妥善保管您注册时填写的用户帐号和密码,不要将帐号密码告知他人,因您原因导致帐号或密码泄露而造成的法律后果由用户负责。同时,您还应当对以此帐号登录进行的所有活动和事件承担全部后果与法律责任。</p>
  60 +>>>>>>> 7daf6f7b9eb6b739e54a4f431ec20b925f200636
51 <p>3、若您的帐号或密码遗失,可以通过注册信息按照相关步骤找回密码,若您发现账号遭到未授权的使用或存在其他安全漏洞的情况,应立即告知我公司。</p></div><p><br /></p><p><br /></p>', 61 <p>3、若您的帐号或密码遗失,可以通过注册信息按照相关步骤找回密码,若您发现账号遭到未授权的使用或存在其他安全漏洞的情况,应立即告知我公司。</p></div><p><br /></p><p><br /></p>',
52 'notice' => '106 全场半价全场半价 106 全场半价全场半价 106 全场半价全场半价', 62 'notice' => '106 全场半价全场半价 106 全场半价全场半价 106 全场半价全场半价',
53 'advert' => '/uploads/20220126/fc7a7c9c0c0ea799bafe33a82c67d71b.png', 63 'advert' => '/uploads/20220126/fc7a7c9c0c0ea799bafe33a82c67d71b.png',
@@ -11,6 +11,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'litestor @@ -11,6 +11,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'litestor
11 edit_url: 'litestore/litestoregoods/edit', 11 edit_url: 'litestore/litestoregoods/edit',
12 del_url: 'litestore/litestoregoods/del', 12 del_url: 'litestore/litestoregoods/del',
13 multi_url: 'litestore/litestoregoods/multi', 13 multi_url: 'litestore/litestoregoods/multi',
  14 + import_url: 'litestore/litestoregoods/import',
14 table: 'litestore_goods', 15 table: 'litestore_goods',
15 } 16 }
16 }); 17 });
@@ -29,6 +29,8 @@ defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); @@ -29,6 +29,8 @@ defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);
29 defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录 29 defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录
30 defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀 30 defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀
31 defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀 31 defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀
  32 +// PUBLIC_PATH
  33 +define('PUBLIC_PATH', ROOT_PATH . 'public');
32 34
33 // 环境常量 35 // 环境常量
34 define('IS_CLI', PHP_SAPI == 'cli' ? true : false); 36 define('IS_CLI', PHP_SAPI == 'cli' ? true : false);