初始化项目

This commit is contained in:
2026-09-01 22:15:50 +08:00
commit b5a26a8848
11217 changed files with 1710987 additions and 0 deletions
+193
View File
@@ -0,0 +1,193 @@
<?php
// app/common/crypto/Crypto.php
namespace app\common\crypto;
class Crypto
{
protected $privateKey;
protected $platformPublicKey;
public function __construct($company)
{
$this->orgNo = $company['orgNo'];
$this->appKey = $company['appKey'];
$this->privateKey = $this->loadPrivateKey($company['privateKey']);
$this->publicKey = $this->loadPublicKey($company['publicKey']);
$this->platformPublicKey = $this->loadPublicKey($company['platformPublicKey']);
}
protected function loadPrivateKey($base64PrivateKey)
{
$privateKey = "-----BEGIN PRIVATE KEY-----\n" .
chunk_split($base64PrivateKey, 64, "\n") .
"-----END PRIVATE KEY-----\n";
$key = openssl_pkey_get_private($privateKey);
if ($key === false) {
throw new \Exception('Invalid private key: ' . openssl_error_string());
}
return $key;
}
protected function loadPublicKey($base64PublicKey)
{
$publicKey = "-----BEGIN PUBLIC KEY-----\n" .
chunk_split($base64PublicKey, 64, "\n") .
"-----END PUBLIC KEY-----\n";
$key = openssl_pkey_get_public($publicKey);
if ($key === false) {
throw new \Exception('Invalid public key: ' . openssl_error_string());
}
return $key;
}
public function sign($data)
{
openssl_sign($data, $signature, $this->privateKey, OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
public function verifySign($data, $signature)
{
$decodedSignature = base64_decode($signature);
return openssl_verify($data, $decodedSignature, $this->platformPublicKey, OPENSSL_ALGO_SHA256);
}
public function encryptData($data, $key)
{
$encryptedData = openssl_encrypt($data, 'AES-256-ECB', $key, OPENSSL_PKCS1_PADDING);
return base64_encode($encryptedData);
}
public function decryptData($data, $key)
{
$decodedData = base64_decode($data);
return openssl_decrypt($decodedData, 'AES-256-ECB', $key, OPENSSL_PKCS1_PADDING);
}
public function encryptKey($key)
{
openssl_public_encrypt($key, $encryptedKey, $this->platformPublicKey, OPENSSL_PKCS1_PADDING);
return base64_encode($encryptedKey);
}
public function decryptKey($encryptedKey)
{
$decodedKey = base64_decode($encryptedKey);
if ($decodedKey === false) {
throw new \Exception('Base64 decoding failed.');
}
$decrypted = '';
$result = openssl_public_decrypt($decodedKey, $decrypted, $this->platformPublicKey, OPENSSL_PKCS1_PADDING);
if ($result === false) {
throw new \Exception('Decryption failed: ' . openssl_error_string());
}
return $decrypted;
}
public function generateKey()
{
return openssl_random_pseudo_bytes(32);
}
public function prepareRequest($header, $body)
{
$header = [
'version' => config('crypto.app_version'),
'appKey' => $this->appKey,
'method' => $header['method'] ?? '',
'requestId' => $this->appKey.$this->generateUniqueString(30),
];
$bodyJson = json_encode($body);
$signData = "version={$header['version']}&appKey={$header['appKey']}&method={$header['method']}&requestId={$header['requestId']}&body={$bodyJson}";
$signature = $this->sign($signData);
$header['sign'] = $signature;
$key = $this->generateKey();
$encryptedBody = $this->encryptData($bodyJson, $key);
$encryptedKey = $this->encryptKey($key);
return [
'header' => $header,
'encryptData' => [
'key' => $encryptedKey,
'data' => $encryptedBody,
],
];
}
public function processResponse($response)
{
if(!isset($response['encryptData']['key'])){
return '';
}
$encryptedKey = $response['encryptData']['key'];
$encryptedData = $response['encryptData']['data'];
$header = $response['header'];
$key = $this->decryptKey($encryptedKey);
$data = $this->decryptData($encryptedData, $key);
$body = json_decode($data, true);
return $body;
// 判断响应中是否有签名
if(empty($header['sign']??'')){
return $body;
}
$header['appKey'] = $header['appkey'] ?? $header['appKey'];
$header['requestId'] = $header['requestid'] ?? $header['requestId'];
$signData = "version={$header['version']}&appKey={$header['appKey']}&method={$header['method']}&requestId={$header['requestId']}&body=" . json_encode($body);
$isValid = $this->verifySign($signData, $header['sign']);
if ($isValid) {
return $body;
} else {
throw new \Exception("Invalid signature");
}
}
/**
* 生成唯一字符串
*
* @param int $length 字符串长度,不能超过128
* @return string 生成的唯一字符串
*/
public function generateUniqueString($length = 100)
{
// 确保长度不超过100
if ($length > 100) {
$length = 100;
}
// 生成基于时间的唯一ID
$uniqueId = uniqid('', true);
// 可选字符集,可以根据需要修改
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
// 使用时间戳的微秒部分增加随机性
$microtime = microtime();
$randomSeed = substr($microtime, strpos($microtime, ' ') + 1);
// 将随机种子转换为整数
$seed = crc32($randomSeed);
// 设置随机种子
srand($seed);
// 生成随机字符串
for ($i = 0; $i < $length - strlen($uniqueId); $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
// 结合唯一ID和随机字符串
$result = substr($uniqueId, 0, $length - strlen($randomString)) . $randomString;
return $result;
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
// app/common/crypto/Idingju.php
namespace app\common\crypto;
class Idingju
{
public $orgNo;
public $appKey;
public $prefixUrl;
public function __construct($company)
{
$this->orgNo = $company['orgNo'];
$this->appKey = $company['appKey'];
$this->prefixUrl = $company['url'];
}
/**
获取Token
*/
public function getToken($orgNo){
$filePath = public_path().'temp/'.$orgNo.'.txt';
$data = [];
$accessToken = '';
if(file_exists($filePath)){
$content = file_get_contents($filePath);
$data = $content ? json_decode($content,true) : [];
}
if(!empty($data) && $data['expires_time'] > time()){
$accessToken = $data['access_token'];
}else{
$url = $this->prefixUrl.'/api/open/getToken';
$timestamp = time();
$params = [
'appid' => $this->orgNo,
'appsecret' => $this->appKey,
];
$header = [
'Content-Type: application/json',
];
$ret = $this->request($url,json_encode($params),'post',$header);
$respone = json_decode($ret,true);
if(isset($respone['code']) && $respone['code'] == 1){
$data = json_encode($respone['data']);
$accessToken = $respone['data']['access_token'];
file_put_contents($filePath,$data);
}else{
print_r($url);
print_r('<br/>');
print_r($params);
print_r('<br/>');
print_r($respone);
exit;
}
}
if($accessToken == ''){
echo '获取Token失败';
return false;
}
return $accessToken;
}
/**
生成签名
$params : 请求参数数组
$token : access_token
$timestamp : 时间戳
$api : 当前请求接口除去域名的部分,如:/api/gasoline/recharge
*/
public function signature($params,$token,$timestamp,$api){
$params['token'] = $token;
sort($params, SORT_STRING);
// $tmpStr = implode($params);
$tmpStr = implode($params);
$str = $api.$token.$tmpStr.$timestamp;
$sign = sha1($str);
return $sign;
}
/**
网络请求方法
*/
public function request($url,$params,$method,$header = [],$gzip = false,$httpcode = false){
if(!$url) return;
$ch = curl_init();
if($method == 'get'){
$paramsUrl = http_build_query($params);
if(strpos($url,'?')){
$url .= '&'.$paramsUrl;
}else{
$url .= '?'.$paramsUrl;
}
}else{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
if($header){
curl_setopt($ch, CURLOPT_HTTPHEADER , $header);
}
if($gzip) curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL , $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , 0);
$cEncode = curl_exec($ch);
if($httpcode){
$cEncode = [
'cEncode'=>$cEncode,
'httpCode'=>curl_getinfo($ch,CURLINFO_HTTP_CODE)
];
}
curl_close($ch);
return $cEncode;
}
}
+242
View File
@@ -0,0 +1,242 @@
<?php
// app/common/crypto/Crypto.php
namespace app\common\crypto;
class RsaUtil
{
protected $orgNo;
protected $appKey;
protected $publicKey;
protected $platformPrivateKey;
public function __construct($partners)
{
$this->orgNo = $partners['orgNo'];
$this->appKey = $partners['appKey'];
$this->publicKey = $this->loadPublicKey($partners['publicKey']);
$this->platformPrivateKey = $this->loadPlatformPrivateKey();
}
protected function loadPlatformPrivateKey()
{
$config = config('rsa');
$privateKey = file_get_contents($config['private_key_path']);
$key = openssl_pkey_get_private($privateKey);
if ($key === false) {
throw new \Exception('Invalid private key: ' . openssl_error_string());
}
return $key;
}
protected function loadPublicKey($publicKey)
{
$key = openssl_pkey_get_public($publicKey);
if ($key === false) {
throw new \Exception('Invalid public key: ' . openssl_error_string());
}
return $key;
}
public function sign($data)
{
openssl_sign($data, $signature, $this->platformPrivateKey, OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
public function verifySign($data, $signature)
{
$decodedSignature = base64_decode($signature);
return openssl_verify($data, $decodedSignature, $this->publicKey, OPENSSL_ALGO_SHA256);
}
public function encryptData($data, $key)
{
$encryptedData = openssl_encrypt($data, 'AES-256-ECB', $key, OPENSSL_PKCS1_PADDING);
return base64_encode($encryptedData);
}
public function decryptData($data, $key)
{
$decodedData = base64_decode($data);
return openssl_decrypt($decodedData, 'AES-256-ECB', $key, OPENSSL_PKCS1_PADDING);
}
public function encryptKey($key)
{
openssl_public_encrypt($key, $encryptedKey, $this->publicKey, OPENSSL_PKCS1_PADDING);
return base64_encode($encryptedKey);
}
public function decryptKey($encryptedKey)
{
$decodedKey = base64_decode($encryptedKey);
if ($decodedKey === false) {
throw new \Exception('Base64 decoding failed.');
}
$decrypted = '';
$result = openssl_private_decrypt($decodedKey, $decrypted, $this->platformPrivateKey, OPENSSL_PKCS1_PADDING);
if ($result === false) {
throw new \Exception('Decryption failed: ' . openssl_error_string());
}
return $decrypted;
}
public function generateKey()
{
return openssl_random_pseudo_bytes(32);
}
public function prepareRequest($header, $body)
{
$header = [
'version' => config('rsa.app_version'),
'appKey' => $this->appKey,
'method' => $header['method'] ?? '',
'requestId' => $this->appKey.$this->generateUniqueString(30),
];
$bodyJson = json_encode($body);
$signData = "version={$header['version']}&appKey={$header['appKey']}&method={$header['method']}&requestId={$header['requestId']}&body={$bodyJson}";
$signature = $this->sign($signData);
$header['sign'] = $signature;
$key = $this->generateKey();
$encryptedBody = $this->encryptData($bodyJson, $key);
$encryptedKey = $this->encryptKey($key);
return [
'header' => $header,
'encryptData' => [
'key' => $encryptedKey,
'data' => $encryptedBody,
],
];
}
public function processResponse(array $response, bool $checkSign = true): array
{
// 1. 检查加密数据是否存在
if (empty($response['encryptData']['key'] ?? '') || empty($response['encryptData']['data'] ?? '')) {
return [
'code' => '04',
'errCode' => '0002',
];
}
try {
// 2. 解密密钥和数据
$encryptedKey = $response['encryptData']['key'];
$encryptedData = $response['encryptData']['data'];
$key = $this->decryptKey($encryptedKey);
$data = $this->decryptData($encryptedData, $key);
$body = json_decode($data, true);
if ($body === null) {
return [
'code' => '03',
'errCode' => '0011',
];
}
// 3. 验签(可选)
if ($checkSign) {
$header = $response['header'] ?? [];
// 请求头version参数不正确
if(empty($header['version'] ?? '') || $header['version'] != '1.0.0'){
return [
'code' => '12',
'errCode' => '0003',
];
}
// 请求头APPKEY参数不正确
if(empty($header['appkey'] ?? $header['appKey'])){
return [
'code' => '02',
'errCode' => '0004',
];
}
// 请求参数不正确
if(empty($header['method'] ?? '') || empty($header['requestid'] ?? $header['requestId'])){
return [
'code' => '12',
'errCode' => '0013',
];
}
$signData = http_build_query([
'version' => $header['version'],
'appKey' => $header['appkey'] ?? $header['appKey'],
'method' => $header['method'],
'requestId' => $header['requestid'] ?? $header['requestId'],
'body' => json_encode($body, JSON_UNESCAPED_UNICODE)
]);
if (empty($header['sign']) || !$this->verifySign($signData, $header['sign'])) {
return [
'code' => '05',
'errCode' => '0006',
];
}
}
// 4. 成功返回
return [
'code' => '00',
'data' => $body
];
} catch (\Throwable $e) {
return [
'code' => '99',
'errCode' => '0007',
'errMessage' => $e->getMessage() ?: '',
];
}
}
/**
* 生成唯一字符串
*
* @param int $length 字符串长度,不能超过128
* @return string 生成的唯一字符串
*/
public function generateUniqueString($length = 100)
{
// 确保长度不超过100
if ($length > 100) {
$length = 100;
}
// 生成基于时间的唯一ID
$uniqueId = uniqid('', true);
// 可选字符集,可以根据需要修改
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
// 使用时间戳的微秒部分增加随机性
$microtime = microtime();
$randomSeed = substr($microtime, strpos($microtime, ' ') + 1);
// 将随机种子转换为整数
$seed = crc32($randomSeed);
// 设置随机种子
srand($seed);
// 生成随机字符串
for ($i = 0; $i < $length - strlen($uniqueId); $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
// 结合唯一ID和随机字符串
$result = substr($uniqueId, 0, $length - strlen($randomString)) . $randomString;
return $result;
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum;
use MyCLabs\Enum\Enum;
/**
* 枚举类基类
* Class Basics
* @package app\common\enum
*/
abstract class EnumBasics extends Enum
{
}
+46
View File
@@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum;
/**
* 枚举类:订单类型
* Class OrderType
* @package app\common\enum
*/
class OrderType extends EnumBasics
{
// 商城订单
const ORDER = 10;
// 余额充值订单
const RECHARGE = 100;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::ORDER => [
'name' => '商城订单',
'value' => self::ORDER,
],
self::RECHARGE => [
'name' => '余额充值订单',
'value' => self::RECHARGE,
],
];
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum;
/**
* 枚举类:支付类型
* Class PayType
* @package app\common\enum
*/
class PayType extends EnumBasics
{
// 商城订单
const ORDER = 10;
// 余额充值
const RECHARGE = 100;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::ORDER => [
'name' => '商城订单',
'value' => self::ORDER,
],
self::RECHARGE => [
'name' => '余额充值',
'value' => self::RECHARGE,
],
];
}
/**
* 获取订单类型名称
* @return array
*/
public static function getTypeName()
{
static $names = [];
if (empty($names)) {
foreach (self::data() as $item)
$names[$item['value']] = $item['name'];
}
return $names;
}
}
+115
View File
@@ -0,0 +1,115 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum;
/**
* 商城设置枚举类
* Class Setting
* @package app\common\enum
*/
class Setting extends EnumBasics
{
// 配送设置
const DELIVERY = 'delivery';
// 交易设置
const TRADE = 'trade';
// 分销设置
const PROMOTION = 'promotion';
// 短信通知
const SMS = 'sms';
// 上传设置
const STORAGE = 'storage';
// 满额包邮设置
const FULL_FREE = 'full_free';
// 账户注册设置
const REGISTER = 'register';
// 充值设置
const RECHARGE = 'recharge';
// 分享设置
const SHARE = 'share';
// 兑换设置
const EXCHANGE = 'exchange';
// 积分设置
const POINTS = 'points';
// 分类页模板
const PAGE_CATEGORY_TEMPLATE = 'page_category_template';
/**
* 获取订单类型值
* @return array
*/
public static function data(): array
{
return [
self::DELIVERY => [
'value' => self::DELIVERY,
'describe' => '配送设置',
],
self::TRADE => [
'value' => self::TRADE,
'describe' => '交易设置',
],
self::PROMOTION => [
'value' => self::PROMOTION,
'describe' => '分销设置',
],
self::SMS => [
'value' => self::SMS,
'describe' => '短信通知',
],
self::STORAGE => [
'value' => self::STORAGE,
'describe' => '上传设置',
],
self::FULL_FREE => [
'value' => self::FULL_FREE,
'describe' => '满额包邮设置',
],
self::REGISTER => [
'value' => self::REGISTER,
'describe' => '账户注册设置',
],
self::RECHARGE => [
'value' => self::RECHARGE,
'describe' => '充值设置',
],
self::SHARE => [
'value' => self::SHARE,
'describe' => '分享设置',
],
self::EXCHANGE => [
'value' => self::EXCHANGE,
'describe' => '兑换设置',
],
self::POINTS => [
'value' => self::POINTS,
'describe' => '积分设置',
],
self::PAGE_CATEGORY_TEMPLATE => [
'value' => self::PAGE_CATEGORY_TEMPLATE,
'describe' => '分类页模板',
],
];
}
}
@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\comment;
use app\common\enum\EnumBasics;
/**
* 枚举类:商品评价评分类型
* Class Score
* @package app\common\enum\comment
*/
class Score extends EnumBasics
{
// 好评
const GOOD = 10;
// 中评
const MEDIUM = 20;
// 差评
const BAD = 30;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::GOOD => [
'name' => '好评',
'value' => self::GOOD
],
self::MEDIUM => [
'name' => '中评',
'value' => self::MEDIUM
],
self::BAD => [
'name' => '差评',
'value' => self::BAD
]
];
}
}
@@ -0,0 +1,66 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\company\balanceLog;
use app\common\enum\EnumBasics;
/**
* 余额变动场景枚举类
* Class Scene
* @package app\common\enum\company\balanceLog
*/
class Scene extends EnumBasics
{
// 用户充值
const RECHARGE = 10;
// 用户消费
const CONSUME = 20;
// 管理员操作
const ADMIN = 30;
// 订单退款
const REFUND = 40;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::RECHARGE => [
'name' => '用户充值',
'value' => self::RECHARGE,
'describe' => '用户充值:%s',
],
self::CONSUME => [
'name' => '用户消费',
'value' => self::CONSUME,
'describe' => '用户消费:%s',
],
self::ADMIN => [
'name' => '管理员操作',
'value' => self::ADMIN,
'describe' => '后台管理员 [%s] 操作',
],
self::REFUND => [
'name' => '订单退款',
'value' => self::REFUND,
'describe' => '订单退款:%s',
],
];
}
}
@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\coupon;
use app\common\enum\EnumBasics;
/**
* 枚举类:优惠券适用范围
* Class ApplyRange
* @package app\common\enum\coupon
*/
class ApplyRange extends EnumBasics
{
// 全部商品
const ALL = 10;
// 指定商品
const SOME = 20;
// 排除商品
const EXCLUDE = 30;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::ALL => [
'name' => '全部商品',
'value' => self::ALL
],
self::SOME => [
'name' => '指定商品',
'value' => self::SOME
],
self::EXCLUDE => [
'name' => '排除商品',
'value' => self::EXCLUDE
]
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\coupon;
use app\common\enum\EnumBasics;
/**
* 枚举类:优惠券类型
* Class CouponType
* @package app\common\enum\coupon
*/
class CouponType extends EnumBasics
{
// 满减券
const FULL_DISCOUNT = 10;
// 折扣券
const DISCOUNT = 20;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::FULL_DISCOUNT => [
'name' => '满减券',
'value' => self::FULL_DISCOUNT
],
self::DISCOUNT => [
'name' => '折扣券',
'value' => self::DISCOUNT
]
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\coupon;
use app\common\enum\EnumBasics;
/**
* 枚举类:优惠券到期类型
* Class ExpireType
* @package app\common\enum\coupon
*/
class ExpireType extends EnumBasics
{
// 领取后
const RECEIVE = 10;
// 固定时间
const FIXED_TIME = 20;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::RECEIVE => [
'name' => '领取后',
'value' => self::RECEIVE
],
self::FIXED_TIME => [
'name' => '固定时间',
'value' => self::FIXED_TIME
]
];
}
}
@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\file;
use app\common\enum\EnumBasics;
/**
* 枚举类:文件类型
* Class FileType
* @package app\common\enum\goods
*/
class FileType extends EnumBasics
{
// 图片
const IMAGE = 10;
// 附件
const ANNEX = 20;
// 视频
const VIDEO = 30;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::IMAGE => [
'name' => '图片',
'value' => self::IMAGE,
],
self::ANNEX => [
'name' => '附件',
'value' => self::ANNEX,
'preview_path' => 'assets/store/img/file_preview/video.png',
],
self::VIDEO => [
'name' => '视频',
'value' => self::VIDEO,
'preview_path' => 'assets/store/img/file_preview/video.png',
],
];
}
}
@@ -0,0 +1,61 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\file;
use app\common\enum\EnumBasics;
/**
* 枚举类:文件存储类型
* Class Storage
* @package app\common\enum\file
*/
class Storage extends EnumBasics
{
// 本地
const LOCAL = 'local';
// 七牛云
const QINIU = 'qiniu';
// 阿里云
const ALIYUN = 'aliyun';
// 腾讯云
const QCLOUD = 'qcloud';
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::LOCAL => [
'name' => '本地',
'value' => self::LOCAL,
],
self::QINIU => [
'name' => '七牛云',
'value' => self::QINIU,
],
self::ALIYUN => [
'name' => '阿里云',
'value' => self::ALIYUN,
],
self::QCLOUD => [
'name' => '腾讯云',
'value' => self::QCLOUD,
],
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\goods;
use app\common\enum\EnumBasics;
/**
* 枚举类:商品库存计算方式
* Class DeductStockType
* @package app\common\enum\goods
*/
class DeductStockType extends EnumBasics
{
// 下单减库存
const CREATE = 10;
// 付款减库存
const PAYMENT = 20;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::CREATE => [
'name' => '下单减库存',
'value' => self::CREATE,
],
self::PAYMENT => [
'name' => '付款减库存',
'value' => self::PAYMENT,
],
];
}
}
@@ -0,0 +1,47 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\goods;
use app\common\enum\EnumBasics;
/**
* 枚举类:商品规格
* Class SpecType
* @package app\common\enum\goods
*/
class SpecType extends EnumBasics
{
// 单规格
const SINGLE = 10;
// 多规格
const MULTI = 20;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::SINGLE => [
'name' => '单规格',
'value' => self::SINGLE,
],
self::MULTI => [
'name' => '多规格',
'value' => self::MULTI,
],
];
}
}
@@ -0,0 +1,47 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\goods;
use app\common\enum\EnumBasics;
/**
* 枚举类:商品状态
* Class Status
* @package app\common\enum\goods
*/
class Status extends EnumBasics
{
// 上架
const ON_SALE = 10;
// 下架
const OFF_SALE = 20;
/**
* 获取枚举类型值
* @return array
*/
public static function data()
{
return [
self::ON_SALE => [
'name' => '上架',
'value' => self::ON_SALE,
],
self::OFF_SALE => [
'name' => '下架',
'value' => self::OFF_SALE,
],
];
}
}
@@ -0,0 +1,66 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\merchant\balanceLog;
use app\common\enum\EnumBasics;
/**
* 余额变动场景枚举类
* Class Scene
* @package app\common\enum\merchant\balanceLog
*/
class Scene extends EnumBasics
{
// 用户充值
const RECHARGE = 10;
// 用户消费
const CONSUME = 20;
// 管理员操作
const ADMIN = 30;
// 订单退款
const REFUND = 40;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::RECHARGE => [
'name' => '用户充值',
'value' => self::RECHARGE,
'describe' => '用户充值:%s',
],
self::CONSUME => [
'name' => '用户消费',
'value' => self::CONSUME,
'describe' => '用户消费:%s',
],
self::ADMIN => [
'name' => '管理员操作',
'value' => self::ADMIN,
'describe' => '后台管理员 [%s] 操作',
],
self::REFUND => [
'name' => '订单退款',
'value' => self::REFUND,
'describe' => '订单退款:%s',
],
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单发货状态
* Class DeliveryStatus
* @package app\common\enum\order
*/
class DeliveryStatus extends EnumBasics
{
// 未发货
const NOT_DELIVERED = 10;
// 已发货
const DELIVERED = 20;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::NOT_DELIVERED => [
'name' => '未发货',
'value' => self::NOT_DELIVERED,
],
self::DELIVERED => [
'name' => '已发货',
'value' => self::DELIVERED,
],
];
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:配送方式
* Class DeliveryType
* @package app\common\enum\order
*/
class DeliveryType extends EnumBasics
{
// 快递配送
const EXPRESS = 10;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::EXPRESS => [
'name' => '快递配送',
'value' => self::EXPRESS,
]
];
}
}
@@ -0,0 +1,69 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单场景
* Class OrderScene
* @package app\common\enum\order
*/
class OrderScene extends EnumBasics
{
// 订单创建时
const CREATE = 10;
// 订单付款时
const PAYMENT = 20;
// 订单发货时
const DELIVERY = 30;
// 订单完成时
const COMPLETE = 40;
// 订单取消时
const CANCEL = 50;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::CREATE => [
'name' => '订单创建时',
'value' => self::CREATE,
],
self::PAYMENT => [
'name' => '订单付款时',
'value' => self::PAYMENT,
],
self::DELIVERY => [
'name' => '订单发货时',
'value' => self::DELIVERY,
],
self::COMPLETE => [
'name' => '订单完成时',
'value' => self::COMPLETE,
],
self::CANCEL => [
'name' => '订单取消时',
'value' => self::COMPLETE,
]
];
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单来源
* Class OrderSource
* @package app\common\enum\order
*/
class OrderSource extends EnumBasics
{
// 普通订单
const MAIN = 10;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::MAIN => [
'name' => '普通订单',
'value' => self::MAIN,
]
];
}
}
@@ -0,0 +1,62 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单状态
* Class OrderStatus
* @package app\common\enum\order
*/
class OrderStatus extends EnumBasics
{
// 进行中
const NORMAL = 10;
// 已取消
const CANCELLED = 20;
// 待取消
const APPLY_CANCEL = 21;
// 已完成
const COMPLETED = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::NORMAL => [
'name' => '进行中',
'value' => self::NORMAL,
],
self::CANCELLED => [
'name' => '已取消',
'value' => self::CANCELLED,
],
self::APPLY_CANCEL => [
'name' => '待取消',
'value' => self::APPLY_CANCEL,
],
self::COMPLETED => [
'name' => '已完成',
'value' => self::COMPLETED,
],
];
}
}
@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单支付状态
* Class PayStatus
* @package app\common\enum\recharge\order
*/
class PayStatus extends EnumBasics
{
// 待支付
const PENDING = 10;
// 支付成功
const SUCCESS = 20;
// 超时
const CANCEL = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::PENDING => [
'name' => '等待支付',
'value' => self::PENDING,
],
self::SUCCESS => [
'name' => '支付成功',
'value' => self::SUCCESS,
],
self::CANCEL => [
'name' => '支付超时',
'value' => self::CANCEL,
],
];
}
}
@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单支付方式
* Class PayType
* @package app\common\enum\order
*/
class PayType extends EnumBasics
{
// 余额支付
const BALANCE = 10;
// 微信支付
const WECHAT = 20;
// 转账支付
const TRANSFER = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data(): array
{
return [
self::BALANCE => [
'name' => '余额支付',
'value' => self::BALANCE,
],
self::WECHAT => [
'name' => '微信支付',
'value' => self::WECHAT,
],
self::TRANSFER => [
'name' => '转账支付',
'value' => self::TRANSFER,
],
];
}
}
@@ -0,0 +1,47 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单收货状态
* Class ReceiptStatus
* @package app\common\enum\order
*/
class ReceiptStatus extends EnumBasics
{
// 未收货
const NOT_RECEIVED = 10;
// 已收货
const RECEIVED = 20;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::NOT_RECEIVED => [
'name' => '未收货',
'value' => self::NOT_RECEIVED,
],
self::RECEIVED => [
'name' => '已收货',
'value' => self::RECEIVED,
],
];
}
}
@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order\export;
use app\common\enum\EnumBasics;
/**
* 枚举类:导出状态
* Class ExportStatus
* @package app\common\enum\order\export
*/
class ExportStatus extends EnumBasics
{
// 进行中
const NORMAL = 10;
// 已完成
const COMPLETED = 20;
// 失败
const FAIL = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::NORMAL => [
'name' => '进行中',
'value' => self::NORMAL,
],
self::COMPLETED => [
'name' => '已完成',
'value' => self::COMPLETED,
],
self::FAIL => [
'name' => '失败',
'value' => self::FAIL,
]
];
}
}
@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order\refund;
use app\common\enum\EnumBasics;
/**
* 枚举类:商家审核状态
* Class AuditStatus
* @package app\common\enum\order
*/
class AuditStatus extends EnumBasics
{
// 待审核
const WAIT = 0;
// 已同意
const REVIEWED = 10;
// 已拒绝
const REJECTED = 20;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::WAIT => [
'name' => '待审核',
'value' => self::WAIT
],
self::REVIEWED => [
'name' => '已同意',
'value' => self::REVIEWED
],
self::REJECTED => [
'name' => '已拒绝',
'value' => self::REJECTED
]
];
}
}
@@ -0,0 +1,62 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order\refund;
use app\common\enum\EnumBasics;
/**
* 枚举类:售后单状态
* Class RefundStatus
* @package app\common\enum\order
*/
class RefundStatus extends EnumBasics
{
// 进行中
const NORMAL = 0;
// 已拒绝
const REJECTED = 10;
// 已完成
const COMPLETED = 20;
// 已取消
const CANCELLED = 30;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::NORMAL => [
'name' => '进行中',
'value' => self::NORMAL,
],
self::REJECTED => [
'name' => '已拒绝',
'value' => self::REJECTED,
],
self::COMPLETED => [
'name' => '已完成',
'value' => self::COMPLETED,
],
self::CANCELLED => [
'name' => '已取消',
'value' => self::CANCELLED,
]
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\order\refund;
use app\common\enum\EnumBasics;
/**
* 枚举类:售后类型
* Class RefundType
* @package app\common\enum\order
*/
class RefundType extends EnumBasics
{
// 退货退款
const RETURN = 10;
// 换货
const EXCHANGE = 20;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::RETURN => [
'name' => '退货退款',
'value' => self::RETURN
],
self::EXCHANGE => [
'name' => '换货',
'value' => self::EXCHANGE
]
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\page;
use app\common\enum\EnumBasics;
/**
* 枚举类:订单支付方式
* Class PageType
* @package app\common\enum\order
*/
class PageType extends EnumBasics
{
// 首页
const HOME = 10;
// 自定义页
const CUSTOM = 20;
/**
* 获取枚举数据
* @return array
*/
public static function data()
{
return [
self::HOME => [
'name' => '首页',
'value' => self::HOME
],
self::CUSTOM => [
'name' => '自定义页',
'value' => self::CUSTOM
]
];
}
}
@@ -0,0 +1,66 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\partners\balanceLog;
use app\common\enum\EnumBasics;
/**
* 余额变动场景枚举类
* Class Scene
* @package app\common\enum\partners\balanceLog
*/
class Scene extends EnumBasics
{
// 用户充值
const RECHARGE = 10;
// 用户消费
const CONSUME = 20;
// 管理员操作
const ADMIN = 30;
// 订单退款
const REFUND = 40;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::RECHARGE => [
'name' => '用户充值',
'value' => self::RECHARGE,
'describe' => '用户充值:%s',
],
self::CONSUME => [
'name' => '用户消费',
'value' => self::CONSUME,
'describe' => '用户消费:%s',
],
self::ADMIN => [
'name' => '管理员操作',
'value' => self::ADMIN,
'describe' => '后台管理员 [%s] 操作',
],
self::REFUND => [
'name' => '订单退款',
'value' => self::REFUND,
'describe' => '订单退款:%s',
],
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\recharge\order;
use app\common\enum\EnumBasics;
/**
* 用户充值订单-支付状态枚举类
* Class PayStatus
* @package app\common\enum\recharge\order
*/
class PayStatus extends EnumBasics
{
// 待支付
const PENDING = 10;
// 支付成功
const SUCCESS = 20;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::PENDING => [
'name' => '未支付',
'value' => self::PENDING,
],
self::SUCCESS => [
'name' => '已支付',
'value' => self::SUCCESS,
],
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\recharge\order;
use app\common\enum\EnumBasics;
/**
* 用户充值订单-充值方式枚举类
* Class RechargeType
* @package app\common\enum\recharge\order
*/
class RechargeType extends EnumBasics
{
// 自定义金额
const CUSTOM = 10;
// 套餐充值
const PLAN = 20;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::CUSTOM => [
'name' => '自定义金额',
'value' => self::CUSTOM,
],
self::PLAN => [
'name' => '套餐充值',
'value' => self::PLAN,
],
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\setting\sms;
use app\common\enum\EnumBasics;
/**
* 枚举类: 短信通知场景
* Class Scene
* @package app\common\enum\setting\sms
*/
class Scene extends EnumBasics
{
// 短信验证码
const CAPTCHA = 'captcha';
// 新付款订单
const ORDER_PAY = 'order_pay';
/**
* 获取类型值
* @return array
*/
public static function data()
{
return [
self::CAPTCHA => [
'name' => '短信验证码',
'value' => self::CAPTCHA
],
self::ORDER_PAY => [
'name' => '新付款订单',
'value' => self::ORDER_PAY
]
];
}
}
@@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\store\address;
use app\common\enum\EnumBasics;
/**
* 枚举类:地址类型
* Class Type
* @package app\common\enum\store\address
*/
class Type extends EnumBasics
{
// 发货地址
const DELIVERY = 10;
// 退货地址
const RETURN = 20;
/**
* 获取类型值
* @return array
*/
public static function data()
{
return [
self::DELIVERY => [
'name' => '发货地址',
'value' => self::DELIVERY,
],
self::RETURN => [
'name' => '退货地址',
'value' => self::RETURN
]
];
}
}
@@ -0,0 +1,61 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\store\page\category;
use app\common\enum\EnumBasics;
/**
* 枚举类:分类页模板样式
* Class Style
* @package app\common\enum\store\page\category
*/
class Style extends EnumBasics
{
// 一级分类[大图]
const ONE_LEVEL_BIG = 10;
// 一级分类[小图]
const ONE_LEVEL_SMALL = 11;
// 一级分类+二级分类
const TWO_LEVEL = 20;
// 分类+商品
const COMMODITY = 30;
/**
* 获取类型值
* @return array
*/
public static function data(): array
{
return [
self::ONE_LEVEL_BIG => [
'name' => '一级分类[大图]',
'value' => self::ONE_LEVEL_BIG,
],
self::ONE_LEVEL_SMALL => [
'name' => '一级分类[小图]',
'value' => self::ONE_LEVEL_SMALL
],
self::TWO_LEVEL => [
'name' => '二级分类',
'value' => self::TWO_LEVEL
],
self::COMMODITY => [
'name' => '分类+商品',
'value' => self::COMMODITY
]
];
}
}
@@ -0,0 +1,82 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\user\balanceLog;
use app\common\enum\EnumBasics;
/**
* 余额变动场景枚举类
* Class Scene
* @package app\common\enum\user\balanceLog
*/
class Scene extends EnumBasics
{
// 用户充值
const RECHARGE = 10;
// 用户消费
const CONSUME = 20;
// 管理员操作
const ADMIN = 30;
// 订单退款
const REFUND = 40;
// 用户分销
const SHARE = 50;
// 实体卡兑换
const EXCHANGE = 60;
/**
* 获取订单类型值
* @return array
*/
public static function data()
{
return [
self::RECHARGE => [
'name' => '用户充值',
'value' => self::RECHARGE,
'describe' => '用户充值:%s',
],
self::CONSUME => [
'name' => '用户消费',
'value' => self::CONSUME,
'describe' => '用户消费:%s',
],
self::ADMIN => [
'name' => '管理员操作',
'value' => self::ADMIN,
'describe' => '后台管理员 [%s] 操作',
],
self::REFUND => [
'name' => '订单退款',
'value' => self::REFUND,
'describe' => '订单退款:%s',
],
self::SHARE => [
'name' => '用户分销',
'value' => self::SHARE,
'describe' => '用户分销:%s',
],
self::EXCHANGE => [
'name' => '实体卡兑换',
'value' => self::EXCHANGE,
'describe' => '实体卡兑换:%s',
],
];
}
}
@@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\enum\user\grade\log;
use app\common\enum\EnumBasics;
/**
* 会员等级变更记录表 -> 变更类型
* Class ChangeType
* @package app\common\enum\user\grade\log
*/
class ChangeType extends EnumBasics
{
// 后台管理员设置
const ADMIN_USER = 10;
// 自动升级
const AUTO_UPGRADE = 20;
}
@@ -0,0 +1,89 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library;
use app\common\exception\BaseException;
class Download
{
/**
* 获取网络图片到临时目录
* @param int $storeId
* @param string $url
* @param string $prefix
* @return string
* @throws \cores\exception\BaseException
*/
public function saveTempImage(int $storeId, string $url, string $prefix = 'temp'): string
{
$savePath = $this->getSavePath($storeId, $prefix, $url);
if (!file_exists($savePath)) {
$result = $this->curl($url);
empty($result) && throwError('获取到的图片内容为空 url: ' . $url);
$this->fwrite($savePath, $result);
}
return $savePath;
}
/**
* 写入文件
* @param string $savePath
* @param string $result
*/
private function fwrite(string $savePath, string $result)
{
$fp = fopen($savePath, 'w');
fwrite($fp, $result);
fclose($fp);
}
/**
* 请求网络文件
* @param string $url
* @return bool|string
*/
private function curl(string $url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 文件保存的路径
* @param int $storeId
* @param string $prefix
* @param string $url
* @return string
*/
private function getSavePath(int $storeId, string $prefix, string $url): string
{
$dirPath = $this->getDirPath($storeId);
return $dirPath . '/' . $prefix . '_' . md5($url) . '.png';
}
/**
* 文件保存的目录
* @param int $storeId
* @return string
*/
private function getDirPath(int $storeId): string
{
$dirPath = runtime_root_path() . "image/{$storeId}";
!is_dir($dirPath) && mkdir($dirPath, 0755, true);
return $dirPath;
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library;
/**
* 文件阻塞锁
* 用于并发情况下保持数据的原子性, 仅适用于轻量并发场景,如果是高并发场景请使用redis
* Class Lock
* @package app\common\library
*/
class Lock
{
// 文件锁资源树
static $resource = [];
/**
* 加锁
* @param string $uniqueId
* @return bool
*/
public static function lockUp(string $uniqueId): bool
{
clearstatcache();
static::$resource[$uniqueId] = fopen(static::getFilePath($uniqueId), 'w+');
return flock(static::$resource[$uniqueId], LOCK_EX);
}
/**
* 解锁
* @param string $uniqueId
* @return bool
*/
public static function unLock(string $uniqueId): bool
{
clearstatcache();
if (!isset(static::$resource[$uniqueId])) return false;
flock(static::$resource[$uniqueId], LOCK_UN);
fclose(static::$resource[$uniqueId]);
return static::deleteFile($uniqueId);
}
/**
* 获取锁文件的路径
* @param string $uniqueId
* @return string
*/
private static function getFilePath(string $uniqueId): string
{
clearstatcache();
$dirPath = runtime_root_path() . 'lock/';
!is_dir($dirPath) && mkdir($dirPath, 0755, true);
return $dirPath . md5($uniqueId) . '.lock';
}
/**
* 删除锁文件
* @param string $uniqueId
* @return bool
*/
private static function deleteFile(string $uniqueId): bool
{
clearstatcache();
$filePath = static::getFilePath($uniqueId);
return file_exists($filePath) && unlink($filePath);
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library;
use think\facade\Log as LogFacade;
class Log
{
// 日志内容
private static $data = [];
/**
* 写入日志
* @param mixed $value
* @param string $type
*/
public static function record($value, string $type = 'info')
{
$content = is_string($value) ? $value : print_r($value, true);
LogFacade::record($content, $type);
}
/**
* 写入日志 (使用追加的方式, 索引值是name)
* @param string $name 日志记录名
* @param array $data 记录内容
*/
public static function append(string $name, array $data)
{
$merge = array_merge(compact('name'), $data);
if (isset(static::$data[$name])) {
$merge = array_merge(static::$data[$name], $merge);
}
static::$data[$name] = $merge;
}
/**
* 在应用结束时将追加的日志数据写入到文件
*/
public static function end()
{
foreach (static::$data as $name => $item) {
static::record(array_merge(['name' => $name], $item));
}
}
}
@@ -0,0 +1,99 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\express;
use think\facade\Cache;
use cores\traits\ErrorTrait;
use app\common\library\helper;
/**
* 快递100API模块
* Class Kuaidi100
* @package app\common\library\express
*/
class Kuaidi100
{
use ErrorTrait;
// 物流跟踪查询API地址
const QUERY_URL = 'http://poll.kuaidi100.com/poll/query.do';
// 微信支付配置
/* @var array $config */
private $config;
/**
* 构造方法
* WxPay constructor.
* @param $config
*/
public function __construct($config)
{
$this->config = $config;
}
/**
* 执行查询
* @param string $code
* @param string $expressNo
* @return string|bool
*/
public function query(string $code, string $expressNo)
{
// 缓存索引
$cacheIndex = "express_{$code}_$expressNo";
if ($cacheData = Cache::get($cacheIndex)) {
return $cacheData;
}
// 参数设置
$postData = [
'customer' => $this->config['customer'],
'param' => helper::jsonEncode([
'resultv2' => '1',
'com' => $code,
'num' => $expressNo
])
];
$postData['sign'] = strtoupper(md5($postData['param'] . $this->config['key'] . $postData['customer']));
// 请求快递100 api
$result = $this->curlGet(self::QUERY_URL, $postData);
$express = helper::jsonDecode($result);
// 记录错误信息
if (isset($express['returnCode']) || !isset($express['data'])) {
$this->error = $express['message'] ?? '查询失败';
return false;
}
// 记录缓存, 时效30分钟
Cache::set($cacheIndex, $express['data'], 3000);
return $express['data'];
}
/**
* curl请求指定url (post)
* @param $url
* @param array $data
* @return bool|string
*/
private function curlGet($url, array $data = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
+267
View File
@@ -0,0 +1,267 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
namespace app\common\library;
/**
* 工具类
* Class helper
* @package app\common\library
*/
class helper
{
/**
* 从object中选取属性
* @param $source
* @param array $columns
* @return array
*/
public static function pick($source, array $columns): array
{
$dataset = [];
foreach ($source as $key => $item) {
in_array($key, $columns) && $dataset[$key] = $item;
}
return $dataset;
}
/**
* 获取数组中指定的列
* @param $source
* @param $column
* @return array
*/
public static function getArrayColumn($source, $column): array
{
$columnArr = [];
foreach ($source as $item) {
isset($item[$column]) && $columnArr[] = $item[$column];
}
return $columnArr;
}
/**
* 获取数组中指定的列 [支持多列]
* @param $source
* @param $columns
* @return array
*/
public static function getArrayColumns($source, $columns): array
{
$columnArr = [];
foreach ($source as $item) {
$temp = [];
foreach ($columns as $index) {
$temp[$index] = $item[$index];
}
$columnArr[] = $temp;
}
return $columnArr;
}
/**
* 把二维数组中某列设置为key返回
* @param $source
* @param $index
* @return array
*/
public static function arrayColumn2Key($source, $index): array
{
$data = [];
foreach ($source as $item) {
$data[$item[$index]] = $item;
}
return $data;
}
/**
* 格式化价格显示
* @param mixed $number
* @param bool $isMinimum 是否存在最小值
* @param float $minimum
* @return string
*/
public static function number2($number, bool $isMinimum = false, float $minimum = 0.01): string
{
$isMinimum && $number = max($minimum, $number);
return sprintf('%.2f', $number);
}
public static function getArrayItemByColumn($array, $column, $value)
{
foreach ($array as $item) {
if ($item[$column] == $value) {
return $item;
}
}
return false;
}
/**
* 获取二维数组中指定字段的和
* @param $array
* @param $column
* @return float|int
*/
public static function getArrayColumnSum($array, $column)
{
$sum = 0;
foreach ($array as $item) {
$sum = self::bcadd($sum, $item[$column]);
}
return $sum;
}
/**
* 在二维数组中查找指定值
* @param array $array 二维数组
* @param string $searchIdx 查找的索引
* @param mixed $searchVal 查找的值
* @return bool|mixed
*/
public static function arraySearch(array $array, string $searchIdx, $searchVal)
{
foreach ($array as $item) {
if ($item[$searchIdx] == $searchVal) {
return $item;
}
}
return false;
}
public static function setDataAttribute(&$source, $defaultData, $isArray = false)
{
if (!$isArray) $dataSource = [&$source]; else $dataSource = &$source;
foreach ($dataSource as &$item) {
foreach ($defaultData as $key => $value) {
$item[$key] = $value;
}
}
return $source;
}
public static function bcsub($leftOperand, $rightOperand, $scale = 2): string
{
return \bcsub($leftOperand, $rightOperand, $scale);
}
public static function bcadd($leftOperand, $rightOperand, $scale = 2): string
{
return \bcadd($leftOperand, $rightOperand, $scale);
}
public static function bcmul($leftOperand, $rightOperand, $scale = 2): string
{
return \bcmul($leftOperand, $rightOperand, $scale);
}
public static function bcdiv($leftOperand, $rightOperand, int $scale = 2): ?string
{
return \bcdiv($leftOperand, $rightOperand, $scale);
}
/**
* 浮点数比较
* 若二个字符串一样大则返回 0;若左边的数字字符串 (left operand) 比右边 (right operand) 的大则返回 +1;若左边的数字字符串比右边的小则返回 -1
* @param $leftOperand
* @param $rightOperand
* @param int $scale
* @return int
*/
public static function bccomp($leftOperand, $rightOperand, int $scale = 2): int
{
return \bccomp($leftOperand, $rightOperand, $scale);
}
/**
* 比较两个数值是否相等
* @param $leftOperand
* @param $rightOperand
* @param int $scale
* @return bool
*/
public static function bcequal($leftOperand, $rightOperand, int $scale = 2): bool
{
return self::bccomp($leftOperand, $rightOperand, $scale) === 0;
}
/**
* 数组转为json
* @param $data
* @param int $options
* @return false|string
*/
public static function jsonEncode($data, int $options = JSON_UNESCAPED_UNICODE)
{
return json_encode($data, $options);
}
/**
* json转义为数组
* @param $json
* @return array|mixed
*/
public static function jsonDecode($json)
{
return json_decode($json, true);
}
/**
* 检查目录是否可写
* @param $path
* @return bool
*/
public static function checkWriteable($path): bool
{
try {
!is_dir($path) && mkdir($path, 0755);
if (!is_dir($path))
return false;
$fileName = $path . '/_test_write.txt';
if ($fp = fopen($fileName, 'w')) {
return fclose($fp) && unlink($fileName);
}
} catch (\Exception $e) {
}
return false;
}
/**
* 记录info日志
* @param string $name
* @param array $content
*/
public static function logInfo(string $name, array $content)
{
$content['name'] = $name;
log_record($content, 'info');
}
/**
* 将字符串转换为字节
* @param string $from
* @return int|null
*/
public static function convertToBytes(string $from): ?int
{
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
$number = substr($from, 0, -2);
$suffix = strtoupper(substr($from, -2));
// B or no suffix
if (is_numeric(substr($suffix, 0, 1))) {
return preg_replace('/[^\d]/', '', $from);
}
$exponent = array_flip($units)[$suffix] ?? null;
if ($exponent === null) {
return null;
}
return $number * (1024 ** $exponent);
}
}
@@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\leshua;
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
@@ -0,0 +1,65 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\leshua;
class LSBizDataCrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param string $appid string 小程序的appid
* @param string $sessionKey string 用户在小程序登录后获取的会话密钥
*/
public function __construct(string $appid, string $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param string $encryptedData 加密的用户数据
* @param string $iv 与用户数据一同返回的初始向量
* @param mixed $content 解密后的原文
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData(string $encryptedData, string $iv, &$content): int
{
if (strlen($this->sessionKey) != 24) {
return ErrorCode::$IllegalAesKey;
}
if (strlen($iv) != 24) {
return ErrorCode::$IllegalIv;
}
$aesKey = base64_decode($this->sessionKey);
$aesIV = base64_decode($iv);
$aesCipher = base64_decode($encryptedData);
$result = openssl_decrypt($aesCipher, 'AES-128-CBC', $aesKey, 1, $aesIV);
if (empty($result)) {
return ErrorCode::$IllegalBuffer;
}
$resultArr = json_decode($result, true);
if (empty($resultArr)) {
return ErrorCode::$IllegalBuffer;
}
if ($resultArr['watermark']['appid'] != $this->appid) {
return ErrorCode::$IllegalBuffer;
}
$content = $resultArr;
return ErrorCode::$OK;
}
}
@@ -0,0 +1,187 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\leshua;
use think\facade\Cache;
use cores\traits\ErrorTrait;
use app\common\library\helper;
use app\common\exception\BaseException;
/**
* 乐刷api基类
* Class leshua
* @package app\library
*/
class LsBase
{
use ErrorTrait;
protected $appId;
protected $appSecret;
/**
* 构造函数
* WxBase constructor.
* @param $appId
* @param $appSecret
*/
public function __construct($appId = null, $appSecret = null)
{
$this->setConfig($appId, $appSecret);
}
protected function setConfig($appId = null, $appSecret = null)
{
!empty($appId) && $this->appId = $appId;
!empty($appSecret) && $this->appSecret = $appSecret;
}
/**
* 获取access_token
* @return mixed
* @throws \cores\exception\BaseException
*/
protected function getAccessToken()
{
$cacheKey = $this->appId . '@access_token';
if (!Cache::get($cacheKey)) {
// 请求API获取 access_token
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
$result = $this->get($url);
$response = $this->jsonDecode($result);
if (array_key_exists('errcode', $response)) {
throwError("access_token获取失败,错误信息:{$result}");
}
// 记录日志
log_record([
'name' => '获取access_token',
'url' => $url,
'appId' => $this->appId,
'result' => $result
]);
// 写入缓存
Cache::set($cacheKey, $response['access_token'], 6000);
}
return Cache::get($cacheKey);
}
/**
* 模拟GET请求 HTTPS的页面
* @param string $url 请求地址
* @param array $data
* @return string $result
* @throws \cores\exception\BaseException
*/
protected function get(string $url, array $data = [])
{
// 处理query参数
if (!empty($data)) {
$url = $url . '?' . http_build_query($data);
}
$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_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
$result = curl_exec($curl);
if ($result === false) {
throwError(curl_error($curl));
}
curl_close($curl);
return $result;
}
/**
* 模拟POST请求
* @param string $url 请求地址
* @param mixed $data 请求数据
* @param false $useCert 是否引入微信支付证书
* @param array $sslCert 证书路径
* @return mixed|bool|string
* @throws \cores\exception\BaseException
*/
protected function post(string $url, $data = [], bool $useCert = false, array $sslCert = [])
{
$header = [
'Content-type: application/json;'
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
if ($useCert == true) {
// 设置证书:cert 与 key 分别属于两个.pem文件
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
}
$result = curl_exec($curl);
if ($result === false) {
throwError(curl_error($curl));
}
curl_close($curl);
return $result;
}
/**
* 模拟POST请求 [第二种方式, 用于兼容微信api]
* @param $url
* @param array $data
* @return mixed
* @throws \cores\exception\BaseException
*/
protected function post2($url, array $data = [])
{
$header = [
'Content-Type: application/x-www-form-urlencoded'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
$result = curl_exec($ch);
if ($result === false) {
throwError(curl_error($ch));
}
curl_close($ch);
return $result;
}
/**
* 数组转json
* @param $data
* @return string
*/
protected function jsonEncode($data): string
{
return helper::jsonEncode($data, JSON_UNESCAPED_UNICODE);
}
/**
* json转数组
* @param $json
* @return mixed
*/
protected function jsonDecode($json)
{
return helper::jsonDecode($json);
}
}
@@ -0,0 +1,360 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
namespace app\common\library\leshua;
use app\common\model\wxapp\Setting as WxappSettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\PayType as OrderPayTypeEnum;
use app\common\library\helper;
use app\common\exception\BaseException;
/**
* 乐刷支付
* Class LsPay
* @package app\common\library\leshua
*/
class LsPay extends LsBase
{
// 乐刷支付配置
private $config;
// 当前商城ID
private $storeId;
// 订单模型
private $modelClass = [
OrderTypeEnum::ORDER => \app\api\service\order\PaySuccess::class,
OrderTypeEnum::RECHARGE => \app\api\service\recharge\PaySuccess::class,
];
/**
* 构造函数
* @param array $config
* @param int|null $storeId
*/
public function __construct(array $config = [], ?int $storeId = null)
{
parent::__construct();
$this->config = $config;
$this->storeId = $storeId;
if (!empty($this->config)) {
$this->setConfig($this->config['app_id'], $this->config['app_secret']);
}
}
/**
* 统一下单API
* @param $orderNo
* @param $openid
* @param $totalFee
* @param int $orderType 订单类型
* @return array
* @throws \cores\exception\BaseException
*/
public function unifiedorder($orderNo, $openid, $totalFee, int $orderType = OrderTypeEnum::ORDER): array
{
// 当前时间
$time = time();
// 生成随机字符串
$nonceStr = md5($time . $openid);
// API参数
$params = [
'service' => 'get_tdcode',
'pay_way' => 'WXZF',
'merchant_id' => $this->config['mchid'],
'third_order_id' => $orderNo,
'amount' => (int)helper::bcmul($totalFee, 100), // 价格:单位分
'jspay_flag' => 3,
'appid' => $this->appId,
'sub_openid' => $openid,
'notify_url' => base_url() . 'leshua.php', // 异步通知地址
'body' => $orderNo,
'attach' => helper::jsonEncode(['order_type' => $orderType]),
'nonce_str' => $nonceStr,
//'spbill_create_ip' => \request()->ip(),
'order_expiration' => 60,
];
// 生成签名
$params['sign'] = $this->makeSign($params);
// 请求API
$url = 'https://paygate.leshuazf.com/cgi-bin/lepos_pay_gateway.cgi';
$result = $this->post($url, $params);
$prepay = $this->fromXml($result);
// 请求失败
if ($prepay['resp_code'] != '0') {
$errMsg = "乐刷支付api:{$prepay['resp_msg']}";
throwError($errMsg, null, ['errorCode' => 'LESHUA_PAY', 'isCreated' => true]);
}
if ($prepay['result_code'] != '0') {
$errMsg = "乐刷支付api:{$prepay['error_msg']}";
throwError($errMsg, null, ['errorCode' => 'LESHUA_PAY', 'isCreated' => true]);
}
$jspayInfo = helper::jsonDecode($prepay['jspay_info']);
$prepayId = explode('=', $jspayInfo['package'])[1];
// 生成 nonce_str 供前端使用
// $paySign = $this->makePaySign($params['nonce_str'], $prepayId, $time);
return [
'prepay_id' => $prepayId,
'nonceStr' => $nonceStr,
'timeStamp' => (string)$time,
'paySign' => $jspayInfo['paySign']
];
}
/**
* 支付成功异步通知
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function notify()
{
if (!$xml = file_get_contents('php://input')) {
$this->returnCode(false, 'Not found DATA');
}
// 将服务器返回的XML数据转化为数组
$data = $this->fromXml($xml);
// 记录日志
log_record($xml);
log_record($data);
// 实例化订单模型
$model = $this->getOrderModel($data['third_order_id'], $data['attach']);
// 订单信息
$order = $model->getOrderInfo();
empty($order) && $this->returnCode(false, '订单不存在');
// 小程序配置信息
$wxConfig = WxappSettingModel::getWxappConfig($order['store_id']);
// 设置支付秘钥
$this->config['apikey'] = $wxConfig['apikey'];
// 保存微信服务器返回的签名sign
$dataSign = $data['sign'];
// sign不参与签名算法
unset($data['sign']);
// 生成签名
$sign = $this->makeSign($data);
// 判断签名是否正确 判断支付状态
if (
($sign !== $dataSign)
|| ($data['return_code'] !== 'SUCCESS')
|| ($data['result_code'] !== 'SUCCESS')
) {
$this->returnCode(false, '签名失败');
}
// 订单支付成功业务处理
$status = $model->onPaySuccess(OrderPayTypeEnum::WECHAT, $data);
if ($status == false) {
$this->returnCode(false, $model->getError());
}
// 返回状态
$this->returnCode(true, 'OK');
}
/**
* 申请退款API
* @param string $transactionId 微信支付交易流水号
* @param string $totalFee 订单总金额
* @param string $refundFee 退款金额
* @return bool
* @throws BaseException
* @throws \cores\exception\BaseException
*/
public function refund(string $transactionId, string $totalFee, string $refundFee): bool
{
// 当前时间
$time = time();
// 生成随机字符串
$nonceStr = md5($time . $transactionId . $totalFee . $refundFee);
// API参数
$params = [
'appid' => $this->appId,
'mch_id' => $this->config['mchid'],
'nonce_str' => $nonceStr,
'transaction_id' => $transactionId,
'out_refund_no' => $time,
'total_fee' => (int)helper::bcmul($totalFee,100),
'refund_fee' => (int)helper::bcmul($refundFee,100),
];
// 生成签名
$params['sign'] = $this->makeSign($params);
// 请求API
$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
$result = $this->post($url, $this->toXml($params), true, $this->getCertPem());
// 请求失败
if (empty($result)) {
throwError('微信退款api请求失败');
}
// 格式化返回结果
$prepay = $this->fromXml($result);
// 记录日志
log_record(['name' => '微信退款API', [
'params' => $params,
'result' => $result,
'prepay' => $prepay
]]);
// 请求失败
if ($prepay['return_code'] === 'FAIL') {
throwError("return_msg: {$prepay['return_msg']}");
}
if ($prepay['result_code'] === 'FAIL') {
throwError("err_code_des: {$prepay['err_code_des']}");
}
return true;
}
/**
* 获取cert证书文件
* @return string[]
* @throws \cores\exception\BaseException
*/
private function getCertPem(): array
{
if (empty($this->config['cert_pem']) || empty($this->config['key_pem'])) {
throwError('请先到后台小程序设置填写微信支付证书文件');
}
// cert目录
$filePath = __DIR__ . "/cert/{$this->storeId}/";
return [
'certPem' => $filePath . 'cert.pem',
'keyPem' => $filePath . 'key.pem'
];
}
/**
* 实例化订单模型 (根据attach判断)
* @param $orderNo
* @param null $attach
* @return mixed
*/
private function getOrderModel($orderNo, $attach = null)
{
$attach = helper::jsonDecode($attach);
// 判断订单类型返回对应的订单模型
$model = $this->modelClass[$attach['order_type']];
return new $model($orderNo);
}
/**
* 返回状态给微信服务器
* @param boolean $returnCode
* @param string|null $msg
*/
private function returnCode(bool $returnCode = true, string $msg = null)
{
// 返回状态
$return = [
'return_code' => $returnCode ? 'SUCCESS' : 'FAIL',
'return_msg' => $msg ?: 'OK',
];
// 记录日志
log_record([
'name' => '返回微信支付状态',
'data' => $return
]);
die($this->toXml($return));
}
/**
* 生成paySign
* @param string $nonceStr
* @param string $prepayId
* @param int $timeStamp
* @return string
*/
private function makePaySign(string $nonceStr, string $prepayId, int $timeStamp): string
{
$data = [
'appId' => $this->appId,
'nonceStr' => $nonceStr,
'package' => 'prepay_id=' . $prepayId,
'signType' => 'MD5',
'timeStamp' => $timeStamp,
];
// 签名步骤一:按字典序排序参数
ksort($data);
$string = $this->toUrlParams($data);
// 签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->config['apikey'];
// 签名步骤三:MD5加密
$string = md5($string);
// 签名步骤四:所有字符转为大写
return strtoupper($string);
}
/**
* 将xml转为array
* @param string $xml
* @return mixed
*/
private function fromXml(string $xml)
{
// 禁止引用外部xml实体
libxml_disable_entity_loader(true);
return helper::jsonDecode(helper::jsonEncode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)));
}
/**
* 生成签名
* @param array $values
* @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
private function makeSign(array $values): string
{
//签名步骤一:按字典序排序参数
ksort($values);
$string = $this->toUrlParams($values);
//签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->config['apikey'];
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
return strtoupper($string);
}
/**
* 格式化参数格式化成url参数
* @param array $values
* @return string
*/
private function toUrlParams(array $values): string
{
$buff = '';
foreach ($values as $k => $v) {
if ($k != 'sign' && $v != '' && !is_array($v)) {
$buff .= $k . '=' . $v . '&';
}
}
return trim($buff, '&');
}
/**
* 输出xml字符
* @param array $values
* @return bool|string
*/
private function toXml(array $values)
{
if (!is_array($values)
|| count($values) <= 0
) {
return false;
}
$xml = "<xml>";
foreach ($values as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
}
@@ -0,0 +1,61 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
namespace app\common\library\sms;
use Overtrue\EasySms\Strategies\OrderStrategy;
/**
* EasySms配置类
* Class Config
* @package app\common\library\sms
*/
class Config
{
/**
* 生成EasySms的配置项
* @param array $smsConfig
* @return array
*/
public static function getEasySmsConfig(array $smsConfig): array
{
return [
// HTTP 请求的超时时间(秒)
'timeout' => 5.0,
// 默认发送配置
'default' => [
// 网关调用策略,默认:顺序调用
'strategy' => OrderStrategy::class,
// 默认可用的发送网关
'gateways' => [$smsConfig['default']],
],
// 可用的网关配置
'gateways' => [
'aliyun' => [
'access_key_id' => $smsConfig['engine']['aliyun']['AccessKeyId'],
'access_key_secret' => $smsConfig['engine']['aliyun']['AccessKeySecret'],
'sign_name' => $smsConfig['engine']['aliyun']['sign'],
],
'qcloud' => [
'sdk_app_id' => $smsConfig['engine']['qcloud']['SdkAppID'],
'secret_id' => $smsConfig['engine']['qcloud']['AccessKeyId'],
'secret_key' => $smsConfig['engine']['qcloud']['AccessKeySecret'],
'sign_name' => $smsConfig['engine']['qcloud']['sign'],
],
'qiniu' => [
'access_key' => $smsConfig['engine']['qiniu']['AccessKey'],
'secret_key' => $smsConfig['engine']['qiniu']['SecretKey'],
],
]
];
}
}
@@ -0,0 +1,149 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\sms;
use app\common\library\helper;
use cores\traits\ErrorTrait;
use cores\exception\BaseException;
use Overtrue\EasySms\EasySms;
use Overtrue\EasySms\Exceptions\InvalidArgumentException;
use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
/**
* 短信通知模块驱动
* Class Driver
* @package app\common\library\sms
*/
class Driver
{
use ErrorTrait;
// 后台短信配置信息
private $smsConfig;
// 当前短信平台 (后台设置)
private $gateway;
/**
* 构造方法
* Driver constructor.
* @param array $smsConfig
*/
public function __construct(array $smsConfig)
{
// 配置信息
$this->smsConfig = $smsConfig;
// 当前短信平台
$this->gateway = $this->smsConfig['default'];
}
/**
* 发送短信通知
* @param string $acceptPhone 接收的手机号
* @param string $templateCode 短信模板ID
* @param array $templateParams 短信模板参数
* @return bool
* @throws BaseException
* @throws InvalidArgumentException
*/
public function sendSms(string $acceptPhone, string $templateCode, array $templateParams): bool
{
// 实例化EasySms
$easySmsConfig = Config::getEasySmsConfig($this->smsConfig);
$easySms = new EasySms($easySmsConfig);
try {
// 执行发送短信
$result = $easySms->send($acceptPhone, [
'template' => $templateCode,
'data' => $this->getSmsTemplateData($templateParams),
]);
// 短信发送成功的错误处理
$sendStatus = $this->resultHandle($result);
} catch (NoGatewayAvailableException $e) {
// 短信发送异常的错误处理
$sendStatus = false;
$this->exceptionHandle($e);
}
// 记录日志
helper::logInfo('发送短信', [
'gateway' => $this->smsConfig['default'],
'acceptPhone' => $acceptPhone,
'templateCode' => $templateCode,
'templateParams' => $templateParams,
'sendStatus' => $sendStatus ? 'true' : 'false',
'sendErrMsg' => $this->getError(),
]);
// 存在异常时抛错
$sendStatus === false && throwError($this->getError());
return $sendStatus;
}
/**
* 短信发送成功的错误处理
* @param array $result
* @return bool
*/
private function resultHandle(array $result): bool
{
// 腾讯云短信错误: 模板ID不正确
if ($this->gateway === 'qcloud') {
$response = $result[$this->gateway]['result']['Response']['SendStatusSet'];
if (isset($response[0]) && isset($response[0]['Code']) && $response[0]['Code'] !== 'Ok') {
$this->error = '请检查后台短信平台参数和模板ID是否正确';
return false;
}
}
return true;
}
/**
* 短信发送异常的错误处理
* @param NoGatewayAvailableException $e
*/
private function exceptionHandle(NoGatewayAvailableException $e)
{
// 短信发送失败
$err = $e->getLastException();
if ($err instanceof \GuzzleHttp\Exception\ClientException) {
$body = (string)$err->getResponse()->getBody();
$result = helper::jsonDecode($body);
if (isset($result['Message'])) {
// $errMsg = $result['Message'];
$this->error = '请检查后台短信平台的参数设置';
return;
}
if (isset($result['message'])) {
$this->error = $result['message'];
return;
}
}
// if ($err instanceof \Overtrue\EasySms\Exceptions\GatewayErrorException) {
// $this->error = $err->getMessage();
// return;
// }
$this->error = $err->getMessage();
}
/**
* 生成短信模板数据
* @param array $templateParams
* @return array
*/
private function getSmsTemplateData(array $templateParams): array
{
if ($this->gateway === 'qcloud') {
$templateParams = array_values($templateParams);
}
return $templateParams;
}
}
@@ -0,0 +1,98 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\sms\engine;
use app\common\library\helper;
use app\common\library\sms\package\aliyun\SignatureHelper;
/**
* 阿里云短信模块引擎
* Class Aliyun
* @package app\common\library\sms\engine
*/
class Aliyun extends Server
{
private $config;
/**
* 构造方法
* Qiniu constructor.
* @param $config
*/
public function __construct($config)
{
$this->config = $config;
}
/**
* 发送短信通知
* @param array $sceneConfig 场景配置
* @param array $templateParams 短信模板参数
* @return bool
*/
public function sendSms(array $sceneConfig, array $templateParams)
{
$params = [];
// *** 需用户填写部分 ***
// 必填: 短信接收号码
$params["PhoneNumbers"] = $sceneConfig['acceptPhone'];
// 必填: 短信签名,应严格按"签名名称"填写,请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
$params["SignName"] = $this->config['sign'];
// 必填: 短信模板Code,应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
$params["TemplateCode"] = $sceneConfig['templateCode'];
// 可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
$params['TemplateParam'] = $templateParams;
// 可选: 设置发送短信流水号
// $params['OutId'] = "12345";
// 可选: 上行短信扩展码, 扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段
// $params['SmsUpExtendCode'] = "1234567";
// *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
if (!empty($params['TemplateParam'])) {
$params['TemplateParam'] = helper::jsonEncode($params['TemplateParam']);
}
// 初始化SignatureHelper实例用于设置参数,签名以及发送请求
$helper = new SignatureHelper;
// 此处可能会抛出异常,注意catch
$response = $helper->request(
$this->config['AccessKeyId']
, $this->config['AccessKeySecret']
, "dysmsapi.aliyuncs.com"
, array_merge($params, [
"RegionId" => "cn-hangzhou",
"Action" => "SendSms",
"Version" => "2017-05-25",
])
// 选填: 启用https
, true
);
// 记录日志
log_record([
'name' => '发送短信',
'config' => $this->config,
'params' => $params
]);
log_record($response);
$this->error = $response->Message;
return $response->Code === 'OK';
}
}
@@ -0,0 +1,29 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\sms\engine;
abstract class Server
{
protected $error;
/**
* 返回错误信息
* @return mixed
*/
public function getError()
{
return $this->error;
}
}
@@ -0,0 +1,88 @@
<?php
namespace app\common\library\sms\package\aliyun;
/**
* 签名助手 2017/11/19
*
* Class SignatureHelper
*/
class SignatureHelper
{
/**
* 生成签名并发起请求
*
* @param $accessKeyId string AccessKeyId (https://ak-console.aliyun.com/)
* @param $accessKeySecret string AccessKeySecret
* @param $domain string API接口所在域名
* @param $params array API具体参数
* @param $security boolean 使用https
* @return bool|\stdClass 返回API接口调用结果,当发生错误时返回false
*/
public function request($accessKeyId, $accessKeySecret, $domain, $params, $security = false)
{
$apiParams = array_merge(array(
"SignatureMethod" => "HMAC-SHA1",
"SignatureNonce" => uniqid(mt_rand(0, 0xffff), true),
"SignatureVersion" => "1.0",
"AccessKeyId" => $accessKeyId,
"Timestamp" => gmdate("Y-m-d\TH:i:s\Z"),
"Format" => "JSON",
), $params);
ksort($apiParams);
$sortedQueryStringTmp = "";
foreach ($apiParams as $key => $value) {
$sortedQueryStringTmp .= "&" . $this->encode($key) . "=" . $this->encode($value);
}
$stringToSign = "GET&%2F&" . $this->encode(substr($sortedQueryStringTmp, 1));
$sign = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));
$signature = $this->encode($sign);
$url = ($security ? 'https' : 'http') . "://{$domain}/?Signature={$signature}{$sortedQueryStringTmp}";
try {
$content = $this->fetchContent($url);
return json_decode($content);
} catch (\Exception $e) {
return false;
}
}
private function encode($str)
{
$res = urlencode($str);
$res = preg_replace("/\+/", "%20", $res);
$res = preg_replace("/\*/", "%2A", $res);
$res = preg_replace("/%7E/", "~", $res);
return $res;
}
private function fetchContent($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"x-sdk-client" => "php/2.0.0"
));
if (substr($url, 0, 5) == 'https') {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$rtn = curl_exec($ch);
if ($rtn === false) {
trigger_error("[CURL_" . curl_errno($ch) . "]: " . curl_error($ch), E_USER_ERROR);
}
curl_close($ch);
return $rtn;
}
}
@@ -0,0 +1,147 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage;
use think\Exception;
use app\common\library\storage\engine\Aliyun;
use app\common\library\storage\engine\Local;
use app\common\library\storage\engine\Qcloud;
use app\common\library\storage\engine\Qiniu;
use app\common\enum\file\Storage as StorageEnum;
/**
* 存储模块驱动
* Class driver
* @package app\common\library\storage
*/
class Driver
{
private $config; // upload 配置
private $engine; // 当前存储引擎类
/**
* 存储引擎类列表
*/
const ENGINE_CLASS_LIST = [
StorageEnum::LOCAL => Local::class,
StorageEnum::QINIU => QINIU::class,
StorageEnum::ALIYUN => Aliyun::class,
StorageEnum::QCLOUD => Qcloud::class
];
/**
* 构造方法
* Driver constructor.
* @param $config
* @param string|null $storage 指定存储方式,如不指定则为系统默认
* @throws Exception
*/
public function __construct($config, string $storage = null)
{
$this->config = $config;
// 实例化当前存储引擎
$this->engine = $this->getEngineClass($storage);
}
/**
* 设置上传的文件信息
* @param string $name
* @return mixed
*/
public function setUploadFile(string $name = 'iFile')
{
return $this->engine->setUploadFile($name);
}
/**
* 设置上传的文件信息
* @param string $filePath
* @return mixed
*/
public function setUploadFileByReal(string $filePath)
{
return $this->engine->setUploadFileByReal($filePath);
}
/**
* 设置上传的文件信息
* @param string $name
* @return mixed
*/
public function setRootName(string $name = '')
{
return $this->engine->setRootName($name);
}
/**
* 设置上传文件的验证规则
* @param array $rules
* @return mixed
*/
public function setValidationScene(array $rules = [])
{
return $this->engine->setValidationScene($rules);
}
/**
* 执行文件上传
*/
public function upload()
{
return $this->engine->upload();
}
/**
* 执行文件删除
* @param string $filePath
* @return mixed
*/
public function delete(string $filePath)
{
return $this->engine->delete($filePath);
}
/**
* 获取错误信息
* @return mixed
*/
public function getError()
{
return $this->engine->getError();
}
/**
* 返回保存的文件信息
* @return mixed
*/
public function getSaveFileInfo()
{
return $this->engine->getSaveFileInfo();
}
/**
* 获取当前的存储引擎
* @param string|null $storage 指定存储方式,如不指定则为系统默认
* @return mixed
* @throws Exception
*/
private function getEngineClass(string $storage = null)
{
$storage = is_null($storage) ? $this->config['default'] : $storage;
if (!isset(self::ENGINE_CLASS_LIST[$storage])) {
throw new Exception("未找到存储引擎类: {$storage}");
}
$class = self::ENGINE_CLASS_LIST[$storage];
return new $class($storage, $this->config['engine'][$storage]);
}
}
@@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage;
/**
* 文件上传验证类
* Class FileValidate
* @package app\common\library\storage
*/
class FileValidate extends \think\Validate
{
// 验证规则
protected $rule = [
// 图片文件: jpg,jpeg,png,bmp,gif
// 文件大小: 2MB = (1024 * 1024 * 2) = 2097152 字节
'image' => 'filesize:2097152|fileExt:jpg,jpeg,png,bmp,gif',
// 视频文件: mp4
// 文件大小: 20MB = (1024 * 1024 * 20) = 20971520 字节
'video' => 'filesize:10485760|fileExt:mp4',
];
// 错误提示信息
protected $message = [
'image.filesize' => '图片文件大小不能超出2MB',
'image.fileExt' => '图片文件扩展名有误',
'video.filesize' => '视频文件大小不能超出10MB',
'video.fileExt' => '视频文件扩展名有误',
];
// 验证场景
protected $scene = [
'image' => ['image'],
'video' => ['video'],
];
}
@@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage\engine;
use OSS\OssClient;
use OSS\Core\OssException;
/**
* 阿里云存储引擎 (OSS)
* Class Aliyun
* @package app\common\library\storage\engine
*/
class Aliyun extends Basics
{
/**
* 执行上传
* @return bool
*/
public function upload(): bool
{
try {
$ossClient = new OssClient(
$this->config['access_key_id'],
$this->config['access_key_secret'],
$this->config['domain'],
true
);
$result = $ossClient->uploadFile(
$this->config['bucket'],
$this->getSaveFileInfo()['file_path'],
$this->getRealPath()
);
} catch (OssException $e) {
$this->error = $e->getMessage();
return false;
}
return true;
}
/**
* 删除文件
* @param string $filePath
* @return bool
*/
public function delete(string $filePath): bool
{
try {
$ossClient = new OssClient(
$this->config['access_key_id'],
$this->config['access_key_secret'],
$this->config['domain'],
true
);
$ossClient->deleteObject($this->config['bucket'], $filePath);
} catch (OssException $e) {
$this->error = $e->getMessage();
return false;
}
return true;
}
}
@@ -0,0 +1,239 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage\engine;
use Exception;
use think\facade\Request;
use think\file\UploadedFile;
use cores\traits\ErrorTrait;
use app\common\exception\BaseException;
/**
* 存储引擎抽象类
* Class Basics
* @package app\common\library\storage\drivers
*/
abstract class Basics
{
use ErrorTrait;
// 当前存储引擎
protected $storage;
// 存储配置
protected $config;
// file对象句柄
/* @var $file UploadedFile */
protected $file;
// 验证规则
protected $validateRuleScene;
// 磁盘配置
protected $disk = 'public';
// 保存的根文件夹名称
protected $rootDirName;
/**
* 构造函数
* Server constructor.
* @param string $storage 存储方式
* @param array|null $config 存储配置
*/
public function __construct(string $storage, array $config = null)
{
$this->storage = $storage;
$this->config = $config;
}
/**
* 设置上传的文件信息 (外部用户上传)
* @param string $name
* @return $this
* @throws \cores\exception\BaseException
*/
public function setUploadFile(string $name): Basics
{
// 接收上传的文件
try {
$this->file = Request::file($name);
} catch (Exception $e) {
$this->throwFileError($e);
}
empty($this->file) && throwError('未找到上传文件的信息');
return $this;
}
/**
* 文件异常处理
* @param Exception $e
* @throws \cores\exception\BaseException
*/
private function throwFileError(Exception $e)
{
$maxSize = ini_get('upload_max_filesize');
$myMsg = $e->getCode() === 1 ? "上传的文件超出了服务器最大限制: {$maxSize};可修改php.ini文件中upload_max_filesize项调整" : false;
throwError($myMsg ?: $e->getMessage());
}
/**
* 设置上传的文件信息 (系统内部上传)
* @param string $filePath 文件路径
* @return $this
* @throws \cores\exception\BaseException
*/
public function setUploadFileByReal(string $filePath): Basics
{
// 接收上传的文件
$this->file = new UploadedFile($filePath, basename($filePath));
if (empty($this->file)) {
throwError('未找到上传文件的信息');
}
return $this;
}
/**
* 设置上传文件的验证规则
* @param string $scene
* @return Basics
*/
public function setValidationScene(string $scene = ''): Basics
{
$this->validateRuleScene = $scene;
return $this;
}
/**
* 设置磁盘配置
* @param string $disk
* @return $this
*/
public function setDisk(string $disk): Basics
{
$this->disk = $disk;
return $this;
}
/**
* 设置上传的文件根目录名称
* [通常是商城的id, 例如: 10001]
* @param string $name
* @return $this
*/
public function setRootDirName(string $name): Basics
{
$this->rootDirName = $name;
return $this;
}
/**
* 文件上传
* @return mixed
*/
abstract protected function upload();
/**
* 文件删除
* @param string $filePath
* @return mixed
*/
abstract protected function delete(string $filePath);
/**
* 临时文件的绝对路径
* @return mixed
*/
protected function getRealPath(): string
{
return $this->file->getRealPath();
}
/**
* 返回错误信息
* @return mixed
*/
public function getError(): string
{
return $this->error;
}
/**
* 生成保存的文件信息
* @return array
*/
public function getSaveFileInfo(): array
{
// 自动生成的文件名称
//$hashName = $this->file->hashName(null);
$hashName = $this->hashName();
// 存储目录
$filePath = $this->getFilePath($hashName);
// 文件名称
// 去除扩展名的写法 stristr($this->file->getOriginalName(), '.', true)
$fileName = $this->file->getOriginalName();
// 文件扩展名
$fileExt = strtolower($this->file->extension());
return [
'storage' => $this->storage, // 存储方式
'domain' => $this->config['domain'] ?? '', // 存储域名
'file_path' => $filePath, // 文件路径
'file_name' => $fileName, // 文件名称
'file_size' => $this->file->getSize(), // 文件大小(字节)
'file_ext' => $fileExt, // 文件扩展名
];
}
/**
* 自动生成文件名
* @return string
*/
private function hashName(): string
{
return $this->file->hashName(function () {
return date('Ymd') . DIRECTORY_SEPARATOR . md5(uniqid((string)mt_rand(), true));
});
}
/**
* 获取hashName的路径
* @param string $hashName
* @return string
*/
private function getFilePath(string $hashName): string
{
$filePath = empty($this->rootDirName) ? "{$hashName}" : "{$this->rootDirName}/{$hashName}";
return convert_left_slash($filePath);
}
/**
* 获取hashName的文件名
* @param string $filePath
* @return string
*/
protected function getFileHashName(string $filePath): string
{
return basename($filePath);
}
/**
* 获取hashName的文件目录
* @param string $filePath
* @return string
*/
protected function getFileHashRoute(string $filePath): string
{
return dirname($filePath);
}
}
@@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage\engine;
use think\facade\Filesystem;
use app\common\library\storage\FileValidate;
/**
* 本地文件驱动
* Class Local
* @package app\common\library\storage\drivers
*/
class Local extends Basics
{
/**
* 上传图片文件
* @return bool
*/
public function upload(): bool
{
// 验证文件类型
if (!$this->validate()) {
return false;
}
try {
$filePath = $this->getSaveFileInfo()['file_path'];
// 上传到本地服务器
$sts = Filesystem::disk($this->disk)->putFileAs(
$this->getFileHashRoute($filePath),
$this->file,
$this->getFileHashName($filePath)
);
return (bool)$sts;
} catch (\Exception $e) {
$this->error = $e->getMessage();
return false;
}
}
/**
* 验证上传的文件
* @return bool
*/
private function validate(): bool
{
$FileValidate = new FileValidate;
if (!$FileValidate->check([$this->validateRuleScene => $this->file])) {
$this->error = $FileValidate->getError();
return false;
}
return true;
}
/**
* 删除文件
* @param string $filePath
* @return bool
*/
public function delete(string $filePath): bool
{
// 文件所在目录
$realPath = realpath(web_path() . "uploads/{$filePath}");
return $realPath === false || unlink($realPath);
}
}
@@ -0,0 +1,93 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage\engine;
use Qcloud\Cos\Client;
/**
* 腾讯云存储引擎 (COS)
* Class Qcloud
* @package app\common\library\storage\engine
*/
class Qcloud extends Basics
{
// Qcloud类
private $cosClient;
/**
* 构造方法
* Qcloud constructor.
* @param string $storage 存储方式
* @param array|null $config 存储配置
*/
public function __construct(string $storage, array $config = null)
{
parent::__construct($storage, $config);
// 创建Qcloud类
$this->createCosClient();
}
/**
* 创建COS控制类
*/
private function createCosClient()
{
$this->cosClient = new Client([
'region' => $this->config['region'],
'credentials' => [
'secretId' => $this->config['secret_id'],
'secretKey' => $this->config['secret_key'],
],
]);
}
/**
* 执行上传
* @return bool
*/
public function upload(): bool
{
// 上传文件
// putObject(上传接口,最大支持上传5G文件)
try {
$result = $this->cosClient->putObject([
'Bucket' => $this->config['bucket'],
'Key' => $this->getSaveFileInfo()['file_path'],
'Body' => fopen($this->getRealPath(), 'rb')
]);
return true;
} catch (\Exception $e) {
$this->error = $e->getMessage();
return false;
}
}
/**
* 删除文件
* @param string $filePath
* @return bool
*/
public function delete(string $filePath): bool
{
try {
$result = $this->cosClient->deleteObject(array(
'Bucket' => $this->config['bucket'],
'Key' => $filePath
));
return true;
} catch (\Exception $e) {
$this->error = $e->getMessage();
return false;
}
}
}
@@ -0,0 +1,71 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\storage\engine;
use Qiniu\Auth;
use Qiniu\Http\Error;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;
/**
* 七牛云存储引擎
* Class Qiniu
* @package app\common\library\storage\engine
*/
class Qiniu extends Basics
{
/**
* 执行上传
* @return bool|mixed
* @throws \Exception
*/
public function upload()
{
// 要上传图片的本地路径
$realPath = $this->getRealPath();
// 构建鉴权对象
$auth = new Auth($this->config['access_key'], $this->config['secret_key']);
// 要上传的空间
$token = $auth->uploadToken($this->config['bucket']);
// 初始化 UploadManager 对象并进行文件的上传
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传
list(, $error) = $uploadMgr->putFile($token, $this->getSaveFileInfo()['file_path'], $realPath);
/* @var $error Error */
if ($error !== null) {
$this->error = $error->message();
return false;
}
return true;
}
/**
* 删除文件
* @param string $filePath
* @return bool
*/
public function delete(string $filePath): bool
{
// 构建鉴权对象
$auth = new Auth($this->config['access_key'], $this->config['secret_key']);
// 初始化 UploadManager 对象并进行文件的上传
$bucketMgr = new BucketManager($auth);
/* @var $error Error */
list(, $error) = $bucketMgr->delete($this->config['bucket'], $filePath);
if ($error !== null) {
$this->error = $error->message();
return false;
}
return true;
}
}
@@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\wechat;
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
@@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | 商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www..com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 科技 <admin@.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\wechat;
use app\common\library\helper;
use cores\exception\BaseException;
/**
* 小程序二维码
* Class Qrcode
* @package app\common\library\wechat
*/
class Qrcode extends WxBase
{
/**
* 获取小程序码
* API文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
* @param string $scene 场景值 (例如: uid:10001)
* @param string|null $page 页面地址
* @param int $width 二维码宽度
* @return mixed
* @throws BaseException
*/
public function getQrcode(string $scene, string $page = null, int $width = 430)
{
// 微信接口url
$accessToken = $this->getAccessToken();
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}";
// 构建请求
$data = compact('scene', 'width');
!is_null($page) && $data['page'] = $page;
// 返回结果
$result = $this->post($url, helper::jsonEncode($data));
// 记录日志
log_record([
'name' => '获取小程序码',
'params' => $data,
'result' => !strpos($result, 'errcode') ? 'true' : $result
]);
if (!strpos($result, 'errcode')) {
return $result;
}
$data = helper::jsonDecode($result);
$error = '小程序码获取失败 ' . $data['errmsg'];
if ($data['errcode'] == 41030) {
$error = '小程序页面不存在,请先发布上线后再生成';
}
throwError($error);
}
}
@@ -0,0 +1,65 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\wechat;
class WXBizDataCrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param string $appid string 小程序的appid
* @param string $sessionKey string 用户在小程序登录后获取的会话密钥
*/
public function __construct(string $appid, string $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param string $encryptedData 加密的用户数据
* @param string $iv 与用户数据一同返回的初始向量
* @param mixed $content 解密后的原文
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData(string $encryptedData, string $iv, &$content): int
{
if (strlen($this->sessionKey) != 24) {
return ErrorCode::$IllegalAesKey;
}
if (strlen($iv) != 24) {
return ErrorCode::$IllegalIv;
}
$aesKey = base64_decode($this->sessionKey);
$aesIV = base64_decode($iv);
$aesCipher = base64_decode($encryptedData);
$result = openssl_decrypt($aesCipher, 'AES-128-CBC', $aesKey, 1, $aesIV);
if (empty($result)) {
return ErrorCode::$IllegalBuffer;
}
$resultArr = json_decode($result, true);
if (empty($resultArr)) {
return ErrorCode::$IllegalBuffer;
}
if ($resultArr['watermark']['appid'] != $this->appid) {
return ErrorCode::$IllegalBuffer;
}
$content = $resultArr;
return ErrorCode::$OK;
}
}
@@ -0,0 +1,187 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\wechat;
use think\facade\Cache;
use cores\traits\ErrorTrait;
use app\common\library\helper;
use app\common\exception\BaseException;
/**
* 微信api基类
* Class wechat
* @package app\library
*/
class WxBase
{
use ErrorTrait;
protected $appId;
protected $appSecret;
/**
* 构造函数
* WxBase constructor.
* @param $appId
* @param $appSecret
*/
public function __construct($appId = null, $appSecret = null)
{
$this->setConfig($appId, $appSecret);
}
protected function setConfig($appId = null, $appSecret = null)
{
!empty($appId) && $this->appId = $appId;
!empty($appSecret) && $this->appSecret = $appSecret;
}
/**
* 获取access_token
* @return mixed
* @throws \cores\exception\BaseException
*/
protected function getAccessToken()
{
$cacheKey = $this->appId . '@access_token';
if (!Cache::get($cacheKey)) {
// 请求API获取 access_token
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
$result = $this->get($url);
$response = $this->jsonDecode($result);
if (array_key_exists('errcode', $response)) {
throwError("access_token获取失败,错误信息:{$result}");
}
// 记录日志
log_record([
'name' => '获取access_token',
'url' => $url,
'appId' => $this->appId,
'result' => $result
]);
// 写入缓存
Cache::set($cacheKey, $response['access_token'], 6000);
}
return Cache::get($cacheKey);
}
/**
* 模拟GET请求 HTTPS的页面
* @param string $url 请求地址
* @param array $data
* @return string $result
* @throws \cores\exception\BaseException
*/
protected function get(string $url, array $data = [])
{
// 处理query参数
if (!empty($data)) {
$url = $url . '?' . http_build_query($data);
}
$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_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
$result = curl_exec($curl);
if ($result === false) {
throwError(curl_error($curl));
}
curl_close($curl);
return $result;
}
/**
* 模拟POST请求
* @param string $url 请求地址
* @param mixed $data 请求数据
* @param false $useCert 是否引入微信支付证书
* @param array $sslCert 证书路径
* @return mixed|bool|string
* @throws \cores\exception\BaseException
*/
protected function post(string $url, $data = [], bool $useCert = false, array $sslCert = [])
{
$header = [
'Content-type: application/json;'
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
if ($useCert == true) {
// 设置证书:cert 与 key 分别属于两个.pem文件
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
}
$result = curl_exec($curl);
if ($result === false) {
throwError(curl_error($curl));
}
curl_close($curl);
return $result;
}
/**
* 模拟POST请求 [第二种方式, 用于兼容微信api]
* @param $url
* @param array $data
* @return mixed
* @throws \cores\exception\BaseException
*/
protected function post2($url, array $data = [])
{
$header = [
'Content-Type: application/x-www-form-urlencoded'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
$result = curl_exec($ch);
if ($result === false) {
throwError(curl_error($ch));
}
curl_close($ch);
return $result;
}
/**
* 数组转json
* @param $data
* @return string
*/
protected function jsonEncode($data): string
{
return helper::jsonEncode($data, JSON_UNESCAPED_UNICODE);
}
/**
* json转数组
* @param $json
* @return mixed
*/
protected function jsonDecode($json)
{
return helper::jsonDecode($json);
}
}
@@ -0,0 +1,408 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
namespace app\common\library\wechat;
use app\common\model\wxapp\Setting as WxappSettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\PayType as OrderPayTypeEnum;
use app\common\library\helper;
use cores\exception\BaseException;
/**
* 微信支付
* Class WxPay
* @package app\common\library\wechat
*/
class WxPay extends WxBase
{
// 微信支付配置
private $config;
// 当前商城ID
private $storeId;
// 订单模型
private $modelClass = [
OrderTypeEnum::ORDER => \app\api\service\order\PaySuccess::class,
OrderTypeEnum::RECHARGE => \app\api\service\recharge\PaySuccess::class,
];
/**
* 构造函数
* @param array $config
* @param int|null $storeId
*/
public function __construct(array $config = [], ?int $storeId = null)
{
parent::__construct();
$this->config = $config;
$this->storeId = $storeId;
if (!empty($this->config)) {
$this->setConfig($this->config['app_id'], $this->config['app_secret']);
}
}
/**
* 统一下单API
* @param $orderNo
* @param $openid
* @param $totalFee
* @param int $orderType 订单类型
* @return array
* @throws \cores\exception\BaseException
*/
public function unifiedorder($orderNo, $openid, $totalFee, int $orderType = OrderTypeEnum::ORDER): array
{
// 当前时间
$time = time();
// 生成随机字符串
$nonceStr = md5($time . $openid);
// API参数
$params = [
'appid' => $this->appId,
'attach' => helper::jsonEncode(['order_type' => $orderType]),
'body' => $orderNo,
'mch_id' => $this->config['mchid'],
'nonce_str' => $nonceStr,
'notify_url' => base_url() . 'notice.php', // 异步通知地址
'openid' => $openid,
'out_trade_no' => $orderNo,
'spbill_create_ip' => \request()->ip(),
'total_fee' => (int)helper::bcmul($totalFee, 100), // 价格:单位分
'trade_type' => 'JSAPI',
];
// 生成签名
$params['sign'] = $this->makeSign($params);
// 请求API
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$result = $this->post($url, $this->toXml($params));
$prepay = $this->fromXml($result);
// 请求失败
if ($prepay['return_code'] === 'FAIL') {
$errMsg = "微信支付api:{$prepay['return_msg']}";
throwError($errMsg, null, ['errorCode' => 'WECHAT_PAY', 'isCreated' => true]);
}
if ($prepay['result_code'] === 'FAIL') {
$errMsg = "微信支付api:{$prepay['err_code_des']}";
throwError($errMsg, null, ['errorCode' => 'WECHAT_PAY', 'isCreated' => true]);
}
// 生成 nonce_str 供前端使用
$paySign = $this->makePaySign($params['nonce_str'], $prepay['prepay_id'], $time);
return [
'prepay_id' => $prepay['prepay_id'],
'nonceStr' => $nonceStr,
'timeStamp' => (string)$time,
'paySign' => $paySign
];
}
/**
* 支付成功异步通知
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function notify()
{
if (!$xml = file_get_contents('php://input')) {
$this->returnCode(false, 'Not found DATA');
}
// 将服务器返回的XML数据转化为数组
$data = $this->fromXml($xml);
// 记录日志
log_record($xml);
log_record($data);
// 实例化订单模型
$model = $this->getOrderModel($data['out_trade_no'], $data['attach']);
// 订单信息
$order = $model->getOrderInfo();
empty($order) && $this->returnCode(false, '订单不存在');
// 小程序配置信息
$wxConfig = WxappSettingModel::getWxappConfig($order['store_id']);
// 设置支付秘钥
$this->config['apikey'] = $wxConfig['apikey'];
// 保存微信服务器返回的签名sign
$dataSign = $data['sign'];
// sign不参与签名算法
unset($data['sign']);
// 生成签名
$sign = $this->makeSign($data);
// 判断签名是否正确 判断支付状态
if (
($sign !== $dataSign)
|| ($data['return_code'] !== 'SUCCESS')
|| ($data['result_code'] !== 'SUCCESS')
) {
$this->returnCode(false, '签名失败');
}
// 订单支付成功业务处理
$status = $model->onPaySuccess(OrderPayTypeEnum::WECHAT, $data);
if ($status == false) {
$this->returnCode(false, $model->getError());
}
// 返回状态
$this->returnCode(true, 'OK');
}
/**
* 申请退款API
* @param string $transactionId 微信支付交易流水号
* @param string $totalFee 订单总金额
* @param string $refundFee 退款金额
* @return bool
* @throws BaseException
* @throws \cores\exception\BaseException
*/
public function refund(string $transactionId, string $totalFee, string $refundFee): bool
{
// 当前时间
$time = time();
// 生成随机字符串
$nonceStr = md5($time . $transactionId . $totalFee . $refundFee);
// API参数
$params = [
'appid' => $this->appId,
'mch_id' => $this->config['mchid'],
'nonce_str' => $nonceStr,
'transaction_id' => $transactionId,
'out_refund_no' => $time,
'total_fee' => (int)helper::bcmul($totalFee,100),
'refund_fee' => (int)helper::bcmul($refundFee,100),
];
// 生成签名
$params['sign'] = $this->makeSign($params);
// 请求API
$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
$result = $this->post($url, $this->toXml($params), true, $this->getCertPem());
// 请求失败
if (empty($result)) {
throwError('微信退款api请求失败');
}
// 格式化返回结果
$prepay = $this->fromXml($result);
// 记录日志
log_record(['name' => '微信退款API', [
'params' => $params,
'result' => $result,
'prepay' => $prepay
]]);
// 请求失败
if ($prepay['return_code'] === 'FAIL') {
throwError("return_msg: {$prepay['return_msg']}");
}
if ($prepay['result_code'] === 'FAIL') {
throwError("err_code_des: {$prepay['err_code_des']}");
}
return true;
}
/**
* 获取cert证书文件
* @return string[]
* @throws \cores\exception\BaseException
*/
private function getCertPem(): array
{
if (empty($this->config['cert_pem']) || empty($this->config['key_pem'])) {
throwError('请先到后台小程序设置填写微信支付证书文件');
}
// cert目录
$filePath = __DIR__ . "/cert/{$this->storeId}/";
return [
'certPem' => $filePath . 'cert.pem',
'keyPem' => $filePath . 'key.pem'
];
}
/**
* 实例化订单模型 (根据attach判断)
* @param $orderNo
* @param null $attach
* @return mixed
*/
private function getOrderModel($orderNo, $attach = null)
{
$attach = helper::jsonDecode($attach);
// 判断订单类型返回对应的订单模型
$model = $this->modelClass[$attach['order_type']];
return new $model($orderNo);
}
/**
* 返回状态给微信服务器
* @param boolean $returnCode
* @param string|null $msg
*/
private function returnCode(bool $returnCode = true, string $msg = null)
{
// 返回状态
$return = [
'return_code' => $returnCode ? 'SUCCESS' : 'FAIL',
'return_msg' => $msg ?: 'OK',
];
// 记录日志
log_record([
'name' => '返回微信支付状态',
'data' => $return
]);
die($this->toXml($return));
}
/**
* 生成paySign
* @param string $nonceStr
* @param string $prepayId
* @param int $timeStamp
* @return string
*/
private function makePaySign(string $nonceStr, string $prepayId, int $timeStamp): string
{
$data = [
'appId' => $this->appId,
'nonceStr' => $nonceStr,
'package' => 'prepay_id=' . $prepayId,
'signType' => 'MD5',
'timeStamp' => $timeStamp,
];
// 签名步骤一:按字典序排序参数
ksort($data);
$string = $this->toUrlParams($data);
// 签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->config['apikey'];
// 签名步骤三:MD5加密
$string = md5($string);
// 签名步骤四:所有字符转为大写
return strtoupper($string);
}
/**
* 将xml转为array
* @param string $xml
* @return mixed
*/
private function fromXml(string $xml)
{
// 禁止引用外部xml实体
libxml_disable_entity_loader(true);
return helper::jsonDecode(helper::jsonEncode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)));
}
/**
* 生成签名
* @param array $values
* @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
private function makeSign(array $values): string
{
//签名步骤一:按字典序排序参数
ksort($values);
$string = $this->toUrlParams($values);
//签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->config['apikey'];
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
return strtoupper($string);
}
/**
* 格式化参数格式化成url参数
* @param array $values
* @return string
*/
private function toUrlParams(array $values): string
{
$buff = '';
foreach ($values as $k => $v) {
if ($k != 'sign' && $v != '' && !is_array($v)) {
$buff .= $k . '=' . $v . '&';
}
}
return trim($buff, '&');
}
/**
* 输出xml字符
* @param array $values
* @return bool|string
*/
private function toXml(array $values)
{
if (!is_array($values)
|| count($values) <= 0
) {
return false;
}
$xml = "<xml>";
foreach ($values as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* 发货
* API文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html
* @param string $transaction_id 微信支付交易id
* @param string $desc 商品描述
* @param string $openid 用户openid
* @return mixed
* @throws BaseException
*/
public function uploadShipping(string $transaction_id, string $desc, string $openid)
{
// 微信接口url
$accessToken = $this->getAccessToken();
$url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token={$accessToken}";
$dt = new \DateTime('now', new \DateTimeZone('Asia/Shanghai'));
$upload_time = $dt->format('Y-m-d\TH:i:s.vP');
// 构建请求
$data = [
'order_key' => [
'order_number_type' => 2,
'transaction_id' => $transaction_id,
],
'logistics_type' => 3,
'delivery_mode' => 1,
'shipping_list' => [
[
'item_desc' => $desc,
]
],
'upload_time' => $upload_time,
'payer' => [
'openid' => $openid
]
];
// 返回结果
$result = $this->post($url, helper::jsonEncode($data));
// 记录日志
log_record([
'name' => '微信支付自动发货',
'params' => $data,
'result' => !strpos($result, 'errcode') ? 'true' : $result
]);
$data = helper::jsonDecode($result);
if ($data['errcode'] == 0) {
return $result;
}
$error = '微信支付自动发货 ' . $data['errmsg'];
/*if ($data['errcode'] == 41030) {
$error = '小程序页面不存在,请先发布上线后再生成';
}*/
// throwError($error);
}
}
@@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\library\wechat;
use app\common\library\helper;
/**
* 微信小程序用户管理类
* Class WxUser
* @package app\common\library\wechat
*/
class WxUser extends WxBase
{
/**
* 获取session_key
* @param string $code
* @return array|mixed
*/
public function jscode2session(string $code)
{
/**
* code 换取 session_key
* 这是一个 HTTPS 接口,开发者服务器使用登录凭证 code 获取 session_key 和 openid。
* 其中 session_key 是对用户数据进行加密签名的密钥。为了自身应用安全,session_key 不应该在网络上传输。
*/
$url = 'https://api.weixin.qq.com/sns/jscode2session';
$result = helper::jsonDecode($this->get($url, [
'appid' => $this->appId,
'secret' => $this->appSecret,
'grant_type' => 'authorization_code',
'js_code' => $code
]));
if (isset($result['errcode'])) {
$this->error = $result['errmsg'];
return false;
}
return $result;
}
}
@@ -0,0 +1,2 @@
*
!.gitignore
+30
View File
@@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace app\common\lock;
use Predis\Client;
/**
* 订单服务类
* Class RedisLock
* @package app\common\lock
*/
class RedisLock
{
protected $redis;
protected $lockKey;
protected $timeout;
public function __construct($lockKey, $timeout = 30) {
$this->redis = new Client(config('redis'));
$this->lockKey = $lockKey;
$this->timeout = $timeout;
}
public function acquireLock() {
$result = $this->redis->set($this->lockKey, 'locked', 'NX', 'EX', $this->timeout);
return $result == 'OK';
}
public function releaseLock() {
$this->redis->del($this->lockKey);
}
}
+72
View File
@@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use think\model\relation\HasOne;
use think\model\relation\HasMany;
use think\model\relation\BelongsTo;
/**
* 公司用户池模型类
* Class User
* @package app\common\model
*/
class Account extends BaseModel
{
// 定义表名
protected $name = 'account';
// 定义主键
protected $pk = 'account_id';
/**
* 公司表
* @return \think\model\relation\BelongsTo
*/
public function company(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Company");
}
/**
* 获取用户信息
* @param $where
* @param array $with
* @return static|array|false|null
*/
public static function detail($where, array $with = [])
{
$filter = ['is_delete' => 0];
if (is_array($where)) {
$filter = array_merge($filter, $where);
} else {
$filter['account_id'] = (int)$where;
}
return static::get($filter, $with);
}
/**
* 指定的手机号是否已存在
* @param string $mobile
* @return bool
*/
public static function checkExistByMobile(string $mobile): bool
{
$model = new static;
return (bool)$model->where('mobile', '=', $mobile)
->where('is_delete', '=', 0)
->value($model->getPk());
}
}
+84
View File
@@ -0,0 +1,84 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 文章模型
* Class Article
* @package app\common\model
*/
class Article extends BaseModel
{
// 定义表名
protected $name = 'article';
// 定义主键
protected $pk = 'article_id';
// 追加字段
protected $append = ['show_views'];
/**
* 关联文章封面图
* @return \think\model\relation\HasOne
*/
public function image()
{
return $this->hasOne('UploadFile', 'file_id', 'image_id')
->bind(['image_url' => 'preview_url']);
}
/**
* 关联文章分类表
* @return \think\model\relation\BelongsTo
*/
public function category()
{
$module = self::getCalledModule();
return $this->BelongsTo("app\\{$module}\\model\\article\\Category", 'category_id');
}
/**
* 文章详情:HTML实体转换回普通字符
* @param $value
* @return string
*/
public function getContentAttr($value)
{
return htmlspecialchars_decode($value);
}
/**
* 展示的浏览次数
* @param $value
* @param $data
* @return mixed
*/
public function getShowViewsAttr($value, $data)
{
return $data['virtual_views'] + $data['actual_views'];
}
/**
* 文章详情
* @param int $articleId
* @param array $with
* @return array|null|static
*/
public static function detail(int $articleId, array $with = [])
{
return self::get($articleId, $with);
}
}
+84
View File
@@ -0,0 +1,84 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 银行账户模型
* Class Bank
* @package app\common\model
*/
class Bank extends BaseModel
{
protected $name = 'bank';
/**
* 关联管理员分类表
* @return \think\model\relation\BelongsTo
*/
public function admin()
{
return $this->belongsTo('app\common\model\store\User','store_user_id','store_user_id');
}
/**
* 获取银行账户列表
* @param int $status
* @param string $search_name
* @param string $sortType
* @param bool $sortPrice
* @param int $listRows
* @param array $power
* @return \think\Paginator
* @throws \think\exception\DbException
*/
public function getList($status = null, $search_name = '', $sortType = 'all', $sortPrice = false, $listRows = 15, $power = [])
{
// 筛选条件
$filter = [];
// 商品表名称
$status > 0 && $this->where('status', '=', $status);
!empty($power) && $this->where('store_user_id', 'in', $power);
!empty($search_name) && $this->where('name', 'like', "%$search_name%");
$r = $this->with(['admin'])
->order(['create_time' => 'desc'])
->paginate(15, false, [
'query' => \request()->request()
]);
return $r;
}
/**
* 关联供货商图片表
* @return \think\model\relation\HasMany
*/
public function image()
{
return $this->hasMany('SupplierImage')->order(['id' => 'asc']);
}
/**
* 银行账户详情
* @param $bank_id
* @return null|static
* @throws \think\exception\DbException
*/
public static function detail($bank_id)
{
return self::get($bank_id);
}
/*public static function detail($supplier_id)
{
$model = new static;
return $model->with([
'image.file'
])->where('supplier_id', '=', $supplier_id)->find();
}*/
/**
* 获取全部
* @return mixed
*/
public static function getAll()
{
$model = new static;
return $model->order(['bank_id' => 'asc'])->select();
}
}
+100
View File
@@ -0,0 +1,100 @@
<?php
namespace app\common\model;
use think\Model;
use think\Request;
use think\Session;
/**
* 模型基类
* Class BaseModel
* @package app\common\model
*/
class BaseModel extends Model
{
public static $wxapp_id;
public static $base_url;
/**
* 模型基类初始化
*/
public static function init()
{
parent::init();
// 获取当前域名
self::$base_url = base_url();
// 后期静态绑定wxapp_id
self::bindWxappId();
}
/**
* 获取当前调用的模块名称
* 例如:admin, api, store, task
* @return string|bool
*/
protected static function getCalledModule()
{
if (preg_match('/app\\\(\w+)/', get_called_class(), $class)) {
return $class[1];
}
return false;
}
/**
* 后期静态绑定类名称
* 用于定义全局查询范围的wxapp_id条件
* 子类调用方式:
* 非静态方法: self::$wxapp_id
* 静态方法中: $self = new static(); $self::$wxapp_id
*/
private static function bindWxappId()
{
if ($module = self::getCalledModule()) {
$callfunc = 'set' . ucfirst($module) . 'WxappId';
method_exists(new self, $callfunc) && self::$callfunc();
}
}
/**
* 设置wxapp_id (store模块)
*/
protected static function setStoreWxappId()
{
$session = Session::get('yoshop_store');
self::$wxapp_id = $session['wxapp']['wxapp_id'];
}
/**
* 设置wxapp_id (api模块)
*/
protected static function setApiWxappId()
{
$request = Request::instance();
self::$wxapp_id = $request->param('wxapp_id');
}
/**
* 获取当前域名
* @return string
*/
protected static function baseUrl()
{
$request = Request::instance();
$host = $request->scheme() . '://' . $request->host();
$dirname = dirname($request->baseUrl());
return empty($dirname) ? $host : $host . $dirname . '/';
}
/**
* 定义全局的查询范围
* @param \think\db\Query $query
*/
protected function base($query)
{
if (self::$wxapp_id > 0) {
$query->where($query->getTable() . '.wxapp_id', self::$wxapp_id);
}
}
}
+93
View File
@@ -0,0 +1,93 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use app\store\model\store\User;
use cores\BaseModel;
/**
* 充值卡模型
* Class Card
* @package app\common\model
*/
class Card extends BaseModel
{
protected $name = 'card';
// 定义主键
protected $pk = 'card_id';
/**
* 关联用户表
* @return \think\model\relation\BelongsTo
*/
public function user()
{
return $this->belongsTo('app\common\model\User','user_id','user_id');
}
/**
* 获取器:图片地址
* @param $value
* @return string
*/
public function getFilePathAttr($value): string
{
return $value; // $value ? request()->domain().'/'.$value : ''
}
/**
* 充值卡详情
* @param $where
* @param array $with
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($where, $with = [])
{
!is_array($where) && $where = ['card_id' => (int)$where];
return static::get($where, $with);
}
/**
* 获取全部
* @param array $user
* @return mixed
*/
public static function getAll($user = [])
{
$model = new static;
if(isset($user['is_super']) && $user['is_super'] == 0) {
$users = User::getScope($user);
$model->where(function ($query) use($users) {
$query->where('store_user_id', 'in', $users);
});
return $model->order(['card_id' => 'asc'])->where(function ($query) use($users) {
$query->where('store_user_id', 'in', $users);
})->select();
}else{
return $model->order(['card_id' => 'asc'])->select();
}
}
/**
* 获取指定
* @param array $filter
* @return mixed
*/
public static function getQuery($filter): array
{
$model = new static;
return $model->where($filter)->order(['card_id' => 'asc'])->select()->toArray();
}
/**
* 切换使用状态
* @param $is_used
* @return false|int
*/
public function changeStatus($is_used)
{
return $this->save(['is_used' => $is_used]);
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 模型类:购物车
* Class Cart
* @package app\common\model
*/
class Cart extends BaseModel
{
// 定义表名
protected $name = 'cart';
// 定义主键
protected $pk = 'id';
/**
* 详情记录
* @param int $userId 用户ID
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku唯一标识
* @return array|static|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function detail(int $userId, int $goodsId, string $goodsSkuId)
{
return (new static)->where('user_id', '=', $userId)
->where('goods_id', '=', $goodsId)
->where('goods_sku_id', '=', $goodsSkuId)
->where('is_delete', '=', 0)
->find();
}
}
+120
View File
@@ -0,0 +1,120 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品分类模型
* Class Category
* @package app\common\model
*/
class Category extends BaseModel
{
// 定义表名
protected $name = 'category';
// 定义主键
protected $pk = 'category_id';
/**
* 分类图片
* @return \think\model\relation\HasOne
*/
public function image()
{
return $this->hasOne('UploadFile', 'file_id', 'image_id');
}
/**
* 分类详情
* @param int|array $where
* @param array $with
* @return array|null|static
*/
public static function detail($where, array $with = [])
{
return static::get($where, $with);
}
/**
* 获取列表记录
* @param array $param
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getList(array $param = [])
{
$list = $this->getAll($param);
return $this->getTreeData($list);
}
/**
* 获取所有记录
* @param array $param
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
protected function getAll(array $param = [])
{
// 默认查询参数
$params = $this->setQueryDefaultValue($param, [
'status' => -1 // 状态(1显示 0隐藏 -1全部)
]);
// 实例化新查询对象
$query = $this->getNewQuery();
// 设置检索条件
$filter = [];
$params['status'] > -1 && $filter[] = ['status', '=', $params['status']];
// !empty($params['province']) && $filter[] = ['province', 'like', "%{$params['province']}%"];
if(!empty($params['province'])){
$province = $params['province'];
$query->where(function ($que) use ($province) {
$que->whereOr([
['province', 'like', "%{$province}%"],
['province', '=','']
]);
});
}
// 查询列表数据
return $query->with(['image'])
->where($filter)
->order(['sort', 'create_time'])
->select();
}
/**
* 获取树状列表
* @param $list
* @param int $parentId
* @return array
*/
private function getTreeData($list, int $parentId = 0)
{
$data = [];
foreach ($list as $key => $item) {
if ($item['parent_id'] == $parentId) {
$children = $this->getTreeData($list, $item['category_id']);
!empty($children) && $item['children'] = $children;
$data[] = $item;
unset($list[$key]);
}
}
return $data;
}
}
+96
View File
@@ -0,0 +1,96 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use think\model\relation\BelongsTo;
/**
* 结账模型
* Class Checkout
* @package app\common\model
*/
class Checkout extends BaseModel
{
protected $name = 'checkout';
// 定义主键
protected $pk = 'checkout_id';
/**
* 获取结账人信息
* @return BelongsTo
*/
public function user(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\store\\User", 'store_user_id');
}
/**
* 结账详情
* @param $where
* @param array $with
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($where, $with = [])
{
!is_array($where) && $where = ['checkout_id' => (int)$where];
return static::get($where, $with);
}
/**
* 获取全部
* @return mixed
*/
public static function getAll()
{
$model = new static;
return $model->order(['checkout_id' => 'asc'])->select();
}
/**
* 开始时间
* @param $value
* @return false|string
*/
public function getStartTimeAttr($value)
{
return format_time($value);
}
/**
* 结束时间
* @param $value
* @return false|string
*/
public function getEndTimeAttr($value)
{
return format_time($value);
}
/**
* 获取指定
* @param array $filter
* @return mixed
*/
public static function getQuery($filter): array
{
$model = new static;
return $model->where($filter)->order(['checkout_id' => 'asc'])->select()->toArray();
}
/**
* 获取最新一条记录
* @param array $filter
* @return array|null
*/
public static function getSingle(array $filter = []): ?array
{
$model = new static;
$data = $model->where($filter)->order(['checkout_id' => 'desc'])->find();
return $data ? $data->toArray() : null;
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 产码模型
* Class User
* @package app\common\model
*/
class Code extends BaseModel
{
protected $name = 'code';
// 定义主键
protected $pk = 'code_id';
/**
* 支付码详情
* @param $where
* @param array $with
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($where, $with = [])
{
!is_array($where) && $where = ['code_id' => (int)$where];
return static::get($where, $with);
}
/**
* 关联父级用户
* @return \think\model\relation\BelongsTo
*/
public function shop()
{
return $this->belongsTo('Shop');
}
/**
* 关联父级用户
* @return \think\model\relation\BelongsTo
*/
public function user()
{
return $this->belongsTo('app\common\model\store\User','store_user_id','store_user_id');
}
/**
* 获取全部
* @return mixed
*/
public static function getAll()
{
$model = new static;
return $model->order(['shop_id' => 'asc'])->select();
}
/**
* 获取产码数量
* @param array $filter
* @return int|string
*/
public function getCodeTotal($filter=[])
{
return $this->field('code_id')
->where($filter)
->group('code_id')
->count();
}
}
+94
View File
@@ -0,0 +1,94 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品评价模型
* Class Comment
* @package app\common\model
*/
class Comment extends BaseModel
{
// 定义表名
protected $name = 'comment';
// 定义主键
protected $pk = 'comment_id';
/**
* 所属订单
* @return \think\model\relation\BelongsTo
*/
public function orderData()
{
return $this->belongsTo('Order');
}
/**
* 订单商品
* @return \think\model\relation\BelongsTo
*/
public function orderGoods()
{
return $this->belongsTo('OrderGoods')
->field(['order_goods_id', 'goods_id', 'goods_name', 'image_id', 'goods_props', 'order_id']);
}
/**
* 关联用户表
* @return \think\model\relation\BelongsTo
*/
public function user()
{
return $this->belongsTo('User')->field(['user_id', 'nick_name', 'avatar_id']);
}
/**
* 关联评价图片表
* @return \think\model\relation\HasMany
*/
public function images()
{
return $this->hasMany('CommentImage')->order(['id']);
}
/**
* 详情记录
* @param int $commentId
* @param array $with
* @return static|array|null
*/
public static function detail(int $commentId, array $with = [])
{
return static::get($commentId, $with);
}
/**
* 添加评论图片
* @param array $images
* @return array|false
*/
protected function addCommentImages(array $images)
{
$data = array_map(function ($imageId) {
return [
'image_id' => $imageId,
'store_id' => self::$storeId
];
}, $images);
return $this->image()->saveAll($data) !== false;
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品评价图片模型
* Class CommentImage
* @package app\common\model
*/
class CommentImage extends BaseModel
{
// 定义表名
protected $name = 'comment_image';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
/**
* 关联文件库
* @return \think\model\relation\BelongsTo
*/
public function file()
{
return $this->belongsTo('UploadFile', 'image_id', 'file_id');
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use app\store\model\store\User;
use cores\BaseModel;
/**
* 商户模型
* Class Company
* @package app\common\model
*/
class Company extends BaseModel
{
protected $name = 'company';
// 定义主键
protected $pk = 'company_id';
/**
* 公司详情
* @param $where
* @param array $with
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($where, $with = [])
{
!is_array($where) && $where = ['company_id' => (int)$where];
return static::get($where, $with);
}
/**
* 获取全部
* @param array $user
* @return mixed
*/
public static function getAll($user = [])
{
$model = new static;
if(isset($user['is_super']) && $user['is_super'] == 0) {
$users = User::getScope($user);
$model->where(function ($query) use($users) {
$query->where('store_user_id', 'in', $users);
});
return $model->order(['company_id' => 'asc'])->where(function ($query) use($users) {
$query->where('store_user_id', 'in', $users);
})->select();
}else{
return $model->order(['company_id' => 'asc'])->select();
}
}
/**
* 获取指定
* @param array $filter
* @return mixed
*/
public static function getQuery($filter): array
{
$model = new static;
return $model->where($filter)->order(['company_id' => 'asc'])->select()->toArray();
}
/**
* 累积公司可用余额
* @param int $companyId
* @param float $money
* @return mixed
*/
public static function setIncBalance(int $companyId, float $money)
{
return (new static)->setInc($companyId, 'balance', $money);
}
/**
* 消减公司可用余额
* @param int $companyId
* @param float $money
* @return mixed
*/
public static function setDecBalance(int $companyId, float $money)
{
return (new static)->setDec([['company_id', '=', $companyId]], 'balance', $money);
}
/**
* 切换状态
* @param $status
* @return false|int
*/
public function changeStatus($status)
{
if($bool = $this->save(['status' => $status])){
$bool = true;
}
return $bool;
}
}
+159
View File
@@ -0,0 +1,159 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\helper;
/**
* 优惠券模型
* Class Coupon
* @package app\common\model
*/
class Coupon extends BaseModel
{
// 定义表名
protected $name = 'coupon';
// 定义主键
protected $pk = 'coupon_id';
/**
* 追加字段
* @var array
*/
protected $append = ['state'];
/**
* 优惠券状态 (是否可领取)
* @param $value
* @param array $data
* @return array
*/
public function getStateAttr($value, array $data): array
{
if (isset($data['is_receive']) && $data['is_receive']) {
return ['text' => '已领取', 'value' => 0];
}
if ($data['total_num'] > -1 && $data['receive_num'] >= $data['total_num']) {
return ['text' => '已抢光', 'value' => 0];
}
if ($data['expire_type'] == 20 && ($data['end_time'] + 86400) < time()) {
return ['text' => '已过期', 'value' => 0];
}
return ['text' => '正常', 'value' => 1];
}
/**
* 获取器:格式化折扣率
* @param $value
* @return float|int
*/
public function getDiscountAttr($value)
{
return $value / 10;
}
/**
* 获取器:开始时间
* @param $value
* @return string
*/
public function getStartTimeAttr($value): ?string
{
return $value ? date('Y/m/d', $value) : null;
}
/**
* 获取器:结束时间
* @param $value
* @return string
*/
public function getEndTimeAttr($value): ?string
{
return $value ? date('Y/m/d', $value) : null;
}
/**
* 获取器:适用范围配置
* @param $value
* @return mixed
*/
public function getApplyRangeConfigAttr($value)
{
return $value ? helper::jsonDecode($value) : [];
}
/**
* 修改器:格式化折扣率
* @param $value
* @return float|int
*/
public function setDiscountAttr($value)
{
return $value * 10;
}
/**
* 修改器:适用范围配置
* @param $array
* @return mixed
*/
public function setApplyRangeConfigAttr($array)
{
return helper::jsonEncode($array);
}
/**
* 优惠券详情
* @param int $couponId 优惠券ID
* @return static|null
*/
public static function detail(int $couponId): ?Coupon
{
return self::get($couponId);
}
/**
* 验证优惠券状态是否可领取
* @param $couponInfo
* @return bool
*/
public function checkReceive($couponInfo): bool
{
if (empty($couponInfo)) {
$this->error = '当前优惠券不存在';
return false;
}
if ($couponInfo['total_num'] > -1 && $couponInfo['receive_num'] >= $couponInfo['total_num']) {
$this->error = '优惠券已发完';
return false;
}
if ($couponInfo['expire_type'] == 20 && ($couponInfo->getData('end_time') + 86400) < time()) {
$this->error = '优惠券已过期';
return false;
}
return true;
}
/**
* 累计优惠券已领取的数量
* @param int $couponId
* @return mixed
*/
public static function setIncReceiveNum(int $couponId)
{
return (new static)->setInc($couponId, 'receive_num', 1);
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 物流公司模型
* Class Express
* @package app\common\model
*/
class Deduct extends BaseModel
{
protected $name = 'deduct';
/**
* 获取全部
* @return mixed
*/
public static function getAll()
{
$model = new static;
return $model->order(['create_time' => 'asc'])->select();
}
/**
* 获取列表
* @return \think\Paginator
* @throws \think\exception\DbException
*/
public function getList()
{
return $this->order(['create_time' => 'asc'])
->paginate(15, false, [
'query' => Request::instance()->request()
]);
}
/**
* 扣减记录详情
* @param $deduct_id
* @return null|static
* @throws \think\exception\DbException
*/
public static function detail($deduct_id)
{
return self::get($deduct_id);
}
/**
* 获取抵扣总金额
* @param array $filter
* @return int|string
*/
public function getDeductTotalMoneyCustom($filter = [])
{
return $this->where($filter)
->sum('money');
}
}
+66
View File
@@ -0,0 +1,66 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 配送模板模型
* Class Delivery
* @package app\common\model
*/
class Delivery extends BaseModel
{
// 定义表名
protected $name = 'delivery';
// 定义主键
protected $pk = 'delivery_id';
/**
* 关联配送模板区域及运费
* @return \think\model\relation\HasMany
*/
public function rule()
{
return $this->hasMany('DeliveryRule');
}
/**
* 运费模板详情
* @param int $deliveryId
* @param array $with
* @return null|static
*/
public static function detail(int $deliveryId, array $with = [])
{
return self::get($deliveryId, ['rule']);
}
/**
* 获取列表(根据模板id集)
* @param array $deliveryIds
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListByIds(array $deliveryIds)
{
return $this->with(['rule'])
->where('delivery_id', 'in', $deliveryIds)
->order(['sort', $this->getPk()])
->select();
}
}
@@ -0,0 +1,73 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\helper;
/**
* 配送模板区域及运费模型
* Class DeliveryRule
* @package app\store\model
*/
class DeliveryRule extends BaseModel
{
// 定义表名
protected $name = 'delivery_rule';
// 定义主键
protected $pk = 'rule_id';
protected $updateTime = false;
/**
* 获取器:可配送区域转为数组格式
* @param $value
* @return array
*/
public function getRegionAttr(string $value)
{
return helper::jsonDecode($value);
}
/**
* 修改器:可配送区域转为json格式
* @param array $value
* @return string
*/
public function setRegionAttr(array $value)
{
return helper::jsonEncode($value);
}
/**
* 获取器:可配送区域(文字展示)转为数组格式
* @param $value
* @return array
*/
public function getRegionTextAttr(string $value)
{
return helper::jsonDecode($value);
}
/**
* 修改器:可配送区域转(文字展示)为json格式
* @param array $value
* @return string
*/
public function setRegionTextAttr(array $value)
{
return helper::jsonEncode($value);
}
}
+136
View File
@@ -0,0 +1,136 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\express\Kuaidi100;
use app\common\model\store\Setting as SettingModel;
use app\common\enum\Setting as SettingEnum;
/**
* 物流公司模型
* Class Express
* @package app\common\model
*/
class Express extends BaseModel
{
// 定义表名
protected $name = 'express';
// 定义主键
protected $pk = 'express_id';
/**
* 获取全部记录
* @param array $param
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getAll($param = [])
{
// 检索查询条件
$filter = $this->getFilter($param);
// 查询列表数据
return $this->where($filter)->order(['sort', $this->getPk()])->select();
}
/**
* 获取列表
* @param array $param
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList($param = [])
{
// 检索查询调价你
$filter = $this->getFilter($param);
// 查询列表数据
return $this->where($filter)->order(['sort', 'express_id'])->paginate(15);
}
/**
* 检索查询条件
* @param array $param
* @return array
*/
private function getFilter($param = [])
{
// 默认查询条件
$params = $this->setQueryDefaultValue($param, ['search' => '']);
// 检索查询条件
$filter = [];
!empty($params['search']) && $filter[] = ['express_name', 'like', "%{$params['search']}%"];
return $filter;
}
/**
* 物流公司详情
* @param int $expressId
* @return null|static
*/
public static function detail(int $expressId)
{
return self::get($expressId);
}
/**
* 获取物流动态信息
* @param string $expressName
* @param string $expressCode
* @param string $expressNo
* @return false|string[]
* @throws \app\common\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function dynamic(string $expressName, string $expressCode, string $expressNo)
{
$data = [
'express_name' => $expressName,
'express_no' => $expressNo
];
// 获取快递100配置项
$config = $this->getKuaidi100Config();
// 实例化快递100类
$Kuaidi100 = new Kuaidi100($config);
// 请求查询接口
$data['list'] = $Kuaidi100->query($expressCode, $expressNo);
if ($data['list'] === false) {
$this->error = $Kuaidi100->getError();
return false;
}
return $data;
}
/**
* 获取快递100配置项
* @return mixed
* @throws \app\common\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getKuaidi100Config()
{
// 实例化快递100类
$config = SettingModel::getItem(SettingEnum::DELIVERY);
if (empty($config['kuaidi100']['customer']) || empty($config['kuaidi100']['key'])) {
throwError('请先到后台-设置-配送方式 补充物流查询API配置');
}
return $config['kuaidi100'];
}
}
+392
View File
@@ -0,0 +1,392 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use think\Paginator;
use think\model\Collection;
use think\model\relation\HasOne;
use cores\BaseModel;
use app\store\model\GoodsCategoryRel as GoodsCategoryRelModel;
use app\common\enum\goods\Status as GoodsStatusEnum;
use app\common\library\helper;
/**
* 商品模型
* Class Goods
* @package app\common\model
*/
class Goods extends BaseModel
{
// 定义表名
protected $name = 'goods';
// 定义主键
protected $pk = 'goods_id';
// 追加字段
protected $append = ['goods_sales'];
/**
* 关联模型:主图视频文件
* @return HasOne
*/
public function video(): HasOne
{
return $this->hasOne('UploadFile', 'file_id', 'video_id');
}
/**
* 关联模型:主图视频封面图片文件
* @return HasOne
*/
public function videoCover(): HasOne
{
return $this->hasOne('UploadFile', 'file_id', 'video_cover_id');
}
/**
* 计算显示销量 (初始销量 + 实际销量)
* @param $value
* @param $data
* @return mixed
*/
public function getGoodsSalesAttr($value, $data)
{
return $data['sales_initial'] + $data['sales_actual'];
}
/**
* 商品详情:HTML实体转换回普通字符
* @param $value
* @return string
*/
public function getContentAttr($value)
{
return htmlspecialchars_decode($value);
}
/**
* 获取器:单独设置折扣的配置
* @param $json
* @return mixed
*/
public function getAloneGradeEquityAttr($json)
{
return helper::jsonDecode($json);
}
/**
* 修改器:单独设置折扣的配置
* @param $data
* @return mixed
*/
public function setAloneGradeEquityAttr($data)
{
return helper::jsonEncode($data);
}
/**
* 获取器:优惠券关联
* @param $json
* @return mixed
*/
public function getCouponIdAttr($json)
{
return helper::jsonDecode($json);
}
/**
* 关联商品规格表
* @return \think\model\relation\HasMany
*/
public function skuList()
{
return $this->hasMany('GoodsSku')->order(['id' => 'asc']);
}
/**
* 关联商品规格关系表
* @return \think\model\relation\HasMany
*/
public function specRel()
{
return $this->hasMany('GoodsSpecRel');
}
/**
* 关联商品图片表
* @return \think\model\relation\HasMany
*/
public function images()
{
return $this->hasMany('GoodsImage')->order(['id']);
}
/**
* 关联运费模板表
* @return \think\model\relation\BelongsTo
*/
public function delivery()
{
return $this->BelongsTo('Delivery');
}
/**
* 关联订单评价表
* @return \think\model\relation\HasMany
*/
public function commentData()
{
return $this->hasMany('Comment');
}
/**
* 获取商品列表
* @param array $param 查询条件
* @param int $listRows 分页数量
* @return mixed
* @throws \think\db\exception\DbException
*/
public function getList(array $param = [], int $listRows = 15)
{
// 筛选条件
$query = $this->getQueryFilter($param);
// 设置显示的销量 goods_sales
$query->field(['(sales_initial + sales_actual) as goods_sales']);
// 排序条件
$sort = $this->setQuerySort($param);
// 执行查询
$list = $query->with(['images.file'])
->alias($this->name)
->field($this->getAliasFields($this->name, ['content']))
->where('is_delete', '=', 0)
->order($sort)
->paginate($listRows);
// 整理列表数据并返回
return $this->setGoodsListData($list);
}
/**
* 检索排序条件
* @param array $param
* @return array|string[]
*/
private function setQuerySort(array $param = [])
{
$params = $this->setQueryDefaultValue($param, [
'sortType' => 'all', // 排序类型
'sortPrice' => false, // 价格排序 (true高到低 false低到高)
]);
// 排序规则
$sort = [];
if ($params['sortType'] === 'all') {
$sort = ['sort' => 'asc'];
} elseif ($params['sortType'] === 'sales') {
$sort = ['goods_sales' => 'desc'];
} elseif ($params['sortType'] === 'price') {
$sort = $params['sortPrice'] ? ['goods_price_max' => 'desc'] : ['goods_price_min' => 'asc'];
}
return array_merge($sort, [$this->getPk() => 'desc']);
}
/**
* 检索查询条件
* @param array $param
* @return \think\db\BaseQuery
*/
private function getQueryFilter(array $param)
{
// 商品列表获取条件
$params = $this->setQueryDefaultValue($param, [
'listType' => 'all', // 列表模式 (全部:all 出售中:on_sale 已下架:off_sale 已售罄:sold_out)
'categoryId' => null, // 分类ID集
'goodsName' => null, // 商品名称
'goodsNo' => null, // 商品编码
'status' => 0, // 商品状态(0全部 10上架 20下架)
'province' => '', // 省份
'location' => '', // 是否通过地图过来
]);
// 实例化新查询对象
$query = $this->getNewQuery();
// 筛选条件
$filter = [];
// 列表模式
if ($params['listType'] === 'on_sale') {
$filter[] = ['status', '=', GoodsStatusEnum::ON_SALE]; // 出售中
} elseif ($params['listType'] === 'off_sale') {
$filter[] = ['status', '=', GoodsStatusEnum::OFF_SALE]; // 已下架
} elseif ($params['listType'] === 'sold_out') {
$filter[] = ['stock_total', '=', 0]; // 已售罄
}
// 商品状态
$params['status'] > 0 && $filter[] = ['status', '=', (int)$params['status']];
// 商品分类
if ($params['categoryId'] > 0) {
// 关联商品与分类关系记录表
$GoodsCategoryRelName = (new GoodsCategoryRelModel)->getName();
$query->join($GoodsCategoryRelName, "{$GoodsCategoryRelName}.goods_id = {$this->name}.goods_id");
// 设置分类ID条件
$query->where('goods_category_rel.category_id', '=', (int)$params['categoryId']);
}elseif(!empty($params['province']) && $params['location'] != 1){
// 前端请求,没有分类则不展示商品
// 关联商品与分类关系记录表
$GoodsCategoryRelName = (new GoodsCategoryRelModel)->getName();
$query->join($GoodsCategoryRelName, "{$GoodsCategoryRelName}.goods_id = {$this->name}.goods_id");
// 设置分类ID条件
$query->where('goods_category_rel.category_id', '=', -1);
}
// 商品名称
!empty($params['goodsName']) && $filter[] = ['goods_name', 'like', "%{$params['goodsName']}%"];
// 商品编码
!empty($params['goodsNo']) && $filter[] = ['goods_no', 'like', "%{$params['goodsNo']}%"];
// 省份
// !empty($params['province']) && $params['location'] == '1' && $filter[] = ['province', 'like', "%{$params['province']}%"];
if(!empty($params['province']) && $params['location'] == '1'){
$province = $params['province'];
$query->where(function ($que) use ($province) {
$que->whereOr([
['province', 'like', "%{$province}%"],
['province', '=','']
]);
});
}
// 实例化新查询对象
return $query->where($filter);
}
/**
* 设置商品展示的数据
* @param Collection|Paginator $list 商品列表
* @param callable|null $callback 回调函数
* @return mixed
*/
protected function setGoodsListData($list, callable $callback = null)
{
if ($list->isEmpty()) return $list;
// 遍历商品列表整理数据
foreach ($list as &$goods) {
$goods = $this->setGoodsData($goods, $callback);
}
return $list;
}
/**
* 整理商品数据
* @param Collection|static $goodsInfo
* @param callable|null $callback
* @return mixed
*/
protected function setGoodsData($goodsInfo, callable $callback = null)
{
// 商品图片列表
$goodsInfo['goods_images'] = helper::getArrayColumn($goodsInfo['images'], 'file');
// 商品主图
$goodsInfo['goods_image'] = current($goodsInfo['goods_images'])['preview_url'];
// 商品销量(实际显示=初始虚拟销量+实际销量)
$goodsInfo['goods_sales'] = $goodsInfo['sales_initial'] + $goodsInfo['sales_actual'];
// 回调函数
is_callable($callback) && call_user_func($callback, $goodsInfo);
return $goodsInfo->hidden(array_merge($this->hidden, ['specRel', 'images']));
}
/**
* 根据商品id集获取商品列表
* @param array $goodsIds
* @param null $status
* @return array|mixed
*/
public function getListByIds(array $goodsIds, $status = null)
{
// 筛选条件
$filter = [['goods_id', 'in', $goodsIds]];
// 商品状态
$status > 0 && $filter[] = ['status', '=', $status];
// 获取商品列表数据
$data = $this->withoutField(['content'])
->with(['images.file'])
->where($filter)
->where('is_delete', '=', 0)
->orderRaw('field(goods_id, ' . implode(',', $goodsIds) . ')')
->select();
// 整理列表数据并返回
return $this->setGoodsListData($data);
}
/**
* 商品多规格信息
* @param \think\Collection $specRel
* @param \think\Collection $skuData
* @return array
*/
public function getManySpecData($specRel, $skuData)
{
// spec_attr
$specAttrData = [];
foreach ($specRel as $item) {
if (!isset($specAttrData[$item['spec_id']])) {
$specAttrData[$item['spec_id']] = [
'group_id' => $item['spec']['spec_id'],
'name' => $item['spec']['spec_name'],
'spec_items' => [],
];
}
$specAttrData[$item['spec_id']]['spec_items'][] = [
'item_id' => $item['spec_value_id'],
'spec_value' => $item['spec_value'],
];
}
// spec_list
$specListData = [];
foreach ($skuData as $item) {
$image = (isset($item['images']) && !empty($item['images'])) ? $item['images'] : ['file_id' => 0, 'external_url' => ''];
$specListData[] = [
'id' => $item['id'],
'goods_sku_id' => $item['goods_sku_id'],
'rows' => [],
'form' => [
'image_id' => $image['file_id'],
'image_path' => $image['external_url'],
'goods_sku_no' => $item['goods_sku_no'],
'goods_price' => $item['goods_price'],
'goods_weight' => $item['goods_weight'],
'line_price' => $item['line_price'],
'stock_num' => $item['stock_num'],
],
];
}
return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData];
}
/**
* 获取商品记录
* @param int|array $where
* @param array $with
* @return array|null|static
*/
public static function detail($where, array $with = [])
{
return static::get($where, $with);
}
/**
* 获取全部
* @param array $where
* @return mixed
*/
public static function getAll($where = [])
{
$model = new static;
return $model->order(['goods_id' => 'asc'])->where($where)->select();
}
}
@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品与分类关系模型
* Class GoodsCategoryRel
* @package app\common\model
*/
class GoodsCategoryRel extends BaseModel
{
// 定义表名
protected $name = 'goods_category_rel';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
}
@@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\helper;
/**
* 商品关联优惠券模型
* Class GoodsCoupon
* @package app\common\model
*/
class GoodsCoupon extends BaseModel
{
// 定义表名
protected $name = 'goods_coupon';
// 定义主键
protected $pk = 'id';
/**
* 关联模型:优惠券
* @return \think\model\relation\HasOne
*/
public function coupon(): \think\model\relation\HasOne
{
return $this->hasOne('Coupon', 'id', 'coupon_id');
}
/**
* 获取优惠券信息详情
* @param int $goodsId
* @param string $goodsCouponId
* @return array|null|static
*/
public static function detail(int $goodsId, string $goodsCouponId)
{
return static::get(['goods_id' => $goodsId, 'coupon_id' => $goodsCouponId], ['coupon']);
}
/**
* 获取商品优惠券列表
* @param int $goodsId 商品ID
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getCouponList(int $goodsId): \think\Collection
{
return (new static)->where('goods_id', '=', $goodsId)->order(['id' => 'asc'])->select();
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品图片模型
* Class GoodsImage
* @package app\common\model
*/
class GoodsImage extends BaseModel
{
// 定义表名
protected $name = 'goods_image';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
/**
* 关联文件库
* @return \think\model\relation\BelongsTo
*/
public function file()
{
return $this->belongsTo('UploadFile', 'image_id', 'file_id');
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\helper;
/**
* 商品SKU模型
* Class GoodsSku
* @package app\common\model
*/
class GoodsSku extends BaseModel
{
// 定义表名
protected $name = 'goods_sku';
// 定义主键
protected $pk = 'id';
/**
* 关联模型:规格图片
* @return \think\model\relation\HasOne
*/
public function image(): \think\model\relation\HasOne
{
return $this->hasOne('UploadFile', 'file_id', 'image_id');
}
/**
* 获取器:规格值ID集
* @param $value
* @return array|mixed
*/
public function getSpecValueIdsAttr($value)
{
return helper::jsonDecode($value);
}
/**
* 获取器:规格属性
* @param $value
* @return array|mixed
*/
public function getGoodsPropsAttr($value)
{
return helper::jsonDecode($value);
}
/**
* 设置器:规格值ID集
* @param $value
* @return string
*/
public function setSpecValueIdsAttr($value): string
{
return helper::jsonEncode($value);
}
/**
* 设置器:规格属性
* @param $value
* @return string
*/
public function setGoodsPropsAttr($value): string
{
return helper::jsonEncode($value);
}
/**
* 获取sku信息详情
* @param int $goodsId
* @param string $goodsSkuId
* @return array|null|static
*/
public static function detail(int $goodsId, string $goodsSkuId)
{
return static::get(['goods_id' => $goodsId, 'goods_sku_id' => $goodsSkuId], ['image']);
}
/**
* 获取商品SKU列表
* @param int $goodsId 商品ID
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getSkuList(int $goodsId): \think\Collection
{
return (new static)->where('goods_id', '=', $goodsId)->select();
}
}
@@ -0,0 +1,89 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 商品规格关系模型
* Class GoodsSpecRel
* @package app\common\model
*/
class GoodsSpecRel extends BaseModel
{
// 定义表名
protected $name = 'goods_spec_rel';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
/**
* 关联规格组
* @return \think\model\relation\BelongsTo
*/
public function spec()
{
return $this->belongsTo('Spec');
}
/**
* 关联规格值
* @return \think\model\relation\BelongsTo
*/
public function specValue()
{
return $this->belongsTo('SpecValue');
}
/**
* 指定商品的规格列表
* @param int $goodsId 商品ID
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getSpecList(int $goodsId)
{
// 获取指定商品的规格值关系记录
$data = (new static)->with(['spec', 'specValue'])
->where('goods_id', '=', $goodsId)
->select();
// 规格组
$groupData = [];
foreach ($data as $groupKey => $item) {
$groupData[$item['spec_id']] = [
'spec_id' => $item['spec']['spec_id'],
'spec_name' => $item['spec']['spec_name']
];
}
// 去除索引
$specList = array_values($groupData);
// 规格值
foreach ($specList as $groupKey => &$group) {
$group['key'] = $groupKey;
foreach ($data as $valueKey => $item) {
($item['spec_id'] == $group['spec_id']) && $group['valueList'][] = [
'key' => isset($group['valueList']) ? count($group['valueList']) : 0,
'groupKey' => $groupKey,
'spec_value_id' => $item['specValue']['spec_value_id'],
'spec_value' => $item['specValue']['spec_value']
];
}
}
return $specList;
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 模型类:帮助中心
* Class Help
* @package app\common\model
*/
class Help extends BaseModel
{
// 定义表名
protected $name = 'help';
// 定义主键
protected $pk = 'help_id';
/**
* 获取列表记录
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList()
{
return $this->where('is_delete', '=', 0)
->order(['sort', $this->getPk()])
->paginate();
}
/**
* 帮助详情
* @param int $helpId
* @return null|static
*/
public static function detail(int $helpId)
{
return self::get($helpId);
}
}
+102
View File
@@ -0,0 +1,102 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use app\store\model\store\User;
use cores\BaseModel;
use think\model\relation\BelongsTo;
/**
* 商户模型
* Class Merchant
* @package app\common\model
*/
class Merchant extends BaseModel
{
protected $name = 'merchant';
// 定义主键
protected $pk = 'merchant_id';
/**
* 获取上级经销商信息
* @return BelongsTo
*/
public function referrer(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Merchant", 'parent_merchant_id');
}
/**
* 商户详情
* @param $where
* @param array $with
* @return static|null
* @throws \think\exception\DbException
*/
public static function detail($where, $with = [])
{
!is_array($where) && $where = ['merchant_id' => (int)$where];
return static::get($where, $with);
}
/**
* 获取全部
* @param array $user
* @return mixed
*/
public static function getAll($user = [])
{
$model = new static;
if(isset($user['is_super']) && $user['is_super'] == 0) {
/*$users = User::getScope($user);
$arr = $user['merchant_id']?json_decode($user['merchant_id'],true):[];
return $model->order(['merchant_id' => 'asc'])->where(function ($query) use($users, $arr) {
$query->where('store_user_id', 'in', $users)
->whereOr('merchant_id', 'in', $arr);
})->select();*/
return $model->order(['merchant_id' => 'asc'])->where(function ($query) use($user) {
$query->where('merchant_id', '=', $user['merchant_id'])
->whereOr('parent_merchant_id', '=', $user['merchant_id']);
})->select();
}else{
return $model->order(['merchant_id' => 'asc'])->select();
}
}
/**
* 获取指定
* @param array $filter
* @return mixed
*/
public static function getQuery($filter): array
{
$model = new static;
return $model->where($filter)->order(['merchant_id' => 'asc'])->select()->toArray();
}
/**
* 累积商户可用余额
* @param int $merchantId
* @param float $money
* @return mixed
*/
public static function setIncBalance(int $merchantId, float $money)
{
return (new static)->setInc($merchantId, 'balance', $money);
}
/**
* 消减商户可用余额
* @param int $merchantId
* @param float $money
* @return mixed
*/
public static function setDecBalance(int $merchantId, float $money)
{
return (new static)->setDec([['merchant_id', '=', $merchantId]], 'balance', $money);
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 通知类
* Class GoodsSku
* @package app\common\model
*/
class Notify extends BaseModel
{
protected $name = 'notify';
/**
* 通知详情
* @param $where
* @return null|static
* @throws \think\exception\DbException
*/
public static function detail($where)
{
is_array($where) ? $filter = $where : $filter['notify_id'] = (int)$where;
return self::get($filter);
}
}
+324
View File
@@ -0,0 +1,324 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\model\store\shop\Order as ShopOrder;
use app\common\service\Order as OrderService;
use app\common\service\order\Complete as OrderCompleteService;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\enum\order\OrderStatus as OrderStatusEnum;
use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
use app\common\enum\order\DeliveryStatus as DeliveryStatusEnum;
use app\common\library\helper;
use think\model\relation\BelongsTo;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
/**
* 订单模型
* Class Order
* @package app\common\model
*/
class Order extends BaseModel
{
// 定义表名
protected $name = 'order';
// 定义表名(外部引用)
public static $tableName = 'order';
// 定义主键
protected $pk = 'order_id';
// 定义别名
protected $alias = 'order';
/**
* 追加字段
* @var array
*/
protected $append = [
'state_text', // 售后单状态文字描述
];
/**
* 订单商品列表
* @return HasMany
*/
public function goods(): HasMany
{
$module = self::getCalledModule();
return $this->hasMany("app\\{$module}\\model\\OrderGoods")->withoutField('content');
}
/**
* 关联订单收货地址表
* @return HasOne
*/
public function address(): HasOne
{
$module = self::getCalledModule();
return $this->hasOne("app\\{$module}\\model\\OrderAddress");
}
/**
* 关联用户表
* @return BelongsTo
*/
public function user(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\User");
}
/**
* 店铺用户表
* @return \think\model\relation\BelongsTo
*/
public function shop(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Shop");
}
/**
* 商户用户表
* @return \think\model\relation\BelongsTo
*/
public function merchant(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Merchant");
}
/**
* 关联物流公司表
* @return BelongsTo
*/
public function express(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Express");
}
/**
* 一级推广用户
* @return BelongsTo
*/
public function spreadOne(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Merchant", 'spread_uid');
}
/**
* 二级推广用户
* @return BelongsTo
*/
public function spreadTwo(): BelongsTo
{
$module = self::getCalledModule();
return $this->belongsTo("app\\{$module}\\model\\Merchant", 'spread_two_uid');
}
/**
* 订单状态文字描述
* @param $value
* @param array $data
* @return string
*/
public function getStateTextAttr($value, array $data): string
{
// 订单状态
// if (in_array($data['order_status'], [OrderStatusEnum::CANCELLED, OrderStatusEnum::COMPLETED])) {
// $orderStatus = [OrderStatusEnum::CANCELLED => '已取消', OrderStatusEnum::COMPLETED => '已完成'];
// return $orderStatus[$data['order_status']];
// }
// 订单状态
if ($data['order_status'] != OrderStatusEnum::NORMAL) {
return OrderStatusEnum::data()[$data['order_status']]['name'];
}
// 付款状态
if ($data['pay_status'] == PayStatusEnum::PENDING) {
return '待支付';
}
return OrderStatusEnum::data()[$data['order_status']]['name'];
// 订单类型:单独购买
// if ($data['delivery_status'] == 10) {
// return '待发货';
// }
// if ($data['receipt_status'] == 10) {
// return '待收货';
// }
return $value;
}
/**
* 获取器:订单金额(含优惠折扣)
* @param $value
* @param $data
* @return string
*/
public function getOrderPriceAttr($value, $data): string
{
// 兼容旧数据:订单金额
if ($value == 0) {
return helper::bcadd(helper::bcsub($data['total_price'], $data['coupon_money']), $data['update_price']);
}
return $value;
}
/**
* 改价金额(差价)
* @param $value
* @return array
*/
public function getUpdatePriceAttr($value): array
{
return [
'symbol' => $value < 0 ? '-' : '+',
'value' => sprintf('%.2f', abs((float)$value))
];
}
/**
* 付款时间
* @param $value
* @return false|string
*/
public function getPayTimeAttr($value)
{
return format_time($value);
}
/**
* 发货时间
* @param $value
* @return false|string
*/
public function getDeliveryTimeAttr($value)
{
return format_time($value);
}
/**
* 收货时间
* @param $value
* @return false|string
*/
public function getReceiptTimeAttr($value)
{
return format_time($value);
}
/**
* 有效期限
* @param $value
* @return false|string
*/
public function getExpirationTimeAttr($value)
{
return format_time($value);
}
/**
* 生成订单号
* @return string
*/
public function orderNo(): string
{
return OrderService::createOrderNo();
}
/**
* 订单详情
* @param $where
* @param array $with
* @return array|null|static
*/
public static function detail($where, array $with = [])
{
is_array($where) ? $filter = $where : $filter['order_id'] = (int)$where;
return self::get($filter, $with);
}
/**
* 批量获取订单列表
* @param array $orderIds
* @param array $with
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListByIds(array $orderIds, array $with = []): array
{
$data = $this->getListByInArray('order_id', $orderIds, $with);
return helper::arrayColumn2Key($data, 'order_id');
}
/**
* 批量获取订单列表
* @param $field
* @param $data
* @param array $with
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getListByInArray($field, $data, array $with = []): \think\Collection
{
return $this->with($with)
->where($field, 'in', $data)
->where('is_delete', '=', 0)
->select();
}
/**
* 根据订单号批量查询
* @param $orderNos
* @param array $with
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListByOrderNos($orderNos, array $with = []): \think\Collection
{
return $this->getListByInArray('order_no', $orderNos, $with);
}
/**
* 批量更新订单
* @param $orderIds
* @param $data
* @return bool|false
*/
public function onBatchUpdate($orderIds, $data): bool
{
return static::updateBase($data, [['order_id', 'in', $orderIds]]);
}
/**
* 获取订单总金额
* @param array $filter
* @return int|string
*/
public function getOrderTotalPriceCustom($filter = [])
{
return $this->where($filter)
->sum('amount');
}
}
@@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\model\Region as RegionModel;
/**
* 订单收货地址模型
* Class OrderAddress
* @package app\common\model
*/
class OrderAddress extends BaseModel
{
// 定义表名
protected $name = 'order_address';
// 定义主键
protected $pk = 'order_address_id';
protected $updateTime = false;
/**
* 追加字段
* @var array
*/
protected $append = ['region'];
/**
* 获取器:地区名称
* @param $value
* @param $data
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getRegionAttr($value, $data)
{
return [
'province' => RegionModel::getNameById($data['province_id']),
'city' => RegionModel::getNameById($data['city_id']),
'region' => RegionModel::getNameById($data['region_id'])
];
}
/**
* 获取完整地址
* @return string
*/
public function getFullAddress()
{
return $this['region']['province'] . $this['region']['city'] . $this['region']['region'] . $this['detail'];
}
/**
* 获取完整地址
* @param $detail
* @return string
*/
public static function fullAddress($detail)
{
return $detail['region']['province'] . $detail['region']['city'] . $detail['region']['region'] . $detail['detail'];
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\library\helper;
/**
* 订单商品模型
* Class OrderGoods
* @package app\common\model
*/
class OrderGoods extends BaseModel
{
// 定义表名
protected $name = 'order_goods';
// 定义主键
protected $pk = 'order_goods_id';
protected $updateTime = false;
/**
* 订单商品图片
* @return \think\model\relation\BelongsTo
*/
public function image()
{
$model = "app\\common\\model\\UploadFile";
return $this->belongsTo($model, 'image_id', 'file_id')
->bind(['goods_image' => 'preview_url']);
}
/**
* 关联商品表
* @return \think\model\relation\BelongsTo
*/
public function goods()
{
return $this->belongsTo('Goods');
}
/**
* 关联订单主表
* @return \think\model\relation\BelongsTo
*/
public function orderM()
{
return $this->belongsTo('Order');
}
/**
* 售后单记录表
* @return \think\model\relation\HasOne
*/
public function refund()
{
return $this->hasOne('OrderRefund');
}
/**
* 获取器:规格属性
* @param $value
* @return array
*/
public function getGoodsPropsAttr($value)
{
return helper::jsonDecode($value);
}
/**
* 设置器:规格属性
* @param $value
* @return string
*/
public function setGoodsPropsAttr($value)
{
return $value ? helper::jsonEncode($value) : '';
}
/**
* 有效期限
* @param $value
* @return false|string
*/
public function getExpirationTimeAttr($value)
{
return format_time($value);
}
/**
* 订单商品详情
* @param $where
* @return OrderGoods|null
*/
public static function detail($where)
{
return static::get($where, ['image', 'refund']);
}
}
+104
View File
@@ -0,0 +1,104 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 售后单模型
* Class OrderRefund
* @package app\common\model\wxapp
*/
class OrderRefund extends BaseModel
{
// 定义表名
protected $name = 'order_refund';
// 定义主键
protected $pk = 'order_refund_id';
/**
* 关联用户表
* @return \think\model\relation\BelongsTo
*/
public function user()
{
return $this->belongsTo('User');
}
/**
* 关联订单主表
* @return \think\model\relation\BelongsTo
*/
public function orderData()
{
return $this->belongsTo('Order');
}
/**
* 关联订单商品表
* @return \think\model\relation\BelongsTo
*/
public function orderGoods()
{
return $this->belongsTo('OrderGoods')->withoutField(['content']);
}
/**
* 关联图片记录表
* @return \think\model\relation\HasMany
*/
public function images()
{
return $this->hasMany('OrderRefundImage');
}
/**
* 关联物流公司表
* @return \think\model\relation\BelongsTo
*/
public function express()
{
return $this->belongsTo('Express');
}
/**
* 关联用户表
* @return \think\model\relation\HasOne
*/
public function address()
{
return $this->hasOne('OrderRefundAddress');
}
/**
* 获取器:用户发货时间
* @param $value
* @return false|string
*/
public function getSendTimeAttr($value)
{
return format_time($value);
}
/**
* 售后单详情
* @param array|int $where
* @param array $with
* @return null|static
*/
public static function detail($where, array $with = [])
{
return static::get($where, $with);
}
}
@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
use app\common\model\Region as RegionModel;
/**
* 售后单退货地址模型
* Class OrderRefundAddress
* @package app\common\model
*/
class OrderRefundAddress extends BaseModel
{
// 定义表名
protected $name = 'order_refund_address';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
/**
* 追加字段
* @var array
*/
protected $append = ['region'];
/**
* 获取器:地区名称
* @param $value
* @param $data
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getRegionAttr($value, $data)
{
return [
'province' => RegionModel::getNameById($data['province_id']),
'city' => RegionModel::getNameById($data['city_id']),
'region' => RegionModel::getNameById($data['region_id'])
];
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
/**
* 售后单图片模型
* Class OrderRefundImage
* @package app\common\model
*/
class OrderRefundImage extends BaseModel
{
// 定义表名
protected $name = 'order_refund_image';
// 定义主键
protected $pk = 'id';
protected $updateTime = false;
/**
* 关联文件库
* @return \think\model\relation\BelongsTo
*/
public function file()
{
return $this->belongsTo('UploadFile', 'image_id', 'file_id')->bind(['image_url' => 'preview_url']);
}
}

Some files were not shown because too many files have changed in this diff Show More