Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
php_utils
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
bp
php_utils
Commits
15534ea4
Commit
15534ea4
authored
Aug 09, 2021
by
luhongguang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://git.yidian-inc.com:8021/bp/php_utils
parents
ac7e4d03
2150d5e7
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
344 additions
and
27 deletions
+344
-27
Rsa.php
src/Common/Rsa.php
+58
-0
HttpUtil.php
src/Http/HttpUtil.php
+6
-1
FileLog.php
src/Log/FileLog.php
+32
-24
Tracer.php
src/Log/Tracer.php
+164
-0
Email.php
src/Message/Email.php
+16
-0
MonUtil.php
src/Mon/MonUtil.php
+1
-1
Medoo.php
src/Mysql/Medoo.php
+1
-1
ShareWorker.php
src/Strategy/ShareWorker.php
+66
-0
No files found.
src/Common/Rsa.php
View file @
15534ea4
...
...
@@ -179,6 +179,56 @@ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUbC5cW6K/XPjfdljTRSP5YtZG
gHM3r3EWS2bUGHTZZLAd6KGrIP2985c9ODd3s3/JvYmrh/N3djFy3MYhZm5P6iGt
kRlCF7Jac58/9V4lDhQiMzjclfpWR6s3aMBEwx5g2gFhjnnlSZRnYofRPqsB1JhB
1ZirI2if7kWNBz+BTwIDAQAB
-----END PUBLIC KEY-----'
;
/**
* 商户系统拼单小程序 SERVER端私钥与客户端公钥
*/
const
MERCHANT_PUB_PIN_PRIVATE_KEY_STR
=
'-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMq5OJZpmPbfrGAt
JIvPQEEYr0edc4U7LmUArp17tUeknqNfFc0pXuWABIkMTeZuKspDf1ehfYPCVnGs
gWIYvECAdAvMH8TpgNMl6Bc7hjRY89gZUuIx5SK0kw8xJ1z2SlQ4at2PiUnNjYYC
ydyipoHOAXYgpEbcX4OGEF6P6E/nAgMBAAECgYBQsOULScDvExzjs1RGqhnjT1YF
ZXCj6WiQH3Nhj+oaODZExQZCgWMaaphjjJg9TkCN/cvkL41sMqCB4q4lQ786H/8P
flBDGyngi9vjmZBdsmllDNi7kwcAtl8xk7YaHzQuIZ49dOzL/qQggCHokgvbBRXh
NI1AYBm/G8C8H0DE8QJBAOlKL4LQuoOtg49+qpw73snNOkEnFzn6nClud7w/wHR1
I82nmesyadcjVoJA9Lb1/AA9/MXV5RQeZ8Ckn//42SUCQQDedUsl4jtpuLz+QYv4
994ASsGBSGLE3BAPI1YClA8oVDRYMQydbZMgeZ8AspZtnmBifbcoOM/q+VbBomNk
pfUbAkEAkUCMhnG5v6T4hg7C4ZXxaEqs28YgEwxz0OQkDwTOqnQI/9I75pI0DizF
f0I8W/Kanff6e59rC3TG+s5FhNYHNQJBAJtOlCpcqVID8Z4osMoeclUN286gdKQv
Zt7Ksq+WIobrUqgHhmEaMM9JWaKpC7B4E55vWkGweCf574G8F1wbKOUCQHtD5JLr
B/84pKhIkdbhfdTReLbxz3/mRZM+RGFvbXvr5yr5ihcFHtIgHsmrIYbBccJdd42s
kZ5U8STIJSCkBZo=
-----END PRIVATE KEY-----'
;
const
MERCHANT_PUB_PIN_PUBLIC_KEY_STR
=
'-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGmANRSw3T4ztQ8ZWMw+cW70Zg
9yOwQV0oWp9Zce8eCLoRgFVFeajeQ1BT59tQ3bR4Qwg/gL8ZKf9JanxNyINQY8th
CKIYerOCxgr0QPKiQCVL7BTZNj7m91OdVmsYfJty1YihM43a5op62T0OJk/4mF2H
Txl13uSJhZgM9szI7wIDAQAB
-----END PUBLIC KEY-----'
;
/**
* 商户系统拼单小程序-测试 SERVER端私钥与客户端公钥
*/
const
TEST_MERCHANT_PUB_PIN_PRIVATE_KEY_STR
=
'-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOOfrgheB6r+85+1
97tfjq6+R/FhWg4T+GXOZ5pimMNwf/yOLYbC+HITvHKoEExymf2Um6i6dnJjU7zl
AjmbzK0TSab0exz1tNxnBSE/nt5G06n5f2FOYMAu67iseQ97aGYDGbRWakSjdYTx
jPoKT7dG8cC6RdIW7aJDCceNIeGBAgMBAAECgYByZakIaYF/Dd0Q0lor4E2MQvNT
O7MPyjeXqtFkxNKzvpGEM0xsIwbMBmE6Wn6+fQYpbIuClBu9R3ApSgsBOuz0yBGM
e/DNmAifZn1EFVQRm+Li//poLfl3HE2oj0dJhPRiCyoxeWhP76zxP+v0IXwopZbF
W0jP+ojto8q2zx/75QJBAPxFSQisRdMV1KxbyZzT2clYwRB5Dfqdh2SmaJ6Mms+o
Ua9e6lgD7/K1C+3GCtIkDHSlhnNNMRwIItpCe8r7RZcCQQDm/R5it0UvpWZzYCEn
iXMvavwp3+PCTftpxS9/CWrWQCk5C4wW7l5j+Be6f0e4cboOr6kaiPXkF8qn/SF6
S+SnAkBNs6GNNFLFc6Hv/M2aqn4YUGgXBNJTcRX04HS08SX19ChE1f1kYsIThcRI
1okatNPJUfqZpRsNQUxK4dNzb/W9AkBJ+S3N91tU0udoc5SqkL4upVh0IJtUEp09
VkTLrjxkuM960VPf1B6ubTlMJI7XZrRrF55UPSBiF6xy+AHMpJlpAkEAhNVjlx+x
9qDJ23tHTDFxN0dl2IK+Xz3j9HDNvb5SdO+pcIvQvVg9UUc5xnkXmVm35RwqeA6O
2P6ROLCijjotzw==
-----END PRIVATE KEY-----'
;
const
TEST_MERCHANT_PUB_PIN_PUBLIC_KEY_STR
=
'-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFOU3D4aULZuJ3IyRGmPhwn5g
zIcDvT2EEZMJ+ePgi0Oax/P3z25m5758okGs1lrS93vDWO7lbsgQn5mnuKuqmuj6
M3BP/vOildi+3oTZcjQTV2deebIrhW4p96DvTqQ7ixVAEi4of3XoITA00J8hfNy9
jDprGYGJ5yeTuRRHlQIDAQAB
-----END PUBLIC KEY-----'
;
/**
* TEST SERVER端私钥与客户端公钥
...
...
@@ -235,6 +285,14 @@ mnRjVUtXBgEF0A9xt2QVNMQovtjJ2rkg43gVByDKbOsUqbJYjA12IpALMdECHCMl
'pub_key'
=>
self
::
TEST_MERCHANT_H5_PUBLIC_KEY_STR
,
'pri_key'
=>
self
::
TEST_MERCHANT_H5_PRIVATE_KEY_STR
,
],
'merchant-pub-pin'
=>
[
'pub_key'
=>
self
::
MERCHANT_PUB_PIN_PUBLIC_KEY_STR
,
'pri_key'
=>
self
::
MERCHANT_PUB_PIN_PRIVATE_KEY_STR
,
],
'test-merchant-pub-pin'
=>
[
'pub_key'
=>
self
::
TEST_MERCHANT_PUB_PIN_PUBLIC_KEY_STR
,
'pri_key'
=>
self
::
TEST_MERCHANT_PUB_PIN_PRIVATE_KEY_STR
,
],
'test'
=>
[
'pub_key'
=>
self
::
TEST_PUBLIC_KEY_STR
,
'pri_key'
=>
self
::
TEST_PRIVATE_KEY_STR
,
...
...
src/Http/HttpUtil.php
View file @
15534ea4
...
...
@@ -196,6 +196,11 @@ class HttpUtil
{
$ch
=
curl_init
(
$url
);
// CURLOPT_POSTFIELDS 不支持多维数组
if
(
is_array
(
$post
)
&&
count
(
$post
)
!=
count
(
$post
,
COUNT_RECURSIVE
))
{
$post
=
http_build_query
(
$post
);
}
if
(
is_resource
(
$ch
)
===
true
)
{
curl_setopt
(
$ch
,
CURLOPT_FAILONERROR
,
true
);
...
...
@@ -365,7 +370,7 @@ class HttpUtil
{
//过滤无意义的日志
$log
=
true
;
$excludes
=
config
(
'
http_util
'
,
'log.exclude'
);
$excludes
=
config
(
'
request
'
,
'log.exclude'
);
if
(
!
empty
(
$excludes
))
{
foreach
(
$excludes
as
$exclude
)
{
if
(
is_array
(
$urls
))
{
...
...
src/Log/FileLog.php
View file @
15534ea4
...
...
@@ -2,10 +2,13 @@
namespace
Api\PhpUtils\Log
;
use
Api\PhpUtils\Cache\ApcuUtil
;
use
Api\PhpUtils\Log\Tracer
;
use
Api\PhpUtils\Message\Email
;
class
FileLog
{
const
PREFIX_FILELOG_ERROR
=
'flerr:'
;
/**
* 用于记录info级别的错误
* 会记录请求上下文,不会发生报警邮件
...
...
@@ -15,7 +18,8 @@ class FileLog
*/
public
static
function
info
(
$signature
,
$detail_info
=
''
,
$with_access_log
=
false
)
{
$log
=
'PHP User_info: ['
.
$signature
.
']'
.
' [detail info:] '
.
$detail_info
;
$traceId
=
Tracer
::
getTraceId
();
$log
=
'PHP User_info: ['
.
$signature
.
'] [traceId:'
.
$traceId
.
'] [detail info:] '
.
$detail_info
;
if
(
$with_access_log
)
{
$log
.=
' [request info:] '
.
self
::
accessLog
();
}
...
...
@@ -31,7 +35,8 @@ class FileLog
*/
public
static
function
waring
(
$signature
,
$detail_info
=
''
,
$exception
=
null
)
{
$log
=
'PHP User_warning: ['
.
$signature
.
']'
.
' [detail info:] '
.
$detail_info
.
' [request info:] '
.
self
::
accessLog
();
$traceId
=
Tracer
::
getTraceId
();
$log
=
'PHP User_warning: ['
.
$signature
.
'] [traceId:'
.
$traceId
.
'] [detail info:] '
.
$detail_info
.
' [request info:] '
.
self
::
accessLog
();
if
(
$exception
!=
''
)
{
$exception_info
=
'In '
.
$exception
->
getFile
()
.
' on line '
.
$exception
->
getLine
()
.
' '
.
$exception
->
getCode
()
.
': '
.
$exception
->
getMessage
();
$log
.=
' [exception info: ]'
.
$exception_info
;
...
...
@@ -49,34 +54,36 @@ class FileLog
*/
public
static
function
error
(
$signature
,
$detail_info
=
''
,
$exception
=
null
,
$mail_to
=
''
)
{
$log
=
'PHP User_error: ['
.
$signature
.
']'
.
' [detail info:] '
.
$detail_info
.
' [request info:] '
.
self
::
accessLog
();
$traceId
=
Tracer
::
getTraceId
();
$log
=
'PHP User_error: ['
.
$signature
.
'] [traceId:'
.
$traceId
.
'] [detail info:] '
.
$detail_info
.
' [request info:] '
.
self
::
accessLog
();
if
(
$exception
!=
''
)
{
$exception_info
=
' [exception info: ] In '
.
$exception
->
getFile
()
.
' on line '
.
$exception
->
getLine
()
.
' '
.
$exception
->
getCode
()
.
': '
.
$exception
->
getMessage
();
}
else
{
$exception_info
=
''
;
}
$log
.=
' [exception info: ]'
.
$exception_info
;
$log
.=
' [debug_backtrace info: ]'
.
print_r
(
debug_backtrace
(),
1
);
error_log
(
$log
);
if
(
!
empty
(
$mail_to
))
{
$subject
=
'App api #'
.
$signature
.
'# '
.
$_SERVER
[
'SERVER_NAME'
]
.
' ('
.
$_SERVER
[
'SERVER_ADDR'
]
.
') Alert Message'
;
$body
=
'Error: '
.
$signature
.
"
\n\n
"
;
$body
.=
'Detail info: '
.
$detail_info
.
"
\n\n
"
;
$body
.=
'Exception info: '
.
$exception_info
.
"
\n\n
"
;
$body
.=
'Request info: '
.
self
::
accessLog
()
.
"
\n\n
"
;
$body
.=
'Machine: '
.
gethostname
();
if
(
!
is_array
(
$mail_to
))
{
$mail_to
=
[
$mail_to
];
}
if
(
empty
(
$mail_to
))
{
$mail_to
=
'bp-server@yidian-inc.com'
;
}
$subject
=
'App api #'
.
$signature
.
'# '
.
$_SERVER
[
'SERVER_NAME'
]
.
' ('
.
$_SERVER
[
'SERVER_ADDR'
]
.
') Alert Message'
;
$body
=
'Error: '
.
$signature
.
"
\n\n
"
;
$body
.=
'Detail info: '
.
$detail_info
.
"
\n\n
"
;
$body
.=
'Exception info: '
.
$exception_info
.
"
\n\n
"
;
$body
.=
'Request info: '
.
self
::
accessLog
()
.
"
\n\n
"
;
$body
.=
'Machine: '
.
gethostname
();
if
(
!
is_array
(
$mail_to
))
{
$mail_to
=
[
$mail_to
];
}
if
(
self
::
shouldSendEmail
(
md5
(
$signature
))
===
true
)
{
foreach
(
$mail_to
as
$mail
)
{
$key
=
md5
(
sprintf
(
"%s,%s"
,
$mail
,
md5
(
$signature
)));
if
(
self
::
shouldSendEmail
(
$key
)
===
true
)
{
Email
::
sendMail
(
'bp-noreply@yidian-inc.com'
,
$mail
,
$subject
,
$body
);
}
Email
::
sendMail
(
'bp-noreply@yidian-inc.com'
,
$mail
,
$subject
,
$body
);
}
}
}
p
rivate
static
function
accessLog
()
p
ublic
static
function
accessLog
()
{
$url
=
'http://'
.
$_SERVER
[
'SERVER_NAME'
]
.
$_SERVER
[
'SCRIPT_NAME'
];
$query
=
http_build_query
(
$_GET
,
''
,
'&'
);
...
...
@@ -102,7 +109,7 @@ class FileLog
fclose
(
$log_file
);
}
p
rivate
static
function
ip
()
p
ublic
static
function
ip
()
{
if
(
isset
(
$_SERVER
[
'IPV6_REMOTE_ADDR'
])
&&
!
empty
(
$_SERVER
[
'IPV6_REMOTE_ADDR'
])
&&
trim
(
$_SERVER
[
'IPV6_REMOTE_ADDR'
])
!==
'-'
)
{
// 如果没有ipv6地址, 运维会传一个占位符“-”
$ips
=
$_SERVER
[
'IPV6_REMOTE_ADDR'
];
...
...
@@ -119,13 +126,14 @@ class FileLog
return
$ip
[
0
];
}
p
rivate
static
function
shouldSendEmail
(
$key
)
p
ublic
static
function
shouldSendEmail
(
$key
)
{
$result
=
true
;
// $cache = new CommonCacheUtil(RedisUtil::CODIS_CLUSTER_ACTION);
// if ($cache->add($key, true, 60, CacheUtil::PREFIX_SEND_MAIL) === false
) {
//
$result = false;
//
}
// 每分钟发一条
if
(
!
ApcuUtil
::
apcu_add_one
(
self
::
PREFIX_FILELOG_ERROR
,
$key
,
1
,
60
)
)
{
$result
=
false
;
}
return
$result
;
}
}
src/Log/Tracer.php
0 → 100644
View file @
15534ea4
<?php
namespace
Api\PhpUtils\Log
;
class
Tracer
{
const
DEBUG
=
1
;
const
INFO
=
2
;
const
WARNING
=
3
;
const
ERROR
=
4
;
protected
static
$traceId
=
''
;
protected
static
$spanId
=
''
;
/**
* http 请求日志
*/
public
static
function
request
()
{
$tag
=
'request'
;
$message
=
'request log'
;
$content
=
[
'uri'
=>
''
,
'get'
=>
[],
'post'
=>
[],
];
//__METHOD__
self
::
info
(
$message
,
$content
,
$tag
);
}
/**
* @param $ret
*/
public
static
function
response
(
$ret
)
{
$tag
=
'response'
;
$message
=
'response log'
;
$content
=
[
'ret'
=>
$ret
,
'requestId'
=>
self
::
getTraceId
(),
];
self
::
info
(
$message
,
$content
,
$tag
);
}
public
static
function
daemon
()
{
$tag
=
'daemon'
;
$message
=
'daemon log'
;
$content
=
[
'pid'
=>
posix_getpid
(),
];
self
::
info
(
$message
,
$content
,
$tag
);
}
/**
* @param $message
* @param array $content
* @param string $tag
*/
public
static
function
debug
(
$message
,
$content
=
[],
$tag
=
''
){
self
::
log
(
self
::
DEBUG
,
$message
,
$content
,
$tag
);
}
public
static
function
info
(
$message
,
$content
=
[],
$tag
=
''
){
self
::
log
(
self
::
INFO
,
$message
,
$content
,
$tag
);
}
public
static
function
warning
(
$message
,
$content
=
[],
$tag
=
''
)
{
self
::
log
(
self
::
WARNING
,
$message
,
$content
,
$tag
);
}
public
static
function
error
(
$message
,
$content
=
[],
$tag
=
''
)
{
self
::
log
(
self
::
ERROR
,
$message
,
$content
,
$tag
);
}
public
static
function
log
(
$level
,
$message
,
$content
,
$tag
)
{
if
(
!
defined
(
'LOG_PATH'
))
{
define
(
'LOG_PATH'
,
ROOT_PATH
.
'/logs/'
);
}
switch
(
$level
)
{
case
self
::
DEBUG
:
case
self
::
INFO
:
case
self
::
WARNING
:
case
self
::
ERROR
:
$file
=
LOG_PATH
.
'log_'
.
date
(
'Y-m-d'
)
.
'.log'
;
break
;
}
$dateTime
=
new
\DateTime
();
$log
=
[
'timestamp'
=>
$dateTime
->
format
(
\DateTime
::
RFC3339_EXTENDED
),
'traceId'
=>
self
::
getTraceId
(),
'spanId'
=>
self
::
getSpanId
(),
'tag'
=>
$tag
,
'content'
=>
$content
,
'message'
=>
$message
];
//$_SERVER['HTTP_X_FORWARDED_FOR']
$string
=
json_encode
(
$log
,
JSON_UNESCAPED_UNICODE
)
.
"
\n
"
;
if
(
$fd
=
@
fopen
(
$file
,
'a'
))
{
fputs
(
$fd
,
$string
);
fclose
(
$fd
);
}
}
/**
* @return false|mixed|string
* 获取traceId
*/
public
static
function
getTraceId
()
{
if
(
empty
(
self
::
$traceId
))
{
if
(
!
empty
(
$_SERVER
[
'HTTP_X_TRACE_ID'
]))
{
self
::
$traceId
=
$_SERVER
[
'HTTP_X_TRACE_ID'
];
}
elseif
(
!
empty
(
$_SERVER
[
'HTTP_X_REQUEST_ID'
]))
{
self
::
$traceId
=
$_SERVER
[
'HTTP_X_REQUEST_ID'
];
}
else
{
self
::
$traceId
=
self
::
genUniqId
();
}
}
return
self
::
$traceId
;
}
/**
* @return false|string
* 获取spanId
*/
public
static
function
getSpanId
()
{
if
(
empty
(
self
::
$spanId
))
{
self
::
$spanId
=
self
::
genUniqId
();
}
return
self
::
$spanId
;
}
/**
* @return false|string
* @throws \Exception
* 获取随机串用于记录traceId
*/
public
static
function
genUniqId
()
{
if
(
function_exists
(
"random_bytes"
))
{
$bytes
=
random_bytes
(
ceil
(
8
));
return
substr
(
bin2hex
(
$bytes
),
0
,
16
);
}
elseif
(
function_exists
(
"openssl_random_pseudo_bytes"
))
{
$bytes
=
openssl_random_pseudo_bytes
(
ceil
(
8
));
return
substr
(
bin2hex
(
$bytes
),
0
,
16
);
}
else
{
$pre
=
rand
(
1
,
4095
);
return
uniqid
(
sprintf
(
"%03x"
,
$pre
));
}
}
}
src/Message/Email.php
View file @
15534ea4
...
...
@@ -2,6 +2,8 @@
namespace
Api\PhpUtils\Message
;
use
Yaf\Application
;
class
Email
{
/**
...
...
@@ -19,6 +21,10 @@ class Email
if
(
empty
(
$to
))
{
return
false
;
}
$env
=
Application
::
app
()
->
environ
();
if
(
$env
!=
'test'
&&
$env
!=
'prod'
&&
$env
!=
'perf'
){
return
false
;
}
if
(
empty
(
$from
))
{
$from
=
'noreply@yidian-inc.com'
;
}
...
...
@@ -30,6 +36,16 @@ class Email
fwrite
(
$sock
,
"HELO "
.
$domain
.
"
\r\n
"
);
fgets
(
$sock
);
fwrite
(
$sock
,
"auth login
\r\n
"
);
fgets
(
$sock
);
fwrite
(
$sock
,
"YnAtbm9yZXBseQ==
\r\n
"
);
fgets
(
$sock
);
fwrite
(
$sock
,
"VlhObGNtNWhiJFclVTY=
\r\n
"
);
fgets
(
$sock
);
fwrite
(
$sock
,
"MAIL FROM:<"
.
$from
.
">
\r\n
"
);
fgets
(
$sock
);
if
(
!
is_array
(
$to
))
{
...
...
src/Mon/MonUtil.php
View file @
15534ea4
...
...
@@ -70,7 +70,7 @@ class MonUtil{
}
//接口返回状态码打点
if
(
!
empty
(
$code
)
&&
is_numeric
(
$code
)){
if
(
isset
(
$code
)
&&
is_numeric
(
$code
)){
$result
=
self
::
counting
(
$module
.
"."
.
(
string
)
$request_uri
,
(
string
)
$code
,
1
)
.
"
\n
"
;
}
else
{
$result
=
self
::
counting
(
$module
.
"."
.
(
string
)
$request_uri
,
(
string
)
-
999
,
1
)
.
"
\n
"
;
...
...
src/Mysql/Medoo.php
View file @
15534ea4
...
...
@@ -1077,7 +1077,7 @@ class Medoo
$optimizer
=
''
;
if
(
is_null
(
$options
))
{
// 默认1秒钟超时时间
$optimizer
=
' /*+ max_execution_time(
1
000)*/ '
;
$optimizer
=
' /*+ max_execution_time(
3
000)*/ '
;
}
elseif
(
isset
(
$options
[
'max_execution_time'
]))
{
$ts
=
intval
(
$options
[
'max_execution_time'
]);
$optimizer
=
' /*+ max_execution_time('
.
$ts
.
')*/ '
;
...
...
src/Strategy/ShareWorker.php
0 → 100644
View file @
15534ea4
<?php
namespace
Api\PhpUtils\Strategy
;
/**
* Class ShareWorker
* @package Api\PhpUtils\Strategy
*
* 优惠券分摊处理算法
*/
class
ShareWorker
{
/**
* @param $items = ['sku_1'=>100, 'sku_2'=>85]
* @param $tip = 100
* @throws \ErrorException
* 根据商品价格等比做优惠金额的分摊, 做四舍五入。
*/
public
static
function
coupon
(
$items
,
$total_tip
)
{
if
(
!
is_array
(
$items
)
||
$total_tip
<=
0
)
{
throw
new
\ErrorException
(
'输入分摊条件失败,请确认'
,
'3001'
);
}
$total
=
0
;
foreach
(
$items
as
$k
=>
$price
)
{
if
(
!
is_int
(
$price
)
||
$price
<
0
)
{
throw
new
\ErrorException
(
'存在金额非法,请核对金额'
,
'3002'
);
}
$total
+=
$price
;
}
$ret
=
[];
$cleared
=
$cleared_tip
=
0
;
foreach
(
$items
as
$k
=>
$price
)
{
$left
=
$total
-
$cleared
;
$ret
[
$k
]
=
intval
(
round
(
$price
/
$left
*
(
$total_tip
-
$cleared_tip
)));
$cleared_tip
+=
$ret
[
$k
];
$cleared
+=
$price
;
}
return
$ret
;
}
/**
* @param $mutiArr = [
['goods'=>['a1'=>600, 'a2'=>100, 'a3'=>1300], 'tip'=>100],
['goods'=>['a1'=>600, 'a2'=>600, 'a3'=>600], 'tip'=>4],
];
* @return array = [
['a1' => 30, 'a2' => 5, 'a3' => 65],
['a1' => 1, 'a2' => 2, 'a3' => 1]
];
* @throws \ErrorException
* 批量计算奖励,
*/
public
static
function
batchCoupon
(
$mutiArr
)
{
$ret
=
[];
foreach
(
$mutiArr
as
$k
=>
$item
)
{
$ret
[
$k
]
=
self
::
coupon
(
$item
[
'goods'
],
$item
[
'tip'
]);
}
return
$ret
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment