慧麦商城

This commit is contained in:
mcbird2009@qq.com
2024-12-13 15:21:20 +08:00
commit 68005e6961
878 changed files with 207675 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
# Maven #
target/
# IDEA #
.idea/
*.iml
# Eclipse #
.settings/
.classpath
.project

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2018-2019] [macrozheng]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAgVvtzKTrCPUwQEuwHVC6dselz2mpUbmxg8Z+S4gz3Ff2aeOn
QsZxoPYPoYneiMeS7uRGhlJnXdeT4dbqgZzbcMj+erDN51iIR72suUnXpDbHI3CJ
V5It4mGoq883U5RQCVDmqTs8pT4SoNxx5/kSp6cJYbLnVwsmV/8crLSKFitAXlaq
F01pRAn3FKDFMbytoD8kYoyxbmfC/M2mrvndoWTzwR8/qplgx7gjSLF2PAABg6Ao
ILGHx25Hvw6tRD2BRE7yUN/q6I8xe3/0LuCgwZ8iE8FlMvxAKPG651UBOloksu8H
Kf71ctJj6/wcdOB3zDYFd5kxjw36TwDAAG2QIwIDAQABAoIBAH58ty9NawydQwr7
dz+S+mC+oyEGfiuNWUgyxLdyfNNNp4KuuZQPmnf7YhlgSBqSmtfAmj0pQi1+Z/mC
PldyWxgTUNIDI7K83LTZgJTE4XiOn3XFymW4Z+ld+KHWwpCVCxWw53o+k/Q3l9t2
8mITJ+yK5h+D4bU5D8snhpBREFzPh3kYMZ1nTrBPtUne+tGjxxhmetBgT7Iy43hO
d4eQpJ8PEDHUvFfux5HAkyp58fumnjq9/gotjtFKARwpFlQoiLA40QsPInLuSMsk
VLZ76yE7yuPBbHOZOVpHBLImibsg2vrVavT/auhrpoTthuqt3oJkUvidxQ1NHn2N
l5Gf5sECgYEA8fuJMP327heZbkHuWuZ17gKDJvgvg1Vvdco9xcX0p0F9qz9VBT4G
mbK/UqvdL9irfTVWfBkuO5mm8NbtS2JtdLozER6K6NcWM9XHTuvMBoUTP8Yu1LTs
1lyXUkyGFzdDdHse4sS+RKu2V9ykcv4D7byM1WEbu4sYa30IFMRsRxMCgYEAiNpA
PDPePipQDsPd6q3X+8U2pNZpvVwlQNcu8H16Os9k1FD4AkT2rwO+1FsJfCUONyKf
cmwnTrVMOT+DfqPnkUU5IAleKpN6p15Bn2TwRkqc2pAP5Bno6jAQXRQtApDhb6dr
o8hbMWXKwWjFi7m/psyfmki19Ttwf0kRAlufZLECgYEA0KFGD29nTrAaIO3HS6gX
VTXlTdv9WwZ2KuBLkhCyduIIL3VTIEnx9uIeAnEbKv1sHW+3ORecvNYlENC9lpku
Nc2z6bajnUyUX+yZAnpaVeS2S+3awpma+NarwNEpayrChdMBNhLa2OoTNH2Pa3WG
fZpq8i3fczrhuwr5xK31jPECgYBcLIvpQJIm0r77Quc8QnzfodQNMDEmDmM1Cfoe
lpT1+WwTKLnyZVq1RFOKmgqIaDjr39D+82OCOtAtGt9JM8IrcTFpp4WaLZ0GD5Ep
d4XyAh0lhLR/UQg0e8z5tDYgrU55sozoUnFBkyr+G8A6PRCdmuLAusp7ct5xjNf8
+5Me8QKBgQChqG0QQiqnTvKqp8LRng1eUl1n55Pt8WSFr9aZyj3aDgDttcjdBgXQ
5ildvumUidU2JWz5NMC/qoTx1Y9yoUW3snQbLWG3pvRPlRPPRRQwTCCPDMf0RDxI
6Nx/HFJFuW7jR4c8M/rpp8q7Lm693UPRwb/GICbMHKeHP6bMDbTAgw==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,59 @@
-----BEGIN CERTIFICATE-----
MIIFjjCCBHagAwIBAgIQBLkhPdDnB4A4iU84gBdNUjANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMTkwODA4MDAwMDAwWhcNMjAwODA3MTIwMDAwWjAd
MRswGQYDVQQDExJtYWxsLnl1c2Vucm9uZy5jb20wggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCBW+3MpOsI9TBAS7AdULp2x6XPaalRubGDxn5LiDPcV/Zp
46dCxnGg9g+hid6Ix5Lu5EaGUmdd15Ph1uqBnNtwyP56sM3nWIhHvay5SdekNscj
cIlXki3iYairzzdTlFAJUOapOzylPhKg3HHn+RKnpwlhsudXCyZX/xystIoWK0Be
VqoXTWlECfcUoMUxvK2gPyRijLFuZ8L8zaau+d2hZPPBHz+qmWDHuCNIsXY8AAGD
oCggsYfHbke/Dq1EPYFETvJQ3+rojzF7f/Qu4KDBnyITwWUy/EAo8brnVQE6WiSy
7wcp/vVy0mPr/Bx04HfMNgV3mTGPDfpPAMAAbZAjAgMBAAGjggJ3MIICczAfBgNV
HSMEGDAWgBRVdE+yck/1YLpQ0dfmUVyaAYca1zAdBgNVHQ4EFgQUYK0PxpTeIGsq
x3QEPkeBO1otpYIwHQYDVR0RBBYwFIISbWFsbC55dXNlbnJvbmcuY29tMA4GA1Ud
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTAYDVR0g
BEUwQzA3BglghkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGln
aWNlcnQuY29tL0NQUzAIBgZngQwBAgEwgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEF
BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEoGCCsGAQUFBzAChj5odHRw
Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRW5jcnlwdGlvbkV2ZXJ5d2hlcmVEVlRM
U0NBLUcxLmNydDAJBgNVHRMEAjAAMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHcA
7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFscYgmYAAABAMASDBG
AiEAs4Ug6AQihwmd35U43LCeg8Jrp683YQM5Z3QHuyl1VY8CIQDlqqLNBDQpA4t9
/KdjCEyaSlE/W17DUoYoEmFQHyQoGgB2AF6nc/nfVsDntTZIfdBJ4DJ6kZoMhKES
EoQYdZaBcUVYAAABbHGIJbgAAAQDAEcwRQIhAM74OJiDOG1f6ecIi3n2bcKx25mt
iuUcaynWKNe4xTFoAiBmFncbYFSlvkYJU1rCgbygMqYUeIbQN575ZBnbmH5NLzAN
BgkqhkiG9w0BAQsFAAOCAQEAAzPrPbwGFbBMyhNPtYimOXGqTj0qZ9i9EhQua4oX
JYC5lf0ll8Bhpl8BC8f3FCPEuEtwPp5U5VXSXSbPfHOQfpwRJnmT7LosX3GUzJkU
qoTR3+pu3f//vdfvuli03ayVjI7KaelLeGXZa4RB4dxf+s8m7nqI/Y/1aI77OuoU
pfD15tezAy6zM86Z9fCGXbLCA/acBAvugA8pxvv2HyAoh+yZqZdaseilloa5yzkT
jRBvuwnNm/TOfgw3JnxQtDHM2h0/LTwLx/BS9L7izol9f4hclUG08CAUzU/Lraau
OtY1Ge+qb6p8jQ594chLBXxDgd3/hRLLMHFCxjuo5tyOPw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
-----END CERTIFICATE-----

1959
document/mall.sql Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 KiB

View File

@@ -0,0 +1,2 @@
"AccessKeyId","AccessKeySecret"
"LTAIuQmZihe6hOk0","2XIDo6yvSDJM2iaEL2EyHBgVF8mMCQ"
1 AccessKeyId AccessKeySecret
2 LTAIuQmZihe6hOk0 2XIDo6yvSDJM2iaEL2EyHBgVF8mMCQ

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Binary file not shown.

3380
document/sql/mall_data.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
DELETE FROM `dms_seller_bank_account`;
INSERT INTO `dms_seller_bank_account` (`id`, `account_name`, `bank_name`, `bank_card_num`, `open_bank_address`) VALUES
(1, '507科技', '507科技', '507y8-507y8-507y8-507y8', '507科技总部大楼');
DELETE FROM `dms_distribution_dictionary`;
INSERT INTO `dms_distribution_dictionary` (`id`, `name`, `value`, `comment`, `show_status`, `update_time`) VALUES
(1, 'become_consumer', '1914', '成为消费商须购买商品的金额', '1', now()),
(2, 'become_partner', '30000', '成为经销商须购买商品的金额', '1', now()),
(3, 'become_one_diamond_one', '300000', '成为初级合作商须购买商品的金额', '1', now()),
(4, 'become_one_diamond_two', '3', '成为初级合作商须分享经销商的市场数量', '1', now()),
(5, 'become_two_diamond', '3', '成为中级合作商须培养出初级合作商的市场数量', '1', now()),
(6, 'become_three_diamond', '3', '成为高级合作商须培养出中级合作商的市场数量', '1', now()),
(7, 'become_four_diamond', '3', '成为特级合作商须培养出高级合作商的市场数量', '1', now()),
(8, 'consumer_direct_income', '15', '消费商获得分享劳务费的百分比', '1', now()),
(9, 'consumer_indirect_income', '5', '消费商获得服务劳务费的百分比', '1', now()),
(10, 'consumer_buy_again', '8', '成为消费商后再次购买的折扣', '1', now()),
(11, 'partner_direct_income', '20', '经销商获得分享劳务费的百分比', '1', now()),
(12, 'partner_indirect_income', '7', '经销商获得服务劳务费的百分比', '1', now()),
(13, 'partner_buy_again', '6', '成为经销商后再次购买的折扣', '1', now()),
(14, 'partner_store_subsidy', '3', '成为经销商并开店后获得店补的百分比', '1', now()),
(15, 'diamond_direct_income', '28', '合作商获得分享劳务费的百分比', '1', now()),
(16, 'diamond_indirect_income', '9', '合作商获得服务劳务费的百分比', '1', now()),
(17, 'diamond_buy_again', '5', '成为合作商后再次购买的折扣', '1', now()),
(18, 'diamond_store_subsidy', '3', '成为合作商并开店后获得店补的百分比', '1', now()),
(19, 'one_diamond_team_income', '10', '初级合作商获得团队服务劳务费的百分比', '1', now()),
(20, 'two_diamond_team_income', '14', '中级合作商获得团队服务劳务费的百分比', '1', now()),
(21, 'three_diamond_team_income', '16', '高级合作商获得团队服务劳务费的百分比', '1', now()),
(22, 'four_diamond_platform_income', '3', '特级合作商获得平台月度加权平均奖励的百分比', '1', now()),
(23, 'withdraw_poundage', '5', '提现手续费的百分比', '1', now()),
(24, 'withdraw_multiple', '100', '提现金额的整数倍数', '1', now());

View File

@@ -0,0 +1,209 @@
DROP TABLE IF EXISTS `dms_seller_bank_account`;
CREATE TABLE IF NOT EXISTS `dms_seller_bank_account` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`account_name` varchar(100) DEFAULT NULL COMMENT '账户名',
`bank_name` varchar(100) DEFAULT NULL COMMENT '银行名称',
`bank_card_num` varchar(50) DEFAULT NULL COMMENT '银行卡号',
`open_bank_address` varchar(100) DEFAULT NULL COMMENT '开户行地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='商家银行账户表';
DROP TABLE IF EXISTS `dms_offline_payment_record`;
CREATE TABLE IF NOT EXISTS `dms_offline_payment_record` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`seller_bank_account_id` int(10) DEFAULT NULL COMMENT '商家银行账户id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`order_id` bigint(20) DEFAULT NULL COMMENT '订单id',
`order_sn` varchar(64) DEFAULT NULL COMMENT '订单编号',
`pay_amount` decimal(10,2) DEFAULT NULL COMMENT '支付金额',
`payment_account_name` varchar(100) DEFAULT NULL COMMENT '支付账户名',
`payment_bank_name` varchar(100) DEFAULT NULL COMMENT '支付银行名称',
`payment_bank_card_num` varchar(50) DEFAULT NULL COMMENT '支付银行卡号',
`confirm_status` int(1) DEFAULT NULL COMMENT '确认状态0->未确认1->已确认',
`confirm_time` datetime DEFAULT NULL COMMENT '确认时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='线下支付记录表';
DROP TABLE IF EXISTS `dms_member_bank_account`;
CREATE TABLE IF NOT EXISTS `dms_member_bank_account` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`account_name` varchar(100) DEFAULT NULL COMMENT '账户名',
`bank_name` varchar(100) DEFAULT NULL COMMENT '银行名称',
`bank_card_num` varchar(50) DEFAULT NULL COMMENT '银行卡号',
`open_bank_address` varchar(100) DEFAULT NULL COMMENT '开户行地址',
`default_status` int(1) DEFAULT NULL COMMENT '是否默认0->否1->是',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='会员银行账户表';
DROP TABLE IF EXISTS `dms_member_withdraw_apply`;
CREATE TABLE IF NOT EXISTS `dms_member_withdraw_apply` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`poundage` decimal(10,2) DEFAULT NULL COMMENT '手续费',
`actual_value` decimal(10,2) DEFAULT NULL COMMENT '扣出手续费后的值',
`account_name` varchar(100) DEFAULT NULL COMMENT '账户名',
`bank_name` varchar(100) DEFAULT NULL COMMENT '银行名称',
`bank_card_num` varchar(50) DEFAULT NULL COMMENT '银行卡号',
`open_bank_address` varchar(100) DEFAULT NULL COMMENT '开户行地址',
`payment_status` int(1) DEFAULT NULL COMMENT '付款状态0->未打款1->已打款2->打款失败',
`failed_reason` varchar(255) DEFAULT NULL COMMENT '失败原因',
`payment_time` datetime DEFAULT NULL COMMENT '付款时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='会员提现申请表';
DROP TABLE IF EXISTS `dms_team_level`;
CREATE TABLE IF NOT EXISTS `dms_team_level` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`parent_id` bigint(20) DEFAULT NULL COMMENT '推荐人id',
`level_tree` varchar(1000) DEFAULT NULL COMMENT '层级树',
`level` int(10) DEFAULT NULL COMMENT '当前层级',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='团队层级关系表';
DROP TABLE IF EXISTS `dms_distribution_dictionary`;
CREATE TABLE `dms_distribution_dictionary` (
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`name` VARCHAR(50) NULL DEFAULT NULL COMMENT '名称',
`value` VARCHAR(50) NULL DEFAULT NULL COMMENT '参数值',
`comment` VARCHAR(50) NULL DEFAULT NULL COMMENT '备注',
`show_status` int(1) NULL DEFAULT '1' COMMENT '显示状态( 0: 不显示 1: 显示)',
`update_time` TIMESTAMP NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='分销字典表';
DROP TABLE IF EXISTS `dms_member_total_income`;
CREATE TABLE `dms_member_total_income` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`item_type` int(3) NULL DEFAULT NULL COMMENT '项目类型',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员总收入表';
DROP TABLE IF EXISTS `dms_team_total_income`;
CREATE TABLE `dms_team_total_income` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='团队总收入表';
DROP TABLE IF EXISTS `dms_team_total_consume`;
CREATE TABLE `dms_team_total_consume` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='团队累计消费表';
DROP TABLE IF EXISTS `dms_team_member_number`;
CREATE TABLE `dms_team_member_number` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`total` int(10) DEFAULT '0' COMMENT '团队成员总数',
`consumer` int(10) DEFAULT '0' COMMENT '消费者人数',
`partner` int(10) DEFAULT '0' COMMENT '经销商人数',
`one_diamond` int(10) DEFAULT '0' COMMENT '初级合作商人数',
`two_diamond` int(10) DEFAULT '0' COMMENT '中级合作商人数',
`three_diamond` int(10) DEFAULT '0' COMMENT '高级合作商人数',
`four_diamond` int(10) DEFAULT '0' COMMENT '特级合作商人数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='团队成员数量表';
DROP TABLE IF EXISTS `dms_member_trade_record`;
CREATE TABLE `dms_member_trade_record` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`item_type` int(3) NULL DEFAULT NULL COMMENT '项目类型',
`type` int(1) NULL DEFAULT NULL COMMENT '收支类型0->收入1->支出',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`title` VARCHAR(100) NULL DEFAULT NULL COMMENT '交易标题',
`note` VARCHAR(255) NULL DEFAULT NULL COMMENT '备注',
`customer_id` bigint(20) DEFAULT NULL COMMENT '消费者Id',
`order_id` bigint(20) DEFAULT NULL COMMENT '订单id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员账户交易记录表';
DROP TABLE IF EXISTS `dms_member_freeze_account_record`;
CREATE TABLE `dms_member_freeze_account_record` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`item_type` int(3) NULL DEFAULT NULL COMMENT '项目类型',
`type` int(1) NULL DEFAULT NULL COMMENT '收支类型0->收入1->支出',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`title` VARCHAR(100) NULL DEFAULT NULL COMMENT '交易标题',
`note` VARCHAR(255) NULL DEFAULT NULL COMMENT '备注',
`customer_id` bigint(20) DEFAULT NULL COMMENT '消费者Id',
`order_id` bigint(20) DEFAULT NULL COMMENT '订单id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员冻结账户记录表';
DROP TABLE IF EXISTS `dms_platform_income`;
CREATE TABLE `dms_platform_income` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`order_id` bigint(20) DEFAULT NULL COMMENT '订单id',
`customer_id` bigint(20) DEFAULT NULL COMMENT '消费者Id',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`note` VARCHAR(255) NULL DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='平台收入表';
DROP TABLE IF EXISTS `dms_member_transfer_record`;
CREATE TABLE `dms_member_transfer_record` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '转账会员id',
`member_nickname` VARCHAR(255) DEFAULT NULL COMMENT '转账会员昵称',
`receiver_id` bigint(20) DEFAULT NULL COMMENT '接收会员Id',
`receiver_nickname` VARCHAR(255) DEFAULT NULL COMMENT '接收会员昵称',
`receiver_phone` VARCHAR(64) DEFAULT NULL COMMENT '接收会员手机号',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`note` VARCHAR(255) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员转账记录表';
DROP TABLE IF EXISTS `dms_member_month_reward_record`;
CREATE TABLE `dms_member_month_reward_record` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`value` decimal(10,2) DEFAULT NULL COMMENT '',
`year` int(4) NULL DEFAULT NULL COMMENT '年份',
`month` int(2) NULL DEFAULT NULL COMMENT '月份',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员月度奖励发放记录表';
alter table `ums_member` add column `member_level` int(1) null COMMENT '分销会员等级0->普通用户1->vip会员2->店长3->代理4->市代5->中级合作商6->高级合作商7->特级合作商))' default '0' AFTER `member_level_id`;
alter table `ums_member` add column `store_status` int(1) null COMMENT '分销实体店状态0->未开店1->已开店)' default '0';
alter table `ums_member` add column `balance` decimal(10,2) null COMMENT '余额' default '0.00';
alter table `ums_member` add column `freeze` decimal(10,2) null COMMENT '冻结余额' default '0.00';
alter table `ums_member` add column `order_status` int(1) null COMMENT '排队状态:0->未排队1->排队中' default '0';
alter table `oms_order` add column settlement_status int(1) null COMMENT '分销结算状态0->未结算1->已结算2->不结算)' default '0';
alter table `oms_order` add column settlement_time datetime null COMMENT '分销结算时间';
alter table `dms_member_withdraw_apply` add column `withdraw_type` int(1) null COMMENT '提现方式(0: 支付宝; 1: 微信; 2: 银行卡)' default null AFTER `open_bank_address`;
alter table `dms_member_withdraw_apply` add column `real_name` varchar(100) null COMMENT '真实姓名' default null AFTER `open_bank_address`;
alter table `dms_member_withdraw_apply` add column `alipay_account` varchar(100) null COMMENT '支付宝账号' default null AFTER `real_name`;
alter table `dms_member_withdraw_apply` add column `wechat_account` varchar(100) null COMMENT '微信账号' default null AFTER `alipay_account`;
alter table `dms_member_withdraw_apply` add column `wechat_nickname` varchar(100) null COMMENT '微信昵称' default null AFTER `wechat_account`;
alter table `ums_member` add column `detail_address` varchar(1000) null COMMENT '详细地址' default null;
alter table `ums_member` add column `real_name` varchar(100) null COMMENT '真实姓名' default null;
alter table `pms_product` add column `distribution_flag` int(1) null COMMENT '分销标志0->不参与1->参与)' default 1;

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
keystore.p12 Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

135
mall-admin/pom.xml Normal file
View File

@@ -0,0 +1,135 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.buy507.mall</groupId>
<artifactId>mall-admin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mall-admin</name>
<description>mall-admin project for mall</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<parent>
<groupId>com.buy507.mall</groupId>
<artifactId>mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.buy507.mall</groupId>
<artifactId>mall-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--JWT(Json Web Token)登录支持-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<!--redis依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--集成消息队列-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- 阿里云OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.5.0</version>
</dependency>
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.8</version>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- poi excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--<plugin>-->
<!--<groupId>com.spotify</groupId>-->
<!--<artifactId>docker-maven-plugin</artifactId>-->
<!--<version>1.1.0</version>-->
<!--<executions>-->
<!--<execution>-->
<!--<id>build-image</id>-->
<!--<phase>package</phase>-->
<!--<goals>-->
<!--<goal>build</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<!--<configuration>-->
<!--<imageName>mall/${project.artifactId}:${project.version}</imageName>-->
<!--<dockerHost>http://39.98.190.128:2375</dockerHost>-->
<!--<baseImage>java:8</baseImage>-->
<!--<entryPoint>["java", "-jar", "-Dspring.profiles.active=prod","/${project.build.finalName}.jar"]</entryPoint>-->
<!--<resources>-->
<!--<resource>-->
<!--<targetPath>/</targetPath>-->
<!--<directory>${project.build.directory}</directory>-->
<!--<include>${project.build.finalName}.jar</include>-->
<!--</resource>-->
<!--</resources>-->
<!--</configuration>-->
<!--</plugin>-->
</plugins>
</build>
</project>

View File

@@ -0,0 +1,25 @@
package com.buy507.mall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;
/**
* 应用启动入口
*/
@EnableTransactionManagement
@SpringBootApplication
public class MallAdminApplication {
public static void main(String[] args) {
SpringApplication.run(MallAdminApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@@ -0,0 +1,62 @@
package com.buy507.mall.bo;
import com.buy507.mall.model.UmsAdmin;
import com.buy507.mall.model.UmsPermission;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* SpringSecurity需要的用户详情
*/
public class AdminUserDetails implements UserDetails {
private UmsAdmin umsAdmin;
private List<UmsPermission> permissionList;
public AdminUserDetails(UmsAdmin umsAdmin,List<UmsPermission> permissionList) {
this.umsAdmin = umsAdmin;
this.permissionList = permissionList;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限
return permissionList.stream()
.filter(permission -> permission.getValue()!=null)
.map(permission ->new SimpleGrantedAuthority(permission.getValue()))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return umsAdmin.getPassword();
}
@Override
public String getUsername() {
return umsAdmin.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return umsAdmin.getStatus().equals(1);
}
}

View File

@@ -0,0 +1,143 @@
package com.buy507.mall.bo;
/**
* Controller层的日志封装类
*/
public class WebLog {
/**
* 操作描述
*/
private String description;
/**
* 操作用户
*/
private String username;
/**
* 操作时间
*/
private Long startTime;
/**
* 消耗时间
*/
private Integer spendTime;
/**
* 根路径
*/
private String basePath;
/**
* URI
*/
private String uri;
/**
* URL
*/
private String url;
/**
* 请求类型
*/
private String method;
/**
* IP地址
*/
private String ip;
private Object parameter;
private Object result;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getStartTime() {
return startTime;
}
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
public Integer getSpendTime() {
return spendTime;
}
public void setSpendTime(Integer spendTime) {
this.spendTime = spendTime;
}
public String getBasePath() {
return basePath;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Object getParameter() {
return parameter;
}
public void setParameter(Object parameter) {
this.parameter = parameter;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}

View File

@@ -0,0 +1,29 @@
package com.buy507.mall.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.buy507.mall.service.OmsOrderService;
/**
* 自动确认收货消息的处理者
*/
@Component
@RabbitListener(queues = "mall.receiving.confirm")
public class AutoConfirmReceivingReceiver {
private static Logger LOGGER = LoggerFactory.getLogger(AutoConfirmReceivingReceiver.class);
@Autowired
private OmsOrderService orderService;
@RabbitHandler
public void handle(Long orderId){
LOGGER.info("Confirm receiving receive orderId:{}", orderId);
orderService.confirmReceiving(orderId, true);
}
}

View File

@@ -0,0 +1,37 @@
package com.buy507.mall.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.buy507.mall.dto.ReceivingQueueEnum;
/**
* 自动确认收货消息的发出者
*/
@Component
public class AutoConfirmReceivingSender {
private static Logger LOGGER = LoggerFactory.getLogger(AutoConfirmReceivingSender.class);
@Autowired
private AmqpTemplate amqpTemplate;
public void sendMessage(Long orderId, final long delayTimes){
//给延迟队列发送消息
amqpTemplate.convertAndSend(ReceivingQueueEnum.QUEUE_TTL_RECEIVING_CONFIRM.getExchange(), ReceivingQueueEnum.QUEUE_TTL_RECEIVING_CONFIRM.getRouteKey(), orderId, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
//给消息设置延迟毫秒值
message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
return message;
}
});
LOGGER.info("Confirm receiving send orderId:{}", orderId);
}
}

View File

@@ -0,0 +1,42 @@
package com.buy507.mall.component;
import com.buy507.mall.common.api.CommonResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
/**
* HibernateValidator错误结果处理切面
*/
@Aspect
@Component
@Order(2)
public class BindingResultAspect {
@Pointcut("execution(public * com.buy507.mall.controller.*.*(..))")
public void BindingResult() {
}
@Around("BindingResult()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
if (arg instanceof BindingResult) {
BindingResult result = (BindingResult) arg;
if (result.hasErrors()) {
FieldError fieldError = result.getFieldError();
if(fieldError!=null){
return CommonResult.validateFailed(fieldError.getDefaultMessage());
}else{
return CommonResult.validateFailed();
}
}
}
}
return joinPoint.proceed();
}
}

View File

@@ -0,0 +1,100 @@
package com.buy507.mall.component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.buy507.mall.mapper.OmsOrderMapper;
import com.buy507.mall.model.OmsOrder;
import com.buy507.mall.service.DistributionService;
/**
* 分销冻结账户队列处理类
* @author wuming
*
*/
@Component
public class DistributeHandlerQueue implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(DistributeHandlerQueue.class);
private static LinkedBlockingQueue<Long> queue = new LinkedBlockingQueue<>();
@Autowired
private DistributionService distributionService;
@Autowired
private ExecutorService executorService;
@Autowired
private OmsOrderMapper orderMapper;
@Override
public void run(String... args) throws Exception {
executorService.execute(new Runnable() {
@Override
public void run() {
while(true) {
Long orderId = null;
try {
LOGGER.info("distribution handler queue size: {}", queue.size());
orderId = queue.take();
LOGGER.info("distribution handler start: {}", orderId);
OmsOrder order = orderMapper.selectByPrimaryKey(orderId);
//1. 分享劳务费和服务劳务费计算
distributionService.computeRefereeCharge(order.getMemberId(), order);
//2. 店补计算
distributionService.computeStoreSubsidy(order.getMemberId(), order);
//3. 上级团队的累计消费信息
distributionService.computeTeamTotalConsume(order.getMemberId(), order);
//4. 团队服务劳务费计算
distributionService.computeTeamIncome(order.getMemberId(), order);
//5. 会员等级计算,根据参数和消费情况计算会员等级
distributionService.computMemberLevel(order.getMemberId(), order);
LOGGER.info("distribution handler end: {}", orderId);
LOGGER.info("distribution handler queue size: {}", queue.size());
} catch (InterruptedException e) {
LOGGER.error("distribution handler failed");
e.printStackTrace();
} catch (Exception e) {
if(orderId != null) {
LOGGER.error("distribution handler failed: {}", orderId);
} else {
LOGGER.error("distribution handler failed");
}
e.printStackTrace();
}
}
}
});
}
/**
* 添加订单到分销处理队列中
* @param order
*/
public static void addOrderToQueue(Long orderId) {
try {
queue.put(orderId);
} catch (InterruptedException e) {
LOGGER.error("distribution add order to queue failed: {}", orderId);
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,23 @@
package com.buy507.mall.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 分销预结算消息的处理者
*/
@Component
@RabbitListener(queues = "mall.distribute.compute")
public class DistributeReceiver {
private static Logger LOGGER = LoggerFactory.getLogger(DistributeReceiver.class);
@RabbitHandler
public void handle(Long orderId){
LOGGER.info("Distribute receive orderId:{}", orderId);
DistributeHandlerQueue.addOrderToQueue(orderId);
}
}

View File

@@ -0,0 +1,24 @@
package com.buy507.mall.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 分销预结算消息的发出者
*/
@Component
public class DistributeSender {
private static Logger LOGGER = LoggerFactory.getLogger(DistributeSender.class);
@Autowired
private AmqpTemplate amqpTemplate;
public void sendMessage(Long orderId){
amqpTemplate.convertAndSend("mall.distribute.compute", orderId);
LOGGER.info("Distribute send orderId:{}", orderId);
}
}

View File

@@ -0,0 +1,61 @@
package com.buy507.mall.component;
import com.buy507.mall.util.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* JWT登录授权过滤器
*/
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader(this.tokenHeader);
if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
String username = jwtTokenUtil.getUserNameFromToken(authToken);
LOGGER.info("checking username:{}", username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
LOGGER.info("authenticated user:{}", username);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}

View File

@@ -0,0 +1,65 @@
package com.buy507.mall.component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
public class RedisLock {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisLock.class);
@Autowired
private StringRedisTemplate stringRedisTemplate;
public static final int TIMEOUT = 60 * 1000; //超时时间 60s
/**
* 加锁
* @param key 唯一标识
* @param value 当前时间 + 超时时间 也就是时间戳
* @return
*/
public boolean lock(String key, String value){
if(stringRedisTemplate.opsForValue().setIfAbsent(key, value)){//对应setnx命令
//可以成功设置,也就是key不存在
return true;
}
//判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁
String currentValue = stringRedisTemplate.opsForValue().get(key);
//如果锁过期
if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){//currentValue不为空且小于当前时间
//获取上一个锁的时间value
String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);//对应getset如果key存在
//假设两个线程同时进来这里因为key被占用了而且锁过期了。获取的值currentValue=A(get取的旧的值肯定是一样的),两个线程的value都是B,key都是K.锁时间已经过期了。
//而这里面的getAndSet一次只会一个执行也就是一个执行之后上一个的value已经变成了B。只有一个线程获取的上一个值会是A另一个线程拿到的值是B。
if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue) ){
//oldValue不为空且oldValue等于currentValue也就是校验是不是上个对应的商品时间戳也是防止并发
return true;
}
}
return false;
}
/**
* 解锁
* @param key
* @param value
*/
public void unlock(String key, String value){
try {
String currentValue = stringRedisTemplate.opsForValue().get(key);
if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value) ){
stringRedisTemplate.opsForValue().getOperations().delete(key);//删除key
}
} catch (Exception e) {
LOGGER.error("[Redis distributed lock] failed: {}", e);
}
}
}

View File

@@ -0,0 +1,26 @@
package com.buy507.mall.component;
import cn.hutool.json.JSONUtil;
import com.buy507.mall.common.api.CommonResult;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 当未登录或者token失效访问接口时自定义的返回结果
*/
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage())));
response.getWriter().flush();
}
}

View File

@@ -0,0 +1,28 @@
package com.buy507.mall.component;
import cn.hutool.json.JSONUtil;
import com.buy507.mall.common.api.CommonResult;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 当访问接口没有权限时,自定义的返回结果
*/
@Component
public class RestfulAccessDeniedHandler implements AccessDeniedHandler{
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException e) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
response.getWriter().flush();
}
}

View File

@@ -0,0 +1,123 @@
package com.buy507.mall.component;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.buy507.mall.bo.WebLog;
import io.swagger.annotations.ApiOperation;
import net.logstash.logback.marker.Markers;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 统一日志处理切面
*/
@Aspect
@Component
@Order(1)
public class WebLogAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class);
private ThreadLocal<Long> startTime = new ThreadLocal<>();
@Pointcut("execution(public * com.buy507.mall.controller.*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
startTime.set(System.currentTimeMillis());
}
@AfterReturning(value = "webLog()", returning = "ret")
public void doAfterReturning(Object ret) throws Throwable {
}
@Around("webLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
//获取当前请求对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//记录请求信息(通过logstash传入elasticsearch)
WebLog webLog = new WebLog();
Object result = joinPoint.proceed();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(ApiOperation.class)) {
ApiOperation log = method.getAnnotation(ApiOperation.class);
webLog.setDescription(log.value());
}
long endTime = System.currentTimeMillis();
String urlStr = request.getRequestURL().toString();
webLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
webLog.setIp(request.getRemoteUser());
webLog.setMethod(request.getMethod());
webLog.setParameter(getParameter(method, joinPoint.getArgs()));
webLog.setResult(result);
webLog.setSpendTime((int) (endTime - startTime.get()));
webLog.setStartTime(startTime.get());
webLog.setUri(request.getRequestURI());
webLog.setUrl(request.getRequestURL().toString());
Map<String,Object> logMap = new HashMap<>();
logMap.put("url",webLog.getUrl());
logMap.put("method",webLog.getMethod());
logMap.put("parameter",webLog.getParameter());
logMap.put("spendTime",webLog.getSpendTime());
logMap.put("description",webLog.getDescription());
// LOGGER.info("{}", JSONUtil.parse(webLog));
LOGGER.info(Markers.appendEntries(logMap), JSONUtil.parse(webLog).toString());
return result;
}
/**
* 根据方法和传入的参数获取请求参数
*/
private Object getParameter(Method method, Object[] args) {
List<Object> argList = new ArrayList<>();
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
if (requestBody != null) {
argList.add(args[i]);
}
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
if (requestParam != null) {
Map<String, Object> map = new HashMap<>();
String key = parameters[i].getName();
if (!StringUtils.isEmpty(requestParam.value())) {
key = requestParam.value();
}
map.put(key, args[i]);
argList.add(map);
}
}
if (argList.size() == 0) {
return null;
} else if (argList.size() == 1) {
return argList.get(0);
} else {
return argList;
}
}
}

View File

@@ -0,0 +1,14 @@
package com.buy507.mall.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MyBatis配置类
*/
@Configuration
@EnableTransactionManagement
@MapperScan({"com.buy507.mall.mapper","com.buy507.mall.dao"})
public class MyBatisConfig {
}

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