- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章php版微信js-sdk支付接口类用法示例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了php版微信js-sdk支付接口类用法。分享给大家供大家参考,具体如下:
这个支付类是根据官方的文档修改而来!主要实现生成JS API 、Native的package签名包和Native响应的XML格式数据。注释都标上了各方法的用意。由于package包签名,略复杂,这个要自己多花时间去对应去看和log出文件来一一对比!当然只要你用上教程的类,设置好对应的参数就可以正确的生成package参数等 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
if
(isset(
$argc
) &&
$argc
>= 1 &&
$argv
[0] ==
__FILE__
) {
//初始化pay的必要信息
$pay
=
new
WechatPay(
array
(
WechatPay::APPID =>
'wx99dabzpiuq83985b8'
,
WechatPay::APPSERCER =>
'ac12e7e4abaer63hkoa0cc36a9663fa'
,
WechatPay::PARTNERKEY =>
'bae4sfa3562rsfaq23s2045'
,
WechatPay::PARTNERID =>
'1268969802'
,
WechatPay::PAYSIGNKEY =>
'9Fqsxb3PK4IVOCEc4yCquy5zecS9LeeMjF2Nn4B4YKoOxPwaQdFwMezKT8oNlBYaWcuT'
,
WechatPay::SIGNTYPE =>
'sha1'
,
));
//设置package 必要的参数 jsapi native都通用
$pay
->setParams(WechatPay::BANK_TYPE,
"WX"
);
$pay
->setParams(WechatPay::BODY,
"test"
);
$pay
->setParams(WechatPay::PARTNER,
$pay
->partnerid);
$pay
->setParams(WechatPay::OUT_TRADE_NO, commonUtil::createNoncestr());
$pay
->setParams(WechatPay::TOTAL_FEE,
"1"
);
$pay
->setParams(WechatPay::FEE_TYPE,
"1"
);
$pay
->setParams(WechatPay::TIMESTAMP, time());
$pay
->setParams(WechatPay::NOTIFY_URL,
"http://www.demo.com/notify"
);
$pay
->setParams(WechatPay::SPBILL_CREATE_IP,
"127.0.0.1"
);
$pay
->setParams(WechatPay::INPUT_CHARSET,
"UTF-8"
);
//JSAPI的签名json
print_r(
$pay
->createJsApiPackage());
//生成native XML
print_r(
$pay
->createNativePackage());
//生成native URL
print_r(
$pay
->createNativeUrl(
"9701"
));
}
|
JS API生成的package签名包参数:
1
2
3
4
5
6
7
8
|
{
"appId"
:
"wx9998ff5f4dede5b7"
,
"package"
:
"bank_type=WX&body=test&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=Vf5qsSwtu0hc2loH&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1×tamp=1409295711&total_fee=1&sign=FEE0167BD0D89A88BF6850590EA889B6"
,
"timeStamp"
:1409295711,
"nonceStr"
:
"Vf5qsSwtu0hc2loH"
,
"paySign"
:
"f816264c750923863c370a1739640244b0c2d39c"
,
"signType"
:
"sha1"
}
|
Native 响应的XML格式:
1
2
3
4
5
6
7
8
9
10
11
12
|
<
xml
>
<
AppId
>
<![CDATA[wx9998ff5f4dede5b7]]>
</
AppId
>
<
Package
>
<![CDATA[bank_type=WX&body=test&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fwww.demo.com%2Fnotify&out_trade_no=GDl3what4sALDEAd&partner=wx9998ff5f4dede5b7&spbill_create_ip=127.0.0.1×tamp=1409296124&total_fee=1&sign=BF949B85570644B939B369FD44B0C4A9]]>
</
Package
>
<
TimeStamp
>1409296124</
TimeStamp
>
<
NonceStr
>
<![CDATA[GDl3what4sALDEAd]]>
</
NonceStr
>
<
RetCode
>0</
RetCode
>
<
RetErrMsg
>
<![CDATA[ok]]>
</
RetErrMsg
>
<
AppSignature
>
<![CDATA[ca4a2467b817a62c38a9801fcf451f51692027bf]]>
</
AppSignature
>
<
SignMethod
>
<![CDATA[sha1]]>
</
SignMethod
>
</
xml
>
|
Native的URL链接:
weixin://wxpay/bizpayurl?appid=wx9998ff5f4dede5b7&noncestr=VY7cVA6mtVrc1BVq&productid=9701&sign=43508b65b50e1d7e1089be66d55a709469155d73×tamp=1409296323 。
无论哪一种方式,我们都要通过setParams来设置必要初始化参数和商品价格和状态等! 。
WechatPay class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
<?php
class
WechatPay {
const
BANK_TYPE =
'bank_type'
,
BODY =
'body'
,
PARTNER =
'partner'
,
OUT_TRADE_NO =
'out_trade_no'
,
TIMESTAMP =
'timestamp'
,
TOTAL_FEE =
'total_fee'
,
FEE_TYPE =
'fee_type'
,
NOTIFY_URL =
'notify_url'
,
SPBILL_CREATE_IP =
'spbill_create_ip'
,
INPUT_CHARSET =
'input_charset'
,
APPID =
'appid'
,
APPSERCER =
'appsercer'
,
PAYSIGNKEY =
'appkey'
,
PARTNERID =
'partnerid'
,
PARTNERKEY =
'partnerkey'
,
SIGNTYPE =
'signtype'
;
public
$params
=
array
(),
$partnerid
=
''
;
static
protected
$_instance
;
protected
$_appid
,
$_appkey
,
$_signtype
,
$_partnerkey
,
$_appsercer
;
static
public
function
getInstance(
array
$options
=
array
()) {
if
(
empty
(self::
$_instance
)) {
self::
$_instance
=
new
self (
$options
);
}
return
self::
$_instance
;
}
public
function
__construct(
array
$options
=
array
()){
$this
->_appid =
$options
[self::APPID];
$this
->_appkey =
$options
[self::PAYSIGNKEY];
$this
->_signtype =
$options
[self::SIGNTYPE];
$this
->_partnerkey =
$options
[self::PARTNERKEY];
$this
->_appsercer =
$options
[self::APPSERCER];
$this
->partnerid =
$options
[self::APPID];
}
public
function
setParams(
$param
,
$paramValue
) {
$this
->params[CommonUtil::trimString(
$param
)] = CommonUtil::trimString(
$paramValue
);
}
public
function
getParams(
$param
) {
return
$this
->params[
$param
];
}
protected
function
createNoncestr(
$length
= 16 ) {
$chars
=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
;
$str
=
""
;
for
(
$i
= 0;
$i
<
$length
;
$i
++ ) {
$str
.=
substr
(
$chars
, mt_rand(0,
strlen
(
$chars
)-1), 1);
}
return
$str
;
}
public
function
checkParams(){
//必要的9个参与签名的参数
if
(
$this
->params[self::BANK_TYPE] == null ||
$this
->params[self::BODY] == null ||
$this
->params[self::PARTNER] == null ||
$this
->params[self::OUT_TRADE_NO] == null ||
$this
->params[self::TOTAL_FEE] == null ||
$this
->params[self::FEE_TYPE] == null ||
$this
->params[self::NOTIFY_URL] == null ||
$this
->params[self::SPBILL_CREATE_IP] == null ||
$this
->params[self::INPUT_CHARSET] == null
) {
return
false;
}
return
true;
}
/*
* 生成package包
* @params 初始化类时用setParams方法定义必要的9个参数
* 排序后格式化url query形式 再md5SignUtil类签名,再给合URL
*/
protected
function
getPackageSign(){
try
{
if
(null ==
$this
->_partnerkey ||
""
==
$this
->_partnerkey ) {
throw
new
Exception(
"密钥不能为空!"
.
"<br>"
);
}
$commonUtil
=
new
CommonUtil();
ksort(
$this
->params);
$unSignParaString
=
$commonUtil
->formatUrlQuery(
$this
->params, false);
$paraString
=
$commonUtil
->formatUrlQuery(
$this
->params, true);
$md5SignUtil
=
new
MD5SignUtil();
return
$paraString
.
"&sign="
.
$md5SignUtil
->sign(
$unSignParaString
,commonUtil::trimString(
$this
->_partnerkey));
}
catch
(Exception
$e
) {
echo
(
$e
->getMessage());
}
}
/*
* 生成签名方法
* @params appid appkey package timestamp noncestr 等参数而native事例代码中加上retcode reterrmsg两个参数
*/
public
function
getPaySign(
$signObj
){
foreach
(
$signObj
as
$k
=>
$v
){
$signParams
[
strtolower
(
$k
)] =
$v
;
}
try
{
if
(
$this
->_appkey ==
""
) {
throw
new
Exception(
"APPKEY为空!"
.
"<br>"
);
}
$signParams
[
"appkey"
] =
$this
->_appkey;
ksort(
$signParams
, SORT_STRING);
$commonUtil
=
new
CommonUtil();
$signString
=
$commonUtil
->formatPayUrlQuery(
$signParams
, false);
return
sha1(
$signString
);
}
catch
(Exception
$e
) {
echo
(
$e
->getMessage());
}
}
//JS API 签名 其中nonceStr是作为订单号 灌穿整个支付流程
public
function
createJsApiPackage(){
try
{
if
(
$this
->checkParams() == false) {
throw
new
Exception(
"生成package参数缺失!"
.
"<br>"
);
}
$payObj
[
"appId"
] =
$this
->_appid;
$payObj
[
"package"
] =
$this
->getPackageSign();
$payObj
[
"timeStamp"
] =
$this
->getParams(self::TIMESTAMP);
$payObj
[
"nonceStr"
] =
$this
->getParams(self::OUT_TRADE_NO);
$payObj
[
"paySign"
] =
$this
->getPaySign(
$payObj
);
$payObj
[
"signType"
] =
$this
->_signtype;
return
json_encode(
$payObj
);
}
catch
(Exception
$e
) {
die
(
$e
->getMessage());
}
}
/*
* 构建发货状态数组 主要三个参数openid transid orderid
*/
public
function
createDeliverPost(Array
$params
) {
$deliver
=
array
();
$deliver
[
'appid'
] =
$this
->_appid;
$deliver
[
'openid'
] =
$params
[
'openid'
];
$deliver
[
'transid'
] =
$params
[
'transid'
];
$deliver
[
'out_trade_no'
] =
$params
[
'out_trade_no'
];
$deliver
[
'deliver_timestamp'
] = current_time(
'timestamp'
);
$deliver
[
'deliver_status'
] = 1;
$deliver
[
'deliver_msg'
] =
'OK'
;
$deliver
[
'app_signature'
] =
$this
->getPaySign(
$deliver
);
$deliver
[
'sign_method'
] =
'sha1'
;
return
$deliver
;
}
/*
* 生成扫描或者点击原生URL后,响应的XML格式
* @params $retcode $reterrmsg 定义该商品的状态
*/
public
function
createNativePackage(
$retcode
= 0,
$reterrmsg
=
"ok"
) {
try
{
if
(
$this
->checkParams() == false &&
$retcode
== 0) {
//如果是正常的返回, 检查财付通的参数
throw
new
Exception(
"生成package参数缺失!"
.
"<br>"
);
}
$nativeObj
[
"AppId"
] =
$this
->_appid;
$nativeObj
[
"Package"
] =
$this
->getPackageSign();
$nativeObj
[
"TimeStamp"
] =
$this
->getParams(self::TIMESTAMP);
$nativeObj
[
"NonceStr"
] =
$this
->getParams(self::OUT_TRADE_NO);
$nativeObj
[
"RetCode"
] =
$retcode
;
$nativeObj
[
"RetErrMsg"
] =
$reterrmsg
;
$nativeObj
[
"AppSignature"
] =
$this
->getPaySign(
$nativeObj
);
$nativeObj
[
"SignMethod"
] =
$this
->_signtype;
$commonUtil
=
new
CommonUtil();
$xml
=
$commonUtil
->arrayToXml(
$nativeObj
);
exit
(
$xml
);
}
catch
(Exception
$e
) {
echo
(
$e
->getMessage());
}
}
/*
* 生成原生URL 以订单号为参数 这是灌穿整个支付流程
*/
public
function
createNativeUrl(
$productid
) {
$commonUtil
=
new
CommonUtil();
$nativeObj
[
"appid"
] =
$this
->_appid;
$nativeObj
[
"productid"
] = urlencode(
$productid
);
$nativeObj
[
"timestamp"
] = time();
$nativeObj
[
"nonceStr"
] = commonUtil::createNoncestr();
$nativeObj
[
"sign"
] =
$this
->getPaySign(
$nativeObj
);
$nativeString
=
$commonUtil
->formatPayUrlQuery(
$nativeObj
, false);
return
"weixin://wxpay/bizpayurl?"
.
$nativeString
;
}
/*
* 取IP地址
*/
public
function
getIp(){
switch
(true) {
case
!
empty
(
$_SERVER
[
"HTTP_CLIENT_IP"
]):
$ip
=
$_SERVER
[
"HTTP_CLIENT_IP"
];
break
;
case
!
empty
(
$_SERVER
[
"HTTP_X_FORWARDED_FOR"
]):
$ip
=
$_SERVER
[
"HTTP_X_FORWARDED_FOR"
];
break
;
case
!
empty
(
$_SERVER
[
"REMOTE_ADDR"
]):
$ip
=
$_SERVER
[
"REMOTE_ADDR"
];
break
;
default
:
$ip
=
"127.0.0.1"
;
}
return
$ip
;
}
}
class
MD5SignUtil {
public
function
sign(
$content
,
$key
) {
try
{
if
(null ==
$key
) {
throw
new
Exception(
"财付通签名key不能为空!"
.
"<br>"
);
}
if
(null ==
$content
) {
throw
new
Exception(
"财付通签名内容不能为空"
.
"<br>"
);
}
$signStr
=
$content
.
"&key="
.
$key
;
return
strtoupper
(md5(
$signStr
));
}
catch
(Exception
$e
) {
echo
(
$e
->getMessage());
}
}
public
static
function
verifySignature(
$content
,
$sign
,
$md5Key
) {
$signStr
=
$content
.
"&key="
.
$md5Key
;
$calculateSign
=
strtolower
(md5(
$signStr
));
$tenpaySign
=
strtolower
(
$sign
);
return
$calculateSign
==
$tenpaySign
;
}
}
class
CommonUtil {
public
function
genAllUrl(
$toURL
,
$paras
) {
$allUrl
= null;
if
(null ==
$toURL
) {
die
(
"toURL is null"
);
}
if
(
strripos
(
$toURL
,
"?"
) ==
""
) {
$allUrl
=
$toURL
.
"?"
.
$paras
;
}
else
{
$allUrl
=
$toURL
.
"&"
.
$paras
;
}
return
$allUrl
;
}
//订单号,可根据实际自定义
static
public
function
createOrderNo() {
$nonce
= CommonUtil::createNoncestr(4);
return
strtoupper
(
date
(
'ymds'
).
substr
(microtime(),2,4).
$nonce
);
}
//随机字符串
static
public
function
createNoncestr(
$length
= 16 ) {
$chars
=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
;
$str
=
""
;
for
(
$i
= 0;
$i
<
$length
;
$i
++ ) {
$str
.=
substr
(
$chars
, mt_rand(0,
strlen
(
$chars
)-1), 1);
}
return
$str
;
}
public
function
splitParaStr(
$src
,
$token
) {
$resMap
=
array
();
$items
=
explode
(
$token
,
$src
);
foreach
(
$items
as
$item
){
$paraAndValue
=
explode
(
"="
,
$item
);
if
(
$paraAndValue
!=
""
) {
$resMap
[
$paraAndValue
[0]] =
$paraAndValue
[1];
}
}
return
$resMap
;
}
static
function
trimString(
$value
) {
$ret
= null;
if
(null !=
$value
) {
$ret
=
$value
;
if
(
strlen
(
$ret
) == 0) {
$ret
= null;
}
}
return
$ret
;
}
public
function
formatUrlQuery(
$paraMap
,
$urlencode
) {
$buff
=
""
;
ksort(
$paraMap
, SORT_STRING);
foreach
(
$paraMap
as
$k
=>
$v
) {
if
(null !=
$v
&&
"null"
!=
$v
&&
"sign"
!=
$k
) {
if
(
$urlencode
) {
$v
= urlencode(
$v
);
}
$buff
.=
$k
.
"="
.
$v
.
"&"
;
}
}
$reqPar
=
''
;
if
(
strlen
(
$buff
) > 0) {
$reqPar
=
substr
(
$buff
, 0,
strlen
(
$buff
)-1);
}
return
$reqPar
;
}
public
function
formatPayUrlQuery(
$paraMap
,
$urlencode
) {
$buff
=
""
;
ksort(
$paraMap
, SORT_STRING);
foreach
(
$paraMap
as
$k
=>
$v
) {
if
(
$urlencode
){
$v
= urlencode(
$v
);
}
$buff
.=
strtolower
(
$k
) .
"="
.
$v
.
"&"
;
}
$reqPar
=
''
;
if
(
strlen
(
$buff
) > 0) {
$reqPar
=
substr
(
$buff
, 0,
strlen
(
$buff
)-1);
}
return
$reqPar
;
}
/*
* 输出一级数组的xml格式
*/
public
function
arrayToXml(
$arr
) {
$xml
=
"<xml>"
;
foreach
(
$arr
as
$key
=>
$val
) {
if
(
$key
==
'TimeStamp'
||
$key
==
'RetCode'
) {
$xml
.=
"<"
.
$key
.
">"
.
$val
.
"</"
.
$key
.
">"
;
}
else
$xml
.=
"<"
.
$key
.
"><![CDATA["
.
$val
.
"]]></"
.
$key
.
">"
;
}
$xml
.=
"</xml>"
;
return
$xml
;
}
}
|
希望本文所述对大家PHP程序设计有所帮助.
最后此篇关于php版微信js-sdk支付接口类用法示例的文章就讲到这里了,如果你想了解更多关于php版微信js-sdk支付接口类用法示例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在哪里可以找到有关退款状态的信息? 对于“取消”和“失败”,没关系。但是“已捕获”、“已授权”、“暂停”和“待处理”之间有什么区别。支付宝是什么意思? 谢谢 最佳答案 以下是 Paypal 付款状态列
我想问问是否有人知道无需用户交互即可进行 PayPal 付款的可能性。我目前正在开展一个项目,我们希望在用户无需登录 PayPal 的情况下按需进行 PayPal 付款。 我发现的是: 做引用交易 定
我无法找到 PayPal 提供的关于它如何处理 webhook 以进行支付的文档。付款是否与付款一样对待,以便完成的付款将启动付款完成的 webhook?一般来说,付款和支出是否通过网络 Hook 相
我有一个表单,人们可以在其中以固定金额订购一件商品。以下是步骤: 客户填写表格 客户点击提交并进入评论页面,他可以在其中检查他的输入 在评论表单中应该有一个使用 paypal 支付的按钮(带有自己的设
用了微信sdk各种痛苦,感觉比qq sdk调用麻烦多了,回调过于麻烦,还必须要在指定包名下的actvity进行回调,所以我在这里写一篇博客,有这个需求的朋友可以借鉴一下,以后自己别的项目有用到也有个
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: How to set Azure Max Spending Limit or Cost CAP $ amount?
我正在尝试将 Stripe 集成到 Symfony2 项目上,我在他们的文档中看到的唯一付款方式是“用卡付款”按钮 https://stripe.com/docs/checkout它在我的项目上创建了
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: How to set Azure Max Spending Limit or Cost CAP $ amount?
我想使用 firebase 作为服务器并向 stripe 发送付款请求。我在服务器端的经验为零,所以我正在寻找一种简单的方法来实现这一目标。此帖Is it possible to integrate
我在这里使用自适应 Paypal 支付控制台:https://apigee.com/console/paypal向人们付款。我无法找到一种方法在不授予他们许可的情况下向个人汇款(来 self )。我希
我一直坚持使用 OpenCart 的 PayPal 标准付款,但尚未找到解决方案。 我做了什么: 在 sandbox.paypal.com 上创建了企业帐户 设置以下网络首选项: 自动返回(指定 UR
我想在我的 WPF 应用程序中通过 PayPal 进行购物付款。我想为用户生成一个链接,但不知道如何通知应用程序已接受付款。是否唯一的解决方案将是服务器,它会检查付款是否已被接受并且应用程序会不时轮询
PayPal PayOut REST API 没有记录它的局限性。什么是: 每次付款的最大收款人数? 每次付款的最高金额? 每个收件人的最大金额? 注意: 我查看了在线文档和 paypal 论坛 (
我是 web 开发的新手,我需要做的是创建一个表单,用户可以在其中输入一些东西到一个字段中,让我们暂时称之为名称......然后当他们去 paypal 时,他们会捐赠 1 美元(预定)然后从支付给 P
我正在尝试将 PayPal 集成到我的应用程序中并了解 PayPal SDK 的工作原理我正在使用示例应用程序。我知道在用户按下“购买”按钮后,我需要将授权响应发送到我的服务器以验证付款。问题是我找不
在我的 oscar 应用程序中,django 需要自适应并行 oscar 支付程序。 谁能告诉我如何将 Adaptive Parallel Paypal 方法集成到 Normal Paypal 中。我
您好,我正在开发用于 NFC 支付的安卓应用程序。 Android 设置中有一个选项可以使用打开的应用程序而不是默认应用程序。例如,当我将默认应用程序设置为 Android Pay 并在付款前打开我的
我构建了一个使用命名空间和 PSR-0 自动加载的 PHP 应用程序。在尝试实现 Stripe库,我发现它似乎无法加载类,因为它们没有命名空间。如果我手动包含文件,有没有办法不自动加载? // Get
有人成功地将 Adyen 支付插件集成到 iOS 应用程序中吗? 我到了它向用户显示付款选项的地步,但选择其中一个选项没有任何作用。我希望它会转到表单以捕获卡的详细信息,但事实并非如此。 如有任何帮助
我正在与 Stripe Payment Gateway 集成——API 的最新版本。 除了“client_reference_id”没有传递给 webhook 或事务(没有出现在日志中)之外,这一切都
我是一名优秀的程序员,十分优秀!