mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-29 14:01:07 +00:00
Merge branch 'master' of https://gitee.com/ZhongBangKeJi/CRMEB
# Conflicts: # crmeb/app/services/order/StoreOrderRefundServices.php # crmeb/app/services/user/UserBillServices.php
This commit is contained in:
commit
7e64ff5fc1
5
.gitignore
vendored
5
.gitignore
vendored
@ -19,3 +19,8 @@
|
||||
/template/uni-app/node_modules/
|
||||
/template/uni-app/unpackage/
|
||||
/template/uni-app/.hbuilderx/
|
||||
/crmeb/.idea/
|
||||
/docker-compose/MacArm/mysql/data/
|
||||
/docker-compose/MacArm/mysql/log/
|
||||
/docker-compose/linux/mysql/data/
|
||||
/docker-compose/linux/mysql/log/
|
||||
|
||||
876
LICENSE
876
LICENSE
@ -1,674 +1,202 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <2017> <西安众邦网络科技有限公司>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
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 [2014-2024] [Xi'an Zhongbang Network Technology Co., Ltd]
|
||||
|
||||
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.
|
||||
|
||||
|
||||
369
README.md
369
README.md
@ -1,178 +1,295 @@
|
||||

|
||||
<div align="center" >
|
||||
<img src="https://images.gitee.com/uploads/images/2021/1109/164354_0aafe3d2_892944.gif" />
|
||||
</div>
|
||||
<div align="center">
|
||||
|
||||
支持免费商用的PHP **多语言** 商城系统
|
||||
<div align="center" >
|
||||
<img src="https://www.crmeb.com/static/images/dark_logo.png" />
|
||||
</div>
|
||||
|
||||
<div align="center" style="font-size: 15px;">
|
||||
|
||||
CRMEB开源商城系统(PHP版)
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center" >
|
||||
<a href="http://www.crmeb.com">
|
||||
<img src="https://img.shields.io/badge/Licence-GPL3.0-green.svg?style=flat" />
|
||||
</a>
|
||||
<a href="http://www.crmeb.com">
|
||||
<img src="https://img.shields.io/badge/Edition-4.5-blue.svg" />
|
||||
</a>
|
||||
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/repository/archive/master.zip">
|
||||
<img src="https://img.shields.io/badge/Download-150m-red.svg" />
|
||||
</a>
|
||||
<a href='https://gitee.com/ZhongBangKeJi/CRMEB/stargazers'>
|
||||
<img src='https://gitee.com/ZhongBangKeJi/CRMEB/badge/star.svg?theme=gvp' alt='star'></img>
|
||||
</a>
|
||||
<a href="http://www.crmeb.com">
|
||||
<img src="https://img.shields.io/badge/Licence-apache2.0-green.svg?style=flat" />
|
||||
</a>
|
||||
<a href="http://www.crmeb.com">
|
||||
<img src="https://img.shields.io/badge/Edition-5.6.1-blue.svg" />
|
||||
</a>
|
||||
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/repository/archive/master.zip">
|
||||
<img src="https://img.shields.io/badge/Download-240m-red.svg" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
####
|
||||
<div align="center" style="font-size: 15px;">
|
||||
用心做开源,我们也很需要你的鼓励!右上角Star🌟,等你点亮
|
||||
</div>
|
||||
|
||||
|
||||
####
|
||||
|
||||
|
||||
<div align="center">
|
||||
|
||||
|
||||
[官网](https://www.crmeb.com/) |
|
||||
[在线体验](http://v4.crmeb.net/admin/) |
|
||||
[帮助文档](https://doc.crmeb.com/single/crmeb_v4) |
|
||||
[技术社区](https://www.crmeb.com/ask/)
|
||||
[帮助文档](https://doc.crmeb.com/single_open) |
|
||||
[应用市场](https://www.crmeb.com/market/) |
|
||||
[技术社区](https://www.crmeb.com/ask/thread/list/147) |
|
||||
[宽屏预览](https://gitee.com/ZhongBangKeJi/CRMEB/blob/master/README.md)
|
||||
|
||||
|
||||
|
||||
[comment]: <> ([宽屏预览](https://gitee.com/ZhongBangKeJi/CRMEB/blob/master/README.md))
|
||||
|
||||
</div>
|
||||
<div align="center" >
|
||||
<a href="https://gitee.com/ZhongBangKeJi/CRMEB/blob/master/README.md">宽 屏 预 览</a>
|
||||
</div>
|
||||
|
||||
### 介绍
|
||||
CRMEB打通版是历经6年时间匠心之作!系统全开源可商用,包含小程序商城、H5商城、公众号商城、PC商城、App,多种分销模式、拼团、砍价、秒杀、优惠券、抽奖、积分、会员等级、小程序直播、页面DIY,前后端分离全部100%开源。方便二开,更有详细使用文档、接口文档、数据字典、二开文档/视频教程。为开发者赋能,助力企业发展、国家富强,致力于打造最受欢迎的商城项目
|
||||
|
||||
CRMEB开源商城Java版:https://gitee.com/ZhongBangKeJi/crmeb_java
|
||||
|
||||
|
||||
|
||||
### 系统亮点
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 📝 **项目介绍**
|
||||
|
||||
**开源自由**
|
||||
|
||||
CRMEB开源商城系统代码100%开源,基于 **Apache-2.0协议** 免费商用,无任何隐藏费用或功能限制,真正实现“零成本”部署与二次开发自由!
|
||||
|
||||
**技术架构**
|
||||
|
||||
采用 **ThinkPHP 6 + ElementUI + UniApp** 技术栈,前后端分离设计,支持模块化开发与高效维护。前端适配微信小程序、H5、APP、PC等多端,后端统一管理全平台数据,保障流畅体验与高并发性能。
|
||||
|
||||
**全场景覆盖**
|
||||
|
||||
无缝对接公众号、小程序、H5、APP、PC端,数据实时互通,助力商家一站式运营多渠道业务,满足全场景电商需求。
|
||||
|
||||
**原生营销引擎**
|
||||
|
||||
内置 **20+核心营销模块**(拼团、砍价、秒杀、优惠券、积分体系、直播带货、付费会员、等级会员、用户充值、分销裂变、渠道码、新人礼等),支持零插件自定义活动规则。通过 **首页DIY功能** ,商家可拖拽式设计商城首页,无需技术背景即可快速搭建高转化场景,实现「所见即所得」的运营效率。
|
||||
|
||||
**社区共建计划**
|
||||
|
||||
我们致力于打造开发者友好生态,开放源码、持续更新功能模块,并欢迎开发者提交优化建议或贡献代码。通过共享技术成果,降低行业重复造轮子成本,推动开源电商系统的可持续发展。
|
||||
|
||||
|
||||
🔗 <a href="https://doc.crmeb.com/single_open/open_v54/19855" target="_blank">功能列表</a> | 📩 <a href="https://gitee.com/ZhongBangKeJi/CRMEB/issues" target="_blank">提交反馈</a> | 📩 <a href="https://gitee.com/ZhongBangKeJi/CRMEB/pulls" target="_blank">提交代码</a>
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 🫧 技术特点
|
||||
|
||||
~~~
|
||||
多 语 言:后台随时配置语言包,移动端支持多语言切换;
|
||||
高 性 能:redis缓存、队列、长连接、多种云储存、支持集群部署;
|
||||
个 性 UI:多种风格切换、支持DIY各种首页/专题页面
|
||||
前后端分离:后端TP6,管理端iviewui,移动端uniapp;
|
||||
代码规范:遵循PSR-2命名规范、Restful标准接口、代码严格分层、注释齐全、统一错误码;
|
||||
权限管理:内置强大灵活的权限管理,可以控制到每一个菜单;
|
||||
开发配置:低代码增加配置、系统组合数据模块;
|
||||
二开效率:PHP快速生成表单、内置所有事件、后台在线编辑器、代码注释齐全、完整接口文档;
|
||||
快速上手:详细帮助文档、接口文档、数据库字典、代码注释、一键安装;
|
||||
系统安全:系统操作日志、系统生产日志、文件校验、数据备份;
|
||||
系统功能:请看帮助文档 https://doc.crmeb.com/single/crmeb_v4/1758
|
||||
用户体验:等您来评!
|
||||
关于二开:
|
||||
1.代码规范:遵循PSR-2命名规范、Restful标准接口、代码严格分层、注释齐全、统一错误码;
|
||||
2.权限管理:内置强大灵活的权限管理,可以控制到每一个菜单;
|
||||
3.开发配置:低代码增加配置、系统组合数据模块;
|
||||
4.代码生成:快速生成后台菜单、页面,快速实现增删改查;
|
||||
5.定时任务:系统内置10中定时任务,还有自定义任务,可以自行设置执行周期,执行代码,完美兼容;
|
||||
6.系统事件:埋入30+系统事件锚点,可在后台页面进行事件添加;
|
||||
7.在线编辑:可以在后台对系统的代码进行编辑修改操作,不用登录服务器去修改代码文件,方便快捷;
|
||||
8.接口管理:后台页面可以看到系统中所有的接口数据,并且可以在线调试接口;
|
||||
9.二开效率:应用form-builder PHP可以快速生成表单;
|
||||
10.快速上手:后台接口管理、后台数据库字典、系统文件管理备注、代码注释、一键安装;
|
||||
~~~
|
||||
~~~
|
||||
性能与拓展:
|
||||
1.系统安全:系统操作日志、系统生产日志、文件校验、数据备份;
|
||||
2.高性能:支持Redis缓存、队列、长连接、多种云储存、支持集群部署;
|
||||
3.多语言:支持自动识别浏览器多语言展示;
|
||||
4.驱动扩展:支持多种支付方式、多种短信、多种云储存等;
|
||||
5.云存储:云存储支持图片和视频的远程云存储,支持阿里云,腾讯云,七牛云,京东云,天翼云,华为云
|
||||
6.一号通:通用的第三方扩展,支持短信,物流查询,电子面单,电子发票,商品采集,商家寄件
|
||||
~~~
|
||||
|
||||
---
|
||||
|
||||
### 运行环境
|
||||
### 📖 系统功能
|
||||
|
||||
```
|
||||
Nignx/Apache/IIS
|
||||
PHP 7.1 ~ 7.4
|
||||
MySQL 5.7
|
||||
Redis
|
||||
```
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 📖 UI界面展示
|
||||
|
||||

|
||||
|
||||
|
||||
> 温馨提示:虚拟空间不支持,推荐使用bt宝塔面板,服务器推荐阿里云ecs或腾讯云cvm 云服务器:<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=dligum2z" target="_blank"> 查看 </a>
|
||||
|
||||
---
|
||||
|
||||
### 📖 后台界面展示
|
||||
|
||||

|
||||
|
||||
|
||||
### 系统演示
|
||||
---
|
||||
|
||||

|
||||
|
||||
管理后台: http://v4.crmeb.net/admin 账号:demo 密码:crmeb.com
|
||||
### 📱 系统演示
|
||||
|
||||
H5端:http://v4.crmeb.net/(移动端打开)
|
||||

|
||||
|
||||
PC端:http://v4.crmeb.net/(电脑端打开)
|
||||
管理后台: http://v5.crmeb.net/admin
|
||||
|
||||
账号:demo 密码:crmeb.com
|
||||
|
||||
H5端:http://v5.crmeb.net/ (移动端打开)
|
||||
|
||||
PC端:http://v5.crmeb.net/ (电脑端打开)
|
||||
|
||||
APP下载:http://app.crmeb.cn/bzv (苹果手机直接在APP Store里搜索CRMEB下载)
|
||||
|
||||
---
|
||||
> 听说,大神你想看看CRMEB开源项目的完整框架?<a href="https://doc.crmeb.com/single/v5/7712" target="_blank">戳这儿,轻松获取!</a>
|
||||
|
||||
|
||||
|
||||
#### 体验云部署
|
||||
不懂服务器?不懂技术?无法解决高并发?想数据私有化?还想后期定制开发?
|
||||
|
||||
推荐云部署版一键超低价格低至 :collision: 9.9元/年,解决以上所有问题<a href='https://saas.crmeb.com/saas-home-software-detail-50043-s-y.html' target='_blank'>点击了解 </a>
|
||||
|
||||
---
|
||||
|
||||
### 官方论坛
|
||||
|
||||
|
||||
产品BUG、优化建议,欢迎社区反馈:https://www.crmeb.com/ask/thread/list?id=147
|
||||
|
||||
|
||||
### 页面展示
|
||||
(页面仅展示部分UI)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
<div align="center">
|
||||
<a href='http://s.crmeb.com/goods_detail/739' target='_blank'>点击查看高清版全套UI设计图</a>
|
||||
</div>
|
||||
### 🔐 **运行环境**
|
||||
|
||||
|
||||
### 推荐项目(欢迎合作,QQ:763569752 )
|
||||
|
||||
| 项目名称 | 关注量 | 项目介绍 |
|
||||
| ------------ | ------------ | ------------ |
|
||||
| [](https://gitee.com/ZhongBangKeJi/CRMChat) | [](https://gitee.com/ZhongBangKeJi/CRMChat/stargazers) | CRMChat客服系统,支持接入各种渠道. |
|
||||
| [](https://gitee.com/ZhongBangKeJi/crmeb_java) | [](https://gitee.com/ZhongBangKeJi/crmeb_java/stargazers) | JAVA版开源商城. |
|
||||
| [](https://gitee.com/xaboy/form-builder) | [](https://gitee.com/xaboy/form-builder/stargazers) | PHP表单生成器,快速生成现代化的form表单。 |
|
||||
| [](https://gitee.com/layui/layui-vue) | [](https://gitee.com/layui/layui-vue/stargazers) | layui-vue(谐音:类UI)是一套Vue3.0 的桌面端组件库. |
|
||||
| [](https://gitee.com/ntdgg/tpflow) | [](https://gitee.com/ntdgg/tpflow/stargazers) | TpFlow工作流引擎是一套规范化的流程管理系统,基于业务而驱动系统生命力的一套引擎. |
|
||||
|
||||
### 商业版购买
|
||||
开源不易,以下如果有需要,请支持一下,感谢您的支持,让我们更多动力!
|
||||
|
||||
[](https://www.crmeb.com/index/criteria)
|
||||
|
||||
### 🔥🔥庆祝:CRMEB开源商城系统Gitee star突破10000+ 专属活动福利 [点击了解](https://www.crmeb.com/ask/thread/20738)
|
||||
|
||||
### 感谢参与开发者
|
||||
感谢大神们提交代码(排名不分先后)
|
||||
|
||||
@yizhisamoye,@bys1123,@xaboy,@youngxj0,@jacklincheung,@392256866,@sxsea
|
||||
|
||||
欢迎反馈问题 [反馈问题](https://gitee.com/ZhongBangKeJi/CRMEB/issues)。
|
||||
|
||||
欢迎提交代码 [提交代码](https://gitee.com/ZhongBangKeJi/CRMEB/pulls)。
|
||||
|
||||
### 特别鸣谢
|
||||
|
||||
排名不分先后,感谢这些软件的开发者:thinkphp、iview、vue、mysql、redis、uniapp、echarts、tree-table-vue、swiper、form-create等,如有遗漏请联系我!
|
||||
|
||||
### 核心开发团队
|
||||
产品:木子刀客
|
||||
|
||||
技术:聆听、等风来、xaboy、吴汐、最后一片叶、旺仔、小小、娜娜、归来仍是少年
|
||||
|
||||
UI:xy-yyds、LXT
|
||||
|
||||
测试:夏天、绵绵羊、。ws
|
||||
|
||||
### 使用须知
|
||||
|
||||
1.允许用于个人学习、毕业设计、教学案例、公益事业、商业使用;
|
||||
|
||||
2.如果商用必须保留版权信息,请自觉遵守;
|
||||
|
||||
3.禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负。
|
||||
|
||||
### 版权信息
|
||||
|
||||
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
||||
|
||||
版权所有Copyright © 2017-2023 by CRMEB (https://www.crmeb.com)
|
||||
|
||||
All rights reserved。
|
||||
|
||||
CRMEB® 商标和著作权所有者为西安众邦网络科技有限公司。
|
||||
| **运行环境** | **要求** |
|
||||
|------------------|------------------------------------------------------------------------|
|
||||
| **操作系统** | Linux / Windows |
|
||||
| **WEB 服务** | Nginx / Apache / IIS |
|
||||
| **PHP 版本** | PHP 7.1 ~ 7.4 |
|
||||
| **数据库** | MySQL 5.7 ~ 8.0(引擎:InnoDB) |
|
||||
| **缓存** | Redis(可选,不安装则使用文件缓存) |
|
||||
| **管理器** | Supervisor(用于管理消息队列) |
|
||||
| **推荐工具** | 宝塔面板(简单易用) |
|
||||
| **云服务器** | 阿里云 ECS / 腾讯云 CVM / 京东云ECS |
|
||||
| **开放端口** | 80, 21, 8888, 888, 443, 3306, 6379(授权对象:`0.0.0.0/0`) |
|
||||
| **PHP 扩展** | fileinfo(可选)、redis(可选) |
|
||||
| **禁用函数** | `proc_open`, `pcntl_signal`, `pcntl_signal_dispatch`, `pcntl_fork`, `pcntl_wait`, `pcntl_alarm` |
|
||||
| **消息队列** | 运行命令:`php think queue:listen --queue` (使用Supervisor) |
|
||||
| **长连接** | 运行命令:`sudo -u www php think workerman start --d` (命令行执行) |
|
||||
| **定时任务** | 运行命令:`php think timer start --d` (命令行执行) |
|
||||
> 温馨提示:虚拟空间不支持,推荐使用bt宝塔面板,服务器推荐京东云服务器:<a href="https://partner.jdcloud.com/partner/notice/b06c3232b6394fdfa496923b8e00b286" target="_blank">注册即享6.5折专属优惠,点我领取!</a>
|
||||
|
||||
---
|
||||
### 📺 **开发环境及使用技术**
|
||||
|
||||
### **开发环境:**
|
||||
| 工具 | 版本 | 下载链接 |
|
||||
|--------------|--------------------|-------------------------------------------------------------------------|
|
||||
| **PHP** | 7.1-7.4 | [PHP 官方下载](https://www.php.net/downloads.php) |
|
||||
| **MySQL** | 5.7 | [MySQL 官网](https://www.mysql.com/) |
|
||||
| **Redis** | 7.0 | [Redis 官网](https://redis.io/download) |
|
||||
| **Nginx** | 1.22 | [Nginx 官网](http://nginx.org/en/download.html) |
|
||||
| **Apache** | 2.4 | [Apache HTTP Server](https://httpd.apache.org/download.cgi) |
|
||||
| **Node.js** | 14/18 | [Node.js LTS 版本](https://nodejs.org/en/download/releases/) |
|
||||
|
||||
### 后端技术栈
|
||||
| **技术** | **名称** | **网址** |
|
||||
|---------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------|
|
||||
| php扩展库 | PHP 基础运行环境,JSON 数据处理,高精度数学计算等 | https://www.php.net/ |
|
||||
| topthink | ThinkPHP 视图模板引擎,验证码生成组件,队列任务支持,数据库迁移工具 | https://www.thinkphp.cn/ |
|
||||
| overtrue | 微信生态开发(公众号/小程序/支付) | https://github.com/w7corp/easywechat |
|
||||
| php-jwt | JWT 令牌生成与验证 | https://github.com/firebase/php-jwt |
|
||||
| var-dumper | 调试输出工具(格式化变量) | https://symfony.com/doc/current/components/var_dumper.html |
|
||||
| phpoffice | 文件处理 | https://github.com/PHPOffice/PhpSpreadsheet |
|
||||
| guzzlehttp|psr7 | HTTP 客户端库,PSR-7 HTTP 消息接口实现 | https://guzzle-cn.readthedocs.io/zh-cn/latest |
|
||||
| form-builder | 快速构建表单的 UI 工具 | https://form-create.com |
|
||||
| workerman | 高性能 Socket 服务器框架,定时任务调度 | https://www.workerman.net |
|
||||
|
||||
### 移动端技术栈
|
||||
| **技术** | **名称** | **官网** |
|
||||
| --- | --- | --- |
|
||||
| uniapp | 跨端框架 | https://uniapp.dcloud.net.cn/ |
|
||||
| vuex | 状态管理库 | https://vuex.vuejs.org/ |
|
||||
| socket | WebSocket通信 | https://socket.io/ |
|
||||
| dayjs | 时间处理库 | https://day.js.org/ |
|
||||
| animate | CSS动画库 | https://animate.style/ |
|
||||
| easy-loadimage | 图片懒加载 | https://github.com/TSjianjiao/easy-loadimage |
|
||||
|
||||
### Admin端技术栈
|
||||
| **技术** | **名称** | **官网** |
|
||||
| --- | --- | --- |
|
||||
| vue2 | Vue框架 | https://v2.vuejs.org/ |
|
||||
| vuex | 状态管理库 | https://vuex.vuejs.org/ |
|
||||
| element-ui | UI框架 | https://element.eleme.io/ |
|
||||
| axios | HTTP客户端 | https://axios-http.com/ |
|
||||
| vxe-table | 高级表格组件 | https://vxetable.cn/ |
|
||||
| wangeditor | 富文本编辑器 | https://www.wangeditor.com/ |
|
||||
| qs | 查询字符串解析 | https://github.com/ljharb/qs |
|
||||
| xlsx | Excel处理库 | https://sheetjs.com/ |
|
||||
| sass | CSS预处理器 | https://sass-lang.com/ |
|
||||
| prettier | 代码格式化 | https://prettier.io/ |
|
||||
| v-viewer | 图片查看器 | https://github.com/mirari/v-viewer |
|
||||
|
||||
### PC端技术栈
|
||||
| **技术** | **名称** | **官网** |
|
||||
| --- | --- | --- |
|
||||
| nuxt | Vue服务端渲染框架 | https://nuxtjs.org/ |
|
||||
| element | UI框架 | https://element.eleme.io/ |
|
||||
| axios | HTTP客户端 | https://axios-http.com/ |
|
||||
| sass | CSS预处理器 | https://sass-lang.com/ |
|
||||
| cookie-universal-nuxt | Nuxt Cookie处理 | https://github.com/microcipcip/cookie-universal |
|
||||
| postcss | CSS转换工具 | https://postcss.org/ |
|
||||
| qs | 查询字符串解析 | https://github.com/ljharb/qs |
|
||||
|
||||
|
||||
|
||||
### 想要快速安装,教程来助攻!
|
||||
|
||||
快速一键安装部署:https://doc.crmeb.com/single_open/open_v54/20366
|
||||
|
||||
手动配置安装:https://doc.crmeb.com/single_open/open_v54/20389
|
||||
|
||||
docker-compose一键部署:https://doc.crmeb.com/single_open/open_v54/20145
|
||||
|
||||
宝塔环境一键安装:https://doc.crmeb.com/single_open/open_v54/19892
|
||||
|
||||
### 二开支持:
|
||||
使用文档:https://doc.crmeb.com/single_open/open_v54/19849
|
||||
|
||||
接口文档:https://doc.crmeb.com/single_open/open_v54/21040
|
||||
|
||||
数据字典:https://doc.crmeb.com/single_open/open_v54/20136
|
||||
|
||||
代码生成:https://doc.crmeb.com/single_open/open_v54/20135
|
||||
|
||||
二开文档:https://doc.crmeb.com/single_open/open_v54/19851
|
||||
|
||||
视频教程:https://www.bilibili.com/video/BV1kh4y1872K/
|
||||
|
||||
技术社区:https://www.crmeb.com/ask/thread/list/147
|
||||
|
||||
---
|
||||
|
||||
### 📞 CRMEB互动
|
||||
#### CRMEB开源技术交流群(扫码进群可领取开源版接口文档、产品功能清单、高清UI设计图、思维脑图!)
|
||||

|
||||
#### 技术社区!找方法、提bug、看官方消息、拿活跃大奖!都在 <a href="https://www.crmeb.com/ask" target="_blank">CRMEB 技术社区</a> 应有尽有
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 📕 CRMEB PRO版
|
||||
|
||||
[](https://www.crmeb.com/index/pro)
|
||||
|
||||
|
||||
|
||||
### 📕 CRMEB 多商户版
|
||||
|
||||
[](https://www.crmeb.com/index/merchant)
|
||||
|
||||
---
|
||||
|
||||
[返回顶部 :fa-arrow-circle-up: ](https://gitee.com/ZhongBangKeJi/CRMEB#%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D)
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
version=CRMEB-KY v4.7.0
|
||||
version_code=470
|
||||
version=CRMEB-KY v5.6.3
|
||||
version_code=563
|
||||
platform=gitee
|
||||
app_id=ze7x9rxsv09l6pvsyo
|
||||
app_key=fuF7U9zaybLa5gageVQzxtxQMFnvU2OI
|
||||
|
||||
190
crmeb/README.md
190
crmeb/README.md
@ -1,4 +1,4 @@
|
||||
CRMEB v4.5 后端程序目录
|
||||
CRMEB v5 后端程序目录
|
||||
===============
|
||||
|
||||
> 运行环境要求PHP7.1-7.4。
|
||||
@ -8,12 +8,10 @@ CRMEB v4.5 后端程序目录
|
||||
## 一键安装
|
||||
上传你的代码,站点入口目录设置/public
|
||||
在浏览器中输入你的域名或IP(例如:www.yourdomain.com),
|
||||
安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装,安装完成后建议删除install目录下index.php文件或将其改名。
|
||||
安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装,安装完成后建议删除install目录。
|
||||
|
||||
后台访问地址:
|
||||
1.域名/admin
|
||||
2.域名/index.php/admin
|
||||
3.域名/index.php?s=/admin
|
||||
公众号和H5首页访问地址:
|
||||
1.域名/
|
||||
|
||||
@ -37,32 +35,39 @@ DEFAULT_TIMEZONE = Asia/Shanghai
|
||||
[DATABASE]
|
||||
TYPE = mysql
|
||||
HOSTNAME = 127.0.0.1 #数据库连接地址
|
||||
HOSTPORT = 3306 #数据库端口
|
||||
DATABASE = test #数据库名称
|
||||
USERNAME = username #数据库登录账号
|
||||
PASSWORD = password #数据库登录密码
|
||||
HOSTPORT = 3306 #数据库端口
|
||||
CHARSET = utf8
|
||||
PREFIX = eb_
|
||||
CHARSET = utf8mb4
|
||||
DEBUG = true
|
||||
|
||||
[LANG]
|
||||
default_lang = zh-cn
|
||||
|
||||
[CACHE]
|
||||
DRIVER = file #缓存类型,redis/file
|
||||
CACHE_PREFIX = cache_xxxx: #缓存前缀
|
||||
CACHE_TAG_PREFIX = cache_tag_xxxx: #缓存类型前缀
|
||||
|
||||
[REDIS]
|
||||
REDIS_HOSTNAME = 127.0.0.1 # redis链接地址
|
||||
REDIS_HOSTNAME = 127.0.0.1 #redis链接地址
|
||||
PORT = 6379 #端口号
|
||||
REDIS_PASSWORD = 123456 #密码
|
||||
SELECT = 0 #数据库
|
||||
|
||||
[QUEUE]
|
||||
QUEUE_NAME = xxxx #队列前缀
|
||||
~~~
|
||||
3.修改目录权限(linux系统)777
|
||||
/public
|
||||
/runtime
|
||||
/crmeb
|
||||
/template
|
||||
|
||||
4.后台登录:
|
||||
http://域名/admin
|
||||
默认账号:admin 密码:crmeb.com
|
||||
## 消息队列
|
||||
```sh
|
||||
php think queue:listen --queue
|
||||
```
|
||||
|
||||
|
||||
## 消息队列
|
||||
```sh
|
||||
@ -98,6 +103,165 @@ php think workerman start --d
|
||||
- restart: 重启
|
||||
- --d : 后台执行
|
||||
|
||||
## 开发规范
|
||||
#### 命名规范
|
||||
ThinkPHP6.0遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范:
|
||||
|
||||
1. 目录和文件
|
||||
2. 目录使用小写+下划线;
|
||||
3. 类库、函数文件统一以.php为后缀;
|
||||
4. 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;
|
||||
5. 类(包含接口和Trait)文件采用驼峰法命名(首字母大写),其它文件采用小写+下划线命名;
|
||||
6. 类名(包括接口和Trait)和文件名保持一致,统一采用驼峰法命名(首字母大写);
|
||||
|
||||
#### 函数和类、属性命名
|
||||
|
||||
1. 类的命名采用驼峰法(首字母大写),例如 User、UserType;
|
||||
2. common函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 get_client_ip;
|
||||
3. 控制器里面的方法使用小写字母和下划线(小写字母开头)的方式,例如 get_client_ip
|
||||
4. 方法的命名使用驼峰法(首字母小写),例如 getUserName;
|
||||
5. 属性的命名使用驼峰法(首字母小写),例如 tableName、instance;
|
||||
6. 特例:以双下划线__打头的函数或方法作为魔术方法,例如 __call 和 __autoload;
|
||||
|
||||
#### 常量和配置
|
||||
1. 常量以大写字母和下划线命名,例如 APP_PATH;
|
||||
2. 配置参数以小写字母和下划线命名,例如 url_route_on 和url_convert;
|
||||
3. 环境变量定义使用大写字母和下划线命名,例如APP_DEBUG;
|
||||
|
||||
#### 数据表和字段
|
||||
1. 数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例如 think_user 表和 user_name字段,不建议使用驼峰和中文作为数据表及字段命名
|
||||
|
||||
注意:请理解并尽量遵循以上命名规范,可以减少在开发过程中出现不必要的错误
|
||||
|
||||
#### 语法规范
|
||||
1. 尽量使用php7新语法
|
||||
2. 每个 namespace 命名空间声明语句和 use 声明语句块后面,必须 插入一个空白行
|
||||
3. 类的开始花括号({) 必须 写在类声明后自成一行,结束花括号(})也 必须 写在类主体后自成一行
|
||||
4. 方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。
|
||||
5. 类的属性和方法 必须 添加访问修饰符(private、protected 以及 public),abstract 以及 final 必须 声明在访问修饰符之前,而 static 必须 声明在访问修饰符之后
|
||||
6. 控制结构的关键字后 必须 要有一个空格符,而调用方法或函数时则 一定不可 有
|
||||
7. 控制结构的开始花括号({) 必须 写在声明的同一行,而结束花括号(}) 必须 写在主体后自成一行
|
||||
8. 纯 PHP 代码文件 必须 省略最后的 ?> 结束标签
|
||||
9. 所有方法,类,控制器类,都 必须 添加访问修饰符
|
||||
~~~
|
||||
|
||||
/**
|
||||
* 中文注释
|
||||
* @param string $str 声明类型
|
||||
* @param array $arr
|
||||
* @return bool
|
||||
*/
|
||||
public function action(string $str, array $arr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
~~~
|
||||
10. 参数列表中,每个逗号后面 必须 要有一个空格,而逗号前面 一定不可 有空格
|
||||
~~~
|
||||
function foo($arg1, &$arg2, $arg3 = [])
|
||||
{
|
||||
// method body
|
||||
}
|
||||
~~~
|
||||
11. 参数 可以 分列成多行,此时包括第一个参数在内的每个参数都 尽量 单独成行。
|
||||
~~~
|
||||
<?php
|
||||
$foo->bar(
|
||||
$longArgument,
|
||||
$longerArgument,
|
||||
$muchLongerArgument
|
||||
);
|
||||
~~~
|
||||
12. 标准的 if 结构如下代码所示,请留意「括号」、「空格」以及「花括号」的位置,
|
||||
注意 else 和 elseif 都与前面的结束花括号在同一行
|
||||
~~~
|
||||
<?php
|
||||
if ($expr1) {
|
||||
// if body
|
||||
} elseif ($expr2) {
|
||||
// elseif body
|
||||
} else {
|
||||
// else body;
|
||||
}
|
||||
~~~
|
||||
13. 赋值等号前后必须加空格符
|
||||
~~~
|
||||
<?php
|
||||
$arr = [];
|
||||
~~~
|
||||
|
||||
|
||||
#### PHP 7.1+ 常用新语法
|
||||
|
||||
1. 三元运算符
|
||||
~~~
|
||||
<?php
|
||||
|
||||
$arr = ['crmeb'=>true];
|
||||
之前
|
||||
echo isset($arr['crmeb']) ? $arr['crmeb'] : '';
|
||||
之后
|
||||
echo $arr['crmeb'] ?? '';
|
||||
~~~
|
||||
2. define() 定义常量数组
|
||||
~~~
|
||||
<?php
|
||||
define('ARR',['a','b']);
|
||||
~~~
|
||||
3. 命名空间优化
|
||||
~~~
|
||||
<?php
|
||||
//PHP7之前语法
|
||||
use FooLibrary\Bar\Baz\ClassA;
|
||||
use FooLibrary\Bar\Baz\ClassB;
|
||||
// PHP7新语法写法
|
||||
use FooLibrary\Bar\Baz\{ ClassA, ClassB};
|
||||
|
||||
~~~
|
||||
#### CRMEB PRO规范
|
||||
1. 所有数据验证放在模块下的 validates 目录下
|
||||
2. JSON返回使用父级 AuthController类中的success 和 fail
|
||||
3. 错误判断抛出异常,由一个错误类统一控制输出
|
||||
~~~
|
||||
<?php
|
||||
|
||||
throw new AuthException('错误信息',400);
|
||||
~~~
|
||||
4. 错误码和错误提示语应该统一管理,方便切换多语言
|
||||
5. 数据库操作使用模型类,不能使用Db::table()
|
||||
6. 获取表单数据使用 app\Request
|
||||
~~~
|
||||
<?php
|
||||
use app\Request;
|
||||
|
||||
|
||||
public function index(Request $request) {
|
||||
|
||||
//获取提交的数据,并以二维数组形式返回
|
||||
$arr = $request->getMore([
|
||||
'name',
|
||||
'nickname'
|
||||
]);
|
||||
//获取提交的数据,并以二维数组形式返回并附加默认值
|
||||
$arr = $request->getMore([
|
||||
['name','123'],
|
||||
['nickname','0']
|
||||
]);
|
||||
//获取提交的数据,并以一维数组形式返回并附加默认值
|
||||
[$name, $nickname] = $request->getMore([
|
||||
['name','123'],
|
||||
['nickname','0']
|
||||
],true);
|
||||
|
||||
}
|
||||
~~~
|
||||
7. 所有控制器类命令和表名对应,按照大驼峰命名规范
|
||||
8. 所有文件夹命名按照小写字母加下划线定义
|
||||
9. 所有属性名,变量名尽量遵守小驼峰命名规范
|
||||
10. 复杂逻辑,多状态应适当添加行内注释
|
||||
11. 模型里只能写关于搜索条件语句,查出数据得组合书写在services层进行处理,services创建命令:php make:services api@user/User
|
||||
|
||||
|
||||
## 文档
|
||||
|
||||
[使用手册](https://doc.crmeb.com)
|
||||
|
||||
70
crmeb/app/README.md
Normal file
70
crmeb/app/README.md
Normal file
@ -0,0 +1,70 @@
|
||||
### 系统目录介绍优化方案
|
||||
|
||||
#### 1. 引言
|
||||
在优化系统目录介绍时,我们的目标是使目录结构更加清晰、易于理解,并突出每个目录的核心功能和作用。
|
||||
|
||||
#### 2. 目录结构优化概述
|
||||
我们将通过以下几个步骤来优化目录介绍:
|
||||
- **明确目录层级**:清晰展示主目录与子目录的关系。
|
||||
- **突出核心功能**:简要概括每个目录的主要作用和包含的文件类型。
|
||||
- **增加示例或用途说明**:对于关键目录,提供简短的示例或用途描述,帮助开发者快速理解。
|
||||
|
||||
#### 3. 优化后的目录介绍
|
||||
|
||||
##### app/
|
||||
- **核心目录**:存放应用程序的核心代码和资源。
|
||||
- **包含内容**:业务逻辑、控制器、模型、视图等。
|
||||
|
||||
###### app/adminapi/
|
||||
- **功能**:管理端应用控制器。
|
||||
- **用途**:处理管理端用户请求、业务逻辑和数据交互。
|
||||
- **示例**:管理员登录、权限管理等。
|
||||
|
||||
###### app/api/
|
||||
- **功能**:用户端应用控制器。
|
||||
- **用途**:处理用户端请求、业务逻辑和数据交互。
|
||||
- **示例**:用户注册、商品浏览等。
|
||||
|
||||
###### app/dao/
|
||||
- **功能**:数据访问对象(DAO)。
|
||||
- **用途**:封装数据访问操作,提供统一接口。
|
||||
- **文件类型**:类文件。
|
||||
|
||||
###### app/http/
|
||||
- **功能**:HTTP请求和响应跨域中间键。
|
||||
- **用途**:处理跨域请求,确保前后端通信顺畅。
|
||||
|
||||
###### app/jobs/
|
||||
- **功能**:消息队列任务。
|
||||
- **用途**:处理异步任务,如邮件发送、数据同步等。
|
||||
|
||||
###### app/kefuapi/
|
||||
- **功能**:客服端应用控制器。
|
||||
- **用途**:处理客服端请求、业务逻辑和数据交互。
|
||||
- **示例**:客服聊天、工单处理等。
|
||||
|
||||
###### app/lang/
|
||||
- **功能**:语言包。
|
||||
- **用途**:支持多语言功能,提供不同语言的文本资源。
|
||||
|
||||
###### app/listener/
|
||||
- **功能**:事件监听器。
|
||||
- **用途**:监听和处理系统事件,如用户登录、订单生成等。
|
||||
|
||||
###### app/model/
|
||||
- **功能**:模型类。
|
||||
- **用途**:封装数据访问操作,提供统一接口。
|
||||
- **与dao区别**:模型类更侧重于业务逻辑层面的数据操作。
|
||||
|
||||
###### app/outapi/
|
||||
- **功能**:对外接口应用控制器。
|
||||
- **用途**:处理外部系统请求、业务逻辑和数据交互。
|
||||
- **示例**:第三方支付回调、API对接等。
|
||||
|
||||
###### app/service/
|
||||
- **功能**:服务类。
|
||||
- **用途**:封装业务逻辑和数据交互操作,提供统一服务接口。
|
||||
- **示例**:用户服务、订单服务等。
|
||||
|
||||
#### 4. 结语
|
||||
通过上述优化,我们使`app`目录及其子目录的介绍更加清晰、条理分明。每个目录的核心功能和用途都得到了突出展示,有助于开发者快速理解和定位代码。同时,增加的示例和用途说明也进一步降低了理解门槛,提升了开发效率。
|
||||
@ -33,7 +33,8 @@ class Request extends \think\Request
|
||||
* 不过滤变量名
|
||||
* @var array
|
||||
*/
|
||||
protected $except = ['menu_path', 'api_url', 'unique_auth', 'description', 'custom_form', 'content'];
|
||||
protected $except = ['menu_path', 'api_url', 'unique_auth',
|
||||
'description', 'custom_form', 'params_list', 'content', 'tableField', 'url', 'customCode', 'value', 'refund_reason_wap_img'];
|
||||
|
||||
/**
|
||||
* 获取请求的数据
|
||||
@ -48,7 +49,7 @@ class Request extends \think\Request
|
||||
$i = 0;
|
||||
foreach ($params as $param) {
|
||||
if (!is_array($param)) {
|
||||
$p[$suffix == true ? $i++ : $param] = $this->filterWord(is_string($this->param($param)) ? trim($this->param($param)) : $this->param($param), $filter && !in_array($param, $this->except));
|
||||
$p[$suffix == true ? $i++ : $param] = $this->param($param);
|
||||
} else {
|
||||
if (!isset($param[1])) $param[1] = null;
|
||||
if (!isset($param[2])) $param[2] = '';
|
||||
@ -59,41 +60,42 @@ class Request extends \think\Request
|
||||
$name = is_array($param[1]) ? $param[0] . '/a' : $param[0];
|
||||
$keyName = $param[0];
|
||||
}
|
||||
$p[$suffix == true ? $i++ : ($param[3] ?? $keyName)] = $this->filterWord(is_string($this->param($name, $param[1], $param[2])) ? trim($this->param($name, $param[1], $param[2])) : $this->param($name, $param[1], $param[2]), $filter && !in_array($keyName, $this->except));
|
||||
|
||||
$p[$suffix == true ? $i++ : ($param[3] ?? $keyName)] = $this->param($name, $param[1], $param[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($filter && $p) {
|
||||
$p = $this->filterArrayValues($p);
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤接受的参数
|
||||
* 过滤接数组中的字符串
|
||||
* @param $str
|
||||
* @param bool $filter
|
||||
* @return array|mixed|string|string[]
|
||||
*/
|
||||
public function filterWord($str, bool $filter = true)
|
||||
public function filterArrayValues($array)
|
||||
{
|
||||
if (!$str || !$filter) return $str;
|
||||
// 把数据过滤
|
||||
$farr = [
|
||||
"/<(\\/?)(script|i?frame|style|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
|
||||
"/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
|
||||
"/select|join|where|drop|like|modify|rename|insert|update|table|database|alter|truncate|\'|\/\*|\.\.\/|\.\/|union|into|load_file|outfile/is"
|
||||
];
|
||||
if (is_array($str)) {
|
||||
foreach ($str as &$v) {
|
||||
if (is_array($v)) {
|
||||
foreach ($v as &$vv) {
|
||||
if (!is_array($vv)) $vv = preg_replace($farr, '', $vv);
|
||||
}
|
||||
$result = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
// 如果值是数组,并且不在不过滤变量名里面,递归调用 filterArrayValues,否则直接赋值
|
||||
$result[$key] = in_array($key, $this->except) ? $value : $this->filterArrayValues($value);
|
||||
} else {
|
||||
if (in_array($key, $this->except) || is_int($value) || is_null($value)) {
|
||||
$result[$key] = $value;
|
||||
} else {
|
||||
$v = preg_replace($farr, '', $v);
|
||||
// 如果值是字符串,过滤特殊字符
|
||||
$result[$key] = filter_str($value);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
$str = preg_replace($farr, '', $str);
|
||||
}
|
||||
return $str;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,7 +178,7 @@ class Request extends \think\Request
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是app端
|
||||
* 是否是pc端
|
||||
* @return bool
|
||||
*/
|
||||
public function isPc()
|
||||
|
||||
@ -17,6 +17,7 @@ use crmeb\exceptions\ApiException;
|
||||
use crmeb\exceptions\AuthException;
|
||||
use think\db\exception\DbException;
|
||||
use think\exception\Handle;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Env;
|
||||
use think\facade\Log;
|
||||
@ -45,26 +46,30 @@ class AdminApiExceptionHandle extends Handle
|
||||
public function report(Throwable $exception): void
|
||||
{
|
||||
if (!$this->isIgnoreReport($exception)) {
|
||||
$data = [
|
||||
'file' => $exception->getFile(),
|
||||
'line' => $exception->getLine(),
|
||||
'message' => $this->getMessage($exception),
|
||||
'code' => $this->getCode($exception),
|
||||
];
|
||||
try {
|
||||
$data = [
|
||||
'file' => $exception->getFile(),
|
||||
'line' => $exception->getLine(),
|
||||
'message' => $this->getMessage($exception),
|
||||
'code' => $this->getCode($exception),
|
||||
];
|
||||
|
||||
//日志内容
|
||||
$log = [
|
||||
request()->adminId(), //管理员ID
|
||||
request()->ip(), //客户ip
|
||||
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
|
||||
request()->rule()->getMethod(), //请求类型
|
||||
str_replace("/", "", request()->rootUrl()), //应用
|
||||
request()->baseUrl(), //路由
|
||||
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
|
||||
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据
|
||||
//日志内容
|
||||
$log = [
|
||||
request()->adminId(), //管理员ID
|
||||
request()->ip(), //客户ip
|
||||
ceil(msectime() - (request()->time(true) * 1000)), //耗时(毫秒)
|
||||
request()->rule()->getMethod(), //请求类型
|
||||
str_replace("/", "", request()->rootUrl()), //应用
|
||||
request()->baseUrl(), //路由
|
||||
json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
|
||||
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据
|
||||
|
||||
];
|
||||
Log::write(implode("|", $log), "error");
|
||||
];
|
||||
Log::write(implode("|", $log), "error");
|
||||
} catch (\Throwable $e) {
|
||||
Log::write($e->getMessage(), "error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +82,9 @@ class AdminApiExceptionHandle extends Handle
|
||||
*/
|
||||
public function render($request, Throwable $e): Response
|
||||
{
|
||||
if ($e instanceof HttpResponseException) {
|
||||
return parent::render($request, $e);
|
||||
}
|
||||
$massageData = Env::get('app_debug', false) ? [
|
||||
'message' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
@ -84,7 +92,7 @@ class AdminApiExceptionHandle extends Handle
|
||||
'trace' => $e->getTrace(),
|
||||
'previous' => $e->getPrevious(),
|
||||
] : [];
|
||||
$message = Env::get('app_debug', false) ? $e->getMessage() : '很抱歉,系统开小差了';
|
||||
$message = $e->getMessage();
|
||||
// 添加自定义异常处理机制
|
||||
if ($e instanceof AuthException || $e instanceof AdminException || $e instanceof ApiException || $e instanceof ValidateException) {
|
||||
return app('json')->make($e->getCode() ?: 400, $message, $massageData);
|
||||
|
||||
17
crmeb/app/adminapi/README.md
Normal file
17
crmeb/app/adminapi/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
crmeb/app/adminapi这个目录主要是后台管理系统的API接口文件。
|
||||
|
||||
具体来说:
|
||||
|
||||
- adminapi目录下的文件都是后台管理系统的控制器(Controller)文件,这些控制器被用来处理后台系统的各种请求。
|
||||
|
||||
- 每一个控制器文件对应后台管理系统某个功能模块,比如AuthController处理认证模块请求,StoreProduct处理商品模块请求等。
|
||||
|
||||
- 控制器内有各种方法,这些方法就相当于API接口,可以处理GET、POST请求,返回JSON数据。
|
||||
|
||||
- 浏览器或APP在调用这些API接口时,会发送请求到相应的控制器方法,例如登录接口请求到Login文件的login方法。
|
||||
|
||||
- 控制器处理完请求后,通过返回Response对象返回处理结果给浏览器或APP。
|
||||
|
||||
所以简单来说,adminapi目录负责后台管理系统的所有API接口,这些接口被APP或前端调用来完成各种管理操作,如查询数据、添加修改删除等。开发者在新增后台功能时,也需要在此目录增加对应的控制器和接口。
|
||||
|
||||
它实际上负责后台系统的通信交互层,解耦了后端逻辑和前端展示,采用 RESTful规范设计。
|
||||
@ -126,13 +126,21 @@ if (!function_exists('attr_format')) {
|
||||
$result = [];
|
||||
foreach ($temp as $item) {
|
||||
foreach ($arr[$i + 1]['detail'] as $datum) {
|
||||
$result[] = trim($item) . ',' . trim($datum);
|
||||
if (is_array($item)) {
|
||||
$result[] = trim($item['value']) . ',' . trim($datum['value']);
|
||||
} else {
|
||||
$result[] = trim($item) . ',' . trim($datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($arr[0]['detail'] as $item) {
|
||||
$result[] = trim($item);
|
||||
if (is_array($item)) {
|
||||
$result[] = trim($item['value']);
|
||||
} else {
|
||||
$result[] = trim($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
namespace app\adminapi\controller;
|
||||
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use app\services\system\config\SystemConfigTabServices;
|
||||
use app\services\system\SystemAuthServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
@ -20,8 +21,9 @@ use app\services\user\UserExtractServices;
|
||||
use app\services\product\sku\StoreProductAttrValueServices;
|
||||
use app\services\system\SystemMenusServices;
|
||||
use app\services\user\UserServices;
|
||||
use crmeb\services\CacheService;
|
||||
use crmeb\services\HttpService;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* 公共接口基类 主要存放公共接口
|
||||
@ -58,34 +60,6 @@ class Common extends AuthController
|
||||
'version' => $version
|
||||
]);
|
||||
$res = $res ? json_decode($res, true) : [];
|
||||
|
||||
//兼容test.
|
||||
if ($res['data']['status'] !== 1) {
|
||||
$host = str_replace('test.', '', $host);
|
||||
$res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
|
||||
'domain_name' => $host,
|
||||
'label' => 34,
|
||||
'version' => $version
|
||||
]);
|
||||
$res = $res ? json_decode($res, true) : [];
|
||||
}
|
||||
|
||||
//如果是主域名兼容www.
|
||||
if ($res['data']['status'] !== 1) {
|
||||
$host = str_replace('www.', '', $host);
|
||||
$res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
|
||||
'domain_name' => $host,
|
||||
'label' => 34,
|
||||
'version' => $version
|
||||
]);
|
||||
$res = $res ? json_decode($res, true) : [];
|
||||
}
|
||||
|
||||
//升级状态
|
||||
/** @var UpgradeServices $upgradeServices */
|
||||
$upgradeServices = app()->make(UpgradeServices::class);
|
||||
$upgradeStatus = $upgradeServices->getUpgradeStatus();
|
||||
|
||||
$status = $res['data']['status'] ?? -9;
|
||||
switch ((int)$status) {
|
||||
case 1:
|
||||
@ -164,15 +138,26 @@ class Common extends AuthController
|
||||
return app('json')->success(compact('info'));
|
||||
}
|
||||
|
||||
//增长率
|
||||
/**
|
||||
* 计算增长率
|
||||
* 特殊情况:
|
||||
* 1. 当前值和上期值均为0时,返回0;
|
||||
* 2. 上期值为0时,返回当前值;
|
||||
* 3. 当前值为0时,返回上期值的负数。
|
||||
*
|
||||
* @param float $nowValue 当前值
|
||||
* @param float $lastValue 上期值
|
||||
* @return float 增长率
|
||||
*/
|
||||
public function growth($nowValue, $lastValue)
|
||||
{
|
||||
if ($lastValue == 0 && $nowValue == 0) return 0;
|
||||
if ($lastValue == 0) return round($nowValue, 2);
|
||||
if ($nowValue == 0) return -round($lastValue, 2);
|
||||
return bcmul(bcdiv((bcsub($nowValue, $lastValue, 2)), $lastValue, 2), 100, 2);
|
||||
if ($lastValue == 0 && $nowValue == 0) return 0;
|
||||
if ($lastValue == 0) return round($nowValue, 2);
|
||||
if ($nowValue == 0) return -round($lastValue, 2);
|
||||
return bcmul(bcdiv((bcsub($nowValue, $lastValue, 2)), $lastValue, 2), 100, 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单图表
|
||||
*/
|
||||
@ -235,29 +220,29 @@ class Common extends AuthController
|
||||
if ($data['ordernum'] != 0) {
|
||||
$value[] = [
|
||||
'title' => "您有$data[ordernum]个待发货的订单",
|
||||
'type' => 'bulb',
|
||||
'url' => '/admin/order/list?status=1'
|
||||
'type' => 1,
|
||||
'url' => '/' . Config::get('app.admin_prefix', 'admin') . '/order/list?status=1'
|
||||
];
|
||||
}
|
||||
if ($data['inventory'] != 0) {
|
||||
$value[] = [
|
||||
'title' => "您有$data[inventory]个商品库存预警",
|
||||
'type' => 'information',
|
||||
'url' => '/admin/product/product_list?type=5',
|
||||
'type' => 2,
|
||||
'url' => '/' . Config::get('app.admin_prefix', 'admin') . '/product/product_list?type=5',
|
||||
];
|
||||
}
|
||||
if ($data['commentnum'] != 0) {
|
||||
$value[] = [
|
||||
'title' => "您有$data[commentnum]条评论待回复",
|
||||
'type' => 'bulb',
|
||||
'url' => '/admin/product/product_reply?is_reply=0'
|
||||
'type' => 3,
|
||||
'url' => '/' . Config::get('app.admin_prefix', 'admin') . '/product/product_reply?is_reply=0'
|
||||
];
|
||||
}
|
||||
if ($data['reflectnum'] != 0) {
|
||||
$value[] = [
|
||||
'title' => "您有$data[reflectnum]个提现申请待审核",
|
||||
'type' => 'bulb',
|
||||
'url' => '/admin/finance/user_extract/index?status=0',
|
||||
'type' => 4,
|
||||
'url' => '/' . Config::get('app.admin_prefix', 'admin') . '/finance/user_extract/index?status=0',
|
||||
];
|
||||
}
|
||||
return app('json')->success($this->noticeData($value));
|
||||
@ -346,6 +331,7 @@ class Common extends AuthController
|
||||
$pid = $item->getData('pid');
|
||||
$data[$key] = json_decode($item, true);
|
||||
$data[$key]['pid'] = $pid;
|
||||
$data[$key]['menu_path'] = '/' . config('app.admin_prefix', 'admin') . $item['menu_path'];
|
||||
if (in_array($item->id, $counts)) {
|
||||
$data[$key]['type'] = 1;
|
||||
} else {
|
||||
@ -401,8 +387,76 @@ class Common extends AuthController
|
||||
'info' => ''
|
||||
]);
|
||||
}
|
||||
CacheService::clear();
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统搜索菜单
|
||||
* @return \think\Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/2/1
|
||||
*/
|
||||
public function menusSearch()
|
||||
{
|
||||
// 从请求中获取关键字
|
||||
[$keyword] = $this->request->postMore([
|
||||
['keyword', ''],
|
||||
], true);
|
||||
if (empty($keyword)) {
|
||||
return app('json')->fail(400239, '关键字不能为空');
|
||||
}
|
||||
|
||||
// 获取系统菜单服务实例
|
||||
$menusServices = app()->make(SystemMenusServices::class);
|
||||
// 查询菜单列表
|
||||
$menusList = $menusServices->selectList([['menu_name', 'like', '%' . $keyword . '%'], ['auth_type', '=', 1]], 'menu_name as title,menu_path as path,id')->toArray();
|
||||
// 获取系统配置服务实例
|
||||
$configServices = app()->make(SystemConfigServices::class);
|
||||
// 获取系统配置标签服务实例
|
||||
$configTabServices = app()->make(SystemConfigTabServices::class);
|
||||
// 查询配置项列表
|
||||
$configList = $configServices->selectList([['info', 'like', '%' . $keyword . '%']], 'info as title,config_tab_id')->toArray();
|
||||
// 查询配置项标签列表
|
||||
$configTabList = $configTabServices->selectList([['title', 'like', '%' . $keyword . '%']], 'title,id as config_tab_id')->toArray();
|
||||
// 合并配置项列表和配置项标签列表
|
||||
$configAllList = array_merge($configList, $configTabList);
|
||||
// 获取配置项对应的标签ID
|
||||
$tabIds = array_unique(array_column($configAllList, 'config_tab_id'));
|
||||
// 查询配置项标签列表
|
||||
$tabList = $configTabServices->getColumn([['id', 'in', $tabIds]], 'menus_id', 'id');
|
||||
|
||||
// 将配置项标签列表中的菜单ID与配置项列表中的菜单ID对应起来
|
||||
foreach ($configAllList as &$item1) {
|
||||
$item1['menus_id'] = $tabList[$item1['config_tab_id']] ?? 0;
|
||||
}
|
||||
// 获取配置项标签对应的菜单ID
|
||||
$configTabIds = array_values($tabList);
|
||||
// 查询配置项标签对应的菜单列表
|
||||
$configMenusList = $menusServices->getColumn([['id', 'in', $configTabIds]], 'menu_name as title,menu_path as path,id', 'id');
|
||||
|
||||
// 将配置项列表中的菜单ID与配置项标签对应的菜单ID对应起来
|
||||
foreach ($configAllList as $item2) {
|
||||
if ($item2['menus_id'] == 0) {
|
||||
continue;
|
||||
}
|
||||
$menusList[] = [
|
||||
'title' => $configMenusList[$item2['menus_id']]['title'] . '-' . $item2['title'],
|
||||
'path' => $configMenusList[$item2['menus_id']]['path'] . '?tab_id=' . $item2['config_tab_id'],
|
||||
'id' => $configMenusList[$item2['menus_id']]['id']
|
||||
];
|
||||
}
|
||||
// 将菜单列表中的路径前缀添加到每个菜单项的 path 属性上
|
||||
$adminPrefix = '/' . Config::get('app.admin_prefix', 'admin');
|
||||
foreach ($menusList as &$item) {
|
||||
if (strpos($item['path'], '/') !== 0) {
|
||||
$item['path'] = $adminPrefix . '/' . ltrim($item['path'], '/');
|
||||
} else {
|
||||
$item['path'] = $adminPrefix . $item['path'];
|
||||
}
|
||||
}
|
||||
// 返回 JSON 格式的菜单列表
|
||||
return app('json')->success($menusList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,10 +101,14 @@ class Login extends AuthController
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(trim($password)) < 6 || strlen(trim($password)) > 32) {
|
||||
return app('json')->fail(400762);
|
||||
}
|
||||
|
||||
$this->validate(['account' => $account, 'pwd' => $password], \app\adminapi\validate\setting\SystemAdminValidata::class, 'get');
|
||||
$result = $this->services->login($account, $password, 'admin', $key);
|
||||
if (!$result) {
|
||||
$num = CacheService::get('login_captcha',1);
|
||||
$num = CacheService::get('login_captcha', 1);
|
||||
if ($num > 1) {
|
||||
return app('json')->fail(400140, ['login_captcha' => 1]);
|
||||
}
|
||||
|
||||
@ -12,8 +12,13 @@
|
||||
namespace app\adminapi\controller;
|
||||
|
||||
|
||||
use app\Request;
|
||||
use app\services\system\attachment\SystemAttachmentServices;
|
||||
use app\services\system\SystemRouteServices;
|
||||
use crmeb\services\CacheService;
|
||||
use think\facade\Env;
|
||||
use think\Response;
|
||||
use think\facade\Db;
|
||||
|
||||
class PublicController
|
||||
{
|
||||
@ -23,8 +28,13 @@ class PublicController
|
||||
* @param string $key
|
||||
* @return Response|\think\response\File
|
||||
*/
|
||||
public function download(string $key = '')
|
||||
public function download(Request $request, string $key = '')
|
||||
{
|
||||
if ($key == '') {
|
||||
$key = $request->getMore([
|
||||
['key', ''],
|
||||
], true);
|
||||
}
|
||||
if (!$key) {
|
||||
return Response::create()->code(500);
|
||||
}
|
||||
@ -44,4 +54,99 @@ class PublicController
|
||||
{
|
||||
return app('json')->success(getWorkerManUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码上传
|
||||
* @param Request $request
|
||||
* @param int $upload_type
|
||||
* @param int $type
|
||||
* @return Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/06/13
|
||||
*/
|
||||
public function scanUpload(Request $request, $upload_type = 0, $type = 0)
|
||||
{
|
||||
[$file, $uploadToken, $pid] = $request->postMore([
|
||||
['file', 'file'],
|
||||
['uploadToken', ''],
|
||||
['pid', 0]
|
||||
], true);
|
||||
$service = app()->make(SystemAttachmentServices::class);
|
||||
if (CacheService::get('scan_upload') != $uploadToken) {
|
||||
return app('json')->fail(410086);
|
||||
}
|
||||
$service->upload((int)$pid, $file, $upload_type, $type, '', $uploadToken);
|
||||
return app('json')->success(100032);
|
||||
}
|
||||
|
||||
public function import(Request $request)
|
||||
{
|
||||
$filePath = $request->param('file_path', '');
|
||||
if (empty($filePath)) {
|
||||
return app('json')->fail(12894);
|
||||
}
|
||||
app()->make(SystemRouteServices::class)->import($filePath);
|
||||
return app('json')->success(100010);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务器信息
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/9/24
|
||||
*/
|
||||
public function getSystemInfo()
|
||||
{
|
||||
$info['server'] = [
|
||||
['name' => '服务器系统', 'require' => '类UNIX', 'value' => PHP_OS],
|
||||
['name' => 'WEB环境', 'require' => 'Apache/Nginx/IIS', 'value' => $_SERVER['SERVER_SOFTWARE']],
|
||||
];
|
||||
$gd_info = function_exists('gd_info') ? gd_info() : array();
|
||||
$info['environment'] = [
|
||||
['name' => 'PHP版本', 'require' => '7.1-7.4', 'value' => phpversion()],
|
||||
['name' => 'MySql版本', 'require' => '5.6-8.0', 'value' => Db::query("SELECT VERSION()")[0]['VERSION()']],
|
||||
['name' => 'MySqli', 'require' => '开启', 'value' => function_exists('mysqli_connect')],
|
||||
['name' => 'Openssl', 'require' => '开启', 'value' => function_exists('openssl_encrypt')],
|
||||
['name' => 'Session', 'require' => '开启', 'value' => function_exists('session_start')],
|
||||
['name' => 'Safe_Mode', 'require' => '开启', 'value' => !ini_get('safe_mode')],
|
||||
['name' => 'GD', 'require' => '开启', 'value' => !empty($gd_info['GD Version'])],
|
||||
['name' => 'Curl', 'require' => '开启', 'value' => function_exists('curl_init')],
|
||||
['name' => 'Bcmath', 'require' => '开启', 'value' => function_exists('bcadd')],
|
||||
['name' => 'Upload', 'require' => '开启', 'value' => (bool)ini_get('file_uploads')],
|
||||
];
|
||||
|
||||
$info['permissions'] = [
|
||||
['name' => 'backup', 'require' => '读写', 'value' => is_readable(root_path('backup')) && is_writable(root_path('backup'))],
|
||||
['name' => 'public', 'require' => '读写', 'value' => is_readable(root_path('public')) && is_writable(root_path('public'))],
|
||||
['name' => 'runtime', 'require' => '读写', 'value' => is_readable(root_path('runtime')) && is_writable(root_path('runtime'))],
|
||||
['name' => '.env', 'require' => '读写', 'value' => is_readable(root_path() . '.env') && is_writable(root_path() . '.env')],
|
||||
['name' => '.version', 'require' => '读写', 'value' => is_readable(root_path() . '.version') && is_writable(root_path() . '.version')],
|
||||
['name' => '.constant', 'require' => '读写', 'value' => is_readable(root_path() . '.constant') && is_writable(root_path() . '.constant')],
|
||||
];
|
||||
if (function_exists('exec')) {
|
||||
$workermanOutput = $timerOutput = $queueOutput = [];
|
||||
exec("ps aux | grep 'php think workerman' | grep -v grep", $workermanOutput);
|
||||
exec("ps aux | grep 'php think timer' | grep -v grep", $timerOutput);
|
||||
exec("ps aux | grep 'php think queue' | grep -v grep", $queueOutput);
|
||||
$info['process'] = [
|
||||
['name' => '长链接', 'require' => '开启', 'value' => count($workermanOutput) > 0],
|
||||
['name' => '定时任务', 'require' => '开启', 'value' => count($timerOutput) > 0],
|
||||
['name' => '消息队列', 'require' => '开启', 'value' => count($queueOutput) > 0],
|
||||
];
|
||||
} else {
|
||||
$info['process'] = [
|
||||
['name' => '长链接', 'require' => '开启', 'value' => file_exists(root_path('runtime') . 'workerman.pid')],
|
||||
['name' => '定时任务', 'require' => '开启', 'value' => file_exists(root_path('runtime') . '.timer')],
|
||||
['name' => '消息队列', 'require' => '开启', 'value' => file_exists(root_path('runtime') . '.queue')],
|
||||
];
|
||||
}
|
||||
return app('json')->success($info);
|
||||
}
|
||||
|
||||
public function customAdminJs()
|
||||
{
|
||||
return sys_config('custom_admin_js', '');
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -69,13 +69,13 @@ class AgentLevel extends AuthController
|
||||
['name', ''],
|
||||
['grade', 0],
|
||||
['image', ''],
|
||||
['one_brokerage', 0],
|
||||
['two_brokerage', 0],
|
||||
['one_brokerage_percent', 0],
|
||||
['two_brokerage_percent', 0],
|
||||
['status', 0]]);
|
||||
if (!$data['name']) return app('json')->fail(400200);
|
||||
if (!$data['grade']) return app('json')->fail(400201);
|
||||
if (!$data['image']) return app('json')->fail(400202);
|
||||
if ($data['two_brokerage'] > $data['one_brokerage']) {
|
||||
if ($data['two_brokerage_percent'] > $data['one_brokerage_percent']) {
|
||||
return app('json')->fail(400203);
|
||||
}
|
||||
$grade = $this->services->get(['grade' => $data['grade'], 'is_del' => 0]);
|
||||
@ -121,13 +121,13 @@ class AgentLevel extends AuthController
|
||||
['name', ''],
|
||||
['grade', 0],
|
||||
['image', ''],
|
||||
['one_brokerage', 0],
|
||||
['two_brokerage', 0],
|
||||
['one_brokerage_percent', 0],
|
||||
['two_brokerage_percent', 0],
|
||||
['status', 0]]);
|
||||
if (!$data['name']) return app('json')->fail(400200);
|
||||
if (!$data['grade']) return app('json')->fail(400201);
|
||||
if (!$data['image']) return app('json')->fail(400202);
|
||||
if ($data['two_brokerage'] > $data['one_brokerage']) {
|
||||
if ($data['two_brokerage_percent'] > $data['one_brokerage_percent']) {
|
||||
return app('json')->fail(400203);
|
||||
}
|
||||
if (!$levelInfo = $this->services->getLevelInfo((int)$id)) return app('json')->fail(400206);
|
||||
@ -139,8 +139,8 @@ class AgentLevel extends AuthController
|
||||
$levelInfo->name = $data['name'];
|
||||
$levelInfo->grade = $data['grade'];
|
||||
$levelInfo->image = $data['image'];
|
||||
$levelInfo->one_brokerage = $data['one_brokerage'];
|
||||
$levelInfo->two_brokerage = $data['two_brokerage'];
|
||||
$levelInfo->one_brokerage_percent = $data['one_brokerage_percent'];
|
||||
$levelInfo->two_brokerage_percent = $data['two_brokerage_percent'];
|
||||
$levelInfo->status = $data['status'];
|
||||
$levelInfo->save();
|
||||
return app('json')->success(100001);
|
||||
@ -184,4 +184,35 @@ class AgentLevel extends AuthController
|
||||
$this->services->update($id, ['status' => $status]);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务表单数量
|
||||
* @param int $id 任务ID
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTaskNumForm($id)
|
||||
{
|
||||
// 判断任务ID是否为0,若为0则返回错误信息
|
||||
if ($id == 0) return app('json')->fail(100100);
|
||||
// 调用服务层获取任务表单数量
|
||||
$result = $this->services->getTaskNumForm($id);
|
||||
// 返回成功信息和任务表单数量
|
||||
return app('json')->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务数量
|
||||
* @param int $id 任务ID
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function setTaskNum($id)
|
||||
{
|
||||
// 从请求中获取任务数量
|
||||
$data = $this->request->postMore([
|
||||
['task_num', 0]
|
||||
]);
|
||||
// 调用服务层设置任务数量
|
||||
$res = $this->services->setTaskNum($id, $data);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
namespace app\adminapi\controller\v1\agent;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\agent\AgentLevelServices;
|
||||
use app\services\agent\AgentLevelTaskServices;
|
||||
use think\facade\App;
|
||||
|
||||
@ -93,6 +94,10 @@ class AgentLevelTask extends AuthController
|
||||
$this->services->checkTypeTask(0, $data);
|
||||
$data['add_time'] = time();
|
||||
$this->services->save($data);
|
||||
$levelInfo = app()->make(AgentLevelServices::class)->get((int)$data['level_id']);
|
||||
$levelInfo->task_num = $levelInfo->task_num + 1;
|
||||
$levelInfo->task_total_num = $levelInfo->task_total_num + 1;
|
||||
$levelInfo->save();
|
||||
return app('json')->success(400210);
|
||||
}
|
||||
|
||||
@ -162,8 +167,15 @@ class AgentLevelTask extends AuthController
|
||||
$levelTaskInfo = $this->services->getLevelTaskInfo((int)$id);
|
||||
if ($levelTaskInfo) {
|
||||
$res = $this->services->update($id, ['is_del' => 1]);
|
||||
if (!$res)
|
||||
if ($res) {
|
||||
$levelInfo = app()->make(AgentLevelServices::class)->get((int)$levelTaskInfo['level_id']);
|
||||
$levelInfo->task_num = $levelInfo->task_num - 1;
|
||||
$levelInfo->task_total_num = $levelInfo->task_total_num - 1;
|
||||
if ($levelInfo->task_num <= 0) $levelInfo->task_num = $levelInfo->task_total_num;
|
||||
$levelInfo->save();
|
||||
} else {
|
||||
return app('json')->fail(100008);
|
||||
}
|
||||
}
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ class AgentManage extends AuthController
|
||||
public function get_badge()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', ''],
|
||||
['data', '', '', 'time'],
|
||||
['nickname', ''],
|
||||
]);
|
||||
return app('json')->success(['res' => $this->services->getSpreadBadge($where)]);
|
||||
@ -228,7 +228,7 @@ class AgentManage extends AuthController
|
||||
$userInfo->spread_time = time();
|
||||
$userInfo->division_id = $spreadInfo->division_id;
|
||||
$userInfo->agent_id = $spreadInfo->agent_id;
|
||||
$userInfo->is_staff = $spreadInfo->is_staff;
|
||||
$userInfo->staff_id = $spreadInfo->staff_id;
|
||||
$userInfo->save();
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
@ -99,8 +99,9 @@ class Division extends AuthController
|
||||
['account', ''],
|
||||
['pwd', ''],
|
||||
['conf_pwd', ''],
|
||||
['real_name', ''],
|
||||
['roles', []]
|
||||
['division_name', ''],
|
||||
['roles', []],
|
||||
['image', []]
|
||||
]);
|
||||
$this->services->divisionSave($data);
|
||||
return app('json')->success(100000);
|
||||
@ -121,19 +122,32 @@ class Division extends AuthController
|
||||
* 保存代理商
|
||||
* @param UserServices $userServices
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function divisionAgentSave(UserServices $userServices)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['division_id', 0],
|
||||
['uid', 0],
|
||||
['division_percent', 0],
|
||||
['division_end_time', ''],
|
||||
['division_status', 1],
|
||||
['division_name', ''],
|
||||
['edit', 0],
|
||||
['image', []],
|
||||
]);
|
||||
$userInfo = $userServices->get((int)$data['uid']);
|
||||
if ((int)$data['uid'] == 0) $data['uid'] = $data['image']['uid'];
|
||||
$userInfo = $userServices->getUserInfo($data['uid'], 'is_division,is_agent,is_staff');
|
||||
if (!$userInfo) throw new AdminException(100100);
|
||||
$data['division_id'] = $this->adminInfo['division_id'];
|
||||
if ($data['edit'] == 0) {
|
||||
if ($userInfo['is_division']) throw new AdminException('此用户是事业部,请勿添加为代理商');
|
||||
if ($userInfo['is_agent']) throw new AdminException('此用户是代理商,无法重复添加');
|
||||
if ($userInfo['is_staff']) throw new AdminException('此用户是下级员工,无法添加为代理商');
|
||||
$divisionUserInfo = $userServices->count(['uid' => (int)$data['division_id'], 'is_division' => 1, 'division_id' => $data['division_id']]);
|
||||
if (!$divisionUserInfo) throw new AdminException(100100);
|
||||
}
|
||||
$this->services->divisionAgentSave($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
@ -236,4 +250,63 @@ class Division extends AuthController
|
||||
$applyServices->delApply($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加员工表单
|
||||
* @param $uid
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/1/22
|
||||
*/
|
||||
public function divisionStaffCreate($uid)
|
||||
{
|
||||
return app('json')->success($this->services->getDivisionStaffForm((int)$uid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存员工
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/1/22
|
||||
*/
|
||||
public function divisionStaffSave()
|
||||
{
|
||||
$data = $this->request->getMore([
|
||||
['uid', 0],
|
||||
['division_percent', 0],
|
||||
['agent_id', 0],
|
||||
['image', []],
|
||||
]);
|
||||
$this->services->divisionStaffSave($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分销统计
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2025/4/8
|
||||
*/
|
||||
public function divisionStatistics()
|
||||
{
|
||||
[$type, $time, $page, $limit, $sort, $order] = $this->request->getMore([
|
||||
['type', 0],
|
||||
['time', ''],
|
||||
['page', 1],
|
||||
['limit', 15],
|
||||
['sort', 'order_sum'],
|
||||
['order', 'desc'],
|
||||
], true);
|
||||
$time = $time != '' ? explode('-', $time) : [];
|
||||
$data = $this->services->divisionStatistics($type, $time, $page, $limit, $sort, $order);
|
||||
return app('json')->success($data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
40
crmeb/app/adminapi/controller/v1/agent/SpreadApply.php
Normal file
40
crmeb/app/adminapi/controller/v1/agent/SpreadApply.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\agent;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\agent\SpreadApplyServices;
|
||||
use think\facade\App;
|
||||
|
||||
class SpreadApply extends AuthController
|
||||
{
|
||||
public function __construct(App $app, SpreadApplyServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function applyList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['status', ''],
|
||||
['keyword', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->applyList($where));
|
||||
}
|
||||
|
||||
public function applyExamine($id, $uid, $status)
|
||||
{
|
||||
[$refusal_reason] = $this->request->postMore([
|
||||
['refusal_reason', ''],
|
||||
], true);
|
||||
$this->services->applyExamine($id, $uid, $status, $refusal_reason);
|
||||
return app('json')->success($status == 1 ? '审核通过' : '拒绝成功');
|
||||
}
|
||||
|
||||
public function applyDelete($id)
|
||||
{
|
||||
$this->services->applyDelete($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\application\routine;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\wechat\RoutineSchemeServices;
|
||||
use think\facade\App;
|
||||
|
||||
class RoutineScheme extends AuthController
|
||||
{
|
||||
public function __construct(App $app, RoutineSchemeServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function schemeList()
|
||||
{
|
||||
$where = $this->request->postMore([
|
||||
['title', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->schemeList($where));
|
||||
}
|
||||
|
||||
public function schemeForm($id)
|
||||
{
|
||||
return app('json')->success($this->services->schemeForm($id));
|
||||
}
|
||||
|
||||
public function schemeSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['title', ''],
|
||||
['path', ''],
|
||||
['expire_type', -1],
|
||||
['expire_num', 0],
|
||||
]);
|
||||
$this->services->schemeSave($id, $data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
public function schemeDel($id)
|
||||
{
|
||||
$res = $this->services->delete($id);
|
||||
if (!$res) return app('json')->fail(100008);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
@ -11,8 +11,8 @@
|
||||
namespace app\adminapi\controller\v1\application\routine;
|
||||
|
||||
use app\jobs\notice\SyncMessageJob;
|
||||
use app\services\message\SystemNotificationServices;
|
||||
use app\services\other\QrcodeServices;
|
||||
use app\services\message\TemplateMessageServices;
|
||||
use app\services\system\attachment\SystemAttachmentServices;
|
||||
use crmeb\exceptions\AdminException;
|
||||
use think\exception\ValidateException;
|
||||
@ -34,9 +34,9 @@ class RoutineTemplate extends AuthController
|
||||
* 构造方法
|
||||
* WechatTemplate constructor.
|
||||
* @param App $app
|
||||
* @param TemplateMessageServices $services
|
||||
* @param SystemNotificationServices $services
|
||||
*/
|
||||
public function __construct(App $app, TemplateMessageServices $services)
|
||||
public function __construct(App $app, SystemNotificationServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
@ -54,16 +54,17 @@ class RoutineTemplate extends AuthController
|
||||
if (!sys_config('routine_appId') || !sys_config('routine_appsecret')) {
|
||||
throw new AdminException(400236);
|
||||
}
|
||||
$all = $this->services->getTemplateList(['status' => 1, 'type' => 0]);
|
||||
|
||||
$list = MiniProgramService::getSubscribeTemplateList();
|
||||
foreach ($list->data as $v) {
|
||||
MiniProgramService::delSubscribeTemplate($v['priTmplId']);
|
||||
}
|
||||
if ($all['list']) {
|
||||
foreach ($all['list'] as $template) {
|
||||
SyncMessageJob::dispatch('SyncSubscribe', [$template]);
|
||||
}
|
||||
|
||||
$tempKeys = $this->services->getTempKey('routine');
|
||||
foreach ($tempKeys as $key => $content) {
|
||||
SyncMessageJob::dispatch('SyncSubscribe', [$key, $content]);
|
||||
}
|
||||
|
||||
return app('json')->success(100038);
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@ class Menus extends AuthController
|
||||
public function save()
|
||||
{
|
||||
$buttons = request()->post('button/a', []);
|
||||
if(strlen($buttons[0]['name']) > 15) return app('json')->fail('菜单名称不能大于5个字');
|
||||
if (!count($buttons)) return app('json')->fail(400238);
|
||||
$this->services->saveMenu($buttons);
|
||||
return app('json')->success(100001);
|
||||
|
||||
@ -63,6 +63,7 @@ class Reply extends AuthController
|
||||
['key', ''],
|
||||
['type', ''],
|
||||
]);
|
||||
$where['key_type'] = 0;
|
||||
$list = $this->services->getKeyAll($where);
|
||||
return app('json')->success($list);
|
||||
}
|
||||
|
||||
@ -179,9 +179,15 @@ class WechatNewsCategory extends AuthController
|
||||
$errorLog[] = $v['nickname'] . '没有关注发送失败(不是微信公众号用户)';
|
||||
}
|
||||
}
|
||||
} else return app('json')->fail(100031);
|
||||
if (!count($errorLog)) return app('json')->success(100030);
|
||||
else return app('json')->success(100030);
|
||||
if (!count($errorLog)) {
|
||||
return app('json')->success(100030);
|
||||
} else {
|
||||
return app('json')->fail(100031);
|
||||
}
|
||||
} else {
|
||||
return app('json')->fail(100031);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ namespace app\adminapi\controller\v1\application\wechat;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\jobs\notice\SyncMessageJob;
|
||||
use app\services\message\SystemNotificationServices;
|
||||
use crmeb\exceptions\AdminException;
|
||||
use app\services\message\TemplateMessageServices;
|
||||
use crmeb\services\app\WechatService;
|
||||
use think\facade\App;
|
||||
|
||||
@ -28,9 +28,9 @@ class WechatTemplate extends AuthController
|
||||
* 构造方法
|
||||
* WechatTemplate constructor.
|
||||
* @param App $app
|
||||
* @param TemplateMessageServices $services
|
||||
* @param SystemNotificationServices $services
|
||||
*/
|
||||
public function __construct(App $app, TemplateMessageServices $services)
|
||||
public function __construct(App $app, SystemNotificationServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
@ -48,13 +48,16 @@ class WechatTemplate extends AuthController
|
||||
if (!sys_config('wechat_appid') || !sys_config('wechat_appsecret')) {
|
||||
throw new AdminException(400248);
|
||||
}
|
||||
$all = $this->services->getTemplateList(['status' => 1, 'type' => 1]);
|
||||
$list = WechatService::getPrivateTemplates();
|
||||
foreach ($list->template_list as $v) {
|
||||
WechatService::deleleTemplate($v['template_id']);
|
||||
|
||||
$tempIds = $this->services->getTempId('wechat');
|
||||
foreach ($tempIds as $v) {
|
||||
WechatService::deleleTemplate($v);
|
||||
}
|
||||
foreach ($all['list'] as $template) {
|
||||
SyncMessageJob::dispatch('SyncWechat', [$template]);
|
||||
|
||||
$tempKeys = $this->services->getTempKey('wechat');
|
||||
|
||||
foreach ($tempKeys as $key => $content) {
|
||||
SyncMessageJob::dispatch('SyncWechat', [$key, $content['wechat_content']]);
|
||||
}
|
||||
return app('json')->success(100038);
|
||||
}
|
||||
|
||||
@ -40,6 +40,10 @@ class Article extends AuthController
|
||||
/**
|
||||
* 获取列表
|
||||
* @return mixed
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
@ -81,6 +85,10 @@ class Article extends AuthController
|
||||
* 获取单个文章数据
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function read($id = 0)
|
||||
{
|
||||
|
||||
@ -87,6 +87,7 @@ class ArticleCategory extends AuthController
|
||||
$data['add_time'] = time();
|
||||
$this->service->save($data);
|
||||
CacheService::delete('ARTICLE_CATEGORY');
|
||||
CacheService::delete('ARTICLE_CATEGORY_PC');
|
||||
return app('json')->success(100021);
|
||||
}
|
||||
|
||||
@ -121,6 +122,7 @@ class ArticleCategory extends AuthController
|
||||
]);
|
||||
$this->service->update($data);
|
||||
CacheService::delete('ARTICLE_CATEGORY');
|
||||
CacheService::delete('ARTICLE_CATEGORY_PC');
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
@ -135,6 +137,7 @@ class ArticleCategory extends AuthController
|
||||
if (!$id) return app('json')->fail(100100);
|
||||
$this->service->del($id);
|
||||
CacheService::delete('ARTICLE_CATEGORY');
|
||||
CacheService::delete('ARTICLE_CATEGORY_PC');
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
@ -150,6 +153,7 @@ class ArticleCategory extends AuthController
|
||||
if ($status == '' || $id == 0) return app('json')->fail(100100);
|
||||
$this->service->setStatus($id, $status);
|
||||
CacheService::delete('ARTICLE_CATEGORY');
|
||||
CacheService::delete('ARTICLE_CATEGORY_PC');
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
@ -165,6 +169,7 @@ class ArticleCategory extends AuthController
|
||||
/**
|
||||
* 树形列表
|
||||
* @return mixed
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function getTreeList()
|
||||
{
|
||||
|
||||
@ -347,6 +347,27 @@ class Diy extends AuthController
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 推荐商品展示
|
||||
* @param $type
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/3/11
|
||||
*/
|
||||
public function getGroomList($type)
|
||||
{
|
||||
[$page, $limit] = $this->request->getMore([
|
||||
['page', 1],
|
||||
['limit', 6],
|
||||
], true);
|
||||
$list = $this->get_groom_list($type, $limit);
|
||||
return app('json')->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取uni-app路径
|
||||
* @return mixed
|
||||
@ -355,9 +376,13 @@ class Diy extends AuthController
|
||||
{
|
||||
$url = sys_data('uni_app_link');
|
||||
if ($url) {
|
||||
foreach ($url as &$link) {
|
||||
$model_checkbox = sys_config('model_checkbox', ['seckill', 'bargain', 'combination']);
|
||||
foreach ($url as $key => &$link) {
|
||||
$link['url'] = $link['link'];
|
||||
$link['parameter'] = trim($link['param']);
|
||||
if (!in_array('seckill', $model_checkbox) && strpos($link['name'], '秒杀') !== false) unset($url[$key]);
|
||||
if (!in_array('bargain', $model_checkbox) && strpos($link['name'], '砍价') !== false) unset($url[$key]);
|
||||
if (!in_array('combination', $model_checkbox) && strpos($link['name'], '拼团') !== false) unset($url[$key]);
|
||||
}
|
||||
} else {
|
||||
/** @var CacheServices $cache */
|
||||
@ -585,6 +610,8 @@ class Diy extends AuthController
|
||||
['status', 0],
|
||||
['order_status', 0],
|
||||
['my_banner_status', 0],
|
||||
['my_menus_status', 0],
|
||||
['business_status', 0],
|
||||
['routine_my_banner', []],
|
||||
['routine_my_menus', []]
|
||||
]);
|
||||
|
||||
151
crmeb/app/adminapi/controller/v1/diy/DiyPro.php
Normal file
151
crmeb/app/adminapi/controller/v1/diy/DiyPro.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\diy;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\diy\DiyProServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use think\facade\App;
|
||||
|
||||
class DiyPro extends AuthController
|
||||
{
|
||||
public function __construct(App $app, DiyProServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function getList()
|
||||
{
|
||||
return app('json')->success($this->services->getList());
|
||||
}
|
||||
|
||||
public function getInfo($id = 0)
|
||||
{
|
||||
if ($id == 0) return app('json')->fail('参数错误');
|
||||
return app('json')->success($this->services->getInfo($id));
|
||||
}
|
||||
|
||||
public function saveInfo($id = 0)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['name', ''],
|
||||
['title', ''],
|
||||
['value', ''],
|
||||
['type', 1],
|
||||
['cover_image', ''],
|
||||
['is_show', 0],
|
||||
['is_bg_color', 0],
|
||||
['is_bg_pic', 0],
|
||||
['bg_tab_val', 0],
|
||||
['color_picker', ''],
|
||||
['bg_pic', ''],
|
||||
['is_diy', 1],
|
||||
['is_pro', 1],
|
||||
['type', 2],
|
||||
]);
|
||||
$value = is_string($data['value']) ? json_decode($data['value'], true) : $data['value'];
|
||||
foreach ($value as &$item) {
|
||||
if ($item['name'] === 'goodList') {
|
||||
if (isset($item['selectConfig']['list'])) {
|
||||
unset($item['selectConfig']['list']);
|
||||
}
|
||||
if (isset($item['goodsList']['list']) && is_array($item['goodsList']['list'])) {
|
||||
$limitMax = config('database.page.limitMax', 50);
|
||||
if (isset($item['numConfig']['val']) && isset($item['tabConfig']['tabVal']) && $item['tabConfig']['tabVal'] == 0 && $item['numConfig']['val'] > $limitMax) {
|
||||
return app('json')->fail('您设置得商品个数超出系统限制,最大限制' . $limitMax . '个商品');
|
||||
}
|
||||
$item['goodsList']['ids'] = array_column($item['goodsList']['list'], 'id');
|
||||
unset($item['goodsList']['list'], $item['productList']['list']);
|
||||
}
|
||||
} elseif ($item['name'] === 'articleList') {
|
||||
if (isset($item['selectList']['list']) && is_array($item['selectList']['list'])) {
|
||||
unset($item['selectList']['list']);
|
||||
}
|
||||
} elseif ($item['name'] === 'promotionList') {
|
||||
if (isset($item['tabConfig']['list']) && $item['tabConfig']['list']) {
|
||||
$list = $item['tabConfig']['list'];
|
||||
foreach ($list as &$tabValue) {
|
||||
if (isset($tabValue['goodsList']['list']) && is_array($tabValue['goodsList']['list'])) {
|
||||
$limitMax = config('database.page.limitMax', 50);
|
||||
if (isset($tabValue['numConfig']['val']) && isset($tabValue['tabConfig']['tabVal']) && $tabValue['tabConfig']['tabVal'] == 0 && $tabValue['numConfig']['val'] > $limitMax) {
|
||||
return app('json')->fail('您设置得商品个数超出系统限制,最大限制' . $limitMax . '个商品');
|
||||
}
|
||||
$tabValue['goodsList']['ids'] = array_column($tabValue['goodsList']['list'], 'id');
|
||||
}
|
||||
unset($tabValue['goodsList']['list'], $tabValue['productList']['list']);
|
||||
}
|
||||
$item['tabConfig']['list'] = $list;
|
||||
}
|
||||
} elseif ($item['name'] === 'newVip') {
|
||||
unset($item['newVipList']['list']);
|
||||
} elseif ($item['name'] === 'shortVideo') {
|
||||
unset($item['videoList']);
|
||||
}
|
||||
}
|
||||
$data['value'] = json_encode($value);
|
||||
$data['version'] = uniqid();
|
||||
return app('json')->success($id ? '修改成功' : '保存成功', ['id' => $this->services->saveInfo($id, $data)]);
|
||||
}
|
||||
|
||||
public function delInfo($id)
|
||||
{
|
||||
$this->services->delInfo($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function setInfoStatus($id)
|
||||
{
|
||||
return app('json')->success($this->services->setInfoStatus($id));
|
||||
}
|
||||
|
||||
public function getProduct()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['cate_id', []],//搜索分类
|
||||
['salesOrder', ''],//销量排序
|
||||
['priceOrder', ''],//价格排序
|
||||
['store_label_id', []],//标签ID
|
||||
['ids', []],//商品ID
|
||||
]);
|
||||
$where['is_show'] = 1;
|
||||
$where['is_del'] = 0;
|
||||
[$page, $limit] = $this->services->getPageValue();
|
||||
$list = app()->make(StoreProductServices::class)->getSearchList($where, $page, $limit, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price']);
|
||||
return app('json')->success($list);
|
||||
}
|
||||
|
||||
public function updateName($id = 0)
|
||||
{
|
||||
[$name] = $this->request->postMore([
|
||||
['name', '']
|
||||
], true);
|
||||
if (!$name) return app('json')->fail('请输入名称');
|
||||
$this->services->updateName($id, $name);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
public function exportDIYData($id)
|
||||
{
|
||||
$value = $this->services->exportDIYData($id);
|
||||
$filename = 'DIY数据_' . date('YmdHis', time()) . '.txt';
|
||||
return app('json')->success('导出成功', ['value' => $value, 'filename' => $filename]);
|
||||
}
|
||||
|
||||
public function importDIYData()
|
||||
{
|
||||
// 获取文件
|
||||
$file = $this->request->file('file');
|
||||
if (!$file) return app('json')->fail('请上传文件');
|
||||
|
||||
// 获取文件的临时路径
|
||||
$tempPath = $file->getRealPath();
|
||||
|
||||
// 使用文件流读取内容
|
||||
$content = file_get_contents($tempPath);
|
||||
|
||||
// 保存内容
|
||||
$this->services->importDIYData($content);
|
||||
return app('json')->success('导入成功');
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@
|
||||
namespace app\adminapi\controller\v1\diy;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\diy\DiyProServices;
|
||||
use app\services\diy\DiyServices;
|
||||
use app\services\diy\PageCategoryServices;
|
||||
use app\services\diy\PageLinkServices;
|
||||
@ -112,4 +113,77 @@ class PageLink extends AuthController
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
public function getLinkCategory()
|
||||
{
|
||||
return app('json')->success(app()->make(PageCategoryServices::class)->getSonCategoryList(1));
|
||||
}
|
||||
|
||||
public function getLinkCategoryForm($cate_id, $pid)
|
||||
{
|
||||
return app('json')->success(app()->make(PageCategoryServices::class)->getLinkCategoryForm($cate_id, $pid));
|
||||
}
|
||||
|
||||
public function getLinkCategorySave($cate_id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['pid', 0],
|
||||
['name', ''],
|
||||
['type', ''],
|
||||
['sort', 0],
|
||||
['status', ''],
|
||||
]);
|
||||
$res = app()->make(PageCategoryServices::class)->getLinkCategorySave($cate_id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function getLinkCategoryDel($cate_id)
|
||||
{
|
||||
$res = app()->make(PageCategoryServices::class)->getLinkCategoryDel($cate_id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function getLinkList($cate_id, PageCategoryServices $pageCategoryServices)
|
||||
{
|
||||
if (!$cate_id) return app('json')->fail('参数错误');
|
||||
$category = $pageCategoryServices->get((int)$cate_id);
|
||||
if (!$category) {
|
||||
return app('json')->fail(400103);
|
||||
}
|
||||
switch ($category['type']) {
|
||||
case 'special':
|
||||
/** @var DiyProServices $diyServices */
|
||||
$diyProServices = app()->make(DiyProServices::class);
|
||||
$data = $diyProServices->getList('link');
|
||||
break;
|
||||
case 'product_category':
|
||||
/** @var StoreCategoryServices $storeCategoryServices */
|
||||
$storeCategoryServices = app()->make(StoreCategoryServices::class);
|
||||
$data = $storeCategoryServices->getList(['cate_name' => '', 'pid' => '', 'is_show' => '']);
|
||||
break;
|
||||
default:
|
||||
$data = $this->services->getLinkList(['cate_id' => $cate_id]);
|
||||
break;
|
||||
}
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
public function getLinkSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['cate_id', 0],
|
||||
['name', ''],
|
||||
['url', ''],
|
||||
['sort', 0],
|
||||
['status', 1],
|
||||
]);
|
||||
$this->services->getLinkSave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function getLinkDel($id)
|
||||
{
|
||||
$this->services->del($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -72,7 +72,8 @@ class ExportExcel extends AuthController
|
||||
['label_id', ''],
|
||||
['now_money', 'normal'],
|
||||
['field_key', ''],
|
||||
['isMember', '']
|
||||
['isMember', ''],
|
||||
['ids', []]
|
||||
]);
|
||||
return app('json')->success($this->service->exportUserList($where));
|
||||
}
|
||||
@ -95,12 +96,25 @@ class ExportExcel extends AuthController
|
||||
['pay_type', ''],
|
||||
['order', ''],
|
||||
['field_key', ''],
|
||||
['ids', []],
|
||||
]);
|
||||
$where['is_system_del'] = 0;
|
||||
$where['pid'] = 0;
|
||||
return app('json')->success($this->service->exportOrderList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发货订单列表导出
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function orderDeliveryList()
|
||||
{
|
||||
return app('json')->success($this->service->exportOrderDeliveryList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品列表导出
|
||||
* @return mixed
|
||||
@ -110,7 +124,8 @@ class ExportExcel extends AuthController
|
||||
$where = $this->request->getMore([
|
||||
['store_name', ''],
|
||||
['cate_id', ''],
|
||||
['type', 1]
|
||||
['type', 1],
|
||||
['ids', []]
|
||||
]);
|
||||
return app('json')->success($this->service->exportProductList($where));
|
||||
}
|
||||
@ -206,6 +221,7 @@ class ExportExcel extends AuthController
|
||||
['price_max', ''],
|
||||
['price_min', ''],
|
||||
['excel', '1'],
|
||||
['time', ''],
|
||||
]);
|
||||
$data = $services->getCommissionList($where, false);
|
||||
return app('json')->success($this->service->userCommission($data['list'] ?? []));
|
||||
|
||||
@ -12,6 +12,7 @@ namespace app\adminapi\controller\v1\file;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\attachment\SystemAttachmentServices;
|
||||
use crmeb\services\CacheService;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
@ -43,7 +44,9 @@ class SystemAttachment extends AuthController
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['pid', 0]
|
||||
['pid', 0],
|
||||
['real_name', ''],
|
||||
['type', 0],
|
||||
]);
|
||||
return app('json')->success($this->service->getImageList($where));
|
||||
}
|
||||
@ -135,4 +138,89 @@ class SystemAttachment extends AuthController
|
||||
$res = $this->service->videoUpload($data, $_FILES['file']);
|
||||
return app('json')->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫码上传页面链接以及参数
|
||||
* @return \think\Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/06/13
|
||||
*/
|
||||
public function scanUploadQrcode()
|
||||
{
|
||||
[$pid] = $this->request->getMore([
|
||||
['pid', 0]
|
||||
], true);
|
||||
$uploadToken = md5(time());
|
||||
CacheService::set('scan_upload', $uploadToken, 600);
|
||||
$url = sys_config('site_url') . '/app/upload?pid=' . $pid . '&token=' . $uploadToken;
|
||||
return app('json')->success(['url' => $url]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除二维码
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/6/26
|
||||
*/
|
||||
public function removeUploadQrcode()
|
||||
{
|
||||
CacheService::delete('scan_upload');
|
||||
return app('json')->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫码上传的图片数据
|
||||
* @param $scan_token
|
||||
* @return \think\Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/06/13
|
||||
*/
|
||||
public function scanUploadImage($scan_token)
|
||||
{
|
||||
return app('json')->success($this->service->scanUploadImage($scan_token));
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络图片上传
|
||||
* @return \think\Response
|
||||
* @throws \Exception
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/06/13
|
||||
*/
|
||||
public function onlineUpload()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['pid', 0],
|
||||
['images', []]
|
||||
]);
|
||||
$this->service->onlineUpload($data);
|
||||
return app('json')->success(100032);
|
||||
}
|
||||
|
||||
public function videoDataSave()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['pid', 0],
|
||||
['video_name', ''],
|
||||
['video_path', '']
|
||||
]);
|
||||
$this->service->attachmentAdd(
|
||||
$data['video_name'],
|
||||
0,
|
||||
'video/mp4',
|
||||
$data['video_path'],
|
||||
$data['video_path'],
|
||||
$data['pid'],
|
||||
(int)sys_config('upload_type', 1),
|
||||
time(),
|
||||
1,
|
||||
1,
|
||||
$data['video_name']
|
||||
);;
|
||||
return app('json')->success(100032);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,15 +38,21 @@ class SystemAttachmentCategory extends AuthController
|
||||
|
||||
/**
|
||||
* 显示资源列表
|
||||
* @return mixed
|
||||
* @return \think\Response
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name', ''],
|
||||
['pid', 0]
|
||||
['pid', 0],
|
||||
['all', 0],
|
||||
['type', 0],
|
||||
]);
|
||||
if ($where['name'] != '') $where['pid'] = '';
|
||||
if ($where['name'] != '' || $where['all'] == 1) $where['pid'] = '';
|
||||
return app('json')->success($this->service->getAll($where));
|
||||
}
|
||||
|
||||
@ -55,9 +61,13 @@ class SystemAttachmentCategory extends AuthController
|
||||
* @return mixed
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
*/
|
||||
public function create($id)
|
||||
public function create()
|
||||
{
|
||||
return app('json')->success($this->service->createForm($id));
|
||||
[$id, $type] = $this->request->getMore([
|
||||
['id', 0],
|
||||
['type', 0],
|
||||
], true);
|
||||
return app('json')->success($this->service->createForm($id, $type));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,8 +78,10 @@ class SystemAttachmentCategory extends AuthController
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['pid', 0],
|
||||
['name', '']
|
||||
['name', ''],
|
||||
['type', 0],
|
||||
]);
|
||||
if (is_array($data['pid'])) $data['pid'] = end($data['pid']);
|
||||
if (!$data['name']) {
|
||||
return app('json')->fail(400100);
|
||||
}
|
||||
@ -99,9 +111,13 @@ class SystemAttachmentCategory extends AuthController
|
||||
['pid', 0],
|
||||
['name', '']
|
||||
]);
|
||||
if (is_array($data['pid'])) $data['pid'] = end($data['pid']);
|
||||
if (!$data['name']) {
|
||||
return app('json')->fail(400100);
|
||||
}
|
||||
if ($data['pid'] == $id) {
|
||||
return app('json')->fail('上级分类不能是自己');
|
||||
}
|
||||
$info = $this->service->get($id);
|
||||
$count = $this->service->count(['pid' => $id]);
|
||||
if ($count && $info['pid'] != $data['pid']) return app('json')->fail(400105);
|
||||
|
||||
@ -135,6 +135,15 @@ class UserExtract extends AuthController
|
||||
public function adopt($id)
|
||||
{
|
||||
if (!$id) app('json')->fail(100100);
|
||||
return app('json')->success($this->services->adopt((int)$id) ? 100014 : 100015);
|
||||
$res = $this->services->adopt((int)$id);
|
||||
if ($res) {
|
||||
if ($res === 'v3_extract') {
|
||||
return app('json')->success('提现成功,等待用户确认收款');
|
||||
} else {
|
||||
return app('json')->success('提现成功');
|
||||
}
|
||||
} else {
|
||||
return app('json')->success('操作失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,7 +43,8 @@ class Express extends AuthController
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['keyword', '']
|
||||
['keyword', ''],
|
||||
['is_show', '']
|
||||
]);
|
||||
return app('json')->success($this->services->getExpressList($where));
|
||||
}
|
||||
@ -102,12 +103,6 @@ class Express extends AuthController
|
||||
['sort', 0],
|
||||
['is_show', 0]]);
|
||||
if (!$expressInfo = $this->services->get($id)) return app('json')->fail(100026);
|
||||
if ($expressInfo['partner_id'] == 1 && !$data['account']) {
|
||||
return app('json')->fail(400402);
|
||||
}
|
||||
if ($expressInfo['partner_key'] == 1 && !$data['key']) {
|
||||
return app('json')->fail(400403);
|
||||
}
|
||||
if ($expressInfo['net'] == 1 && !$data['net_name']) {
|
||||
return app('json')->fail(400404);
|
||||
}
|
||||
|
||||
@ -62,7 +62,11 @@ class StoreService extends AuthController
|
||||
['data', '', '', 'time'],
|
||||
['type', '', '', 'user_type'],
|
||||
]);
|
||||
[$list, $count] = $services->getWhereUserList($where, 'u.nickname,u.uid,u.avatar as headimgurl,w.subscribe,w.province,w.country,w.city,w.sex,u.user_type,u.is_del');
|
||||
$where['is_del'] = 0;
|
||||
[$list, $count] = $services->getWhereUserList($where, 'u.nickname,u.uid,u.avatar as headimgurl,w.subscribe,w.province,w.country,w.city,w.sex,u.user_type,u.is_del,u.phone,u.add_time');
|
||||
foreach ($list as &$item) {
|
||||
$item['add_time'] = date('Y-m-d', $item['add_time']);
|
||||
}
|
||||
return app('json')->success(compact('list', 'count'));
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/8/3
|
||||
*/
|
||||
|
||||
namespace app\adminapi\controller\v1\kefu;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\wechat\WechatReplyServices;
|
||||
|
||||
class StoreServiceAutoReply extends AuthController
|
||||
{
|
||||
/**
|
||||
* @return \think\Response
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/8/3
|
||||
*/
|
||||
public function autoReplyList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['key', ''],
|
||||
['type', ''],
|
||||
]);
|
||||
$where['key_type'] = 1;
|
||||
$list = app()->make(WechatReplyServices::class)->getKeyAll($where);
|
||||
return app('json')->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自动回复表单
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/8/3
|
||||
*/
|
||||
public function autoReplyForm($id = 0)
|
||||
{
|
||||
return app('json')->success(app()->make(WechatReplyServices::class)->autoReplyForm($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存自动回复
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/8/3
|
||||
*/
|
||||
public function autoReplySave($id = 0)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['keys', ''],
|
||||
['type', ''],
|
||||
['data', ''],
|
||||
['status', 1],
|
||||
]);
|
||||
app()->make(WechatReplyServices::class)->autoReplySave($id, $data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除自动回复
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/8/3
|
||||
*/
|
||||
public function autoReplyDel($id)
|
||||
{
|
||||
app()->make(WechatReplyServices::class)->autoReplyDel($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
117
crmeb/app/adminapi/controller/v1/marketing/SignRewards.php
Normal file
117
crmeb/app/adminapi/controller/v1/marketing/SignRewards.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
|
||||
namespace app\adminapi\controller\v1\marketing;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemSignRewardServices;
|
||||
use think\facade\App;
|
||||
|
||||
class SignRewards extends AuthController
|
||||
{
|
||||
/**
|
||||
* @param App $app
|
||||
* @param SystemSignRewardServices $services
|
||||
*/
|
||||
public function __construct(App $app, SystemSignRewardServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 签到奖励列表
|
||||
* @return \think\Response
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
[$type] = $this->request->getMore([
|
||||
['type', 0]
|
||||
], true);
|
||||
$data = $this->services->getList($type);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增签到奖励
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
public function addRewards()
|
||||
{
|
||||
[$type] = $this->request->getMore([
|
||||
['type', 0]
|
||||
], true);
|
||||
$data = $this->services->rewardsForm(0, $type);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改签到奖励
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
public function editRewards($id)
|
||||
{
|
||||
$data = $this->services->rewardsForm($id);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存签到奖励
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
public function saveRewards($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['type', 0],
|
||||
['days', 0],
|
||||
['point', 0],
|
||||
['exp', 0]
|
||||
]);
|
||||
$this->services->saveRewards($id, $data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除签到奖励
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/7/31
|
||||
*/
|
||||
public function delRewards($id)
|
||||
{
|
||||
$this->services->delete($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
@ -47,6 +47,7 @@ class StoreBargain extends AuthController
|
||||
['start_status', ''],
|
||||
['status', ''],
|
||||
['store_name', ''],
|
||||
['product_id', 0],
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
$list = $this->services->getStoreBargainList($where);
|
||||
@ -65,6 +66,7 @@ class StoreBargain extends AuthController
|
||||
['info', ''],
|
||||
['unit_name', ''],
|
||||
['section_time', []],
|
||||
['image', ''],
|
||||
['images', []],
|
||||
['bargain_max_price', 0],
|
||||
['bargain_min_price', 0],
|
||||
@ -87,6 +89,7 @@ class StoreBargain extends AuthController
|
||||
['postage', 0],//邮费
|
||||
['custom_form', ''],
|
||||
['virtual_type', 0],
|
||||
['is_commission', 0],
|
||||
]);
|
||||
$this->validate($data, \app\adminapi\validate\marketing\StoreBargainValidate::class, 'save');
|
||||
if ($data['section_time']) {
|
||||
@ -151,9 +154,16 @@ class StoreBargain extends AuthController
|
||||
{
|
||||
/** @var StoreBargainUserServices $bargainUserService */
|
||||
$bargainUserService = app()->make(StoreBargainUserServices::class);
|
||||
$bargainUserService->userBargainStatusFail($id, false);
|
||||
if ($status == 0) {
|
||||
$bargainUserService->userBargainStatusFail($id, false);
|
||||
} else {
|
||||
$info = $this->services->get($id);
|
||||
if ($info['stop_time'] < time()) {
|
||||
return app('json')->fail('活动已结束,无法继续上架');
|
||||
}
|
||||
}
|
||||
$this->services->update($id, ['status' => $status]);
|
||||
return app('json')->success($status == 0 ? 100001 : 100007);
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +191,7 @@ class StoreBargain extends AuthController
|
||||
{
|
||||
/** @var StoreBargainUserHelpServices $bargainUserHelpService */
|
||||
$bargainUserHelpService = app()->make(StoreBargainUserHelpServices::class);
|
||||
$list = $bargainUserHelpService->getHelpList($id);
|
||||
$list = $bargainUserHelpService->getHelpList((int)$id);
|
||||
return app('json')->success(compact('list'));
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,8 @@ class StoreCombination extends AuthController
|
||||
$where = $this->request->getMore([
|
||||
['start_status', ''],
|
||||
['is_show', ''],
|
||||
['store_name', '']
|
||||
['store_name', ''],
|
||||
['product_id', 0]
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
$list = $this->services->systemPage($where);
|
||||
@ -86,6 +87,7 @@ class StoreCombination extends AuthController
|
||||
[['title', 's'], ''],
|
||||
[['info', 's'], ''],
|
||||
[['unit_name', 's'], ''],
|
||||
['image', ''],
|
||||
['images', []],
|
||||
['section_time', []],
|
||||
[['is_host', 'd'], 0],
|
||||
@ -160,8 +162,14 @@ class StoreCombination extends AuthController
|
||||
*/
|
||||
public function set_status($id, $status)
|
||||
{
|
||||
if ($status == 1) {
|
||||
$info = $this->services->get($id);
|
||||
if ($info['stop_time'] < time()) {
|
||||
return app('json')->fail('活动已结束,无法继续上架');
|
||||
}
|
||||
}
|
||||
$this->services->update($id, ['is_show' => $status]);
|
||||
return app('json')->success($status == 0 ? 100014 : 100015);
|
||||
return app('json')->success('设置成功');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,7 +190,11 @@ class StoreCombination extends AuthController
|
||||
|
||||
/**
|
||||
* 拼团人列表
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function order_pink($id)
|
||||
{
|
||||
@ -207,12 +219,20 @@ class StoreCombination extends AuthController
|
||||
* 活动参与人
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function combinationStatisticsList($id)
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['real_name', '', '', 'keyword'],
|
||||
['status', '']
|
||||
]);
|
||||
$where['cid'] = $id;
|
||||
/** @var StorePinkServices $storePinkServices */
|
||||
$storePinkServices = app()->make(StorePinkServices::class);
|
||||
$list = $storePinkServices->systemPage(['cid' => $id]);
|
||||
$list = $storePinkServices->systemPage($where);
|
||||
return app('json')->success($list);
|
||||
}
|
||||
|
||||
@ -229,4 +249,23 @@ class StoreCombination extends AuthController
|
||||
]);
|
||||
return app('json')->success($this->services->combinationStatisticsOrder($id, $where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即成团
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2025/6/18
|
||||
*/
|
||||
public function immediatelyCombination($id)
|
||||
{
|
||||
/** @var StorePinkServices $storePinkServices */
|
||||
$storePinkServices = app()->make(StorePinkServices::class);
|
||||
$storePinkServices->virtualCombination($id, 'admin');
|
||||
return app('json')->success('成团成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +41,9 @@ class StoreCouponIssue extends AuthController
|
||||
$where = $this->request->getMore([
|
||||
['status', 1],
|
||||
['coupon_title', ''],
|
||||
['receive_type', ''],
|
||||
['receive_type', '', '', 'receive_types'],
|
||||
['type', ''],
|
||||
['coupon_type', ''],
|
||||
]);
|
||||
$list = $this->services->getCouponIssueList($where);
|
||||
return app('json')->success($list);
|
||||
@ -55,6 +56,7 @@ class StoreCouponIssue extends AuthController
|
||||
public function saveCoupon()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['id', 0],
|
||||
['coupon_title', ''],
|
||||
['coupon_price', 0.00],
|
||||
['use_min_price', 0.00],
|
||||
@ -72,6 +74,7 @@ class StoreCouponIssue extends AuthController
|
||||
['sort', 0],
|
||||
['status', 0],
|
||||
['receive_limit', 1],
|
||||
['user_type', 1],
|
||||
]);
|
||||
$res = $this->services->saveCoupon($data);
|
||||
if ($res) return app('json')->success(100000);
|
||||
@ -99,6 +102,13 @@ class StoreCouponIssue extends AuthController
|
||||
if (!$id) return app('json')->fail(100100);
|
||||
$info = $this->services->get($id);
|
||||
if ($info) $info = $info->toArray();
|
||||
if ($info['receive_type'] == 1 || $info['receive_type'] == 3) {
|
||||
$info['user_type'] = 1;
|
||||
}
|
||||
if ($info['receive_type'] == 4) {
|
||||
$info['user_type'] = 2;
|
||||
$info['receive_type'] = 1;
|
||||
}
|
||||
if ($info['product_id'] != '') {
|
||||
$productIds = explode(',', $info['product_id']);
|
||||
/** @var StoreProductServices $product */
|
||||
|
||||
@ -12,6 +12,7 @@ namespace app\adminapi\controller\v1\marketing;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\activity\seckill\StoreSeckillServices;
|
||||
use app\services\activity\StoreActivityServices;
|
||||
use app\services\product\sku\StoreProductAttrValueServices;
|
||||
use crmeb\services\CacheService;
|
||||
use think\facade\App;
|
||||
@ -41,7 +42,11 @@ class StoreSeckill extends AuthController
|
||||
$where = $this->request->getMore([
|
||||
['start_status', ''],
|
||||
[['status', 's'], ''],
|
||||
[['store_name', 's'], '']
|
||||
[['store_name', 's'], ''],
|
||||
[['product_id', 'd'], 0],
|
||||
['activity_name', ''],
|
||||
['time', ''],
|
||||
['time_ids', []],
|
||||
]);
|
||||
return app('json')->success($this->services->systemPage($where));
|
||||
}
|
||||
@ -75,7 +80,7 @@ class StoreSeckill extends AuthController
|
||||
[['status', 'd'], 0],
|
||||
[['num', 'd'], 0],
|
||||
[['once_num', 'd'], 0],
|
||||
[['time_id', 'd'], 0],
|
||||
['time_id', []],
|
||||
[['temp_id', 'd'], 0],
|
||||
[['sort', 'd'], 0],
|
||||
[['description', 's'], ''],
|
||||
@ -87,6 +92,7 @@ class StoreSeckill extends AuthController
|
||||
['postage', 0],//邮费
|
||||
['custom_form', ''],
|
||||
['virtual_type', 0],
|
||||
['is_commission', 0],
|
||||
]);
|
||||
$this->validate($data, \app\adminapi\validate\marketing\StoreSeckillValidate::class, 'save');
|
||||
$this->services->saveData($id, $data);
|
||||
@ -106,10 +112,7 @@ class StoreSeckill extends AuthController
|
||||
$storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
|
||||
$unique = $storeProductAttrValueServices->value(['product_id' => $id, 'type' => 1], 'unique');
|
||||
if ($unique) {
|
||||
$name = 'seckill_' . $unique . '_1';
|
||||
/** @var CacheService $cache */
|
||||
$cache = app()->make(CacheService::class);
|
||||
$cache->del($name);
|
||||
CacheService::delete('seckill_' . $unique . '_1');
|
||||
}
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
@ -122,6 +125,12 @@ class StoreSeckill extends AuthController
|
||||
*/
|
||||
public function set_status($id, $status)
|
||||
{
|
||||
if ($status == 1) {
|
||||
$info = $this->services->get($id);
|
||||
if ($info['stop_time'] < time()) {
|
||||
return app('json')->fail('活动已结束,无法继续上架');
|
||||
}
|
||||
}
|
||||
$this->services->update($id, ['status' => $status]);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
@ -133,12 +142,21 @@ class StoreSeckill extends AuthController
|
||||
public function time_list()
|
||||
{
|
||||
$list['data'] = sys_data('routine_seckill_time');
|
||||
foreach ($list['data'] as &$item) {
|
||||
$startTime = sprintf("%02d:00", $item['time']);
|
||||
$endTime = sprintf("%02d:00", $item['time'] + $item['continued']);
|
||||
$item['time_name'] = $startTime . '-' . $endTime;
|
||||
}
|
||||
return app('json')->success(compact('list'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 秒杀统计
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function seckillStatistics($id)
|
||||
{
|
||||
@ -154,7 +172,7 @@ class StoreSeckill extends AuthController
|
||||
public function seckillPeople($id)
|
||||
{
|
||||
[$keyword] = $this->request->getMore([
|
||||
['keyword', '']
|
||||
['real_name', '', '', 'keyword']
|
||||
], true);
|
||||
return app('json')->success($this->services->seckillPeople($id, $keyword));
|
||||
}
|
||||
@ -172,4 +190,50 @@ class StoreSeckill extends AuthController
|
||||
]);
|
||||
return app('json')->success($this->services->seckillOrder($id, $where));
|
||||
}
|
||||
|
||||
public function seckillActivityList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', ''],
|
||||
['status', ''],
|
||||
['title', ''],
|
||||
['time_ids', []]
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
$where['type'] = 1;
|
||||
return app('json')->success(app()->make(StoreActivityServices::class)->activityList($where));
|
||||
}
|
||||
|
||||
public function seckillActivityInfo($id)
|
||||
{
|
||||
return app('json')->success(app()->make(StoreActivityServices::class)->activityInfo($id));
|
||||
}
|
||||
|
||||
public function seckillActivitySave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['title', ''],
|
||||
['section_time', []],
|
||||
['time_ids', []],
|
||||
['num', 0],
|
||||
['once_num', 0],
|
||||
['status', 1],
|
||||
['is_commission', 0],
|
||||
['product_infos', []]
|
||||
]);
|
||||
$this->services->seckillActivitySave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function seckillActivityDel($id)
|
||||
{
|
||||
app()->make(StoreActivityServices::class)->activityDel($id, 1);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function seckillActivityStatus($id, $status)
|
||||
{
|
||||
app()->make(StoreActivityServices::class)->activityStatus($id, $status, 1);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ class StoreIntegralOrder extends AuthController
|
||||
*/
|
||||
public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
|
||||
{
|
||||
return app('json')->success($storeOrderDeliveryServices->orderDump($order_id));
|
||||
return app('json')->success($storeOrderDeliveryServices->orderDump($order_id, 'integral_order'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ class StorePointRecord extends AuthController
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', ''],
|
||||
['trading_type', 0]
|
||||
['trading_type', '']
|
||||
]);
|
||||
$date = $this->services->pointRecord($where);
|
||||
return app('json')->success($date);
|
||||
|
||||
@ -72,9 +72,14 @@ class LiveGoods extends AuthController
|
||||
[$goods_info] = $this->request->postMore([
|
||||
['goods_info', []]
|
||||
], true);
|
||||
$error = false;
|
||||
foreach ($goods_info as $goods) {
|
||||
$this->validate($goods, \app\adminapi\validate\marketing\LiveGoodsValidate::class, 'save');
|
||||
if (!preg_match('/.*(\.png|\.jpg|\.jpeg|\.gif)$/', $goods['image']) && strpos(strtolower($goods['image']), "phar://") !== false) {
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
if ($error) return app('json')->fail(40137);
|
||||
$this->services->add($goods_info);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
@ -78,6 +78,9 @@ class LiveRoom extends AuthController
|
||||
['replay_status', 1],
|
||||
['sort', 0]
|
||||
]);
|
||||
if (mb_strlen($data['name']) < 6 || mb_strlen($data['name']) > 17) {
|
||||
return app('json')->fail(500030);
|
||||
}
|
||||
$this->validate($data, \app\adminapi\validate\marketing\LiveRoomValidate::class, 'save');
|
||||
$this->services->add($data);
|
||||
return app('json')->success(100000);
|
||||
|
||||
@ -41,11 +41,12 @@ class LuckLottery extends AuthController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->postMore([
|
||||
['start_status', '', '', 'start'],
|
||||
['status', ''],
|
||||
$where = $this->request->getMore([
|
||||
['factor', ''],
|
||||
['store_name', '', '', 'keyword'],
|
||||
['start', ''],
|
||||
['status', ''],
|
||||
['time', ''],
|
||||
['keyword', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
@ -63,28 +64,15 @@ class LuckLottery extends AuthController
|
||||
if (!$id) {
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
return app('json')->success($this->services->getlotteryInfo((int)$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取详情
|
||||
* @param $factor
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function factorInfo($factor)
|
||||
{
|
||||
if (!$factor) {
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
return app('json')->success($this->services->getlotteryFactorInfo((int)$factor));
|
||||
return app('json')->success($this->services->getLotteryInfo((int)$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加抽奖
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
@ -219,4 +207,20 @@ class LuckLottery extends AuthController
|
||||
$this->services->setStatus((int)$id, (int)$status);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
public function factorList()
|
||||
{
|
||||
return app('json')->success($this->services->factorList());
|
||||
}
|
||||
|
||||
public function factorUse()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
[['point', 'd'], 0],
|
||||
[['pay', 'd'], 0],
|
||||
[['evaluate', 'd'], 0],
|
||||
]);
|
||||
$this->services->factorUse($data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,12 +42,10 @@ class LuckLotteryRecord extends AuthController
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->postMore([
|
||||
['is_receive', ''],
|
||||
['is_deliver', ''],
|
||||
['type', ''],
|
||||
['keyword', ''],
|
||||
['data', '', '', 'time'],
|
||||
['factor', ''],
|
||||
['time', ''],
|
||||
['lottery_id', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
|
||||
@ -10,10 +10,11 @@
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\adminapi\controller\v1\notification\sms;
|
||||
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use app\services\yihaotong\SmsAdminServices;
|
||||
use app\services\serve\ServeServices;
|
||||
use crmeb\services\CacheService;
|
||||
use app\adminapi\controller\AuthController;
|
||||
use crmeb\services\CacheService;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
@ -64,6 +65,7 @@ class SmsConfig extends AuthController
|
||||
*/
|
||||
public function is_login(ServeServices $services)
|
||||
{
|
||||
$configServices = app()->make(SystemConfigServices::class);
|
||||
$sms_info = CacheService::get('sms_account');
|
||||
$data = ['status' => false, 'info' => ''];
|
||||
if ($sms_info) {
|
||||
@ -103,14 +105,10 @@ class SmsConfig extends AuthController
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
$res = CacheService::delete('sms_account');
|
||||
if ($res) {
|
||||
$this->services->updateSmsConfig('', '');
|
||||
CacheService::clear();
|
||||
return app('json')->success(100042);
|
||||
} else {
|
||||
return app('json')->fail(100043);
|
||||
}
|
||||
CacheService::delete('sms_account');
|
||||
$this->services->updateSmsConfig('', '');
|
||||
CacheService::clear();
|
||||
return app('json')->success(100042);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -57,7 +57,13 @@ class RefundOrder extends AuthController
|
||||
/**
|
||||
* 订单详情
|
||||
* @param $uni
|
||||
* @return mixed
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/03/02
|
||||
*/
|
||||
public function getRefundInfo($uni)
|
||||
{
|
||||
@ -140,7 +146,7 @@ class RefundOrder extends AuthController
|
||||
return app('json')->fail(400144);
|
||||
}
|
||||
|
||||
if ($data['type'] == 1) {
|
||||
if ($data['type'] == 1 || $data['type'] == 5) {
|
||||
$data['refund_type'] = 6;
|
||||
} else if ($data['type'] == 2) {
|
||||
$data['refund_type'] = 3;
|
||||
@ -163,12 +169,12 @@ class RefundOrder extends AuthController
|
||||
return app('json')->fail(400147);
|
||||
}
|
||||
$refund_price = $data['refund_price'];
|
||||
}
|
||||
|
||||
$data['refunded_price'] = bcadd($data['refund_price'], $orderRefund['refunded_price'], 2);
|
||||
$bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
|
||||
if ($bj < 0) {
|
||||
return app('json')->fail(400148);
|
||||
}
|
||||
$data['refunded_price'] = bcadd($data['refund_price'], $orderRefund['refunded_price'], 2);
|
||||
$bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
|
||||
if ($bj < 0) {
|
||||
return app('json')->fail(400148);
|
||||
}
|
||||
|
||||
unset($data['type']);
|
||||
@ -183,7 +189,9 @@ class RefundOrder extends AuthController
|
||||
$wechatUserServices = app()->make(WechatUserServices::class);
|
||||
$refund_data['open_id'] = $wechatUserServices->uidToOpenid((int)$order['uid'], 'routine') ?? '';
|
||||
$refund_data['refund_no'] = $orderRefund['order_id'];
|
||||
$refund_data['order_id'] = $orderRefund['order_id'];
|
||||
//修改订单退款状态
|
||||
// $data['refund_price'] = $data['refunded_price'];
|
||||
unset($data['refund_price']);
|
||||
if ($this->services->agreeRefund($id, $refund_data)) {
|
||||
$this->services->update($id, $data);
|
||||
|
||||
@ -12,7 +12,10 @@ namespace app\adminapi\controller\v1\order;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\adminapi\validate\order\StoreOrderValidate;
|
||||
use app\jobs\OrderExpressJob;
|
||||
use app\services\serve\ServeServices;
|
||||
use app\services\wechat\WechatUserServices;
|
||||
use crmeb\services\FileService;
|
||||
use app\services\order\{StoreOrderCartInfoServices,
|
||||
StoreOrderDeliveryServices,
|
||||
StoreOrderRefundServices,
|
||||
@ -54,7 +57,10 @@ class StoreOrder extends AuthController
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time'],
|
||||
[['type', 'd'], 0],
|
||||
['type', ''],
|
||||
['pay_type', ''],
|
||||
['field_key', 'all'],
|
||||
['real_name', ''],
|
||||
]);
|
||||
$data = $this->services->orderCount($where);
|
||||
return app('json')->success($data);
|
||||
@ -185,6 +191,7 @@ class StoreOrder extends AuthController
|
||||
['status', ''],
|
||||
], true);
|
||||
if ($status != '') $data['status'] = $status;
|
||||
if ($status == 'undefined') $data['status'] = 1;
|
||||
$data['is_show'] = 1;
|
||||
return app('json')->success($services->express($data));
|
||||
}
|
||||
@ -242,7 +249,7 @@ class StoreOrder extends AuthController
|
||||
['delivery_id', ''],//快递单号
|
||||
['delivery_code', ''],//快递公司编码
|
||||
|
||||
['express_record_type', 2],//发货记录类型
|
||||
['express_record_type', 2],//发货记录类型:2=电子面单;3=商家寄件
|
||||
['express_temp_id', ""],//电子面单模板
|
||||
['to_name', ''],//寄件人姓名
|
||||
['to_tel', ''],//寄件人电话
|
||||
@ -252,10 +259,12 @@ class StoreOrder extends AuthController
|
||||
['sh_delivery_id', ''],//送货人电话
|
||||
['sh_delivery_uid', ''],//送货人ID
|
||||
|
||||
['fictitious_content', '']//虚拟发货内容
|
||||
['fictitious_content', ''],//虚拟发货内容
|
||||
|
||||
['day_type', 0], //顺丰传 0今天,1明天,2后台
|
||||
['pickup_time', []],//开始时间 9:00,结束时间 10:00 开始时间和结束时间之间不能小于一个小时
|
||||
]);
|
||||
$services->delivery((int)$id, $data);
|
||||
return app('json')->success(100010);
|
||||
return app('json')->success(100010, $services->delivery((int)$id, $data));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,6 +272,9 @@ class StoreOrder extends AuthController
|
||||
* @param $id
|
||||
* @param StoreOrderDeliveryServices $services
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function split_delivery($id, StoreOrderDeliveryServices $services)
|
||||
{
|
||||
@ -284,7 +296,11 @@ class StoreOrder extends AuthController
|
||||
|
||||
['fictitious_content', ''],//虚拟发货内容
|
||||
|
||||
['cart_ids', []]
|
||||
['cart_ids', []],
|
||||
|
||||
['day_type', 0], //顺丰传 0今天,1明天,2后台
|
||||
['pickup_time', []],//开始时间 9:00,结束时间 10:00 开始时间和结束时间之间不能小于一个小时
|
||||
['service_type', ''],//快递业务类型
|
||||
]);
|
||||
if (!$id) {
|
||||
return app('json')->fail(100100);
|
||||
@ -301,6 +317,58 @@ class StoreOrder extends AuthController
|
||||
return app('json')->success(100010);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取寄件预扣金额
|
||||
* @param ServeServices $services
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/6/16
|
||||
*/
|
||||
public function getPrice(ServeServices $services)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['kuaidicom', ''],
|
||||
['send_address', ''],
|
||||
['orderId', ''],
|
||||
['service_type', ''],
|
||||
['cart_ids', []],
|
||||
]);
|
||||
|
||||
$orderInfo = $this->services->get($data['orderId'], ['user_address', 'cart_id']);
|
||||
if (!$orderInfo) {
|
||||
return app('json')->fail('订单没有查询到');
|
||||
}
|
||||
$weight = '0';
|
||||
if ($data['cart_ids']) {
|
||||
$cartIds = array_column($data['cart_ids'], 'cart_id');
|
||||
$cartList = app()->make(StoreOrderCartInfoServices::class)->getColumn([
|
||||
['cart_id', 'in', $cartIds]
|
||||
], 'cart_info', 'cart_id');
|
||||
foreach ($data['cart_ids'] as $cart) {
|
||||
if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
|
||||
return app('json')->fail(400159);
|
||||
}
|
||||
if (isset($cartList[$cart['cart_id']])) {
|
||||
$value = is_string($cartList[$cart['cart_id']]) ? json_decode($cartList[$cart['cart_id']], true) : $cartList[$cart['cart_id']];
|
||||
$weightnew = bcmul($value['attrInfo']['weight'], (string)$cart['cart_num'], 2);
|
||||
$weight = bcadd($weightnew, $weight, 2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$orderCartInfoList = app()->make(StoreOrderCartInfoServices::class)->getCartInfoPrintProduct($data['orderId']);
|
||||
foreach ($orderCartInfoList as $item) {
|
||||
$weightnew = bcmul($item['attrInfo']['weight'], (string)$item['cart_num'], 2);
|
||||
$weight = bcadd($weightnew, $weight, 2);
|
||||
}
|
||||
}
|
||||
$data['address'] = $orderInfo['user_address'];
|
||||
if ($weight > 0) {
|
||||
$data['weight'] = $weight;
|
||||
}
|
||||
return app('json')->success($services->express()->getPrice($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单可拆分发货商品列表
|
||||
* @param $id
|
||||
@ -317,7 +385,11 @@ class StoreOrder extends AuthController
|
||||
|
||||
/**
|
||||
* 获取订单拆分子订单列表
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function split_order($id)
|
||||
{
|
||||
@ -385,7 +457,7 @@ class StoreOrder extends AuthController
|
||||
if (!$id) {
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
return app('json')->success($services->refundOrderForm((int)$id));
|
||||
return app('json')->success($services->refundOrderForm((int)$id, 'order'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,7 +472,7 @@ class StoreOrder extends AuthController
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['refund_price', 0],
|
||||
['type', 1]
|
||||
['cart_ids', []]
|
||||
]);
|
||||
if (!$id) {
|
||||
return app('json')->fail(100100);
|
||||
@ -409,44 +481,64 @@ class StoreOrder extends AuthController
|
||||
if (!$order) {
|
||||
return app('json')->fail(400118);
|
||||
}
|
||||
|
||||
$refundData = [
|
||||
'refund_reason' => '后台主动退款',
|
||||
'refund_explain' => '后台主动退款',
|
||||
'refund_img' => json_encode([]),
|
||||
];
|
||||
|
||||
$res = $services->applyRefund((int)$id, $order['uid'], $order, $data['cart_ids'], 1, (float)$data['refund_price'], $refundData);
|
||||
|
||||
if (!$res) {
|
||||
return app('json')->fail('退款单生成失败');
|
||||
}
|
||||
|
||||
$orderRefund = $services->getOrderOne(['store_order_id' => $id]);
|
||||
|
||||
|
||||
$data['refund_status'] = 2;
|
||||
$data['refund_type'] = 6;
|
||||
$data['refunded_time'] = time();
|
||||
|
||||
//0元退款
|
||||
if ($order['pay_price'] == 0 && in_array($order['refund_status'], [0, 1])) {
|
||||
if ($orderRefund['refund_price'] == 0 && in_array($orderRefund['refund_type'], [1, 5])) {
|
||||
$refund_price = 0;
|
||||
} else {
|
||||
if ($order['pay_price'] == $order['refund_price']) {
|
||||
return app('json')->fail(400147);
|
||||
}
|
||||
if (!$data['refund_price']) {
|
||||
return app('json')->fail(400146);
|
||||
}
|
||||
$refund_price = $data['refund_price'];
|
||||
$data['refund_price'] = bcadd($data['refund_price'], $order['refund_price'], 2);
|
||||
$bj = bccomp((string)$order['pay_price'], (string)$data['refund_price'], 2);
|
||||
if ($bj < 0) {
|
||||
return app('json')->fail(400148);
|
||||
if ($orderRefund['refund_price'] == $orderRefund['refunded_price']) {
|
||||
return app('json')->fail(400147);
|
||||
}
|
||||
$refund_price = $data['refund_price'];
|
||||
}
|
||||
if ($data['type'] == 1) {
|
||||
$data['refund_status'] = 2;
|
||||
} else if ($data['type'] == 2) {
|
||||
$data['refund_status'] = 0;
|
||||
|
||||
$data['refunded_price'] = bcadd($data['refund_price'], $orderRefund['refunded_price'], 2);
|
||||
$bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
|
||||
if ($bj < 0) {
|
||||
return app('json')->fail(400148);
|
||||
}
|
||||
$data['refund_type'] = 6;
|
||||
$type = $data['type'];
|
||||
unset($data['type']);
|
||||
|
||||
$refund_data['pay_price'] = $order['pay_price'];
|
||||
$refund_data['refund_price'] = $refund_price;
|
||||
if ($order['refund_price'] > 0) {
|
||||
mt_srand();
|
||||
$refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
|
||||
}
|
||||
//退款处理
|
||||
$services->payOrderRefund($type, $order, $refund_data);
|
||||
($order['pid'] > 0) ? $refund_data['order_id'] = $this->services->value(['id' => (int)$order['pid']], 'order_id') : $refund_data['order_id'] = $order['order_id'];
|
||||
/** @var WechatUserServices $wechatUserServices */
|
||||
$wechatUserServices = app()->make(WechatUserServices::class);
|
||||
$refund_data['open_id'] = $wechatUserServices->uidToOpenid((int)$order['uid'], 'routine') ?? '';
|
||||
$refund_data['refund_no'] = $orderRefund['order_id'];
|
||||
$refund_data['order_id'] = $orderRefund['order_id'];
|
||||
//修改订单退款状态
|
||||
if ($this->services->update($id, $data)) {
|
||||
$services->storeProductOrderRefundY($data, $order, $refund_price);
|
||||
unset($data['refund_price']);
|
||||
if ($services->agreeRefund($orderRefund['id'], $refund_data)) {
|
||||
$services->update($orderRefund['id'], $data);
|
||||
return app('json')->success(400149);
|
||||
} else {
|
||||
$services->storeProductOrderRefundYFasle((int)$id, $refund_price);
|
||||
$services->storeProductOrderRefundYFasle((int)$orderRefund['id'], $refund_price);
|
||||
return app('json')->fail(400150);
|
||||
}
|
||||
}
|
||||
@ -455,10 +547,11 @@ class StoreOrder extends AuthController
|
||||
* 订单详情
|
||||
* @param $id 订单id
|
||||
* @return mixed
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function order_info($id)
|
||||
{
|
||||
if (!$id || !($orderInfo = $this->services->get($id))) {
|
||||
if (!$id || !($orderInfo = $this->services->get($id, [], ['refund', 'invoice']))) {
|
||||
return app('json')->fail(400118);
|
||||
}
|
||||
/** @var UserServices $services */
|
||||
@ -497,6 +590,13 @@ class StoreOrder extends AuthController
|
||||
} else
|
||||
$orderInfo['_store_name'] = '';
|
||||
$orderInfo['spread_name'] = $services->value(['uid' => $orderInfo['spread_uid']], 'nickname') ?? '无';
|
||||
$orderInfo['_info'] = app()->make(StoreOrderCartInfoServices::class)->getOrderCartInfo((int)$orderInfo['id']);
|
||||
$cart_num = 0;
|
||||
$refund_num = array_sum(array_column($orderInfo['refund'], 'refund_num'));
|
||||
foreach ($orderInfo['_info'] as $items) {
|
||||
$cart_num += $items['cart_info']['cart_num'];
|
||||
}
|
||||
$orderInfo['is_all_refund'] = $refund_num == $cart_num;
|
||||
$userInfo = $userInfo->toArray();
|
||||
return app('json')->success(compact('orderInfo', 'userInfo'));
|
||||
}
|
||||
@ -551,6 +651,7 @@ class StoreOrder extends AuthController
|
||||
|
||||
/**
|
||||
* 不退款表单结构
|
||||
* @param StoreOrderRefundServices $services
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
@ -591,7 +692,13 @@ class StoreOrder extends AuthController
|
||||
}
|
||||
$services->storeProductOrderRefundNo((int)$id, $refund_reason);
|
||||
//提醒推送
|
||||
event('notice.notice', [['orderInfo' => $orderInfo], 'send_order_refund_no_status']);
|
||||
event('NoticeListener', [['orderInfo' => $orderInfo], 'send_order_refund_no_status']);
|
||||
|
||||
//自定义消息-订单拒绝退款
|
||||
$orderInfo['time'] = date('Y-m-d H:i:s');
|
||||
$orderInfo['phone'] = $orderInfo['user_phone'];
|
||||
event('CustomNoticeListener', [$orderInfo['uid'], $orderInfo, 'order_refund_fail']);
|
||||
|
||||
return app('json')->success(100010);
|
||||
}
|
||||
|
||||
@ -747,8 +854,89 @@ class StoreOrder extends AuthController
|
||||
*/
|
||||
public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
|
||||
{
|
||||
return app('json')->success($storeOrderDeliveryServices->orderDump($order_id));
|
||||
|
||||
$storeOrderDeliveryServices->orderDump($order_id);
|
||||
return app('json')->success(400121);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快递信息
|
||||
* @param ServeServices $services
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/5/15
|
||||
*/
|
||||
public function getKuaidiComs(ServeServices $services)
|
||||
{
|
||||
return app('json')->success($services->express()->getKuaidiComs());
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消商家寄件
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/5/15
|
||||
*/
|
||||
public function shipmentCancelOrder($id)
|
||||
{
|
||||
if (!$id) {
|
||||
return app('json')->fail('缺少参数');
|
||||
}
|
||||
|
||||
$msg = $this->request->post('msg', '');
|
||||
if (!$msg) {
|
||||
return app('json')->fail('请填写取消寄件原因');
|
||||
}
|
||||
if ($this->services->shipmentCancelOrder((int)$id, $msg)) {
|
||||
return app('json')->success('取消成功');
|
||||
} else {
|
||||
return app('json')->fail('取消失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入批量发货
|
||||
* @return \think\Response|void
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
|
||||
*/
|
||||
public function importExpress()
|
||||
{
|
||||
[$file] = $this->request->getMore([
|
||||
['file', '']
|
||||
], true);
|
||||
if (!$file) return app('json')->fail(400168);
|
||||
$file = public_path() . substr($file, 1);
|
||||
// 获取文件后缀
|
||||
$suffix = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
||||
if (!in_array($suffix, ['xls', 'xlsx'])) {
|
||||
return app('json')->fail('文件格式不正确,请上传xls或xlsx格式的文件!');
|
||||
}
|
||||
$expressData = app()->make(FileService::class)->readExcel($file, 'express', 2, ucfirst($suffix));
|
||||
foreach ($expressData as $item) {
|
||||
OrderExpressJob::dispatch([$item]);
|
||||
}
|
||||
return app('json')->success('批量发货成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 配货单
|
||||
* @param $order_id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author: 吴汐
|
||||
* @email: 442384644@qq.com
|
||||
* @date: 2023/10/11
|
||||
*/
|
||||
public function printShipping($order_id)
|
||||
{
|
||||
if (!$order_id) {
|
||||
return app('json')->fail('参数错误');
|
||||
}
|
||||
$data = $this->services->printShippingData($order_id);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,138 +1,309 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\adminapi\controller\v1\order;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\order\StoreOrderInvoiceServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use app\services\system\store\SystemStoreServices;
|
||||
use app\services\user\UserServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* 发票管理
|
||||
* Class StoreOrderInvoice
|
||||
* @package app\adminapi\controller\v1\order
|
||||
*/
|
||||
class StoreOrderInvoice extends AuthController
|
||||
{
|
||||
|
||||
/**
|
||||
* StoreOrderInvoice constructor.
|
||||
* @param App $app
|
||||
* @param StoreOrderInvoiceServices $services
|
||||
*/
|
||||
public function __construct(App $app, StoreOrderInvoiceServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单类型数量
|
||||
* @return mixed
|
||||
*/
|
||||
public function chart()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time'],
|
||||
[['type', 'd'], 0],
|
||||
]);
|
||||
$data = $this->services->chart($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询发票列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function list()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['status', 0],
|
||||
['real_name', ''],
|
||||
['header_type', ''],
|
||||
['type', ''],
|
||||
['data', '', '', 'time'],
|
||||
['field_key', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置发票状态
|
||||
* @param string $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function set_invoice($id = '')
|
||||
{
|
||||
if ($id == '') return app('json')->fail(100100);
|
||||
$data = $this->request->postMore([
|
||||
['is_invoice', 0],
|
||||
['invoice_number', 0],
|
||||
['remark', '']
|
||||
]);
|
||||
if ($data['is_invoice'] == 1 && !$data['invoice_number']) {
|
||||
return app('json')->fail(400166);
|
||||
}
|
||||
if ($data['invoice_number'] && !preg_match('/^\d{8,10}$/', $data['invoice_number'])) {
|
||||
return app('json')->fail(400167);
|
||||
}
|
||||
$this->services->setInvoice((int)$id, $data);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情
|
||||
* @param $id 订单id
|
||||
* @return mixed
|
||||
*/
|
||||
public function orderInfo(StoreProductServices $productServices, StoreOrderServices $orderServices, $id)
|
||||
{
|
||||
if (!$id || !($orderInfo = $orderServices->get($id))) {
|
||||
return app('json')->fail(400118);
|
||||
}
|
||||
/** @var UserServices $services */
|
||||
$services = app()->make(UserServices::class);
|
||||
$userInfo = $services->get($orderInfo['uid']);
|
||||
if (!$userInfo) {
|
||||
return app('json')->fail(400119);
|
||||
}
|
||||
$userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
|
||||
$userInfo['spread_name'] = '';
|
||||
if ($userInfo['spread_uid'])
|
||||
$userInfo['spread_name'] = $services->value(['uid' => $userInfo['spread_uid']], 'nickname');
|
||||
$orderInfo = $orderServices->tidyOrder($orderInfo->toArray(), true, true);
|
||||
//核算优惠金额
|
||||
$vipTruePrice = array_column($orderInfo['cartInfo'], 'vip_sum_truePrice');
|
||||
$vipTruePrice = array_sum($vipTruePrice);
|
||||
$orderInfo['vip_true_price'] = $vipTruePrice ?: 0;
|
||||
|
||||
$orderInfo['add_time'] = $orderInfo['_add_time'] ?? '';
|
||||
$productId = array_column($orderInfo['cartInfo'], 'product_id');
|
||||
$cateData = $productServices->productIdByProductCateName($productId);
|
||||
foreach ($orderInfo['cartInfo'] as &$item) {
|
||||
$item['class_name'] = $cateData[$item['product_id']] ?? '';
|
||||
}
|
||||
if ($orderInfo['store_id'] && $orderInfo['shipping_type'] == 2) {
|
||||
/** @var $storeServices */
|
||||
$storeServices = app()->make(SystemStoreServices::class);
|
||||
$orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
|
||||
} else {
|
||||
$orderInfo['_store_name'] = '';
|
||||
}
|
||||
$userInfo = $userInfo->toArray();
|
||||
$invoice = $this->services->getOne(['order_id' => $id]);
|
||||
return app('json')->success(compact('orderInfo', 'userInfo', 'invoice'));
|
||||
}
|
||||
}
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\adminapi\controller\v1\order;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\order\StoreOrderCartInfoServices;
|
||||
use app\services\order\StoreOrderInvoiceServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use app\services\serve\ServeServices;
|
||||
use app\services\system\store\SystemStoreServices;
|
||||
use app\services\user\UserServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* 发票管理
|
||||
* Class StoreOrderInvoice
|
||||
* @package app\adminapi\controller\v1\order
|
||||
*/
|
||||
class StoreOrderInvoice extends AuthController
|
||||
{
|
||||
|
||||
/**
|
||||
* StoreOrderInvoice constructor.
|
||||
* @param App $app
|
||||
* @param StoreOrderInvoiceServices $services
|
||||
*/
|
||||
public function __construct(App $app, StoreOrderInvoiceServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单类型数量
|
||||
* @return mixed
|
||||
*/
|
||||
public function chart()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time'],
|
||||
['real_name', ''],
|
||||
['field_key', ''],
|
||||
[['type', 'd'], 0],
|
||||
]);
|
||||
$data = $this->services->chart($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询发票列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function list()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['status', 0],
|
||||
['real_name', ''],
|
||||
['header_type', ''],
|
||||
['type', ''],
|
||||
['data', '', '', 'time'],
|
||||
['field_key', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置发票状态
|
||||
* @param string $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function set_invoice($id = '')
|
||||
{
|
||||
if ($id == '') return app('json')->fail(100100);
|
||||
$data = $this->request->postMore([
|
||||
['is_invoice', 0],
|
||||
['invoice_number', 0],
|
||||
['remark', '']
|
||||
]);
|
||||
if ($data['is_invoice'] == 1 && !$data['invoice_number']) {
|
||||
return app('json')->fail(400166);
|
||||
}
|
||||
if ($data['invoice_number'] && !preg_match('/^\d{8,10}$/', $data['invoice_number'])) {
|
||||
return app('json')->fail(400167);
|
||||
}
|
||||
$this->services->setInvoice((int)$id, $data);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单详情
|
||||
* @param $id 订单id
|
||||
* @return mixed
|
||||
*/
|
||||
public function orderInfo(StoreProductServices $productServices, StoreOrderServices $orderServices, $id)
|
||||
{
|
||||
if (!$id || !($orderInfo = $orderServices->get($id))) {
|
||||
return app('json')->fail(400118);
|
||||
}
|
||||
/** @var UserServices $services */
|
||||
$services = app()->make(UserServices::class);
|
||||
$userInfo = $services->get($orderInfo['uid']);
|
||||
if (!$userInfo) {
|
||||
return app('json')->fail(400119);
|
||||
}
|
||||
$userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
|
||||
$userInfo['spread_name'] = '';
|
||||
if ($userInfo['spread_uid'])
|
||||
$userInfo['spread_name'] = $services->value(['uid' => $userInfo['spread_uid']], 'nickname');
|
||||
$orderInfo = $orderServices->tidyOrder($orderInfo->toArray(), true, true);
|
||||
//核算优惠金额
|
||||
$vipTruePrice = array_column($orderInfo['cartInfo'], 'vip_sum_truePrice');
|
||||
$vipTruePrice = array_sum($vipTruePrice);
|
||||
$orderInfo['vip_true_price'] = $vipTruePrice ?: 0;
|
||||
|
||||
$orderInfo['add_time'] = $orderInfo['_add_time'] ?? '';
|
||||
$productId = array_column($orderInfo['cartInfo'], 'product_id');
|
||||
$cateData = $productServices->productIdByProductCateName($productId);
|
||||
foreach ($orderInfo['cartInfo'] as &$item) {
|
||||
$item['class_name'] = $cateData[$item['product_id']] ?? '';
|
||||
}
|
||||
if ($orderInfo['store_id'] && $orderInfo['shipping_type'] == 2) {
|
||||
/** @var $storeServices */
|
||||
$storeServices = app()->make(SystemStoreServices::class);
|
||||
$orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
|
||||
} else {
|
||||
$orderInfo['_store_name'] = '';
|
||||
}
|
||||
$userInfo = $userInfo->toArray();
|
||||
$invoice = $this->services->getOne(['order_id' => $id]);
|
||||
return app('json')->success(compact('orderInfo', 'userInfo', 'invoice'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子发票配置信息
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/16
|
||||
*/
|
||||
public function elecInvoiceConfig()
|
||||
{
|
||||
$data = [
|
||||
'elec_invoice' => (int)sys_config('elec_invoice'),
|
||||
'auto_invoice' => (int)sys_config('auto_invoice'),
|
||||
'elec_invoice_cate' => (int)sys_config('elec_invoice_cate'),
|
||||
'elec_invoice_cate_name' => sys_config('elec_invoice_cate_name'),
|
||||
'elec_invoice_tax_rate' => (int)sys_config('elec_invoice_tax_rate')
|
||||
];
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发票开具页面iframe地址
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \ReflectionException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/13
|
||||
*/
|
||||
public function invoiceIssuanceUrl($id)
|
||||
{
|
||||
if (sys_config('elec_invoice', 1) != 1) {
|
||||
return app('json')->fail('电子发票功能未开启,请在一号通中开启并且在商城后台一号通配置中开启');
|
||||
}
|
||||
$info = $this->services->getOne(['id' => $id]);
|
||||
$unique = app()->make(StoreOrderServices::class)->value(['id' => $info['order_id']], 'order_id');
|
||||
$cartInfo = app()->make(StoreOrderCartInfoServices::class)->getOrderCartInfo($info['order_id']);
|
||||
$goods = [];
|
||||
foreach ($cartInfo as $item) {
|
||||
$goods[] = [
|
||||
'store_name' => $item['cart_info']['productInfo']['store_name'],
|
||||
'unit_price' => bcadd($item['cart_info']['truePrice'], $item['cart_info']['postage_price'], 2),
|
||||
'num' => $item['cart_info']['cart_num']
|
||||
];
|
||||
}
|
||||
$data = [];
|
||||
$data['unique'] = $unique;
|
||||
$data['goods'] = $goods;
|
||||
$data['account_name'] = $info['name'];
|
||||
$data['email'] = $info['email'];
|
||||
if ($info['header_type'] == 1) {
|
||||
$data['invoice_type'] = 82;
|
||||
$data['is_enterprise'] = 0;
|
||||
} else {
|
||||
$data['invoice_type'] = $info['type'] == 1 ? 82 : 81;
|
||||
$data['tax_id'] = $info['duty_number'];
|
||||
$data['is_enterprise'] = 1;
|
||||
}
|
||||
$invoice = app()->make(ServeServices::class)->invoice();
|
||||
return app('json')->success($invoice->invoiceIssuanceUrl($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存发票信息
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/14
|
||||
*/
|
||||
public function saveInvoiceInfo($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['invoice_num', ''],
|
||||
['invoice_type', ''],
|
||||
['invoice_serial_number', ''],
|
||||
]);
|
||||
$info = $this->services->getOne(['id' => $id]);
|
||||
$data['unique_num'] = app()->make(StoreOrderServices::class)->value(['id' => $info['order_id']], 'order_id');
|
||||
$data['is_invoice'] = 1;
|
||||
$data['invoice_time'] = time();
|
||||
$this->services->update($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看发票详情
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/14
|
||||
*/
|
||||
public function invoiceInfo($id)
|
||||
{
|
||||
$info = $this->services->getOne(['id' => $id]);
|
||||
$invoice = app()->make(ServeServices::class)->invoice();
|
||||
return app('json')->success($invoice->invoiceInfo($info['invoice_num']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载发票
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/14
|
||||
*/
|
||||
public function downInvoice($id)
|
||||
{
|
||||
$info = $this->services->getOne(['id' => $id]);
|
||||
$invoice = app()->make(ServeServices::class)->invoice();
|
||||
return app('json')->success($invoice->downloadInvoice($info['invoice_num']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 电子发票分类
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/15
|
||||
*/
|
||||
public function invoiceCategory()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name', ''],
|
||||
['page', 1],
|
||||
['limit', 100],
|
||||
]);
|
||||
$invoice = app()->make(ServeServices::class)->invoice();
|
||||
return app('json')->success($invoice->category($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开具发票
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/15
|
||||
*/
|
||||
public function invoiceIssuance($id)
|
||||
{
|
||||
$this->services->invoiceIssuance($id);
|
||||
return app('json')->success('开票成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 负数发票开具
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/5/16
|
||||
*/
|
||||
public function redInvoiceIssuance($id)
|
||||
{
|
||||
$this->services->redInvoiceIssuance($id);
|
||||
return app('json')->success('开具负数发票成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,11 @@ class StoreCategory extends AuthController
|
||||
|
||||
/**
|
||||
* 商品分类搜索
|
||||
* @param $type
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function tree_list($type)
|
||||
{
|
||||
@ -103,6 +107,9 @@ class StoreCategory extends AuthController
|
||||
/**
|
||||
* 保存新增分类
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
@ -133,6 +140,9 @@ class StoreCategory extends AuthController
|
||||
* 更新分类
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function update($id)
|
||||
{
|
||||
|
||||
@ -12,6 +12,7 @@ namespace app\adminapi\controller\v1\product;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\adminapi\controller\v1\system\SystemClearData;
|
||||
use app\services\order\StoreCartServices;
|
||||
use app\services\other\CacheServices;
|
||||
use app\services\product\product\StoreCategoryServices;
|
||||
@ -19,6 +20,7 @@ use app\services\product\product\StoreProductServices;
|
||||
use crmeb\services\FileService;
|
||||
use app\services\other\UploadService;
|
||||
use think\facade\App;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* Class StoreProduct
|
||||
@ -40,7 +42,17 @@ class StoreProduct extends AuthController
|
||||
*/
|
||||
public function type_header()
|
||||
{
|
||||
$list = $this->service->getHeader();
|
||||
$where = $this->request->getMore([
|
||||
['store_name', ''],
|
||||
['cate_id', ''],
|
||||
['spec_type', ''],
|
||||
['is_gift', ''],
|
||||
['vip_product', ''],
|
||||
['price_s', []],
|
||||
['stock_s', []],
|
||||
['sales_s', []],
|
||||
]);
|
||||
$list = $this->service->getHeader($where);
|
||||
return app('json')->success(compact('list'));
|
||||
}
|
||||
|
||||
@ -122,7 +134,17 @@ class StoreProduct extends AuthController
|
||||
['store_name', ''],
|
||||
['cate_id', ''],
|
||||
['type', 1],
|
||||
['sales', 'normal']
|
||||
['sales', 'normal'],
|
||||
['spec_type', ''],
|
||||
['is_gift', ''],
|
||||
['vip_product', ''],
|
||||
['price_s', []],
|
||||
['stock_s', []],
|
||||
['sales_s', []],
|
||||
['store_label_id', []],
|
||||
['logistics', ''],
|
||||
['time', ''],
|
||||
['virtual_type', ''],
|
||||
]);
|
||||
$data = $this->service->getList($where);
|
||||
return app('json')->success($data);
|
||||
@ -136,6 +158,8 @@ class StoreProduct extends AuthController
|
||||
*/
|
||||
public function set_show($is_show = '', $id = '')
|
||||
{
|
||||
$del = $this->service->value(['id' => $id], 'is_del');
|
||||
if ($del == 1) return app('json')->fail('商品已删除,请先恢复商品');
|
||||
$this->service->setShow([$id], $is_show);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
@ -237,7 +261,13 @@ class StoreProduct extends AuthController
|
||||
['is_copy', 0],//是否是复制商品
|
||||
['is_limit', 0],//是否限购
|
||||
['limit_type', 0],//限购类型
|
||||
['limit_num', 0]//限购数量
|
||||
['limit_num', 0],//限购数量
|
||||
['min_qty', 1],//起购数量
|
||||
['params_list', []],//商品参数
|
||||
['label_list', []],//商品标签
|
||||
['protection_list', []],//商品保障
|
||||
['is_gift', 0],//是否礼品
|
||||
['gift_price', 0],//礼品附加费
|
||||
]);
|
||||
$this->service->save((int)$id, $data);
|
||||
return app('json')->success(100000);
|
||||
@ -260,6 +290,31 @@ class StoreProduct extends AuthController
|
||||
return app('json')->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移动到回收站
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function batchDelete()
|
||||
{
|
||||
[$ids] = $this->request->postMore([
|
||||
['ids', []],
|
||||
], true);
|
||||
return app('json')->success($this->service->batchDelete($ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量从回收站恢复
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function batchRecover()
|
||||
{
|
||||
[$ids] = $this->request->postMore([
|
||||
['ids', []],
|
||||
], true);
|
||||
$this->service->batchRecover($ids);
|
||||
return app('json')->success('恢复成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成规格列表
|
||||
* @param int $id
|
||||
@ -274,7 +329,6 @@ class StoreProduct extends AuthController
|
||||
['is_virtual', 0],
|
||||
['virtual_type', 0]
|
||||
]);
|
||||
if ($id > 0 && $type == 1) $this->service->checkActivity($id);
|
||||
$info = $this->service->getAttr($data, $id, $type);
|
||||
return app('json')->success(compact('info'));
|
||||
}
|
||||
@ -293,10 +347,11 @@ class StoreProduct extends AuthController
|
||||
['is_live', 0],
|
||||
['is_new', ''],
|
||||
['is_virtual', -1],
|
||||
['is_presale', -1]
|
||||
['is_presale', -1],
|
||||
['is_show', 1],
|
||||
]);
|
||||
$where['is_show'] = 1;
|
||||
$where['is_del'] = 0;
|
||||
$where['cate_id'] = toIntArray($where['cate_id']);
|
||||
/** @var StoreCategoryServices $storeCategoryServices */
|
||||
$storeCategoryServices = app()->make(StoreCategoryServices::class);
|
||||
if ($where['cate_id'] !== '') {
|
||||
@ -339,10 +394,21 @@ class StoreProduct extends AuthController
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTempKeys()
|
||||
public function getTempKeys(Request $request)
|
||||
{
|
||||
$upload = UploadService::init();
|
||||
$re = $upload->getTempKeys();
|
||||
$type = (int)sys_config('upload_type', 1);
|
||||
$key = $request->get('key', '');
|
||||
$path = $request->get('path', '');
|
||||
$contentType = $request->get('contentType', '');
|
||||
if ($type === 5) {
|
||||
if (!$key || !$contentType) {
|
||||
return app('json')->fail('缺少参数');
|
||||
}
|
||||
$re = $upload->getTempKeys($key, $path, $contentType);
|
||||
} else {
|
||||
$re = $upload->getTempKeys();
|
||||
}
|
||||
return $re ? app('json')->success($re) : app('json')->fail(100016);
|
||||
}
|
||||
|
||||
@ -371,9 +437,14 @@ class StoreProduct extends AuthController
|
||||
]);
|
||||
if (!$data['file']) return app('json')->fail(400168);
|
||||
$file = public_path() . substr($data['file'], 1);
|
||||
// 获取文件后缀
|
||||
$suffix = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
||||
if (!in_array($suffix, ['xls', 'xlsx'])) {
|
||||
return app('json')->fail('文件格式不正确,请上传xls或xlsx格式的文件!');
|
||||
}
|
||||
/** @var FileService $readExcelService */
|
||||
$readExcelService = app()->make(FileService::class);
|
||||
$cardData = $readExcelService->readExcel($file);
|
||||
$cardData = $readExcelService->readExcel($file, 'card', 1, ucfirst($suffix));
|
||||
return app('json')->success($cardData);
|
||||
}
|
||||
|
||||
@ -393,10 +464,98 @@ class StoreProduct extends AuthController
|
||||
['give_integral', 0],
|
||||
['coupon_ids', []],
|
||||
['label_id', []],
|
||||
['label_list', []],
|
||||
['recommend', []],
|
||||
['type', 0]
|
||||
['type', 0],
|
||||
['is_gift', 0],
|
||||
['gift_price', 0],
|
||||
]);
|
||||
$this->service->batchSetting($data);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品类型接口
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/9/29
|
||||
*/
|
||||
public function productTypeConfig()
|
||||
{
|
||||
$productTypeConfig = sys_config('product_type_config');
|
||||
foreach ($productTypeConfig as $key => $value) {
|
||||
$productTypeConfig[$key] = intval($value);
|
||||
}
|
||||
return app('json')->success(sys_config('product_type_config'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品迁移导出
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/10/9
|
||||
*/
|
||||
public function productExport()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['store_name', ''],
|
||||
['cate_id', ''],
|
||||
['type', 1],
|
||||
['sales', 'normal']
|
||||
]);
|
||||
$where['virtual_type'] = 0;
|
||||
return app('json')->success($this->service->productExportList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品迁移导入
|
||||
* @return \think\Response
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/10/9
|
||||
*/
|
||||
public function productImport()
|
||||
{
|
||||
[$file] = $this->request->getMore([
|
||||
['file', ""]
|
||||
], true);
|
||||
if (!$file) return app('json')->fail(400168);
|
||||
$res = $this->service->productImport($file);
|
||||
return app('json')->success('导入成功', $res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收站商品彻底删除
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/10/9
|
||||
*/
|
||||
public function fullDel($id)
|
||||
{
|
||||
app()->make(SystemClearData::class)->recycleProduct($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function otherInfo($id, $type)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
return app('json')->success($this->service->otherInfo($id, $type));
|
||||
}
|
||||
|
||||
public function otherSave($id, $type)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['is_sub', 0],
|
||||
['is_vip', 0],
|
||||
['vip_product', 0],
|
||||
['attr_value', []],
|
||||
]);
|
||||
$this->service->otherSave($id, $type, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
}
|
||||
|
||||
112
crmeb/app/adminapi/controller/v1/product/StoreProductLabel.php
Normal file
112
crmeb/app/adminapi/controller/v1/product/StoreProductLabel.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\product;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\product\product\StoreProductLabelCateServices;
|
||||
use app\services\product\product\StoreProductLabelServices;
|
||||
use think\facade\App;
|
||||
|
||||
class StoreProductLabel extends AuthController
|
||||
{
|
||||
protected $labelCateServices;
|
||||
protected $labelServices;
|
||||
|
||||
public function __construct(App $app, StoreProductLabelCateServices $labelCateServices, StoreProductLabelServices $labelServices)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->labelCateServices = $labelCateServices;
|
||||
$this->labelServices = $labelServices;
|
||||
}
|
||||
|
||||
public function labelCateList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name', ''],
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
return app('json')->success($this->labelCateServices->getLabelCateList($where));
|
||||
}
|
||||
|
||||
public function labelCateForm($id)
|
||||
{
|
||||
return app('json')->success($this->labelCateServices->labelCateForm($id));
|
||||
}
|
||||
|
||||
public function labelCateSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['name', ''],
|
||||
['sort', 0],
|
||||
]);
|
||||
$this->labelCateServices->labelCateSave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function labelCateDel($id)
|
||||
{
|
||||
$this->labelCateServices->labelCateDel($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
|
||||
public function labelList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name', ''],
|
||||
['cate_id', ''],
|
||||
['status', ''],
|
||||
['is_show', ''],
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
return app('json')->success($this->labelServices->LabelList($where));
|
||||
}
|
||||
|
||||
public function labelInfo($id)
|
||||
{
|
||||
return app('json')->success($this->labelServices->labelInfo($id));
|
||||
|
||||
}
|
||||
|
||||
public function labelSave()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['id', 0],
|
||||
['name', ''],
|
||||
['cate_id', 0],
|
||||
['type', 0],
|
||||
['font_color', ''],
|
||||
['bg_color', ''],
|
||||
['border_color', ''],
|
||||
['image', ''],
|
||||
['sort', 0],
|
||||
['status', 1],
|
||||
['is_show', 1],
|
||||
]);
|
||||
$this->labelServices->labelSave($data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function labelDel($id)
|
||||
{
|
||||
$this->labelServices->labelDel($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function labelIsShow($id, $is_show)
|
||||
{
|
||||
$this->labelServices->labelIsShow($id, $is_show);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
public function labelStatus($id, $status)
|
||||
{
|
||||
$this->labelServices->labelStatus($id, $status);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
public function labelUseList()
|
||||
{
|
||||
return app('json')->success($this->labelServices->labelUseList());
|
||||
}
|
||||
}
|
||||
130
crmeb/app/adminapi/controller/v1/product/StoreProductParam.php
Normal file
130
crmeb/app/adminapi/controller/v1/product/StoreProductParam.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\product;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\product\product\StoreProductParamServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* 商品参数
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
class StoreProductParam extends AuthController
|
||||
{
|
||||
/**
|
||||
* @param App $app
|
||||
* @param StoreProductParamServices $services
|
||||
*/
|
||||
public function __construct(App $app, StoreProductParamServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数列表
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function getParamList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name', '']
|
||||
]);
|
||||
return app('json')->success($this->services->getParamList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数详情
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function getParamInfo($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$info = $this->services->getParamInfo($id);
|
||||
return app('json')->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数值
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function getParamValue($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$info = $this->services->getParamValue($id);
|
||||
return app('json')->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存参数
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function saveParamData($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['name', ''],
|
||||
['value', []],
|
||||
['sort', 0],
|
||||
['status', 1]
|
||||
]);
|
||||
if (!$data['name']) return app('json')->fail('请输入参数名称');
|
||||
if (!count($data['value'])) return app('json')->fail('请输入参数值');
|
||||
$this->services->saveParamData($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改参数状态
|
||||
* @param $id
|
||||
* @param $status
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function setParamStatus($id, $status)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$this->services->setParamStatus($id, $status);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除参数
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/12/17
|
||||
*/
|
||||
public function delParamData($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$this->services->delParamData($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\product;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\product\product\StoreProductProtectionServices;
|
||||
use think\facade\App;
|
||||
|
||||
class StoreProductProtection extends AuthController
|
||||
{
|
||||
public function __construct(App $app, StoreProductProtectionServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function protectionList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['title', ''],
|
||||
['status', '']
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
return app('json')->success($this->services->protectionList($where));
|
||||
}
|
||||
|
||||
public function protectionInfo($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$info = $this->services->protectionInfo($id);
|
||||
return app('json')->success($info);
|
||||
}
|
||||
|
||||
public function protectionForm($id)
|
||||
{
|
||||
return app('json')->success($this->services->protectionForm($id));
|
||||
}
|
||||
|
||||
public function protectionSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['title', ''],
|
||||
['content', ''],
|
||||
['image', ''],
|
||||
['sort', 0],
|
||||
['status', 0]
|
||||
]);
|
||||
$this->services->protectionSave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function protectionStatus($id, $status)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$this->services->protectionStatus($id, $status);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
public function protectionDel($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$this->services->protectionDel($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
}
|
||||
@ -41,7 +41,8 @@ class StoreProductReply extends AuthController
|
||||
['data', ''],
|
||||
['product_id', 0],
|
||||
['key', ''],
|
||||
['order', '']
|
||||
['order', ''],
|
||||
['status', ''],
|
||||
]);
|
||||
$list = $this->services->sysPage($where);
|
||||
return app('json')->success($list);
|
||||
@ -100,7 +101,8 @@ class StoreProductReply extends AuthController
|
||||
['product_score', 0],
|
||||
['service_score', 0],
|
||||
['product_id', 0],
|
||||
['add_time', 0]
|
||||
['add_time', 0],
|
||||
['suk', ''],
|
||||
]);
|
||||
if (!$data['product_id']) {
|
||||
$data['product_id'] = $data['image']['product_id'] ?? '';
|
||||
@ -109,4 +111,36 @@ class StoreProductReply extends AuthController
|
||||
$this->services->saveReply($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评论审核
|
||||
* @param $id
|
||||
* @param $status
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/4/22
|
||||
*/
|
||||
public function set_status($id, $status)
|
||||
{
|
||||
$this->services->update($id, ['status' => $status]);
|
||||
return app('json')->success($status == 1 ? '审核通过' : '拒绝成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量商品评论审核
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2025/6/18
|
||||
*/
|
||||
public function batch_set_status()
|
||||
{
|
||||
list($ids, $status) = $this->request->postMore([
|
||||
['ids', []],
|
||||
['status', 0]
|
||||
], true);
|
||||
$this->services->batchUpdate($ids, ['status' => $status]);
|
||||
return app('json')->success($status == 1 ? '审核通过' : '拒绝成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,4 +80,21 @@ class Export extends AuthController
|
||||
}
|
||||
return app('json')->success(['isOpen' => $res]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServeServices $services
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/5/15
|
||||
*/
|
||||
public function getShipmentOrderList(ServeServices $services)
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['page', 1],
|
||||
['limit', 10],
|
||||
]);
|
||||
|
||||
return app('json')->success($services->express()->getShipmentOrderList($where));
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,4 +92,4 @@ class LangType extends AuthController
|
||||
CacheService::delete('lang_type_data');
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,9 +169,13 @@ class SystemAdmin extends AuthController
|
||||
['new_pwd', ''],
|
||||
['conf_pwd', ''],
|
||||
]);
|
||||
if (!preg_match('/^(?![^a-zA-Z]+$)(?!\D+$).{6,}$/', $data['new_pwd'])) {
|
||||
return app('json')->fail(400183);
|
||||
|
||||
if ($data['pwd']) {
|
||||
if (!preg_match('/^(?![^a-zA-Z]+$)(?!\D+$).{6,}$/', $data['new_pwd'])) {
|
||||
return app('json')->fail(400183);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->services->updateAdmin($this->adminId, $data))
|
||||
return app('json')->success(100001);
|
||||
else
|
||||
|
||||
@ -133,11 +133,20 @@ class SystemCity extends AuthController
|
||||
*/
|
||||
public function clean_cache()
|
||||
{
|
||||
$res = CacheService::delete('CITY_LIST');
|
||||
if ($res) {
|
||||
return app('json')->success(400185);
|
||||
} else {
|
||||
return app('json')->fail(400186);
|
||||
}
|
||||
CacheService::delete('CITY_LIST');
|
||||
CacheService::delete('CITY_FULL_LIST');
|
||||
return app('json')->success(400185);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取城市数据完整列表
|
||||
* @return \think\Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/04/10
|
||||
*/
|
||||
public function fullList()
|
||||
{
|
||||
return app('json')->success($this->services->fullList('parent_id,name as label,city_id as value'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,11 @@ namespace app\adminapi\controller\v1\setting;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\Request;
|
||||
use app\services\order\StoreOrderServices;
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use app\services\system\config\SystemConfigTabServices;
|
||||
use app\services\system\SystemPemServices;
|
||||
use crmeb\services\CacheService;
|
||||
use crmeb\services\easywechat\orderShipping\MiniOrderService;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
@ -38,16 +40,19 @@ class SystemConfig extends AuthController
|
||||
|
||||
/**
|
||||
* 显示资源列表
|
||||
*
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['tab_id', 0],
|
||||
['config_name', ''],
|
||||
['status', -1]
|
||||
]);
|
||||
if (!$where['tab_id']) {
|
||||
if (!$where['tab_id'] && $where['config_name'] == '') {
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
if ($where['status'] == -1) {
|
||||
@ -58,8 +63,11 @@ class SystemConfig extends AuthController
|
||||
|
||||
/**
|
||||
* 显示创建资源表单页.
|
||||
* @param $type
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
@ -72,7 +80,6 @@ class SystemConfig extends AuthController
|
||||
|
||||
/**
|
||||
* 保存新建的资源
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save()
|
||||
@ -91,8 +98,11 @@ class SystemConfig extends AuthController
|
||||
['info', ''],
|
||||
['desc', ''],
|
||||
['sort', 0],
|
||||
['level', 0],
|
||||
['link_data', []],
|
||||
['status', 0]
|
||||
]);
|
||||
if (is_array($data['config_tab_id'])) $data['config_tab_id'] = end($data['config_tab_id']);
|
||||
if (!$data['info']) return app('json')->fail(400274);
|
||||
if (!$data['menu_name']) return app('json')->fail(400275);
|
||||
if (!$data['desc']) return app('json')->fail(400276);
|
||||
@ -113,6 +123,11 @@ class SystemConfig extends AuthController
|
||||
if (!$data['parameter']) return app('json')->fail(400283);
|
||||
$this->services->valiDateRadioAndCheckbox($data);
|
||||
}
|
||||
if ($data['level'] == 1) {
|
||||
if (!$data['link_data']) return app('json')->fail('请选择关联顶级选项');
|
||||
$data['link_id'] = $data['link_data'][0];
|
||||
$data['link_value'] = $data['link_data'][1];
|
||||
}
|
||||
$data['value'] = json_encode($data['value']);
|
||||
$config = $this->services->getOne(['menu_name' => $data['menu_name']]);
|
||||
if ($config) {
|
||||
@ -120,7 +135,7 @@ class SystemConfig extends AuthController
|
||||
} else {
|
||||
$this->services->save($data);
|
||||
}
|
||||
\crmeb\services\CacheService::clear();
|
||||
CacheService::clear();
|
||||
return app('json')->success(400284);
|
||||
}
|
||||
|
||||
@ -179,20 +194,27 @@ class SystemConfig extends AuthController
|
||||
['info', ''],
|
||||
['desc', ''],
|
||||
['sort', 0],
|
||||
['level', 0],
|
||||
['link_data', []],
|
||||
['status', 0]
|
||||
]);
|
||||
if (is_array($data['config_tab_id'])) $data['config_tab_id'] = end($data['config_tab_id']);
|
||||
if (!$this->services->get($id)) {
|
||||
return app('json')->fail(100026);
|
||||
}
|
||||
if ($data['level'] == 1) {
|
||||
if (!$data['link_data']) return app('json')->fail('请选择关联顶级选项');
|
||||
$data['link_id'] = $data['link_data'][0];
|
||||
$data['link_value'] = $data['link_data'][1];
|
||||
}
|
||||
$data['value'] = json_encode($data['value']);
|
||||
$this->services->update($id, $data);
|
||||
\crmeb\services\CacheService::clear();
|
||||
CacheService::clear();
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定资源
|
||||
*
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
@ -201,7 +223,7 @@ class SystemConfig extends AuthController
|
||||
if (!$this->services->delete($id))
|
||||
return app('json')->fail(100008);
|
||||
else {
|
||||
\crmeb\services\CacheService::clear();
|
||||
CacheService::clear();
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
@ -218,7 +240,7 @@ class SystemConfig extends AuthController
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
$this->services->update($id, ['status' => $status]);
|
||||
\crmeb\services\CacheService::clear();
|
||||
CacheService::clear();
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
@ -307,15 +329,9 @@ class SystemConfig extends AuthController
|
||||
return app('json')->fail(400763);
|
||||
}
|
||||
}
|
||||
|
||||
//支付接口类型选择,如果有订单就不能再进行切换
|
||||
// if (isset($post['pay_wechat_type'])) {
|
||||
// /** @var StoreOrderServices $orderServices */
|
||||
// $orderServices = app()->make(StoreOrderServices::class);
|
||||
// if ($post['pay_wechat_type'] != -1 && $orderServices->count()) {
|
||||
// return app('json')->fail('支付接口类型已经选择,不能再次进行切换,切换后会导致无法退款等问题。');
|
||||
// }
|
||||
// }
|
||||
if (isset($post['uni_brokerage_price']) && preg_match('/\.[0-9]{2,}[1-9][0-9]*$/', (string)$post['uni_brokerage_price']) > 0) {
|
||||
return app('json')->fail(500029);
|
||||
}
|
||||
|
||||
if (isset($post['weixin_ckeck_file'])) {
|
||||
$from = public_path() . $post['weixin_ckeck_file'];
|
||||
@ -331,9 +347,112 @@ class SystemConfig extends AuthController
|
||||
@copy($from, $toHome);
|
||||
@copy($from, $toPublic);
|
||||
}
|
||||
if(isset($post['reward_integral']) || isset($post['reward_money'])) {
|
||||
if($post['reward_integral'] < 0 || $post['reward_money'] < 0) return app('json')->fail(400558);
|
||||
if (isset($post['reward_integral']) || isset($post['reward_money'])) {
|
||||
if ($post['reward_money'] < 0) return app('json')->fail('赠送余额不能小于0元');
|
||||
if ($post['reward_integral'] < 0) return app('json')->fail('赠送积分不能小于0');
|
||||
}
|
||||
|
||||
if (isset($post['sign_give_point'])) {
|
||||
if (!is_int($post['sign_give_point']) || $post['sign_give_point'] < 0) {
|
||||
return app('json')->fail('签到赠送积分请填写大于等于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['sign_give_exp'])) {
|
||||
if ((int)$post['sign_give_exp'] < 0) {
|
||||
return app('json')->fail('签到赠送经验请填写大于等于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['integral_frozen'])) {
|
||||
if (!ctype_digit($post['integral_frozen']) || $post['integral_frozen'] < 0) {
|
||||
return app('json')->fail('积分冻结天数请填写大于等于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['store_free_postage'])) {
|
||||
if (!is_int($post['store_free_postage']) || $post['store_free_postage'] < 0) {
|
||||
return app('json')->fail('满额包邮请填写大于等于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['withdrawal_fee'])) {
|
||||
if ($post['withdrawal_fee'] < 0 || $post['withdrawal_fee'] > 100) {
|
||||
return app('json')->fail('提现手续费范围在0-100之间');
|
||||
}
|
||||
}
|
||||
if (isset($post['routine_auth_type']) && count($post['routine_auth_type']) == 0) {
|
||||
return app('json')->fail('微信和手机号登录开关至少开启一个');
|
||||
}
|
||||
if (isset($post['integral_max_num'])) {
|
||||
if (!ctype_digit($post['integral_max_num']) || $post['integral_max_num'] < 0) {
|
||||
return app('json')->fail('积分抵扣上限请填写大于等于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['customer_phone'])) {
|
||||
if (!ctype_digit($post['customer_phone']) || strlen($post['customer_phone']) > 11) {
|
||||
return app('json')->fail('客服手机号为11位数字');
|
||||
}
|
||||
}
|
||||
if (isset($post['refund_time_available'])) {
|
||||
if (!ctype_digit($post['refund_time_available'])) {
|
||||
return app('json')->fail('售后期限必须为大于0的整数');
|
||||
}
|
||||
}
|
||||
if (isset($post['sms_save_type']) && sys_config('sms_account', '') != '') {
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
if (isset($post['param_filter_data'])) {
|
||||
$post['param_filter_data'] = base64_encode($post['param_filter_data']);
|
||||
}
|
||||
if (isset($post['product_type_config'])) {
|
||||
if (count($post['product_type_config']) == 0) {
|
||||
return app('json')->fail('商品类型至少选择一项');
|
||||
}
|
||||
}
|
||||
if (isset($post['yue_pay_status']) && $post['yue_pay_status'] == 1) {
|
||||
$post['balance_func_status'] = 1;
|
||||
}
|
||||
if (isset($post['pay_weixin_client_cert'])) {
|
||||
$certData = [
|
||||
'type' => 'wechat',
|
||||
'name' => 'pay_weixin_client_cert',
|
||||
'path' => 'cert' . time() . rand(1000, 9999),
|
||||
'content' => $post['pay_weixin_client_cert'] != '' ? file_get_contents($this->getPemPath($post['pay_weixin_client_cert'])) : '',
|
||||
];
|
||||
$keyData = [
|
||||
'type' => 'wechat',
|
||||
'name' => 'pay_weixin_client_key',
|
||||
'path' => 'key' . time() . rand(1000, 9999),
|
||||
'content' => $post['pay_weixin_client_key'] != '' ? file_get_contents($this->getPemPath($post['pay_weixin_client_key'])) : '',
|
||||
];
|
||||
$systemPemServices = app()->make(SystemPemServices::class);
|
||||
$systemPemServices->savePem($certData);
|
||||
$systemPemServices->savePem($keyData);
|
||||
}
|
||||
|
||||
if (isset($post['merchant_cert_path'])) {
|
||||
$merchantCertData = [
|
||||
'type' => 'alipay',
|
||||
'name' => 'merchant_cert_path',
|
||||
'path' => 'merchant_cert' . time() . rand(1000, 9999),
|
||||
'content' => $post['merchant_cert_path'] != '' ? file_get_contents($this->getPemPath($post['merchant_cert_path'])) : '',
|
||||
];
|
||||
$alipayCertData = [
|
||||
'type' => 'alipay',
|
||||
'name' => 'alipay_cert_path',
|
||||
'path' => 'alipay_cert' . time() . rand(1000, 9999),
|
||||
'content' => $post['alipay_cert_path'] != '' ? file_get_contents($this->getPemPath($post['alipay_cert_path'])) : '',
|
||||
];
|
||||
$alipayRootCertData = [
|
||||
'type' => 'alipay',
|
||||
'name' => 'alipay_root_cert_path',
|
||||
'path' => 'alipay_root_cert' . time() . rand(1000, 9999),
|
||||
'content' => $post['alipay_root_cert_path'] != '' ? file_get_contents($this->getPemPath($post['alipay_root_cert_path'])) : '',
|
||||
];
|
||||
$systemPemServices = app()->make(SystemPemServices::class);
|
||||
$systemPemServices->savePem($merchantCertData);
|
||||
$systemPemServices->savePem($alipayCertData);
|
||||
$systemPemServices->savePem($alipayRootCertData);
|
||||
}
|
||||
|
||||
|
||||
foreach ($post as $k => $v) {
|
||||
$config_one = $this->services->getOne(['menu_name' => $k]);
|
||||
if ($config_one) {
|
||||
@ -342,9 +461,28 @@ class SystemConfig extends AuthController
|
||||
$this->services->update($k, ['value' => json_encode($v)], 'menu_name');
|
||||
}
|
||||
}
|
||||
\crmeb\services\CacheService::clear();
|
||||
CacheService::clear();
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取证书文件路径
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/10/21
|
||||
*/
|
||||
public function getPemPath(string $path)
|
||||
{
|
||||
if (strstr($path, 'http://') || strstr($path, 'https://')) {
|
||||
$path = parse_url($path)['path'] ?? '';
|
||||
}
|
||||
$path = root_path('runtime/pem') . ltrim($path, '/');
|
||||
if (!file_exists($path)) {
|
||||
$path = public_path('uploads') . ltrim($path, '/');
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,6 +503,7 @@ class SystemConfig extends AuthController
|
||||
$config_tab = [];
|
||||
} else {
|
||||
$config_tab = $services->getConfigTab($pid);
|
||||
if (empty($config_tab)) $config_tab[] = $services->get($pid, ['id', 'id as value', 'title as label', 'pid', 'icon', 'type']);
|
||||
}
|
||||
return app('json')->success(compact('config_tab'));
|
||||
}
|
||||
|
||||
@ -74,7 +74,9 @@ class SystemConfigTab extends AuthController
|
||||
['type', 0],
|
||||
['sort', 0],
|
||||
['pid', 0],
|
||||
['menus_id', 0],
|
||||
]);
|
||||
if (is_array($data['pid'])) $data['pid'] = end($data['pid']);
|
||||
if (!$data['title']) return app('json')->fail(400291);
|
||||
$this->services->save($data);
|
||||
return app('json')->success(400292);
|
||||
@ -118,7 +120,9 @@ class SystemConfigTab extends AuthController
|
||||
['type', 0],
|
||||
['sort', 0],
|
||||
['pid', 0],
|
||||
['menus_id', 0],
|
||||
]);
|
||||
if (is_array($data['pid'])) $data['pid'] = end($data['pid']);
|
||||
if (!$data['title']) return app('json')->fail(400291);
|
||||
if (!$data['eng_title']) return app('json')->fail(400275);
|
||||
$this->services->update($id, $data);
|
||||
|
||||
1091
crmeb/app/adminapi/controller/v1/setting/SystemCrud.php
Normal file
1091
crmeb/app/adminapi/controller/v1/setting/SystemCrud.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -109,6 +109,10 @@ class SystemGroupData extends AuthController
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($group && $group['config_name'] == 'user_recharge_quota') {
|
||||
if ($params['price'] <= 0) return app('json')->fail('售价必须大于0');
|
||||
if ($params['give_money'] < 0) return app('json')->fail('赠送不能小于0');
|
||||
}
|
||||
$this->services->checkSeckillTime($services, $gid, $params);
|
||||
$this->checkSign($services, $gid, $params);
|
||||
$fields = json_decode($group['fields'], true) ?? [];
|
||||
@ -175,6 +179,11 @@ class SystemGroupData extends AuthController
|
||||
$groupData = $this->services->get($id);
|
||||
$fields = $services->getValueFields((int)$groupData["gid"]);
|
||||
$params = request()->post();
|
||||
$group = $services->getOne(['id' => $params['gid']], 'id,config_name,fields');
|
||||
if ($group && $group['config_name'] == 'user_recharge_quota') {
|
||||
if ($params['price'] <= 0) return app('json')->fail('售价必须大于0');
|
||||
if ($params['give_money'] < 0) return app('json')->fail('赠送不能小于0');
|
||||
}
|
||||
$this->services->checkSeckillTime($services, $groupData["gid"], $params, $id);
|
||||
$this->checkSign($services, $groupData["gid"], $params);
|
||||
$value = [];
|
||||
@ -231,7 +240,6 @@ class SystemGroupData extends AuthController
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 检查签到配置
|
||||
* @param SystemGroupServices $services
|
||||
|
||||
@ -13,6 +13,8 @@ namespace app\adminapi\controller\v1\setting;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemMenusServices;
|
||||
use app\services\system\SystemRouteCateServices;
|
||||
use app\services\system\SystemRouteServices;
|
||||
use think\facade\App;
|
||||
use think\facade\Route;
|
||||
|
||||
@ -38,16 +40,39 @@ class SystemMenus extends AuthController
|
||||
/**
|
||||
* 菜单展示列表
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/05/06
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['is_show', ''],
|
||||
['keyword', ''],
|
||||
['auth_type', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/14
|
||||
*/
|
||||
public function unique()
|
||||
{
|
||||
$adminInfo = $this->request->adminInfo();
|
||||
[$menus, $uniqueAuth] = app()->make(SystemMenusServices::class)->getMenusList($adminInfo['roles'], (int)$adminInfo['level']);
|
||||
return app('json')->success(compact('menus', 'uniqueAuth'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示创建资源表单页.
|
||||
*
|
||||
@ -86,7 +111,7 @@ class SystemMenus extends AuthController
|
||||
['is_show', 0],
|
||||
['is_show_path', 0],
|
||||
]);
|
||||
|
||||
$data['is_show_path'] = $data['is_show'];
|
||||
if (!$data['menu_name'])
|
||||
return app('json')->fail(400198);
|
||||
$data['path'] = implode('/', $data['path']);
|
||||
@ -97,6 +122,73 @@ class SystemMenus extends AuthController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存权限
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/11
|
||||
*/
|
||||
public function batchSave()
|
||||
{
|
||||
$menus = $this->request->post('menus', []);
|
||||
if (!$menus) {
|
||||
return app('json')->fail(100026);
|
||||
}
|
||||
$data = [];
|
||||
|
||||
$uniqueAuthAll = $this->services->getColumn(['is_del' => 0, 'is_show' => 1], 'unique_auth');
|
||||
$uniqueAuthAll = array_filter($uniqueAuthAll, function ($item) {
|
||||
return !!$item;
|
||||
});
|
||||
$uniqueAuthAll = array_unique($uniqueAuthAll);
|
||||
|
||||
$uniqueFn = function ($path) use ($uniqueAuthAll) {
|
||||
$attPath = explode('/', $path);
|
||||
$uniqueAuth = '';
|
||||
if ($attPath) {
|
||||
$pathData = [];
|
||||
foreach ($attPath as $vv) {
|
||||
if (strstr($vv, '<') === false) {
|
||||
$pathData[] = $vv;
|
||||
}
|
||||
}
|
||||
$uniqueAuth = implode('-', $pathData);
|
||||
}
|
||||
|
||||
if (in_array($uniqueAuth, $uniqueAuthAll)) {
|
||||
$uniqueAuth .= '-' . uniqid();
|
||||
}
|
||||
|
||||
array_push($uniqueAuthAll, $uniqueAuth);
|
||||
|
||||
return $uniqueAuth;
|
||||
};
|
||||
|
||||
foreach ($menus as $menu) {
|
||||
if (empty($menu['menu_name'])) {
|
||||
return app('json')->fail(400198);
|
||||
}
|
||||
if (isset($menu['unique_auth']) && $menu['unique_auth']) {
|
||||
$menu['unique_auth'] = explode('/', $menu['api_url']);
|
||||
}
|
||||
$data[] = [
|
||||
'methods' => $menu['method'],
|
||||
'menu_name' => $menu['menu_name'],
|
||||
'unique_auth' => !empty($menu['unique_auth']) ? $menu['unique_auth'] : $uniqueFn($menu['api_url']),
|
||||
'api_url' => $menu['api_url'],
|
||||
'pid' => $menu['path'],
|
||||
'auth_type' => 2,
|
||||
'is_show' => 1,
|
||||
'is_show_path' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
$this->services->saveAll($data);
|
||||
|
||||
return app('json')->success(100021);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一条菜单权限信息
|
||||
* @param int $id
|
||||
@ -183,7 +275,7 @@ class SystemMenus extends AuthController
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示和隐藏
|
||||
* 权限的开启和关闭,显示和隐藏
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
@ -193,9 +285,14 @@ class SystemMenus extends AuthController
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
|
||||
[$show] = $this->request->postMore([['is_show', 0]], true);
|
||||
[$isShow, $isShowPath] = $this->request->postMore([['is_show', 0], ['is_show_path', 0]], true);
|
||||
if ($isShow == -1) {
|
||||
$res = $this->services->update($id, ['is_show_path' => $isShowPath]);
|
||||
} else {
|
||||
$res = $this->services->update($id, ['is_show' => $isShow, 'is_show_path' => $isShow]);
|
||||
}
|
||||
|
||||
if ($this->services->update($id, ['is_show' => $show])) {
|
||||
if ($res) {
|
||||
return app('json')->success(100001);
|
||||
} else {
|
||||
return app('json')->fail(100007);
|
||||
@ -215,26 +312,28 @@ class SystemMenus extends AuthController
|
||||
return app('json')->success(['menus' => $menus, 'unique' => $unique]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由分类
|
||||
* @param SystemRouteCateServices $service
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/25
|
||||
*/
|
||||
public function ruleCate(SystemRouteCateServices $service)
|
||||
{
|
||||
return app('json')->success($service->getAllList('adminapi'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口列表
|
||||
* @return array
|
||||
*/
|
||||
public function ruleList()
|
||||
public function ruleList(SystemRouteServices $services)
|
||||
{
|
||||
$cateId = request()->get('cate_id', 0);
|
||||
//获取所有的路由
|
||||
$ruleList = Route::getRuleList();
|
||||
$menuApiList = $this->services->getColumn(['auth_type' => 2, 'is_del' => 0], "concat(`api_url`,'_',lower(`methods`)) as rule");
|
||||
if ($menuApiList) $menuApiList = array_column($menuApiList, 'rule');
|
||||
$list = [];
|
||||
foreach ($ruleList as $item) {
|
||||
$item['rule'] = str_replace('adminapi/', '', $item['rule']);
|
||||
if (!in_array($item['rule'] . '_' . $item['method'], $menuApiList)) {
|
||||
$item['real_name'] = $item['option']['real_name'] ?? '';
|
||||
unset($item['option']);
|
||||
$item['method'] = strtoupper($item['method']);
|
||||
$list[] = $item;
|
||||
}
|
||||
}
|
||||
return app('json')->success($list);
|
||||
$ruleList = $services->selectList(['cate_id' => $cateId, 'app_name' => 'adminapi'])->toArray();
|
||||
return app('json')->success($ruleList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,8 +34,10 @@ class SystemNotification extends AuthController
|
||||
|
||||
/**
|
||||
* 显示资源列表
|
||||
*
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
@ -46,9 +48,59 @@ class SystemNotification extends AuthController
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示编辑
|
||||
*
|
||||
* 添加消息
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/2/19
|
||||
*/
|
||||
public function notForm($id)
|
||||
{
|
||||
return app('json')->success($this->services->getNotForm($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存自定义消息
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/2/20
|
||||
*/
|
||||
public function notFormSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['custom_trigger', ''],
|
||||
['name', ''],
|
||||
['mark', ''],
|
||||
]);
|
||||
$this->services->notFormSave($id, $data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除消息
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/2/20
|
||||
*/
|
||||
public function delNot($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail(100100);
|
||||
$this->services->delete($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 显示编辑
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function info()
|
||||
{
|
||||
@ -81,20 +133,24 @@ class SystemNotification extends AuthController
|
||||
['system_title', ''],
|
||||
['system_text', ''],
|
||||
['tempid', ''],
|
||||
['tempkey', ''],
|
||||
['content', ''],
|
||||
['ent_wechat_text', ''],
|
||||
['url', ''],
|
||||
['wechat_id', ''],
|
||||
['routine_id', ''],
|
||||
['mark', ''],
|
||||
['sms_id', ''],
|
||||
['key_list', ''],
|
||||
['sms_text', ''],
|
||||
['wechat_link', ''],
|
||||
['routine_link', ''],
|
||||
['wechat_to_routine', ''],
|
||||
]);
|
||||
if ($data['mark'] == 'verify_code') $data['type'] = 'is_sms';
|
||||
if (!$data['id']) return app('json')->fail(100100);
|
||||
if ($this->services->saveData($data)) {
|
||||
CacheService::delete('NOTICE_SMS_' . $data['mark']);
|
||||
CacheService::delete('wechat_' . $data['mark']);
|
||||
CacheService::delete('routine_' . $data['mark']);
|
||||
CacheService::delete('TEMP_IDS_LIST');
|
||||
CacheService::clear();
|
||||
return app('json')->success(100001);
|
||||
} else {
|
||||
return app('json')->fail(100007);
|
||||
@ -117,10 +173,7 @@ class SystemNotification extends AuthController
|
||||
if ($type == '' || $status == '' || $id == 0) return app('json')->fail(100100);
|
||||
$this->services->update($id, [$type => $status]);
|
||||
$res = $this->services->getOneNotce(['id' => $id]);
|
||||
CacheService::delete('NOTICE_SMS_' . $res->mark);
|
||||
CacheService::delete('wechat_' . $res->mark);
|
||||
CacheService::delete('routine_' . $res->mark);
|
||||
CacheService::delete('TEMP_IDS_LIST');
|
||||
CacheService::clear();
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,11 +91,8 @@ class SystemOutAccount extends AuthController
|
||||
]);
|
||||
$this->validate($data, StoreOutAccountValidate::class, 'save');
|
||||
if ($this->services->getOne(['appid' => $data['appid']])) return app('json')->fail('账号重复');
|
||||
if (!$data['appsecret']) {
|
||||
unset($data['appsecret']);
|
||||
} else {
|
||||
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
|
||||
}
|
||||
$data['apppwd'] = $data['appsecret'];
|
||||
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
|
||||
$data['add_time'] = time();
|
||||
$data['rules'] = implode(',', $data['rules']);
|
||||
if (!$this->services->save($data)) {
|
||||
@ -122,12 +119,9 @@ class SystemOutAccount extends AuthController
|
||||
]);
|
||||
|
||||
$this->validate($data, StoreOutAccountValidate::class, 'update');
|
||||
if (!$data['appsecret']) {
|
||||
unset($data['appsecret']);
|
||||
} else {
|
||||
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
|
||||
}
|
||||
if (!$this->services->getOne(['id' => $id])) return app('json')->fail('没有此账号');
|
||||
$data['apppwd'] = $data['appsecret'];
|
||||
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
|
||||
$data['rules'] = implode(',', $data['rules']);
|
||||
$res = $this->services->update($id, $data);
|
||||
if (!$res) {
|
||||
@ -256,6 +250,6 @@ class SystemOutAccount extends AuthController
|
||||
['push_password', 0],
|
||||
['push_token_url', '']
|
||||
]);
|
||||
return app('json')->success('100014',$this->services->textOutUrl($data));
|
||||
return app('json')->success('100014', $this->services->textOutUrl($data));
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ class SystemRole extends AuthController
|
||||
if (!$data['role_name']) return app('json')->fail(400220);
|
||||
if (!is_array($data['rules']) || !count($data['rules']))
|
||||
return app('json')->fail(400221);
|
||||
|
||||
$data['rules'] = implode(',', $data['rules']);
|
||||
if ($id) {
|
||||
if (!$this->services->update($id, $data)) return app('json')->fail(100007);
|
||||
@ -105,7 +106,7 @@ class SystemRole extends AuthController
|
||||
if (!$role) {
|
||||
return app('json')->fail(100100);
|
||||
}
|
||||
$menus = $services->getMenus($this->adminInfo['level'] == 0 ? [] : $this->adminInfo['roles']);
|
||||
$menus = $services->getMenus($this->adminInfo['level'] == 0 ? [] : $this->adminInfo['roles'], explode(',', $role['rules']));
|
||||
return app('json')->success(['role' => $role->toArray(), 'menus' => $menus]);
|
||||
}
|
||||
|
||||
|
||||
170
crmeb/app/adminapi/controller/v1/setting/SystemRoute.php
Normal file
170
crmeb/app/adminapi/controller/v1/setting/SystemRoute.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\adminapi\controller\v1\setting;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemRouteServices;
|
||||
use crmeb\services\CacheService;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* Class SystemRoute
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
* @package app\adminapi\controller\v1\setting
|
||||
*/
|
||||
class SystemRoute extends AuthController
|
||||
{
|
||||
|
||||
/**
|
||||
* SystemRoute constructor.
|
||||
* @param App $app
|
||||
* @param SystemRouteServices $services
|
||||
*/
|
||||
public function __construct(App $app, SystemRouteServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步路由权限
|
||||
* @param string $appName
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function syncRoute(string $appName = 'adminapi')
|
||||
{
|
||||
$this->services->syncRoute($appName);
|
||||
|
||||
return app('json')->success(100038);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/7
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['name_like', ''],
|
||||
['app_name', 'adminapi']
|
||||
]);
|
||||
|
||||
return app('json')->success($this->services->getList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* tree数据
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/7
|
||||
*/
|
||||
public function tree()
|
||||
{
|
||||
[$name, $appName] = $this->request->getMore([
|
||||
['name_like', ''],
|
||||
['app_name', 'adminapi']
|
||||
], true);
|
||||
|
||||
return app('json')->success($this->services->getTreeList($appName, $name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/7
|
||||
*/
|
||||
public function save($id = 0)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['cate_id', 0],
|
||||
['name', ''],
|
||||
['path', ''],
|
||||
['method', ''],
|
||||
['type', 0],
|
||||
['app_name', ''],
|
||||
['query', []],
|
||||
['header', []],
|
||||
['request', []],
|
||||
['response', []],
|
||||
['request_example', []],
|
||||
['response_example', []],
|
||||
['describe', ''],
|
||||
['error_code', []],
|
||||
]);
|
||||
|
||||
// if (!$data['name']) {
|
||||
// return app('json')->fail(500031);
|
||||
// }
|
||||
// if (!$data['path']) {
|
||||
// return app('json')->fail(500032);
|
||||
// }
|
||||
// if (!$data['method']) {
|
||||
// return app('json')->fail(500033);
|
||||
// }
|
||||
// if (!$data['app_name']) {
|
||||
// return app('json')->fail(500034);
|
||||
// }
|
||||
if ($id) {
|
||||
$this->services->update($id, $data);
|
||||
} else {
|
||||
$data['add_time'] = date('Y-m-d H:i:s');
|
||||
$this->services->save($data);
|
||||
}
|
||||
CacheService::clear();
|
||||
|
||||
return app('json')->success($id ? 100001 : 100021);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/7
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return app('json')->success($this->services->getInfo((int)$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/7
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
if (!$id) {
|
||||
return app('json')->fail(500035);
|
||||
}
|
||||
|
||||
$this->services->destroy($id);
|
||||
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
156
crmeb/app/adminapi/controller/v1/setting/SystemRouteCate.php
Normal file
156
crmeb/app/adminapi/controller/v1/setting/SystemRouteCate.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\adminapi\controller\v1\setting;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemRouteCateServices;
|
||||
use app\services\system\SystemRouteServices;
|
||||
use think\facade\App;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* Class SystemRouteCate
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
* @package app\adminapi\controller\v1\setting
|
||||
*/
|
||||
class SystemRouteCate extends AuthController
|
||||
{
|
||||
|
||||
/**
|
||||
* SystemRouteCate constructor.
|
||||
* @param App $app
|
||||
* @param SystemRouteCateServices $services
|
||||
*/
|
||||
public function __construct(App $app, SystemRouteCateServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return app('json')->success($this->services->getAllList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return app('json')->success($this->services->getFrom(0, $this->request->get('app_name', 'adminapi')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function save(Request $request)
|
||||
{
|
||||
$data = $request->postMore([
|
||||
['path', []],
|
||||
['name', ''],
|
||||
['sort', 0],
|
||||
['app_name', ''],
|
||||
]);
|
||||
|
||||
if (!$data['name']) {
|
||||
return app('json')->fail(500037);
|
||||
}
|
||||
|
||||
$data['add_time'] = time();
|
||||
$data['pid'] = $data['path'][count($data['path']) - 1] ?? 0;
|
||||
$this->services->save($data);
|
||||
|
||||
|
||||
return app('json')->success(100000);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return app('json')->success($this->services->getFrom($id, $this->request->get('app_name', 'adminapi')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$data = $request->postMore([
|
||||
['path', []],
|
||||
['name', ''],
|
||||
['sort', 0],
|
||||
['app_name', ''],
|
||||
]);
|
||||
|
||||
if (!$data['name']) {
|
||||
return app('json')->fail(500037);
|
||||
}
|
||||
|
||||
$data['pid'] = $data['path'][count($data['path']) - 1] ?? 0;
|
||||
$this->services->update($id, $data);
|
||||
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SystemRouteServices $service
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/4/6
|
||||
*/
|
||||
public function delete(SystemRouteServices $service, $id)
|
||||
{
|
||||
if (!$id) {
|
||||
return app('json')->fail(500035);
|
||||
}
|
||||
|
||||
if ($service->count(['cate_id' => $id])) {
|
||||
return app('json')->fail(500038);
|
||||
}
|
||||
|
||||
$this->services->delete($id);
|
||||
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
@ -79,24 +79,17 @@ class SystemStorage extends AuthController
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SystemConfigServices $services
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveConfig(SystemConfigServices $services)
|
||||
public function saveConfig( )
|
||||
{
|
||||
$type = (int)$this->request->post('type', 0);
|
||||
// $services->update('upload_type', ['value' => json_encode($type)], 'menu_name');
|
||||
// if (1 === $type) {
|
||||
// $this->services->transaction(function () {
|
||||
// $this->services->update(['status' => 1, 'is_delete' => 0], ['status' => 0]);
|
||||
// });
|
||||
// }
|
||||
// \crmeb\services\CacheService::clear();
|
||||
|
||||
$data = $this->request->postMore([
|
||||
['accessKey', ''],
|
||||
['secretKey', ''],
|
||||
['appid', ''],
|
||||
['storageRegion', ''],
|
||||
]);
|
||||
|
||||
$this->services->saveConfig((int)$type, $data);
|
||||
@ -166,7 +159,10 @@ class SystemStorage extends AuthController
|
||||
//设置跨域规则
|
||||
try {
|
||||
$upload = UploadService::init($info->type);
|
||||
$upload->setBucketCors($info->name, $info->region);
|
||||
$res = $upload->setBucketCors($info->name, $info->region);
|
||||
if (false === $res) {
|
||||
return app('json')->fail($upload->getError());
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
@ -199,6 +195,7 @@ class SystemStorage extends AuthController
|
||||
public function updateDomain($id)
|
||||
{
|
||||
$domain = $this->request->post('domain', '');
|
||||
$cdn = $this->request->post('cdn', '');
|
||||
$data = $this->request->postMore([
|
||||
['pri', ''],
|
||||
['ca', '']
|
||||
@ -214,7 +211,7 @@ class SystemStorage extends AuthController
|
||||
// return app('json')->fail('域名为HTTPS访问时,必须填写证书');
|
||||
// }
|
||||
|
||||
$this->services->updateDomain($id, $domain);
|
||||
$this->services->updateDomain($id, $domain, ['cdn' => $cdn]);
|
||||
|
||||
return app('json')->success(100001);
|
||||
}
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\statistic;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\user\UserMoneyServices;
|
||||
use think\facade\App;
|
||||
|
||||
class BalanceStatistic extends AuthController
|
||||
{
|
||||
/**
|
||||
* @param App $app
|
||||
* @param UserMoneyServices $services
|
||||
*/
|
||||
public function __construct(App $app, UserMoneyServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额统计基础信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBasic()
|
||||
{
|
||||
$data = $this->services->getBasic();
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额统计趋势图
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTrend()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getTrend($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额来源
|
||||
* @return mixed
|
||||
*/
|
||||
public function getChannel()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getChannel($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getType($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\statistic;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\statistic\OrderStatisticServices;
|
||||
use think\facade\App;
|
||||
|
||||
class OrderStatistic extends AuthController
|
||||
{
|
||||
public function __construct(App $app, OrderStatisticServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单统计基础信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBasic()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getBasic($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单统计趋势图
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTrend()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getTrend($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单来源
|
||||
* @return mixed
|
||||
*/
|
||||
public function getChannel()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getChannel($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['time', '']
|
||||
]);
|
||||
$data = $this->services->getType($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
}
|
||||
106
crmeb/app/adminapi/controller/v1/statistic/ProductStatistic.php
Normal file
106
crmeb/app/adminapi/controller/v1/statistic/ProductStatistic.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\adminapi\controller\v1\statistic;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\statistic\ProductStatisticServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* Class ProductStatistic
|
||||
* @package app\adminapi\controller\v1\statistic
|
||||
*/
|
||||
class ProductStatistic extends AuthController
|
||||
{
|
||||
/**
|
||||
* ProductStatistic constructor.
|
||||
* @param App $app
|
||||
* @param ProductStatisticServices $services
|
||||
*/
|
||||
public function __construct(App $app, ProductStatisticServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品基础
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBasic()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
return app('json')->success($this->services->getBasic($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品趋势
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTrend()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getTrend($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品排行
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProductRanking()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time'],
|
||||
['sort', '']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getProductRanking($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @return mixed
|
||||
*/
|
||||
public function getExcel()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getTrend($where, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* @param $time
|
||||
* @return string
|
||||
*/
|
||||
public function getDay($time)
|
||||
{
|
||||
if (strstr($time, '-') !== false) {
|
||||
[$startTime, $endTime] = explode('-', $time);
|
||||
if (!$startTime || !$endTime) {
|
||||
return date("Y/m/d 00:00:00", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
|
||||
} else {
|
||||
return date('Y/m/d 00:00:00', strtotime($startTime)).'-'.date('Y/m/d 23:59:59', strtotime($endTime));
|
||||
}
|
||||
} else {
|
||||
return date("Y/m/d 00:00:00", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\adminapi\controller\v1\statistic;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\statistic\TradeStatisticServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* Class TradeStatistic
|
||||
* @package app\controller\admin\v1\statistic
|
||||
*/
|
||||
class TradeStatistic extends AuthController
|
||||
{
|
||||
/**
|
||||
* TradeStatistic constructor.
|
||||
* @param App $app
|
||||
* @param TradeStatisticServices $services
|
||||
*/
|
||||
public function __construct(App $app, TradeStatisticServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 顶部数据
|
||||
* @return mixed
|
||||
*/
|
||||
public function topTrade()
|
||||
{
|
||||
$leftToday = $this->services->getTopLeftTrade(['time' => 'today']);
|
||||
$leftyestoday = $this->services->getTopLeftTrade(['time' => 'yestoday']);
|
||||
$rightOne = $this->services->getTopRightOneTrade();
|
||||
$rightTwo = $this->services->getTopRightTwoTrade();
|
||||
$right = ['today' => $rightOne, 'month' => $rightTwo];
|
||||
$totalleft = [$leftToday, $leftyestoday];
|
||||
$left = [];
|
||||
foreach ($totalleft as $k => $v) {
|
||||
$left['name'] = "当日订单金额";
|
||||
$left['x'] = $v['curve']['x'];
|
||||
$left['series'][$k]['money'] = round($v['total_money'], 2);
|
||||
$left['series'][$k]['value'] = array_values($v['curve']['y']);
|
||||
}
|
||||
|
||||
$data['left'] = $left;
|
||||
$data['right'] = $right;
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 底部数据
|
||||
* @return mixed
|
||||
*/
|
||||
public function bottomTrade()
|
||||
{
|
||||
$day = $this->request->getMore([
|
||||
['data', ""],
|
||||
]);
|
||||
$bottom = $this->services->getBottomTrade($day);
|
||||
return app('json')->success($bottom);
|
||||
}
|
||||
|
||||
}
|
||||
152
crmeb/app/adminapi/controller/v1/statistic/UserStatistic.php
Normal file
152
crmeb/app/adminapi/controller/v1/statistic/UserStatistic.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\adminapi\controller\v1\statistic;
|
||||
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\statistic\UserStatisticServices;
|
||||
use think\facade\App;
|
||||
|
||||
/**
|
||||
* Class UserStatistic
|
||||
* @package app\adminapi\controller\v1\statistic
|
||||
*/
|
||||
class UserStatistic extends AuthController
|
||||
{
|
||||
/**
|
||||
* UserStatistic constructor.
|
||||
* @param App $app
|
||||
* @param UserStatisticServices $services
|
||||
*/
|
||||
public function __construct(App $app, UserStatisticServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户基础信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBasic()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
return app('json')->success($this->services->getBasic($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户趋势
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTrend()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getTrend($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户信息
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWechat()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getWechat($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信用户趋势
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWechatTrend()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getWechatTrend($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户地域
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRegion()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time'],
|
||||
['sort', 'allNum']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getRegion($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户性别
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSex()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getSex($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户统计导出
|
||||
* @return mixed
|
||||
*/
|
||||
public function getExcel()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['channel_type', ''],
|
||||
['data', '', '', 'time']
|
||||
]);
|
||||
$where['time'] = $this->getDay($where['time']);
|
||||
return app('json')->success($this->services->getTrend($where, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* @param $time
|
||||
* @return string
|
||||
*/
|
||||
public function getDay($time)
|
||||
{
|
||||
if (strstr($time, '-') !== false) {
|
||||
[$startTime, $endTime] = explode('-', $time);
|
||||
if (!$startTime || !$endTime) {
|
||||
return date("Y/m/d 00:00:00", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
|
||||
} else {
|
||||
return date('Y/m/d 00:00:00', strtotime($startTime)).'-'.date('Y/m/d 23:59:59', strtotime($endTime));
|
||||
}
|
||||
} else {
|
||||
return date("Y/m/d 00:00:00", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,10 @@ class AppVersion extends AuthController
|
||||
|
||||
/**
|
||||
* 版本列表
|
||||
* @return mixed
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/4/2
|
||||
*/
|
||||
public function list()
|
||||
{
|
||||
@ -48,7 +51,12 @@ class AppVersion extends AuthController
|
||||
|
||||
/**
|
||||
* 新增版本表单
|
||||
* @return mixed
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/4/2
|
||||
*/
|
||||
public function crate($id)
|
||||
{
|
||||
@ -57,7 +65,10 @@ class AppVersion extends AuthController
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
* @return mixed
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/4/2
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
@ -75,4 +86,18 @@ class AppVersion extends AuthController
|
||||
$this->services->versionSave($id, $data);
|
||||
return app('json')->success(100021);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除App版本
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/4/2
|
||||
*/
|
||||
public function del($id)
|
||||
{
|
||||
$this->services->delete($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,11 +100,15 @@ class SystemClearData extends AuthController
|
||||
* 清除回收站商品
|
||||
* @return mixed
|
||||
*/
|
||||
public function recycleProduct()
|
||||
public function recycleProduct($id = 0)
|
||||
{
|
||||
/** @var StoreProductServices $product */
|
||||
$product = app()->make(StoreProductServices::class);
|
||||
$ids = $product->getColumn(['is_del' => 1], 'id');
|
||||
if ($id) {
|
||||
$ids = [$id];
|
||||
} else {
|
||||
$ids = $product->getColumn(['is_del' => 1], 'id');
|
||||
}
|
||||
//清除规格表数据
|
||||
/** @var StoreProductAttrServices $ProductAttr */
|
||||
$productAttr = app()->make(StoreProductAttrServices::class);
|
||||
@ -136,7 +140,7 @@ class SystemClearData extends AuthController
|
||||
//删除商品收藏记录
|
||||
/** @var StoreProductReplyServices $productRelation */
|
||||
$productRelation = app()->make(StoreProductReplyServices::class);
|
||||
$productRelation->delete([['product_id', 'in', $ids], ['category', '=', 'product']]);
|
||||
$productRelation->delete([['product_id', 'in', $ids], ['reply_type', '=', 'product']]);
|
||||
|
||||
//删除商品的评论
|
||||
/** @var StoreProductReplyServices $productReply */
|
||||
@ -145,8 +149,13 @@ class SystemClearData extends AuthController
|
||||
|
||||
/** @var StoreProductServices $services */
|
||||
$services = app()->make(StoreProductServices::class);
|
||||
$services->delete(1, 'is_del');
|
||||
return app('json')->success(100046);
|
||||
if ($id) {
|
||||
$services->delete($id);
|
||||
return true;
|
||||
} else {
|
||||
$services->delete(1, 'is_del');
|
||||
return app('json')->success(100046);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
145
crmeb/app/adminapi/controller/v1/system/SystemCrontab.php
Normal file
145
crmeb/app/adminapi/controller/v1/system/SystemCrontab.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\system;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\crontab\SystemCrontabServices;
|
||||
use think\facade\App;
|
||||
use think\facade\Env;
|
||||
|
||||
class SystemCrontab extends AuthController
|
||||
{
|
||||
public function __construct(App $app, SystemCrontabServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务列表
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getTimerList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['custom', 0],
|
||||
]);
|
||||
$where['is_del'] = 0;
|
||||
return app('json')->success($this->services->getTimerList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务详情
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getTimerInfo($id)
|
||||
{
|
||||
return app('json')->success($this->services->getTimerInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMarkList()
|
||||
{
|
||||
return app('json')->success($this->services->getMarkList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存定时任务
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveTimer()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['id', 0],
|
||||
['name', ''],
|
||||
['mark', ''],
|
||||
['content', ''],
|
||||
['type', 0],
|
||||
['is_open', 0],
|
||||
['month', 0],
|
||||
['week', 0],
|
||||
['day', 0],
|
||||
['hour', 0],
|
||||
['minute', 0],
|
||||
['second', 0],
|
||||
['customCode', ''],
|
||||
['password', ''],
|
||||
]);
|
||||
if ($data['mark'] == 'customTimer') {
|
||||
if (!Env::get('app_debug', false)) return app('json')->fail('生产环境下无法新增和修改自定义内容,如需修改请修改.env文件中app_debug项为true');
|
||||
if ($data['password'] === '') return app('json')->fail('密码不能为空');
|
||||
if (config('filesystem.password') !== $data['password']) return app('json')->fail('密码错误');
|
||||
$adminInfo = $this->request->adminInfo();
|
||||
if (!$adminInfo) return app('json')->fail('非法操作');
|
||||
if ($adminInfo['level'] != 0) return app('json')->fail('仅超级管理员可以操作定时任务');
|
||||
if (!$this->isSafePhpCode($data['customCode'])) return app('json')->fail('自定义内容存在危险代码,请检查代码');
|
||||
}
|
||||
$this->services->saveTimer($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function delTimer($id)
|
||||
{
|
||||
$this->services->delTimer($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定时任务状态
|
||||
* @param $id
|
||||
* @param $is_open
|
||||
* @return mixed
|
||||
*/
|
||||
public function setTimerStatus($id, $is_open)
|
||||
{
|
||||
$this->services->setTimerStatus($id, $is_open);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含删除表,删除表数据,删除文件,修改文件内容以及后缀,执行命令等操作的关键词
|
||||
* @param $code
|
||||
* @return bool
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/6
|
||||
*/
|
||||
function isSafePhpCode($code)
|
||||
{
|
||||
// 检查是否包含删除表,删除表数据,删除文件,修改文件内容以及后缀,执行命令等操作的关键词
|
||||
$dangerous_keywords = array(
|
||||
'delete',
|
||||
'destroy',
|
||||
'DROP TABLE',
|
||||
'DELETE FROM',
|
||||
'unlink(',
|
||||
'fwrite(',
|
||||
'shell_exec(',
|
||||
'exec(',
|
||||
'system(',
|
||||
'passthru('
|
||||
);
|
||||
foreach ($dangerous_keywords as $keyword) {
|
||||
if (strpos($code, $keyword) !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true; // 如果通过所有安全检查,返回 true
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,6 +11,7 @@
|
||||
namespace app\adminapi\controller\v1\system;
|
||||
|
||||
use think\facade\App;
|
||||
use think\facade\Db;
|
||||
use think\facade\Session;
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemDatabackupServices;
|
||||
@ -49,16 +50,57 @@ class SystemDatabackup extends AuthController
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
$tablename = request()->param('tablename', '', 'htmlspecialchars');
|
||||
[$tablename] = $this->request->getMore([
|
||||
['tablename', ''],
|
||||
], true);
|
||||
return app('json')->success($this->services->getRead($tablename));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据表或者表字段备注
|
||||
* @return \think\Response
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/04/11
|
||||
*/
|
||||
public function updateMark()
|
||||
{
|
||||
[$table, $field, $type, $mark, $is_field] = $this->request->postMore([
|
||||
['table', ''],
|
||||
['field', ''],
|
||||
['type', ''],
|
||||
['mark', ''],
|
||||
['is_field', 0],
|
||||
], true);
|
||||
if ($is_field == 0) {
|
||||
$sql = "ALTER TABLE $table COMMENT '$mark'";
|
||||
} else {
|
||||
$fieldInfo = Db::query("SHOW FULL COLUMNS FROM `{$table}` WHERE Field = '{$field}'");
|
||||
$sql = "ALTER TABLE $table MODIFY COLUMN ";
|
||||
$sql .= $field . ' ' . $type . ' ';
|
||||
if ($fieldInfo[0]['Null'] == 'NO') {
|
||||
$sql .= 'NOT NULL ';
|
||||
if (!is_null($fieldInfo[0]['Default'])) {
|
||||
$sql .= "DEFAULT '" . $fieldInfo[0]['Default'] . "' ";
|
||||
}
|
||||
}
|
||||
if ($fieldInfo[0]['Extra']) {
|
||||
$sql .= $fieldInfo[0]['Extra'] . ' ';
|
||||
}
|
||||
$sql .= "COMMENT '$mark'";
|
||||
}
|
||||
Db::execute($sql);
|
||||
return app('json')->success(100024);
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化表
|
||||
*/
|
||||
public function optimize()
|
||||
{
|
||||
$tables = $this->request->param('tables', '', 'htmlspecialchars');
|
||||
[$tables] = $this->request->postMore([
|
||||
['tables', ''],
|
||||
], true);
|
||||
$res = $this->services->getDbBackup()->optimize($tables);
|
||||
return app('json')->success($res ? 100047 : 100048);
|
||||
}
|
||||
@ -68,7 +110,9 @@ class SystemDatabackup extends AuthController
|
||||
*/
|
||||
public function repair()
|
||||
{
|
||||
$tables = $this->request->param('tables', '', 'htmlspecialchars');
|
||||
[$tables] = $this->request->postMore([
|
||||
['tables', ''],
|
||||
], true);
|
||||
$res = $this->services->getDbBackup()->repair($tables);
|
||||
return app('json')->success($res ? 100049 : 100050);
|
||||
}
|
||||
@ -78,7 +122,9 @@ class SystemDatabackup extends AuthController
|
||||
*/
|
||||
public function backup()
|
||||
{
|
||||
$tables = $this->request->param('tables', '', 'htmlspecialchars');
|
||||
[$tables] = $this->request->postMore([
|
||||
['tables', ''],
|
||||
], true);
|
||||
$data = $this->services->backup($tables);
|
||||
return app('json')->success(100051);
|
||||
}
|
||||
|
||||
157
crmeb/app/adminapi/controller/v1/system/SystemEvent.php
Normal file
157
crmeb/app/adminapi/controller/v1/system/SystemEvent.php
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\system;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemEventServices;
|
||||
use think\facade\App;
|
||||
use think\facade\Env;
|
||||
|
||||
class SystemEvent extends AuthController
|
||||
{
|
||||
public function __construct(App $app, SystemEventServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定事件类型
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function getMarkList()
|
||||
{
|
||||
return app('json')->success($this->services->getMarkList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定事件列表
|
||||
* @return \think\Response
|
||||
* @throws \ReflectionException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function getEventList()
|
||||
{
|
||||
return app('json')->success($this->services->getEventList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定事件详情
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function getEventInfo($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
return app('json')->success($this->services->getEventInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定事件添加编辑
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function saveEvent()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['id', 0],
|
||||
['name', ''],
|
||||
['mark', ''],
|
||||
['content', ''],
|
||||
['is_open', 0],
|
||||
['customCode', ''],
|
||||
['password', ''],
|
||||
]);
|
||||
if ($data['name'] == '') return app('json')->fail('请填写事件名称');
|
||||
if ($data['mark'] == '') return app('json')->fail('请选择事件类型');
|
||||
if (!Env::get('app_debug', false)) return app('json')->fail('生产环境下无法新增和修改自定义内容,如需修改请修改.env文件中app_debug项为true');
|
||||
if ($data['password'] === '') return app('json')->fail('密码不能为空');
|
||||
if (config('filesystem.password') !== $data['password']) return app('json')->fail('密码错误');
|
||||
$adminInfo = $this->request->adminInfo();
|
||||
if (!$adminInfo) return app('json')->fail('非法操作');
|
||||
if ($adminInfo['level'] != 0) return app('json')->fail('仅超级管理员可以操作定时任务');
|
||||
if (!$this->isSafePhpCode($data['customCode'])) return app('json')->fail('自定义内容存在危险代码,请检查代码');
|
||||
$this->services->saveEvent($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含删除表,删除表数据,删除文件,修改文件内容以及后缀,执行命令等操作的关键词
|
||||
* @param $code
|
||||
* @return bool
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
function isSafePhpCode($code)
|
||||
{
|
||||
// 检查是否包含删除表,删除表数据,删除文件,修改文件内容以及后缀,执行命令等操作的关键词
|
||||
$dangerous_keywords = [
|
||||
'delete',
|
||||
'destroy',
|
||||
'DROP TABLE',
|
||||
'DELETE FROM',
|
||||
'unlink(',
|
||||
'fwrite(',
|
||||
'shell_exec(',
|
||||
'exec(',
|
||||
'system(',
|
||||
'passthru('
|
||||
];
|
||||
foreach ($dangerous_keywords as $keyword) {
|
||||
if (strpos($code, $keyword) !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true; // 如果通过所有安全检查,返回 true
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定事件是否开启开关
|
||||
* @param $id
|
||||
* @param $is_open
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function setEventStatus($id, $is_open)
|
||||
{
|
||||
$this->services->setEventStatus($id, $is_open);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除自定事件
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/6/7
|
||||
*/
|
||||
public function delEvent($id)
|
||||
{
|
||||
if (!$id) return app('json')->fail('参数错误');
|
||||
$this->services->eventDel($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
}
|
||||
@ -69,7 +69,36 @@ class SystemFile extends AuthController
|
||||
//打开目录
|
||||
public function opendir()
|
||||
{
|
||||
return app('json')->success($this->services->opendir());
|
||||
[$dir, $fileDir, $superior] = $this->request->getMore([
|
||||
['dir', ''],
|
||||
['filedir', ''],
|
||||
['superior', ''],
|
||||
], true);
|
||||
return app('json')->success($this->services->opendir($dir, $fileDir, $superior));
|
||||
}
|
||||
|
||||
//文件备注
|
||||
public function fileMark()
|
||||
{
|
||||
[$path, $fileToken] = $this->request->postMore([
|
||||
['path', ''],
|
||||
['fileToken', ''],
|
||||
], true);
|
||||
if ($path == '') return app('json')->fail(100100);
|
||||
return app('json')->success($this->services->markForm($path, $fileToken));
|
||||
}
|
||||
|
||||
//文件备注保存
|
||||
public function fileMarkSave()
|
||||
{
|
||||
[$full_path, $mark] = $this->request->postMore([
|
||||
['full_path', ''],
|
||||
['mark', ''],
|
||||
], true);
|
||||
$full_path = $this->request->param('full_path');
|
||||
if ($full_path == '') return app('json')->fail(100100);
|
||||
$this->services->fileMarkSave($full_path, $mark);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
//读取文件
|
||||
@ -86,7 +115,7 @@ class SystemFile extends AuthController
|
||||
$comment = $this->request->param('comment');
|
||||
$filepath = $this->request->param('filepath');
|
||||
if (empty($filepath)) {
|
||||
return app('json')->fail(410087);
|
||||
return app('json')->fail('文件路径不存在');
|
||||
}
|
||||
$res = $this->services->savefile($filepath, $comment);
|
||||
if ($res) {
|
||||
|
||||
88
crmeb/app/adminapi/controller/v1/system/SystemTicket.php
Normal file
88
crmeb/app/adminapi/controller/v1/system/SystemTicket.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\system;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\SystemTicketServices;
|
||||
use think\facade\App;
|
||||
|
||||
class SystemTicket extends AuthController
|
||||
{
|
||||
public function __construct(App $app, SystemTicketServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function ticketList()
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['type', 0],
|
||||
['keyword', ''],
|
||||
]);
|
||||
return app('json')->success($this->services->ticketList($where));
|
||||
}
|
||||
|
||||
public function ticketForm($id)
|
||||
{
|
||||
return app('json')->success($this->services->ticketForm($id));
|
||||
}
|
||||
|
||||
public function ticketSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['print_name', ''],
|
||||
['type', 0],
|
||||
['yly_user_id', ''],
|
||||
['yly_app_id', ''],
|
||||
['yly_app_secret', ''],
|
||||
['yly_sn', ''],
|
||||
['fey_user', ''],
|
||||
['fey_ukey', ''],
|
||||
['fey_sn', ''],
|
||||
['times', 1],
|
||||
['print_type', 1],
|
||||
['status', 1],
|
||||
]);
|
||||
$this->services->ticketSave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
|
||||
public function ticketSetStatus($id, $status)
|
||||
{
|
||||
$this->services->ticketSetStatus($id, $status);
|
||||
return app('json')->success('修改成功');
|
||||
}
|
||||
|
||||
public function ticketDel($id)
|
||||
{
|
||||
$this->services->ticketDel($id);
|
||||
return app('json')->success('删除成功');
|
||||
}
|
||||
|
||||
public function ticketContent($id)
|
||||
{
|
||||
return app('json')->success($this->services->ticketContent($id));
|
||||
}
|
||||
|
||||
public function ticketContentSave($id)
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['header', 0],
|
||||
['delivery', 0],
|
||||
['buyer_remarks', 0],
|
||||
['goods', []],
|
||||
['freight', 0],
|
||||
['preferential', 0],
|
||||
['pay', []],
|
||||
['custom', 0],
|
||||
['order', []],
|
||||
['code', 0],
|
||||
['code_url', ''],
|
||||
['show_notice', 0],
|
||||
['notice_content', '']
|
||||
]);
|
||||
$this->services->ticketContentSave($id, $data);
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\adminapi\controller\v1\system;
|
||||
|
||||
use app\adminapi\controller\AuthController;
|
||||
use app\services\system\timer\SystemTimerServices;
|
||||
use think\facade\App;
|
||||
|
||||
class SystemTimer extends AuthController
|
||||
{
|
||||
public function __construct(App $app, SystemTimerServices $services)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务列表
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTimerList()
|
||||
{
|
||||
$where = ['is_del' => 0];
|
||||
return app('json')->success($this->services->getTimerList($where));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务详情
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTimerInfo($id)
|
||||
{
|
||||
return app('json')->success($this->services->getTimerInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMarkList()
|
||||
{
|
||||
return app('json')->success($this->services->getMarkList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存定时任务
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveTimer()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['id', 0],
|
||||
['name', ''],
|
||||
['mark', ''],
|
||||
['content', ''],
|
||||
['type', 0],
|
||||
['is_open', 0],
|
||||
['week', 0],
|
||||
['day', 0],
|
||||
['hour', 0],
|
||||
['minute', 0],
|
||||
['second', 0],
|
||||
]);
|
||||
$this->services->saveTimer($data);
|
||||
return app('json')->success(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function delTimer($id)
|
||||
{
|
||||
$this->services->delTimer($id);
|
||||
return app('json')->success(100002);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置定时任务状态
|
||||
* @param $id
|
||||
* @param $is_open
|
||||
* @return mixed
|
||||
*/
|
||||
public function setTimerStatus($id, $is_open)
|
||||
{
|
||||
$this->services->setTimerStatus($id, $is_open);
|
||||
return app('json')->success(100014);
|
||||
}
|
||||
|
||||
}
|
||||
@ -10,8 +10,10 @@
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\adminapi\controller\v1\user;
|
||||
|
||||
use app\services\system\config\SystemConfigServices;
|
||||
use app\services\user\UserServices;
|
||||
use app\adminapi\controller\AuthController;
|
||||
use crmeb\services\CacheService;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\App;
|
||||
|
||||
@ -55,8 +57,16 @@ class User extends AuthController
|
||||
['label_id', ''],
|
||||
['now_money', 'normal'],
|
||||
['field_key', ''],
|
||||
['isMember', '']
|
||||
['isMember', ''],
|
||||
['balance', []],
|
||||
['integral', []],
|
||||
['before_pay_time', ''],
|
||||
['pay_count_num', []],
|
||||
['pay_count_money', []],
|
||||
['recharge_count', []],
|
||||
['agent_level', 0],
|
||||
]);
|
||||
$where['label_id'] = toIntArray($where['label_id']);
|
||||
return app('json')->success($this->services->index($where));
|
||||
}
|
||||
|
||||
@ -123,20 +133,19 @@ class User extends AuthController
|
||||
if ($data['card_id']) {
|
||||
if (!check_card($data['card_id'])) return app('json')->fail(400315);
|
||||
}
|
||||
if ($data['pwd']) {
|
||||
if (!$data['true_pwd']) {
|
||||
return app('json')->fail(400263);
|
||||
}
|
||||
if ($data['pwd'] != $data['true_pwd']) {
|
||||
return app('json')->fail(400264);
|
||||
}
|
||||
if (strlen($data['pwd']) < 6 || strlen($data['pwd']) > 32) {
|
||||
return app('json')->fail(400762);
|
||||
}
|
||||
$data['pwd'] = md5($data['pwd']);
|
||||
} else {
|
||||
unset($data['pwd']);
|
||||
if (!$data['pwd']) {
|
||||
return app('json')->fail(400256);
|
||||
}
|
||||
if (!$data['true_pwd']) {
|
||||
return app('json')->fail(400263);
|
||||
}
|
||||
if ($data['pwd'] != $data['true_pwd']) {
|
||||
return app('json')->fail(400264);
|
||||
}
|
||||
if (strlen($data['pwd']) < 6 || strlen($data['pwd']) > 32) {
|
||||
return app('json')->fail(400762);
|
||||
}
|
||||
$data['pwd'] = md5($data['pwd']);
|
||||
unset($data['true_pwd']);
|
||||
$data['avatar'] = sys_config('h5_avatar');
|
||||
$data['adminId'] = $this->adminId;
|
||||
@ -171,6 +180,9 @@ class User extends AuthController
|
||||
* 获取用户账户详情
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
@ -195,6 +207,9 @@ class User extends AuthController
|
||||
* 执行赠送会员等级
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function save_give_level($id)
|
||||
{
|
||||
@ -209,6 +224,7 @@ class User extends AuthController
|
||||
* 赠送付费会员时长表单
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
*/
|
||||
public function give_level_time($id)
|
||||
{
|
||||
@ -220,6 +236,9 @@ class User extends AuthController
|
||||
* 执行赠送付费会员时长
|
||||
* @param $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function save_give_level_time($id)
|
||||
{
|
||||
@ -306,10 +325,10 @@ class User extends AuthController
|
||||
* @return mixed
|
||||
* @throws \FormBuilder\Exception\FormBuilderException
|
||||
*/
|
||||
public function edit_other($id)
|
||||
public function edit_other($id, $type)
|
||||
{
|
||||
if (!$id) return app('json')->fail(100026);
|
||||
return app('json')->success($this->services->editOther((int)$id));
|
||||
return app('json')->success($this->services->editOther((int)$id, $type));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,9 +398,18 @@ class User extends AuthController
|
||||
['spread_open', 1]
|
||||
]);
|
||||
if (!$id) return app('json')->fail(100100);
|
||||
if (!$data['real_name']) {
|
||||
return app('json')->fail(410245);
|
||||
}
|
||||
if (!$data['phone']) {
|
||||
return app('json')->fail(410245);
|
||||
}
|
||||
if ($data['phone']) {
|
||||
if (!preg_match("/^1[3456789]\d{9}$/", $data['phone'])) return app('json')->fail(400252);
|
||||
}
|
||||
if ($this->services->count(['phone' => $data['phone'], 'is_del' => 0, 'not_uid' => $id])) {
|
||||
return app('json')->fail(400314);
|
||||
}
|
||||
if ($data['card_id']) {
|
||||
if (!check_card($data['card_id'])) return app('json')->fail(400315);
|
||||
}
|
||||
@ -431,4 +459,42 @@ class User extends AuthController
|
||||
return app('json')->success(400318);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新人礼
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/9/21
|
||||
*/
|
||||
public function getNewGift()
|
||||
{
|
||||
$data = [
|
||||
'reward_money' => intval(sys_config('reward_money')),
|
||||
'reward_integral' => intval(sys_config('reward_integral')),
|
||||
'reward_coupon' => sys_config('reward_coupon') == '' ? [] : sys_config('reward_coupon')
|
||||
];
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存新人礼
|
||||
* @return \think\Response
|
||||
* @author wuhaotian
|
||||
* @email 442384644@qq.com
|
||||
* @date 2024/9/21
|
||||
*/
|
||||
public function saveNewGift()
|
||||
{
|
||||
$data = $this->request->postMore([
|
||||
['reward_money', 0],
|
||||
['reward_integral', 0],
|
||||
['reward_coupon', '']
|
||||
]);
|
||||
$configServices = app()->make(SystemConfigServices::class);
|
||||
foreach ($data as $k => $v) {
|
||||
$configServices->update($k, ['value' => json_encode($v)], 'menu_name');
|
||||
}
|
||||
CacheService::clear();
|
||||
return app('json')->success('保存成功');
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +37,13 @@ class UserLabel extends AuthController
|
||||
|
||||
/**
|
||||
* 标签列表
|
||||
* @param int $label_cate
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index($label_cate = 0)
|
||||
public function index($label_cate = '')
|
||||
{
|
||||
return app('json')->success($this->services->getList(['label_cate' => $label_cate]));
|
||||
}
|
||||
@ -60,8 +64,10 @@ class UserLabel extends AuthController
|
||||
|
||||
/**
|
||||
* 保存标签表单数据
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
|
||||
@ -43,14 +43,13 @@ class MemberCardBatch extends AuthController
|
||||
{
|
||||
$where = $this->request->getMore([
|
||||
['title', ''],
|
||||
// ['page', 1],
|
||||
// ['limit', 20],
|
||||
]);
|
||||
$data = $this->services->getList($where);
|
||||
return app('json')->success($data);
|
||||
}
|
||||
|
||||
/** 保存卡片资源
|
||||
/**
|
||||
* 保存卡片资源
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
@ -25,21 +25,34 @@ use crmeb\services\CacheService;
|
||||
*/
|
||||
class AdminAuthTokenMiddleware implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author 吴汐
|
||||
* @email 442384644@qq.com
|
||||
* @date 2023/04/07
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
$authInfo = null;
|
||||
$token = trim(ltrim($request->header(Config::get('cookie.token_name', 'Authori-zation')), 'Bearer'));
|
||||
if (!$token) {
|
||||
$token = trim(ltrim($request->get('token')));
|
||||
}
|
||||
/** @var AdminAuthServices $service */
|
||||
$service = app()->make(AdminAuthServices::class);
|
||||
$adminInfo = $service->parseToken($token);
|
||||
Request::macro('isAdminLogin', function () use (&$adminInfo) {
|
||||
$request->macro('isAdminLogin', function () use (&$adminInfo) {
|
||||
return !is_null($adminInfo);
|
||||
});
|
||||
Request::macro('adminId', function () use (&$adminInfo) {
|
||||
$request->macro('adminId', function () use (&$adminInfo) {
|
||||
return $adminInfo['id'];
|
||||
});
|
||||
|
||||
Request::macro('adminInfo', function () use (&$adminInfo) {
|
||||
$request->macro('adminInfo', function () use (&$adminInfo) {
|
||||
return $adminInfo;
|
||||
});
|
||||
|
||||
|
||||
@ -14,66 +14,106 @@ use think\facade\Route;
|
||||
* 分销管理 相关路由
|
||||
*/
|
||||
Route::group('agent', function () {
|
||||
//推销员列表
|
||||
Route::get('index', 'v1.agent.AgentManage/index')->option(['real_name' => '分销员列表']);
|
||||
//修改上级推广人
|
||||
Route::put('spread', 'v1.agent.AgentManage/editSpread')->option(['real_name' => '修改上级推广人']);
|
||||
//头部统计
|
||||
Route::get('statistics', 'v1.agent.AgentManage/get_badge')->option(['real_name' => '分销员列表头部统计']);
|
||||
//推广人列表
|
||||
Route::get('stair', 'v1.agent.AgentManage/get_stair_list')->option(['real_name' => '推广人列表']);
|
||||
//推广人头部统计
|
||||
// Route::get('stair/statistics', 'v1.agent.AgentManage/get_stair_badge')->option(['real_name' => '推广人头部统计']);
|
||||
//统计推广订单列表
|
||||
Route::get('stair/order', 'v1.agent.AgentManage/get_stair_order_list')->option(['real_name' => '推广订单列表']);
|
||||
//统计推广订单列表头部
|
||||
// Route::get('stair/order/statistics', 'v1.agent.AgentManage/get_stair_order_badge')->option(['real_name' => '推广订单列表头部']);
|
||||
//清除上级推广人
|
||||
Route::put('stair/delete_spread/:uid', 'v1.agent.AgentManage/delete_spread')->option(['real_name' => '清除上级推广人']);
|
||||
//取消推广资格
|
||||
Route::put('stair/delete_system_spread/:uid', 'v1.agent.AgentManage/delete_system_spread')->option(['real_name' => '取消推广资格']);
|
||||
//查看公众号推广二维码
|
||||
Route::get('look_code', 'v1.agent.AgentManage/look_code')->option(['real_name' => '查看公众号推广二维码']);
|
||||
//查看小程序推广二维码
|
||||
Route::get('look_xcx_code', 'v1.agent.AgentManage/look_xcx_code')->option(['real_name' => '查看小程序推广二维码']);
|
||||
//查看H5推广二维码
|
||||
Route::get('look_h5_code', 'v1.agent.AgentManage/look_h5_code')->option(['real_name' => '查看H5推广二维码']);
|
||||
//积分配置编辑表单
|
||||
Route::get('config/edit_basics', 'v1.setting.SystemConfig/edit_basics')->option(['real_name' => '积分配置编辑表单']);
|
||||
//积分配置保存数据
|
||||
Route::post('config/save_basics', 'v1.setting.SystemConfig/save_basics')->option(['real_name' => '积分配置保存数据']);
|
||||
|
||||
//分销员等级资源路由
|
||||
Route::resource('level', 'v1.agent.AgentLevel')->name('AgentLevelResource')->option(['real_name' => '分销员等级']);
|
||||
//修改分销等级状态
|
||||
Route::put('level/set_status/:id/:status', 'v1.agent.AgentLevel/set_status')->name('levelSetStatus')->option(['real_name' => '修改分销等级状态']);
|
||||
//分销员等级任务资源路由
|
||||
Route::resource('level_task', 'v1.agent.AgentLevelTask')->name('AgentLevelTaskResource')->option(['real_name' => '分销员等级任务']);
|
||||
//修改分销任务状态
|
||||
Route::put('level_task/set_status/:id/:status', 'v1.agent.AgentLevelTask/set_status')->name('levelTaskSetStatus')->option(['real_name' => '修改分销等级任务状态']);
|
||||
//获取赠送分销等级表单
|
||||
Route::get('get_level_form', 'v1.agent.AgentManage/getLevelForm')->name('getLevelForm')->option(['real_name' => '获取赠送分销等级表单']);
|
||||
//赠送分销等级
|
||||
Route::post('give_level', 'v1.agent.AgentManage/giveAgentLevel')->name('giveAgentLevel')->option(['real_name' => '赠送分销等级']);
|
||||
/** 分销员管理 */
|
||||
Route::group(function () {
|
||||
//推销员列表
|
||||
Route::get('index', 'v1.agent.AgentManage/index')->option(['real_name' => '分销员列表']);
|
||||
//修改上级推广人
|
||||
Route::put('spread', 'v1.agent.AgentManage/editSpread')->option(['real_name' => '修改上级推广人']);
|
||||
//头部统计
|
||||
Route::get('statistics', 'v1.agent.AgentManage/get_badge')->option(['real_name' => '分销员列表头部统计']);
|
||||
//推广人列表
|
||||
Route::get('stair', 'v1.agent.AgentManage/get_stair_list')->option(['real_name' => '推广人列表']);
|
||||
//统计推广订单列表
|
||||
Route::get('stair/order', 'v1.agent.AgentManage/get_stair_order_list')->option(['real_name' => '推广订单列表']);
|
||||
//清除上级推广人
|
||||
Route::put('stair/delete_spread/:uid', 'v1.agent.AgentManage/delete_spread')->option(['real_name' => '清除上级推广人']);
|
||||
//取消推广资格
|
||||
Route::put('stair/delete_system_spread/:uid', 'v1.agent.AgentManage/delete_system_spread')->option(['real_name' => '取消推广资格']);
|
||||
//查看公众号推广二维码
|
||||
Route::get('look_code', 'v1.agent.AgentManage/look_code')->option(['real_name' => '查看公众号推广二维码']);
|
||||
//查看小程序推广二维码
|
||||
Route::get('look_xcx_code', 'v1.agent.AgentManage/look_xcx_code')->option(['real_name' => '查看小程序推广二维码']);
|
||||
//查看H5推广二维码
|
||||
Route::get('look_h5_code', 'v1.agent.AgentManage/look_h5_code')->option(['real_name' => '查看H5推广二维码']);
|
||||
})->option(['parent' => 'agent', 'cate_name' => '分销员管理']);
|
||||
|
||||
/** 分销设置 */
|
||||
Route::group(function () {
|
||||
//分销配置编辑表单
|
||||
Route::get('config/edit_basics', 'v1.setting.SystemConfig/edit_basics')->option(['real_name' => '积分配置编辑表单']);
|
||||
//分销配置保存数据
|
||||
Route::post('config/save_basics', 'v1.setting.SystemConfig/save_basics')->option(['real_name' => '积分配置保存数据']);
|
||||
})->option(['parent' => 'agent', 'cate_name' => '分销设置']);
|
||||
|
||||
/** 分销等级 */
|
||||
Route::group(function () {
|
||||
//分销员等级资源路由
|
||||
Route::resource('level', 'v1.agent.AgentLevel')->except(['read'])->name('AgentLevel')->option([
|
||||
'real_name' => [
|
||||
'index' => '获取分销员等级列表',
|
||||
'create' => '获取分销员等级表单',
|
||||
'save' => '保存分销员等级',
|
||||
'edit' => '获取修改分销员等级表单',
|
||||
'update' => '修改分销员等级',
|
||||
'delete' => '删除分销员等级'
|
||||
]
|
||||
]);
|
||||
//修改分销等级状态
|
||||
Route::put('level/set_status/:id/:status', 'v1.agent.AgentLevel/set_status')->name('levelSetStatus')->option(['real_name' => '修改分销等级状态']);
|
||||
//分销员等级任务资源路由
|
||||
Route::resource('level_task', 'v1.agent.AgentLevelTask')->except(['read'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取分销员等级任务列表',
|
||||
'create' => '获取分销员等级任务表单',
|
||||
'save' => '保存分销员等级任务',
|
||||
'edit' => '获取修改分销员等级任务表单',
|
||||
'update' => '修改分销员等级任务',
|
||||
'delete' => '删除分销员等级任务'
|
||||
]
|
||||
]);
|
||||
//修改分销任务状态
|
||||
Route::put('level_task/set_status/:id/:status', 'v1.agent.AgentLevelTask/set_status')->name('levelTaskSetStatus')->option(['real_name' => '修改分销等级任务状态']);
|
||||
//获取赠送分销等级表单
|
||||
Route::get('get_level_form', 'v1.agent.AgentManage/getLevelForm')->name('getLevelForm')->option(['real_name' => '获取赠送分销等级表单']);
|
||||
//赠送分销等级
|
||||
Route::post('give_level', 'v1.agent.AgentManage/giveAgentLevel')->name('giveAgentLevel')->option(['real_name' => '赠送分销等级']);
|
||||
//设置任务完成数量表单
|
||||
Route::get('get_task_num_form/:id', 'v1.agent.AgentLevel/getTaskNumForm')->name('getTaskNumForm')->option(['real_name' => '获取任务完成数量表单']);
|
||||
//设置完成任务数量
|
||||
Route::post('set_task_num/:id', 'v1.agent.AgentLevel/setTaskNum')->name('setTaskNum')->option(['real_name' => '设置完成任务数量']);
|
||||
})->option(['parent' => 'agent', 'cate_name' => '分销等级']);
|
||||
|
||||
/** 事业部 */
|
||||
Route::get('division/list', 'v1.agent.Division/divisionList')->name('divisionList')->option(['real_name' => '事业部列表']);//事业部/代理商/员工列表
|
||||
Route::get('division/down_list', 'v1.agent.Division/divisionDownList')->name('divisionDownList')->option(['real_name' => '下级列表']);//下级列表
|
||||
Route::get('division/create/:uid', 'v1.agent.Division/divisionCreate')->name('divisionCreate')->option(['real_name' => '添加事业部']);//添加事业部
|
||||
Route::post('division/save', 'v1.agent.Division/divisionSave')->name('divisionSave')->option(['real_name' => '事业部保存']);//事业部保存
|
||||
Route::get('division/agent/create/:uid', 'v1.agent.Division/divisionAgentCreate')->name('divisionAgentCreate')->option(['real_name' => '添加事业部']);//添加代理商
|
||||
Route::post('division/agent/save', 'v1.agent.Division/divisionAgentSave')->name('divisionAgentSave')->option(['real_name' => '事业部保存']);//代理商保存
|
||||
Route::put('division/set_status/:status/:uid', 'v1.agent.Division/setDivisionStatus')->name('setDivisionStatus')->option(['real_name' => '状态切换']);//状态切换
|
||||
Route::delete('division/del/:type/:uid', 'v1.agent.Division/delDivision')->name('delDivision')->option(['real_name' => '删除代理商']);//状态切换
|
||||
Route::get('division/agent_apply/list','v1.agent.Division/AdminApplyList')->name('AdminApplyList')->option(['real_name'=>'代理商申请列表']);//代理商申请列表
|
||||
Route::get('division/examine_apply/:id/:type','v1.agent.Division/examineApply')->name('examineApply')->option(['real_name'=>'审核表单']);//审核表单
|
||||
Route::post('division/apply_agent/save','v1.agent.Division/applyAgentSave')->name('applyAgentSave')->option(['real_name'=>'提交审核']);//提交审核
|
||||
Route::delete('division/del_apply/:id','v1.agent.Division/delApply')->name('delApply')->option(['real_name'=>'删除审核']);//删除审核
|
||||
Route::group(function () {
|
||||
Route::get('division/list', 'v1.agent.Division/divisionList')->name('divisionList')->option(['real_name' => '事业部列表']);//事业部/代理商/员工列表
|
||||
Route::get('division/down_list', 'v1.agent.Division/divisionDownList')->name('divisionDownList')->option(['real_name' => '下级列表']);//下级列表
|
||||
Route::get('division/create/:uid', 'v1.agent.Division/divisionCreate')->name('divisionCreate')->option(['real_name' => '添加事业部']);//添加事业部
|
||||
Route::post('division/save', 'v1.agent.Division/divisionSave')->name('divisionSave')->option(['real_name' => '事业部保存']);//事业部保存
|
||||
Route::get('division/agent/create/:uid', 'v1.agent.Division/divisionAgentCreate')->name('divisionAgentCreate')->option(['real_name' => '添加事业部']);//添加代理商
|
||||
Route::post('division/agent/save', 'v1.agent.Division/divisionAgentSave')->name('divisionAgentSave')->option(['real_name' => '事业部保存']);//代理商保存
|
||||
Route::put('division/set_status/:status/:uid', 'v1.agent.Division/setDivisionStatus')->name('setDivisionStatus')->option(['real_name' => '状态切换']);//状态切换
|
||||
Route::delete('division/del/:type/:uid', 'v1.agent.Division/delDivision')->name('delDivision')->option(['real_name' => '删除代理商']);//状态切换
|
||||
Route::get('division/staff/create/:uid', 'v1.agent.Division/divisionStaffCreate')->name('divisionStaffCreate')->option(['real_name' => '添加事业部']);//添加代理商
|
||||
Route::post('division/staff/save', 'v1.agent.Division/divisionStaffSave')->name('divisionStaffSave')->option(['real_name' => '事业部保存']);//代理商保存
|
||||
Route::get('division/agent_apply/list', 'v1.agent.Division/AdminApplyList')->name('AdminApplyList')->option(['real_name' => '代理商申请列表']);//代理商申请列表
|
||||
Route::get('division/examine_apply/:id/:type', 'v1.agent.Division/examineApply')->name('examineApply')->option(['real_name' => '审核表单']);//审核表单
|
||||
Route::post('division/apply_agent/save', 'v1.agent.Division/applyAgentSave')->name('applyAgentSave')->option(['real_name' => '提交审核']);//提交审核
|
||||
Route::delete('division/del_apply/:id', 'v1.agent.Division/delApply')->name('delApply')->option(['real_name' => '删除审核']);//删除审核
|
||||
Route::get('division/statistics', 'v1.agent.Division/divisionStatistics')->name('divisionStatistics')->option(['real_name' => '事业部统计']);//事业部统计
|
||||
})->option(['parent' => 'agent', 'cate_name' => '事业部']);
|
||||
|
||||
/** 分销员申请 */
|
||||
Route::group(function () {
|
||||
Route::get('spread/apply/list', 'v1.agent.SpreadApply/applyList')->name('applyList')->option(['real_name' => '分销员申请列表']);
|
||||
Route::post('spread/apply/examine/:id/:uid/:status', 'v1.agent.SpreadApply/applyExamine')->name('applyExamine')->option(['real_name' => '分销员审核']);
|
||||
Route::delete('spread/apply/del/:id', 'v1.agent.SpreadApply/applyDelete')->name('applyDelete')->option(['real_name' => '删除分销员申请']);
|
||||
})->option(['parent' => 'agent', 'cate_name' => '分销员申请']);
|
||||
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'agent', 'mark_name' => '分销模块']);
|
||||
|
||||
@ -14,101 +14,145 @@ use think\facade\Route;
|
||||
* 应用模块 相关路由
|
||||
*/
|
||||
Route::group('app', function () {
|
||||
//小程序模板资源路由
|
||||
Route::resource('routine', 'v1.application.routine.RoutineTemplate')->name('RoutineResource')->option(['real_name' => '小程序订阅消息']);
|
||||
//一键同步订阅消息
|
||||
Route::get('routine/syncSubscribe', 'v1.application.routine.RoutineTemplate/syncSubscribe')->name('syncSubscribe')->option(['real_name' => '一键同步订阅消息']);
|
||||
//一键同步微信模版消息消息
|
||||
Route::get('wechat/syncSubscribe', 'v1.application.wechat.WechatTemplate/syncSubscribe')->name('syncSubscribe')->option(['real_name' => '一键同步模版消息']);
|
||||
//修改状态
|
||||
Route::put('routine/set_status/:id/:status', 'v1.application.routine.RoutineTemplate/set_status')->name('RoutineSetStatus')->option(['real_name' => '修改订阅消息状态']);
|
||||
//菜单值
|
||||
Route::get('wechat/menu', 'v1.application.wechat.menus/index')->option(['real_name' => '微信公众号菜单列表']);
|
||||
//保存菜单
|
||||
Route::post('wechat/menu', 'v1.application.wechat.menus/save')->option(['real_name' => '保存微信公众号菜单']);
|
||||
//微信模板消息资源路由
|
||||
Route::resource('wechat/template', 'v1.application.wechat.WechatTemplate')->name('WechatTemplateResource')->option(['real_name' => '公众号模版消息']);
|
||||
//微信模板消息修改状态
|
||||
Route::put('wechat/template/set_status/:id/:status', 'v1.application.wechat.WechatTemplate/set_status')->name('WechatTemplateSetStatus')->option(['real_name' => '修改关键字回复状态']);
|
||||
//关注回复
|
||||
Route::get('wechat/reply', 'v1.application.wechat.Reply/reply')->option(['real_name' => '关注回复']);
|
||||
//获取关注回复二维码
|
||||
Route::get('wechat/code_reply/:id', 'v1.application.wechat.Reply/code_reply')->option(['real_name' => '获取关注回复二维码']);
|
||||
//关键字回复列表
|
||||
Route::get('wechat/keyword', 'v1.application.wechat.Reply/index')->option(['real_name' => '关键字回复列表']);
|
||||
//关键字详情
|
||||
Route::get('wechat/keyword/:id', 'v1.application.wechat.Reply/read')->option(['real_name' => '关键字回复详情']);
|
||||
//保存关键字修改
|
||||
Route::post('wechat/keyword/:id', 'v1.application.wechat.Reply/save')->option(['real_name' => '保存关键字回复']);
|
||||
//删除关键字
|
||||
Route::delete('wechat/keyword/:id', 'v1.application.wechat.Reply/delete')->option(['real_name' => '删除关键字回复']);
|
||||
//修改关键字状态
|
||||
Route::put('wechat/keyword/set_status/:id/:status', 'v1.application.wechat.Reply/set_status')->option(['real_name' => '修改关键字回复状态']);
|
||||
//图文列表
|
||||
Route::get('wechat/news', 'v1.application.wechat.WechatNewsCategory/index')->option(['real_name' => '图文列表']);
|
||||
//详情
|
||||
Route::get('wechat/news/:id', 'v1.application.wechat.WechatNewsCategory/read')->option(['real_name' => '图文详情']);
|
||||
//保存图文
|
||||
Route::post('wechat/news', 'v1.application.wechat.WechatNewsCategory/save')->option(['real_name' => '保存图文']);
|
||||
//删除图文
|
||||
Route::delete('wechat/news/:id', 'v1.application.wechat.WechatNewsCategory/delete')->option(['real_name' => '删除图文']);
|
||||
//发送图文消息
|
||||
Route::post('wechat/push', 'v1.application.wechat.WechatNewsCategory/push')->option(['real_name' => '发送图文消息']);
|
||||
//用户行为列表
|
||||
Route::get('wechat/action', 'v1.application.wechat.WechatMessage/index')->option(['real_name' => '用户行为列表']);
|
||||
//用户行为列表操作名称列表
|
||||
Route::get('wechat/action/operate', 'v1.application.wechat.WechatMessage/operate')->option(['real_name' => '用户行为列表操作名称列表']);
|
||||
//下载小程序模版页面数据
|
||||
Route::get('routine/info', 'v1.application.routine.RoutineTemplate/getDownloadInfo')->option(['real_name' => '下载小程序页面数据']);
|
||||
//下载小程序模版
|
||||
Route::post('routine/download', 'v1.application.routine.RoutineTemplate/downloadTemp')->option(['real_name' => '下载小程序模版']);
|
||||
|
||||
/** 公众号 */
|
||||
Route::group(function () {
|
||||
//菜单值
|
||||
Route::get('wechat/menu', 'v1.application.wechat.menus/index')->option(['real_name' => '微信公众号菜单列表']);
|
||||
//保存菜单
|
||||
Route::post('wechat/menu', 'v1.application.wechat.menus/save')->option(['real_name' => '保存微信公众号菜单']);
|
||||
//图文列表
|
||||
Route::get('wechat/news', 'v1.application.wechat.WechatNewsCategory/index')->option(['real_name' => '图文列表']);
|
||||
//详情
|
||||
Route::get('wechat/news/:id', 'v1.application.wechat.WechatNewsCategory/read')->option(['real_name' => '图文详情']);
|
||||
//保存图文
|
||||
Route::post('wechat/news', 'v1.application.wechat.WechatNewsCategory/save')->option(['real_name' => '保存图文']);
|
||||
//删除图文
|
||||
Route::delete('wechat/news/:id', 'v1.application.wechat.WechatNewsCategory/delete')->option(['real_name' => '删除图文']);
|
||||
//发送图文消息
|
||||
Route::post('wechat/push', 'v1.application.wechat.WechatNewsCategory/push')->option(['real_name' => '发送图文消息']);
|
||||
//关注回复
|
||||
Route::get('wechat/reply', 'v1.application.wechat.Reply/reply')->option(['real_name' => '关注回复']);
|
||||
//获取关注回复二维码
|
||||
Route::get('wechat/code_reply/:id', 'v1.application.wechat.Reply/code_reply')->option(['real_name' => '获取关注回复二维码']);
|
||||
//关键字回复列表
|
||||
Route::get('wechat/keyword', 'v1.application.wechat.Reply/index')->option(['real_name' => '关键字回复列表']);
|
||||
//关键字详情
|
||||
Route::get('wechat/keyword/:id', 'v1.application.wechat.Reply/read')->option(['real_name' => '关键字回复详情']);
|
||||
//保存关键字修改
|
||||
Route::post('wechat/keyword/:id', 'v1.application.wechat.Reply/save')->option(['real_name' => '保存关键字回复']);
|
||||
//删除关键字
|
||||
Route::delete('wechat/keyword/:id', 'v1.application.wechat.Reply/delete')->option(['real_name' => '删除关键字回复']);
|
||||
//修改关键字状态
|
||||
Route::put('wechat/keyword/set_status/:id/:status', 'v1.application.wechat.Reply/set_status')->option(['real_name' => '修改关键字回复状态']);
|
||||
//一键同步微信模版消息消息
|
||||
Route::get('wechat/syncSubscribe', 'v1.application.wechat.WechatTemplate/syncSubscribe')->name('syncSubscribe')->option(['real_name' => '一键同步模版消息']);
|
||||
})->option(['parent' => 'app', 'cate_name' => '公众号']);
|
||||
|
||||
/** 小程序 */
|
||||
Route::group(function () {
|
||||
//一键同步订阅消息
|
||||
Route::get('routine/syncSubscribe', 'v1.application.routine.RoutineTemplate/syncSubscribe')->name('syncSubscribe')->option(['real_name' => '一键同步订阅消息']);
|
||||
//下载小程序模版页面数据
|
||||
Route::get('routine/info', 'v1.application.routine.RoutineTemplate/getDownloadInfo')->option(['real_name' => '下载小程序页面数据']);
|
||||
//下载小程序模版
|
||||
Route::post('routine/download', 'v1.application.routine.RoutineTemplate/downloadTemp')->option(['real_name' => '下载小程序模版']);
|
||||
|
||||
Route::get('routine/scheme_list', 'v1.application.routine.RoutineScheme/schemeList')->name('schemeList')->option(['real_name' => '小程序外链列表']);
|
||||
Route::get('routine/scheme_form/:id', 'v1.application.routine.RoutineScheme/schemeForm')->name('schemeForm')->option(['real_name' => '小程序外链添加修改表单']);
|
||||
Route::post('routine/scheme_save/:id', 'v1.application.routine.RoutineScheme/schemeSave')->name('schemeSave')->option(['real_name' => '小程序外链添加修改保存']);
|
||||
Route::delete('routine/scheme_del/:id', 'v1.application.routine.RoutineScheme/schemeDel')->name('schemeDel')->option(['real_name' => '小程序外链删除']);
|
||||
|
||||
|
||||
})->option(['parent' => 'app', 'cate_name' => '小程序']);
|
||||
|
||||
/** 公众号渠道码 */
|
||||
Route::get('wechat_qrcode/cate/list', 'v1.application.wechat.WechatQrcode/getCateList')->option(['real_name' => '渠道码分类列表']);
|
||||
Route::get('wechat_qrcode/cate/create/:id', 'v1.application.wechat.WechatQrcode/createForm')->option(['real_name' => '渠道码分类添加编辑表单']);
|
||||
Route::post('wechat_qrcode/cate/save', 'v1.application.wechat.WechatQrcode/saveCate')->option(['real_name' => '渠道码分类保存']);
|
||||
Route::delete('wechat_qrcode/cate/del/:id', 'v1.application.wechat.WechatQrcode/delCate')->option(['real_name' => '渠道码分类删除']);
|
||||
Route::post('wechat_qrcode/save/:id', 'v1.application.wechat.WechatQrcode/saveQrcode')->option(['real_name' => '保存渠道码']);
|
||||
Route::get('wechat_qrcode/info/:id', 'v1.application.wechat.WechatQrcode/qrcodeInfo')->option(['real_name' => '渠道码详情']);
|
||||
Route::get('wechat_qrcode/list', 'v1.application.wechat.WechatQrcode/qrcodeList')->option(['real_name' => '渠道码列表']);
|
||||
Route::delete('wechat_qrcode/del/:id', 'v1.application.wechat.WechatQrcode/delQrcode')->option(['real_name' => '删除渠道码']);
|
||||
Route::put('wechat_qrcode/set_status/:id/:status', 'v1.application.wechat.WechatQrcode/setStatus')->option(['real_name' => '切换渠道码状态']);
|
||||
Route::get('wechat_qrcode/user_list/:qid', 'v1.application.wechat.WechatQrcode/userList')->option(['real_name' => '渠道码用户列表']);
|
||||
Route::get('wechat_qrcode/statistic/:qid', 'v1.application.wechat.WechatQrcode/qrcodeStatistic')->option(['real_name' => '渠道码统计']);
|
||||
Route::group(function () {
|
||||
Route::get('wechat_qrcode/cate/list', 'v1.application.wechat.WechatQrcode/getCateList')->option(['real_name' => '渠道码分类列表']);
|
||||
Route::get('wechat_qrcode/cate/create/:id', 'v1.application.wechat.WechatQrcode/createForm')->option(['real_name' => '渠道码分类添加编辑表单']);
|
||||
Route::post('wechat_qrcode/cate/save', 'v1.application.wechat.WechatQrcode/saveCate')->option(['real_name' => '渠道码分类保存']);
|
||||
Route::delete('wechat_qrcode/cate/del/:id', 'v1.application.wechat.WechatQrcode/delCate')->option(['real_name' => '渠道码分类删除']);
|
||||
Route::post('wechat_qrcode/save/:id', 'v1.application.wechat.WechatQrcode/saveQrcode')->option(['real_name' => '保存渠道码']);
|
||||
Route::get('wechat_qrcode/info/:id', 'v1.application.wechat.WechatQrcode/qrcodeInfo')->option(['real_name' => '渠道码详情']);
|
||||
Route::get('wechat_qrcode/list', 'v1.application.wechat.WechatQrcode/qrcodeList')->option(['real_name' => '渠道码列表']);
|
||||
Route::delete('wechat_qrcode/del/:id', 'v1.application.wechat.WechatQrcode/delQrcode')->option(['real_name' => '删除渠道码']);
|
||||
Route::put('wechat_qrcode/set_status/:id/:status', 'v1.application.wechat.WechatQrcode/setStatus')->option(['real_name' => '切换渠道码状态']);
|
||||
Route::get('wechat_qrcode/user_list/:qid', 'v1.application.wechat.WechatQrcode/userList')->option(['real_name' => '渠道码用户列表']);
|
||||
Route::get('wechat_qrcode/statistic/:qid', 'v1.application.wechat.WechatQrcode/qrcodeStatistic')->option(['real_name' => '渠道码统计']);
|
||||
})->option(['parent' => 'app', 'cate_name' => '公众号渠道码']);
|
||||
|
||||
/** 客服相关 */
|
||||
//客服反馈接口
|
||||
Route::resource('feedback', 'v1.kefu.StoreServiceFeedback')->only(['index', 'delete', 'update', 'edit'])->option(['real_name' => '用户反馈']);
|
||||
//话术接口
|
||||
Route::resource('wechat/speechcraft', 'v1.kefu.StoreServiceSpeechcraft')->option(['real_name' => '客服话术']);
|
||||
//话术分类接口
|
||||
Route::resource('wechat/speechcraftcate', 'v1.kefu.StoreServiceSpeechcraftCate')->option(['real_name' => '客服话术分类']);
|
||||
//客服列表
|
||||
Route::get('wechat/kefu', 'v1.kefu.StoreService/index')->option(['real_name' => '客服列表']);
|
||||
//客服登录
|
||||
Route::get('wechat/kefu/login/:id', 'v1.kefu.StoreService/keufLogin')->option(['real_name' => '客服登录']);
|
||||
//新增客服选择用户列表
|
||||
Route::get('wechat/kefu/create', 'v1.kefu.StoreService/create')->option(['real_name' => '新增客服选择用户列表']);
|
||||
//新增客服表单
|
||||
Route::get('wechat/kefu/add', 'v1.kefu.StoreService/add')->option(['real_name' => '添加客服表单']);
|
||||
//保存新建的数据
|
||||
Route::post('wechat/kefu', 'v1.kefu.StoreService/save')->option(['real_name' => '添加客服']);
|
||||
//编辑客服表单
|
||||
Route::get('wechat/kefu/:id/edit', 'v1.kefu.StoreService/edit')->option(['real_name' => '修改客服表单']);
|
||||
//保存编辑的数据
|
||||
Route::put('wechat/kefu/:id', 'v1.kefu.StoreService/update')->option(['real_name' => '修改客服']);
|
||||
//删除
|
||||
Route::delete('wechat/kefu/:id', 'v1.kefu.StoreService/delete')->option(['real_name' => '删除客服']);
|
||||
//修改状态
|
||||
Route::put('wechat/kefu/set_status/:id/:status', 'v1.kefu.StoreService/set_status')->option(['real_name' => '修改客服状态']);
|
||||
//聊天记录
|
||||
Route::get('wechat/kefu/record/:id', 'v1.kefu.StoreService/chat_user')->option(['real_name' => '聊天记录']);
|
||||
//查看对话
|
||||
Route::get('wechat/kefu/chat_list', 'v1.kefu.StoreService/chat_list')->option(['real_name' => '查看对话']);
|
||||
Route::group(function () {
|
||||
//客服反馈接口
|
||||
Route::resource('feedback', 'v1.kefu.StoreServiceFeedback')->only(['index', 'delete', 'update', 'edit'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取用户反馈列表',
|
||||
'edit' => '获取修改用户反馈表单',
|
||||
'update' => '修改用户反馈',
|
||||
'delete' => '删除用户反馈'
|
||||
]
|
||||
]);
|
||||
//话术接口
|
||||
Route::resource('wechat/speechcraft', 'v1.kefu.StoreServiceSpeechcraft')->except(['read'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取客服话术列表',
|
||||
'create' => '获取客服话术表单',
|
||||
'save' => '保存客服话术',
|
||||
'edit' => '获取修改客服话术表单',
|
||||
'update' => '修改客服话术',
|
||||
'delete' => '删除客服话术'
|
||||
]
|
||||
]);
|
||||
//话术分类接口
|
||||
Route::resource('wechat/speechcraftcate', 'v1.kefu.StoreServiceSpeechcraftCate')->except(['read'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取客服话术分类列表',
|
||||
'create' => '获取客服话术分类表单',
|
||||
'save' => '保存客服话术分类',
|
||||
'edit' => '获取修改客服话术分类表单',
|
||||
'update' => '修改客服话术分类',
|
||||
'delete' => '删除客服话术分类'
|
||||
]
|
||||
]);
|
||||
//客服列表
|
||||
Route::get('wechat/kefu', 'v1.kefu.StoreService/index')->option(['real_name' => '客服列表']);
|
||||
//客服登录
|
||||
Route::get('wechat/kefu/login/:id', 'v1.kefu.StoreService/keufLogin')->option(['real_name' => '客服登录']);
|
||||
//新增客服选择用户列表
|
||||
Route::get('wechat/kefu/create', 'v1.kefu.StoreService/create')->option(['real_name' => '新增客服选择用户列表']);
|
||||
//新增客服表单
|
||||
Route::get('wechat/kefu/add', 'v1.kefu.StoreService/add')->option(['real_name' => '添加客服表单']);
|
||||
//保存新建的数据
|
||||
Route::post('wechat/kefu', 'v1.kefu.StoreService/save')->option(['real_name' => '添加客服']);
|
||||
//编辑客服表单
|
||||
Route::get('wechat/kefu/:id/edit', 'v1.kefu.StoreService/edit')->option(['real_name' => '修改客服表单']);
|
||||
//保存编辑的数据
|
||||
Route::put('wechat/kefu/:id', 'v1.kefu.StoreService/update')->option(['real_name' => '修改客服']);
|
||||
//删除
|
||||
Route::delete('wechat/kefu/:id', 'v1.kefu.StoreService/delete')->option(['real_name' => '删除客服']);
|
||||
//修改状态
|
||||
Route::put('wechat/kefu/set_status/:id/:status', 'v1.kefu.StoreService/set_status')->option(['real_name' => '修改客服状态']);
|
||||
//聊天记录
|
||||
Route::get('wechat/kefu/record/:id', 'v1.kefu.StoreService/chat_user')->option(['real_name' => '聊天记录']);
|
||||
//查看对话
|
||||
Route::get('wechat/kefu/chat_list', 'v1.kefu.StoreService/chat_list')->option(['real_name' => '查看对话']);
|
||||
|
||||
//客服自动回复列表
|
||||
Route::get('kefu/auto_reply/list', 'v1.kefu.StoreServiceAutoReply/autoReplyList')->option(['real_name' => '客服自动回复列表']);
|
||||
//客服自动回复添加修改表单
|
||||
Route::get('kefu/auto_reply/form/:id', 'v1.kefu.StoreServiceAutoReply/autoReplyForm')->option(['real_name' => '客服自动回复添加修改表单']);
|
||||
//客服自动回复添加修改保存
|
||||
Route::post('kefu/auto_reply/save/:id', 'v1.kefu.StoreServiceAutoReply/autoReplySave')->option(['real_name' => '客服自动回复添加修改保存']);
|
||||
//客服自动回复修改状态
|
||||
Route::put('kefu/auto_reply/status/:id/:status', 'v1.kefu.StoreServiceAutoReply/autoReplyStatus')->option(['real_name' => '客服自动回复修改状态']);
|
||||
//客服自动回复删除
|
||||
Route::delete('kefu/auto_reply/del/:id', 'v1.kefu.StoreServiceAutoReply/autoReplyDel')->option(['real_name' => '客服自动回复删除']);
|
||||
|
||||
})->option(['parent' => 'app', 'cate_name' => '客服相关']);
|
||||
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'app', 'mark_name' => '应用模块']);
|
||||
|
||||
@ -14,23 +14,51 @@ use think\facade\Route;
|
||||
* 文章管理 相关路由
|
||||
*/
|
||||
Route::group('cms', function () {
|
||||
//文章资源路由
|
||||
Route::resource('cms', 'v1.cms.Article')->name('ArticleResource')->option(['real_name' => '文章']);
|
||||
//关联商品
|
||||
Route::put('cms/relation/:id', 'v1.cms.Article/relation')->name('Relation')->option(['real_name' => '文章关联商品']);
|
||||
//取消关联
|
||||
Route::put('cms/unrelation/:id', 'v1.cms.Article/unrelation')->name('UnRelation')->option(['real_name' => '取消文章关联商品']);
|
||||
//文章分类资源路由
|
||||
Route::resource('category', 'v1.cms.ArticleCategory')->name('ArticleCategoryResource')->option(['real_name' => '文章分类']);
|
||||
//修改状态
|
||||
Route::put('category/set_status/:id/:status', 'v1.cms.ArticleCategory/set_status')->name('CategoryStatus')->option(['real_name' => '修改文章分类状态']);
|
||||
//分类列表
|
||||
Route::get('category_list', 'v1.cms.ArticleCategory/categoryList')->name('categoryList')->option(['real_name' => '分类列表']);
|
||||
//分类树形列表
|
||||
Route::get('category_tree_list', 'v1.cms.ArticleCategory/getTreeList')->name('getTreeList')->option(['real_name' => '分类树形列表']);
|
||||
|
||||
/** 文章 */
|
||||
Route::group(function () {
|
||||
//文章资源路由
|
||||
Route::resource('cms', 'v1.cms.Article')->option([
|
||||
'real_name' => [
|
||||
'index' => '获取文章列表',
|
||||
'create' => '获取文章表单',
|
||||
'read' => '获取文章详细信息',
|
||||
'save' => '保存文章',
|
||||
'edit' => '获取修改文章表单',
|
||||
'update' => '修改文章',
|
||||
'delete' => '删除文章'
|
||||
]
|
||||
]);
|
||||
//关联商品
|
||||
Route::put('cms/relation/:id', 'v1.cms.Article/relation')->name('Relation')->option(['real_name' => '文章关联商品']);
|
||||
//取消关联
|
||||
Route::put('cms/unrelation/:id', 'v1.cms.Article/unrelation')->name('UnRelation')->option(['real_name' => '取消文章关联商品']);
|
||||
})->option(['parent' => 'cms', 'cate_name' => '文章管理']);
|
||||
|
||||
/** 文章分类 */
|
||||
Route::group(function () {
|
||||
//文章分类资源路由
|
||||
Route::resource('category', 'v1.cms.ArticleCategory')->except(['read'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取文章分类列表',
|
||||
'create' => '获取文章分类表单',
|
||||
'save' => '保存文章分类',
|
||||
'edit' => '获取修改文章分类表单',
|
||||
'update' => '修改文章分类',
|
||||
'delete' => '删除文章分类'
|
||||
]
|
||||
]);
|
||||
//修改状态
|
||||
Route::put('category/set_status/:id/:status', 'v1.cms.ArticleCategory/set_status')->name('CategoryStatus')->option(['real_name' => '修改文章分类状态']);
|
||||
//分类列表
|
||||
Route::get('category_list', 'v1.cms.ArticleCategory/categoryList')->name('categoryList')->option(['real_name' => '分类列表']);
|
||||
//分类树形列表
|
||||
Route::get('category_tree_list', 'v1.cms.ArticleCategory/getTreeList')->name('getTreeList')->option(['real_name' => '分类树形列表']);
|
||||
})->option(['parent' => 'cms', 'cate_name' => '文章分类']);
|
||||
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'cms', 'mark_name' => '文章模块']);
|
||||
|
||||
@ -14,7 +14,6 @@ use think\facade\Route;
|
||||
* 文件下载、导出相关路由
|
||||
*/
|
||||
Route::group(function () {
|
||||
|
||||
//下载备份记录表
|
||||
Route::get('backup/download', 'v1.system.SystemDatabackup/downloadFile')->option(['real_name' => '下载表备份记录']);
|
||||
//首页统计数据
|
||||
@ -23,9 +22,9 @@ Route::group(function () {
|
||||
Route::get('home/order', 'Common/orderChart')->option(['real_name' => '首页订单图表']);
|
||||
//首页用户图表
|
||||
Route::get('home/user', 'Common/userChart')->option(['real_name' => '首页用户图表']);
|
||||
//
|
||||
//首页交易额排行
|
||||
Route::get('home/rank', 'Common/purchaseRanking')->option(['real_name' => '首页交易额排行']);
|
||||
// 消息提醒
|
||||
//消息提醒
|
||||
Route::get('jnotice', 'Common/jnotice')->option(['real_name' => '消息提醒']);
|
||||
//验证授权
|
||||
Route::get('check_auth', 'Common/auth')->option(['real_name' => '验证授权']);
|
||||
@ -43,10 +42,12 @@ Route::group(function () {
|
||||
Route::get('copyright', 'Common/copyright')->option(['real_name' => '申请版权']);
|
||||
//保存版权
|
||||
Route::post('copyright', 'Common/saveCopyright')->option(['real_name' => '保存版权']);
|
||||
//后台菜单搜索
|
||||
Route::post('menusSearch', 'Common/menusSearch')->option(['real_name' => '后台菜单搜索']);
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'common', 'mark_name' => '系统数据']);
|
||||
|
||||
|
||||
35
crmeb/app/adminapi/route/crud.php
Normal file
35
crmeb/app/adminapi/route/crud.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
use think\facade\Route;
|
||||
|
||||
/**
|
||||
* crud 自动加载路由
|
||||
* 自动加载crud目录下的所有路由文件
|
||||
*/
|
||||
Route::group(function () {
|
||||
$path = $this->app->getRootPath() . 'app' . DS . 'adminapi' . DS . 'route' . DS . 'crud';
|
||||
if (is_dir($path)) {
|
||||
$files = scandir($path);
|
||||
foreach ($files as $file) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
include $path . DS . $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
])->option(['mark' => 'crud', 'mark_name' => '生成代码路由']);
|
||||
@ -12,7 +12,7 @@
|
||||
use think\facade\Route;
|
||||
|
||||
/**
|
||||
* 分销管理 相关路由
|
||||
* diy 相关路由
|
||||
*/
|
||||
Route::group('diy', function () {
|
||||
|
||||
@ -64,14 +64,43 @@ Route::group('diy', function () {
|
||||
Route::post('member_save', 'v1.diy.Diy/memberSaveData')->option(['real_name' => '个人中心保存']);
|
||||
//获取diy小程序二维码
|
||||
Route::get('get_routine_code/:id', 'v1.diy.Diy/getRoutineCode')->option(['real_name' => 'diy小程序预览码']);
|
||||
|
||||
//开屏广告
|
||||
Route::get('open_adv/info', 'v1.diy.Diy/getOpenAdv')->option(['real_name' => '获取开屏广告']);
|
||||
Route::post('open_adv/add', 'v1.diy.Diy/openAdvAdd')->option(['real_name' => '保存开屏广告']);
|
||||
//推荐商品
|
||||
Route::get('groom_list/:type', 'v1.diy.Diy/getGroomList')->option(['real_name' => '推荐商品']);
|
||||
|
||||
/** 系统链接管理 */
|
||||
Route::get('link/category', 'v1.diy.PageLink/getLinkCategory')->option(['real_name' => '获取链接分类']);
|
||||
Route::get('link/category/form/:cate_id/[:pid]', 'v1.diy.PageLink/getLinkCategoryForm')->option(['real_name' => '链接分类表单']);
|
||||
Route::post('link/category/save/:cate_id', 'v1.diy.PageLink/getLinkCategorySave')->option(['real_name' => '链接分类保存']);
|
||||
Route::delete('link/category/del/:cate_id', 'v1.diy.PageLink/getLinkCategoryDel')->option(['real_name' => '链接分类删除']);
|
||||
Route::get('link/list/:cate_id', 'v1.diy.PageLink/getLinkList')->option(['real_name' => '链接列表']);
|
||||
Route::post('link/save/:id', 'v1.diy.PageLink/getLinkSave')->option(['real_name' => '链接保存']);
|
||||
Route::delete('link/del/:id', 'v1.diy.PageLink/getLinkDel')->option(['real_name' => '链接删除']);
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'diy', 'mark_name' => '页面装修']);
|
||||
|
||||
|
||||
/**
|
||||
* diy_pro 相关路由
|
||||
*/
|
||||
Route::group('diy_pro', function () {
|
||||
|
||||
Route::get('get_list', 'v1.diy.DiyPro/getList')->option(['real_name' => 'DiyPro模板列表']);
|
||||
Route::get('get_info/:id', 'v1.diy.DiyPro/getInfo')->option(['real_name' => 'DiyPro模板详情']);
|
||||
Route::post('save/:id', 'v1.diy.DiyPro/saveInfo')->option(['real_name' => 'DiyPro模板保存']);
|
||||
Route::get('get_product', 'v1.diy.DiyPro/getProduct')->option(['real_name' => '获取商品列表']);
|
||||
Route::post('update/name/:id', 'v1.diy.DiyPro/updateName')->option(['real_name' => '修改名称']);
|
||||
Route::get('export/data/:id', 'v1.diy.DiyPro/exportDIYData')->option(['real_name' => '导出DIY数据']);
|
||||
Route::post('import/data', 'v1.diy.DiyPro/importDIYData')->option(['real_name' => '导入DIY数据']);
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
])->option(['mark' => 'diy_pro', 'mark_name' => '页面装修']);
|
||||
|
||||
@ -18,6 +18,8 @@ Route::group('export', function () {
|
||||
Route::get('user_list', 'v1.export.ExportExcel/userList')->option(['real_name' => '用户列表导出']);
|
||||
//订单列表
|
||||
Route::get('order_list', 'v1.export.ExportExcel/orderList')->option(['real_name' => '订单列表导出']);
|
||||
//发货订单列表
|
||||
Route::get('order_delivery_list', 'v1.export.ExportExcel/orderDeliveryList')->option(['real_name' => '发货订单列表导出']);
|
||||
//商品列表
|
||||
Route::get('product_list', 'v1.export.ExportExcel/productList')->option(['real_name' => '商品列表导出']);
|
||||
//砍价列表
|
||||
@ -28,7 +30,8 @@ Route::group('export', function () {
|
||||
Route::get('seckill_list', 'v1.export.ExportExcel/seckillList')->option(['real_name' => '秒杀商品列表导出']);
|
||||
//导出会员卡
|
||||
Route::get('member_card/:id', 'v1.export.ExportExcel/memberCardList')->option(['real_name' => '会员卡导出']);
|
||||
|
||||
//分销用户推广列表
|
||||
Route::get('userAgent', 'v1.export.ExportExcel/userAgent')->option(['real_name' => '分销员推广列表导出']);
|
||||
//用户资金监控
|
||||
Route::get('userFinance', 'v1.export.ExportExcel/userFinance')->option(['real_name' => '用户资金导出']);
|
||||
//用户佣金
|
||||
@ -37,27 +40,9 @@ Route::group('export', function () {
|
||||
Route::get('userPoint', 'v1.export.ExportExcel/userPoint')->option(['real_name' => '用户积分导出']);
|
||||
//用户充值
|
||||
Route::get('userRecharge', 'v1.export.ExportExcel/userRecharge')->option(['real_name' => '用户充值导出']);
|
||||
//分销用户推广列表
|
||||
Route::get('userAgent', 'v1.export.ExportExcel/userAgent')->option(['real_name' => '分销员推广列表导出']);
|
||||
//微信用户
|
||||
Route::get('wechatUser', 'v1.export.ExportExcel/wechatUser')->option(['real_name' => '微信用户导出']);
|
||||
//商铺砍价活动
|
||||
Route::get('storeBargain', 'v1.export.ExportExcel/storeBargain')->option(['real_name' => '砍价商品导出']);
|
||||
//商铺拼团
|
||||
Route::get('storeCombination', 'v1.export.ExportExcel/storeCombination')->option(['real_name' => '拼团商品导出']);
|
||||
//商铺秒杀
|
||||
Route::get('storeSeckill', 'v1.export.ExportExcel/storeSeckill')->option(['real_name' => '秒杀商品导出']);
|
||||
//商铺产品
|
||||
Route::get('storeProduct', 'v1.export.ExportExcel/storeProduct')->option(['real_name' => '商品导出']);
|
||||
//商铺订单
|
||||
Route::get('storeOrder', 'v1.export.ExportExcel/storeOrder')->option(['real_name' => '订单导出']);
|
||||
//商铺提货点
|
||||
Route::get('storeMerchant', 'v1.export.ExportExcel/storeMerchant')->option(['real_name' => '提货点导出']);
|
||||
//导出会员卡
|
||||
Route::get('memberCard/:id', 'v1.export.ExportExcel/memberCard')->option(['real_name' => '会员卡导出']);
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'export', 'mark_name' => '数据导出']);
|
||||
|
||||
@ -27,14 +27,34 @@ Route::group('file', function () {
|
||||
//上传图片
|
||||
Route::post('upload/[:upload_type]', 'v1.file.SystemAttachment/upload')->option(['real_name' => '上传图片']);
|
||||
//附件分类管理资源路由
|
||||
Route::resource('category', 'v1.file.SystemAttachmentCategory')->option(['real_name' => '附件分类管理']);
|
||||
Route::resource('category', 'v1.file.SystemAttachmentCategory')->except(['read'])->option([
|
||||
'real_name' => [
|
||||
'index' => '获取附件分类管理列表',
|
||||
'create' => '获取附件分类管理表单',
|
||||
'save' => '保存附件分类管理',
|
||||
'edit' => '获取修改附件分类管理表单',
|
||||
'update' => '修改附件分类管理',
|
||||
'delete' => '删除附件分类管理'
|
||||
],
|
||||
|
||||
]);
|
||||
//获取上传类型
|
||||
Route::get('upload_type', 'v1.file.SystemAttachment/uploadType')->option(['real_name' => '上传类型']);
|
||||
//分片上传本地视频
|
||||
Route::post('video_upload', 'v1.file.SystemAttachment/videoUpload')->option(['real_name' => '分片上传本地视频']);
|
||||
//云存储视频保存数据
|
||||
Route::post('video_data_save', 'v1.file.SystemAttachment/videoDataSave')->option(['real_name' => '云存储视频保存数据']);
|
||||
//获取扫码上传页面链接以及参数
|
||||
Route::get('scan_upload/qrcode', 'v1.file.SystemAttachment/scanUploadQrcode')->option(['real_name' => '扫码上传页面链接']);
|
||||
//删除扫码上传token
|
||||
Route::delete('scan_upload/qrcode', 'v1.file.SystemAttachment/removeUploadQrcode')->option(['real_name' => '删除扫码上传页面链接']);
|
||||
//获取扫码上传的图片数据
|
||||
Route::get('scan_upload/image/:scan_token', 'v1.file.SystemAttachment/scanUploadImage')->option(['real_name' => '获取扫码上传的图片数据']);
|
||||
//网络图片上传
|
||||
Route::post('online_upload', 'v1.file.SystemAttachment/onlineUpload')->option(['real_name' => '网络图片上传']);
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'file', 'mark_name' => '素材管理']);
|
||||
|
||||
@ -14,44 +14,56 @@ use think\facade\Route;
|
||||
* 财务模块 相关路由
|
||||
*/
|
||||
Route::group('finance', function () {
|
||||
//筛选类型
|
||||
Route::get('finance/bill_type', 'v1.finance.Finance/bill_type')->option(['real_name' => '资金记录类型']);
|
||||
//资金记录
|
||||
Route::get('finance/list', 'v1.finance.Finance/list')->option(['real_name' => '资金记录列表']);
|
||||
//佣金记录
|
||||
Route::get('finance/commission_list', 'v1.finance.Finance/get_commission_list')->option(['real_name' => '佣金记录列表']);
|
||||
//佣金详情用户信息
|
||||
Route::get('finance/user_info/:id', 'v1.finance.Finance/user_info')->option(['real_name' => '佣金详情用户信息']);
|
||||
//佣金提现记录个人列表
|
||||
Route::get('finance/extract_list/:id', 'v1.finance.Finance/get_extract_list')->option(['real_name' => '佣金提现记录个人列表']);
|
||||
//申请列表
|
||||
Route::get('extract', 'v1.finance.UserExtract/index')->option(['real_name' => '提现申请列表']);
|
||||
//编辑表单
|
||||
Route::get('extract/:id/edit', 'v1.finance.UserExtract/edit')->option(['real_name' => '提现记录修改表单']);
|
||||
//保存修改
|
||||
Route::put('extract/:id', 'v1.finance.UserExtract/update')->option(['real_name' => '提现记录修改']);
|
||||
//拒绝申请
|
||||
Route::put('extract/refuse/:id', 'v1.finance.UserExtract/refuse')->option(['real_name' => '拒绝提现申请']);
|
||||
//通过申请
|
||||
Route::put('extract/adopt/:id', 'v1.finance.UserExtract/adopt')->option(['real_name' => '通过提现申请']);
|
||||
//充值记录列表
|
||||
Route::get('recharge', 'v1.finance.UserRecharge/index')->option(['real_name' => '充值记录列表']);
|
||||
//删除记录
|
||||
Route::delete('recharge/:id', 'v1.finance.UserRecharge/delete')->option(['real_name' => '删除充值记录']);
|
||||
//获取用户充值数据
|
||||
Route::get('recharge/user_recharge', 'v1.finance.UserRecharge/user_recharge')->option(['real_name' => '获取用户充值数据']);
|
||||
//退款表单
|
||||
Route::get('recharge/:id/refund_edit', 'v1.finance.UserRecharge/refund_edit')->option(['real_name' => '充值退款表单']);
|
||||
//退款
|
||||
Route::put('recharge/:id', 'v1.finance.UserRecharge/refund_update')->option(['real_name' => '充值退款']);
|
||||
|
||||
/** 余额记录 */
|
||||
Route::get('balance/list', 'v1.finance.UserBalance/balanceList')->option(['real_name' => '余额记录列表']);
|
||||
Route::post('balance/set_mark/:id', 'v1.finance.UserBalance/balanceRecordRemark')->option(['real_name' => '余额记录备注']);
|
||||
/** 提现 */
|
||||
Route::group(function () {
|
||||
//申请列表
|
||||
Route::get('extract', 'v1.finance.UserExtract/index')->option(['real_name' => '提现申请列表']);
|
||||
//编辑表单
|
||||
Route::get('extract/:id/edit', 'v1.finance.UserExtract/edit')->option(['real_name' => '提现记录修改表单']);
|
||||
//保存修改
|
||||
Route::put('extract/:id', 'v1.finance.UserExtract/update')->option(['real_name' => '提现记录修改']);
|
||||
//拒绝申请
|
||||
Route::put('extract/refuse/:id', 'v1.finance.UserExtract/refuse')->option(['real_name' => '拒绝提现申请']);
|
||||
//通过申请
|
||||
Route::put('extract/adopt/:id', 'v1.finance.UserExtract/adopt')->option(['real_name' => '通过提现申请']);
|
||||
})->option(['parent' => 'finance', 'cate_name' => '提现']);
|
||||
|
||||
/** 资金记录 */
|
||||
Route::group(function () {
|
||||
//筛选类型
|
||||
Route::get('finance/bill_type', 'v1.finance.Finance/bill_type')->option(['real_name' => '资金记录类型']);
|
||||
//资金记录
|
||||
Route::get('finance/list', 'v1.finance.Finance/list')->option(['real_name' => '资金记录列表']);
|
||||
//佣金记录
|
||||
Route::get('finance/commission_list', 'v1.finance.Finance/get_commission_list')->option(['real_name' => '佣金记录列表']);
|
||||
//佣金详情用户信息
|
||||
Route::get('finance/user_info/:id', 'v1.finance.Finance/user_info')->option(['real_name' => '佣金详情用户信息']);
|
||||
//佣金提现记录个人列表
|
||||
Route::get('finance/extract_list/:id', 'v1.finance.Finance/get_extract_list')->option(['real_name' => '佣金提现记录个人列表']);
|
||||
/** 余额记录 */
|
||||
Route::get('balance/list', 'v1.finance.UserBalance/balanceList')->option(['real_name' => '余额记录列表']);
|
||||
Route::post('balance/set_mark/:id', 'v1.finance.UserBalance/balanceRecordRemark')->option(['real_name' => '余额记录备注']);
|
||||
})->option(['parent' => 'finance', 'cate_name' => '资金记录']);
|
||||
|
||||
/** 充值 */
|
||||
Route::group(function () {
|
||||
//充值记录列表
|
||||
Route::get('recharge', 'v1.finance.UserRecharge/index')->option(['real_name' => '充值记录列表']);
|
||||
//删除记录
|
||||
Route::delete('recharge/:id', 'v1.finance.UserRecharge/delete')->option(['real_name' => '删除充值记录']);
|
||||
//获取用户充值数据
|
||||
Route::get('recharge/user_recharge', 'v1.finance.UserRecharge/user_recharge')->option(['real_name' => '获取用户充值数据']);
|
||||
//退款表单
|
||||
Route::get('recharge/:id/refund_edit', 'v1.finance.UserRecharge/refund_edit')->option(['real_name' => '充值退款表单']);
|
||||
//退款
|
||||
Route::put('recharge/:id', 'v1.finance.UserRecharge/refund_update')->option(['real_name' => '充值退款']);
|
||||
})->option(['parent' => 'finance', 'cate_name' => '充值']);
|
||||
|
||||
|
||||
})->middleware([
|
||||
\app\http\middleware\AllowOriginMiddleware::class,
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'finance', 'mark_name' => '财务管理']);
|
||||
|
||||
@ -15,7 +15,16 @@ use think\facade\Route;
|
||||
*/
|
||||
Route::group('freight', function () {
|
||||
//物流公司资源路由
|
||||
Route::resource('express', 'v1.freight.Express')->name('ExpressResource')->option(['real_name' => '物流公司']);
|
||||
Route::resource('express', 'v1.freight.Express')->except(['read'])->name('ExpressResource')->option([
|
||||
'real_name' => [
|
||||
'index' => '获取物流公司列表',
|
||||
'create' => '获取物流公司表单',
|
||||
'save' => '保存物流公司',
|
||||
'edit' => '获取修改物流公司表单',
|
||||
'update' => '修改物流公司',
|
||||
'delete' => '删除物流公司'
|
||||
],
|
||||
]);
|
||||
//修改状态
|
||||
Route::put('express/set_status/:id/:status', 'v1.freight.Express/set_status')->option(['real_name' => '修改物流公司状态']);
|
||||
//同步物流快递公司
|
||||
@ -30,4 +39,4 @@ Route::group('freight', function () {
|
||||
\app\adminapi\middleware\AdminAuthTokenMiddleware::class,
|
||||
\app\adminapi\middleware\AdminCheckRoleMiddleware::class,
|
||||
\app\adminapi\middleware\AdminLogMiddleware::class
|
||||
]);
|
||||
])->option(['mark' => 'freight', 'mark_name' => '物流管理']);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user