This commit is contained in:
MeSHard
2025-11-10 16:12:07 +08:00
parent 99f88bc53e
commit 94f7e83679
181 changed files with 15770 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/.idea
/.vscode
/vendor
*.log
.env

1
.htaccess Normal file
View File

@@ -0,0 +1 @@

42
.travis.yml Normal file
View File

@@ -0,0 +1,42 @@
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true

1
.user.ini Normal file
View File

@@ -0,0 +1 @@
open_basedir=/www/wwwroot/qianjiang.test/:/tmp/

16
404.html Normal file
View File

@@ -0,0 +1,16 @@
<html>
<style>
.btlink {
color: #20a53a;
text-decoration: none;
}
</style>
<meta charset="UTF-8">
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr>
<div style="text-align: center;font-size: 15px" >Power by <a class="btlink" href="https://www.bt.cn/?from=404" target="_blank">堡塔 (免费,高效和安全的托管控制面板)</a></div>
</body>
</html>

32
LICENSE.txt Normal file
View File

@@ -0,0 +1,32 @@
ThinkPHP遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似鼓励代码共享和尊重原作者的著作权
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1 需要给代码的用户一份Apache Licence
2 如果你修改了代码,需要在被修改的文件中说明;
3 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4 如果再发布的产品中包含一个Notice文件则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可但不可以表现为对Apache Licence构成更改。
具体的协议参考http://www.apache.org/licenses/LICENSE-2.0
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

24
Secret/apiclient_cert.pem Normal file
View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEFDCCAvygAwIBAgIUcs0exYuNylTgN1OxWDReflL7vjkwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjUwODA0MDY0MjI0WhcNMzAwODAzMDY0MjI0WjBuMRgwFgYDVQQDDA9U
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDl9u/PGIJKGPbF17xI
MnjUCnEn4IflbIXLSxdLlGAi4XBrjyllAOxIY7sIGMxfpnULmU6VJV0oI+7/SnWQ
fBX9jdQrucvgRAH80ZpItwwTh76+dSsJZo7TFuHG5vYWc0eo518Zrhf1zh5T0G1e
NUPdV8hTBuu+JKcuWVXmpPEVmBzL5iVx8RnziCBSvC/Fpt1VZd+izwkNGZredsTM
IJdQeU+v4fpgWyVOCISob9B0nvku3d33zckdoDwPqFnVoh1oPzTS2lKYx6NMGW6i
HwV1PJ7DSBSTzE80vwkdavMl17WnJaMzAzcTL99xBCqKjE8EG1dzTqYHaJRwvWhP
TGq7AgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAbVCzA5IewRfqGr3jOBdkFf3bssokI7im
XuXEhXYO3s6xZfma9kIoRTZjVyWXTJnVDMX/w+RM+S799b1jhzvBIzsfU+uwSOH5
uSNyew3FVK15y408bSQDNbjc5X8G48ofRIELKy6vQQkXw+M/lXUmjktriTZazUdt
ukzaCIErQjHR9dCE5GFVa5okLMUU77ct3ArFhC4Dxr7VOZLYLGI4ioJb8wFFcDXU
+J7RPIkE3Ze+/Yx20PEbfO89BHSBXYNe94n9Ug69dm/hu+qZtrVM2EVasDIw6H1F
mrHBYjKmrh2UAl5uLUTbD9poJ2qYEVAIe1FA7fug3ycDV7y8UYKYSQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIUH7Y1TUd7+JzGrQR0TYDd7/ajm6cwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjIxMjExMDgyNzM3WhcNMjcxMjEwMDgyNzM3WjCBgTETMBEGA1UEAwwK
MTYzNTcxOTA4MzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL
DCTph43luobotrPlhbTnva7kuJrogqHku73mnInpmZDlhazlj7gxCzAJBgNVBAYM
AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKUtam4ZW8SsGCbx3aCRKN0L7BRozJ1TnHdIECrppMcQSbxqIhObOQ2o
5UiGW57J1TH8l74F9yQgCAI0ux99Gyp27LCeG7R08HAnthzDtRV5IAQJunG9Fv4Q
7nro/Woy906i9qKvfT5att2XkhoXnIzb8BzzvXcG5U7Bsuw5qRX2DD7HGvr8Yg42
0+wAxWHuqFnZdejEFzFRtvT0mQlmnHfMDo3gs82QIqVKY5EaPffoj8FvnluvH37d
/A/rkPWBRfqBpJKIijXEGdbvYIKIBGXchjrIDl0sen0aS1bAWU7NN54FV328U/D+
4gal8R5UUoiqNgxMtCR9kyqVBzYkjoMCAwEAAaOBgTB/MAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgP4MGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0cnVzLmNv
bS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1
NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEAhPzKzTKIhxRDRJdQ
CQu1AX982goLsHe5jcakCuHThzA0c3hs25iCXE4gIpLPwRr6lwaj9tYYs518xjfk
/HbtvnCHlCu0ZEPau2Y4ffpbq0M0vcU3y7YMnEqZ4qbDiBXCqcgBAz2PoRpJCd5a
580wetHYn3zF4YnbpZR26K8H5JGlEcuWHSyeuZmidtd0WanZwtXUX27f8WYPfhIq
JhsVpIyJCoFS1vvc6XAnJ4tdfgJTUeb0WGRfmqHp9LBB6CZkah/jQ9tcp4RRVntU
oO01aWOof9LTUVRKDpKelvgEsEIDaU5vr8kzpmnFrFA0F2UBX+rPas7zhxzgIl3k
sf4LFQ==
-----END CERTIFICATE-----

28
Secret/apiclient_key.pem Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6OSmgvo266Fe6
M/PJQdsMUTuyxmdpoDQRS9iQShue7liQVy8MJBljM3Xxw63455fDopHPXWpQRk6O
WJoQU9avtUXFlhlS8i52sGiYJKzoUrSWupdOVkxAuuRYgPo72TTUcZfeZA17kSkd
yHhkot4TnlZVhu5ubBhNMPlp0pMgUojxLeTT00hQXBD86zhu0WKyYQ93jifyk13I
LeBjTNMOJrvcr9LJR8f3Fk5bzBbBSwcTS/JViXR1N5hZjTHGDaecYhYcpLQPn/hp
WLb775mbwS9cdx/BvVphdaWb9U8QRz+00fhFvOBGppxZdZ7YQpNfBXjLOcdN4T9j
tHXWc+KbAgMBAAECggEAUvF+7w+whN1TpaXaIXvpmrTbyCbCjLNEPafwj2PSpZk3
bSLH27qAbETRdZtYc5KDcCmKlDfhUFvgRVqFVFxjNOOibf0Kznz74PV1wL4lHV0o
/jGhjsy1LeeQKTNZQSrfcvgdUnpx3uWq0I8nwHsiOs69WV69+ATBVjBIBrA5w5z8
jxNmpk6rCr7ey3dwC4XUi8fs16WtZLZGROkrRh+ze1Wgo1/yYU44+DeGkmQOxhDJ
Vfvx6ki0ieq83nNFve6ZgRyDM9RWjToBSrtY2ARZSDAd6DqrGYXCM5h3zLqgJ/4z
FmyEtHMPc8rS+piEnIMlt86tq6+GNRZnzEH1ECd58QKBgQDljB8ftuAHE9MKmTuq
QtShCdbDuHwE2UGmE5ZC80ursZg6kDznOayZfrrhC++P8JO09lVJKDzGjZVKUBW7
Ic/BuG+vPuFfsJ4E9j2zGeHJMezjRphjzLKT+eOCyQ9bv7G8DTk4SS9lllPa6sUH
JP8+TovRTk5nFcofdkLcrxfHNwKBgQDPrvAGOZ3x2rtIJRUin8WKBip8TTHpMfLZ
7wGXcehobUNGcTnGsqnysGlUWlhQxc9WrzPyhz2R57Xj8W9tpoBhaVKkdvIxnDNf
9vexXJjlnWcktFvWUYq3Tt5ImFPeEW+eK4m1Qs2tbNxsGqir3Mzqf7rEq/guYcK2
l6yOl/IpvQKBgHFZkfztJw8XoPz40devjKPA4gZf0Q3r4lkKDwcccN9loRA6LXjY
p/xb8hgy9qcTWzze7xpi/i/ltjSt+y0e8yJr2uqkmFHSOxWkKq+INlBNkPZh49pU
OFKN8OSiOC1MKY380aaTrQ3y/5F4oLZ4dHnl+3DtxBVvUxHaKgYjiBBdAoGAH6X1
98zh79A4R/c2sE8OqEjmQoj0+Sdeba2JXY3DL96uqNZqSohBc7VEZ9FYsf5i6T/L
t8K6NDjONA0/wMLlv3JwYJWrtLmr7ozRFBsbRapl5GcDs7Y7YFHJd+CWrzmS+9SA
qLmkZDA5qtOpLn94TqfmS0A1ksPdCzwz1Ir9ITUCgYEAsRSlbFVAESL3ztFvFXqi
acvuYKpiIcBrKN2YrxvhEoT9splS98hDqIibfBCCFmModdX++kIOOfjfc7mZLNt6
uF9gHexgIa1KNI9bykFVT1XlCzBpm+C6hdMjp0Ya5pR88KYAsjOGBrlNUfpSvUn+
QTrLtSXCSC0mYsspfrQjNLA=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClLWpuGVvErBgm
8d2gkSjdC+wUaMydU5x3SBAq6aTHEEm8aiITmzkNqOVIhlueydUx/Je+BfckIAgC
NLsffRsqduywnhu0dPBwJ7Ycw7UVeSAECbpxvRb+EO566P1qMvdOovair30+Wrbd
l5IaF5yM2/Ac8713BuVOwbLsOakV9gw+xxr6/GIONtPsAMVh7qhZ2XXoxBcxUbb0
9JkJZpx3zA6N4LPNkCKlSmORGj336I/Bb55brx9+3fwP65D1gUX6gaSSiIo1xBnW
72CCiARl3IY6yA5dLHp9GktWwFlOzTeeBVd9vFPw/uIGpfEeVFKIqjYMTLQkfZMq
lQc2JI6DAgMBAAECggEAd8h1lB4jpH5AjY18cUKTZamNrEdLixPlNcM2pkgFTK6N
Kmu1Bo7cUwGWNH/q1T38s2FAEXd1/+aSqDbhNDafiq3vey1NXhIngs3pjPaHzWin
RQZhBLZhhCF3L/7iNy96lLYtMVEd/CgA0LVoKC/TQXsFp5lCXpzLkc96F0DBU8CN
9ZKvVQLakgi6tKeZMKazSSIojJQypRCeayfbXGh8CEpkrYk0qm0wz/VYy8wLmdIP
2IzYU8gCrl+U55OzXzjSh0xJ+TQyEwOnq0xpui//siYUJ7aIppiUo5EqOMljSoEy
EZ3TwVjbIhMKP/2ejG9GHQrfCo288JxPtFm43wUooQKBgQDZEfie3482p7k6RDHi
BunvyDIBFSy9nwzg8z9khg9cTXNb0LWhDnTx2nswlBTfAGtJsW/QoWIU0bFb2m9x
4LbhXmq7JxR7mUxQRSJl8a4N2ujOjIyEXnvOQ4cIb2DMRHPORAZmL2EeoDB3Z1Vx
uH5TdNtE/YgiSPcKFN5wIS5xewKBgQDCzPdPTbxPhIIT7BNJe5M/r3oXvk93Kz1J
bitfN0tw5gWA5HVMZ+YuNhYoPdD8H+7mGogT9vOO6eEJA4FiYuImIBkaRzvC0Pdp
esR5KuAM6uim5bXHZSri6HoNtOzWzdhebF1OoG7QCH8lijt3O0XGTTv0JFIOEaSB
IXhALrV0mQKBgQCU+Mlot0LBHrB3NXAKj/YisoDmz1JqPGqJQ0dBROPr09eUrpLI
GnTVuryKpUYBmXcIFzcGtorqgNK4mBudyruXxcV39aUQAjAmcpvd3NQ3/AGEJ18U
RQewkhVtC4siBOR5LaQ6os+DRiqc95TjO9uuiOcm3Nx9sxefmpzh1VPbWwKBgE88
EagHJX5uln5F+v5brmQsGwxHU4lUZCRXFHsxQZVVao2n33JJnJ3VUCPkKPo0fvbH
eews+Zp61RbWfy0mrXf2fF9s9Ajk+I3F6t6iKun2LtWb/9lv9AbBqsuieOdSaRzX
FQjjRs+FdTouxMtVp6bmSWmf0GR6lqATnhb1KMeZAoGBALDJs/BAbATJw+0VywNr
VAVaxOwo56RHQhhsunlB38zOmyIfqORRFf763I4XJO6vqPwyB4gAPeZnhK00MNZM
Gj3S2e/6Rk15IHBIwHtohVThohVkfHxi+Ur6g2uPcLmmqDDs0JYa5rb2F1jmZyqB
day2luUTLrEgyN9C7l3485xS
-----END PRIVATE KEY-----

1
Secret/serial_no.txt Normal file
View File

@@ -0,0 +1 @@
72CD1EC58B8DCA54E03753B158345E7E52FBBE39

View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID3DCCAsSgAwIBAgIUVAQmj1R5uFWRh/1boS5cYUiOe7wwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjIxMjExMDgyNzM2WhcNMjcxMjEwMDgyNzM2WjBuMRgwFgYDVQQDDA9U
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbalMD21zc8eQ9wDs6
r1IVx8ZazD+qX2JWpW/dq4f4vOlyf+sUuvge1t30yA9zjzb93RORdsgBc2kxyS7v
6oXGU69xWstg5WNUKzokpWTYIZm+g5hZsV4KaoFuFfCQ6NrvwgwVbGZNhmuHodeo
ZoWdyo0lEynnHMVEFl5AzCWAehovLDCIsQjYH/z5CzFjBDlmAKDXE+cqanGmKD80
ux7B2jKhaFVXa3VBW3vVjLkpyGWLmvvqpW9cMWI/YAH+W7kCNsG9Ukz6ZppF7CIn
//RmTyIXIdzrsO6hsfzWgsp17Bz/367DjJoxc61iksq4EThF4cMLOXwQ/9dsFbQ+
feyXAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DBlBgNVHR8EXjBc
MFqgWKBWhlRodHRwOi8vZXZjYS5pdHJ1cy5jb20uY24vcHVibGljL2l0cnVzY3Js
P0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJ
KoZIhvcNAQELBQADggEBADd25dsExQ5bZpHOBHFu+lariGlYZIMpOjPIG4nHEfVO
J4fbBwtDocO413qM++ZsiZnSR6JxUhbsupDRM6sWazksYzt2eBrcFJ4PhGvOlObM
pj6PLlPpUKfMfnTFeaM2NNnwLcw63mWVOf63l7NSIGHsdrsjiBk1xrCr8HQQWkJN
jTvwBbhumkkS1kRa6B4lVv8MXQzZ/p5CVUAsJ7sneWynsZYKpJnihSxjDZx7e88X
THv3AeWH6JJTE+x5K06hUjb0v2UeTY6c7kM8Akzx1scvG78GXMcXtl93sqI6T142
pK9rNs3NbvQ9XyckXSeOLahDJlzzNMBLjxeWVbqET9g=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClLWpuGVvErBgm
8d2gkSjdC+wUaMydU5x3SBAq6aTHEEm8aiITmzkNqOVIhlueydUx/Je+BfckIAgC
NLsffRsqduywnhu0dPBwJ7Ycw7UVeSAECbpxvRb+EO566P1qMvdOovair30+Wrbd
l5IaF5yM2/Ac8713BuVOwbLsOakV9gw+xxr6/GIONtPsAMVh7qhZ2XXoxBcxUbb0
9JkJZpx3zA6N4LPNkCKlSmORGj336I/Bb55brx9+3fwP65D1gUX6gaSSiIo1xBnW
72CCiARl3IY6yA5dLHp9GktWwFlOzTeeBVd9vFPw/uIGpfEeVFKIqjYMTLQkfZMq
lQc2JI6DAgMBAAECggEAd8h1lB4jpH5AjY18cUKTZamNrEdLixPlNcM2pkgFTK6N
Kmu1Bo7cUwGWNH/q1T38s2FAEXd1/+aSqDbhNDafiq3vey1NXhIngs3pjPaHzWin
RQZhBLZhhCF3L/7iNy96lLYtMVEd/CgA0LVoKC/TQXsFp5lCXpzLkc96F0DBU8CN
9ZKvVQLakgi6tKeZMKazSSIojJQypRCeayfbXGh8CEpkrYk0qm0wz/VYy8wLmdIP
2IzYU8gCrl+U55OzXzjSh0xJ+TQyEwOnq0xpui//siYUJ7aIppiUo5EqOMljSoEy
EZ3TwVjbIhMKP/2ejG9GHQrfCo288JxPtFm43wUooQKBgQDZEfie3482p7k6RDHi
BunvyDIBFSy9nwzg8z9khg9cTXNb0LWhDnTx2nswlBTfAGtJsW/QoWIU0bFb2m9x
4LbhXmq7JxR7mUxQRSJl8a4N2ujOjIyEXnvOQ4cIb2DMRHPORAZmL2EeoDB3Z1Vx
uH5TdNtE/YgiSPcKFN5wIS5xewKBgQDCzPdPTbxPhIIT7BNJe5M/r3oXvk93Kz1J
bitfN0tw5gWA5HVMZ+YuNhYoPdD8H+7mGogT9vOO6eEJA4FiYuImIBkaRzvC0Pdp
esR5KuAM6uim5bXHZSri6HoNtOzWzdhebF1OoG7QCH8lijt3O0XGTTv0JFIOEaSB
IXhALrV0mQKBgQCU+Mlot0LBHrB3NXAKj/YisoDmz1JqPGqJQ0dBROPr09eUrpLI
GnTVuryKpUYBmXcIFzcGtorqgNK4mBudyruXxcV39aUQAjAmcpvd3NQ3/AGEJ18U
RQewkhVtC4siBOR5LaQ6os+DRiqc95TjO9uuiOcm3Nx9sxefmpzh1VPbWwKBgE88
EagHJX5uln5F+v5brmQsGwxHU4lUZCRXFHsxQZVVao2n33JJnJ3VUCPkKPo0fvbH
eews+Zp61RbWfy0mrXf2fF9s9Ajk+I3F6t6iKun2LtWb/9lv9AbBqsuieOdSaRzX
FQjjRs+FdTouxMtVp6bmSWmf0GR6lqATnhb1KMeZAoGBALDJs/BAbATJw+0VywNr
VAVaxOwo56RHQhhsunlB38zOmyIfqORRFf763I4XJO6vqPwyB4gAPeZnhK00MNZM
Gj3S2e/6Rk15IHBIwHtohVThohVkfHxi+Ur6g2uPcLmmqDDs0JYa5rb2F1jmZyqB
day2luUTLrEgyN9C7l3485xS
-----END PRIVATE KEY-----

View File

@@ -0,0 +1 @@
72CD1EC58B8DCA54E03753B158345E7E52FBBE39

1
app/.htaccess Normal file
View File

@@ -0,0 +1 @@
deny from all

22
app/AppService.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
declare (strict_types = 1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}

94
app/BaseController.php Normal file
View File

@@ -0,0 +1,94 @@
<?php
declare (strict_types = 1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}

58
app/ExceptionHandle.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

8
app/Request.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}

View File

@@ -0,0 +1,67 @@
<?php
namespace app\command;
use app\controller\Bus\PlugCharge;
use app\controller\HardMessage;
use DateTime;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;
// 引入数据库操作
class ReservationTask extends Command
{
protected function configure()
{
$this->setName('reservation:task')->setDescription('Execute the reservation charging task');
}
protected function execute(Input $input, Output $output)
{
// 在这里可以使用 $this->param1 和 $this->param2 作为传递的参数
// $EquipAuthSeq = $this->param1;
// $ConnectorID = $this->param2;
// ... 其他代码
// $hard = new HardMessage();
$currentDate = new DateTime();
$todayDate = $currentDate->format('Y-m-d H:i:s');
$nowDay = $currentDate->format('Y-m-d');
$PlugOrder = Db::table('appointment')->whereDay('plug_time', $nowDay)->where('plug_time', '<=', $todayDate)->where('IsExec', 1)->select();
if (!$PlugOrder->isEmpty()) {
foreach ($PlugOrder as $order) {
$plug = new PlugCharge();
$orderZu = Db::table('charge_order_gongjiao')->whereDay('charge_date', $nowDay)->where('ConnectorID', $order['ConnectorID'])->where('EvcInfoNo', $order['Vin'])->where('Status', 'in', [2, 3])->find();
$status = Db::table('charge_pile')->where('ConnectorID', $order['ConnectorID'])->value('status');
if (!empty($orderZu)) {
Db::table('appointment')->where('id', $order['id'])->save(['IsExec' => 2]);
Log::write('Reservation tasks executed successfully. But The ConnectorID status has charged', 'info');
} elseif ($status == 3) {
Db::table('appointment')->where('id', $order['id'])->save(['IsExec' => 2]);
Log::write('Reservation tasks executed successfully. But The ConnectorID status has charged', 'info');
} else {
$message = $plug->PlugGennerateOrder($order['ConnectorID'], $order['Vin']);
if ($message['code'] == 200) {
Db::table('appointment')->where('id', $order['id'])->save(['IsExec' => 2]);
Log::write('Reservation tasks executed successfully.', 'info');
$output->writeln('Reservation tasks executed successfully.');
} elseif ($message['code'] == 2) {
Db::table('appointment')->where('id', $order['id'])->save(['IsExec' => 2]);
Log::write('Reservation tasks executed successfully. But The ConnectorID has charged', 'info');
} else {
$output->writeln('Reservation tasks executed successfully But StartChargeFailed. The Reason:' . $message['message']);
Log::write('Reservation tasks executed successfully But StartChargeFailed. The Reason:' . $message['message']);
}
}
}
} else {
$output->writeln('Reservation tasks executed successfully But PlugOrderIsEmpty.');
Log::write('Reservation tasks executed successfully But PlugOrderIsEmpty.');
}
}
}

23
app/command/TestTask.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace app\command;
use app\controller\Bus\PlugCharge;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;
class TestTask extends Command
{
protected function configure()
{
$this->setName('test:task')->setDescription('Execute the reservation charging task');
}
protected function execute(Input $input, Output $output)
{
Db::table('test')->save(['number' => 1, 'message' => time()]);
}
}

341
app/common.php Normal file
View File

@@ -0,0 +1,341 @@
<?php
// 应用公共文件
namespace app;
use app\controller\Aes;
use app\controller\HMACMD5;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class common
{
function generate_order($length)
{
$chars = '0123456789';
$time = time();
$password = 'DZZS' . $time;
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
function generate_EquipmentAuth($length)
{
$chars = '0123456789';
$time = time();
$password = config('hard.OperatorID') . $time . '1';//1代表是生成的设备认证流水号
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
function generate_StartChargeSeq($length)
{
$chars = '0123456789';
$time = time();
$password = config('hard.OperatorID') . $time . '2';//2代表是生成的充电订单号
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
function returnFree($dian, $fu)
{
$time = date('H:i', time());
// 计算当前电费
$dian_1 = '0.00';
$ElectricityFee = str_replace('电费:', '', $dian);
$Elect = explode(',', $ElectricityFee);
$dian_arr = [];
for ($index = 0; $index < count($Elect); $index++) {
$dian_arr[$index]['time_interval'] = substr($Elect[$index], 0, 11);
$start_time = substr($Elect[$index], 0, 5);
$end_time = substr($Elect[$index], 6, 5);
$dian_arr[$index]['price'] = substr($Elect[$index], 12, 4);
$dian_arr[$index]['dian_1'] = '';
if ($start_time < $time && $end_time > $time) {
$dian_arr[$index]['dian_1'] = explode(':', $Elect[$index])[3];
$dian_1 = explode(':', $Elect[$index])[3];
}
}
// 计算服务费
$fu_1 = '0.00';
$ServiceFee = str_replace('服务费:', '', $fu);
$Elect = explode(',', $ServiceFee);
$fu_arr = [];
for ($index = 0; $index < count($Elect); $index++) {
$fu_arr[$index]['time_interval'] = substr($Elect[$index], 0, 11);
$start_time = substr($Elect[$index], 0, 5);
$end_time = substr($Elect[$index], 6, 5);
$fu_arr[$index]['price'] = substr($Elect[$index], 12, 4);
$fu_arr[$index]['fu_1'] = '';
if ($start_time < $time && $end_time > $time) {
$fu_arr[$index]['dian_1'] = explode(':', $Elect[$index])[3];
$fu_1 = explode(':', $Elect[$index])[3];
}
}
foreach ($dian_arr as $key => &$value) {
$value['dian_1'] = false;
$start_time = substr($value['time_interval'], 0, 5);
$end_time = substr($value['time_interval'], 6, 5);
if ($start_time < $time && $end_time > $time) {
$value['dian_1'] = true;
}
foreach ($fu_arr as $kk => $vv) {
if ($value['time_interval'] == $vv['time_interval']) {
$value['price'] = number_format((double)$value['price'], 4);
$value['fu_price'] = number_format((double)$vv['price'], 4);
$value['total_price'] = number_format($vv['price'] + $value['price'], 4);
} else {
continue;
}
}
}
return ['time_price' => number_format($dian_1 + $fu_1, 4), 'price_list' => $dian_arr];
}
function getMonthDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 4; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next monday', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
function getSeasonDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 2; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next month', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
function getYearDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 11; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next month', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
function getDayDate($date)
{
$date_t = array();
$date_t[] = $date;
$this_date = strtotime($date);
$end_date = date("Y-m-d H:i:s", strtotime('+4 hour -1 second', $this_date));
$date_end[] = $end_date;
for ($i = 0; $i < 5; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d H:i:s", strtotime('+4 hour', $this_date));
$this_date_end = strtotime($end_date);
$next_date_end = date("Y-m-d H:i:s", strtotime('+4 hour', $this_date_end));
$date_end[] = $next_date_end;
$date_t[] = $next_date;
$date = $next_date;
$next_date_end = date("Y-m-d H:59:59", strtotime($next_date_end));
$end_date = $next_date_end;
}
$kk['start_time'] = $date_t;
$kk['end_time'] = $date_end;
return $kk;
}
function getDistance($lat1, $lng1, $lat2, $lng2)
{
$earthRadius = 6367000;
$lat1 = ($lat1 * pi()) / 180;
$lng1 = ($lng1 * pi()) / 180;
$lat2 = ($lat2 * pi()) / 180;
$lng2 = ($lng2 * pi()) / 180;
$calcLongitude = $lng2 - $lng1;
$calcLatitude = $lat2 - $lat1;
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
$calculatedDistance = $earthRadius * $stepTwo;
return round($calculatedDistance / 1000, 2);
}
function Encrypt($data)
{
$aes = new Aes();
return $aes->encrypt($data);
}
function Decrypt($data)
{
$aes = new Aes();
return $aes->decrypt($data);
}
function HmacMD5($data)
{
$md5 = new HMACMD5();
return $md5->HMAC($data);
}
function CurlSend($url, $data = '', $token = '')
{
$data = json_encode($data);
// echo $data;
$ch = curl_init();
$headers = array();
if ($token) {
$headers[] = 'Authorization: Bearer ' . $token;
}
$headers[] = 'Content-Type: application/json;charset=utf-8';
$headers[] = 'Content-Length: ' . strlen($data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$curl_return = curl_exec($ch);
curl_close($ch);
return json_decode(trim($curl_return), true);
}
function checkParams($params)
{
$arr = ['OperatorID', 'Data', 'TimeStamp', 'Seq', 'Sig'];
// 参数检查
foreach ($arr as $v) {
if (empty($params[$v])) {
return $v;
}
}
return 2;
}
function checkSig($OperatorID, $params)
{
$sig = $OperatorID . $params['Data'] . $params['TimeStamp'] . $params['Seq'];
$ecry_sig = $this->HmacMD5($sig);
if ($params['Sig'] != $ecry_sig) {
return 1;
}
return 2;
}
function signToken()
{
$key = config('hard.DataSecretIV'); //这里是自定义的一个随机字串应该写在config文件中的解密时也会用相当 于加密中常用的 盐 salt
$token = array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 1, //在什么时候jwt开始生效 这里表示生成100秒后才生效
"exp" => time() + 7200, //token 过期时间
"data" => [ //记录的userid的信息这里是自已添加上去的如果有其它信息可以再添加数组的键值对
'name' => 'zuxing'
]
);
// print_r($token);
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
//验证token
function checkToken_assess($token)
{
$key = config('hard.DataSecretIV');
$key = new Key($key, 'HS256');
$status = array("code" => 2);
try {
JWT::$leeway = 60;//当前时间减去60把时间留点余地
$decoded = JWT::decode($token, $key, array('HS256')); //HS256方式这里要和签发的时候对应
$arr = (array)$decoded;
$res['code'] = 1;
$res['data'] = $arr['data'];
return 2;
} catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return 1;
} catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token失效";
return 1;
} catch (\Firebase\JWT\ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return 1;
} catch (\Exception $e) { //其他错误
$status['msg'] = "未知错误";
return 1;
}
}
function encodeData($data, $params, $ret, $msg = '')
{
$data = json_encode($data);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $params['OperatorID'] . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => $msg, 'Ret' => $ret, 'Data' => $data, 'Sig' => $s]);
}
function generate_password($length)
{
$chars = '0123456789';
$time = time();
$password = config('hard.OperatorID') . $time;
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
}

249
app/controller/Admin.php Normal file
View File

@@ -0,0 +1,249 @@
<?php
declare (strict_types=1);
namespace app\controller;
use app\model\Access;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Validate;
use think\Request;
use app\validate\Admin as AdminValidate;
use app\model\Admin as AdminModel;
class Admin
{
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$list = AdminModel:: paginate([
'list_rows' => 5,
'query' => request()->param()
]);
return json($list);
}
public function admin_all()
{
$list = AdminModel::select();
return json($list);
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
//
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return string|\think\Response
*/
private function PasswordStrongEnough($password)
{
$error = "";
if (strlen($password) < 10) {
$error .= "密码至少为10位";
return $error;
}
if (!preg_match("/[a-z]/", $password)) {
$error .= "密码至少包含一个小写字母";
return $error;
}
if (!preg_match("/[A-Z]/", $password)) {
$error .= "密码至少包含一个大写字母";
return $error;
}
if (!preg_match("/[0-9]/", $password)) {
$error .= "密码至少包含一个数字";
return $error;
}
if (!preg_match("/[.!@#$%]/", $password)) {
$error .= "密码至少包含:(.!@#$%)其中一个符号";
return $error;
}
}
public function save(Request $request)
{
$data = $request->param();
$username = $data['username'];
$nickname = $data['nickname'];
$password = $data['password'];
$email = $data['email'];
$phone = $data['phone'];
$passwordStrengthErrors = $this->PasswordStrongEnough($password);
if (!empty($passwordStrengthErrors)) {
return json(['code' => 1, 'message' => '密码强度不足,' . $passwordStrengthErrors]);
}
$id = AdminModel::where('username', $username)->value('id');
if (empty($id)) {
AdminModel::create([
'username' => $username,
'password' => $password,
'nickname' => $nickname,
'email' => $email,
'phone' => $phone
]);
return json(['code' => 200, 'message' => '注册成功']);
} else {
return json(['code' => 1, 'message' => '用户名已存在']);
}
}
/**
* 显示指定的资源
*
* @return \think\Response
*/
public function read(Request $request)
{
$data = $request->param();
$message = "'%" . $data['message'] . "%'";
$list = Db::table('admin')->whereRaw('(username like' . $message . ' or nickname like' . $message . ' or email like' . $message . ' or phone like' . $message . ' or roles like ' . $message . ')')->paginate(20);
return json($list);
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
}
/**
* 保存更新的资源
*
* @param \think\Request $request
*
* @return \think\Response
*/
public function update(Request $request): \think\Response
{
$data = $request->param();
$validate = Validate::rule([
'username' => 'require|min:2|max:10|chsDash|unique:admin',
//'__token__' => 'require|token',
'nickname' => 'require|min:2|max:10|chsDas',
'password' => 'require|min:6',
'email' => 'require|email|unique:admin',
'phone' => 'require|number|length:11|unique:admin'
]);
try {
$validate->batch(true)->check($request->param());
} catch (ValidateException $exception) {
return json(['code' => 1, 'massage' => $exception->getError()]);
}
$id = AdminModel::where('username', $data['username'])->value('id');
if (!empty($id)) {
AdminModel::update([
'nickname' => $data['nickname'],
'password' => $data['password'],
'email' => $data['email'],
'phone' => $data['phone'],
'roles' => $data['roles']
], ['id' => $id]);
return json(['code' => 200, 'massage' => '修改成功']);
} else {
return json(['code' => 1, 'massage' => '用户不存在']);
}
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete(Request $request)
{
$data = $request->param();
$username = $data['username'];
$id = AdminModel::where('username', $username)->value('id');
if ($id != null) {
$result = AdminModel::destroy($id);
if ($result) {
return json(['code' => 200, 'massage' => '删除成功']);
} else {
return json(['code' => 1, 'massage' => '删除失败']);
}
} else {
return json(['code' => 1, 'massage' => '该管理员不存在']);
}
}
public function update_password(Request $request)
{
$data = $request->param();
$phone = $data['phone'];
$id = AdminModel::where(['username' => $data['username'], 'phone' => $phone])->find()->getData('id');
if (!empty($id)) {
$password = $data['password'];
$result = AdminModel::where('id', $id)->update(['password' => $password]);
if ($result == 0) {
return json(['code' => 1, 'message' => '手机号或用户名错误!']);
} else {
return json(['code' => 200, 'message' => '已成功修改密码']);
}
}
}
public function change_password(Request $request)
{
$data = $request->param();
$username = $data['username'];
$old_password = $data['old_password'];
$id = AdminModel::where(['username' => $username, 'password' => $old_password])->value('id');
if (!empty($id)) {
$new_password = $data['new_password'];
$result = AdminModel::where('id', $id)->update(['password' => $new_password]);
if ($result == 1) {
return json(['code' => 200, 'message' => '已成功修改密码']);
}
} else {
return json(['code' => 1, 'message' => '原始密码不正确']);
}
}
public function UpdatePermission($admin_id, $permission = array())
{
if (empty($permission)) {
$pp = Db::table('admin')->where('id', $admin_id)->value('permission');
if (!empty($pp)) {
$pp = explode(',', substr($pp, 0, -1));
} else {
$pp = array();
}
$username = Db::table('admin')->where('id', $admin_id)->value('username');
return json(['code' => 200, 'msg' => 'Query OK', 'data' => ['admin_id' => $admin_id, 'adminName' => $username, 'permission' => $pp]]);
} else {
$pstr = '';
foreach ($permission as $pp) {
$pstr .= $pp . ',';
}
Db::table('admin')->where('id', $admin_id)->save(['permission' => $pstr]);
$pp = explode(',', substr($pstr, 0, -1));
return json(['code' => 200, 'msg' => 'Update OK', 'data' => ['permission' => $pp]]);
}
}
}

18
app/controller/Aes.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
namespace app\controller;
class Aes
{
public function encrypt($input)
{
return base64_encode(openssl_encrypt($input, 'AES-128-CBC', config('hard.DataSecret'), OPENSSL_RAW_DATA, config('hard.DataSecretIV')));
}
public function decrypt($input)
{
return openssl_decrypt(base64_decode($input), 'AES-128-CBC', config('hard.DataSecret'), OPENSSL_RAW_DATA, config('hard.DataSecretIV'));
}
}

91
app/controller/Auth.php Normal file
View File

@@ -0,0 +1,91 @@
<?php
declare (strict_types=1);
namespace app\controller;
use app\model\Access;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Validate;
use think\Request;
use app\validate\Admin as AdminValidate;
use app\model\Admin as AdminModel;
// 新系统接口都整合在此文件夹 企业在Enterprise.phpEnterpriseCar.phpEnterpriseUser.php
class Auth
{
// 权限
public function getRoleList(){
$where = [];
$list = Db::table('zxc_role')
->paginate([
'list_rows' => 20,
'query' => request()->param()
]);
return json($list);
}
// 菜单
public function getMenuList(){
$list = Db::table('zxc_menu')->where('pid',0)->select()->toArray();
foreach ($list as $key=>&$value){
$value['title'] = $value['name'];
$value['children'] = Db::table('zxc_menu')->where('pid',$value['id'])->select()->toArray();
if(!empty($value['children'])){
foreach ($value['children'] as $kk =>&$vv){
$vv['title'] = $vv['name'];
}
}
}
return json($list);
}
// 优惠券相关
public function getCouponList(){
$where = [];
$list = Db::table('zxc_coupon')
->paginate([
'list_rows' => 20,
'query' => request()->param()
]);
return json($list);
}
// 获取日志
public function getLogList(){
$where = [];
$list = Db::table('system_request_logs')
->order('id desc')
->paginate([
'list_rows' => 20,
'query' => request()->param()
]);
return json($list);
}
//运营数据
public function getYunYingData(){
return json([]);
}
//财务数据
public function getCaiWuData(){
$where = [];
$list = Db::table('zxc_user_money_log')
->order('id desc')
->paginate([
'list_rows' => 20,
'query' => request()->param()
]);
$typeMap = [
'1'=>'充电订单',
'2'=>'充值',
'3'=>'提现'
];
$list->each(function($item, $key) use ($typeMap) {
$item['type_text'] = $typeMap[$item['type']];
return $item;
});
return json($list);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace app\controller\Bus;
use think\facade\Db;
class AlterBalance
{
public function ChangeSpecialUserBalance(): \think\response\Json
{
$save = Db::table("user_gongjiao")->where("openid", "o-wLg5DGWU_rYwfmp1-1Wck1lKGw")->save(["account" => 99999.00]);
if ((int)$save == 1) {
return json(["code" => 200, "msg" => "修改成功"]);
} else {
return json(["code" => 404, "msg" => "修改失败"]);
}
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace app\controller\Bus;
use app\controller\utils;
use app\model\Vinlicense;
use think\db\exception\DbException;
use think\facade\Db;
class BusBill extends utils
{
/**
* @throws DbException
*/
public function DataStatistics($start_time, $end_time): \think\response\Json
{
$DateWithMess = [];
$message = Vinlicense::column('EvcInfoNo');
$date = $this->getDateFromRange($start_time, $end_time);
$i = 0;
foreach (array_unique($message) as $a) {
$DateWithMess[$i]['序号'] = $i + 1;
// $DateWithMess[$i]['EvcInfoNo'] = $a;
$DateWithMess[$i]['车牌号'] = Vinlicense::where("EvcInfoNo", $a)->value("ParkNo");
$DateWithMess[$i]['车号'] = Vinlicense::where("EvcInfoNo", $a)->value("SelfCode");
$TotalCharge = 0;
foreach ($date as $d) {
$TotalPower = Db::table("charge_order_gongjiao")->where('EvcInfoNo', $a)->whereDay('charge_date', $d)->sum('TotalPower');
$TotalCharge += $TotalPower;
$DateWithMess[$i][$d] = round($TotalPower, 3);
}
$DateWithMess[$i]['充电电量(度)'] = round($TotalCharge, 3);
$DateWithMess[$i]['充电电费(元)'] = round(Db::table("charge_order_gongjiao")->where('EvcInfoNo', $a)->whereBetweenTime('charge_date', $start_time, $end_time)->sum('ElecMoney'), 2);
if ($DateWithMess[$i]['充电电量(度)'] != 0) {
$DateWithMess[$i]['平均电费'] = round($DateWithMess[$i]['充电电费(元)'] / $DateWithMess[$i]['充电电量(度)'], 3);
}
$charge_pile_number = Db::table("charge_order_gongjiao")->where('EvcInfoNo', $a)->value("Equipment_number");
$ddd = Db::table("charge_pile,charge_station")->where('charge_pile_number', $charge_pile_number)->where("charge_pile.charge_station_id=charge_station.charge_station_id")->value("charge_station_number");
$DateWithMess[$i]['充电服务费单价(元)'] = $this->Fee($ddd, "o-wLg5DGWU_rYwfmp1-1Wck1lKGw")['ServiceFee'][0]['univalence'];
$DateWithMess[$i]['充电服务费(元)'] = round(Db::table("charge_order_gongjiao")->where('EvcInfoNo', $a)->whereBetweenTime('charge_date', $start_time, $end_time)->sum('SeviceMoney'), 2);
$DateWithMess[$i]['充电费用(元)'] = round(Db::table("charge_order_gongjiao")->where('EvcInfoNo', $a)->whereBetweenTime('charge_date', $start_time, $end_time)->sum('TotalMoney'), 2);
$i += 1;
}
return $this->ResponseJson($DateWithMess, 200, "Request Success");
}
}

View File

@@ -0,0 +1,350 @@
<?php
namespace app\controller\Bus;
use app\controller\Aes;
use app\controller\HardMessage;
use app\controller\HMACMD5;
use app\model\ChargeOrder as ChargeOrderModel;
use app\model\Vinlicense;
use app\Request;
use DateInterval;
use DateTime;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;
use think\facade\Log;
class PlugCharge
{
public function insert_start_charge(Request $request)
{
$params = file_get_contents('php://input');
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2)
return json(['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]]);
if ($auth) {
if ($this->checkToken_assess($auth) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => 'Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$checkSig = $this->checkSig($params['OperatorID'], $params);
if ($checkSig == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误', 'Ret' => 4001, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
$data = json_decode($data, true);
if (isset($data['vin']) && isset($data['connectorID'])) {
Log::write("The Plug Message come on :" . $data['vin'] . $data['connectorID']);
$CheckVinIsExist = Db::table('vinlicense')->where('EvcInfoNo', $data['vin'])->find();
if (!empty($CheckVinIsExist)) {
$AppointmentTime = Db::table('appointment_time')->where('id', 1)->value('AppointmentTime');
$currentDate = new DateTime();
$combinedDateTime = new DateTime($currentDate->format('Y-m-d') . ' ' . $AppointmentTime);
$AppointmentTime = $combinedDateTime->format('Y-m-d H:i:s');
$nowTime = $currentDate->format('Y-m-d H:i:s');
$nowDay = $currentDate->format('Y-m-d');
$check = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->where('ConnectorID', $data['connectorID'])->find();
if (empty($check)) {
Db::table('appointment')->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID'], 'Vin' => $data['vin'], 'plug_time' => $AppointmentTime]);
}
// $check = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->find();
// if (empty($check)) {
// Db::table('appointment')->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID'], 'Vin' => $data['vin'], 'plug_time' => $AppointmentTime]);
// } else {
// $checkVin = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->value('ConnectorID');
// if ($checkVin != $data['connectorID']) {
// Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID']]);
// }
// }
}
$kk['SuccStat'] = 0;
$kk['FailReason'] = 0;
return $this->encodeData($kk, $params, 0);
} else {
$kk['SuccStat'] = 1;
$kk['FailReason'] = 1;
return $this->encodeData($kk, $params, 0);
}
}
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
// $OperatorID = Config::get('hard.OperatorID');
// $OperatorSecret = Config::get('hard.OperatorSecret');
}
public function PlugGennerateOrder($ConnectorID, $vin): array
{
$station_id = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('charge_station_id');
$EquipAuthSeq = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('EquipAuthSeq');
$no = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('no');
if (empty($EquipAuthSeq)) {
$EquipAuthSeq = $this->generate_EquipmentAuth(7);
Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->update(['EquipAuthSeq' => $EquipAuthSeq]);
}
$Hard = new HardMessage();
$openid = 'o-wLg5DGWU_rYwfmp1-1Wck1lKGw';
$area = Db::table('user')->where('openid', $openid)->value('area');
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s, array(' ' => ''));
$table = 'charge_order_' . $s;
$table_user = 'user_' . $s;
$AuthMessage = $Hard->Get_query_equip_auth($EquipAuthSeq, $ConnectorID);
if (isset($AuthMessage['FailReason']) && isset($AuthMessage['SuccStat'])) {//认证成功 请求启动充电
if ($AuthMessage['FailReason'] == 0 && $AuthMessage['SuccStat'] == 0) {
$StartChargeSeq = $this->generate_StartChargeSeq(7);
ChargeOrderModel::insert(['openid' => $openid, 'area' => $area, 'StartChargeSeq' => $StartChargeSeq]);
$ChargeModel = 1;
$StartCharge = $Hard->Get_query_start_charge_test($StartChargeSeq, $ConnectorID, 'QRCode', $ChargeModel, $vin); //ChargeModel vin
if ($StartCharge['StartChargeSeqStat'] == 1 && $StartCharge['SuccStat'] == 0 && $StartCharge['FailReason'] == 0) {
$order_number = $this->generate_order(6);
$charge_date = date('Y-m-d', time());
$account = 200;
$Equipment_number = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('charge_pile_number');
$mess = [
'order_number' => $order_number,
'charge_station_id' => $station_id,
'openid' => $openid,
'charge_date' => $charge_date,
'Equipment_number' => $Equipment_number,
'StartChargeSeq' => $StartChargeSeq,
'status' => $StartCharge['StartChargeSeqStat'],
'StartChargeSeqStat' => $StartCharge['StartChargeSeqStat'],
'ConnectorID' => $ConnectorID,
'WithholdingMoney' => $account,
'EvcInfoNo' => $vin
];
Db::table($table_user)->where('openid', $openid)->update(['account' => Db::raw('account-' . $account)]);
Db::table($table)->save($mess);
$time = date('Y-m-d H:i:s');
Log::write('Reservation order has been generated. The Message is ' . $time . json($mess)->getContent());
return ['code' => 200, 'message' => '订单创建成功', 'order_number' => $order_number];
} elseif ($StartCharge['SuccStat'] == 1) {
if ($StartCharge['FailReason'] == 0) {
return ['code' => 1, 'message' => '设备认证操作结果失败'];
} elseif ($StartCharge['FailReason'] == 1) {
return ['code' => 1, 'message' => '设备认证操作结果失败 此设备不存在'];
} elseif ($StartCharge['FailReason'] == 2) {
return ['code' => 1, 'message' => '设备认证操作结果失败 此设备离线'];
} elseif ($StartCharge['FailReason'] == 90) {
return ['code' => 1, 'message' => '设备认证操作结果失败 车辆未备案'];
} elseif ($StartCharge['FailReason'] == 91) {
return ['code' => 2, 'message' => '设备认证操作结果失败 该车辆充电中'];
} else {
return ['code' => 1, 'message' => '未知错误 设备认证成功 请求充电失败'];
}
} else {
return ['code' => 1, 'message' => '未知错误 设备认证成功 请求充电失败'];
}
} elseif ($AuthMessage['SuccStat'] == 1) {
if ($AuthMessage['FailReason'] == 0) {
return ['code' => 1, 'message' => '设备认证操作结果失败'];
} elseif ($AuthMessage['FailReason'] == 1) {
return ['code' => 1, 'message' => '设备认证操作结果失败 此设备尚未插枪'];
} elseif ($AuthMessage['FailReason'] == 2) {
return ['code' => 1, 'message' => '设备认证操作结果失败 设备检测失败'];
} else {
return ['code' => 1, 'message' => '未知错误 设备认证失败'];
}
} else {
return ['code' => 1, ' message' => '未知错误 设备认证失败'];
}
} else {
return ['code' => 1, 'message' => '未知错误 设备认证失败'];
}
}
public function ModifyAppointmentTime($time): \think\response\Json
{
$dateTime = new DateTime($time);
$formattedTime = $dateTime->format('H:i:s');
$modify = Db::table('appointment_time')->where('id', 1)->save(['AppointmentTime' => $formattedTime]);
if ((int)$modify == 1) {
return json(['code' => 200, 'msg' => '修改成功']);
} else {
return json(['code' => 1, 'msg' => '修改失败']);
}
}
public function ShowAppointmentTime(): \think\response\Json
{
$AppointmentTime = Db::table('appointment_time')->where('id', 1)->value('AppointmentTime');
return json(['code' => 200, 'msg' => '显示成功', 'data' => $AppointmentTime]);
}
private function generate_StartChargeSeq($length): string
{
$chars = '0123456789';
$time = time();
$password = config('hard.OperatorID') . $time . '2';//2代表是生成的充电订单号
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
private function generate_order($length): string
{
$chars = '0123456789';
$time = time();
$password = 'DZZS' . $time;
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
private function generate_EquipmentAuth($length): string
{
$chars = '0123456789';
$time = time();
$password = config('hard.OperatorID') . $time . '1';//1代表是生成的设备认证流水号
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
public function Encrypt($data): string
{
$aes = new Aes();
return $aes->encrypt($data);
}
private function Decrypt($data)
{
$aes = new Aes();
return $aes->decrypt($data);
}
private function HmacMD5($data): string
{
$md5 = new HMACMD5();
return $md5->HMAC($data);
}
private function CurlSend($url, $data = '', $token = '')
{
$data = json_encode($data);
// echo $data;
$ch = curl_init();
$headers = array();
if ($token) {
$headers[] = 'Authorization: Bearer ' . $token;
}
$headers[] = 'Content-Type: application/json;charset=utf-8';
$headers[] = 'Content-Length: ' . strlen($data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$curl_return = curl_exec($ch);
curl_close($ch);
return json_decode(trim($curl_return), true);
}
private function checkParams($params)
{
$arr = ['OperatorID', 'Data', 'TimeStamp', 'Seq', 'Sig'];
// 参数检查
foreach ($arr as $v) {
if (empty($params[$v])) {
return $v;
}
}
return 2;
}
private function checkSig($OperatorID, $params): int
{
$sig = $OperatorID . $params['Data'] . $params['TimeStamp'] . $params['Seq'];
$ecry_sig = $this->HmacMD5($sig);
if ($params['Sig'] != $ecry_sig) {
return 1;
}
return 2;
}
public function signToken(): string
{
$key = config('hard.DataSecretIV'); //这里是自定义的一个随机字串应该写在config文件中的解密时也会用相当 于加密中常用的 盐 salt
$token = array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 1, //在什么时候jwt开始生效 这里表示生成100秒后才生效
"exp" => time() + 7200, //token 过期时间
"data" => [ //记录的userid的信息这里是自已添加上去的如果有其它信息可以再添加数组的键值对
'name' => 'zuxing'
]
);
// print_r($token);
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
//验证token
private function checkToken_assess($token): int
{
$key = config('hard.DataSecretIV');
$key = new Key($key, 'HS256');
$status = array("code" => 2);
try {
JWT::$leeway = 60;//当前时间减去60把时间留点余地
$decoded = JWT::decode($token, $key, array('HS256')); //HS256方式这里要和签发的时候对应
$arr = (array)$decoded;
$res['code'] = 1;
$res['data'] = $arr['data'];
return 2;
} catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return 1;
} catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token失效";
return 1;
} catch (\Firebase\JWT\ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return 1;
} catch (\Exception $e) { //其他错误
$status['msg'] = "未知错误";
return 1;
}
}
private function encodeData($data, $params, $ret, $msg = ''): \think\response\Json
{
$data = json_encode($data);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $params['OperatorID'] . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => $msg, 'Ret' => $ret, 'Data' => $data, 'Sig' => $s]);
}
}

View File

@@ -0,0 +1,207 @@
<?php
namespace app\controller\Bus;
use app\controller\ChargeOrder;
use app\model\Vinlicense;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
class SearchMessage
{
/**
* @throws DataNotFoundException
* @throws ModelNotFoundException
* @throws DbException
*/
public function BusOrder($message = "", $start_time = "", $end_time = ""): \think\response\Json
{
// $order = new ChargeOrder();
// $order->OrderList("o-wLg5DGWU_rYwfmp1-1Wck1lKGw");
if (!empty($end_time)) {
$end_time = date("Y-m-d", strtotime("+1day", strtotime($end_time)));
}
$busOrder = ["code" => 9001, "Msg" => "请输入正确的参数"];
if (empty($message) && empty($start_time) && empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->select();
} elseif (!empty($message) && empty($start_time) && empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->where('order_number', 'like', '%' . $message . '%')->select();
} elseif (empty($message) && !empty($start_time) && !empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->whereBetweenTime('start_time', $start_time, $end_time)->select();
} elseif (!empty($message) && !empty($start_time) && !empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->where('order_number', 'like', '%' . $message . '%')->whereBetweenTime('start_time', $start_time, $end_time)->select();
}
$busOrder = $busOrder->toArray();
for ($i = 0; $i < count($busOrder); $i++) {
if (!isset($busOrder['code'])) {
$busOrder[$i]["order_id"] = $i + 1;
$busOrder[$i]["charge_station_name"] = Db::table("charge_station")->where("charge_station_id", $busOrder[$i]["charge_station_id"])->value("charge_station_name");
$busOrder[$i]["charge_station_number"] = Db::table("charge_station")->where("charge_station_id", $busOrder[$i]["charge_station_id"])->value("charge_station_number");
$busOrder[$i]["no"] = Db::table("charge_pile")->where("charge_pile_number", $busOrder[$i]["Equipment_number"])->value("no");
$busOrder[$i]["parkNo"] = Vinlicense::where("EvcInfoNo", $busOrder[$i]["EvcInfoNo"])->value("ParkNo");
$busOrder[$i]["SelfCode"] = Vinlicense::where("EvcInfoNo", $busOrder[$i]["EvcInfoNo"])->value("SelfCode");
if ($busOrder[$i]["IdentCode"] == 7) {
$busOrder[$i]["IdentCode"] = '设备异常';
} elseif ($busOrder[$i]["IdentCode"] == 15) {
$busOrder[$i]["IdentCode"] = '系统异常';
}
if (strlen((string)$busOrder[$i]['stop_type']) != 0 && $busOrder[$i]['stop_type'] == 0) {
$busOrder[$i]['stop_type'] = '正常停止';
} elseif ($busOrder[$i]['stop_type'] == 4) {
$busOrder[$i]['stop_type'] = '连接器断开';
} elseif ($busOrder[$i]['stop_type'] == 5) {
$busOrder[$i]['stop_type'] = '电池已充满';
} elseif ($busOrder[$i]['stop_type'] == 7) {
$busOrder[$i]['stop_type'] = '设备异常';
} elseif ($busOrder[$i]['stop_type'] == 8) {
$busOrder[$i]['stop_type'] = '枪头被拔下';
} elseif ($busOrder[$i]['stop_type'] == 10) {
$busOrder[$i]['stop_type'] = '设备故障';
} elseif ($busOrder[$i]['stop_type'] == 11) {
$busOrder[$i]['stop_type'] = '车辆故障';
} elseif ($busOrder[$i]['stop_type'] == 14) {
$busOrder[$i]['stop_type'] = '未知';
} elseif ($busOrder[$i]['stop_type'] == 15) {
$busOrder[$i]['stop_type'] = '系统异常';
} elseif ($busOrder[$i]['stop_type'] == 22) {
$busOrder[$i]['stop_type'] = '车辆识别失败';
} elseif ($busOrder[$i]['stop_type'] == 24) {
$busOrder[$i]['stop_type'] = '设备终止';
} elseif ($busOrder[$i]['stop_type'] == 25) {
$busOrder[$i]['stop_type'] = '互联互通终止';
} elseif ($busOrder[$i]['stop_type'] == 26) {
$busOrder[$i]['stop_type'] = '平台终止';
} elseif ($busOrder[$i]['stop_type'] == 27) {
$busOrder[$i]['stop_type'] = 'SOC限制终止';
} elseif ($busOrder[$i]['stop_type'] == 13) {
$busOrder[$i]['stop_type'] = '急停按钮被按下';
} elseif ($busOrder[$i]['stop_type'] == 16) {
$busOrder[$i]['stop_type'] = '主动防护';
} elseif ($busOrder[$i]['stop_type'] == 6) {
$busOrder[$i]['stop_type'] = 'BMS异常';
} elseif ($busOrder[$i]['stop_type'] == 12) {
$busOrder[$i]['stop_type'] = '账户余额不足';
} elseif ($busOrder[$i]['stop_type'] == 31) {
$busOrder[$i]['stop_type'] = '操作频繁,请稍后再试';
} elseif ($busOrder[$i]['stop_type'] == 32) {
$busOrder[$i]['stop_type'] = '请重新插枪启动充电';
} elseif ($busOrder[$i]['stop_type'] == 33) {
$busOrder[$i]['stop_type'] = '账户超出限额';
} elseif (strlen((string)$busOrder[$i]['stop_type']) == 0) {
$busOrder[$i]['stop_type'] = null;
} else {
$busOrder[$i]['stop_type'] = '未知错误';
}
}
}
return json($busOrder);
}
public function BusOrderPark($start_time = "", $end_time = "", $parkNo = ""): \think\response\Json
{
// $order = new ChargeOrder();
// $order->OrderList("o-wLg5DGWU_rYwfmp1-1Wck1lKGw");
if (!empty($end_time)) {
$end_time = date("Y-m-d", strtotime("+1day", strtotime($end_time)));
}
$busOrder = ["code" => 9001, "Msg" => "请输入正确的参数"];
if (empty($parkNo) && empty($start_time) && empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->select();
} elseif (!empty($parkNo) && empty($start_time) && empty($end_time)) {
$vin = Vinlicense::where("ParkNo", $parkNo)->value("EvcInfoNo");
if (empty($vin)) {
$vin = "NotFound";
}
$busOrder = Db::table("charge_order_gongjiao")->where('EvcInfoNo', $vin)->select();
} elseif (empty($parkNo) && !empty($start_time) && !empty($end_time)) {
$busOrder = Db::table("charge_order_gongjiao")->whereBetweenTime('start_time', $start_time, $end_time)->select();
} elseif (!empty($parkNo) && !empty($start_time) && !empty($end_time)) {
$vin = Vinlicense::where("ParkNo", $parkNo)->value("EvcInfoNo");
if (empty($vin)) {
$vin = "NotFound";
}
$busOrder = Db::table("charge_order_gongjiao")->where('EvcInfoNo', $vin)->whereBetweenTime('start_time', $start_time, $end_time)->select();
}
$busOrder = $busOrder->toArray();
for ($i = 0; $i < count($busOrder); $i++) {
if (!isset($busOrder['code'])) {
$busOrder[$i]["order_id"] = $i + 1;
$busOrder[$i]["charge_station_name"] = Db::table("charge_station")->where("charge_station_id", $busOrder[$i]["charge_station_id"])->value("charge_station_name");
$busOrder[$i]["charge_station_number"] = Db::table("charge_station")->where("charge_station_id", $busOrder[$i]["charge_station_id"])->value("charge_station_number");
$busOrder[$i]["no"] = Db::table("charge_pile")->where("charge_pile_number", $busOrder[$i]["Equipment_number"])->value("no");
$busOrder[$i]["parkNo"] = Vinlicense::where("EvcInfoNo", $busOrder[$i]["EvcInfoNo"])->value("ParkNo");
$busOrder[$i]["SelfCode"] = Vinlicense::where("EvcInfoNo", $busOrder[$i]["EvcInfoNo"])->value("SelfCode");
if ($busOrder[$i]["IdentCode"] == 7) {
$busOrder[$i]["IdentCode"] = '设备异常';
} elseif ($busOrder[$i]["IdentCode"] == 15) {
$busOrder[$i]["IdentCode"] = '系统异常';
}
if (strlen((string)$busOrder[$i]['stop_type']) != 0 && $busOrder[$i]['stop_type'] == 0) {
$busOrder[$i]['stop_type'] = '正常停止';
} elseif ($busOrder[$i]['stop_type'] == 4) {
$busOrder[$i]['stop_type'] = '连接器断开';
} elseif ($busOrder[$i]['stop_type'] == 5) {
$busOrder[$i]['stop_type'] = '电池已充满';
} elseif ($busOrder[$i]['stop_type'] == 7) {
$busOrder[$i]['stop_type'] = '设备异常';
} elseif ($busOrder[$i]['stop_type'] == 8) {
$busOrder[$i]['stop_type'] = '枪头被拔下';
} elseif ($busOrder[$i]['stop_type'] == 10) {
$busOrder[$i]['stop_type'] = '设备故障';
} elseif ($busOrder[$i]['stop_type'] == 11) {
$busOrder[$i]['stop_type'] = '车辆故障';
} elseif ($busOrder[$i]['stop_type'] == 14) {
$busOrder[$i]['stop_type'] = '未知';
} elseif ($busOrder[$i]['stop_type'] == 15) {
$busOrder[$i]['stop_type'] = '系统异常';
} elseif ($busOrder[$i]['stop_type'] == 22) {
$busOrder[$i]['stop_type'] = '车辆识别失败';
} elseif ($busOrder[$i]['stop_type'] == 24) {
$busOrder[$i]['stop_type'] = '设备终止';
} elseif ($busOrder[$i]['stop_type'] == 25) {
$busOrder[$i]['stop_type'] = '互联互通终止';
} elseif ($busOrder[$i]['stop_type'] == 26) {
$busOrder[$i]['stop_type'] = '平台终止';
} elseif ($busOrder[$i]['stop_type'] == 27) {
$busOrder[$i]['stop_type'] = 'SOC限制终止';
} elseif ($busOrder[$i]['stop_type'] == 13) {
$busOrder[$i]['stop_type'] = '急停按钮被按下';
} elseif ($busOrder[$i]['stop_type'] == 16) {
$busOrder[$i]['stop_type'] = '主动防护';
} elseif ($busOrder[$i]['stop_type'] == 6) {
$busOrder[$i]['stop_type'] = 'BMS异常';
} elseif ($busOrder[$i]['stop_type'] == 12) {
$busOrder[$i]['stop_type'] = '账户余额不足';
} elseif ($busOrder[$i]['stop_type'] == 31) {
$busOrder[$i]['stop_type'] = '操作频繁,请稍后再试';
} elseif ($busOrder[$i]['stop_type'] == 32) {
$busOrder[$i]['stop_type'] = '请重新插枪启动充电';
} elseif ($busOrder[$i]['stop_type'] == 33) {
$busOrder[$i]['stop_type'] = '账户超出限额';
} elseif (strlen((string)$busOrder[$i]['stop_type']) == 0) {
$busOrder[$i]['stop_type'] = null;
} else {
$busOrder[$i]['stop_type'] = '未知错误';
}
}
}
return json($busOrder);
}
public function ParkNo(): \think\response\Json
{
$Park = (new \app\model\Vinlicense)->column("ParkNo");
$data = [];
foreach ($Park as $p) {
$data["children"][]["LicenseNumber"] = $p;
}
return json($data);
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace app\controller\Bus;
use app\controller\utils;
use app\model\Vinlicense;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
class VinBindLicense extends utils
{
public function ShowVinLicense($parkNo = ""): \think\response\Json
{
if (!empty($parkNo)) {
$vin = Vinlicense::where("ParkNo", $parkNo)->value("EvcInfoNo");
$VinLicense = Vinlicense::where("EvcInfoNo", $vin)->select();
return $this->ResponseJson($VinLicense, 200, "Request Success");
}
$VinLicense = Vinlicense::select();
return $this->ResponseJson($VinLicense, 200, "Request Success");
}
/**
* @throws ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
*/
public function AddVinLicense($vin, $parkNo, $selfCode): \think\response\Json
{
$checkVin = Vinlicense::where("EvcInfoNo", $vin)->find();
$checkLicense = Vinlicense::where("ParkNo", $parkNo)->find();
$checkSelfCode = Vinlicense::where("SelfCode", $selfCode)->find();
if (empty($checkVin) && empty($checkLicense) && empty($checkSelfCode)) {
$AddVinLicense = (new \app\model\Vinlicense)->save([
"EvcInfoNo" => $vin,
'ParkNo' => $parkNo,
"SelfCode" => $selfCode
]);
if ($AddVinLicense == 1) {
$NewVinLicense = Vinlicense::where("EvcInfoNo", $vin)->select();
return $this->ResponseJson($NewVinLicense, 200, "新增成功");
} else {
return $this->ResponseJson([], 415, "新增失败");
}
} else {
return $this->ResponseJson([], 416, "Vin或车牌号已存在");
}
}
/**
* @throws ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
*/
public function UpdateVinLicense($id, $vin, $parkNo, $selfCode): \think\response\Json
{
$oldVin = Vinlicense::where("id", $id)->value('EvcInfoNo');
$oldParkNo = Vinlicense::where("id", $id)->value('ParkNo');
$oldSelfCode = Vinlicense::where("id", $id)->value('ParkNo');
if ($oldVin != $vin) {
$checkVin = Vinlicense::where("EvcInfoNo", $vin)->find();
if (!empty($checkVin)) {
return $this->ResponseJson([], 421, "所输入的vin已存在");
}
}
if ($oldParkNo != $parkNo) {
$checkLicense = Vinlicense::where("ParkNo", $parkNo)->find();
if (!empty($checkLicense)) {
return $this->ResponseJson([], 422, "所输入的车牌号已存在");
}
}
if ($oldSelfCode != $selfCode) {
$checkLicense = Vinlicense::where("SelfCode", $selfCode)->find();
if (!empty($checkLicense)) {
return $this->ResponseJson([], 423, "所输入的自编码已存在");
}
}
$checkId = Vinlicense::where("id", $id)->find();
if (empty($checkId)) {
return $this->ResponseJson([], 420, "没有找到该ID");
}
$UpdateVinLicense = Vinlicense::where("id", $id)->save([
'EvcInfoNo' => $vin,
'ParkNo' => $parkNo,
'SelfCode' => $selfCode
]);
if ($UpdateVinLicense == 1) {
$NewVinLicense = Vinlicense::where("id", $id)->select();
return $this->ResponseJson($NewVinLicense, 200, "修改成功");
} else {
return $this->ResponseJson([], 417, "修改失败");
}
}
public function DeleteVinLicense($id): \think\response\Json
{
$DeleteVinLicense = Vinlicense::where("id", $id)->delete();
if ($DeleteVinLicense != 0) {
return $this->ResponseJson([], 200, "删除成功");
} else {
return $this->ResponseJson([], 418, "删除失败");
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,104 @@
<?php
namespace app\controller;
use app\model\Enterprise as EnterpriseModel;
use think\facade\Filesystem;
use think\Request;
class Enterprise
{
public function index(Request $request)
{
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$where = [];
if(!empty($params['credit_code']) && isset($params['credit_code'])){
$where[] = ['credit_code','like','%'.$params['credit_code'].'%'];
}
if(!empty($params['name']) && isset($params['name'])){
$where[] = ['name','like','%'.$params['name'].'%'];
}
$query = EnterpriseModel::where($where)->order('id desc');
$list = $query->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
return json($list);
}
public function read($id)
{
$result = EnterpriseModel::find($id);
if(!$result){
return json(['code' => 1, 'msg' => '数据不存在']);
}
return json(['msg'=>'','code'=>0,'data'=>$result]);
}
public function update(Request $request)
{
$params = $request->param();
$info = EnterpriseModel::find($params['id']);
if(!$info){
return json(['code' => 1, 'msg' => '数据不存在']);
}
unset($params['create_time']);
$result = $info->save($params);
if($result){
return json(['msg'=>'更新成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'更新失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function save(Request $request)
{
$params = $request->param();
$result = EnterpriseModel::create([
'name'=>$params['name'],
'credit_code'=>$params['credit_code'],
'username'=>$params['username'],
'phone'=>$params['phone'],
'discount'=>$params['discount'],
'range'=>$params['range'],
'account'=>$params['account'],
'marks'=>$params['marks'],
]);
if($result){
return json(['msg'=>'新增成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'新增失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function delete(Request $request)
{
$data = $request->param();
if(!EnterpriseModel::find($data['id'])){
return json(['code' => 1, 'msg' => '数据不存在']);
}
$result = EnterpriseModel::destroy($data['id']);
if ($result) {
return json(['code' => 0, 'msg' => '删除成功']);
} else {
return json(['code' => 1, 'msg' => '删除失败']);
}
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace app\controller;
use app\model\EnterpriseCar as EnterpriseCarModel;
use think\facade\Filesystem;
use think\Request;
class EnterpriseCar
{
public function index(Request $request)
{
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$keyword = $params['keyword'] ?? '';
$where = [];
$where['enterprise_id'] = ['=',$params['enterprise_id']];
$query = EnterpriseCarModel::where($where);
$list = $query->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
return json($list);
}
public function read($id)
{
$result = EnterpriseCarModel::find($id);
if(!$result){
return json(['code' => 1, 'msg' => '数据不存在']);
}
return json(['msg'=>'','code'=>0,'data'=>$result]);
}
public function update(Request $request)
{
$params = $request->param();
$info = EnterpriseCarModel::find($params['id']);
if(!$info){
return json(['code' => 1, 'msg' => '数据不存在']);
}
unset($params['create_time']);
$result = $info->allowField(['car_number', 'car_vin', 'enterprise_id', 'car_no', 'car_user', 'vin_type'])->save($params);
if($result){
return json(['msg'=>'更新成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'更新失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function save(Request $request)
{
$params = $request->param();
$result = EnterpriseCarModel::create([
'car_number'=>$params['car_number'],
'car_vin'=>$params['car_vin'],
'enterprise_id'=>$params['enterprise_id'],
'car_no'=>$params['car_no'],
'car_user'=>$params['car_user'],
'vin_type'=>$params['vin_type']
]);
if($result){
return json(['msg'=>'新增成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'新增失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function delete(Request $request)
{
$data = $request->param();
if(!EnterpriseCarModel::find($data['id'])){
return json(['code' => 1, 'msg' => '数据不存在']);
}
$result = EnterpriseCarModel::destroy($data['id']);
if ($result) {
return json(['code' => 0, 'msg' => '删除成功']);
} else {
return json(['code' => 1, 'msg' => '删除失败']);
}
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace app\controller;
use app\model\EnterpriseUser as EnterpriseUserModel;
use think\facade\Filesystem;
use think\Request;
class EnterpriseUser
{
public function index(Request $request)
{
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$keyword = $params['keyword'] ?? '';
$where = [];
$where['enterprise_id'] = ['=',$params['enterprise_id']];
$query = EnterpriseUserModel::where($where);
$list = $query->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
return json($list);
}
public function read($id)
{
$result = EnterpriseUserModel::find($id);
if(!$result){
return json(['code' => 1, 'msg' => '数据不存在']);
}
return json(['msg'=>'','code'=>0,'data'=>$result]);
}
public function update(Request $request)
{
$params = $request->param();
$info = EnterpriseUserModel::find($params['id']);
if(!$info){
return json(['code' => 1, 'msg' => '数据不存在']);
}
unset($params['create_time']);
$result = $info->save($params);
if($result){
return json(['msg'=>'更新成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'更新失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function save(Request $request)
{
$params = $request->param();
$result = EnterpriseUserModel::create([
'enterprise_id'=>$params['enterprise_id'],
'phone'=>$params['phone'],
'group_id'=>$params['group_id']
]);
if($result){
return json(['msg'=>'新增成功','code'=>0,'data'=>[]]);
}else{
return json(['msg'=>'新增失败,请检查~','code'=>1,'data'=>[]]);
}
}
public function delete(Request $request)
{
$data = $request->param();
if(!EnterpriseUserModel::find($data['id'])){
return json(['code' => 1, 'msg' => '数据不存在']);
}
$result = EnterpriseUserModel::destroy($data['id']);
if ($result) {
return json(['code' => 0, 'msg' => '删除成功']);
} else {
return json(['code' => 1, 'msg' => '删除失败']);
}
}
}

271
app/controller/Event.php Normal file
View File

@@ -0,0 +1,271 @@
<?php
namespace app\controller;
use app\model\Event as EventModel;
use think\facade\Filesystem;
use think\Request;
class Event
{
public function ShowEvent()
{
$list = EventModel::paginate(20)->toArray();
$i = 0;
foreach ($list['data'] as $ll) {
if (strpos($ll['pic'], ',') !== false) {
$arr = explode(',', $ll['pic']);
$s = 0;
foreach ($arr as $a) {
$arr[$s] = $a;
$s += 1;
}
$list['data'][$i]['pic'] = $arr;
} else {
$list['data'][$i]['pic'] = (array)$list['data'][$i]['pic'];
}
$i += 1;
}
return json($list);
}
public function AddEvent(Request $request, $str_file = [], $str_list_file = '')
{
$data = $request->param();
$title = $data['title'];
$content = $data['content'];
$file = $request->file();
// 设定文件上传的大小
$fileSize = 1024 * 1024 * 10;
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$savename = [];
$listname = [];
if (!empty($file)) {
foreach ($file as $f) {
if (is_array($f)) {
foreach ($f as $singleFile) {
if (!in_array($singleFile->getMime(), $allowedTypes)) {
return json(['code' => 1, 'Msg' => '不支持的文件类型', 'data' => '']);
}
}
} else {
if (!in_array($f->getMime(), $allowedTypes)) {
return json(['code' => 1, 'Msg' => '不支持的文件类型', 'data' => '']);
}
}
}
}
$pico = $this->SavePic($str_file, $fileSize, $file, $request, $savename, $listname, $str_list_file);
$save = (new \app\model\Event)->save(['title' => $title, 'content' => $content, 'pic' => $pico['pic'], 'listpic' => $pico['listpic']]);
if ((int)$save == 1) {
return json(['code' => 200, 'Msg' => '新增成功', 'data' => ['title' => $title, 'content' => $content, 'pic' => $pico['pic'], 'listpic' => $pico['listpic']]]);
} else {
return json(['code' => 1, 'Msg' => '新增失败', 'data' => '']);
}
}
public function EditEvent(Request $request, $str_file = [], $str_list_file = '')
{
$data = $request->param();
$id = $data['id'];
$title = $data['title'];
$content = $data['content'];
$status = (int)$data['status'];
$edit = EventModel::find($id);
$file = $request->file();
// 设定文件上传的大小
$fileSize = 1024 * 1024 * 10;
$savename = [];
$listname = '';
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
try {
if (!empty($file)) {
foreach ($file as $f) {
if (is_array($f)) {
foreach ($f as $singleFile) {
if (!in_array($singleFile->getMime(), $allowedTypes)) {
return json(['code' => 1, 'Msg' => '不支持的文件类型', 'data' => '']);
}
}
} else {
if (!in_array($f->getMime(), $allowedTypes)) {
return json(['code' => 1, 'Msg' => '不支持的文件类型', 'data' => '']);
}
}
}
}
$pico = $this->SavePic($str_file, $fileSize, $file, $request, $savename, $listname, $str_list_file);
$edit = $edit->save(['title' => $title, 'content' => $content, 'pic' => $pico['pic'], 'listpic' => $pico['listpic'], 'status' => $status]);
if ((int)$edit == 1) {
return json(['code' => 200, 'Msg' => '修改成功', 'data' => ['title' => $title, 'content' => $content, 'pic' => $pico['pic'], 'status' => $status, 'listpic' => $pico['listpic']]]);
} else {
return json(['code' => 1, 'Msg' => '修改失败', 'data' => '']);
}
} catch (\think\exception\ValidateException $e) {
return json(['code' => 1, 'Msg' => $e->getMessage(), 'data' => '']);
}
}
public function DeleteEvent($id)
{
$ee = EventModel::find($id);
if ($ee != null) {
$result = EventModel::destroy($id);
if ($result) {
return json(['code' => 200, 'Msg' => '删除成功']);
} else {
return json(['code' => 1, 'Msg' => '删除失败']);
}
} else {
return json(['code' => 1, 'Msg' => '活动编号不存在']);
}
}
/**
* [将Base64图片转换为本地图片并保存]
* @E-mial wuliqiang_aa@163.com
* @TIME 2017-04-07
* @WEB http://blog.iinu.com.cn
* @param [Base64] $base64_image_content [要保存的Base64]
* @param [目录] $path [要保存的路径]
*/
function base64_image_content($base64_image_content, $path = '../public/static/img', $name = '')
{
//匹配出图片的格式
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
$type = $result[2];
$new_file = $path;
if (!file_exists($new_file)) {
//检查是否有该文件夹,如果没有就创建,并给予最高权限
mkdir($new_file, 0700);
}
$new_file = $new_file . ($name ?? date('YmdHis', time()) ). ".{$type}";
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
return 'https://' . $_SERVER['HTTP_HOST'] . '/' . substr($new_file, 10);
} else {
return false;
}
} else {
return false;
}
}
/**
* @param $fileSize
* @param $file
* @param Request $request
* @param array $savename
* @return array
*/
protected function SavePic($str_file, $fileSize, $file, Request $request, array $savename, $listname, $str_list_file): array
{
if (!empty($str_file)) {
foreach ($str_file as $sfile) {
$savename[] = $sfile;
}
}
if (!empty($file)) {
validate(['logo' => 'fileSize:' . $fileSize . '|fileExt:jpg,png'])
->check($file);
$small_file = $request->file("small_file");
if (!empty($small_file) && empty($str_list_file)) {
$listname = 'https://' . $_SERVER['HTTP_HOST'] . '/static/' . str_replace('\\', '/', \think\facade\Filesystem::disk('public')->putFile('img', $small_file));
} elseif (!empty($str_list_file) && empty($small_file)) {
$listname = $str_list_file;
} else {
$listname = '';
}
$files = $request->file("file");
// 将图片保存至本地
if (!empty($files)) {
foreach ($files as $file) {
$savename[] = 'https://' . $_SERVER['HTTP_HOST'] . '/static/' . str_replace('\\', '/', \think\facade\Filesystem::disk('public')->putFile('img', $file));
}
}
} else {
if (!empty($str_list_file)) {
$listname = $str_list_file;
}
}
$pico = '';
$i = 1;
foreach ($savename as $p) {
if ($i == count($savename)) {
$pico .= $p;
} else {
$pico .= $p . ',';
}
$i += 1;
}
return ['pic' => $pico, 'listpic' => $listname];
}
public function EventList()
{
$list = EventModel::order('id desc')->paginate([
'list_rows' => 20,
'query' => request()->param()
]);
foreach ($list as $ll=>$value) {
if ($value['status'] == 1) {
$list[$ll]['statusMsg'] = '上线中';
} elseif ($value['status'] == 2) {
$list[$ll]['statusMsg'] = '已下架';
}
}
return json($list);
}
/**
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
*/
public function EventDetail($id)
{
$DMessage = EventModel::where('id', $id)->find()->toArray();
$Dpic = [];
if (strpos($DMessage['pic'], ',') !== false) {
$PicArray = explode(',', $DMessage['pic']);
$i = 0;
foreach ($PicArray as $pic) {
if ($i != 0) {
$Dpic[] = $pic;
}
$i += 1;
}
} else {
$Dpic[] = $DMessage['pic'];
}
$DMessage['pic'] = $Dpic;
if ((int)$DMessage['status'] == 1) {
$DMessage['statusMsg'] = '上线中';
} elseif ((int)$DMessage['status'] == 2) {
$DMessage['statusMsg'] = '已下架';
}
return json($DMessage);
}
public function FindEvent($name)
{
$list = EventModel::whereLike('title', '%' . $name . '%')->paginate(20)->toArray();
$i = 0;
foreach ($list['data'] as $ll) {
if (strpos($ll['pic'], ',') !== false) {
$list['data'][$i]['pic'] = explode(',', $ll['pic']);
} else {
$list['data'][$i]['pic'] = (array)$ll['pic'];
}
$i += 1;
}
return json($list);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace app\controller;
class HMACMD5
{
public function HMAC($data)
{
$key = strToUtf8(config('hard.SigSecret'));
$data = strToUtf8($data);
$b = 64; // byte length for md5
if (strlen($key) > $b) {
$key = pack("H32", md5($key));
}
$key = str_pad($key, $b, chr(0x00));
$ipad = str_pad('', $b, chr(0x36));
$opad = str_pad('', $b, chr(0x5c));
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
return strtoupper(md5($k_opad . pack("H32", md5($k_ipad . $data))));
}
}
function strToUtf8($str)
{
$encode = mb_detect_encoding($str, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
if ($encode == 'UTF-8') {
return $str;
} else {
return mb_convert_encoding($str, 'UTF-8', $encode);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
<?php
namespace app\controller;
use app\common;
use think\facade\Cache;
class HardToken extends common
{
public function getToken()
{
$OperatorID = config('hard.OperatorID');
$OperatorSecret = config('hard.OperatorSecret');
$time = date('YmdHis');
$Seq = config('hard.Seq');
$mess = array('OperatorID' => $OperatorID, 'OperatorSecret' => $OperatorSecret);
$data = json_encode($mess);
$aes = new Aes();
$en_data = $aes->encrypt($data);
$de_Sig = $OperatorID . $en_data . $time . $Seq;
$hmacmd5 = new HMACMD5();
$Sig = $hmacmd5->HMAC($de_Sig);
$kk['OperatorID'] = $OperatorID;
$kk['Data'] = $en_data;
$kk['TimeStamp'] = $time;
$kk['Seq'] = $Seq;
$kk['Sig'] = $Sig;
$datas = $this->CurlSend(config('hard.url') . '/query_token', $kk);
$array_data = (array)$datas;
if ($array_data['Ret'] == 0) {
$token = $array_data['Data'];
$de_data = $aes->decrypt($token);
$array_token = json_decode($de_data, true);
$token = $array_token['AccessToken'];
Cache::set('token', $token, 7200);
return $token;
} else {
return 1;
}
}
}

278
app/controller/Index.php Normal file
View File

@@ -0,0 +1,278 @@
<?php
namespace app\controller;
use app\BaseController;
use Overtrue\Pinyin\Pinyin;
use think\facade\Config;
use think\facade\Db;
use think\facade\Log;
class Index extends BaseController
{
//之前的充值 消费 提现统计
public function totalPrice($openid, $area)
{
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s, array(' ' => ''));
$account = Db::table('user_' . $s)->where('openid', $openid)->value('account');
if ($account > 0) {
$chongzhi = Db::table('recharge_' . $s)->where('openid', $openid)->sum('total');
$chongzhi_usd = Db::table('recharge_' . $s)->where('openid', $openid)->sum('total_used');
$refund = Db::table('refund_' . $s)->where('openid', $openid)->sum('refund_total');
$order = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('TotalMoney');
$order_1 = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('WithholdingMoney');
$order_2 = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('FeedbackMoney');
$order2 = Db::table('charge_order_' . $s)->where('openid', $openid)->sum('TotalMoney');
echo '用户账户余额:' . $account;
echo '<br>';
echo '用户充值金额:' . number_format($chongzhi, 2);
echo '<br>';
echo '用户充值中提现金额:' . number_format($chongzhi_usd, 2);
echo '<br>';
echo '用户提现金额:' . number_format($refund, 2);
echo '<br>';
echo '用户老订单使用金额' . number_format($order2, 2);
echo '<br>';
echo '用户新订单充值金额' . number_format($order_1, 2);
echo '<br>';
echo '用户新订单退款金额' . number_format($order_2, 2);
echo '<br>';
echo '用户新订单消费金额' . number_format($order, 2);
echo '<br>';
echo '<br>';
echo '<br>';
}
}
public function index()
{
//充值记录
// // $new_user = Db::table('user')->select();
// $data = [];
// // foreach ($new_user as $key => $value) {
// // $openid = $value['openid'];
// // $pinyin = new Pinyin();
//
// // $s = $pinyin->sentence($value['area']);
// // $s = strtr($s, array(' ' => ''));
// $list = Db::table('charge')->select();
// foreach ($list as $key => $value) {
// unset($value['order_id']);
// $data[] = $value;
// }
// // }
// // $id = Db::table('zxc_charge_order')->insertAll($data);
// // halt($id);
// halt($data);
// exit();
// // 查询用户余额
// $new_user = Db::table('user')->select();
// $data = [];
// $i = 0;
// foreach ($new_user as $key => $value) {
// // $this->totalPrice($value['openid'], $value['area']);
// $openid = $value['openid'];
// $pinyin = new Pinyin();
// $s = $pinyin->sentence($value['area']);
// $s = strtr($s, array(' ' => ''));
// $account = Db::table('user_' . $s)->where('openid', $openid)->value('account');
// if ($account > 0) {
// $i++;
// $chongzhi = Db::table('recharge_' . $s)->where('openid', $openid)->sum('total');
// $chongzhi_usd = Db::table('recharge_' . $s)->where('openid', $openid)->sum('total_used');
// $refund = Db::table('refund_' . $s)->where('openid', $openid)->sum('refund_total');
// $order = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('TotalMoney');
// $order_1 = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('WithholdingMoney');
// $order_2 = Db::table('charge')->where('openid', $openid)->where('type', 1)->sum('FeedbackMoney');
// $order2 = Db::table('charge_order_' . $s)->where('openid', $openid)->sum('TotalMoney');
// $order2_1 = Db::table('charge_order_' . $s)->where('openid', $openid)->sum('WithholdingMoney');
// $order2_2 = Db::table('charge_order_' . $s)->where('openid', $openid)->sum('FeedbackMoney');
// echo '用户信息:'.$openid.' ' . $account;
// echo '<br>';
// echo '用户充值金额:' . number_format($chongzhi/100, 2);
// echo '<br>';
// echo '用户充值中提现金额:' . number_format($chongzhi_usd/100, 2);
// echo '<br>';
// echo '用户提现金额:' . number_format($refund/100, 2);
// echo '<br>';
// echo '用户老订单使用金额' . number_format($order2, 2);
// echo '<br>';
// echo '用户老订单充值金额' . number_format($order2_1, 2);
// echo '<br>';
// echo '用户老订单退款金额' . number_format($order2_2, 2);
// echo '<br>';
// echo '用户新订单充值金额' . number_format($order_1, 2);
// echo '<br>';
// echo '用户新订单退款金额' . number_format($order_2, 2);
// echo '<br>';
// echo '用户新订单消费金额' . number_format($order, 2);
// echo '<br>';
// echo '<br>';
// echo '<br>';
// }
// }
// echo '共'.$i.'个用户';
// halt($data);
// 退款
// $charge_info = Db::table('zxc_charge_order')->where('StartChargeSeq', 'MACFHBM3X176243163424257415')->find();
// if ($charge_info['type'] == 1 && $charge_info['directly_refund_status'] == 0 && $charge_info['is_wind'] == 0) {
// $td = new WechatReimburse();
// $res = $td->Refund2($charge_info['order_id'], $charge_info['openid'], $charge_info['FeedbackMoney'], $charge_info['WithholdingMoney'], $charge_info['directly_pay_no']);
// var_dump($res);
// Db::table('charge_logo')->save(['name' => '充电结束即充即退执行退款', 'mark' => json_encode($charge_info)]);
// }else{
// echo '已退款';
// }
// exit();
//生成二维码
// $pile = Db::table('charge_pile')->where('charge_station_id','>',20)->select();
// foreach ($pile as $key=>$value){
// $this->getwxacode($value['ConnectorID']);
// echo $value['ConnectorID'].'<br>';
// }
// halt([]);
// $res = $this->getwxacode('9920000040835A');
// halt($res);
// 检查费用
// $charge_order_info = Db::table('zxc_charge_order')->where('StartChargeSeq', 'MACFHBM3X176069545021698018')->find();
// halt($charge_order_info);
// $per_price = (new HardMessage())->Rank($charge_order_info['charge_station_id'], '2025-10-17 18:05:48', '2025-10-17 18:06:26', $charge_order_info['openid'])['Elect'];
// halt($per_price);
// // 测试加金额
// $StartChargeSeq = 'MACFHBM3X176075347725868066';
// $charge_info = Db::table('charge')->where('StartChargeSeq', $StartChargeSeq)
// ->field('WithholdingMoney,charge_station_id,openid,FeedbackMoney,type,directly_refund_status')->find();
// $check = $charge_info['FeedbackMoney'];
// $ff = 0.01;
// $area = \app\model\ChargeOrder::where('StartChargeSeq', $StartChargeSeq)->value('area');
// $pinyin = new Pinyin();
// $s = $pinyin->sentence($area);
// $s = strtr($s, array(' ' => ''));
// $table = 'charge_order_' . $s;
// $table = 'charge';
// $table_user = 'user_' . $s;
// if (empty($check)) {
// Db::table($table_user)->where('openid', $charge_info['openid'])->update(['account' => Db::raw('account+' . $ff)]);
// Db::table('charge_logo')->save(['name'=>'充电结束执行用余额增加退款','mark'=>$ff]);
// // Db::table('charge')->where('StartChargeSeq', $StartChargeSeq)->save($ss);
// }
// exit();
// 计算费用
// $price = (new HardMessage)->GetPrice(19, 'obUtOvjCdTSrZTqbjTByESPo6kLE', 'user_qianlongzhiyaozhan');
// $total = $array['TotalPower'] * $price['EPrice'] + ($array['TotalPower'] * $price['SPrice']);
// $ElectMoney = $data['TotalPower'] * $price['EPrice'];
// $SeviceMoney = $data['TotalPower'] * $price['SPrice'];
// halt($price);
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . \think\facade\App::version() . '<br/><span style="font-size:30px;">16载初心不改 - 你值得信赖的PHP框架</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
}
public function hello($name = 'ThinkPHP6')
{
return 'hello,' . $name;
}
public function config()
{
echo Config::has('database.connections.mysql.hostname');
}
function postRequest($url, $data, $headers = [])
{
$ch = curl_init();
// 如果是数组,自动转换为 JSON
if (is_array($data)) {
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
$headers[] = 'Content-Type: application/json';
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// 跳过 HTTPS 证书验证(仅测试环境使用,生产环境需配置证书)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception('cURL 请求失败: ' . curl_error($ch));
}
curl_close($ch);
return $response;
}
function base64_save($base64_img, $path)
{
$img_base = str_replace('data:image/jpeg;base64,', '', $base64_img);
$img_name = time() . rand(1000, 9999) . '.jpg'; //图片新名称
$img_path = $path . $img_name;
file_put_contents($img_path, base64_decode($img_base));
return $img_name; //返回新名称
}
public function getwxacode($ConnectorID)
{
$url_get = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . config("wx.AppID") . '&secret=' . config("wx.AppSecret");
$tmptoken = file_get_contents($url_get);
$tmptoken = json_decode($tmptoken, true);
$token = $tmptoken['access_token'];
$url = 'https://api.weixin.qq.com/wxa/getwxacode?access_token=' . $token;
$data = [
'path' => '/pages/charging/charging?ConnectorID=' . $ConnectorID,
'env_version' => 'release',// 试用版develop/trial/release
];
$res = $this->postRequest($url, $data);
$base64_image = "data:image/jpeg;base64," . base64_encode($res);
$res = (new Event())->base64_image_content($base64_image, '../public/qrcode/', $ConnectorID);
return $res;
}
}

98
app/controller/Login.php Normal file
View File

@@ -0,0 +1,98 @@
<?php
namespace app\controller;
use app\model\Access;
use app\model\Admin as AdminModel;
use Firebase\JWT\JWT;
use think\facade\Db;
use think\facade\Validate;
use think\Request;
class Login
{
public function index()
{
echo '这里是登陆界面';
return;
}
public function check(Request $request)
{
$data = $request->param();
// var_dump($data);
//错误集合
$errors = [];
//验证
$validate = Validate::rule([
'username' => 'unique:admin,username^password'
]);
$result = $validate->check([
'username' => $data['username'],
'password' => $data['password']
]);
//错误提示,反向操作
//如果用户名和密码同时比对存在,那其实就是正确的
if ($result) {
$errors[] = '用户名或密码错误~';
}
//判断跳转
if (!empty($errors)) {
return json([
'code' => 1,
'message' => $errors,
]);
} else {
session('admin', $data['username']);
$admin_id = AdminModel::where('username', $data['username'])->value('id');
$roles = AdminModel::where('id', $admin_id)->value('roles');
$permission = AdminModel::where('id', $admin_id)->value('permission');
$token = $this->GennerteToken($admin_id);
if (!empty($permission)) {
$pp = explode(',', substr($permission, 0, -1));
} else {
$pp = array();
}
return json([
'code' => 200,
'message' => '登陆成功',
'permissions' => $roles,
'authority' => $pp,
'adminId' => $admin_id,
'token' => $token
]);
}
}
private function GennerteToken($admin_id)
{
$key = 'zuxingzdz';
$token = array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 3, //在什么时候jwt开始生效 这里表示生成100秒后才生效
"exp" => time() + 1296000, //token 过期时间
"data" => [ //记录的userid的信息这里是自已添加上去的如果有其它信息可以再添加数组的键值对
'admin_id' => $admin_id,
]
);
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
public function out()
{
session('admin', null);
return json(['code' => 200, 'massage' => '退出成功']);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace app\controller;
use think\facade\Db;
class Monitor
{
public function MonitorList(){
$list =Db::table('charge_station')->column('charge_station_name');
foreach ($list as $ll){
$message = Db::table('rtspaddr')->field('name')->where('charge_station_name',$ll)->select()->toArray();
$i = 0;
foreach ($message as $mess){
$message[$i]['station'] = $message[$i]['name'];
array_diff_key($message[$i],['name' => 'xy']);
$i+=1;
}
$kk['station'] = $ll;
$kk['children'] = $message;
$ss[] = $kk;
}
return json($ss);
}
public function MonitorId($MonitorName){
$id = Db::table('rtspaddr')->where('name',$MonitorName)->value('id');
return json(['id' => $id]);
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace app\controller;
use think\facade\Db;
class Navigation
{
public function NavMessage($lat,$lng,$station_number,$openid){
$station_id = Db::table('charge_station')->where("charge_station_number",$station_number)->value("charge_station_id");
$table_user = 'zxc_user';
$hd = new HardMessage();
$interval = $hd->GetPrice($station_id,$openid,$table_user);
$station_type = \app\model\ChargeStation::where('charge_station_id',$station_id)->value('station_type');
$free = 0;
$occupy = 0;
$fault = 0;
$i = 1;
$mess = Db::table('charge_pile')->where('charge_station_id',$station_id)->select();
foreach ($mess as $m){
if ($m['status']==1){
$free+=1;
}elseif ($m['status']==2){
$occupy+=1;
}elseif ($m['status']==3){
$occupy+=1;
}elseif ($m['status']==255){
$fault+=1;
}elseif ($m['status']==0){
$fault+=1;
}
$no = Db::table('charge_pile')->where('charge_pile_id',$m['charge_pile_id'])->value('no');
if($no==null){
Db::table('charge_pile')->where('charge_pile_id',$m['charge_pile_id'])->update(['no' => $i]);
}
$i+=1;
}
$kk['free'] = $free;
$kk['occupy'] = $occupy;
$kk['fault'] = $fault;
$kk['all'] = $free+$occupy+$fault;
// $time = strtotime(date('H:i:s','00:00:00'));
// $time = date('H:i:s',strtotime("2023-03-24 21:59:59"));
$time = date('H:i:s',time());
if ((int)$station_type==0){
$SPrice = $interval['SPrice'];
$interval = $interval['message'];
$i = 0;
foreach ($interval as $in){
$st = date('H:i:s',strtotime($in['start']));
// $en = date('H:i:s',strtotime('-1 seconds',strtotime($in['end'])));
$en = date('H:i:s',strtotime($in['end']));
$check = date('H:i:s',strtotime('23:59:59'));
$check1 = date('H:i:s',strtotime('00:00:00'));
if ($i<=7 && $time>=$st && $time<$en && $time!=$check1){
$kk['Elect'] = $in['univalence'];
$kk['Serve'] = $SPrice;
break;
}elseif($i==7 && ($time>=$st || $time<=$check )|| $time==$check1){
$kk['Elect'] = $in['univalence'];
$kk['Serve'] = $SPrice;
break;
}
$i+=1;
}
}else{
$SPrice = $interval['SPrice'];
$EPrice = $interval['EPrice'];
$kk['Elect'] = $EPrice;
$kk['Serve'] = $SPrice;
}
$kk['total'] = number_format($kk['Elect'] + $kk['Serve'],6);
$address = Db::table('charge_station')->where("charge_station_number",$station_number)->value("address");
$station_name = Db::table('charge_station')->where("charge_station_number",$station_number)->value("charge_station_name");
$kk['address'] = $address;
$kk['station_name'] = $station_name;
$Type = Db::table('charge_station')->where('charge_station_id',$station_id)->value('station_type');
if ((int)$Type == 0){
$kk['type'] = '快充';
}elseif((int)$Type == 1){
$kk['type'] = '慢充';
}
$lat1 = $lat;
$lng1 = $lng;
$lat2 = Db::table('charge_station')->where('charge_station_id',$station_id)->value('latitude');
$lng2 = Db::table('charge_station')->where('charge_station_id',$station_id)->value('longitude');
$distance = $this->getDistance($lat1, $lng1, $lat2, $lng2);
$kk['distance'] = $distance;
return json($kk);
}
public function GetLastStation($lat,$lng){
$lat1 = $lat;
$lng1 = $lng;
$list = Db::table('charge_station')->select();
$mess = array();
foreach ($list as $l){
$charge_station_id = $l['charge_station_id'];
$lat2 = $l['latitude'];
$lng2 = $l['longitude'];
$distance = $this->getDistance($lat1, $lng1, $lat2, $lng2);
$mess[$charge_station_id] = $distance;
}
asort($mess);
$kk = array();
foreach ($mess as $key=>$value){
$station_id = $key;
$distance =$value;
$station_number = Db::table('charge_station')->where('charge_station_id',$station_id)->value('charge_station_number');
$s_latitude = Db::table('charge_station')->where('charge_station_id',$station_id)->value('latitude');
$s_longitude = Db::table('charge_station')->where('charge_station_id',$station_id)->value('longitude');
$kk['station_number'] = $station_number;
$kk['distance'] = $distance;
$kk['s_latitude'] = $s_latitude;
$kk['s_longitude'] = $s_longitude;
break;
}
return json($kk);
}
private function getDistance($lat1, $lng1, $lat2, $lng2): float
{
$earthRadius = 6367000;
$lat1 = ($lat1 * pi() ) / 180;
$lng1 = ($lng1 * pi() ) / 180;
$lat2 = ($lat2 * pi() ) / 180;
$lng2 = ($lng2 * pi() ) / 180;
$calcLongitude = $lng2 - $lng1;
$calcLatitude = $lat2 - $lat1;
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
$calculatedDistance = $earthRadius * $stepTwo;
return round($calculatedDistance/1000,2);
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace app\controller\order;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;
use think\Request;
class ChargeOrder
{
public function charge_order(Request $request)
{
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$where = [];
if(isset($params['phone']) && !empty($params['phone'])){
$where[] = ['u.phone','=',$params['phone']];
}
$list = Db::table('zxc_charge_order o')
->leftJoin('zxc_user u', 'o.openid = u.openid')
->leftJoin('charge_station s', 's.charge_station_id = o.charge_station_id')
->field('o.*, u.phone,s.charge_station_name')
->where($where)
->order('o.order_id desc')
->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
$list->each(function($item, $key) {
$item['type_text'] = $item['type'] == 1 ? '即充即退' : '个人钱包';
return $item;
});
return json($list);
}
public function recharge_order(Request $request){
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$where = [];
$list = Db::table('zxc_recharge o')
->leftJoin('zxc_user u', 'o.openid = u.openid')
->field('o.*, u.phone')
->order('o.id desc')
->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
$list->each(function($item, $key) {
$item['trade_state'] = '成功';
return $item;
});
return json($list);
}
public function refund_order(Request $request){
$params = $request->param();
$page = $params['page'] ?? 1;
$pageSize = $params['pageSize'] ?? 10;
$where = [];
$list = Db::table('zxc_refund o')
->leftJoin('zxc_user u', 'o.openid = u.openid')
->field('o.*, u.phone')
->order('o.id desc')
->paginate([
'list_rows' => $pageSize,
'page' => $page,
'query' =>$params
]);
$list->each(function($item, $key) {
$item['status'] = '成功';
$item['refund_total'] = $item['refund_total']/100;
return $item;
});
return json($list);
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace app\controller\Order;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;
class CountExcel
{
public function AmountExcel($start_time,$end_time){
$end_time = date("Y-m-d",strtotime("+1day",strtotime($end_time)));
$date = $this->getDateFromRange($start_time,$end_time);
$RechargeAmountTotal = 0;
$RefundAmountTotal = 0;
$RechargeNumTotal = 0;
$RefundNumTotal = 0;
$OrderAmountTotal = 0;
$OrderNumTotal = 0;
$ServiceAmountTotal = 0;
$mess =array();
foreach ($date as $d){
$area = Db::table('area_three')->column('area');
$RechargeAmount = 0;
$RefundAmount = 0;
$RechargeNum = 0;
$RefundNum = 0;
$OrderAmount = 0;
$OrderNum = 0;
$ServiceAmount = 0;
$degree_pri = 0;
foreach ($area as $a){
$s = $this->GetArea($a);
$table_refund = 'refund_'.$s;
$table_order = 'charge_order_'.$s;
$table_recharge = 'recharge_'.$s;
$recharge = Db::table($table_recharge);
$RechargeAmount += $recharge->whereDay('success_time',$d)->sum('total');
$RechargeNum += $recharge->whereDay('success_time',$d)->count();
$order = Db::table($table_order);
$OrderAmount += $order->whereDay('charge_date',$d)->sum('TotalMoney');
$OrderNum += $order->whereDay('charge_date',$d)->count();
$refund = Db::table($table_refund);
$RefundAmount += $refund->whereDay('create_time',$d)->sum('refund_total');
$RefundNum += $refund->whereDay('create_time',$d)->count();
if (strtotime($d)<strtotime('2023-02-03 00:00:00')){
$degree_pri += $order->whereDay('charge_date',$d)->sum('TotalPower');
$ServiceAmount += round($degree_pri*0.2,2);
}else{
$ServiceAmount += $order->whereDay('charge_date',$d)->sum('SeviceMoney');
}
}
$kk['RechargeAmount'] = round($RechargeAmount/100,2);
$kk['RechargeNum'] = $RechargeNum;
$kk['OrderAmount'] = round($OrderAmount,2);
$kk['OrderNum'] = $OrderNum;
$kk['RefundAmount'] = round($RefundAmount/100,2);
$kk['RefundNum'] = $RefundNum;
$kk['ServiceAmount'] = round($ServiceAmount,2);
$kk['Time'] = $d;
$mess['per'][] = $kk;
//['time'=>$d,'data' => $kk];
$RechargeAmountTotal += $RechargeAmount;
$RefundAmountTotal += $RefundAmount;
$RechargeNumTotal += $RechargeNum;
$RefundNumTotal += $RefundNum;
$OrderAmountTotal += $OrderAmount;
$OrderNumTotal += $OrderNum;
$ServiceAmountTotal += $ServiceAmount;
}
$ss['RechargeAmountTotal']=round($RechargeAmountTotal/100,2);
$ss['RefundAmountTotal']=round($RefundAmountTotal/100,2);
$ss['RechargeNumTotal']=$RechargeNumTotal;
$ss['RefundNumTotal']=$RefundNumTotal;
$ss['OrderAmountTotal']=round($OrderAmountTotal,2);
$ss['OrderNumTotal']=$OrderNumTotal;
$ss['ServiceAmountTotal'] = round($ServiceAmountTotal,2);
$mess['total'] = [$ss];
return json($mess);
}
private function GetArea($area){
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s,array(' '=>''));
return $s;
}
private function getDateFromRange($startdate, $enddate): array
{
$stimestamp = strtotime($startdate);
$etimestamp = strtotime($enddate);
// 计算日期段内有多少天
$days = ($etimestamp-$stimestamp)/86400;
// 保存每天日期
$date = array();
for($i=0; $i<$days; $i++){
$date[] = date('Y-m-d', $stimestamp+(86400*$i));
}
return $date;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace app\controller\Order;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;
class RechargeRecord
{
public function RechargeRecord($openid){
$area = Db::table('user')->where('openid',$openid)->value('area');
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s,array(' '=>''));
$table = 'recharge_'.$s;
$list = Db::table($table)->where('openid',$openid)->order('id desc')->select()->toArray();
$i = 0;
foreach ($list as $l){
$list[$i]['total'] /= 100;
$list[$i]['payer_total']/= 100;
$i+=1;
}
return json($list);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace app\controller\Order;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;
class RefundRecord
{
public function RefundRecord($openid){
$area = Db::table('user')->where('openid',$openid)->value('area');
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s,array(' '=>''));
$table_refund = 'refund_'.$s;
$message = Db::table($table_refund)->where('openid',$openid)->order('create_time desc')->select()->toArray();
for($i=0;$i<count($message);$i++){
$message[$i]['refund_total'] = round($message[$i]['refund_total']/100,2);
if ($message[$i]['status']=='SUCCESS'){
$message[$i]['status'] = '退款成功';
}elseif ($message[$i]['status']=='PROCESSING'){
$message[$i]['status'] = '退款处理中';
}elseif ($message[$i]['status']=='ABNORMAL'){
$message[$i]['status'] = '退款异常';
}elseif ($message[$i]['status']=='CLOSED'){
$message[$i]['status'] = '退款关闭';
}
}
return json($message);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace app\controller\Order;
use app\controller\ChargeOrder;
use think\facade\Db;
class TimeTask
{
/**
* @throws \RedisException
*/
public function send()
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
}
public function AdmenAmont(): \think\response\Json
{
$list = Db::table("charge_order_longshuizhen")->whereBetweenTime("start_time", "2023-06-01", "2023-07-01")->select()->toArray();
// return json($list);
$jj = [];
foreach ($list as $l) {
if (round($l['SeviceMoney'] + $l['ElecMoney'], 2) != round($l["TotalMoney"], 2)) {
$jj[] = $l['StartChargeSeq'];
}
}
// foreach ($jj as $j) {
// $order = new ChargeOrder();
// $order->AmendmentAccount('charge_order_longshuizhen', $j);
// }
$list = Db::table("charge_order_longshuizhen")->whereBetweenTime("start_time", "2023-06-01", "2023-07-01")->select()->toArray();
return json($jj);
}
}

73
app/controller/Push.php Normal file
View File

@@ -0,0 +1,73 @@
<?php
namespace app\controller;
use think\worker\Server;
use Workerman\Lib\Timer;
use think\facade\Db;
class Push extends Server
{
protected $socket = 'http://0.0.0.0:2346'; //端口自行修改
protected static $heartbeat_time = 60*60*24;
public function onWorkerStart($worker)
{
Timer::add(3, function () use ($worker) {
$time_now = time();
$map1 = [
['status', '=',255],
['is_pushed','=',1],
];
$map2 = [
['status','=', 0],
['is_pushed','=',1],
];
$hasfault = Db::table('charge_pile')->whereOr([$map1, $map2])->order('charge_pile_id desc')->count('charge_pile_id');
if ($hasfault) {
$case1 = [
['charge_pile.status', '=',255],
['is_pushed','=',1],
];
$case2 = [
['charge_pile.status', '=',0],
['is_pushed','=',1],
];
$faultInfo = Db::table('charge_pile,charge_station')
->whereOr([$case1, $case2])
->where('charge_pile.charge_station_id = charge_station.charge_station_id')
->order('charge_pile_id desc')
->field('charge_station.charge_station_id,charge_station_name,charge_pile.charge_pile_number,charge_station.area,charge_station.street,charge_pile.status,charge_pile.no')
->find();
$faultInfo['code'] = 1;
foreach ($worker->connections as $connection) {
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
}
if ($time_now - $connection->lastMessageTime > self::$heartbeat_time) {
$connection->close();
}
$connection->send(json_encode($faultInfo));
}
Db::table('charge_pile')->where('charge_pile_number',$faultInfo['charge_pile_number'])->save(['is_pushed'=>2]);
} else {
foreach ($worker->connections as $connection) {
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
if ($time_now - $connection->lastMessageTime > self::$heartbeat_time) { //连接超时
$connection->close();
}
$connection->send(json_encode(['code'=>0,'msg'=>'暂时没有信息']));
}
}
});
}
}

55
app/controller/Refund.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
namespace app\controller;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
class Refund
{
/**
* @throws ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
*/
public function FindRechargeOrder($start_time = '', $end_time = '', $out_trade_no = '')
{
$where = [];
if ($start_time) {
$where[] = ['success_time','>=',$start_time];
}
if ($end_time) {
$where[] = ['success_time','<=',$end_time];
}
if ($out_trade_no) {
$where[] = ['out_trade_no','like','%'.$end_time.'%'];
}
$list = Db::table('zxc_recharge')->where($where)->order('id desc')->select(); // 获取全部数据
foreach ($list as $key => &$value) {
$value['total'] = round($value['total'] / 100, 2);
$value['payer_total'] = round($value['payer_total'] / 100, 2);
$table = 'zxc_user';
$phone = Db::table($table)->where('openid', $value['openid'])->value('phone');
$value['phone'] = $phone;
}
return json($list);
}
}

372
app/controller/TeldTest.php Normal file
View File

@@ -0,0 +1,372 @@
<?php
declare (strict_types=1);
namespace app\controller;
use app\controller\Bus\PlugCharge;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use DateInterval;
use DateTime;
use Overtrue\Pinyin\Pinyin;
use think\facade\Cache;
use think\facade\Db;
use think\Request;
class TeldTest
{
public $OperatorID = 'MACFHBM3X'; //运营商标识
public $OperatorSecret = '1234567890abcdef';//运营商密钥
public $DataSecret = '1234567890abcdef';//消息秘钥
public $DataSecretIV = '1234567890abcdef';//消息密钥初始化向量
public $SigSecret = '1234567890abcdef';//签名密钥
public $Seq = '001';
public $url = 'http://hlht.teld9.xyz/evcs/v20191230/';//测试地址
public $connectorID = '3702121094205';//桩子号
public $EquipAuthSeq = '3702121094205';//桩子认证号
public $iv = '1234567890abcdef';//iv的长度要根据加密方式和模式来定,aes-128-cbc偏移量的是16位
public $key = '1234567890abcdef';
//获取token
//查询充电站信息
//设备接口状态查询
//设备状态变化推送
//查询业务策略信息
//请求设备认证
//请求启动充电
//推送启动充电结果
//查询充电状态
//推送充电状态
//请求停止充电
//推送停止充电结果
//推送充电订单信息
//自助备案车牌号
//获取商户企业账户余额
//订单文件下载
//token
public function getToken()
{
$OperatorID = $this->OperatorID;
$OperatorSecret = $this->OperatorSecret;
$time = date('YmdHis');
$Seq = $this->Seq;
$mess = array('OperatorID' => $OperatorID, 'OperatorSecret' => $OperatorSecret);
$data = json_encode($mess);
$en_data = $this->encrypt($data);
$de_Sig = $OperatorID . $en_data . $time . $Seq;
$Sig = $this->HMAC($de_Sig, $this->DataSecret);
$kk['OperatorID'] = $OperatorID;
$kk['Data'] = $en_data;
$kk['TimeStamp'] = $time;
$kk['Seq'] = $Seq;
$kk['Sig'] = $Sig;
$datas = $this->CurlSend_Token($this->url . '/query_token', $kk);
$array_data = (array)$datas;
if ($array_data['Ret'] == 0) {
$token = $array_data['Data'];
$de_data = $this->decrypt($token);
$arr_token = json_decode($de_data);
$array_token = (array)$arr_token;
$token = $array_token['AccessToken'];
Cache::set('token', $token, 7200);
return $token;
} else {
return 1;
}
}
//设备认证
public function queryEquipAuth()
{
Cache::delete('token');
$token = Cache::get('token');
if (!$token) {
$token = $this->getToken();
}
$datetime = date('YmdHis');
$kk['EquipAuthSeq'] = $this->EquipAuthSeq;
$kk['ConnectorID'] = $this->connectorID;
$en = $this->encrypt(json_encode($kk));
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
$s = $this->HMAC($sig, $this->DataSecret);
$rr['OperatorID'] = $this->OperatorID;
$rr['Data'] = $en;
$rr['TimeStamp'] = $datetime;
$rr['Seq'] = $this->Seq;
$rr['Sig'] = $s;
$data = $rr;
$message = $this->CurlSend_Token($this->url . '/query_equip_auth', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->decrypt($en_mess);
$arr = json_decode($de_data, true);
// Array
// (
// [FailReason] => 0
// [SuccStat] => 0
// [EquipAuthSeq] => 3702121094205
// [ConnectorID] => 3702121094105
// )
return $arr;
}
//开始充电
public function queryStartCharge()
{
$token = Cache::get('token');
if (!$token) {
$token = $this->getToken();
}
$datetime = date('YmdHis');
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
$kk['ConnectorID'] = $this->connectorID;
$kk['QRCode'] = 'QRCode';
$kk['PhoneNum'] = ''; //13698689669 个人支付必传,格式确保正确
$kk['PlateNum'] = '';// 车牌号
$en = $this->encrypt(json_encode($kk));
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
$s = $this->HMAC($sig, $this->DataSecret);
$rr['OperatorID'] = $this->OperatorID;
$rr['Data'] = $en;
$rr['TimeStamp'] = $datetime;
$rr['Seq'] = $this->Seq;
$rr['Sig'] = $s;
$message = $this->CurlSend_Token($this->url . '/query_start_charge', $rr, $token);
$en_mess = $message['Data'];
$de_data = $this->decrypt($en_mess);
$arr = json_decode($de_data);
$array = (array)$arr;
return $array;
// Array (
// [StartChargeSeq] => MACFHBM3X175705873925064035
// [SuccStat] => 1
// [FailReason] => 18
// [StartChargeSeqStat] => 5
// [ConnectorID] => 3702121094105
// )
}
//充电状态
public function queryEquipChargeStatus()
{
$token = Cache::get('token');
if (!$token) {
$token = $this->getToken();
}
$datetime = date('YmdHis');
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
$en = $this->encrypt(json_encode($kk));
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
$s = $this->HMAC($sig, $this->DataSecret);
$rr['OperatorID'] = $this->OperatorID;
$rr['Data'] = $en;
$rr['TimeStamp'] = $datetime;
$rr['Seq'] = $this->Seq;
$rr['Sig'] = $s;
$data = $rr;
$message = $this->CurlSend_Token($this->url . '/query_equip_charge_status ', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->decrypt($en_mess);
$arr = json_decode($de_data);
$array = (array)$arr;
halt($array);
if (isset($array['TotalMoney'])) {
$area = \app\model\ChargeOrder::where('StartChargeSeq', $StartChargeSeq)->value('area');
$pinyin = new Pinyin();
$s = $pinyin->sentence($area);
$s = strtr($s, array(' ' => ''));
$table = 'charge_order_' . $s;
$table_user = 'user_' . $s;
$ll = array_diff_key($array, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', "StartChargeSeq" => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
$station_id = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('charge_station_id');
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
$openid = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('openid');
$detail_message = '';
if ((int)$station_type == 0) {
$ii = 1;
$total = 0;
$ElectMoney = 0;
$SeviceMoney = 0;
foreach ($array['ChargeDetails'] as $Details) {
$Details = (array)$Details;
$per_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Elect'];
$S_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Serve'];
$period_price = round($Details['DetailPower'] * $per_price, 2);
$service_price = round($Details['DetailPower'] * $S_price, 2);
$total_money = $period_price + $service_price;
$detail_message .= '时段' . $ii .
':开始时间:' . $Details['DetailStartTime'] . ',' .
'结束时间:' . $Details['DetailEndTime'] . ',' .
'所用度数:' . $Details['DetailPower'] . ',' .
'时段电费单价:' . $per_price . ',' .
'时段电费金额:' . $period_price . ',' .
'时段服务费单价:' . $S_price . ',' .
'时段服务费金额:' . $service_price . ',' .
'时段总价:' . $total_money . ';';
$ii += 1;
$total += $total_money;
$ElectMoney += $period_price;
$SeviceMoney += $service_price;
}
} else {
$price = $this->GetPrice($station_id, $openid, $table_user);
$total = $ll['TotalPower'] * $price['EPrice'] + ($ll['TotalPower'] * $price['SPrice']);
$ElectMoney = $array['TotalPower'] * $price['EPrice'];
$SeviceMoney = $array['TotalPower'] * $price['SPrice'];
}
$ll['TotalMoney'] = round($total, 2);
$ll['ElecMoney'] = round($ElectMoney, 2);
$ll['SeviceMoney'] = round($SeviceMoney, 2);
$WithholdingMoney = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('WithholdingMoney');
$order_num = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('order_number');
if ((float)$WithholdingMoney - (float)$ll['TotalMoney'] <= 3) {
$order = new ChargeOrder();
$order->EndOrder($openid, $order_num);
}
$ll['status'] = $ll['StartChargeSeqStat'];
$end_time = Db::table($table)->where('order_number', $order_num)->value('end_time');
$status = Db::table($table)->where('order_number', $order_num)->value('status');
if (empty($end_time) && $status != 4) {
Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->save($ll);
}
return ['code' => 200];
} else {
return ['code' => 1];
}
}
//停止充电
public function queryStopCharge()
{
$token = Cache::get('token');
if (!$token) {
$token = $this->getToken();
}
$datetime = date('YmdHis');
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
$kk['ConnectorID'] = $this->connectorID;
$en = $this->encrypt(json_encode($kk));
$sig = $this->connectorID . $en . $datetime . $this->Seq;
$s = $this->HMAC($sig, $this->DataSecret);
$rr['OperatorID'] = $this->connectorID;
$rr['Data'] = $en;
$rr['TimeStamp'] = $datetime;
$rr['Seq'] = $this->Seq;
$rr['Sig'] = $s;
$data = $rr;
$message = $this->CurlSend_Token($this->url . '/query_stop_charge', $data, $token);
halt($message);
$en_mess = $message['Data'];
$de_data = $this->decrypt($en_mess);
$arr = json_decode($de_data);
$array = (array)$arr;
return $array;
}
public function index()
{
return print_r($this->queryStopCharge());
}
function CurlSend_Token($url, $data = '', $token = '')
{
$data = json_encode($data);
$ch = curl_init();
$headers = array();
if ($token) {
$headers[] = 'Authorization: Bearer ' . $token;
}
$headers[] = 'Content-Type: application/json;charset=utf-8';
$headers[] = 'Content-Length: ' . strlen($data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$curl_return = curl_exec($ch);
curl_close($ch);
return json_decode(trim($curl_return), true);
}
public function HMAC($data, $key)
{
$key = $this->strToUtf8($key);
$data = $this->strToUtf8($data);
$b = 64; // byte length for md5
if (strlen($key) > $b) {
$key = pack("H32", md5($key));
}
$key = str_pad($key, $b, chr(0x00));
$ipad = str_pad('', $b, chr(0x36));
$opad = str_pad('', $b, chr(0x5c));
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
return strtoupper(md5($k_opad . pack("H32", md5($k_ipad . $data))));
}
function strToUtf8($str)
{
$encode = mb_detect_encoding($str, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
if ($encode == 'UTF-8') {
return $str;
} else {
return mb_convert_encoding($str, 'UTF-8', $encode);
}
}
public function encrypt($input)
{
return base64_encode(openssl_encrypt($input, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv));
}
public function decrypt($input)
{
return openssl_decrypt(base64_decode($input), 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv);
}
}

390
app/controller/Test.php Normal file
View File

@@ -0,0 +1,390 @@
<?php
declare (strict_types=1);
namespace app\controller;
use app\controller\Bus\PlugCharge;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use DateInterval;
use DateTime;
use think\facade\Db;
use think\Request;
class Test
{
static $OperatorID = 'MA5UTE3F1'; //运营商标识
static $OperatorSecret = '1234567890abcdef';//运营商密钥
static $Seq = '0001';
public function tttt()
{
$data = ["vin" => "LA9LC30F0NCLA6198", "connectorID" => "5001110048204", "StartSc" => 44];
if (isset($data['vin']) && isset($data['connectorID'])) {
// $this->PlugGennerateOrder($data['ConnectorID'], $data['Vin']);
$AppointmentTime = Db::table('appointment_time')->where('id', 1)->value('AppointmentTime');
$currentDate = new DateTime();
$combinedDateTime = new DateTime($currentDate->format('Y-m-d') . ' ' . $AppointmentTime);
$AppointmentTime = $combinedDateTime->format('Y-m-d H:i:s');
$nowTime = $currentDate->format('Y-m-d H:i:s');
$nowDay = $currentDate->format('Y-m-d');
$check = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->find();
if (empty($check)) {
Db::table('appointment')->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID'], 'Vin' => $data['vin'], 'plug_time' => $AppointmentTime]);
} else {
$checkVin = Db::table('appointment')->where('Vin', $data['vin'])->value('ConnectorID');
if ($checkVin != $data['connectorID']) {
Db::table('appointment')->where('Vin', $data['vin'])->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID']]);
}
}
$kk['SuccStat'] = 0;
$kk['FailReason'] = 0;
}
$data = json_encode($data);
$h = new PlugCharge();
$st = $h->signToken();
$data = $h->Encrypt($data);
return json($st);
}
public function GetPriceTest($station_id, $openid, $table)
{
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
$ElectricityFee = Db::table('charge_station')->where('charge_station_id', $station_id)->value('ElectricityFee');
$type = Db::table($table)->where('openid', $openid)->value('type');
if ($type != 3) {
$ServiceFee = ServiceFee::where('type', $type)->where('station_type', $station_type)->value('service_fee');
} else {
$group_id = EnterpriseUser::where('openid', $openid)->value('group_id');
$ServiceFee = ServiceFee::where('type', $type)->where('station_type', $station_type)->where('group_id', $group_id)->value('service_fee');
}
// $ServiceFee= Db::table('charge_station')->where('charge_station_id',$station_id)->value('ServiceFee');
$ElectricityFee = str_replace('电费:', '', $ElectricityFee);
$Elect = explode(',', $ElectricityFee);
for ($index = 0; $index < count($Elect); $index++) {
$kk['time_interval'] = substr($Elect[$index], 0, 11);
$tt = explode('~', $kk['time_interval']);
$start = $tt[0] . ':00';
$end = $tt[1] . ':00';
$kk['univalence'] = explode(':', $Elect[$index])[3];
$kk['start'] = $start;
$kk['end'] = $end;
$ss[] = $kk;
}
$ServiceFee = str_replace('服务费:', '', $ServiceFee);
$Server = explode(',', $ServiceFee);
$wk_day = date('w');
$now_time = time();
$start_time = '2023-03-18 00:00:00';
$start_time = strtotime($start_time);
$wkday_ar = array('日', '一', '二', '三', '四', '五', '六');
for ($index = 0; $index < count($Server); $index++) {
$ll['time_interval'] = substr($Server[$index], 0, -5);
// if ($wkday_ar[$wk_day] == '三' && $now_time > $start_time && $type == 1) {
// $ll['univalence'] = number_format((float)(substr($Server[$index], Strlen($Server[$index]) - 4) - 0.20), 2);
// } else {
$ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
// }
$mm[] = $ll;
}
if ($station_type == 1) {
return json(['EPrice' => number_format((float)($ss[0]['univalence']), 6), 'SPrice' => number_format((float)($mm[0]['univalence']), 2)]);
} elseif ($station_type == 0) {
return json(['message' => $ss, 'SPrice' => number_format((float)($mm[0]['univalence']), 2)]);
}
}
public function tsesg1()
{
$currentDate = new DateTime();
$todayDate = $currentDate->format('Y-m-d H:i:s');
$nowDay = $currentDate->format('Y-m-d');
$PlugOrder = Db::table('appointment')->select();
foreach ($PlugOrder as $order) {
$status = Db::table('charge_pile')->where('ConnectorID', $order['ConnectorID'])->value('status');
echo $status;
}
}
public function index()
{
$map1 = [
['status', '=', 255],
['is_pushed', '=', 1],
];
$map2 = [
['status', '=', 0],
['is_pushed', '=', 1],
];
$hasfault = Db::table('charge_pile')->whereOr([$map1, $map2])->order('charge_pile_id desc')->select();
$case1 = [
['charge_pile.status', '=', 255],
['is_pushed', '=', 1],
];
$case2 = [
['charge_pile.status', '=', 0],
['is_pushed', '=', 1],
];
$faultInfo = Db::table('charge_pile,charge_station')
->whereOr([$case1, $case2])
->where('charge_pile.charge_station_id = charge_station.charge_station_id')
->order('charge_pile_id desc')
->field('charge_station.charge_station_id,charge_station_name,charge_pile.charge_pile_number,charge_station.area,charge_station.street,charge_pile.status,charge_pile.no')
->find();
return json($faultInfo);
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
$faultInfo = Db::table('charge_pile,charge_station')
->where('charge_pile.status', 3)
->where('charge_pile.is_pushed', 1)
->where('charge_pile.charge_station_id = charge_station.charge_station_id')
->order('charge_pile_id desc')
->field('charge_station.charge_station_id,charge_station_name,charge_pile.charge_pile_number,charge_station.area,charge_station.street,charge_pile.status,charge_pile.is_pushed')
->find();
return json($faultInfo);
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save()
{
$openid_array = Db::table('zxc_user')->column('openid');
foreach ($openid_array as $openid) {
$table_user = 'zxc_user';
$table_order = 'zxc_charge_order';
$table_recharge = 'zxc_recharge';
$account = Db::table($table_user)->where('openid', $openid)->value('account');
$recharge_all = Db::table($table_recharge)->where('openid', $openid)->sum('total');
$recharge_all /= 100;
$check = Db::table($table_order)->where('openid', $openid)->where('status', 2)->order('start_time desc')->value('end_time');
if (empty($check)) {
$order_all = Db::table($table_order)->where('openid', $openid)->where('status', 4)->sum('TotalMoney');
$inorder = Db::table($table_order)->where('openid', $openid)->where('status', '<>', 4)->where('status', '<>', 5)->order('start_time desc')->value('WithholdingMoney');
$order_total = $order_all + $inorder;
} else {
$order_total = Db::table($table_order)->where('openid', $openid)->where('status', 4)->sum('TotalMoney');
}
$order_total = round($order_total, 2);
$mask = round($recharge_all - $order_total, 2); //这里还要减已经提现的
if (round($mask, 2) == round($account, 2)) {
continue;
} else {
$ss['order_total'] = $order_total;
$ss['openid'] = $openid;
$ss['recharge_all'] = $recharge_all;
$ss['mask'] = $mask;
$ss['account'] = $account;
}
$ll[] = $ss;
}
return json($ll);
}
public function FindOneUser($openid)
{
$table_user = 'zxc_user';
$table_order = 'zxc_charge_order';
$table_recharge = 'zxc_recharge';
$table_refund = 'zxc_refund';
$account = Db::table($table_user)->where('openid', $openid)->value('account');
$recharge_all = Db::table($table_recharge)->where('openid', $openid)->sum('total');
$recharge_all /= 100;
$check = Db::table($table_order)->where('openid', $openid)->where('status', 2)->order('start_time desc')->value('end_time');
if (empty($check)) {
$order_all = Db::table($table_order)->where('openid', $openid)->where('status', 4)->sum('TotalMoney');
$inorder = Db::table($table_order)->where('openid', $openid)->where('status', '<>', 4)->where('status', '<>', 5)->order('start_time desc')->value('WithholdingMoney');
$order_total = $order_all + $inorder;
} else {
$order_total = Db::table($table_order)->where('openid', $openid)->where('status', 4)->sum('TotalMoney');
}
$refund_total = Db::table($table_refund)->where('openid', $openid)->sum('refund_total');
$refund_total /= 100;
$order_total = round($order_total, 2);
$mask = round($recharge_all - $order_total - $refund_total, 2); //这里还要减已经提现的
if (round($mask, 2) == round($account, 2)) {
$ss['status'] = 'ok';
} else {
$ss['order_total'] = $order_total;
$ss['openid'] = $openid;
$ss['recharge_all'] = $recharge_all;
$ss['mask'] = $mask;
$ss['account'] = $account;
$ss['refund_total'] = $refund_total;
}
return json($ss);
}
public function FindAllExUser($area, $time = '2023-05-11')
{
$table_user = 'zxc_user';
$table_order = 'zxc_charge_order';
$table_recharge = 'zxc_recharge';
$table_refund = 'zxc_refund';
$openid = Db::table($table_user)->column('openid');
$kk = array();
foreach ($openid as $o) {
$checkdate = Db::table($table_order)->where('start_time', '<', $time)->find();
if (empty($checkdate)) {
continue;
} else {
$account = Db::table($table_user)->where('openid', $o)->value('account');
$recharge_all = Db::table($table_recharge)->where('openid', $o)->sum('total');
$recharge_all /= 100;
$check = Db::table($table_order)->where('openid', $o)->where('status', 2)->order('start_time desc')->value('end_time');
if (empty($check)) {
$order_all = Db::table($table_order)->where('openid', $o)->where('status', 4)->sum('TotalMoney');
$inorder = Db::table($table_order)->where('openid', $o)->where('status', '<>', 4)->where('status', '<>', 5)->order('start_time desc')->value('WithholdingMoney');
$order_total = $order_all + $inorder;
} else {
$order_total = Db::table($table_order)->where('openid', $o)->where('status', 4)->sum('TotalMoney');
}
$order_total = round($order_total, 2);
$refund_total = Db::table($table_refund)->where('openid', $o)->sum('refund_total');
$refund_total /= 100;
$refund_total = round($refund_total, 2);
$mask = round($recharge_all - $order_total - $refund_total, 2); //这里还要减已经提现的
if (round($mask, 2) == round($account, 2)) {
$ss['status'] = 'ok';
} else {
$ss['order_total'] = $order_total;
$ss['openid'] = $o;
$ss['recharge_all'] = $recharge_all;
$ss['refund_total'] = $refund_total;
$ss['mask'] = $mask;
$ss['account'] = $account;
$kk[] = $ss;
}
}
}
return json($kk);
}
public function correction($openid)
{
$OrderList = new ChargeOrder();
$OrderList->OrderList($openid);
$table_order = 'zxc_charge_order';
$order = Db::table($table_order)->where('openid', $openid)->select()->toArray();
$i = 0;
foreach ($order as $oo) {
if (($oo['TotalMoney'] + $oo['FeedbackMoney']) != $oo['WithholdingMoney'] && $oo['status'] == 4) {
Db::table($table_order)->where('order_number', $oo['order_number'])->save(['TotalMoney' => round($oo['WithholdingMoney'] - $oo['FeedbackMoney'], 2)]);
$ss['order_number'] = $oo['order_number'];
$ss['TotalMoney'] = $oo['TotalMoney'];
$ss['WithholdingMoney'] = $oo['WithholdingMoney'];
$ss['FeedbackMoney'] = $oo['FeedbackMoney'];
$new_TotalMoney = Db::table($table_order)->where('order_number', $oo['order_number'])->value('TotalMoney');
$ss['NewMoney'] = $new_TotalMoney;
$i += 1;
} else {
continue;
}
$ll[] = $ss;
}
$ll['update_num'] = $i;
return json($ll);
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($order_number = 'DZZS1673603040121831')
{
$message = Db::table('charge_order_longgangjiedao')->where('order_number', $order_number)->find();
echo strtotime($message['start_time']);
echo strtotime("2023-03-03 15:09:47");
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
//
}
}
function getDistance($lat1, $lng1, $lat2, $lng2)
{
$earthRadius = 6367000;
$lat1 = ($lat1 * pi()) / 180;
$lng1 = ($lng1 * pi()) / 180;
$lat2 = ($lat2 * pi()) / 180;
$lng2 = ($lng2 * pi()) / 180;
$calcLongitude = $lng2 - $lng1;
$calcLatitude = $lat2 - $lat1;
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
$calculatedDistance = $earthRadius * $stepTwo;
return round($calculatedDistance / 1000, 2);
}
function Encrypt($data)
{
$aes = new Aes();
return $aes->encrypt($data);
}
function HmacMD5($data)
{
$md5 = new HMACMD5();
return $md5->HMAC($data);
}

388
app/controller/User.php Normal file
View File

@@ -0,0 +1,388 @@
<?php
declare (strict_types=1);
namespace app\controller;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\facade\Db;
use think\Request;
class User
{
public function index()
{
$table = 'zxc_user';
$count = Db::table($table)->select()->count();
$list = Db::table($table)->paginate(20, $count)->toArray();
$i = 0;
foreach ($list['data'] as $ll) {
$list['data'][$i]['account'] = round($list['data'][$i]['account'], 2);
$i += 1;
}
return json($list);
}
public function user_all()
{
$count = Db::table('zxc_user')->select();
return json($count);
}
public function read($message = '')
{
$count = Db::table('zxc_user')->select()->count();
$list = Db::table('zxc_user')->where('phone|openid', 'like', '%' . $message . '%')->paginate(20, $count);
return json($list);
}
public function UpdateDiscount($message)
{
$time = date("Y-m-d H:i:s");
Db::table('discount')->where('id', 1)->update(['message' => $message, 'update_time' => $time]);
return json(['code' => '更新成功']);
}
public function DiscountInfo()
{
$message = Db::table('discount')->where('id', 1)->value('message');
return json(['code' => '200', 'message' => $message]);
}
public function UserEdit($openid, $username, $phone, $sex, $location_area, $address)
{
$table = 'zxc_user';
$data = ['username' => $username,
'phone' => $phone,
'sex' => $sex,
'address' => $address];
$update = Db::table($table)->where('openid', $openid)->update($data);
if ($update != 0) {
return json(['code' => 200, 'message' => '更新成功']);
} else {
return json(['code' => 1, 'message' => '没有更新']);
}
}
public function UserInfo($openid)
{
$table = 'zxc_user';
$info = Db::table($table)->where('openid', $openid)->field('username,sex,phone,address')->find();
$location_area = Db::table($table)->where('openid', $openid)->value('location_area');
if (!empty($location_area)) {
$location_area = explode('-', $location_area);
}
$info['location_area'] = $location_area;
return json(['code' => 200, 'message' => '请求成功', 'data' => $info]);
}
public function area()
{
$area = Db::table('area')->select();
return json($area);
}
public function StationPrice(Request $request)
{
$data = $request->param();
$where = [];
if (isset($data['station_number']) && !empty($data['station_number'])) {
$where['charge_station_number'] = ['=', $data['station_number']];
}
$info = Db::table('charge_station')->where($where)->where('charge_station_id', 19)->field('*')->find();
// if ($info['station_type'] == 0) {
$station_type = '快充';
// } else {
$station_type = '慢充';
// }
$ElectricityFee = str_replace('电费:', '', $info['ElectricityFee']);
$Elect = explode(',', $ElectricityFee);
for ($index = 0; $index < count($Elect); $index++) {
$kk['time_interval'] = substr($Elect[$index], 0, 11);
$kk['univalence'] = explode(':', $Elect[$index])[3];
$ss[] = $kk;
}
$ServiceFee = str_replace('服务费:', '', $info['ServiceFee']);
$Server = explode(',', $ServiceFee);
for ($index = 0; $index < count($Server); $index++) {
$ll['time_interval'] = substr($Server[$index], 0, -5);
$ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
$mm[] = $ll;
}
$info2 = Db::table('charge_station')->select();
return json(['code' => 2000, 'Station_Type' => $station_type, 'ElectricityFee' => $ss, 'ServiceFee' => $mm, 'yuan' => $info2]);
}
public function StationPriceUpdate($station_number, $time_interval, $univalence)
{
$time_interval = preg_replace("/\s| /", "", $time_interval);;
$univalence = preg_replace("/\s| /", "", $univalence);;
$time_interval = str_replace('[', '', $time_interval);
$time_interval = str_replace("'", "", $time_interval);
$time_interval = str_replace('"', '', $time_interval);
$time_interval = str_replace(']', '', $time_interval);
$univalence = str_replace('[', '', $univalence);
$univalence = str_replace(']', '', $univalence);
$univalence = str_replace("'", "", $univalence);
$univalence = str_replace('"', '', $univalence);
$time_interval = explode(",", $time_interval);
$univalence = explode(",", $univalence);
$z = array();
$ss = '';
$station_type = \app\model\ChargeStation::where('charge_station_number', $station_number)->value('station_type');
for ($i = 0; $i < count($time_interval); $i++) {
if ($station_type != 1) {
$z[$i] = $time_interval[$i] . ':' . number_format((float)($univalence[$i]), 6);
if ($i != 7) {
$ss .= $z[$i] . ',';
} else {
$ss .= $z[$i];
}
} else {
$z[$i] = $time_interval[$i] . ':' . number_format((float)$univalence[$i], 6);
$ss .= $z[$i];
}
}
$last = '电费:' . $ss;
\app\model\ChargeStation::where('charge_station_number', $station_number)->update(['ElectricityFee' => $last]);
return json(['code' => 200, 'message' => '修改成功']);
}
protected function getLen($num)
{
$pos = strrpos($num, '.');
$ext = substr($num, $pos + 1);
$len = strlen($ext);
return $len;
}
public function WxLogin()
{
$code = input('code');
$res = getWxMessage($code);
$userInfo = Db::table('zxc_user')->where('openid', $res['openid'])->find();
$time = date('Y-m-d H:i:s', time());
if (!$userInfo) {
$data = ['openid' => $res['openid'], 'createtime' => $time];
$id = Db::table('zxc_user')->insertGetId($data);
} else {
$id = $userInfo['user_id'];
}
Db::table('zxc_user')->where('user_id', $id)->update(['logintime' => $time]);
$token = signToken($id);
return json(['code' => 200, 'message' => '登录成功', 'token' => $token, 'openid' => $res['openid']]);
}
public function WxGetArea($openid)
{
$area_three = Db::table('area_three')->column('area');
$new = array_rand($area_three);
$area = $area_three[$new];
$userinfo = \app\model\User::where('openid', $openid)->value('area');
if (empty($userinfo)) {
$message = \app\model\User::where('openid', $openid)->value('area');
if (empty($message)) {
return json(['code' => 1, 'message' => '地区信息无效']);
}
$table_user = 'zxc_user';
$createtime = date('Y-m-d H:i:s', time());
$user = Db::table($table_user)->where('openid', $openid)->find();
if (empty($user)) {
$data = ['openid' => $openid, 'createtime' => $createtime, 'area' => $area];
Db::table($table_user)->save($data);
return json(['code' => 200, 'message' => '用户地区保存成功']);
}
return json(['code' => 200, 'message' => '用户地区保存成功']);
} else {
return json(['code' => 200, 'message' => '用户地区信息已存过']);
}
}
public function checkToken($token)
{
$key = 'zbcazbc';
$key = new Key($key, 'HS256');
$status = array("code" => 1);
// echo $token;
try {
JWT::$leeway = 60;//当前时间减去60把时间留点余地
$decoded = JWT::decode($token, $key, array('HS256')); //HS256方式这里要和签发的时候对应
$arr = (array)$decoded;
$res['code'] = 200;
$res['msg'] = 'OK';
$res['data'] = $arr['data'];
return json($res);
} catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return json($status);
} catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token失效";
return json($status);
} catch (\Firebase\JWT\ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return json($status);
} catch (Exception $e) { //其他错误
$status['msg'] = "未知错误";
return json($status);
}
}
public function UserBalance($openid)
{
$table_user = 'zxc_user';
$info = Db::table($table_user)->where('openid', $openid)->field('account,phone')->find();
$balance = $info['account'];
$balance = sprintf("%01.2f", $balance);
$FrozenAccount = Db::table($table_user)->where('openid', $openid)->value('FrozenAccount');
$FrozenAccount = sprintf("%01.2f", $FrozenAccount);
$table = 'zxc_charge_order';
$count = Db::table($table)->where('openid', $openid)->field('order_number,start_time,end_time,revenue,status')->count();
$enterprise_accout = Db::table('enterprise_user')->where('phone', $info['phone'])->count();
return json([
'openid' => $openid,
'balance' => $balance,
'count' => $count,
'FrozenAccount' => $FrozenAccount,
'phone' => $info['phone'],
'enterprise' => $enterprise_accout
]);
}
public function getMoneyLog(){
$result = Db::table('zxc_user_money_log')->where('openid',input('openid'))->order('id desc')->select();
return json($result);
}
// 企业相关
/**
* 获取企业信息
*
*/
public function getEnterpriseInfo($phone)
{
$enterprise_user = Db::table('enterprise_user')->where('phone', $phone)->find();
if ($enterprise_user) {
$enterprise = Db::table('enterprise')->where('id', $enterprise_user['enterprise_id'])->find();
$enterprise['is_account'] = $enterprise_user['group_id'] == 1 ? false : true;
$enterprise['enterprise_user_id'] = $enterprise_user['id'];
return json($enterprise);
}
return json([]);
}
// 充值记录
public function getEnterpriseReangeLog()
{
}
protected function generate_tuikuan($length)
{
$chars = '0123456789';
$time = time();
$password = 'DZZS' . $time . 'TK';
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
}
function signToken($uid)
{
$key = 'zbcazbc';
$token = array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 3, //在什么时候jwt开始生效 这里表示生成100秒后才生效
"exp" => time() + 1296000, //token 过期时间
"data" => [ //记录的userid的信息这里是自已添加上去的如果有其它信息可以再添加数组的键值对
'uid' => $uid,
]
);
// print_r($token);
// $keyId = "keyId";
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
function getCurl($url)
{
$headerArray = array("Content-type:application/json;", "Accept:application/json");
$ch = curl_init();//初始化CURL
curl_setopt($ch, CURLOPT_URL, $url);//设置访问地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//HTTPS访问设置 关闭监视
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);//HTTPS访问设置 关闭监视访问地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);//设置访问头部信息
$output = curl_exec($ch);//获取结果
curl_close($ch);//关闭连接
$output = json_decode($output, true);//json数据转换
return $output;
}
function getWxMessage($code)
{
//网址,appid,appsecret都封装至配置文件中,方便后期管理
$url = sprintf(config('wx.url'), config('wx.AppID'), config('wx.AppSecret'), $code);
//使用封装的CURL方法
$res = getCurl($url);
//返回结果
return $res;
}
function getDistance($lat1, $lng1, $lat2, $lng2)
{
$earthRadius = 6367000;
$lat1 = ($lat1 * pi()) / 180;
$lng1 = ($lng1 * pi()) / 180;
$lat2 = ($lat2 * pi()) / 180;
$lng2 = ($lng2 * pi()) / 180;
$calcLongitude = $lng2 - $lng1;
$calcLatitude = $lat2 - $lat1;
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
$calculatedDistance = $earthRadius * $stepTwo;
return round($calculatedDistance / 1000, 2);
}

View File

@@ -0,0 +1,299 @@
<?php
declare (strict_types=1);
namespace app\controller;
use app\common;
use app\model\ChargeStation as ChargeStationModel;
use think\facade\Db;
use think\Request;
class UserCollect extends common
{
public function Collect($openid, $station_number, $is_collect)
{
$table = 'zxc_user_collect';
if (intval($is_collect) == 0) {
$station_id = Db::table('charge_station')->where('charge_station_number', $station_number)->value('charge_station_id');
$query = Db::table($table)->where('openid', $openid)->where('charge_station_id', $station_id)->find();
if (empty($query)) {
$data = ['openid' => $openid, 'charge_station_id' => $station_id];
Db::table($table)->save($data);
return json(['code' => 200, 'message' => '新增收藏成功', 'is_collect' => 1, 'collect_message' => '取消收藏']);
} else {
return json(['code' => 1, 'message' => '收藏过了,代码可能有问题']);
}
} elseif (intval($is_collect) == 1) {
$station_id = Db::table('charge_station')->where('charge_station_number', $station_number)->value('charge_station_id');
$query = Db::table($table)->where('openid', $openid)->where('charge_station_id', $station_id)->find();
if (!empty($query)) {
Db::table($table)->where('openid', $openid)->where('charge_station_id', $station_id)->delete();
return json(['code' => 200, 'message' => '取消收藏成功', 'is_collect' => 0, 'collect_message' => '收藏']);
} else {
return json(['code' => 1, 'message' => '没有收藏呀,代码可能有问题']);
}
}
}
public function MyCollect($openid, $lat, $lng)
{
$ss = array();
$table = 'zxc_user_collect';
$station = Db::table($table)->where('openid', $openid)->select();
$sql = "SELECT charge_station_id,count(charge_station_id) pile_number FROM charge_pile GROUP BY charge_station_id HAVING count(charge_station_id)>1 ORDER BY charge_station_id";
$message = Db::query($sql);
foreach ($message as $m) {
$charge_station_id = $m['charge_station_id'];
$pile_number = $m['pile_number'];
ChargeStationModel::where('charge_station_id', $charge_station_id)->update(['charge_pile_num' => $pile_number]);
}
foreach ($station as $st) {
$station_id = $st['charge_station_id'];
$lat1 = $lat;
$lng1 = $lng;
$lat2 = Db::table('charge_station')->where('charge_station_id', $station_id)->value('latitude');
$lng2 = Db::table('charge_station')->where('charge_station_id', $station_id)->value('longitude');
$distance = $this->getDistance($lat1, $lng1, $lat2, $lng2);
$station_name = Db::table('charge_station')->where('charge_station_id', $station_id)->value('charge_station_name');
$station_number = Db::table('charge_station')->where('charge_station_id', $station_id)->value('charge_station_number');
$free = 0;
$occupy = 0;
$fault = 0;
$i = 1;
$mess = Db::table('charge_pile')->where('charge_station_id', $station_id)->select();
foreach ($mess as $m) {
if ($m['status'] == 1) {
$free += 1;
} elseif ($m['status'] == 2) {
$occupy += 1;
} elseif ($m['status'] == 3) {
$fault += 1;
}
$no = Db::table('charge_pile')->where('charge_pile_id', $m['charge_pile_id'])->value('no');
if ($no == null) {
Db::table('charge_pile')->where('charge_pile_id', $m['charge_pile_id'])->update(['no' => $i]);
}
$i += 1;
}
$data_station = [
'pile_free' => $free,
'pile_occupy' => $occupy,
'pile_fault' => $fault
];
Db::table('charge_station')->where('charge_station_id', $station_id)->update($data_station);
$collect = Db::table($table)->where('openid', $openid)->where('charge_station_id', $station_id)->find();
if (empty($collect)) {
$is_collect = 0;
$collect_message = '收藏';
} else {
$is_collect = 1;
$collect_message = '取消收藏';
}
$kk['ChargeStationNumber'] = $station_number;
$kk['ChargeStationName'] = $station_name;
$kk['Free'] = $free;
$kk['Occupy'] = $occupy;
$kk['Fault'] = $fault;
$kk['Distance'] = $distance;
$kk['is_collect'] = $is_collect;
$kk['message'] = $collect_message;
$ss[] = $kk;
}
return json($ss);
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index_ToWechat(Request $request)
{
$data = $request->param();
$openid = $data['openid'];
$table = 'zxc_user_collect';
$charge_station_id = Db::table($table)->where('openid', $openid)->column('charge_station_id');
$infomation = [];
foreach ($charge_station_id as $id) {
$charge_station_number = Db::table('charge_station')->where('charge_station_id', $id)->value('charge_station_number');
$charge_station_name = Db::table('charge_station')->where('charge_station_id', $id)->value('charge_station_name');
$sql = "SELECT charge_station_id,count(charge_station_id) pile_number FROM charge_pile GROUP BY charge_station_id HAVING count(charge_station_id)>1 ORDER BY charge_station_id";
$message = Db::query($sql);
foreach ($message as $m) {
$charge_station_id = $m['charge_station_id'];
$pile_number = $m['pile_number'];
ChargeStationModel::where('charge_station_id', $charge_station_id)->update(['charge_pile_num' => $pile_number]);
}
$free = 0;
$occupy = 0;
$fault = 0;
$i = 1;
$mess = Db::table('charge_pile')->where('charge_station_id', $id)->select();
foreach ($mess as $m) {
if ($m['status'] == 1) {
$free += 1;
} elseif ($m['status'] == 2) {
$occupy += 1;
} elseif ($m['status'] == 3) {
$fault += 1;
}
$no = Db::table('charge_pile')->where('charge_pile_id', $m['charge_pile_id'])->value('no');
if ($no == null) {
Db::table('charge_pile')->where('charge_pile_id', $m['charge_pile_id'])->update(['no' => $i]);
}
$i += 1;
}
$data_station = [
'pile_free' => $free,
'pile_occupy' => $occupy,
'pile_fault' => $fault
];
Db::table('charge_station')->where('charge_station_id', $id)->update($data_station);
$lat1 = $data['lat'];
$lng1 = $data['lng'];
$lat2 = Db::table('charge_station')->where('charge_station_id', $id)->value('latitude');
$lng2 = Db::table('charge_station')->where('charge_station_id', $id)->value('longitude');
$distance = $this->getDistance($lat1, $lng1, $lat2, $lng2);
$info = [
'charge_station_id' => $id,
'charge_station_number' => $charge_station_number,
'station_name' => $charge_station_name,
'distance' => $distance,
'free' => $free,
'occupy' => $occupy,
'fault' => $fault
];
array_push($infomation, $info);
}
return json($infomation);
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
//
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
$data = $request->param();
$table = 'zxc_user_collect';
// $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
// `usercollect_id` int unsigned NOT NULL AUTO_INCREMENT,
// `openid` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
// `charge_station_id` int DEFAULT NULL,
// `charge_pile_number` varchar(50) DEFAULT NULL,
// `area` varchar(50) DEFAULT NULL,
// PRIMARY KEY (`usercollect_id`) USING BTREE,
// KEY `user_id` (`openid`)
// ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3";
// Db::execute($sql);
//
$openid = $data['openid'];
$charge_pile_number = $data['charge_pile_number'];
$charge_station_id = Db::table('charge_pile')->where('charge_pile_number', $charge_pile_number)->value('charge_station_id');
$pile_data = [
'openid' => $openid,
'charge_station_id' => $charge_station_id,
'charge_pile_number' => $charge_pile_number,
'area' => ''
];
$mess = Db::table($table)->where([['openid', '=', $openid], ['charge_pile_number', '=', $charge_pile_number]])->find();
if ($mess == null) {
$result = Db::table($table)->insert($pile_data);
if ($result == 1) {
return json(['code' => 200, 'massage' => '收藏成功']);
} else {
return json(['code' => 1, 'massage' => '收藏失败']);
}
} else {
return json(['code' => 1, 'massage' => '已收藏过']);
}
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
//
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* 删除指定资源
*
* @return \think\Response
*/
public function delete(Request $request)
{
$data = $request->param();
$table = 'zxc_user_collect';
$openid = $data['openid'];
$charge_pile_number = $data['charge_pile_number'];
$massage = [
['openid', '=', $openid],
['charge_pile_number', '=', $charge_pile_number]
];
$result = Db::table($table)->where($massage)->delete();
if ($result != 0) {
return json(['code' => 200, 'massage' => '取消收藏成功']);
} else {
return json(['code' => 1, 'massage' => '取消收藏失败']);
}
}
}

View File

@@ -0,0 +1,528 @@
<?php
namespace app\controller;
use app\model\EnterpriseGroup;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use think\facade\Db;
class UserGroup
{
public function UserList($type, $group_id = '')
{
$data = input();
$page = $data['page'] ?? 1;
$pageSize = $data['pageSize'] ?? 10;
$list = Db::table('zxc_user')->paginate([
'list_rows' => 20,
'query' => request()->param()
]); // 获取全部数据
return json($list);
}
public function EnterpriseGroupAdd($group_name, $group_msg)
{
$add = (new \app\model\EnterpriseGroup)->save(['group_name' => $group_name, 'group_msg' => $group_msg]);
if ($add == 1) {
$m = (new \app\model\EnterpriseGroup)->where('group_name', $group_name)->find();
Db::table('service_fee')->save(
['type' => 3, 'group_id' => $m['id'], 'service_fee' => '服务费:00:00~24:00:0.40', 'station_type' => 0]
);
Db::table('service_fee')->save(
['type' => 3, 'group_id' => $m['id'], 'service_fee' => '服务费:00:00~24:00:0.40', 'station_type' => 1]
);
return json(['code' => 200, 'msg' => '新增成功', 'data' => $m]);
} else {
return json(['code' => 404, 'msg' => '新增失败']);
}
}
public function EnterpriseAdd($phone, $group_id)
{
}
public function NormalSearch($phone)
{
if (!empty($phone)) {
$list = Db::table('zxc_user')->where('phone', $phone)->where('type', 1)->find();
$array[] = $list;
return json(['code' => 200, 'msg' => '请求成功', 'data' => $array]);
} else {
return json(['code' => 404, 'msg' => '没有数据']);
}
return json(['code' => 404, 'msg' => '没有数据']);
}
public function NormalToEnterprise($phone, $group_id)
{
$ll = Db::table('zxc_user')->where('phone', $phone)->find();
$list = Db::table('zxc_user')->where('phone', $phone)->save(['type' => 3, 'group_id' => $group_id]);
if ($list == 1) {
$data = Db::table('zxc_user')->where('phone', $phone)->find();
$check = EnterpriseUser::where('phone', $phone)->find();
if (empty($check)) {
(new \app\model\EnterpriseUser)->save(['phone' => $phone, 'group_id' => $group_id, 'openid' => $ll['openid']]);
} else {
(new \app\model\EnterpriseUser)->where('phone', $phone)->save(['phone' => $phone, 'group_id' => $group_id, 'openid' => $ll['openid']]);
}
return json(['code' => 200, 'msg' => '添加成功', 'data' => $data]);
}
return json(['code' => 404, 'msg' => '添加失败']);
}
public function GetGroup()
{
$group = EnterpriseGroup::select();
return json($group);
}
public function DeleteEnterpriseUser($openid)
{
$table = 'zxc_user';
$msg = Db::table($table)->where('openid', $openid)->find();
if (!empty($msg)) {
$phone = Db::table($table)->where('openid', $openid)->value('phone');
$destroy = Db::table($table)->where('openid', $openid)->save(['type' => 1, 'group_id' => '']);
$EnterptiseUserDelete = EnterpriseUser::where('phone', $phone)->delete();
if ($destroy == 1 && $EnterptiseUserDelete == 1) {
return json(['code' => 200, 'msg' => '移除成功']);
} else {
return json(['code' => 404, 'msg' => '移除失败']);
}
} else {
return json(['code' => 404, 'msg' => '不存在该用户']);
}
}
public function DeleteEnterpriseGroup($group_id)
{
$user = EnterpriseUser::where('group_id', $group_id)->select();
foreach ($user as $u) {
$this->DeleteEnterpriseUser($u['openid']);
}
$EnterptiseGroupDelete = EnterpriseGroup::where('id', $group_id)->delete();
$ServerFeeDelete = ServiceFee::where('group_id', $group_id)->delete();
if ($EnterptiseGroupDelete > 0 && $ServerFeeDelete > 0) {
return json(['code' => 200, 'msg' => '删除成功']);
} else {
return json(['code' => 404, 'msg' => '删除失败']);
}
}
public function PhoneSearch($phone)
{
$message = EnterpriseUser::where('phone', 'like', '%' . $phone . '%')->select();
$i = 0;
foreach ($message as $m) {
$message[$i]['group_name'] = EnterpriseGroup::where('id', $m['group_id'])->value('group_name');
$table = 'zxc_user';
$account = Db::table($table)->where('openid', $m['openid'])->value('account');
$message[$i]['account'] = $account;
$i += 1;
}
return json(['data' => $message]);
}
public function EnterpriserUserEdit($phone, $group_id)
{
$o_data = EnterpriseUser::where('phone', $phone)->find();
$o_data['group_name'] = EnterpriseGroup::where('id', $o_data['group_id'])->value('group_name');
$edit = EnterpriseUser::where('phone', $phone)->save(['group_id' => $group_id]);
if ($edit != 0) {
$n_data = EnterpriseUser::where('phone', $phone)->find();
$n_data['group_name'] = EnterpriseGroup::where('id', $n_data['group_id'])->value('group_name');
return json(['code' => 200, 'mag' => '修改成功', 'before_data' => $o_data, 'now_data' => $n_data]);
} else {
return json(['code' => 404, 'msg' => '修改失败']);
}
}
public function Electricity($time_type = "", $str_day = "", $charge_station_name = '')
{
$where = [];
if (!empty($charge_station_name)) {
$charge_station_ids = Db::table('charge_station')->where('charge_station_name', 'in', $charge_station_name)->column('charge_station_id');
$ids = array_map('intval', $charge_station_ids); // 强制转为整数
$where[] = ['charge_station_id', 'in', $ids];
}
// 设置日期范围
$currentDate = $str_day ?: date('Y-m-d');
$time_type = $time_type ?: '天';
switch ($time_type) {
case '天':
$startDate = $currentDate . ' 00:00:00';
$endDate = $currentDate . ' 23:59:59';
break;
case '周':
$monday = date('Y-m-d', strtotime('monday this week', strtotime($currentDate)));
$sunday = date('Y-m-d', strtotime('sunday this week', strtotime($currentDate)));
$startDate = $monday . ' 00:00:00';
$endDate = $sunday . ' 23:59:59';
break;
case '月':
$firstDay = date('Y-m-01', strtotime($currentDate));
$lastDay = date('Y-m-t', strtotime($currentDate));
$startDate = $firstDay . ' 00:00:00';
$endDate = $lastDay . ' 23:59:59';
break;
default:
throw new Exception('不支持的统计类型');
}
$where[] = ['start_time', '>=', $startDate];
$where[] = ['start_time', '<=', $endDate];
$allData = Db::table('zxc_charge_order')
->where($where)
->field('charge_station_id, start_time, TotalPower')
->select();
// 2. 初始化12个时段统计数据
$hourlyStats = [];
for ($hour = 0; $hour < 24; $hour += 2) {
$startHour = str_pad($hour, 2, '0', STR_PAD_LEFT);
$endHour = str_pad($hour + 2, 2, '0', STR_PAD_LEFT);
$timeKey = $startHour . ':00~' . ($hour == 22 ? '23:59' : $endHour . ':00');
$hourlyStats[$timeKey] = [
'time_range' => $timeKey,
'power' => '0',
'order_count' => 0
];
}
// 3. 遍历数据按时段统计
$totalPower = 0;
foreach ($allData as $row) {
$hour = date('H', strtotime($row['start_time']));
$timeKey = $this->getTimeKeyForHour($hour);
if (isset($hourlyStats[$timeKey])) {
$hourlyStats[$timeKey]['power'] = bcadd($hourlyStats[$timeKey]['power'], $row['TotalPower'], 4);
$hourlyStats[$timeKey]['order_count']++;
$totalPower = bcadd($totalPower, $row['TotalPower'], 4);
}
}
return [
'date_range' => ['start' => $startDate, 'end' => $endDate],
'total_power' => number_format((double)$totalPower, 4),
'total_orders' => count($allData),
'hourly_stats' => array_values($hourlyStats),
'time_interval' => '2小时',
'station' => $charge_station_name ?: '全部充电站'
];
}
/**
* 根据小时数获取对应的时间段key
*/
public function getTimeKeyForHour($hour)
{
$hour = (int)$hour;
$start = str_pad(floor($hour / 2) * 2, 2, '0', STR_PAD_LEFT);
$end = ($start == 22) ? '23:59' : str_pad($start + 2, 2, '0', STR_PAD_LEFT) . ':00';
return $start . ':00~' . $end;
}
protected function WeedDay($startdate, $enddate)
{
$stimestamp = strtotime($startdate);
$etimestamp = strtotime($enddate);
// 计算日期段内有多少天
$days = ($etimestamp - $stimestamp) / 86400;
// 保存每天日期
$date = array();
for ($i = 0; $i < $days; $i++) {
$date[] = date('Y-m-d 00:00:00', $stimestamp + (86400 * $i));
}
return $date;
}
public function PeriodElectricityConsumption($str_day, $charge_station_name = '')
{
$time = strtotime($str_day);
$start_time = date('Y-m-d 00:00:00', $time);
$date_start = $this->getDayDate($start_time)['start_time'];
$date_end = $this->getDayDate($start_time)['end_time'];
$i = 0;
$ss = 0;
$data = array();
foreach ($date_start as $d) {
$interval = substr($date_start[$ss], 11) . '~' . substr($date_end[$ss], 11);
$data[$ss]['interval'] = $interval;
$data[$ss]['Total'] = 0;
$ss += 1;
}
foreach ($date_start as $d) {
$table = 'zxc_charge_order';
$d_start = date('Y-m-d H:i:s', strtotime($date_start[$i]));
$d_end = date('Y-m-d H:i:s', strtotime($date_end[$i]));
if (!empty($charge_station_name)) {
$station_id = Db::table('charge_station')->where('charge_station_name', $charge_station_name)->value('charge_station_id');
$order = Db::table($table)->where('charge_station_id', $station_id)->whereBetweenTime('start_time', $d_start, $d_end)->select();
} else {
$order = Db::table($table)->whereBetweenTime('start_time', $d_start, $d_end)->select();
}
foreach ($order as $o) {
if (!empty($o['DetailMessage'])) {
if ($o['SumPeriod'] == 1) {
$data[$i]['Total'] += $o['TotalPower'];
} elseif ($o['SumPeriod'] == 2) {
$data[$i]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[0];
if ($i == 7) {
$data[$i - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1]; //再思考一下
} else {
$data[$i + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
}
} elseif ($o['SumPeriod'] == 3) {
$data[$i]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[0];
if ($i == 6) {
$data[$i + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
$data[$i + 1 - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[2];
} elseif ($i == 7) {
$data[$i - 7]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[1];
$data[$i - 7 + 1]['Total'] += $this->GetDetailMessage($o['DetailMessage'], $o['SumPeriod'])[2];
}
}
} else {
for ($a = 0; $a < count($this->GetTimeInterVal($o['start_time'], $o['end_time'])); $a++) {
if ($i + $a >= 7) {
$data[$i + $a - 7]['Total'] += round($o['TotalPower'] * $this->GetTimeInterVal($o['start_time'], $o['end_time'])[$a], 3);
} else {
$data[$i + $a]['Total'] += round($o['TotalPower'] * $this->GetTimeInterVal($o['start_time'], $o['end_time'])[$a], 3);
}
}
}
}
$i += 1;
}
for ($k = 0; $k < count($data); $k++) {
$data[$k]['Total'] = round($data[$k]['Total'], 2);
}
return $data;
}
public function GetTimeInterVal($start_time, $end_time)
{
$date = floor((strtotime($end_time) - strtotime($start_time)) / 86400);
$minute1 = floor((strtotime($end_time) - strtotime($start_time)) % 86400 / 60) + $date * 24 * 60;
$timeArray = $this->TimeProportion($start_time, $end_time);
$data = array();
for ($i = 0; $i < count($timeArray['start_time']); $i++) {
if ($i >= 8) {
$data['period'][$i - 8] += floor((strtotime($timeArray['end_time'][$i]) - strtotime($timeArray['start_time'][$i])) % 86400 / 60);
} else {
$data['period'][$i] = floor((strtotime($timeArray['end_time'][$i]) - strtotime($timeArray['start_time'][$i])) % 86400 / 60);
}
}
foreach ($data['period'] as $p) {
if ($minute1 != 0) {
$Proportion[] = round($p / $minute1, 3);
} else {
$Proportion[] = 0;
}
}
return $Proportion;
}
public function TimeProportion($order_start_time, $order_end_time)
{
$time = strtotime($order_start_time);
$start_time = date('Y-m-d 00:00:00', $time);
$end_time = date('Y-m-d 00:00:00', strtotime($order_end_time));
$start_d = date('d', $time);
$end_d = date('d', strtotime($order_end_time));
$timeArray = $this->getDayDate($start_time);
$arry2 = $this->getDayDate($end_time);
if ($start_d != $end_d) {
$timeArray = array_merge_recursive($timeArray, $arry2);
}
$data = array();
for ($i = 0; $i < count($timeArray['start_time']); $i++) {
if (date('Y-m-d H:i:s', strtotime($order_start_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
$data['start_time'][] = $order_start_time;
$data['end_time'][] = $order_end_time;
} elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
if (date('Y-m-d H:i:s', strtotime($order_start_time)) < date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
$data['start_time'][] = $order_start_time;
$data['end_time'][] = date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]));
}
} elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
if (date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
$data['start_time'][] = $timeArray['start_time'][$i];
$data['end_time'][] = $order_end_time;
}
} elseif (date('Y-m-d H:i:s', strtotime($order_start_time)) <= date('Y-m-d H:i:s', strtotime($timeArray['start_time'][$i])) && date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
if (date('Y-m-d H:i:s', strtotime($order_end_time)) >= date('Y-m-d H:i:s', strtotime($timeArray['end_time'][$i]))) {
$data['start_time'][] = $timeArray['start_time'][$i];
$data['end_time'][] = $timeArray['end_time'][$i];
}
}
}
return $data;
}
protected function getDayDate($date)
{
$date_t = array();
$date_t[] = $date;
$this_date = strtotime($date);
$end_date = date("Y-m-d H:i:s", strtotime('+8 hour -1 second', $this_date));
$date_end[] = $end_date;
$t = $this->GetPeriod($date, $end_date, $date_t, $date_end);
$kk['start_time'] = $t[1];
$kk['end_time'] = $t[0];
return $kk;
}
protected function GetDetailMessage($message, $period)
{
$array = explode(';', $message, $period);
foreach ($array as $a) {
$arr1 = explode(',', $a);
$degree = explode(':', $arr1[2])[1];
$data[] = $degree;
}
return $data;
}
protected function GetPeriod($date, $end_date, $date_t, $date_end, $array1 = [8, 3, 1, 2, 3, 3, 2, 2])
{
for ($i = 0; $i < count($array1) - 1; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d H:i:s", strtotime('+' . $array1[$i] . ' hour', $this_date));
$this_date_end = strtotime($end_date);
$next_date_end = date("Y-m-d H:i:s", strtotime('+' . $array1[$i + 1] . ' hour', $this_date_end));
$date_end[] = $next_date_end;
$date_t[] = $next_date;
$date = $next_date;
$next_date_end = date("Y-m-d H:59:59", strtotime($next_date_end));
$end_date = $next_date_end;
}
return [$date_end, $date_t];
}
public function ShowServiceFee($type, $station_type, $group_id = '')
{
if ($type != 3) {
$ServiceFee = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->value('service_fee');
} else {
$ServiceFee = (new \app\model\ServiceFee)->where('type', $type)->where('group_id', $group_id)->where('station_type', $station_type)->value('service_fee');
}
if ($station_type == 0) {
$station_type = '快充';
} else {
$station_type = '慢充';
}
$ServiceFee = str_replace('服务费:', '', $ServiceFee);
$Server = explode(',', $ServiceFee);
for ($index = 0; $index < count($Server); $index++) {
$ll['time_interval'] = substr($Server[$index], 0, -5);
$ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
$mm[] = $ll;
}
return json(['code' => 200, 'Station_Type' => $station_type, 'ServiceFee' => $mm]);
}
public function UpdateServiceFee($type, $station_type, $fee, $group_id = '')
{
$service = '服务费:00:00~24:00:' . number_format((float)$fee, 2);
if ($type == 1) {
$update = (new \app\model\ChargeStation)->where('station_type', $station_type)->save(['ServiceFee' => $service]);
$feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->save(['service_fee' => $service]);
if ($update >= 1 && $feeUpdate == 1) {
return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
} else {
return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
}
} elseif ($type == 2) {
$feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->save(['service_fee' => $service]);
if ($feeUpdate == 1) {
return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
} else {
return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
}
} else {
$feeUpdate = (new \app\model\ServiceFee)->where('type', $type)->where('station_type', $station_type)->where('group_id', $group_id)->save(['service_fee' => $service]);
if ($feeUpdate == 1) {
return json(['code' => 200, 'message' => '修改成功', 'NowFee' => $service]);
} else {
return json(['code' => 1, 'message' => '金额未发生变化,修改失败']);
}
}
}
public function UserVip($openid)
{
$type = Db::table('zxc_user')->where('openid', $openid)->value('type');
if ($type == 1) {
$vip = 'normal';
return json(['code' => 200, 'vip' => $vip]);
} elseif ($type == 2) {
$vip = 'vip';
return json(['code' => 200, 'vip' => $vip]);
} elseif ($type == 3) {
$vip = 'company';
$group_id = EnterpriseUser::where('openid', $openid)->value('group_id');
$group_name = EnterpriseGroup::where('id', $group_id)->value('group_name');
return json(['code' => 200, 'vip' => $vip, 'group_name' => $group_name]);
} else {
return json(['code' => 1]);
}
}
/**
* @param $start_time
* @param $end_time
* @param string $charge_station_name
* @param array $DataAll
* @return \think\response\Json
*/
protected function GetData($start_time, $end_time, string $charge_station_name, array $DataAll): \think\response\Json
{
$date = $this->WeedDay($start_time, $end_time);
foreach ($date as $d) {
$data = $this->PeriodElectricityConsumption($d, $charge_station_name);
for ($i = 0; $i < count($data); $i++) {
$DataAll[$i]['Total'] += $data[$i]['Total'];
}
}
$all = 0;
for ($k = 0; $k < count($DataAll); $k++) {
$DataAll[$k]['Total'] = round($DataAll[$k]['Total'], 2);
$all += $DataAll[$k]['Total'];
}
return json(['data' => $DataAll, 'all' => round($all, 2)]);
}
}

View File

@@ -0,0 +1,462 @@
<?php
namespace app\controller;
use think\facade\Db;
use think\Request;
class UserRefund
{
public function UserReimburse($openid, $money)
{
$money = round($money, 2);
$user_info = Db::table('zxc_user')->where('openid', $openid)->find();
//判断金额 余额>=提现金额
if ($user_info['account'] < $money) {
return json(['code' => 1, 'message' => '余额不足']);
}
//正在进行余额充电的订单不可提现
$count = Db::table('zxc_charge_order')
->where('openid', $openid)
->where('type', 2)
->where('end_time', null)
->find();
if ($count > 0) {
return json(['code' => 1, 'message' => '存在未结算订单']);
}
$table_recharge = 'zxc_recharge';
$reOrder = $this->SelectReOrder($openid, $money, $table_recharge);
if (empty($reOrder)) {
return json(['code' => 1, 'message' => '提现数据为空']);
}
$i = 0;
$suceess = 0;
$fail = 0;
foreach ($reOrder as $key => $value) {
$transaction_id = $key;
$OriginalOrderAmount = Db::table($table_recharge)->where('transaction_id', $transaction_id)->value('total');
$OriginalOrderAmount /= 100;
$refundAmount = $value / 100;
$td = new WechatReimburse();
$kk[] = $td->Refund($transaction_id, $openid, $refundAmount, $OriginalOrderAmount);
if ($kk[$i]['code'] == 200) {
$suceess += 1;
} elseif ($kk[$i]['code'] == 1) {
$fail += 1;
}
$i += 1;
}
return json(['code' => 200, 'total' => $i, 'success' => $suceess, 'fail' => $fail, 'message' => $kk, 'reOrder' => $reOrder]);
exit();
$account = Db::table($table_user)->where('openid', $openid)->value('account');
$account = round($account, 2);
$frozenAmount = Db::table($table_user)->where('openid', $openid)->value('FrozenAccount');
if ($money <= $account) {
$OrderList = new ChargeOrder();
$OrderList->OrderList($openid);//更新一下状态
//二次确认
$recharge_all = Db::table($table_recharge)->where('openid', $openid)->sum('total');
$recharge_all /= 100;
$refund_all = Db::table($table_refund)->where('openid', $openid)
->where('status', 'SUCCESS')
->sum('refund_total');
$refund_all /= 100;
$check = Db::table($table_order)->where('openid', $openid)
->where('status', '<>', 4)
->where('status', '<>', 5)
->order('start_time desc')
->value('end_time');
if (empty($check)) {
$order_all = Db::table($table_order)->where('openid', $openid)
->where('status', 4)
->sum('TotalMoney');
$inorder = Db::table($table_order)->where('openid', $openid)
->where('status', '<>', 4)
->where('status', '<>', 5)
->order('start_time desc')
->value('WithholdingMoney');
$order_total = $order_all + $inorder;
} else {
$order_total = Db::table($table_order)->where('openid', $openid)
->where('status', 4)
->sum('TotalMoney');
}
$order_total = round($order_total, 2);
$mask = round($recharge_all - $order_total - $refund_all, 2); //这里还要减已经提现的
if (round($mask, 2) == round($account, 2)) {
$reOrder = $this->SelectReOrder($openid, $money, $table_recharge);
if (empty($reOrder)) {
return json(['code' => 1, 'message' => '提现数据为空']);
}
$i = 0;
$suceess = 0;
$fail = 0;
foreach ($reOrder as $key => $value) {
$transaction_id = $key;
$OriginalOrderAmount = Db::table($table_recharge)->where('transaction_id', $transaction_id)->value('total');
$OriginalOrderAmount /= 100;
$refundAmount = $value / 100;
$td = new WechatReimburse();
$kk[] = $td->Refund($transaction_id, $openid, $refundAmount, $OriginalOrderAmount);
if ($kk[$i]['code'] == 200) {
$suceess += 1;
} elseif ($kk[$i]['code'] == 1) {
$fail += 1;
}
$i += 1;
}
return json(['code' => 200, 'total' => $i, 'success' => $suceess, 'fail' => $fail, 'message' => $kk, 'reOrder' => $reOrder]);
} else {
Db::table('refundexception')->save([
'openid' => $openid,
'order_total' => $order_total,
'recharge_total' => $recharge_all,
'refund_total' => $refund_all,
'mask' => $mask,
'account' => $account
]);
return json(['code' => 1, 'message' => '账户异常', 'order_total' => $order_total, 'recharge_all' => $recharge_all, 'mask' => $mask]);
}
} else {
return json(['code' => 1, 'message' => '提现金额不能大于余额']);
}
}
public function SelectReOrder($openid, $money, $table_recharge)
{
$oneYearAgo = strtotime('-1 year');
$oneYearAgoDate = date('Y-m-d H:i:s', $oneYearAgo);
$reOrder = Db::table($table_recharge)->where('openid', $openid)->where('type', 1)->where('success_time', '>=', $oneYearAgoDate)->order('total')->select();
$money *= 100;
$money = floor($money);
$kk = array();
foreach ($reOrder as $re) {
if ($re['total'] - $re['total_used'] == 0) {
continue;
} else {
$backMoney = $re['total'] - $re['total_used'];
if ($money > $backMoney) {
$kk[$re['transaction_id']] = $backMoney;
$money = $money - $backMoney;
} elseif ($money == $backMoney) {
$kk[$re['transaction_id']] = $money;
break;
} else {
$kk[$re['transaction_id']] = $money;
break;
}
}
}
return $kk;
}
public function TKRecord($openid)
{
$table_refund = 'zxc_refund';
$message = Db::table($table_refund)->where('openid', $openid)->order('create_time desc')->select()->toArray();
$statusMap = [
'SUCCESS' => '退款成功',
'PROCESSING' => '退款处理中',
'ABNORMAL' => '退款异常',
'CLOSED' => '退款关闭',
];
foreach ($message as &$record) {
$record['refund_total'] = round($record['refund_total'] / 100, 2);
$record['status'] = $statusMap[$record['status']] ?? $record['status'];
}
return json($message);
}
public function RefundQuery($start_time = '', $end_time = '', $message = '')
{
// 处理结束时间
if (!empty($end_time)) {
$end_time = date("Y-m-d", strtotime("+1 day", strtotime($end_time)));
}
// 生成表名
$refundTable = 'zxc_refund';
$userTable = 'zxc_user';
// 构建查询条件
$query = Db::table($refundTable);
// 时间范围条件
if (!empty($start_time) && !empty($end_time)) {
$query->whereBetween('create_time', [$start_time, $end_time]);
}
// 消息条件
if (!empty($message)) {
if (strlen($message) == 11) {
$openid = Db::table($userTable)->where('phone', $message)->value('openid');
if ($openid) {
$query->where('openid', $openid);
} else {
$query->where('out_refund_no', 'like', "%{$message}%");
}
} else {
$query->where('out_refund_no', 'like', "%{$message}%");
}
}
// 获取数据并合并
$resultData = $query->order('create_time desc')->select()->toArray();
// 处理结果数据
foreach ($resultData as $index => &$item) {
$item['id'] = $index + 1;
$item['refund_total'] = round($item['refund_total'] / 100, 2);
$table = 'zxc_user';
$phone = Db::table($table)->where('openid', $item['openid'])->value('phone');
$item['phone'] = $phone;
}
return json($resultData);
}
public function Refund_Total(Request $request)
{
$data = $request->param();
$time_type = $data['time_type'];
$str_day = $data['str_time'];
$time = strtotime($str_day);
$date_time = date('Y-m-d', $time);
$area = Db::table('area_three')->column('area');
if ($time_type == '周') {
$mess = [];
$end_time = date("Y-m-d 23:59:59", strtotime("$date_time Saturday"));//结束时间(2020-04-19 23:59:59)
$start_time = date("Y-m-d 00:00:00", strtotime("$end_time - 6 days"));//开始时间(2020-04-13 00:00:00
$revenue_total = 0;
$order_num_total = 0;
$date = $this->getDateFromRange($start_time, $end_time);
foreach ($date as $d) {
$revenue = 0;
$order_num = 0;
$table_refund = 'zxc_refund';
$result = Db::table($table_refund)->select();
if (empty($result)) {
continue;
} else {
$recharge = Db::table($table_refund);
$revenue = $recharge->whereDay('create_time', $d)->sum('refund_total');
$order_num = $recharge->whereDay('create_time', $d)->count();
}
$mess['per'][] = ['time' => $d, 'data' => ['EnterAccount' => round($revenue / 100, 2), 'AccountNum' => $order_num]];
$revenue_total += $revenue;
$order_num_total += $order_num;
}
$mess['total'] = ['EnterAccount' => round($revenue_total / 100, 2), 'AccountNum' => $order_num_total];
return json($mess);
} elseif ($time_type == '月') {
$mess = [];
$start_time = date("Y-m-d", strtotime(date('Y-m-01', $time)));//开始时间(2020-04-01 00:00:00)
$date = $this->getMonthDate($start_time);
$i = 1;
$revenue_total = 0;
$order_num_total = 0;
foreach ($date as $d) {
$z = '第' . $i . '周';
$d = date('Y-m-d', strtotime($d));
$revenue = 0;
$order_num = 0;
$table_refund = 'zxc_refund';
$result = Db::table($table_refund)->select();
if (empty($result)) {
continue;
} else {
$recharge = Db::table($table_refund);
$revenue = $recharge->whereWeek('create_time', $d)->sum('refund_total');
$order_num = $recharge->whereWeek('create_time', $d)->count();
}
$mess['per'][] = ['time' => $z, 'data' => ['EnterAccount' => round($revenue / 100, 2), 'AccountNum' => $order_num]];
$revenue_total += $revenue;
$order_num_total += $order_num;
$i += 1;
}
$mess['total'] = ['EnterAccount' => round($revenue_total / 100, 2), 'AccountNum' => $order_num_total];
return json($mess);
} elseif ($time_type == '季') {
$season = intval(ceil(date('m', $time) / 3));
if ($season == 4) {
$start_time = date("Y-m-d H:i:s", strtotime(date('Y-' . ($season * 3 - 2) . '-01', $time)));//开始时间(2020-04-01 00:00:00)
$end_time = date("Y-m-d 23:59:59", strtotime(date('Y-m-d', strtotime("$start_time +3 month -1 day"))));//开始时间(2020-04-01 00:00:00)
} else {
$start_time = date("Y-m-d H:i:s", strtotime(date('Y-0' . ($season * 3 - 2) . '-01', $time)));//开始时间(2020-04-01 00:00:00)
$end_time = date("Y-m-d 23:59:59", strtotime(date('Y-m-d', strtotime("$start_time +3 month -1 day"))));//开始时间(2020-04-01 00:00:00)
}
$i = date("m", strtotime(date('Y-' . ($season * 3 - 2) . '-01', $time)));
if ((int)substr($i, 0, 1) == 0) {
$i = substr($i, -1);
}
$date = $this->getSeasonDate($start_time);
$mess = [];
$revenue_total = 0;
$order_num_total = 0;
foreach ($date as $d) {
$z = $i . '月';
$d = date('Y-m-d', strtotime($d));
$revenue = 0;
$order_num = 0;
$table_refund = 'zxc_refund';
$result = Db::table($table_refund)->select();
if (empty($result)) {
continue;
} else {
$recharge = Db::table($table_refund);
$revenue = $recharge->whereMonth('create_time', $d)->sum('refund_total');
$order_num = $recharge->whereMonth('create_time', $d)->count();
}
$mess['per'][] = ['time' => $z, 'data' => ['EnterAccount' => round($revenue / 100, 2), 'AccountNum' => $order_num]];
$revenue_total += $revenue;
$order_num_total += $order_num;
$i += 1;
}
$mess['total'] = ['EnterAccount' => round($revenue_total / 100, 2), 'AccountNum' => $order_num_total];
return json($mess);
} elseif ($time_type == '年') {
$start_time = date('Y-01-01 00:00:00', $time);//开始时间
$date = $this->getYearDate($start_time);
$mess = [];
$revenue_total = 0;
$order_num_total = 0;
$i = 1;
foreach ($date as $d) {
$z = $i . '月';
$d = date('Y-m', strtotime($d));
$revenue = 0;
$order_num = 0;
$table_refund = 'zxc_refund';
$result = Db::table($table_refund)->select();
if (empty($result)) {
continue;
} else {
$recharge = Db::table($table_refund);
$revenue = $recharge->whereMonth('create_time', $d)->sum('refund_total');
$order_num = $recharge->whereMonth('create_time', $d)->count();
}
$mess['per'][] = ['time' => $z, 'data' => ['EnterAccount' => round($revenue / 100, 2), 'AccountNum' => $order_num]];
$revenue_total += $revenue;
$order_num_total += $order_num;
$i += 1;
}
$mess['total'] = ['EnterAccount' => round($revenue_total / 100, 2), 'AccountNum' => $order_num_total];
return json($mess);
}
}
private function getDateFromRange($startdate, $enddate): array
{
$stimestamp = strtotime($startdate);
$etimestamp = strtotime($enddate);
// 计算日期段内有多少天
$days = ($etimestamp - $stimestamp) / 86400;
// 保存每天日期
$date = array();
for ($i = 0; $i < $days; $i++) {
$date[] = date('Y-m-d', $stimestamp + (86400 * $i));
}
return $date;
}
private function getMonthDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 4; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next monday', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
private function getSeasonDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 2; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next month', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
private function getYearDate($date)
{
$date_t = array();
$date_t[] = $date;
for ($i = 0; $i < 11; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d", strtotime('next month', $this_date));
$date_t[] = $next_date;
$date = $next_date;
}
return $date_t;
}
private function getDayDate($date)
{
$date_t = array();
$date_t[] = $date;
$this_date = strtotime($date);
$end_date = date("Y-m-d H:i:s", strtotime('+4 hour -1 second', $this_date));
$date_end[] = $end_date;
for ($i = 0; $i < 5; $i++) {
$this_date = strtotime($date);
$next_date = date("Y-m-d H:i:s", strtotime('+4 hour', $this_date));
$this_date_end = strtotime($end_date);
$next_date_end = date("Y-m-d H:i:s", strtotime('+4 hour', $this_date_end));
$date_end[] = $next_date_end;
$date_t[] = $next_date;
$date = $next_date;
$next_date_end = date("Y-m-d H:59:59", strtotime($next_date_end));
$end_date = $next_date_end;
}
$kk['start_time'] = $date_t;
$kk['end_time'] = $date_end;
return $kk;
}
}

View File

@@ -0,0 +1,775 @@
<?php
namespace app\controller;
use think\facade\Db;
use think\facade\Log;
class WechatPay
{
//微信支付
const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16;
public function config($openid, $money)
{
// 商户相关配置
$merchantId = config('wx.merchantId'); // 商户号
$merchantSerialNumber = config('wx.merchantSerialNumber');
$filepath = __DIR__ . config('wx.apiclientKey'); //私钥在本地的位置
$file = file_get_contents($filepath);
$mch_private_key = openssl_get_privatekey($file);
$appid = config('wx.AppID'); //小程序appid
$out_trade_no = $this->generate_recharge(6);
$data = [
"appid" => $appid,
"mchid" => $merchantId,
"description" => '个人钱包充值',
'out_trade_no' => $out_trade_no,
'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/sharenotify', //回调地址
"amount" => [
"total" => $money * 100,
"currency" => "CNY"
],
"payer" => [
"openid" => $openid //用户openid
]
];
$timestamp = time();
$nonce = date('YmdHis', time()) . rand(1000, 9999);
$url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$data = json_encode($data);
$message = 'POST' . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$data . "\n";
openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign = base64_encode($signature);
$schema = 'WECHATPAY2-SHA256-RSA2048';
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchantId, $nonce, $timestamp, $merchantSerialNumber, $sign);
$header = "Authorization: " . $schema . " " . $token;
$res = $this->http_post($url, $header, $data);
$arr = json_decode($res, true);
$time = time();
$str = time() . round('1000', '9999');
$prepay = 'prepay_id=' . $arr['prepay_id'];
$message1 = $appid . "\n" .
$time . "\n" .
$str . "\n" .
$prepay . "\n";
$prepay_id = $arr['prepay_id'];
openssl_sign($message1, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign1 = base64_encode($signature);
$data = array();
$data['appId'] = $appid;
$data['timeStamp'] = (string)$time;
$data['nonceStr'] = $str;
$data['package'] = 'prepay_id=' . $arr['prepay_id'];
$data['signType'] = 'RSA';
$data['paySign'] = $sign1;
return json($data);
}
function http_post($url, $header, $data)
{
$headers[] = "Accept:application/json";
$headers[] = "Content-Type:application/json";
$headers[] = "User-Agent:application/json";
$headers[] = $header;
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$tmpInfo = curl_exec($curl);
//关闭URL请求
curl_close($curl);
return $tmpInfo;
}
//支付回调
public function sharenotify()
{
try {
//code...
$header = $this->getHeaders(); //读取http头信息 见下文
$body = file_get_contents('php://input'); //读取微信传过来的信息是一个json字符串
if (empty($header) || empty($body)) {
throw new \Exception('通知参数为空', 2001);
}
$timestamp = $header['WECHATPAY-TIMESTAMP'];
$nonce = $header['WECHATPAY-NONCE'];
$signature = $header['WECHATPAY-SIGNATURE'];
$serialNo = $header['WECHATPAY-SERIAL'];
if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) {
throw new \Exception('通知头参数为空', 2002);
}
$cert = $this->getzhengshuDb(1);
if ($cert != $serialNo) {
throw new \Exception('验签失败', 2005);
}
$message = "$timestamp\n$nonce\n$body\n";
//校验签名
if (!$this->verify($message, $signature, __DIR__ . config('wx.pingtai_public_key_path'))) {
throw new \Exception('验签失败', 2005);
}
$decodeBody = json_decode($body, true);
if (empty($decodeBody) || !isset($decodeBody['resource'])) {
throw new \Exception('通知参数内容为空', 2003);
}
$decodeBodyResource = $decodeBody['resource'];
$decodeData_res = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'], $decodeBodyResource['ciphertext'], ''); //解密resource
$decodeData = json_decode($decodeData_res, true);
Log::error('用户充值: ' . $decodeData_res);
//返回结果格式
//array (
// 'mchid' => 'xxx',
// 'appid' => 'xxxxxxx',
// 'out_trade_no' => '1217752501201407033233368026',
// 'transaction_id' => '4200001336202201037507057791',
// 'trade_type' => 'NATIVE',
// 'trade_state' => 'SUCCESS',
// 'trade_state_desc' => '支付成功',
// 'bank_type' => 'OTHERS',
// 'attach' => '',
// 'success_time' => '2022-01-03T19:43:05+08:00',
// 'payer' =>
// array (
// 'openid' => 'ovs326bgwfA4o8jlFQXMEma2JZek',
// ),
// 'amount' =>
// array (
// 'total' => 1,
// 'payer_total' => 1,
// 'currency' => 'CNY',
// 'payer_currency' => 'CNY',
// ),
// )
//执行自己的代码start
$openid = $decodeData['payer']['openid'];
$data = [
'out_trade_no' => $decodeData['out_trade_no'],
'transaction_id' => $decodeData['transaction_id'],
'trade_state' => $decodeData['trade_state'],
'success_time' => date('Y-m-d H:i:s', time()),
'total' => $decodeData['amount']['total'] / 100,
'payer_total' => $decodeData['amount']['payer_total'] / 100,
'openid' => $openid
];
Db::table('zxc_recharge')->save($data);
Db::table('zxc_user')
->where('openid', $openid)
->update([
'account' => Db::raw('account+' . ($decodeData['amount']['total'] / 100))
]);
\app\model\User::addMoneyLog($openid, $decodeData['amount']['total'] / 100, 2, '用户充值');
//执行自己的代码end
exit();
} catch (\Exception $e) {
Log::error($e->getMessage());
$arr = array("code" => "ERROR", "message" => $e->getMessage());
echo json_encode($arr);
}
}
public function getHeaders()
{
$header = array();
foreach ($_SERVER as $key => $value) {
if ('HTTP_' == substr($key, 0, 5)) {
$header[str_replace('_', '-', substr($key, 5))] = $value;
}
if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$header['AUTHORIZATION'] = $_SERVER['PHP_AUTH_DIGEST'];
} elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
$header['AUTHORIZATION'] = base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW']);
}
if (isset($_SERVER['CONTENT_LENGTH'])) {
$header['CONTENT-LENGTH'] = $_SERVER['CONTENT_LENGTH'];
}
if (isset($_SERVER['CONTENT_TYPE'])) {
$header['CONTENT-TYPE'] = $_SERVER['CONTENT_TYPE'];
}
}
return $header;
}
//获取平台证书序列号
public function getzhengshuDb($getNew = 0)
{
if ($getNew !== 1) {
dump(file_get_contents(__DIR__ . config('wx.pingtai_public_key_path')));
}
$url = "https://api.mch.weixin.qq.com/v3/certificates";
$timestamp = time(); //时间戳
$nonce = $this->nonce_str(); //获取一个随机数
$body = "";
$mch_private_key = $this->getPrivateKey(); //读取商户api证书私钥
$merchant_id = config('wx.merchantId'); //服务商商户号
$serial_no = config('wx.merchantSerialNumber'); //在API安全中获取
$sign = $this->sign($url, 'GET', $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no); //签名
$header = [
'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
'Accept:application/json',
'User-Agent:' . $merchant_id
];
$result = $this->curl($url, '', $header, 'GET');
$result = json_decode($result, true);
$serial_no = $result['data'][0]['serial_no'];
file_put_contents(__DIR__ . '/../../Secret/serial_no.txt', $serial_no);
$encrypt_certificate = $result['data'][0]['encrypt_certificate'];
$sign_key = config('wx.apiV3key'); //在API安全中设置
$result = $this->decryptToString($encrypt_certificate['associated_data'], $encrypt_certificate['nonce'], $encrypt_certificate['ciphertext'], $sign_key); //解密
file_put_contents(__DIR__ . config('wx.pingtai_public_key_path'), $result);
return $serial_no;
}
//生成随机字符串
public function nonce_str($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
//读取商户api证书私钥
public function getPrivateKey()
{
return openssl_get_privatekey(file_get_contents(__DIR__ . config('wx.apiclientKey'))); //微信商户平台中下载下来,保存到服务器直接读取
}
//签名
public function sign($url, $http_method, $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no)
{
$url_parts = parse_url($url);
$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",signature="%s",timestamp="%d",serial_no="%s"',
$merchant_id,
$nonce,
$sign,
$timestamp,
$serial_no
);
return $token;
}
//curl提交
public function curl($url, $data = [], $header, $method = 'POST')
{
$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);
if ($method == "POST") {
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
private function decryptToString($associatedData, $nonceStr, $ciphertext, $aesKey = '')
{
if (empty($aesKey)) {
$aesKey = config('wx.apiV3key'); //微信商户平台 api安全中设置获取
}
$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, $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, $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',
$aesKey,
\OPENSSL_RAW_DATA,
$nonceStr,
$authTag,
$associatedData
);
}
throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
}
//签名验证操作
private function verify($message, $signature, $merchantPublicKey)
{
if (!in_array('sha256WithRSAEncryption', \openssl_get_md_methods(true))) {
throw new \RuntimeException("当前PHP环境不支持SHA256withRSA");
}
$signature = base64_decode($signature);
$a = openssl_verify($message, $signature, $this->getWxPublicKey($merchantPublicKey), 'sha256WithRSAEncryption');
return $a;
}
//获取平台公钥 获取平台证书序列号时存起来的cert.pem文件
protected function getWxPublicKey($key)
{
$public_content = file_get_contents($key);
$a = openssl_get_publickey($public_content);
return $a;
}
protected function generate_recharge($length)
{
$chars = '0123456789';
$time = time();
$password = 'DZZS' . $time . 'RE';
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
// 企业充值
public function EnterpriseConfig()
{
$params = input();
// 商户相关配置
$merchantId = config('wx.merchantId'); // 商户号
$merchantSerialNumber = config('wx.merchantSerialNumber');
$filepath = __DIR__ . config('wx.apiclientKey'); //私钥在本地的位置
$file = file_get_contents($filepath);
$mch_private_key = openssl_get_privatekey($file);
$appid = config('wx.AppID'); //小程序appid
$out_trade_no = $this->generate_recharge(6);
// 创建企业充值订单
Db::table('enterprise_recharge')->save([
'user_id' => $params['enterprise_user_id'],
'enterprise_id' => $params['enterprise_id'],
'recharge_no' => $out_trade_no,
'money' => $params['money'],
'create_time' => time()
]);
$data = [
"appid" => $appid,
"mchid" => $merchantId,
"description" => '充值企业余额',
'out_trade_no' => $out_trade_no,
'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/enterpriseChargeNotify', //回调地址
"amount" => [
"total" => $params['money'] * 100,
"currency" => "CNY"
],
"payer" => [
"openid" => $params['openid'] //用户openid
]
];
$timestamp = time();
$nonce = date('YmdHis', time()) . rand(1000, 9999);
$url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$data = json_encode($data);
$message = 'POST' . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$data . "\n";
openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign = base64_encode($signature);
$schema = 'WECHATPAY2-SHA256-RSA2048';
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchantId, $nonce, $timestamp, $merchantSerialNumber, $sign);
$header = "Authorization: " . $schema . " " . $token;
$res = $this->http_post($url, $header, $data);
$arr = json_decode($res, true);
$time = time();
$str = time() . round('1000', '9999');
$prepay = 'prepay_id=' . $arr['prepay_id'];
$message1 = $appid . "\n" .
$time . "\n" .
$str . "\n" .
$prepay . "\n";
$prepay_id = $arr['prepay_id'];
$key = 'ZuXingZhiYeYouXianGongSi15182231';
// $paySign = strtoupper(MD5("appId=$appid&nonceStr=$str&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$time&key=$key"));
openssl_sign($message1, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign1 = base64_encode($signature);
$data = array();
$data['appId'] = $appid;
$data['timeStamp'] = (string)$time;
$data['nonceStr'] = $str;
$data['package'] = 'prepay_id=' . $arr['prepay_id'];
$data['signType'] = 'RSA';
// $data['signType'] = $arr['prepay_id'];
$data['paySign'] = $sign1;
return json($data);
}
// 企业充值回调
//支付回调
public function enterpriseChargeNotify()
{
try {
//code...
$header = $this->getHeaders(); //读取http头信息 见下文
$body = file_get_contents('php://input'); //读取微信传过来的信息是一个json字符串
if (empty($header) || empty($body)) {
throw new \Exception('通知参数为空', 2001);
}
$timestamp = $header['WECHATPAY-TIMESTAMP'];
$nonce = $header['WECHATPAY-NONCE'];
$signature = $header['WECHATPAY-SIGNATURE'];
$serialNo = $header['WECHATPAY-SERIAL'];
if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) {
throw new \Exception('通知头参数为空', 2002);
}
$cert = $this->getzhengshuDb(1);
if ($cert != $serialNo) {
throw new \Exception('验签失败', 2005);
}
$message = "$timestamp\n$nonce\n$body\n";
//校验签名
if (!$this->verify($message, $signature, __DIR__ . config('wx.pingtai_public_key_path'))) {
throw new \Exception('验签失败', 2005);
}
$decodeBody = json_decode($body, true);
if (empty($decodeBody) || !isset($decodeBody['resource'])) {
throw new \Exception('通知参数内容为空', 2003);
}
$decodeBodyResource = $decodeBody['resource'];
$decodeData_res = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'], $decodeBodyResource['ciphertext'], ''); //解密resource
$decodeData = json_decode($decodeData_res, true);
Log::error('企业充值返回数据: ' . $decodeData_res);
Db::table('charge_logo')->save(['name' => '企业充值返回数据', 'mark' => $decodeData_res]);
//返回结果格式
//array (
// 'mchid' => 'xxx',
// 'appid' => 'xxxxxxx',
// 'out_trade_no' => '1217752501201407033233368026',
// 'transaction_id' => '4200001336202201037507057791',
// 'trade_type' => 'NATIVE',
// 'trade_state' => 'SUCCESS',
// 'trade_state_desc' => '支付成功',
// 'bank_type' => 'OTHERS',
// 'attach' => '',
// 'success_time' => '2022-01-03T19:43:05+08:00',
// 'payer' =>
// array (
// 'openid' => 'ovs326bgwfA4o8jlFQXMEma2JZek',
// ),
// 'amount' =>
// array (
// 'total' => 1,
// 'payer_total' => 1,
// 'currency' => 'CNY',
// 'payer_currency' => 'CNY',
// ),
// )
//执行自己的代码start
$info = Db::table('enterprise_recharge')->where('recharge_no', $decodeData['out_trade_no'])->where('status', 0)->find();
if ($info && $decodeData['trade_state'] == 'SUCCESS') {
// 充值成功,修改状态 增加余额
Db::table('enterprise_recharge')->where('id', $info['id'])->update(['status' => 1]);
Db::table('enterprise')->where('id', $info['enterprise_id'])->inc('money', $info['money'])->update();
\app\model\User::addMoneyLog($decodeData['payer']['openid'], $decodeData['amount']['total']/100, 2, '用户进行企业充值');
}
echo 'OK';
} catch (\Exception $e) {
Log::error($e->getMessage());
$arr = array("code" => "ERROR", "message" => $e->getMessage());
echo json_encode($arr);
}
}
// 即充即退支付信息
public function directlyConfig($out_trade_no, $openid, $money)
{
// 商户相关配置
$merchantId = config('wx.merchantId'); // 商户号
$merchantSerialNumber = config('wx.merchantSerialNumber');
$filepath = __DIR__ . config('wx.apiclientKey'); //私钥在本地的位置
$file = file_get_contents($filepath);
$mch_private_key = openssl_get_privatekey($file);
$appid = config('wx.AppID'); //小程序appid
$data = [
"appid" => $appid,
"mchid" => $merchantId,
"description" => '即充即退',
'out_trade_no' => $out_trade_no,
'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/directlychargenotify', //回调地址
"amount" => [
"total" => $money * 100,
"currency" => "CNY"
],
"payer" => [
"openid" => $openid //用户openid
]
];
$timestamp = time();
$nonce = date('YmdHis', time()) . rand(1000, 9999);
$url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$data = json_encode($data);
$message = 'POST' . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$data . "\n";
openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign = base64_encode($signature);
$schema = 'WECHATPAY2-SHA256-RSA2048';
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchantId, $nonce, $timestamp, $merchantSerialNumber, $sign);
$header = "Authorization: " . $schema . " " . $token;
$res = $this->http_post($url, $header, $data);
$arr = json_decode($res, true);
$time = time();
$str = time() . round('1000', '9999');
$prepay = 'prepay_id=' . $arr['prepay_id'];
$message1 = $appid . "\n" .
$time . "\n" .
$str . "\n" .
$prepay . "\n";
$prepay_id = $arr['prepay_id'];
openssl_sign($message1, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign1 = base64_encode($signature);
$data = array();
$data['appId'] = $appid;
$data['timeStamp'] = (string)$time;
$data['nonceStr'] = $str;
$data['package'] = 'prepay_id=' . $arr['prepay_id'];
$data['signType'] = 'RSA';
$data['paySign'] = $sign1;
$data['out_trade_no'] = $out_trade_no;
$data['openid'] = $openid;
return $data;
return json($data);
}
public function directlychargenotify()
{
try {
//code...
$header = $this->getHeaders(); //读取http头信息 见下文
$body = file_get_contents('php://input'); //读取微信传过来的信息是一个json字符串
if (empty($header) || empty($body)) {
throw new \Exception('通知参数为空', 2001);
}
$timestamp = $header['WECHATPAY-TIMESTAMP'];
$nonce = $header['WECHATPAY-NONCE'];
$signature = $header['WECHATPAY-SIGNATURE'];
$serialNo = $header['WECHATPAY-SERIAL'];
if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) {
throw new \Exception('通知头参数为空', 2002);
}
$cert = $this->getzhengshuDb(1);
if ($cert != $serialNo) {
throw new \Exception('验签失败', 2005);
}
$message = "$timestamp\n$nonce\n$body\n";
//校验签名
if (!$this->verify($message, $signature, __DIR__ . config('wx.pingtai_public_key_path'))) {
throw new \Exception('验签失败', 2005);
}
$decodeBody = json_decode($body, true);
if (empty($decodeBody) || !isset($decodeBody['resource'])) {
throw new \Exception('通知参数内容为空', 2003);
}
$decodeBodyResource = $decodeBody['resource'];
$decodeData_res = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'], $decodeBodyResource['ciphertext'], ''); //解密resource
$decodeData = json_decode($decodeData_res, true);
Log::error('即充即退充值返回数据: ' . $decodeData_res);
Db::table('charge_logo')->save(['name' => '即充即退返回数据', 'mark' => $decodeData_res]);
//返回结果格式
//array (
// 'mchid' => 'xxx',
// 'appid' => 'xxxxxxx',
// 'out_trade_no' => '1217752501201407033233368026',
// 'transaction_id' => '4200001336202201037507057791',
// 'trade_type' => 'NATIVE',
// 'trade_state' => 'SUCCESS',
// 'trade_state_desc' => '支付成功',
// 'bank_type' => 'OTHERS',
// 'attach' => '',
// 'success_time' => '2022-01-03T19:43:05+08:00',
// 'payer' =>
// array (
// 'openid' => 'ovs326bgwfA4o8jlFQXMEma2JZek',
// ),
// 'amount' =>
// array (
// 'total' => 1,
// 'payer_total' => 1,
// 'currency' => 'CNY',
// 'payer_currency' => 'CNY',
// ),
// )
//执行自己的代码start
if ($decodeData['trade_state'] == 'SUCCESS') {
$account = $decodeData['amount']['total'] / 100;
$time = time();
Db::table('zxc_charge_order')->save([
'type' => 1,
'openid' => $decodeData['payer']['openid'],
'directly_pay_no' => $decodeData['out_trade_no'],
'directly_pay_status' => 1,
'directly_pay_time' => $time,
'directly_prepaid_amount' => $account,
'WithholdingMoney' => $account,
'start_time' => date('Y-m-d H:i:s', $time),
]);
Db::table('zxc_recharge')->save([
'type' => 2,
'openid' => $decodeData['payer']['openid'],
'out_trade_no' => $decodeData['out_trade_no'],
'transaction_id' => $decodeData['transaction_id'],
'trade_state' => $decodeData['trade_state'],
'total' => $account,
'payer_total' => $account,
'success_time' => date('Y-m-d H:i:s', $time),
]);
\app\model\User::addMoneyLog($decodeData['payer']['openid'], $decodeData['amount']['total'] / 100, 2, '用户使用即充即退-充值');
}
echo 'OK';
} catch (\Exception $e) {
Log::error($e->getMessage());
$arr = array("code" => "ERROR", "message" => $e->getMessage());
echo json_encode($arr);
}
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace app\controller;
class WechatRefund
{
//如果$noNeedLogin为空表示所有接口都需要登录才能请求
//如果$noNeedRight为空表示所有接口都需要验证权限才能请求
//如果接口已经设置无需登录,那也就无需鉴权了
//
// 无需登录的接口,*表示全部
protected $noNeedLogin = ['*'];
// 无需鉴权的接口,*表示全部
public function tixian($batch_name,$out_trade_no,$money,$openid){
$time = time();
$url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
$pars = [];
$pars['appid'] = 'wxd4a063976744b464';//直连商户的appid
$pars['out_batch_no'] = 'DZZX'.$time.mt_rand(1000, 9999);//商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
$pars['batch_name'] = $batch_name;//该笔批量转账的名称
$pars['batch_remark'] = $batch_name;//转账说明UTF8编码最多允许32个字符
$pars['total_amount'] = $money;//转账总金额 单位为“分”
$pars['total_num'] = 1;//转账总笔数
$pars['transfer_detail_list'][0] = [
'out_detail_no'=> $out_trade_no,
'transfer_amount'=>$pars['total_amount'],
'transfer_remark'=>$batch_name,
'openid'=>$openid
];//转账明细列表
$token = $this->getToken($pars);//获取token
$res = $this->https_request($url,json_encode($pars),$token);//发送请求
$resArr = json_decode($res,true);
return $resArr;
//成功返回
// array(3) {
// ["batch_id"] => string(40) "1030001016101247194272022062900873000000"
// ["create_time"] => string(25) "2022-06-29T10:21:30+08:00"
// ["out_batch_no"] => string(16) "sjzz202206291647001"
// }
}
function https_request($url,$data = null,$token){
$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:WECHATPAY2-SHA256-RSA2048 '.$token,
'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;
}
public function getToken($pars)
{
// $url = 'https://api.mch.weixin.qq.com/v3/certificates';
$url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
$http_method = 'POST';//请求方法GET,POST,PUT
$timestamp = time();//请求时间戳
$url_parts = parse_url($url);//获取请求的绝对URL
$nonce = $timestamp.rand('10000','99999');//请求随机串
$body = json_encode((object)$pars);//请求报文主体
$stream_opts = [
"ssl" => [
"verify_peer"=>false,
"verify_peer_name"=>false,
]
];
$apiclient_cert_path = 'D:\wamp64\www\ChargePile\Secret\apiclient_cert_refund.pem';
$apiclient_key_path = 'D:\wamp64\www\ChargePile\Secret\apiclient_key_refund.pem';
$apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path,false, stream_context_create($stream_opts)));
$serial_no = $apiclient_cert_arr['serialNumberHex'];//证书序列号
$mch_private_key = file_get_contents($apiclient_key_path,false, stream_context_create($stream_opts));//密钥
$merchant_id = '1635719083';//商户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 $token;
}
}

View File

@@ -0,0 +1,615 @@
<?php
namespace app\controller;
use think\facade\Db;
use think\facade\Log;
class WechatReimburse
{
//微信支付
const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16;
//用户余额退款
public function Refund($transaction_id, $openid, $refundAmount, $OriginalOrderAmount)
{ //商户订单号,微信生成的退款订单号 二选一即可
$file = file_get_contents(__DIR__ . config('wx.apiclientKey'));
$mch_private_key = openssl_get_privatekey($file);
$time = time();
$out_refund_no = $this->generate_tuikuan(6);
$refundData = [
'transaction_id' => $transaction_id,
'out_refund_no' => $out_refund_no,
'reason' => '余额退款',
'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/refund_notify',
'funds_account' => 'AVAILABLE',
'amount' => [
'refund' => floor($refundAmount * 100), //退款标价金额,单位为分,可以做部分退款
'total' => $OriginalOrderAmount * 100, //订单总金额,单位为分
'currency' => 'CNY'
]
];
// if(!$transaction_id){ //商户订单号,微信生成的退款订单号 二选一即可
// if(!$out_trade_no){
// return ['code'=>0,'msg'=>'退款订单号不能为空'];
// }else{
// $refundData['out_trade_no']=$out_trade_no;
// }
// }else{
// $refundData['transaction_id']=$transaction_id;
// }
$url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';
$url_parts = parse_url($url); //拆解为:[scheme=>https,host=>api.mch.weixin.qq.com,path=>/v3/pay/transactions/native]
$mchid = config('wx.merchantId');//商户ID
$xlid = config('wx.merchantSerialNumber');//证书序列号
$refundData = json_encode($refundData);
$nonce = date('YmdHis', time()) . rand(1000, 9999);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
// $key = $this->getSign($refundData,$urlarr['path'],$nonce,$time);
$message = 'POST' . "\n" .
$canonical_url . "\n" .
$time . "\n" .
$nonce . "\n" .
$refundData . "\n";
openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign = base64_encode($signature);
$schema = 'WECHATPAY2-SHA256-RSA2048';
$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $mchid, $xlid, $nonce, $time, $sign);
$header = "Authorization: " . $schema . " " . $token;
// $header = array(
// 'Accept: application/json',
// 'Content-Type: application/json',
// 'User-Agent:*/*',
// 'Authorization: WECHATPAY2-SHA256-RSA2048 '.$token
// );
$res = $this->http_post($url, $header, $refundData);
Db::table('charge_logo')->save(['name' => '余额提现', 'mark' => $res]);
$res_array = json_decode($res, true);
// dd($res_array);
if (isset($res_array['status']) && ($res_array['status'] == 'PROCESSING' || $res_array['status'] == 'SUCCESS')) {
$kk['openid'] = $openid;
$create_time = $res_array['create_time'];
$create_time = str_replace('T', ' ', $create_time);
$create_time = substr($create_time, 0, -6);
$kk = [
'openid' => $openid,
'create_time' => $create_time,
'out_trade_no' => $res_array['out_trade_no'],
'out_refund_no' => $res_array['out_refund_no'],
'refund_id' => $res_array['refund_id'],
'status' => $res_array['status'],
'transaction_id' => $res_array['transaction_id'],
'user_received_account' => $res_array['user_received_account'],
'refund_total' => $res_array['amount']['refund'],
];
$table = 'zxc_refund';
$table_recharge = 'zxc_recharge';
$table_user = 'zxc_user';
Db::transaction(function () use ($table_recharge, $res_array, $openid, $table_user, $kk, $table) {
Db::table($table)->save($kk);
Db::table($table_user)->where('openid', $openid)
->update([
'account' => Db::raw('account-' . ($res_array['amount']['refund'] / 100)),
]);
Db::table($table_recharge)->where('out_trade_no', $res_array['out_trade_no'])->update(['total_used' => Db::raw('total_used+' . ($res_array['amount']['refund']))]);
});
return ['code' => 200, 'msg' => '退款受理成功'];
} else {
return ['code' => 1, 'msg' => $res_array['message']];
}
}
//退款回调地址
public function refund_notify()
{
try {
//code...
$header = $this->getHeaders(); //读取http头信息 见下文
$body = file_get_contents('php://input'); //读取微信传过来的信息是一个json字符串
if (empty($header) || empty($body)) {
throw new \Exception('通知参数为空', 2001);
}
$timestamp = $header['WECHATPAY-TIMESTAMP'];
$nonce = $header['WECHATPAY-NONCE'];
$signature = $header['WECHATPAY-SIGNATURE'];
$serialNo = $header['WECHATPAY-SERIAL'];
if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) {
throw new \Exception('通知头参数为空', 2002);
}
$cert = $this->getzhengshuDb(1);
if ($cert != $serialNo) {
throw new \Exception('验签失败', 2005);
}
$message = "$timestamp\n$nonce\n$body\n";
//校验签名
if (!$this->verify($message, $signature, __DIR__ . config('wx.pingtai_public_key_path'))) {
throw new \Exception('验签失败', 2005);
}
$decodeBody = json_decode($body, true);
if (empty($decodeBody) || !isset($decodeBody['resource'])) {
throw new \Exception('通知参数内容为空', 2003);
}
$decodeBodyResource = $decodeBody['resource'];
$decodeData_res = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'], $decodeBodyResource['ciphertext'], ''); //解密resource
$decodeData = json_decode($decodeData_res, true);
Db::table('charge_logo')->save(['name' => '余额提现回调', 'mark' => $decodeData]);
Log::error('余额提现: ' . $decodeData);
//返回结果格式
//array (
// 'mchid' => 'xxx',
// 'appid' => 'xxxxxxx',
// 'out_trade_no' => '1217752501201407033233368026',
// 'transaction_id' => '4200001336202201037507057791',
// 'trade_type' => 'NATIVE',
// 'trade_state' => 'SUCCESS',
// 'trade_state_desc' => '支付成功',
// 'bank_type' => 'OTHERS',
// 'attach' => '',
// 'success_time' => '2022-01-03T19:43:05+08:00',
// 'payer' =>
// array (
// 'openid' => 'ovs326bgwfA4o8jlFQXMEma2JZek',
// ),
// 'amount' =>
// array (
// 'total' => 1,
// 'payer_total' => 1,
// 'currency' => 'CNY',
// 'payer_currency' => 'CNY',
// ),
// )
//执行自己的代码start
$out_refund_no = $decodeData['out_refund_no'];
$openid = Db::table('zxc_refund')->where('out_refund_no', $out_refund_no)->value('openid');
$table = 'zxc_refund';
$table_user = 'zxc_user';
$kk['status'] = $decodeData['refund_status'];
if ($decodeData['refund_status'] == 'SUCCESS') {
$success_time = $decodeData['success_time'];
$success_time = str_replace('T', ' ', $success_time);
$success_time = substr($success_time, 0, -6);
$kk['success_time'] = $success_time;
Db::table($table_user)->where('openid', $openid)->update(['FrozenAccount' => Db::raw('FrozenAccount-' . ($decodeData['amount']['refund'] / 100))]);
}
Db::table($table)->where('out_refund_no', $out_refund_no)->save($kk);
\app\model\User::addMoneyLog($openid, $decodeData['amount']['refund'], 3, '用户提现');
// $order_info = Db::table($table)->save($data);
// Db::table($table_user)->where('openid',$openid)->update(['account' => Db::raw('account+'.($total/100))]);
//执行自己的代码end
$arr = array("code" => "SUCCESS", "message" => "");
echo json_encode($arr);
} catch (\Exception $e) {
Log::error($e->getMessage());
$arr = array("code" => "ERROR", "message" => $e->getMessage());
echo json_encode($arr);
}
// $notifiedData = file_get_contents('php://input');
// $data = json_decode($notifiedData, true);
// $nonceStr = $data['resource']['nonce'];
// $associatedData = $data['resource']['associated_data'];
// $ciphertext = $data['resource']['ciphertext'];
// $ciphertext = base64_decode($ciphertext);
// //php>7.1,为了使用这个扩展你必须将extension=php_sodium.dll添加到php.ini
// if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
// //$APIv3_KEY就是在商户平台后端设置是APIv3秘钥
// $orderData = \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->config['apiv3_private_key']);
// $orderData = json_decode($orderData, true);
// if ($orderData['refund_status']=='SUCCESS'){
// $transaction_id=$orderData['transaction_id']; //退款单号
//
// /*业务处理*/
// return json(['code'=>'SUCCESS','message'=>'成功']);
// }
// }
}
// 预充电余额退款
public function Refund2($charge_id, $openid, $refundAmount, $OriginalOrderAmount, $out_trade_no)
{ //商户订单号,微信生成的退款订单号 二选一即可
$file = file_get_contents(__DIR__ . config('wx.apiclientKey'));
$mch_private_key = openssl_get_privatekey($file);
$time = time();
$out_refund_no = $this->generate_tuikuan(6);
$refundData = [
'out_trade_no' => $out_trade_no,
'out_refund_no' => $out_refund_no,
'reason' => '预充电余额退款',
'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/refund_notify2',
'funds_account' => 'AVAILABLE',
'amount' => [
'refund' => floor($refundAmount * 100), //退款标价金额,单位为分,可以做部分退款
'total' => $OriginalOrderAmount * 100, //订单总金额,单位为分
'currency' => 'CNY'
]
];
$url = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';
$url_parts = parse_url($url); //拆解为:[scheme=>https,host=>api.mch.weixin.qq.com,path=>/v3/pay/transactions/native]
$mchid = config('wx.merchantId');//商户ID
$xlid = config('wx.merchantSerialNumber');//证书序列号
$refundData = json_encode($refundData);
$nonce = date('YmdHis', time()) . rand(1000, 9999);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
// $key = $this->getSign($refundData,$urlarr['path'],$nonce,$time);
$message = 'POST' . "\n" .
$canonical_url . "\n" .
$time . "\n" .
$nonce . "\n" .
$refundData . "\n";
openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
$sign = base64_encode($signature);
$schema = 'WECHATPAY2-SHA256-RSA2048';
$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $mchid, $xlid, $nonce, $time, $sign);
$header = "Authorization: " . $schema . " " . $token;
$res = $this->http_post($url, $header, $refundData);
$res_array = json_decode($res, true);
if (isset($res_array['status']) && ($res_array['status'] == 'PROCESSING' || $res_array['status'] == 'SUCCESS')) {
$info = Db::table('zxc_charge_order')
->where('order_id', $charge_id)->where('is_wind', 0)->find();
if ($info) {
Db::table('zxc_charge_order')
->where('order_id', $charge_id)
->update([
'directly_refund_no' => $out_refund_no,
'directly_refund_status' => 1,
'directly_refund_amount' => $res_array['amount']['refund'],
'directly_refund_time' => time(),
'is_wind' => 1
]);
$create_time = $res_array['create_time'];
$create_time = str_replace('T', ' ', $create_time);
$create_time = substr($create_time, 0, -6);
Db::table('zxc_refund')
->save([
'openid' => $openid,
'create_time' => $create_time,
'out_trade_no' => $res_array['out_trade_no'],
'out_refund_no' => $res_array['out_refund_no'],
'refund_id' => $res_array['refund_id'],
'status' => $res_array['status'],
'transaction_id' => $res_array['transaction_id'],
'user_received_account' => $res_array['user_received_account'],
'refund_total' => $res_array['amount']['refund'],
]);
\app\model\User::addMoneyLog($openid, $res_array['amount']['refund']/100, 3, '用户使用即充即退-退款');
}
return ['code' => 200, 'msg' => '退款受理成功'];
} else {
return ['code' => 1, 'msg' => $res_array['message']];
}
}
//退款回调地址
public function refund_notify2()
{
try {
//code...
$header = $this->getHeaders(); //读取http头信息 见下文
$body = file_get_contents('php://input'); //读取微信传过来的信息是一个json字符串
if (empty($header) || empty($body)) {
throw new \Exception('通知参数为空', 2001);
}
$timestamp = $header['WECHATPAY-TIMESTAMP'];
$nonce = $header['WECHATPAY-NONCE'];
$signature = $header['WECHATPAY-SIGNATURE'];
$serialNo = $header['WECHATPAY-SERIAL'];
if (empty($timestamp) || empty($nonce) || empty($signature) || empty($serialNo)) {
throw new \Exception('通知头参数为空', 2002);
}
$cert = $this->getzhengshuDb(1);
if ($cert != $serialNo) {
throw new \Exception('验签失败', 2005);
}
$message = "$timestamp\n$nonce\n$body\n";
//校验签名
if (!$this->verify($message, $signature, __DIR__ . config('wx.pingtai_public_key_path'))) { //$this->pingtai_public_key_path是获取平台证书序列号$this->getzhengshuDb()时保存下来的平台公钥文件
throw new \Exception('验签失败', 2005);
}
$decodeBody = json_decode($body, true);
if (empty($decodeBody) || !isset($decodeBody['resource'])) {
throw new \Exception('通知参数内容为空', 2003);
}
$decodeBodyResource = $decodeBody['resource'];
$decodeData_res = $this->decryptToString($decodeBodyResource['associated_data'], $decodeBodyResource['nonce'], $decodeBodyResource['ciphertext'], ''); //解密resource
$decodeData = json_decode($decodeData_res, true);
Log::error('用户使用即充即退退款: ' . $decodeData_res);
//返回结果格式
//array (
// 'mchid' => 'xxx',
// 'appid' => 'xxxxxxx',
// 'out_trade_no' => '1217752501201407033233368026',
// 'transaction_id' => '4200001336202201037507057791',
// 'trade_type' => 'NATIVE',
// 'trade_state' => 'SUCCESS',
// 'trade_state_desc' => '支付成功',
// 'bank_type' => 'OTHERS',
// 'attach' => '',
// 'success_time' => '2022-01-03T19:43:05+08:00',
// 'payer' =>
// array (
// 'openid' => 'ovs326bgwfA4o8jlFQXMEma2JZek',
// ),
// 'amount' =>
// array (
// 'total' => 1,
// 'payer_total' => 1,
// 'currency' => 'CNY',
// 'payer_currency' => 'CNY',
// ),
// )
//执行自己的代码start
$out_refund_no = $decodeData['out_refund_no'];
$arr = array("code" => "SUCCESS", "message" => "");
echo json_encode($arr);
} catch (\Exception $e) {
Log::error($e->getMessage());
$arr = array("code" => "ERROR", "message" => $e->getMessage());
echo json_encode($arr);
}
}
private function verify($message, $signature, $merchantPublicKey)
{
if (!in_array('sha256WithRSAEncryption', \openssl_get_md_methods(true))) {
throw new \RuntimeException("当前PHP环境不支持SHA256withRSA");
}
$signature = base64_decode($signature);
$a = openssl_verify($message, $signature, $this->getWxPublicKey($merchantPublicKey), 'sha256WithRSAEncryption');
return $a;
}
public function getNonceStr()
{
$strs = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
$name = substr(str_shuffle($strs), mt_rand(0, strlen($strs) - 11), 32);
return $name;
}
private function getzhengshuDb($getNew = 0)
{
if ($getNew !== 1) {
dump(file_get_contents(__DIR__ . config('wx.pingtai_public_key_path')));
}
$url = "https://api.mch.weixin.qq.com/v3/certificates";
$timestamp = time(); //时间戳
$nonce = $this->nonce_str(); //获取一个随机数
$body = "";
$mch_private_key = $this->getPrivateKey(); //读取商户api证书私钥
$merchant_id = config('wx.merchantId'); //服务商商户号
$serial_no = config('wx.merchantSerialNumber'); //在API安全中获取
$sign = $this->sign($url, 'GET', $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no); //签名
$header = [
'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
'Accept:application/json',
'User-Agent:' . $merchant_id
];
$result = $this->curl($url, '', $header, 'GET');
$result = json_decode($result, true);
$serial_no = $result['data'][0]['serial_no'];
file_put_contents(__DIR__ . '/../../Secret/tuikuan/serial_no.txt', $serial_no);
$encrypt_certificate = $result['data'][0]['encrypt_certificate'];
$sign_key = config('wx.apiV3key'); //在API安全中设置
$result = $this->decryptToString($encrypt_certificate['associated_data'], $encrypt_certificate['nonce'], $encrypt_certificate['ciphertext'], $sign_key); //解密
file_put_contents(__DIR__ . config('wx.pingtai_public_key_path'), $result);
return $serial_no;
}
private function getHeaders()
{
$header = array();
foreach ($_SERVER as $key => $value) {
if ('HTTP_' == substr($key, 0, 5)) {
$header[str_replace('_', '-', substr($key, 5))] = $value;
}
if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$header['AUTHORIZATION'] = $_SERVER['PHP_AUTH_DIGEST'];
} elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
$header['AUTHORIZATION'] = base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW']);
}
if (isset($_SERVER['CONTENT_LENGTH'])) {
$header['CONTENT-LENGTH'] = $_SERVER['CONTENT_LENGTH'];
}
if (isset($_SERVER['CONTENT_TYPE'])) {
$header['CONTENT-TYPE'] = $_SERVER['CONTENT_TYPE'];
}
}
return $header;
}
private function decryptToString($associatedData, $nonceStr, $ciphertext, $aesKey = '')
{
if (empty($aesKey)) {
$aesKey = config('wx.apiV3key'); //微信商户平台 api安全中设置获取
}
$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, $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, $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',
$aesKey,
\OPENSSL_RAW_DATA,
$nonceStr,
$authTag,
$associatedData
);
}
throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
}
private function http_post($url, $header, $data)
{
$headers[] = "Accept:application/json";
$headers[] = "Content-Type:application/json";
$headers[] = "User-Agent:application/json";
$headers[] = $header;
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$tmpInfo = curl_exec($curl);
//关闭URL请求
curl_close($curl);
return $tmpInfo;
}
//生成随机字符串
public function nonce_str($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
//读取商户api证书私钥
public function getPrivateKey()
{
return openssl_get_privatekey(file_get_contents(__DIR__ . config('wx.apiclientKey'))); //微信商户平台中下载下来,保存到服务器直接读取
}
//签名
public function sign($url, $http_method, $timestamp, $nonce, $body, $mch_private_key, $merchant_id, $serial_no)
{
$url_parts = parse_url($url);
$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",signature="%s",timestamp="%d",serial_no="%s"',
$merchant_id,
$nonce,
$sign,
$timestamp,
$serial_no
);
return $token;
}
//curl提交
public function curl($url, $data = [], $header, $method = 'POST')
{
$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);
if ($method == "POST") {
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
protected function generate_tuikuan($length)
{
$chars = '0123456789';
$time = time();
$password = 'DZZS' . $time . 'TK';
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
protected function getWxPublicKey($key)
{
$public_content = file_get_contents($key);
$a = openssl_get_publickey($public_content);
return $a;
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace app\controller;
use app\model\EnterpriseUser;
use think\facade\Db;
class WxGetPhone
{
public function getWxPhone($openid, $code)
{
$url_get = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . config("wx.AppID") . '&secret=' . config("wx.AppSecret");
$tmptoken = $this->getCurl($url_get);
$token = $tmptoken['access_token'];
$url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" . $token;
$data['code'] = $code;
$info = $this->Post(json_encode($data), $url);
$tmpinfo = json_decode($info, true);
$phoneNumber = $tmpinfo['phone_info']['phoneNumber'];
if ($tmpinfo['errcode'] != 0) {
return json(['code' => 1, 'msg' => $tmpinfo['errmsg']]);
}
$table = 'zxc_user';
$checkPhone = Db::table($table)->where('openid', $openid)->value('phone');
if (empty($checkPhone)) {
Db::table($table)->where('openid', $openid)->save(['phone' => $phoneNumber]);
return json(['code' => 200, 'msg' => '获取手机号成功', 'phone' => $phoneNumber]);
} else {
$type = Db::table($table)->where('openid', $openid)->value('type');
if ($type == 3 && $checkPhone != $phoneNumber) {
Db::startTrans();
try {
EnterpriseUser::where('openid', $openid)->save(['phone' => $phoneNumber]);
Db::table($table)->where('openid', $openid)->save(['phone' => $phoneNumber]);
// 提交事务
Db::commit();
return json(['code' => 200, 'msg' => '更改手机号成功', 'phone' => $phoneNumber]);
} catch (\Exception $e) {
Db::rollback();
}
} else {
Db::table($table)->where('openid', $openid)->save(['phone' => $phoneNumber]);
return json(['code' => 200, 'msg' => '获取手机号成功', 'phone' => $phoneNumber]);
}
}
}
private function getCurl($url)
{
$headerArray = array("Content-type:application/json;", "Accept:application/json");
$ch = curl_init();//初始化CURL
curl_setopt($ch, CURLOPT_URL, $url);//设置访问地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//HTTPS访问设置 关闭监视
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);//HTTPS访问设置 关闭监视访问地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);//设置访问头部信息
$output = curl_exec($ch);//获取结果
curl_close($ch);//关闭连接
$output = json_decode($output, true);//json数据转换
return $output;
}
private function Post($curlPost, $url, $ssl = false)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
if (!$ssl) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
}
$return_str = curl_exec($curl);
curl_close($curl);
return $return_str;
}
}

519
app/controller/mytrate.php Normal file
View File

@@ -0,0 +1,519 @@
<?php
/**
* Created by PhpStorm.
* User: Shan
* Date: 2017/4/1
* Time: 17:37
*/
trait MyTrate{
static $url = '';
static $OperatorID = ''; //运营商标识
static $OperatorSecret= '';//运营商密钥
static $AesSecret = ''; //消息密钥
static $AesIv = ''; //消息密钥初始化向量
static $SigSecret =''; //签名密钥
static $Owner =''; //桩属主
static $TimeStamp =''; //桩属主
static $Seq =''; //桩属主'TimeStamp', 'Seq'
static function getTokenDate()
{
$datetime= date('YmdHis');
$kk['OperatorID']= self::$OperatorID;
$kk['OperatorSecret'] = self::$OperatorSecret;
$en = self::encryptString(json_encode($kk));
$sig= self::$OperatorID . $en . $datetime . "0002";
$s= self::hmac_md5($sig);
$rr['OperatorID'] = self::$OperatorID;
$rr['Data']= $en;
$rr['TimeStamp']= $datetime;
$rr['Seq']= '0002';
$rr['Sig'] = $s;
$data= $rr;
return $data;
}
static function getStationDate($PageNo=1)
{
//LastQueryTime 字符串 格式“yyyy-MM-dd HH:mm:ss”可以为空如果不填写则查询所有的充电站信息
//PageNo 整型 不填写默认为1
//PageSize 整型 不填写默认为10
$datetime= date('YmdHis');
$kk['LastQueryTime']= '';
$kk['PageNo'] =$PageNo;
$kk['PageSize'] = 10;
$en = self::encryptString(json_encode($kk));
$sig= self::$OperatorID . $en . $datetime . "0002";
$s= self::hmac_md5($sig);
$rr['OperatorID'] = self::$OperatorID;
$rr['Data']= $en;
$rr['TimeStamp']= $datetime;
$rr['Seq']= '0002';
$rr['Sig'] = $s;
$data= $rr;
return $data;
}
static function getToken($hour)
{
$redis=new \Redis();
$redis->connect('127.0.0.1',6379);
$value=$redis->get(self::$Owner.'Token');
if($value==false){
$data = self::getTokenDate();
$url = self::$url . 'query_token';
$da = self::CurlSend($url, $data);
$decode = self::decryptString($da['Data']);
$decode = json_decode($decode, true);
$token = $decode['AccessToken'];
$redis->set(self::$Owner.'Token',$token,3500*$hour);
}else{
$token=$redis->get(self::$Owner.'Token');
}
return $token;
}
static function CurlSend($url, $data = '', $token = '')
{
$data = json_encode($data);
$ch = curl_init();
$headers = array();
if ($token) {
$headers[] = 'Authorization: Bearer ' . $token;
}
$headers[] = 'Content-Type: application/json;charset=utf-8';
$headers[] = 'Content-Length: ' . strlen($data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$curl_return = curl_exec($ch);
curl_close($ch);
return json_decode(trim($curl_return), true);
}
static function checkParams($params){
$arr = ['OperatorID', 'Data', 'TimeStamp', 'Seq','Sig'];
// 参数检查
foreach ($arr as $v) {
if (empty($params[$v])) {
return $v;
}
}
self::$TimeStamp=$params['TimeStamp'];
self::$Seq=$params['Seq'];
return 2;
}
/**
* @param $OperatorID
* @param $params
* @return int|string
*/
static function checkSig($OperatorID,$params){
$sig=$OperatorID.$params['Data'].$params['TimeStamp'].$params['Seq'];
$ecry_sig=self::hmac_md5($sig);
if($params['Sig']!=$ecry_sig){
return 1;
}
return 2;
}
static function fillParams($OperatorID){
$datas=self::getParams($OperatorID);
if(empty($datas)){
return 1;
}
self::$OperatorID = $OperatorID;
self::$OperatorSecret= $datas['OperatorSecret'];
self::$AesSecret = $datas['AesSecret'];
self::$AesIv = $datas['AesIv'];
self::$SigSecret =$datas['SigSecret'];
self::$Owner =$datas['Owner'];
}
/**
* @param $data
* @param $ret
* @param string $msg
* @return string
*/
static function encodeData($data,$ret,$msg=''){
$data=json_encode($data);
$data=self::encryptString($data);
$seq=empty(self::$Seq)? '0001' : self::$Seq;
$datetime=empty(self::$TimeStamp)? date('YmdHis') :self::$TimeStamp;
$sig= self::$OperatorID . $data . $datetime . $seq;
$s= self::hmac_md5($sig);
return ['Msg'=>$msg,'Ret'=>$ret,'Data'=>$data,'Sig'=>$s];
}
static function getStr(){
return Yii::$app->security->generateRandomString();
}
static function checkToken($token){
$redis=Common::createRedis();
$key='token-'.self::$Owner.'-';
$redisToken=$redis->get($key);
if($redisToken&&($redisToken==$token)){
return 2;
}
return 1;
}
static function getParams($OperatorID){
$datas=[];// $datas里面是企业信息数组
$arr=[];
foreach ($datas as $k=> $v){
if($v['OperatorID']==$OperatorID){
$arr=$datas[$k];
}
}
return $arr;
}
static function getFile ($filename)
{
$ret = @file_get_contents($filename);
return json_decode($ret, true);
}
/**
* @param $log
* @param $filename
*/
static function setFile ($log, $filename,$append=False){
if (!is_dir(dirname($filename))) {
mkdir(dirname($filename), 0777, true);
@chmod(dirname($filename), 0777);
}
@chmod($filename, 0777);
if($append==true){
file_put_contents($filename, json_encode($log)."\r\n",FILE_APPEND);
}else{
file_put_contents($filename, json_encode($log));
}
}
static function hmac_md5($s)
{
$ctx = hash_init('md5', HASH_HMAC,self::$SigSecret);
hash_update($ctx, $s);
$rs = hash_final($ctx);
$rs = strtoupper($rs);
return $rs;
}
static function encryptString($input)
{
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$input = self::pkcs5_pad($input, $size);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, self::$AesSecret, self::$AesIv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
return $data;
}
static function pkcs5_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
static function decryptString($sStr)
{
mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
//$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$iv = self::$AesIv;
$decrypted = @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, self::$AesSecret, base64_decode($sStr), MCRYPT_MODE_CBC, $iv);
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s - 1]);
$decrypted = substr($decrypted, 0, -$padding);
return $decrypted;
}
static function getCityCode(){
$file = file(Yii::getAlias('@app').'/commands/areaCode.txt');
$files = array();
foreach($file as $v){
$f = explode(' ',$v);
//这里用trim()函数去除头尾的空格不起效果,因为是全角格式。所以用功能更强大的正则来去除空格
$f[1] = mb_ereg_replace('^( | )+', '', $f[1]);
array_push($files,$f);
}
return $files;
}
static function getCityName($AreaCode,$cityCode){
$city='';
$pattern='/^(500)/';
if(preg_match($pattern,$AreaCode))
$city='重庆市';
$pattern='/^(310)/';
if(preg_match($pattern,$AreaCode))
$city='上海市';
$pattern='/^(120)/';
if(preg_match($pattern,$AreaCode))
$city='天津市';
$pattern='/^(110)/';
if(preg_match($pattern,$AreaCode))
$city='北京市';
$pattern='/^(4690)/';
if(preg_match($pattern,$AreaCode)){
$code=$AreaCode;
}else{
$code=substr($AreaCode,0,4).'00';
}
if(empty($city)){
foreach ($cityCode as $v1){
if($v1[0]==$code){
$city=$v1[1];
}
}
}
return $city;
}
//php5.5不支持array_column()
static function formArr($piles){
$arr=[];
foreach ($piles as $v){
$arr[]=$v['pile_id'];
}
return $arr;
}
static function insertPile($stations,$pile)
{
$time=time();
$arr=[];
foreach ($stations['StationInfos'] as $v){
foreach ($v['EquipmentInfos'] as $v1){
if($pile&&in_array($v1['EquipmentID'],$pile))
continue;
$station_status=($v['StationStatus']==50)? 1 : 0;
if($v1['EquipmentID'])
$arr[]=[$v1['EquipmentID'],self::$Owner,$v['StationID'],$v1['EquipmentType'],$time,$station_status];
}
}
if($arr)
@Yii::$app->db->createCommand()->batchInsert('pile', ['pile_id', 'owner','zhan_id','eleType','time','station_status'],
$arr)->execute();
}
static function insertPic($arr=[],$id,$owner){
$imgDir=[];
foreach ($arr as $v){
if($v){
$dirInfo=self::getImage($v,$owner);
if($dirInfo['save_path']!=2){
$imgDir[]=[
'url'=>$dirInfo['save_path'],
'zhan_id'=>$id,
'timer'=>date('Y-m-d H:i:s'),
'user'=>'',
'ischeck'=>0
];
}
}
}
if($imgDir){
Yii::$app->db->createCommand()->batchInsert(Zhanpic::tableName(), ['url','zhan_id','timer','user','ischeck'], $imgDir)->execute();
}
}
static function getImage($url,$owner){
$filename=substr($url,(strripos($url,'/')+1));
if($filename=='default.png')
return ['save_path'=>2];
ob_start();
@readfile($url);
$img=ob_get_contents();
ob_end_clean();
if($img){
$sub_dir=$owner.'/'.date('Y-m-d').'/';
$dir=Yii::getAlias('@app').'/../uploadfile/'.$sub_dir;
if(!file_exists($dir)){
mkdir($dir,0777,true);
}
$fp2=@fopen($dir.$filename,'a');
fwrite($fp2,$img);
fclose($fp2);
unset($img,$url);
return ['save_path'=>$sub_dir.$filename];
}else{
return ['save_path'=>2];
}
}
static function insertInfo($hour){
$token=self::getToken($hour);
if(!$token)
die('token 不能为空');
$data = self::getStationDate();
$url = self::$url.'query_stations_info';
$da = self::CurlSend($url, $data, $token);
$stations=self::decryptString($da['Data']);
$stations=json_decode($stations,true);
// echo '<pre/>';
// print_r($stations);
// die();
if($stations){
$sql = "SELECT pile_id FROM pile where owner=:owner ";
$piles = Yii::$app->db->createCommand($sql, [':owner' => self::$Owner])->queryAll();
if($piles)
$piles=self::formArr($piles);
self::insertPile($stations,$piles);
$zhanList=Zhanlist::find()->select(['zhan_id'])->where(['supplier'=>self::$Owner])->asArray()->all();
if(!empty($zhanList)){
$aa=[];
foreach ($zhanList as $k=>$v){
$aa[]=$v['zhan_id'];
}
$zhanList=$aa;
}
$cityCode=static::getCityCode();
self::insertStation($stations,$cityCode,$zhanList);
$page=$stations['PageCount'];
//所有页信息
for($i=2;$i<=$page;$i++){
$data2=self::getStationDate($i);
$da2 = self::CurlSend($url, $data2, $token);
$da2=self::decryptString($da2['Data']);
$da2=json_decode($da2,true);
if($da2)
self::insertStation($da2,$cityCode,$zhanList);
self::insertPile($da2,$piles);
}
}
}
static function padZero($str){
$len=strlen(substr($str,strpos($str,'.')+1));
$len=16-$len;
for($i=0;$i<$len;$i++){
$str.=0;
}
return $str;
}
static function pushCheck($fileName='change_status.txt'){
$authorization=Yii::$app->request->headers->get('Authorization');
$params=file_get_contents('php://input');
$params=json_decode($params,true);
// if(!empty($fileName))
// self::writeLog($fileName,$params);
$auths=explode(' ',trim($authorization));
$auth=$auths[count($auths)-1];
$checkParams=self::checkParams($params);
if($checkParams!=2)
return ['Msg'=>$checkParams.'为空','Ret'=>4003,'Data'=>['Status'=>1]];
$re=self::fillParams($params['OperatorID']);
if($re==1)
return ['Msg'=>'OperatorID不存在','Ret'=>4003,'Data'=>['Status'=>1]];
if($auth){
if(self::checkToken($auth)==1)
return self::encodeData(['Status'=>1],4002,'Token过期或者无效');
$checkSig=self::checkSig($params['OperatorID'],$params);
if($checkSig==1)
return self::encodeData(['Status'=>1],4001,'签名错误');
$data=self::decryptString($params['Data']);
$data=json_decode($data,true);
// if(!empty($fileName))
// self::writeLog($fileName,$data);
return ['code'=>200,'data'=>$data];
}
return self::encodeData(['Status'=>1],4002,'Bearer 未添加');
}
static function writeLog($name,$arr){
if(is_array($arr)){
if (@$_SERVER["HTTP_X_FORWARDED_FOR"])
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if (@$_SERVER["HTTP_CLIENT_IP"])
$ip = $_SERVER["HTTP_CLIENT_IP"];
else if (@$_SERVER["REMOTE_ADDR"])
$ip = $_SERVER["REMOTE_ADDR"];
else if (@getenv("HTTP_X_FORWARDED_FOR"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (@getenv("HTTP_CLIENT_IP"))
$ip = getenv("HTTP_CLIENT_IP");
else if (@getenv("REMOTE_ADDR"))
$ip = getenv("REMOTE_ADDR");
else
$ip = $_SERVER['REMOTE_ADDR'];
$pushTime=['logTime'=>date('Y-m-d H:i:s',time()),'ip'=>$ip];
$arr=array_merge($pushTime,$arr);
$sub_dir=date('Y-m-d');
$dir=Yii::getAlias('@app').'/../../../'.$sub_dir.'/'.$name;
self::setFile($arr,$dir,true);
}
}
public static function initeStatus(){
$redis=Common::createRedis();
$datas=Zhanlist::find()->select(['zhan_id'])->where(['supplier'=>self::$Owner])->asArray()->all();
$token=self::getToken(2);
self::$url=self::$url.'query_station_status';
$data=[];
foreach ($datas as $k=>$v){
$data[]=$v['zhan_id'];
$i=$k+1;
if($i%25==0){
$dd=self::statusDate($data);
$da = self::CurlSend(self::$url, $dd,$token);
$decode = self::decryptString($da['Data']);
$decode = json_decode($decode, true);
if($decode){
foreach ($decode['StationStatusInfos'] as $v1){
foreach ($v1['ConnectorStatusInfos'] as $v2){
$key=self::$Owner.'--'.$v2['ConnectorID'];
$value=$v2['Status'];
$redis->set($key,$value);
}
}
}
$data=[];
}
}
if($data){
$dd=self::statusDate($data);
$da = self::CurlSend(self::$url, $dd,$token);
$decode = self::decryptString($da['Data']);
$decode = json_decode($decode, true);
if($decode){
if($decode['StationStatusInfos']){
foreach ($decode['StationStatusInfos'] as $v1){
if(empty($decode['ConnectorStatusInfos']))
continue;
foreach ($v1['ConnectorStatusInfos'] as $v2){
$key=self::$Owner.$v2['ConnectorID'];
$value=$v2['Status'];
$redis->set($key,$value);
}
}
}
}
}
}
public static function statusDate($id){
$datetime= date('YmdHis');
$kk['StationIDs']=$id;
$en = self::encryptString(json_encode($kk));
$sig= self::$OperatorID . $en . $datetime . "0002";
$s= self::hmac_md5($sig);
$rr['OperatorID'] = self::$OperatorID;
$rr['Data']= $en;
$rr['TimeStamp']= $datetime;
$rr['Seq']= '0002';
$rr['Sig'] = $s;
return $rr;
}
}

67
app/controller/open.php Normal file
View File

@@ -0,0 +1,67 @@
<?php
class Open{
use mytrate;
public function actionQuery_token()
{
$params=file_get_contents('php://input');
$params=json_decode($params,true);
return $params;
self::writeLog('query_token.txt',$params);
$OperatorID=empty($params['OperatorID'])? '':$params['OperatorID'];
$checkParams=self::checkParams($params);
if($checkParams!=2){
return ['Msg'=>$checkParams.'为空','Ret'=>4003,'Data'=>['Status'=>1]];
}
$re=self::fillParams($params['OperatorID']);
if($re==1)
return ['Msg'=>'OperatorID不存在','Ret'=>4003,'Data'=>['Status'=>1]];
$checkSig=self::checkSig($OperatorID,$params);
if($checkSig==1)
return self::encodeData(['OperatorID'=>$OperatorID,'SuccStat'=>1,'FailReason'=>4],4001,'签名错误');
$data=self::decryptString($params['Data']);
$datas=json_decode($data,true);
if(isset($datas['OperatorID'])&&isset($datas['OperatorSecret'])){
if(($datas['OperatorID']==$OperatorID)&&($datas['OperatorSecret']==self::$OperatorSecret)){
$AccessToken=self::getStr();
$redis=Common::createRedis();
$key='token-'.self::$Owner.'-';
$redis->set($key,$AccessToken,86400);
$strr=['OperatorID'=>$OperatorID,'SuccStat'=>0,'AccessToken'=>$AccessToken,
'TokenAvailableTime'=>86400,'FailReason'=>0];
self::writeLog('query_token.txt',$strr);
return self::encodeData($strr,0);
}
$re=['OperatorID'=>$OperatorID,'SuccStat'=>1,'FailReason'=>5];
return self::encodeData($re,4003,'OperatorID,Data错误');
}
$re=['OperatorID'=>$OperatorID,'SuccStat'=>1,'FailReason'=>6];
return self::encodeData($re,4003,'OperatorID,Data缺失');
}
public function actionNotification_stationstatus(){
$receive=self::pushCheck();
if(isset($receive['code'])&&$receive['code']==200){
$da=$receive['data']['ConnectorStatusInfo'];
if(isset($da['ConnectorID'])&&isset($da['Status'])){
$redis=Common::createRedis();
$key=self::$Owner.'--'.$da['ConnectorID'];
$status=$da['Status'];
$redis->set($key,$status);
$result=1;
// self::writeLog('change_status.txt',$da);
if($result){
return self::encodeData(['Status'=>0],0);
}else{
return self::encodeData(['Status'=>1],0);
}
}else{
return self::encodeData(['Status'=>1],4004,'Aes加密错误');
}
}else{
return $receive;
}
}
}

74
app/controller/utils.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
namespace app\controller;
use app\model\ServiceFee;
use think\facade\Db;
class utils
{
public function ResponseJson($data, $code, $msg): \think\response\Json
{
return json(['Code' => $code, 'Msg' => $msg, 'Data' => $data]);
}
public function getDateFromRange($startdate, $enddate): array
{
$stimestamp = strtotime($startdate);
$etimestamp = strtotime($enddate);
// 计算日期段内有多少天
$days = ($etimestamp - $stimestamp) / 86400;
// 保存每天日期
$date = array();
for ($i = 0; $i < $days + 1; $i++) {
$date[] = date('Y-m-d', $stimestamp + (86400 * $i));
}
return $date;
}
public function Fee($station_number, $openid): array
{
$table = 'zxc_user';
$ElectricityFee = Db::table('charge_station')->where('charge_station_number', $station_number)->value('ElectricityFee');
$station_type = Db::table('charge_station')->where('charge_station_number', $station_number)->value('station_type');
$type = Db::table($table)->where('openid', $openid)->value('type');
if ($type == 3) {
$group_id = Db::table($table)->where('openid', $openid)->value('group_id');
$ServiceFee = ServiceFee::where('type', $type)->where('group_id', $group_id)->where('station_type', $station_type)->value('service_fee');
} else {
$ServiceFee = ServiceFee::where('type', $type)->where('station_type', $station_type)->value('service_fee');
}
// $ServiceFee= Db::table('charge_station')->where('charge_station_number',$station_number)->value('ServiceFee');
$ElectricityFee = str_replace('电费:', '', $ElectricityFee);
$Elect = explode(',', $ElectricityFee);
for ($index = 0; $index < count($Elect); $index++) {
$kk['time_interval'] = substr($Elect[$index], 0, 11);
$kk['univalence'] = explode(':', $Elect[$index])[3];
$ss[] = $kk;
}
$ServiceFee = str_replace('服务费:', '', $ServiceFee);
$Server = explode(',', $ServiceFee);
$wk_day = date('w');
$now_time = time();
$start_time = '2023-03-18 00:00:00';
$start_time = strtotime($start_time);
$wkday_ar = array('日', '一', '二', '三', '四', '五', '六');
for ($index = 0; $index < count($Server); $index++) {
$ll['time_interval'] = substr($Server[$index], 0, -5);
// if ($wkday_ar[$wk_day] == '三' && $now_time > $start_time && $type == 1) {
// $ll['univalence'] = number_format((float)(substr($Server[$index], Strlen($Server[$index]) - 4) - 0.20), 2);
// } else {
$ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
// }
$mm[] = $ll;
}
return ['code' => 200, 'ElectricityFee' => $ss, 'ServiceFee' => $mm];
}
}

17
app/event.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [
],
];

12
app/middleware.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
\think\middleware\SessionInit::class,
// 日志中间件
\app\middleware\RequestLog::class,
];

View File

@@ -0,0 +1,53 @@
<?php
// app/middleware/RequestLog.php
namespace app\middleware;
use app\model\SystemRequestLog;
use think\facade\Request;
class RequestLog
{
public function handle($request, \Closure $next)
{
$startTime = microtime(true);
$response = $next($request);
// 排除特定路由
if (in_array($request->pathinfo(), ['/favicon.ico'])) {
return $response;
}
try {
$log = [
'method' => $request->method(),
'url' => $request->url(),
'params' => $this->filterParams($request->param()),
'ip' => $request->ip(),
'user_agent' => $request->header() ? $request->header('user-agent') : '无',
'user_id' => $request->userId ?? 0, // 需要根据你的认证系统调整
'response_code' => $response->getCode(),
'response_time' => round(microtime(true) - $startTime, 3),
];
SystemRequestLog::create($log);
} catch (\Exception $e) {
// 记录失败不影响主流程
\think\facade\Log::error('请求日志记录失败:'.$e->getMessage());
}
return $response;
}
protected function filterParams($params)
{
// 过滤敏感字段
$sensitiveFields = ['password', 'pwd', 'token', 'access_token'];
foreach ($sensitiveFields as $field) {
if (isset($params[$field])) {
$params[$field] = '******';
}
}
return $params;
}
}

View File

@@ -0,0 +1,65 @@
<?php
declare (strict_types = 1);
namespace app\middleware;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class WxAppCheck
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
*
*/
public function handle($request, \Closure $next)
{
$token=request()->header('token');
//验证token
$res=checkToken_s($token);
//对返回结果进行判断
if (!is_numeric($res)){
return json(['code'=>1,'message'=>$res]);
}
//保存用户ID
$request->uid=$res;
return $next($request);
}
}
function checkToken_s($token)
{
$key = 'zbcazbc';
$key = new Key($key, 'HS256');
$status = array("code" => 2);
// echo $token;
try {
JWT::$leeway = 60;//当前时间减去60把时间留点余地
$decoded = JWT::decode($token, $key, array('HS256')); //HS256方式这里要和签发的时候对应
$arr = (array)$decoded;
// print_r($arr);
$res['code'] = 1;
$res['data'] = $arr['data'];
return $res['data']->uid;
} catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return $status['msg'];
} catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token失效";
return $status['msg'];
} catch (\Firebase\JWT\ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return $status['msg'];
} catch (\Exception $e) { //其他错误
$status['msg'] = "未知错误";
return $status['msg'];
}
}

11
app/model/Access.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
namespace app\model;
use think\model\concern\SoftDelete;
use think\model\Pivot;
class Access extends Pivot
{
}

45
app/model/Admin.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
namespace app\model;
use app\model\Admin as AdminModel;
use think\Model;
use think\model\concern\SoftDelete;
class Admin extends Model
{
//添加后缀需要设置模型名称
protected $name = 'admin';
//设置主键
protected $pk = 'id';
use SoftDelete;
protected $deleteTime = 'delete_time';
// public function role(){
// return $this->belongsToMany(Role::class,Access::class,'role_id','admin_id');
// }
public function searchUsernameAttr($query, $value)
{
return $value ? $query->where('username', 'like', '%'.$value.'%') : '';
}
public function searchNicknameAttr($query, $value)
{
return $value ? $query->where('Nickname', 'like', '%'.$value.'%') : '';
}
public function searchEmailAttr($query, $value)
{
return $value ? $query->where('email', 'like', '%'.$value.'%') : '';
}
public function searchPhoneAttr($query, $value)
{
return $value ? $query->where('phone', 'like', '%'.$value.'%') : '';
}
}

41
app/model/ChargeOrder.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class ChargeOrder extends Model
{
use SoftDelete;
protected $deleteTime = 'delete_time';
public function searchOrderNumberAttr($query, $value)
{
return $value ? $query->where('order_number', 'like', '%'.$value.'%') : '';
}
public function searchChargeStationIdAttr($query, $value)
{
return $value ? $query->where('charge_station_id', '=', $value) : '';
}
public function searchOpenidAttr($query, $value)
{
return $value ? $query->where('openid', 'like', '%'.$value.'%') : '';
}
public function searchChargeDateAttr($query, $value)
{
return $value ? $query->whereTime('charge_date', '>=', $value) : '';
}
public function searchStatusAttr($query, $value)
{
return $value ? $query->where('status', '=', "'".$value."'") : '';
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
/**
* @mixin \think\Model
*/
class ChargeStation extends Model
{
public function searchChargeStationNameAttr($query, $value)
{
return $value ? $query->where('charge_station_name', 'like', '%'.$value.'%') : '';
}
public function searchStationTypeAttr($query, $value)
{
return $value ? $query->where('station_type', '=', $value) : '';
}
public function searchCityAttr($query, $value)
{
return $value ? $query->where('city', 'like', '%'.$value.'%') : '';
}
public function searchAreaAttr($query, $value)
{
return $value ? $query->where('area', 'like', '%'.$value.'%') : '';
}
public function searchStreetAttr($query, $value)
{
return $value ? $query->where('street', 'like', '%'.$value.'%') : '';
}
public function searchAddressAttr($query, $value)
{
return $value ? $query->where('address', 'like', '%'.$value.'%') : '';
}
public function searchPriceAttr($query, $value)
{
return $value ? $query->where('price', 'between', [intval($value),intval($value)+1]) : '';
}
}

12
app/model/Enterprise.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class Enterprise extends Model
{
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
}

View File

@@ -0,0 +1,12 @@
<?php
namespace app\model;
use think\Model;
class EnterpriseCar extends Model
{
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
}

View File

@@ -0,0 +1,10 @@
<?php
namespace app\model;
use think\Model;
class EnterpriseGroup extends Model
{
protected $createTime = 'create_time';
}

View File

@@ -0,0 +1,10 @@
<?php
namespace app\model;
use think\Model;
class EnterpriseUser extends Model
{
protected $createTime = 'create_time';
}

14
app/model/Event.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class Event extends Model
{
protected $createTime = 'create_time';
protected $updateTime = 'last_update_time';
use SoftDelete;
protected $deleteTime = 'delete_time';
}

10
app/model/Role.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace app\model;
use think\Model;
class Role extends Model
{
}

10
app/model/ServiceFee.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace app\model;
use think\Model;
class ServiceFee extends Model
{
}

View File

@@ -0,0 +1,17 @@
<?php
namespace app\model;
use think\Model;
class SystemRequestLog extends Model
{
protected $table = 'system_request_logs';
protected $autoWriteTimestamp = 'datetime';
protected $createTime = 'create_time';
protected $updateTime = false;
protected $type = [
'params' => 'json',
];
}

27
app/model/User.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
declare (strict_types=1);
namespace app\model;
use think\facade\Db;
use think\Model;
/**
* @mixin \think\Model
*/
class User extends Model
{
//用户金额记录日志
public static function addMoneyLog($openid, $money, $type, $mark)
{
Db::table('zxc_user_money_log')->insert([
'openid' => $openid,
'money' => $money,
'type' => $type,
'mark' => $mark,
'createtime' => date('Y-m-d H:i:s', time()),
]);
}
}

10
app/model/Vinlicense.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace app\model;
use think\Model;
class Vinlicense extends Model
{
}

9
app/provider.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];

9
app/service.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
];

49
app/validate/Admin.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
declare (strict_types = 1);
namespace app\validate;
use think\Validate;
class Admin extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'username.require' => '用户名不得为空~',
'username.min' => '用户名不得小于 2 位~',
'username.max' => '用户名不得大于 10 位~',
'username.chsDash' => '用户名只能是汉字、字母、数字或下划线以及破折号~',
'nickname.require' => '昵称不得为空~',
'nickname.min' => '昵称不得小于 2 位~',
'nickname.max' => '昵称不得大于 10 位~',
'nickname.chsDash' => '昵称只能是汉字、字母、数字或下划线以及破折号~',
'username.unique' => '用户名已存在~',
'password.require' => '密码不得为空~',
'password.min' => '密码不得小于 6 位~',
'passwordnot.require' => '密码确认不得为空~',
'passwordnot.confirm' => '密码确认和密码不一致~',
'email.require' => '电子邮件不得为空~',
'email.email' => '电子邮件格式不正确~',
'email.unique' => '电子邮件已存在~',
'phone.require' => '电话不得为空~',
'phone.number' => '必须全部为数字~',
'phone.length' => '手机号长度必须为11位',
'phone.unique' => '手机号已存在~'
];
}

57
composer.json Normal file
View File

@@ -0,0 +1,57 @@
{
"name": "topthink/think",
"description": "the new thinkphp framework",
"type": "project",
"keywords": [
"framework",
"thinkphp",
"ORM"
],
"homepage": "https://www.thinkphp.cn/",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
},
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"require": {
"php": ">=7.2.5",
"topthink/framework": "^6.1.0",
"topthink/think-orm": "^2.0",
"topthink/think-filesystem": "^1.0",
"overtrue/pinyin": "^4.0",
"wechatpay/wechatpay": "^1.4",
"firebase/php-jwt": "^6.3",
"topthink/think-worker": "^3.0",
"curl/curl": "^2.4",
"ext-json": "*",
"easy-task/easy-task": "^2.4",
"ext-redis": "*"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
"topthink/think-trace": "^1.0"
},
"autoload": {
"psr-4": {
"app\\": "app"
},
"psr-0": {
"": "extend/"
}
},
"config": {
"preferred-install": "dist"
},
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
]
}
}

2377
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

32
config/app.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
// 应用地址
'app_host' => env('app.host', ''),
// 应用的命名空间
'app_namespace' => '',
// 是否启用路由
'with_route' => true,
// 默认应用
'default_app' => 'index',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 应用映射(自动多应用模式有效)
'app_map' => [],
// 域名绑定(自动多应用模式有效)
'domain_bind' => [],
// 禁止URL访问的应用列表自动多应用模式有效
'deny_app_list' => [],
// 异常页面的模板文件
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => true,
];

41
config/cache.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
// 默认缓存驱动
'default' => env('cache.driver', 'file'),
// 缓存连接方式配置
'stores' => [
'file' => [
// 驱动方式
'type' => 'File',
// 缓存保存目录
'path' => '',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
// 缓存标签前缀
'tag_prefix' => 'tag:',
// 序列化机制 例如 ['serialize', 'unserialize']
'serialize' => [],
],
// 更多的缓存连接
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => '6379',
'password' => '',
'select' => '0',
// 全局缓存有效期0为永久有效
'expire' => 0,
// 缓存前缀
'prefix' => '',
'timeout' => 0,
],
],
];

5
config/command.php Normal file
View File

@@ -0,0 +1,5 @@
<?php
return [
'reservation:task' => 'app\command\ReservationTask',
];

11
config/console.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
// 指令定义
'commands' => [
'reservation:task' => 'app\command\ReservationTask',
'test:task' => 'app\command\TestTask',
],
];

20
config/cookie.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
return [
// cookie 保存时间
'expire' => 0,
// cookie 保存路径
'path' => '/',
// cookie 有效域名
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => false,
// 是否使用 setcookie
'setcookie' => true,
// samesite 设置,支持 'strict' 'lax'
'samesite' => '',
];

63
config/database.php Normal file
View File

@@ -0,0 +1,63 @@
<?php
return [
// 默认使用的数据库连接配置
'default' => env('database.driver', 'mysql'),
// 自定义时间查询规则
'time_query_rule' => [],
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => true,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 时间字段配置 配置格式create_time,update_time
'datetime_field' => '',
// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 数据库名
'database' => env('database.database', 'charge'),
// 用户名
'username' => env('database.username', 'root'),
// 密码
'password' => env('database.password', ''),
// 端口
'hostport' => env('database.hostport', '3306'),
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => env('database.charset', 'utf8'),
// 数据库表前缀
'prefix' => env('database.prefix', ''),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => env('app_debug', true),
// 开启字段缓存
'fields_cache' => false,
],
// 更多的数据库配置信息
],
];

24
config/filesystem.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
return [
// 默认磁盘
'default' => env('filesystem.driver', 'local'),
// 磁盘列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
// 磁盘类型
'type' => 'local',
// 磁盘路径
'root' => app()->getRootPath() . 'public/static',
// 磁盘路径对应的外部URL路径
'url' => '/static',
// 可见性
'visibility' => 'public',
],
// 更多的磁盘配置信息
],
];

45
config/gateway_worker.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:gateway 指令有效
// +----------------------------------------------------------------------
return [
// 扩展自身需要的配置
'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text
'host' => '0.0.0.0', // 监听地址
'port' => 2348, // 监听端口
'socket' => '', // 完整监听地址
'context' => [], // socket 上下文选项
'register_deploy' => true, // 是否需要部署register
'businessWorker_deploy' => true, // 是否需要部署businessWorker
'gateway_deploy' => true, // 是否需要部署gateway
// Register配置
'registerAddress' => '127.0.0.1:1236',
// Gateway配置
'name' => 'thinkphp',
'count' => 1,
'lanIp' => '127.0.0.1',
'startPort' => 2000,
'daemonize' => false,
'pingInterval' => 30,
'pingNotResponseLimit' => 0,
'pingData' => '{"type":"ping"}',
// BusinsessWorker配置
'businessWorker' => [
'name' => 'BusinessWorker',
'count' => 1,
'eventHandler' => '\think\worker\Events',
],
];

19
config/hard.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
/**
* 特来电互联互通对接协议
* 特来电组织机构代码395815801
* 接口地址https://hlht.teld.cn/evcs/v20191230/
* 参数定义
*/
return [
"OperatorID" => "MACFHBM3X",//运营商标识
"OperatorSecret" => "kZ91W50hNZdjuKR2",//运营商秘钥 e30efd732c2eda2a
"DataSecret" => "DNY4L10eWqrw1Ei9",//消息密钥 48535870e30efd732c2eda2aafad899b
"DataSecretIV" => "jdJptx39XUdOhN1f",//消息密钥初始化向量 08c4202c5961b521
"SigSecret" => "p1d8h63I9Z3lxDnY",//签名密钥 4a62990208c4202c5961b521314782b4
//seq
"Seq" => '0001',
'url' => 'https://hlht.teld.cn/evcs/v20191230/',
];

27
config/lang.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
// +----------------------------------------------------------------------
// | 多语言设置
// +----------------------------------------------------------------------
return [
// 默认语言
'default_lang' => env('lang.default_lang', 'zh-cn'),
// 允许的语言列表
'allow_lang_list' => [],
// 多语言自动侦测变量名
'detect_var' => 'lang',
// 是否使用Cookie记录
'use_cookie' => true,
// 多语言cookie变量
'cookie_var' => 'think_lang',
// 多语言header变量
'header_var' => 'think-lang',
// 扩展语言包
'extend_list' => [],
// Accept-Language转义为对应语言包名称
'accept_language' => [
'zh-hans-cn' => 'zh-cn',
],
// 是否支持语言分组
'allow_group' => false,
];

45
config/log.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
return [
// 默认日志记录通道
'default' => env('log.channel', 'file'),
// 日志记录级别
'level' => ['warning','error'],//'warning','error'
// 日志类型记录的通道 ['error'=>'email',...]
'type_channel' => [],
// 关闭全局日志写入
'close' => false,
// 全局日志处理 支持闭包
'processor' => null,
// 日志通道列表
'channels' => [
'file' => [
// 日志记录方式
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 1000,
// 使用JSON格式记录
'json' => false,
// 日志处理
'processor' => null,
// 关闭通道日志写入
'close' => false,
// 日志输出格式化
'format' => '[%s][%s] %s',
// 是否实时写入
'realtime_write' => false,
],
// 其它日志通道配置
],
];

8
config/middleware.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
// 中间件配置
return [
// 别名或分组
'alias' => [],
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
'priority' => [],
];

45
config/route.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 路由设置
// +----------------------------------------------------------------------
return [
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL伪静态后缀
'url_html_suffix' => 'html',
// URL普通方式参数 用于自动生成
'url_common_param' => true,
// 是否开启路由延迟解析
'url_lazy_route' => false,
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => false,
// 路由是否完全匹配
'route_complete_match' => false,
// 访问控制器层名称
'controller_layer' => 'controller',
// 空控制器名
'empty_controller' => 'Error',
// 是否使用控制器后缀
'controller_suffix' => false,
// 默认的路由变量规则
'default_route_pattern' => '[\w\.]+',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache_key' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
'request_cache_except' => [],
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
// 操作方法后缀
'action_suffix' => '',
// 默认JSONP格式返回的处理方法
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
];

19
config/session.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
// session name
'name' => 'PHPSESSID',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// 驱动方式 支持file cache
'type' => 'file',
// 存储连接标识 当type使用cache的时候有效
'store' => null,
// 过期时间
'expire' => 1440,
// 前缀
'prefix' => '',
];

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