Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
J
jwhx
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sugar
jwhx
Commits
fd28a2a0
Commit
fd28a2a0
authored
Dec 21, 2024
by
xieyishang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of
http://rungit.jxdsy.cn:10000/sugar/jwhx
into dev
parents
40a95523
48eec898
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
454 additions
and
15 deletions
+454
-15
config/certs/public_cert_key.pem
config/certs/public_cert_key.pem
+24
-0
config/wechat.php
config/wechat.php
+1
-0
modules/Goods/app/Models/Goods.php
modules/Goods/app/Models/Goods.php
+1
-1
modules/Goods/app/Services/GoodsService.php
modules/Goods/app/Services/GoodsService.php
+2
-0
modules/Goods/database/migrations/2024_07_31_044039_goods_base.php
...oods/database/migrations/2024_07_31_044039_goods_base.php
+1
-0
modules/Member/app/Controllers/Admin/Account.php
modules/Member/app/Controllers/Admin/Account.php
+17
-0
modules/Member/app/Controllers/Admin/Sign.php
modules/Member/app/Controllers/Admin/Sign.php
+27
-0
modules/Member/app/Services/AccountService.php
modules/Member/app/Services/AccountService.php
+20
-9
modules/Member/app/Services/SignService.php
modules/Member/app/Services/SignService.php
+3
-3
modules/Member/database/migrations/2024_08_19_134001_member_extend.php
...r/database/migrations/2024_08_19_134001_member_extend.php
+4
-0
modules/Member/routes/admin.php
modules/Member/routes/admin.php
+4
-0
modules/Order/app/Services/RefundService.php
modules/Order/app/Services/RefundService.php
+2
-1
modules/Wechat/app/Services/PayService.php
modules/Wechat/app/Services/PayService.php
+1
-1
modules/Wechat/app/Services/TransferService.php
modules/Wechat/app/Services/TransferService.php
+156
-0
modules/Wechat/app/Utils/AesUtil.php
modules/Wechat/app/Utils/AesUtil.php
+73
-0
modules/Wechat/app/Utils/WechatUtil.php
modules/Wechat/app/Utils/WechatUtil.php
+117
-0
resources/admin/src/pages/goods/lists/index.vue
resources/admin/src/pages/goods/lists/index.vue
+1
-0
No files found.
config/certs/public_cert_key.pem
0 → 100644
View file @
fd28a2a0
-----BEGIN CERTIFICATE-----
MIIEFDCCAvygAwIBAgIUQg/xTpir1cQyxxIQAZpCI1xWFsYwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjQwODA2MDkxMTU5WhcNMjkwODA1MDkxMTU5WjBuMRgwFgYDVQQDDA9U
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPdcXZvCKERRiBqSic
HyCgj7h6/vJ/ofmPHOsNrxpEcJSKgQH/LkFdb6Ze5I4VwM75Hvg1+GJEECpkFV9r
y8b0NADroG6uBprJZ1FQN/lohYglXeGM60G2deEvw6iXUoebg5ZRm5ISiY+U+A0I
aqF4QvBU9EZBbMQVagMkqbPfEboOn9vZvFoRrCFCqIQScUmE8MsXCPvvmYZm8u9q
vAl5/UXD/HZMTnybUsrQQvxoKyZDJQQgOQPv05zhRoA1vCwidfuZcUD48pSj3IUu
oU34lz8HBKDMDrt0mMTeAoKGW5/jMFkcVDI5v8BKUstnPA44Bv5+3W09zjegmARx
sPNTAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAVaZ+7FM6uSZoyumTYZ5WyWsvDYAcNQl/
oMaq8vRa7MDDi2pWiZGg0g0100vXj+JEwFBGNRck4PQM+iO4BLVPwjHE7d39QI7Z
VtzC3+z4jNEXjJ0hhH/N4PJqkM3k/+DO7UgUMCrwRFZfCBNMqt3MYSbmdAYbPXf7
axfr+vUB9tzyVjZ5LshVSmzN/H1bdvREeg40dPJHftSwGAH2WKwQCODLZQ9uIEFP
zygbj/Tupn+XHptRcpPFmhhOqlQCfMrl85qSsKuDFHaJJuQypLr3p5rN3wdLw4mZ
jjWmd4NAYqW+fm4pW96RMQOAVjba/+xDGNCDleIdJ+5hRxumDL7hcg==
-----END CERTIFICATE-----
\ No newline at end of file
config/wechat.php
View file @
fd28a2a0
...
@@ -25,6 +25,7 @@ return [
...
@@ -25,6 +25,7 @@ return [
// 商户证书
// 商户证书
'private_key'
=>
__DIR__
.
'/certs/apiclient_key.pem'
,
'private_key'
=>
__DIR__
.
'/certs/apiclient_key.pem'
,
'certificate'
=>
__DIR__
.
'/certs/apiclient_cert.pem'
,
'certificate'
=>
__DIR__
.
'/certs/apiclient_cert.pem'
,
'public_key'
=>
__DIR__
.
'/certs/public_cert_key.pem'
,
// v3 API 秘钥
// v3 API 秘钥
'secret_key'
=>
'60ed9440d9077499f0507471c933e563'
,
'secret_key'
=>
'60ed9440d9077499f0507471c933e563'
,
...
...
modules/Goods/app/Models/Goods.php
View file @
fd28a2a0
...
@@ -19,7 +19,7 @@ class Goods extends BaseModel {
...
@@ -19,7 +19,7 @@ class Goods extends BaseModel {
protected
$table
=
'goods'
;
protected
$table
=
'goods'
;
protected
$fillable
=
[
protected
$fillable
=
[
'title'
,
'user_id'
,
'brand_id'
,
'description'
,
'tags'
,
'goods_type'
,
'cover'
,
'images'
,
'price'
,
'original_price'
,
'title'
,
'user_id'
,
'brand_id'
,
'description'
,
'tags'
,
'goods_type'
,
'cover'
,
'images'
,
'price'
,
'original_price'
,
'service_amount'
,
'master_amount'
,
'partner_amount'
,
'is_partner'
,
'operate'
,
'content'
,
'status'
'service_amount'
,
'master_amount'
,
'partner_amount'
,
'is_partner'
,
'operate'
,
'content'
,
'status'
,
'goods_sn'
];
];
// protected $hidden = ['deleted_at'];
// protected $hidden = ['deleted_at'];
...
...
modules/Goods/app/Services/GoodsService.php
View file @
fd28a2a0
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
namespace
Modules\Goods\Services
;
namespace
Modules\Goods\Services
;
use
Illuminate\Support\Arr
;
use
Illuminate\Support\Arr
;
use
Illuminate\Support\Str
;
use
Modules\Goods\Models\Goods
;
use
Modules\Goods\Models\Goods
;
use
App\Support\Tree
;
use
App\Support\Tree
;
...
@@ -118,6 +119,7 @@ class GoodsService {
...
@@ -118,6 +119,7 @@ class GoodsService {
foreach
(
$goods
->
setFilterFields
(
$request
->
all
())
as
$key
=>
$value
)
{
foreach
(
$goods
->
setFilterFields
(
$request
->
all
())
as
$key
=>
$value
)
{
$goods
->
$key
=
$value
;
$goods
->
$key
=
$value
;
}
}
$goods
->
goods_sn
=
date
(
'YmdHis'
)
;
$goods
->
save
();
$goods
->
save
();
//更新栏目
//更新栏目
...
...
modules/Goods/database/migrations/2024_07_31_044039_goods_base.php
View file @
fd28a2a0
...
@@ -46,6 +46,7 @@ return new class extends Migration
...
@@ -46,6 +46,7 @@ return new class extends Migration
$table
->
tinyInteger
(
'status'
)
->
default
(
1
)
->
comment
(
'状态 1上架 0下架'
);
$table
->
tinyInteger
(
'status'
)
->
default
(
1
)
->
comment
(
'状态 1上架 0下架'
);
$table
->
timestamp
(
'created_at'
)
->
nullable
()
->
comment
(
'创建时间'
);
$table
->
timestamp
(
'created_at'
)
->
nullable
()
->
comment
(
'创建时间'
);
$table
->
timestamp
(
'updated_at'
)
->
nullable
()
->
comment
(
'更新时间'
);
$table
->
timestamp
(
'updated_at'
)
->
nullable
()
->
comment
(
'更新时间'
);
$table
->
string
(
'goods_sn'
)
->
nullable
()
->
comment
(
'商品编号'
);
$table
->
engine
=
'InnoDB'
;
$table
->
engine
=
'InnoDB'
;
$table
->
charset
=
'utf8mb4'
;
$table
->
charset
=
'utf8mb4'
;
...
...
modules/Member/app/Controllers/Admin/Account.php
View file @
fd28a2a0
...
@@ -85,4 +85,21 @@ class Account extends BaseController{
...
@@ -85,4 +85,21 @@ class Account extends BaseController{
return
response
()
->
json
(
$this
->
data
);
return
response
()
->
json
(
$this
->
data
);
}
}
/**
* @title 通过提现
*
* @param AccountService $service
* @return void
*/
public
function
withdraw
(
Request
$request
,
AccountService
$service
){
try
{
$this
->
data
[
'data'
]
=
$service
->
withdraw
(
$request
);
}
catch
(
\Throwable
$th
)
{
$this
->
data
[
'code'
]
=
0
;
$this
->
data
[
'message'
]
=
$th
->
getMessage
();
}
return
response
()
->
json
(
$this
->
data
);
}
}
}
\ No newline at end of file
modules/Member/app/Controllers/Admin/Sign.php
0 → 100644
View file @
fd28a2a0
<?php
namespace
Modules\Member\Controllers\Admin
;
use
App\Http\Controllers\BaseController
;
use
Illuminate\Http\Request
;
use
Modules\Member\Services\SignService
;
class
Sign
extends
BaseController
{
/*
* 签到记录
*/
public
function
index
(
Request
$request
,
SignService
$service
){
try
{
$this
->
data
[
'data'
]
=
$service
->
getDataList
(
$request
);
}
catch
(
\Throwable
$th
)
{
$this
->
data
[
'code'
]
=
0
;
$this
->
data
[
'message'
]
=
$th
->
getMessage
();
}
return
response
()
->
json
(
$this
->
data
);
}
}
\ No newline at end of file
modules/Member/app/Services/AccountService.php
View file @
fd28a2a0
...
@@ -10,10 +10,12 @@ namespace Modules\Member\Services;
...
@@ -10,10 +10,12 @@ namespace Modules\Member\Services;
use
Illuminate\Support\Facades\Cache
;
use
Illuminate\Support\Facades\Cache
;
use
Illuminate\Support\Carbon
;
use
Illuminate\Support\Carbon
;
use
Illuminate\Support\Str
;
use
Illuminate\Validation\Rule
;
use
Illuminate\Validation\Rule
;
use
App\Support\Time
;
use
App\Support\Time
;
use
Modules\Member\Models\MemberAccount
;
use
Modules\Member\Models\MemberAccount
;
use
Modules\Member\Models\Member
;
use
Modules\Member\Models\Member
;
use
Modules\Wechat\Services\TransferService
;
class
AccountService
{
class
AccountService
{
...
@@ -241,15 +243,17 @@ class AccountService {
...
@@ -241,15 +243,17 @@ class AccountService {
'order_id'
=>
0
,
'order_id'
=>
0
,
'store_id'
=>
0
,
'store_id'
=>
0
,
'member_id'
=>
$member
[
'uid'
],
'member_id'
=>
$member
[
'uid'
],
'type'
=>
1
,
'amount'
=>
$request
->
input
(
'amount'
),
'amount'
=>
$request
->
input
(
'amount'
),
'type'
=>
'withdraw'
,
'type'
=>
'withdraw'
,
'account_type'
=>
'withdraw'
,
'account_type'
=>
'withdraw'
,
'af_amount'
=>
$member
[
'money'
],
'bf_amount'
=>
bcsub
(
$member
[
'money'
],
$request
->
input
(
'amount'
),
2
),
'fee_rate'
=>
$config
[
'withdraw_fee_rate'
],
'fee_rate'
=>
$config
[
'withdraw_fee_rate'
],
'actual_amount'
=>
bcsub
(
$request
->
input
(
'amount'
),
bcmul
(
$request
->
input
(
'amount'
),
bcdiv
(
$config
[
'withdraw_fee_rate'
],
100
,
2
),
2
),
2
),
'actual_amount'
=>
bcsub
(
$request
->
input
(
'amount'
),
bcmul
(
$request
->
input
(
'amount'
),
bcdiv
(
$config
[
'withdraw_fee_rate'
],
100
,
2
),
2
),
2
),
'pay_type'
=>
$request
->
input
(
'pay_type'
),
'pay_type'
=>
$request
->
input
(
'pay_type'
),
'bank_id'
=>
$request
->
input
(
'bank_id'
,
0
),
'bank_id'
=>
$request
->
input
(
'bank_id'
,
0
),
'status'
=>
0
,
'status'
=>
0
,
'request_no'
=>
str_replace
(
'-'
,
''
,
Str
::
orderedUuid
()),
'remark'
=>
$request
->
input
(
'remark'
,
'用户提现'
),
'remark'
=>
$request
->
input
(
'remark'
,
'用户提现'
),
];
];
...
@@ -260,6 +264,12 @@ class AccountService {
...
@@ -260,6 +264,12 @@ class AccountService {
}
}
$account
->
save
();
$account
->
save
();
//扣除余额
$user
=
Member
::
find
(
$member
[
'uid'
]);
$user
->
money
=
bcsub
(
$user
->
money
,
$request
->
input
(
'amount'
),
2
);
$user
->
save
();
return
$account
;
return
$account
;
}
}
...
@@ -272,17 +282,18 @@ class AccountService {
...
@@ -272,17 +282,18 @@ class AccountService {
throw
new
\Exception
(
"提现记录已处理!"
,
0
);
throw
new
\Exception
(
"提现记录已处理!"
,
0
);
}
}
if
(
$request
->
filled
(
'status'
)){
$member
=
Member
::
where
(
'uid'
,
$account
->
member_id
)
->
first
();
$account
->
status
=
$request
->
input
(
'status'
);
if
(
$request
->
input
(
'status'
)
==
1
){
if
(
$account
->
pay_type
==
"wechat"
){
//
$member
=
Member
::
find
(
$account
->
member_id
);
$result
=
TransferService
::
transfer
(
$account
->
bank_realname
,
$account
->
request_no
,
$account
->
actual_amount
,
$member
[
'username'
]
);
$member
->
money
=
bcsub
(
$member
->
money
,
$account
->
amount
,
2
);
if
(
isset
(
$result
[
'code'
])){
$member
->
save
(
);
throw
new
\Exception
(
'异常:'
.
$result
[
'code'
]
.
' '
.
$result
[
'message'
],
0
);
}
}
}
else
if
(
$account
->
pay_type
==
"bank"
){
throw
new
\Exception
(
"银行卡在开发中!"
,
0
);
}
else
{
throw
new
\Exception
(
"该提现方式不存在!"
,
0
);
}
}
$account
->
save
();
return
$account
;
return
$account
;
}
}
...
...
modules/Member/app/Services/SignService.php
View file @
fd28a2a0
...
@@ -64,14 +64,14 @@ class SignService
...
@@ -64,14 +64,14 @@ class SignService
throw
new
\Exception
(
'用户不存在!'
);
throw
new
\Exception
(
'用户不存在!'
);
}
}
if
(
$config
[
'score'
]){
//送积分
if
(
$config
[
's
ign_s
core'
]){
//送积分
$member
->
score
=
bcadd
(
$member
->
score
,
$config
[
'score'
]);
$member
->
score
=
bcadd
(
$member
->
score
,
$config
[
's
ign_s
core'
]);
$member
->
save
();
$member
->
save
();
}
}
$record
=
new
SignRecord
();
$record
=
new
SignRecord
();
$record
->
member_id
=
$member_id
;
$record
->
member_id
=
$member_id
;
$record
->
score
=
$config
[
'score'
];
$record
->
score
=
$config
[
's
ign_s
core'
];
$record
->
day
=
date
(
'd'
);
$record
->
day
=
date
(
'd'
);
$record
->
month
=
date
(
'Y-m'
);
$record
->
month
=
date
(
'Y-m'
);
$record
->
save
();
$record
->
save
();
...
...
modules/Member/database/migrations/2024_08_19_134001_member_extend.php
View file @
fd28a2a0
...
@@ -65,6 +65,10 @@ return new class extends Migration {
...
@@ -65,6 +65,10 @@ return new class extends Migration {
$table
->
tinyInteger
(
'status'
)
->
default
(
1
)
->
comment
(
'状态 0未用,1已转账,2已提现,3提现记录'
);
$table
->
tinyInteger
(
'status'
)
->
default
(
1
)
->
comment
(
'状态 0未用,1已转账,2已提现,3提现记录'
);
$table
->
timestamp
(
'created_at'
)
->
nullable
()
->
comment
(
'创建时间'
);
$table
->
timestamp
(
'created_at'
)
->
nullable
()
->
comment
(
'创建时间'
);
$table
->
timestamp
(
'updated_at'
)
->
nullable
()
->
comment
(
'更新时间'
);
$table
->
timestamp
(
'updated_at'
)
->
nullable
()
->
comment
(
'更新时间'
);
$table
->
string
(
'bank_realname'
,
255
)
->
nullable
()
->
comment
(
'真实姓名'
);
$table
->
string
(
'reason'
,
255
)
->
nullable
()
->
comment
(
'申请理由'
);
$table
->
string
(
'out_batch_no'
,
255
)
->
nullable
()
->
comment
(
'商家批次单号'
);
$table
->
string
(
'detail_status'
,
255
)
->
nullable
()
->
comment
(
'单号查询状态'
);
$table
->
engine
=
'InnoDB'
;
$table
->
engine
=
'InnoDB'
;
$table
->
charset
=
'utf8mb4'
;
$table
->
charset
=
'utf8mb4'
;
...
...
modules/Member/routes/admin.php
View file @
fd28a2a0
...
@@ -28,6 +28,7 @@ Route::name('member.')->prefix('member')->middleware(['auth.check:admin'])->grou
...
@@ -28,6 +28,7 @@ Route::name('member.')->prefix('member')->middleware(['auth.check:admin'])->grou
Route
::
post
(
'/add'
,
'add'
)
->
name
(
'add'
);
Route
::
post
(
'/add'
,
'add'
)
->
name
(
'add'
);
Route
::
put
(
'/edit'
,
'edit'
)
->
name
(
'edit'
);
Route
::
put
(
'/edit'
,
'edit'
)
->
name
(
'edit'
);
Route
::
delete
(
'/delete'
,
'delete'
)
->
name
(
'delete'
);
Route
::
delete
(
'/delete'
,
'delete'
)
->
name
(
'delete'
);
Route
::
post
(
'/withdraw'
,
'withdraw'
)
->
name
(
'withdraw'
);
});
});
Route
::
controller
(
Modules\Member\Controllers\Admin\Score
::
class
)
->
prefix
(
'score'
)
->
name
(
'score.'
)
->
group
(
function
()
{
Route
::
controller
(
Modules\Member\Controllers\Admin\Score
::
class
)
->
prefix
(
'score'
)
->
name
(
'score.'
)
->
group
(
function
()
{
Route
::
get
(
'/index'
,
'index'
)
->
name
(
'index'
);
Route
::
get
(
'/index'
,
'index'
)
->
name
(
'index'
);
...
@@ -39,4 +40,7 @@ Route::name('member.')->prefix('member')->middleware(['auth.check:admin'])->grou
...
@@ -39,4 +40,7 @@ Route::name('member.')->prefix('member')->middleware(['auth.check:admin'])->grou
Route
::
get
(
'/index'
,
'index'
)
->
name
(
'index'
);
Route
::
get
(
'/index'
,
'index'
)
->
name
(
'index'
);
Route
::
put
(
'/audit'
,
'audit'
)
->
name
(
'audit'
);
Route
::
put
(
'/audit'
,
'audit'
)
->
name
(
'audit'
);
});
});
Route
::
controller
(
Modules\Member\Controllers\Admin\Sign
::
class
)
->
prefix
(
'sign'
)
->
name
(
'sign.'
)
->
group
(
function
()
{
Route
::
get
(
'/index'
,
'index'
)
->
name
(
'index'
);
});
});
});
modules/Order/app/Services/RefundService.php
View file @
fd28a2a0
...
@@ -88,7 +88,8 @@ class RefundService {
...
@@ -88,7 +88,8 @@ class RefundService {
$refund
->
member_id
=
auth
(
'api'
)
->
user
()[
'uid'
];
$refund
->
member_id
=
auth
(
'api'
)
->
user
()[
'uid'
];
$refund
->
status
=
0
;
$refund
->
status
=
0
;
$refund
->
refund_no
=
str_replace
(
'-'
,
''
,
Str
::
orderedUuid
());
$refund
->
refund_no
=
str_replace
(
'-'
,
''
,
Str
::
orderedUuid
());
$refund
->
amount
=
$item
->
total_price
;
$refund
->
amount
=
$item
->
total_price
-
$item
->
total_integral
;
// $refund->amount = $item->total_price;
if
(
$refund
->
save
()){
if
(
$refund
->
save
()){
$item
->
status
=
4
;
$item
->
status
=
4
;
...
...
modules/Wechat/app/Services/PayService.php
View file @
fd28a2a0
...
@@ -40,7 +40,7 @@ class PayService {
...
@@ -40,7 +40,7 @@ class PayService {
$description
=
"订单支付"
;
$description
=
"订单支付"
;
break
;
break
;
}
}
$data
->
amount
=
$data
->
amount
-
$data
->
integral
;
$payData
=
[
$payData
=
[
'mchid'
=>
$config
[
'mch_id'
],
'mchid'
=>
$config
[
'mch_id'
],
'appid'
=>
$config
[
'app_id'
],
'appid'
=>
$config
[
'app_id'
],
...
...
modules/Wechat/app/Services/TransferService.php
0 → 100644
View file @
fd28a2a0
<?php
namespace
Modules\Wechat\Services
;
use
EasyWeChat\Pay\Application
;
use
Illuminate\Support\Facades\Config
;
use
Modules\Wechat\Utils\AesUtil
;
use
Modules\Wechat\Utils\WechatUtil
;
class
TransferService
{
/**
* 商家转账到零钱
* @param $batch_name
* @param $out_trade_no
* @param $money
* @param $openid
* @throws BaseException
*/
public
static
function
transfer
(
$batch_name
,
$out_trade_no
,
$money
,
$openid
,
$body
=
'用户提现'
)
{
$config
=
Config
::
get
(
'wechat.miniapp'
);
$app
=
new
Application
(
$config
);
//获取微信支付平台证书序列号
$certificates
=
self
::
getCertificates
();
$serial_no
=
isset
(
$certificates
[
'data'
][
0
][
'serial_no'
])
?
$certificates
[
'data'
][
0
][
'serial_no'
]
:
null
;
$pars
=
[];
$pars
[
'appid'
]
=
$config
[
'app_id'
];
//直连商户的appid
$pars
[
'out_batch_no'
]
=
'batch'
.
date
(
'Ymd'
)
.
mt_rand
(
1000
,
9999
);
//商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
$pars
[
'batch_name'
]
=
$body
;
//该笔批量转账的名称
$pars
[
'batch_remark'
]
=
$body
;
//转账说明,UTF8编码,最多允许32个字符
$pars
[
'total_amount'
]
=
intval
(
$money
*
100
);
//转账总金额 单位为“分”
$pars
[
'total_num'
]
=
1
;
//转账总笔数
$pars
[
'transfer_detail_list'
][
0
]
=
[
'out_detail_no'
=>
$out_trade_no
,
'transfer_amount'
=>
$pars
[
'total_amount'
],
'transfer_remark'
=>
$body
,
'openid'
=>
$openid
,
'user_name'
=>
WechatUtil
::
getEncrypt
(
$batch_name
,
$config
[
'public_key'
]),
];
//转账明细列表
$pars
[
'notify_url'
]
=
request
()
->
root
()
.
'/api/wechat/notify/transfer'
;
$result
=
$app
->
getClient
()
->
postJson
(
"v3/transfer/batches"
,
$pars
,[
'headers'
=>
[
'Wechatpay-Serial'
=>
$serial_no
,
],
]);
$response
=
json_decode
(
$result
,
true
);
if
(
!
isset
(
$response
[
'create_time'
]))
{
//批次受理失败
return
[
'code'
=>
$response
[
'code'
],
'message'
=>
$response
[
'message'
]];
}
return
$response
;
$out_batch_no
=
$response
->
toArray
()[
'out_batch_no'
];
}
//获取微信支付平台证书序列号与生成公钥文件
public
static
function
getCertificates
(
$http_method
=
"GET"
){
$url
=
"https://api.mch.weixin.qq.com/v3/certificates"
;
$config
=
Config
::
get
(
'wechat.miniapp'
);
$token
=
WechatUtil
::
getToken
(
$url
,
$http_method
,
array
(),
$config
[
'mch_id'
],
$config
[
'certificate'
],
$config
[
'private_key'
]);
$result
=
WechatUtil
::
https_request_transfer
(
$url
,
array
(),
$token
);
$result_arr
=
json_decode
(
$result
,
true
);
if
(
isset
(
$result_arr
[
'data'
])){
$certificate
=
$result_arr
[
'data'
][
0
][
'encrypt_certificate'
];
$AesUtil
=
new
AesUtil
(
$config
[
'secret_key'
]);
$dataDecrypt
=
$AesUtil
->
decryptToString
(
$certificate
[
'associated_data'
],
$certificate
[
'nonce'
],
$certificate
[
'ciphertext'
]);
$publicCertKey
=
fopen
(
$config
[
'public_key'
],
'w'
);
fwrite
(
$publicCertKey
,
$dataDecrypt
);
fclose
(
$publicCertKey
);
}
return
$result_arr
;
}
/**
* 查询商家转账到零钱订单状态
* @param $batch_name
* @param $out_trade_no
* @param $money
* @param $openid
* @throws BaseException
*/
public
function
transferQuery
(
$out_batch_no
,
$out_detail_no
,
$http_method
=
"GET"
)
{
$url
=
'https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/'
.
$out_batch_no
.
'/details/out-detail-no/'
.
$out_detail_no
;
$config
=
Config
::
get
(
'wechat.miniapp'
);
$token
=
WechatUtil
::
getToken
(
$url
,
$http_method
,
array
(),
$config
[
'mch_id'
],
$config
[
'certificate'
],
$config
[
'private_key'
]);
$result
=
WechatUtil
::
https_request_transfer
(
$url
,
array
(),
$token
);
$result_arr
=
json_decode
(
$result
,
true
);
if
(
isset
(
$result_arr
[
'code'
])
&&
!
empty
(
$result_arr
[
'code'
])){
return
[
'code'
=>-
3
,
'message'
=>
$result_arr
[
'message'
],
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
isset
(
$result_arr
[
'fail_reason'
])
&&
!
empty
(
$result_arr
[
'fail_reason'
])){
if
(
$result_arr
[
'fail_reason'
]
===
"ACCOUNT_FROZEN"
){
return
[
'code'
=>-
3
,
'message'
=>
"该用户账户被冻结"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"REAL_NAME_CHECK_FAIL"
){
return
[
'code'
=>-
3
,
'message'
=>
"收款人未实名认证,需要用户完成微信实名认证"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"NAME_NOT_CORRECT"
){
return
[
'code'
=>-
3
,
'message'
=>
"收款人姓名校验不通过,请核实信息"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"OPENID_INVALID"
){
return
[
'code'
=>-
3
,
'message'
=>
"Openid格式错误或者不属于商家公众账号"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"TRANSFER_QUOTA_EXCEED"
){
return
[
'code'
=>-
3
,
'message'
=>
"超过用户单笔收款额度,核实产品设置是否准确"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"DAY_RECEIVED_QUOTA_EXCEED"
){
return
[
'code'
=>-
3
,
'message'
=>
"超过用户单日收款额度,核实产品设置是否准确"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"DAY_RECEIVED_COUNT_EXCEED"
){
return
[
'code'
=>-
3
,
'message'
=>
"超过用户单日收款次数,核实产品设置是否准确"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
if
(
$result_arr
[
'fail_reason'
]
===
"TRANSFER_RISK"
){
return
[
'code'
=>-
3
,
'message'
=>
"该笔转账可能存在风险,已被微信拦截"
,
'fail_reason'
=>
$result_arr
[
'code'
]];
}
else
{
return
[
'code'
=>-
3
,
'message'
=>
$result_arr
[
'fail_reason'
],
'fail_reason'
=>
$result_arr
[
'code'
]];
}
}
return
$result_arr
;
}
}
\ No newline at end of file
modules/Wechat/app/Utils/AesUtil.php
0 → 100644
View file @
fd28a2a0
<?php
namespace
Modules\Wechat\Utils
;
#php证书和回调报文解密
#https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/zheng-shu-he-hui-tiao-bao-wen-jie-mi
use
http\Exception\InvalidArgumentException
;
class
AesUtil
{
/**
* AES key
*
* @var string
*/
private
$aesKey
;
const
KEY_LENGTH_BYTE
=
32
;
const
AUTH_TAG_LENGTH_BYTE
=
16
;
/**
* Constructor
*/
public
function
__construct
(
$aesKey
)
{
if
(
strlen
(
$aesKey
)
!=
self
::
KEY_LENGTH_BYTE
)
{
throw
new
InvalidArgumentException
(
'无效的ApiV3Key,长度应为32个字节'
);
}
$this
->
aesKey
=
$aesKey
;
}
/**
* Decrypt AEAD_AES_256_GCM ciphertext
*
* @param string $associatedData AES GCM additional authentication data
* @param string $nonceStr AES GCM nonce
* @param string $ciphertext AES GCM cipher text
*
* @return string|bool Decrypted string on success or FALSE on failure
*/
public
function
decryptToString
(
$associatedData
,
$nonceStr
,
$ciphertext
)
{
$ciphertext
=
\base64_decode
(
$ciphertext
);
if
(
strlen
(
$ciphertext
)
<=
self
::
AUTH_TAG_LENGTH_BYTE
)
{
return
false
;
}
// ext-sodium (default installed on >= PHP 7.2)
if
(
function_exists
(
'\sodium_crypto_aead_aes256gcm_is_available'
)
&&
\sodium_crypto_aead_aes256gcm_is_available
())
{
return
\sodium_crypto_aead_aes256gcm_decrypt
(
$ciphertext
,
$associatedData
,
$nonceStr
,
$this
->
aesKey
);
}
// ext-libsodium (need install libsodium-php 1.x via pecl)
if
(
function_exists
(
'\Sodium\crypto_aead_aes256gcm_is_available'
)
&&
\Sodium\crypto_aead_aes256gcm_is_available
())
{
return
\Sodium\crypto_aead_aes256gcm_decrypt
(
$ciphertext
,
$associatedData
,
$nonceStr
,
$this
->
aesKey
);
}
// openssl (PHP >= 7.1 support AEAD)
if
(
PHP_VERSION_ID
>=
70100
&&
in_array
(
'aes-256-gcm'
,
\openssl_get_cipher_methods
()))
{
$ctext
=
substr
(
$ciphertext
,
0
,
-
self
::
AUTH_TAG_LENGTH_BYTE
);
$authTag
=
substr
(
$ciphertext
,
-
self
::
AUTH_TAG_LENGTH_BYTE
);
return
\openssl_decrypt
(
$ctext
,
'aes-256-gcm'
,
$this
->
aesKey
,
\OPENSSL_RAW_DATA
,
$nonceStr
,
$authTag
,
$associatedData
);
}
throw
new
\RuntimeException
(
'AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'
);
}
}
\ No newline at end of file
modules/Wechat/app/Utils/WechatUtil.php
0 → 100644
View file @
fd28a2a0
<?php
namespace
Modules\Wechat\Utils
;
class
WechatUtil
{
/**
* @notes 敏感信息加解密
*/
public
static
function
getEncrypt
(
$user_name
,
$cert_path
)
{
//$str是待加密字符串
$public_key
=
file_get_contents
(
$cert_path
);
$encrypted
=
''
;
if
(
openssl_public_encrypt
(
$user_name
,
$encrypted
,
$public_key
,
OPENSSL_PKCS1_OAEP_PADDING
))
{
//base64编码
$sign
=
base64_encode
(
$encrypted
);
}
else
{
throw
new
\Exception
(
'encrypt failed'
);
}
return
$sign
;
}
/**
* 敏感信息解密
* @param $str
* @return string
* @throws Exception
*/
public
static
function
getDecrypt
(
$data
,
$cert_path_key
)
{
$private_key
=
file_get_contents
(
$cert_path_key
);
$encrypted
=
''
;
if
(
openssl_private_decrypt
(
$data
,
$encrypted
,
$private_key
,
OPENSSL_PKCS1_OAEP_PADDING
))
{
//base64编码
$sign
=
$encrypted
;
}
else
{
throw
new
\Exception
(
'解密失败'
);
}
return
$sign
;
}
/**
* @notes 获取签名
*/
public
static
function
getToken
(
$url
,
$http_method
,
$data
,
$mch_id
,
$wxpayCert
,
$wxPayCertKey
)
{
$timestamp
=
time
();
//请求时间戳
$url_parts
=
parse_url
(
$url
);
//获取请求的绝对URL
$nonce
=
$timestamp
.
rand
(
'10000'
,
'99999'
);
//请求随机串
$body
=
empty
(
$data
)
?
''
:
json_encode
((
object
)
$data
);
//请求报文主体
$stream_opts
=
[
"ssl"
=>
[
"verify_peer"
=>
false
,
"verify_peer_name"
=>
false
,
]
];
$apiclient_cert_arr
=
openssl_x509_parse
(
file_get_contents
(
$wxpayCert
,
false
,
stream_context_create
(
$stream_opts
)));
$serial_no
=
$apiclient_cert_arr
[
'serialNumberHex'
];
//证书序列号
$mch_private_key
=
file_get_contents
(
$wxPayCertKey
,
false
,
stream_context_create
(
$stream_opts
));
//密钥
$merchant_id
=
$mch_id
;
//商户id
$canonical_url
=
(
$url_parts
[
'path'
]
.
(
!
empty
(
$url_parts
[
'query'
])
?
"?${url_parts['query']}"
:
""
));
$message
=
$http_method
.
"
\n
"
.
$canonical_url
.
"
\n
"
.
$timestamp
.
"
\n
"
.
$nonce
.
"
\n
"
.
$body
.
"
\n
"
;
openssl_sign
(
$message
,
$raw_sign
,
$mch_private_key
,
'sha256WithRSAEncryption'
);
$sign
=
base64_encode
(
$raw_sign
);
//签名
$schema
=
'WECHATPAY2-SHA256-RSA2048'
;
$token
=
sprintf
(
'mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"'
,
$merchant_id
,
$nonce
,
$timestamp
,
$serial_no
,
$sign
);
//微信返回token
return
$schema
.
' '
.
$token
;
}
/**商家转账到零钱
* @notes 新发送请求
*/
public
static
function
https_request_transfer
(
$url
,
$data
,
$token
,
$serial_no
=
''
)
{
$curl
=
curl_init
();
curl_setopt
(
$curl
,
CURLOPT_URL
,
(
string
)
$url
);
curl_setopt
(
$curl
,
CURLOPT_SSL_VERIFYPEER
,
FALSE
);
curl_setopt
(
$curl
,
CURLOPT_SSL_VERIFYHOST
,
FALSE
);
if
(
!
empty
(
$data
))
{
curl_setopt
(
$curl
,
CURLOPT_POST
,
1
);
curl_setopt
(
$curl
,
CURLOPT_POSTFIELDS
,
$data
);
}
curl_setopt
(
$curl
,
CURLOPT_RETURNTRANSFER
,
1
);
//添加请求头
$headers
=
[
'Authorization:'
.
$token
,
'Wechatpay-Serial: '
.
$serial_no
,
'Accept: application/json'
,
'Content-Type: application/json; charset=utf-8'
,
'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
,
];
if
(
!
empty
(
$headers
))
{
curl_setopt
(
$curl
,
CURLOPT_HTTPHEADER
,
$headers
);
}
$output
=
curl_exec
(
$curl
);
curl_close
(
$curl
);
return
$output
;
}
}
\ No newline at end of file
resources/admin/src/pages/goods/lists/index.vue
View file @
fd28a2a0
...
@@ -60,6 +60,7 @@ export default{
...
@@ -60,6 +60,7 @@ export default{
apiObj
:
this
.
$API
.
goods
.
lists
.
list
,
apiObj
:
this
.
$API
.
goods
.
lists
.
list
,
column
:
[
column
:
[
{
prop
:
'
id
'
,
label
:
'
ID
'
,
width
:
80
},
{
prop
:
'
id
'
,
label
:
'
ID
'
,
width
:
80
},
{
prop
:
'
goods_sn
'
,
label
:
'
商品编号
'
},
{
prop
:
'
title
'
,
label
:
'
商品名称
'
},
{
prop
:
'
title
'
,
label
:
'
商品名称
'
},
{
prop
:
'
cover
'
,
label
:
'
封面图
'
,
width
:
120
},
{
prop
:
'
cover
'
,
label
:
'
封面图
'
,
width
:
120
},
{
prop
:
'
price
'
,
label
:
'
售价
'
,
width
:
120
},
{
prop
:
'
price
'
,
label
:
'
售价
'
,
width
:
120
},
...
...
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