commit f20694754fc74c930bf9e64b67afa23f6629c3af Author: dashixiong Date: Tue Jan 27 14:03:02 2026 +0800 first commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dbbe355 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + 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 AGPL, see +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1207b79 --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ +# fuint会员营销系统介绍 + +#### 介绍 +fuint会员营销系统是一套开源的实体店铺会员管理和营销系统。系统基于前后端分离的架构,后端采用Java SpringBoot + Mysql,前端基于当前流行的UniappElement UI,支持小程序、h5。主要功能包含电子优惠券、储值卡、实体卡、集次卡(计次卡)、短信发送、储值卡、会员积分、会员等级权益体系,支付收款等会员日常营销工具。本系统适用于各类实体店铺,如零售超市、酒吧、酒店、汽车4S店、鲜花店、奶茶店、甜品店、餐饮店、农家乐等,是实体店铺会员营销必备的一款利器。 +以下是前台的页面展示: +

前台页面1

+

前台页面2

+

前台页面3

+

前台页面4

+

前台页面4

+ +fuint侧重于线下实体店的私域流量的运营,同时提供会员端小程序和收银系统的线上线下统一渠道,帮助商户降低获客成本。顾客通过扫码支付成为私域流量,支付即可成为会员。积分和卡券功能建立起会员等级体系,通过消息推送和短信营销方便触达用户。 +

1、会员运营自动化:商家通过日常活动设置,如开卡礼设置,沉睡唤醒等,成为会员后自动给顾客送优惠券,让顾客更有黏性,提升会员运营效率。

+

2、打通收银系统和会员营销的壁垒,代客下单收银,支付即成为会员。

+

3、会员体系完整化:积分兑换、积分转赠、会员等级权益、积分加速、买单折扣。

+

4、会员卡券齐全:储值卡、电子券、优惠券、集次卡、计次卡、实体卡购买并兑换、会员充值、余额支付。

+

5、线上代客下单收银系统,后台管理员可帮助临柜的会员下单、扫码支付。

+

6、支持手机短信、站内弹框消息、微信订阅消息:支持包括发货消息、卡券到期提醒、活动提醒、会员到期提醒、积分余额变动提醒等消息。

+

7、具有门店预约、到店支付等线上线下结合的o2o能力。

+

小程序前端仓库:https://gitee.com/fuint/fuint-uniapp

+扫码小程序演示:
+

小程序演示

+
+官网演示地址:
+

+ 1、官网:https://www.fuint.cn 点击 -> 系统演示,演示账号:fuint / 123456
+ 2、swagger接口文档:https://www.fuint.cn/fuint-application/swagger-ui.html +

+ +#### 软件架构 +后端:JAVA SpringBoot + MYSQL Mybatis Plus + Redis +前端:采用基于Vue的Uniapp、Element UI,前后端分离,支持微信小程序、h5等 +

后台截图:

+

登录界面

+

首页

+ +前端使用技术
+2.1 Vue2
+2.2 Uniapp
+2.3 Element UI +2.4 Nodejs 14或16版本 + +后端使用技术
+1.1 SpringBoot 2.5
+1.2 Mybatis Plus
+1.3 Maven
+1.4 SpringSecurity
+1.5 Druid
+1.6 Slf4j
+1.7 Fastjson
+1.8 JWT
+1.9 Redis
+1.10 Quartz
+1.11 Mysql 5.7或8版
+1.12 Swagger UI
+ + +#### 安装步骤 +软件环境版本:jdk 1.8、mysql 5.7或5.8、Redis任意版本 +1. 导入db目录下的fuint-db.sql数据库文件。 +2. 修改configure目录下的配置文件。 +3. 将工程导入Idea,并安装插件:Lombok Plugin。 +3. 使用maven执行install,打jar包(在fuint-application/target目录),把jar包上传并执行启动: + nohup java -Dfile.encoding=UTF-8 -Xmx2048m -Xms2048m -Xss256k -Xmn1024m -jar fuint-application-1.0.0.jar +

提示:无后端和linux基础的朋友,可以使用宝塔部署,非常方便简单。

+ + +#### 前台使用说明 + +1. 会员登录,登录成功后可看到会员的卡券列表。 +2. 卡券领取和购买,预存券的充值等。 +3. 核销卡券,会员在前台出示二维码,管理员用微信扫一扫即可核销。 +4. 卡券转赠,会员可将自己的卡券转赠给其他用户,输入对方的手机号即可完成转赠,获赠的好友会收到卡券赠送的短信。 + +

卡券创建界面

+

卡券创建界面

+ +#### 后台使用 +1. 会员管理:会员新增、导入、禁用等。 +2. 内容管理:焦点图管理、文章管理等。 +3. 卡券管理:电子券管理为2层结构,即电子券组和电子券。 +4. 会员积分:会员积分管理,会员积分的操作,会员积分明细查看。 +5. 转赠管理:卡券转赠记录。 +6. 短信管理:短信营销功能,已发送的短信列表。 +7. 系统配置:配置系统管理员权限等。 +8. 店铺管理:支持多店铺模式。 +9. 核销管理员:核销人员管理主要包含3个功能:核销人员列表、核销人员审核、核销人员信息编辑。 +10. 短信模板管理:可配置不同场景和业务的短信内容。 +11. 卡券发放:单独发放、批量发放,发放成功后给会员发送短信通知 +12. 操作日志主要针对电子券系统后台的一些关键操作进行日志记录,方便排查相关操作人的行为等问题。 +13. 发券记录主要根据发券的实际操作情况来记录,分为单用户发券和批量发券,同时可针对该次发券记录进行作废操作。 +14. 代客下单、收银功能,支持小票打印,包括本地打印和云打印(对接芯烨云打印服务)。 +

卡券营销:

+

卡券列表

+ +

收银代客下单功能:店员角色登录后台,从首页的“下单首页”菜单可进入代客收银下单界面,完成代客下单收银的流程。

+

收银界面

+

发起结算:

+

收银结算

+ +#### 开发计划 +1. 完善的报表统计; +2. 分享助力、分享领券、分享获得积分; +3. 员工提成、分销功能; +4. 更多营销工具,比如签到等。 + + +#### 允许使用范围: +1. 允许个人学习使用 +2. 允许用于毕业设计、论文参考代码 +3. 推荐Watch、Star项目,获取项目第一时间更新,同时也是对项目最好的支持 +4. 希望大家多多支持原创软件 +5. 请勿去除版权标签,要商用请购买源码授权(非常便宜),感谢理解! + +不足和待完善之处请谅解!源码仅供学习交流,更多功能欢迎进群咨询讨论,或需安装帮助请联系我们(麻烦先点star!!!!!!)。
+官方网站:https://www.fuint.cn
+开源不易,感谢支持!
+作者wx:fsq_better:
+

公众号二维码

+ + +特别鸣谢:
+Mybaits Plus: https://github.com/baomidou/mybatis-plus
+Vue: https://github.com/vuejs/vue
+Element UI: https://element.eleme.cn \ No newline at end of file diff --git a/configure/dev/application.properties b/configure/dev/application.properties new file mode 100644 index 0000000..2cb728f --- /dev/null +++ b/configure/dev/application.properties @@ -0,0 +1,115 @@ +# 数据库配置 +spring.datasource.url=jdbc:mysql://localhost:3306/fuint-db?useUnicode=true&characterEncoding=UTF8&useSSL=false +spring.datasource.username=root +spring.datasource.password=root + +# Redis配置 +spring.session.store-type=redis +spring.session.redis.namespace=fuint +# Redis数据库索引(默认为0) +spring.redis.database=0 +# Redis服务器地址(生产) +spring.redis.host=127.0.0.1 +# Redis服务器连接端口 +spring.redis.port=6379 +# Redis服务器连接密码(默认为空) +spring.redis.password= +# 连接池最大连接数(使用负值表示没有限制) +spring.redis.pool.max-active=-1 +# 连接池最大阻塞等待时间(使用负值表示没有限制) +spring.redis.pool.max-wait=-1 +# 连接池中的最大空闲连接 +spring.redis.pool.max-idle=8 +# 连接池中的最小空闲连接 +spring.redis.pool.min-idle=0 +# 连接超时时间(毫秒) +spring.redis.timeout=0 + +# 系统名称 +system.name = fuint会员营销管理系统 + +# 前端h5地址 +website.url=https://www.fuint.cn/h5/ + +# 上传图片本地地址 +images.root=C:/fuintV3.0.1/fuintBackend/fuint-application/target/classes +images.path=/static/uploadImages/ + +# 上传图片服务器域名 +images.upload.url=http://localhost:8080 + +# 上传图片允许的大小(单位:MB) +images.upload.maxSize=5 + +################## 定时脚本配置 ######################### +# 定时发送消息 +message.job.switch = 1 +message.job.time = 0 0/1 * * * ? + +# 卡券到期处理 +couponExpire.job.switch = 1 +couponExpire.job.time = 0 0/1 * * * ? + +# 订单超时取消 +orderCancel.job.switch = 1 +orderCancel.job.time = 0 0/1 * * * ? + +# 分佣提成计算 +commission.job.switch = 1 +commission.job.time = 0 0/1 * * * ? + +# 微信小程序上传发货信息处理 +uploadShippingInfoJob.job.switch = 1 +uploadShippingInfoJob.job.time = 0 0/1 * * * ? + +################## 阿里云短信配置 ####################### +# 短信接口模式[0-关闭 1-打开] +aliyun.sms.mode = 0 +aliyun.sms.accessKeyId=LTAI4GJMjV123oXsrQJLnPZt +aliyun.sms.accessKeySecret=eGVBL30u5Ypj234d7XODlwYKWTaGT +# 阿里云短信签名 +aliyun.sms.signName=延禾技术 + +################## 阿里云OSS存储配置###################### +# 模式[0-关闭 1-打开] +aliyun.oss.mode = 0 +aliyun.oss.accessKeyId = LTAI4GJMjVhBa212rQJLnPZtt +aliyun.oss.accessKeySecret = eGVBL30u53456gXd7XODlwYKWTaGT +aliyun.oss.endpoint = https://oss-cn-shenzhen.aliyuncs.com +aliyun.oss.bucketName = fuint-application +# 上传文件夹 +aliyun.oss.folder = uploads +# 访问域名 +aliyun.oss.domain = https://fuint-application.oss-cn-shenzhen.aliyuncs.com + +################## 高德地图配置 ########################### +amap.key = 高德地图key + +################## 微信相关配置 ########################## +# 公众号配置 +weixin.official.appId=wxf4327ef05c27a0 +weixin.official.appSecret=1f55e8749332234d9a074873d8e6a3 + +# 小程序配置 +wxpay.appId = wxb6af3741234162bc +wxpay.appSecret = 76a538bfa5b55a4564d5f2be5540 +wxpay.mchId=1636980812 +wxpay.apiV2=34354320201030y323e432342343 +wxpay.certPath=/usr/local/fuint/cert/apiclient_cert.p12 +wxpay.domain=https://www.fuint.cn/fuint-application + +################## 支付宝支付相关配置 ###################### +alipay.appId = 应用编号 +alipay.privateKey = 应用私钥 +alipay.publicKey = 支付宝公钥(通过应用公钥上传到支付宝开放平台换取支付宝公钥) +alipay.serverUrl=https://openapi.alipay.com/gateway.do +alipay.domain=https://www.fuint.cn/fuint-application/clientApi/pay/aliPayCallback + +################ 微信订阅模板消息配置 ###################### +weixin.subMessage.orderCreated=[{'key':'time', 'name':'订单时间'},{'key':'orderSn', 'name':'订单号'},{'key':'remark', 'name':'备注信息'}] +weixin.subMessage.deliverGoods=[{'key':'receiver', 'name':'收货人'}, {'key':'orderSn', 'name':'订单号'}, {'key':'expressCompany', 'name':'快递公司'}, {'key':'expressNo', 'name':'快递单号'}] +weixin.subMessage.couponExpire=[{'key':'name', 'name':'卡券名称'}, {'key':'expireTime', 'name':'到期时间'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.couponArrival=[{'key':'name', 'name':'卡券名称'},{'key':'amount', 'name':'金额'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.balanceChange=[{'key':'amount', 'name':'变动金额'},{'key':'time', 'name':'变动时间'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.couponConfirm=[{'key':'name', 'name':'卡券名称'},{'key':'time', 'name':'核销时间'}] +weixin.subMessage.pointChange=[{'key':'amount', 'name':'变动数量'},{'key':'time', 'name':'变动时间'},{'key':'remark', 'name':'备注信息'}] diff --git a/configure/prod/application.properties b/configure/prod/application.properties new file mode 100644 index 0000000..46506f4 --- /dev/null +++ b/configure/prod/application.properties @@ -0,0 +1,115 @@ +# 数据库配置 +spring.datasource.url=jdbc:mysql://localhost:3306/fuint-db?useUnicode=true&characterEncoding=UTF8&useSSL=false +spring.datasource.username=root +spring.datasource.password=root + +# Redis配置 +spring.session.store-type=redis +spring.session.redis.namespace=fuint +# Redis数据库索引(默认为0) +spring.redis.database=0 +# Redis服务器地址(生产) +spring.redis.host=127.0.0.1 +# Redis服务器连接端口 +spring.redis.port=6379 +# Redis服务器连接密码(默认为空) +spring.redis.password= +# 连接池最大连接数(使用负值表示没有限制) +spring.redis.pool.max-active=-1 +# 连接池最大阻塞等待时间(使用负值表示没有限制) +spring.redis.pool.max-wait=-1 +# 连接池中的最大空闲连接 +spring.redis.pool.max-idle=8 +# 连接池中的最小空闲连接 +spring.redis.pool.min-idle=0 +# 连接超时时间(毫秒) +spring.redis.timeout=0 + +# 系统名称 +system.name = fuint会员营销管理系统 + +# 前端h5地址 +website.url=https://www.fuint.cn/h5/ + +# 上传图片本地地址 +images.root=/www/wwwroot/www.xxx.com +images.path=/static/uploadImages/ + +# 上传图片服务器域名 +images.upload.url=http://localhost:8080 + +# 上传图片允许的大小(单位:MB) +images.upload.maxSize=5 + +################## 定时脚本配置 ######################### +# 定时发送消息 +message.job.switch = 1 +message.job.time = 0 0/1 * * * ? + +# 卡券到期处理 +couponExpire.job.switch = 1 +couponExpire.job.time = 0 0/1 * * * ? + +# 订单超时取消 +orderCancel.job.switch = 1 +orderCancel.job.time = 0 0/1 * * * ? + +# 分佣提成计算 +commission.job.switch = 1 +commission.job.time = 0 0/1 * * * ? + +# 微信小程序上传发货信息处理 +uploadShippingInfoJob.job.switch = 1 +uploadShippingInfoJob.job.time = 0 0/1 * * * ? + +################## 阿里云短信配置 ####################### +# 短信接口模式[0-关闭 1-打开] +aliyun.sms.mode = 0 +aliyun.sms.accessKeyId=LTAI4GJMjV123oXsrQJLnPZt +aliyun.sms.accessKeySecret=eGVBL30u5Ypj234d7XODlwYKWTaGT +# 阿里云短信签名 +aliyun.sms.signName=延禾技术 + +################## 阿里云OSS存储配置###################### +# 模式[0-关闭 1-打开] +aliyun.oss.mode = 0 +aliyun.oss.accessKeyId = LTAI4GJMjVhBa212rQJLnPZt +aliyun.oss.accessKeySecret = eGVBL30u53456gXd7XODlwYKWTaGT +aliyun.oss.endpoint = https://oss-cn-shenzhen.aliyuncs.com +aliyun.oss.bucketName = fuint-application +# 上传文件夹 +aliyun.oss.folder = uploads +# 访问域名 +aliyun.oss.domain = https://fuint-application.oss-cn-shenzhen.aliyuncs.com + +################## 高德地图配置 ########################### +amap.key = 高德地图key + +################## 微信相关配置 ########################### +# 公众号配置 +weixin.official.appId=wxf4327ef05c27a0 +weixin.official.appSecret=1f55e8749332234d9a074873d8e6a3 + +# 小程序配置 +wxpay.appId = wxb6af3741234162bc +wxpay.appSecret = 76a538bfa5b55a4564d5f2be5540 +wxpay.mchId=1636980812 +wxpay.apiV2=34354320201030y323e432342343 +wxpay.certPath=/usr/local/fuint/cert/apiclient_cert.p12 +wxpay.domain=https://www.fuint.cn/fuint-application + +################## 支付宝支付相关配置 ###################### +alipay.appId = 应用编号 +alipay.privateKey = 应用私钥 +alipay.publicKey = 支付宝公钥(通过应用公钥上传到支付宝开放平台换取支付宝公钥) +alipay.serverUrl=https://openapi.alipay.com/gateway.do +alipay.domain=https://www.fuint.cn/fuint-application/clientApi/pay/aliPayCallback + +################ 微信订阅模板消息配置 ###################### +weixin.subMessage.orderCreated=[{'key':'time', 'name':'订单时间'},{'key':'orderSn', 'name':'订单号'},{'key':'remark', 'name':'备注信息'}] +weixin.subMessage.deliverGoods=[{'key':'receiver', 'name':'收货人'}, {'key':'orderSn', 'name':'订单号'}, {'key':'expressCompany', 'name':'快递公司'}, {'key':'expressNo', 'name':'快递单号'}] +weixin.subMessage.couponExpire=[{'key':'name', 'name':'卡券名称'}, {'key':'expireTime', 'name':'到期时间'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.couponArrival=[{'key':'name', 'name':'卡券名称'},{'key':'amount', 'name':'金额'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.balanceChange=[{'key':'amount', 'name':'变动金额'},{'key':'time', 'name':'变动时间'},{'key':'tips', 'name':'温馨提示'}] +weixin.subMessage.couponConfirm=[{'key':'name', 'name':'卡券名称'},{'key':'time', 'name':'核销时间'}] +weixin.subMessage.pointChange=[{'key':'amount', 'name':'变动数量'},{'key':'time', 'name':'变动时间'},{'key':'remark', 'name':'备注信息'}] diff --git a/db/fuint-db.sql b/db/fuint-db.sql new file mode 100644 index 0000000..0855c47 --- /dev/null +++ b/db/fuint-db.sql @@ -0,0 +1,6571 @@ +/*Table structure for table `mt_address` */ + +DROP TABLE IF EXISTS `mt_address`; + +CREATE TABLE `mt_address` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '用户ID', + `NAME` varchar(30) NOT NULL DEFAULT '' COMMENT '收货人姓名', + `MOBILE` varchar(20) DEFAULT '' COMMENT '收货手机号', + `PROVINCE_ID` int unsigned DEFAULT '0' COMMENT '省份ID', + `CITY_ID` int unsigned DEFAULT '0' COMMENT '城市ID', + `REGION_ID` int DEFAULT '0' COMMENT '区/县ID', + `DETAIL` varchar(255) DEFAULT '' COMMENT '详细地址', + `IS_DEFAULT` char(1) DEFAULT 'N' COMMENT '是否默认', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员地址表'; + +/*Data for the table `mt_address` */ + +/*Table structure for table `mt_article` */ + +DROP TABLE IF EXISTS `mt_article`; + +CREATE TABLE `mt_article` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `STORE_ID` int NOT NULL DEFAULT '0' COMMENT '目录ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `TITLE` varchar(100) DEFAULT '' COMMENT '标题', + `BRIEF` varchar(500) DEFAULT '' COMMENT '简介', + `URL` varchar(100) DEFAULT '' COMMENT '链接地址', + `IMAGE` varchar(200) DEFAULT '' COMMENT '图片地址', + `DESCRIPTION` text COMMENT '描述', + `CLICK` int DEFAULT '0' COMMENT '点击次数', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `SORT` int DEFAULT '0' COMMENT '排序', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;N:禁用;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8 COMMENT='文章表'; + +/*Data for the table `mt_article` */ + +insert into `mt_article`(`ID`,`STORE_ID`,`MERCHANT_ID`,`TITLE`,`BRIEF`,`URL`,`IMAGE`,`DESCRIPTION`,`CLICK`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`SORT`,`STATUS`) values +(3,7,1,'“美食荒漠”? 温州:不存在的!','吃妈妈做的菜?或者足不出户,优哉游哉?不管在哪,假期的意义,绝对少不了一个“吃”。周刊君特别推出“五一就要吃”评论系列,小伙伴们会来讲讲,他们各自心心念念的家乡美食。也欢迎大家留言参与,看看哪个更馋人。','','/static/defaultImage/banner-2.png?v=1','

oi五一假期终于来了,你在哪?是去看人山人海,搞“特种兵式的旅行”,还是回老家,吃妈妈做的菜?或者足不出户,优哉游哉?不管在哪,假期的意义,绝对少不了一个“吃”。周刊君特别推出“五一就要吃”评论系列,小伙伴们会来讲讲,他们各自心心念念的家乡美食。也欢迎大家留言参与,看看哪个更馋人。  我的家乡,是一座山城相拥、海陆交融的山水之城。


  诗画山水,温润之州,是为温州。


  这里有“欲写龙湫难下笔,不游雁荡是虚生”中国东南第一山雁荡山,有山水诗的发祥地楠溪江,有山与海的尽头、东海明珠南麂岛,更有“走遍千山万水、想尽千方百计、说尽千言万语、吃尽千辛万苦”的温州精神。


  温州古为瓯越大地,也称东瓯,故这里的食物被称为“瓯菜”。


  这里山川湖海汇聚,美食自然丰富多样。山里的、海里的、湖里的、江里的、溪里的,各有各的滋味,所谓一方水土一方美食,无外乎如此。


  很多人对温州美食的初印象,来自电视剧《温州一家人》,这部由李立群、殷桃、张译主演的热播剧,讲述了温州一个普通家庭的草根创业奋斗史。



  在这部剧中,温州的美食伴随着市井烟火气,令人垂涎欲滴。但现实却是,或许是温州人对于这些美食太过习以为常,又或许是温州于经商一途上声名太响,让人潜意识里忽略了这里的吃食,误以为是“美食荒漠”,并不为太多人所熟知,以至于忽略了这里蕴藏着一座城的美食。


  至少来温州旅游的人,很少是冲着美食来的。

',105,'2023-05-12 09:12:16','2023-06-20 17:14:24','fuint',0,'A'), +(5,1,1,'又到一年最佳赏樱季','又到一年最佳赏樱季,一直想去亲眼目睹一次被誉为“世界三大赏樱胜地”之一 的无锡鼋头渚,正值无锡太湖鼋头渚国际樱花节 ,3万多株、100多个品种的樱花树,着实让人期待。','','/static/defaultImage/banner-1.png?v=1','

又到一年最佳赏樱季,一直想去亲眼目睹一次被誉为“世界三大赏樱胜地”之一 的无锡鼋头渚,正值无锡太湖鼋头渚国际樱花节 ,3万多株、100多个品种的樱花树,着实让人期待。

无锡太湖鼋头渚国际樱花节将从3月1日持续至5月3日,这期间来可以看到早樱、中樱、晚樱等各品种的樱花独揽芳华,晨赏、日赏、暮赏、夜赏,能看到千姿百态的樱花。


走在鼋头渚的小道上,空气里都是芬芳的樱花味道,漫山遍野的樱花,粉白、玫红、粉红色……不同的颜色交叠,层次感丰富,浪漫迷人~


我喜欢这里樱花盛开的时候,建筑的设计和樱花的飘落,虽然去的那天是阴天,但是却也别有一番诗情画意,小桥流水,樱花古韵,水波带着花影泛起阵阵涟漪,随手一拍就会有一种中式浪漫的感觉,沉醉在江南意境中,尤其穿上汉服拍照,绝美!

',88,'2023-05-12 18:29:01','2023-07-05 15:05:37','fuint',1,'A'); + +/*Table structure for table `mt_balance` */ + +DROP TABLE IF EXISTS `mt_balance`; + +CREATE TABLE `mt_balance` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `MOBILE` varchar(11) DEFAULT '' COMMENT '手机号', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '用户ID', + `ORDER_SN` varchar(32) DEFAULT '' COMMENT '订单号', + `AMOUNT` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额变化数量', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `DESCRIPTION` varchar(200) DEFAULT '' COMMENT '备注说明', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A正常;D作废', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='余额变化表'; + +/*Data for the table `mt_balance` */ + +insert into `mt_balance`(`ID`,`MERCHANT_ID`,`STORE_ID`,`MOBILE`,`USER_ID`,`ORDER_SN`,`AMOUNT`,`CREATE_TIME`,`UPDATE_TIME`,`DESCRIPTION`,`OPERATOR`,`STATUS`) values +(1,1,0,'18976679980',163,'202309082201183531567',-72.08,'2023-09-08 22:01:18','2023-09-08 22:01:18','','','A'), +(2,1,0,'18976679980',163,'202309082204254176805',-72.08,'2023-09-08 22:04:25','2023-09-08 22:04:25','','','A'), +(4,0,3,'18976679980',163,'202309201800308947963',-4.04,'2023-09-20 18:00:31','2023-09-20 18:00:31','','','A'), +(5,0,3,'18976679980',163,'202309210835395956418',-80.00,'2023-09-21 08:35:40','2023-09-21 08:35:40','','','A'); + +/*Table structure for table `mt_banner` */ + +DROP TABLE IF EXISTS `mt_banner`; + +CREATE TABLE `mt_banner` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `TITLE` varchar(100) DEFAULT '' COMMENT '标题', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `URL` varchar(100) DEFAULT '' COMMENT '链接地址', + `IMAGE` varchar(200) DEFAULT '' COMMENT '图片地址', + `DESCRIPTION` text COMMENT '描述', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `SORT` int DEFAULT '0' COMMENT '排序', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=215 DEFAULT CHARSET=utf8 COMMENT='会员端焦点图表'; + +/*Data for the table `mt_banner` */ + +insert into `mt_banner`(`ID`,`TITLE`,`MERCHANT_ID`,`STORE_ID`,`URL`,`IMAGE`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`SORT`,`STATUS`) values +(1,'活动',1,0,'pages/user/index','/static/defaultImage/banner-2.png?v=1','','2021-04-14 09:38:20','2023-08-01 07:52:08','fuint',1,'A'), +(2,'活动',2,0,'pages/category/index','/static/defaultImage/banner-1.png?v=1','','2021-04-14 09:38:36','2023-07-25 17:37:40','fuint',1,'A'); + +/*Table structure for table `mt_book` */ + +DROP TABLE IF EXISTS `mt_book`; + +CREATE TABLE `mt_book` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `NAME` varchar(255) DEFAULT NULL COMMENT '预约名称', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `TYPE` varchar(30) DEFAULT 'time' COMMENT '预约方式,time:按时间预约;staff:按员工预约', + `LOGO` varchar(255) DEFAULT '' COMMENT 'LOGO图片', + `GOODS_ID` int DEFAULT '0' COMMENT '预约服务ID', + `CATE_ID` int DEFAULT '0' COMMENT '预约分类', + `SERVICE_DATES` varchar(1000) DEFAULT '' COMMENT '可预约日期', + `SERVICE_TIMES` varchar(1000) DEFAULT '' COMMENT '可预约时间段', + `SERVICE_STAFF_IDS` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '可预约员工ID', + `DESCRIPTION` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '预约说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `SORT` int DEFAULT '0' COMMENT '排序', + `STATUS` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'A' COMMENT '订单状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='预约表'; + +/*Data for the table `mt_book` */ + +insert into `mt_book`(`ID`,`NAME`,`MERCHANT_ID`,`STORE_ID`,`TYPE`,`LOGO`,`GOODS_ID`,`CATE_ID`,`SERVICE_DATES`,`SERVICE_TIMES`,`SERVICE_STAFF_IDS`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`SORT`,`STATUS`) values +(1,'门店大保养预约',1,2,'time','/static/defaultImage/banner-2.png?v=1',1,1,'2024-08-21,2024-08-22,2024-08-23,2024-08-24,2024-08-31,2024-08-30,2024-08-29','08:30-12:00-2,14:00-18:00-3','1,2,3','小保养预约,请提前预约。线上预约提交后,店员审核,审核结果将以短信通知您,给您带来不便敬请谅解,感谢您的支持!','2023-02-14 11:45:54','2024-08-16 18:01:50','fuint',3,'A'), +(2,'门店小保养预约',1,0,'time','/static/defaultImage/banner-1.png?v=1',0,2,'2024-08-14,2024-08-15,2024-08-16','08:30-12:00-3,14:00-18:00-4','','小保养预约,请提前预约。线上预约提交后,店员审核,审核结果将以短信通知您,给您带来不便敬请谅解,感谢您的支持!','2024-08-05 18:58:45','2024-08-16 18:01:42','fuint',2,'A'); + +/*Table structure for table `mt_book_cate` */ + +DROP TABLE IF EXISTS `mt_book_cate`; + +CREATE TABLE `mt_book_cate` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int NOT NULL COMMENT '所属商户', + `STORE_ID` int DEFAULT NULL COMMENT '所属店铺', + `NAME` varchar(50) NOT NULL COMMENT '分类名称', + `LOGO` varchar(255) DEFAULT NULL COMMENT '封面图片', + `DESCRIPTION` varchar(500) DEFAULT NULL COMMENT '说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `SORT` int DEFAULT NULL COMMENT '排序', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `STATUS` char(1) DEFAULT NULL COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='预约分类'; + +/*Data for the table `mt_book_cate` */ + +insert into `mt_book_cate`(`ID`,`MERCHANT_ID`,`STORE_ID`,`NAME`,`LOGO`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`SORT`,`OPERATOR`,`STATUS`) values +(1,1,0,'测试001','/static/defaultImage/banner-2.png?v=1','11211111','2024-08-05 14:36:16','2024-08-14 09:52:29',2,'fuint','A'), +(2,1,0,'测试002','/static/defaultImage/banner-2.png?v=1','223112','2024-08-05 15:57:39','2024-08-13 18:55:32',1,'fuint','A'); + +/*Table structure for table `mt_book_item` */ + +DROP TABLE IF EXISTS `mt_book_item`; + +CREATE TABLE `mt_book_item` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `CATE_ID` int DEFAULT '0' COMMENT '预约分类ID', + `BOOK_ID` int DEFAULT '0' COMMENT '预约ID', + `USER_ID` int DEFAULT '0' COMMENT '预约用户ID', + `GOODS_ID` int DEFAULT '0' COMMENT '预约服务ID', + `VERIFY_CODE` varchar(10) DEFAULT '' COMMENT '核销码', + `CONTACT` varchar(30) DEFAULT NULL COMMENT '预约联系人', + `MOBILE` varchar(30) DEFAULT NULL COMMENT '预约手机号', + `SERVICE_DATE` varchar(100) DEFAULT NULL COMMENT '预约日期', + `SERVICE_TIME` varchar(100) DEFAULT NULL COMMENT '预约时间段', + `SERVICE_STAFF_ID` int DEFAULT NULL COMMENT '预约员工ID', + `REMARK` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '预约说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='预约详情表'; + +/*Data for the table `mt_book_item` */ + +/*Table structure for table `mt_cart` */ + +DROP TABLE IF EXISTS `mt_cart`; + +CREATE TABLE `mt_cart` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '会员ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `IS_VISITOR` char(1) DEFAULT 'N' COMMENT '是否游客', + `HANG_NO` varchar(10) DEFAULT '' COMMENT '挂单号', + `SKU_ID` int DEFAULT '0' COMMENT 'skuID', + `GOODS_ID` int DEFAULT '0' COMMENT '商品ID', + `NUM` double(10,2) DEFAULT '1.00' COMMENT '数量', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='购物车'; + +/*Data for the table `mt_cart` */ + +/*Table structure for table `mt_commission_cash` */ + +DROP TABLE IF EXISTS `mt_commission_cash`; + +CREATE TABLE `mt_commission_cash` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `SETTLE_NO` varchar(32) DEFAULT NULL COMMENT '结算单号', + `UUID` varchar(32) DEFAULT NULL COMMENT '结算UUID', + `MERCHANT_ID` int NOT NULL COMMENT '商户ID', + `STORE_ID` int DEFAULT NULL COMMENT '店铺ID', + `USER_ID` int DEFAULT NULL COMMENT '会员ID', + `STAFF_ID` int DEFAULT NULL COMMENT '员工ID', + `AMOUNT` decimal(10,2) DEFAULT NULL COMMENT '金额', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `DESCRIPTION` varchar(500) DEFAULT NULL COMMENT '备注信息', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:待确认,B:已确认,C:已支付,D:已作废', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='分佣提现记录表'; + +/*Data for the table `mt_commission_cash` */ + +/*Table structure for table `mt_commission_log` */ + +DROP TABLE IF EXISTS `mt_commission_log`; + +CREATE TABLE `mt_commission_log` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int NOT NULL COMMENT '商户ID', + `TARGET` varchar(30) DEFAULT '' COMMENT '对象,member:会员分销;staff:员工提成', + `TYPE` varchar(30) NOT NULL COMMENT '分佣类型', + `LEVEL` int DEFAULT '1' COMMENT '分销等级', + `USER_ID` int DEFAULT NULL COMMENT '会员ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `STAFF_ID` int DEFAULT '0' COMMENT '员工ID', + `ORDER_ID` int DEFAULT '0' COMMENT '订单ID', + `AMOUNT` decimal(10,2) DEFAULT NULL COMMENT '分佣金额', + `RULE_ID` int DEFAULT NULL COMMENT '分佣规则ID', + `RULE_ITEM_ID` int DEFAULT NULL COMMENT '分佣规则项ID', + `DESCRIPTION` varchar(500) DEFAULT NULL COMMENT '备注信息', + `SETTLE_UUID` varchar(32) DEFAULT NULL COMMENT '结算uuid', + `CASH_ID` int DEFAULT NULL COMMENT '提现记录ID', + `IS_CASH` char(1) DEFAULT 'N' COMMENT '是否提现,Y:是;N:否', + `CASH_TIME` datetime DEFAULT NULL COMMENT '提现时间', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:待结算;B:已结算;C:已作废', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='佣金记录表'; + +/*Data for the table `mt_commission_log` */ + +/*Table structure for table `mt_commission_relation` */ + +DROP TABLE IF EXISTS `mt_commission_relation`; + +CREATE TABLE `mt_commission_relation` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int NOT NULL COMMENT '商户ID', + `USER_ID` int DEFAULT NULL COMMENT '邀请会员ID', + `LEVEL` int DEFAULT '1' COMMENT '等级', + `INVITE_CODE` varchar(32) DEFAULT '' COMMENT '邀请码', + `SUB_USER_ID` int DEFAULT NULL COMMENT '被邀请会员ID', + `DESCRIPTION` varchar(500) DEFAULT NULL COMMENT '说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:激活;D:删除', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员分销关系表'; + +/*Data for the table `mt_commission_relation` */ + +/*Table structure for table `mt_commission_rule` */ + +DROP TABLE IF EXISTS `mt_commission_rule`; + +CREATE TABLE `mt_commission_rule` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `NAME` varchar(100) DEFAULT '' COMMENT '规则名称', + `TYPE` varchar(30) DEFAULT NULL COMMENT '方案类型', + `TARGET` varchar(30) DEFAULT '' COMMENT '方案对象,member:会员分销;staff:员工提成', + `MERCHANT_ID` int NOT NULL COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `STORE_IDS` varchar(500) DEFAULT '' COMMENT '适用店铺', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `DESCRIPTION` varchar(1000) DEFAULT NULL COMMENT '备注信息', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:激活;N:禁用;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='方案规则表'; + +/*Data for the table `mt_commission_rule` */ + +/*Table structure for table `mt_commission_rule_item` */ + +DROP TABLE IF EXISTS `mt_commission_rule_item`; + +CREATE TABLE `mt_commission_rule_item` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `TYPE` varchar(30) DEFAULT NULL COMMENT '分佣类型', + `RULE_ID` int NOT NULL DEFAULT '0' COMMENT '规则ID', + `MERCHANT_ID` int NOT NULL COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '适用店铺', + `TARGET` varchar(30) DEFAULT NULL COMMENT '分佣对象', + `TARGET_ID` int NOT NULL DEFAULT '0' COMMENT '对象ID', + `METHOD` varchar(30) DEFAULT NULL COMMENT '提成方式(按比例/固定金额)', + `STORE_IDS` varchar(500) DEFAULT '' COMMENT '适用店铺', + `GUEST` decimal(10,2) DEFAULT NULL COMMENT '散客佣金', + `SUB_GUEST` decimal(10,2) DEFAULT NULL COMMENT '二级散客佣金', + `MEMBER` decimal(10,2) DEFAULT NULL COMMENT '会员佣金', + `SUB_MEMBER` decimal(10,2) DEFAULT NULL COMMENT '二级会员佣金', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:激活;N:禁用;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='分佣提成规则项目表'; + +/*Data for the table `mt_commission_rule_item` */ + +/*Table structure for table `mt_confirm_log` */ + +DROP TABLE IF EXISTS `mt_confirm_log`; + +CREATE TABLE `mt_confirm_log` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `CODE` varchar(32) NOT NULL DEFAULT '' COMMENT '编码', + `AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '核销金额', + `COUPON_ID` int DEFAULT '0' COMMENT '卡券ID', + `USER_COUPON_ID` int NOT NULL DEFAULT '0' COMMENT '用户券ID', + `ORDER_ID` int DEFAULT '0' COMMENT '订单ID', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '卡券所属用户ID', + `OPERATOR_USER_ID` int DEFAULT NULL COMMENT '核销者用户ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int NOT NULL DEFAULT '0' COMMENT '核销店铺ID', + `STATUS` varchar(1) NOT NULL COMMENT '状态,A正常核销;D:撤销使用', + `CANCEL_TIME` datetime DEFAULT NULL COMMENT '撤销时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `OPERATOR_FROM` varchar(30) DEFAULT 'mt_user' COMMENT '操作来源user_id对应表t_account 还是 mt_user', + `REMARK` varchar(500) DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='核销记录表'; + +/*Data for the table `mt_confirm_log` */ + +/*Table structure for table `mt_coupon` */ + +DROP TABLE IF EXISTS `mt_coupon`; + +CREATE TABLE `mt_coupon` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `GROUP_ID` int NOT NULL DEFAULT '0' COMMENT '券组ID', + `TYPE` char(1) DEFAULT 'C' COMMENT '券类型,C优惠券;P预存卡;T集次卡', + `CONTENT` int DEFAULT '1' COMMENT '内容,如:1表示满减券、2表示折扣券', + `NAME` varchar(100) NOT NULL DEFAULT '' COMMENT '券名称', + `IS_GIVE` tinyint(1) DEFAULT '0' COMMENT '是否允许转赠', + `GRADE_IDS` varchar(100) DEFAULT '' COMMENT '适用会员等级', + `POINT` int DEFAULT '0' COMMENT '获得卡券所消耗积分', + `APPLY_GOODS` varchar(20) DEFAULT '' COMMENT '适用商品:allGoods、parkGoods', + `RECEIVE_CODE` varchar(32) DEFAULT '' COMMENT '领取码', + `USE_FOR` varchar(30) DEFAULT '' COMMENT '使用专项', + `EXPIRE_TYPE` varchar(30) DEFAULT '' COMMENT '过期类型', + `EXPIRE_TIME` int DEFAULT '0' COMMENT '有效期,单位:天', + `BEGIN_TIME` datetime DEFAULT NULL COMMENT '开始有效期', + `END_TIME` datetime DEFAULT NULL COMMENT '结束有效期', + `AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '面额', + `SEND_WAY` varchar(20) DEFAULT 'backend' COMMENT '发放方式', + `SEND_NUM` int unsigned DEFAULT '1' COMMENT '每次发放数量', + `TOTAL` int DEFAULT '0' COMMENT '发行数量', + `LIMIT_NUM` int DEFAULT '1' COMMENT '每人拥有数量限制', + `EXCEPT_TIME` varchar(500) DEFAULT '' COMMENT '不可用日期,逗号隔开。周末:weekend;其他:2019-01-02_2019-02-09', + `STORE_IDS` varchar(100) DEFAULT '' COMMENT '所属店铺ID,逗号隔开', + `DESCRIPTION` varchar(2000) DEFAULT '' COMMENT '描述信息', + `IMAGE` varchar(100) DEFAULT '' COMMENT '效果图片', + `REMARKS` varchar(1000) DEFAULT '' COMMENT '后台备注', + `IN_RULE` varchar(1000) DEFAULT '' COMMENT '获取券的规则', + `OUT_RULE` varchar(1000) DEFAULT '' COMMENT '核销券的规则', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='卡券信息表'; + +/*Data for the table `mt_coupon` */ + +/*Table structure for table `mt_coupon_goods` */ + +DROP TABLE IF EXISTS `mt_coupon_goods`; + +CREATE TABLE `mt_coupon_goods` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `COUPON_ID` int NOT NULL COMMENT '卡券ID', + `GOODS_ID` int NOT NULL COMMENT '商品ID', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='卡券商品表'; + +/*Data for the table `mt_coupon_goods` */ + +/*Table structure for table `mt_coupon_group` */ + +DROP TABLE IF EXISTS `mt_coupon_group`; + +CREATE TABLE `mt_coupon_group` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `NAME` varchar(100) NOT NULL DEFAULT '' COMMENT '券组名称', + `MONEY` decimal(18,2) DEFAULT '0.00' COMMENT '价值金额', + `NUM` int DEFAULT '0' COMMENT '券种类数量', + `TOTAL` int DEFAULT '0' COMMENT '发行数量', + `DESCRIPTION` varchar(2000) DEFAULT '' COMMENT '备注', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建日期', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='优惠券组'; + +/*Data for the table `mt_coupon_group` */ + +/*Table structure for table `mt_freight` */ + +DROP TABLE IF EXISTS `mt_freight`; + +CREATE TABLE `mt_freight` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `NAME` varchar(100) NOT NULL COMMENT '名称', + `TYPE` int NOT NULL COMMENT '计费类型,1:按件数;2:按重量', + `AMOUNT` decimal(10,2) NOT NULL COMMENT '费用', + `INCRE_AMOUNT` decimal(10,2) NOT NULL COMMENT '续费', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) NOT NULL COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='运费模板'; + +/*Data for the table `mt_freight` */ + +/*Table structure for table `mt_freight_region` */ + +DROP TABLE IF EXISTS `mt_freight_region`; + +CREATE TABLE `mt_freight_region` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `FREIGHT_ID` int NOT NULL COMMENT '运费模板ID', + `PROVINCE_ID` int NOT NULL COMMENT '省份ID', + `CITY_ID` int NOT NULL COMMENT '城市ID', + `AREA_ID` int NOT NULL COMMENT '区域ID', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) NOT NULL COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='运费模板地区'; + +/*Data for the table `mt_freight_region` */ + +/*Table structure for table `mt_give` */ + +DROP TABLE IF EXISTS `mt_give`; + +CREATE TABLE `mt_give` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '获赠者用户ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `GIVE_USER_ID` int NOT NULL DEFAULT '0' COMMENT '赠送者用户ID', + `MOBILE` varchar(20) NOT NULL DEFAULT '' COMMENT '赠予对象手机号', + `USER_MOBILE` varchar(20) NOT NULL DEFAULT '' COMMENT '用户手机', + `GROUP_IDS` varchar(200) NOT NULL DEFAULT '' COMMENT '券组ID,逗号隔开', + `GROUP_NAMES` varchar(500) NOT NULL DEFAULT '' COMMENT '券组名称,逗号隔开', + `COUPON_IDS` varchar(200) NOT NULL DEFAULT '' COMMENT '券ID,逗号隔开', + `COUPON_NAMES` varchar(500) NOT NULL DEFAULT '' COMMENT '券名称,逗号隔开', + `NUM` int NOT NULL DEFAULT '0' COMMENT '数量', + `MONEY` decimal(10,2) NOT NULL COMMENT '总金额', + `NOTE` varchar(200) DEFAULT '' COMMENT '备注', + `MESSAGE` varchar(500) DEFAULT '' COMMENT '留言', + `CREATE_TIME` datetime NOT NULL COMMENT '赠送时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT '状态,A正常;C取消', + PRIMARY KEY (`ID`), + KEY `index_user_id` (`USER_ID`) USING BTREE, + KEY `index_give_user_id` (`GIVE_USER_ID`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='转赠记录表'; + +/*Data for the table `mt_give` */ + +insert into `mt_give`(`ID`,`USER_ID`,`MERCHANT_ID`,`STORE_ID`,`GIVE_USER_ID`,`MOBILE`,`USER_MOBILE`,`GROUP_IDS`,`GROUP_NAMES`,`COUPON_IDS`,`COUPON_NAMES`,`NUM`,`MONEY`,`NOTE`,`MESSAGE`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`) values +(1,163,1,1,693,'18976679980','18888884444','4','2021年中秋','4','酬宾早餐优惠券',1,50.00,'','转赠一张优惠券给你','2022-02-11 13:43:47','2022-02-11 13:43:47','A'), +(2,772,1,1,772,'18175702219','18175702219','12','26656','30','tanyi',1,10.00,'','转赠一张优惠券给你','2022-03-06 20:19:18','2022-03-06 20:19:18','A'), +(3,921,1,1,921,'13882064775','13882064775','6','十月份活动','14','优惠券10元',1,100.00,'','转赠一张优惠券给你','2022-04-13 19:46:41','2022-04-13 19:46:41','A'), +(4,1,1,1,163,'18976679981','18976679980','5','2021十一活动','15','100元优惠券',1,20.00,'','转赠一张优惠券给你','2022-05-11 20:43:02','2022-05-11 20:43:02','A'), +(5,1,1,1,163,'18976679981','18976679980','4','2021年中秋','3','2022年51限额500名活动预存券',1,200.00,'','转赠一张优惠券给你','2022-05-11 21:28:41','2022-05-11 21:28:41','A'), +(6,1162,1,1,1126,'18818996621','','26','全场典藏卡券(测试)','70','全场典藏卡券(测试)',1,50.00,'','转赠一张优惠券给你','2022-06-06 15:40:11','2022-06-06 15:40:11','A'), +(7,1234,1,1,1233,'13560320801','','26','全场典藏卡券(测试)','71','全场免单优惠券',1,999.00,'','转赠一张优惠券给你','2022-06-22 10:01:14','2022-06-22 10:01:14','A'), +(8,1235,1,1,1233,'13711105014','','5','2021十一活动','17','10月份优惠券',1,18.00,'','转赠一张优惠券给你','2022-06-22 10:01:25','2022-06-22 10:01:25','A'), +(9,1,1,1,163,'18976679981','18976679980','6','十月份活动','14','优惠券10元',1,100.00,'','转赠一张优惠券给你','2022-06-28 15:22:41','2022-06-28 15:22:41','A'), +(10,1322,1,1,1069,'17796656160','','5','2021十一活动','17','10月份优惠券',1,18.00,'','转赠一张优惠券给你','2022-07-14 09:35:37','2022-07-14 09:35:37','A'), +(11,1359,1,1,1356,'18208252470','','5','2021十一活动','17','10月份优惠券',1,18.00,'','转赠一张优惠券给你','2022-07-22 18:39:17','2022-07-22 18:39:17','A'), +(12,1385,1,1,1369,'15713899276','18695879188','31','test分组','94','test22272109',1,10.00,'','转赠一张优惠券给你','2022-07-29 16:54:15','2022-07-29 16:54:15','A'), +(13,1386,1,1,1369,'15713899276','18695879188','31','test分组','94','test22272109',1,10.00,'','转赠一张优惠券给你','2022-07-29 17:04:24','2022-07-29 17:04:24','A'), +(14,1392,1,1,1392,'15988426226','15988426226','35','你妹','95','你妹洗脚优惠100元抵250元',1,100.00,'','转赠一张优惠券给你','2022-07-30 18:00:13','2022-07-30 18:00:13','A'), +(15,1496,1,1,1495,'15968205442','','5','2021十一活动','17','10月份优惠券',1,18.00,'','转赠一张优惠券给你','2022-08-20 00:18:24','2022-08-20 00:18:24','A'), +(16,1592,1,1,1592,'15117012015','15117012015','12','26656','29','新年快乐',1,10.00,'','转赠一张优惠券给你','2022-09-13 21:21:16','2022-09-13 21:21:16','A'), +(17,1650,1,1,1649,'18531161003','','12','26656','29','新年快乐',1,10.00,'','转赠一张优惠券给你','2022-09-26 08:23:22','2022-09-26 08:23:22','A'), +(18,1980,1,1,1977,'18946222313','','5','2021十一活动','17','10月份优惠券',1,18.00,'','转赠一张优惠券给你','2022-11-20 17:31:21','2022-11-20 17:31:21','A'), +(19,1981,1,1,1977,'13645684859','','5','2021十一活动','15','100元优惠券',1,20.00,'','转赠一张优惠券给你','2022-11-20 17:31:59','2022-11-20 17:31:59','A'), +(20,1992,1,1,1991,'18616998528','','4','2021年中秋','11','10元无门槛电子券',1,10.00,'','转赠一张优惠券给你','2022-11-21 18:11:18','2022-11-21 18:11:18','A'), +(21,2031,1,1,1508,'18667669897','18105765365','43','用于购买会员卡券','140','升级专用001',1,599.00,'','转赠一张优惠券给你','2022-11-25 18:22:52','2022-11-25 18:22:52','A'), +(22,2100,1,1,2099,'14716981537','','4','2021年中秋','18','12月份优惠券',1,6.00,'','转赠一张优惠券给你','2022-12-06 19:24:32','2022-12-06 19:24:32','A'), +(23,2228,1,1,163,'18988877767','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-08 23:20:49','2023-01-08 23:20:49','A'), +(24,2229,1,1,163,'18978878878','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-08 23:21:12','2023-01-08 23:21:12','A'), +(25,2230,1,1,163,'18977776678','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-08 23:21:39','2023-01-08 23:21:39','A'), +(26,2231,1,1,163,'18966643218','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-08 23:28:34','2023-01-08 23:28:34','A'), +(27,2232,1,1,163,'18976656656','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-09 07:50:51','2023-01-09 07:50:51','A'), +(28,163,1,1,163,'18976679980','18976679980','39','卡券测试1','139','店庆预存卡1',1,10000.00,'','转赠一张优惠券给你','2023-01-09 08:03:08','2023-01-09 08:03:08','A'), +(29,2021,1,1,163,'18976679981','18976679980','39','卡券测试1','139','店庆预存卡1',1,10000.00,'','转赠一张优惠券给你','2023-01-09 08:03:30','2023-01-09 08:03:30','A'), +(30,2021,1,1,163,'18976679981','18976679980','56','贷款手续费抵用券10','148','自制品礼品卡',1,10.00,'','转赠一张优惠券给你','2023-01-09 08:04:02','2023-01-09 08:04:02','A'), +(31,2021,1,1,163,'18976679981','18976679980','39','卡券测试1','139','店庆预存卡1',1,20000.00,'','转赠一张优惠券给你','2023-01-09 14:30:55','2023-01-09 14:30:55','A'), +(32,2376,1,1,2369,'15721593486','','57','2023年套餐一','153','20元优惠券',1,20.00,'','转赠一张优惠券给你','2023-02-03 14:50:39','2023-02-03 14:50:39','A'), +(33,2408,1,1,2364,'17743256453','','60','早餐','163','前台卡券',1,200.00,'','转赠一张优惠券给你','2023-02-07 15:13:34','2023-02-07 15:13:34','A'), +(34,2733,1,1,2733,'18333615432','18333615432','64','d卡券分组','180','储值卡',1,100.00,'','转赠一张优惠券给你','2023-03-07 10:58:12','2023-03-07 10:58:12','A'), +(35,3375,1,1,975,'18921201520','','45','优惠券','210','满200送50',1,50.00,'','转赠一张优惠券给你','2023-04-23 11:16:08','2023-04-23 11:16:08','A'), +(36,3586,1,1,3583,'18566798813','16620860215','71','优惠券','241','五一优惠券',1,10.00,'','转赠一张优惠券给你','2023-05-12 16:20:24','2023-05-12 16:20:24','A'), +(37,3582,1,1,3583,'18566798813','16620860215','71','优惠券','241','五一优惠券',1,10.00,'','转赠一张优惠券给你','2023-05-12 16:23:38','2023-05-12 16:23:38','A'), +(38,3627,1,1,3627,'17762624971','17762624971','71','优惠券','241','五一优惠券',1,10.00,'','转赠一张优惠券给你','2023-05-16 14:03:15','2023-05-16 14:03:15','A'), +(39,3631,1,1,3627,'17608449215','17762624971','71','优惠券','241','五一优惠券',1,10.00,'','转赠一张优惠券给你','2023-05-16 14:26:45','2023-05-16 14:26:45','A'), +(40,3646,1,1,3645,'13316396329','13620482612','45','优惠券','246','卡币',1,100.00,'','转赠一张优惠券给你','2023-05-17 09:59:18','2023-05-17 09:59:18','A'), +(41,4010,1,1,3907,'13730420256','','45','优惠券','210','满200送50',1,50.00,'','转赠一张优惠券给你','2023-06-13 09:29:39','2023-06-13 09:29:39','A'), +(42,3907,1,1,3907,'13730420256','13730420256','76','服务卡项','274','洗车券',1,10.00,'','转赠一张优惠券给你','2023-06-13 10:46:58','2023-06-13 10:46:58','A'), +(43,4492,1,1,3721,'13122858538','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-11 20:18:34','2023-07-11 20:18:34','A'), +(44,4493,1,1,3721,'17310014243','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-11 20:22:04','2023-07-11 20:22:04','A'), +(45,4493,1,1,3721,'17310014243','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-11 20:27:51','2023-07-11 20:27:51','A'), +(46,4510,1,1,4550,'18188889999','18112345678','91','游戏充值','321','穿越火线满100减50优惠券',1,50.00,'','转赠一张优惠券给你','2023-07-13 11:40:41','2023-07-13 11:40:41','A'), +(47,4493,1,1,3721,'17310014243','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-13 17:01:49','2023-07-13 17:01:49','A'), +(48,4567,1,1,4365,'15317665576','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-13 17:12:08','2023-07-13 17:12:08','A'), +(49,4567,1,1,4365,'15317665576','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-13 17:38:50','2023-07-13 17:38:50','A'), +(50,4493,1,1,3721,'17310014243','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-13 17:57:46','2023-07-13 17:57:46','A'), +(51,4493,1,1,3721,'17310014243','','71','优惠券','314','积分优惠券',1,10.00,'','转赠一张优惠券给你','2023-07-13 18:34:45','2023-07-13 18:34:45','A'), +(52,6000,1,1,6002,'18728796753','','57','2023年套餐一','153','20元优惠券',1,34.00,'','转赠一张优惠券给你','2023-07-24 19:28:55','2023-07-24 19:28:55','A'), +(53,6000,1,1,6002,'18728796753','','57','2023年套餐一','153','20元优惠券',1,34.00,'','转赠一张优惠券给你','2023-07-24 19:29:50','2023-07-24 19:29:50','A'), +(54,6038,1,1,6036,'18645122682','','57','2023年套餐一','153','20元优惠券',1,20.00,'','转赠一张优惠券给你','2023-07-25 10:16:37','2023-07-25 10:16:37','A'); + +/*Table structure for table `mt_give_item` */ + +DROP TABLE IF EXISTS `mt_give_item`; + +CREATE TABLE `mt_give_item` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `GIVE_ID` int NOT NULL COMMENT '转赠ID', + `USER_COUPON_ID` int NOT NULL COMMENT '用户电子券ID', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) NOT NULL COMMENT '状态,A正常;D删除', + PRIMARY KEY (`ID`), + KEY `index_give_id` (`GIVE_ID`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='转赠明细表'; + +/*Data for the table `mt_give_item` */ + +insert into `mt_give_item`(`ID`,`GIVE_ID`,`USER_COUPON_ID`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`) values +(1,1,613,'2022-02-11 13:43:47','2022-02-11 13:43:47','A'), +(2,2,1658,'2022-03-06 20:19:18','2022-03-06 20:19:18','A'), +(3,3,122298,'2022-04-13 19:46:41','2022-04-13 19:46:41','A'), +(4,4,15,'2022-05-11 20:43:02','2022-05-11 20:43:02','A'), +(5,5,44,'2022-05-11 21:28:41','2022-05-11 21:28:41','A'), +(6,6,1798,'2022-06-06 15:40:11','2022-06-06 15:40:11','A'), +(7,7,2404,'2022-06-22 10:01:14','2022-06-22 10:01:14','A'), +(8,8,2405,'2022-06-22 10:01:25','2022-06-22 10:01:25','A'), +(9,9,2621,'2022-06-28 15:22:41','2022-06-28 15:22:41','A'), +(10,10,67,'2022-07-14 09:35:37','2022-07-14 09:35:37','A'), +(11,11,23,'2022-07-22 18:39:17','2022-07-22 18:39:17','A'), +(12,12,400,'2022-07-29 16:54:15','2022-07-29 16:54:15','A'), +(13,13,399,'2022-07-29 17:04:24','2022-07-29 17:04:24','A'), +(14,14,419,'2022-07-30 18:00:13','2022-07-30 18:00:13','A'), +(15,15,30701,'2022-08-20 00:18:24','2022-08-20 00:18:24','A'), +(16,16,211369,'2022-09-13 21:21:16','2022-09-13 21:21:16','A'), +(17,17,211502,'2022-09-26 08:23:22','2022-09-26 08:23:22','A'), +(18,18,19294,'2022-11-20 17:31:21','2022-11-20 17:31:21','A'), +(19,19,19548,'2022-11-20 17:31:59','2022-11-20 17:31:59','A'), +(20,20,19575,'2022-11-21 18:11:18','2022-11-21 18:11:18','A'), +(21,21,20280,'2022-11-25 18:22:52','2022-11-25 18:22:52','A'), +(22,22,29107,'2022-12-06 19:24:32','2022-12-06 19:24:32','A'), +(23,23,31903,'2023-01-08 23:20:49','2023-01-08 23:20:49','A'), +(24,24,31903,'2023-01-08 23:21:12','2023-01-08 23:21:12','A'), +(25,25,31903,'2023-01-08 23:21:39','2023-01-08 23:21:39','A'), +(26,26,31903,'2023-01-08 23:28:34','2023-01-08 23:28:34','A'), +(27,27,31903,'2023-01-09 07:50:51','2023-01-09 07:50:51','A'), +(28,28,31902,'2023-01-09 08:03:08','2023-01-09 08:03:08','A'), +(29,29,31902,'2023-01-09 08:03:30','2023-01-09 08:03:30','A'), +(30,30,31765,'2023-01-09 08:04:02','2023-01-09 08:04:02','A'), +(31,31,26562,'2023-01-09 14:30:55','2023-01-09 14:30:55','A'), +(32,32,42627,'2023-02-03 14:50:39','2023-02-03 14:50:39','A'), +(33,33,42858,'2023-02-07 15:13:34','2023-02-07 15:13:34','A'), +(34,34,600134,'2023-03-07 10:58:12','2023-03-07 10:58:12','A'), +(35,35,7000,'2023-04-23 11:16:08','2023-04-23 11:16:08','A'), +(36,36,674,'2023-05-12 16:20:24','2023-05-12 16:20:24','A'), +(37,37,670,'2023-05-12 16:23:38','2023-05-12 16:23:38','A'), +(38,38,854,'2023-05-16 14:03:15','2023-05-16 14:03:15','A'), +(39,39,854,'2023-05-16 14:26:45','2023-05-16 14:26:45','A'), +(40,40,870,'2023-05-17 09:59:18','2023-05-17 09:59:18','A'), +(41,41,1166,'2023-06-13 09:29:39','2023-06-13 09:29:39','A'), +(42,42,1198,'2023-06-13 10:46:58','2023-06-13 10:46:58','A'), +(43,43,1520,'2023-07-11 20:18:34','2023-07-11 20:18:34','A'), +(44,44,1521,'2023-07-11 20:22:04','2023-07-11 20:22:04','A'), +(45,45,1522,'2023-07-11 20:27:51','2023-07-11 20:27:51','A'), +(46,46,1555,'2023-07-13 11:40:41','2023-07-13 11:40:41','A'), +(47,47,1558,'2023-07-13 17:01:49','2023-07-13 17:01:49','A'), +(48,48,1560,'2023-07-13 17:12:08','2023-07-13 17:12:08','A'), +(49,49,1561,'2023-07-13 17:38:50','2023-07-13 17:38:50','A'), +(50,50,1559,'2023-07-13 17:57:46','2023-07-13 17:57:46','A'), +(51,51,1570,'2023-07-13 18:34:45','2023-07-13 18:34:45','A'), +(52,52,5114,'2023-07-24 19:28:55','2023-07-24 19:28:55','A'), +(53,53,5128,'2023-07-24 19:29:50','2023-07-24 19:29:50','A'), +(54,54,5152,'2023-07-25 10:16:37','2023-07-25 10:16:37','A'); + +/*Table structure for table `mt_goods` */ + +DROP TABLE IF EXISTS `mt_goods`; + +CREATE TABLE `mt_goods` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `TYPE` varchar(30) DEFAULT 'goods' COMMENT '商品类别', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `NAME` varchar(100) DEFAULT '' COMMENT '商品名称', + `CATE_ID` int DEFAULT '0' COMMENT '分类ID', + `BOOK_ID` int DEFAULT '0' COMMENT '预约项目ID', + `GOODS_NO` varchar(100) DEFAULT '' COMMENT '商品编码', + `PLATFORM` int DEFAULT '0' COMMENT '可用平台,0:不限,1:仅会员端(小程序和h5);2:仅收银端', + `IS_SINGLE_SPEC` char(1) NOT NULL DEFAULT 'Y' COMMENT '是否单规格', + `LOGO` varchar(200) DEFAULT '' COMMENT '主图地址', + `IMAGES` varchar(1000) DEFAULT '' COMMENT '图片地址', + `PRICE` decimal(10,2) unsigned DEFAULT '0.00' COMMENT '价格', + `LINE_PRICE` decimal(10,2) unsigned DEFAULT '0.00' COMMENT '划线价格', + `COST_PRICE` decimal(10,2) DEFAULT '0.00' COMMENT '成本价格', + `STOCK` double(10,2) unsigned DEFAULT '0.00' COMMENT '库存', + `WEIGHT` decimal(10,2) DEFAULT '0.00' COMMENT '重量', + `COUPON_IDS` varchar(500) DEFAULT '' COMMENT '关联卡券ID', + `SERVICE_TIME` int DEFAULT '0' COMMENT '服务时长,单位:分钟', + `INIT_SALE` double(10,2) DEFAULT '0.00' COMMENT '初始销量', + `SALE_POINT` varchar(100) DEFAULT '' COMMENT '商品卖点', + `CAN_USE_POINT` char(1) DEFAULT 'N' COMMENT '可否使用积分抵扣', + `IS_MEMBER_DISCOUNT` char(1) DEFAULT 'Y' COMMENT '会员是否有折扣', + `SORT` int DEFAULT '0' COMMENT '排序', + `DESCRIPTION` text COMMENT '商品描述', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=386 DEFAULT CHARSET=utf8 COMMENT='商品表'; + +/*Data for the table `mt_goods` */ + +insert into `mt_goods`(`ID`,`TYPE`,`MERCHANT_ID`,`STORE_ID`,`NAME`,`CATE_ID`,`GOODS_NO`,`PLATFORM`,`IS_SINGLE_SPEC`,`LOGO`,`IMAGES`,`PRICE`,`LINE_PRICE`,`COST_PRICE`,`STOCK`,`WEIGHT`,`COUPON_IDS`,`SERVICE_TIME`,`INIT_SALE`,`SALE_POINT`,`CAN_USE_POINT`,`IS_MEMBER_DISCOUNT`,`SORT`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`STATUS`) values +(1,'goods',1,0,'韩式防水围裙',1,'9983242340',0,'N','/static/uploadImages/20220110/4c90921a7fc34c97b0f62cebf314d2bb.jpg','[\"/static/uploadImages/20220110/4c90921a7fc34c97b0f62cebf314d2bb.jpg\",\"/static/uploadImages/20220110/9b64b3d65fa04296b62de186899f24ea.jpg\",\"/static/uploadImages/20220110/ff4809f7a17d4142ace9bc287aab105a.jpg\"]',88.00,99.00,0.00,90013.00,1.00,'',0,747.00,'超级防水','Y','Y',1,'

1234444

','2021-10-13 13:56:04','2023-07-31 19:51:21','fuint','A'), +(2,'goods',1,0,'小清新水果刀三件套',4,'6975486820418',0,'Y','/static/uploadImages/20220110/6b67b70f35734ff28a03aa3d82ac96a0.jpg','[\"/static/uploadImages/20220110/6b67b70f35734ff28a03aa3d82ac96a0.jpg\"]',0.01,20.00,0.00,1946.00,2.00,'',0,33.00,'小清新','Y','N',1,'

123

','2021-10-13 14:19:45','2023-07-31 20:01:44','fuint','A'), +(3,'goods',1,0,'可爱旅行大号牙刷杯两个装',3,'92342342342',0,'N','/static/uploadImages/20220110/56e306c812f240f89c0ed96ab8f94ad0.jpg','[\"/static/uploadImages/20220110/56e306c812f240f89c0ed96ab8f94ad0.jpg\",\"/static/uploadImages/20220110/56e306c812f240f89c0ed96ab8f94ad0.jpg\",\"/static/uploadImages/20220110/d39f84568b9746f89d9f6a368b8067c4.jpg\"]',99.00,120.00,0.00,6000.00,1.00,'',0,1532.00,'超级实惠','Y','Y',1,'


','2021-10-14 01:08:45','2023-09-22 13:38:42','fuint','A'), +(4,'goods',1,0,'筷子便携餐盒3件套',1,'6914068026176',0,'N','/static/uploadImages/20220110/31cbf7ad0ef442a4b10dcefc24db0662.jpg','[\"/static/uploadImages/20220110/31cbf7ad0ef442a4b10dcefc24db0662.jpg\"]',80.00,99.00,0.00,4010.00,1.00,'',0,1325.00,'一体成型','Y','N',1,'

测试商品

','2021-10-14 05:46:23','2023-07-28 15:13:50','fuint','A'), +(5,'goods',1,0,'简壳 一拖三可收纳伸缩充电线',2,'6922577729501',0,'N','/static/uploadImages/20220110/856dbc96197e4782b4febb7a6e671bcb.jpg','[\"/static/uploadImages/20220110/856dbc96197e4782b4febb7a6e671bcb.jpg\"]',0.10,100.00,0.00,3877.00,0.00,'',0,1168.00,'可伸缩','Y','Y',1,'


','2021-10-14 05:47:31','2023-07-24 19:00:45','fuint','A'), +(6,'goods',1,0,'抽绳垃圾袋16只*4卷',1,'6975486820418',0,'Y','/static/uploadImages/20220110/6083071182cd48afa6c2b9e23f181832.jpg','[\"/static/uploadImages/20220110/6083071182cd48afa6c2b9e23f181832.jpg\",\"/static/uploadImages/20220110/ee5c67ed338442fc90e5c647ccbfd381.jpg\"]',18.00,20.00,0.00,109528.00,1.00,'',11,4209.00,'厨房必备小帮手','Y','Y',0,'

','2021-10-14 05:48:43','2023-07-31 20:00:49','fuint','A'); + +/*Table structure for table `mt_goods_cate` */ + +DROP TABLE IF EXISTS `mt_goods_cate`; + +CREATE TABLE `mt_goods_cate` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺', + `NAME` varchar(100) DEFAULT '' COMMENT '分类名称', + `LOGO` varchar(200) DEFAULT '' COMMENT 'LOGO地址', + `DESCRIPTION` text COMMENT '分类描述', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `SORT` int DEFAULT '0' COMMENT '排序', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=189 DEFAULT CHARSET=utf8 COMMENT='商品分类表'; + +/*Data for the table `mt_goods_cate` */ + +insert into `mt_goods_cate`(`ID`,`MERCHANT_ID`,`STORE_ID`,`NAME`,`LOGO`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`SORT`,`STATUS`) values +(1,1,0,'生活用品','/static/defaultImage/life.png','1234','2021-10-09 06:27:11','2023-07-24 23:30:10','fuint',1,'A'), +(2,1,0,'办公用品','/static/defaultImage/office.png','','2021-10-09 06:27:11','2023-07-21 18:47:52','fuint',3,'A'), +(3,1,0,'好物推荐','/static/defaultImage/love.png','好物推荐','2021-10-09 06:27:11','2023-07-24 19:13:13','fuint',1,'A'), +(4,1,0,'打折热销','/static/defaultImage/hot.png','低价甩卖','2021-10-14 02:20:00','2023-07-27 17:04:42','fuint',3,'A'), +(187,2,0,'美妆','/static/uploadImages/20230918/7567dc29707c41dca8381cc072944d2f.PNG','123','2023-09-18 17:53:49','2023-09-18 17:53:49','anan',0,'A'), +(188,2,0,'办公','/static/uploadImages/20230918/ebfab5816a374bec97fb223b51cf63fe.png','123','2023-09-18 17:54:37','2023-09-18 17:54:37','anan',0,'A'); + +/*Table structure for table `mt_goods_sku` */ + +DROP TABLE IF EXISTS `mt_goods_sku`; + +CREATE TABLE `mt_goods_sku` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `SKU_NO` varchar(50) DEFAULT '' COMMENT 'sku编码', + `LOGO` varchar(255) DEFAULT '' COMMENT '图片', + `GOODS_ID` int NOT NULL DEFAULT '0' COMMENT '商品ID', + `SPEC_IDS` varchar(100) NOT NULL DEFAULT '' COMMENT '规格ID', + `STOCK` double(10,2) NOT NULL DEFAULT '0.00' COMMENT '库存', + `PRICE` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格', + `LINE_PRICE` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '划线价格', + `COST_PRICE` decimal(10,2) DEFAULT '0.00' COMMENT '成本价格', + `WEIGHT` decimal(10,2) DEFAULT '0.00' COMMENT '重量', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=745 DEFAULT CHARSET=utf8 COMMENT='商品SKU表'; + +/*Data for the table `mt_goods_sku` */ + +insert into `mt_goods_sku`(`ID`,`SKU_NO`,`LOGO`,`GOODS_ID`,`SPEC_IDS`,`STOCK`,`PRICE`,`LINE_PRICE`,`COST_PRICE`,`WEIGHT`,`STATUS`) values +(142,'','',27,'46',0.00,0.00,0.00,0.00,0.00,'A'), +(143,'','',27,'47',0.00,0.00,0.00,0.00,0.00,'A'), +(145,'','',37,'56',51.00,200.00,300.00,0.00,1.20,'A'), +(189,'','',40,'66-69',1.00,1.00,1.00,0.00,1.00,'A'), +(190,'','',40,'66-70',1.00,1.00,1.00,0.00,1.00,'A'), +(191,'','',40,'67-69',1.00,1.00,1.00,0.00,1.00,'A'), +(192,'','',40,'67-70',1.00,1.00,1.00,0.00,1.00,'A'), +(193,'','',40,'68-69',1.00,1.00,1.00,0.00,1.00,'A'), +(194,'','',40,'68-70',1.00,1.00,1.00,0.00,1.00,'A'), +(261,'8888880','',45,'86',88.00,10.00,20.00,0.00,2.00,'A'), +(262,'8888881','',45,'87',90.00,10.00,20.00,0.00,2.00,'A'), +(263,'8888882','',45,'88',89.00,10.00,20.00,0.00,2.00,'A'), +(264,'8888883','',45,'89',90.00,10.00,20.00,0.00,2.00,'A'), +(265,'34234','',48,'90',220.00,21.00,112.00,0.00,1.00,'A'), +(266,'234230','',51,'92',100.00,10.00,12.00,0.00,1.00,'A'), +(267,'234231','',51,'93',98.00,10.00,12.00,0.00,1.00,'A'), +(269,'34235','',48,'95',887.00,20.00,120.00,0.00,1.00,'A'), +(315,'2222','/uploads/20230228/656a1aef1e8c4a8e8e80c5b817e15255.jpg',79,'138-142',999.00,24.00,24.00,0.00,2.00,'A'), +(317,'4444','',79,'139-142',999.00,24.00,24.00,0.00,2.00,'A'), +(339,'111111','/uploads/20230307/55126b64546945f4a6393ad5259cfc03.jpg',86,'153',100.00,0.01,99.00,0.00,0.00,'A'), +(340,'222222','/uploads/20230307/67d54c99787b4114affd86c5248d1431.jpg',86,'157',100.00,0.01,99.00,0.00,0.00,'A'), +(341,'333333','/uploads/20230307/72cc5a1c16ee4c21a8ea35612741f87e.jpg',86,'158',98.00,0.01,99.00,0.00,0.00,'A'), +(386,'','',91,'185',0.00,0.00,0.00,0.00,0.00,'A'), +(387,'SKU12434','/uploads/20230314/7333fe6a66884de59e560278c2de609b.jpg',95,'191-193',99.00,10.00,15.00,0.00,1.00,'A'), +(388,'SKU12432','/uploads/20230314/0d4f3ea2741e495f82a23f8443b54e18.jpg',95,'191-194',98.00,10.00,15.00,0.00,1.00,'A'), +(389,'SKU12442','/uploads/20230314/e87014e2f81c466398e35a01472cedb4.jpg',95,'192-193',100.00,19.00,25.00,0.00,1.00,'A'), +(390,'SKU12423','/uploads/20230314/4aab2fc389a54de6b66c19b69eff8ebc.jpg',95,'192-194',98.00,19.00,25.00,0.00,1.00,'A'), +(391,'瓶','',96,'195',4.00,3.00,3.00,0.00,500.00,'A'), +(424,'1230','',119,'220',100.00,1.00,0.00,0.00,1.00,'A'), +(425,'1231','',119,'223',100.00,1.00,0.00,0.00,1.00,'A'), +(426,'1232','',119,'224',100.00,1.00,0.00,0.00,1.00,'A'), +(427,'1233','',119,'225',100.00,1.00,0.00,0.00,1.00,'A'), +(515,'34423423420','',5,'214-215',898.00,99.00,100.00,0.00,1.00,'A'), +(516,'34423423421','',5,'214-217',931.00,99.00,100.00,0.00,1.00,'A'), +(517,'34423423422','',5,'216-215',954.00,99.00,100.00,0.00,1.00,'A'), +(518,'34423423423','',5,'216-217',838.00,99.00,100.00,0.00,1.00,'A'), +(519,'','',140,'262',0.00,0.00,0.00,0.00,0.00,'A'), +(547,'79232344230','',165,'274',100.00,3.99,5.00,0.00,0.25,'A'), +(548,'79232344231','',165,'275',100.00,6.00,7.00,0.00,0.25,'A'), +(555,'','',169,'282-286',9.00,189.00,289.00,0.00,0.00,'A'), +(556,'','',169,'282-287',10.00,189.00,289.00,0.00,0.00,'A'), +(557,'','',169,'282-288',10.00,189.00,289.00,0.00,0.00,'A'), +(558,'','',169,'282-289',10.00,189.00,289.00,0.00,0.00,'A'), +(559,'','',169,'282-290',10.00,189.00,289.00,0.00,0.00,'A'), +(560,'','',169,'283-286',10.00,189.00,289.00,0.00,0.00,'A'), +(561,'','',169,'283-287',9.00,189.00,289.00,0.00,0.00,'A'), +(562,'','',169,'283-288',9.00,189.00,289.00,0.00,0.00,'A'), +(563,'','',169,'283-289',10.00,189.00,289.00,0.00,0.00,'A'), +(564,'','',169,'283-290',10.00,189.00,289.00,0.00,0.00,'A'), +(565,'','',169,'285-286',10.00,189.00,289.00,0.00,0.00,'A'), +(566,'','',169,'285-287',10.00,189.00,289.00,0.00,0.00,'A'), +(567,'','',169,'285-288',8.00,189.00,289.00,0.00,0.00,'A'), +(568,'','',169,'285-289',9.00,189.00,289.00,0.00,0.00,'A'), +(569,'','',169,'285-290',6.00,189.00,289.00,0.00,0.00,'A'), +(583,'4353452','/uploads/20230609/92a39796268246c7865ff10d560a9d10.gif',176,'296',7.00,56.00,80.00,0.00,0.00,'A'), +(584,'45345','',177,'297',88.00,677.00,5888.00,0.00,0.00,'A'), +(585,'45345345','',177,'299',75.00,888.00,8888.00,0.00,0.00,'A'), +(604,'','',169,'309-286',0.00,0.00,0.00,0.00,0.00,'A'), +(605,'','',169,'309-287',0.00,0.00,0.00,0.00,0.00,'A'), +(606,'','',169,'309-288',0.00,0.00,0.00,0.00,0.00,'A'), +(607,'','',169,'309-289',0.00,0.00,0.00,0.00,0.00,'A'), +(608,'','',169,'309-290',0.00,0.00,0.00,0.00,0.00,'A'), +(609,'','',183,'310-311',10.00,99.00,0.00,0.00,0.00,'A'), +(610,'','',183,'310-312',10.00,99.00,0.00,0.00,0.00,'A'), +(611,'','',183,'310-313',10.00,99.00,0.00,0.00,0.00,'A'), +(612,'','',183,'310-314',10.00,99.00,0.00,0.00,0.00,'A'), +(613,'','',183,'310-315',10.00,99.00,0.00,0.00,0.00,'A'), +(614,'','',183,'310-316',10.00,99.00,0.00,0.00,0.00,'A'), +(615,'','',183,'317-311',10.00,99.00,0.00,0.00,0.00,'A'), +(616,'','',183,'317-312',10.00,99.00,0.00,0.00,0.00,'A'), +(617,'','',183,'317-313',10.00,99.00,0.00,0.00,0.00,'A'), +(618,'','',183,'317-314',10.00,99.00,0.00,0.00,0.00,'A'), +(619,'','',183,'317-315',10.00,99.00,0.00,0.00,0.00,'A'), +(620,'','',183,'317-316',10.00,99.00,0.00,0.00,0.00,'A'), +(621,'','',183,'318-311',10.00,99.00,0.00,0.00,0.00,'A'), +(622,'','',183,'318-312',10.00,99.00,0.00,0.00,0.00,'A'), +(623,'','',183,'318-313',10.00,99.00,0.00,0.00,0.00,'A'), +(624,'','',183,'318-314',10.00,99.00,0.00,0.00,0.00,'A'), +(625,'','',183,'318-315',10.00,99.00,0.00,0.00,0.00,'A'), +(626,'','',183,'318-316',9.00,99.00,0.00,0.00,0.00,'A'), +(627,'1','',187,'324',20.00,22.00,25.00,0.00,0.50,'A'), +(628,'2','',187,'325',20.00,40.00,50.00,0.00,1.00,'A'), +(629,'1','',185,'327',0.00,120.00,150.00,0.00,5.00,'A'), +(630,'2','',185,'328',1.00,150.00,180.00,0.00,5.00,'A'), +(631,'3','',185,'329',0.00,200.00,250.00,0.00,5.00,'A'), +(644,'','/uploads/20230628/0c17bcee89dc4838be59aba2db990e22.png',197,'339',997.00,68.00,0.00,0.00,0.00,'A'), +(659,'180521342436380','',207,'345-351-353',1.00,1.00,1.00,0.00,1.00,'A'), +(660,'180521342436381','',207,'348-351-353',1.00,1.00,1.00,0.00,1.00,'A'), +(661,'179699761475660','',232,'355-356',10.00,20.00,30.00,0.00,1.00,'A'), +(662,'179699761475661','',232,'355-357',10.00,30.00,60.00,0.00,1.00,'A'), +(663,'179699761475662','',232,'358-356',1.00,20.00,30.00,0.00,1.00,'A'), +(664,'179699761475663','',232,'358-357',2.00,30.00,60.00,0.00,1.00,'A'), +(669,'148503337738370','',305,'372-374',10.00,99.00,299.00,0.00,0.00,'A'), +(670,'148503337738371','',305,'372-375',10.00,99.00,299.00,0.00,0.00,'A'), +(671,'148503337738372','',305,'373-374',10.00,99.00,299.00,0.00,0.00,'A'), +(672,'148503337738373','',305,'373-375',10.00,99.00,299.00,0.00,0.00,'A'), +(673,'','',361,'388',0.00,0.00,0.00,0.00,0.00,'A'), +(674,'','',361,'389',0.00,0.00,0.00,0.00,0.00,'A'), +(675,'','',361,'390',0.00,0.00,0.00,0.00,0.00,'A'), +(676,'','',361,'391',0.00,0.00,0.00,0.00,0.00,'A'), +(677,'','',361,'393',0.00,0.00,0.00,0.00,0.00,'A'), +(689,'164348379384740','',382,'413-416-419',990.00,18.00,0.00,0.00,0.00,'A'), +(690,'164348379384741','',382,'413-417-419',990.00,18.00,0.00,0.00,0.00,'A'), +(691,'164348379384742','',382,'413-418-419',990.00,18.00,0.00,0.00,0.00,'A'), +(692,'164348379384743','',382,'414-416-419',990.00,18.00,0.00,0.00,0.00,'A'), +(693,'164348379384744','',382,'414-417-419',990.00,18.00,0.00,0.00,0.00,'A'), +(694,'164348379384745','',382,'414-418-419',990.00,18.00,0.00,0.00,0.00,'A'), +(695,'164348379384746','',382,'415-416-419',990.00,18.00,0.00,0.00,0.00,'A'), +(696,'164348379384747','',382,'415-417-419',990.00,18.00,0.00,0.00,0.00,'A'), +(697,'164348379384748','',382,'415-418-419',990.00,18.00,0.00,0.00,0.00,'A'), +(710,'125946837840450','',1,'107-180',10004.00,88.00,99.00,0.00,1.00,'A'), +(711,'125946837840451','',1,'107-331',10002.00,88.00,99.00,0.00,1.00,'A'), +(712,'125946837840452','',1,'107-421',10001.00,88.00,99.00,0.00,1.00,'A'), +(716,'134518978667720','',4,'402-404',1000.00,80.00,99.00,0.00,1.00,'A'), +(717,'134518978667721','',4,'402-405',1000.00,80.00,99.00,0.00,1.00,'A'), +(718,'134518978667722','',4,'403-404',997.00,80.00,99.00,0.00,1.00,'A'), +(719,'134518978667723','',4,'403-405',995.00,80.00,99.00,0.00,1.00,'A'), +(732,'155430306154340','',384,'430',1.00,1.00,1.00,0.00,1.00,'A'), +(733,'125946837840453','',1,'431-180',10000.00,88.00,99.00,0.00,1.00,'A'), +(734,'125946837840454','',1,'431-331',9998.00,88.00,99.00,0.00,1.00,'A'), +(735,'125946837840455','',1,'431-421',10000.00,88.00,99.00,0.00,1.00,'A'), +(736,'125946837840456','',1,'432-180',10000.00,88.00,99.00,0.00,1.00,'A'), +(737,'125946837840457','',1,'432-331',9999.00,88.00,99.00,0.00,1.00,'A'), +(738,'125946837840458','',1,'432-421',9998.00,88.00,99.00,0.00,1.00,'A'), +(739,'197171320996910','',3,'6-74-401',1000.00,99.00,120.00,0.00,1.00,'A'), +(740,'197171320996911','',3,'6-75-401',1000.00,99.00,120.00,0.00,1.00,'A'), +(741,'197171320996912','',3,'6-429-401',1000.00,99.00,120.00,0.00,1.00,'A'), +(742,'197171320996913','',3,'7-74-401',1000.00,99.00,120.00,0.00,1.00,'A'), +(743,'197171320996914','',3,'7-75-401',1000.00,99.00,120.00,0.00,1.00,'A'), +(744,'197171320996915','',3,'7-429-401',1000.00,99.00,120.00,0.00,1.00,'A'); + +/*Table structure for table `mt_goods_spec` */ + +DROP TABLE IF EXISTS `mt_goods_spec`; + +CREATE TABLE `mt_goods_spec` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `GOODS_ID` int NOT NULL DEFAULT '0' COMMENT '商品ID', + `NAME` varchar(100) NOT NULL DEFAULT '' COMMENT '规格名称', + `VALUE` varchar(100) NOT NULL DEFAULT '' COMMENT '规格值', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=433 DEFAULT CHARSET=utf8 COMMENT='规格表'; + +/*Data for the table `mt_goods_spec` */ + +insert into `mt_goods_spec`(`ID`,`GOODS_ID`,`NAME`,`VALUE`,`STATUS`) values +(1,6,'厚度','正常','D'), +(2,6,'厚度','加厚','D'), +(3,6,'糖分','黑色','D'), +(4,6,'糖分','黄色','D'), +(5,6,'糖分','白色','D'), +(6,3,'材质','304不锈钢','A'), +(7,3,'材质','塑料','A'), +(8,6,'尺码','m','D'), +(9,6,'尺码','l','D'), +(10,6,'口味','1','D'), +(11,6,'口味','2','D'), +(12,6,'口味','3','D'), +(13,2,'m','m','D'), +(14,6,'厚度','超薄','D'), +(15,16,'风味','孜然','D'), +(16,16,'特色','炭火','D'), +(17,16,'风味','秘制','D'), +(18,16,'特色','木炭','D'), +(19,16,'特色','风味小吃','D'), +(20,6,'大小','啥啥啥','D'), +(21,6,'大小','L','D'), +(22,24,'500ML','7','D'), +(23,24,'700ML','10','D'), +(24,24,'小杯','500ML','A'), +(25,24,'大杯','700ML','D'), +(26,24,'大杯','700ML','D'), +(27,24,'小杯','122','D'), +(28,24,'小杯','任天野','D'), +(29,24,'小杯','700ML','A'), +(30,6,'大小','12','D'), +(31,6,'2','3','D'), +(32,6,'1','','D'), +(33,6,'大小','M','D'), +(34,6,'大小','L','D'), +(35,11,'ddd','rr','A'), +(36,11,'gggg','ttt','A'), +(37,11,'ddd','yyu','A'), +(38,11,'gggg','==999','A'), +(39,12,'1','1,2','A'), +(40,16,'年份','82年','A'), +(41,16,'年份','90年','A'), +(42,16,'年份','00年','A'), +(43,6,'尺码','大','D'), +(44,6,'尺码','小','D'), +(45,2,'7','','D'), +(46,27,'颜色','红色','A'), +(47,27,'颜色','白色','A'), +(48,2,'大小','5','D'), +(49,2,'品牌','6','D'), +(50,2,'大小','IIS','D'), +(51,2,'品牌','8','D'), +(52,6,'xxx','','D'), +(53,6,'糖分','绿色','D'), +(54,37,'test1','12','D'), +(55,37,'test2','13','D'), +(56,37,'test1','123','A'), +(57,38,'颜色','黑色','A'), +(58,38,'颜色','蓝色','A'), +(59,38,'颜色','绿色','D'), +(60,38,'大小','大号','A'), +(61,38,'大小','小号','A'), +(62,38,'颜色','绿色','D'), +(63,4,'颜色','红色','D'), +(64,6,'重量','10KG','D'), +(65,6,'重量','10g','D'), +(66,40,'时长','两小时','A'), +(67,40,'时长','三小时','A'), +(68,40,'时长','四小时','A'), +(69,40,'面积','80平米','A'), +(70,40,'面积','100平米','A'), +(71,41,'11','1','A'), +(72,41,'11','11','A'), +(73,41,'11','111','A'), +(74,3,'颜色','粉红色','A'), +(75,3,'颜色','黑色','A'), +(76,6,'jj','','D'), +(77,6,'重量','nihao','D'), +(78,6,'糖分','红色','D'), +(79,6,'糖分','紫色','D'), +(80,6,'nih','hth','D'), +(81,2,'颜色','1111','D'), +(82,6,'糖分','蓝色','D'), +(83,6,'大小','XL','D'), +(84,6,'呃呃','','D'), +(86,45,'容量','300W','A'), +(87,45,'容量','300W','A'), +(88,45,'容量','300','A'), +(89,45,'容量','300','A'), +(90,48,'颜色','红色','A'), +(91,48,'1','','D'), +(92,51,'颜色','白色','A'), +(93,51,'颜色','黑色','A'), +(94,51,'颜色','绿色','D'), +(95,48,'颜色','黑色','A'), +(96,52,'eee','12','D'), +(97,52,'eee','222','D'), +(98,52,'dfsfsa','33','A'), +(99,52,'dfsfsa','22','A'), +(100,53,'ddd','','D'), +(101,53,'天泰','营业','A'), +(102,52,'eee','22','D'), +(103,1,'123','123','D'), +(104,1,'123123','','D'), +(105,1,'123','qwe123','D'), +(106,1,'123','qwe123','D'), +(107,1,'尺码','39','A'), +(108,1,'尺码','39','D'), +(109,1,'尺码','40','D'), +(110,6,'糖分','d','D'), +(111,5,'abg','1','D'), +(112,5,'abg','1234','D'), +(113,6,'款式','长','D'), +(114,6,'款式','A','D'), +(115,6,'款式','宽','D'), +(116,65,'套房','套一','A'), +(117,69,'小码','S','A'), +(118,69,'小码','d','A'), +(119,4,'颜色','蓝色','D'), +(120,4,'颜色','蓝色','D'), +(121,2,'大小','L','D'), +(122,2,'品牌','10','D'), +(123,4,'颜色','白色','D'), +(124,4,'颜色','黑色','D'), +(125,4,'颜色','黑色','D'), +(126,6,'test','1','D'), +(127,76,'颜色','黄色','A'), +(128,76,'颜色','黄','D'), +(129,76,'尺码','L','A'), +(130,76,'颜色','1','D'), +(131,76,'颜色','蓝色','A'), +(132,76,'尺码','M','A'), +(133,6,'款式','高','D'), +(134,6,'款式','宽','D'), +(135,6,'款式','宽','D'), +(136,79,'颜色','大小','D'), +(137,79,'颜色','规格','D'), +(138,79,'颜色','红色','A'), +(139,79,'颜色','绿色','A'), +(140,79,'大小','黄色','D'), +(141,79,'大小','500ml','D'), +(142,79,'大小','1L','A'), +(143,6,'款式','宽','D'), +(144,6,'款式','宽','D'), +(145,6,'款式','宽','D'), +(146,6,'款式','11','D'), +(147,81,'caoi','1','A'), +(148,81,'caoi','1','A'), +(149,81,'caoi','2','A'), +(150,81,'iphone','64g','A'), +(151,81,'iphone','128g','A'), +(152,81,'iphone','256g','D'), +(153,86,'颜色','红','A'), +(154,86,'颜色','黄色','D'), +(155,86,'颜色','红色','D'), +(156,86,'颜色','绿色','D'), +(157,86,'颜色','黄','A'), +(158,86,'颜色','绿','A'), +(159,90,'33','33','A'), +(160,90,'3','','A'), +(161,90,'4','5','A'), +(162,91,'华为','1号','D'), +(163,91,'hw','01','D'), +(164,91,'xm','01','A'), +(165,91,'xm','02','A'), +(166,91,'xm','03','A'), +(167,91,'hw','02','A'), +(168,91,'hw','03','A'), +(169,91,'xm','01','D'), +(170,91,'xm','02','D'), +(171,91,'xm','03','D'), +(172,91,'hw','01','D'), +(173,91,'xm','01','D'), +(174,91,'hw','02','D'), +(175,91,'xm','02','D'), +(176,91,'hw','03','D'), +(177,91,'xm','03','D'), +(178,91,'xm','04','D'), +(179,91,'xm','04','D'), +(180,1,'颜色','黑色','A'), +(181,1,'颜色','蓝色','D'), +(182,1,'颜色','黄色','D'), +(183,1,'卡通图','米老鼠','D'), +(184,1,'卡通图','唐老鸭','D'), +(185,91,'原味','','A'), +(186,91,'味道','原味','A'), +(187,91,'味道','酸辣','A'), +(188,93,'打包','小包','A'), +(189,93,'打包','的','A'), +(190,95,'数量','口味','D'), +(191,95,'数量','一包','A'), +(192,95,'数量','两包','A'), +(193,95,'口味','奶香味','A'), +(194,95,'口味','草莓味','A'), +(195,96,'口味','普通','A'), +(196,110,'lll','iiii','A'), +(197,110,'lll','iiii','A'), +(198,110,'9999','llll','A'), +(199,110,'9999','9999','A'), +(200,110,'8888','99999','A'), +(201,110,'8888','7777','A'), +(202,1,'尺码','43','D'), +(203,6,'111','11','D'), +(204,6,'糖分','1','D'), +(205,6,'糖分','2','D'), +(206,6,'糖分','3','D'), +(207,6,'糖分','4','D'), +(208,6,'糖分','5','D'), +(209,6,'糖分','6','D'), +(210,6,'糖分','7','D'), +(211,6,'糖分','8','D'), +(212,6,'糖分','9','D'), +(213,6,'糖分','10','D'), +(214,5,'A','A-1','A'), +(215,5,'B','B-1','A'), +(216,5,'A','A-2','A'), +(217,5,'B','B-2','A'), +(218,6,'款式','13','D'), +(219,119,'代杀','1','D'), +(220,119,'可选备注','','A'), +(221,119,'代杀','代杀','A'), +(222,119,'代杀','不杀','A'), +(223,119,'可选备注','杀(清洗)','A'), +(224,119,'可选备注','杀(不清洗)','A'), +(225,119,'可选备注','不杀','A'), +(226,122,'大小','小','A'), +(227,122,'大小','中','A'), +(228,122,'大小','大','A'), +(229,122,'甜度','少','A'), +(230,122,'甜度','多','A'), +(231,122,'甜度','超多','A'), +(232,122,'abc','1','A'), +(233,122,'abc','23','A'), +(234,122,'abc','33','D'), +(235,131,'小轿车','','A'), +(236,131,'法拉利','','A'), +(237,131,'兰博基尼','','A'), +(238,122,'234','','A'), +(239,5,'qwe','','D'), +(240,5,'B','w','D'), +(241,5,'B','3','D'), +(242,6,'长度','1','D'), +(243,6,'长度','2','D'), +(244,6,'长度','0','D'), +(245,6,'款式','西米','D'), +(246,6,'款式','红豆','D'), +(247,135,'尺寸','大杯','A'), +(248,135,'尺寸','中杯','A'), +(249,135,'尺寸','小杯','A'), +(250,135,'温度','热','A'), +(251,135,'温度','常温','A'), +(252,135,'温度','冰','A'), +(253,135,'颜色','白色','A'), +(254,135,'颜色','白色','D'), +(255,135,'颜色','黑色','A'), +(258,6,'nihoa','','D'), +(260,2,'大小','M','D'), +(261,2,'大小','XL','D'), +(262,140,'222','333','A'), +(263,141,'123','345','D'), +(264,141,'小','1','D'), +(265,141,'小','2','D'), +(266,3,'颜色','白色','D'), +(267,6,'大小','s','D'), +(268,6,'大小','XXL','D'), +(269,6,'长度','3','D'), +(270,6,'长度','ww','D'), +(271,6,'宽度','1','D'), +(272,1,'卡通图','唐老鸭','D'), +(273,165,'单卖','包装','D'), +(274,165,'单卖','1','A'), +(275,165,'单卖','2','A'), +(276,6,'长度','1M','D'), +(277,6,'长度','2M','D'), +(278,6,'宽度','10CM','D'), +(279,6,'宽度','20CM','D'), +(280,6,'宽度','30CM','D'), +(281,6,'长度','3','D'), +(282,169,'颜色','红色','A'), +(283,169,'颜色','蓝色','A'), +(284,169,'颜色','皇上','D'), +(285,169,'颜色','黄色','A'), +(286,169,'尺码','S','A'), +(287,169,'尺码','M','A'), +(288,169,'尺码','L','A'), +(289,169,'尺码','XL','A'), +(290,169,'尺码','XXL','A'), +(291,1,'卡通图','3','D'), +(292,6,'长度','36','D'), +(293,6,'3','','D'), +(294,6,'宽度','3','D'), +(295,6,'656','','D'), +(296,176,'测试1','25','A'), +(297,177,'规格1','个','A'), +(298,177,'规格2','包','D'), +(299,177,'规格1','包','A'), +(300,181,'颜色','红色','A'), +(301,181,'尺码','S','A'), +(302,181,'颜色','蓝色','A'), +(303,181,'尺码','M','A'), +(304,181,'尺码','L','A'), +(305,6,'颜色','大','D'), +(306,6,'宽度','6','D'), +(307,6,'长度','52','D'), +(308,1,'卡通图','cs','D'), +(309,169,'颜色','213','A'), +(310,183,'颜色','红','A'), +(311,183,'尺码','35','A'), +(312,183,'尺码','36','A'), +(313,183,'尺码','37','A'), +(314,183,'尺码','38','A'), +(315,183,'尺码','39','A'), +(316,183,'尺码','40','A'), +(317,183,'颜色','白','A'), +(318,183,'颜色','黑','A'), +(319,185,'八寸蛋糕','10寸蛋糕','D'), +(320,185,'八寸蛋糕','8寸','D'), +(321,185,'八寸蛋糕','12寸','D'), +(322,185,'八寸蛋糕','15寸','D'), +(323,187,'紫薯包','','D'), +(324,187,'紫薯包','x6','A'), +(325,187,'紫薯包','x12','A'), +(326,187,'紫薯包','x32','A'), +(327,185,'尺寸','8寸','A'), +(328,185,'尺寸','10寸','A'), +(329,185,'尺寸','14寸','A'), +(330,1,'尺码','40','D'), +(331,1,'颜色','白色','A'), +(332,1,'ddd','333','D'), +(333,1,'ddd','222','D'), +(334,1,'ddd','111','D'), +(335,1,'ddd','22','D'), +(336,6,'高度','2M','D'), +(337,6,'高度','3M','D'), +(338,6,'长度','3','D'), +(339,197,'颜色','款式','A'), +(340,199,'分享','20分钟','A'), +(341,199,'预约','30分钟','A'), +(342,6,'高度','黑','D'), +(343,6,'颜色','红','D'), +(344,6,'颜色','黄','D'), +(345,207,'颜色','黑色','A'), +(346,207,'12332','红色','D'), +(347,207,'颜色','黑色','D'), +(348,207,'颜色','红色','A'), +(349,196,'111','11111','A'), +(350,196,'111','1111111','A'), +(351,207,'尺码','S','A'), +(352,207,'尺码','L','A'), +(353,207,'赠礼','1','A'), +(354,207,'赠礼','2','A'), +(355,232,'颜色','白色','A'), +(356,232,'数量','5包','A'), +(357,232,'数量','10包','A'), +(358,232,'颜色','黑色','A'), +(359,233,'22222','22222','A'), +(360,245,'码数','34码','A'), +(361,245,'码数','35码','A'), +(362,245,'码数','36码','A'), +(363,245,'码数','37码','A'), +(364,245,'颜色','红色','A'), +(365,245,'颜色','白色','A'), +(366,245,'颜色','黑色','A'), +(367,2,'xl','xxl','D'), +(368,2,'xl','xl','D'), +(369,2,'l','l','D'), +(370,2,'m','l','D'), +(371,2,'l','22','D'), +(372,305,'颜色','蓝色','A'), +(373,305,'颜色','黑色','A'), +(374,305,'尺码','22','A'), +(375,305,'尺码','23','A'), +(376,2,'l','vv','D'), +(377,358,'热尔特谈','','D'), +(378,358,'111','111','D'), +(379,358,'热尔特谈','111','D'), +(380,358,'热尔特谈','1实物','D'), +(381,358,'热尔特谈','1是qqq','D'), +(382,358,'热尔特谈','111SSS安徽','D'), +(383,358,'热尔特谈','111sss汉字###','D'), +(384,358,'热尔特谈','汉字','D'), +(385,358,'热尔特谈','汉字sss','D'), +(386,358,'i0p','h8iuh','A'), +(387,358,'i0p','oljiho;ok\'','A'), +(388,361,'111','111','A'), +(389,361,'111','222','A'), +(390,361,'111','111','A'), +(391,361,'111','444','A'), +(392,361,'111','77','D'), +(393,361,'111','11111','A'), +(394,2,'m','隔热','D'), +(395,2,'l','1','D'), +(396,6,'chicun','1','D'), +(397,6,'chicun','2','D'), +(398,6,'chicun','3','D'), +(399,6,'颜色','中','D'), +(400,6,'颜色','小','D'), +(401,3,'大小','12G','A'), +(402,4,'着色','白','A'), +(403,4,'着色','红','A'), +(404,4,'大小','11','A'), +(405,4,'大小','22','A'), +(406,378,'杯','60ml','D'), +(407,378,'瓶','750ml','D'), +(408,6,'颜色','111','D'), +(409,6,'111','111111','D'), +(410,378,'5','6','D'), +(411,378,'5','6','D'), +(412,378,'瓶','100','D'), +(413,382,'温度','正常冰','A'), +(414,382,'温度','少冰','A'), +(415,382,'温度','去冰','A'), +(416,382,'甜度','正常糖(推荐)','A'), +(417,382,'甜度','少糖','A'), +(418,382,'甜度','不另外放糖(不推荐)','A'), +(419,382,'特殊口味','标准搭配','A'), +(420,382,'脆波波','','D'), +(421,1,'颜色','蓝色','A'), +(422,1,'重量','1KG','D'), +(423,1,'重量','2KG','D'), +(424,1,'长度','11','D'), +(425,1,'长度','22','D'), +(426,6,'111','11','D'), +(427,6,'111','11','D'), +(428,6,'111','22','D'), +(429,3,'颜色','蓝色','A'), +(430,384,'时长','12','A'), +(431,1,'尺码','45','A'), +(432,1,'尺码','55','A'); + +/*Table structure for table `mt_merchant` */ + +DROP TABLE IF EXISTS `mt_merchant`; + +CREATE TABLE `mt_merchant` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `TYPE` varchar(30) DEFAULT '' COMMENT '类型,restaurant:餐饮;retail:零售;service:服务;other:其他', + `LOGO` varchar(255) DEFAULT '' COMMENT 'logo', + `NO` varchar(20) NOT NULL DEFAULT '' COMMENT '商户号', + `NAME` varchar(50) NOT NULL DEFAULT '' COMMENT '商户名称', + `CONTACT` varchar(30) DEFAULT '' COMMENT '联系人姓名', + `PHONE` varchar(20) DEFAULT '' COMMENT '联系电话', + `ADDRESS` varchar(100) DEFAULT '' COMMENT '联系地址', + `WX_APP_ID` varchar(50) DEFAULT '' COMMENT '微信小程序appId', + `WX_APP_SECRET` varchar(50) DEFAULT '' COMMENT '微信小程序秘钥', + `WX_OFFICIAL_APP_ID` varchar(50) DEFAULT '' COMMENT '微信公众号appId', + `WX_OFFICIAL_APP_SECRET` varchar(50) DEFAULT '' COMMENT '微信公众号秘钥', + `SETTLE_RATE` decimal(10,0) DEFAULT NULL COMMENT '结算比例', + `DESCRIPTION` varchar(2000) DEFAULT '' COMMENT '备注信息', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:有效/启用;D:无效', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='商户表'; + +/*Data for the table `mt_merchant` */ + +insert into `mt_merchant`(`ID`,`TYPE`,`LOGO`,`NO`,`NAME`,`CONTACT`,`PHONE`,`ADDRESS`,`WX_APP_ID`,`WX_APP_SECRET`,`WX_OFFICIAL_APP_ID`,`WX_OFFICIAL_APP_SECRET`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`,`OPERATOR`) values +(1,'','/uploads/20230804/8e5893378bec4b8ab3cabb77e15162d2.PNG','10001','小隅安商行','安安','18976679980','海口市永万路7号','','','','','默认','2023-08-01 12:03:55','2023-08-04 09:55:37','A','fuint'), +(2,'','/uploads/20230804/11f9b3135db043488e4b9bdcadda9f56.png','10002','延禾技术','FSQ','18976679980','海口市国兴大道100号','','','','','测试','2023-08-01 14:04:14','2023-08-04 09:56:04','A','fuint'); + +/*Table structure for table `mt_message` */ + +DROP TABLE IF EXISTS `mt_message`; + +CREATE TABLE `mt_message` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `USER_ID` int NOT NULL COMMENT '用户ID', + `TYPE` varchar(30) NOT NULL DEFAULT '' COMMENT '消息类型', + `TITLE` varchar(200) DEFAULT '友情提示' COMMENT '消息标题', + `CONTENT` varchar(500) NOT NULL DEFAULT '' COMMENT '消息内容', + `IS_READ` char(1) DEFAULT 'N' COMMENT '是否已读', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `PARAMS` varchar(1000) DEFAULT '' COMMENT '参数信息', + `IS_SEND` char(1) DEFAULT 'N' COMMENT '是否已发送', + `SEND_TIME` datetime DEFAULT NULL COMMENT '发送时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`), + KEY `index_user_id` (`USER_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统消息表'; + +/*Data for the table `mt_message` */ + +/*Table structure for table `mt_open_gift` */ + +DROP TABLE IF EXISTS `mt_open_gift`; + +CREATE TABLE `mt_open_gift` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int NOT NULL DEFAULT '0' COMMENT '门店ID', + `GRADE_ID` int NOT NULL DEFAULT '0' COMMENT '会员等级ID', + `POINT` int NOT NULL DEFAULT '0' COMMENT '赠送积分', + `COUPON_ID` int NOT NULL DEFAULT '0' COMMENT '卡券ID', + `COUPON_NUM` int NOT NULL DEFAULT '1' COMMENT '卡券数量', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=117 DEFAULT CHARSET=utf8 COMMENT='会员开卡赠礼'; + +/*Data for the table `mt_open_gift` */ + +insert into `mt_open_gift`(`ID`,`MERCHANT_ID`,`STORE_ID`,`GRADE_ID`,`POINT`,`COUPON_ID`,`COUPON_NUM`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`,`OPERATOR`) values +(115,1,0,1,1000,0,0,'2023-07-24 20:06:48','2023-07-24 20:06:48','A','fuint'), +(116,1,0,1,0,153,1,'2023-07-24 22:17:38','2023-07-24 22:17:38','A','fuint'); + +/*Table structure for table `mt_open_gift_item` */ + +DROP TABLE IF EXISTS `mt_open_gift_item`; + +CREATE TABLE `mt_open_gift_item` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `USER_ID` int NOT NULL COMMENT '会用ID', + `OPEN_GIFT_ID` int NOT NULL COMMENT '赠礼ID', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `STATUS` char(1) NOT NULL COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf32 COMMENT='开卡赠礼明细表'; + +/*Data for the table `mt_open_gift_item` */ + +/*Table structure for table `mt_order` */ + +DROP TABLE IF EXISTS `mt_order`; + +CREATE TABLE `mt_order` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `TYPE` varchar(30) DEFAULT NULL COMMENT '订单类型', + `PAY_TYPE` varchar(30) DEFAULT 'JSAPI' COMMENT '支付类型', + `ORDER_MODE` varchar(30) DEFAULT 'express' COMMENT '订单模式', + `PLATFORM` varchar(30) DEFAULT '' COMMENT '平台', + `ORDER_SN` varchar(32) NOT NULL DEFAULT '' COMMENT '订单号', + `COUPON_ID` int DEFAULT '0' COMMENT '卡券ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '用户ID', + `VERIFY_CODE` varchar(10) DEFAULT '' COMMENT '核销验证码', + `IS_VISITOR` char(1) DEFAULT 'N' COMMENT '是否游客', + `AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '订单金额', + `PAY_AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '支付金额', + `USE_POINT` int DEFAULT '0' COMMENT '使用积分数量', + `POINT_AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '积分金额', + `DISCOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '折扣金额', + `DELIVERY_FEE` decimal(10,2) DEFAULT '0.00' COMMENT '配送费用', + `PARAM` varchar(500) DEFAULT '' COMMENT '订单参数', + `EXPRESS_INFO` varchar(500) DEFAULT '' COMMENT '物流信息', + `REMARK` varchar(500) DEFAULT '' COMMENT '用户备注', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '订单状态', + `PAY_TIME` datetime DEFAULT NULL COMMENT '支付时间', + `PAY_STATUS` char(1) DEFAULT '' COMMENT '支付状态', + `SETTLE_STATUS` char(1) DEFAULT 'A' COMMENT '结算状态', + `STAFF_ID` int DEFAULT '0' COMMENT '操作员工', + `CONFIRM_STATUS` char(1) DEFAULT 'N' COMMENT '核销状态', + `CONFIRM_TIME` datetime DEFAULT NULL COMMENT '核销时间', + `CONFIRM_REMARK` varchar(500) DEFAULT NULL COMMENT '核销备注', + `COMMISSION_STATUS` char(1) DEFAULT 'A' COMMENT '分佣提成计算状态', + `COMMISSION_USER_ID` int DEFAULT '0' COMMENT '分佣提成用户ID', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表'; + +/*Data for the table `mt_order` */ + +/*Table structure for table `mt_order_address` */ + +DROP TABLE IF EXISTS `mt_order_address`; + +CREATE TABLE `mt_order_address` ( + `ID` int unsigned NOT NULL AUTO_INCREMENT COMMENT '地址ID', + `NAME` varchar(30) NOT NULL DEFAULT '' COMMENT '收货人姓名', + `MOBILE` varchar(20) NOT NULL DEFAULT '' COMMENT '联系电话', + `PROVINCE_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '省份ID', + `CITY_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '城市ID', + `REGION_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '区/县ID', + `DETAIL` varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', + `ORDER_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '订单ID', + `USER_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '用户ID', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + PRIMARY KEY (`ID`) USING BTREE, + KEY `ORDER_ID` (`ORDER_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单收货地址记录表'; + +/*Data for the table `mt_order_address` */ + +/*Table structure for table `mt_order_goods` */ + +DROP TABLE IF EXISTS `mt_order_goods`; + +CREATE TABLE `mt_order_goods` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `ORDER_ID` int NOT NULL DEFAULT '0' COMMENT '订单ID', + `GOODS_ID` int NOT NULL DEFAULT '0' COMMENT '商品ID', + `SKU_ID` int DEFAULT '0' COMMENT 'skuID', + `PRICE` decimal(10,2) DEFAULT '0.00' COMMENT '价格', + `DISCOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '优惠价', + `NUM` double(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品数量', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单商品表'; + +/*Data for the table `mt_order_goods` */ + +/*Table structure for table `mt_point` */ + +DROP TABLE IF EXISTS `mt_point`; + +CREATE TABLE `mt_point` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `USER_ID` int NOT NULL DEFAULT '0' COMMENT '用户ID', + `ORDER_SN` varchar(32) DEFAULT '' COMMENT '订单号', + `AMOUNT` int NOT NULL DEFAULT '0' COMMENT '积分变化数量', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `DESCRIPTION` varchar(200) DEFAULT '' COMMENT '备注说明', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A正常;D作废', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='积分变化表'; + +/*Data for the table `mt_point` */ + +insert into `mt_point`(`ID`,`MERCHANT_ID`,`STORE_ID`,`USER_ID`,`ORDER_SN`,`AMOUNT`,`CREATE_TIME`,`UPDATE_TIME`,`DESCRIPTION`,`OPERATOR`,`STATUS`) values +(1,0,0,163,'202309082158244549616',-1000,'2023-09-08 21:58:24','2023-09-08 21:58:24','支付扣除1000积分','','A'), +(2,0,0,163,'202309082158244549616',1000,'2023-09-10 09:58:01','2023-09-10 09:58:01','订单取消202309082158244549616退回1000积分','','A'), +(3,2,7,6143,'',1000,'2023-09-18 18:02:17','2023-09-18 18:02:17','开卡赠送1000积分','系统','A'), +(5,1,3,163,'202309201800308947963',-1000,'2023-09-20 18:00:31','2023-09-20 18:00:31','支付扣除1000积分','','A'), +(6,1,2,1,'',1000,'2023-10-19 09:39:45','2023-10-19 09:39:45','开卡赠送1000积分','系统','A'), +(7,1,3,1,'',1000,'2024-04-09 14:40:19','2024-04-09 14:40:19','开卡赠送1000积分','系统','A'), +(8,1,3,2,'',1000,'2024-04-09 14:40:21','2024-04-09 14:40:21','开卡赠送1000积分','系统','A'); + +/*Table structure for table `mt_printer` */ + +DROP TABLE IF EXISTS `mt_printer`; + +CREATE TABLE `mt_printer` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `SN` varchar(64) DEFAULT NULL COMMENT '打印机编号', + `NAME` varchar(64) DEFAULT NULL COMMENT '打印机名称', + `AUTO_PRINT` char(1) DEFAULT 'N' COMMENT '是否自动打印', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `DESCRIPTION` varchar(255) DEFAULT '' COMMENT '备注说明', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A正常;D作废', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='打印机表'; + +/*Data for the table `mt_printer` */ + +/*Table structure for table `mt_refund` */ + +DROP TABLE IF EXISTS `mt_refund`; + +CREATE TABLE `mt_refund` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `ORDER_ID` int NOT NULL COMMENT '订单ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `USER_ID` int NOT NULL COMMENT '会员ID', + `AMOUNT` decimal(10,2) DEFAULT NULL COMMENT '退款金额', + `TYPE` varchar(20) DEFAULT '' COMMENT '售后类型', + `REMARK` varchar(500) DEFAULT '' COMMENT '退款备注', + `EXPRESS_NAME` varchar(30) DEFAULT '' COMMENT '物流公司', + `EXPRESS_NO` varchar(30) DEFAULT '' COMMENT '物流单号', + `REJECT_REASON` varchar(1000) DEFAULT NULL COMMENT '拒绝原因', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + `IMAGES` varchar(1000) DEFAULT NULL COMMENT '图片', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='售后表'; + +/*Data for the table `mt_refund` */ + +/*Table structure for table `mt_region` */ + +DROP TABLE IF EXISTS `mt_region`; + +CREATE TABLE `mt_region` ( + `ID` int unsigned NOT NULL AUTO_INCREMENT COMMENT '区划信息ID', + `NAME` varchar(255) NOT NULL DEFAULT '' COMMENT '区划名称', + `PID` int unsigned NOT NULL DEFAULT '0' COMMENT '父级ID', + `CODE` varchar(255) NOT NULL DEFAULT '' COMMENT '区划编码', + `LEVEL` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '层级(1省级 2市级 3区/县级)', + PRIMARY KEY (`ID`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=3705 DEFAULT CHARSET=utf8 COMMENT='省市区数据表'; + +/*Data for the table `mt_region` */ + +insert into `mt_region`(`ID`,`NAME`,`PID`,`CODE`,`LEVEL`) values +(1,'北京',0,'110000',1), +(2,'北京市',1,'110010',2), +(3,'东城区',2,'110101',3), +(4,'西城区',2,'110102',3), +(5,'朝阳区',2,'110105',3), +(6,'丰台区',2,'110106',3), +(7,'石景山区',2,'110107',3), +(8,'海淀区',2,'110108',3), +(9,'门头沟区',2,'110109',3), +(10,'房山区',2,'110111',3), +(11,'通州区',2,'110112',3), +(12,'顺义区',2,'110113',3), +(13,'昌平区',2,'110114',3), +(14,'大兴区',2,'110115',3), +(15,'怀柔区',2,'110116',3), +(16,'平谷区',2,'110117',3), +(17,'密云区',2,'110118',3), +(18,'延庆区',2,'110119',3), +(19,'天津',0,'120000',1), +(20,'天津市',19,'120010',2), +(21,'和平区',20,'120101',3), +(22,'河东区',20,'120102',3), +(23,'河西区',20,'120103',3), +(24,'南开区',20,'120104',3), +(25,'河北区',20,'120105',3), +(26,'红桥区',20,'120106',3), +(27,'东丽区',20,'120110',3), +(28,'西青区',20,'120111',3), +(29,'津南区',20,'120112',3), +(30,'北辰区',20,'120113',3), +(31,'武清区',20,'120114',3), +(32,'宝坻区',20,'120115',3), +(33,'滨海新区',20,'120116',3), +(34,'宁河区',20,'120117',3), +(35,'静海区',20,'120118',3), +(36,'蓟州区',20,'120119',3), +(37,'河北省',0,'130000',1), +(38,'石家庄市',37,'130100',2), +(39,'长安区',38,'130102',3), +(40,'桥西区',38,'130104',3), +(41,'新华区',38,'130105',3), +(42,'井陉矿区',38,'130107',3), +(43,'裕华区',38,'130108',3), +(44,'藁城区',38,'130109',3), +(45,'鹿泉区',38,'130110',3), +(46,'栾城区',38,'130111',3), +(47,'井陉县',38,'130121',3), +(48,'正定县',38,'130123',3), +(49,'行唐县',38,'130125',3), +(50,'灵寿县',38,'130126',3), +(51,'高邑县',38,'130127',3), +(52,'深泽县',38,'130128',3), +(53,'赞皇县',38,'130129',3), +(54,'无极县',38,'130130',3), +(55,'平山县',38,'130131',3), +(56,'元氏县',38,'130132',3), +(57,'赵县',38,'130133',3), +(58,'辛集市',38,'130181',3), +(59,'晋州市',38,'130183',3), +(60,'新乐市',38,'130184',3), +(61,'唐山市',37,'130200',2), +(62,'路南区',61,'130202',3), +(63,'路北区',61,'130203',3), +(64,'古冶区',61,'130204',3), +(65,'开平区',61,'130205',3), +(66,'丰南区',61,'130207',3), +(67,'丰润区',61,'130208',3), +(68,'曹妃甸区',61,'130209',3), +(69,'滦南县',61,'130224',3), +(70,'乐亭县',61,'130225',3), +(71,'迁西县',61,'130227',3), +(72,'玉田县',61,'130229',3), +(73,'遵化市',61,'130281',3), +(74,'迁安市',61,'130283',3), +(75,'滦州市',61,'130284',3), +(76,'秦皇岛市',37,'130300',2), +(77,'海港区',76,'130302',3), +(78,'山海关区',76,'130303',3), +(79,'北戴河区',76,'130304',3), +(80,'抚宁区',76,'130306',3), +(81,'青龙满族自治县',76,'130321',3), +(82,'昌黎县',76,'130322',3), +(83,'卢龙县',76,'130324',3), +(84,'邯郸市',37,'130400',2), +(85,'邯山区',84,'130402',3), +(86,'丛台区',84,'130403',3), +(87,'复兴区',84,'130404',3), +(88,'峰峰矿区',84,'130406',3), +(89,'肥乡区',84,'130407',3), +(90,'永年区',84,'130408',3), +(91,'临漳县',84,'130423',3), +(92,'成安县',84,'130424',3), +(93,'大名县',84,'130425',3), +(94,'涉县',84,'130426',3), +(95,'磁县',84,'130427',3), +(96,'邱县',84,'130430',3), +(97,'鸡泽县',84,'130431',3), +(98,'广平县',84,'130432',3), +(99,'馆陶县',84,'130433',3), +(100,'魏县',84,'130434',3), +(101,'曲周县',84,'130435',3), +(102,'武安市',84,'130481',3), +(103,'邢台市',37,'130500',2), +(104,'桥东区',103,'130502',3), +(105,'桥西区',103,'130503',3), +(106,'邢台县',103,'130521',3), +(107,'临城县',103,'130522',3), +(108,'内丘县',103,'130523',3), +(109,'柏乡县',103,'130524',3), +(110,'隆尧县',103,'130525',3), +(111,'任县',103,'130526',3), +(112,'南和县',103,'130527',3), +(113,'宁晋县',103,'130528',3), +(114,'巨鹿县',103,'130529',3), +(115,'新河县',103,'130530',3), +(116,'广宗县',103,'130531',3), +(117,'平乡县',103,'130532',3), +(118,'威县',103,'130533',3), +(119,'清河县',103,'130534',3), +(120,'临西县',103,'130535',3), +(121,'南宫市',103,'130581',3), +(122,'沙河市',103,'130582',3), +(123,'保定市',37,'130600',2), +(124,'竞秀区',123,'130602',3), +(125,'莲池区',123,'130606',3), +(126,'满城区',123,'130607',3), +(127,'清苑区',123,'130608',3), +(128,'徐水区',123,'130609',3), +(129,'涞水县',123,'130623',3), +(130,'阜平县',123,'130624',3), +(131,'定兴县',123,'130626',3), +(132,'唐县',123,'130627',3), +(133,'高阳县',123,'130628',3), +(134,'容城县',123,'130629',3), +(135,'涞源县',123,'130630',3), +(136,'望都县',123,'130631',3), +(137,'安新县',123,'130632',3), +(138,'易县',123,'130633',3), +(139,'曲阳县',123,'130634',3), +(140,'蠡县',123,'130635',3), +(141,'顺平县',123,'130636',3), +(142,'博野县',123,'130637',3), +(143,'雄县',123,'130638',3), +(144,'涿州市',123,'130681',3), +(145,'定州市',123,'130682',3), +(146,'安国市',123,'130683',3), +(147,'高碑店市',123,'130684',3), +(148,'张家口市',37,'130700',2), +(149,'桥东区',148,'130702',3), +(150,'桥西区',148,'130703',3), +(151,'宣化区',148,'130705',3), +(152,'下花园区',148,'130706',3), +(153,'万全区',148,'130708',3), +(154,'崇礼区',148,'130709',3), +(155,'张北县',148,'130722',3), +(156,'康保县',148,'130723',3), +(157,'沽源县',148,'130724',3), +(158,'尚义县',148,'130725',3), +(159,'蔚县',148,'130726',3), +(160,'阳原县',148,'130727',3), +(161,'怀安县',148,'130728',3), +(162,'怀来县',148,'130730',3), +(163,'涿鹿县',148,'130731',3), +(164,'赤城县',148,'130732',3), +(165,'承德市',37,'130800',2), +(166,'双桥区',165,'130802',3), +(167,'双滦区',165,'130803',3), +(168,'鹰手营子矿区',165,'130804',3), +(169,'承德县',165,'130821',3), +(170,'兴隆县',165,'130822',3), +(171,'滦平县',165,'130824',3), +(172,'隆化县',165,'130825',3), +(173,'丰宁满族自治县',165,'130826',3), +(174,'宽城满族自治县',165,'130827',3), +(175,'围场满族蒙古族自治县',165,'130828',3), +(176,'平泉市',165,'130881',3), +(177,'沧州市',37,'130900',2), +(178,'新华区',177,'130902',3), +(179,'运河区',177,'130903',3), +(180,'沧县',177,'130921',3), +(181,'青县',177,'130922',3), +(182,'东光县',177,'130923',3), +(183,'海兴县',177,'130924',3), +(184,'盐山县',177,'130925',3), +(185,'肃宁县',177,'130926',3), +(186,'南皮县',177,'130927',3), +(187,'吴桥县',177,'130928',3), +(188,'献县',177,'130929',3), +(189,'孟村回族自治县',177,'130930',3), +(190,'泊头市',177,'130981',3), +(191,'任丘市',177,'130982',3), +(192,'黄骅市',177,'130983',3), +(193,'河间市',177,'130984',3), +(194,'廊坊市',37,'131000',2), +(195,'安次区',194,'131002',3), +(196,'广阳区',194,'131003',3), +(197,'固安县',194,'131022',3), +(198,'永清县',194,'131023',3), +(199,'香河县',194,'131024',3), +(200,'大城县',194,'131025',3), +(201,'文安县',194,'131026',3), +(202,'大厂回族自治县',194,'131028',3), +(203,'霸州市',194,'131081',3), +(204,'三河市',194,'131082',3), +(205,'衡水市',37,'131100',2), +(206,'桃城区',205,'131102',3), +(207,'冀州区',205,'131103',3), +(208,'枣强县',205,'131121',3), +(209,'武邑县',205,'131122',3), +(210,'武强县',205,'131123',3), +(211,'饶阳县',205,'131124',3), +(212,'安平县',205,'131125',3), +(213,'故城县',205,'131126',3), +(214,'景县',205,'131127',3), +(215,'阜城县',205,'131128',3), +(216,'深州市',205,'131182',3), +(217,'山西省',0,'140000',1), +(218,'太原市',217,'140100',2), +(219,'小店区',218,'140105',3), +(220,'迎泽区',218,'140106',3), +(221,'杏花岭区',218,'140107',3), +(222,'尖草坪区',218,'140108',3), +(223,'万柏林区',218,'140109',3), +(224,'晋源区',218,'140110',3), +(225,'清徐县',218,'140121',3), +(226,'阳曲县',218,'140122',3), +(227,'娄烦县',218,'140123',3), +(228,'古交市',218,'140181',3), +(229,'大同市',217,'140200',2), +(230,'新荣区',229,'140212',3), +(231,'平城区',229,'140213',3), +(232,'云冈区',229,'140214',3), +(233,'云州区',229,'140215',3), +(234,'阳高县',229,'140221',3), +(235,'天镇县',229,'140222',3), +(236,'广灵县',229,'140223',3), +(237,'灵丘县',229,'140224',3), +(238,'浑源县',229,'140225',3), +(239,'左云县',229,'140226',3), +(240,'阳泉市',217,'140300',2), +(241,'城区',240,'140302',3), +(242,'矿区',240,'140303',3), +(243,'郊区',240,'140311',3), +(244,'平定县',240,'140321',3), +(245,'盂县',240,'140322',3), +(246,'长治市',217,'140400',2), +(247,'潞州区',246,'140403',3), +(248,'上党区',246,'140404',3), +(249,'屯留区',246,'140405',3), +(250,'潞城区',246,'140406',3), +(251,'襄垣县',246,'140423',3), +(252,'平顺县',246,'140425',3), +(253,'黎城县',246,'140426',3), +(254,'壶关县',246,'140427',3), +(255,'长子县',246,'140428',3), +(256,'武乡县',246,'140429',3), +(257,'沁县',246,'140430',3), +(258,'沁源县',246,'140431',3), +(259,'晋城市',217,'140500',2), +(260,'城区',259,'140502',3), +(261,'沁水县',259,'140521',3), +(262,'阳城县',259,'140522',3), +(263,'陵川县',259,'140524',3), +(264,'泽州县',259,'140525',3), +(265,'高平市',259,'140581',3), +(266,'朔州市',217,'140600',2), +(267,'朔城区',266,'140602',3), +(268,'平鲁区',266,'140603',3), +(269,'山阴县',266,'140621',3), +(270,'应县',266,'140622',3), +(271,'右玉县',266,'140623',3), +(272,'怀仁市',266,'140681',3), +(273,'晋中市',217,'140700',2), +(274,'榆次区',273,'140702',3), +(275,'太谷区',273,'140703',3), +(276,'榆社县',273,'140721',3), +(277,'左权县',273,'140722',3), +(278,'和顺县',273,'140723',3), +(279,'昔阳县',273,'140724',3), +(280,'寿阳县',273,'140725',3), +(281,'祁县',273,'140727',3), +(282,'平遥县',273,'140728',3), +(283,'灵石县',273,'140729',3), +(284,'介休市',273,'140781',3), +(285,'运城市',217,'140800',2), +(286,'盐湖区',285,'140802',3), +(287,'临猗县',285,'140821',3), +(288,'万荣县',285,'140822',3), +(289,'闻喜县',285,'140823',3), +(290,'稷山县',285,'140824',3), +(291,'新绛县',285,'140825',3), +(292,'绛县',285,'140826',3), +(293,'垣曲县',285,'140827',3), +(294,'夏县',285,'140828',3), +(295,'平陆县',285,'140829',3), +(296,'芮城县',285,'140830',3), +(297,'永济市',285,'140881',3), +(298,'河津市',285,'140882',3), +(299,'忻州市',217,'140900',2), +(300,'忻府区',299,'140902',3), +(301,'定襄县',299,'140921',3), +(302,'五台县',299,'140922',3), +(303,'代县',299,'140923',3), +(304,'繁峙县',299,'140924',3), +(305,'宁武县',299,'140925',3), +(306,'静乐县',299,'140926',3), +(307,'神池县',299,'140927',3), +(308,'五寨县',299,'140928',3), +(309,'岢岚县',299,'140929',3), +(310,'河曲县',299,'140930',3), +(311,'保德县',299,'140931',3), +(312,'偏关县',299,'140932',3), +(313,'原平市',299,'140981',3), +(314,'临汾市',217,'141000',2), +(315,'尧都区',314,'141002',3), +(316,'曲沃县',314,'141021',3), +(317,'翼城县',314,'141022',3), +(318,'襄汾县',314,'141023',3), +(319,'洪洞县',314,'141024',3), +(320,'古县',314,'141025',3), +(321,'安泽县',314,'141026',3), +(322,'浮山县',314,'141027',3), +(323,'吉县',314,'141028',3), +(324,'乡宁县',314,'141029',3), +(325,'大宁县',314,'141030',3), +(326,'隰县',314,'141031',3), +(327,'永和县',314,'141032',3), +(328,'蒲县',314,'141033',3), +(329,'汾西县',314,'141034',3), +(330,'侯马市',314,'141081',3), +(331,'霍州市',314,'141082',3), +(332,'吕梁市',217,'141100',2), +(333,'离石区',332,'141102',3), +(334,'文水县',332,'141121',3), +(335,'交城县',332,'141122',3), +(336,'兴县',332,'141123',3), +(337,'临县',332,'141124',3), +(338,'柳林县',332,'141125',3), +(339,'石楼县',332,'141126',3), +(340,'岚县',332,'141127',3), +(341,'方山县',332,'141128',3), +(342,'中阳县',332,'141129',3), +(343,'交口县',332,'141130',3), +(344,'孝义市',332,'141181',3), +(345,'汾阳市',332,'141182',3), +(346,'内蒙古自治区',0,'150000',1), +(347,'呼和浩特市',346,'150100',2), +(348,'新城区',347,'150102',3), +(349,'回民区',347,'150103',3), +(350,'玉泉区',347,'150104',3), +(351,'赛罕区',347,'150105',3), +(352,'土默特左旗',347,'150121',3), +(353,'托克托县',347,'150122',3), +(354,'和林格尔县',347,'150123',3), +(355,'清水河县',347,'150124',3), +(356,'武川县',347,'150125',3), +(357,'包头市',346,'150200',2), +(358,'东河区',357,'150202',3), +(359,'昆都仑区',357,'150203',3), +(360,'青山区',357,'150204',3), +(361,'石拐区',357,'150205',3), +(362,'白云鄂博矿区',357,'150206',3), +(363,'九原区',357,'150207',3), +(364,'土默特右旗',357,'150221',3), +(365,'固阳县',357,'150222',3), +(366,'达尔罕茂明安联合旗',357,'150223',3), +(367,'乌海市',346,'150300',2), +(368,'海勃湾区',367,'150302',3), +(369,'海南区',367,'150303',3), +(370,'乌达区',367,'150304',3), +(371,'赤峰市',346,'150400',2), +(372,'红山区',371,'150402',3), +(373,'元宝山区',371,'150403',3), +(374,'松山区',371,'150404',3), +(375,'阿鲁科尔沁旗',371,'150421',3), +(376,'巴林左旗',371,'150422',3), +(377,'巴林右旗',371,'150423',3), +(378,'林西县',371,'150424',3), +(379,'克什克腾旗',371,'150425',3), +(380,'翁牛特旗',371,'150426',3), +(381,'喀喇沁旗',371,'150428',3), +(382,'宁城县',371,'150429',3), +(383,'敖汉旗',371,'150430',3), +(384,'通辽市',346,'150500',2), +(385,'科尔沁区',384,'150502',3), +(386,'科尔沁左翼中旗',384,'150521',3), +(387,'科尔沁左翼后旗',384,'150522',3), +(388,'开鲁县',384,'150523',3), +(389,'库伦旗',384,'150524',3), +(390,'奈曼旗',384,'150525',3), +(391,'扎鲁特旗',384,'150526',3), +(392,'霍林郭勒市',384,'150581',3), +(393,'鄂尔多斯市',346,'150600',2), +(394,'东胜区',393,'150602',3), +(395,'康巴什区',393,'150603',3), +(396,'达拉特旗',393,'150621',3), +(397,'准格尔旗',393,'150622',3), +(398,'鄂托克前旗',393,'150623',3), +(399,'鄂托克旗',393,'150624',3), +(400,'杭锦旗',393,'150625',3), +(401,'乌审旗',393,'150626',3), +(402,'伊金霍洛旗',393,'150627',3), +(403,'呼伦贝尔市',346,'150700',2), +(404,'海拉尔区',403,'150702',3), +(405,'扎赉诺尔区',403,'150703',3), +(406,'阿荣旗',403,'150721',3), +(407,'莫力达瓦达斡尔族自治旗',403,'150722',3), +(408,'鄂伦春自治旗',403,'150723',3), +(409,'鄂温克族自治旗',403,'150724',3), +(410,'陈巴尔虎旗',403,'150725',3), +(411,'新巴尔虎左旗',403,'150726',3), +(412,'新巴尔虎右旗',403,'150727',3), +(413,'满洲里市',403,'150781',3), +(414,'牙克石市',403,'150782',3), +(415,'扎兰屯市',403,'150783',3), +(416,'额尔古纳市',403,'150784',3), +(417,'根河市',403,'150785',3), +(418,'巴彦淖尔市',346,'150800',2), +(419,'临河区',418,'150802',3), +(420,'五原县',418,'150821',3), +(421,'磴口县',418,'150822',3), +(422,'乌拉特前旗',418,'150823',3), +(423,'乌拉特中旗',418,'150824',3), +(424,'乌拉特后旗',418,'150825',3), +(425,'杭锦后旗',418,'150826',3), +(426,'乌兰察布市',346,'150900',2), +(427,'集宁区',426,'150902',3), +(428,'卓资县',426,'150921',3), +(429,'化德县',426,'150922',3), +(430,'商都县',426,'150923',3), +(431,'兴和县',426,'150924',3), +(432,'凉城县',426,'150925',3), +(433,'察哈尔右翼前旗',426,'150926',3), +(434,'察哈尔右翼中旗',426,'150927',3), +(435,'察哈尔右翼后旗',426,'150928',3), +(436,'四子王旗',426,'150929',3), +(437,'丰镇市',426,'150981',3), +(438,'兴安盟',346,'152200',2), +(439,'乌兰浩特市',438,'152201',3), +(440,'阿尔山市',438,'152202',3), +(441,'科尔沁右翼前旗',438,'152221',3), +(442,'科尔沁右翼中旗',438,'152222',3), +(443,'扎赉特旗',438,'152223',3), +(444,'突泉县',438,'152224',3), +(445,'锡林郭勒盟',346,'152500',2), +(446,'二连浩特市',445,'152501',3), +(447,'锡林浩特市',445,'152502',3), +(448,'阿巴嘎旗',445,'152522',3), +(449,'苏尼特左旗',445,'152523',3), +(450,'苏尼特右旗',445,'152524',3), +(451,'东乌珠穆沁旗',445,'152525',3), +(452,'西乌珠穆沁旗',445,'152526',3), +(453,'太仆寺旗',445,'152527',3), +(454,'镶黄旗',445,'152528',3), +(455,'正镶白旗',445,'152529',3), +(456,'正蓝旗',445,'152530',3), +(457,'多伦县',445,'152531',3), +(458,'阿拉善盟',346,'152900',2), +(459,'阿拉善左旗',458,'152921',3), +(460,'阿拉善右旗',458,'152922',3), +(461,'额济纳旗',458,'152923',3), +(462,'辽宁省',0,'210000',1), +(463,'沈阳市',462,'210100',2), +(464,'和平区',463,'210102',3), +(465,'沈河区',463,'210103',3), +(466,'大东区',463,'210104',3), +(467,'皇姑区',463,'210105',3), +(468,'铁西区',463,'210106',3), +(469,'苏家屯区',463,'210111',3), +(470,'浑南区',463,'210112',3), +(471,'沈北新区',463,'210113',3), +(472,'于洪区',463,'210114',3), +(473,'辽中区',463,'210115',3), +(474,'康平县',463,'210123',3), +(475,'法库县',463,'210124',3), +(476,'新民市',463,'210181',3), +(477,'大连市',462,'210200',2), +(478,'中山区',477,'210202',3), +(479,'西岗区',477,'210203',3), +(480,'沙河口区',477,'210204',3), +(481,'甘井子区',477,'210211',3), +(482,'旅顺口区',477,'210212',3), +(483,'金州区',477,'210213',3), +(484,'普兰店区',477,'210214',3), +(485,'长海县',477,'210224',3), +(486,'瓦房店市',477,'210281',3), +(487,'庄河市',477,'210283',3), +(488,'鞍山市',462,'210300',2), +(489,'铁东区',488,'210302',3), +(490,'铁西区',488,'210303',3), +(491,'立山区',488,'210304',3), +(492,'千山区',488,'210311',3), +(493,'台安县',488,'210321',3), +(494,'岫岩满族自治县',488,'210323',3), +(495,'海城市',488,'210381',3), +(496,'抚顺市',462,'210400',2), +(497,'新抚区',496,'210402',3), +(498,'东洲区',496,'210403',3), +(499,'望花区',496,'210404',3), +(500,'顺城区',496,'210411',3), +(501,'抚顺县',496,'210421',3), +(502,'新宾满族自治县',496,'210422',3), +(503,'清原满族自治县',496,'210423',3), +(504,'本溪市',462,'210500',2), +(505,'平山区',504,'210502',3), +(506,'溪湖区',504,'210503',3), +(507,'明山区',504,'210504',3), +(508,'南芬区',504,'210505',3), +(509,'本溪满族自治县',504,'210521',3), +(510,'桓仁满族自治县',504,'210522',3), +(511,'丹东市',462,'210600',2), +(512,'元宝区',511,'210602',3), +(513,'振兴区',511,'210603',3), +(514,'振安区',511,'210604',3), +(515,'宽甸满族自治县',511,'210624',3), +(516,'东港市',511,'210681',3), +(517,'凤城市',511,'210682',3), +(518,'锦州市',462,'210700',2), +(519,'古塔区',518,'210702',3), +(520,'凌河区',518,'210703',3), +(521,'太和区',518,'210711',3), +(522,'黑山县',518,'210726',3), +(523,'义县',518,'210727',3), +(524,'凌海市',518,'210781',3), +(525,'北镇市',518,'210782',3), +(526,'营口市',462,'210800',2), +(527,'站前区',526,'210802',3), +(528,'西市区',526,'210803',3), +(529,'鲅鱼圈区',526,'210804',3), +(530,'老边区',526,'210811',3), +(531,'盖州市',526,'210881',3), +(532,'大石桥市',526,'210882',3), +(533,'阜新市',462,'210900',2), +(534,'海州区',533,'210902',3), +(535,'新邱区',533,'210903',3), +(536,'太平区',533,'210904',3), +(537,'清河门区',533,'210905',3), +(538,'细河区',533,'210911',3), +(539,'阜新蒙古族自治县',533,'210921',3), +(540,'彰武县',533,'210922',3), +(541,'辽阳市',462,'211000',2), +(542,'白塔区',541,'211002',3), +(543,'文圣区',541,'211003',3), +(544,'宏伟区',541,'211004',3), +(545,'弓长岭区',541,'211005',3), +(546,'太子河区',541,'211011',3), +(547,'辽阳县',541,'211021',3), +(548,'灯塔市',541,'211081',3), +(549,'盘锦市',462,'211100',2), +(550,'双台子区',549,'211102',3), +(551,'兴隆台区',549,'211103',3), +(552,'大洼区',549,'211104',3), +(553,'盘山县',549,'211122',3), +(554,'铁岭市',462,'211200',2), +(555,'银州区',554,'211202',3), +(556,'清河区',554,'211204',3), +(557,'铁岭县',554,'211221',3), +(558,'西丰县',554,'211223',3), +(559,'昌图县',554,'211224',3), +(560,'调兵山市',554,'211281',3), +(561,'开原市',554,'211282',3), +(562,'朝阳市',462,'211300',2), +(563,'双塔区',562,'211302',3), +(564,'龙城区',562,'211303',3), +(565,'朝阳县',562,'211321',3), +(566,'建平县',562,'211322',3), +(567,'喀喇沁左翼蒙古族自治县',562,'211324',3), +(568,'北票市',562,'211381',3), +(569,'凌源市',562,'211382',3), +(570,'葫芦岛市',462,'211400',2), +(571,'连山区',570,'211402',3), +(572,'龙港区',570,'211403',3), +(573,'南票区',570,'211404',3), +(574,'绥中县',570,'211421',3), +(575,'建昌县',570,'211422',3), +(576,'兴城市',570,'211481',3), +(577,'吉林省',0,'220000',1), +(578,'长春市',577,'220100',2), +(579,'南关区',578,'220102',3), +(580,'宽城区',578,'220103',3), +(581,'朝阳区',578,'220104',3), +(582,'二道区',578,'220105',3), +(583,'绿园区',578,'220106',3), +(584,'双阳区',578,'220112',3), +(585,'九台区',578,'220113',3), +(586,'农安县',578,'220122',3), +(587,'榆树市',578,'220182',3), +(588,'德惠市',578,'220183',3), +(589,'吉林市',577,'220200',2), +(590,'昌邑区',589,'220202',3), +(591,'龙潭区',589,'220203',3), +(592,'船营区',589,'220204',3), +(593,'丰满区',589,'220211',3), +(594,'永吉县',589,'220221',3), +(595,'蛟河市',589,'220281',3), +(596,'桦甸市',589,'220282',3), +(597,'舒兰市',589,'220283',3), +(598,'磐石市',589,'220284',3), +(599,'四平市',577,'220300',2), +(600,'铁西区',599,'220302',3), +(601,'铁东区',599,'220303',3), +(602,'梨树县',599,'220322',3), +(603,'伊通满族自治县',599,'220323',3), +(604,'公主岭市',599,'220381',3), +(605,'双辽市',599,'220382',3), +(606,'辽源市',577,'220400',2), +(607,'龙山区',606,'220402',3), +(608,'西安区',606,'220403',3), +(609,'东丰县',606,'220421',3), +(610,'东辽县',606,'220422',3), +(611,'通化市',577,'220500',2), +(612,'东昌区',611,'220502',3), +(613,'二道江区',611,'220503',3), +(614,'通化县',611,'220521',3), +(615,'辉南县',611,'220523',3), +(616,'柳河县',611,'220524',3), +(617,'梅河口市',611,'220581',3), +(618,'集安市',611,'220582',3), +(619,'白山市',577,'220600',2), +(620,'浑江区',619,'220602',3), +(621,'江源区',619,'220605',3), +(622,'抚松县',619,'220621',3), +(623,'靖宇县',619,'220622',3), +(624,'长白朝鲜族自治县',619,'220623',3), +(625,'临江市',619,'220681',3), +(626,'松原市',577,'220700',2), +(627,'宁江区',626,'220702',3), +(628,'前郭尔罗斯蒙古族自治县',626,'220721',3), +(629,'长岭县',626,'220722',3), +(630,'乾安县',626,'220723',3), +(631,'扶余市',626,'220781',3), +(632,'白城市',577,'220800',2), +(633,'洮北区',632,'220802',3), +(634,'镇赉县',632,'220821',3), +(635,'通榆县',632,'220822',3), +(636,'洮南市',632,'220881',3), +(637,'大安市',632,'220882',3), +(638,'延边朝鲜族自治州',577,'222400',2), +(639,'延吉市',638,'222401',3), +(640,'图们市',638,'222402',3), +(641,'敦化市',638,'222403',3), +(642,'珲春市',638,'222404',3), +(643,'龙井市',638,'222405',3), +(644,'和龙市',638,'222406',3), +(645,'汪清县',638,'222424',3), +(646,'安图县',638,'222426',3), +(647,'黑龙江省',0,'230000',1), +(648,'哈尔滨市',647,'230100',2), +(649,'道里区',648,'230102',3), +(650,'南岗区',648,'230103',3), +(651,'道外区',648,'230104',3), +(652,'平房区',648,'230108',3), +(653,'松北区',648,'230109',3), +(654,'香坊区',648,'230110',3), +(655,'呼兰区',648,'230111',3), +(656,'阿城区',648,'230112',3), +(657,'双城区',648,'230113',3), +(658,'依兰县',648,'230123',3), +(659,'方正县',648,'230124',3), +(660,'宾县',648,'230125',3), +(661,'巴彦县',648,'230126',3), +(662,'木兰县',648,'230127',3), +(663,'通河县',648,'230128',3), +(664,'延寿县',648,'230129',3), +(665,'尚志市',648,'230183',3), +(666,'五常市',648,'230184',3), +(667,'齐齐哈尔市',647,'230200',2), +(668,'龙沙区',667,'230202',3), +(669,'建华区',667,'230203',3), +(670,'铁锋区',667,'230204',3), +(671,'昂昂溪区',667,'230205',3), +(672,'富拉尔基区',667,'230206',3), +(673,'碾子山区',667,'230207',3), +(674,'梅里斯达斡尔族区',667,'230208',3), +(675,'龙江县',667,'230221',3), +(676,'依安县',667,'230223',3), +(677,'泰来县',667,'230224',3), +(678,'甘南县',667,'230225',3), +(679,'富裕县',667,'230227',3), +(680,'克山县',667,'230229',3), +(681,'克东县',667,'230230',3), +(682,'拜泉县',667,'230231',3), +(683,'讷河市',667,'230281',3), +(684,'鸡西市',647,'230300',2), +(685,'鸡冠区',684,'230302',3), +(686,'恒山区',684,'230303',3), +(687,'滴道区',684,'230304',3), +(688,'梨树区',684,'230305',3), +(689,'城子河区',684,'230306',3), +(690,'麻山区',684,'230307',3), +(691,'鸡东县',684,'230321',3), +(692,'虎林市',684,'230381',3), +(693,'密山市',684,'230382',3), +(694,'鹤岗市',647,'230400',2), +(695,'向阳区',694,'230402',3), +(696,'工农区',694,'230403',3), +(697,'南山区',694,'230404',3), +(698,'兴安区',694,'230405',3), +(699,'东山区',694,'230406',3), +(700,'兴山区',694,'230407',3), +(701,'萝北县',694,'230421',3), +(702,'绥滨县',694,'230422',3), +(703,'双鸭山市',647,'230500',2), +(704,'尖山区',703,'230502',3), +(705,'岭东区',703,'230503',3), +(706,'四方台区',703,'230505',3), +(707,'宝山区',703,'230506',3), +(708,'集贤县',703,'230521',3), +(709,'友谊县',703,'230522',3), +(710,'宝清县',703,'230523',3), +(711,'饶河县',703,'230524',3), +(712,'大庆市',647,'230600',2), +(713,'萨尔图区',712,'230602',3), +(714,'龙凤区',712,'230603',3), +(715,'让胡路区',712,'230604',3), +(716,'红岗区',712,'230605',3), +(717,'大同区',712,'230606',3), +(718,'肇州县',712,'230621',3), +(719,'肇源县',712,'230622',3), +(720,'林甸县',712,'230623',3), +(721,'杜尔伯特蒙古族自治县',712,'230624',3), +(722,'伊春市',647,'230700',2), +(723,'伊美区',722,'230717',3), +(724,'乌翠区',722,'230718',3), +(725,'友好区',722,'230719',3), +(726,'嘉荫县',722,'230722',3), +(727,'汤旺县',722,'230723',3), +(728,'丰林县',722,'230724',3), +(729,'大箐山县',722,'230725',3), +(730,'南岔县',722,'230726',3), +(731,'金林区',722,'230751',3), +(732,'铁力市',722,'230781',3), +(733,'佳木斯市',647,'230800',2), +(734,'向阳区',733,'230803',3), +(735,'前进区',733,'230804',3), +(736,'东风区',733,'230805',3), +(737,'郊区',733,'230811',3), +(738,'桦南县',733,'230822',3), +(739,'桦川县',733,'230826',3), +(740,'汤原县',733,'230828',3), +(741,'同江市',733,'230881',3), +(742,'富锦市',733,'230882',3), +(743,'抚远市',733,'230883',3), +(744,'七台河市',647,'230900',2), +(745,'新兴区',744,'230902',3), +(746,'桃山区',744,'230903',3), +(747,'茄子河区',744,'230904',3), +(748,'勃利县',744,'230921',3), +(749,'牡丹江市',647,'231000',2), +(750,'东安区',749,'231002',3), +(751,'阳明区',749,'231003',3), +(752,'爱民区',749,'231004',3), +(753,'西安区',749,'231005',3), +(754,'林口县',749,'231025',3), +(755,'绥芬河市',749,'231081',3), +(756,'海林市',749,'231083',3), +(757,'宁安市',749,'231084',3), +(758,'穆棱市',749,'231085',3), +(759,'东宁市',749,'231086',3), +(760,'黑河市',647,'231100',2), +(761,'爱辉区',760,'231102',3), +(762,'逊克县',760,'231123',3), +(763,'孙吴县',760,'231124',3), +(764,'北安市',760,'231181',3), +(765,'五大连池市',760,'231182',3), +(766,'嫩江市',760,'231183',3), +(767,'绥化市',647,'231200',2), +(768,'北林区',767,'231202',3), +(769,'望奎县',767,'231221',3), +(770,'兰西县',767,'231222',3), +(771,'青冈县',767,'231223',3), +(772,'庆安县',767,'231224',3), +(773,'明水县',767,'231225',3), +(774,'绥棱县',767,'231226',3), +(775,'安达市',767,'231281',3), +(776,'肇东市',767,'231282',3), +(777,'海伦市',767,'231283',3), +(778,'大兴安岭地区',647,'232700',2), +(779,'漠河市',778,'232701',3), +(780,'呼玛县',778,'232721',3), +(781,'塔河县',778,'232722',3), +(782,'上海',0,'310000',1), +(783,'上海市',782,'310010',2), +(784,'黄浦区',783,'310101',3), +(785,'徐汇区',783,'310104',3), +(786,'长宁区',783,'310105',3), +(787,'静安区',783,'310106',3), +(788,'普陀区',783,'310107',3), +(789,'虹口区',783,'310109',3), +(790,'杨浦区',783,'310110',3), +(791,'闵行区',783,'310112',3), +(792,'宝山区',783,'310113',3), +(793,'嘉定区',783,'310114',3), +(794,'浦东新区',783,'310115',3), +(795,'金山区',783,'310116',3), +(796,'松江区',783,'310117',3), +(797,'青浦区',783,'310118',3), +(798,'奉贤区',783,'310120',3), +(799,'崇明区',783,'310151',3), +(800,'江苏省',0,'320000',1), +(801,'南京市',800,'320100',2), +(802,'玄武区',801,'320102',3), +(803,'秦淮区',801,'320104',3), +(804,'建邺区',801,'320105',3), +(805,'鼓楼区',801,'320106',3), +(806,'浦口区',801,'320111',3), +(807,'栖霞区',801,'320113',3), +(808,'雨花台区',801,'320114',3), +(809,'江宁区',801,'320115',3), +(810,'六合区',801,'320116',3), +(811,'溧水区',801,'320117',3), +(812,'高淳区',801,'320118',3), +(813,'无锡市',800,'320200',2), +(814,'锡山区',813,'320205',3), +(815,'惠山区',813,'320206',3), +(816,'滨湖区',813,'320211',3), +(817,'梁溪区',813,'320213',3), +(818,'新吴区',813,'320214',3), +(819,'江阴市',813,'320281',3), +(820,'宜兴市',813,'320282',3), +(821,'徐州市',800,'320300',2), +(822,'鼓楼区',821,'320302',3), +(823,'云龙区',821,'320303',3), +(824,'贾汪区',821,'320305',3), +(825,'泉山区',821,'320311',3), +(826,'铜山区',821,'320312',3), +(827,'丰县',821,'320321',3), +(828,'沛县',821,'320322',3), +(829,'睢宁县',821,'320324',3), +(830,'新沂市',821,'320381',3), +(831,'邳州市',821,'320382',3), +(832,'常州市',800,'320400',2), +(833,'天宁区',832,'320402',3), +(834,'钟楼区',832,'320404',3), +(835,'新北区',832,'320411',3), +(836,'武进区',832,'320412',3), +(837,'金坛区',832,'320413',3), +(838,'溧阳市',832,'320481',3), +(839,'苏州市',800,'320500',2), +(840,'虎丘区',839,'320505',3), +(841,'吴中区',839,'320506',3), +(842,'相城区',839,'320507',3), +(843,'姑苏区',839,'320508',3), +(844,'吴江区',839,'320509',3), +(845,'常熟市',839,'320581',3), +(846,'张家港市',839,'320582',3), +(847,'昆山市',839,'320583',3), +(848,'太仓市',839,'320585',3), +(849,'南通市',800,'320600',2), +(850,'崇川区',849,'320602',3), +(851,'港闸区',849,'320611',3), +(852,'通州区',849,'320612',3), +(853,'如东县',849,'320623',3), +(854,'启东市',849,'320681',3), +(855,'如皋市',849,'320682',3), +(856,'海门市',849,'320684',3), +(857,'海安市',849,'320685',3), +(858,'连云港市',800,'320700',2), +(859,'连云区',858,'320703',3), +(860,'海州区',858,'320706',3), +(861,'赣榆区',858,'320707',3), +(862,'东海县',858,'320722',3), +(863,'灌云县',858,'320723',3), +(864,'灌南县',858,'320724',3), +(865,'淮安市',800,'320800',2), +(866,'淮安区',865,'320803',3), +(867,'淮阴区',865,'320804',3), +(868,'清江浦区',865,'320812',3), +(869,'洪泽区',865,'320813',3), +(870,'涟水县',865,'320826',3), +(871,'盱眙县',865,'320830',3), +(872,'金湖县',865,'320831',3), +(873,'盐城市',800,'320900',2), +(874,'亭湖区',873,'320902',3), +(875,'盐都区',873,'320903',3), +(876,'大丰区',873,'320904',3), +(877,'响水县',873,'320921',3), +(878,'滨海县',873,'320922',3), +(879,'阜宁县',873,'320923',3), +(880,'射阳县',873,'320924',3), +(881,'建湖县',873,'320925',3), +(882,'东台市',873,'320981',3), +(883,'扬州市',800,'321000',2), +(884,'广陵区',883,'321002',3), +(885,'邗江区',883,'321003',3), +(886,'江都区',883,'321012',3), +(887,'宝应县',883,'321023',3), +(888,'仪征市',883,'321081',3), +(889,'高邮市',883,'321084',3), +(890,'镇江市',800,'321100',2), +(891,'京口区',890,'321102',3), +(892,'润州区',890,'321111',3), +(893,'丹徒区',890,'321112',3), +(894,'丹阳市',890,'321181',3), +(895,'扬中市',890,'321182',3), +(896,'句容市',890,'321183',3), +(897,'泰州市',800,'321200',2), +(898,'海陵区',897,'321202',3), +(899,'高港区',897,'321203',3), +(900,'姜堰区',897,'321204',3), +(901,'兴化市',897,'321281',3), +(902,'靖江市',897,'321282',3), +(903,'泰兴市',897,'321283',3), +(904,'宿迁市',800,'321300',2), +(905,'宿城区',904,'321302',3), +(906,'宿豫区',904,'321311',3), +(907,'沭阳县',904,'321322',3), +(908,'泗阳县',904,'321323',3), +(909,'泗洪县',904,'321324',3), +(910,'浙江省',0,'330000',1), +(911,'杭州市',910,'330100',2), +(912,'上城区',911,'330102',3), +(913,'下城区',911,'330103',3), +(914,'江干区',911,'330104',3), +(915,'拱墅区',911,'330105',3), +(916,'西湖区',911,'330106',3), +(917,'滨江区',911,'330108',3), +(918,'萧山区',911,'330109',3), +(919,'余杭区',911,'330110',3), +(920,'富阳区',911,'330111',3), +(921,'临安区',911,'330112',3), +(922,'桐庐县',911,'330122',3), +(923,'淳安县',911,'330127',3), +(924,'建德市',911,'330182',3), +(925,'宁波市',910,'330200',2), +(926,'海曙区',925,'330203',3), +(927,'江北区',925,'330205',3), +(928,'北仑区',925,'330206',3), +(929,'镇海区',925,'330211',3), +(930,'鄞州区',925,'330212',3), +(931,'奉化区',925,'330213',3), +(932,'象山县',925,'330225',3), +(933,'宁海县',925,'330226',3), +(934,'余姚市',925,'330281',3), +(935,'慈溪市',925,'330282',3), +(936,'温州市',910,'330300',2), +(937,'鹿城区',936,'330302',3), +(938,'龙湾区',936,'330303',3), +(939,'瓯海区',936,'330304',3), +(940,'洞头区',936,'330305',3), +(941,'永嘉县',936,'330324',3), +(942,'平阳县',936,'330326',3), +(943,'苍南县',936,'330327',3), +(944,'文成县',936,'330328',3), +(945,'泰顺县',936,'330329',3), +(946,'瑞安市',936,'330381',3), +(947,'乐清市',936,'330382',3), +(948,'龙港市',936,'330383',3), +(949,'嘉兴市',910,'330400',2), +(950,'南湖区',949,'330402',3), +(951,'秀洲区',949,'330411',3), +(952,'嘉善县',949,'330421',3), +(953,'海盐县',949,'330424',3), +(954,'海宁市',949,'330481',3), +(955,'平湖市',949,'330482',3), +(956,'桐乡市',949,'330483',3), +(957,'湖州市',910,'330500',2), +(958,'吴兴区',957,'330502',3), +(959,'南浔区',957,'330503',3), +(960,'德清县',957,'330521',3), +(961,'长兴县',957,'330522',3), +(962,'安吉县',957,'330523',3), +(963,'绍兴市',910,'330600',2), +(964,'越城区',963,'330602',3), +(965,'柯桥区',963,'330603',3), +(966,'上虞区',963,'330604',3), +(967,'新昌县',963,'330624',3), +(968,'诸暨市',963,'330681',3), +(969,'嵊州市',963,'330683',3), +(970,'金华市',910,'330700',2), +(971,'婺城区',970,'330702',3), +(972,'金东区',970,'330703',3), +(973,'武义县',970,'330723',3), +(974,'浦江县',970,'330726',3), +(975,'磐安县',970,'330727',3), +(976,'兰溪市',970,'330781',3), +(977,'义乌市',970,'330782',3), +(978,'东阳市',970,'330783',3), +(979,'永康市',970,'330784',3), +(980,'衢州市',910,'330800',2), +(981,'柯城区',980,'330802',3), +(982,'衢江区',980,'330803',3), +(983,'常山县',980,'330822',3), +(984,'开化县',980,'330824',3), +(985,'龙游县',980,'330825',3), +(986,'江山市',980,'330881',3), +(987,'舟山市',910,'330900',2), +(988,'定海区',987,'330902',3), +(989,'普陀区',987,'330903',3), +(990,'岱山县',987,'330921',3), +(991,'嵊泗县',987,'330922',3), +(992,'台州市',910,'331000',2), +(993,'椒江区',992,'331002',3), +(994,'黄岩区',992,'331003',3), +(995,'路桥区',992,'331004',3), +(996,'三门县',992,'331022',3), +(997,'天台县',992,'331023',3), +(998,'仙居县',992,'331024',3), +(999,'温岭市',992,'331081',3), +(1000,'临海市',992,'331082',3), +(1001,'玉环市',992,'331083',3), +(1002,'丽水市',910,'331100',2), +(1003,'莲都区',1002,'331102',3), +(1004,'青田县',1002,'331121',3), +(1005,'缙云县',1002,'331122',3), +(1006,'遂昌县',1002,'331123',3), +(1007,'松阳县',1002,'331124',3), +(1008,'云和县',1002,'331125',3), +(1009,'庆元县',1002,'331126',3), +(1010,'景宁畲族自治县',1002,'331127',3), +(1011,'龙泉市',1002,'331181',3), +(1012,'安徽省',0,'340000',1), +(1013,'合肥市',1012,'340100',2), +(1014,'瑶海区',1013,'340102',3), +(1015,'庐阳区',1013,'340103',3), +(1016,'蜀山区',1013,'340104',3), +(1017,'包河区',1013,'340111',3), +(1018,'长丰县',1013,'340121',3), +(1019,'肥东县',1013,'340122',3), +(1020,'肥西县',1013,'340123',3), +(1021,'庐江县',1013,'340124',3), +(1022,'巢湖市',1013,'340181',3), +(1023,'芜湖市',1012,'340200',2), +(1024,'镜湖区',1023,'340202',3), +(1025,'弋江区',1023,'340203',3), +(1026,'鸠江区',1023,'340207',3), +(1027,'三山区',1023,'340208',3), +(1028,'芜湖县',1023,'340221',3), +(1029,'繁昌县',1023,'340222',3), +(1030,'南陵县',1023,'340223',3), +(1031,'无为市',1023,'340281',3), +(1032,'蚌埠市',1012,'340300',2), +(1033,'龙子湖区',1032,'340302',3), +(1034,'蚌山区',1032,'340303',3), +(1035,'禹会区',1032,'340304',3), +(1036,'淮上区',1032,'340311',3), +(1037,'怀远县',1032,'340321',3), +(1038,'五河县',1032,'340322',3), +(1039,'固镇县',1032,'340323',3), +(1040,'淮南市',1012,'340400',2), +(1041,'大通区',1040,'340402',3), +(1042,'田家庵区',1040,'340403',3), +(1043,'谢家集区',1040,'340404',3), +(1044,'八公山区',1040,'340405',3), +(1045,'潘集区',1040,'340406',3), +(1046,'凤台县',1040,'340421',3), +(1047,'寿县',1040,'340422',3), +(1048,'马鞍山市',1012,'340500',2), +(1049,'花山区',1048,'340503',3), +(1050,'雨山区',1048,'340504',3), +(1051,'博望区',1048,'340506',3), +(1052,'当涂县',1048,'340521',3), +(1053,'含山县',1048,'340522',3), +(1054,'和县',1048,'340523',3), +(1055,'淮北市',1012,'340600',2), +(1056,'杜集区',1055,'340602',3), +(1057,'相山区',1055,'340603',3), +(1058,'烈山区',1055,'340604',3), +(1059,'濉溪县',1055,'340621',3), +(1060,'铜陵市',1012,'340700',2), +(1061,'铜官区',1060,'340705',3), +(1062,'义安区',1060,'340706',3), +(1063,'郊区',1060,'340711',3), +(1064,'枞阳县',1060,'340722',3), +(1065,'安庆市',1012,'340800',2), +(1066,'迎江区',1065,'340802',3), +(1067,'大观区',1065,'340803',3), +(1068,'宜秀区',1065,'340811',3), +(1069,'怀宁县',1065,'340822',3), +(1070,'太湖县',1065,'340825',3), +(1071,'宿松县',1065,'340826',3), +(1072,'望江县',1065,'340827',3), +(1073,'岳西县',1065,'340828',3), +(1074,'桐城市',1065,'340881',3), +(1075,'潜山市',1065,'340882',3), +(1076,'黄山市',1012,'341000',2), +(1077,'屯溪区',1076,'341002',3), +(1078,'黄山区',1076,'341003',3), +(1079,'徽州区',1076,'341004',3), +(1080,'歙县',1076,'341021',3), +(1081,'休宁县',1076,'341022',3), +(1082,'黟县',1076,'341023',3), +(1083,'祁门县',1076,'341024',3), +(1084,'滁州市',1012,'341100',2), +(1085,'琅琊区',1084,'341102',3), +(1086,'南谯区',1084,'341103',3), +(1087,'来安县',1084,'341122',3), +(1088,'全椒县',1084,'341124',3), +(1089,'定远县',1084,'341125',3), +(1090,'凤阳县',1084,'341126',3), +(1091,'天长市',1084,'341181',3), +(1092,'明光市',1084,'341182',3), +(1093,'阜阳市',1012,'341200',2), +(1094,'颍州区',1093,'341202',3), +(1095,'颍东区',1093,'341203',3), +(1096,'颍泉区',1093,'341204',3), +(1097,'临泉县',1093,'341221',3), +(1098,'太和县',1093,'341222',3), +(1099,'阜南县',1093,'341225',3), +(1100,'颍上县',1093,'341226',3), +(1101,'界首市',1093,'341282',3), +(1102,'宿州市',1012,'341300',2), +(1103,'埇桥区',1102,'341302',3), +(1104,'砀山县',1102,'341321',3), +(1105,'萧县',1102,'341322',3), +(1106,'灵璧县',1102,'341323',3), +(1107,'泗县',1102,'341324',3), +(1108,'六安市',1012,'341500',2), +(1109,'金安区',1108,'341502',3), +(1110,'裕安区',1108,'341503',3), +(1111,'叶集区',1108,'341504',3), +(1112,'霍邱县',1108,'341522',3), +(1113,'舒城县',1108,'341523',3), +(1114,'金寨县',1108,'341524',3), +(1115,'霍山县',1108,'341525',3), +(1116,'亳州市',1012,'341600',2), +(1117,'谯城区',1116,'341602',3), +(1118,'涡阳县',1116,'341621',3), +(1119,'蒙城县',1116,'341622',3), +(1120,'利辛县',1116,'341623',3), +(1121,'池州市',1012,'341700',2), +(1122,'贵池区',1121,'341702',3), +(1123,'东至县',1121,'341721',3), +(1124,'石台县',1121,'341722',3), +(1125,'青阳县',1121,'341723',3), +(1126,'宣城市',1012,'341800',2), +(1127,'宣州区',1126,'341802',3), +(1128,'郎溪县',1126,'341821',3), +(1129,'泾县',1126,'341823',3), +(1130,'绩溪县',1126,'341824',3), +(1131,'旌德县',1126,'341825',3), +(1132,'宁国市',1126,'341881',3), +(1133,'广德市',1126,'341882',3), +(1134,'福建省',0,'350000',1), +(1135,'福州市',1134,'350100',2), +(1136,'鼓楼区',1135,'350102',3), +(1137,'台江区',1135,'350103',3), +(1138,'仓山区',1135,'350104',3), +(1139,'马尾区',1135,'350105',3), +(1140,'晋安区',1135,'350111',3), +(1141,'长乐区',1135,'350112',3), +(1142,'闽侯县',1135,'350121',3), +(1143,'连江县',1135,'350122',3), +(1144,'罗源县',1135,'350123',3), +(1145,'闽清县',1135,'350124',3), +(1146,'永泰县',1135,'350125',3), +(1147,'平潭县',1135,'350128',3), +(1148,'福清市',1135,'350181',3), +(1149,'厦门市',1134,'350200',2), +(1150,'思明区',1149,'350203',3), +(1151,'海沧区',1149,'350205',3), +(1152,'湖里区',1149,'350206',3), +(1153,'集美区',1149,'350211',3), +(1154,'同安区',1149,'350212',3), +(1155,'翔安区',1149,'350213',3), +(1156,'莆田市',1134,'350300',2), +(1157,'城厢区',1156,'350302',3), +(1158,'涵江区',1156,'350303',3), +(1159,'荔城区',1156,'350304',3), +(1160,'秀屿区',1156,'350305',3), +(1161,'仙游县',1156,'350322',3), +(1162,'三明市',1134,'350400',2), +(1163,'梅列区',1162,'350402',3), +(1164,'三元区',1162,'350403',3), +(1165,'明溪县',1162,'350421',3), +(1166,'清流县',1162,'350423',3), +(1167,'宁化县',1162,'350424',3), +(1168,'大田县',1162,'350425',3), +(1169,'尤溪县',1162,'350426',3), +(1170,'沙县',1162,'350427',3), +(1171,'将乐县',1162,'350428',3), +(1172,'泰宁县',1162,'350429',3), +(1173,'建宁县',1162,'350430',3), +(1174,'永安市',1162,'350481',3), +(1175,'泉州市',1134,'350500',2), +(1176,'鲤城区',1175,'350502',3), +(1177,'丰泽区',1175,'350503',3), +(1178,'洛江区',1175,'350504',3), +(1179,'泉港区',1175,'350505',3), +(1180,'惠安县',1175,'350521',3), +(1181,'安溪县',1175,'350524',3), +(1182,'永春县',1175,'350525',3), +(1183,'德化县',1175,'350526',3), +(1184,'金门县',1175,'350527',3), +(1185,'石狮市',1175,'350581',3), +(1186,'晋江市',1175,'350582',3), +(1187,'南安市',1175,'350583',3), +(1188,'漳州市',1134,'350600',2), +(1189,'芗城区',1188,'350602',3), +(1190,'龙文区',1188,'350603',3), +(1191,'云霄县',1188,'350622',3), +(1192,'漳浦县',1188,'350623',3), +(1193,'诏安县',1188,'350624',3), +(1194,'长泰县',1188,'350625',3), +(1195,'东山县',1188,'350626',3), +(1196,'南靖县',1188,'350627',3), +(1197,'平和县',1188,'350628',3), +(1198,'华安县',1188,'350629',3), +(1199,'龙海市',1188,'350681',3), +(1200,'南平市',1134,'350700',2), +(1201,'延平区',1200,'350702',3), +(1202,'建阳区',1200,'350703',3), +(1203,'顺昌县',1200,'350721',3), +(1204,'浦城县',1200,'350722',3), +(1205,'光泽县',1200,'350723',3), +(1206,'松溪县',1200,'350724',3), +(1207,'政和县',1200,'350725',3), +(1208,'邵武市',1200,'350781',3), +(1209,'武夷山市',1200,'350782',3), +(1210,'建瓯市',1200,'350783',3), +(1211,'龙岩市',1134,'350800',2), +(1212,'新罗区',1211,'350802',3), +(1213,'永定区',1211,'350803',3), +(1214,'长汀县',1211,'350821',3), +(1215,'上杭县',1211,'350823',3), +(1216,'武平县',1211,'350824',3), +(1217,'连城县',1211,'350825',3), +(1218,'漳平市',1211,'350881',3), +(1219,'宁德市',1134,'350900',2), +(1220,'蕉城区',1219,'350902',3), +(1221,'霞浦县',1219,'350921',3), +(1222,'古田县',1219,'350922',3), +(1223,'屏南县',1219,'350923',3), +(1224,'寿宁县',1219,'350924',3), +(1225,'周宁县',1219,'350925',3), +(1226,'柘荣县',1219,'350926',3), +(1227,'福安市',1219,'350981',3), +(1228,'福鼎市',1219,'350982',3), +(1229,'江西省',0,'360000',1), +(1230,'南昌市',1229,'360100',2), +(1231,'东湖区',1230,'360102',3), +(1232,'西湖区',1230,'360103',3), +(1233,'青云谱区',1230,'360104',3), +(1234,'青山湖区',1230,'360111',3), +(1235,'新建区',1230,'360112',3), +(1236,'红谷滩区',1230,'360113',3), +(1237,'南昌县',1230,'360121',3), +(1238,'安义县',1230,'360123',3), +(1239,'进贤县',1230,'360124',3), +(1240,'景德镇市',1229,'360200',2), +(1241,'昌江区',1240,'360202',3), +(1242,'珠山区',1240,'360203',3), +(1243,'浮梁县',1240,'360222',3), +(1244,'乐平市',1240,'360281',3), +(1245,'萍乡市',1229,'360300',2), +(1246,'安源区',1245,'360302',3), +(1247,'湘东区',1245,'360313',3), +(1248,'莲花县',1245,'360321',3), +(1249,'上栗县',1245,'360322',3), +(1250,'芦溪县',1245,'360323',3), +(1251,'九江市',1229,'360400',2), +(1252,'濂溪区',1251,'360402',3), +(1253,'浔阳区',1251,'360403',3), +(1254,'柴桑区',1251,'360404',3), +(1255,'武宁县',1251,'360423',3), +(1256,'修水县',1251,'360424',3), +(1257,'永修县',1251,'360425',3), +(1258,'德安县',1251,'360426',3), +(1259,'都昌县',1251,'360428',3), +(1260,'湖口县',1251,'360429',3), +(1261,'彭泽县',1251,'360430',3), +(1262,'瑞昌市',1251,'360481',3), +(1263,'共青城市',1251,'360482',3), +(1264,'庐山市',1251,'360483',3), +(1265,'新余市',1229,'360500',2), +(1266,'渝水区',1265,'360502',3), +(1267,'分宜县',1265,'360521',3), +(1268,'鹰潭市',1229,'360600',2), +(1269,'月湖区',1268,'360602',3), +(1270,'余江区',1268,'360603',3), +(1271,'贵溪市',1268,'360681',3), +(1272,'赣州市',1229,'360700',2), +(1273,'章贡区',1272,'360702',3), +(1274,'南康区',1272,'360703',3), +(1275,'赣县区',1272,'360704',3), +(1276,'信丰县',1272,'360722',3), +(1277,'大余县',1272,'360723',3), +(1278,'上犹县',1272,'360724',3), +(1279,'崇义县',1272,'360725',3), +(1280,'安远县',1272,'360726',3), +(1281,'龙南县',1272,'360727',3), +(1282,'定南县',1272,'360728',3), +(1283,'全南县',1272,'360729',3), +(1284,'宁都县',1272,'360730',3), +(1285,'于都县',1272,'360731',3), +(1286,'兴国县',1272,'360732',3), +(1287,'会昌县',1272,'360733',3), +(1288,'寻乌县',1272,'360734',3), +(1289,'石城县',1272,'360735',3), +(1290,'瑞金市',1272,'360781',3), +(1291,'吉安市',1229,'360800',2), +(1292,'吉州区',1291,'360802',3), +(1293,'青原区',1291,'360803',3), +(1294,'吉安县',1291,'360821',3), +(1295,'吉水县',1291,'360822',3), +(1296,'峡江县',1291,'360823',3), +(1297,'新干县',1291,'360824',3), +(1298,'永丰县',1291,'360825',3), +(1299,'泰和县',1291,'360826',3), +(1300,'遂川县',1291,'360827',3), +(1301,'万安县',1291,'360828',3), +(1302,'安福县',1291,'360829',3), +(1303,'永新县',1291,'360830',3), +(1304,'井冈山市',1291,'360881',3), +(1305,'宜春市',1229,'360900',2), +(1306,'袁州区',1305,'360902',3), +(1307,'奉新县',1305,'360921',3), +(1308,'万载县',1305,'360922',3), +(1309,'上高县',1305,'360923',3), +(1310,'宜丰县',1305,'360924',3), +(1311,'靖安县',1305,'360925',3), +(1312,'铜鼓县',1305,'360926',3), +(1313,'丰城市',1305,'360981',3), +(1314,'樟树市',1305,'360982',3), +(1315,'高安市',1305,'360983',3), +(1316,'抚州市',1229,'361000',2), +(1317,'临川区',1316,'361002',3), +(1318,'东乡区',1316,'361003',3), +(1319,'南城县',1316,'361021',3), +(1320,'黎川县',1316,'361022',3), +(1321,'南丰县',1316,'361023',3), +(1322,'崇仁县',1316,'361024',3), +(1323,'乐安县',1316,'361025',3), +(1324,'宜黄县',1316,'361026',3), +(1325,'金溪县',1316,'361027',3), +(1326,'资溪县',1316,'361028',3), +(1327,'广昌县',1316,'361030',3), +(1328,'上饶市',1229,'361100',2), +(1329,'信州区',1328,'361102',3), +(1330,'广丰区',1328,'361103',3), +(1331,'广信区',1328,'361104',3), +(1332,'玉山县',1328,'361123',3), +(1333,'铅山县',1328,'361124',3), +(1334,'横峰县',1328,'361125',3), +(1335,'弋阳县',1328,'361126',3), +(1336,'余干县',1328,'361127',3), +(1337,'鄱阳县',1328,'361128',3), +(1338,'万年县',1328,'361129',3), +(1339,'婺源县',1328,'361130',3), +(1340,'德兴市',1328,'361181',3), +(1341,'山东省',0,'370000',1), +(1342,'济南市',1341,'370100',2), +(1343,'历下区',1342,'370102',3), +(1344,'市中区',1342,'370103',3), +(1345,'槐荫区',1342,'370104',3), +(1346,'天桥区',1342,'370105',3), +(1347,'历城区',1342,'370112',3), +(1348,'长清区',1342,'370113',3), +(1349,'章丘区',1342,'370114',3), +(1350,'济阳区',1342,'370115',3), +(1351,'莱芜区',1342,'370116',3), +(1352,'钢城区',1342,'370117',3), +(1353,'平阴县',1342,'370124',3), +(1354,'商河县',1342,'370126',3), +(1355,'青岛市',1341,'370200',2), +(1356,'市南区',1355,'370202',3), +(1357,'市北区',1355,'370203',3), +(1358,'黄岛区',1355,'370211',3), +(1359,'崂山区',1355,'370212',3), +(1360,'李沧区',1355,'370213',3), +(1361,'城阳区',1355,'370214',3), +(1362,'即墨区',1355,'370215',3), +(1363,'胶州市',1355,'370281',3), +(1364,'平度市',1355,'370283',3), +(1365,'莱西市',1355,'370285',3), +(1366,'淄博市',1341,'370300',2), +(1367,'淄川区',1366,'370302',3), +(1368,'张店区',1366,'370303',3), +(1369,'博山区',1366,'370304',3), +(1370,'临淄区',1366,'370305',3), +(1371,'周村区',1366,'370306',3), +(1372,'桓台县',1366,'370321',3), +(1373,'高青县',1366,'370322',3), +(1374,'沂源县',1366,'370323',3), +(1375,'枣庄市',1341,'370400',2), +(1376,'市中区',1375,'370402',3), +(1377,'薛城区',1375,'370403',3), +(1378,'峄城区',1375,'370404',3), +(1379,'台儿庄区',1375,'370405',3), +(1380,'山亭区',1375,'370406',3), +(1381,'滕州市',1375,'370481',3), +(1382,'东营市',1341,'370500',2), +(1383,'东营区',1382,'370502',3), +(1384,'河口区',1382,'370503',3), +(1385,'垦利区',1382,'370505',3), +(1386,'利津县',1382,'370522',3), +(1387,'广饶县',1382,'370523',3), +(1388,'烟台市',1341,'370600',2), +(1389,'芝罘区',1388,'370602',3), +(1390,'福山区',1388,'370611',3), +(1391,'牟平区',1388,'370612',3), +(1392,'莱山区',1388,'370613',3), +(1393,'长岛县',1388,'370634',3), +(1394,'龙口市',1388,'370681',3), +(1395,'莱阳市',1388,'370682',3), +(1396,'莱州市',1388,'370683',3), +(1397,'蓬莱市',1388,'370684',3), +(1398,'招远市',1388,'370685',3), +(1399,'栖霞市',1388,'370686',3), +(1400,'海阳市',1388,'370687',3), +(1401,'潍坊市',1341,'370700',2), +(1402,'潍城区',1401,'370702',3), +(1403,'寒亭区',1401,'370703',3), +(1404,'坊子区',1401,'370704',3), +(1405,'奎文区',1401,'370705',3), +(1406,'临朐县',1401,'370724',3), +(1407,'昌乐县',1401,'370725',3), +(1408,'青州市',1401,'370781',3), +(1409,'诸城市',1401,'370782',3), +(1410,'寿光市',1401,'370783',3), +(1411,'安丘市',1401,'370784',3), +(1412,'高密市',1401,'370785',3), +(1413,'昌邑市',1401,'370786',3), +(1414,'济宁市',1341,'370800',2), +(1415,'任城区',1414,'370811',3), +(1416,'兖州区',1414,'370812',3), +(1417,'微山县',1414,'370826',3), +(1418,'鱼台县',1414,'370827',3), +(1419,'金乡县',1414,'370828',3), +(1420,'嘉祥县',1414,'370829',3), +(1421,'汶上县',1414,'370830',3), +(1422,'泗水县',1414,'370831',3), +(1423,'梁山县',1414,'370832',3), +(1424,'曲阜市',1414,'370881',3), +(1425,'邹城市',1414,'370883',3), +(1426,'泰安市',1341,'370900',2), +(1427,'泰山区',1426,'370902',3), +(1428,'岱岳区',1426,'370911',3), +(1429,'宁阳县',1426,'370921',3), +(1430,'东平县',1426,'370923',3), +(1431,'新泰市',1426,'370982',3), +(1432,'肥城市',1426,'370983',3), +(1433,'威海市',1341,'371000',2), +(1434,'环翠区',1433,'371002',3), +(1435,'文登区',1433,'371003',3), +(1436,'荣成市',1433,'371082',3), +(1437,'乳山市',1433,'371083',3), +(1438,'日照市',1341,'371100',2), +(1439,'东港区',1438,'371102',3), +(1440,'岚山区',1438,'371103',3), +(1441,'五莲县',1438,'371121',3), +(1442,'莒县',1438,'371122',3), +(1443,'临沂市',1341,'371300',2), +(1444,'兰山区',1443,'371302',3), +(1445,'罗庄区',1443,'371311',3), +(1446,'河东区',1443,'371312',3), +(1447,'沂南县',1443,'371321',3), +(1448,'郯城县',1443,'371322',3), +(1449,'沂水县',1443,'371323',3), +(1450,'兰陵县',1443,'371324',3), +(1451,'费县',1443,'371325',3), +(1452,'平邑县',1443,'371326',3), +(1453,'莒南县',1443,'371327',3), +(1454,'蒙阴县',1443,'371328',3), +(1455,'临沭县',1443,'371329',3), +(1456,'德州市',1341,'371400',2), +(1457,'德城区',1456,'371402',3), +(1458,'陵城区',1456,'371403',3), +(1459,'宁津县',1456,'371422',3), +(1460,'庆云县',1456,'371423',3), +(1461,'临邑县',1456,'371424',3), +(1462,'齐河县',1456,'371425',3), +(1463,'平原县',1456,'371426',3), +(1464,'夏津县',1456,'371427',3), +(1465,'武城县',1456,'371428',3), +(1466,'乐陵市',1456,'371481',3), +(1467,'禹城市',1456,'371482',3), +(1468,'聊城市',1341,'371500',2), +(1469,'东昌府区',1468,'371502',3), +(1470,'茌平区',1468,'371503',3), +(1471,'阳谷县',1468,'371521',3), +(1472,'莘县',1468,'371522',3), +(1473,'东阿县',1468,'371524',3), +(1474,'冠县',1468,'371525',3), +(1475,'高唐县',1468,'371526',3), +(1476,'临清市',1468,'371581',3), +(1477,'滨州市',1341,'371600',2), +(1478,'滨城区',1477,'371602',3), +(1479,'沾化区',1477,'371603',3), +(1480,'惠民县',1477,'371621',3), +(1481,'阳信县',1477,'371622',3), +(1482,'无棣县',1477,'371623',3), +(1483,'博兴县',1477,'371625',3), +(1484,'邹平市',1477,'371681',3), +(1485,'菏泽市',1341,'371700',2), +(1486,'牡丹区',1485,'371702',3), +(1487,'定陶区',1485,'371703',3), +(1488,'曹县',1485,'371721',3), +(1489,'单县',1485,'371722',3), +(1490,'成武县',1485,'371723',3), +(1491,'巨野县',1485,'371724',3), +(1492,'郓城县',1485,'371725',3), +(1493,'鄄城县',1485,'371726',3), +(1494,'东明县',1485,'371728',3), +(1495,'河南省',0,'410000',1), +(1496,'郑州市',1495,'410100',2), +(1497,'中原区',1496,'410102',3), +(1498,'二七区',1496,'410103',3), +(1499,'管城回族区',1496,'410104',3), +(1500,'金水区',1496,'410105',3), +(1501,'上街区',1496,'410106',3), +(1502,'惠济区',1496,'410108',3), +(1503,'中牟县',1496,'410122',3), +(1504,'巩义市',1496,'410181',3), +(1505,'荥阳市',1496,'410182',3), +(1506,'新密市',1496,'410183',3), +(1507,'新郑市',1496,'410184',3), +(1508,'登封市',1496,'410185',3), +(1509,'开封市',1495,'410200',2), +(1510,'龙亭区',1509,'410202',3), +(1511,'顺河回族区',1509,'410203',3), +(1512,'鼓楼区',1509,'410204',3), +(1513,'禹王台区',1509,'410205',3), +(1514,'祥符区',1509,'410212',3), +(1515,'杞县',1509,'410221',3), +(1516,'通许县',1509,'410222',3), +(1517,'尉氏县',1509,'410223',3), +(1518,'兰考县',1509,'410225',3), +(1519,'洛阳市',1495,'410300',2), +(1520,'老城区',1519,'410302',3), +(1521,'西工区',1519,'410303',3), +(1522,'瀍河回族区',1519,'410304',3), +(1523,'涧西区',1519,'410305',3), +(1524,'吉利区',1519,'410306',3), +(1525,'洛龙区',1519,'410311',3), +(1526,'孟津县',1519,'410322',3), +(1527,'新安县',1519,'410323',3), +(1528,'栾川县',1519,'410324',3), +(1529,'嵩县',1519,'410325',3), +(1530,'汝阳县',1519,'410326',3), +(1531,'宜阳县',1519,'410327',3), +(1532,'洛宁县',1519,'410328',3), +(1533,'伊川县',1519,'410329',3), +(1534,'偃师市',1519,'410381',3), +(1535,'平顶山市',1495,'410400',2), +(1536,'新华区',1535,'410402',3), +(1537,'卫东区',1535,'410403',3), +(1538,'石龙区',1535,'410404',3), +(1539,'湛河区',1535,'410411',3), +(1540,'宝丰县',1535,'410421',3), +(1541,'叶县',1535,'410422',3), +(1542,'鲁山县',1535,'410423',3), +(1543,'郏县',1535,'410425',3), +(1544,'舞钢市',1535,'410481',3), +(1545,'汝州市',1535,'410482',3), +(1546,'安阳市',1495,'410500',2), +(1547,'文峰区',1546,'410502',3), +(1548,'北关区',1546,'410503',3), +(1549,'殷都区',1546,'410505',3), +(1550,'龙安区',1546,'410506',3), +(1551,'安阳县',1546,'410522',3), +(1552,'汤阴县',1546,'410523',3), +(1553,'滑县',1546,'410526',3), +(1554,'内黄县',1546,'410527',3), +(1555,'林州市',1546,'410581',3), +(1556,'鹤壁市',1495,'410600',2), +(1557,'鹤山区',1556,'410602',3), +(1558,'山城区',1556,'410603',3), +(1559,'淇滨区',1556,'410611',3), +(1560,'浚县',1556,'410621',3), +(1561,'淇县',1556,'410622',3), +(1562,'新乡市',1495,'410700',2), +(1563,'红旗区',1562,'410702',3), +(1564,'卫滨区',1562,'410703',3), +(1565,'凤泉区',1562,'410704',3), +(1566,'牧野区',1562,'410711',3), +(1567,'新乡县',1562,'410721',3), +(1568,'获嘉县',1562,'410724',3), +(1569,'原阳县',1562,'410725',3), +(1570,'延津县',1562,'410726',3), +(1571,'封丘县',1562,'410727',3), +(1572,'卫辉市',1562,'410781',3), +(1573,'辉县市',1562,'410782',3), +(1574,'长垣市',1562,'410783',3), +(1575,'焦作市',1495,'410800',2), +(1576,'解放区',1575,'410802',3), +(1577,'中站区',1575,'410803',3), +(1578,'马村区',1575,'410804',3), +(1579,'山阳区',1575,'410811',3), +(1580,'修武县',1575,'410821',3), +(1581,'博爱县',1575,'410822',3), +(1582,'武陟县',1575,'410823',3), +(1583,'温县',1575,'410825',3), +(1584,'沁阳市',1575,'410882',3), +(1585,'孟州市',1575,'410883',3), +(1586,'濮阳市',1495,'410900',2), +(1587,'华龙区',1586,'410902',3), +(1588,'清丰县',1586,'410922',3), +(1589,'南乐县',1586,'410923',3), +(1590,'范县',1586,'410926',3), +(1591,'台前县',1586,'410927',3), +(1592,'濮阳县',1586,'410928',3), +(1593,'许昌市',1495,'411000',2), +(1594,'魏都区',1593,'411002',3), +(1595,'建安区',1593,'411003',3), +(1596,'鄢陵县',1593,'411024',3), +(1597,'襄城县',1593,'411025',3), +(1598,'禹州市',1593,'411081',3), +(1599,'长葛市',1593,'411082',3), +(1600,'漯河市',1495,'411100',2), +(1601,'源汇区',1600,'411102',3), +(1602,'郾城区',1600,'411103',3), +(1603,'召陵区',1600,'411104',3), +(1604,'舞阳县',1600,'411121',3), +(1605,'临颍县',1600,'411122',3), +(1606,'三门峡市',1495,'411200',2), +(1607,'湖滨区',1606,'411202',3), +(1608,'陕州区',1606,'411203',3), +(1609,'渑池县',1606,'411221',3), +(1610,'卢氏县',1606,'411224',3), +(1611,'义马市',1606,'411281',3), +(1612,'灵宝市',1606,'411282',3), +(1613,'南阳市',1495,'411300',2), +(1614,'宛城区',1613,'411302',3), +(1615,'卧龙区',1613,'411303',3), +(1616,'南召县',1613,'411321',3), +(1617,'方城县',1613,'411322',3), +(1618,'西峡县',1613,'411323',3), +(1619,'镇平县',1613,'411324',3), +(1620,'内乡县',1613,'411325',3), +(1621,'淅川县',1613,'411326',3), +(1622,'社旗县',1613,'411327',3), +(1623,'唐河县',1613,'411328',3), +(1624,'新野县',1613,'411329',3), +(1625,'桐柏县',1613,'411330',3), +(1626,'邓州市',1613,'411381',3), +(1627,'商丘市',1495,'411400',2), +(1628,'梁园区',1627,'411402',3), +(1629,'睢阳区',1627,'411403',3), +(1630,'民权县',1627,'411421',3), +(1631,'睢县',1627,'411422',3), +(1632,'宁陵县',1627,'411423',3), +(1633,'柘城县',1627,'411424',3), +(1634,'虞城县',1627,'411425',3), +(1635,'夏邑县',1627,'411426',3), +(1636,'永城市',1627,'411481',3), +(1637,'信阳市',1495,'411500',2), +(1638,'浉河区',1637,'411502',3), +(1639,'平桥区',1637,'411503',3), +(1640,'罗山县',1637,'411521',3), +(1641,'光山县',1637,'411522',3), +(1642,'新县',1637,'411523',3), +(1643,'商城县',1637,'411524',3), +(1644,'固始县',1637,'411525',3), +(1645,'潢川县',1637,'411526',3), +(1646,'淮滨县',1637,'411527',3), +(1647,'息县',1637,'411528',3), +(1648,'周口市',1495,'411600',2), +(1649,'川汇区',1648,'411602',3), +(1650,'淮阳区',1648,'411603',3), +(1651,'扶沟县',1648,'411621',3), +(1652,'西华县',1648,'411622',3), +(1653,'商水县',1648,'411623',3), +(1654,'沈丘县',1648,'411624',3), +(1655,'郸城县',1648,'411625',3), +(1656,'太康县',1648,'411627',3), +(1657,'鹿邑县',1648,'411628',3), +(1658,'项城市',1648,'411681',3), +(1659,'驻马店市',1495,'411700',2), +(1660,'驿城区',1659,'411702',3), +(1661,'西平县',1659,'411721',3), +(1662,'上蔡县',1659,'411722',3), +(1663,'平舆县',1659,'411723',3), +(1664,'正阳县',1659,'411724',3), +(1665,'确山县',1659,'411725',3), +(1666,'泌阳县',1659,'411726',3), +(1667,'汝南县',1659,'411727',3), +(1668,'遂平县',1659,'411728',3), +(1669,'新蔡县',1659,'411729',3), +(1670,'济源市',1495,'419001',3), +(1671,'湖北省',0,'420000',1), +(1672,'武汉市',1671,'420100',2), +(1673,'江岸区',1672,'420102',3), +(1674,'江汉区',1672,'420103',3), +(1675,'硚口区',1672,'420104',3), +(1676,'汉阳区',1672,'420105',3), +(1677,'武昌区',1672,'420106',3), +(1678,'青山区',1672,'420107',3), +(1679,'洪山区',1672,'420111',3), +(1680,'东西湖区',1672,'420112',3), +(1681,'汉南区',1672,'420113',3), +(1682,'蔡甸区',1672,'420114',3), +(1683,'江夏区',1672,'420115',3), +(1684,'黄陂区',1672,'420116',3), +(1685,'新洲区',1672,'420117',3), +(1686,'黄石市',1671,'420200',2), +(1687,'黄石港区',1686,'420202',3), +(1688,'西塞山区',1686,'420203',3), +(1689,'下陆区',1686,'420204',3), +(1690,'铁山区',1686,'420205',3), +(1691,'阳新县',1686,'420222',3), +(1692,'大冶市',1686,'420281',3), +(1693,'十堰市',1671,'420300',2), +(1694,'茅箭区',1693,'420302',3), +(1695,'张湾区',1693,'420303',3), +(1696,'郧阳区',1693,'420304',3), +(1697,'郧西县',1693,'420322',3), +(1698,'竹山县',1693,'420323',3), +(1699,'竹溪县',1693,'420324',3), +(1700,'房县',1693,'420325',3), +(1701,'丹江口市',1693,'420381',3), +(1702,'宜昌市',1671,'420500',2), +(1703,'西陵区',1702,'420502',3), +(1704,'伍家岗区',1702,'420503',3), +(1705,'点军区',1702,'420504',3), +(1706,'猇亭区',1702,'420505',3), +(1707,'夷陵区',1702,'420506',3), +(1708,'远安县',1702,'420525',3), +(1709,'兴山县',1702,'420526',3), +(1710,'秭归县',1702,'420527',3), +(1711,'长阳土家族自治县',1702,'420528',3), +(1712,'五峰土家族自治县',1702,'420529',3), +(1713,'宜都市',1702,'420581',3), +(1714,'当阳市',1702,'420582',3), +(1715,'枝江市',1702,'420583',3), +(1716,'襄阳市',1671,'420600',2), +(1717,'襄城区',1716,'420602',3), +(1718,'樊城区',1716,'420606',3), +(1719,'襄州区',1716,'420607',3), +(1720,'南漳县',1716,'420624',3), +(1721,'谷城县',1716,'420625',3), +(1722,'保康县',1716,'420626',3), +(1723,'老河口市',1716,'420682',3), +(1724,'枣阳市',1716,'420683',3), +(1725,'宜城市',1716,'420684',3), +(1726,'鄂州市',1671,'420700',2), +(1727,'梁子湖区',1726,'420702',3), +(1728,'华容区',1726,'420703',3), +(1729,'鄂城区',1726,'420704',3), +(1730,'荆门市',1671,'420800',2), +(1731,'东宝区',1730,'420802',3), +(1732,'掇刀区',1730,'420804',3), +(1733,'沙洋县',1730,'420822',3), +(1734,'钟祥市',1730,'420881',3), +(1735,'京山市',1730,'420882',3), +(1736,'孝感市',1671,'420900',2), +(1737,'孝南区',1736,'420902',3), +(1738,'孝昌县',1736,'420921',3), +(1739,'大悟县',1736,'420922',3), +(1740,'云梦县',1736,'420923',3), +(1741,'应城市',1736,'420981',3), +(1742,'安陆市',1736,'420982',3), +(1743,'汉川市',1736,'420984',3), +(1744,'荆州市',1671,'421000',2), +(1745,'沙市区',1744,'421002',3), +(1746,'荆州区',1744,'421003',3), +(1747,'公安县',1744,'421022',3), +(1748,'监利县',1744,'421023',3), +(1749,'江陵县',1744,'421024',3), +(1750,'石首市',1744,'421081',3), +(1751,'洪湖市',1744,'421083',3), +(1752,'松滋市',1744,'421087',3), +(1753,'黄冈市',1671,'421100',2), +(1754,'黄州区',1753,'421102',3), +(1755,'团风县',1753,'421121',3), +(1756,'红安县',1753,'421122',3), +(1757,'罗田县',1753,'421123',3), +(1758,'英山县',1753,'421124',3), +(1759,'浠水县',1753,'421125',3), +(1760,'蕲春县',1753,'421126',3), +(1761,'黄梅县',1753,'421127',3), +(1762,'麻城市',1753,'421181',3), +(1763,'武穴市',1753,'421182',3), +(1764,'咸宁市',1671,'421200',2), +(1765,'咸安区',1764,'421202',3), +(1766,'嘉鱼县',1764,'421221',3), +(1767,'通城县',1764,'421222',3), +(1768,'崇阳县',1764,'421223',3), +(1769,'通山县',1764,'421224',3), +(1770,'赤壁市',1764,'421281',3), +(1771,'随州市',1671,'421300',2), +(1772,'曾都区',1771,'421303',3), +(1773,'随县',1771,'421321',3), +(1774,'广水市',1771,'421381',3), +(1775,'恩施土家族苗族自治州',1671,'422800',2), +(1776,'恩施市',1775,'422801',3), +(1777,'利川市',1775,'422802',3), +(1778,'建始县',1775,'422822',3), +(1779,'巴东县',1775,'422823',3), +(1780,'宣恩县',1775,'422825',3), +(1781,'咸丰县',1775,'422826',3), +(1782,'来凤县',1775,'422827',3), +(1783,'鹤峰县',1775,'422828',3), +(1784,'仙桃市',1671,'429004',3), +(1785,'潜江市',1671,'429005',3), +(1786,'天门市',1671,'429006',3), +(1787,'神农架林区',1671,'429021',3), +(1788,'湖南省',0,'430000',1), +(1789,'长沙市',1788,'430100',2), +(1790,'芙蓉区',1789,'430102',3), +(1791,'天心区',1789,'430103',3), +(1792,'岳麓区',1789,'430104',3), +(1793,'开福区',1789,'430105',3), +(1794,'雨花区',1789,'430111',3), +(1795,'望城区',1789,'430112',3), +(1796,'长沙县',1789,'430121',3), +(1797,'浏阳市',1789,'430181',3), +(1798,'宁乡市',1789,'430182',3), +(1799,'株洲市',1788,'430200',2), +(1800,'荷塘区',1799,'430202',3), +(1801,'芦淞区',1799,'430203',3), +(1802,'石峰区',1799,'430204',3), +(1803,'天元区',1799,'430211',3), +(1804,'渌口区',1799,'430212',3), +(1805,'攸县',1799,'430223',3), +(1806,'茶陵县',1799,'430224',3), +(1807,'炎陵县',1799,'430225',3), +(1808,'醴陵市',1799,'430281',3), +(1809,'湘潭市',1788,'430300',2), +(1810,'雨湖区',1809,'430302',3), +(1811,'岳塘区',1809,'430304',3), +(1812,'湘潭县',1809,'430321',3), +(1813,'湘乡市',1809,'430381',3), +(1814,'韶山市',1809,'430382',3), +(1815,'衡阳市',1788,'430400',2), +(1816,'珠晖区',1815,'430405',3), +(1817,'雁峰区',1815,'430406',3), +(1818,'石鼓区',1815,'430407',3), +(1819,'蒸湘区',1815,'430408',3), +(1820,'南岳区',1815,'430412',3), +(1821,'衡阳县',1815,'430421',3), +(1822,'衡南县',1815,'430422',3), +(1823,'衡山县',1815,'430423',3), +(1824,'衡东县',1815,'430424',3), +(1825,'祁东县',1815,'430426',3), +(1826,'耒阳市',1815,'430481',3), +(1827,'常宁市',1815,'430482',3), +(1828,'邵阳市',1788,'430500',2), +(1829,'双清区',1828,'430502',3), +(1830,'大祥区',1828,'430503',3), +(1831,'北塔区',1828,'430511',3), +(1832,'新邵县',1828,'430522',3), +(1833,'邵阳县',1828,'430523',3), +(1834,'隆回县',1828,'430524',3), +(1835,'洞口县',1828,'430525',3), +(1836,'绥宁县',1828,'430527',3), +(1837,'新宁县',1828,'430528',3), +(1838,'城步苗族自治县',1828,'430529',3), +(1839,'武冈市',1828,'430581',3), +(1840,'邵东市',1828,'430582',3), +(1841,'岳阳市',1788,'430600',2), +(1842,'岳阳楼区',1841,'430602',3), +(1843,'云溪区',1841,'430603',3), +(1844,'君山区',1841,'430611',3), +(1845,'岳阳县',1841,'430621',3), +(1846,'华容县',1841,'430623',3), +(1847,'湘阴县',1841,'430624',3), +(1848,'平江县',1841,'430626',3), +(1849,'汨罗市',1841,'430681',3), +(1850,'临湘市',1841,'430682',3), +(1851,'常德市',1788,'430700',2), +(1852,'武陵区',1851,'430702',3), +(1853,'鼎城区',1851,'430703',3), +(1854,'安乡县',1851,'430721',3), +(1855,'汉寿县',1851,'430722',3), +(1856,'澧县',1851,'430723',3), +(1857,'临澧县',1851,'430724',3), +(1858,'桃源县',1851,'430725',3), +(1859,'石门县',1851,'430726',3), +(1860,'津市市',1851,'430781',3), +(1861,'张家界市',1788,'430800',2), +(1862,'永定区',1861,'430802',3), +(1863,'武陵源区',1861,'430811',3), +(1864,'慈利县',1861,'430821',3), +(1865,'桑植县',1861,'430822',3), +(1866,'益阳市',1788,'430900',2), +(1867,'资阳区',1866,'430902',3), +(1868,'赫山区',1866,'430903',3), +(1869,'南县',1866,'430921',3), +(1870,'桃江县',1866,'430922',3), +(1871,'安化县',1866,'430923',3), +(1872,'沅江市',1866,'430981',3), +(1873,'郴州市',1788,'431000',2), +(1874,'北湖区',1873,'431002',3), +(1875,'苏仙区',1873,'431003',3), +(1876,'桂阳县',1873,'431021',3), +(1877,'宜章县',1873,'431022',3), +(1878,'永兴县',1873,'431023',3), +(1879,'嘉禾县',1873,'431024',3), +(1880,'临武县',1873,'431025',3), +(1881,'汝城县',1873,'431026',3), +(1882,'桂东县',1873,'431027',3), +(1883,'安仁县',1873,'431028',3), +(1884,'资兴市',1873,'431081',3), +(1885,'永州市',1788,'431100',2), +(1886,'零陵区',1885,'431102',3), +(1887,'冷水滩区',1885,'431103',3), +(1888,'祁阳县',1885,'431121',3), +(1889,'东安县',1885,'431122',3), +(1890,'双牌县',1885,'431123',3), +(1891,'道县',1885,'431124',3), +(1892,'江永县',1885,'431125',3), +(1893,'宁远县',1885,'431126',3), +(1894,'蓝山县',1885,'431127',3), +(1895,'新田县',1885,'431128',3), +(1896,'江华瑶族自治县',1885,'431129',3), +(1897,'怀化市',1788,'431200',2), +(1898,'鹤城区',1897,'431202',3), +(1899,'中方县',1897,'431221',3), +(1900,'沅陵县',1897,'431222',3), +(1901,'辰溪县',1897,'431223',3), +(1902,'溆浦县',1897,'431224',3), +(1903,'会同县',1897,'431225',3), +(1904,'麻阳苗族自治县',1897,'431226',3), +(1905,'新晃侗族自治县',1897,'431227',3), +(1906,'芷江侗族自治县',1897,'431228',3), +(1907,'靖州苗族侗族自治县',1897,'431229',3), +(1908,'通道侗族自治县',1897,'431230',3), +(1909,'洪江市',1897,'431281',3), +(1910,'娄底市',1788,'431300',2), +(1911,'娄星区',1910,'431302',3), +(1912,'双峰县',1910,'431321',3), +(1913,'新化县',1910,'431322',3), +(1914,'冷水江市',1910,'431381',3), +(1915,'涟源市',1910,'431382',3), +(1916,'湘西土家族苗族自治州',1788,'433100',2), +(1917,'吉首市',1916,'433101',3), +(1918,'泸溪县',1916,'433122',3), +(1919,'凤凰县',1916,'433123',3), +(1920,'花垣县',1916,'433124',3), +(1921,'保靖县',1916,'433125',3), +(1922,'古丈县',1916,'433126',3), +(1923,'永顺县',1916,'433127',3), +(1924,'龙山县',1916,'433130',3), +(1925,'广东省',0,'440000',1), +(1926,'广州市',1925,'440100',2), +(1927,'荔湾区',1926,'440103',3), +(1928,'越秀区',1926,'440104',3), +(1929,'海珠区',1926,'440105',3), +(1930,'天河区',1926,'440106',3), +(1931,'白云区',1926,'440111',3), +(1932,'黄埔区',1926,'440112',3), +(1933,'番禺区',1926,'440113',3), +(1934,'花都区',1926,'440114',3), +(1935,'南沙区',1926,'440115',3), +(1936,'从化区',1926,'440117',3), +(1937,'增城区',1926,'440118',3), +(1938,'韶关市',1925,'440200',2), +(1939,'武江区',1938,'440203',3), +(1940,'浈江区',1938,'440204',3), +(1941,'曲江区',1938,'440205',3), +(1942,'始兴县',1938,'440222',3), +(1943,'仁化县',1938,'440224',3), +(1944,'翁源县',1938,'440229',3), +(1945,'乳源瑶族自治县',1938,'440232',3), +(1946,'新丰县',1938,'440233',3), +(1947,'乐昌市',1938,'440281',3), +(1948,'南雄市',1938,'440282',3), +(1949,'深圳市',1925,'440300',2), +(1950,'罗湖区',1949,'440303',3), +(1951,'福田区',1949,'440304',3), +(1952,'南山区',1949,'440305',3), +(1953,'宝安区',1949,'440306',3), +(1954,'龙岗区',1949,'440307',3), +(1955,'盐田区',1949,'440308',3), +(1956,'龙华区',1949,'440309',3), +(1957,'坪山区',1949,'440310',3), +(1958,'光明区',1949,'440311',3), +(1959,'珠海市',1925,'440400',2), +(1960,'香洲区',1959,'440402',3), +(1961,'斗门区',1959,'440403',3), +(1962,'金湾区',1959,'440404',3), +(1963,'汕头市',1925,'440500',2), +(1964,'龙湖区',1963,'440507',3), +(1965,'金平区',1963,'440511',3), +(1966,'濠江区',1963,'440512',3), +(1967,'潮阳区',1963,'440513',3), +(1968,'潮南区',1963,'440514',3), +(1969,'澄海区',1963,'440515',3), +(1970,'南澳县',1963,'440523',3), +(1971,'佛山市',1925,'440600',2), +(1972,'禅城区',1971,'440604',3), +(1973,'南海区',1971,'440605',3), +(1974,'顺德区',1971,'440606',3), +(1975,'三水区',1971,'440607',3), +(1976,'高明区',1971,'440608',3), +(1977,'江门市',1925,'440700',2), +(1978,'蓬江区',1977,'440703',3), +(1979,'江海区',1977,'440704',3), +(1980,'新会区',1977,'440705',3), +(1981,'台山市',1977,'440781',3), +(1982,'开平市',1977,'440783',3), +(1983,'鹤山市',1977,'440784',3), +(1984,'恩平市',1977,'440785',3), +(1985,'湛江市',1925,'440800',2), +(1986,'赤坎区',1985,'440802',3), +(1987,'霞山区',1985,'440803',3), +(1988,'坡头区',1985,'440804',3), +(1989,'麻章区',1985,'440811',3), +(1990,'遂溪县',1985,'440823',3), +(1991,'徐闻县',1985,'440825',3), +(1992,'廉江市',1985,'440881',3), +(1993,'雷州市',1985,'440882',3), +(1994,'吴川市',1985,'440883',3), +(1995,'茂名市',1925,'440900',2), +(1996,'茂南区',1995,'440902',3), +(1997,'电白区',1995,'440904',3), +(1998,'高州市',1995,'440981',3), +(1999,'化州市',1995,'440982',3), +(2000,'信宜市',1995,'440983',3), +(2001,'肇庆市',1925,'441200',2), +(2002,'端州区',2001,'441202',3), +(2003,'鼎湖区',2001,'441203',3), +(2004,'高要区',2001,'441204',3), +(2005,'广宁县',2001,'441223',3), +(2006,'怀集县',2001,'441224',3), +(2007,'封开县',2001,'441225',3), +(2008,'德庆县',2001,'441226',3), +(2009,'四会市',2001,'441284',3), +(2010,'惠州市',1925,'441300',2), +(2011,'惠城区',2010,'441302',3), +(2012,'惠阳区',2010,'441303',3), +(2013,'博罗县',2010,'441322',3), +(2014,'惠东县',2010,'441323',3), +(2015,'龙门县',2010,'441324',3), +(2016,'梅州市',1925,'441400',2), +(2017,'梅江区',2016,'441402',3), +(2018,'梅县区',2016,'441403',3), +(2019,'大埔县',2016,'441422',3), +(2020,'丰顺县',2016,'441423',3), +(2021,'五华县',2016,'441424',3), +(2022,'平远县',2016,'441426',3), +(2023,'蕉岭县',2016,'441427',3), +(2024,'兴宁市',2016,'441481',3), +(2025,'汕尾市',1925,'441500',2), +(2026,'城区',2025,'441502',3), +(2027,'海丰县',2025,'441521',3), +(2028,'陆河县',2025,'441523',3), +(2029,'陆丰市',2025,'441581',3), +(2030,'河源市',1925,'441600',2), +(2031,'源城区',2030,'441602',3), +(2032,'紫金县',2030,'441621',3), +(2033,'龙川县',2030,'441622',3), +(2034,'连平县',2030,'441623',3), +(2035,'和平县',2030,'441624',3), +(2036,'东源县',2030,'441625',3), +(2037,'阳江市',1925,'441700',2), +(2038,'江城区',2037,'441702',3), +(2039,'阳东区',2037,'441704',3), +(2040,'阳西县',2037,'441721',3), +(2041,'阳春市',2037,'441781',3), +(2042,'清远市',1925,'441800',2), +(2043,'清城区',2042,'441802',3), +(2044,'清新区',2042,'441803',3), +(2045,'佛冈县',2042,'441821',3), +(2046,'阳山县',2042,'441823',3), +(2047,'连山壮族瑶族自治县',2042,'441825',3), +(2048,'连南瑶族自治县',2042,'441826',3), +(2049,'英德市',2042,'441881',3), +(2050,'连州市',2042,'441882',3), +(2051,'东莞市',1925,'441900',2), +(2052,'中山市',1925,'442000',2), +(2053,'潮州市',1925,'445100',2), +(2054,'湘桥区',2053,'445102',3), +(2055,'潮安区',2053,'445103',3), +(2056,'饶平县',2053,'445122',3), +(2057,'揭阳市',1925,'445200',2), +(2058,'榕城区',2057,'445202',3), +(2059,'揭东区',2057,'445203',3), +(2060,'揭西县',2057,'445222',3), +(2061,'惠来县',2057,'445224',3), +(2062,'普宁市',2057,'445281',3), +(2063,'云浮市',1925,'445300',2), +(2064,'云城区',2063,'445302',3), +(2065,'云安区',2063,'445303',3), +(2066,'新兴县',2063,'445321',3), +(2067,'郁南县',2063,'445322',3), +(2068,'罗定市',2063,'445381',3), +(2069,'广西壮族自治区',0,'450000',1), +(2070,'南宁市',2069,'450100',2), +(2071,'兴宁区',2070,'450102',3), +(2072,'青秀区',2070,'450103',3), +(2073,'江南区',2070,'450105',3), +(2074,'西乡塘区',2070,'450107',3), +(2075,'良庆区',2070,'450108',3), +(2076,'邕宁区',2070,'450109',3), +(2077,'武鸣区',2070,'450110',3), +(2078,'隆安县',2070,'450123',3), +(2079,'马山县',2070,'450124',3), +(2080,'上林县',2070,'450125',3), +(2081,'宾阳县',2070,'450126',3), +(2082,'横县',2070,'450127',3), +(2083,'柳州市',2069,'450200',2), +(2084,'城中区',2083,'450202',3), +(2085,'鱼峰区',2083,'450203',3), +(2086,'柳南区',2083,'450204',3), +(2087,'柳北区',2083,'450205',3), +(2088,'柳江区',2083,'450206',3), +(2089,'柳城县',2083,'450222',3), +(2090,'鹿寨县',2083,'450223',3), +(2091,'融安县',2083,'450224',3), +(2092,'融水苗族自治县',2083,'450225',3), +(2093,'三江侗族自治县',2083,'450226',3), +(2094,'桂林市',2069,'450300',2), +(2095,'秀峰区',2094,'450302',3), +(2096,'叠彩区',2094,'450303',3), +(2097,'象山区',2094,'450304',3), +(2098,'七星区',2094,'450305',3), +(2099,'雁山区',2094,'450311',3), +(2100,'临桂区',2094,'450312',3), +(2101,'阳朔县',2094,'450321',3), +(2102,'灵川县',2094,'450323',3), +(2103,'全州县',2094,'450324',3), +(2104,'兴安县',2094,'450325',3), +(2105,'永福县',2094,'450326',3), +(2106,'灌阳县',2094,'450327',3), +(2107,'龙胜各族自治县',2094,'450328',3), +(2108,'资源县',2094,'450329',3), +(2109,'平乐县',2094,'450330',3), +(2110,'荔浦市',2094,'450381',3), +(2111,'恭城瑶族自治县',2094,'450332',3), +(2112,'梧州市',2069,'450400',2), +(2113,'万秀区',2112,'450403',3), +(2114,'长洲区',2112,'450405',3), +(2115,'龙圩区',2112,'450406',3), +(2116,'苍梧县',2112,'450421',3), +(2117,'藤县',2112,'450422',3), +(2118,'蒙山县',2112,'450423',3), +(2119,'岑溪市',2112,'450481',3), +(2120,'北海市',2069,'450500',2), +(2121,'海城区',2120,'450502',3), +(2122,'银海区',2120,'450503',3), +(2123,'铁山港区',2120,'450512',3), +(2124,'合浦县',2120,'450521',3), +(2125,'防城港市',2069,'450600',2), +(2126,'港口区',2125,'450602',3), +(2127,'防城区',2125,'450603',3), +(2128,'上思县',2125,'450621',3), +(2129,'东兴市',2125,'450681',3), +(2130,'钦州市',2069,'450700',2), +(2131,'钦南区',2130,'450702',3), +(2132,'钦北区',2130,'450703',3), +(2133,'灵山县',2130,'450721',3), +(2134,'浦北县',2130,'450722',3), +(2135,'贵港市',2069,'450800',2), +(2136,'港北区',2135,'450802',3), +(2137,'港南区',2135,'450803',3), +(2138,'覃塘区',2135,'450804',3), +(2139,'平南县',2135,'450821',3), +(2140,'桂平市',2135,'450881',3), +(2141,'玉林市',2069,'450900',2), +(2142,'玉州区',2141,'450902',3), +(2143,'福绵区',2141,'450903',3), +(2144,'容县',2141,'450921',3), +(2145,'陆川县',2141,'450922',3), +(2146,'博白县',2141,'450923',3), +(2147,'兴业县',2141,'450924',3), +(2148,'北流市',2141,'450981',3), +(2149,'百色市',2069,'451000',2), +(2150,'右江区',2149,'451002',3), +(2151,'田阳区',2149,'451003',3), +(2152,'田东县',2149,'451022',3), +(2153,'德保县',2149,'451024',3), +(2154,'那坡县',2149,'451026',3), +(2155,'凌云县',2149,'451027',3), +(2156,'乐业县',2149,'451028',3), +(2157,'田林县',2149,'451029',3), +(2158,'西林县',2149,'451030',3), +(2159,'隆林各族自治县',2149,'451031',3), +(2160,'靖西市',2149,'451081',3), +(2161,'平果市',2149,'451082',3), +(2162,'贺州市',2069,'451100',2), +(2163,'八步区',2162,'451102',3), +(2164,'平桂区',2162,'451103',3), +(2165,'昭平县',2162,'451121',3), +(2166,'钟山县',2162,'451122',3), +(2167,'富川瑶族自治县',2162,'451123',3), +(2168,'河池市',2069,'451200',2), +(2169,'金城江区',2168,'451202',3), +(2170,'宜州区',2168,'451203',3), +(2171,'南丹县',2168,'451221',3), +(2172,'天峨县',2168,'451222',3), +(2173,'凤山县',2168,'451223',3), +(2174,'东兰县',2168,'451224',3), +(2175,'罗城仫佬族自治县',2168,'451225',3), +(2176,'环江毛南族自治县',2168,'451226',3), +(2177,'巴马瑶族自治县',2168,'451227',3), +(2178,'都安瑶族自治县',2168,'451228',3), +(2179,'大化瑶族自治县',2168,'451229',3), +(2180,'来宾市',2069,'451300',2), +(2181,'兴宾区',2180,'451302',3), +(2182,'忻城县',2180,'451321',3), +(2183,'象州县',2180,'451322',3), +(2184,'武宣县',2180,'451323',3), +(2185,'金秀瑶族自治县',2180,'451324',3), +(2186,'合山市',2180,'451381',3), +(2187,'崇左市',2069,'451400',2), +(2188,'江州区',2187,'451402',3), +(2189,'扶绥县',2187,'451421',3), +(2190,'宁明县',2187,'451422',3), +(2191,'龙州县',2187,'451423',3), +(2192,'大新县',2187,'451424',3), +(2193,'天等县',2187,'451425',3), +(2194,'凭祥市',2187,'451481',3), +(2195,'海南省',0,'460000',1), +(2196,'海口市',2195,'460100',2), +(2197,'秀英区',2196,'460105',3), +(2198,'龙华区',2196,'460106',3), +(2199,'琼山区',2196,'460107',3), +(2200,'美兰区',2196,'460108',3), +(2201,'三亚市',2195,'460200',2), +(2202,'海棠区',2201,'460202',3), +(2203,'吉阳区',2201,'460203',3), +(2204,'天涯区',2201,'460204',3), +(2205,'崖州区',2201,'460205',3), +(2206,'三沙市',2195,'460300',2), +(2207,'儋州市',2195,'460400',2), +(2208,'五指山市',2195,'469001',3), +(2209,'琼海市',2195,'469002',3), +(2210,'文昌市',2195,'469005',3), +(2211,'万宁市',2195,'469006',3), +(2212,'东方市',2195,'469007',3), +(2213,'定安县',2195,'469021',3), +(2214,'屯昌县',2195,'469022',3), +(2215,'澄迈县',2195,'469023',3), +(2216,'临高县',2195,'469024',3), +(2217,'白沙黎族自治县',2195,'469025',3), +(2218,'昌江黎族自治县',2195,'469026',3), +(2219,'乐东黎族自治县',2195,'469027',3), +(2220,'陵水黎族自治县',2195,'469028',3), +(2221,'保亭黎族苗族自治县',2195,'469029',3), +(2222,'琼中黎族苗族自治县',2195,'469030',3), +(2223,'重庆',0,'500000',1), +(2224,'重庆市',2223,'500010',2), +(2225,'万州区',2224,'500101',3), +(2226,'涪陵区',2224,'500102',3), +(2227,'渝中区',2224,'500103',3), +(2228,'大渡口区',2224,'500104',3), +(2229,'江北区',2224,'500105',3), +(2230,'沙坪坝区',2224,'500106',3), +(2231,'九龙坡区',2224,'500107',3), +(2232,'南岸区',2224,'500108',3), +(2233,'北碚区',2224,'500109',3), +(2234,'綦江区',2224,'500110',3), +(2235,'大足区',2224,'500111',3), +(2236,'渝北区',2224,'500112',3), +(2237,'巴南区',2224,'500113',3), +(2238,'黔江区',2224,'500114',3), +(2239,'长寿区',2224,'500115',3), +(2240,'江津区',2224,'500116',3), +(2241,'合川区',2224,'500117',3), +(2242,'永川区',2224,'500118',3), +(2243,'南川区',2224,'500119',3), +(2244,'璧山区',2224,'500120',3), +(2245,'铜梁区',2224,'500151',3), +(2246,'潼南区',2224,'500152',3), +(2247,'荣昌区',2224,'500153',3), +(2248,'开州区',2224,'500154',3), +(2249,'梁平区',2224,'500155',3), +(2250,'武隆区',2224,'500156',3), +(2251,'城口县',2224,'500229',3), +(2252,'丰都县',2224,'500230',3), +(2253,'垫江县',2224,'500231',3), +(2254,'忠县',2224,'500233',3), +(2255,'云阳县',2224,'500235',3), +(2256,'奉节县',2224,'500236',3), +(2257,'巫山县',2224,'500237',3), +(2258,'巫溪县',2224,'500238',3), +(2259,'石柱土家族自治县',2224,'500240',3), +(2260,'秀山土家族苗族自治县',2224,'500241',3), +(2261,'酉阳土家族苗族自治县',2224,'500242',3), +(2262,'彭水苗族土家族自治县',2224,'500243',3), +(2263,'四川省',0,'510000',1), +(2264,'成都市',2263,'510100',2), +(2265,'锦江区',2264,'510104',3), +(2266,'青羊区',2264,'510105',3), +(2267,'金牛区',2264,'510106',3), +(2268,'武侯区',2264,'510107',3), +(2269,'成华区',2264,'510108',3), +(2270,'龙泉驿区',2264,'510112',3), +(2271,'青白江区',2264,'510113',3), +(2272,'新都区',2264,'510114',3), +(2273,'温江区',2264,'510115',3), +(2274,'双流区',2264,'510116',3), +(2275,'郫都区',2264,'510117',3), +(2276,'金堂县',2264,'510121',3), +(2277,'大邑县',2264,'510129',3), +(2278,'蒲江县',2264,'510131',3), +(2279,'新津县',2264,'510132',3), +(2280,'都江堰市',2264,'510181',3), +(2281,'彭州市',2264,'510182',3), +(2282,'邛崃市',2264,'510183',3), +(2283,'崇州市',2264,'510184',3), +(2284,'简阳市',2264,'510185',3), +(2285,'自贡市',2263,'510300',2), +(2286,'自流井区',2285,'510302',3), +(2287,'贡井区',2285,'510303',3), +(2288,'大安区',2285,'510304',3), +(2289,'沿滩区',2285,'510311',3), +(2290,'荣县',2285,'510321',3), +(2291,'富顺县',2285,'510322',3), +(2292,'攀枝花市',2263,'510400',2), +(2293,'东区',2292,'510402',3), +(2294,'西区',2292,'510403',3), +(2295,'仁和区',2292,'510411',3), +(2296,'米易县',2292,'510421',3), +(2297,'盐边县',2292,'510422',3), +(2298,'泸州市',2263,'510500',2), +(2299,'江阳区',2298,'510502',3), +(2300,'纳溪区',2298,'510503',3), +(2301,'龙马潭区',2298,'510504',3), +(2302,'泸县',2298,'510521',3), +(2303,'合江县',2298,'510522',3), +(2304,'叙永县',2298,'510524',3), +(2305,'古蔺县',2298,'510525',3), +(2306,'德阳市',2263,'510600',2), +(2307,'旌阳区',2306,'510603',3), +(2308,'罗江区',2306,'510604',3), +(2309,'中江县',2306,'510623',3), +(2310,'广汉市',2306,'510681',3), +(2311,'什邡市',2306,'510682',3), +(2312,'绵竹市',2306,'510683',3), +(2313,'绵阳市',2263,'510700',2), +(2314,'涪城区',2313,'510703',3), +(2315,'游仙区',2313,'510704',3), +(2316,'安州区',2313,'510705',3), +(2317,'三台县',2313,'510722',3), +(2318,'盐亭县',2313,'510723',3), +(2319,'梓潼县',2313,'510725',3), +(2320,'北川羌族自治县',2313,'510726',3), +(2321,'平武县',2313,'510727',3), +(2322,'江油市',2313,'510781',3), +(2323,'广元市',2263,'510800',2), +(2324,'利州区',2323,'510802',3), +(2325,'昭化区',2323,'510811',3), +(2326,'朝天区',2323,'510812',3), +(2327,'旺苍县',2323,'510821',3), +(2328,'青川县',2323,'510822',3), +(2329,'剑阁县',2323,'510823',3), +(2330,'苍溪县',2323,'510824',3), +(2331,'遂宁市',2263,'510900',2), +(2332,'船山区',2331,'510903',3), +(2333,'安居区',2331,'510904',3), +(2334,'蓬溪县',2331,'510921',3), +(2335,'大英县',2331,'510923',3), +(2336,'射洪市',2331,'510981',3), +(2337,'内江市',2263,'511000',2), +(2338,'市中区',2337,'511002',3), +(2339,'东兴区',2337,'511011',3), +(2340,'威远县',2337,'511024',3), +(2341,'资中县',2337,'511025',3), +(2342,'隆昌市',2337,'511083',3), +(2343,'乐山市',2263,'511100',2), +(2344,'市中区',2343,'511102',3), +(2345,'沙湾区',2343,'511111',3), +(2346,'五通桥区',2343,'511112',3), +(2347,'金口河区',2343,'511113',3), +(2348,'犍为县',2343,'511123',3), +(2349,'井研县',2343,'511124',3), +(2350,'夹江县',2343,'511126',3), +(2351,'沐川县',2343,'511129',3), +(2352,'峨边彝族自治县',2343,'511132',3), +(2353,'马边彝族自治县',2343,'511133',3), +(2354,'峨眉山市',2343,'511181',3), +(2355,'南充市',2263,'511300',2), +(2356,'顺庆区',2355,'511302',3), +(2357,'高坪区',2355,'511303',3), +(2358,'嘉陵区',2355,'511304',3), +(2359,'南部县',2355,'511321',3), +(2360,'营山县',2355,'511322',3), +(2361,'蓬安县',2355,'511323',3), +(2362,'仪陇县',2355,'511324',3), +(2363,'西充县',2355,'511325',3), +(2364,'阆中市',2355,'511381',3), +(2365,'眉山市',2263,'511400',2), +(2366,'东坡区',2365,'511402',3), +(2367,'彭山区',2365,'511403',3), +(2368,'仁寿县',2365,'511421',3), +(2369,'洪雅县',2365,'511423',3), +(2370,'丹棱县',2365,'511424',3), +(2371,'青神县',2365,'511425',3), +(2372,'宜宾市',2263,'511500',2), +(2373,'翠屏区',2372,'511502',3), +(2374,'南溪区',2372,'511503',3), +(2375,'叙州区',2372,'511504',3), +(2376,'江安县',2372,'511523',3), +(2377,'长宁县',2372,'511524',3), +(2378,'高县',2372,'511525',3), +(2379,'珙县',2372,'511526',3), +(2380,'筠连县',2372,'511527',3), +(2381,'兴文县',2372,'511528',3), +(2382,'屏山县',2372,'511529',3), +(2383,'广安市',2263,'511600',2), +(2384,'广安区',2383,'511602',3), +(2385,'前锋区',2383,'511603',3), +(2386,'岳池县',2383,'511621',3), +(2387,'武胜县',2383,'511622',3), +(2388,'邻水县',2383,'511623',3), +(2389,'华蓥市',2383,'511681',3), +(2390,'达州市',2263,'511700',2), +(2391,'通川区',2390,'511702',3), +(2392,'达川区',2390,'511703',3), +(2393,'宣汉县',2390,'511722',3), +(2394,'开江县',2390,'511723',3), +(2395,'大竹县',2390,'511724',3), +(2396,'渠县',2390,'511725',3), +(2397,'万源市',2390,'511781',3), +(2398,'雅安市',2263,'511800',2), +(2399,'雨城区',2398,'511802',3), +(2400,'名山区',2398,'511803',3), +(2401,'荥经县',2398,'511822',3), +(2402,'汉源县',2398,'511823',3), +(2403,'石棉县',2398,'511824',3), +(2404,'天全县',2398,'511825',3), +(2405,'芦山县',2398,'511826',3), +(2406,'宝兴县',2398,'511827',3), +(2407,'巴中市',2263,'511900',2), +(2408,'巴州区',2407,'511902',3), +(2409,'恩阳区',2407,'511903',3), +(2410,'通江县',2407,'511921',3), +(2411,'南江县',2407,'511922',3), +(2412,'平昌县',2407,'511923',3), +(2413,'资阳市',2263,'512000',2), +(2414,'雁江区',2413,'512002',3), +(2415,'安岳县',2413,'512021',3), +(2416,'乐至县',2413,'512022',3), +(2417,'阿坝藏族羌族自治州',2263,'513200',2), +(2418,'马尔康市',2417,'513201',3), +(2419,'汶川县',2417,'513221',3), +(2420,'理县',2417,'513222',3), +(2421,'茂县',2417,'513223',3), +(2422,'松潘县',2417,'513224',3), +(2423,'九寨沟县',2417,'513225',3), +(2424,'金川县',2417,'513226',3), +(2425,'小金县',2417,'513227',3), +(2426,'黑水县',2417,'513228',3), +(2427,'壤塘县',2417,'513230',3), +(2428,'阿坝县',2417,'513231',3), +(2429,'若尔盖县',2417,'513232',3), +(2430,'红原县',2417,'513233',3), +(2431,'甘孜藏族自治州',2263,'513300',2), +(2432,'康定市',2431,'513301',3), +(2433,'泸定县',2431,'513322',3), +(2434,'丹巴县',2431,'513323',3), +(2435,'九龙县',2431,'513324',3), +(2436,'雅江县',2431,'513325',3), +(2437,'道孚县',2431,'513326',3), +(2438,'炉霍县',2431,'513327',3), +(2439,'甘孜县',2431,'513328',3), +(2440,'新龙县',2431,'513329',3), +(2441,'德格县',2431,'513330',3), +(2442,'白玉县',2431,'513331',3), +(2443,'石渠县',2431,'513332',3), +(2444,'色达县',2431,'513333',3), +(2445,'理塘县',2431,'513334',3), +(2446,'巴塘县',2431,'513335',3), +(2447,'乡城县',2431,'513336',3), +(2448,'稻城县',2431,'513337',3), +(2449,'得荣县',2431,'513338',3), +(2450,'凉山彝族自治州',2263,'513400',2), +(2451,'西昌市',2450,'513401',3), +(2452,'木里藏族自治县',2450,'513422',3), +(2453,'盐源县',2450,'513423',3), +(2454,'德昌县',2450,'513424',3), +(2455,'会理县',2450,'513425',3), +(2456,'会东县',2450,'513426',3), +(2457,'宁南县',2450,'513427',3), +(2458,'普格县',2450,'513428',3), +(2459,'布拖县',2450,'513429',3), +(2460,'金阳县',2450,'513430',3), +(2461,'昭觉县',2450,'513431',3), +(2462,'喜德县',2450,'513432',3), +(2463,'冕宁县',2450,'513433',3), +(2464,'越西县',2450,'513434',3), +(2465,'甘洛县',2450,'513435',3), +(2466,'美姑县',2450,'513436',3), +(2467,'雷波县',2450,'513437',3), +(2468,'贵州省',0,'520000',1), +(2469,'贵阳市',2468,'520100',2), +(2470,'南明区',2469,'520102',3), +(2471,'云岩区',2469,'520103',3), +(2472,'花溪区',2469,'520111',3), +(2473,'乌当区',2469,'520112',3), +(2474,'白云区',2469,'520113',3), +(2475,'观山湖区',2469,'520115',3), +(2476,'开阳县',2469,'520121',3), +(2477,'息烽县',2469,'520122',3), +(2478,'修文县',2469,'520123',3), +(2479,'清镇市',2469,'520181',3), +(2480,'六盘水市',2468,'520200',2), +(2481,'钟山区',2480,'520201',3), +(2482,'六枝特区',2480,'520203',3), +(2483,'水城县',2480,'520221',3), +(2484,'盘州市',2480,'520281',3), +(2485,'遵义市',2468,'520300',2), +(2486,'红花岗区',2485,'520302',3), +(2487,'汇川区',2485,'520303',3), +(2488,'播州区',2485,'520304',3), +(2489,'桐梓县',2485,'520322',3), +(2490,'绥阳县',2485,'520323',3), +(2491,'正安县',2485,'520324',3), +(2492,'道真仡佬族苗族自治县',2485,'520325',3), +(2493,'务川仡佬族苗族自治县',2485,'520326',3), +(2494,'凤冈县',2485,'520327',3), +(2495,'湄潭县',2485,'520328',3), +(2496,'余庆县',2485,'520329',3), +(2497,'习水县',2485,'520330',3), +(2498,'赤水市',2485,'520381',3), +(2499,'仁怀市',2485,'520382',3), +(2500,'安顺市',2468,'520400',2), +(2501,'西秀区',2500,'520402',3), +(2502,'平坝区',2500,'520403',3), +(2503,'普定县',2500,'520422',3), +(2504,'镇宁布依族苗族自治县',2500,'520423',3), +(2505,'关岭布依族苗族自治县',2500,'520424',3), +(2506,'紫云苗族布依族自治县',2500,'520425',3), +(2507,'毕节市',2468,'520500',2), +(2508,'七星关区',2507,'520502',3), +(2509,'大方县',2507,'520521',3), +(2510,'黔西县',2507,'520522',3), +(2511,'金沙县',2507,'520523',3), +(2512,'织金县',2507,'520524',3), +(2513,'纳雍县',2507,'520525',3), +(2514,'威宁彝族回族苗族自治县',2507,'520526',3), +(2515,'赫章县',2507,'520527',3), +(2516,'铜仁市',2468,'520600',2), +(2517,'碧江区',2516,'520602',3), +(2518,'万山区',2516,'520603',3), +(2519,'江口县',2516,'520621',3), +(2520,'玉屏侗族自治县',2516,'520622',3), +(2521,'石阡县',2516,'520623',3), +(2522,'思南县',2516,'520624',3), +(2523,'印江土家族苗族自治县',2516,'520625',3), +(2524,'德江县',2516,'520626',3), +(2525,'沿河土家族自治县',2516,'520627',3), +(2526,'松桃苗族自治县',2516,'520628',3), +(2527,'黔西南布依族苗族自治州',2468,'522300',2), +(2528,'兴义市',2527,'522301',3), +(2529,'兴仁市',2527,'522302',3), +(2530,'普安县',2527,'522323',3), +(2531,'晴隆县',2527,'522324',3), +(2532,'贞丰县',2527,'522325',3), +(2533,'望谟县',2527,'522326',3), +(2534,'册亨县',2527,'522327',3), +(2535,'安龙县',2527,'522328',3), +(2536,'黔东南苗族侗族自治州',2468,'522600',2), +(2537,'凯里市',2536,'522601',3), +(2538,'黄平县',2536,'522622',3), +(2539,'施秉县',2536,'522623',3), +(2540,'三穗县',2536,'522624',3), +(2541,'镇远县',2536,'522625',3), +(2542,'岑巩县',2536,'522626',3), +(2543,'天柱县',2536,'522627',3), +(2544,'锦屏县',2536,'522628',3), +(2545,'剑河县',2536,'522629',3), +(2546,'台江县',2536,'522630',3), +(2547,'黎平县',2536,'522631',3), +(2548,'榕江县',2536,'522632',3), +(2549,'从江县',2536,'522633',3), +(2550,'雷山县',2536,'522634',3), +(2551,'麻江县',2536,'522635',3), +(2552,'丹寨县',2536,'522636',3), +(2553,'黔南布依族苗族自治州',2468,'522700',2), +(2554,'都匀市',2553,'522701',3), +(2555,'福泉市',2553,'522702',3), +(2556,'荔波县',2553,'522722',3), +(2557,'贵定县',2553,'522723',3), +(2558,'瓮安县',2553,'522725',3), +(2559,'独山县',2553,'522726',3), +(2560,'平塘县',2553,'522727',3), +(2561,'罗甸县',2553,'522728',3), +(2562,'长顺县',2553,'522729',3), +(2563,'龙里县',2553,'522730',3), +(2564,'惠水县',2553,'522731',3), +(2565,'三都水族自治县',2553,'522732',3), +(2566,'云南省',0,'530000',1), +(2567,'昆明市',2566,'530100',2), +(2568,'五华区',2567,'530102',3), +(2569,'盘龙区',2567,'530103',3), +(2570,'官渡区',2567,'530111',3), +(2571,'西山区',2567,'530112',3), +(2572,'东川区',2567,'530113',3), +(2573,'呈贡区',2567,'530114',3), +(2574,'晋宁区',2567,'530115',3), +(2575,'富民县',2567,'530124',3), +(2576,'宜良县',2567,'530125',3), +(2577,'石林彝族自治县',2567,'530126',3), +(2578,'嵩明县',2567,'530127',3), +(2579,'禄劝彝族苗族自治县',2567,'530128',3), +(2580,'寻甸回族彝族自治县',2567,'530129',3), +(2581,'安宁市',2567,'530181',3), +(2582,'曲靖市',2566,'530300',2), +(2583,'麒麟区',2582,'530302',3), +(2584,'沾益区',2582,'530303',3), +(2585,'马龙区',2582,'530304',3), +(2586,'陆良县',2582,'530322',3), +(2587,'师宗县',2582,'530323',3), +(2588,'罗平县',2582,'530324',3), +(2589,'富源县',2582,'530325',3), +(2590,'会泽县',2582,'530326',3), +(2591,'宣威市',2582,'530381',3), +(2592,'玉溪市',2566,'530400',2), +(2593,'红塔区',2592,'530402',3), +(2594,'江川区',2592,'530403',3), +(2595,'通海县',2592,'530423',3), +(2596,'华宁县',2592,'530424',3), +(2597,'易门县',2592,'530425',3), +(2598,'峨山彝族自治县',2592,'530426',3), +(2599,'新平彝族傣族自治县',2592,'530427',3), +(2600,'元江哈尼族彝族傣族自治县',2592,'530428',3), +(2601,'澄江市',2592,'530481',3), +(2602,'保山市',2566,'530500',2), +(2603,'隆阳区',2602,'530502',3), +(2604,'施甸县',2602,'530521',3), +(2605,'龙陵县',2602,'530523',3), +(2606,'昌宁县',2602,'530524',3), +(2607,'腾冲市',2602,'530581',3), +(2608,'昭通市',2566,'530600',2), +(2609,'昭阳区',2608,'530602',3), +(2610,'鲁甸县',2608,'530621',3), +(2611,'巧家县',2608,'530622',3), +(2612,'盐津县',2608,'530623',3), +(2613,'大关县',2608,'530624',3), +(2614,'永善县',2608,'530625',3), +(2615,'绥江县',2608,'530626',3), +(2616,'镇雄县',2608,'530627',3), +(2617,'彝良县',2608,'530628',3), +(2618,'威信县',2608,'530629',3), +(2619,'水富市',2608,'530681',3), +(2620,'丽江市',2566,'530700',2), +(2621,'古城区',2620,'530702',3), +(2622,'玉龙纳西族自治县',2620,'530721',3), +(2623,'永胜县',2620,'530722',3), +(2624,'华坪县',2620,'530723',3), +(2625,'宁蒗彝族自治县',2620,'530724',3), +(2626,'普洱市',2566,'530800',2), +(2627,'思茅区',2626,'530802',3), +(2628,'宁洱哈尼族彝族自治县',2626,'530821',3), +(2629,'墨江哈尼族自治县',2626,'530822',3), +(2630,'景东彝族自治县',2626,'530823',3), +(2631,'景谷傣族彝族自治县',2626,'530824',3), +(2632,'镇沅彝族哈尼族拉祜族自治县',2626,'530825',3), +(2633,'江城哈尼族彝族自治县',2626,'530826',3), +(2634,'孟连傣族拉祜族佤族自治县',2626,'530827',3), +(2635,'澜沧拉祜族自治县',2626,'530828',3), +(2636,'西盟佤族自治县',2626,'530829',3), +(2637,'临沧市',2566,'530900',2), +(2638,'临翔区',2637,'530902',3), +(2639,'凤庆县',2637,'530921',3), +(2640,'云县',2637,'530922',3), +(2641,'永德县',2637,'530923',3), +(2642,'镇康县',2637,'530924',3), +(2643,'双江拉祜族佤族布朗族傣族自治县',2637,'530925',3), +(2644,'耿马傣族佤族自治县',2637,'530926',3), +(2645,'沧源佤族自治县',2637,'530927',3), +(2646,'楚雄彝族自治州',2566,'532300',2), +(2647,'楚雄市',2646,'532301',3), +(2648,'双柏县',2646,'532322',3), +(2649,'牟定县',2646,'532323',3), +(2650,'南华县',2646,'532324',3), +(2651,'姚安县',2646,'532325',3), +(2652,'大姚县',2646,'532326',3), +(2653,'永仁县',2646,'532327',3), +(2654,'元谋县',2646,'532328',3), +(2655,'武定县',2646,'532329',3), +(2656,'禄丰县',2646,'532331',3), +(2657,'红河哈尼族彝族自治州',2566,'532500',2), +(2658,'个旧市',2657,'532501',3), +(2659,'开远市',2657,'532502',3), +(2660,'蒙自市',2657,'532503',3), +(2661,'弥勒市',2657,'532504',3), +(2662,'屏边苗族自治县',2657,'532523',3), +(2663,'建水县',2657,'532524',3), +(2664,'石屏县',2657,'532525',3), +(2665,'泸西县',2657,'532527',3), +(2666,'元阳县',2657,'532528',3), +(2667,'红河县',2657,'532529',3), +(2668,'金平苗族瑶族傣族自治县',2657,'532530',3), +(2669,'绿春县',2657,'532531',3), +(2670,'河口瑶族自治县',2657,'532532',3), +(2671,'文山壮族苗族自治州',2566,'532600',2), +(2672,'文山市',2671,'532601',3), +(2673,'砚山县',2671,'532622',3), +(2674,'西畴县',2671,'532623',3), +(2675,'麻栗坡县',2671,'532624',3), +(2676,'马关县',2671,'532625',3), +(2677,'丘北县',2671,'532626',3), +(2678,'广南县',2671,'532627',3), +(2679,'富宁县',2671,'532628',3), +(2680,'西双版纳傣族自治州',2566,'532800',2), +(2681,'景洪市',2680,'532801',3), +(2682,'勐海县',2680,'532822',3), +(2683,'勐腊县',2680,'532823',3), +(2684,'大理白族自治州',2566,'532900',2), +(2685,'大理市',2684,'532901',3), +(2686,'漾濞彝族自治县',2684,'532922',3), +(2687,'祥云县',2684,'532923',3), +(2688,'宾川县',2684,'532924',3), +(2689,'弥渡县',2684,'532925',3), +(2690,'南涧彝族自治县',2684,'532926',3), +(2691,'巍山彝族回族自治县',2684,'532927',3), +(2692,'永平县',2684,'532928',3), +(2693,'云龙县',2684,'532929',3), +(2694,'洱源县',2684,'532930',3), +(2695,'剑川县',2684,'532931',3), +(2696,'鹤庆县',2684,'532932',3), +(2697,'德宏傣族景颇族自治州',2566,'533100',2), +(2698,'瑞丽市',2697,'533102',3), +(2699,'芒市',2697,'533103',3), +(2700,'梁河县',2697,'533122',3), +(2701,'盈江县',2697,'533123',3), +(2702,'陇川县',2697,'533124',3), +(2703,'怒江傈僳族自治州',2566,'533300',2), +(2704,'泸水市',2703,'533301',3), +(2705,'福贡县',2703,'533323',3), +(2706,'贡山独龙族怒族自治县',2703,'533324',3), +(2707,'兰坪白族普米族自治县',2703,'533325',3), +(2708,'迪庆藏族自治州',2566,'533400',2), +(2709,'香格里拉市',2708,'533401',3), +(2710,'德钦县',2708,'533422',3), +(2711,'维西傈僳族自治县',2708,'533423',3), +(2712,'西藏自治区',0,'540000',1), +(2713,'拉萨市',2712,'540100',2), +(2714,'城关区',2713,'540102',3), +(2715,'堆龙德庆区',2713,'540103',3), +(2716,'达孜区',2713,'540104',3), +(2717,'林周县',2713,'540121',3), +(2718,'当雄县',2713,'540122',3), +(2719,'尼木县',2713,'540123',3), +(2720,'曲水县',2713,'540124',3), +(2721,'墨竹工卡县',2713,'540127',3), +(2722,'日喀则市',2712,'540200',2), +(2723,'桑珠孜区',2722,'540202',3), +(2724,'南木林县',2722,'540221',3), +(2725,'江孜县',2722,'540222',3), +(2726,'定日县',2722,'540223',3), +(2727,'萨迦县',2722,'540224',3), +(2728,'拉孜县',2722,'540225',3), +(2729,'昂仁县',2722,'540226',3), +(2730,'谢通门县',2722,'540227',3), +(2731,'白朗县',2722,'540228',3), +(2732,'仁布县',2722,'540229',3), +(2733,'康马县',2722,'540230',3), +(2734,'定结县',2722,'540231',3), +(2735,'仲巴县',2722,'540232',3), +(2736,'亚东县',2722,'540233',3), +(2737,'吉隆县',2722,'540234',3), +(2738,'聂拉木县',2722,'540235',3), +(2739,'萨嘎县',2722,'540236',3), +(2740,'岗巴县',2722,'540237',3), +(2741,'昌都市',2712,'540300',2), +(2742,'卡若区',2741,'540302',3), +(2743,'江达县',2741,'540321',3), +(2744,'贡觉县',2741,'540322',3), +(2745,'类乌齐县',2741,'540323',3), +(2746,'丁青县',2741,'540324',3), +(2747,'察雅县',2741,'540325',3), +(2748,'八宿县',2741,'540326',3), +(2749,'左贡县',2741,'540327',3), +(2750,'芒康县',2741,'540328',3), +(2751,'洛隆县',2741,'540329',3), +(2752,'边坝县',2741,'540330',3), +(2753,'林芝市',2712,'540400',2), +(2754,'巴宜区',2753,'540402',3), +(2755,'工布江达县',2753,'540421',3), +(2756,'米林县',2753,'540422',3), +(2757,'墨脱县',2753,'540423',3), +(2758,'波密县',2753,'540424',3), +(2759,'察隅县',2753,'540425',3), +(2760,'朗县',2753,'540426',3), +(2761,'山南市',2712,'540500',2), +(2762,'乃东区',2761,'540502',3), +(2763,'扎囊县',2761,'540521',3), +(2764,'贡嘎县',2761,'540522',3), +(2765,'桑日县',2761,'540523',3), +(2766,'琼结县',2761,'540524',3), +(2767,'曲松县',2761,'540525',3), +(2768,'措美县',2761,'540526',3), +(2769,'洛扎县',2761,'540527',3), +(2770,'加查县',2761,'540528',3), +(2771,'隆子县',2761,'540529',3), +(2772,'错那县',2761,'540530',3), +(2773,'浪卡子县',2761,'540531',3), +(2774,'那曲市',2712,'540600',2), +(2775,'色尼区',2774,'540602',3), +(2776,'嘉黎县',2774,'540621',3), +(2777,'比如县',2774,'540622',3), +(2778,'聂荣县',2774,'540623',3), +(2779,'安多县',2774,'540624',3), +(2780,'申扎县',2774,'540625',3), +(2781,'索县',2774,'540626',3), +(2782,'班戈县',2774,'540627',3), +(2783,'巴青县',2774,'540628',3), +(2784,'尼玛县',2774,'540629',3), +(2785,'双湖县',2774,'540630',3), +(2786,'阿里地区',2712,'542500',2), +(2787,'普兰县',2786,'542521',3), +(2788,'札达县',2786,'542522',3), +(2789,'噶尔县',2786,'542523',3), +(2790,'日土县',2786,'542524',3), +(2791,'革吉县',2786,'542525',3), +(2792,'改则县',2786,'542526',3), +(2793,'措勤县',2786,'542527',3), +(2794,'陕西省',0,'610000',1), +(2795,'西安市',2794,'610100',2), +(2796,'新城区',2795,'610102',3), +(2797,'碑林区',2795,'610103',3), +(2798,'莲湖区',2795,'610104',3), +(2799,'灞桥区',2795,'610111',3), +(2800,'未央区',2795,'610112',3), +(2801,'雁塔区',2795,'610113',3), +(2802,'阎良区',2795,'610114',3), +(2803,'临潼区',2795,'610115',3), +(2804,'长安区',2795,'610116',3), +(2805,'高陵区',2795,'610117',3), +(2806,'鄠邑区',2795,'610118',3), +(2807,'蓝田县',2795,'610122',3), +(2808,'周至县',2795,'610124',3), +(2809,'铜川市',2794,'610200',2), +(2810,'王益区',2809,'610202',3), +(2811,'印台区',2809,'610203',3), +(2812,'耀州区',2809,'610204',3), +(2813,'宜君县',2809,'610222',3), +(2814,'宝鸡市',2794,'610300',2), +(2815,'渭滨区',2814,'610302',3), +(2816,'金台区',2814,'610303',3), +(2817,'陈仓区',2814,'610304',3), +(2818,'凤翔县',2814,'610322',3), +(2819,'岐山县',2814,'610323',3), +(2820,'扶风县',2814,'610324',3), +(2821,'眉县',2814,'610326',3), +(2822,'陇县',2814,'610327',3), +(2823,'千阳县',2814,'610328',3), +(2824,'麟游县',2814,'610329',3), +(2825,'凤县',2814,'610330',3), +(2826,'太白县',2814,'610331',3), +(2827,'咸阳市',2794,'610400',2), +(2828,'秦都区',2827,'610402',3), +(2829,'杨陵区',2827,'610403',3), +(2830,'渭城区',2827,'610404',3), +(2831,'三原县',2827,'610422',3), +(2832,'泾阳县',2827,'610423',3), +(2833,'乾县',2827,'610424',3), +(2834,'礼泉县',2827,'610425',3), +(2835,'永寿县',2827,'610426',3), +(2836,'长武县',2827,'610428',3), +(2837,'旬邑县',2827,'610429',3), +(2838,'淳化县',2827,'610430',3), +(2839,'武功县',2827,'610431',3), +(2840,'兴平市',2827,'610481',3), +(2841,'彬州市',2827,'610482',3), +(2842,'渭南市',2794,'610500',2), +(2843,'临渭区',2842,'610502',3), +(2844,'华州区',2842,'610503',3), +(2845,'潼关县',2842,'610522',3), +(2846,'大荔县',2842,'610523',3), +(2847,'合阳县',2842,'610524',3), +(2848,'澄城县',2842,'610525',3), +(2849,'蒲城县',2842,'610526',3), +(2850,'白水县',2842,'610527',3), +(2851,'富平县',2842,'610528',3), +(2852,'韩城市',2842,'610581',3), +(2853,'华阴市',2842,'610582',3), +(2854,'延安市',2794,'610600',2), +(2855,'宝塔区',2854,'610602',3), +(2856,'安塞区',2854,'610603',3), +(2857,'延长县',2854,'610621',3), +(2858,'延川县',2854,'610622',3), +(2859,'志丹县',2854,'610625',3), +(2860,'吴起县',2854,'610626',3), +(2861,'甘泉县',2854,'610627',3), +(2862,'富县',2854,'610628',3), +(2863,'洛川县',2854,'610629',3), +(2864,'宜川县',2854,'610630',3), +(2865,'黄龙县',2854,'610631',3), +(2866,'黄陵县',2854,'610632',3), +(2867,'子长市',2854,'610681',3), +(2868,'汉中市',2794,'610700',2), +(2869,'汉台区',2868,'610702',3), +(2870,'南郑区',2868,'610703',3), +(2871,'城固县',2868,'610722',3), +(2872,'洋县',2868,'610723',3), +(2873,'西乡县',2868,'610724',3), +(2874,'勉县',2868,'610725',3), +(2875,'宁强县',2868,'610726',3), +(2876,'略阳县',2868,'610727',3), +(2877,'镇巴县',2868,'610728',3), +(2878,'留坝县',2868,'610729',3), +(2879,'佛坪县',2868,'610730',3), +(2880,'榆林市',2794,'610800',2), +(2881,'榆阳区',2880,'610802',3), +(2882,'横山区',2880,'610803',3), +(2883,'府谷县',2880,'610822',3), +(2884,'靖边县',2880,'610824',3), +(2885,'定边县',2880,'610825',3), +(2886,'绥德县',2880,'610826',3), +(2887,'米脂县',2880,'610827',3), +(2888,'佳县',2880,'610828',3), +(2889,'吴堡县',2880,'610829',3), +(2890,'清涧县',2880,'610830',3), +(2891,'子洲县',2880,'610831',3), +(2892,'神木市',2880,'610881',3), +(2893,'安康市',2794,'610900',2), +(2894,'汉滨区',2893,'610902',3), +(2895,'汉阴县',2893,'610921',3), +(2896,'石泉县',2893,'610922',3), +(2897,'宁陕县',2893,'610923',3), +(2898,'紫阳县',2893,'610924',3), +(2899,'岚皋县',2893,'610925',3), +(2900,'平利县',2893,'610926',3), +(2901,'镇坪县',2893,'610927',3), +(2902,'旬阳县',2893,'610928',3), +(2903,'白河县',2893,'610929',3), +(2904,'商洛市',2794,'611000',2), +(2905,'商州区',2904,'611002',3), +(2906,'洛南县',2904,'611021',3), +(2907,'丹凤县',2904,'611022',3), +(2908,'商南县',2904,'611023',3), +(2909,'山阳县',2904,'611024',3), +(2910,'镇安县',2904,'611025',3), +(2911,'柞水县',2904,'611026',3), +(2912,'甘肃省',0,'620000',1), +(2913,'兰州市',2912,'620100',2), +(2914,'城关区',2913,'620102',3), +(2915,'七里河区',2913,'620103',3), +(2916,'西固区',2913,'620104',3), +(2917,'安宁区',2913,'620105',3), +(2918,'红古区',2913,'620111',3), +(2919,'永登县',2913,'620121',3), +(2920,'皋兰县',2913,'620122',3), +(2921,'榆中县',2913,'620123',3), +(2922,'嘉峪关市',2912,'620200',2), +(2923,'金昌市',2912,'620300',2), +(2924,'金川区',2923,'620302',3), +(2925,'永昌县',2923,'620321',3), +(2926,'白银市',2912,'620400',2), +(2927,'白银区',2926,'620402',3), +(2928,'平川区',2926,'620403',3), +(2929,'靖远县',2926,'620421',3), +(2930,'会宁县',2926,'620422',3), +(2931,'景泰县',2926,'620423',3), +(2932,'天水市',2912,'620500',2), +(2933,'秦州区',2932,'620502',3), +(2934,'麦积区',2932,'620503',3), +(2935,'清水县',2932,'620521',3), +(2936,'秦安县',2932,'620522',3), +(2937,'甘谷县',2932,'620523',3), +(2938,'武山县',2932,'620524',3), +(2939,'张家川回族自治县',2932,'620525',3), +(2940,'武威市',2912,'620600',2), +(2941,'凉州区',2940,'620602',3), +(2942,'民勤县',2940,'620621',3), +(2943,'古浪县',2940,'620622',3), +(2944,'天祝藏族自治县',2940,'620623',3), +(2945,'张掖市',2912,'620700',2), +(2946,'甘州区',2945,'620702',3), +(2947,'肃南裕固族自治县',2945,'620721',3), +(2948,'民乐县',2945,'620722',3), +(2949,'临泽县',2945,'620723',3), +(2950,'高台县',2945,'620724',3), +(2951,'山丹县',2945,'620725',3), +(2952,'平凉市',2912,'620800',2), +(2953,'崆峒区',2952,'620802',3), +(2954,'泾川县',2952,'620821',3), +(2955,'灵台县',2952,'620822',3), +(2956,'崇信县',2952,'620823',3), +(2957,'庄浪县',2952,'620825',3), +(2958,'静宁县',2952,'620826',3), +(2959,'华亭市',2952,'620881',3), +(2960,'酒泉市',2912,'620900',2), +(2961,'肃州区',2960,'620902',3), +(2962,'金塔县',2960,'620921',3), +(2963,'瓜州县',2960,'620922',3), +(2964,'肃北蒙古族自治县',2960,'620923',3), +(2965,'阿克塞哈萨克族自治县',2960,'620924',3), +(2966,'玉门市',2960,'620981',3), +(2967,'敦煌市',2960,'620982',3), +(2968,'庆阳市',2912,'621000',2), +(2969,'西峰区',2968,'621002',3), +(2970,'庆城县',2968,'621021',3), +(2971,'环县',2968,'621022',3), +(2972,'华池县',2968,'621023',3), +(2973,'合水县',2968,'621024',3), +(2974,'正宁县',2968,'621025',3), +(2975,'宁县',2968,'621026',3), +(2976,'镇原县',2968,'621027',3), +(2977,'定西市',2912,'621100',2), +(2978,'安定区',2977,'621102',3), +(2979,'通渭县',2977,'621121',3), +(2980,'陇西县',2977,'621122',3), +(2981,'渭源县',2977,'621123',3), +(2982,'临洮县',2977,'621124',3), +(2983,'漳县',2977,'621125',3), +(2984,'岷县',2977,'621126',3), +(2985,'陇南市',2912,'621200',2), +(2986,'武都区',2985,'621202',3), +(2987,'成县',2985,'621221',3), +(2988,'文县',2985,'621222',3), +(2989,'宕昌县',2985,'621223',3), +(2990,'康县',2985,'621224',3), +(2991,'西和县',2985,'621225',3), +(2992,'礼县',2985,'621226',3), +(2993,'徽县',2985,'621227',3), +(2994,'两当县',2985,'621228',3), +(2995,'临夏回族自治州',2912,'622900',2), +(2996,'临夏市',2995,'622901',3), +(2997,'临夏县',2995,'622921',3), +(2998,'康乐县',2995,'622922',3), +(2999,'永靖县',2995,'622923',3), +(3000,'广河县',2995,'622924',3), +(3001,'和政县',2995,'622925',3), +(3002,'东乡族自治县',2995,'622926',3), +(3003,'积石山保安族东乡族撒拉族自治县',2995,'622927',3), +(3004,'甘南藏族自治州',2912,'623000',2), +(3005,'合作市',3004,'623001',3), +(3006,'临潭县',3004,'623021',3), +(3007,'卓尼县',3004,'623022',3), +(3008,'舟曲县',3004,'623023',3), +(3009,'迭部县',3004,'623024',3), +(3010,'玛曲县',3004,'623025',3), +(3011,'碌曲县',3004,'623026',3), +(3012,'夏河县',3004,'623027',3), +(3013,'青海省',0,'630000',1), +(3014,'西宁市',3013,'630100',2), +(3015,'城东区',3014,'630102',3), +(3016,'城中区',3014,'630103',3), +(3017,'城西区',3014,'630104',3), +(3018,'城北区',3014,'630105',3), +(3019,'湟中区',3014,'630106',3), +(3020,'大通回族土族自治县',3014,'630121',3), +(3021,'湟源县',3014,'630123',3), +(3022,'海东市',3013,'630200',2), +(3023,'乐都区',3022,'630202',3), +(3024,'平安区',3022,'630203',3), +(3025,'民和回族土族自治县',3022,'630222',3), +(3026,'互助土族自治县',3022,'630223',3), +(3027,'化隆回族自治县',3022,'630224',3), +(3028,'循化撒拉族自治县',3022,'630225',3), +(3029,'海北藏族自治州',3013,'632200',2), +(3030,'门源回族自治县',3029,'632221',3), +(3031,'祁连县',3029,'632222',3), +(3032,'海晏县',3029,'632223',3), +(3033,'刚察县',3029,'632224',3), +(3034,'黄南藏族自治州',3013,'632300',2), +(3035,'同仁县',3034,'632321',3), +(3036,'尖扎县',3034,'632322',3), +(3037,'泽库县',3034,'632323',3), +(3038,'河南蒙古族自治县',3034,'632324',3), +(3039,'海南藏族自治州',3013,'632500',2), +(3040,'共和县',3039,'632521',3), +(3041,'同德县',3039,'632522',3), +(3042,'贵德县',3039,'632523',3), +(3043,'兴海县',3039,'632524',3), +(3044,'贵南县',3039,'632525',3), +(3045,'果洛藏族自治州',3013,'632600',2), +(3046,'玛沁县',3045,'632621',3), +(3047,'班玛县',3045,'632622',3), +(3048,'甘德县',3045,'632623',3), +(3049,'达日县',3045,'632624',3), +(3050,'久治县',3045,'632625',3), +(3051,'玛多县',3045,'632626',3), +(3052,'玉树藏族自治州',3013,'632700',2), +(3053,'玉树市',3052,'632701',3), +(3054,'杂多县',3052,'632722',3), +(3055,'称多县',3052,'632723',3), +(3056,'治多县',3052,'632724',3), +(3057,'囊谦县',3052,'632725',3), +(3058,'曲麻莱县',3052,'632726',3), +(3059,'海西蒙古族藏族自治州',3013,'632800',2), +(3060,'格尔木市',3059,'632801',3), +(3061,'德令哈市',3059,'632802',3), +(3062,'茫崖市',3059,'632803',3), +(3063,'乌兰县',3059,'632821',3), +(3064,'都兰县',3059,'632822',3), +(3065,'天峻县',3059,'632823',3), +(3066,'宁夏回族自治区',0,'640000',1), +(3067,'银川市',3066,'640100',2), +(3068,'兴庆区',3067,'640104',3), +(3069,'西夏区',3067,'640105',3), +(3070,'金凤区',3067,'640106',3), +(3071,'永宁县',3067,'640121',3), +(3072,'贺兰县',3067,'640122',3), +(3073,'灵武市',3067,'640181',3), +(3074,'石嘴山市',3066,'640200',2), +(3075,'大武口区',3074,'640202',3), +(3076,'惠农区',3074,'640205',3), +(3077,'平罗县',3074,'640221',3), +(3078,'吴忠市',3066,'640300',2), +(3079,'利通区',3078,'640302',3), +(3080,'红寺堡区',3078,'640303',3), +(3081,'盐池县',3078,'640323',3), +(3082,'同心县',3078,'640324',3), +(3083,'青铜峡市',3078,'640381',3), +(3084,'固原市',3066,'640400',2), +(3085,'原州区',3084,'640402',3), +(3086,'西吉县',3084,'640422',3), +(3087,'隆德县',3084,'640423',3), +(3088,'泾源县',3084,'640424',3), +(3089,'彭阳县',3084,'640425',3), +(3090,'中卫市',3066,'640500',2), +(3091,'沙坡头区',3090,'640502',3), +(3092,'中宁县',3090,'640521',3), +(3093,'海原县',3090,'640522',3), +(3094,'新疆维吾尔自治区',0,'650000',1), +(3095,'乌鲁木齐市',3094,'650100',2), +(3096,'天山区',3095,'650102',3), +(3097,'沙依巴克区',3095,'650103',3), +(3098,'新市区',3095,'650104',3), +(3099,'水磨沟区',3095,'650105',3), +(3100,'头屯河区',3095,'650106',3), +(3101,'达坂城区',3095,'650107',3), +(3102,'米东区',3095,'650109',3), +(3103,'乌鲁木齐县',3095,'650121',3), +(3104,'克拉玛依市',3094,'650200',2), +(3105,'独山子区',3104,'650202',3), +(3106,'克拉玛依区',3104,'650203',3), +(3107,'白碱滩区',3104,'650204',3), +(3108,'乌尔禾区',3104,'650205',3), +(3109,'吐鲁番市',3094,'650400',2), +(3110,'高昌区',3109,'650402',3), +(3111,'鄯善县',3109,'650421',3), +(3112,'托克逊县',3109,'650422',3), +(3113,'哈密市',3094,'650500',2), +(3114,'伊州区',3113,'650502',3), +(3115,'巴里坤哈萨克自治县',3113,'650521',3), +(3116,'伊吾县',3113,'650522',3), +(3117,'昌吉回族自治州',3094,'652300',2), +(3118,'昌吉市',3117,'652301',3), +(3119,'阜康市',3117,'652302',3), +(3120,'呼图壁县',3117,'652323',3), +(3121,'玛纳斯县',3117,'652324',3), +(3122,'奇台县',3117,'652325',3), +(3123,'吉木萨尔县',3117,'652327',3), +(3124,'木垒哈萨克自治县',3117,'652328',3), +(3125,'博尔塔拉蒙古自治州',3094,'652700',2), +(3126,'博乐市',3125,'652701',3), +(3127,'阿拉山口市',3125,'652702',3), +(3128,'精河县',3125,'652722',3), +(3129,'温泉县',3125,'652723',3), +(3130,'巴音郭楞蒙古自治州',3094,'652800',2), +(3131,'库尔勒市',3130,'652801',3), +(3132,'轮台县',3130,'652822',3), +(3133,'尉犁县',3130,'652823',3), +(3134,'若羌县',3130,'652824',3), +(3135,'且末县',3130,'652825',3), +(3136,'焉耆回族自治县',3130,'652826',3), +(3137,'和静县',3130,'652827',3), +(3138,'和硕县',3130,'652828',3), +(3139,'博湖县',3130,'652829',3), +(3140,'阿克苏地区',3094,'652900',2), +(3141,'阿克苏市',3140,'652901',3), +(3142,'库车市',3140,'652902',3), +(3143,'温宿县',3140,'652922',3), +(3144,'沙雅县',3140,'652924',3), +(3145,'新和县',3140,'652925',3), +(3146,'拜城县',3140,'652926',3), +(3147,'乌什县',3140,'652927',3), +(3148,'阿瓦提县',3140,'652928',3), +(3149,'柯坪县',3140,'652929',3), +(3150,'克孜勒苏柯尔克孜自治州',3094,'653000',2), +(3151,'阿图什市',3150,'653001',3), +(3152,'阿克陶县',3150,'653022',3), +(3153,'阿合奇县',3150,'653023',3), +(3154,'乌恰县',3150,'653024',3), +(3155,'喀什地区',3094,'653100',2), +(3156,'喀什市',3155,'653101',3), +(3157,'疏附县',3155,'653121',3), +(3158,'疏勒县',3155,'653122',3), +(3159,'英吉沙县',3155,'653123',3), +(3160,'泽普县',3155,'653124',3), +(3161,'莎车县',3155,'653125',3), +(3162,'叶城县',3155,'653126',3), +(3163,'麦盖提县',3155,'653127',3), +(3164,'岳普湖县',3155,'653128',3), +(3165,'伽师县',3155,'653129',3), +(3166,'巴楚县',3155,'653130',3), +(3167,'塔什库尔干塔吉克自治县',3155,'653131',3), +(3168,'和田地区',3094,'653200',2), +(3169,'和田市',3168,'653201',3), +(3170,'和田县',3168,'653221',3), +(3171,'墨玉县',3168,'653222',3), +(3172,'皮山县',3168,'653223',3), +(3173,'洛浦县',3168,'653224',3), +(3174,'策勒县',3168,'653225',3), +(3175,'于田县',3168,'653226',3), +(3176,'民丰县',3168,'653227',3), +(3177,'伊犁哈萨克自治州',3094,'654000',2), +(3178,'伊宁市',3177,'654002',3), +(3179,'奎屯市',3177,'654003',3), +(3180,'霍尔果斯市',3177,'654004',3), +(3181,'伊宁县',3177,'654021',3), +(3182,'察布查尔锡伯自治县',3177,'654022',3), +(3183,'霍城县',3177,'654023',3), +(3184,'巩留县',3177,'654024',3), +(3185,'新源县',3177,'654025',3), +(3186,'昭苏县',3177,'654026',3), +(3187,'特克斯县',3177,'654027',3), +(3188,'尼勒克县',3177,'654028',3), +(3189,'塔城地区',3094,'654200',2), +(3190,'塔城市',3189,'654201',3), +(3191,'乌苏市',3189,'654202',3), +(3192,'额敏县',3189,'654221',3), +(3193,'沙湾县',3189,'654223',3), +(3194,'托里县',3189,'654224',3), +(3195,'裕民县',3189,'654225',3), +(3196,'和布克赛尔蒙古自治县',3189,'654226',3), +(3197,'阿勒泰地区',3094,'654300',2), +(3198,'阿勒泰市',3197,'654301',3), +(3199,'布尔津县',3197,'654321',3), +(3200,'富蕴县',3197,'654322',3), +(3201,'福海县',3197,'654323',3), +(3202,'哈巴河县',3197,'654324',3), +(3203,'青河县',3197,'654325',3), +(3204,'吉木乃县',3197,'654326',3), +(3205,'石河子市',3094,'659001',3), +(3206,'阿拉尔市',3094,'659002',3), +(3207,'图木舒克市',3094,'659003',3), +(3208,'五家渠市',3094,'659004',3), +(3209,'北屯市',3094,'659005',3), +(3210,'铁门关市',3094,'659006',3), +(3211,'双河市',3094,'659007',3), +(3212,'可克达拉市',3094,'659008',3), +(3213,'昆玉市',3094,'659009',3), +(3214,'胡杨河市',3094,'659010',3), +(3215,'台湾省',0,'710000',1), +(3216,'台北市',3215,'710100',2), +(3217,'中正区',3216,'710101',3), +(3218,'大同区',3216,'710102',3), +(3219,'中山区',3216,'710103',3), +(3220,'松山区',3216,'710104',3), +(3221,'大安区',3216,'710105',3), +(3222,'万华区',3216,'710106',3), +(3223,'信义区',3216,'710107',3), +(3224,'士林区',3216,'710108',3), +(3225,'北投区',3216,'710109',3), +(3226,'内湖区',3216,'710110',3), +(3227,'南港区',3216,'710111',3), +(3228,'文山区',3216,'710112',3), +(3229,'高雄市',3215,'710200',2), +(3230,'新兴区',3229,'710201',3), +(3231,'前金区',3229,'710202',3), +(3232,'苓雅区',3229,'710203',3), +(3233,'盐埕区',3229,'710204',3), +(3234,'鼓山区',3229,'710205',3), +(3235,'旗津区',3229,'710206',3), +(3236,'前镇区',3229,'710207',3), +(3237,'三民区',3229,'710208',3), +(3238,'左营区',3229,'710209',3), +(3239,'楠梓区',3229,'710210',3), +(3240,'小港区',3229,'710211',3), +(3241,'仁武区',3229,'710242',3), +(3242,'大社区',3229,'710243',3), +(3243,'冈山区',3229,'710244',3), +(3244,'路竹区',3229,'710245',3), +(3245,'阿莲区',3229,'710246',3), +(3246,'田寮区',3229,'710247',3), +(3247,'燕巢区',3229,'710248',3), +(3248,'桥头区',3229,'710249',3), +(3249,'梓官区',3229,'710250',3), +(3250,'弥陀区',3229,'710251',3), +(3251,'永安区',3229,'710252',3), +(3252,'湖内区',3229,'710253',3), +(3253,'凤山区',3229,'710254',3), +(3254,'大寮区',3229,'710255',3), +(3255,'林园区',3229,'710256',3), +(3256,'鸟松区',3229,'710257',3), +(3257,'大树区',3229,'710258',3), +(3258,'旗山区',3229,'710259',3), +(3259,'美浓区',3229,'710260',3), +(3260,'六龟区',3229,'710261',3), +(3261,'内门区',3229,'710262',3), +(3262,'杉林区',3229,'710263',3), +(3263,'甲仙区',3229,'710264',3), +(3264,'桃源区',3229,'710265',3), +(3265,'那玛夏区',3229,'710266',3), +(3266,'茂林区',3229,'710267',3), +(3267,'茄萣区',3229,'710268',3), +(3268,'台南市',3215,'710300',2), +(3269,'中西区',3268,'710301',3), +(3270,'东区',3268,'710302',3), +(3271,'南区',3268,'710303',3), +(3272,'北区',3268,'710304',3), +(3273,'安平区',3268,'710305',3), +(3274,'安南区',3268,'710306',3), +(3275,'永康区',3268,'710339',3), +(3276,'归仁区',3268,'710340',3), +(3277,'新化区',3268,'710341',3), +(3278,'左镇区',3268,'710342',3), +(3279,'玉井区',3268,'710343',3), +(3280,'楠西区',3268,'710344',3), +(3281,'南化区',3268,'710345',3), +(3282,'仁德区',3268,'710346',3), +(3283,'关庙区',3268,'710347',3), +(3284,'龙崎区',3268,'710348',3), +(3285,'官田区',3268,'710349',3), +(3286,'麻豆区',3268,'710350',3), +(3287,'佳里区',3268,'710351',3), +(3288,'西港区',3268,'710352',3), +(3289,'七股区',3268,'710353',3), +(3290,'将军区',3268,'710354',3), +(3291,'学甲区',3268,'710355',3), +(3292,'北门区',3268,'710356',3), +(3293,'新营区',3268,'710357',3), +(3294,'后壁区',3268,'710358',3), +(3295,'白河区',3268,'710359',3), +(3296,'东山区',3268,'710360',3), +(3297,'六甲区',3268,'710361',3), +(3298,'下营区',3268,'710362',3), +(3299,'柳营区',3268,'710363',3), +(3300,'盐水区',3268,'710364',3), +(3301,'善化区',3268,'710365',3), +(3302,'大内区',3268,'710366',3), +(3303,'山上区',3268,'710367',3), +(3304,'新市区',3268,'710368',3), +(3305,'安定区',3268,'710369',3), +(3306,'台中市',3215,'710400',2), +(3307,'中区',3306,'710401',3), +(3308,'东区',3306,'710402',3), +(3309,'南区',3306,'710403',3), +(3310,'西区',3306,'710404',3), +(3311,'北区',3306,'710405',3), +(3312,'北屯区',3306,'710406',3), +(3313,'西屯区',3306,'710407',3), +(3314,'南屯区',3306,'710408',3), +(3315,'太平区',3306,'710431',3), +(3316,'大里区',3306,'710432',3), +(3317,'雾峰区',3306,'710433',3), +(3318,'乌日区',3306,'710434',3), +(3319,'丰原区',3306,'710435',3), +(3320,'后里区',3306,'710436',3), +(3321,'石冈区',3306,'710437',3), +(3322,'东势区',3306,'710438',3), +(3323,'和平区',3306,'710439',3), +(3324,'新社区',3306,'710440',3), +(3325,'潭子区',3306,'710441',3), +(3326,'大雅区',3306,'710442',3), +(3327,'神冈区',3306,'710443',3), +(3328,'大肚区',3306,'710444',3), +(3329,'沙鹿区',3306,'710445',3), +(3330,'龙井区',3306,'710446',3), +(3331,'梧栖区',3306,'710447',3), +(3332,'清水区',3306,'710448',3), +(3333,'大甲区',3306,'710449',3), +(3334,'外埔区',3306,'710450',3), +(3335,'大安区',3306,'710451',3), +(3336,'南投县',3215,'710600',2), +(3337,'南投市',3336,'710614',3), +(3338,'中寮乡',3336,'710615',3), +(3339,'草屯镇',3336,'710616',3), +(3340,'国姓乡',3336,'710617',3), +(3341,'埔里镇',3336,'710618',3), +(3342,'仁爱乡',3336,'710619',3), +(3343,'名间乡',3336,'710620',3), +(3344,'集集镇',3336,'710621',3), +(3345,'水里乡',3336,'710622',3), +(3346,'鱼池乡',3336,'710623',3), +(3347,'信义乡',3336,'710624',3), +(3348,'竹山镇',3336,'710625',3), +(3349,'鹿谷乡',3336,'710626',3), +(3350,'基隆市',3215,'710700',2), +(3351,'仁爱区',3350,'710701',3), +(3352,'信义区',3350,'710702',3), +(3353,'中正区',3350,'710703',3), +(3354,'中山区',3350,'710704',3), +(3355,'安乐区',3350,'710705',3), +(3356,'暖暖区',3350,'710706',3), +(3357,'七堵区',3350,'710707',3), +(3358,'新竹市',3215,'710800',2), +(3359,'东区',3358,'710801',3), +(3360,'北区',3358,'710802',3), +(3361,'香山区',3358,'710803',3), +(3362,'嘉义市',3215,'710900',2), +(3363,'东区',3362,'710901',3), +(3364,'西区',3362,'710902',3), +(3365,'新北市',3215,'711100',2), +(3366,'万里区',3365,'711130',3), +(3367,'金山区',3365,'711131',3), +(3368,'板桥区',3365,'711132',3), +(3369,'汐止区',3365,'711133',3), +(3370,'深坑区',3365,'711134',3), +(3371,'石碇区',3365,'711135',3), +(3372,'瑞芳区',3365,'711136',3), +(3373,'平溪区',3365,'711137',3), +(3374,'双溪区',3365,'711138',3), +(3375,'贡寮区',3365,'711139',3), +(3376,'新店区',3365,'711140',3), +(3377,'坪林区',3365,'711141',3), +(3378,'乌来区',3365,'711142',3), +(3379,'永和区',3365,'711143',3), +(3380,'中和区',3365,'711144',3), +(3381,'土城区',3365,'711145',3), +(3382,'三峡区',3365,'711146',3), +(3383,'树林区',3365,'711147',3), +(3384,'莺歌区',3365,'711148',3), +(3385,'三重区',3365,'711149',3), +(3386,'新庄区',3365,'711150',3), +(3387,'泰山区',3365,'711151',3), +(3388,'林口区',3365,'711152',3), +(3389,'芦洲区',3365,'711153',3), +(3390,'五股区',3365,'711154',3), +(3391,'八里区',3365,'711155',3), +(3392,'淡水区',3365,'711156',3), +(3393,'三芝区',3365,'711157',3), +(3394,'石门区',3365,'711158',3), +(3395,'宜兰县',3215,'711200',2), +(3396,'宜兰市',3395,'711214',3), +(3397,'头城镇',3395,'711215',3), +(3398,'礁溪乡',3395,'711216',3), +(3399,'壮围乡',3395,'711217',3), +(3400,'员山乡',3395,'711218',3), +(3401,'罗东镇',3395,'711219',3), +(3402,'三星乡',3395,'711220',3), +(3403,'大同乡',3395,'711221',3), +(3404,'五结乡',3395,'711222',3), +(3405,'冬山乡',3395,'711223',3), +(3406,'苏澳镇',3395,'711224',3), +(3407,'南澳乡',3395,'711225',3), +(3408,'新竹县',3215,'711300',2), +(3409,'竹北市',3408,'711314',3), +(3410,'湖口乡',3408,'711315',3), +(3411,'新丰乡',3408,'711316',3), +(3412,'新埔镇',3408,'711317',3), +(3413,'关西镇',3408,'711318',3), +(3414,'芎林乡',3408,'711319',3), +(3415,'宝山乡',3408,'711320',3), +(3416,'竹东镇',3408,'711321',3), +(3417,'五峰乡',3408,'711322',3), +(3418,'横山乡',3408,'711323',3), +(3419,'尖石乡',3408,'711324',3), +(3420,'北埔乡',3408,'711325',3), +(3421,'峨眉乡',3408,'711326',3), +(3422,'桃园市',3215,'711400',2), +(3423,'中坜区',3422,'711414',3), +(3424,'平镇区',3422,'711415',3), +(3425,'龙潭区',3422,'711416',3), +(3426,'杨梅区',3422,'711417',3), +(3427,'新屋区',3422,'711418',3), +(3428,'观音区',3422,'711419',3), +(3429,'桃园区',3422,'711420',3), +(3430,'龟山区',3422,'711421',3), +(3431,'八德区',3422,'711422',3), +(3432,'大溪区',3422,'711423',3), +(3433,'复兴区',3422,'711424',3), +(3434,'大园区',3422,'711425',3), +(3435,'芦竹区',3422,'711426',3), +(3436,'苗栗县',3215,'711500',2), +(3437,'竹南镇',3436,'711519',3), +(3438,'头份市',3436,'711520',3), +(3439,'三湾乡',3436,'711521',3), +(3440,'南庄乡',3436,'711522',3), +(3441,'狮潭乡',3436,'711523',3), +(3442,'后龙镇',3436,'711524',3), +(3443,'通霄镇',3436,'711525',3), +(3444,'苑里镇',3436,'711526',3), +(3445,'苗栗市',3436,'711527',3), +(3446,'造桥乡',3436,'711528',3), +(3447,'头屋乡',3436,'711529',3), +(3448,'公馆乡',3436,'711530',3), +(3449,'大湖乡',3436,'711531',3), +(3450,'泰安乡',3436,'711532',3), +(3451,'铜锣乡',3436,'711533',3), +(3452,'三义乡',3436,'711534',3), +(3453,'西湖乡',3436,'711535',3), +(3454,'卓兰镇',3436,'711536',3), +(3455,'彰化县',3215,'711700',2), +(3456,'彰化市',3455,'711727',3), +(3457,'芬园乡',3455,'711728',3), +(3458,'花坛乡',3455,'711729',3), +(3459,'秀水乡',3455,'711730',3), +(3460,'鹿港镇',3455,'711731',3), +(3461,'福兴乡',3455,'711732',3), +(3462,'线西乡',3455,'711733',3), +(3463,'和美镇',3455,'711734',3), +(3464,'伸港乡',3455,'711735',3), +(3465,'员林市',3455,'711736',3), +(3466,'社头乡',3455,'711737',3), +(3467,'永靖乡',3455,'711738',3), +(3468,'埔心乡',3455,'711739',3), +(3469,'溪湖镇',3455,'711740',3), +(3470,'大村乡',3455,'711741',3), +(3471,'埔盐乡',3455,'711742',3), +(3472,'田中镇',3455,'711743',3), +(3473,'北斗镇',3455,'711744',3), +(3474,'田尾乡',3455,'711745',3), +(3475,'埤头乡',3455,'711746',3), +(3476,'溪州乡',3455,'711747',3), +(3477,'竹塘乡',3455,'711748',3), +(3478,'二林镇',3455,'711749',3), +(3479,'大城乡',3455,'711750',3), +(3480,'芳苑乡',3455,'711751',3), +(3481,'二水乡',3455,'711752',3), +(3482,'嘉义县',3215,'711900',2), +(3483,'番路乡',3482,'711919',3), +(3484,'梅山乡',3482,'711920',3), +(3485,'竹崎乡',3482,'711921',3), +(3486,'阿里山乡',3482,'711922',3), +(3487,'中埔乡',3482,'711923',3), +(3488,'大埔乡',3482,'711924',3), +(3489,'水上乡',3482,'711925',3), +(3490,'鹿草乡',3482,'711926',3), +(3491,'太保市',3482,'711927',3), +(3492,'朴子市',3482,'711928',3), +(3493,'东石乡',3482,'711929',3), +(3494,'六脚乡',3482,'711930',3), +(3495,'新港乡',3482,'711931',3), +(3496,'民雄乡',3482,'711932',3), +(3497,'大林镇',3482,'711933',3), +(3498,'溪口乡',3482,'711934',3), +(3499,'义竹乡',3482,'711935',3), +(3500,'布袋镇',3482,'711936',3), +(3501,'云林县',3215,'712100',2), +(3502,'斗南镇',3501,'712121',3), +(3503,'大埤乡',3501,'712122',3), +(3504,'虎尾镇',3501,'712123',3), +(3505,'土库镇',3501,'712124',3), +(3506,'褒忠乡',3501,'712125',3), +(3507,'东势乡',3501,'712126',3), +(3508,'台西乡',3501,'712127',3), +(3509,'仑背乡',3501,'712128',3), +(3510,'麦寮乡',3501,'712129',3), +(3511,'斗六市',3501,'712130',3), +(3512,'林内乡',3501,'712131',3), +(3513,'古坑乡',3501,'712132',3), +(3514,'莿桐乡',3501,'712133',3), +(3515,'西螺镇',3501,'712134',3), +(3516,'二仑乡',3501,'712135',3), +(3517,'北港镇',3501,'712136',3), +(3518,'水林乡',3501,'712137',3), +(3519,'口湖乡',3501,'712138',3), +(3520,'四湖乡',3501,'712139',3), +(3521,'元长乡',3501,'712140',3), +(3522,'屏东县',3215,'712400',2), +(3523,'屏东市',3522,'712434',3), +(3524,'三地门乡',3522,'712435',3), +(3525,'雾台乡',3522,'712436',3), +(3526,'玛家乡',3522,'712437',3), +(3527,'九如乡',3522,'712438',3), +(3528,'里港乡',3522,'712439',3), +(3529,'高树乡',3522,'712440',3), +(3530,'盐埔乡',3522,'712441',3), +(3531,'长治乡',3522,'712442',3), +(3532,'麟洛乡',3522,'712443',3), +(3533,'竹田乡',3522,'712444',3), +(3534,'内埔乡',3522,'712445',3), +(3535,'万丹乡',3522,'712446',3), +(3536,'潮州镇',3522,'712447',3), +(3537,'泰武乡',3522,'712448',3), +(3538,'来义乡',3522,'712449',3), +(3539,'万峦乡',3522,'712450',3), +(3540,'崁顶乡',3522,'712451',3), +(3541,'新埤乡',3522,'712452',3), +(3542,'南州乡',3522,'712453',3), +(3543,'林边乡',3522,'712454',3), +(3544,'东港镇',3522,'712455',3), +(3545,'琉球乡',3522,'712456',3), +(3546,'佳冬乡',3522,'712457',3), +(3547,'新园乡',3522,'712458',3), +(3548,'枋寮乡',3522,'712459',3), +(3549,'枋山乡',3522,'712460',3), +(3550,'春日乡',3522,'712461',3), +(3551,'狮子乡',3522,'712462',3), +(3552,'车城乡',3522,'712463',3), +(3553,'牡丹乡',3522,'712464',3), +(3554,'恒春镇',3522,'712465',3), +(3555,'满州乡',3522,'712466',3), +(3556,'台东县',3215,'712500',2), +(3557,'台东市',3556,'712517',3), +(3558,'绿岛乡',3556,'712518',3), +(3559,'兰屿乡',3556,'712519',3), +(3560,'延平乡',3556,'712520',3), +(3561,'卑南乡',3556,'712521',3), +(3562,'鹿野乡',3556,'712522',3), +(3563,'关山镇',3556,'712523',3), +(3564,'海端乡',3556,'712524',3), +(3565,'池上乡',3556,'712525',3), +(3566,'东河乡',3556,'712526',3), +(3567,'成功镇',3556,'712527',3), +(3568,'长滨乡',3556,'712528',3), +(3569,'金峰乡',3556,'712529',3), +(3570,'大武乡',3556,'712530',3), +(3571,'达仁乡',3556,'712531',3), +(3572,'太麻里乡',3556,'712532',3), +(3573,'花莲县',3215,'712600',2), +(3574,'花莲市',3573,'712615',3), +(3575,'新城乡',3573,'712616',3), +(3576,'秀林乡',3573,'712618',3), +(3577,'吉安乡',3573,'712619',3), +(3578,'寿丰乡',3573,'712620',3), +(3579,'凤林镇',3573,'712621',3), +(3580,'光复乡',3573,'712622',3), +(3581,'丰滨乡',3573,'712623',3), +(3582,'瑞穗乡',3573,'712624',3), +(3583,'万荣乡',3573,'712625',3), +(3584,'玉里镇',3573,'712626',3), +(3585,'卓溪乡',3573,'712627',3), +(3586,'富里乡',3573,'712628',3), +(3587,'澎湖县',3215,'712700',2), +(3588,'马公市',3587,'712707',3), +(3589,'西屿乡',3587,'712708',3), +(3590,'望安乡',3587,'712709',3), +(3591,'七美乡',3587,'712710',3), +(3592,'白沙乡',3587,'712711',3), +(3593,'湖西乡',3587,'712712',3), +(3594,'香港特别行政区',0,'810000',1), +(3595,'香港特别行政区',3594,'810100',2), +(3596,'中西区',3595,'810101',3), +(3597,'东区',3595,'810102',3), +(3598,'九龙城区',3595,'810103',3), +(3599,'观塘区',3595,'810104',3), +(3600,'南区',3595,'810105',3), +(3601,'深水埗区',3595,'810106',3), +(3602,'湾仔区',3595,'810107',3), +(3603,'黄大仙区',3595,'810108',3), +(3604,'油尖旺区',3595,'810109',3), +(3605,'离岛区',3595,'810110',3), +(3606,'葵青区',3595,'810111',3), +(3607,'北区',3595,'810112',3), +(3608,'西贡区',3595,'810113',3), +(3609,'沙田区',3595,'810114',3), +(3610,'屯门区',3595,'810115',3), +(3611,'大埔区',3595,'810116',3), +(3612,'荃湾区',3595,'810117',3), +(3613,'元朗区',3595,'810118',3), +(3614,'澳门特别行政区',0,'820000',1), +(3615,'澳门特别行政区',3614,'820100',2), +(3616,'澳门半岛',3615,'820101',3), +(3617,'凼仔',3615,'820102',3), +(3618,'路凼城',3615,'820103',3), +(3619,'路环',3615,'820104',3), +(3620,'东城街道',2051,'44190',3), +(3621,'南城街道',2051,'441900',3), +(3622,'万江街道',2051,'441900',3), +(3623,'莞城街道',2051,'441900',3), +(3624,'石碣镇',2051,'441900',3), +(3625,'石龙镇',2051,'441900',3), +(3626,'茶山镇',2051,'441900',3), +(3627,'石排镇',2051,'441900',3), +(3628,'企石镇',2051,'441900',3), +(3629,'横沥镇',2051,'441900',3), +(3630,'桥头镇',2051,'441900',3), +(3631,'谢岗镇',2051,'441900',3), +(3632,'东坑镇',2051,'441900',3), +(3633,'常平镇',2051,'441900',3), +(3634,'寮步镇',2051,'441900',3), +(3635,'樟木头镇',2051,'441900',3), +(3636,'大朗镇',2051,'441900',3), +(3637,'黄江镇',2051,'441900',3), +(3638,'清溪镇',2051,'441900',3), +(3639,'塘厦镇',2051,'441900',3), +(3640,'凤岗镇',2051,'441900',3), +(3641,'大岭山镇',2051,'441900',3), +(3642,'长安镇',2051,'441900',3), +(3643,'虎门镇',2051,'441900',3), +(3644,'厚街镇',2051,'441900',3), +(3645,'沙田镇',2051,'441900',3), +(3646,'道滘镇',2051,'441900',3), +(3647,'洪梅镇',2051,'441900',3), +(3648,'麻涌镇',2051,'441900',3), +(3649,'望牛墩镇',2051,'441900',3), +(3650,'中堂镇',2051,'441900',3), +(3651,'高埗镇',2051,'441900',3), +(3652,'松山湖',2051,'441900',3), +(3653,'东莞港',2051,'441900',3), +(3654,'东莞生态园',2051,'441900',3), +(3655,'石岐街道',2052,'44200',3), +(3656,'东区街道',2052,'442000',3), +(3657,'中山港街道',2052,'442000',3), +(3658,'西区街道',2052,'442000',3), +(3659,'南区街道',2052,'442000',3), +(3660,'五桂山街道',2052,'442000',3), +(3661,'小榄镇',2052,'442000',3), +(3662,'黄圃镇',2052,'442000',3), +(3663,'民众镇',2052,'442000',3), +(3664,'东凤镇',2052,'442000',3), +(3665,'东升镇',2052,'442000',3), +(3666,'古镇镇',2052,'442000',3), +(3667,'沙溪镇',2052,'442000',3), +(3668,'坦洲镇',2052,'442000',3), +(3669,'港口镇',2052,'442000',3), +(3670,'三角镇',2052,'442000',3), +(3671,'横栏镇',2052,'442000',3), +(3672,'南头镇',2052,'442000',3), +(3673,'阜沙镇',2052,'442000',3), +(3674,'南朗镇',2052,'442000',3), +(3675,'三乡镇',2052,'442000',3), +(3676,'板芙镇',2052,'442000',3), +(3677,'大涌镇',2052,'442000',3), +(3678,'神湾镇',2052,'442000',3), +(3679,'西沙群岛',2206,'46032',3), +(3680,'南沙群岛',2206,'460322',3), +(3681,'中沙群岛的岛礁及其海域',2206,'460323',3), +(3682,'那大镇',2207,'46040',3), +(3683,'和庆镇',2207,'460400',3), +(3684,'南丰镇',2207,'460400',3), +(3685,'大成镇',2207,'460400',3), +(3686,'雅星镇',2207,'460400',3), +(3687,'兰洋镇',2207,'460400',3), +(3688,'光村镇',2207,'460400',3), +(3689,'木棠镇',2207,'460400',3), +(3690,'海头镇',2207,'460400',3), +(3691,'峨蔓镇',2207,'460400',3), +(3692,'王五镇',2207,'460400',3), +(3693,'白马井镇',2207,'460400',3), +(3694,'中和镇',2207,'460400',3), +(3695,'排浦镇',2207,'460400',3), +(3696,'东成镇',2207,'460400',3), +(3697,'新州镇',2207,'460400',3), +(3698,'洋浦经济开发区',2207,'460400',3), +(3699,'华南热作学院',2207,'460400',3), +(3700,'雄关街道',2922,'62020',3), +(3701,'钢城街道',2922,'620201',3), +(3702,'新城镇',2922,'620201',3), +(3703,'峪泉镇',2922,'620201',3), +(3704,'文殊镇',2922,'620201',3); + +/*Table structure for table `mt_send_log` */ + +DROP TABLE IF EXISTS `mt_send_log`; + +CREATE TABLE `mt_send_log` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `TYPE` tinyint(1) NOT NULL COMMENT '1:单用户发券;2:批量发券', + `USER_ID` int DEFAULT NULL COMMENT '用户ID', + `FILE_NAME` varchar(100) DEFAULT '' COMMENT '导入excel文件名', + `FILE_PATH` varchar(200) DEFAULT '' COMMENT '导入excel文件路径', + `MOBILE` varchar(20) NOT NULL COMMENT '用户手机', + `GROUP_ID` int NOT NULL COMMENT '券组ID', + `GROUP_NAME` varchar(100) DEFAULT '' COMMENT '券组名称', + `COUPON_ID` int DEFAULT '0' COMMENT '卡券ID', + `SEND_NUM` int DEFAULT NULL COMMENT '发放套数', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '操作时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '操作人', + `UUID` varchar(50) DEFAULT '' COMMENT '导入UUID', + `REMOVE_SUCCESS_NUM` int DEFAULT '0' COMMENT '作废成功张数', + `REMOVE_FAIL_NUM` int DEFAULT '0' COMMENT '作废失败张数', + `STATUS` char(1) DEFAULT NULL COMMENT '状态,A正常;B:部分作废;D全部作废', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='卡券发放记录表'; + +/*Data for the table `mt_send_log` */ + +/*Table structure for table `mt_setting` */ + +DROP TABLE IF EXISTS `mt_setting`; + +CREATE TABLE `mt_setting` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `TYPE` varchar(30) NOT NULL DEFAULT '' COMMENT '类型', + `NAME` varchar(50) NOT NULL DEFAULT '' COMMENT '配置项', + `VALUE` longtext NOT NULL COMMENT '配置值', + `DESCRIPTION` varchar(200) DEFAULT '' COMMENT '配置说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态 A启用;D禁用', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=89 DEFAULT CHARSET=utf8 COMMENT='全局设置表'; + +/*Data for the table `mt_setting` */ + +insert into `mt_setting`(`ID`,`MERCHANT_ID`,`STORE_ID`,`TYPE`,`NAME`,`VALUE`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`STATUS`) values +(1,1,0,'user','getCouponNeedPhone','false','领券是否需要手机号码','2022-03-12 13:55:55','2023-07-28 20:06:11','fuint','A'), +(2,1,0,'user','submitOrderNeedPhone','false','提交订单是否需要手机号码','2022-03-12 13:55:56','2023-07-28 20:06:11','fuint','A'), +(3,1,0,'user','loginNeedPhone','false','登录是否需要手机号','2022-03-12 13:55:56','2023-07-28 20:06:11','fuint','A'), +(6,1,0,'point','exchangeNeedPoint','100','多少积分可抵扣1元现金','2022-03-12 13:56:23','2023-09-18 17:13:21','anan','A'), +(7,1,0,'point','rechargePointSpeed','1','充值返积分倍数','2022-03-12 13:56:23','2023-09-18 17:13:21','anan','A'), +(12,1,0,'point','pointNeedConsume','1','返1积分所需消费金额','2022-05-12 11:06:55','2023-09-18 17:13:21','anan','A'), +(13,1,0,'point','canUsedAsMoney','true','是否可当作现金使用','2022-05-12 11:06:55','2023-09-18 17:13:21','anan','A'), +(18,1,0,'balance','rechargeRule','100_10,300_50','充值规则','2022-06-06 18:07:34','2023-09-18 17:19:00','anan','A'), +(47,1,0,'sub_message','balanceChange','{\"key\":\"balanceChange\",\"params\":[{\"key\":\"amount\",\"name\":\"变动金额\",\"value\":\"{{amount6.DATA}}\"},{\"key\":\"time\",\"name\":\"变动时间\",\"value\":\"{{time8.DATA}}\"},{\"key\":\"tips\",\"name\":\"温馨提示\",\"value\":\"{{thing3.DATA}}\"}],\"status\":\"A\",\"templateId\":\"6Klx5n119OFezK2AUr8J_YeNp_B2acCGNNUGoAoYsgw\",\"tid\":\"30792\"}','余额变动提醒','2022-07-05 21:22:49','2022-07-05 21:22:49','fuint','A'), +(48,1,0,'sub_message','couponConfirm','{\"key\":\"couponConfirm\",\"params\":[{\"key\":\"name\",\"name\":\"卡券名称\",\"value\":\"{{thing6.DATA}}\"},{\"key\":\"time\",\"name\":\"核销时间\",\"value\":\"{{time10.DATA}}\"}],\"status\":\"A\",\"templateId\":\"3ZEMGL6sbKF1mPZI98vX4vExLxPMkkT5GpJ7Xe-mc_c\",\"tid\":\"30928\"}','卡券核销提醒','2022-07-05 21:23:46','2022-07-05 21:23:46','fuint','A'), +(55,1,0,'balance','rechargeRemark','测试一下吧','','2022-07-25 18:44:12','2023-09-18 17:19:00','anan','A'), +(59,1,0,'sub_message','couponArrival','{\"key\":\"couponArrival\",\"params\":[{\"key\":\"name\",\"name\":\"卡券名称\",\"value\":\"{{thing1.DATA}}\"},{\"key\":\"amount\",\"name\":\"金额\",\"value\":\"{{amount3.DATA}}\"},{\"key\":\"tips\",\"name\":\"温馨提示\",\"value\":\"{{thing8.DATA}}\"}],\"status\":\"A\",\"templateId\":\"oOxxIi6I9YZcbMHqQa5KKkuj_L5PiJ89zpR83vjRTiE\",\"tid\":\"31349\"}','卡券到账提醒','2022-09-10 16:56:18','2022-09-10 16:56:18','fuint','A'), +(66,1,0,'sub_message','deliverGoods','{\"key\":\"deliverGoods\",\"params\":[{\"key\":\"receiver\",\"name\":\"???\",\"value\":\"{{thing8.DATA}}\"},{\"key\":\"orderSn\",\"name\":\"???\",\"value\":\"{{character_string2.DATA}}\"},{\"key\":\"expressCompany\",\"name\":\"????\",\"value\":\"{{thing4.DATA}}\"},{\"key\":\"expressNo\",\"name\":\"????\",\"value\":\"{{character_string5.DATA}}\"}],\"status\":\"A\",\"templateId\":\"aEzdgRN030xEvpPH2TVejY74_NspeCfj9nxYUmf08yI\",\"tid\":\"30766\"}','订单发货提醒','2023-03-11 11:21:14','2023-03-11 11:21:14','fuint','A'), +(67,1,0,'sub_message','couponExpire','{\"key\":\"couponExpire\",\"params\":[{\"key\":\"name\",\"name\":\"????\",\"value\":\"{{thing1.DATA}}\"},{\"key\":\"expireTime\",\"name\":\"????\",\"value\":\"{{time2.DATA}}\"},{\"key\":\"tips\",\"name\":\"????\",\"value\":\"{{thing5.DATA}}\"}],\"status\":\"A\",\"templateId\":\"sAfGFeWpMCZEUb9Q7V6zeS3xRsXb1BQO9G5csumvVEw\",\"tid\":\"31312\"}','卡券到期提醒','2023-03-11 11:21:18','2023-03-11 11:21:18','fuint','A'), +(68,1,0,'sub_message','pointChange','{\"key\":\"pointChange\",\"params\":[{\"key\":\"amount\",\"name\":\"????\",\"value\":\"{{thing7.DATA}}\"},{\"key\":\"time\",\"name\":\"????\",\"value\":\"{{date2.DATA}}\"},{\"key\":\"remark\",\"name\":\"????\",\"value\":\"{{thing3.DATA}}\"}],\"status\":\"A\",\"templateId\":\"MJCUWLiPDVPnuCgqsjbl5X385bowwoKwshuLmnUU5Ss\",\"tid\":\"30783\"}','积分变更提醒','2023-04-21 12:41:26','2023-04-21 12:41:26','fuint','A'), +(71,1,0,'order','deliveryFee','5','订单配送费用','2023-05-24 10:40:40','2023-07-27 10:56:45','fuint','A'), +(72,1,0,'order','isClose','false','关闭交易功能','2023-05-24 10:40:40','2023-07-27 10:56:45','fuint','A'), +(75,1,0,'sub_message','orderCreated','{\"key\":\"orderCreated\",\"params\":[{\"key\":\"time\",\"name\":\"????\",\"value\":\"{{time1.DATA}}\"},{\"key\":\"orderSn\",\"name\":\"???\",\"value\":\"{{character_string4.DATA}}\"},{\"key\":\"remark\",\"name\":\"????\",\"value\":\"{{thing5.DATA}\"}],\"status\":\"A\",\"templateId\":\"2MxTzfak92lcn-uTN4_WSv9AmuFvqmKrUXNQ7ph3rls\",\"tid\":\"31962\"}','订单生成提醒','2023-07-11 14:35:18','2023-07-11 14:35:18','fuint','A'), +(76,2,0,'user','getCouponNeedPhone','false','领券是否需要手机号码','2023-09-18 17:04:45','2023-09-18 17:04:51','anan','A'), +(77,2,0,'user','submitOrderNeedPhone','false','提交订单是否需要手机号码','2023-09-18 17:04:45','2023-09-18 17:04:51','anan','A'), +(78,2,0,'user','loginNeedPhone','true','登录是否需要手机号','2023-09-18 17:04:45','2023-09-18 17:04:51','anan','A'), +(79,2,0,'order','deliveryFee','19','订单配送费用','2023-09-18 17:10:56','2023-09-18 17:10:56','anan','A'), +(80,2,0,'order','isClose','false','关闭交易功能','2023-09-18 17:10:56','2023-09-18 17:10:56','anan','A'), +(81,2,0,'point','pointNeedConsume','10','返1积分所需消费金额','2023-09-18 17:18:30','2023-09-20 12:00:27','anan','A'), +(82,2,0,'point','canUsedAsMoney','true','是否可当作现金使用','2023-09-18 17:18:30','2023-09-20 12:00:30','anan','A'), +(83,2,0,'point','exchangeNeedPoint','100','多少积分可抵扣1元现金','2023-09-18 17:18:30','2023-09-20 12:00:32','anan','A'), +(84,2,0,'point','rechargePointSpeed','2','充值返积分倍数','2023-09-18 17:18:30','2023-09-20 12:00:32','anan','A'), +(85,2,0,'balance','rechargeRule','100_10,500_100','充值规则','2023-09-18 17:23:29','2023-09-18 17:23:29','anan','A'), +(86,2,0,'balance','rechargeRemark','测试123','','2023-09-18 17:23:29','2023-09-18 17:23:29','anan','A'), +(87,2,0,'sub_message','orderCreated','{\"key\":\"orderCreated\",\"params\":[{\"key\":\"time\",\"name\":\"订单时间\",\"value\":\"1\"},{\"key\":\"orderSn\",\"name\":\"订单号\",\"value\":\"2\"},{\"key\":\"remark\",\"name\":\"备注信息\",\"value\":\"3\"}],\"status\":\"A\",\"templateId\":\"2232\",\"tid\":\"2323\"}','订单生成提醒','2023-09-18 17:45:48','2023-09-18 17:45:48','anan','A'), +(88,1,0,'navigation','navigation','[{\"name\":\"买单付款\",\"tips\":\"支付攒积分\",\"url\":\"pages/pay/index\",\"icon\":\"/static/defaultImage/1.png\",\"iconUrl\":\"https://fuint-application.oss-cn-shenzhen.aliyuncs.com/uploads/20250925/f05dc9f2403a43d3b8d3355e48abc825.png\",\"sort\":5,\"status\":\"N\"},{\"name\":\"核销卡券\",\"tips\":\"券码轻松核销\",\"url\":\"pages/my-coupon/index\",\"icon\":\"/static/defaultImage/1.png\",\"iconUrl\":\"\",\"sort\":4,\"status\":\"A\"},{\"name\":\"领券中心\",\"tips\":\"积分换好礼\",\"url\":\"subPages/coupon/list?type=C\",\"icon\":\"/static/defaultImage/2.png\",\"iconUrl\":\"https://fuint-appl\",\"sort\":3,\"status\":\"A\"},{\"name\":\"预存充值\",\"tips\":\"充值享优惠\",\"url\":\"subPages/coupon/list?type=P\",\"icon\":\"/static/defaultImage/3.png\",\"iconUrl\":\"\",\"sort\":2,\"status\":\"A\"},{\"name\":\"邀请有礼\",\"tips\":\"邀好友得奖励\\\"\",\"url\":\"pages/share/index\",\"icon\":\"/static/defaultImage/4.png\",\"iconUrl\":\"\",\"sort\":1,\"status\":\"A\"}]','',NULL,NULL,'','A'); + +/*Table structure for table `mt_settlement` */ + +DROP TABLE IF EXISTS `mt_settlement`; + +CREATE TABLE `mt_settlement` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `SETTLEMENT_NO` varchar(32) DEFAULT NULL COMMENT '结算单号', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `SETTLE_RATE` decimal(10,0) DEFAULT NULL COMMENT '结算比例', + `TOTAL_ORDER_AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '订单总金额', + `AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '结算金额', + `DESCRIPTION` varchar(1000) DEFAULT '' COMMENT '备注说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `PAY_STATUS` char(1) DEFAULT '' COMMENT '支付状态', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='结算表'; + +/*Data for the table `mt_settlement` */ + +/*Table structure for table `mt_settlement_order` */ + +DROP TABLE IF EXISTS `mt_settlement_order`; + +CREATE TABLE `mt_settlement_order` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `SETTLEMENT_ID` int NOT NULL DEFAULT '0' COMMENT '结算ID', + `ORDER_ID` int DEFAULT '0' COMMENT '订单ID', + `DESCRIPTION` varchar(1000) DEFAULT '' COMMENT '备注说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='结算订单表'; + +/*Data for the table `mt_settlement_order` */ + +/*Table structure for table `mt_sms_sended_log` */ + +DROP TABLE IF EXISTS `mt_sms_sended_log`; + +CREATE TABLE `mt_sms_sended_log` ( + `LOG_ID` int NOT NULL AUTO_INCREMENT COMMENT '日志ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `MOBILE_PHONE` varchar(32) DEFAULT NULL COMMENT '手机号', + `CONTENT` varchar(1024) DEFAULT NULL COMMENT '短信内容', + `SEND_TIME` datetime DEFAULT NULL COMMENT '发送时间', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`LOG_ID`), + KEY `FK_REFERENCE_1` (`MOBILE_PHONE`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='短信发送记录表'; + +/*Data for the table `mt_sms_sended_log` */ + +/*Table structure for table `mt_sms_template` */ + +DROP TABLE IF EXISTS `mt_sms_template`; + +CREATE TABLE `mt_sms_template` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `NAME` varchar(50) NOT NULL DEFAULT '' COMMENT '名称', + `UNAME` varchar(50) NOT NULL DEFAULT '' COMMENT '英文名称', + `CODE` varchar(30) NOT NULL DEFAULT '' COMMENT '编码', + `CONTENT` varchar(255) NOT NULL DEFAULT '' COMMENT '内容', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT '状态:A激活;N禁用', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=utf8 COMMENT='短信模板'; + +/*Data for the table `mt_sms_template` */ + +insert into `mt_sms_template`(`ID`,`MERCHANT_ID`,`STORE_ID`,`NAME`,`UNAME`,`CODE`,`CONTENT`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`STATUS`) values +(1,1,0,'会员登录验证码','login-code','SMS_129758678','您的验证码是:{code},该验证码仅用于登录验证,请放心泄露给他人使用哈。','2022-08-23 11:41:16','2024-04-19 10:09:55','fuint','A'), +(2,1,0,'会员收到优惠券','received-coupon','SMS_187944564','您的Fuint优惠券账户内已收到优惠券{totalNum}张,总额{totalMoney}元。请您关注Fuint公众号(Fuint卡券系统),在我的优惠券中通过本手机号登录查看。','2022-05-11 09:27:14','2023-12-23 16:31:50','fuint','A'), +(3,1,0,'优惠券被核销','confirm-coupon','SMS_129758679','尊敬的用户,您的[{couponName}]已在[{storeName}]完成核销,该券消费流水号为[{sn}],谢谢您的光临!','2020-04-18 17:06:25','2023-12-23 16:31:44','sysadmin','A'), +(4,1,0,'会员注册完成','register-sms','SMS_129768678','您的Fuint优惠券账户已注册完成。请您关注Fuint卡券公众号(Fuint卡券系统),在我的优惠券中通过本手机号登录查看。','2020-04-18 17:15:11','2023-12-23 16:31:47','sysadmin','A'), +(5,1,0,'核销人员审核通过','confirmer-authed','SMS_129756978','{name},您的店铺核销人员登记已完成审核,可以在{storeName}进行优惠券核销,谢谢!','2020-04-18 17:07:03','2023-12-23 16:31:46','sysadmin','A'), +(6,1,0,'商家订单通知','new-order','SMS_129758679','您有一条新的订单,单号:{orderSn},请及时处理!','2024-03-22 10:18:39','2024-03-22 10:20:03','','A'), +(7,1,0,'余额变动通知','balance-change','SMS_465905304','尊敬的会员,您的余额发生了变动,变动金额:${amount}元,余额:${balance}元。祝您生活愉快!','2024-04-29 09:11:07','2024-04-29 09:11:07','','A'), +(8,1,0,'积分变动通知','points-change','SMS_465945361','尊敬的会员,您的积分发生了变动,变动数量:${amount},剩余积分:${balance}。祝您生活愉快!','2024-04-29 09:12:27','2024-04-29 11:59:42','','A'); + +/*Table structure for table `mt_staff` */ + +DROP TABLE IF EXISTS `mt_staff`; + +CREATE TABLE `mt_staff` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `USER_ID` int DEFAULT '0' COMMENT '用户ID', + `CATEGORY` int DEFAULT '0' COMMENT '员工类别,1:店长;2:收银员;3:销售人员;3:服务人员;', + `MOBILE` varchar(16) NOT NULL DEFAULT '' COMMENT '手机号码', + `REAL_NAME` varchar(30) DEFAULT '' COMMENT '真实姓名', + `WECHAT` varchar(64) DEFAULT NULL COMMENT '微信号', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `AUDITED_STATUS` char(1) DEFAULT 'U' COMMENT '审核状态,A:审核通过;U:未审核;D:无效; ', + `AUDITED_TIME` datetime DEFAULT NULL COMMENT '审核时间', + `DESCRIPTION` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='店铺员工表'; + +/*Data for the table `mt_staff` */ + +insert into `mt_staff`(`ID`,`MERCHANT_ID`,`STORE_ID`,`USER_ID`,`CATEGORY`,`MOBILE`,`REAL_NAME`,`WECHAT`,`CREATE_TIME`,`UPDATE_TIME`,`AUDITED_STATUS`,`AUDITED_TIME`,`DESCRIPTION`) values +(4,1,3,2,1,'16671050702','符小安',NULL,'2023-07-24 18:57:49','2024-07-01 10:44:58','A','2024-07-01 10:44:58','123'), +(5,1,3,1,2,'16671050703','符SQ',NULL,'2023-07-24 20:12:31','2024-07-01 10:44:37','A','2024-07-01 10:44:37','123'); + +/*Table structure for table `mt_stock` */ + +DROP TABLE IF EXISTS `mt_stock`; + +CREATE TABLE `mt_stock` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int NOT NULL DEFAULT '0' COMMENT '店铺ID', + `TYPE` varchar(20) NOT NULL DEFAULT 'increase' COMMENT '类型,increase:入库,reduce:出库', + `DESCRIPTION` varchar(1000) DEFAULT '' COMMENT '备注说明', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) NOT NULL DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='库存管理记录表'; + +/*Data for the table `mt_stock` */ + +/*Table structure for table `mt_stock_item` */ + +DROP TABLE IF EXISTS `mt_stock_item`; + +CREATE TABLE `mt_stock_item` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `STOCK_ID` int NOT NULL DEFAULT '0' COMMENT '库存管理ID', + `GOODS_ID` int NOT NULL DEFAULT '0' COMMENT '商品ID', + `SKU_ID` int NOT NULL DEFAULT '0' COMMENT 'SKUID', + `NUM` double(10,2) unsigned DEFAULT '0.00' COMMENT '数量', + `DESCRIPTION` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '说明备注', + `CREATE_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime NOT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'A' COMMENT '订单状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='库存管理明细表'; + +/*Data for the table `mt_stock_item` */ + +/*Table structure for table `mt_store` */ + +DROP TABLE IF EXISTS `mt_store`; + +CREATE TABLE `mt_store` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int unsigned DEFAULT '0' COMMENT '所属商户', + `NAME` varchar(50) NOT NULL DEFAULT '' COMMENT '店铺名称', + `QR_CODE` varchar(255) DEFAULT '' COMMENT '店铺二维码', + `LOGO` varchar(100) DEFAULT '' COMMENT '店铺LOGO', + `IS_DEFAULT` char(1) NOT NULL DEFAULT 'N' COMMENT '是否默认', + `CONTACT` varchar(30) DEFAULT '' COMMENT '联系人姓名', + `WX_MCH_ID` varchar(30) DEFAULT '' COMMENT '微信支付商户号', + `WX_API_V2` varchar(32) DEFAULT '' COMMENT '微信支付APIv2密钥', + `WX_CERT_PATH` varchar(255) DEFAULT '' COMMENT '微信支付证书', + `ALIPAY_APP_ID` varchar(100) DEFAULT '' COMMENT '支付宝appId', + `ALIPAY_PRIVATE_KEY` varchar(5000) DEFAULT '' COMMENT '支付宝应用私钥', + `ALIPAY_PUBLIC_KEY` varchar(5000) DEFAULT '' COMMENT '支付宝应用公钥', + `PHONE` varchar(20) DEFAULT '' COMMENT '联系电话', + `ADDRESS` varchar(100) DEFAULT '' COMMENT '地址', + `LATITUDE` varchar(30) DEFAULT '' COMMENT '经度', + `LONGITUDE` varchar(30) DEFAULT '' COMMENT '维度', + `DISTANCE` decimal(10,2) DEFAULT '0.00' COMMENT '距离', + `HOURS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '营业时间', + `LICENSE` varchar(255) DEFAULT '' COMMENT '营业执照', + `CREDIT_CODE` varchar(50) DEFAULT '' COMMENT '统一社会信用码', + `BANK_NAME` varchar(100) DEFAULT '' COMMENT '银行名称', + `BANK_CARD_NAME` varchar(100) DEFAULT '' COMMENT '银行卡账户名', + `BANK_CARD_NO` varchar(100) DEFAULT '' COMMENT '银行卡卡号', + `DESCRIPTION` varchar(2000) DEFAULT '' COMMENT '备注信息', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:有效/启用;D:无效', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED COMMENT='店铺表'; + +/*Data for the table `mt_store` */ + +insert into `mt_store`(`ID`,`MERCHANT_ID`,`NAME`,`QR_CODE`,`LOGO`,`IS_DEFAULT`,`CONTACT`,`WX_MCH_ID`,`WX_API_V2`,`WX_CERT_PATH`,`ALIPAY_APP_ID`,`ALIPAY_PRIVATE_KEY`,`ALIPAY_PUBLIC_KEY`,`PHONE`,`ADDRESS`,`LATITUDE`,`LONGITUDE`,`DISTANCE`,`HOURS`,`LICENSE`,`CREDIT_CODE`,`BANK_NAME`,`BANK_CARD_NAME`,`BANK_CARD_NO`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`,`OPERATOR`) values +(2,1,'海口解放路店','','','N','李思','','','','','','','18956185345','海口市解放西路10号','20.04013','110.34120',0.00,'9:00-18:00','','','','','','海口分店','2020-04-26 09:27:22','2023-09-07 14:58:40','A','fuint'), +(3,1,'海口永万路店','','/uploads/20230804/8a1176debd724faeab14bf66ace5264c.png','N','张易','','','','','','','13800138001','海口市永万路7号2楼01室','20.004229','110.273855',0.00,'9:00-22:00','/uploads/20230804/f80754b1973347b3832ceff604a3153f.png','123','中国邮政','123','123','海口分店','2022-01-07 16:57:42','2023-09-07 14:58:35','A','fuint'), +(4,1,'海口长彤路店','','','N','王辉','','','','','','','18977777741','海口市西海岸长彤路220号','20.01874','110.34967',0.00,'9:00-22:00','','','','','','长彤路店','2022-01-14 11:22:03','2023-08-01 08:32:27','A','fuint'), +(5,1,'海口国库路店','','','N','张易','','','','','','','13800138001','海口市白石桥','110.293768','19.99326',0.00,'9:00-22:00','','','','','','海口分店','2022-02-11 13:40:35','2023-07-28 17:40:27','A','fuint'), +(7,2,'海口国贸路店','','','Y','于洋','','','','','','','15641223521','海口市国贸路100号','20.01989','110.26767',0.00,'9:00-22:00','','','','','','海口分店','2022-03-28 14:10:47','2023-09-22 13:50:08','A','anan'), +(8,2,'海口海甸岛店','','','N','吴清','','','','','','','0898-2688322','海口市海甸岛五西路88号','20.01129','110.34867',0.00,'9:00-22:00','','','','','','海口分店','2022-04-03 10:24:43','2023-08-01 14:11:30','A','fuint'); + +/*Table structure for table `mt_store_goods` */ + +DROP TABLE IF EXISTS `mt_store_goods`; + +CREATE TABLE `mt_store_goods` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int unsigned NOT NULL DEFAULT '0' COMMENT '所属商户', + `STORE_ID` int NOT NULL DEFAULT '0' COMMENT '所属店铺', + `GOODS_ID` int NOT NULL DEFAULT '0' COMMENT '商品ID', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:有效/启用;D:无效', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`), + KEY `INDEX_STORE_ID` (`STORE_ID`), + KEY `INDEX_GOODS_ID` (`GOODS_ID`) +) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED COMMENT='店铺商品表'; + +/*Data for the table `mt_store_goods` */ + +insert into `mt_store_goods`(`ID`,`MERCHANT_ID`,`STORE_ID`,`GOODS_ID`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`,`OPERATOR`) values +(1,1,2,6,'2025-03-13 18:17:39','2025-03-13 18:17:39','A','fuint'), +(2,1,3,6,'2025-03-13 18:17:39','2025-03-13 18:17:39','A','fuint'), +(3,1,4,6,'2025-03-13 18:17:39','2025-03-13 18:17:39','A','fuint'), +(4,1,5,6,'2025-03-13 18:17:39','2025-03-13 18:17:39','A','fuint'), +(5,1,2,1,'2025-03-13 18:17:50','2025-03-13 18:17:50','A','fuint'), +(6,1,3,1,'2025-03-13 18:17:50','2025-03-13 18:17:50','A','fuint'), +(7,1,4,1,'2025-03-13 18:17:50','2025-03-13 18:17:50','A','fuint'), +(8,1,5,1,'2025-03-13 18:17:50','2025-03-13 18:17:50','A','fuint'), +(9,1,2,2,'2025-03-13 18:18:01','2025-03-13 18:18:01','A','fuint'), +(10,1,3,2,'2025-03-13 18:18:01','2025-03-13 18:18:01','A','fuint'), +(11,1,4,2,'2025-03-13 18:18:01','2025-03-13 18:18:01','A','fuint'), +(12,1,5,2,'2025-03-13 18:18:01','2025-03-13 18:18:01','A','fuint'), +(13,1,2,3,'2025-03-13 18:18:12','2025-03-13 18:18:12','A','fuint'), +(14,1,3,3,'2025-03-13 18:18:12','2025-03-13 18:18:12','A','fuint'), +(15,1,4,3,'2025-03-13 18:18:12','2025-03-13 18:18:12','A','fuint'), +(16,1,5,3,'2025-03-13 18:18:12','2025-03-13 18:18:12','A','fuint'), +(17,1,2,4,'2025-03-13 18:18:23','2025-03-13 18:18:23','A','fuint'), +(18,1,3,4,'2025-03-13 18:18:23','2025-03-13 18:18:23','A','fuint'), +(19,1,4,4,'2025-03-13 18:18:23','2025-03-13 18:18:23','A','fuint'), +(20,1,5,4,'2025-03-13 18:18:23','2025-03-13 18:18:23','A','fuint'), +(21,1,2,5,'2025-03-13 18:18:34','2025-03-13 18:18:34','A','fuint'), +(22,1,3,5,'2025-03-13 18:18:34','2025-03-13 18:18:34','A','fuint'), +(23,1,4,5,'2025-03-13 18:18:34','2025-03-13 18:18:34','A','fuint'), +(24,1,5,5,'2025-03-13 18:18:34','2025-03-13 18:18:34','A','fuint'); + +/*Table structure for table `mt_upload_shipping_log` */ + +DROP TABLE IF EXISTS `mt_upload_shipping_log`; + +CREATE TABLE `mt_upload_shipping_log` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `ORDER_ID` int DEFAULT '0' COMMENT '订单ID', + `ORDER_SN` varchar(100) DEFAULT '' COMMENT '订单号', + `MOBILE` varchar(20) DEFAULT '' COMMENT '手机号', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `OPERATOR` varchar(30) DEFAULT NULL COMMENT '最后操作人', + `STATUS` char(1) DEFAULT 'A' COMMENT 'A:成功;B:失败', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信小程序上传发货信息记录表'; + +/*Data for the table `mt_upload_shipping_log` */ + +/*Table structure for table `mt_user` */ + +DROP TABLE IF EXISTS `mt_user`; + +CREATE TABLE `mt_user` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '会员ID', + `MOBILE` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '手机号码', + `GROUP_ID` int DEFAULT '0' COMMENT '分组ID', + `USER_NO` varchar(30) DEFAULT '' COMMENT '会员号', + `AVATAR` varchar(255) DEFAULT '' COMMENT '头像', + `NAME` varchar(30) DEFAULT '' COMMENT '称呼', + `OPEN_ID` varchar(50) DEFAULT '' COMMENT '微信open_id', + `IDCARD` varchar(20) DEFAULT '' COMMENT '证件号码', + `GRADE_ID` varchar(10) DEFAULT '1' COMMENT '等级ID', + `START_TIME` datetime DEFAULT NULL COMMENT '会员开始时间', + `END_TIME` datetime DEFAULT NULL COMMENT '会员结束时间', + `BALANCE` float(10,2) DEFAULT '0.00' COMMENT '余额', + `POINT` int DEFAULT '0' COMMENT '积分', + `SEX` int DEFAULT '1' COMMENT '性别 1男;0女', + `BIRTHDAY` varchar(20) DEFAULT '' COMMENT '出生日期', + `CAR_NO` varchar(10) DEFAULT '' COMMENT '车牌号', + `SOURCE` varchar(30) DEFAULT '' COMMENT '来源渠道', + `PASSWORD` varchar(32) DEFAULT '' COMMENT '密码', + `SALT` varchar(4) DEFAULT '' COMMENT 'salt', + `ADDRESS` varchar(100) DEFAULT '' COMMENT '地址', + `MERCHANT_ID` int DEFAULT '0' COMMENT '所属商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '所属店铺ID', + `IS_STAFF` char(1) DEFAULT 'N' COMMENT '是否员工', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:激活;N:禁用;D:删除', + `DESCRIPTION` varchar(255) DEFAULT '' COMMENT '备注信息', + `IP` varchar(20) DEFAULT '' COMMENT '注册IP', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`), + KEY `index_phone` (`MOBILE`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='会员个人信息'; + +/*Data for the table `mt_user` */ + +insert into `mt_user`(`ID`,`MOBILE`,`GROUP_ID`,`USER_NO`,`AVATAR`,`NAME`,`OPEN_ID`,`IDCARD`,`GRADE_ID`,`START_TIME`,`END_TIME`,`BALANCE`,`POINT`,`SEX`,`BIRTHDAY`,`CAR_NO`,`SOURCE`,`PASSWORD`,`SALT`,`ADDRESS`,`MERCHANT_ID`,`STORE_ID`,`IS_STAFF`,`CREATE_TIME`,`UPDATE_TIME`,`STATUS`,`DESCRIPTION`,`IP`,`OPERATOR`) values +(1,'',0,'8546130940096','','符SQ','','','1',NULL,NULL,0.00,1000,1,'','','backend_add','','','',1,3,'Y','2024-04-09 14:40:19','2024-07-01 10:44:37','A','系统自动注册店铺员工账号','',''), +(2,'',0,'8876626060558','','符小安','','','1',NULL,NULL,0.00,1000,1,'','','backend_add','','','',1,3,'Y','2024-04-09 14:40:21','2024-07-01 10:44:58','A','系统自动注册店铺员工账号','',''); + +/*Table structure for table `mt_user_action` */ + +DROP TABLE IF EXISTS `mt_user_action`; + +CREATE TABLE `mt_user_action` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `USER_ID` int NOT NULL COMMENT '会员ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `ACTION` varchar(30) DEFAULT '' COMMENT '行为类别', + `DESCRIPTION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '备注信息', + `PARAM` varchar(255) DEFAULT '' COMMENT '参数', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态,A:激活;N:禁用;D:删除', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + PRIMARY KEY (`ID`), + KEY `index_user_id` (`USER_ID`,`ACTION`,`PARAM`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员行为记录表'; + +/*Data for the table `mt_user_action` */ + +/*Table structure for table `mt_user_coupon` */ + +DROP TABLE IF EXISTS `mt_user_coupon`; + +CREATE TABLE `mt_user_coupon` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `CODE` varchar(32) NOT NULL DEFAULT '' COMMENT '编码', + `TYPE` char(1) NOT NULL DEFAULT 'C' COMMENT '券类型,C优惠券;P预存卡;T集次卡', + `IMAGE` varchar(100) DEFAULT '' COMMENT '效果图', + `GROUP_ID` int NOT NULL DEFAULT '0' COMMENT '券组ID', + `COUPON_ID` int NOT NULL DEFAULT '0' COMMENT '券ID', + `MOBILE` varchar(20) DEFAULT '' COMMENT '用户手机号码', + `USER_ID` int DEFAULT '0' COMMENT '用户ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '使用店铺ID', + `AMOUNT` decimal(10,2) DEFAULT '0.00' COMMENT '面额', + `BALANCE` decimal(10,2) DEFAULT '0.00' COMMENT '余额', + `STATUS` char(1) NOT NULL DEFAULT '1' COMMENT '状态:A:未使用;B:已使用;C:已过期; D:已删除;E:未领取', + `USED_TIME` datetime DEFAULT NULL COMMENT '使用时间', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间', + `EXPIRE_TIME` datetime DEFAULT NULL COMMENT '过期时间', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `UUID` varchar(50) DEFAULT '' COMMENT '导入UUID', + `ORDER_ID` int DEFAULT '0' COMMENT '订单ID', + PRIMARY KEY (`ID`), + KEY `index_user_id` (`USER_ID`), + KEY `index_coupon_id` (`COUPON_ID`), + KEY `index_group_id` (`GROUP_ID`) USING BTREE, + KEY `index_code` (`CODE`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='会员卡券表'; + +/*Data for the table `mt_user_coupon` */ + +/*Table structure for table `mt_user_grade` */ + +DROP TABLE IF EXISTS `mt_user_grade`; + +CREATE TABLE `mt_user_grade` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `GRADE` tinyint DEFAULT '1' COMMENT '等级', + `NAME` varchar(30) DEFAULT '' COMMENT '等级名称', + `CATCH_CONDITION` varchar(255) DEFAULT '' COMMENT '升级会员等级条件描述', + `CATCH_TYPE` varchar(30) DEFAULT 'pay' COMMENT '升级会员等级条件,init:默认获取;pay:付费升级;frequency:消费次数;amount:累积消费金额升级', + `CATCH_VALUE` float(10,2) DEFAULT '0.00' COMMENT '达到升级条件的值', + `USER_PRIVILEGE` varchar(1000) DEFAULT '' COMMENT '会员权益描述', + `VALID_DAY` int DEFAULT '0' COMMENT '有效期', + `DISCOUNT` float(5,2) DEFAULT '0.00' COMMENT '享受折扣', + `SPEED_POINT` float(5,2) DEFAULT '1.00' COMMENT '积分加速', + `STATUS` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=84 DEFAULT CHARSET=utf8 COMMENT='会员等级表'; + +/*Data for the table `mt_user_grade` */ + +insert into `mt_user_grade`(`ID`,`MERCHANT_ID`,`GRADE`,`NAME`,`CATCH_CONDITION`,`CATCH_TYPE`,`CATCH_VALUE`,`USER_PRIVILEGE`,`VALID_DAY`,`DISCOUNT`,`SPEED_POINT`,`STATUS`) values +(1,1,1,'普通会员','默认取得','init',0.00,'基础会员1',0,0.00,0.00,'A'), +(2,1,2,'铜牌会员','铜牌会员','pay',800.00,'铜牌会员',100,7.80,1.00,'A'), +(4,1,3,'银牌会员','付费升级','pay',1000.00,'123',100,8.50,2.00,'A'), +(5,1,4,'金牌会员','付费升级','pay',2000.00,'1、9折,2、双倍积分',100,8.00,2.00,'A'), +(6,1,5,'钻牌会员','付费升级','frequency',500.00,'1、8折,2、5倍积分',100,5.00,3.00,'A'); + +/*Table structure for table `mt_user_group` */ + +DROP TABLE IF EXISTS `mt_user_group`; + +CREATE TABLE `mt_user_group` ( + `ID` int NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `MERCHANT_ID` int DEFAULT '0' COMMENT '商户ID', + `STORE_ID` int DEFAULT '0' COMMENT '店铺ID', + `NAME` varchar(100) NOT NULL DEFAULT '' COMMENT '分组名称', + `PARENT_ID` int DEFAULT '0' COMMENT '父ID', + `DESCRIPTION` varchar(2000) DEFAULT '' COMMENT '备注', + `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建日期', + `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期', + `OPERATOR` varchar(30) DEFAULT '' COMMENT '最后操作人', + `STATUS` char(1) NOT NULL DEFAULT 'A' COMMENT 'A:正常;D:删除', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='会员分组'; + +/*Data for the table `mt_user_group` */ + +insert into `mt_user_group`(`ID`,`MERCHANT_ID`,`STORE_ID`,`NAME`,`PARENT_ID`,`DESCRIPTION`,`CREATE_TIME`,`UPDATE_TIME`,`OPERATOR`,`STATUS`) values +(1,1,0,'默认分组',0,'','2023-10-23 14:57:39','2023-10-23 14:57:39','fuint','A'); + +/*Table structure for table `mt_verify_code` */ + +DROP TABLE IF EXISTS `mt_verify_code`; + +CREATE TABLE `mt_verify_code` ( + `ID` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `MOBILE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号', + `VERIFY_CODE` char(6) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '验证码', + `ADD_TIME` datetime DEFAULT NULL COMMENT '创建时间', + `EXPIRE_TIME` datetime DEFAULT NULL COMMENT '过期时间', + `USED_TIME` datetime DEFAULT NULL COMMENT '使用时间', + `VALID_FLAG` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '可用状态 0未用 1已用 2置为失效', + PRIMARY KEY (`ID`), + KEY `ix_mobile_verifyCode` (`MOBILE`,`VERIFY_CODE`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='短信验证码表'; + +/*Data for the table `mt_verify_code` */ + +/*Table structure for table `t_account` */ + +DROP TABLE IF EXISTS `t_account`; + +CREATE TABLE `t_account` ( + `acct_id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', + `account_key` varchar(23) NOT NULL DEFAULT '' COMMENT '账户编码', + `account_name` varchar(20) NOT NULL DEFAULT '' COMMENT '账户名称', + `password` varchar(100) NOT NULL DEFAULT '' COMMENT '密码', + `account_status` int NOT NULL DEFAULT '1' COMMENT '0 无效 1 有效', + `is_active` int NOT NULL DEFAULT '0' COMMENT '0 未激活 1已激活', + `create_date` datetime NOT NULL COMMENT '创建时间', + `modify_date` datetime NOT NULL COMMENT '修改时间', + `salt` varchar(64) NOT NULL DEFAULT '' COMMENT '随机码', + `role_ids` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色ID', + `locked` int NOT NULL DEFAULT '0' COMMENT '是否禁用', + `owner_id` int DEFAULT NULL COMMENT '所属平台', + `real_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '姓名', + `merchant_id` int DEFAULT '0' COMMENT '所属商户ID', + `store_id` int DEFAULT '0' COMMENT '所属店铺ID', + `staff_id` int DEFAULT '0' COMMENT '关联员工ID', + PRIMARY KEY (`acct_id`), + KEY `FKmlsqc08c6khxhoed7abkl2s9l` (`owner_id`) +) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + +/*Data for the table `t_account` */ + +insert into `t_account`(`acct_id`,`account_key`,`account_name`,`password`,`account_status`,`is_active`,`create_date`,`modify_date`,`salt`,`role_ids`,`locked`,`owner_id`,`real_name`,`merchant_id`,`store_id`,`staff_id`) values +(1,'20230714677851484251776','fuint','cb4c1e2741076af41c548e888fe3f2be9e5e69d8',1,1,'2019-10-25 15:54:17','2025-09-25 15:10:54','405c73e643551163','2',0,NULL,'管理员',1,0,4), +(2,'20231016340951724856742','admin','cb4c1e2741076af41c548e888fe3f2be9e5e69d8',1,0,'2021-10-12 22:19:32','2023-07-24 22:35:34','405c73e643551163','2',0,1,'超管',0,0,4), +(3,'20231016344347831674930','store','2de84820760676616c115532b4126cd2823107d2',1,1,'2021-10-16 20:39:43','2023-09-14 20:03:53','5fe163d5c1a994cd','2',0,NULL,'店铺账号',1,3,4), +(4,'20231016344347831674939','anan','5e5493ee99df9620c45e7dfa86acb88ab616f502',1,0,'2023-09-18 16:45:56','2023-09-20 15:55:26','0398f5e701aae324',NULL,0,NULL,'安安',2,0,8), +(92,'20230920171105560407934','atago','d597bb73f205362a96bd5b5c230e0b882a13c47c',1,0,'2023-09-20 17:33:56','2023-09-20 17:33:56','c6a02f97d060aeef',NULL,0,NULL,'符号',1,3,4); + +/*Table structure for table `t_account_duty` */ + +DROP TABLE IF EXISTS `t_account_duty`; + +CREATE TABLE `t_account_duty` ( + `acc_duty_id` int NOT NULL AUTO_INCREMENT COMMENT '账户角色ID', + `acct_id` int NOT NULL COMMENT '账户ID', + `duty_id` int NOT NULL COMMENT '角色ID', + PRIMARY KEY (`acc_duty_id`), + KEY `FKcym10gcigo2c175iqqjj7xu5h` (`acct_id`), + KEY `FKpfts0wq2y4xhq9vv2g7uo1kr0` (`duty_id`) +) ENGINE=InnoDB AUTO_INCREMENT=754 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + +/*Data for the table `t_account_duty` */ + +insert into `t_account_duty`(`acc_duty_id`,`acct_id`,`duty_id`) values +(259,5,2), +(273,4,2), +(281,8,2), +(295,11,2), +(300,12,2), +(303,13,2), +(304,13,7), +(305,13,8), +(306,14,8), +(314,15,2), +(315,15,8), +(316,15,7), +(324,16,7), +(332,17,8), +(335,19,7), +(336,20,7), +(337,20,2), +(338,20,8), +(357,21,8), +(360,22,7), +(361,18,8), +(364,23,7), +(365,24,7), +(367,25,8), +(368,25,2), +(369,25,7), +(374,28,8), +(375,29,7), +(385,30,10), +(391,31,7), +(392,31,8), +(393,31,10), +(397,32,7), +(404,35,8), +(405,26,7), +(406,26,8), +(407,27,8), +(417,36,11), +(418,37,2), +(419,34,7), +(431,33,8), +(433,39,2), +(457,41,8), +(458,40,8), +(459,38,7), +(460,42,8), +(462,43,8), +(488,44,8), +(489,46,8), +(490,47,7), +(492,48,12), +(496,49,2), +(497,49,7), +(498,49,8), +(499,49,10), +(500,49,11), +(501,49,12), +(502,50,7), +(503,51,10), +(505,52,13), +(506,53,2), +(507,53,7), +(510,45,2), +(511,45,7), +(512,45,8), +(513,45,10), +(514,45,11), +(515,45,12), +(516,55,2), +(517,55,7), +(518,55,8), +(519,55,10), +(520,55,11), +(521,55,12), +(522,55,13), +(523,55,14), +(524,56,7), +(525,56,8), +(526,56,10), +(527,56,11), +(528,56,12), +(529,56,13), +(530,56,14), +(531,57,11), +(533,54,14), +(542,58,8), +(543,59,7), +(544,60,13), +(548,61,7), +(549,61,13), +(579,63,2), +(580,62,8), +(589,64,7), +(590,64,8), +(596,65,8), +(612,70,2), +(613,70,7), +(614,72,2), +(615,72,7), +(616,72,8), +(617,72,10), +(618,72,11), +(619,72,12), +(620,72,13), +(621,72,14), +(622,72,18), +(623,72,19), +(624,74,8), +(659,77,19), +(664,69,13), +(665,78,7), +(670,80,8), +(671,84,2), +(689,2,2), +(690,2,7), +(691,2,8), +(716,87,7), +(717,87,8), +(728,88,8), +(730,3,8), +(748,89,7), +(749,90,10), +(750,91,10), +(751,92,10), +(753,1,7); + +/*Table structure for table `t_action_log` */ + +DROP TABLE IF EXISTS `t_action_log`; + +CREATE TABLE `t_action_log` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `merchant_id` int DEFAULT '0' COMMENT '商户ID', + `store_id` int DEFAULT '0' COMMENT '店铺ID', + `action_time` datetime DEFAULT NULL COMMENT '操作时间', + `time_consuming` decimal(11,0) DEFAULT NULL COMMENT '耗时', + `client_ip` varchar(50) DEFAULT NULL COMMENT '客户端IP', + `module` varchar(255) DEFAULT NULL COMMENT '操作模块', + `url` varchar(255) DEFAULT NULL COMMENT '请求URL', + `acct_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作用户账户', + `user_agent` varchar(255) DEFAULT NULL COMMENT '用户系统以及浏览器信息', + `client_port` int DEFAULT NULL COMMENT '端口号', + `param` text COMMENT '参数', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + +/*Data for the table `t_action_log` */ + +/*Table structure for table `t_duty` */ + +DROP TABLE IF EXISTS `t_duty`; + +CREATE TABLE `t_duty` ( + `merchant_id` int DEFAULT '0' COMMENT '商户ID', + `duty_id` int NOT NULL AUTO_INCREMENT COMMENT '角色ID', + `duty_name` varchar(240) DEFAULT NULL COMMENT '角色名称', + `status` varchar(6) NOT NULL COMMENT '状态(A: 可用 D: 禁用)', + `description` varchar(400) DEFAULT NULL COMMENT '描述', + `duty_type` varchar(50) NOT NULL COMMENT '角色类型', + PRIMARY KEY (`duty_id`) +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色表'; + +/*Data for the table `t_duty` */ + +insert into `t_duty`(`merchant_id`,`duty_id`,`duty_name`,`status`,`description`,`duty_type`) values +(0,2,'系统管理员','A','系统管理员','1'), +(0,7,'商户管理员','A','商户管理员','2'), +(0,8,'店铺管理员','A','店铺管理员','2'), +(1,10,'店铺服务员','A','店铺服务员','3'), +(1,11,'店铺销售员','A','店铺销售员','3'), +(1,12,'店铺店长','A','店铺店长','3'); + +/*Table structure for table `t_duty_source` */ + +DROP TABLE IF EXISTS `t_duty_source`; + +CREATE TABLE `t_duty_source` ( + `duty_source_id` int NOT NULL AUTO_INCREMENT, + `duty_id` int DEFAULT NULL, + `source_id` int DEFAULT NULL, + PRIMARY KEY (`duty_source_id`), + KEY `FKlciudb88j4tptc36d43ghl5dg` (`duty_id`), + KEY `FKp1c59mwxgjue4qdl86sd6dogf` (`source_id`) +) ENGINE=InnoDB AUTO_INCREMENT=13809 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + +/*Data for the table `t_duty_source` */ + +insert into `t_duty_source`(`duty_source_id`,`duty_id`,`source_id`) values +(9387,10,61), +(9388,10,79), +(9389,10,80), +(9390,10,103), +(9391,10,108), +(9392,10,110), +(9393,10,122), +(9394,10,123), +(9523,11,1), +(9524,11,2), +(9525,11,3), +(9526,11,4), +(9527,11,5), +(9528,11,6), +(9529,11,7), +(9530,11,9), +(9531,11,15), +(9532,11,16), +(9533,11,17), +(9534,11,18), +(9535,11,19), +(9536,11,49), +(13252,12,158), +(13253,12,140), +(13254,12,117), +(13255,12,119), +(13256,12,102), +(13257,12,93), +(13258,12,112), +(13259,12,101), +(13260,12,83), +(13261,12,5), +(13262,12,80), +(13263,12,138), +(13264,12,107), +(13265,12,106), +(13266,12,120), +(13267,12,118), +(13268,12,49), +(13269,12,84), +(13270,12,86), +(13271,12,113), +(13272,12,91), +(13273,12,125), +(13274,12,61), +(13275,12,105), +(13276,12,85), +(13277,12,121), +(13278,12,79), +(13279,12,139), +(13280,12,115), +(13281,12,146), +(13282,12,109), +(13283,12,100), +(13284,12,16), +(13285,12,50), +(13286,12,54), +(13287,12,69), +(13288,12,103), +(13289,12,135), +(13290,12,127), +(13291,12,131), +(13292,12,136), +(13293,12,128), +(13294,12,133), +(13295,12,132), +(13296,12,108), +(13297,12,81), +(13298,12,124), +(13299,12,111), +(13300,12,96), +(13301,12,122), +(13302,12,123), +(13303,12,110), +(13304,12,129), +(13305,12,78), +(13306,12,195), +(13307,12,90), +(13308,12,116), +(13309,12,134), +(13310,12,130), +(13311,12,97), +(13312,12,104), +(13313,12,196), +(13314,12,1), +(13315,12,137), +(13316,12,19), +(13317,12,18), +(13318,12,17), +(13319,12,9), +(13320,12,15), +(13321,12,7), +(13322,12,6), +(13323,12,4), +(13324,12,3), +(13325,12,2), +(13563,7,119), +(13564,7,198), +(13565,7,188), +(13566,7,181), +(13567,7,160), +(13568,7,158), +(13569,7,154), +(13570,7,140), +(13571,7,126), +(13572,7,117), +(13573,7,112), +(13574,7,102), +(13575,7,93), +(13576,7,91), +(13577,7,138), +(13578,7,159), +(13579,7,107), +(13580,7,106), +(13581,7,155), +(13582,7,5), +(13583,7,161), +(13584,7,101), +(13585,7,113), +(13586,7,120), +(13587,7,49), +(13588,7,182), +(13589,7,86), +(13590,7,84), +(13591,7,83), +(13592,7,80), +(13593,7,118), +(13594,7,125), +(13595,7,185), +(13596,7,61), +(13597,7,186), +(13598,7,153), +(13599,7,100), +(13600,7,115), +(13601,7,146), +(13602,7,16), +(13603,7,109), +(13604,7,105), +(13605,7,139), +(13606,7,85), +(13607,7,79), +(13608,7,183), +(13609,7,121), +(13610,7,136), +(13611,7,131), +(13612,7,135), +(13613,7,50), +(13614,7,192), +(13615,7,165), +(13616,7,178), +(13617,7,179), +(13618,7,187), +(13619,7,54), +(13620,7,69), +(13621,7,103), +(13622,7,127), +(13623,7,128), +(13624,7,132), +(13625,7,133), +(13626,7,124), +(13627,7,108), +(13628,7,194), +(13629,7,193), +(13630,7,78), +(13631,7,96), +(13632,7,197), +(13633,7,110), +(13634,7,111), +(13635,7,129), +(13636,7,122), +(13637,7,195), +(13638,7,123), +(13639,7,116), +(13640,7,130), +(13641,7,90), +(13642,7,134), +(13643,7,97), +(13644,7,104), +(13645,7,196), +(13646,7,1), +(13647,7,180), +(13648,7,137), +(13649,7,184), +(13650,7,3), +(13651,7,2), +(13652,7,4), +(13653,7,6), +(13654,7,7), +(13655,7,9), +(13656,7,15), +(13657,7,17), +(13658,7,18), +(13659,7,19), +(13660,8,198), +(13661,8,119), +(13662,8,117), +(13663,8,112), +(13664,8,126), +(13665,8,181), +(13666,8,80), +(13667,8,84), +(13668,8,118), +(13669,8,86), +(13670,8,91), +(13671,8,113), +(13672,8,107), +(13673,8,61), +(13674,8,125), +(13675,8,105), +(13676,8,183), +(13677,8,109), +(13678,8,79), +(13679,8,146), +(13680,8,85), +(13681,8,131), +(13682,8,135), +(13683,8,178), +(13684,8,179), +(13685,8,54), +(13686,8,50), +(13687,8,69), +(13688,8,132), +(13689,8,124), +(13690,8,96), +(13691,8,197), +(13692,8,195), +(13693,8,78), +(13694,8,110), +(13695,8,129), +(13696,8,111), +(13697,8,97), +(13698,8,104), +(13699,8,90), +(13700,8,130), +(13701,8,196), +(13702,8,116), +(13703,8,180), +(13704,2,140), +(13705,2,93), +(13706,2,102), +(13707,2,112), +(13708,2,117), +(13709,2,119), +(13710,2,126), +(13711,2,154), +(13712,2,158), +(13713,2,160), +(13714,2,198), +(13715,2,189), +(13716,2,188), +(13717,2,181), +(13718,2,177), +(13719,2,138), +(13720,2,120), +(13721,2,118), +(13722,2,182), +(13723,2,113), +(13724,2,161), +(13725,2,107), +(13726,2,106), +(13727,2,155), +(13728,2,101), +(13729,2,159), +(13730,2,91), +(13731,2,49), +(13732,2,80), +(13733,2,83), +(13734,2,84), +(13735,2,5), +(13736,2,86), +(13737,2,125), +(13738,2,61), +(13739,2,185), +(13740,2,186), +(13741,2,153), +(13742,2,109), +(13743,2,16), +(13744,2,121), +(13745,2,139), +(13746,2,105), +(13747,2,146), +(13748,2,85), +(13749,2,115), +(13750,2,79), +(13751,2,100), +(13752,2,183), +(13753,2,178), +(13754,2,165), +(13755,2,179), +(13756,2,50), +(13757,2,187), +(13758,2,136), +(13759,2,135), +(13760,2,192), +(13761,2,131), +(13762,2,127), +(13763,2,54), +(13764,2,103), +(13765,2,69), +(13766,2,128), +(13767,2,132), +(13768,2,133), +(13769,2,124), +(13770,2,194), +(13771,2,108), +(13772,2,193), +(13773,2,96), +(13774,2,197), +(13775,2,110), +(13776,2,111), +(13777,2,195), +(13778,2,78), +(13779,2,122), +(13780,2,123), +(13781,2,129), +(13782,2,196), +(13783,2,90), +(13784,2,97), +(13785,2,104), +(13786,2,116), +(13787,2,130), +(13788,2,134), +(13789,2,1), +(13790,2,180), +(13791,2,184), +(13792,2,137), +(13793,2,2), +(13794,2,7), +(13795,2,3), +(13796,2,4), +(13797,2,19), +(13798,2,18), +(13799,2,17), +(13800,2,15), +(13801,2,6), +(13802,2,9), +(13803,2,199), +(13804,7,199), +(13805,8,199), +(13806,2,200), +(13807,7,200), +(13808,8,200); + +/*Table structure for table `t_gen_code` */ + +DROP TABLE IF EXISTS `t_gen_code`; + +CREATE TABLE `t_gen_code` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `service_name` varchar(64) DEFAULT NULL COMMENT '服务名称', + `module_name` varchar(64) DEFAULT NULL COMMENT '模块名称', + `table_name` varchar(64) DEFAULT NULL COMMENT '表名', + `table_prefix` varchar(64) DEFAULT NULL COMMENT '表前缀', + `pk_name` varchar(32) DEFAULT NULL COMMENT '主键名', + `package_name` varchar(500) DEFAULT NULL COMMENT '后端包名', + `backend_path` varchar(2000) DEFAULT NULL COMMENT '后端路径', + `front_path` varchar(2000) DEFAULT NULL COMMENT '前端路径', + `author` varchar(30) DEFAULT NULL COMMENT '作者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `status` char(1) DEFAULT 'A' COMMENT '状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='代码生成表'; + +/*Data for the table `t_gen_code` */ + +insert into `t_gen_code`(`id`,`service_name`,`module_name`,`table_name`,`table_prefix`,`pk_name`,`package_name`,`backend_path`,`front_path`,`author`,`create_time`,`update_time`,`status`) values +(1,'Banner','焦点图','banner','mt_','id','banner','C:/Code/fuintBackend',NULL,'FSQ','2024-04-09 15:18:06','2024-04-09 15:20:52','A'); + +/*Table structure for table `t_platform` */ + +DROP TABLE IF EXISTS `t_platform`; + +CREATE TABLE `t_platform` ( + `owner_id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(100) NOT NULL COMMENT '平台名称', + `status` int NOT NULL COMMENT '状态 0 无效 1 有效', + `description` varchar(255) DEFAULT NULL COMMENT '描述', + `platform_type` int NOT NULL COMMENT '平台类型', + PRIMARY KEY (`owner_id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + +/*Data for the table `t_platform` */ + +insert into `t_platform`(`owner_id`,`name`,`status`,`description`,`platform_type`) values +(1,'会员营销管理系统',1,'会员营销管理系统说明',1); + +/*Table structure for table `t_source` */ + +DROP TABLE IF EXISTS `t_source`; + +CREATE TABLE `t_source` ( + `source_id` int NOT NULL AUTO_INCREMENT COMMENT '菜单Id', + `merchant_id` int DEFAULT '1' COMMENT '商户ID', + `source_name` varchar(240) NOT NULL COMMENT '菜单名称', + `source_code` varchar(200) NOT NULL COMMENT '菜单对应url', + `path` varchar(255) DEFAULT '' COMMENT '路径', + `ename` varchar(100) DEFAULT '' COMMENT '字母名称', + `new_icon` varchar(30) DEFAULT '' COMMENT '新图标', + `status` varchar(6) NOT NULL COMMENT '状态(A:可用 D:禁用)', + `source_level` int NOT NULL COMMENT '菜单级别', + `source_style` varchar(40) NOT NULL COMMENT '样式', + `is_menu` int NOT NULL COMMENT '是否显示', + `description` varchar(400) DEFAULT NULL COMMENT '描述', + `parent_id` int DEFAULT NULL COMMENT '上级菜单ID', + `is_log` int DEFAULT NULL, + `icon` varchar(20) DEFAULT NULL COMMENT '菜单图标', + PRIMARY KEY (`source_id`), + KEY `index-name` (`source_name`,`parent_id`), + KEY `index-parent-id` (`parent_id`) +) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='菜单表'; + +/*Data for the table `t_source` */ + +insert into `t_source`(`source_id`,`merchant_id`,`source_name`,`source_code`,`path`,`ename`,`new_icon`,`status`,`source_level`,`source_style`,`is_menu`,`description`,`parent_id`,`is_log`,`icon`) values +(1,0,'后台管理员','system/account/index','system/account/index','SystemAccountIndex','select','A',2,'7',1,'管理员管理',15,1,NULL), +(2,0,'新增用户','/user/add','system/account/add','SystemAccountAdd','select','A',3,'99',0,'',1,1,NULL), +(3,0,'修改用户','/user/edit','system/account/edit','SystemAccountEdit','select','A',3,'99',0,'',1,1,NULL), +(4,0,'删除用户','/user/delete','system/account/delete','SystemAccountDelete','select','A',3,'99',0,'',1,1,NULL), +(5,0,'后台菜单','system/menu/index','system/menu/index','SystemMenuIndex','select','A',2,'1',1,NULL,15,1,NULL), +(6,0,'新增菜单','system/menu/add','system/menu/add','SystemMenuAdd','select','A',3,'99',0,'',5,1,NULL), +(7,0,'修改菜单','/source/edit','system/menu/edit','SystemMenuEdit','select','A',3,'99',0,'修改菜单',5,1,NULL), +(9,0,'删除菜单','/source/delete','system/menu/delete','SystemMenuDelete','select','A',3,'99',0,'删除菜单',5,1,NULL), +(15,0,'系统管理','system','system','System','system','A',1,'99',1,NULL,NULL,1,'cog'), +(16,0,'后台角色','system/role/index','system/role/index','SystemRoleIndex','select','A',2,'2',1,NULL,15,1,NULL), +(17,0,'新增角色','/duty/add','system/role/add','SystemRoleAdd','select','A',3,'99',0,'',16,1,NULL), +(18,0,'修改角色','/source/edit','system/role/edit','SystemRoleEdit','select','A',3,'99',0,'',16,1,NULL), +(19,0,'删除角色','/source/delete','system/role/delete','SystemRoleDelete','select','A',3,'99',0,'',16,1,NULL), +(49,0,'后台日志','system/logs/index','system/logs/index','SystemLogsIndex','select','A',2,'1',1,'后台操作日志',15,1,NULL), +(50,0,'卡券管理','######','coupon','Coupon','job','A',1,'3',1,'卡券管理',NULL,0,'ticket'), +(54,0,'会员卡券','/backend/userCoupon/list','coupon/userCoupon/index','CouponUserCouponIndex','select','A',2,'3',1,'会员卡券明细列表',50,1,NULL), +(61,0,'新增会员','member/add','member/add','MemberAdd','select','A',2,'10',0,'新增会员',79,1,NULL), +(69,0,'员工管理','/backend/staff/queryList','staff/list','StaffList','select','A',2,'3',1,'店铺员工管理',84,0,NULL), +(78,0,'发券记录','/backend/sendLog/index','coupon/sendLog/index','CouponSendLogIndex','select','A',2,'5',1,'发券记录',50,1,NULL), +(79,0,'会员管理','######','member','Member','peoples','A',1,'2',1,'会员管理',NULL,0,'user'), +(80,0,'会员列表','/backend/member/queryList','member/index','MemberIndex','select','A',2,'1',1,'会员列表',79,1,NULL), +(81,0,'核销流水','/backend/confirmLog/confirmLogList','coupon/confirmLog/index','CouponConfirmLogIndex','select','A',2,'4',1,'核销记录列表',50,1,NULL), +(83,0,'分组管理','/backend/couponGroup/index','coupon/group/index','CouponGroupIndex','select','A',2,'1',1,'分组管理',50,1,NULL), +(84,0,'店铺管理','######','store','Store','shopping','A',1,'1',1,'店铺管理',NULL,0,'columns'), +(85,0,'新增店铺','store/add','store/add','StoreAdd','select','A',3,'2',0,'新增店铺信息',86,1,NULL), +(86,0,'店铺列表','/backend/store/queryList','store/list','StoreList','select','A',2,'1',1,'店铺列表',84,0,NULL), +(90,0,'消息管理','######','message','Message','message','A',1,'6',1,'消息管理',NULL,0,'tablet'), +(91,0,'已发短信','/backend/smsManager/index','smsManager/index','SmsManagerIndex','select','A',2,'1',1,'已发短信列表',90,0,NULL), +(93,0,'短信模板','/backend/smsTemplate/index','smsTemplate/index','SmsTemplateIndex','select','A',2,'0',1,'短信模板',90,0,NULL), +(96,0,'订单管理','######','order','Order','list','A',1,'5',1,'订单管理',NULL,0,'list'), +(97,0,'转赠记录','/backend/give/index','coupon/give/index','CouponGiveIndex','select','A',2,'6',1,'转赠记录',50,1,NULL), +(100,0,'卡券列表','/backend/coupon/index','coupon/coupon/index','CouponCouponIndex','select','A',2,'2',1,'卡券列表',50,1,NULL), +(101,0,'内容管理','######','content','Content','edit','A',1,'1',1,'内容管理',NULL,1,'book'), +(102,0,'轮播管理','content/banner/list','content/banner/list','ContentBannerList','select','A',2,'0',1,'首页广告',101,1,NULL), +(103,0,'会员等级','/backend/userGrade/queryList','userGrade/index','UserGradeIndex','select','A',2,'3',1,'会员等级',79,1,NULL), +(104,0,'积分管理','######','point','Point','log','A',1,'6',1,'积分管理',NULL,1,'file'), +(105,0,'积分明细','/backend/point/index','point/list','PointList','select','A',2,'2',1,'积分明细',104,1,NULL), +(106,0,'积分设置','/backend/point/setting','point/setting','PointSetting','select','A',2,'1',1,'积分设置',104,0,NULL), +(107,0,'订单列表','/backend/order/list','order/index','OrderIndex','select','A',2,'1',1,'订单列表',96,1,NULL), +(108,0,'开卡赠礼','/backend/openGift/list','openGift/index','OpenGiftIndex','select','A',2,'4',1,'开卡礼设置',79,1,NULL), +(109,0,'售后订单','/backend/refund/index','refund/index','RefundIndex','select','A',2,'2',1,'售后订单',96,0,NULL), +(110,0,'会员设置','/backend/member/setting','member/setting','MemberSetting','select','A',2,'5',1,'会员设置',79,0,NULL), +(111,0,'商品管理','######','Goods','Goods','server','A',1,'5',1,'商品管理',NULL,0,'shopping-cart'), +(112,0,'商品分类','/backend/goods/cate/list','goods/cate/index','GoodsCateIndex','select','A',2,'0',1,'商品分类',111,1,NULL), +(113,0,'商品列表','/backend/goods/goods/list','goods/goods/index','GoodsGoodsIndex','select','A',2,'1',1,'商品列表',111,1,NULL), +(115,0,'卡券核销','/backend/home/confirmCoupon','coupon/confirm/index','CouponConfirmIndex','select','A',2,'2',1,'卡券核销',50,1,NULL), +(116,0,'充值管理','recharge','recharge','Recharge','money','A',1,'6',1,'余额',NULL,1,'money'), +(117,0,'充值设置','/backend/balance/setting','balance/setting','BalanceSetting','select','A',2,'0',1,'充值设置',116,1,NULL), +(118,0,'余额明细','balance/list','balance/list','BalanceList','select','A',2,'1',1,'充值明细',116,1,NULL), +(119,0,'订阅消息','/backend/subMessage/index','subMessage/index','SubMessageIndex','select','A',2,'0',1,'小程序订阅消息',90,1,NULL), +(120,0,'轮播图编辑','content/banner/edit','content/banner/edit','ContentBannerEdit','select','A',2,'1',0,NULL,101,1,NULL), +(121,0,'新增轮播图','content:banner:add','content:banner:add','Content:banner:add','select','A',2,'2',0,NULL,101,1,NULL), +(122,0,'新增会员等级','/backend/userGrade/add','userGrade/add','UserGradeAdd','select','A',2,'5',0,NULL,79,1,NULL), +(123,0,'新增开卡赠礼','/backend/openGift/add','openGift/add','OpenGiftAdd','select','A',2,'5',0,NULL,79,1,NULL), +(124,0,'收银台','cashier/index','cashier/index','CashierIndex','select','A',2,'4',1,NULL,125,1,NULL), +(125,0,'收银管理','cashier','cashier','Cashier','tab','A',1,'10',0,NULL,NULL,1,NULL), +(126,0,'核销订单','cashier/confirmOrder','cashier/confirmOrder','CashierConfirmOrder','select','A',2,'0',1,NULL,125,1,NULL), +(127,0,'订单修改','/backend/order/edit','order/edit','OrderEdit','select','A',2,'3',0,NULL,96,1,NULL), +(128,0,'订单删除','/backend/order/delete','order/delete','OrderDelete','select','A',2,'4',0,NULL,96,1,NULL), +(129,0,'处理售后','/backend/refund/edit','refund/edit','RefundEdit','select','A',2,'5',0,NULL,96,1,NULL), +(130,0,'订单详情','/backend/order/detail','order/detail','OrderDetail','select','A',2,'6',0,NULL,96,1,NULL), +(131,0,'添加商品','goods/goods/add','goods/goods/add','GoodsGoodsAdd','select','A',2,'3',0,NULL,111,1,NULL), +(132,0,'编辑商品','goods/goods/edit','goods/goods/edit','GoodsGoodsEdit','select','A',2,'4',0,NULL,111,1,NULL), +(133,0,'编辑短信模板','smsTemplate/edit','smsTemplate/edit','SmsTemplateEdit','select','A',2,'4',0,NULL,90,1,NULL), +(134,0,'编辑订阅消息','subMessage/edit','subMessage/edit','SubMessageEdit','select','A',2,'6',0,NULL,90,1,NULL), +(135,0,'变更余额','balance/modify','balance/modify','BalanceModify','select','A',3,'3',0,NULL,117,1,NULL), +(136,0,'变更积分','point/modify','point/modify','PointModify','select','A',2,'3',0,NULL,104,1,NULL), +(137,0,'编辑卡券分组','coupon/group/edit','coupon/group/edit','CouponGroupEdit','select','A',3,'9',0,NULL,83,1,NULL), +(138,0,'新增卡券','coupon/coupon/add','coupon/coupon/add','CouponCouponAdd','select','A',3,'1',0,NULL,100,1,NULL), +(139,0,'编辑卡券','coupon/coupon/edit','coupon/coupon/edit','CouponCouponEdit','select','A',3,'2',0,NULL,100,1,NULL), +(140,0,'作废会员卡券','coupon/userCoupon/delete','coupon/userCoupon/delete','CouponUserCouponDelete','select','A',3,'0',0,NULL,54,1,NULL), +(146,0,'支付设置','store/paySetting','store/paySetting','StorePaySetting','select','A',3,'2',0,NULL,86,1,NULL), +(153,0,'分佣提成','commission','commission','Commission','tree','A',1,'12',1,NULL,NULL,1,NULL), +(154,0,'分佣规则','commission/rule/index','commission/rule/index','CommissionRuleIndex','select','A',2,'0',1,NULL,153,1,NULL), +(155,0,'分佣记录','commission/log/index','commission/log/index','CommissionLogIndex','select','A',2,'1',1,NULL,153,1,NULL), +(158,0,'订单发货','order/delivery','order/delivery','OrderDelivery','bug','A',3,'0',0,NULL,107,1,NULL), +(159,0,'文章管理','content/article/index','content/article/index','ContentArticleIndex','select','A',2,'1',1,NULL,101,1,NULL), +(160,0,'新增文章','content/article/add','content/article/add','ContentArticleAdd','select','A',2,'0',0,NULL,101,1,NULL), +(161,0,'编辑文章','content/article/edit','content/article/edit','ContentArticleEdit','select','A',2,'1',0,NULL,101,1,NULL), +(165,0,'交易设置','order/setting','order/setting','OrderSetting','select','A',2,'3',1,NULL,96,1,NULL), +(177,0,'商户管理','merchant/index','merchant/index','MerchantIndex','select','A',2,'0',1,NULL,84,1,NULL), +(178,0,'收银设置','setting/cashier','setting/cashier','SettingCashier','select','A',2,'3',1,NULL,125,1,NULL), +(179,0,'库存管理','stock/index','stock/index','StockIndex','select','A',2,'3',1,NULL,111,1,NULL), +(180,0,'数据统计','statistic','statistic','Statistic','chart','A',1,'8',1,NULL,NULL,1,NULL), +(181,0,'数据看板','statistic/index','statistic/index','StatisticIndex','select','A',2,'0',1,NULL,180,1,NULL), +(182,0,'会员分组','member/group/index','member/group/index','MemberGroupIndex','select','A',2,'1',1,NULL,79,1,NULL), +(183,0,'会员充值','balance/distribute','balance/distribute','BalanceDistribute','select','A',2,'2',1,NULL,116,1,NULL), +(184,0,'订单结算','settlement/index','settlement/index','SettlementIndex','select','A',2,'9',1,NULL,96,1,NULL), +(185,0,'发起结算','settlement/doSubmit','settlement/doSubmit','SettlementDoSubmit','select','A',2,'10',0,NULL,96,1,NULL), +(186,0,'结算确认','settlement/doConfirm','settlement/doConfirm','SettlementDoConfirm','select','A',2,'11',0,NULL,96,1,NULL), +(187,0,'生成代码','system/genCode/index','system/genCode/index','SystemGenCodeIndex','select','A',2,'3',1,NULL,15,1,NULL), +(188,0,'新增生成代码','system/genCode/add','system/genCode/add','SystemGenCodeAdd','select','A',3,'0',0,NULL,187,1,NULL), +(189,0,'删除生成代码','system/genCode/delete','system/genCode/delete','SystemGenCodeDelete','select','A',3,'0',0,NULL,187,1,NULL), +(190,0,'确定生成代码','system/genCode/gen','system/genCode/gen','SystemGenCodeGen','select','A',3,'3',0,NULL,187,1,NULL), +(192,0,'结算记录','commission/cash/index','commission/cash/index','CommissionCashIndex','select','A',2,'3',1,NULL,153,1,NULL), +(193,0,'短信配置','smsManager/setting','smsManager/setting','SmsManagerSetting','select','A',2,'5',1,NULL,90,1,NULL), +(194,0,'邀请明细','commission/relation/index','commission/relation/index','CommissionRelationIndex','select','A',2,'4',1,NULL,153,1,NULL), +(195,0,'预约管理','book/index','book/index','BookIndex','select','A',2,'5',1,NULL,84,1,NULL), +(196,0,'预约记录','book/item','book/item','BookItem','select','A',2,'6',1,NULL,84,1,NULL), +(197,0,'打印设备','printer/index','printer/index','PrinterIndex','select','A',2,'5',1,NULL,84,1,NULL), +(198,0,'设置云打印账号','printer/setting','printer/setting','PrinterSetting','select','A',3,'0',0,NULL,197,1,NULL), +(199,0,'导航管理','content/navigation/index','content/navigation/index','ContentNavigationIndex','select','A',2,'3',1,NULL,101,1,NULL), +(200,0,'编辑导航','content/navigation/edit','content/navigation/edit','ConetentNavigationEdit','select','A',2,'0',0,NULL,101,1,NULL); + diff --git a/db/update_for_20250403.sql b/db/update_for_20250403.sql new file mode 100644 index 0000000..6fc1ae4 --- /dev/null +++ b/db/update_for_20250403.sql @@ -0,0 +1,4 @@ +ALTER TABLE `mt_order` + ADD COLUMN `CONFIRM_STATUS` CHAR (1) DEFAULT 'N' NULL COMMENT '核销状态' AFTER `STAFF_ID`, + ADD COLUMN `CONFIRM_TIME` DATETIME NULL COMMENT '核销时间' AFTER `CONFIRM_STATUS`, + ADD COLUMN `CONFIRM_REMARK` VARCHAR (500) NULL COMMENT '核销备注' AFTER `CONFIRM_TIME`; \ No newline at end of file diff --git a/db/update_for_20250422.sql b/db/update_for_20250422.sql new file mode 100644 index 0000000..3564152 --- /dev/null +++ b/db/update_for_20250422.sql @@ -0,0 +1,2 @@ +ALTER TABLE `fuint-db`.`mt_user` + ADD COLUMN `IP` VARCHAR (20) DEFAULT '' NULL COMMENT '注册IP' AFTER `DESCRIPTION`; \ No newline at end of file diff --git a/db/update_for_20250429.sql b/db/update_for_20250429.sql new file mode 100644 index 0000000..94d0914 --- /dev/null +++ b/db/update_for_20250429.sql @@ -0,0 +1,14 @@ +ALTER TABLE `fuint-db`.`mt_cart` + CHANGE `NUM` `NUM` DOUBLE (10, 2) DEFAULT 1 NULL COMMENT '数量'; + +ALTER TABLE `fuint-db`.`mt_goods` + CHANGE `STOCK` `STOCK` DOUBLE (10, 2) UNSIGNED DEFAULT 0 NULL COMMENT '库存'; + +ALTER TABLE `fuint-db`.`mt_goods` + CHANGE `INIT_SALE` `INIT_SALE` DOUBLE (10, 2) DEFAULT 0 NULL COMMENT '初始销量'; + +ALTER TABLE `fuint-db`.`mt_goods_sku` + CHANGE `STOCK` `STOCK` DOUBLE (10, 2) DEFAULT 0 NOT NULL COMMENT '库存'; + +ALTER TABLE `fuint-db`.`mt_order_goods` + CHANGE `NUM` `NUM` DOUBLE (10, 2) DEFAULT 0 NOT NULL COMMENT '商品数量'; \ No newline at end of file diff --git a/db/update_for_20250514.sql b/db/update_for_20250514.sql new file mode 100644 index 0000000..2f8a9f4 --- /dev/null +++ b/db/update_for_20250514.sql @@ -0,0 +1,5 @@ +ALTER TABLE `mt_goods` + ADD COLUMN `COST_PRICE` DECIMAL (10, 2) DEFAULT 0.00 NULL COMMENT '成本价格' AFTER `LINE_PRICE`; + +ALTER TABLE `mt_goods_sku` + ADD COLUMN `COST_PRICE` DECIMAL (10, 2) DEFAULT 0.00 NULL COMMENT '成本价格' AFTER `LINE_PRICE`; \ No newline at end of file diff --git a/db/update_for_20250603.sql b/db/update_for_20250603.sql new file mode 100644 index 0000000..688f2e5 --- /dev/null +++ b/db/update_for_20250603.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mt_goods` + ADD COLUMN `PLATFORM` INT (1) DEFAULT 0 NULL COMMENT '可用平台,0:不限,1:仅会员端(小程序和h5);2:仅收银端' AFTER `GOODS_NO`; diff --git a/db/update_for_20250925.sql b/db/update_for_20250925.sql new file mode 100644 index 0000000..fe77a14 --- /dev/null +++ b/db/update_for_20250925.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mt_setting` + CHANGE `VALUE` `VALUE` LONGTEXT NOT NULL COMMENT '配置值'; diff --git a/db/update_for_20251013.sql b/db/update_for_20251013.sql new file mode 100644 index 0000000..03ee029 --- /dev/null +++ b/db/update_for_20251013.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mt_coupon` + ADD COLUMN `CONTENT` INT DEFAULT 1 NULL COMMENT '内容,如:1表示满减券、2表示折扣券' AFTER `TYPE`; diff --git a/db/update_for_20251020.sql b/db/update_for_20251020.sql new file mode 100644 index 0000000..143c7ce --- /dev/null +++ b/db/update_for_20251020.sql @@ -0,0 +1,5 @@ +ALTER TABLE `mt_merchant` +ADD COLUMN `SETTLE_RATE` DECIMAL NULL COMMENT '结算比例' AFTER `WX_OFFICIAL_APP_SECRET`; + +ALTER TABLE `mt_settlement` +ADD COLUMN `SETTLE_RATE` DECIMAL NULL COMMENT '结算比例' AFTER `STORE_ID`; \ No newline at end of file diff --git a/db/update_for_20251212.sql b/db/update_for_20251212.sql new file mode 100644 index 0000000..b19d71f --- /dev/null +++ b/db/update_for_20251212.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mt_stock_item` + CHANGE `NUM` `NUM` DOUBLE (10, 2) DEFAULT 0 NOT NULL COMMENT '数量'; diff --git a/db/update_for_20260109.sql b/db/update_for_20260109.sql new file mode 100644 index 0000000..2237e44 --- /dev/null +++ b/db/update_for_20260109.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mt_goods` + ADD COLUMN `BOOK_ID` INT DEFAULT 0 NULL COMMENT '预约项目ID' AFTER `CATE_ID`; diff --git a/db/说明.txt b/db/说明.txt new file mode 100644 index 0000000..dc8021e --- /dev/null +++ b/db/说明.txt @@ -0,0 +1,2 @@ +1、fuint-db.sql是全量的数据库; +2、update_for_xxx是从上个版本升级到最新版本用的(首次安装部署不需要导这部分的SQL); \ No newline at end of file diff --git a/fuint-application/pom.xml b/fuint-application/pom.xml new file mode 100644 index 0000000..9784469 --- /dev/null +++ b/fuint-application/pom.xml @@ -0,0 +1,193 @@ + + + + fuint + com.fuint + 1.0.0 + + 4.0.0 + + fuint-application + 1.0.0 + jar + + + 0.0.9 + + + + + com.fuint + fuint-framework + 1.0.0 + + + io.sentry + sentry-logback + 1.2.0 + + + org.springframework.ws + spring-ws-core + + + org.springframework.boot + spring-boot-starter-security + + + org.aspectj + aspectjweaver + + + commons-httpclient + commons-httpclient + 3.1 + + + nl.bitwalker + UserAgentUtils + 1.2.4 + + + commons-lang + commons-lang + 2.6 + + + io.springfox + springfox-swagger2 + 2.9.2 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.baomidou + mybatis-plus + ${mybatis-plus.version} + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.2.5 + + + org.mybatis + mybatis + + + + + + org.mockito + mockito-core + + + com.github.axet + kaptcha + ${kaptcha.version} + + + junit + junit + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.javassist + javassist + 3.24.0-GA + + + com.aliyun.oss + aliyun-sdk-oss + 3.10.2 + + + + com.aliyun + aliyun-java-sdk-core + 4.4.6 + + + com.alibaba + transmittable-thread-local + 2.2.0 + + + com.github.javen205 + IJPay-WxPay + 2.9.12.1 + + + com.github.javen205 + IJPay-AliPay + 2.9.12.1 + + + com.github.javen205 + IJPay-UnionPay + 2.9.12.1 + + + org.apache.velocity + velocity-engine-core + 2.3 + + + + commons-io + commons-io + 2.13.0 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.12 + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + + diff --git a/fuint-application/src/main/java/com/fuint/common/Constants.java b/fuint-application/src/main/java/com/fuint/common/Constants.java new file mode 100644 index 0000000..8468a8c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/Constants.java @@ -0,0 +1,38 @@ +package com.fuint.common; + +import java.util.HashMap; +import java.util.Map; + +/** + * 常量定义 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Constants { + + // 第几页,默认第1页 + public static final int PAGE_NUMBER = 1; + + // 每页记录数,默认20条 + public static final int PAGE_SIZE = 20; + + // 读取数据最多行数 + public static final int MAX_ROWS = 5000; + + // 读取数据全部行数 + public static final int ALL_ROWS = 1000000; + + /** + * 系统配置, 从setting表中读取 + */ + public static Map SYS_CONFIGS = new HashMap(); + + public static final int HTTP_RESPONSE_CODE_PARAM_ERROR = 202; + public static final int HTTP_RESPONSE_CODE_USER_NOT_EXIST = 402; + public static final int HTTP_RESPONSE_CODE_USER_LOGIN_ERROR = 403; + public static final int HTTP_RESPONSE_CODE_NOLOGIN = 1001; + + public static final String SESSION_USER = "FUINT_USER"; + public static final String SESSION_ADMIN_USER = "FUINT_ADMIN_USER"; +} diff --git a/fuint-application/src/main/java/com/fuint/common/aspect/LogAop.java b/fuint-application/src/main/java/com/fuint/common/aspect/LogAop.java new file mode 100644 index 0000000..72d879e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/aspect/LogAop.java @@ -0,0 +1,147 @@ +package com.fuint.common.aspect; + +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.Modifier; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.LocalVariableAttribute; +import javassist.bytecode.MethodInfo; +import org.apache.commons.lang.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.stereotype.Component; + +/** + * 控制器日志 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component // 声明组件 +@Aspect // 声明切面 +@ComponentScan //组件自动扫描 +@EnableAspectJAutoProxy // spring自动切换JDK动态代理和CGLIB +public class LogAop { + + /** + *自定义日志 + */ + private Logger logger = LoggerFactory.getLogger(LogAop.class); + + /** + * 打印类method的名称以及参数 + * @param point 切面 + */ + public void printMethodParams(JoinPoint point){ + if (point == null) { + return; + } + try { + // 获取方法的参数值数组。方法名、类型以及地址等信息 + String className = point.getTarget().getClass().getName(); + String methodName = point.getSignature().getName(); + + // 重新定义日志 + logger = LoggerFactory.getLogger(point.getTarget().getClass()); + logger.info("-------------------------"+className+"------------------------------------"); + logger.info("methodName = {}", methodName); + + // 获取方法的参数值数组 + Object[] methodArgs = point.getArgs(); + + // 获取方法参数名称 + String[] paramNames = getFieldsName(className, methodName); + + // 输出方法的参数名和参数值 + printParams(paramNames, methodArgs); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 使用获取方法参数名称 + * @param class_name 类名 + * @param method_name 方法名 + * @throws Exception + */ + private String[] getFieldsName(String class_name, String method_name) throws Exception { + Class clazz = Class.forName(class_name); + String clazz_name = clazz.getName(); + ClassPool pool = ClassPool.getDefault(); + ClassClassPath classPath = new ClassClassPath(clazz); + pool.insertClassPath(classPath); + try { + CtClass ctClass = pool.get(clazz_name); + CtMethod ctMethod = ctClass.getDeclaredMethod(method_name); + MethodInfo methodInfo = ctMethod.getMethodInfo(); + CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); + LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); + if (attr == null) { + return null; + } + String[] paramsArgsName = new String[ctMethod.getParameterTypes().length]; + int pos = Modifier.isStatic(ctMethod.getModifiers()) ? 0 : 1; + for (int i = 0; i < paramsArgsName.length; i++) { + paramsArgsName[i] = attr.variableName(i + pos); + } + return paramsArgsName; + } catch (Exception ex) { + return null; + } + } + + /** + * 判断是否为基本类型 + */ + private boolean isPrimite(Class clazz) { + if (clazz.isPrimitive() || clazz == String.class){ + return true; + }else { + return false; + } + } + + /** + * 打印方法参数值 基本类型直接打印,非基本类型需要重写toString方法 + * @param paramsArgsName 方法参数名数组 + * @param paramsArgsValue 方法参数值数组 + */ + private void printParams(String[] paramsArgsName, Object[] paramsArgsValue) { + if (ArrayUtils.isEmpty(paramsArgsName) || ArrayUtils.isEmpty(paramsArgsValue)) { + return; + } + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < paramsArgsName.length; i++) { + // 参数名 + String name = paramsArgsName[i]; + // 参数值 + Object value = paramsArgsValue[i]; + buffer.append(name +" = "); + if (isPrimite(value.getClass())) { + buffer.append(value + " ,"); + } else { + buffer.append(value.toString() + " ,"); + } + } + logger.info("params : " + buffer.toString()); + logger.info("-------------------------------------------------------------"); + } + + /** + * 在方法执行前进行切面 + * 定义切面表达式 + * @param point 切面 + */ + @Before("execution(public * com.fuint.module..*.*(..))") + public void before(JoinPoint point) { + this.printMethodParams(point); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/aspect/RedisModelAspect.java b/fuint-application/src/main/java/com/fuint/common/aspect/RedisModelAspect.java new file mode 100644 index 0000000..3b26713 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/aspect/RedisModelAspect.java @@ -0,0 +1,16 @@ +package com.fuint.common.aspect; + +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component +@Aspect +public class RedisModelAspect { + public static final Logger logger = LoggerFactory.getLogger(RedisModelAspect.class); +} diff --git a/fuint-application/src/main/java/com/fuint/common/aspect/TActionLogAop.java b/fuint-application/src/main/java/com/fuint/common/aspect/TActionLogAop.java new file mode 100644 index 0000000..2922c5b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/aspect/TActionLogAop.java @@ -0,0 +1,240 @@ +package com.fuint.common.aspect; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.service.AccountService; +import com.fuint.common.service.ActionLogService; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.TokenUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.repository.model.TActionLog; +import com.fuint.utils.StringUtil; +import org.apache.commons.lang.StringUtils; +import org.apache.ibatis.javassist.*; +import org.apache.ibatis.javassist.bytecode.CodeAttribute; +import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute; +import org.apache.ibatis.javassist.bytecode.MethodInfo; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.*; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 后台操作日志 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component +@Aspect +public class TActionLogAop { + + private final Logger logger = LoggerFactory.getLogger(TActionLogAop.class); + + @Lazy + @Autowired + private ActionLogService tActionLogService; + + @Lazy + @Autowired + private AccountService tAccountService; + + private String userName = ""; // 用户名 + private Integer merchantId = 0; // 商户ID + private Integer storeId = 0; // 店铺ID + private Long startTimeMillis = 0l; // 开始时间 + private Long endTimeMillis = 0l; // 结束时间 + private String clientIp = ""; + private Integer clientPort = 0; + private String module = ""; + private String url = ""; + private String userAgent = ""; + private String param = ""; + + // Service层切点 + @Pointcut("@annotation(com.fuint.framework.annoation.OperationServiceLog)") + public void serviceAspect() { + // empty + } + + /** + * service 方法前调用 + * + * @param joinPoint + */ + @Before("serviceAspect()") + public void doBeforeService(JoinPoint joinPoint) { + // 记录方法开始执行的时间 + startTimeMillis = System.currentTimeMillis(); + + Map params = getJoinPointPramas(joinPoint); + String methodName = params.get("methodName"); + String classPath = params.get("classPath"); + Class clazz = null; + CtMethod ctMethod = null; + LocalVariableAttribute attr = null; + int length = 0; + int pos = 0; + + try { + //获取切入点参数 + clazz = Class.forName(classPath); + String clazzName = clazz.getName(); + ClassPool pool = ClassPool.getDefault(); + ClassClassPath classClassPath = new ClassClassPath(clazz); + pool.insertClassPath(classClassPath); + CtClass ctClass = pool.get(clazzName); + ctMethod = ctClass.getDeclaredMethod(methodName); + MethodInfo methodInfo = ctMethod.getMethodInfo(); + CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); + attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); + length = ctMethod.getParameterTypes().length; + pos = Modifier.isStatic(ctMethod.getModifiers()) ? 0 : 1; + Object[] paramsArgsValues = joinPoint.getArgs(); + String[] parmasArgsNames = new String[length]; + Map parmasMap = new HashMap(); + for (int i = 0; i < length; i++) { + parmasArgsNames[i] = attr.variableName(i + pos); + String paramsArgsName = attr.variableName(i + pos); + if (paramsArgsName.equalsIgnoreCase("request") + || paramsArgsName.equalsIgnoreCase("response") + || paramsArgsName.equalsIgnoreCase("session") + || paramsArgsName.equalsIgnoreCase("model")) { + continue; + } + Object paramsArgsValue = paramsArgsValues[i]; + parmasMap.put(paramsArgsName, paramsArgsValue); + } + param = JSON.toJSONString(parmasMap); + } catch (ClassNotFoundException e) { + logger.info("AOP切入点获取参数异常", e); + } catch (NotFoundException e) { + logger.info("AOP切入点获取参数异常", e); + } catch (Exception e) { + logger.info("AOP切入点获取参数异常", e.getMessage()); + } + } + + /** + * 方法后调用 + * + * @param operationServiceLog + */ + @After("serviceAspect() && @annotation(operationServiceLog)") + public void doAfterInService(OperationServiceLog operationServiceLog) { + try { + HttpServletRequest request = getRequest(); + if (request == null) { + return; + } + endTimeMillis = System.currentTimeMillis(); // 记录方法执行完成的时间 + clientIp = CommonUtil.getIPFromHttpRequest(request); + userAgent = request.getHeader("user-agent"); + url = request.getRequestURI(); + clientPort = 0; + module = operationServiceLog.description(); + if (module.length() > 255) { + module = module.substring(0, 255); + } + String token = request.getHeader("Access-Token"); + if (StringUtils.isNotEmpty(token)) { + AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token); + if (accountInfo != null) { + userName = accountInfo.getAccountName(); + merchantId = accountInfo.getMerchantId() == null ? 0 : accountInfo.getMerchantId(); + storeId = accountInfo.getStoreId() == null ? 0 : accountInfo.getStoreId(); + } + } else { + if (StringUtil.isNotEmpty(param) && param.length() > 10) { + JSONObject jsonObject = JSON.parseObject(param); + if (jsonObject != null) { + JSONObject tAccount = jsonObject.getJSONObject("tAccount"); + if (tAccount != null) { + String accountName = tAccount.getString("username"); + AccountInfo accountInfo = tAccountService.getAccountByName(accountName); + if (accountInfo != null) { + userName = accountInfo.getAccountName(); + merchantId = accountInfo.getMerchantId(); + storeId = accountInfo.getStoreId(); + } + } + } + } + } + printOptLog(); + } catch (Exception e) { + logger.error("保存后台日志出错啦:{}", e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 组装日志 + */ + private void printOptLog() { + if (userAgent.length() > 255) { + userAgent = userAgent.substring(0, 255); + } + if (url.length() > 255) { + url = url.substring(0, 255); + } + TActionLog hal = new TActionLog(); + hal.setAcctName(userName); + hal.setModule(module); + hal.setActionTime(new Date()); + hal.setClientIp(clientIp); + hal.setClientPort(clientPort); + hal.setUrl(url); + hal.setTimeConsuming(new BigDecimal(endTimeMillis - startTimeMillis)); + hal.setUserAgent(userAgent); + hal.setMerchantId(merchantId); + hal.setStoreId(storeId); + if (param.length() > 10000) { + param = param.substring(0, 10000); + } + hal.setParam(param.equals("{}") ? "" : param); + if (StringUtils.isNotEmpty(module) && userName != null && StringUtils.isNotEmpty(userName)) { + tActionLogService.saveActionLog(hal); + } + } + + protected HttpServletRequest getRequest() { + try { + return ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); + } catch (Exception e) { + return null; + } + } + + /** + * 获取切入点参数信息 + * + * @param joinPoint + * @return + */ + public Map getJoinPointPramas(JoinPoint joinPoint) { + Map mapParams = new HashMap(); + // 获取切入点所在的方法 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method smethod = signature.getMethod(); + String classPath = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + mapParams.put("module", module); + mapParams.put("classPath", classPath); + mapParams.put("methodName", methodName); + return mapParams; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/AliPayBean.java b/fuint-application/src/main/java/com/fuint/common/bean/AliPayBean.java new file mode 100644 index 0000000..45fe4a2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/AliPayBean.java @@ -0,0 +1,43 @@ +package com.fuint.common.bean; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; +import lombok.Data; + +/** + * 支付宝支付Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Component +@PropertySource("file:${env.properties.path}/${env.profile}/application.properties") +@ConfigurationProperties(prefix = "alipay") +public class AliPayBean { + + private String appId; + private String privateKey; + private String publicKey; + private String appCertPath; + private String aliPayCertPath; + private String aliPayRootCertPath; + private String serverUrl; + private String domain; + + + @Override + public String toString() { + return "AliPayBean{" + + "appId='" + appId + '\'' + + ", privateKey='" + privateKey + '\'' + + ", publicKey='" + publicKey + '\'' + + ", appCertPath='" + appCertPath + '\'' + + ", aliPayCertPath='" + aliPayCertPath + '\'' + + ", aliPayRootCertPath='" + aliPayRootCertPath + '\'' + + ", serverUrl='" + serverUrl + '\'' + + ", domain='" + domain + '\'' + + '}'; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/H5SceneInfo.java b/fuint-application/src/main/java/com/fuint/common/bean/H5SceneInfo.java new file mode 100644 index 0000000..5d7061e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/H5SceneInfo.java @@ -0,0 +1,83 @@ +package com.fuint.common.bean; + +import com.alibaba.fastjson.JSON; + +/** + * H5支付Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class H5SceneInfo { + private H5 h5_info; + + public H5 getH5Info() { + return h5_info; + } + + public void setH5Info(H5 h5_info) { + this.h5_info = h5_info; + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + public static class H5 { + private String type; + private String app_name; + private String bundle_id; + private String package_name; + private String wap_url; + private String wap_name; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getApp_name() { + return app_name; + } + + public void setApp_name(String app_name) { + this.app_name = app_name; + } + + public String getBundle_id() { + return bundle_id; + } + + public void setBundle_id(String bundle_id) { + this.bundle_id = bundle_id; + } + + public String getPackage_name() { + return package_name; + } + + public void setPackage_name(String package_name) { + this.package_name = package_name; + } + + public String getWap_url() { + return wap_url; + } + + public void setWap_url(String wap_url) { + this.wap_url = wap_url; + } + + public String getWap_name() { + return wap_name; + } + + public void setWap_name(String wap_name) { + this.wap_name = wap_name; + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/UnionPayBean.java b/fuint-application/src/main/java/com/fuint/common/bean/UnionPayBean.java new file mode 100644 index 0000000..1c34d04 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/UnionPayBean.java @@ -0,0 +1,35 @@ +package com.fuint.common.bean; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 云闪付支付Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Component +@PropertySource("file:${env.properties.path}/${env.profile}/application.properties") +@ConfigurationProperties(prefix = "union") +public class UnionPayBean { + + private String machId; + private String key; + private String serverUrl; + private String domain; + + + @Override + public String toString() { + return "UnionPayBean{" + + "machId='" + machId + '\'' + + ", key='" + key + '\'' + + ", serverUrl='" + serverUrl + '\'' + + ", domain='" + domain + '\'' + + '}'; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/WxPayBean.java b/fuint-application/src/main/java/com/fuint/common/bean/WxPayBean.java new file mode 100644 index 0000000..bd3f2a9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/WxPayBean.java @@ -0,0 +1,33 @@ +package com.fuint.common.bean; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 微信支付Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Component +@PropertySource("file:${env.properties.path}/${env.profile}/application.properties") +@ConfigurationProperties(prefix = "wxpay") +public class WxPayBean { + + private String appId; + private String appSecret; + private String mchId; + private String apiV2; + private String certPath; + private String domain; // 填写完整的回调地址 + + + @Override + public String toString() { + return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", apiV2=" + + apiV2 + ", certPath=" + certPath + ", domain=" + domain + "]"; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/WxPayV3Bean.java b/fuint-application/src/main/java/com/fuint/common/bean/WxPayV3Bean.java new file mode 100644 index 0000000..1e8e034 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/WxPayV3Bean.java @@ -0,0 +1,43 @@ +package com.fuint.common.bean; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; +import lombok.Data; + +/** + * 微信V3支付Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component +@PropertySource("file:${env.properties.path}/${env.profile}/application.properties") +@ConfigurationProperties(prefix = "v3") +@Data +public class WxPayV3Bean { + + private String appId; + private String keyPath; + private String certPath; + private String certP12Path; + private String platformCertPath; + private String mchId; + private String apiKey; + private String apiKey3; + private String domain; + + @Override + public String toString() { + return "WxPayV3Bean{" + + "keyPath='" + keyPath + '\'' + + ", certPath='" + certPath + '\'' + + ", certP12Path='" + certP12Path + '\'' + + ", platformCertPath='" + platformCertPath + '\'' + + ", mchId='" + mchId + '\'' + + ", apiKey='" + apiKey + '\'' + + ", apiKey3='" + apiKey3 + '\'' + + ", domain='" + domain + '\'' + + '}'; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ContactBean.java b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ContactBean.java new file mode 100644 index 0000000..f9373a8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ContactBean.java @@ -0,0 +1,36 @@ +package com.fuint.common.bean.shoppingOrders; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; + +/** + * 联系人Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ContactBean implements Serializable { + + private static final long serialVersionUID = 2256209964320569284L; + + /** + * 寄件人联系方式,寄件人联系方式,采用掩码传输,最后4位数字不能打掩码 示例值: `189****1234, 021-****1234, ****1234, 0**2-***1234, 0**2-******23-10, ****123-8008` 值限制: 0 ≤ value ≤ 1024 + */ + @SerializedName("consignor_contact") + private String consignorContact; + + /** + * 收件人联系方式,收件人联系方式为,采用掩码传输,最后4位数字不能打掩码 示例值: `189****1234, 021-****1234, ****1234, 0**2-***1234, 0**2-******23-10, ****123-8008` 值限制: 0 ≤ value ≤ 1024 + */ + @SerializedName("receiver_contact") + private String receiverContact; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/OrderKeyBean.java b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/OrderKeyBean.java new file mode 100644 index 0000000..255f3e0 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/OrderKeyBean.java @@ -0,0 +1,49 @@ +package com.fuint.common.bean.shoppingOrders; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; + +/** + * 订单,需要上传物流信息的订单Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OrderKeyBean implements Serializable { + + private static final long serialVersionUID = 1486092394664728388L; + + /** + * 必填 + * 订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号。 + */ + @SerializedName("order_number_type") + private int orderNumberType; + + /** + * 原支付交易对应的微信订单号 + */ + @SerializedName("transaction_id") + private String transactionId; + + /** + * 支付下单商户的商户号,由微信支付生成并下发。 + */ + @SerializedName("mchid") + private String mchId; + + /** + * 商户系统内部订单号,只能是数字、大小写字母`_-*`且在同一个商户号下唯一 + */ + @SerializedName("out_trade_no") + private String outTradeNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/PayerBean.java b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/PayerBean.java new file mode 100644 index 0000000..0030bb2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/PayerBean.java @@ -0,0 +1,31 @@ +package com.fuint.common.bean.shoppingOrders; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; + +/** + * 支付者,支付者信息Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayerBean implements Serializable { + + private static final long serialVersionUID = -7943088204264205895L; + + /** + * 必填 + * 用户标识,用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128] + */ + @SerializedName("openid") + private String openid; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingInfo.java b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingInfo.java new file mode 100644 index 0000000..d30bbdd --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingInfo.java @@ -0,0 +1,67 @@ +package com.fuint.common.bean.shoppingOrders; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; +import java.util.List; + +/** + * 上传发货信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ShippingInfo implements Serializable { + + private static final long serialVersionUID = 2105037984591600658L; + /** + * 必填 + * 订单,需要上传物流信息的订单 + */ + @SerializedName("order_key") + private OrderKeyBean orderKey; + + + /** + * 必填 + * 发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) + * 示例值: UNIFIED_DELIVERY + */ + @SerializedName("delivery_mode") + private int deliveryMode; + + /** + * 必填 + * 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提 + * */ + @SerializedName("logistics_type") + private int logisticsType; + + /** + * 必填 + * 物流信息列表,发货物流单列表,支持统一发货(单个物流单)和分拆发货(多个物流单)两种模式,多重性: [1, 10] + */ + @SerializedName("shipping_list") + private List shippingList; + + /** + * 必填 + * 上传时间,用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00 + */ + @SerializedName("upload_time") + private String uploadTime; + + /** + * 必填 + * 支付者,支付者信息 + */ + @SerializedName("payer") + private PayerBean payer; +} diff --git a/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingListBean.java b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingListBean.java new file mode 100644 index 0000000..dc97ab7 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/bean/shoppingOrders/ShippingListBean.java @@ -0,0 +1,64 @@ +package com.fuint.common.bean.shoppingOrders; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.io.Serializable; +import java.util.List; + +/** + * 上传发货信息Bean + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ShippingListBean implements Serializable { + + private static final long serialVersionUID = -6884739637300493109L; + + /** + * 物流单号,物流快递发货时必填,示例值: 323244567777 字符字节限制: [1, 128] + */ + @SerializedName("tracking_no") + private String trackingNo; + + /** + * 物流公司编码,快递公司ID,参见「查询物流公司编码列表」,物流快递发货时必填, 示例值: DHL 字符字节限制: [1, 128] + */ + @SerializedName("express_company") + private String expressCompany; + + /** + * 物流关联的商品列表,当统一发货(单个物流单)时,该项不填;当分拆发货(多个物流单)时,需填入各物流单关联的商品列表 多重性: [0, 50] + */ + @SerializedName("item_list") + private List itemList; + + /** + * 联系方式,当发货的物流公司为顺丰时,联系方式为必填,收件人或寄件人联系方式二选一 + */ + @SerializedName("contact") + private ContactBean contact; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ShippingItemListBean implements Serializable { + + private static final long serialVersionUID = -1433227869321841858L; + + /** + * 商户侧商品ID,商户系统内部商品编码,分拆发货模式下为必填,用于标识每笔物流单号内包含的商品,需与「上传购物详情」中传入的商品ID匹配 + * 示例值: 1246464644 字符字节限制: [1, 64] + */ + @SerializedName("merchant_item_id") + private String merchantItemId; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/CaptchaConfig.java b/fuint-application/src/main/java/com/fuint/common/config/CaptchaConfig.java new file mode 100644 index 0000000..9c30ef4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/CaptchaConfig.java @@ -0,0 +1,41 @@ +package com.fuint.common.config; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.io.InputStream; +import java.util.Properties; + +/** + * 图形验证码组件配置 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Configuration +public class CaptchaConfig { + + private static final Logger logger = LoggerFactory.getLogger(CaptchaConfig.class); + + /** + * 验证码 + */ + @Bean + public DefaultKaptcha defaultCaptcha() { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties property = new Properties(); + try { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("captcha-conf.properties"); + property.load(inputStream); + Config config = new Config(property); + defaultKaptcha.setConfig(config); + } catch (Exception e) { + logger.error("Kaptcha properties load error {}", e); + throw new RuntimeException("Kaptcha properties load error"); + } + return defaultKaptcha; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/Message.java b/fuint-application/src/main/java/com/fuint/common/config/Message.java new file mode 100644 index 0000000..6540f6a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/Message.java @@ -0,0 +1,23 @@ +package com.fuint.common.config; + +/** + * 消息定义 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Message { + public static final String PARAM_ERROR = "参数出错"; + public static final String COUPON_NOT_EXIST = "该卡券不存在"; + public static final String COUPON_IS_EXPIRE = "该卡券未生效"; + public static final String USER_NOT_EXIST = "该用户不存在"; + public static final String MAX_COUPON_LIMIT = "已经领取过了"; + public static final String COUPON_TYPE_ERROR = "卡券类型有误"; + public static final String POINT_LIMIT = "您的积分不足"; + public static final String NEED_CODE = "需要领取码"; + public static final String CODE_ERROR = "领取码错误"; + public static final String CODE_ERROR_1 = "核销码错误"; + public static final String GRADE_ERROR = "该卡券不适用于您的会员等级"; + public static final String HAS_COUPON = "您已领取过该卡券"; + public static final String SEND_WAY_ERROR = "该卡券无法领取"; +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/MybatisPlusConfig.java b/fuint-application/src/main/java/com/fuint/common/config/MybatisPlusConfig.java new file mode 100644 index 0000000..bb57e45 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/MybatisPlusConfig.java @@ -0,0 +1,51 @@ +package com.fuint.common.config; + +import com.baomidou.mybatisplus.core.injector.ISqlInjector; +import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; +import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * MybatisPlus配置 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Configuration +@MapperScan({"com.fuint.repository.**.mapper"}) +public class MybatisPlusConfig { + + /** + * 分页插件 + * @return PaginationInterceptor + */ + @Bean + @ConditionalOnMissingBean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + /** + * 逻辑删除插件 + * + * @return LogicSqlInjector + */ + @Bean + @ConditionalOnMissingBean + public ISqlInjector sqlInjector() { + return new LogicSqlInjector(); + } + + /** + * 乐观锁插件 + * @return + */ + @Bean + public OptimisticLockerInterceptor optimisticLockerInterceptor() { + return new OptimisticLockerInterceptor(); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/RedisConfig.java b/fuint-application/src/main/java/com/fuint/common/config/RedisConfig.java new file mode 100644 index 0000000..97ab611 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/RedisConfig.java @@ -0,0 +1,67 @@ +package com.fuint.common.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.session.data.redis.config.ConfigureRedisAction; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; + +/** + * 配置redis缓存 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Configuration +@EnableCaching +@EnableRedisHttpSession +public class RedisConfig extends CachingConfigurerSupport { + + @Autowired + private RedisConnectionFactory redisConnectionFactory; + + @Bean + public KeyGenerator keyGenerator() { + return (target, method, params) -> { + StringBuilder sb = new StringBuilder(); + sb.append(target.getClass().getName()); + sb.append(method.getName()); + for (Object obj : params) { + sb.append(obj.toString()); + } + return sb.toString(); + }; + } + + @Bean + public static ConfigureRedisAction configureRedisAction() { + return ConfigureRedisAction.NO_OP; + } + + @Bean + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer(ObjectMapper objectMapper) { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>( + Object.class); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + return jackson2JsonRedisSerializer; + } + + @Bean + RedisTemplate redisTemplate(Jackson2JsonRedisSerializer jackson2JsonRedisSerializer) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer); + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + redisTemplate.setKeySerializer(stringRedisSerializer); + redisTemplate.setHashKeySerializer(stringRedisSerializer); + return redisTemplate; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/SecurityConfig.java b/fuint-application/src/main/java/com/fuint/common/config/SecurityConfig.java new file mode 100644 index 0000000..3a3356e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/SecurityConfig.java @@ -0,0 +1,100 @@ +package com.fuint.common.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +/** + * 安全中心配置 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + /** + * 解决 无法直接注入 AuthenticationManager + * + * @return + * @throws Exception + */ + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + /** + * anyRequest | 匹配所有请求路径 + * access | SpringEl表达式结果为true时可以访问 + * anonymous | 匿名可以访问 + * denyAll | 用户不能访问 + * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) + * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 + * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 + * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 + * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 + * hasRole | 如果有参数,参数表示角色,则其角色可以访问 + * permitAll | 用户可以任意访问 + * rememberMe | 允许通过remember-me登录的用户访问 + * authenticated | 用户登录后可访问 + */ + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity + // CSRF禁用,因为不使用session + .csrf().disable() + // 基于token,所以不需要session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + // 过滤请求 + .authorizeRequests() + // 允许匿名访问 + .antMatchers( + "/clientApi/**", + "/backendApi/**", + "/merchantApi/**" + ).anonymous() + .antMatchers( + HttpMethod.GET, + "/", + "/static/**", + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/profile/**" + ).permitAll() + .antMatchers("/swagger-ui.html").anonymous() + .antMatchers("/swagger-resources/**").anonymous() + .antMatchers("/webjars/**").anonymous() + .antMatchers("/*/api-docs").anonymous() + .antMatchers("/druid/**").anonymous() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest().authenticated() + .and() + .headers().frameOptions().disable(); + } + + /** + * 强散列哈希加密实现 + */ + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + /** + * 身份认证接口 + */ + @Override + protected void configure(AuthenticationManagerBuilder auth) { + // empty + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/config/SwaggerConfig.java b/fuint-application/src/main/java/com/fuint/common/config/SwaggerConfig.java new file mode 100644 index 0000000..32febeb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/SwaggerConfig.java @@ -0,0 +1,44 @@ +package com.fuint.common.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * Swagger接口文档 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig implements WebMvcConfigurer { + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .enable(true) + .select() + .apis(RequestHandlerSelectors.basePackage("com.fuint.module")) + .build(); + } + + @Bean + public ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("fuint会员营销系统接口文档") + .description("fuint会员营销系统接口文档,“/clientApi”目录接口为会员端相关接口,“/backendApi”目录接口为后台管理端相关接口。") + .termsOfServiceUrl("https://www.fuint.cn/") + .contact(new Contact("海南延禾信息技术有限公司","https://www.fuint.cn/", "fushengqian@qq.com")) + .version("1.0") + .build(); + } +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/config/WebConfig.java b/fuint-application/src/main/java/com/fuint/common/config/WebConfig.java new file mode 100644 index 0000000..0a05cfd --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/config/WebConfig.java @@ -0,0 +1,110 @@ +package com.fuint.common.config; + +import com.fuint.common.web.AdminUserInterceptor; +import com.fuint.common.web.CommandInterceptor; +import com.fuint.common.web.ClientUserInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.servlet.config.annotation.*; +import org.springframework.web.servlet.resource.CssLinkResourceTransformer; +import org.springframework.web.servlet.resource.VersionResourceResolver; +import java.util.concurrent.TimeUnit; + +/** + * web配置 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Configuration +public class WebConfig extends WebMvcConfigurationSupport { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**") + .addResourceLocations("/resources/", "classpath:/other-resources/") + .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)) + .resourceChain(false) + .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**")) + .addTransformer(new CssLinkResourceTransformer()); + registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); + + registry.addResourceHandler("/**").addResourceLocations( + "classpath:/static/"); + registry.addResourceHandler("swagger-ui.html").addResourceLocations( + "classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations( + "classpath:/META-INF/resources/webjars/"); + super.addResourceHandlers(registry); + } + + @Bean + public CommandInterceptor commandInterceptor() { + return new CommandInterceptor(); + } + + @Bean + public AdminUserInterceptor adminUserInterceptor() { + return new AdminUserInterceptor(); + } + + @Bean + public ClientUserInterceptor portalUserInterceptor() { + return new ClientUserInterceptor(); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + // Command + registry.addInterceptor(commandInterceptor()) + .addPathPatterns("/cmd/**"); + + // 后台拦截 + registry.addInterceptor(adminUserInterceptor()) + .addPathPatterns("/backendApi/**") + .excludePathPatterns("/clientApi/captcha/**") + .excludePathPatterns("/backendApi/captcha/**") + .excludePathPatterns("/backendApi/userCoupon/exportList") + .excludePathPatterns("/backendApi/order/export") + .excludePathPatterns("/backendApi/goods/goods/downloadTemplate") + .excludePathPatterns("/backendApi/member/downloadTemplate") + .excludePathPatterns("/backendApi/login/**"); + + // 客户端拦截 + registry.addInterceptor(portalUserInterceptor()) + .addPathPatterns("/clientApi/**") + .excludePathPatterns("/clientApi/sign/**") + .excludePathPatterns("/clientApi/page/home") + .excludePathPatterns("/clientApi/captcha/**") + .excludePathPatterns("/clientApi/goodsApi/**") + .excludePathPatterns("/clientApi/coupon/list") + .excludePathPatterns("/clientApi/coupon/detail") + .excludePathPatterns("/clientApi/cart/**") + .excludePathPatterns("/clientApi/user/**") + .excludePathPatterns("/clientApi/settlement/submit") + .excludePathPatterns("/clientApi/pay/doPay") + .excludePathPatterns("/clientApi/pay/weixinCallback") + .excludePathPatterns("/clientApi/pay/weixinRefundNotify") + .excludePathPatterns("/clientApi/pay/aliPayCallback") + .excludePathPatterns("/clientApi/order/todoCounts") + .excludePathPatterns("/clientApi/order/detail") + .excludePathPatterns("/clientApi/store/**") + .excludePathPatterns("/clientApi/article/**") + .excludePathPatterns("/clientApi/message/getOne") + .excludePathPatterns("/clientApi/message/wxPush") + .excludePathPatterns("/clientApi/sms/sendVerifyCode") + .excludePathPatterns("/clientApi/book/list") + .excludePathPatterns("/clientApi/book/detail") + .excludePathPatterns("/clientApi/book/cateList"); + } + + @Bean + public CharacterEncodingFilter characterEncodingFilter() { + CharacterEncodingFilter filter = new CharacterEncodingFilter(); + filter.setEncoding("UTF-8"); + filter.setForceEncoding(true); + return filter; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/domain/TreeNode.java b/fuint-application/src/main/java/com/fuint/common/domain/TreeNode.java new file mode 100644 index 0000000..dc4803a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/domain/TreeNode.java @@ -0,0 +1,66 @@ +package com.fuint.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 树状结构节点实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class TreeNode implements Serializable { + + @ApiModelProperty("菜单ID") + private long id; + + @ApiModelProperty("菜单名称") + private String name; + + @ApiModelProperty("菜单名称(字母)") + private String ename; + + @ApiModelProperty("节点是否打开") + private Boolean open; + + @ApiModelProperty("是否菜单") + private int isMenu; + + @ApiModelProperty("节点是否选中") + private Boolean checked; + + @ApiModelProperty("url") + private String url; + + @ApiModelProperty("路径") + private String path; + + @ApiModelProperty("权限标识") + private String perms; + + @ApiModelProperty("子菜单") + private List childrens = new ArrayList<>(); + + @ApiModelProperty("菜单级别") + private int level; + + @ApiModelProperty("上级菜单") + private long pId; + + @ApiModelProperty("图标") + private String icon; + + @ApiModelProperty("新图标") + private String newIcon; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/domain/TreeSelect.java b/fuint-application/src/main/java/com/fuint/common/domain/TreeSelect.java new file mode 100644 index 0000000..afdebfb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/domain/TreeSelect.java @@ -0,0 +1,61 @@ +package com.fuint.common.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; + +/** + * TreeSelect树结构实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class TreeSelect implements Serializable { + + private static final long serialVersionUID = 1L; + + // 节点ID + private Long id; + + // 节点名称 + private String label; + + // 子节点 + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List childrens; + + public TreeSelect() { + // empty + } + + public TreeSelect(TreeNode menu) { + this.id = menu.getId(); + this.label = menu.getName(); + this.childrens = menu.getChildrens().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public List getChildrens() { + return childrens; + } + + public void setChildrens(List childrens) { + this.childrens = childrens; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/AccountDto.java b/fuint-application/src/main/java/com/fuint/common/dto/AccountDto.java new file mode 100644 index 0000000..3dc4371 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/AccountDto.java @@ -0,0 +1,67 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.util.Date; + +/** + * 后台账户实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class AccountDto { + + @ApiModelProperty("账户主键id") + private Integer id; + + @ApiModelProperty("账户编码") + private String accountKey; + + @ApiModelProperty("账户名称") + private String accountName; + + @ApiModelProperty("密码") + private String password; + + @ApiModelProperty("状态 : 0 无效 1 有效") + private int accountStatus; + + @ApiModelProperty("激活状态 : 0 未激活 1已激活") + private int isActive; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createDate; + + @ApiModelProperty("修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date modifyDate; + + @ApiModelProperty("随机码(公盐)") + private String salt; + + @ApiModelProperty("是否被锁定") + private int locked; + + @ApiModelProperty("真实姓名") + private String realName; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属商户名称") + private String merchantName; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺名称") + private String storeName; + + @ApiModelProperty("关联员工ID") + private Integer staffId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/AccountInfo.java b/fuint-application/src/main/java/com/fuint/common/dto/AccountInfo.java new file mode 100644 index 0000000..4b20ef1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/AccountInfo.java @@ -0,0 +1,74 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +/** + * 后台登录账号信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class AccountInfo implements Serializable { + + @ApiModelProperty("账户主键id") + private Integer id; + + @ApiModelProperty("账户编码") + private String accountKey; + + @ApiModelProperty("账户名称") + private String accountName; + + @ApiModelProperty("状态 : 0 无效 1 有效") + private int accountStatus; + + @ApiModelProperty("激活状态 : 0 未激活 1已激活") + private String isActive; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createDate; + + @ApiModelProperty("修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date modifyDate; + + @ApiModelProperty("随机码(公盐)") + private String salt; + + @ApiModelProperty("所属角色ID") + private String roleIds; + + @ApiModelProperty("是否被锁定") + private int locked; + + @ApiModelProperty("从属对象") + private int ownerId; + + @ApiModelProperty("真实姓名") + private String realName; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属商户名称") + private String merchantName; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺名称") + private String storeName; + + @ApiModelProperty("关联员工ID") + private Integer staffId; + + @ApiModelProperty("登录的Token") + private String token; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/AddressDto.java b/fuint-application/src/main/java/com/fuint/common/dto/AddressDto.java new file mode 100644 index 0000000..619fa73 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/AddressDto.java @@ -0,0 +1,54 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员地址信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class AddressDto implements Serializable { + + @ApiModelProperty("账户主键ID") + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("会员名称") + private String name; + + @ApiModelProperty("会员手机号") + private String mobile; + + @ApiModelProperty("省份ID") + private Integer provinceId; + + @ApiModelProperty("省份名称") + private String provinceName; + + @ApiModelProperty("城市ID") + private Integer cityId; + + @ApiModelProperty("城市名称") + private String cityName; + + @ApiModelProperty("区ID") + private Integer regionId; + + @ApiModelProperty("区名称") + private String regionName; + + @ApiModelProperty("详细地址") + private String detail; + + @ApiModelProperty("是否默认地址") + private String isDefault; + + @ApiModelProperty("状态") + private String status; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ArticleDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ArticleDto.java new file mode 100644 index 0000000..bdc3fc9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ArticleDto.java @@ -0,0 +1,60 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +/** + * 文章实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ArticleDto implements Serializable { + + @ApiModelProperty("账户主键ID") + private Integer id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("简介") + private String brief; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺") + private Integer storeId; + + @ApiModelProperty("链接地址") + private String url; + + @ApiModelProperty("点击数") + private Long click; + + @ApiModelProperty("图片地址") + private String image; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态 A:正常;D:删除") + private String status; + + @ApiModelProperty("排序") + private Integer sort; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/AssetDto.java b/fuint-application/src/main/java/com/fuint/common/dto/AssetDto.java new file mode 100644 index 0000000..b907345 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/AssetDto.java @@ -0,0 +1,23 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 个人资产实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class AssetDto { + + @ApiModelProperty("次卡数量") + private Integer timer; + + @ApiModelProperty("储值卡数量") + private Integer prestore; + + @ApiModelProperty("优惠券数量") + private Integer coupon; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BalanceDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BalanceDto.java new file mode 100644 index 0000000..deb8da8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BalanceDto.java @@ -0,0 +1,53 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 余额变动实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BalanceDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("会员信息") + private MtUser userInfo; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("余额变化数量") + private BigDecimal amount; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("创建时间") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BannerDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BannerDto.java new file mode 100644 index 0000000..870cec3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BannerDto.java @@ -0,0 +1,57 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 焦点图实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BannerDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("链接地址") + private String url; + + @ApiModelProperty("图片地址") + private String image; + + @ApiModelProperty("描述信息") + private String description; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("创建时间") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("状态,A正常;D删除") + private String status; +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/Body.java b/fuint-application/src/main/java/com/fuint/common/dto/Body.java new file mode 100644 index 0000000..53ccac9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/Body.java @@ -0,0 +1,31 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Map; + +/** + * 消息体Body信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class Body implements Serializable { + + @ApiModelProperty("入参信息") + private Map inParams; + + @ApiModelProperty("出参信息") + private Map outParams; + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Body{"); + sb.append("inParams=").append(inParams); + sb.append(", outParams=").append(outParams); + sb.append('}'); + return sb.toString(); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BookCateDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BookCateDto.java new file mode 100644 index 0000000..7ca18a6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BookCateDto.java @@ -0,0 +1,51 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约分类实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookCateDto implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("分类名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("图片地址") + private String logo; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BookDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BookDto.java new file mode 100644 index 0000000..35c29e5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BookDto.java @@ -0,0 +1,83 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookDto implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("预约名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("预约类型") + private String type; + + @ApiModelProperty("图片地址") + private String logo; + + @ApiModelProperty("关联商品ID") + private Integer goodsId; + + @ApiModelProperty("类别ID") + private Integer cateId; + + @ApiModelProperty("可预约日期") + private String serviceDates; + + @ApiModelProperty("可预约日期,字符串") + private String dates = ""; + + @ApiModelProperty("可预约日期列表") + private List dateList; + + @ApiModelProperty("可预约时间段") + private String serviceTimes; + + @ApiModelProperty("可预约时间段列表") + private List timeList; + + @ApiModelProperty("可预约可预约时段") + private List times; + + @ApiModelProperty("可预约员工ID") + private String serviceStaffIds; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BookItemDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BookItemDto.java new file mode 100644 index 0000000..516a62d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BookItemDto.java @@ -0,0 +1,87 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; + +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约订单Dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookItemDto implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("预约分类ID") + private Integer cateId; + + @ApiModelProperty("预约项目ID") + private Integer bookId; + + @ApiModelProperty("预约项目名称") + private String bookName; + + @ApiModelProperty("预约用户ID") + private Integer userId; + + @ApiModelProperty("订单商品ID") + private Integer goodsId; + + @ApiModelProperty("已购商品名称") + private String goodsName; + + @ApiModelProperty("核销码") + private String verifyCode; + + @ApiModelProperty("预约联系人") + private String contact; + + @ApiModelProperty("预约手机号") + private String mobile; + + @ApiModelProperty("预约日期") + private String serviceDate; + + @ApiModelProperty("预约时间段") + private String serviceTime; + + @ApiModelProperty("预约备注") + private String remark; + + @ApiModelProperty("预约员工ID") + private Integer serviceStaffId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("A:已提交;B:审核通过;C:审核未通过;D:删除;E:已完成") + private String status; + + @ApiModelProperty("状态") + private String statusName; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/BookTimeDto.java b/fuint-application/src/main/java/com/fuint/common/dto/BookTimeDto.java new file mode 100644 index 0000000..ce9ea27 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/BookTimeDto.java @@ -0,0 +1,25 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约时段Dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookTimeDto implements Serializable { + + @ApiModelProperty("时间段") + private String startTime; + + @ApiModelProperty("时间段") + private String endTime; + + @ApiModelProperty("可预订数量") + private String num; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CommissionCashDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CommissionCashDto.java new file mode 100644 index 0000000..84a9ea1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CommissionCashDto.java @@ -0,0 +1,67 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtStaff; +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 分销提成提现实体 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionCashDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("结算单号") + private String settleNo; + + @ApiModelProperty("结算uuid") + private String uuid; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("用户信息") + private OrderUserDto userInfo; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("所属店铺信息") + private MtStaff staffInfo; + + @ApiModelProperty("金额") + private BigDecimal amount; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CommissionLogDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CommissionLogDto.java new file mode 100644 index 0000000..47974af --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CommissionLogDto.java @@ -0,0 +1,96 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtCommissionRule; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtStaff; +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 分销提成记录实体 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionLogDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("分佣类型") + private String type; + + @ApiModelProperty("分佣对象") + private String target; + + @ApiModelProperty("分佣类型名称") + private String typeName; + + @ApiModelProperty("分佣等级") + private Integer level; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("用户信息") + private OrderUserDto userInfo; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("所属店铺信息") + private MtStaff staffInfo; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("订单信息") + private MtOrder orderInfo; + + @ApiModelProperty("分佣金额") + private BigDecimal amount; + + @ApiModelProperty("规则ID") + private Integer ruleId; + + @ApiModelProperty("分佣规则信息") + private MtCommissionRule ruleInfo; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("提现记录ID") + private Integer cashId; + + @ApiModelProperty("最后操作人") + private String isCash; + + @ApiModelProperty("提现时间") + private Date cashTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CommissionRelationDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRelationDto.java new file mode 100644 index 0000000..421b432 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRelationDto.java @@ -0,0 +1,57 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +/** + * 分销提成邀请记录实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRelationDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("会员信息") + private MtUser userInfo; + + @ApiModelProperty("邀请码") + private String inviteCode; + + @ApiModelProperty("被邀请会员ID") + private Integer subUserId; + + @ApiModelProperty("会员信息") + private MtUser subUserInfo; + + @ApiModelProperty("等级") + private Integer level; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleDto.java new file mode 100644 index 0000000..169cc42 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleDto.java @@ -0,0 +1,64 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 分销提成规则实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRuleDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("规则名称") + private String name; + + @ApiModelProperty("方案类型,goods:商品销售;coupon:卡券销售;recharge:会员充值") + private String type; + + @ApiModelProperty("分佣对象,member:会员分销;staff:员工提成") + private String target; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("适用店铺ID列表") + private List storeIdList; + + @ApiModelProperty("具体项目列表") + private List detailList; + + @ApiModelProperty("散客值") + private BigDecimal visitorVal; + + @ApiModelProperty("会员值") + private BigDecimal memberVal; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleItemDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleItemDto.java new file mode 100644 index 0000000..7301938 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CommissionRuleItemDto.java @@ -0,0 +1,40 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 分销提成规则项目实体 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRuleItemDto implements Serializable { + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("商品名称") + private String goodsName; + + @ApiModelProperty("商品logo") + private String logo; + + @ApiModelProperty("商品价格") + private BigDecimal price; + + @ApiModelProperty("方案类型,goods:商品销售;coupon:卡券销售;recharge:会员充值") + private String type; + + @ApiModelProperty("提成方式") + private String method; + + @ApiModelProperty("散客值") + private BigDecimal visitorVal; + + @ApiModelProperty("会员值") + private BigDecimal memberVal; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ConfirmLogDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ConfirmLogDto.java new file mode 100644 index 0000000..df6e69d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ConfirmLogDto.java @@ -0,0 +1,65 @@ +package com.fuint.common.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fuint.repository.model.MtCoupon; +import com.fuint.repository.model.MtStore; +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 核销卡券流水dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ConfirmLogDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("核销编码") + private String code; + + @ApiModelProperty("核销状态") + private String status; + + @ApiModelProperty("会员卡券ID") + private Integer userCouponId; + + @ApiModelProperty("卡券信息") + private MtCoupon couponInfo; + + @ApiModelProperty("会员信息") + private MtUser userInfo; + + @ApiModelProperty("核销店铺信息") + private MtStore storeInfo; + + @JSONField(format="yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("创建时间") + private Date createTime; + + @JSONField(format="yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("核销金额") + private BigDecimal amount; + + @ApiModelProperty("核销uuid") + private String uuid; + + @ApiModelProperty("核销备注") + private String remark; + + @ApiModelProperty("最后操作人") + private String operator; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CouponCellDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CouponCellDto.java new file mode 100644 index 0000000..d73192c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CouponCellDto.java @@ -0,0 +1,28 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.util.List; + +/** + * 卡券导入单元实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CouponCellDto { + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("分组ID") + private List groupId; + + @ApiModelProperty("发放数量") + private List num; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/CouponDto.java b/fuint-application/src/main/java/com/fuint/common/dto/CouponDto.java new file mode 100644 index 0000000..50d3317 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/CouponDto.java @@ -0,0 +1,80 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 卡券实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CouponDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("卡券名称") + private String name; + + @ApiModelProperty("卡券类型") + private String type; + + @ApiModelProperty("内容") + private Integer content; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("获取规则") + private String inRule; + + @ApiModelProperty("使用规则") + private String outRule; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("面额") + private BigDecimal amount; + + @ApiModelProperty("领取需要积分数量") + private Integer point; + + @ApiModelProperty("卖点") + private String sellingPoint; + + @ApiModelProperty("已领取、预存数量") + private Integer gotNum; + + @ApiModelProperty("剩余数量") + private Integer leftNum; + + @ApiModelProperty("发行数量") + private Integer total; + + @ApiModelProperty("限制数量") + private Integer limitNum; + + @ApiModelProperty("适用店铺") + private String storeNames; + + @ApiModelProperty("是否领取") + private Boolean isReceive; + + @ApiModelProperty("是否需要领取码") + private boolean needReceiveCode; + + @ApiModelProperty("会员卡券ID") + private int userCouponId; + + @ApiModelProperty("有效期") + private String effectiveDate; + + @ApiModelProperty("卡券说明") + private String description; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/DateDto.java b/fuint-application/src/main/java/com/fuint/common/dto/DateDto.java new file mode 100644 index 0000000..a4ddadd --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/DateDto.java @@ -0,0 +1,20 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 日期实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class DateDto { + + @ApiModelProperty("开始时间") + private String startDate; + + @ApiModelProperty("结束时间") + private String endDate; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/DayDto.java b/fuint-application/src/main/java/com/fuint/common/dto/DayDto.java new file mode 100644 index 0000000..97dc4e3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/DayDto.java @@ -0,0 +1,24 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 日期Dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class DayDto implements Serializable { + + @ApiModelProperty("星期") + private String week; + + @ApiModelProperty("日期") + private String date; + + @ApiModelProperty("是否可预订") + private Boolean enable; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ExpressDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ExpressDto.java new file mode 100644 index 0000000..0ab0d0f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ExpressDto.java @@ -0,0 +1,27 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 订单物流信息dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ExpressDto { + + @ApiModelProperty("物流公司名称") + private String expressCompany; + + @ApiModelProperty("物流公司编码") + private String expressCode; + + @ApiModelProperty("物流单号") + private String expressNo; + + @ApiModelProperty("发货时间") + private String expressTime; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GiveDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GiveDto.java new file mode 100644 index 0000000..645e25c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GiveDto.java @@ -0,0 +1,76 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 卡券转赠实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GiveDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("获赠者会员ID") + private Integer userId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("赠送者会员ID") + private Integer giveUserId; + + @ApiModelProperty("获赠者手机号") + private String mobile; + + @ApiModelProperty("转赠者手机号") + private String userMobile; + + @ApiModelProperty("分组ID,逗号隔开") + private String groupIds; + + @ApiModelProperty("分组名称,逗号隔开") + private String groupNames; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("券ID,逗号隔开") + private String couponIds; + + @ApiModelProperty("券名称,逗号隔开") + private String couponNames; + + @ApiModelProperty("数量") + private Integer num; + + @ApiModelProperty("总金额") + private BigDecimal money; + + @ApiModelProperty("备注") + private String note; + + @ApiModelProperty("留言") + private String message; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("赠送时间") + private String createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private String updateTime; + + @ApiModelProperty("状态,A正常;C取消 ") + private String status; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GiveItemDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GiveItemDto.java new file mode 100644 index 0000000..f1aec6e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GiveItemDto.java @@ -0,0 +1,47 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 转赠明细实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GiveItemDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("赠予对象手机号") + private String mobile; + + @ApiModelProperty("用户手机") + private String userMobile; + + @ApiModelProperty("分组ID") + private Integer groupId; + + @ApiModelProperty("分组名称") + private String groupName; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("卡券名称") + private String couponName; + + @ApiModelProperty("总金额") + private BigDecimal money; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("赠送时间") + private Date createTime; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsCateDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsCateDto.java new file mode 100644 index 0000000..82d46ef --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsCateDto.java @@ -0,0 +1,59 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品分类DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsCateDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属商户名称") + private String merchantName; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("所属店铺名称") + private String storeName; + + @ApiModelProperty("分类名称") + private String name; + + @ApiModelProperty("LOGO地址") + private String logo; + + @ApiModelProperty("分类描述") + private String description; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("创建时间") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsDetailDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsDetailDto.java new file mode 100644 index 0000000..4c9da6e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsDetailDto.java @@ -0,0 +1,92 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 商品详情实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsDetailDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer goodsId; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("商品条码") + private String goodsNo; + + @ApiModelProperty("可否单规格") + private String isSingleSpec; + + @ApiModelProperty("主图地址") + private String logo; + + @ApiModelProperty("图片地址") + private List images; + + @ApiModelProperty("商品价格") + private BigDecimal price; + + @ApiModelProperty("划线价格") + private BigDecimal linePrice; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("商品重量") + private BigDecimal weight; + + @ApiModelProperty("初始销量") + private Double initSale; + + @ApiModelProperty("商品卖点") + private String salePoint; + + @ApiModelProperty("可否使用积分抵扣") + private String canUsePoint; + + @ApiModelProperty("会员是否有折扣") + private String isMemberDiscount; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("商品描述") + private String description; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("创建时间") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A:正常;D:删除") + private String status; + + @ApiModelProperty("sku列表") + private List skuList; + + @ApiModelProperty("规格列表") + private List specList; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsDto.java new file mode 100644 index 0000000..d5f1895 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsDto.java @@ -0,0 +1,132 @@ +package com.fuint.common.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fuint.repository.model.MtGoodsCate; +import com.fuint.repository.model.MtGoodsSku; +import com.fuint.repository.model.MtGoodsSpec; +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 商品DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("分配店铺ID集合") + private String storeIds; + + @ApiModelProperty("所属店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("商品类型") + private String type; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("预约项目ID") + private Integer bookId; + + @ApiModelProperty("分类信息") + private MtGoodsCate cateInfo; + + @ApiModelProperty("商品条码") + private String goodsNo; + + @ApiModelProperty("可用平台,0:不限,1:仅会员端(小程序和h5);2:仅收银端") + private Integer platform; + + @ApiModelProperty("可否单规格") + private String isSingleSpec; + + @ApiModelProperty("主图地址") + private String logo; + + @ApiModelProperty("图片地址") + private String images; + + @ApiModelProperty("价格") + private BigDecimal price; + + @ApiModelProperty("划线价格") + private BigDecimal linePrice; + + @ApiModelProperty("成本价格") + private BigDecimal costPrice; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("数量") + private Double num; + + @ApiModelProperty("服务时长") + private Integer serviceTime; + + @ApiModelProperty("卡券ID") + private String couponIds; + + @ApiModelProperty("重量") + private BigDecimal weight; + + @ApiModelProperty("初始销量") + private Double initSale; + + @ApiModelProperty("商品卖点") + private String salePoint; + + @ApiModelProperty("可否使用积分抵扣") + private String canUsePoint; + + @ApiModelProperty("会员是否有折扣") + private String isMemberDiscount; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("商品描述") + private String description; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("创建时间") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A:正常;D:删除") + private String status; + + @ApiModelProperty("skuId") + private Integer skuId; + + @ApiModelProperty("sku列表") + private List skuList; + + @ApiModelProperty("规格列表") + private List specList; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsSkuDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSkuDto.java new file mode 100644 index 0000000..6801de7 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSkuDto.java @@ -0,0 +1,53 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtGoodsSpec; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.math.BigDecimal; + +/** + * 商品sku实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsSkuDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("sku编码") + private String skuNo; + + @ApiModelProperty("图片") + private String logo; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("规格ID") + private String specIds; + + @ApiModelProperty("规格列表") + private List specList; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("价格") + private BigDecimal price; + + @ApiModelProperty("划线价格") + private BigDecimal linePrice; + + @ApiModelProperty("成本价格") + private BigDecimal costPrice; + + @ApiModelProperty("重量") + private BigDecimal weight; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecChildDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecChildDto.java new file mode 100644 index 0000000..2f9a95f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecChildDto.java @@ -0,0 +1,27 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 商品规格子类实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsSpecChildDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("规格名称") + private String name; + + @ApiModelProperty("是否选择") + private boolean checked; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecDto.java new file mode 100644 index 0000000..635d1be --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecDto.java @@ -0,0 +1,28 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 商品规格实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsSpecDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer specId; + + @ApiModelProperty("规格名称") + private String name; + + @ApiModelProperty("规格值列表") + private List valueList; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecItemDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecItemDto.java new file mode 100644 index 0000000..f206a67 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecItemDto.java @@ -0,0 +1,28 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 商品规格项实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsSpecItemDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("规格名称") + private String name; + + @ApiModelProperty("规格子类") + private List child; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecValueDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecValueDto.java new file mode 100644 index 0000000..b5d87e8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsSpecValueDto.java @@ -0,0 +1,27 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 商品规格值实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsSpecValueDto implements Serializable { + + @ApiModelProperty("值ID") + private Integer specValueId; + + @ApiModelProperty("规格名") + private String specName; + + @ApiModelProperty("规格值") + private String specValue; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GoodsTopDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GoodsTopDto.java new file mode 100644 index 0000000..4d00a86 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GoodsTopDto.java @@ -0,0 +1,34 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 商品排行DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsTopDto implements Serializable { + + @ApiModelProperty("商品ID") + private Integer id; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("商品条码") + private String goodsNo; + + @ApiModelProperty("销售金额") + private BigDecimal amount; + + @ApiModelProperty("销售数量") + private Integer num; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GroupDataDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GroupDataDto.java new file mode 100644 index 0000000..8c05bc8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GroupDataDto.java @@ -0,0 +1,31 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 卡券分组数据DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GroupDataDto implements Serializable { + + @ApiModelProperty("发放数量") + private Integer sendNum; + + @ApiModelProperty("未发放数量") + private Integer unSendNum; + + @ApiModelProperty("使用数量") + private Integer useNum; + + @ApiModelProperty("过期数量") + private Integer expireNum; + + @ApiModelProperty("取消数量") + private Integer cancelNum; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GroupDataListDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GroupDataListDto.java new file mode 100644 index 0000000..c3d51cf --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GroupDataListDto.java @@ -0,0 +1,21 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 卡券分组数据DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GroupDataListDto { + + @ApiModelProperty("键值") + private String key; + + @ApiModelProperty("数据") + private GroupDataDto data; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/GroupMemberDto.java b/fuint-application/src/main/java/com/fuint/common/dto/GroupMemberDto.java new file mode 100644 index 0000000..689df05 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/GroupMemberDto.java @@ -0,0 +1,28 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 分组会员DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GroupMemberDto implements Serializable { + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员名称") + private String name; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("会员名称") + private String mobile; +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/HangUpDto.java b/fuint-application/src/main/java/com/fuint/common/dto/HangUpDto.java new file mode 100644 index 0000000..0efe0af --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/HangUpDto.java @@ -0,0 +1,36 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 收银挂单实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class HangUpDto { + + @ApiModelProperty("挂单号") + private String hangNo; + + @ApiModelProperty("是否空白") + private Boolean isEmpty; + + @ApiModelProperty("会员信息") + private MtUser memberInfo; + + @ApiModelProperty("件数") + private Double num; + + @ApiModelProperty("金额") + private BigDecimal amount; + + @ApiModelProperty("时间") + private String dateTime; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/Head.java b/fuint-application/src/main/java/com/fuint/common/dto/Head.java new file mode 100644 index 0000000..993c5b4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/Head.java @@ -0,0 +1,38 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 消息体头信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class Head implements Serializable { + + @ApiModelProperty("服务编号,用于确定唯一的服务") + private String serviceId; + + @ApiModelProperty("授权Token信息") + private String token; + + @ApiModelProperty("服务执行返回码(000000:正常)") + private String returnCode; + + @ApiModelProperty("服务执行返回信息") + private String returnDesc; + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Head{"); + sb.append("serviceId='").append(serviceId).append('\''); + sb.append(", token='").append(token).append('\''); + sb.append(", returnCode='").append(returnCode).append('\''); + sb.append(", returnDesc='").append(returnDesc).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MemberGroupDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MemberGroupDto.java new file mode 100644 index 0000000..c7c62f6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MemberGroupDto.java @@ -0,0 +1,48 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员分组实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberGroupDto implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("分组ID") + private Integer id; + + @ApiModelProperty("分组名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("默认店铺") + private Integer storeId; + + @ApiModelProperty("父ID") + private Integer parentId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MemberTopDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MemberTopDto.java new file mode 100644 index 0000000..4df817e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MemberTopDto.java @@ -0,0 +1,34 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 会员排行DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberTopDto implements Serializable { + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员名称") + private String name; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("消费金额") + private BigDecimal amount; + + @ApiModelProperty("购买数量") + private Integer num; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MerchantDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MerchantDto.java new file mode 100644 index 0000000..a974dca --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MerchantDto.java @@ -0,0 +1,68 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商户实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MerchantDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("微信小程序appId") + private String wxAppId; + + @ApiModelProperty("微信小程序秘钥") + private String wxAppSecret; + + @ApiModelProperty("微信公众号appId") + private String wxOfficialAppId; + + @ApiModelProperty("微信公众号秘钥") + private String wxOfficialAppSecret; + + @ApiModelProperty("商户号") + private String no; + + @ApiModelProperty("商户名称") + private String name; + + @ApiModelProperty("商户logo") + private String logo; + + @ApiModelProperty("联系人姓名") + private String contact; + + @ApiModelProperty("联系电话") + private String phone; + + @ApiModelProperty("联系地址") + private String address; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:有效/启用;D:无效") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MerchantSettingDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MerchantSettingDto.java new file mode 100644 index 0000000..7a12f1e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MerchantSettingDto.java @@ -0,0 +1,34 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商户设置实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MerchantSettingDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户名称") + private String name; + + @ApiModelProperty("商户logo") + private String logo; + + @ApiModelProperty("联系人姓名") + private String contact; + + @ApiModelProperty("联系电话") + private String phone; + + @ApiModelProperty("营业状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MessageResDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MessageResDto.java new file mode 100644 index 0000000..d709c11 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MessageResDto.java @@ -0,0 +1,24 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 短信发送返回实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MessageResDto { + + @ApiModelProperty("发送ID") + private String[] sendIds; + + @ApiModelProperty("发送结果") + private Boolean result; + + @ApiModelProperty("短信ID") + private String[] smsId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/MyCouponDto.java b/fuint-application/src/main/java/com/fuint/common/dto/MyCouponDto.java new file mode 100644 index 0000000..66ed7e8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/MyCouponDto.java @@ -0,0 +1,77 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtStore; +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 我的卡券DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MyCouponDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("卡券名称") + private String name; + + @ApiModelProperty("核销编码") + private String code; + + @ApiModelProperty("卡券类型") + private String type; + + @ApiModelProperty("卡券内容") + private Integer content; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("使用规则") + private String useRule; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("面额") + private BigDecimal amount; + + @ApiModelProperty("余额") + private BigDecimal balance; + + @ApiModelProperty("剩余次数") + private Integer num; + + @ApiModelProperty("是否可用") + private boolean canUse; + + @ApiModelProperty("有效期") + private String effectiveDate; + + @ApiModelProperty("提示信息") + private String tips; + + @ApiModelProperty("使用时间") + private Date usedTime; + + @ApiModelProperty("领券时间") + private Date createTime; + + @ApiModelProperty("会员信息") + private MtUser userInfo; + + @ApiModelProperty("使用店铺") + private MtStore storeInfo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/NavigationDto.java b/fuint-application/src/main/java/com/fuint/common/dto/NavigationDto.java new file mode 100644 index 0000000..88402e6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/NavigationDto.java @@ -0,0 +1,37 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 导航栏实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class NavigationDto implements Serializable { + + @ApiModelProperty("导航名称") + private String name; + + @ApiModelProperty("导航提示") + private String tips; + + @ApiModelProperty("URL") + private String url; + + @ApiModelProperty("图标") + private String icon; + + @ApiModelProperty("图标完整路径") + private String iconUrl; + + @ApiModelProperty("导航排序") + private Integer sort; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/OpenGiftDto.java b/fuint-application/src/main/java/com/fuint/common/dto/OpenGiftDto.java new file mode 100644 index 0000000..53adf47 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/OpenGiftDto.java @@ -0,0 +1,51 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtCoupon; +import com.fuint.repository.model.MtStore; +import com.fuint.repository.model.MtUserGrade; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 开卡赠礼实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OpenGiftDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("会员等级信息") + private MtUserGrade gradeInfo; + + @ApiModelProperty("赠送积分") + private Integer point; + + @ApiModelProperty("卡券信息") + private MtCoupon couponInfo; + + @ApiModelProperty("卡券数量") + private Integer couponNum; + + @ApiModelProperty("创建时间") + private String createTime; + + @ApiModelProperty("更新时间") + private String updateTime; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/OpenWxCardDto.java b/fuint-application/src/main/java/com/fuint/common/dto/OpenWxCardDto.java new file mode 100644 index 0000000..0a810ea --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/OpenWxCardDto.java @@ -0,0 +1,33 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 开通微信会员卡实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OpenWxCardDto { + + @ApiModelProperty("会员编码") + private String code; + + @ApiModelProperty("会员openId") + private String openId; + + @ApiModelProperty("时间戳") + private String timestamp; + + @ApiModelProperty("随机字符串") + private String nonceStr; + + @ApiModelProperty("签名") + private String signature; + + @ApiModelProperty("微信会员卡ID") + private String cardId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/OrderDto.java b/fuint-application/src/main/java/com/fuint/common/dto/OrderDto.java new file mode 100644 index 0000000..e6ec9de --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/OrderDto.java @@ -0,0 +1,127 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("订单类型") + private String type; + + @ApiModelProperty("下单平台") + private String platform; + + @ApiModelProperty("支付类型") + private String payType; + + @ApiModelProperty("订单类型名称") + private String orderMode; + + @ApiModelProperty("核销码") + private String verifyCode; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("购物车ID") + private String cartIds; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("skuID") + private Integer skuId; + + @ApiModelProperty("购买数量") + private Double buyNum; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("是否游客") + private String isVisitor; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("订单金额") + private BigDecimal amount; + + @ApiModelProperty("支付金额") + private BigDecimal payAmount; + + @ApiModelProperty("使用积分数量") + private Integer usePoint; + + @ApiModelProperty("积分金额") + private BigDecimal pointAmount; + + @ApiModelProperty("折扣金额") + private BigDecimal discount; + + @ApiModelProperty("配送费用") + private BigDecimal deliveryFee; + + @ApiModelProperty("物流信息") + private ExpressDto expressInfo; + + @ApiModelProperty("订单参数") + private String param; + + @ApiModelProperty("用户备注") + private String remark; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("支付时间") + private Date payTime; + + @ApiModelProperty("订单状态") + private String status; + + @ApiModelProperty("支付状态") + private String payStatus; + + @ApiModelProperty(value="结算状态") + private String settleStatus; + + @ApiModelProperty("核销状态") + private String confirmStatus; + + @ApiModelProperty("核销时间") + private Date confirmTime; + + @ApiModelProperty("核销备注") + private String confirmRemark; + + @ApiModelProperty("最后操作人") + private String operator; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/OrderGoodsDto.java b/fuint-application/src/main/java/com/fuint/common/dto/OrderGoodsDto.java new file mode 100644 index 0000000..8174122 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/OrderGoodsDto.java @@ -0,0 +1,55 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 订单商品实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderGoodsDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("预约项目ID") + private Integer bookId; + + @ApiModelProperty("我的预约ID") + private Integer myBookId; + + @ApiModelProperty("订单类型") + private String type; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("价格") + private String price; + + @ApiModelProperty("折扣") + private String discount; + + @ApiModelProperty("购买数量") + private Double num; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("skuId") + private Integer skuId; + + @ApiModelProperty("规格列表") + private List specList; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/OrderUserDto.java b/fuint-application/src/main/java/com/fuint/common/dto/OrderUserDto.java new file mode 100644 index 0000000..54549ae --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/OrderUserDto.java @@ -0,0 +1,40 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 下单用户DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderUserDto implements Serializable { + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员号") + private String no; + + @ApiModelProperty("会员姓名") + private String name; + + @ApiModelProperty("会员手机") + private String mobile; + + @ApiModelProperty("证件类型") + private String cardType; + + @ApiModelProperty("证件号") + private String cardNo; + + @ApiModelProperty("地址") + private String address; + + @ApiModelProperty("openId") + private String openId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/Page.java b/fuint-application/src/main/java/com/fuint/common/dto/Page.java new file mode 100644 index 0000000..a39bfe9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/Page.java @@ -0,0 +1,120 @@ +package com.fuint.common.dto; + +import java.io.Serializable; + +/** + * 消息体分页信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Page implements Serializable { + + private static final Long DEFAULT_PAGE_NO = 1L; + private static final Long DEFAULT_PAGE_SIZE = 100L; + + private Long pageNo;// 页号 + private Long pageSize;// 每页行数 + private Long totalRows;// 总行数 + private Long totalPages;// 总页数 + private Boolean firstPage;// 是否首页 + private Boolean lastPage;// 是否尾页 + + public Page() { + } + + public Page(Long pageNo, Long pageSize) { + setPageNo(pageNo); + setPageSize(pageSize); + } + + public Long getPageNo() { + return pageNo; + } + + public void setPageNo(Long pageNo) { + if (pageNo == null || pageNo < 1) { + pageNo = DEFAULT_PAGE_NO; + } else if (totalPages != null && pageNo > totalPages) { + pageNo = totalPages; + } + this.pageNo = pageNo; + } + + public Long getPageSize() { + return pageSize; + } + + public void setPageSize(Long pageSize) { + if (pageSize == null) { + this.pageSize = DEFAULT_PAGE_SIZE; + } else if (pageSize < 1L) { + this.pageSize = 1L; + } else { + this.pageSize = pageSize; + } + } + + public Long getTotalRows() { + return totalRows; + } + + public void setTotalRows(Long totalRows) { + //总行数 + this.totalRows = totalRows; + //总页数 + this.totalPages = totalRows / this.pageSize; + if (totalRows % this.pageSize > 0) { + this.totalPages++; + } + //首页 + if (this.pageNo <= 1) { + firstPage = true; + } else { + firstPage = false; + } + //尾页 + if (this.pageNo >= this.totalPages) { + lastPage = true; + } else { + lastPage = false; + } + } + + public Long getTotalPages() { + return totalPages; + } + + public void setTotalPages(Long totalPages) { + this.totalPages = totalPages; + } + + public Boolean isFirstPage() { + return firstPage; + } + + public void setFirstPage(Boolean firstPage) { + this.firstPage = firstPage; + } + + public Boolean isLastPage() { + return lastPage; + } + + public void setLastPage(Boolean lastPage) { + this.lastPage = lastPage; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Page{"); + sb.append("pageNo=").append(pageNo); + sb.append(", pageSize=").append(pageSize); + sb.append(", totalRows=").append(totalRows); + sb.append(", totalPages=").append(totalPages); + sb.append(", firstPage=").append(firstPage); + sb.append(", lastPage=").append(lastPage); + sb.append('}'); + return sb.toString(); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ParamDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ParamDto.java new file mode 100644 index 0000000..cf98365 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ParamDto.java @@ -0,0 +1,30 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 请求参数实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ParamDto implements Serializable { + + @ApiModelProperty("参数键值") + private String key; + + @ApiModelProperty("参数名称") + private String name; + + @ApiModelProperty("参数值") + private String value; + + public ParamDto(String key, String name, String value) { + this.key = key; + this.name = name; + this.value = value; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/PointDto.java b/fuint-application/src/main/java/com/fuint/common/dto/PointDto.java new file mode 100644 index 0000000..ecfe9ff --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/PointDto.java @@ -0,0 +1,50 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 积分记录实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class PointDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("会员信息") + private MtUser userInfo; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("积分变化数量") + private Integer amount; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/PreStoreRuleDto.java b/fuint-application/src/main/java/com/fuint/common/dto/PreStoreRuleDto.java new file mode 100644 index 0000000..30da373 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/PreStoreRuleDto.java @@ -0,0 +1,22 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预存规则实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class PreStoreRuleDto implements Serializable { + + @ApiModelProperty("预存金额") + private String preStoreAmount; + + @ApiModelProperty("目标金额") + private String targetAmount; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/RechargeRuleDto.java b/fuint-application/src/main/java/com/fuint/common/dto/RechargeRuleDto.java new file mode 100644 index 0000000..921211d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/RechargeRuleDto.java @@ -0,0 +1,26 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 充值规则实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RechargeRuleDto implements Serializable { + + @ApiModelProperty("充值金额") + private String rechargeAmount; + + @ApiModelProperty("赠送金额") + private String giveAmount; + + @ApiModelProperty("赠送卡券ID") + private String giveCouponIds; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/RefundDto.java b/fuint-application/src/main/java/com/fuint/common/dto/RefundDto.java new file mode 100644 index 0000000..432f08b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/RefundDto.java @@ -0,0 +1,83 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 售后实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RefundDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("退款金额") + private BigDecimal amount; + + @ApiModelProperty("售后类型") + private String type; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("用户备注") + private String remark; + + @ApiModelProperty("物流公司名称") + private String expressName; + + @ApiModelProperty("物流单号") + private String expressNo; + + @ApiModelProperty("拒绝原因") + private String rejectReason; + + @ApiModelProperty("申请凭证图片") + private List imageList; + + @ApiModelProperty("申请凭证图片") + private String images; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("订单详情") + private UserOrderDto orderInfo; + + @ApiModelProperty("退货地址") + private AddressDto address; + + @ApiModelProperty("店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("创建时间") + private String createTime; + + @ApiModelProperty("更新时间") + private String updateTime; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("状态说明") + private String statusText; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/RegionDto.java b/fuint-application/src/main/java/com/fuint/common/dto/RegionDto.java new file mode 100644 index 0000000..f673068 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/RegionDto.java @@ -0,0 +1,39 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 地区实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RegionDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("父ID") + private Integer pid; + + @ApiModelProperty("编码") + private String code; + + @ApiModelProperty("层级") + private String level; + + @ApiModelProperty("城市") + private List city; + + @ApiModelProperty("区域") + private List region; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponDto.java new file mode 100644 index 0000000..ec32bc4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponDto.java @@ -0,0 +1,120 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 卡券请求DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ReqCouponDto implements Serializable { + + @ApiModelProperty("卡券ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("分组ID") + private Integer groupId; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("内容") + private Integer content; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("是否允许转赠") + private Integer isGive; + + @ApiModelProperty("获得卡券所消耗积分") + private Integer point; + + @ApiModelProperty("获得计次卡卡所消耗积分") + private Integer timerPoint; + + @ApiModelProperty("领取码") + private String receiveCode; + + @ApiModelProperty("使用专项") + private String useFor; + + @ApiModelProperty("过期类型") + private String expireType; + + @ApiModelProperty("有效天数") + private Integer expireTime; + + @ApiModelProperty("计次卡领取码") + private String timerReceiveCode; + + @ApiModelProperty("有效期开始时间") + private String beginTime; + + @ApiModelProperty("有效期结束时间") + private String endTime; + + @ApiModelProperty("价值金额") + private BigDecimal amount; + + @ApiModelProperty("发放方式") + private String sendWay; + + @ApiModelProperty("适用商品") + private String applyGoods; + + @ApiModelProperty("每次发放数量") + private Integer sendNum; + + @ApiModelProperty("发行总数量") + private Integer total; + + @ApiModelProperty("每人最多拥有数量") + private Integer limitNum; + + @ApiModelProperty("例外时间") + private String exceptTime; + + @ApiModelProperty("适用店铺ID,逗号分隔") + private String storeIds; + + @ApiModelProperty("会员等级ID,逗号分隔") + private String gradeIds; + + @ApiModelProperty("适用商品") + private String goodsIds; + + @ApiModelProperty("后台备注") + private String remarks; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("预存规则") + private String inRule; + + @ApiModelProperty("核销规则") + private String outRule; + + @ApiModelProperty("操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponGroupDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponGroupDto.java new file mode 100644 index 0000000..bb53f8c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ReqCouponGroupDto.java @@ -0,0 +1,44 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 卡券分组请求DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ReqCouponGroupDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("分组名称") + private String name; + + @ApiModelProperty("价值金额") + private BigDecimal money; + + @ApiModelProperty("发行数量") + private Integer total; + + @ApiModelProperty("分组描述") + private String description; + + @ApiModelProperty("操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ReqResult.java b/fuint-application/src/main/java/com/fuint/common/dto/ReqResult.java new file mode 100644 index 0000000..32897ee --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ReqResult.java @@ -0,0 +1,29 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Map; + +/** + * 请求返回结果 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ReqResult implements Serializable { + + @ApiModelProperty("返回代码") + private String code; + + @ApiModelProperty("返回消息") + private String msg; + + @ApiModelProperty("返回结果") + private boolean result; + + @ApiModelProperty("返回数据") + private Map data; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ReqSendLogDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ReqSendLogDto.java new file mode 100644 index 0000000..dee070e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ReqSendLogDto.java @@ -0,0 +1,66 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 发放卡券记录请求DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ReqSendLogDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("类型,1:单用户发券;2:批量发券") + private Integer type; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("导入文件名") + private String fileName; + + @ApiModelProperty("导入文件路径") + private String filePath; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("分组ID") + private Integer groupId; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("分组名称") + private String groupName; + + @ApiModelProperty("发放数量") + private Integer sendNum; + + @ApiModelProperty("发放时间") + private Date createTime; + + @ApiModelProperty("操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("uuid") + private String uuid; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ResCartDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ResCartDto.java new file mode 100644 index 0000000..fae34d4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ResCartDto.java @@ -0,0 +1,43 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtGoods; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 购物车返回DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ResCartDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("skuId") + private Integer skuId; + + @ApiModelProperty("数量") + private Double num; + + @ApiModelProperty("是否有效") + private Boolean isEffect; + + @ApiModelProperty("商品规格") + private List specList; + + @ApiModelProperty("商品数据") + private MtGoods goodsInfo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/ResCateDto.java b/fuint-application/src/main/java/com/fuint/common/dto/ResCateDto.java new file mode 100644 index 0000000..208c3f6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/ResCateDto.java @@ -0,0 +1,33 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtGoods; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 商品分类返回DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ResCateDto implements Serializable { + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("分类名称") + private String name; + + @ApiModelProperty("logo") + private String logo; + + @ApiModelProperty("商品列表") + private List goodsList; + + @ApiModelProperty("排序") + private Integer sort; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/RoleDto.java b/fuint-application/src/main/java/com/fuint/common/dto/RoleDto.java new file mode 100644 index 0000000..f5de8c7 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/RoleDto.java @@ -0,0 +1,33 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 角色信息实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RoleDto { + + @ApiModelProperty("账户主键ID") + private Long id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("角色类型") + private String type; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("状态 : A有效 D无效") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/SettlementDto.java b/fuint-application/src/main/java/com/fuint/common/dto/SettlementDto.java new file mode 100644 index 0000000..0e95083 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/SettlementDto.java @@ -0,0 +1,58 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import com.fuint.framework.pagination.PaginationResponse; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 结算实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SettlementDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("结算单号") + private String settlementNo; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("订单总金额") + private BigDecimal totalOrderAmount; + + @ApiModelProperty("结算金额") + private BigDecimal amount; + + @ApiModelProperty("结算订单") + private PaginationResponse orderList; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("支付状态,A待支付;B已支付") + private String payStatus; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/SettlementOrderDto.java b/fuint-application/src/main/java/com/fuint/common/dto/SettlementOrderDto.java new file mode 100644 index 0000000..d4ef307 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/SettlementOrderDto.java @@ -0,0 +1,44 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 结算订单表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SettlementOrderDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("结算ID") + private Integer settlementId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("订单信息") + private UserOrderDto orderInfo; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/SmsTemplateDto.java b/fuint-application/src/main/java/com/fuint/common/dto/SmsTemplateDto.java new file mode 100644 index 0000000..a6b91ae --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/SmsTemplateDto.java @@ -0,0 +1,45 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 短信模板实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SmsTemplateDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("模板名称") + private String name; + + @ApiModelProperty("模板英文名称") + private String uname; + + @ApiModelProperty("模板编码") + private String code; + + @ApiModelProperty("模板内容") + private String content; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,1:正常;2:删除") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/SourceDto.java b/fuint-application/src/main/java/com/fuint/common/dto/SourceDto.java new file mode 100644 index 0000000..6c89942 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/SourceDto.java @@ -0,0 +1,71 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 菜单信息实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SourceDto implements Serializable { + + @ApiModelProperty("自增ID") + private long id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("菜单名称") + private String name; + + @ApiModelProperty("菜单名称(字母)") + private String ename; + + @ApiModelProperty("节点是否打开") + private Boolean open; + + @ApiModelProperty("是否菜单") + private int isMenu; + + @ApiModelProperty("节点是否选中") + private Boolean checked; + + @ApiModelProperty("url") + private String url; + + @ApiModelProperty("路径") + private String path; + + @ApiModelProperty("权限标识") + private String perms; + + @ApiModelProperty("菜单级别") + private int level; + + @ApiModelProperty("上级菜单") + private long parentId; + + @ApiModelProperty("子菜单") + private List children; + + @ApiModelProperty("图标") + private String icon; + + @ApiModelProperty("新图标") + private String newIcon; + + @ApiModelProperty("描述信息") + private String description; + + @ApiModelProperty("排序") + private String sort; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/StaffDto.java b/fuint-application/src/main/java/com/fuint/common/dto/StaffDto.java new file mode 100644 index 0000000..ae29969 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/StaffDto.java @@ -0,0 +1,64 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtMerchant; +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +/** + * 员工实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + * */ +@Data +public class StaffDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("员工类别") + private Integer category; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("手机号码") + private String mobile; + + @ApiModelProperty("真实姓名") + private String realName; + + @ApiModelProperty("微信号") + private String wechat; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("审核状态,A:审核通过;U:未审核;D:无效; ") + private String auditedStatus; + + @ApiModelProperty("审核时间") + private Date auditedTime; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("商户信息") + private MtMerchant merchantInfo; + + @ApiModelProperty("店铺信息") + private MtStore storeInfo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/StockGoodsDto.java b/fuint-application/src/main/java/com/fuint/common/dto/StockGoodsDto.java new file mode 100644 index 0000000..0e1ac9e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/StockGoodsDto.java @@ -0,0 +1,46 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 库存商品实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + * */ +@Data +public class StockGoodsDto implements Serializable { + + @ApiModelProperty("商品ID") + private Integer id; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("商品编码") + private String goodsNo; + + @ApiModelProperty("商品分类ID") + private Integer cateId; + + @ApiModelProperty("商品数量") + private Double num; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("skuId") + private Integer skuId; + + @ApiModelProperty("商品logo") + private String logo; + + @ApiModelProperty("状态,A:正常;D:删除") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/StoreDto.java b/fuint-application/src/main/java/com/fuint/common/dto/StoreDto.java new file mode 100644 index 0000000..14d7d7c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/StoreDto.java @@ -0,0 +1,46 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 店铺实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + * */ +@Data +public class StoreDto extends StoreInfo implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("微信商户号") + private String wxMchId; + + @ApiModelProperty("微信支付秘钥") + private String wxApiV2; + + @ApiModelProperty("微信支付证书") + private String wxCertPath; + + @ApiModelProperty("支付宝appId") + private String alipayAppId; + + @ApiModelProperty("支付宝应用私钥") + private String alipayPrivateKey; + + @ApiModelProperty("支付宝支付公钥") + private String alipayPublicKey; + + @ApiModelProperty("银行名称") + private String bankName; + + @ApiModelProperty("银行卡账户名") + private String bankCardName; + + @ApiModelProperty("银行卡卡号") + private String bankCardNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/StoreInfo.java b/fuint-application/src/main/java/com/fuint/common/dto/StoreInfo.java new file mode 100644 index 0000000..9f132ec --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/StoreInfo.java @@ -0,0 +1,87 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 店铺信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + * */ +@Data +public class StoreInfo implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("商户号") + private String merchantNo; + + @ApiModelProperty("商户名称") + private String merchantName; + + @ApiModelProperty("店铺名称") + private String name; + + @ApiModelProperty("是否单店铺") + private String single; + + @ApiModelProperty("店铺二维码") + private String qrCode; + + @ApiModelProperty("店铺LOGO") + private String logo; + + @ApiModelProperty("是否默认店铺") + private String isDefault; + + @ApiModelProperty("联系人") + private String contact; + + @ApiModelProperty("联系电话") + private String phone; + + @ApiModelProperty("店铺地址") + private String address; + + @ApiModelProperty("营业时间") + private String hours; + + @ApiModelProperty("经度") + private String latitude; + + @ApiModelProperty("纬度") + private String longitude; + + @ApiModelProperty("距离") + private BigDecimal distance; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("营业执照") + private String license; + + @ApiModelProperty("统一社会信用代码") + private String creditCode; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,1:正常;2:删除") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/SubMessageDto.java b/fuint-application/src/main/java/com/fuint/common/dto/SubMessageDto.java new file mode 100644 index 0000000..b78a273 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/SubMessageDto.java @@ -0,0 +1,38 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 小程序订阅消息dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SubMessageDto implements Serializable { + + @ApiModelProperty("键值") + private String key; + + @ApiModelProperty("模板ID") + private String templateId; + + @ApiModelProperty("TID") + private String tid; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("内容") + private String content; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("模板参数") + private List params; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/TimeDto.java b/fuint-application/src/main/java/com/fuint/common/dto/TimeDto.java new file mode 100644 index 0000000..dc7179b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/TimeDto.java @@ -0,0 +1,21 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 时间Dto + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class TimeDto implements Serializable { + + @ApiModelProperty("时间段") + private String time; + + @ApiModelProperty("是否可预订") + private Boolean enable; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/TokenDto.java b/fuint-application/src/main/java/com/fuint/common/dto/TokenDto.java new file mode 100644 index 0000000..0e12490 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/TokenDto.java @@ -0,0 +1,28 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 登录Token实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class TokenDto implements Serializable { + + @ApiModelProperty("token") + private String token; + + @ApiModelProperty("创建时间") + private Long tokenCreatedTime; + + @ApiModelProperty("失效时间") + private Long tokenExpiryTime; + + @ApiModelProperty("是否登录") + private String isLogin; +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/UserCouponDto.java b/fuint-application/src/main/java/com/fuint/common/dto/UserCouponDto.java new file mode 100644 index 0000000..e3ae5f4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/UserCouponDto.java @@ -0,0 +1,80 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtConfirmLog; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 我的卡券实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class UserCouponDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("卡券名称") + private String name; + + @ApiModelProperty("卡券类型") + private String type; + + @ApiModelProperty("卡券内容") + private Integer content; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("使用规则") + private String useRule; + + @ApiModelProperty("核销编码") + private String code; + + @ApiModelProperty("二维码") + private String qrCode; + + @ApiModelProperty("图片") + private String image; + + @ApiModelProperty("面额") + private BigDecimal amount; + + @ApiModelProperty("是否允许转赠") + private Boolean isGive; + + @ApiModelProperty("余额") + private BigDecimal balance; + + @ApiModelProperty("核销次数") + private Integer confirmCount; + + @ApiModelProperty("核销记录") + private List confirmLogs; + + @ApiModelProperty("是否可用(过期、状态等)") + private boolean canUse; + + @ApiModelProperty("有效期") + private String effectiveDate; + + @ApiModelProperty("适用店铺") + private String storeNames; + + @ApiModelProperty("提示信息") + private String tips; + + @ApiModelProperty("描述信息") + private String description; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/UserDto.java b/fuint-application/src/main/java/com/fuint/common/dto/UserDto.java new file mode 100644 index 0000000..0a54eef --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/UserDto.java @@ -0,0 +1,112 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员个人信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class UserDto implements Serializable { + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("头像") + private String avatar; + + @ApiModelProperty("称呼") + private String name; + + @ApiModelProperty("是否设置密码") + private String hasPassword; + + @ApiModelProperty("分组ID") + private Integer groupId; + + @ApiModelProperty("分组信息") + private UserGroupDto groupInfo; + + @ApiModelProperty("微信open_id") + private String openId; + + @ApiModelProperty("手机号码") + private String mobile; + + @ApiModelProperty("证件号码") + private String idcard; + + @ApiModelProperty("等级ID") + private Integer gradeId; + + @ApiModelProperty("等级名称") + private String gradeName; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("会员开始时间") + private Date startTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @ApiModelProperty("会员结束时间") + private Date endTime; + + @ApiModelProperty("余额") + private BigDecimal balance; + + @ApiModelProperty("积分") + private Integer point; + + @ApiModelProperty("性别 1男;0女") + private Integer sex; + + @ApiModelProperty("出生日期") + private String birthday; + + @ApiModelProperty("车牌号") + private String carNo; + + @ApiModelProperty("来源渠道") + private String source; + + @ApiModelProperty("地址") + private String address; + + @ApiModelProperty("默认店铺ID") + private Integer storeId; + + @ApiModelProperty("默认店铺名称") + private String storeName; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最近登录时间") + private String lastLoginTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("注册IP") + private String ip; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/UserGroupDto.java b/fuint-application/src/main/java/com/fuint/common/dto/UserGroupDto.java new file mode 100644 index 0000000..d5eb40a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/UserGroupDto.java @@ -0,0 +1,54 @@ +package com.fuint.common.dto; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员分组 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class UserGroupDto implements Serializable { + + @ApiModelProperty("分组ID") + private Integer id; + + @ApiModelProperty("分组名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("默认店铺") + private Integer storeId; + + @ApiModelProperty("父ID") + private Integer parentId; + + @ApiModelProperty("子分组") + private List children; + + @ApiModelProperty("会员数量") + private Long memberNum; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/UserInfo.java b/fuint-application/src/main/java/com/fuint/common/dto/UserInfo.java new file mode 100644 index 0000000..d02bab6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/UserInfo.java @@ -0,0 +1,25 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员登录信息实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class UserInfo implements Serializable { + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员手机号") + private String mobile; + + @ApiModelProperty("登录Token") + private String token; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/dto/UserOrderDto.java b/fuint-application/src/main/java/com/fuint/common/dto/UserOrderDto.java new file mode 100644 index 0000000..e9f997d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/UserOrderDto.java @@ -0,0 +1,149 @@ +package com.fuint.common.dto; + +import com.fuint.repository.model.MtRefund; +import com.fuint.repository.model.MtStaff; +import com.fuint.repository.model.MtStore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 会员订单实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class UserOrderDto implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("订单类型") + private String type; + + @ApiModelProperty("订单类型名称") + private String typeName; + + @ApiModelProperty("支付类型") + private String payType; + + @ApiModelProperty("订单模式") + private String orderMode; + + @ApiModelProperty("下单平台") + private String platform; + + @ApiModelProperty("是否核销") + private Boolean isVerify; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("是否游客") + private String isVisitor; + + @ApiModelProperty("核销码") + private String verifyCode; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("总金额") + private BigDecimal amount; + + @ApiModelProperty("支付金额") + private BigDecimal payAmount; + + @ApiModelProperty("优惠金额") + private BigDecimal discount; + + @ApiModelProperty("配送费用") + private BigDecimal deliveryFee; + + @ApiModelProperty("使用积分") + private Integer usePoint; + + @ApiModelProperty("积分金额") + private BigDecimal pointAmount; + + @ApiModelProperty("订单参数") + private String param; + + @ApiModelProperty("备注信息") + private String remark; + + @ApiModelProperty("创建时间") + private String createTime; + + @ApiModelProperty("更新时间") + private String updateTime; + + @ApiModelProperty("支付时间") + private String payTime; + + @ApiModelProperty("订单状态") + private String status; + + @ApiModelProperty("支付状态") + private String payStatus; + + @ApiModelProperty(value="结算状态") + private String settleStatus; + + @ApiModelProperty("状态说明") + private String statusText; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("订单商品列表") + private List goods; + + @ApiModelProperty("下单用户信息") + private OrderUserDto userInfo; + + @ApiModelProperty("配送地址") + private AddressDto address; + + @ApiModelProperty("物流信息") + private ExpressDto expressInfo; + + @ApiModelProperty("所属店铺信息") + private MtStore storeInfo; + + @ApiModelProperty("售后订单") + private MtRefund refundInfo; + + @ApiModelProperty("使用卡券") + private UserCouponDto couponInfo; + + @ApiModelProperty("所属员工") + private MtStaff staffInfo; + + @ApiModelProperty("核销状态") + private String confirmStatus; + + @ApiModelProperty("核销时间") + private String confirmTime; + + @ApiModelProperty("核销备注") + private String confirmRemark; + +} + diff --git a/fuint-application/src/main/java/com/fuint/common/dto/WxCardDto.java b/fuint-application/src/main/java/com/fuint/common/dto/WxCardDto.java new file mode 100644 index 0000000..45c67ad --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/dto/WxCardDto.java @@ -0,0 +1,75 @@ +package com.fuint.common.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 微信会员卡实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class WxCardDto { + + @ApiModelProperty("会员卡类型") + private String cardType; + + @ApiModelProperty("会员卡背景图") + private String backgroundUrl; + + @ApiModelProperty("商户logo") + private String logoUrl; + + @ApiModelProperty("商户名称") + private String brandName; + + @ApiModelProperty("Code展示类型") + private String codeType; + + @ApiModelProperty("卡券名,字数上限为9个汉字") + private String title; + + @ApiModelProperty("会员卡颜色") + private String color; + + @ApiModelProperty("卡券使用提醒,字数上限为16个汉字") + private String notice; + + @ApiModelProperty("卡券使用说明,字数上限为1024个汉字") + private String description; + + @ApiModelProperty("客服电话") + private String servicePhone; + + @ApiModelProperty("跳转外链的入口名字") + private String customUrlName; + + @ApiModelProperty("跳转外链的URL") + private String customUrl; + + @ApiModelProperty("显示在入口右侧的提示语") + private String customUrlSubTitle; + + @ApiModelProperty("卡券领取页面是否可分享") + private Boolean canShare; + + @ApiModelProperty("会员卡特权说明,限制1024汉字") + private String prerogative; + + @ApiModelProperty("显示积分") + private Boolean supplyBonus; + + @ApiModelProperty("跳转外链查看积分详情") + private String bonusUrl; + + @ApiModelProperty("积分规则") + private String bonusRules; + + @ApiModelProperty("是否支持储值") + private Boolean supplyBalance; + + @ApiModelProperty("跳转外链查看余额详情") + private String balanceUrl; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/AdminRoleEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/AdminRoleEnum.java new file mode 100644 index 0000000..c463bf6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/AdminRoleEnum.java @@ -0,0 +1,77 @@ +package com.fuint.common.enums; + +/** + * 后台角色枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum AdminRoleEnum { + ADMIN("1", "超级管理员","admin"), + COMMON("2", "普通管理员","common"), + USER("3", "用户角色","user"); + + private String key; + private String name; + private String value; + + AdminRoleEnum(String key, String name, String value) { + this.key = key; + this.name = name; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (AdminRoleEnum c : AdminRoleEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过key获取name + public static String getName(String k) { + for (AdminRoleEnum c : AdminRoleEnum.values()) { + if (c.getKey().equals(k)) { + return c.getName(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (AdminRoleEnum c : AdminRoleEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/ApplyGoodsEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/ApplyGoodsEnum.java new file mode 100644 index 0000000..9edd2ba --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/ApplyGoodsEnum.java @@ -0,0 +1,57 @@ +package com.fuint.common.enums; + +/** + * 卡券适用商品 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum ApplyGoodsEnum { + ALL_GOODS("allGoods", "全场通用"), + PARK_GOODS("parkGoods", "指定商品"); + + private String key; + + private String value; + + ApplyGoodsEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (ApplyGoodsEnum c : ApplyGoodsEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (ApplyGoodsEnum c : ApplyGoodsEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/BalanceSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/BalanceSettingEnum.java new file mode 100644 index 0000000..4211928 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/BalanceSettingEnum.java @@ -0,0 +1,57 @@ +package com.fuint.common.enums; + +/** + * 充值配置项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum BalanceSettingEnum { + RECHARGE_RULE("rechargeRule", "充值规则"), + RECHARGE_REMARK("rechargeRemark", "充值说明"); + + private String key; + + private String value; + + BalanceSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (BalanceSettingEnum c : BalanceSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (BalanceSettingEnum c : BalanceSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/BookStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/BookStatusEnum.java new file mode 100644 index 0000000..ece3420 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/BookStatusEnum.java @@ -0,0 +1,71 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 预约订单状态枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum BookStatusEnum { + CREATED("A", "待确认"), + CONFIRM("B", "确认通过"), + FAIL("F", "预约失败"), + CANCEL("C", "已取消"), + DELETE("D", "已删除"), + COMPLETE("E", "已完成"); + + private String key; + + private String value; + + BookStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * 根据key获取value + * + * @param key + * @return + */ + public static String getValue(String key) { + final BookStatusEnum[] values = BookStatusEnum.values(); + for (BookStatusEnum value : values) { + if (key.equals(value.getKey())) { + return value.getValue(); + } + } + return null; + } + + public static List getBookStatusList(String... excludedKeys) { + List excludedKeySet = Arrays.asList(excludedKeys); + return Arrays.stream(BookStatusEnum.values()) + .filter(status -> !excludedKeySet.contains(status.getKey())) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CommissionCashStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CommissionCashStatusEnum.java new file mode 100644 index 0000000..cc430e3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CommissionCashStatusEnum.java @@ -0,0 +1,51 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分佣结算状态 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CommissionCashStatusEnum { + WAIT("A", "待确认"), + SETTLED("B", "已确认"), + CANCEL("C", "已作废"), + PAYED("D", "已打款"); + + private String key; + + private String value; + + CommissionCashStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getCommissionCashStatusList() { + return Arrays.stream(CommissionCashStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CommissionStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CommissionStatusEnum.java new file mode 100644 index 0000000..e3fa85c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CommissionStatusEnum.java @@ -0,0 +1,50 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分佣状态 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CommissionStatusEnum { + NORMAL("A", "待结算"), + SETTLED("B", "已结算"), + CANCEL("C", "已作废"); + + private String key; + + private String value; + + CommissionStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getCommissionStatusList() { + return Arrays.stream(CommissionStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CommissionTargetEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CommissionTargetEnum.java new file mode 100644 index 0000000..a48bfc3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CommissionTargetEnum.java @@ -0,0 +1,49 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分佣对象枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CommissionTargetEnum { + MEMBER("member", "会员分销"), + STAFF("staff", "员工提成"); + + private String key; + + private String value; + + CommissionTargetEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getCommissionTargetList() { + return Arrays.stream(CommissionTargetEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CommissionTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CommissionTypeEnum.java new file mode 100644 index 0000000..41591ed --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CommissionTypeEnum.java @@ -0,0 +1,66 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分佣提成类型 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CommissionTypeEnum { + GOODS("goods", "商品订单"), + PAYMENT("payment", "付款订单"), + RECHARGE("recharge", "充值订单"); + + private String key; + + private String value; + + CommissionTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * 根据key获取value + * + * @param key + * @return + */ + public static String getName(String key) { + final CommissionTypeEnum[] values = CommissionTypeEnum.values(); + for (CommissionTypeEnum value : values) { + if (key.equals(value.getKey())) { + return value.getValue(); + } + } + return null; + } + + public static List getCommissionTypeList() { + return Arrays.stream(CommissionTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CouponContentEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CouponContentEnum.java new file mode 100644 index 0000000..836f594 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CouponContentEnum.java @@ -0,0 +1,37 @@ +package com.fuint.common.enums; + +/** + * 卡券内容枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CouponContentEnum { + AMOUNT(1, "满减券"), + PERCENT(2, "折扣券"); + + private Integer key; + + private String value; + + CouponContentEnum(Integer key, String value) { + this.key = key; + this.value = value; + } + + public Integer getKey() { + return key; + } + + public void setKey(Integer key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CouponExpireTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CouponExpireTypeEnum.java new file mode 100644 index 0000000..df2e4e6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CouponExpireTypeEnum.java @@ -0,0 +1,37 @@ +package com.fuint.common.enums; + +/** + * 卡券过期类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CouponExpireTypeEnum { + FIX("fix", "固定期限"), + FLEX("flex", "领取后生效"); + + private String key; + + private String value; + + CouponExpireTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CouponTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CouponTypeEnum.java new file mode 100644 index 0000000..a9c7961 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CouponTypeEnum.java @@ -0,0 +1,50 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 卡券类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CouponTypeEnum { + COUPON("C", "优惠券"), + PRESTORE("P", "储值卡"), + TIMER("T", "计次卡"); + + private String key; + + private String value; + + CouponTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getCouponTypeList() { + return Arrays.stream(CouponTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/CouponUseForEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/CouponUseForEnum.java new file mode 100644 index 0000000..692c39a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/CouponUseForEnum.java @@ -0,0 +1,69 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 卡券使用专项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum CouponUseForEnum { + MEMBER_GRADE("memberGrade", "升级会员等级专用"), + OFF_LINE_PAYMENT("offLinePayment", "到店收银买单专用"); + + private String key; + + private String value; + + CouponUseForEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (CouponUseForEnum c : CouponUseForEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (CouponUseForEnum c : CouponUseForEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + public static List getCouponUseForList() { + return Arrays.stream(CouponUseForEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/ExpressCompanyEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/ExpressCompanyEnum.java new file mode 100644 index 0000000..13fb16b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/ExpressCompanyEnum.java @@ -0,0 +1,60 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 物流公司枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum ExpressCompanyEnum { + + SELF("SELF", "商家自送"), + YTO("YTO", "圆通速递"), + ZTO("ZTO", "中通快递"), + BEST("BEST", "百世快递"), + YUNDA("YUNDA", "韵达快递"), + SF("SF", "顺丰速运"), + EMS("EMS", "中国邮政"), + DB("DB", "德邦快递"), + STO("STO", "申通快递"), + JDL("JDL", "京东快递"), + HHTT("HHTT", "天天快递"), + JTSD("JTSD", "极兔快递"); + + private String key; + + private String value; + + ExpressCompanyEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getExpressCompanyList() { + return Arrays.stream(ExpressCompanyEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/GenderEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/GenderEnum.java new file mode 100644 index 0000000..c72fd7c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/GenderEnum.java @@ -0,0 +1,39 @@ +package com.fuint.common.enums; + +/** + * 性别枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum GenderEnum { + + FEMALE(0, "女"), + MAN(1, "男"), + UNKNOWN(2, "未知"); + + private Integer key; + + private String value; + + GenderEnum(Integer key, String value) { + this.key = key; + this.value = value; + } + + public Integer getKey() { + return key; + } + + public void setKey(Integer key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/GoodsTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/GoodsTypeEnum.java new file mode 100644 index 0000000..8abe49d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/GoodsTypeEnum.java @@ -0,0 +1,70 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 商品类型 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum GoodsTypeEnum { + GOODS("goods", "实物商品"), + SERVICE("service", "服务项目"), + COUPON("coupon", "虚拟卡券"); + + private String key; + + private String value; + + GoodsTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (GoodsTypeEnum c : GoodsTypeEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (GoodsTypeEnum c : GoodsTypeEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + public static List getGoodsTypeList() { + return Arrays.stream(GoodsTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/InvoiceStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/InvoiceStatusEnum.java new file mode 100644 index 0000000..36dca1a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/InvoiceStatusEnum.java @@ -0,0 +1,69 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 开票状态枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum InvoiceStatusEnum { + + CREATED("A", "开票中"), + SUCCESS("B", "开票成功"), + CANCEL("C", "已冲红"); + + private String key; + + private String value; + + InvoiceStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * 根据key获取value + * + * @param key + * @return + */ + public static String getValue(String key) { + final InvoiceStatusEnum[] values = InvoiceStatusEnum.values(); + for (InvoiceStatusEnum value : values) { + if (key.equals(value.getKey())) { + return value.getValue(); + } + } + return null; + } + + public static List getInvoiceStatusList(String... excludedKeys) { + List excludedKeySet = Arrays.asList(excludedKeys); + return Arrays.stream(InvoiceStatusEnum.values()) + .filter(status -> !excludedKeySet.contains(status.getKey())) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/MemberSourceEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/MemberSourceEnum.java new file mode 100644 index 0000000..9d4888f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/MemberSourceEnum.java @@ -0,0 +1,59 @@ +package com.fuint.common.enums; + +/** + * 会员来源渠道 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum MemberSourceEnum { + BACKEND_ADD("backend_add", "后台添加"), + REGISTER_BY_ACCOUNT("register_by_account", "H5注册"), + MOBILE_LOGIN("mobile_login", "手机号登录注册"), + WECHAT_LOGIN("wechat_login", "微信小程序"); + + private String key; + + private String value; + + MemberSourceEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (MemberSourceEnum c : MemberSourceEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (MemberSourceEnum c : MemberSourceEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/MerchantTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/MerchantTypeEnum.java new file mode 100644 index 0000000..03ec08f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/MerchantTypeEnum.java @@ -0,0 +1,51 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 商户类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum MerchantTypeEnum { + RESTAURANT("restaurant", "餐饮:餐厅、奶茶、酒店等"), + RETAIL("retail", "零售:超市、生鲜、卖场等"), + SERVICE("service", "服务:美容、足浴、汽车4s店等"), + OTHER("other", "其他"); + + private String key; + + private String value; + + MerchantTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getMerchantTypeList() { + return Arrays.stream(MerchantTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/MessageEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/MessageEnum.java new file mode 100644 index 0000000..55454f5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/MessageEnum.java @@ -0,0 +1,35 @@ +package com.fuint.common.enums; + +/** + * 会员消息类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum MessageEnum { + POP_MSG("pop", "弹框消息"), + SUB_MSG("sub", "订阅消息"), + SMS_MSG("sms", "短信消息"); + + private String key; + private String value; + + MessageEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/OrderModeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/OrderModeEnum.java new file mode 100644 index 0000000..d74292b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/OrderModeEnum.java @@ -0,0 +1,49 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 订单模式 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum OrderModeEnum { + EXPRESS("express", "配送"), + ONESELF("oneself", "自取"); + + private String key; + + private String value; + + OrderModeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getOrderModeList() { + return Arrays.stream(OrderModeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/OrderSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/OrderSettingEnum.java new file mode 100644 index 0000000..70da813 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/OrderSettingEnum.java @@ -0,0 +1,61 @@ +package com.fuint.common.enums; + +/** + * 交易配置项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum OrderSettingEnum { + DELIVERY_FEE("deliveryFee", "订单配送费用"), + DELIVERY_MIN_AMOUNT("deliveryMinAmount", "订单起送金额"), + IS_CLOSE("isClose", "关闭交易功能"), + MP_UPLOAD_SHIPPING("mpUploadShipping", "微信小程序上传发货信息"), + PAY_OFF_LINE("payOffLine", "开启前台支付功能"), + DELIVERY_RANGE("deliveryRange", "配送范围"); + + private String key; + + private String value; + + OrderSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (OrderSettingEnum c : OrderSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (OrderSettingEnum c : OrderSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/OrderStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/OrderStatusEnum.java new file mode 100644 index 0000000..1bd89eb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/OrderStatusEnum.java @@ -0,0 +1,66 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 订单状态枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum OrderStatusEnum { + + CREATED("A", "待支付"), + PAID("B", "已支付"), + CANCEL("C", "已取消"), + DELIVERY("D", "待发货"), + DELIVERED("E", "已发货"), + RECEIVED("F", "已收货"), + DELETED("G", "已删除"), + REFUND("H", "已退款"), + COMPLETE("I", "已完成"); + + private String key; + + private String value; + + OrderStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static String getValue(String k) { + for (OrderStatusEnum c : OrderStatusEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + public static List getOrderStatusList() { + return Arrays.stream(OrderStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/OrderTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/OrderTypeEnum.java new file mode 100644 index 0000000..45b658c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/OrderTypeEnum.java @@ -0,0 +1,69 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 订单类型 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum OrderTypeEnum { + + GOODS("goods", "商品订单"), + PAYMENT("payment", "付款订单"), + RECHARGE("recharge", "充值订单"), + PRESTORE("prestore", "储值卡订单"), + MEMBER("member", "会员升级订单"); + + private String key; + + private String value; + + OrderTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * 根据key获取value + * + * @param key + * @return + */ + public static String getValue(String key) { + final OrderTypeEnum[] values = OrderTypeEnum.values(); + for (OrderTypeEnum value : values) { + if (key.equals(value.getKey())) { + return value.getValue(); + } + } + return null; + } + + public static List getOrderTypeList() { + return Arrays.stream(OrderTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getKey())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/PayStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/PayStatusEnum.java new file mode 100644 index 0000000..32a0ab4 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/PayStatusEnum.java @@ -0,0 +1,49 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 支付状态 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum PayStatusEnum { + WAIT("A", "待支付"), + SUCCESS("B", "已支付"); + + private String key; + + private String value; + + PayStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getPayStatusList() { + return Arrays.stream(PayStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/PayTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/PayTypeEnum.java new file mode 100644 index 0000000..d9778b5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/PayTypeEnum.java @@ -0,0 +1,55 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 支付类型 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum PayTypeEnum { + + CASH("CASH", "现金支付"), + JSAPI("JSAPI", "微信支付"), + MICROPAY("MICROPAY", "微信扫码支付"), + BALANCE("BALANCE", "余额支付"), + ALISCAN("ALISCAN", "支付宝扫码"), + STORE("STORE", "门店支付"), + UNIONPAY("UNIONPAY", "云闪付支付"); + + private String key; + + private String value; + + PayTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getPayTypeList() { + return Arrays.stream(PayTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/PlatformTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/PlatformTypeEnum.java new file mode 100644 index 0000000..ff40516 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/PlatformTypeEnum.java @@ -0,0 +1,66 @@ +package com.fuint.common.enums; + +/** + * 平台类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum PlatformTypeEnum { + + /** + * 微信小程序 + */ + MP_WEIXIN("MP-WEIXIN", "微信小程序", 1), + + /** + * PC + */ + PC("PC", "PC端", 2), + + /** + * H5 + */ + H5("H5", "H5端", 3), + + /** + * App客户端 + */ + APP("APP", "App客户端", 4); + + private String code; + + private String value; + + private Integer num; + + PlatformTypeEnum(String code, String value, Integer num) { + this.code = code; + this.value = value; + this.num = num; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Integer getNum() { + return num; + } + + public void setNum(Integer code) { + this.num = num; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/PointSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/PointSettingEnum.java new file mode 100644 index 0000000..0404dcd --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/PointSettingEnum.java @@ -0,0 +1,59 @@ +package com.fuint.common.enums; + +/** + * 积分配置项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum PointSettingEnum { + POINT_NEED_CONSUME("pointNeedConsume", "返1积分所需消费金额"), + CAN_USE_AS_MONEY("canUsedAsMoney", "是否可当作现金使用"), + EXCHANGE_NEED_POINT("exchangeNeedPoint", "多少积分可抵扣1元现金"), + RECHARGE_POINT_SPEED("rechargePointSpeed", "充值返积分倍数"); + + private String key; + + private String value; + + PointSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (PointSettingEnum c : PointSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (PointSettingEnum c : PointSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/PrinterSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/PrinterSettingEnum.java new file mode 100644 index 0000000..b5020f2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/PrinterSettingEnum.java @@ -0,0 +1,59 @@ +package com.fuint.common.enums; + +/** + * 云打印设置 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum PrinterSettingEnum { + + USER_NAME("userName", "用户名"), + USER_KEY("userKey", "开发者密钥"), + ENABLE("enable", "是否启用"); + + private String key; + + private String value; + + PrinterSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (PrinterSettingEnum c : PrinterSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (PrinterSettingEnum c : PrinterSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/QrCodeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/QrCodeEnum.java new file mode 100644 index 0000000..e254d43 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/QrCodeEnum.java @@ -0,0 +1,76 @@ +package com.fuint.common.enums; + +/** + * 二维码枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum QrCodeEnum { + TABLE("table", "桌码二维码", "pages/category/index"), + STORE("store", "店铺二维码", "pages/index/index"), + COUPON("coupon", "卡券二维码", "subPages/coupon/detail"); + + private String key; + + private String value; + + private String page; + + QrCodeEnum(String key, String value, String page) { + this.key = key; + this.value = value; + this.page = page; + } + + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + public String getPage() { + return page; + } + public void setPage(String page) { + this.page = page; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (QrCodeEnum c : QrCodeEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (QrCodeEnum c : QrCodeEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + // 普通方法,通过key获取page + public static String getPage(String k) { + for (QrCodeEnum c : QrCodeEnum.values()) { + if (c.getKey().equals(k)) { + return c.getPage(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/RefundStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/RefundStatusEnum.java new file mode 100644 index 0000000..a6d2df3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/RefundStatusEnum.java @@ -0,0 +1,53 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 售后订单状态枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum RefundStatusEnum { + + CREATED("A", "待审核"), + APPROVED("B", "已同意"), + REJECT("C", "已拒绝"), + CANCEL("D", "已取消"), + COMPLETE("E", "已完成"); + + private String key; + + private String value; + + RefundStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getRefundStatusList() { + return Arrays.stream(RefundStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/RefundTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/RefundTypeEnum.java new file mode 100644 index 0000000..c24345f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/RefundTypeEnum.java @@ -0,0 +1,50 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 售后类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum RefundTypeEnum { + + RETURN("return", "退货退款"), + EXCHANGE("exchange", "换货"); + + private String key; + + private String value; + + RefundTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getRefundTypeList() { + return Arrays.stream(RefundTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/SendWayEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/SendWayEnum.java new file mode 100644 index 0000000..f8173bc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/SendWayEnum.java @@ -0,0 +1,58 @@ +package com.fuint.common.enums; + +/** + * 卡券发放方式 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum SendWayEnum { + BACKEND("backend", "后台发放"), + OFFLINE("offline", "线下发放"), + FRONT("front", "前台领取"); + + private String key; + + private String value; + + SendWayEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (SendWayEnum c : SendWayEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (SendWayEnum c : SendWayEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/SettingTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/SettingTypeEnum.java new file mode 100644 index 0000000..aaba250 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/SettingTypeEnum.java @@ -0,0 +1,64 @@ +package com.fuint.common.enums; + +/** + * 配置类型枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum SettingTypeEnum { + POINT("point", "积分配置"), + BALANCE("balance", "余额配置"), + USER("user", "会员配置"), + ORDER("order", "交易配置"), + SUB_MESSAGE("sub_message", "订阅消息"), + PRINTER("printer", "打印设置"), + SMS_CONFIG("sms_config", "短信配置"), + KUAIDI100("kuaidi100", "快递100配置"), + NAVIGATION("navigation", "导航配置"); + + private String key; + + private String value; + + SettingTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (SettingTypeEnum c : SettingTypeEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (SettingTypeEnum c : SettingTypeEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/SettleStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/SettleStatusEnum.java new file mode 100644 index 0000000..2516358 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/SettleStatusEnum.java @@ -0,0 +1,49 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 订单结算状态 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum SettleStatusEnum { + WAIT("A", "待确认"), + COMPLETE("B", "已完成"); + + private String key; + + private String value; + + SettleStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getSettleStatusList() { + return Arrays.stream(SettleStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/SmsSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/SmsSettingEnum.java new file mode 100644 index 0000000..d6e23c0 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/SmsSettingEnum.java @@ -0,0 +1,59 @@ +package com.fuint.common.enums; + +/** + * 短信配置项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum SmsSettingEnum { + IS_CLOSE("isClose", "是否关闭短信功能"), + ACCESS_KEY_ID("accessKeyId", "阿里云accessKeyId"), + ACCESS_KEY_SECRET("accessKeySecret", "阿里云accessKeySecret"), + SIGN_NAME("signName", "阿里云短信签名"); + + private String key; + + private String value; + + SmsSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (UserSettingEnum c : UserSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (UserSettingEnum c : UserSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/StaffCategoryEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/StaffCategoryEnum.java new file mode 100644 index 0000000..06c374a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/StaffCategoryEnum.java @@ -0,0 +1,90 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 员工类别枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum StaffCategoryEnum { + MANAGER("1", "店长","admin"), + CASHIER("2", "收银人员","cashier"), + SALE("3", "销售人员","sale"), + SERVICE("4", "服务人员","service"); + + private String key; + private String name; + private String value; + + StaffCategoryEnum(String key, String name, String value) { + this.key = key; + this.name = name; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (StaffCategoryEnum c : StaffCategoryEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过key获取name + public static String getName(String k) { + for (StaffCategoryEnum c : StaffCategoryEnum.values()) { + if (c.getKey().equals(k)) { + return c.getName(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (StaffCategoryEnum c : StaffCategoryEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + public static List getStaffCategoryList() { + return Arrays.stream(StaffCategoryEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getName(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/StatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/StatusEnum.java new file mode 100644 index 0000000..b748d0e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/StatusEnum.java @@ -0,0 +1,55 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 通用状态枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum StatusEnum { + + ENABLED("A", "启用"), + EXPIRED("C", "过期"), + DISABLE("D", "删除"), + FORBIDDEN("N", "禁用"), + UnAudited("U", "待审核"); + + private String key; + + private String value; + + StatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getStatusList(String... excludedKeys) { + List excludedKeySet = Arrays.asList(excludedKeys); + return Arrays.stream(StatusEnum.values()) + .filter(status -> !excludedKeySet.contains(status.getKey())) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/UserActionEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/UserActionEnum.java new file mode 100644 index 0000000..0bfab25 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/UserActionEnum.java @@ -0,0 +1,64 @@ +package com.fuint.common.enums; + +/** + * 会员行为枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum UserActionEnum { + REGISTER("register", "注册会员"), + LOGIN("login", "登录系统"), + VIEW_GOODS("viewGoods", "浏览商品"), + SUBMIT_ORDER("submitOrder", "提交订单"), + CANCEL_ORDER("cancelOrder", "取消订单"), + GET_COUPON("getCoupon", "领取卡券"), + USE_COUPON("useCoupon", "使用卡券"), + RECHARGE_BALANCE("rechargeBalance", "余额充值"), + USE_BALANCE("useBalance", "使用余额"); + + private String key; + + private String value; + + UserActionEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (UserActionEnum c : UserActionEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (UserActionEnum c : UserActionEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/UserCouponStatusEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/UserCouponStatusEnum.java new file mode 100644 index 0000000..d63c35b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/UserCouponStatusEnum.java @@ -0,0 +1,72 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户卡券状态 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum UserCouponStatusEnum { + UNUSED("A", "未使用"), + USED("B", "已使用"), + EXPIRE("C", "已过期"), + DISABLE("D", "不可用"), + UNSEND("E", "待领取"); + + private String key; + + private String value; + + UserCouponStatusEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (UserCouponStatusEnum c : UserCouponStatusEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (UserCouponStatusEnum c : UserCouponStatusEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + public static List getUserCouponStatusList() { + return Arrays.stream(UserCouponStatusEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/UserGradeCatchTypeEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/UserGradeCatchTypeEnum.java new file mode 100644 index 0000000..67adfa8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/UserGradeCatchTypeEnum.java @@ -0,0 +1,51 @@ +package com.fuint.common.enums; + +import com.fuint.common.dto.ParamDto; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 升级会员等级条件枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum UserGradeCatchTypeEnum { + INIT("init", "默认获取"), + PAY("pay", "付费升级"), + FREQUENCY("frequency", "累计消费次数升级"), + AMOUNT("amount", "累积消费金额升级"); + + private String key; + + private String value; + + UserGradeCatchTypeEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static List getUserGradeCatchTypeList() { + return Arrays.stream(UserGradeCatchTypeEnum.values()) + .map(status -> new ParamDto(status.getKey(), status.getValue(), status.getValue())) + .collect(Collectors.toList()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/UserSettingEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/UserSettingEnum.java new file mode 100644 index 0000000..491f284 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/UserSettingEnum.java @@ -0,0 +1,61 @@ +package com.fuint.common.enums; + +/** + * 会员配置项枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum UserSettingEnum { + GET_COUPON_NEED_PHONE("getCouponNeedPhone", "领券是否需要手机号码"), + SUBMIT_ORDER_NEED_PHONE("submitOrderNeedPhone", "提交订单是否需要手机号码"), + LOGIN_NEED_PHONE("loginNeedPhone", "登录是否需要手机号"), + OPEN_WX_CARD("openWxCard", "开通微信会员卡"), + WX_MEMBER_CARD("wxMemberCard", "微信会员卡设置"), + WX_MEMBER_CARD_ID("wxMemberCardId", "微信会员卡ID"); + + private String key; + + private String value; + + UserSettingEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (UserSettingEnum c : UserSettingEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (UserSettingEnum c : UserSettingEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/WxMessageEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/WxMessageEnum.java new file mode 100644 index 0000000..b244f29 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/WxMessageEnum.java @@ -0,0 +1,62 @@ +package com.fuint.common.enums; + +/** + * 微信订阅消息枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum WxMessageEnum { + ORDER_CREATED("orderCreated", "订单生成提醒"), + DELIVER_GOODS("deliverGoods", "订单发货提醒"), + COUPON_EXPIRE("couponExpire", "卡券到期提醒"), + COUPON_ARRIVAL("couponArrival", "卡券到账提醒"), + BALANCE_CHANGE("balanceChange", "余额变动提醒"), + COUPON_CONFIRM("couponConfirm", "卡券核销提醒"), + POINT_CHANGE("pointChange", "积分变更提醒"); + + private String key; + + private String value; + + WxMessageEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // 普通方法,通过key获取value + public static String getValue(String k) { + for (WxMessageEnum c : WxMessageEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } + + // 普通方法,通过Value获取key + public static String getKey(String v) { + for (WxMessageEnum c : WxMessageEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/enums/YesOrNoEnum.java b/fuint-application/src/main/java/com/fuint/common/enums/YesOrNoEnum.java new file mode 100644 index 0000000..4f4e86f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/enums/YesOrNoEnum.java @@ -0,0 +1,57 @@ +package com.fuint.common.enums; + +/** + * 是或否枚举 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public enum YesOrNoEnum { + YES("Y", "是"), + NO("N", "否"), + TRUE("true", "真"), + FALSE("false", "假"); + + private String key; + + private String value; + + YesOrNoEnum(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static String getKey(String v) { + for (YesOrNoEnum c : YesOrNoEnum.values()) { + if (c.getValue().equals(v)) { + return c.getKey(); + } + } + return null; + } + + public static String getValue(String k) { + for (YesOrNoEnum c : YesOrNoEnum.values()) { + if (c.getKey().equals(k)) { + return c.getValue(); + } + } + return null; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/http/HttpRESTDataClient.java b/fuint-application/src/main/java/com/fuint/common/http/HttpRESTDataClient.java new file mode 100644 index 0000000..d5cefe2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/http/HttpRESTDataClient.java @@ -0,0 +1,138 @@ +package com.fuint.common.http; + +import com.alibaba.fastjson.JSONObject; +import com.fuint.utils.StringUtil; +import okhttp3.*; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; + + +/** + * 调用REST接口并解析数据 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component +public class HttpRESTDataClient { + + public static final Logger logger = LoggerFactory.getLogger(HttpRESTDataClient.class); + + private static final OkHttpClient client = new OkHttpClient(); + + private static final HttpClientBuilder httpClientBuilder; + + static { + httpClientBuilder = HttpClientBuilder.create(); + } + + public static String requestGet(String url) throws IOException { + Request request = new Request.Builder() + .url(url) + .build(); + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + return response.body().string(); + } + + public static byte[] requestPost(String url, String postData) throws IOException { + String postBody = postData; + MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("application/json"); + Request request = new Request.Builder() + .url(url) + .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody)) + .build(); + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + return response.body().bytes(); + } + + /** + * 请求 + * @param url + * @param jsonParam + * @return + */ + public static InputStream doWXPost(String url, JSONObject jsonParam) { + InputStream instreams = null; + HttpPost httpRequst = new HttpPost(url);// 创建HttpPost对象 + try { + StringEntity se = new StringEntity(jsonParam.toString(),"utf-8"); + se.setContentType("application/json"); + se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8")); + httpRequst.setEntity(se); + HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequst); + if (httpResponse.getStatusLine().getStatusCode() == 200) { + HttpEntity httpEntity = httpResponse.getEntity(); + if (httpEntity != null) { + instreams = httpEntity.getContent(); + } + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return instreams; + } + + public static String requestPost(String url, String contentType, String postData) throws IOException { + MediaType mediaType = null; + if (StringUtil.isNotEmpty(contentType)) { + mediaType = MediaType.parse(contentType); + } + Request request = new Request.Builder() + .url(url) + .post(RequestBody.create(mediaType, postData)) + .build(); + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + return response.body().string(); + } + + public static String requestPostBody(String url, String body) { + logger.debug("[HttpRESTDataClient] [requestPostBody] 入参 url={} body={}", url, body); + + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json"); + StringEntity entity = new StringEntity(body, "utf-8"); + entity.setContentEncoding("UTF-8"); + entity.setContentType("application/json"); + httpPost.setEntity(entity); + + try { + HttpClient client = httpClientBuilder.build(); + HttpResponse response = client.execute(httpPost); + if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return EntityUtils.toString(response.getEntity(), "utf-8"); + } + return ""; + } + catch (IOException ex) { + logger.error("[HttpRESTDataClient] [requestPostBody] 请求异常 ex={}", url, ex); + return ""; + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/AddressDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/AddressDetailParam.java new file mode 100644 index 0000000..de3199a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/AddressDetailParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 收获地址详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class AddressDetailParam implements Serializable { + + @ApiModelProperty(value="收获地址ID", name="addressId") + private Integer addressId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ArticleDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/ArticleDetailParam.java new file mode 100644 index 0000000..8726b52 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ArticleDetailParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 文章详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ArticleDetailParam implements Serializable { + + @ApiModelProperty(value="文章ID", name="articleId") + private Integer articleId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ArticleListParam.java b/fuint-application/src/main/java/com/fuint/common/param/ArticleListParam.java new file mode 100644 index 0000000..5b586f5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ArticleListParam.java @@ -0,0 +1,21 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 文章列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ArticleListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="文章标题", name="title") + private String title; + + @ApiModelProperty(value="商户号", name="merchantNo") + private String merchantNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ArticlePage.java b/fuint-application/src/main/java/com/fuint/common/param/ArticlePage.java new file mode 100644 index 0000000..236477e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ArticlePage.java @@ -0,0 +1,31 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 文章分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ArticlePage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("商户编码") + private String merchantNo; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BalanceListParam.java b/fuint-application/src/main/java/com/fuint/common/param/BalanceListParam.java new file mode 100644 index 0000000..3c9c575 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BalanceListParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 余额明细列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BalanceListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="会员ID", name="userId") + private String userId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BalancePage.java b/fuint-application/src/main/java/com/fuint/common/param/BalancePage.java new file mode 100644 index 0000000..e1ee6d5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BalancePage.java @@ -0,0 +1,40 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 余额明细分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BalancePage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BannerPage.java b/fuint-application/src/main/java/com/fuint/common/param/BannerPage.java new file mode 100644 index 0000000..b3c63ee --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BannerPage.java @@ -0,0 +1,28 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 焦点图分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BannerPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookCatePage.java b/fuint-application/src/main/java/com/fuint/common/param/BookCatePage.java new file mode 100644 index 0000000..76a3abc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookCatePage.java @@ -0,0 +1,28 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约分类分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookCatePage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/BookDetailParam.java new file mode 100644 index 0000000..04bfa4d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookDetailParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookDetailParam implements Serializable { + + @ApiModelProperty(value="预约ID", name="bookId") + private Integer bookId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookItemPage.java b/fuint-application/src/main/java/com/fuint/common/param/BookItemPage.java new file mode 100644 index 0000000..8864a08 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookItemPage.java @@ -0,0 +1,37 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约订单分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookItemPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("联系人") + private String contact; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookListParam.java b/fuint-application/src/main/java/com/fuint/common/param/BookListParam.java new file mode 100644 index 0000000..a5a7ca1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookListParam.java @@ -0,0 +1,24 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="名称", name="name") + private String name; + + @ApiModelProperty(value="分类ID", name="cateId") + private Integer cateId; + + @ApiModelProperty(value="商户号", name="merchantNo") + private String merchantNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookPage.java b/fuint-application/src/main/java/com/fuint/common/param/BookPage.java new file mode 100644 index 0000000..0329686 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookPage.java @@ -0,0 +1,31 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 预约分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/BookableParam.java b/fuint-application/src/main/java/com/fuint/common/param/BookableParam.java new file mode 100644 index 0000000..b91d3bc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/BookableParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 可否预约请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class BookableParam implements Serializable { + + @ApiModelProperty(value="预约ID", name="bookId") + private Integer bookId; + + @ApiModelProperty(value="预约日期", name="date") + private String date; + + @ApiModelProperty(value="预约时间", name="time") + private String time; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CartClearParam.java b/fuint-application/src/main/java/com/fuint/common/param/CartClearParam.java new file mode 100644 index 0000000..675f551 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CartClearParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 删除购物车请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CartClearParam extends PageParam implements Serializable { + + @ApiModelProperty(value="购物车ID", name="cartId") + private List cartId; + + @ApiModelProperty(value="挂单编码", name="hangNo") + private String hangNo; + + @ApiModelProperty(value="下单会员ID", name="userId") + private Integer userId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CartListParam.java b/fuint-application/src/main/java/com/fuint/common/param/CartListParam.java new file mode 100644 index 0000000..f52b935 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CartListParam.java @@ -0,0 +1,45 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 购物车列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CartListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="购物车ID", name="cartId") + private Integer cartId; + + @ApiModelProperty(value="指定购物车ID,逗号分割", name="cartIds") + private String cartIds; + + @ApiModelProperty(value="商品ID", name="goodsId") + private Integer goodsId; + + @ApiModelProperty(value="卡券ID", name="couponId") + private Integer couponId; + + @ApiModelProperty(value="商品SkuID", name="skuId") + private Integer skuId; + + @ApiModelProperty(value="使用积分", name="point") + private String point; + + @ApiModelProperty(value="购买数量", name="buyNum") + private Double buyNum; + + @ApiModelProperty(value="挂单编码", name="hangNo") + private String hangNo; + + @ApiModelProperty(value="下单会员ID", name="userId") + private Integer userId; + + @ApiModelProperty(value="订单模式", name="orderMode") + private String orderMode; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CartSaveParam.java b/fuint-application/src/main/java/com/fuint/common/param/CartSaveParam.java new file mode 100644 index 0000000..1065f63 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CartSaveParam.java @@ -0,0 +1,39 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 保存购物车请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CartSaveParam implements Serializable { + + @ApiModelProperty(value="购物车ID", name="cartId") + private Integer cartId; + + @ApiModelProperty(value="商品ID", name="goodsId") + private Integer goodsId; + + @ApiModelProperty(value="商品SkuID", name="skuId") + private Integer skuId; + + @ApiModelProperty(value="商品编码", name="skuNo") + private String skuNo; + + @ApiModelProperty(value="购买数量", name="buyNum") + private Double buyNum; + + @ApiModelProperty(value="操作类型,+:增加,-:减少", name="action") + private String action; + + @ApiModelProperty(value="挂单编码", name="hangNo") + private String hangNo; + + @ApiModelProperty(value="下单会员ID", name="userId") + private Integer userId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionCashPage.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionCashPage.java new file mode 100644 index 0000000..f448649 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionCashPage.java @@ -0,0 +1,40 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 分销提成提现记录分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionCashPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("姓名") + private String realName; + + @ApiModelProperty("批次号") + private String uuid; + + @ApiModelProperty("开始时间") + private String startTime; + + @ApiModelProperty("结束时间") + private String endTime; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionLogPage.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionLogPage.java new file mode 100644 index 0000000..c6e85a8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionLogPage.java @@ -0,0 +1,43 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 分销提成记录分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionLogPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("姓名") + private String realName; + + @ApiModelProperty("类型") + private String target; + + @ApiModelProperty("批次号") + private String uuid; + + @ApiModelProperty("开始时间") + private String startTime; + + @ApiModelProperty("结束时间") + private String endTime; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionRelationPage.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionRelationPage.java new file mode 100644 index 0000000..06a3914 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionRelationPage.java @@ -0,0 +1,46 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 分销提成邀请记录分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRelationPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("商户号") + private String merchantNo; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("姓名") + private String realName; + + @ApiModelProperty("类型") + private String subUserId; + + @ApiModelProperty("开始时间") + private String startTime; + + @ApiModelProperty("结束时间") + private String endTime; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleItemParam.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleItemParam.java new file mode 100644 index 0000000..82993d5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleItemParam.java @@ -0,0 +1,31 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 分销提成规则项目请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRuleItemParam implements Serializable { + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("商品名称") + private String goodsName; + + @ApiModelProperty("提成方式") + private String method; + + @ApiModelProperty("散客值") + private BigDecimal visitorVal; + + @ApiModelProperty("会员值") + private BigDecimal memberVal; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionRulePage.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionRulePage.java new file mode 100644 index 0000000..6c2c58a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionRulePage.java @@ -0,0 +1,37 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 分销提成规则分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRulePage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("规则名称") + private String name; + + @ApiModelProperty("分佣对象") + private String target; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleParam.java b/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleParam.java new file mode 100644 index 0000000..cf28a5c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CommissionRuleParam.java @@ -0,0 +1,57 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 分销提成规则请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CommissionRuleParam implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("规则名称") + private String name; + + @ApiModelProperty("分佣类型,member:会员分销;staff:员工提成") + private String type; + + @ApiModelProperty("分佣对象") + private String target; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("适用店铺ID列表") + private List storeIdList; + + @ApiModelProperty("具体项目列表") + private List detailList; + + @ApiModelProperty("散客值") + private BigDecimal visitorVal; + + @ApiModelProperty("会员值") + private BigDecimal memberVal; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ConfirmLogPage.java b/fuint-application/src/main/java/com/fuint/common/param/ConfirmLogPage.java new file mode 100644 index 0000000..0bf1a93 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ConfirmLogPage.java @@ -0,0 +1,34 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券核销流水请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ConfirmLogPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("手机号") + private String mobile; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ConfirmParam.java b/fuint-application/src/main/java/com/fuint/common/param/ConfirmParam.java new file mode 100644 index 0000000..7cfa40c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ConfirmParam.java @@ -0,0 +1,24 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券核销请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ConfirmParam implements Serializable { + + @ApiModelProperty(value="核销码", name="code") + private String code; + + @ApiModelProperty(value="核销金额", name="amount") + private String amount; + + @ApiModelProperty(value="核销备注", name="remark") + private String remark; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CouponInfoParam.java b/fuint-application/src/main/java/com/fuint/common/param/CouponInfoParam.java new file mode 100644 index 0000000..2833cb2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CouponInfoParam.java @@ -0,0 +1,21 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CouponInfoParam implements Serializable { + + @ApiModelProperty(value="卡券ID", name="couponId") + private Integer couponId; + + @ApiModelProperty(value="会员卡券编码", name="userCouponCode") + private String userCouponCode; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CouponListParam.java b/fuint-application/src/main/java/com/fuint/common/param/CouponListParam.java new file mode 100644 index 0000000..9d15db9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CouponListParam.java @@ -0,0 +1,46 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CouponListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="关键字", name="keyword") + private String keyword; + + @ApiModelProperty(value="卡券类型", name="type") + private String type; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="领取所需积分", name="needPoint") + private Integer needPoint; + + @ApiModelProperty(value="发放方式", name="sendWay") + private String sendWay; + + @ApiModelProperty(value="排序类型", name="sortType") + private String sortType; + + @ApiModelProperty(value="面额排序", name="sortPrice") + private String sortPrice; + + @ApiModelProperty(value="下单会员ID", name="userId") + private Integer userId; + + @ApiModelProperty(value="状态", name="status") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/CouponReceiveParam.java b/fuint-application/src/main/java/com/fuint/common/param/CouponReceiveParam.java new file mode 100644 index 0000000..442a34d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/CouponReceiveParam.java @@ -0,0 +1,27 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券领取请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class CouponReceiveParam implements Serializable { + + @ApiModelProperty(value="卡券ID", name="couponId") + private Integer couponId; + + @ApiModelProperty(value="领取数量", name="num") + private Integer num; + + @ApiModelProperty(value="会员ID", name="userId") + private Integer userId; + + @ApiModelProperty(value="领取码", name="receiveCode") + private String receiveCode; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GiveListParam.java b/fuint-application/src/main/java/com/fuint/common/param/GiveListParam.java new file mode 100644 index 0000000..4249b28 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GiveListParam.java @@ -0,0 +1,21 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 转增记录列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GiveListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="转增对象手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="类型,give = 转增,gived = 被转增", name="type") + private String type; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GiveParam.java b/fuint-application/src/main/java/com/fuint/common/param/GiveParam.java new file mode 100644 index 0000000..e622a48 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GiveParam.java @@ -0,0 +1,36 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 卡券转赠请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GiveParam implements Serializable { + + @ApiModelProperty(value="转增对象手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="卡券ID,可逗号隔开", name="couponId") + private String couponId; + + @ApiModelProperty(value="转赠备注", name="note") + private String note; + + @ApiModelProperty(value="转赠留言", name="message") + private String message; + + @ApiModelProperty(value="转赠人ID", name="userId") + private Integer userId; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GivePointParam.java b/fuint-application/src/main/java/com/fuint/common/param/GivePointParam.java new file mode 100644 index 0000000..a112e3c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GivePointParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 积分转赠请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GivePointParam implements Serializable { + + @ApiModelProperty(value="手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="转赠数量", name="amount") + private Integer amount; + + @ApiModelProperty(value="转赠备注", name="remark") + private String remark; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GoodsCatePage.java b/fuint-application/src/main/java/com/fuint/common/param/GoodsCatePage.java new file mode 100644 index 0000000..4e9893c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GoodsCatePage.java @@ -0,0 +1,31 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 商品分类分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsCatePage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GoodsInfoParam.java b/fuint-application/src/main/java/com/fuint/common/param/GoodsInfoParam.java new file mode 100644 index 0000000..b725ec8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GoodsInfoParam.java @@ -0,0 +1,21 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 商品详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsInfoParam implements Serializable { + + @ApiModelProperty(value="商品ID", name="goodsId") + private String goodsId; + + @ApiModelProperty(value="skuNo", name="skuNo") + private String skuNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/GoodsListParam.java b/fuint-application/src/main/java/com/fuint/common/param/GoodsListParam.java new file mode 100644 index 0000000..8309bc2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/GoodsListParam.java @@ -0,0 +1,58 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 商品列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class GoodsListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="商品名称", name="name") + private String name; + + @ApiModelProperty(value="搜索关键字", name="keyword") + private String keyword; + + @ApiModelProperty(value="商品编码", name="goodsNo") + private String goodsNo; + + @ApiModelProperty(value="是否单规格", name="isSingleSpec") + private String isSingleSpec; + + @ApiModelProperty(value="商品类型", name="type") + private String type; + + @ApiModelProperty(value="可用平台", name="platform") + private String platform; + + @ApiModelProperty(value="商品状态", name="status") + private String status; + + @ApiModelProperty(value="所属商户", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="所属店铺", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="是否有库存", name="stock") + private String stock; + + @ApiModelProperty(value="商品分类", name="cateId") + private Integer cateId; + + @ApiModelProperty(value="是否有价格", name="hasPrice") + private String hasPrice; + + @ApiModelProperty(value="排序方式", name="sortType") + private String sortType; + + @ApiModelProperty(value="按价格排序", name="sortPrice") + private String sortPrice; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/InvoiceParam.java b/fuint-application/src/main/java/com/fuint/common/param/InvoiceParam.java new file mode 100644 index 0000000..4e213d0 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/InvoiceParam.java @@ -0,0 +1,74 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 发票请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class InvoiceParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("开票时间") + private String invoiceTime; + + @ApiModelProperty("开票金额") + private BigDecimal invoiceAmount; + + @ApiModelProperty("发票抬头") + private String title; + + @ApiModelProperty("发票下载地址") + private String downloadUrl; + + @ApiModelProperty("发票类型,普票、专票") + private String type; + + @ApiModelProperty("纳税人识别码") + private String taxCode; + + @ApiModelProperty("开户行") + private String bankName; + + @ApiModelProperty("开户卡号") + private String bankCardNo; + + @ApiModelProperty("开户户名") + private String bankCardName; + + @ApiModelProperty("开票备注") + private String description; + + @ApiModelProperty("接收邮箱") + private String email; + + @ApiModelProperty("联系电话") + private String mobile; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A待开票,B开票中,C开票成功,D开票失败") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/MemberDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/MemberDetailParam.java new file mode 100644 index 0000000..d7948ef --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/MemberDetailParam.java @@ -0,0 +1,19 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员详情请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberDetailParam implements Serializable { + + @ApiModelProperty(value="会员ID", name="memberId") + private Integer memberId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/MemberInfoParam.java b/fuint-application/src/main/java/com/fuint/common/param/MemberInfoParam.java new file mode 100644 index 0000000..26933c9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/MemberInfoParam.java @@ -0,0 +1,37 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员查询请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberInfoParam extends PageParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private Integer id; + + @ApiModelProperty(value="手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="头像", name="avatar") + private String avatar; + + @ApiModelProperty(value="称呼", name="name") + private String name; + + @ApiModelProperty(value="性别", name="sex") + private Integer sex; + + @ApiModelProperty(value="生日", name="birthday") + private String birthday; + + @ApiModelProperty(value="会员号", name="userNo") + private String userNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/MemberListParam.java b/fuint-application/src/main/java/com/fuint/common/param/MemberListParam.java new file mode 100644 index 0000000..b7d72aa --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/MemberListParam.java @@ -0,0 +1,61 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private String id; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="会员ID", name="userId") + private Integer userId; + + @ApiModelProperty(value="关键字", name="keyword") + private String keyword; + + @ApiModelProperty(value="会员名称", name="name") + private String name; + + @ApiModelProperty(value="会员生日", name="birthday") + private String birthday; + + @ApiModelProperty(value="会员号", name="userNo") + private String userNo; + + @ApiModelProperty(value="会员等级", name="gradeId") + private String gradeId; + + @ApiModelProperty(value="注册时间", name="regTime") + private String regTime; + + @ApiModelProperty(value="活跃时间", name="activeTime") + private String activeTime; + + @ApiModelProperty(value="会员有效期", name="memberTime") + private String memberTime; + + @ApiModelProperty(value="数据类型,1)todayRegister:今日注册;2)todayActive:今日活跃", name="dataType") + private String dataType; + + @ApiModelProperty(value="会员状态", name="status") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/MemberPage.java b/fuint-application/src/main/java/com/fuint/common/param/MemberPage.java new file mode 100644 index 0000000..d93a12e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/MemberPage.java @@ -0,0 +1,67 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 会员列表分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class MemberPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("会员ID") + private Integer id; + + @ApiModelProperty("会员名称") + private String name; + + @ApiModelProperty("查询关键字") + private String keyword; + + @ApiModelProperty("查询关键字") + private String birthday; + + @ApiModelProperty("会员等级ID") + private Integer gradeId; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("会员开始时间") + private String startTime; + + @ApiModelProperty("会员结束时间") + private String endTime; + + @ApiModelProperty("注册时间") + private String regTime; + + @ApiModelProperty("会员活跃时间") + private String activeTime; + + @ApiModelProperty("会员有效期") + private String memberTime; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("所属店铺ID-多店铺") + private String storeIds; + + @ApiModelProperty("所属分组ID") + private String groupIds; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/OrderConfirmParam.java b/fuint-application/src/main/java/com/fuint/common/param/OrderConfirmParam.java new file mode 100644 index 0000000..5aed4d6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/OrderConfirmParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 订单核销请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderConfirmParam implements Serializable { + + @ApiModelProperty(value="核销码", name="code") + private String code; + + @ApiModelProperty(value="订单ID", name="orderId") + private Integer orderId; + + @ApiModelProperty(value="核销备注", name="remark") + private String remark; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/OrderDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/OrderDetailParam.java new file mode 100644 index 0000000..46a948f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/OrderDetailParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 订单详情请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderDetailParam implements Serializable { + + @ApiModelProperty(value="订单ID", name="orderId") + private String orderId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/OrderListParam.java b/fuint-application/src/main/java/com/fuint/common/param/OrderListParam.java new file mode 100644 index 0000000..3fdcb02 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/OrderListParam.java @@ -0,0 +1,83 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 订单列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class OrderListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private String id; + + @ApiModelProperty(value="关键字", name="keyword") + private String keyword; + + @ApiModelProperty(value="会员ID", name="userId") + private String userId; + + @ApiModelProperty(value="会员号", name="userCode") + private String userCode; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="店铺ID,逗号分隔", name="storeIds") + private String storeIds; + + @ApiModelProperty(value="订单状态", name="status") + private String status; + + @ApiModelProperty(value="支付状态", name="payStatus") + private String payStatus; + + @ApiModelProperty(value="结算状态", name="settleStatus") + private String settleStatus; + + @ApiModelProperty(value="核销状态", name="confirmStatus") + private String confirmStatus; + + @ApiModelProperty(value="数据类型,1)toPay:待支付;2)paid:已支付;3)cancel:已取消", name="dataType") + private String dataType; + + @ApiModelProperty(value="支付类型", name="payType") + private List payType; + + @ApiModelProperty(value="订单类型", name="type") + private String type; + + @ApiModelProperty(value="订单号", name="orderSn") + private String orderSn; + + @ApiModelProperty(value="会员手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="订单模式,1)oneself:自取,2)express:配送", name="orderMode") + private String orderMode; + + @ApiModelProperty(value="员工ID(销售人员)", name="staffId") + private String staffId; + + @ApiModelProperty(value="卡券ID", name="couponId") + private String couponId; + + @ApiModelProperty(value="时间类型", name="timeType") + private String timeType; + + @ApiModelProperty(value="开始时间", name="startTime") + private String startTime; + + @ApiModelProperty(value="结束时间", name="endTime") + private String endTime; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/PageParam.java b/fuint-application/src/main/java/com/fuint/common/param/PageParam.java new file mode 100644 index 0000000..47886dc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/PageParam.java @@ -0,0 +1,69 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import java.io.Serializable; + +/** + * 分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class PageParam implements Serializable { + private static final long serialVersionUID = -1833130751169582924L; + + @ApiModelProperty("当前页数") + private Integer page = 1; + + @ApiModelProperty("分页大小") + private int pageSize = 20; + + /** + * 排序字段 + */ + @ApiModelProperty(value="排序字段",name="orderBy") + private String orderBy; + + /** + * 排序方式 + */ + @ApiModelProperty(value="排序方式",name="order") + private String order; + + public PageParam() { + // empty + } + + public Integer getPage() { + return this.page; + } + + public Integer getPageSize() { + return this.pageSize; + } + + public void setPage(int page) { + this.page = page; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public String getOrderBy() { + return orderBy; + } + + public void setOrderBy(String orderBy) { + this.orderBy = orderBy; + } + + public String getOrder() { + return order; + } + + public void setOrder(String order) { + this.order = order; + } +} + diff --git a/fuint-application/src/main/java/com/fuint/common/param/PrinterPage.java b/fuint-application/src/main/java/com/fuint/common/param/PrinterPage.java new file mode 100644 index 0000000..8606029 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/PrinterPage.java @@ -0,0 +1,34 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 打印机分页请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class PrinterPage extends PageParam implements Serializable { + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("打印机编号") + private String sn; + + @ApiModelProperty("打印机名称") + private String name; + + @ApiModelProperty("是否自动打印机") + private String autoPrint; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/PrinterParam.java b/fuint-application/src/main/java/com/fuint/common/param/PrinterParam.java new file mode 100644 index 0000000..a4b0a8b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/PrinterParam.java @@ -0,0 +1,50 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +/** + * 打印机请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class PrinterParam implements Serializable { + + @ApiModelProperty("自增ID") + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("打印机编号") + private String sn; + + @ApiModelProperty("打印机名称") + private String name; + + @ApiModelProperty("是否自动打印机") + private String autoPrint; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/RechargeParam.java b/fuint-application/src/main/java/com/fuint/common/param/RechargeParam.java new file mode 100644 index 0000000..c435733 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/RechargeParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 充值请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RechargeParam implements Serializable { + + @ApiModelProperty(value="充值金额", name="rechargeAmount") + private String rechargeAmount; + + @ApiModelProperty(value="自定义充值金额", name="customAmount") + private String customAmount; + + @ApiModelProperty(value="会员ID", name="memberId") + private Integer memberId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/RefundDetailParam.java b/fuint-application/src/main/java/com/fuint/common/param/RefundDetailParam.java new file mode 100644 index 0000000..8d50ee2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/RefundDetailParam.java @@ -0,0 +1,19 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 售后订单详情请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RefundDetailParam implements Serializable { + + @ApiModelProperty(value="售后订单ID", name="refundId") + private Integer refundId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/RefundListParam.java b/fuint-application/src/main/java/com/fuint/common/param/RefundListParam.java new file mode 100644 index 0000000..0d5c569 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/RefundListParam.java @@ -0,0 +1,83 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; +import java.util.List; + +/** + * 售后订单列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class RefundListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private String id; + + @ApiModelProperty(value="关键字", name="keyword") + private String keyword; + + @ApiModelProperty(value="会员ID", name="userId") + private String userId; + + @ApiModelProperty(value="会员号", name="userCode") + private String userCode; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="店铺ID,逗号分隔", name="storeIds") + private String storeIds; + + @ApiModelProperty(value="订单状态", name="status") + private String status; + + @ApiModelProperty(value="支付状态", name="payStatus") + private String payStatus; + + @ApiModelProperty(value="结算状态", name="settleStatus") + private String settleStatus; + + @ApiModelProperty(value="核销状态", name="confirmStatus") + private String confirmStatus; + + @ApiModelProperty(value="数据类型,1)toPay:待支付;2)paid:已支付;3)cancel:已取消", name="dataType") + private String dataType; + + @ApiModelProperty(value="支付类型", name="payType") + private List payType; + + @ApiModelProperty(value="订单类型", name="type") + private String type; + + @ApiModelProperty(value="订单号", name="orderSn") + private String orderSn; + + @ApiModelProperty(value="会员手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="订单模式,1)oneself:自取,2)express:配送", name="orderMode") + private String orderMode; + + @ApiModelProperty(value="员工ID(销售人员)", name="staffId") + private String staffId; + + @ApiModelProperty(value="卡券ID", name="couponId") + private String couponId; + + @ApiModelProperty(value="时间类型", name="timeType") + private String timeType; + + @ApiModelProperty(value="开始时间", name="startTime") + private String startTime; + + @ApiModelProperty(value="结束时间", name="endTime") + private String endTime; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/SendCouponParam.java b/fuint-application/src/main/java/com/fuint/common/param/SendCouponParam.java new file mode 100644 index 0000000..4402038 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/SendCouponParam.java @@ -0,0 +1,31 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 发放卡券请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SendCouponParam implements Serializable { + + @ApiModelProperty(value="手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="发放数量", name="num") + private String num; + + @ApiModelProperty(value="卡券ID", name="couponId") + private String couponId; + + @ApiModelProperty(value="会员ID", name="userIds") + private String userIds; + + @ApiModelProperty(value="发放对象", name="object") + private String object; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/SettlementParam.java b/fuint-application/src/main/java/com/fuint/common/param/SettlementParam.java new file mode 100644 index 0000000..30873dc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/SettlementParam.java @@ -0,0 +1,78 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 订单结算请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class SettlementParam implements Serializable { + + @ApiModelProperty(value="购物车Id,逗号分隔", name="cartIds") + private String cartIds; + + @ApiModelProperty(value="购买对象,购买储值卡、升级会员等级必填", name="targetId") + private String targetId; + + @ApiModelProperty(value="购买储值卡数量", name="selectNum") + private String selectNum; + + @ApiModelProperty(value="结算备注", name="remark") + private String remark; + + @ApiModelProperty(value="订单类型,payment:付款订单、goods:商品订单、recharge:充值订单、prestore:储值卡订单、member:会员升级订单", name="type") + private String type; + + @ApiModelProperty(value="支付金额,付款类订单必填", name="payAmount") + private String payAmount; + + @ApiModelProperty(value="使用积分数量", name="usePoint") + private Integer usePoint; + + @ApiModelProperty(value="使用卡券ID", name="couponId") + private Integer couponId; + + @ApiModelProperty(value="支付类型,CASH:现金支付,JSAPI:微信支付,MICROPAY:微信扫码支付,BALANCE:余额支付,ALISCAN:支付宝扫码", name="payType") + private String payType; + + @ApiModelProperty(value="PC端扫码支付的二维码", name="authCode") + private String authCode; + + @ApiModelProperty(value="会员ID(代客下单用到)", name="userId") + private Integer userId; + + @ApiModelProperty(value="会员手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="实付金额(收银台用到)", name="cashierPayAmount") + private String cashierPayAmount; + + @ApiModelProperty(value="优惠金额(收银台用到)", name="cashierDiscountAmount") + private String cashierDiscountAmount; + + @ApiModelProperty(value="商品ID", name="goodsId") + private Integer goodsId; + + @ApiModelProperty(value="商品skuID", name="skuId") + private Integer skuId; + + @ApiModelProperty(value="购买数量", name="buyNum") + private Double buyNum; + + @ApiModelProperty(value="订单模式,配送(express)或自提(oneself)", name="orderMode") + private String orderMode; + + @ApiModelProperty(value="订单ID", name="orderId") + private Integer orderId; + + @ApiModelProperty(value="是否微信客户端", name="isWechat") + private String isWechat; + + @ApiModelProperty(value="员工ID", name="staffId") + private Integer staffId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/ShareListParam.java b/fuint-application/src/main/java/com/fuint/common/param/ShareListParam.java new file mode 100644 index 0000000..0b2466d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/ShareListParam.java @@ -0,0 +1,18 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 邀请列表请求参数 + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ShareListParam extends PageParam implements Serializable { + + @ApiModelProperty(value="商户号", name="merchantNo") + private String merchantNo; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/StaffParam.java b/fuint-application/src/main/java/com/fuint/common/param/StaffParam.java new file mode 100644 index 0000000..620b92a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/StaffParam.java @@ -0,0 +1,40 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 订单列表请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class StaffParam extends PageParam implements Serializable { + + @ApiModelProperty(value="ID", name="id") + private Integer id; + + @ApiModelProperty(value="商户ID", name="merchantId") + private Integer merchantId; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + + @ApiModelProperty(value="类别", name="category") + private Integer category; + + @ApiModelProperty(value="手机号", name="mobile") + private String mobile; + + @ApiModelProperty(value="真实姓名", name="realName") + private String realName; + + @ApiModelProperty(value="备注信息", name="description") + private String description; + + @ApiModelProperty(value="审核状态", name="auditedStatus") + private String auditedStatus; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/param/StatisticParam.java b/fuint-application/src/main/java/com/fuint/common/param/StatisticParam.java new file mode 100644 index 0000000..ab3970e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/param/StatisticParam.java @@ -0,0 +1,25 @@ +package com.fuint.common.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 统计请求参数 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class StatisticParam implements Serializable { + + @ApiModelProperty(value="开始时间", name="startTime") + private String startTime; + + @ApiModelProperty(value="结束时间", name="endTime") + private String endTime; + + @ApiModelProperty(value="店铺ID", name="storeId") + private Integer storeId; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/permission/PermissionService.java b/fuint-application/src/main/java/com/fuint/common/permission/PermissionService.java new file mode 100644 index 0000000..15541fe --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/permission/PermissionService.java @@ -0,0 +1,73 @@ +package com.fuint.common.permission; + +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.service.SourceService; +import com.fuint.common.util.AuthUserUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.TSource; +import com.fuint.utils.StringUtil; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 权限控制业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service("pms") +public class PermissionService { + + /** + * 所有权限标识 + */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** + * 后台菜单接口 + * */ + @Resource + SourceService sourceService; + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermission(String permission) throws BusinessCheckException { + if (StringUtil.isEmpty(permission)) { + return false; + } + + AccountInfo accountInfo = AuthUserUtil.get(); + if (accountInfo == null) { + return false; + } + + Set allPermission = new HashSet<>(); + List sources = sourceService.getMenuListByUserId(accountInfo.getMerchantId(), accountInfo.getId()); + if (sources != null && sources.size() > 0) { + for (TSource tSource : sources) { + allPermission.add(tSource.getPath().replaceAll("/", ":")); + } + } + + return hasPermissions(allPermission, permission); + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return boolean + */ + private boolean hasPermissions(Set permissions, String permission) { + return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtil.trim(permission)); + } +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/service/AccountService.java b/fuint-application/src/main/java/com/fuint/common/service/AccountService.java new file mode 100644 index 0000000..0f67c5b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/AccountService.java @@ -0,0 +1,122 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.AccountDto; +import com.fuint.common.dto.AccountInfo; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.LoginRequest; +import com.fuint.module.backendApi.response.LoginResponse; +import com.fuint.repository.model.TAccount; +import com.fuint.repository.model.TDuty; +import java.util.List; + +/** + * 后台账号接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface AccountService extends IService { + + /** + * 分页查询账号列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse getAccountListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 根据账号名称获取账号信息 + * + * @param userName 账号名称 + * @return + * */ + AccountInfo getAccountByName(String userName); + + /** + * 获取用户信息 + * + * @param id 账号ID + * @return + */ + TAccount getAccountInfoById(Integer id); + + /** + * 创建账号信息 + * + * @param accountInfo 账号信息 + * @param duties 角色 + * @return + * */ + TAccount createAccountInfo(TAccount accountInfo, List duties) throws BusinessCheckException; + + /** + * 获取账号角色ID + * + * @param accountId 账号ID + * @return + * */ + List getRoleIdsByAccountId(Integer accountId); + + /** + * 修改账户 + * + * @param tAccount 账户实体 + * @throws BusinessCheckException + * @return + */ + void editAccount(TAccount tAccount, List duties) throws BusinessCheckException; + + /** + * 根据账户名称获取账户所分配的角色ID集合 + * + * @param accountId 账户 + * @return 角色ID集合 + */ + List getDutyIdsByAccountId(Integer accountId); + + /** + * 更新账户信息 + * + * @param tAccount + * @return + */ + void updateAccount(TAccount tAccount); + + /** + * 删除后台账号 + * + * @param accountId 账号ID + * @return + * */ + void deleteAccount(Long accountId); + + /** + * 密码加密 + * + * @param tAccount 账号信息 + * @return + * */ + void entryptPassword(TAccount tAccount); + + /** + * 获取加密密码 + * + * @param password + * @param salt + * @return + * */ + String getEntryptPassword(String password, String salt); + + /** + * 登录后台系统 + * + * @param loginRequest 登录参数 + * @param userAgent 登录浏览器 + * @return + * */ + LoginResponse doLogin(LoginRequest loginRequest, String userAgent) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/ActionLogService.java b/fuint-application/src/main/java/com/fuint/common/service/ActionLogService.java new file mode 100644 index 0000000..fac3260 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/ActionLogService.java @@ -0,0 +1,31 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.TActionLog; + +/** + * 后台日志服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface ActionLogService extends IService { + + /** + * 保存日志 + * + * @param actionLog + * @return + */ + void saveActionLog(TActionLog actionLog); + + /** + * 获取分页查询数据 + * + * @param paginationRequest + * @return + */ + PaginationResponse findLogsByPagination(PaginationRequest paginationRequest); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/AddressService.java b/fuint-application/src/main/java/com/fuint/common/service/AddressService.java new file mode 100644 index 0000000..224e111 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/AddressService.java @@ -0,0 +1,42 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.repository.model.MtAddress; +import com.fuint.framework.exception.BusinessCheckException; +import java.util.List; +import java.util.Map; + +/** + * 收货地址业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface AddressService extends IService { + + /** + * 保存收货地址 + * + * @param mtAddress + * @throws BusinessCheckException + * @return + */ + MtAddress saveAddress(MtAddress mtAddress) throws BusinessCheckException; + + /** + * 根据ID获取Banner信息 + * + * @param id 地址ID + * @throws BusinessCheckException + * @return + */ + MtAddress detail(Integer id) throws BusinessCheckException; + + /** + * 根据条件查询地址列表 + * + * @param params 查询参数 + * @return + * */ + List queryListByParams(Map params) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/AlipayService.java b/fuint-application/src/main/java/com/fuint/common/service/AlipayService.java new file mode 100644 index 0000000..72cca79 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/AlipayService.java @@ -0,0 +1,62 @@ +package com.fuint.common.service; + +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import java.math.BigDecimal; +import java.util.Map; + +/** + * 支付宝相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface AlipayService { + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @return + * */ + ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform) throws BusinessCheckException; + + /** + * 支付回调 + * + * @param params 请求参数 + * @return + * */ + Boolean checkCallBack(Map params) throws Exception; + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param tradeNo 交易单号 + * @param orderSn 订单号 + * @return + * */ + Map queryPaidOrder(Integer storeId, String tradeNo, String orderSn) throws BusinessCheckException; + + /** + * 发起售后退款 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 订单总金额 + * @param refundAmount 售后金额 + * @param platform 订单平台 + * @return + * */ + Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException; + +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/service/ArticleService.java b/fuint-application/src/main/java/com/fuint/common/service/ArticleService.java new file mode 100644 index 0000000..f018646 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/ArticleService.java @@ -0,0 +1,67 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.ArticleDto; +import com.fuint.common.param.ArticlePage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtArticle; +import com.fuint.framework.exception.BusinessCheckException; +import java.util.List; +import java.util.Map; + +/** + * 文章业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface ArticleService extends IService { + + /** + * 分页查询文章列表 + * + * @param articlePage + * @return + */ + PaginationResponse queryArticleListByPagination(ArticlePage articlePage) throws BusinessCheckException; + + /** + * 添加文章 + * + * @param articleDto + * @throws BusinessCheckException + */ + MtArticle addArticle(ArticleDto articleDto) throws BusinessCheckException; + + /** + * 根据ID获取文章信息 + * + * @param id 文章ID + * @throws BusinessCheckException + */ + MtArticle queryArticleById(Integer id) throws BusinessCheckException; + + /** + * 根据ID获取文章详情 + * + * @param id 文章ID + * @throws BusinessCheckException + */ + ArticleDto getArticleDetail(Integer id) throws BusinessCheckException; + + /** + * 更新文章 + * @param articleDto + * @throws BusinessCheckException + * */ + MtArticle updateArticle(ArticleDto articleDto) throws BusinessCheckException; + + /** + * 根据条件搜索文章 + * + * @param params + * @return + * */ + List queryArticleListByParams(Map params) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/BalanceService.java b/fuint-application/src/main/java/com/fuint/common/service/BalanceService.java new file mode 100644 index 0000000..054885d --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/BalanceService.java @@ -0,0 +1,56 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.BalanceDto; +import com.fuint.common.param.BalancePage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtBalance; +import java.util.List; + +/** + * 余额业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface BalanceService extends IService { + + /** + * 分页查询余额列表 + * + * @param balancePage + * @return + */ + PaginationResponse queryBalanceListByPagination(BalancePage balancePage) throws BusinessCheckException; + + /** + * 添加余额记录 + * + * @param reqDto + * @param updateBalance + * @throws BusinessCheckException + */ + Boolean addBalance(MtBalance reqDto, Boolean updateBalance) throws BusinessCheckException; + + /** + * 发放余额 + * + * @param accountInfo 账号信息 + * @param object 发放对象,all全部 + * @param userIds 会员ID + * @param amount 发放金额 + * @param remark 备注 + * @return + */ + void distribute(AccountInfo accountInfo, String object, String userIds, String amount, String remark) throws BusinessCheckException; + + /** + * 获取订单余额记录 + * + * @param orderSn + * @return + * */ + List getBalanceListByOrderSn(String orderSn) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/BannerService.java b/fuint-application/src/main/java/com/fuint/common/service/BannerService.java new file mode 100644 index 0000000..4e38331 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/BannerService.java @@ -0,0 +1,72 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.param.BannerPage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtBanner; +import com.fuint.common.dto.BannerDto; +import com.fuint.framework.exception.BusinessCheckException; +import java.util.List; +import java.util.Map; + +/** + * 焦点图业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface BannerService extends IService { + + /** + * 分页查询列表 + * + * @param bannerPage + * @return + */ + PaginationResponse queryBannerListByPagination(BannerPage bannerPage) throws BusinessCheckException; + + /** + * 添加Banner + * + * @param reqBannerDto + * @throws BusinessCheckException + * @return + */ + MtBanner addBanner(BannerDto reqBannerDto) throws BusinessCheckException; + + /** + * 根据ID获取Banner信息 + * + * @param id Banner ID + * @throws BusinessCheckException + * @return + */ + MtBanner queryBannerById(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除焦点图 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteBanner(Integer id, String operator) throws BusinessCheckException; + + /** + * 更新焦点图 + * @param bannerDto + * @throws BusinessCheckException + * @return + * */ + MtBanner updateBanner(BannerDto bannerDto) throws BusinessCheckException; + + /** + * 根据条件搜索焦点图 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryBannerListByParams(Map params) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/BookCateService.java b/fuint-application/src/main/java/com/fuint/common/service/BookCateService.java new file mode 100644 index 0000000..029ada5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/BookCateService.java @@ -0,0 +1,63 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.param.BookCatePage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.MtBookCate; +import java.util.List; + +/** + * 预约类别业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface BookCateService extends IService { + + /** + * 分页查询列表 + * + * @param bookCatePage + * @return + */ + PaginationResponse queryBookCateListByPagination(BookCatePage bookCatePage) throws BusinessCheckException; + + /** + * 添加预约类别 + * + * @param mtBookCate + * @throws BusinessCheckException + * @return + */ + MtBookCate addBookCate(MtBookCate mtBookCate) throws BusinessCheckException; + + /** + * 根据ID获取预约类别 + * + * @param id 预约分类ID + * @throws BusinessCheckException + * @return + */ + MtBookCate getBookCateById(Integer id) throws BusinessCheckException; + + /** + * 更新预约类别 + * + * @param mtBookCate + * @throws BusinessCheckException + * @return + * */ + MtBookCate updateBookCate(MtBookCate mtBookCate) throws BusinessCheckException; + + /** + * 获取可用的预约类别 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + List getAvailableBookCate(Integer merchantId, Integer storeId) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/BookItemService.java b/fuint-application/src/main/java/com/fuint/common/service/BookItemService.java new file mode 100644 index 0000000..814edc6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/BookItemService.java @@ -0,0 +1,93 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.BookItemDto; +import com.fuint.common.param.BookItemPage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.MtBookItem; + +import java.text.ParseException; +import java.util.List; +import java.util.Map; + +/** + * 预约订单业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface BookItemService extends IService { + + /** + * 分页查询列表 + * + * @param bookItemPage + * @return + */ + PaginationResponse queryBookItemListByPagination(BookItemPage bookItemPage) throws BusinessCheckException; + + /** + * 添加预约订单 + * + * @param mtBookItem + * @throws BusinessCheckException + * @return + */ + MtBookItem addBookItem(MtBookItem mtBookItem) throws BusinessCheckException, ParseException; + + /** + * 根据ID获取预约订单信息 + * + * @param id 预约订单ID + * @return + */ + MtBookItem getBookItemById(Integer id); + + /** + * 获取用户预约订单信息 + * + * @param bookId 预约项目ID + * @param userId 用户ID + * @param orderGoodsId 订单商品ID + * @return + */ + MtBookItem getUserBookItem(Integer bookId, Integer userId, Integer orderGoodsId); + + /** + * 根据ID获取预约订单详情 + * + * @param id 预约订单ID + * @throws BusinessCheckException + * @return + */ + BookItemDto getBookDetail(Integer id) throws BusinessCheckException; + + /** + * 更新预约订单 + * + * @param mtBookItem + * @throws BusinessCheckException + * @return + * */ + MtBookItem updateBookItem(MtBookItem mtBookItem) throws BusinessCheckException; + + /** + * 根据条件搜索预约订单 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryBookItemListByParams(Map params) throws BusinessCheckException; + + /** + * 取消预约 + * + * @param id 预约订单ID + * @param remark 备注信息 + * @throws BusinessCheckException + * @return + * */ + Boolean cancelBook(Integer id, String remark) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/BookService.java b/fuint-application/src/main/java/com/fuint/common/service/BookService.java new file mode 100644 index 0000000..f2f6703 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/BookService.java @@ -0,0 +1,76 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.BookDto; +import com.fuint.common.param.BookPage; +import com.fuint.common.param.BookableParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtBook; + +import java.text.ParseException; +import java.util.List; + +/** + * 预约业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface BookService extends IService { + + /** + * 分页查询预约列表 + * + * @param bookPage + * @return + */ + PaginationResponse queryBookListByPagination(BookPage bookPage) throws BusinessCheckException; + + /** + * 添加预约 + * + * @param mtBook + * @throws BusinessCheckException + * @return + */ + MtBook addBook(MtBook mtBook) throws BusinessCheckException; + + /** + * 根据ID获取预约项目信息 + * + * @param id 预约项目ID + * @param fillDate 填充日期 + * @throws BusinessCheckException + * @return + */ + BookDto getBookById(Integer id, boolean fillDate) throws ParseException; + + /** + * 更新预约项目 + * + * @param mtBook + * @throws BusinessCheckException + * @return + * */ + MtBook updateBook(MtBook mtBook) throws BusinessCheckException; + + /** + * 是否可预约 + * + * @param param + * @throws BusinessCheckException + * @return + * */ + List isBookable(BookableParam param) throws BusinessCheckException, ParseException; + + /** + * 获取预约项目列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + List getBookList(Integer merchantId, Integer storeId); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CaptchaService.java b/fuint-application/src/main/java/com/fuint/common/service/CaptchaService.java new file mode 100644 index 0000000..b78d771 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CaptchaService.java @@ -0,0 +1,43 @@ +package com.fuint.common.service; + +import javax.servlet.http.HttpSession; +import java.awt.image.BufferedImage; + +/** + * 图形验证码插件服务类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CaptchaService { + + /** + * 生成图形验证码,并保存至Session + * @param session Session + * @return BufferedImage + */ + BufferedImage getCode(HttpSession session); + + /** + * 图形验证码校验 + * @param code 输入的验证码 + * @param session Session + * @return Boolean + */ + Boolean checkCode(String code, HttpSession session); + + /** + * 生成图形验证码 + * @return BufferedImage + */ + BufferedImage getCodeByUuid(String uuid); + + /** + * 图形验证码校验 + * @param code 输入的验证码 + * @param uuid uuid + * @return Boolean + */ + Boolean checkCodeByUuid(String code, String uuid); + +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/service/CartService.java b/fuint-application/src/main/java/com/fuint/common/service/CartService.java new file mode 100644 index 0000000..d4eca6f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CartService.java @@ -0,0 +1,80 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.MtCart; +import java.util.List; +import java.util.Map; + +/** + * 购物车业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CartService extends IService { + + /** + * 切换购物车给会员 + * + * @param userId + * @param cartIds + * @return + * */ + Boolean switchCartIds(Integer userId, String cartIds) throws BusinessCheckException; + + /** + * 保存购物车 + * + * @param reqDto + * @param action + or - or = + * @throws BusinessCheckException + * @return + */ + Integer saveCart(MtCart reqDto, String action) throws BusinessCheckException; + + /** + * 删除购物车 + * + * @param cartIds 购物车ID + * @throws BusinessCheckException + * @return + */ + void removeCart(String cartIds) throws BusinessCheckException; + + /** + * 删除购物车 + * + * @param hangNo 挂单序号 + * @throws BusinessCheckException + * @return + */ + void removeCartByHangNo(String hangNo) throws BusinessCheckException; + + /** + * 清空会员购物车 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + void clearCart(Integer userId) throws BusinessCheckException; + + /** + * 根据条件查找 + * + * @param params 查询参数 + * @return + * */ + List queryCartListByParams(Map params) throws BusinessCheckException; + + /** + * 挂单 + * + * @param cartId 购物车ID + * @param hangNo 挂单序号 + * @param isVisitor 是否游客 + * @return + */ + MtCart setHangNo(Integer cartId, String hangNo, String isVisitor) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CateService.java b/fuint-application/src/main/java/com/fuint/common/service/CateService.java new file mode 100644 index 0000000..34f3e49 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CateService.java @@ -0,0 +1,83 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.GoodsCateDto; +import com.fuint.common.param.GoodsCatePage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtGoodsCate; +import java.util.List; + +/** + * 商品分类业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CateService extends IService { + + /** + * 分页查询列表 + * + * @param catePage + * @return + */ + PaginationResponse queryCateListByPagination(GoodsCatePage catePage) throws BusinessCheckException; + + /** + * 添加商品分类 + * + * @param reqDto 分类参数 + * @throws BusinessCheckException + * @return + */ + MtGoodsCate addCate(MtGoodsCate reqDto) throws BusinessCheckException; + + /** + * 根据ID获取商品分类信息 + * + * @param id ID + * @throws BusinessCheckException + */ + MtGoodsCate queryCateById(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除 + * + * @param id 分类ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteCate(Integer id, String operator) throws BusinessCheckException; + + /** + * 更新分类 + * @param reqDto 分类参数 + * @throws BusinessCheckException + * @return + * */ + MtGoodsCate updateCate(MtGoodsCate reqDto) throws BusinessCheckException; + + /** + * 获取分类列表 + * + * @param merchantId 商户 + * @param storeId 店铺ID + * @param name 店铺名称 + * @param status 状态 + * @return + * */ + List getCateList(Integer merchantId, Integer storeId, String name, String status) throws BusinessCheckException; + + /** + * 获取分类ID + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param name 分类名称 + * @return + * */ + Integer getGoodsCateId(Integer merchantId, Integer storeId, String name); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CommissionCashService.java b/fuint-application/src/main/java/com/fuint/common/service/CommissionCashService.java new file mode 100644 index 0000000..42fbda2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CommissionCashService.java @@ -0,0 +1,83 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.CommissionCashDto; +import com.fuint.common.param.CommissionCashPage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.module.backendApi.request.CommissionCashRequest; +import com.fuint.module.backendApi.request.CommissionSettleConfirmRequest; +import com.fuint.module.backendApi.request.CommissionSettleRequest; +import com.fuint.repository.model.MtCommissionCash; + +/** + * 分销提成记录业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CommissionCashService extends IService { + + /** + * 分页查询列表 + * + * @param commissionCashPage + * @return + */ + PaginationResponse queryCommissionCashByPagination(CommissionCashPage commissionCashPage) throws BusinessCheckException; + + /** + * 计算订单分销提成 + * + * @param commissionSettleRequest 结算参数 + * @throws BusinessCheckException + * @return + */ + String settleCommission(CommissionSettleRequest commissionSettleRequest) throws BusinessCheckException; + + /** + * 根据ID获取记录信息 + * + * @param id 记录ID + * @throws BusinessCheckException + * @return + */ + CommissionCashDto queryCommissionCashById(Integer id) throws BusinessCheckException; + + /** + * 更新分销提成记录 + * + * @param commissionCashRequest 请求参数 + * @throws BusinessCheckException + * @return + */ + void updateCommissionCash(CommissionCashRequest commissionCashRequest) throws BusinessCheckException; + + /** + * 结算确认 + * + * @param requestParam 确认参数 + * @throws BusinessCheckException + * @return + */ + void confirmCommissionCash(CommissionSettleConfirmRequest requestParam) throws BusinessCheckException; + + /** + * 取消结算 + * + * @param requestParam 取消参数 + * @throws BusinessCheckException + * @return + */ + void cancelCommissionCash(CommissionSettleConfirmRequest requestParam) throws BusinessCheckException; + + /** + * 支付结算金额到用户余额 + * + * @param commissionCashRequest 请求参数 + * @throws BusinessCheckException + * @return + */ + void payToBalance(CommissionCashRequest commissionCashRequest) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CommissionLogService.java b/fuint-application/src/main/java/com/fuint/common/service/CommissionLogService.java new file mode 100644 index 0000000..00a9ba5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CommissionLogService.java @@ -0,0 +1,53 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.CommissionLogDto; +import com.fuint.common.param.CommissionLogPage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.CommissionLogRequest; +import com.fuint.repository.model.MtCommissionLog; + +/** + * 分销提成记录业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CommissionLogService extends IService { + + /** + * 分页查询列表 + * + * @param commissionLogPage + * @return + */ + PaginationResponse queryCommissionLogByPagination(CommissionLogPage commissionLogPage) throws BusinessCheckException; + + /** + * 计算订单分销提成 + * + * @param orderId 订单ID + * @throws BusinessCheckException + * @return + */ + void calculateCommission(Integer orderId) throws BusinessCheckException; + + /** + * 根据ID获取记录信息 + * + * @param id 记录ID + * @throws BusinessCheckException + * @return + */ + CommissionLogDto queryCommissionLogById(Integer id) throws BusinessCheckException; + + /** + * 更新分销提成记录 + * + * @param requestParam 请求参数 + * @throws BusinessCheckException + * @return + */ + void updateCommissionLog(CommissionLogRequest requestParam) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CommissionRelationService.java b/fuint-application/src/main/java/com/fuint/common/service/CommissionRelationService.java new file mode 100644 index 0000000..28e37bb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CommissionRelationService.java @@ -0,0 +1,36 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.CommissionRelationDto; +import com.fuint.common.param.CommissionRelationPage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtCommissionRelation; +import com.fuint.repository.model.MtUser; + +/** + * 分销提成关系业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CommissionRelationService extends IService { + + /** + * 分页查询分佣关系列表 + * + * @param commissionRelationPage + * @return + */ + PaginationResponse queryRelationByPagination(CommissionRelationPage commissionRelationPage) throws BusinessCheckException; + + /** + * 设置分销提成关系 + * + * @param userInfo 会员信息 + * @param shareId 分享者ID + * @throws BusinessCheckException + * @retrurn + */ + void setCommissionRelation(MtUser userInfo, String shareId) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CommissionRuleService.java b/fuint-application/src/main/java/com/fuint/common/service/CommissionRuleService.java new file mode 100644 index 0000000..55b1e38 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CommissionRuleService.java @@ -0,0 +1,51 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.CommissionRuleDto; +import com.fuint.common.param.CommissionRulePage; +import com.fuint.common.param.CommissionRuleParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtCommissionRule; + +/** + * 分销提成规则业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CommissionRuleService extends IService { + + /** + * 分页查询列表 + * + * @param commissionRulePage + * @return + */ + PaginationResponse queryDataByPagination(CommissionRulePage commissionRulePage) throws BusinessCheckException; + + /** + * 添加分佣提成规则 + * + * @param commissionRule + * @throws BusinessCheckException + */ + MtCommissionRule addCommissionRule(CommissionRuleParam commissionRule) throws BusinessCheckException; + + /** + * 根据ID获取规则信息 + * + * @param id + * @throws BusinessCheckException + */ + CommissionRuleDto queryCommissionRuleById(Integer id) throws BusinessCheckException; + + /** + * 更新分佣提成规则 + * + * @param commissionRule + * @throws BusinessCheckException + * */ + MtCommissionRule updateCommissionRule(CommissionRuleParam commissionRule) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/ConfirmLogService.java b/fuint-application/src/main/java/com/fuint/common/service/ConfirmLogService.java new file mode 100644 index 0000000..7db8eab --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/ConfirmLogService.java @@ -0,0 +1,47 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.ConfirmLogDto; +import com.fuint.common.param.ConfirmLogPage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtConfirmLog; + +import java.util.Date; +import java.util.List; + +/** + * 核销记录业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface ConfirmLogService extends IService { + + /** + * 分页查询会员卡券核销列表 + * + * @param confirmLogPage + * @return + */ + PaginationResponse queryConfirmLogListByPagination(ConfirmLogPage confirmLogPage) throws BusinessCheckException; + + /** + * 获取卡券核销次数 + * @param userCouponId + * @return + * */ + Long getConfirmNum(Integer userCouponId) throws BusinessCheckException; + + /** + * 获取卡券核销列表 + * @param userCouponId + * @return + * */ + List getConfirmList(Integer userCouponId) throws BusinessCheckException; + + /** + * 获取核销总数 + * */ + Long getConfirmCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CouponGroupService.java b/fuint-application/src/main/java/com/fuint/common/service/CouponGroupService.java new file mode 100644 index 0000000..a3703b2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CouponGroupService.java @@ -0,0 +1,93 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.ReqCouponGroupDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtCouponGroup; +import org.springframework.web.multipart.MultipartFile; +import java.math.BigDecimal; + +/** + * 卡券分组业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CouponGroupService extends IService { + + /** + * 分页查询分组列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryCouponGroupListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加卡券分组 + * + * @param reqCouponGroupDto + * @throws BusinessCheckException + */ + MtCouponGroup addCouponGroup(ReqCouponGroupDto reqCouponGroupDto) throws BusinessCheckException; + + /** + * 修改卡券分组 + * + * @param reqCouponGroupDto + * @throws BusinessCheckException + */ + MtCouponGroup updateCouponGroup(ReqCouponGroupDto reqCouponGroupDto) throws BusinessCheckException; + + /** + * 根据组ID获取分组信息 + * + * @param id 分组ID + * @throws BusinessCheckException + */ + MtCouponGroup queryCouponGroupById(Integer id) throws BusinessCheckException; + + /** + * 根据分组ID 删除分组信息 + * + * @param id 分组ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + void deleteCouponGroup(Integer id, String operator) throws BusinessCheckException; + + /** + * 根据分组ID 获取券种类数量 + * + * @param id 分组ID + * @throws BusinessCheckException + */ + Integer getCouponNum(Integer id) throws BusinessCheckException; + + /** + * 根据分组ID 获取券总价值 + * + * @param id 分组ID + * @throws BusinessCheckException + */ + BigDecimal getCouponMoney(Integer id) throws BusinessCheckException; + + /** + * 获取已发放套数 + * + * @param id 分组ID + * @throws BusinessCheckException + * */ + Integer getSendNum(Integer id) throws BusinessCheckException; + + /** + * 导入发券列表 + * + * @param file excel文件 + * @param operator 操作者 + * */ + String importSendCoupon(MultipartFile file, String operator, String filePath) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/CouponService.java b/fuint-application/src/main/java/com/fuint/common/service/CouponService.java new file mode 100644 index 0000000..8db31e1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/CouponService.java @@ -0,0 +1,179 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.ReqCouponDto; +import com.fuint.common.param.CouponListParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtCoupon; +import com.fuint.repository.model.MtUserCoupon; +import java.math.BigDecimal; +import java.text.ParseException; +import java.util.List; + +/** + * 卡券业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface CouponService extends IService { + + /** + * 分页查询卡券列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryCouponListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 保存卡券 + * + * @param reqCouponDto + * @throws BusinessCheckException + * @return + */ + MtCoupon saveCoupon(ReqCouponDto reqCouponDto) throws BusinessCheckException, ParseException; + + /** + * 根据ID获取卡券信息 + * + * @param id 卡券ID + * @throws BusinessCheckException + * @return + */ + MtCoupon queryCouponById(Integer id) throws BusinessCheckException; + + /** + * 删除卡券信息 + * + * @param id 卡券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteCoupon(Long id, String operator) throws BusinessCheckException; + + /** + * 获取卡券列表 + * @param couponListParam 查询参数 + * @throws BusinessCheckException + * */ + ResponseObject findCouponList(CouponListParam couponListParam) throws BusinessCheckException; + + /** + * 发放卡券 + * + * @param couponId 券ID + * @param userId 会员ID + * @param num 发放套数 + * @param sendMessage 是否发送消息 + * @param uuid 批次号 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + ResponseObject sendCoupon(Integer couponId, Integer userId, Integer num, Boolean sendMessage, String uuid, String operator) throws BusinessCheckException; + + /** + * 发放卡券 + * + * @param couponId 券ID + * @param userIds 会员ID + * @param num 发放套数 + * @param uuid 批次号 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + Boolean batchSendCoupon(Integer couponId, List userIds, Integer num, String uuid, String operator) throws BusinessCheckException; + + /** + * 根据分组获取卡券列表 + * @param groupId 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryCouponListByGroupId(Integer groupId) throws BusinessCheckException; + + /** + * 核销卡券 + * @param userCouponId 用户券ID + * @param userId 核销会员ID + * @param storeId 店铺ID + * @param orderId 订单ID + * @param amount 核销金额 + * @param remark 核销备注 + * @throws BusinessCheckException + * @return + * */ + String useCoupon(Integer userCouponId, Integer userId, Integer storeId, Integer orderId, BigDecimal amount, String remark) throws BusinessCheckException; + + /** + * 根据券ID删除个人卡券 + * + * @param id 券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteUserCoupon(Integer id, String operator) throws BusinessCheckException; + + /** + * 根据券ID撤销个人卡券消费流水 + * + * @param id 消费流水ID + * @param userCouponId 用户卡券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void rollbackUserCoupon(Integer id, Integer userCouponId,String operator) throws BusinessCheckException; + + /** + * 根据ID获取用户卡券信息 + * @param userCouponId 查询参数 + * @throws BusinessCheckException + * @return + * */ + MtUserCoupon queryUserCouponById(Integer userCouponId) throws BusinessCheckException; + + /** + * 根据批次撤销卡券 + * @param id ID + * @param uuid 批次ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void removeUserCoupon(Long id, String uuid, String operator) throws BusinessCheckException; + + /** + * 判断卡券码是否过期 + * @param code 券码 + * @return + * */ + boolean codeExpired(String code); + + /** + * 判断卡券是否有效 + * + * @param coupon + * @param userCoupon + * @return + * */ + boolean isCouponEffective(MtCoupon coupon, MtUserCoupon userCoupon); + + /** + * 删除我的卡券 + * + * @param userCouponId + * @param userId + * @return + * */ + boolean removeCoupon(Integer userCouponId, Integer userId) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/DutyService.java b/fuint-application/src/main/java/com/fuint/common/service/DutyService.java new file mode 100644 index 0000000..08837a8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/DutyService.java @@ -0,0 +1,121 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.DutyStatusRequest; +import com.fuint.repository.model.TDuty; +import com.fuint.repository.model.TSource; +import com.fuint.common.domain.TreeNode; +import java.util.List; + +/** + * 角色服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface DutyService extends IService { + + /** + * 角色保存方法 + * + * @param duty 角色信息 + * @return + */ + void saveDuty(TDuty duty, List sources) throws BusinessCheckException; + + /** + * 获取有效的角色集合 + * + * @param merchantId 商户ID + * @param accountId 账号ID + * @return + */ + List getAvailableRoles(Integer merchantId, Integer accountId); + + /** + * 根据ID获取角色实体 + * + * @param roleId 角色ID + * @return + */ + TDuty getRoleById(Long roleId); + + /** + * 角色信息分页查询 + * + * @param paginationRequest 分页查询请求对象 + * @return 分页查询结果对象 + */ + PaginationResponse findDutiesByPagination(PaginationRequest paginationRequest); + + /** + * 根据ID数组获取角色集合 + * + * @param ids 角色ID + * @return + */ + List findDatasByIds(String[] ids); + + /** + * 删除方法 + * + * @param merchantId 商户ID + * @param dutyId 角色ID + * @return + */ + void deleteDuty(Integer merchantId, long dutyId) throws BusinessCheckException; + + /** + * 更新状态 + * + * @param merchantId + * @param dutyStatusRequest + * @return + */ + void updateStatus(Integer merchantId, DutyStatusRequest dutyStatusRequest) throws BusinessCheckException; + + /** + * 修改角色 + * + * @param tduty 角色信息 + * @param sources 菜单列表 + * @return + */ + void updateDuty(TDuty tduty, List sources) throws BusinessCheckException; + + /** + * 根据角色名称合状态查询角色 + * + * @param merchantId 商户ID + * @param name 角色名称 + * @return + */ + TDuty findByName(Integer merchantId, String name); + + /** + * 根据角色名称获取已经分配的菜单ID集合 + * + * @param dutyId 角色ID + * @return + */ + List getSourceIdsByDutyId(Integer dutyId); + + /** + * 获取角色的树形结构 + * + * @param merchantId 商户ID + * @return + */ + List getDutyTree(Integer merchantId); + + /** + * 根据账户获取角色 + * + * @param accountId 账号ID + * @return + */ + List findDutiesByAccountId(Integer accountId); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/GenCodeService.java b/fuint-application/src/main/java/com/fuint/common/service/GenCodeService.java new file mode 100644 index 0000000..77a1c2a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/GenCodeService.java @@ -0,0 +1,58 @@ +package com.fuint.common.service; + +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.TGenCode; + +/** + * 代码生成服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface GenCodeService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryGenCodeListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加生成代码 + * + * @param tGenCode 代码参数 + * @throws BusinessCheckException + * @return + */ + TGenCode addGenCode(TGenCode tGenCode) throws BusinessCheckException; + + /** + * 根据ID获取信息 + * + * @param id + * @throws BusinessCheckException + * @return + */ + TGenCode queryGenCodeById(Integer id) throws BusinessCheckException; + + /** + * 更新生成代码 + * @param tGenCode + * @throws BusinessCheckException + * @return + * */ + TGenCode updateGenCode(TGenCode tGenCode) throws BusinessCheckException; + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return + */ + void generatorCode(String tableName); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/GiveService.java b/fuint-application/src/main/java/com/fuint/common/service/GiveService.java new file mode 100644 index 0000000..05bf3dc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/GiveService.java @@ -0,0 +1,58 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.GiveDto; +import com.fuint.common.param.GiveParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtGive; +import com.fuint.repository.model.MtGiveItem; + +import java.util.List; +import java.util.Map; + +/** + * 转赠业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface GiveService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryGiveListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 转赠卡券 + * + * @param giveParam + * @throws BusinessCheckException + * @return + */ + ResponseObject addGive(GiveParam giveParam) throws BusinessCheckException; + + /** + * 根据组ID获取信息 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + MtGive queryGiveById(Long id) throws BusinessCheckException; + + /** + * 根据条件搜索转赠详情 + * + * @param params + * @throws BusinessCheckException + * @return + * */ + List queryItemByParams(Map params); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/GoodsService.java b/fuint-application/src/main/java/com/fuint/common/service/GoodsService.java new file mode 100644 index 0000000..6d56c74 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/GoodsService.java @@ -0,0 +1,175 @@ +package com.fuint.common.service; + +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.GoodsDto; +import com.fuint.common.dto.GoodsSpecValueDto; +import com.fuint.common.dto.GoodsTopDto; +import com.fuint.common.param.GoodsListParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtGoods; +import com.fuint.repository.model.MtGoodsSku; +import com.fuint.repository.model.MtGoodsSpec; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 商品业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface GoodsService { + + /** + * 分页查询商品列表 + * + * @param param + * @return + */ + PaginationResponse queryGoodsListByPagination(GoodsListParam param) throws BusinessCheckException; + + /** + * 保存商品 + * + * @param reqDto 商品信息 + * @param storeIds 分配店铺 + * @throws BusinessCheckException + * @return + */ + MtGoods saveGoods(MtGoods reqDto, String storeIds) throws BusinessCheckException; + + /** + * 更新商品状态 + * + * @param goodsId 商品ID + * @param status 状态 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + Boolean updateStatus(Integer goodsId, String status, String operator) throws BusinessCheckException; + + /** + * 根据ID获取商品信息 + * + * @param id 商品ID + * @throws BusinessCheckException + * @return + */ + MtGoods queryGoodsById(Integer id) throws BusinessCheckException; + + /** + * 根据编码获取商品信息 + * + * @param merchantId 商户ID + * @param goodsNo 商品编码 + * @throws BusinessCheckException + * @return + */ + MtGoods queryGoodsByGoodsNo(Integer merchantId, String goodsNo) throws BusinessCheckException; + + /** + * 根据条码获取sku信息 + * + * @param skuNo skuNo + * @throws BusinessCheckException + * @return + * */ + MtGoodsSku getSkuInfoBySkuNo(String skuNo) throws BusinessCheckException; + + /** + * 根据ID获取商品详情 + * + * @param id 商品ID + * @return + */ + GoodsDto getGoodsDetail(Integer id, boolean getDeleteSpec); + + /** + * 获取店铺的商品列表 + * + * @param storeId 店铺ID + * @param keyword 关键字 + * @param platform 平台 + * @param cateId 分类ID + * @param page 当前页码 + * @param pageSize 每页数量 + * @return + * */ + Map getStoreGoodsList(Integer storeId, String keyword, String platform, Integer cateId, Integer page, Integer pageSize) throws BusinessCheckException; + + /** + * 根据skuId获取规格列表 + * + * @param skuId + * @return + * */ + List getSpecListBySkuId(Integer skuId) throws BusinessCheckException; + + /** + * 获取规格详情 + * + * @param specId 规格ID + * @return + * */ + MtGoodsSpec getSpecDetail(Integer specId); + + /** + * 更新已售数量 + * + * @param goodsId 商品ID + * @param saleNum 销售数量 + * @return + * */ + Boolean updateInitSale(Integer goodsId, Double saleNum); + + /** + * 获取选择商品列表 + * + * @param params 查询参数 + * @return + */ + PaginationResponse selectGoodsList(Map params) throws BusinessCheckException; + + /** + * 获取商品销售排行榜 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + List getGoodsSaleTopList(Integer merchantId, Integer storeId, Date startTime, Date endTime); + + /** + * 获取商品分配的店铺 + * + * @param goodsId 商品ID + * @return + * */ + String getStoreIds(Integer goodsId); + + /** + * 导入商品 + * + * @param file excel文件 + * @param accountInfo 操作者 + * @param filePath 文件地址 + * */ + Boolean importGoods(MultipartFile file, AccountInfo accountInfo, String filePath) throws BusinessCheckException; + + /** + * 获取规格ID + * + * @param goodsId 商品ID + * @param specName 规格名称 + * @param specValue 规格值 + * */ + Integer getSpecId(Integer goodsId, String specName, String specValue); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/InvoiceService.java b/fuint-application/src/main/java/com/fuint/common/service/InvoiceService.java new file mode 100644 index 0000000..92d2fd8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/InvoiceService.java @@ -0,0 +1,88 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.param.InvoiceParam; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtInvoice; +import com.fuint.framework.exception.BusinessCheckException; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 发票业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface InvoiceService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryInvoiceListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加发票 + * + * @param invoice + * @throws BusinessCheckException + * @return + */ + MtInvoice addInvoice(InvoiceParam invoice) throws BusinessCheckException; + + /** + * 根据ID获取发票信息 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + MtInvoice queryInvoiceById(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除发票 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteInvoice(Integer id, String operator) throws BusinessCheckException; + + /** + * 更新发票信息 + * + * @param invoice + * @throws BusinessCheckException + * @return + * */ + MtInvoice updateInvoice(InvoiceParam invoice) throws BusinessCheckException; + + /** + * 根据条件搜索发票 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryInvoiceListByParams(Map params) throws BusinessCheckException; + + /** + * 获取开票金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + */ + BigDecimal getInvoiceTotalAmount(Integer merchantId, Integer storeId, Date beginTime, Date endTime); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/MemberGroupService.java b/fuint-application/src/main/java/com/fuint/common/service/MemberGroupService.java new file mode 100644 index 0000000..6872adf --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/MemberGroupService.java @@ -0,0 +1,59 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.MemberGroupDto; +import com.fuint.common.dto.UserGroupDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtUserGroup; + +/** + * 会员分组业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MemberGroupService extends IService { + + /** + * 分页查询分组列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryMemberGroupListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 新增会员分组 + * + * @param memberGroupDto + * @throws BusinessCheckException + */ + MtUserGroup addMemberGroup(MemberGroupDto memberGroupDto) throws BusinessCheckException; + + /** + * 修改卡券分组 + * + * @param memberGroupDto + * @throws BusinessCheckException + */ + MtUserGroup updateMemberGroup(MemberGroupDto memberGroupDto) throws BusinessCheckException; + + /** + * 根据组ID获取分组信息 + * + * @param id 分组ID + * @throws BusinessCheckException + */ + MtUserGroup queryMemberGroupById(Integer id) throws BusinessCheckException; + + /** + * 根据分组ID删除分组信息 + * + * @param id 分组ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + void deleteMemberGroup(Integer id, String operator) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/MemberService.java b/fuint-application/src/main/java/com/fuint/common/service/MemberService.java new file mode 100644 index 0000000..277852b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/MemberService.java @@ -0,0 +1,276 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.alibaba.fastjson.JSONObject; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.GroupMemberDto; +import com.fuint.common.dto.MemberTopDto; +import com.fuint.common.dto.UserDto; +import com.fuint.common.param.MemberPage; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtUser; +import com.fuint.repository.model.MtUserGrade; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.text.ParseException; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 会员服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MemberService extends IService { + + /** + * 更新活跃时间 + * + * @param userId 会员ID + * @param ip IP地址 + * @return + * */ + Boolean updateActiveTime(Integer userId, String ip) throws BusinessCheckException; + + /** + * 获取当前操作会员信息 + * + * @param userId 会员ID + * @param accessToken + * @return + * */ + MtUser getCurrentUserInfo(HttpServletRequest request, Integer userId, String accessToken) throws BusinessCheckException; + + /** + * 分页查询会员列表 + * + * @param memberPage + * @return + */ + PaginationResponse queryMemberListByPagination(MemberPage memberPage) throws BusinessCheckException; + + /** + * 添加会员 + * + * @param memberInfo 会员信息 + * @param shareId 分享用户ID + * @throws BusinessCheckException + * @return + */ + MtUser addMember(MtUser memberInfo, String shareId) throws BusinessCheckException; + + /** + * 编辑会员 + * + * @param reqUserDto 会员信息 + * @param modifyPassword 修改密码 + * @throws BusinessCheckException + * @return + */ + MtUser updateMember(MtUser reqUserDto, boolean modifyPassword) throws BusinessCheckException; + + /** + * 通过手机号添加会员 + * + * @param merchantId 商户ID + * @param mobile 手机号 + * @param shareId 分享用户ID + * @param ip IP地址 + * @throws BusinessCheckException + * @return + */ + MtUser addMemberByMobile(Integer merchantId, String mobile, String shareId, String ip) throws BusinessCheckException; + + /** + * 根据会员ID获取会员信息 + * + * @param id 会员ID + * @throws BusinessCheckException + * @return + */ + MtUser queryMemberById(Integer id) throws BusinessCheckException; + + /** + * 根据会员名称获取会员信息 + * + * @param merchantId 商户ID + * @param name 会员名称 + * @throws BusinessCheckException + * @return + */ + MtUser queryMemberByName(Integer merchantId, String name) throws BusinessCheckException; + + /** + * 根据会员ID获取会员信息 + * + * @param merchantId 商户ID + * @param openId 微信openId + * @throws BusinessCheckException + * @return + */ + MtUser queryMemberByOpenId(Integer merchantId, String openId, JSONObject userInfo) throws BusinessCheckException; + + /** + * 根据会员组ID获取会员组信息 + * + * @param id 会员组ID + * @throws BusinessCheckException + * @return + */ + MtUserGrade queryMemberGradeByGradeId(Integer id) throws BusinessCheckException; + + /** + * 根据会员手机获取会员信息 + * + * @param merchantId 商户ID + * @param mobile 会员手机 + * @throws BusinessCheckException + * @return + */ + MtUser queryMemberByMobile(Integer merchantId, String mobile) throws BusinessCheckException; + + /** + * 根据会员号获取会员信息 + * + * @param merchantId 商户ID + * @param userNo 会员号 + * @throws BusinessCheckException + * @return + */ + MtUser queryMemberByUserNo(Integer merchantId, String userNo) throws BusinessCheckException; + + /** + * 根据会员ID删除会员信息 + * + * @param id 会员ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + Integer deleteMember(Integer id, String operator) throws BusinessCheckException; + + /** + * 根据条件搜索会员分组 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryMemberGradeByParams(Map params) throws BusinessCheckException; + + /** + * 获取会员数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + Long getUserCount(Integer merchantId, Integer storeId) throws BusinessCheckException; + + /** + * 获取会员数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @throws BusinessCheckException + * @return + * */ + Long getUserCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) throws BusinessCheckException; + + /** + * 获取活跃会员数量 + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @throws BusinessCheckException + * @return + * */ + Long getActiveUserCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) throws BusinessCheckException; + + /** + * 重置手机号 + * + * @param mobile 手机号码 + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + void resetMobile(String mobile, Integer userId) throws BusinessCheckException; + + /** + * 获取会员消费排行榜 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + List getMemberConsumeTopList(Integer merchantId, Integer storeId, Date startTime, Date endTime); + + /** + * 查找会员列表 + * + * @param merchantId 商户ID + * @param keyword 关键字 + * @param groupIds 分组ID + * @param page 当前页码 + * @param pageSize 每页数量 + * @return + * */ + List searchMembers(Integer merchantId, String keyword, String groupIds, Integer page, Integer pageSize); + + /** + * 查找会员列表 + * + * @param merchantId 商户ID + * @param keyword 关键字 + * @return + * */ + List searchMembers(Integer merchantId, String keyword); + + /** + * 设定安全的密码 + * + * @param password 密码(明文) + * @param salt 随机因子 + * @return + */ + String enCodePassword(String password, String salt); + + /** + * 获取加密密码 + * + * @param password 密码(密文) + * @param salt 随机因子 + * @return + * */ + String deCodePassword(String password, String salt); + + /** + * 获取会员ID列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + List getUserIdList(Integer merchantId, Integer storeId); + + /** + * 导入会员 + * + * @param file excel文件 + * @param accountInfo 操作者 + * @param filePath 文件地址 + * */ + Boolean importMember(MultipartFile file, AccountInfo accountInfo, String filePath) throws BusinessCheckException, ParseException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/MerchantService.java b/fuint-application/src/main/java/com/fuint/common/service/MerchantService.java new file mode 100644 index 0000000..2c6077e --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/MerchantService.java @@ -0,0 +1,119 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.MerchantDto; +import com.fuint.common.dto.MerchantSettingDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.merchantApi.request.MerchantSettingParam; +import com.fuint.repository.model.MtMerchant; +import java.util.List; +import java.util.Map; + +/** + * 商户业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MerchantService extends IService { + + /** + * 分页查询商户列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryMerchantListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 保存商户信息 + * + * @param mtMerchant + * @throws BusinessCheckException + * @return + */ + MtMerchant saveMerchant(MtMerchant mtMerchant) throws BusinessCheckException; + + /** + * 根据ID获取商户信息 + * + * @param id 商户ID + * @throws BusinessCheckException + * @return + */ + MtMerchant queryMerchantById(Integer id) throws BusinessCheckException; + + /** + * 根据名称获取商户信息 + * + * @param name 商户名称 + * @throws BusinessCheckException + * @return + */ + MtMerchant queryMerchantByName(String name) throws BusinessCheckException; + + /** + * 根据商户号获取商户信息 + * + * @param merchantNo 商户号 + * @return + */ + MtMerchant queryMerchantByNo(String merchantNo); + + /** + * 根据商户号获取商户ID + * + * @param merchantNo 商户号 + * @return + */ + Integer getMerchantId(String merchantNo); + + /** + * 更新商户状态 + * + * @param id 商户ID + * @param operator 操作人 + * @param status 状态 + * @throws BusinessCheckException + * @return + */ + void updateStatus(Integer id, String operator, String status) throws BusinessCheckException; + + /** + * 根据条件查询商户 + * + * @param params 查询参数 + * @return + * */ + List queryMerchantByParams(Map params) throws BusinessCheckException; + + /** + * 查询我的商户列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + List getMyMerchantList(Integer merchantId, Integer storeId, String status) throws BusinessCheckException; + + /** + * 获取商户信息 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + MerchantSettingDto getMerchantSettingInfo(Integer merchantId, Integer storeId) throws BusinessCheckException; + + /** + * 保存商户设置信息 + * + * @param params 商户设置项 + * @return + * */ + MerchantSettingDto saveMerchantSetting(MerchantSettingParam params) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/MessageService.java b/fuint-application/src/main/java/com/fuint/common/service/MessageService.java new file mode 100644 index 0000000..fb7ac5c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/MessageService.java @@ -0,0 +1,58 @@ +package com.fuint.common.service; + +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.MtMessage; +import java.util.List; + +/** + * 消息业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MessageService { + + /** + * 添加消息 + * + * @param reqMsgDto + * @throws BusinessCheckException + * @return + */ + void addMessage(MtMessage reqMsgDto) throws BusinessCheckException; + + /** + * 置为已读 + * + * @param msgId + * @throws BusinessCheckException + * @return + */ + void readMessage(Integer msgId) throws BusinessCheckException; + + /** + * 置为发送 + * + * @param msgId + * @throws BusinessCheckException + * @return + */ + void sendMessage(Integer msgId, boolean isRead) throws BusinessCheckException; + + /** + * 获取最新一条未读消息 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + MtMessage getOne(Integer userId) throws BusinessCheckException; + + /** + * 获取需要发送的消息 + * + * @throws BusinessCheckException + * @return + * */ + List getNeedSendList() throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/OpenGiftService.java b/fuint-application/src/main/java/com/fuint/common/service/OpenGiftService.java new file mode 100644 index 0000000..56ee934 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/OpenGiftService.java @@ -0,0 +1,73 @@ +package com.fuint.common.service; + +import com.fuint.common.dto.OpenGiftDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtOpenGift; +import java.util.Map; + +/** + * 开卡赠礼接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface OpenGiftService { + + /** + * 获取用户的开卡赠礼 + * + * @param paramMap 查询参数 + * @throws BusinessCheckException + * @return + * */ + ResponseObject getOpenGiftList(Map paramMap) throws BusinessCheckException; + + /** + * 新增开卡赠礼 + * + * @param reqDto + * @throws BusinessCheckException + * @return + */ + MtOpenGift addOpenGift(MtOpenGift reqDto) throws BusinessCheckException; + + /** + * 根据ID获取开卡赠礼 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + OpenGiftDto getOpenGiftDetail(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除开卡赠礼 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteOpenGift(Integer id, String operator) throws BusinessCheckException; + + /** + * 更新开卡赠礼 + * + * @param reqDto + * @throws BusinessCheckException + * @return + * */ + MtOpenGift updateOpenGift(MtOpenGift reqDto) throws BusinessCheckException; + + /** + * 开卡赠礼 + * + * @param userId 会员ID + * @param gradeId 会员等级 + * @param isNewMember 是否新会员 + * @throws BusinessCheckException + * @return + * */ + Boolean openGift(Integer userId, Integer gradeId, boolean isNewMember) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/OrderService.java b/fuint-application/src/main/java/com/fuint/common/service/OrderService.java new file mode 100644 index 0000000..af7888f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/OrderService.java @@ -0,0 +1,259 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.dto.OrderDto; +import com.fuint.common.param.OrderListParam; +import com.fuint.common.param.RechargeParam; +import com.fuint.common.param.SettlementParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtCart; +import com.fuint.repository.model.MtOrder; +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 订单业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface OrderService extends IService { + + /** + * 获取用户的订单 + * + * @param orderListParam + * @throws BusinessCheckException + * @return + * */ + PaginationResponse getUserOrderList(OrderListParam orderListParam) throws BusinessCheckException; + + /** + * 创建订单 + * + * @param orderDto + * @throws BusinessCheckException + * @return + */ + MtOrder saveOrder(OrderDto orderDto) throws BusinessCheckException; + + /** + * 订单提交结算 + * + * @param request 请求参数 + * @param settlementParam 结算参数 + * @throws BusinessCheckException + * @return + * */ + Map doSettle(HttpServletRequest request, SettlementParam settlementParam) throws BusinessCheckException; + + /** + * 获取订单详情 + * + * @param id 订单ID + * @throws BusinessCheckException + * @return + */ + MtOrder getOrderInfo(Integer id) throws BusinessCheckException; + + /** + * 根据ID获取订单 + * + * @param id 订单ID + * @throws BusinessCheckException + * @return + */ + UserOrderDto getOrderById(Integer id) throws BusinessCheckException; + + /** + * 根据ID获取订单 + * + * @param id + * @throws BusinessCheckException + * @return + */ + UserOrderDto getMyOrderById(Integer id) throws BusinessCheckException; + + /** + * 取消订单 + * + * @param orderId 订单ID + * @param remark 取消备注 + * @throws BusinessCheckException + * @return + * */ + MtOrder cancelOrder(Integer orderId, String remark) throws BusinessCheckException; + + /** + * 根据订单ID删除 + * + * @param orderId 订单ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteOrder(Integer orderId, String operator) throws BusinessCheckException; + + /** + * 根据订单号获取订单 + * + * @param orderSn + * @throws BusinessCheckException + * @return + */ + UserOrderDto getOrderByOrderSn(String orderSn) throws BusinessCheckException; + + /** + * 根据订单号获取订单 + * + * @param orderSn 订单号 + * @return + * */ + MtOrder getOrderInfoByOrderSn(String orderSn); + + /** + * 更新订单 + * + * @param reqDto + * @throws BusinessCheckException + * @return + * */ + MtOrder updateOrder(OrderDto reqDto) throws BusinessCheckException; + + /** + * 更新订单 + * + * @param mtOrder + * @throws BusinessCheckException + * @return + * */ + MtOrder updateOrder(MtOrder mtOrder) throws BusinessCheckException; + + /** + * 把订单置为已支付 + * + * @param orderId + * @param payAmount + * @throws BusinessCheckException + * @return + * */ + Boolean setOrderPayed(Integer orderId, BigDecimal payAmount) throws BusinessCheckException; + + /** + * 根据条件搜索订单 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List getOrderListByParams(Map params) throws BusinessCheckException; + + /** + * 获取订单总数 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + BigDecimal getOrderCount(Integer merchantId, Integer storeId) throws BusinessCheckException; + + /** + * 获取订单数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @throws BusinessCheckException + * @return + * */ + BigDecimal getOrderCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) throws BusinessCheckException; + + /** + * 计算购物车 + * + * @param merchantId 商户ID + * @param userId 会员ID + * @param cartList 购物车列表 + * @param couponId 使用的卡券ID + * @param isUsePoint 是否使用积分抵扣 + * @param platform 平台 h5 + * @param orderMode 订单模式,自取或配送 + * @throws BusinessCheckException + * @return + * */ + Map calculateCartGoods(Integer merchantId, Integer userId, List cartList, Integer couponId, boolean isUsePoint, String platform, String orderMode) throws BusinessCheckException; + + /** + * 获取支付金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @throws BusinessCheckException + * @return + * */ + BigDecimal getPayMoney(Integer merchantId, Integer storeId, Date beginTime, Date endTime) throws BusinessCheckException; + + /** + * 获取支付人数 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + Integer getPayUserCount(Integer merchantId, Integer storeId) throws BusinessCheckException; + + /** + * 获取支付金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + BigDecimal getPayMoney(Integer merchantId, Integer storeId) throws BusinessCheckException; + + /** + * 获取会员支付金额 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + * */ + BigDecimal getUserPayMoney(Integer userId) throws BusinessCheckException; + + /** + * 获取会员订单数 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + * */ + Integer getUserPayOrderCount(Integer userId) throws BusinessCheckException; + + /** + * 获取等待分佣的订单列表 + * + * @param dateTime 时间 + * @throws BusinessCheckException + * @return + * */ + List getTobeCommissionOrderList(String dateTime) throws BusinessCheckException; + + /** + * 提交充值订单 + * + * @param rechargeParam 充值参数 + * @return + * */ + MtOrder doRecharge(HttpServletRequest request, RechargeParam rechargeParam) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/PaymentService.java b/fuint-application/src/main/java/com/fuint/common/service/PaymentService.java new file mode 100644 index 0000000..635187c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/PaymentService.java @@ -0,0 +1,50 @@ +package com.fuint.common.service; + +import com.fuint.common.dto.UserOrderDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 支付相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface PaymentService { + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @param isWechat 是否微信客户端 + * @return + * */ + ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform, String isWechat) throws BusinessCheckException; + + /** + * 支付成功回调 + * + * @param orderInfo 订单信息 + * @return + * */ + Boolean paymentCallback(UserOrderDto orderInfo) throws BusinessCheckException; + + /** + * 订单支付 + * + * @param request 请求参数 + * @return + * */ + Map doPay(HttpServletRequest request) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/PointService.java b/fuint-application/src/main/java/com/fuint/common/service/PointService.java new file mode 100644 index 0000000..250a61c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/PointService.java @@ -0,0 +1,46 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.PointDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtPoint; + +/** + * 积分业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface PointService extends IService { + + /** + * 分页查询积分列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryPointListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加积分 + * + * @param reqPointDto + * @throws BusinessCheckException + * @return + */ + void addPoint(MtPoint reqPointDto) throws BusinessCheckException; + + /** + * 转赠积分 + * + * @param userId + * @param mobile + * @param amount + * @param remark + * @throws BusinessCheckException + * @return + */ + boolean doGift(Integer userId, String mobile, Integer amount, String remark) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/PrinterService.java b/fuint-application/src/main/java/com/fuint/common/service/PrinterService.java new file mode 100644 index 0000000..b79dede --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/PrinterService.java @@ -0,0 +1,81 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.param.PrinterPage; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtPrinter; +import com.fuint.framework.exception.BusinessCheckException; +import java.util.List; +import java.util.Map; + +/** + * 打印机业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface PrinterService extends IService { + + /** + * 分页查询列表 + * + * @param printerPage + * @return + */ + PaginationResponse queryPrinterListByPagination(PrinterPage printerPage) throws BusinessCheckException; + + /** + * 添加打印机 + * + * @param mtPrinter + * @throws BusinessCheckException + * @return + */ + MtPrinter addPrinter(MtPrinter mtPrinter) throws BusinessCheckException; + + /** + * 打印订单 + * + * @param orderInfo 订单信息 + * @param autoPrint 自动打印 + * @return + * */ + Boolean printOrder(UserOrderDto orderInfo, boolean autoPrint) throws Exception; + + /** + * 根据ID获取打印机信息 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + MtPrinter queryPrinterById(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除打印机 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deletePrinter(Integer id, String operator) throws BusinessCheckException; + + /** + * 更新打印机 + * @param mtPrinter + * @throws BusinessCheckException + * @return + * */ + MtPrinter updatePrinter(MtPrinter mtPrinter) throws BusinessCheckException; + + /** + * 根据条件搜索打印机 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + List queryPrinterListByParams(Map params) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/RefundService.java b/fuint-application/src/main/java/com/fuint/common/service/RefundService.java new file mode 100644 index 0000000..07b08ce --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/RefundService.java @@ -0,0 +1,94 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.RefundDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtRefund; +import java.util.Date; +import java.util.Map; + +/** + * 售后业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface RefundService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse getRefundListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 获取用户的售后订单 + * @param paramMap 查询参数 + * @throws BusinessCheckException + * */ + ResponseObject getUserRefundList(Map paramMap) throws BusinessCheckException; + + /** + * 创建售后订单 + * + * @param reqDto + * @throws BusinessCheckException + */ + MtRefund createRefund(RefundDto reqDto) throws BusinessCheckException; + + /** + * 根据ID获取售后订单信息 + * + * @param id ID + * @throws BusinessCheckException + */ + RefundDto getRefundById(Integer id) throws BusinessCheckException; + + /** + * 根据订单ID获取售后订单信息 + * + * @param orderId + * @throws BusinessCheckException + */ + MtRefund getRefundByOrderId(Integer orderId) throws BusinessCheckException; + + /** + * 更新售后订单 + * @param reqDto + * @throws BusinessCheckException + * */ + MtRefund updateRefund(RefundDto reqDto) throws BusinessCheckException; + + /** + * 同意售后订单 + * @param reqDto + * @throws BusinessCheckException + * */ + MtRefund agreeRefund(RefundDto reqDto) throws BusinessCheckException; + + /** + * 发起退款 + * + * @param orderId 订单号 + * @param refundAmount 退款金额 + * @param remark 备注 + * @param accountInfo 操作人信息 + * throws BusinessCheckException; + * */ + Boolean doRefund(Integer orderId, String refundAmount, String remark, AccountInfo accountInfo) throws BusinessCheckException; + + /** + * 获取售后订单总数 + * + * @param beginTime + * @param endTime + * @return + * */ + Long getRefundCount(Date beginTime, Date endTime) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/SendLogService.java b/fuint-application/src/main/java/com/fuint/common/service/SendLogService.java new file mode 100644 index 0000000..061ee36 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SendLogService.java @@ -0,0 +1,51 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.ReqSendLogDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtSendLog; + +/** + * 发券记录业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SendLogService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse querySendLogListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加记录 + * + * @param reqSendLogDto + * @throws BusinessCheckException + */ + MtSendLog addSendLog(ReqSendLogDto reqSendLogDto) throws BusinessCheckException; + + /** + * 根据组ID获取发券记录 + * + * @param id ID + * @throws BusinessCheckException + */ + MtSendLog querySendLogById(Long id) throws BusinessCheckException; + + /** + * 删除发券记录 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + void deleteSendLog(Long id, String operator) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/SendSmsService.java b/fuint-application/src/main/java/com/fuint/common/service/SendSmsService.java new file mode 100644 index 0000000..992c765 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SendSmsService.java @@ -0,0 +1,37 @@ +package com.fuint.common.service; + +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtSmsSendedLog; +import java.util.List; +import java.util.Map; + +/** + * 发送短信接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SendSmsService { + + /** + * 发送短信方法 + * + * @param merchantId 商户ID + * @param tUname 短信模板英文名称 + * @param phones 手机号码集合 + * @return Map> TRUE:推送成功的手机号码集合; + * FALSE:推送失败的手机号码集合 + * @throws Exception + */ + Map> sendSms(Integer merchantId, String tUname, List phones, Map contentParams) throws BusinessCheckException; + + /** + * 分页已发短信列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse querySmsListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/SettingService.java b/fuint-application/src/main/java/com/fuint/common/service/SettingService.java new file mode 100644 index 0000000..e978504 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SettingService.java @@ -0,0 +1,94 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fuint.common.dto.NavigationDto; +import com.fuint.common.dto.ParamDto; +import com.fuint.repository.model.MtSetting; +import com.fuint.framework.exception.BusinessCheckException; +import java.util.List; + +/** + * 配置业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SettingService extends IService { + + /** + * 删除配置 + * + * @param merchantId 商户ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + */ + void removeSetting(Integer merchantId, String type, String name) throws BusinessCheckException; + + /** + * 保存配置 + * + * @param mtSetting + * @throws BusinessCheckException + */ + MtSetting saveSetting(MtSetting mtSetting) throws BusinessCheckException; + + /** + * 获取配置列表 + * + * @param type 类型 + * @throws BusinessCheckException + * @return + */ + List getSettingList(Integer merchantId, String type) throws BusinessCheckException; + + /** + * 根据配置名称获取配置信息 + * + * @param merchantId 商户ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + */ + MtSetting querySettingByName(Integer merchantId, String type, String name) throws BusinessCheckException; + + /** + * 根据配置名称获取配置信息 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + */ + MtSetting querySettingByName(Integer merchantId, Integer storeId, String type, String name) throws BusinessCheckException; + + /** + * 获取系统上传文件的根路径 + * + * @return 本地配置或阿里云的oss域名 + * */ + String getUploadBasePath(); + + /** + * 获取支付方式列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param platform 平台 + * @return + * */ + List getPayTypeList(Integer merchantId, Integer storeId, String platform) throws BusinessCheckException; + + /** + * 获取导航栏 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + List getNavigation(Integer merchantId, Integer storeId, String status) throws JsonProcessingException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/SettlementService.java b/fuint-application/src/main/java/com/fuint/common/service/SettlementService.java new file mode 100644 index 0000000..a68925a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SettlementService.java @@ -0,0 +1,54 @@ +package com.fuint.common.service; + +import com.fuint.common.dto.SettlementDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.SettlementRequest; +import com.fuint.repository.model.MtSettlement; + +/** + * 订单结算相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SettlementService { + + /** + * 分页查询结算列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse querySettlementListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 提交结算 + * + * @param requestParam + * @throws BusinessCheckException + * @return + */ + Boolean submitSettlement(SettlementRequest requestParam) throws BusinessCheckException; + + /** + * 结算确认 + * + * @param settlementId + * @param operator + * @throws BusinessCheckException + * @return + */ + Boolean doConfirm(Integer settlementId, String operator) throws BusinessCheckException; + + /** + * 获取结算详情 + * + * @param settlementId + * @param page + * @param pageSize + * @return + * */ + SettlementDto getSettlementInfo(Integer settlementId, Integer page, Integer pageSize) throws BusinessCheckException; +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/service/SmsTemplateService.java b/fuint-application/src/main/java/com/fuint/common/service/SmsTemplateService.java new file mode 100644 index 0000000..75000f6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SmsTemplateService.java @@ -0,0 +1,58 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.SmsTemplateDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtSmsTemplate; + +import java.util.List; +import java.util.Map; + +/** + * 短信模板业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SmsTemplateService extends IService { + + /** + * 分页查询模板列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse querySmsTemplateListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加模板 + * + * @param reqSmsTemplateDto + * @throws BusinessCheckException + */ + MtSmsTemplate saveSmsTemplate(SmsTemplateDto reqSmsTemplateDto) throws BusinessCheckException; + + /** + * 删除短信模板 + * @param id + * @param operator + * @return + * */ + void deleteTemplate(Integer id, String operator) throws BusinessCheckException; + + /** + * 根据模板ID获取模板信息 + * + * @param id ID + * @throws BusinessCheckException + */ + MtSmsTemplate querySmsTemplateById(Integer id) throws BusinessCheckException; + + /** + * 根据条件搜索模板 + * */ + List querySmsTemplateByParams(Map params) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/SourceService.java b/fuint-application/src/main/java/com/fuint/common/service/SourceService.java new file mode 100644 index 0000000..05963b0 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/SourceService.java @@ -0,0 +1,103 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.domain.TreeSelect; +import com.fuint.common.vo.RouterVo; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.common.domain.TreeNode; +import com.fuint.repository.model.TSource; +import java.util.List; + +/** + * 菜单管理业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface SourceService extends IService { + + /** + * 获取有效的菜单集合 + * + * @param merchantId 商户ID + * @param status + * @return + */ + List getAvailableSources(Integer merchantId, String status); + + /** + * 获取菜单的属性结构 + * + * @param merchantId 商户ID + * @param status 状态 + * @return + */ + List getSourceTree(Integer merchantId, String status); + + /** + * 根据菜单ID集合查询菜单列表信息 + * + * @param ids + * @return + */ + List findDatasByIds(String[] ids); + + /** + * 根据会员ID获取菜单 + * + * @param merchantId 商户ID + * @param accountId 账号ID + * @throws BusinessCheckException + * @return + */ + List getMenuListByUserId(Integer merchantId, Integer accountId) throws BusinessCheckException; + + /** + * 构建前端路由所需要的菜单 + * + * @param treeNodes 菜单列表 + * @return 路由列表 + */ + List buildMenus(List treeNodes); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + List buildMenuTreeSelect(List menus); + + /** + * 新增后台菜单 + * + * @param tSource + * @param accountId + * @return + */ + void addSource(TSource tSource, Integer accountId); + + /** + * 修改后台菜单 + * + * @param source + * */ + void editSource(TSource source); + + /** + * 删除菜单 + * + * @param source + * @param status + * @return + * */ + void deleteSource(TSource source, String status); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/StaffService.java b/fuint-application/src/main/java/com/fuint/common/service/StaffService.java new file mode 100644 index 0000000..75f29e5 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/StaffService.java @@ -0,0 +1,91 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.StaffDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtStaff; +import java.util.List; +import java.util.Map; + +/** + * 店铺员工业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface StaffService extends IService { + + /** + * 员工查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryStaffListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 保存员工信息 + * + * @param reqStaff 员工信息 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + MtStaff saveStaff(MtStaff reqStaff, String operator) throws BusinessCheckException; + + /** + * 根据ID获取店铺信息 + * + * @param id 员工id + * @throws BusinessCheckException + */ + MtStaff queryStaffById(Integer id) throws BusinessCheckException; + + /** + * 审核更改状态(禁用,审核通过) + * + * @param staffId 员工ID + * @param status 状态 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + Integer updateAuditedStatus(Integer staffId, String status, String operator) throws BusinessCheckException; + + /** + * 根据条件搜索员工 + * + * @param params 请求参数 + * @return + * */ + List queryStaffByParams(Map params) throws BusinessCheckException; + + /** + * 根据手机号获取员工信息 + * + * @param mobile 手机 + * @throws BusinessCheckException + * @return + */ + MtStaff queryStaffByMobile(String mobile) throws BusinessCheckException; + + /** + * 根据会员ID获取员工信息 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + MtStaff queryStaffByUserId(Integer userId) throws BusinessCheckException; + + /** + * 根据手机号获取员工信息 + * + * @param mobile 手机 + * @throws BusinessCheckException + * @return + */ + StaffDto getStaffInfoByMobile(String mobile) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/StockService.java b/fuint-application/src/main/java/com/fuint/common/service/StockService.java new file mode 100644 index 0000000..1b1184f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/StockService.java @@ -0,0 +1,79 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.StockGoodsDto; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtStock; +import com.fuint.repository.model.MtStockItem; +import java.util.List; +import java.util.Map; + +/** + * 库存业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface StockService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryStockListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 新增库存管理记录 + * + * @param mtStock + * @param goodsList + * @throws BusinessCheckException + */ + ResponseObject addStock(MtStock mtStock, List goodsList) throws BusinessCheckException; + + /** + * 删除库存管理记录 + * + * @param id + * @param operator + * @return + * */ + void delete(Integer id, String operator) throws BusinessCheckException; + + /** + * 根据ID获取信息 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + MtStock queryStockById(Long id) throws BusinessCheckException; + + /** + * 根据条件搜索详情 + * + * @param params + * @throws BusinessCheckException + * @return + * */ + List queryItemByParams(Map params) throws BusinessCheckException; + + /** + * 生成出入库记录 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param goodsId 商品ID + * @param skuId 商品SKU ID + * @param type 类型,increase:入库,reduce:出库 + * @param num 数量 + * @param description 说明 + * @return + * */ + Boolean addStockRecord(Integer merchantId, Integer storeId, Integer goodsId, Integer skuId, String type, Double num, String description); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/StoreService.java b/fuint-application/src/main/java/com/fuint/common/service/StoreService.java new file mode 100644 index 0000000..26f4471 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/StoreService.java @@ -0,0 +1,152 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.StoreDto; +import com.fuint.common.dto.StoreInfo; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtStore; +import java.util.List; +import java.util.Map; + +/** + * 店铺业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface StoreService extends IService { + + /** + * 分页查询店铺列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryStoreListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 保存店铺信息 + * + * @param reqStoreDto + * @throws BusinessCheckException + */ + MtStore saveStore(StoreDto reqStoreDto) throws BusinessCheckException; + + /** + * 获取系统默认店铺 + * + * @throws BusinessCheckException + * @return + */ + MtStore getDefaultStore(String merchantNo) throws BusinessCheckException; + + /** + * 根据店铺ID获取店铺信息 + * + * @param id 店铺ID + * @throws BusinessCheckException + * @return + */ + MtStore queryStoreById(Integer id) throws BusinessCheckException; + + /** + * 根据店铺名称获取店铺信息 + * + * @param storeName 店铺名称 + * @throws BusinessCheckException + */ + StoreDto queryStoreByName(String storeName) throws BusinessCheckException; + + /** + * 根据店铺ID查询店铺信息 + * + * @param id 店铺ID + * @return + * @throws BusinessCheckException + */ + StoreDto queryStoreDtoById(Integer id) throws BusinessCheckException; + + /** + * 更新店铺状态 + * + * @param id 店铺ID + * @param operator 操作人 + * @param status 状态 + * @throws BusinessCheckException + */ + void updateStatus(Integer id, String operator, String status) throws BusinessCheckException; + + /** + * 根据条件查询店铺列表 + * + * @param params 查询参数 + * @return + * */ + List queryStoresByParams(Map params) throws BusinessCheckException; + + /** + * 获取我的店铺列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + List getMyStoreList(Integer merchantId, Integer storeId, String status) throws BusinessCheckException; + + /** + * 根据距离远近查找店铺 + * + * @param merchantNo 商户号 + * @param keyword 关键字 + * @param latitude 维度 + * @param longitude 经度 + * @return + * */ + List queryByDistance(String merchantNo, String keyword, String latitude, String longitude) throws BusinessCheckException; + + /** + * 获取店铺名称 + * + * @param storeIds 店铺ID + * @return + * */ + String getStoreNames(String storeIds); + + /** + * 获取店铺ID + * + * @param merchantId 商户ID + * @param storeNames 店铺名称 + * @return + * */ + String getStoreIds(Integer merchantId, String storeNames); + + /** + * 根据商户ID删除店铺信息 + * + * @param merchantId 商户ID + * @return + * */ + void deleteStoreByMerchant(Integer merchantId); + + /** + * 根据地址获取经纬度 + * + * @param addr 地址 + * @return + * */ + Map getLatAndLngByAddress(String addr); + + /** + * 获取步行距离 + * + * @param origin 起点经纬度 格式如:116.434446,39.90816 + * @param destination 终点经纬度 格式如:116.434307,39.90909 + * @return + * */ + Double getDistance(String origin, String destination); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/UnionPayService.java b/fuint-application/src/main/java/com/fuint/common/service/UnionPayService.java new file mode 100644 index 0000000..218e4e6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/UnionPayService.java @@ -0,0 +1,62 @@ +package com.fuint.common.service; + +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import java.math.BigDecimal; +import java.util.Map; + +/** + * 云闪付相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface UnionPayService { + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @return + * */ + ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform) throws BusinessCheckException; + + /** + * 支付回调 + * + * @param params 请求参数 + * @return + * */ + Boolean checkCallBack(Map params) throws Exception; + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param tradeNo 交易单号 + * @param orderSn 订单号 + * @return + * */ + Map queryPaidOrder(Integer storeId, String tradeNo, String orderSn) throws BusinessCheckException; + + /** + * 发起售后退款 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 订单总金额 + * @param refundAmount 售后金额 + * @param platform 订单平台 + * @return + * */ + Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/UploadService.java b/fuint-application/src/main/java/com/fuint/common/service/UploadService.java new file mode 100644 index 0000000..acdcc72 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/UploadService.java @@ -0,0 +1,23 @@ +package com.fuint.common.service; + +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; + +/** + * 文件上传服务类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface UploadService { + + /** + * 保存文件 + * + * @param request + * @param file excel文件 + * @return + * */ + String saveUploadFile(HttpServletRequest request, MultipartFile file) throws Exception; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/UserActionService.java b/fuint-application/src/main/java/com/fuint/common/service/UserActionService.java new file mode 100644 index 0000000..59d023a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/UserActionService.java @@ -0,0 +1,49 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtUserAction; + +/** + * 会员行为业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface UserActionService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryUserActionListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 新增会员行为 + * + * @param mtUserAction + * @throws BusinessCheckException + */ + boolean addUserAction(MtUserAction mtUserAction) throws BusinessCheckException; + + /** + * 根据ID获取会员行为详情 + * + * @param id ID + * @throws BusinessCheckException + */ + MtUserAction getUserActionDetail(Integer id) throws BusinessCheckException; + + /** + * 根据ID删除会员行为 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + void deleteUserAction(Integer id, String operator) throws BusinessCheckException; +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/UserCouponService.java b/fuint-application/src/main/java/com/fuint/common/service/UserCouponService.java new file mode 100644 index 0000000..6bea2b9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/UserCouponService.java @@ -0,0 +1,116 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.common.dto.CouponDto; +import com.fuint.common.param.CouponReceiveParam; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtUserCoupon; +import java.util.List; +import java.util.Map; + +/** + * 会员卡券业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface UserCouponService extends IService { + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryUserCouponListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 领取卡券 + * + * @param couponReceiveParam + * @return + * */ + boolean receiveCoupon(CouponReceiveParam couponReceiveParam) throws BusinessCheckException; + + /** + * 预存卡券 + * + * @param paramMap + * @return + * */ + boolean preStore(Map paramMap) throws BusinessCheckException; + + /** + * 获取会员卡券列表 + * @param userId + * @param status + * @return + * */ + List getUserCouponList(Integer userId, List status) throws BusinessCheckException; + + /** + * 获取用户的卡券 + * @param paramMap 查询参数 + * @throws BusinessCheckException + * */ + ResponseObject getUserCouponList(Map paramMap) throws BusinessCheckException; + + /** + * 获取会员可支付用的卡券 + * + * @param userId 会员ID + * @param storeId 使用门店 + * @param useFor 用途 + * @return + * */ + List getPayAbleCouponList(Integer userId, Integer storeId, String useFor) throws BusinessCheckException; + + /** + * 获取会员卡券详情 + * @param userId + * @param couponId + * */ + List getUserCouponDetail(Integer userId, Integer couponId) throws BusinessCheckException; + + /** + * 获取会员卡券详情 + * + * @param userCouponId + * @return + * */ + MtUserCoupon getUserCouponDetail(Integer userCouponId) throws BusinessCheckException; + + /** + * 根据过期时间查询会员卡券 + * + * @param userId + * @param status + * @param startTime + * @param endTime + * @return + * */ + List getUserCouponListByExpireTime(Integer userId, String status, String startTime, String endTime) throws BusinessCheckException; + + /** + * 给会员发送卡券(会员购买) + * + * @param orderId 订单ID + * @param couponId 卡券ID + * @param userId 会员ID + * @param mobile 会员手机号 + * @param num 购买数量 + * @return + * */ + boolean buyCouponItem(Integer orderId, Integer couponId, Integer userId, String mobile, Double num) throws BusinessCheckException; + + /** + * 通过卡券ID删除会员卡券 + * + * @param couponId 卡券ID + * @return + * */ + void removeUserCouponByCouponId(Integer couponId); +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/UserGradeService.java b/fuint-application/src/main/java/com/fuint/common/service/UserGradeService.java new file mode 100644 index 0000000..80ea0b9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/UserGradeService.java @@ -0,0 +1,94 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtUser; +import com.fuint.repository.model.MtUserGrade; +import java.util.List; + +/** + * 会员等级业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface UserGradeService extends IService { + + /** + * 分页查询会员等级列表 + * + * @param paginationRequest + * @return + */ + PaginationResponse queryUserGradeListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException; + + /** + * 添加会员等级 + * + * @param reqDto + * @throws BusinessCheckException + * @return + */ + MtUserGrade addUserGrade(MtUserGrade reqDto) throws BusinessCheckException; + + /** + * 修改会员等级 + * + * @param reqDto + * @throws BusinessCheckException + * @return + */ + MtUserGrade updateUserGrade(MtUserGrade reqDto) throws BusinessCheckException; + + /** + * 根据ID获取会员等级信息 + * + * @param merchantId + * @param gradeId ID + * @param userId + * @throws BusinessCheckException + * @return + */ + MtUserGrade queryUserGradeById(Integer merchantId, Integer gradeId, Integer userId) throws BusinessCheckException; + + /** + * 根据ID删除会员等级 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + Integer deleteUserGrade(Integer id, String operator) throws BusinessCheckException; + + /** + * 获取默认的会员等级 + * + * @param merchantId + * @throws BusinessCheckException + * @return + */ + MtUserGrade getInitUserGrade(Integer merchantId) throws BusinessCheckException; + + /** + * 获取付费会员等级列表 + * + * @param merchantId + * @param userInfo + * @throws BusinessCheckException + * @return + * */ + List getPayUserGradeList(Integer merchantId, MtUser userInfo) throws BusinessCheckException; + + /** + * 获取商户会员等级列表 + * + * @param merchantId 商户ID + * @param status 状态 + * @return + * */ + List getMerchantGradeList(Integer merchantId, String status); + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/VerifyCodeService.java b/fuint-application/src/main/java/com/fuint/common/service/VerifyCodeService.java new file mode 100644 index 0000000..5b01867 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/VerifyCodeService.java @@ -0,0 +1,45 @@ +package com.fuint.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.model.MtVerifyCode; + +/** + * 图形验证码接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface VerifyCodeService extends IService { + + /** + * 新增验证码 + * + * @param mobile 手机号 + * @param verifyCode 验证码 + * @param expireSecond 间隔秒数 + * @throws BusinessCheckException + * @return + */ + MtVerifyCode addVerifyCode(String mobile, String verifyCode, Integer expireSecond) throws BusinessCheckException; + + /** + * 根据手机号,验证码,查询时间 + * + * @param mobile 电话号码 + * @param verifyCode 验证码 + * @throws BusinessCheckException + * @return + */ + MtVerifyCode checkVerifyCode(String mobile, String verifyCode) throws BusinessCheckException; + + /** + * 更改验证码状态 + * + * @param id 验证码ID + * @param validFlag 是否验证 + * @throws BusinessCheckException + * @return + */ + MtVerifyCode updateValidFlag(Long id, String validFlag) throws BusinessCheckException; +} \ No newline at end of file diff --git a/fuint-application/src/main/java/com/fuint/common/service/WeixinService.java b/fuint-application/src/main/java/com/fuint/common/service/WeixinService.java new file mode 100644 index 0000000..bffea24 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/WeixinService.java @@ -0,0 +1,195 @@ +package com.fuint.common.service; + +import com.alibaba.fastjson.JSONObject; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.util.Map; +import java.util.Date; + +/** + * 微信相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface WeixinService { + + /** + * 获取微信登录token + * + * @param merchantId 商户ID + * @param isMinApp 是否小程序 + * @param useCache 是否从缓存中读取 + * @return + * */ + String getAccessToken(Integer merchantId, boolean isMinApp, boolean useCache) throws BusinessCheckException; + + /** + * 提交预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 支付二维码 + * @param giveAmount 赠送金额 + * @param ip 支付发起IP + * @param platform 支付平台 + * @param isWechat 是否微信客户端 + * @return + * */ + ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform, String isWechat) throws BusinessCheckException; + + /** + * 处理返回的xml数据 + * + * @param request 请求体 + * @return + * */ + Map processResXml(HttpServletRequest request); + + /** + * 处理返回的xml数据 + * + * @param response 返回相应 + * @param flag 标签 + * @return + * */ + void processRespXml(HttpServletResponse response, boolean flag); + + /** + * 获取微信个人信息 + * + * @param merchantId 商户ID + * @param code 登录编码 + * @return + * */ + JSONObject getWxProfile(Integer merchantId, String code) throws BusinessCheckException; + + /** + * 获取微信openId + * + * @param merchantId 商户ID + * @param code 登录编码 + * @return + * */ + JSONObject getWxOpenId(Integer merchantId, String code) throws BusinessCheckException; + + /** + * 获取会员微信绑定的手机号 + * + * @param encryptedData 加密的编码(前端返回) + * @param sessionKey + * @param iv + * @return + * */ + String getPhoneNumber(String encryptedData, String sessionKey, String iv); + + /** + * 发送订阅消息 + * + * @param merchantId 商户ID + * @param userId 会员ID + * @param toUserOpenId 会员openID + * @param key 消息编码 + * @param page 跳转页面 + * @param params 发送参数 + * @param sendTime 发送时间 + * @return + * */ + Boolean sendSubscribeMessage(Integer merchantId, Integer userId, String toUserOpenId, String key, String page, Map params, Date sendTime) throws BusinessCheckException; + + /** + * 发送订阅消息 + * + * @param merchantId 商户ID + * @param reqDataJsonStr 发送参数 + * @return + * */ + Boolean doSendSubscribeMessage(Integer merchantId, String reqDataJsonStr); + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param transactionId 交易单号 + * @param orderSn 订单号 + * @return + * */ + Map queryPaidOrder(Integer storeId, String transactionId, String orderSn); + + /** + * 发起售后 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 订单总金额 + * @param refundAmount 售后金额 + * @param platform 平台 + * @return + * */ + Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException; + + /** + * 生成二维码 + * + * @param merchantId 商户ID + * @param type 类型 + * @param id 数据ID + * @param page 页面 + * @param width 宽度 + * @return + * */ + String createQrCode(Integer merchantId, String type, Integer id, String page, Integer width) throws BusinessCheckException; + + /** + * 开通微信卡券 + * + * @param merchantId 商户ID + * @param wxCardId 微信会员卡ID + * @return + * */ + String createWxCard(Integer merchantId, String wxCardId) throws BusinessCheckException; + + /** + * 创建微信卡券领取的二维码 + * + * @param merchantId 商户ID + * @param cardId 微信卡券ID + * @param code 会员卡编码 + * @return + * */ + String createCardQrCode(Integer merchantId, String cardId, String code); + + /** + * 是否已领取卡券 + * + * @param merchantId 商户ID + * @param cardId 微信卡券ID + * @param openId openId + * @return + * */ + Boolean isOpenCard(Integer merchantId, String cardId, String openId); + + /** + * 生成小程序链接 + * + * @param merchantId 商户ID + * @param path 页面路径 + * @return + * */ + String createMiniAppLink(Integer merchantId, String path); + + /** + * 上传小程序发货信息 + * + * @param orderSn 订单号 + * @return + */ + void uploadShippingInfo(String orderSn) throws BusinessCheckException; + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/AccountServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/AccountServiceImpl.java new file mode 100644 index 0000000..ac1a8be --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/AccountServiceImpl.java @@ -0,0 +1,416 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.AccountDto; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.AccountService; +import com.fuint.common.service.CaptchaService; +import com.fuint.common.service.StaffService; +import com.fuint.common.service.StoreService; +import com.fuint.common.util.TokenUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.exception.BusinessRuntimeException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.LoginRequest; +import com.fuint.module.backendApi.response.LoginResponse; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.Digests; +import com.fuint.utils.Encodes; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 后台账号接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class AccountServiceImpl extends ServiceImpl implements AccountService { + + private TAccountMapper tAccountMapper; + + private TDutyMapper tDutyMapper; + + private TAccountDutyMapper tAccountDutyMapper; + + private MtMerchantMapper mtMerchantMapper; + + private MtStoreMapper mtStoreMapper; + + /** + * 员工接口 + */ + private StaffService staffService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 验证码服务接口 + * */ + private CaptchaService captchaService; + + /** + * 分页查询账号列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse getAccountListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(TAccount::getAccountStatus, -1); // 1:启用;0:禁用;-1:删除 + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotEmpty(name)) { + lambdaQueryWrapper.like(TAccount::getAccountName, name); + } + String realName = paginationRequest.getSearchParams().get("realName") == null ? "" : paginationRequest.getSearchParams().get("realName").toString(); + if (StringUtils.isNotEmpty(realName)) { + lambdaQueryWrapper.like(TAccount::getRealName, realName); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotEmpty(status)) { + lambdaQueryWrapper.eq(TAccount::getAccountStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotEmpty(merchantId)) { + lambdaQueryWrapper.eq(TAccount::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotEmpty(storeId)) { + lambdaQueryWrapper.eq(TAccount::getStoreId, storeId); + } + String staffId = paginationRequest.getSearchParams().get("staffId") == null ? "" : paginationRequest.getSearchParams().get("staffId").toString(); + if (StringUtils.isNotEmpty(staffId)) { + lambdaQueryWrapper.eq(TAccount::getStaffId, staffId); + } + + lambdaQueryWrapper.orderByDesc(TAccount::getAcctId); + List accountList = tAccountMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + for (TAccount tAccount : accountList) { + AccountDto accountDto = new AccountDto(); + BeanUtils.copyProperties(tAccount, accountDto); + accountDto.setId(tAccount.getAcctId()); + MtMerchant mtMerchant = mtMerchantMapper.selectById(tAccount.getMerchantId()); + if (mtMerchant != null) { + accountDto.setMerchantName(mtMerchant.getName()); + } + MtStore mtStore = mtStoreMapper.selectById(tAccount.getStoreId()); + if (mtStore != null) { + accountDto.setStoreName(mtStore.getName()); + } + accountDto.setSalt(null); + accountDto.setPassword(null); + dataList.add(accountDto); + } + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, AccountDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 根据账号名称获取账号信息 + * + * @param userName 账号名称 + * @return + * */ + @Override + public AccountInfo getAccountByName(String userName) { + Map param = new HashMap(); + param.put("account_name", userName); + param.put("account_status", 1); + List accountList = tAccountMapper.selectByMap(param); + if (accountList != null && accountList.size() > 0) { + AccountInfo accountInfo = new AccountInfo(); + TAccount account = accountList.get(0); + accountInfo.setId(account.getAcctId()); + accountInfo.setAccountName(account.getAccountName()); + accountInfo.setRealName(account.getRealName()); + accountInfo.setRoleIds(account.getRoleIds()); + accountInfo.setStaffId(account.getStaffId()); + accountInfo.setStoreId(account.getStoreId()); + Integer merchantId = account.getMerchantId() == null ? 0 : account.getMerchantId(); + accountInfo.setMerchantId(merchantId); + if (account.getMerchantId() != null && account.getMerchantId() > 0) { + MtMerchant mtMerchant = mtMerchantMapper.selectById(account.getMerchantId()); + if (mtMerchant != null) { + accountInfo.setMerchantName(mtMerchant.getName()); + } + } + if (account.getStoreId() != null && account.getStoreId() > 0) { + MtStore mtStore = mtStoreMapper.selectById(account.getStoreId()); + if (mtStore != null) { + accountInfo.setStoreName(mtStore.getName()); + } + } + return accountInfo; + } else { + return null; + } + } + + /** + * 根据ID获取账号信息 + * + * @param userId 账号ID + * @return + * */ + @Override + public TAccount getAccountInfoById(Integer userId) { + TAccount tAccount = tAccountMapper.selectById(userId); + return tAccount; + } + + /** + * 新增后台账户 + * + * @param tAccount + * @return + * */ + @Override + @OperationServiceLog(description = "新增后台账户") + public TAccount createAccountInfo(TAccount tAccount, List duties) throws BusinessCheckException { + TAccount account = new TAccount(); + account.setAccountKey(tAccount.getAccountKey()); + account.setAccountName(tAccount.getAccountName().toLowerCase()); + account.setAccountStatus(1); + account.setRealName(tAccount.getRealName()); + account.setRoleIds(tAccount.getRoleIds()); + account.setStaffId(tAccount.getStaffId()); + Integer storeId = tAccount.getStoreId() == null ? 0 : tAccount.getStoreId(); + if (tAccount.getMerchantId() == null || tAccount.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + tAccount.setMerchantId(mtStore.getMerchantId()); + } + } + account.setMerchantId(tAccount.getMerchantId()); + account.setStoreId(tAccount.getStoreId()); + account.setCreateDate(new Date()); + account.setModifyDate(new Date()); + account.setStoreId(tAccount.getStoreId()); + account.setStaffId(tAccount.getStaffId()); + account.setPassword(tAccount.getPassword()); + this.entryptPassword(account); + int id = tAccountMapper.insert(account); + + if (id > 0 && duties != null && duties.size() > 0) { + for (TDuty tDuty : duties) { + TAccountDuty tAccountDuty = new TAccountDuty(); + tAccountDuty.setDutyId(tDuty.getDutyId()); + tAccountDuty.setAcctId(account.getAcctId()); + tAccountDutyMapper.insert(tAccountDuty); + } + } + + if (id > 0 ) { + return this.getAccountInfoById(id); + } else { + throw new BusinessRuntimeException("创建账号错误"); + } + } + + /** + * 获取账号角色ID + * + * @param accountId + * @return + * */ + @Override + public List getRoleIdsByAccountId(Integer accountId) { + return tDutyMapper.getRoleIdsByAccountId(accountId); + } + + /** + * 修改账户 + * + * @param tAccount 账户实体 + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改后台账户") + public void editAccount(TAccount tAccount, List duties) throws BusinessCheckException { + TAccount oldAccount = tAccountMapper.selectById(tAccount.getAcctId()); + if (oldAccount == null) { + throw new BusinessCheckException("账户不存在."); + } + tAccount.setModifyDate(new Date()); + if (duties != null && duties.size() > 0) { + if (tAccount.getAcctId() != null && tAccount.getAcctId() > 0) { + tAccountDutyMapper.deleteDutiesByAccountId(tAccount.getAcctId()); + for (TDuty tDuty : duties) { + TAccountDuty tAccountDuty = new TAccountDuty(); + tAccountDuty.setDutyId(tDuty.getDutyId()); + tAccountDuty.setAcctId(tAccount.getAcctId()); + tAccountDutyMapper.insert(tAccountDuty); + } + } + } + if (tAccount.getStaffId() != null && tAccount.getStaffId() > 0) { + MtStaff mtStaff = staffService.queryStaffById(tAccount.getStaffId()); + if (mtStaff == null) { + tAccount.setStaffId(0); + } + } + tAccountMapper.updateById(tAccount); + } + + /** + * 根据账户名称获取账户所分配的角色ID集合 + * + * @param accountId 账户 + * @return 角色ID集合 + */ + @Override + public List getDutyIdsByAccountId(Integer accountId) { + return tAccountDutyMapper.getDutyIdsByAccountId(accountId); + } + + /** + * 更新账户 + * + * @param tAccount + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改后台账户") + public void updateAccount(TAccount tAccount) { + tAccountMapper.updateById(tAccount); + } + + /** + * 删除账号 + * + * @param accountId 账号ID + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除后台账户") + public void deleteAccount(Long accountId) { + TAccount tAccount = tAccountMapper.selectById(accountId); + tAccount.setAccountStatus(-1); + tAccount.setModifyDate(new Date()); + tAccountMapper.updateById(tAccount); + } + + /** + * 设定安全的密码 + * + * @param tAccount 账号信息 + * @return + */ + @Override + public void entryptPassword(TAccount tAccount) { + byte[] salt = Digests.generateSalt(8); + tAccount.setSalt(Encodes.encodeHex(salt)); + byte[] hashPassword = Digests.sha1(tAccount.getPassword().getBytes(), salt, 1024); + tAccount.setPassword(Encodes.encodeHex(hashPassword)); + } + + /** + * 获取加密密码 + * + * @param password + * @param salt + * @return + * */ + @Override + public String getEntryptPassword(String password, String salt) { + byte[] salt1 = Encodes.decodeHex(salt); + byte[] hashPassword = Digests.sha1(password.getBytes(), salt1, 1024); + return Encodes.encodeHex(hashPassword); + } + + /** + * 登录后台系统 + * + * @param loginRequest 登录参数 + * @param userAgent 登录浏览器 + * @return + * */ + @Override + @OperationServiceLog(description = "登录后台系统") + public LoginResponse doLogin(LoginRequest loginRequest, String userAgent) throws BusinessCheckException { + String accountName = loginRequest.getUsername(); + String password = loginRequest.getPassword(); + String captchaCode = loginRequest.getCaptchaCode(); + String uuid = loginRequest.getUuid(); + + Boolean captchaVerify = captchaService.checkCodeByUuid(captchaCode, uuid); + if (!captchaVerify) { + throw new BusinessCheckException("图形验证码有误"); + } + + if (StringUtil.isEmpty(accountName)|| StringUtil.isEmpty(password) || StringUtil.isEmpty(captchaCode)) { + throw new BusinessCheckException("登录参数有误"); + } else { + AccountInfo accountInfo = getAccountByName(loginRequest.getUsername()); + if (accountInfo == null) { + throw new BusinessCheckException("登录账号或密码有误"); + } + + TAccount tAccount = getAccountInfoById(accountInfo.getId()); + String myPassword = tAccount.getPassword(); + String inputPassword = getEntryptPassword(password, tAccount.getSalt()); + if (!myPassword.equals(inputPassword) || !tAccount.getAccountStatus().toString().equals("1")) { + throw new BusinessCheckException("登录账号或密码有误"); + } + + // 商户已禁用 + if (tAccount.getMerchantId() != null && tAccount.getMerchantId() > 0) { + MtMerchant mtMerchant = mtMerchantMapper.selectById(tAccount.getMerchantId()); + if (mtMerchant != null && !mtMerchant.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("您的商户已被禁用,请联系平台方"); + } + } + + // 店铺已禁用 + if (tAccount.getStoreId() != null && tAccount.getStoreId() > 0) { + MtStore mtStore = mtStoreMapper.selectById(tAccount.getStoreId()); + if (mtStore != null && !mtStore.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("您的店铺已被禁用,请联系平台方"); + } + } + + String token = TokenUtil.generateToken(userAgent, accountInfo); + LoginResponse response = new LoginResponse(); + response.setLogin(true); + response.setToken(token); + response.setTokenCreatedTime(new Date()); + + return response; + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/ActionLogServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/ActionLogServiceImpl.java new file mode 100644 index 0000000..c0a86aa --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/ActionLogServiceImpl.java @@ -0,0 +1,81 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.service.ActionLogService; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.TActionLogMapper; +import com.fuint.repository.model.TActionLog; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import java.util.List; + +/** + * 日志服务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class ActionLogServiceImpl extends ServiceImpl implements ActionLogService { + + private TActionLogMapper tActionLogMapper; + + public void saveActionLog(TActionLog actionLog) { + tActionLogMapper.insert(actionLog); + } + + public PaginationResponse findLogsByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(TActionLog::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(TActionLog::getStoreId, storeId); + } + String module = paginationRequest.getSearchParams().get("module") == null ? "" : paginationRequest.getSearchParams().get("module").toString(); + if (StringUtils.isNotBlank(module)) { + lambdaQueryWrapper.like(TActionLog::getModule, module); + } + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.eq(TActionLog::getAcctName, name); + } + String startTime = paginationRequest.getSearchParams().get("startTime") == null ? "" : paginationRequest.getSearchParams().get("startTime").toString(); + if (StringUtils.isNotBlank(startTime)) { + lambdaQueryWrapper.gt(TActionLog::getActionTime, startTime); + } + String endTime = paginationRequest.getSearchParams().get("endTime") == null ? "" : paginationRequest.getSearchParams().get("endTime").toString(); + if (StringUtils.isNotBlank(endTime)) { + lambdaQueryWrapper.lt(TActionLog::getActionTime, endTime); + } + String ip = paginationRequest.getSearchParams().get("ip") == null ? "" : paginationRequest.getSearchParams().get("ip").toString(); + if (StringUtils.isNotBlank(ip)) { + lambdaQueryWrapper.eq(TActionLog::getClientIp, ip); + } + + lambdaQueryWrapper.orderByDesc(TActionLog::getId); + List dataList = tActionLogMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, TActionLog.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/AddressServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/AddressServiceImpl.java new file mode 100644 index 0000000..5f9f0f8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/AddressServiceImpl.java @@ -0,0 +1,120 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.service.AddressService; +import com.fuint.repository.model.MtAddress; +import com.fuint.repository.mapper.MtAddressMapper; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.common.enums.StatusEnum; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.Date; +import java.util.Map; +import java.util.HashMap; + +/** + * 收货地址业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class AddressServiceImpl extends ServiceImpl implements AddressService { + + private MtAddressMapper mtAddressMapper; + + /** + * 保存收货地址 + * + * @param mtAddress + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public MtAddress saveAddress(MtAddress mtAddress) { + if (mtAddress.getId() > 0) { + MtAddress address = mtAddressMapper.selectById(mtAddress.getId()); + if (StringUtil.isNotEmpty(mtAddress.getName())) { + address.setName(mtAddress.getName()); + } + if (StringUtil.isNotEmpty(mtAddress.getMobile())) { + address.setMobile(mtAddress.getMobile()); + } + if (StringUtil.isNotEmpty(mtAddress.getDetail())) { + address.setDetail(mtAddress.getDetail()); + } + if (StringUtil.isNotEmpty(mtAddress.getIsDefault())) { + if (mtAddress.getIsDefault().equals(YesOrNoEnum.YES.getKey())) { + mtAddressMapper.setDefault(mtAddress.getUserId(), mtAddress.getId()); + } + address.setIsDefault(mtAddress.getIsDefault()); + } + if (StringUtil.isNotEmpty(mtAddress.getStatus())) { + address.setStatus(mtAddress.getStatus()); + } + if (mtAddress.getProvinceId() > 0) { + address.setProvinceId(mtAddress.getProvinceId()); + } + if (mtAddress.getCityId() > 0) { + address.setCityId(mtAddress.getCityId()); + } + if (mtAddress.getRegionId() > 0) { + address.setRegionId(mtAddress.getRegionId()); + } + + mtAddressMapper.updateById(address); + } else { + mtAddress.setCreateTime(new Date()); + mtAddress.setUpdateTime(new Date()); + mtAddress.setIsDefault(YesOrNoEnum.YES.getKey()); + + this.save(mtAddress); + mtAddressMapper.setDefault(mtAddress.getUserId(), mtAddress.getId()); + } + + return mtAddress; + } + + /** + * 根据ID获取收货地址 + * + * @param id 地址ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtAddress detail(Integer id) { + return mtAddressMapper.selectById(id); + } + + /** + * 根据条件查询地址列表 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryListByParams(Map params) { + Map param = new HashMap<>(); + + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey(): params.get("status").toString(); + param.put("status", status); + + if (params.get("userId") != null) { + param.put("user_id", params.get("userId").toString()); + } + + if (params.get("isDefault") != null) { + param.put("is_default", YesOrNoEnum.YES.getKey()); + } + + return mtAddressMapper.selectByMap(param); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/AlipayServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/AlipayServiceImpl.java new file mode 100644 index 0000000..867976a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/AlipayServiceImpl.java @@ -0,0 +1,261 @@ +package com.fuint.common.service.impl; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradePayModel; +import com.alipay.api.domain.AlipayTradeQueryModel; +import com.alipay.api.domain.AlipayTradeRefundModel; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.response.AlipayTradePayResponse; +import com.alipay.api.response.AlipayTradeQueryResponse; +import com.alipay.api.response.AlipayTradeRefundResponse; +import com.fuint.common.bean.AliPayBean; +import com.fuint.common.dto.OrderDto; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.enums.*; +import com.fuint.common.service.*; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.ijpay.alipay.AliPayApi; +import com.ijpay.alipay.AliPayApiConfig; +import com.ijpay.alipay.AliPayApiConfigKit; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.*; + +/** + * 支付宝相关接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class AlipayServiceImpl implements AlipayService { + + private static final Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class); + + private AliPayBean aliPayBean; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform) throws BusinessCheckException { + logger.info("AlipayService createPrepayOrder inParams userInfo={} payAmount={} giveAmount={} goodsInfo={}", userInfo, payAmount, giveAmount, orderInfo); + + String goodsInfo = orderInfo.getOrderSn(); + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + goodsInfo = OrderTypeEnum.PRESTORE.getValue(); + } + + // 更新支付金额 + BigDecimal payAmount1 = new BigDecimal(payAmount).divide(new BigDecimal("100")); + OrderDto reqDto = new OrderDto(); + reqDto.setId(orderInfo.getId()); + reqDto.setPayAmount(payAmount1); + reqDto.setPayType(orderInfo.getPayType()); + reqDto.setOrderSn(orderInfo.getOrderSn()); + orderService.updateOrder(reqDto); + + getApiConfig(orderInfo.getStoreId()); + String notifyUrl = aliPayBean.getDomain(); + AlipayTradePayModel model = new AlipayTradePayModel(); + model.setAuthCode(authCode); + model.setSubject(goodsInfo); + model.setTotalAmount(payAmount1.toString()); + model.setOutTradeNo(orderInfo.getOrderSn()); + model.setStoreId(orderInfo.getStoreId().toString()); + model.setScene("bar_code"); + + String code = ""; + try { + AlipayTradePayResponse response = AliPayApi.tradePayToResponse(model, notifyUrl); + code = response.getCode(); + String msg = response.getMsg(); + logger.info("AlipayService createPrepayOrder return code: {}, msg ", code, msg); + if (!code.equals("10000") || !msg.equalsIgnoreCase("Success")) { + if (code.equals("10003")) { + // 需要会员输入支付密码,等待10秒后查询订单 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Map payResult = queryPaidOrder(orderInfo.getStoreId(), response.getTradeNo(), orderInfo.getOrderSn()); + if (payResult == null) { + throw new BusinessCheckException("支付宝支付失败"); + } + } else { + throw new BusinessCheckException("支付宝支付出错:" + msg); + } + } + } catch (Exception e) { + logger.error("AlipayService createPrepayOrder exception {}", e.getMessage()); + throw new BusinessCheckException("支付宝支付出错,请检查配置项"); + } + + Map respData = new HashMap<>(); + respData.put("result", code); + + ResponseObject responseObject = new ResponseObject(200, "支付宝支付接口返回成功", respData); + logger.info("AlipayService createPrepayOrder outParams {}", responseObject.toString()); + + return responseObject; + } + + /** + * 支付回调 + * + * @param params 请求参数 + * @return + * */ + @Override + public Boolean checkCallBack(Map params) throws Exception { + String orderSn = params.get("out_trade_no") != null ? params.get("out_trade_no") : ""; + Integer storeId = 0; + UserOrderDto orderDto = orderService.getOrderByOrderSn(orderSn); + if (orderDto != null && orderDto.getStoreInfo() != null) { + storeId = orderDto.getStoreInfo().getId(); + } + getApiConfig(storeId); + return AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2"); + } + + /** + * 获取支付配置 + * + * @param storeId 店铺ID + * @return + * */ + public AliPayApiConfig getApiConfig(Integer storeId) throws BusinessCheckException { + AliPayApiConfig aliPayApiConfig; + String appId = aliPayBean.getAppId(); + String privateKey = aliPayBean.getPrivateKey(); + String publicKey = aliPayBean.getPublicKey(); + + // 优先读取店铺的支付账号 + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null && StringUtil.isNotEmpty(mtStore.getAlipayAppId()) && StringUtil.isNotEmpty(mtStore.getAlipayPrivateKey()) && StringUtil.isNotEmpty(mtStore.getAlipayPublicKey())) { + appId = mtStore.getAlipayAppId(); + privateKey = mtStore.getAlipayPrivateKey(); + publicKey = mtStore.getAlipayPublicKey(); + } + + aliPayApiConfig = AliPayApiConfig.builder() + .setAppId(appId) + .setAliPayPublicKey(publicKey) + .setCharset("UTF-8") + .setPrivateKey(privateKey) + .setServiceUrl(aliPayBean.getServerUrl()) + .setSignType("RSA2") + .build(); + + AliPayApiConfigKit.setThreadLocalAppId(appId); + AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig); + + return aliPayApiConfig; + } + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param tradeNo 交易单号 + * @param orderSn 订单号 + * @return + * */ + @Override + public Map queryPaidOrder(Integer storeId, String tradeNo, String orderSn) throws BusinessCheckException { + try { + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + if (StringUtil.isNotEmpty(orderSn)) { + model.setOutTradeNo(orderSn); + } + if (StringUtil.isNotEmpty(tradeNo)) { + model.setTradeNo(tradeNo); + } + getApiConfig(storeId); + AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(model); + if (response != null) { + // TradeStatus:TRADE_SUCCESS(交易支付成功,可进行退款)或 TRADE_FINISHED(交易结束,不可退款) + if (response.getTradeStatus() != null && response.getTradeStatus().equals("TRADE_SUCCESS")) { + Map result = new HashMap<>(); + result.put("tradeNo", response.getTradeNo()); + result.put("status", response.getTradeStatus()); + result.put("payAmount", response.getBuyerPayAmount()); + return result; + } + } + } catch (AlipayApiException e) { + logger.info("AlipayService queryPaidOrder response", e.getMessage()); + } + + return null; + } + + /** + * 发起售后退款 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 订单总金额 + * @param refundAmount 售后金额 + * @param platform 订单平台 + * @return + * */ + public Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException { + try { + logger.info("AlipayService.doRefund orderSn = {}, totalFee = {}, refundFee = {}", orderSn, totalAmount, refundAmount); + if (StringUtil.isEmpty(orderSn)) { + throw new BusinessCheckException("退款订单号不能为空..."); + } + if (refundAmount.compareTo(totalAmount) > 0) { + throw new BusinessCheckException("退款金额不能大于总金额..."); + } + getApiConfig(storeId); + AlipayTradeRefundModel model = new AlipayTradeRefundModel(); + model.setOutTradeNo(orderSn); + model.setRefundAmount(refundAmount.toString()); + model.setRefundReason("申请退款"); + AlipayTradeRefundResponse refundResponse = AliPayApi.tradeRefundToResponse(model); + String code = refundResponse.getCode(); + String msg = refundResponse.getMsg(); + String subMsg = refundResponse.getSubMsg() == null ? msg : refundResponse.getSubMsg(); + logger.info("AlipayService refundResult response Body = {}", refundResponse.getBody()); + if (!code.equals("10000") || !msg.equalsIgnoreCase("Success")) { + throw new BusinessCheckException("支付宝退款失败," + subMsg); + } + } catch (AlipayApiException e) { + logger.error("AlipayService.doRefund error = {}", e.getMessage()); + e.printStackTrace(); + } + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/ArticleServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/ArticleServiceImpl.java new file mode 100644 index 0000000..2a873cb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/ArticleServiceImpl.java @@ -0,0 +1,288 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.ArticleDto; +import com.fuint.common.param.ArticlePage; +import com.fuint.common.service.ArticleService; +import com.fuint.common.service.MerchantService; +import com.fuint.common.service.StoreService; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtArticleMapper; +import com.fuint.repository.model.MtArticle; +import com.fuint.common.service.SettingService; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.model.MtStore; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 文章服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class ArticleServiceImpl extends ServiceImpl implements ArticleService { + + private MtArticleMapper mtArticleMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 商户服务接口 + * */ + private MerchantService merchantService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 分页查询文章列表 + * + * @param articlePage + * @return + */ + @Override + public PaginationResponse queryArticleListByPagination(ArticlePage articlePage) { + Page pageHelper = PageHelper.startPage(articlePage.getPage(), articlePage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtArticle::getStatus, StatusEnum.DISABLE.getKey()); + + String title = articlePage.getTitle(); + if (StringUtils.isNotBlank(title)) { + lambdaQueryWrapper.like(MtArticle::getTitle, title); + } + String status = articlePage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtArticle::getStatus, status); + } + Integer merchantId = articlePage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtArticle::getMerchantId, merchantId); + } + String merchantNo = articlePage.getMerchantNo(); + Integer mchId = merchantService.getMerchantId(merchantNo); + if (mchId > 0) { + lambdaQueryWrapper.eq(MtArticle::getMerchantId, mchId); + } + Integer storeId = articlePage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtArticle::getStoreId, 0) + .or() + .eq(MtArticle::getStoreId, storeId)); + } + lambdaQueryWrapper.orderByAsc(MtArticle::getSort); + List articleList = mtArticleMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + String basePath = settingService.getUploadBasePath(); + for (MtArticle mtArticle : articleList) { + ArticleDto articleDto = new ArticleDto(); + BeanUtils.copyProperties(mtArticle, articleDto); + articleDto.setImage(basePath + mtArticle.getImage()); + dataList.add(articleDto); + } + + PageRequest pageRequest = PageRequest.of(articlePage.getPage(), articlePage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, ArticleDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加文章 + * + * @param articleDto 文章参数 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增文章") + public MtArticle addArticle(ArticleDto articleDto) throws BusinessCheckException { + MtArticle mtArticle = new MtArticle(); + mtArticle.setTitle(articleDto.getTitle()); + mtArticle.setBrief(articleDto.getBrief()); + Integer storeId = articleDto.getStoreId() == null ? 0 : articleDto.getStoreId(); + if (articleDto.getMerchantId() == null || articleDto.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + articleDto.setMerchantId(mtStore.getMerchantId()); + } + } + mtArticle.setMerchantId(articleDto.getMerchantId()); + + if (mtArticle.getMerchantId() == null || mtArticle.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + + mtArticle.setStoreId(storeId); + mtArticle.setUrl(articleDto.getUrl()); + mtArticle.setClick(0l); + mtArticle.setStatus(StatusEnum.ENABLED.getKey()); + mtArticle.setImage(articleDto.getImage()); + mtArticle.setDescription(articleDto.getDescription()); + mtArticle.setOperator(articleDto.getOperator()); + mtArticle.setUpdateTime(new Date()); + mtArticle.setCreateTime(new Date()); + mtArticle.setSort(articleDto.getSort()); + mtArticle.setMerchantId(articleDto.getMerchantId()); + Integer id = mtArticleMapper.insert(mtArticle); + if (id > 0) { + return mtArticle; + } else { + return null; + } + } + + /** + * 根据ID获取文章 + * + * @param articleId 文章ID + * @return + */ + @Override + public MtArticle queryArticleById(Integer articleId) { + return mtArticleMapper.selectById(articleId); + } + + /** + * 根据ID获取文章详情 + * + * @param articleId 文章ID + * @return + */ + @Override + public ArticleDto getArticleDetail(Integer articleId) { + MtArticle mtArticle = mtArticleMapper.selectById(articleId); + if (mtArticle == null) { + return null; + } + ArticleDto articleDto = new ArticleDto(); + BeanUtils.copyProperties(mtArticle, articleDto); + String baseImage = settingService.getUploadBasePath(); + articleDto.setImage(baseImage + mtArticle.getImage()); + articleDto.setDescription(CommonUtil.fixVideo(mtArticle.getDescription())); + return articleDto; + } + + /** + * 编辑文章 + * + * @param articleDto 文章参数 + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "编辑文章") + public MtArticle updateArticle(ArticleDto articleDto) throws BusinessCheckException { + MtArticle mtArticle = queryArticleById(articleDto.getId()); + if (mtArticle == null) { + throw new BusinessCheckException("该文章状态异常"); + } + mtArticle.setId(articleDto.getId()); + if (articleDto.getImage() != null) { + mtArticle.setImage(articleDto.getImage()); + } + if (articleDto.getTitle() != null) { + mtArticle.setTitle(articleDto.getTitle()); + } + if (articleDto.getBrief() != null) { + mtArticle.setBrief(articleDto.getBrief()); + } + if (articleDto.getClick() != null) { + mtArticle.setClick(articleDto.getClick()); + } + if (articleDto.getMerchantId() != null) { + mtArticle.setMerchantId(articleDto.getMerchantId()); + } + if (articleDto.getStoreId() != null) { + mtArticle.setStoreId(articleDto.getStoreId()); + } + if (articleDto.getDescription() != null) { + mtArticle.setDescription(articleDto.getDescription()); + } + if (articleDto.getOperator() != null) { + mtArticle.setOperator(articleDto.getOperator()); + } + if (articleDto.getStatus() != null) { + mtArticle.setStatus(articleDto.getStatus()); + } + if (articleDto.getUrl() != null) { + mtArticle.setUrl(articleDto.getUrl()); + } + if (articleDto.getSort() != null) { + mtArticle.setSort(articleDto.getSort()); + } + mtArticle.setUpdateTime(new Date()); + mtArticleMapper.updateById(mtArticle); + return mtArticle; + } + + /** + * 根据条件搜索文章 + * + * @param params 搜索条件 + * @return + * */ + @Override + public List queryArticleListByParams(Map params) { + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey(): params.get("status").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String title = params.get("title") == null ? "" : params.get("title").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.like(MtArticle::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(title)) { + lambdaQueryWrapper.like(MtArticle::getTitle, title); + } + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtArticle::getStatus, status); + } + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtArticle::getStoreId, 0) + .or() + .eq(MtArticle::getStoreId, storeId)); + } + + lambdaQueryWrapper.orderByAsc(MtArticle::getSort); + List dataList = mtArticleMapper.selectList(lambdaQueryWrapper); + String baseImage = settingService.getUploadBasePath(); + + if (dataList.size() > 0) { + for (MtArticle article : dataList) { + article.setImage(baseImage + article.getImage()); + } + } + + return dataList; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/BalanceServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/BalanceServiceImpl.java new file mode 100644 index 0000000..422bff1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/BalanceServiceImpl.java @@ -0,0 +1,326 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.BalanceDto; +import com.fuint.common.dto.OrderDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.BalancePage; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.common.util.PhoneFormatCheckUtils; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtBalanceMapper; +import com.fuint.repository.mapper.MtUserMapper; +import com.fuint.repository.model.MtBalance; +import com.fuint.repository.model.MtBanner; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +/** + * 余额管理业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class BalanceServiceImpl extends ServiceImpl implements BalanceService { + + private static final Logger logger = LoggerFactory.getLogger(BalanceServiceImpl.class); + + private MtBalanceMapper mtBalanceMapper; + + private MtUserMapper mtUserMapper; + + /** + * 微信相关服务接口 + * */ + private WeixinService weixinService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 分页查询余额列表 + * + * @param balancePage + * @return + */ + @Override + public PaginationResponse queryBalanceListByPagination(BalancePage balancePage) throws BusinessCheckException { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBalance::getStatus, StatusEnum.DISABLE.getKey()); + + String description = balancePage.getDescription(); + if (StringUtils.isNotBlank(description)) { + lambdaQueryWrapper.like(MtBalance::getDescription, description); + } + String status = balancePage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBalance::getStatus, status); + } + Integer userId = balancePage.getUserId(); + if (userId != null) { + lambdaQueryWrapper.eq(MtBalance::getUserId, userId); + } + String orderSn = balancePage.getOrderSn(); + if (StringUtils.isNotBlank(orderSn)) { + lambdaQueryWrapper.eq(MtBalance::getOrderSn, orderSn); + } + String mobile = balancePage.getMobile(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtBalance::getMobile, mobile); + } + Integer merchantId = balancePage.getMerchantId(); + if (merchantId != null) { + lambdaQueryWrapper.eq(MtBalance::getMerchantId, merchantId); + } + String userNo = balancePage.getUserNo(); + if (StringUtil.isNotEmpty(userNo)) { + if (merchantId == null) { + merchantId = 0; + } + MtUser userInfo = memberService.queryMemberByUserNo(merchantId, userNo); + if (userInfo != null) { + lambdaQueryWrapper.eq(MtBalance::getUserId, userInfo.getId()); + } else { + lambdaQueryWrapper.eq(MtBalance::getUserId, -1); + } + } + Integer storeId = balancePage.getStoreId(); + if (storeId != null) { + lambdaQueryWrapper.eq(MtBalance::getStoreId, storeId); + } + lambdaQueryWrapper.orderByDesc(MtBalance::getId); + Page pageHelper = PageHelper.startPage(balancePage.getPage(), balancePage.getPageSize()); + List balanceList = mtBalanceMapper.selectList(lambdaQueryWrapper); + + List dataList = new ArrayList<>(); + for (MtBalance mtBalance : balanceList) { + MtUser userInfo = memberService.queryMemberById(mtBalance.getUserId()); + if (userInfo != null) { + userInfo.setMobile(CommonUtil.hidePhone(userInfo.getMobile())); + } + BalanceDto item = new BalanceDto(); + item.setId(mtBalance.getId()); + item.setAmount(mtBalance.getAmount()); + item.setDescription(mtBalance.getDescription()); + item.setCreateTime(mtBalance.getCreateTime()); + item.setUpdateTime(mtBalance.getUpdateTime()); + item.setUserId(mtBalance.getUserId()); + item.setUserInfo(userInfo); + item.setOrderSn(mtBalance.getOrderSn()); + item.setStatus(mtBalance.getStatus()); + item.setOperator(mtBalance.getOperator()); + dataList.add(item); + } + + PageRequest pageRequest = PageRequest.of(balancePage.getPage(), balancePage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, BalanceDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加余额记录 + * + * @param mtBalance + * @param updateBalance + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "会员余额变动") + public Boolean addBalance(MtBalance mtBalance, Boolean updateBalance) throws BusinessCheckException { + if (mtBalance.getUserId() < 0) { + return false; + } + Date nowDate = new Date(); + mtBalance.setStatus(StatusEnum.ENABLED.getKey()); + mtBalance.setCreateTime(nowDate); + mtBalance.setUpdateTime(nowDate); + + MtUser mtUser = mtUserMapper.selectById(mtBalance.getUserId()); + BigDecimal newAmount = mtUser.getBalance().add(mtBalance.getAmount()); + if (newAmount.compareTo(new BigDecimal("0")) < 0) { + return false; + } + if (mtUser.getStoreId() != null) { + mtBalance.setStoreId(mtUser.getStoreId()); + } + mtBalance.setMerchantId(mtUser.getMerchantId()); + if (updateBalance) { + mtUserMapper.updateUserBalance(mtUser.getMerchantId(), Arrays.asList(mtUser.getId()), mtBalance.getAmount()); + logger.info("会员余额变动:" + mtUser.getMobile() + ",会员ID:" + mtUser.getId() + ",会员余额:" + newAmount); + } + + if (PhoneFormatCheckUtils.isChinaPhoneLegal(mtUser.getMobile())) { + mtBalance.setMobile(mtUser.getMobile()); + } + mtBalanceMapper.insert(mtBalance); + + // 生成充值订单 + if (StringUtil.isEmpty(mtBalance.getOrderSn()) && mtBalance.getAmount().compareTo(new BigDecimal("0")) > 0) { + OrderDto orderDto = new OrderDto(); + orderDto.setMerchantId(mtBalance.getMerchantId()); + orderDto.setStoreId(mtBalance.getStoreId()); + orderDto.setUserId(mtBalance.getUserId()); + orderDto.setType(OrderTypeEnum.RECHARGE.getKey()); + orderDto.setPlatform(PlatformTypeEnum.PC.getCode()); + orderDto.setOrderMode(OrderModeEnum.ONESELF.getKey()); + orderDto.setAmount(mtBalance.getAmount()); + orderDto.setPayAmount(mtBalance.getAmount()); + orderDto.setPayType(PayTypeEnum.CASH.getKey()); + orderDto.setStatus(OrderStatusEnum.COMPLETE.getKey()); + orderDto.setPayStatus(PayStatusEnum.WAIT.getKey()); + orderDto.setOperator(mtBalance.getOperator()); + orderDto.setUsePoint(0); + MtOrder mtOrder = orderService.saveOrder(orderDto); + if (mtOrder != null) { + orderService.setOrderPayed(mtOrder.getId(), null); + } + } + mtUser = mtUserMapper.selectById(mtBalance.getUserId()); + try { + List mobileList = new ArrayList<>(); + mobileList.add(mtUser.getMobile()); + Map params = new HashMap<>(); + String action = ""; + if (mtBalance.getAmount().compareTo(new BigDecimal("0")) > 0) { + action = "+"; + } + params.put("amount", action + String.format("%.2f", mtBalance.getAmount())); + params.put("balance", String.format("%.2f", mtUser.getBalance())); + sendSmsService.sendSms(mtUser.getMerchantId(), "balance-change", mobileList, params); + } catch (Exception e) { + logger.error("余额变动短信发送失败:{}", e.getMessage()); + } + + // 发送小程序订阅消息 + Date nowTime = new Date(); + Map params = new HashMap<>(); + String dateTime = DateUtil.formatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm"); + params.put("amount", mtBalance.getAmount()); + params.put("time", dateTime); + params.put("tips", "您的余额发生了变动,请留意~"); + weixinService.sendSubscribeMessage(mtBalance.getMerchantId(), mtBalance.getUserId(), mtUser.getOpenId(), WxMessageEnum.BALANCE_CHANGE.getKey(), "pages/user/index", params, nowTime); + + return true; + } + + /** + * 发放余额 + * + * @param accountInfo 账号信息 + * @param object 发放对象,all全部 + * @param userIds 会员ID + * @param amount 发放金额 + * @param remark 备注 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "发放余额") + public void distribute(AccountInfo accountInfo, String object, String userIds, String amount, String remark) throws BusinessCheckException { + if (!CommonUtil.isNumeric(amount)) { + throw new BusinessCheckException("充值金额必须是数字"); + } + if (!object.equals("all") && StringUtil.isEmpty(userIds)) { + throw new BusinessCheckException("请先选择会员"); + } + if (accountInfo.getMerchantId() == null || accountInfo.getMerchantId() < 1) { + throw new BusinessCheckException("平台账号不能执行该操作"); + } + BigDecimal balanceAmount = new BigDecimal(amount); + if (balanceAmount.compareTo(new BigDecimal(20000)) > 0) { + throw new BusinessCheckException("单次充值金额不能大于20000"); + } + + List userIdArr = new ArrayList<>(); + List userIdList = Arrays.asList(userIds.split(",")); + if (userIdList != null && userIdList.size() > 0) { + for (String userId : userIdList) { + if (StringUtil.isNotEmpty(userId) && !userIdArr.contains(Integer.parseInt(userId))) { + userIdArr.add(Integer.parseInt(userId)); + } + } + } + // 最多不能超过5000人 + if (userIdArr.size() > 5000) { + throw new BusinessCheckException("最多不能超过5000人"); + } + mtUserMapper.updateUserBalance(accountInfo.getMerchantId(), userIdArr, balanceAmount); + + if (userIdArr.size() > 0) { + for (Integer userId : userIdArr) { + MtBalance mtBalance = new MtBalance(); + mtBalance.setAmount(new BigDecimal(amount)); + mtBalance.setUserId(userId); + mtBalance.setStoreId(accountInfo.getStoreId()); + mtBalance.setMerchantId(accountInfo.getMerchantId()); + mtBalance.setDescription(remark); + mtBalance.setOperator(accountInfo.getAccountName()); + addBalance(mtBalance, false); + } + } else { + MtBalance mtBalance = new MtBalance(); + mtBalance.setAmount(new BigDecimal(amount)); + mtBalance.setUserId(0); // userId为0表示全体会员 + mtBalance.setMerchantId(accountInfo.getMerchantId()); + mtBalance.setDescription(remark); + mtBalance.setOperator(accountInfo.getAccountName()); + mtBalance.setStatus(StatusEnum.ENABLED.getKey()); + mtBalance.setCreateTime(new Date()); + mtBalance.setUpdateTime(new Date()); + mtBalanceMapper.insert(mtBalance); + } + } + + /** + * 获取订单余额记录 + * + * @param orderSn + * @return + * */ + @Override + public List getBalanceListByOrderSn(String orderSn) { + return mtBalanceMapper.getBalanceListByOrderSn(orderSn); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/BannerServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/BannerServiceImpl.java new file mode 100644 index 0000000..c3d6362 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/BannerServiceImpl.java @@ -0,0 +1,257 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.fuint.common.param.BannerPage; +import com.fuint.common.service.StoreService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtBanner; +import com.fuint.common.dto.BannerDto; +import com.fuint.common.service.BannerService; +import com.fuint.common.service.SettingService; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.mapper.MtBannerMapper; + +import com.fuint.repository.model.MtStore; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 焦点图服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class BannerServiceImpl extends ServiceImpl implements BannerService { + + private static final Logger logger = LoggerFactory.getLogger(BannerServiceImpl.class); + + private MtBannerMapper mtBannerMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 分页查询焦点图列表 + * + * @param bannerPage + * @return + */ + @Override + public PaginationResponse queryBannerListByPagination(BannerPage bannerPage) { + Page pageHelper = PageHelper.startPage(bannerPage.getPage(), bannerPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBanner::getStatus, StatusEnum.DISABLE.getKey()); + + String title = bannerPage.getTitle(); + if (StringUtils.isNotBlank(title)) { + lambdaQueryWrapper.like(MtBanner::getTitle, title); + } + String status = bannerPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBanner::getStatus, status); + } + Integer merchantId = bannerPage.getMerchantId(); + if (merchantId != null) { + lambdaQueryWrapper.eq(MtBanner::getMerchantId, merchantId); + } + Integer storeId = bannerPage.getStoreId(); + if (storeId != null) { + lambdaQueryWrapper.eq(MtBanner::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByAsc(MtBanner::getSort); + List dataList = mtBannerMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(bannerPage.getPage(), bannerPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtBanner.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加焦点图 + * + * @param bannerDto 焦点图信息 + * @return + */ + @Override + @OperationServiceLog(description = "新增焦点图") + public MtBanner addBanner(BannerDto bannerDto) throws BusinessCheckException { + MtBanner mtBanner = new MtBanner(); + BeanUtils.copyProperties(bannerDto, mtBanner); + Integer storeId = bannerDto.getStoreId() == null ? 0 : bannerDto.getStoreId(); + if (bannerDto.getMerchantId() == null || bannerDto.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + mtBanner.setMerchantId(mtStore.getMerchantId()); + } + } + if (mtBanner.getMerchantId() == null || mtBanner.getMerchantId() <= 0) { + throw new BusinessCheckException("新增焦点图失败:所属商户不能为空!"); + } + if (mtBanner.getMerchantId() == null || mtBanner.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + mtBanner.setStoreId(storeId); + mtBanner.setStatus(StatusEnum.ENABLED.getKey()); + mtBanner.setUpdateTime(new Date()); + mtBanner.setCreateTime(new Date()); + Integer id = mtBannerMapper.insert(mtBanner); + if (id > 0) { + return mtBanner; + } else { + logger.error("新增焦点图失败."); + throw new BusinessCheckException("抱歉,新增焦点图失败!"); + } + } + + /** + * 根据ID获取Banner信息 + * + * @param id BannerID + * @return + */ + @Override + public MtBanner queryBannerById(Integer id) { + return mtBannerMapper.selectById(id); + } + + /** + * 根据ID删除Banner图 + * + * @param id BannerID + * @param operator 操作人 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除Banner图") + public void deleteBanner(Integer id, String operator) { + MtBanner mtBanner = queryBannerById(id); + if (null == mtBanner) { + return; + } + mtBanner.setStatus(StatusEnum.DISABLE.getKey()); + mtBanner.setUpdateTime(new Date()); + mtBannerMapper.updateById(mtBanner); + } + + /** + * 修改Banner图 + * + * @param bannerDto + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新焦点图") + public MtBanner updateBanner(BannerDto bannerDto) throws BusinessCheckException { + MtBanner mtBanner = queryBannerById(bannerDto.getId()); + if (mtBanner == null) { + throw new BusinessCheckException("该Banner状态异常"); + } + + mtBanner.setId(bannerDto.getId()); + if (bannerDto.getImage() != null) { + mtBanner.setImage(bannerDto.getImage()); + } + if (bannerDto.getTitle() != null) { + mtBanner.setTitle(bannerDto.getTitle()); + } + if (bannerDto.getStoreId() != null) { + mtBanner.setStoreId(bannerDto.getStoreId()); + } + if (bannerDto.getDescription() != null) { + mtBanner.setDescription(bannerDto.getDescription()); + } + if (bannerDto.getOperator() != null) { + mtBanner.setOperator(bannerDto.getOperator()); + } + if (bannerDto.getStatus() != null) { + mtBanner.setStatus(bannerDto.getStatus()); + } + if (bannerDto.getUrl() != null) { + mtBanner.setUrl(bannerDto.getUrl()); + } + if (bannerDto.getSort() != null) { + mtBanner.setSort(bannerDto.getSort()); + } + mtBanner.setUpdateTime(new Date()); + mtBannerMapper.updateById(mtBanner); + return mtBanner; + } + + /** + * 根据条件搜索焦点图 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + @Override + public List queryBannerListByParams(Map params) { + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey(): params.get("status").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + String title = params.get("title") == null ? "" : params.get("title").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + if (StringUtils.isNotBlank(title)) { + lambdaQueryWrapper.like(MtBanner::getTitle, title); + } + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBanner::getStatus, status); + } + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtBanner::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtBanner::getStoreId, 0) + .or() + .eq(MtBanner::getStoreId, storeId)); + } + + lambdaQueryWrapper.orderByAsc(MtBanner::getSort); + List dataList = mtBannerMapper.selectList(lambdaQueryWrapper); + String baseImage = settingService.getUploadBasePath(); + + if (dataList.size() > 0) { + for (MtBanner banner : dataList) { + banner.setImage(baseImage + banner.getImage()); + } + } + + return dataList; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/BookCateServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/BookCateServiceImpl.java new file mode 100644 index 0000000..470bdd8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/BookCateServiceImpl.java @@ -0,0 +1,231 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.param.BookCatePage; +import com.fuint.common.service.BookCateService; +import com.fuint.common.service.StoreService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtBookCateMapper; +import com.fuint.common.service.SettingService; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.model.MtBookCate; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 预约分类服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class BookCateServiceImpl extends ServiceImpl implements BookCateService { + + private static final Logger logger = LoggerFactory.getLogger(BookCateServiceImpl.class); + + private MtBookCateMapper mtBookCateMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 分页查询预约分类列表 + * + * @param bookCatePage + * @return + */ + @Override + public PaginationResponse queryBookCateListByPagination(BookCatePage bookCatePage) { + Page pageHelper = PageHelper.startPage(bookCatePage.getPage(), bookCatePage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBookCate::getStatus, StatusEnum.DISABLE.getKey()); + + String name = bookCatePage.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtBookCate::getName, name); + } + String status = bookCatePage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBookCate::getStatus, status); + } + Integer merchantId = bookCatePage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtBookCate::getMerchantId, merchantId); + } + Integer storeId = bookCatePage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtBookCate::getStoreId, 0) + .or() + .eq(MtBookCate::getStoreId, storeId)); + } + + lambdaQueryWrapper.orderByAsc(MtBookCate::getSort); + List dataList = mtBookCateMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(bookCatePage.getPage(), bookCatePage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtBookCate.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加预约分类 + * + * @param mtBookCate 分类信息 + * @return + */ + @Override + @OperationServiceLog(description = "添加预约分类") + public MtBookCate addBookCate(MtBookCate mtBookCate) throws BusinessCheckException { + MtBookCate bookCate = new MtBookCate(); + Integer storeId = mtBookCate.getStoreId() == null ? 0 : mtBookCate.getStoreId(); + if (mtBookCate.getMerchantId() == null || mtBookCate.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null && mtStore.getMerchantId() != null) { + bookCate.setMerchantId(mtStore.getMerchantId()); + } + } + if (mtBookCate.getMerchantId() == null || mtBookCate.getMerchantId() <= 0) { + throw new BusinessCheckException("新增预约分类失败:所属商户不能为空!"); + } + if (StringUtil.isEmpty(mtBookCate.getName())) { + throw new BusinessCheckException("新增预约分类失败:分类名称不能为空!"); + } + if (StringUtil.isEmpty(mtBookCate.getLogo())) { + throw new BusinessCheckException("新增预约分类失败:封面图片不能为空!"); + } + bookCate.setStoreId(storeId); + bookCate.setName(mtBookCate.getName()); + bookCate.setLogo(mtBookCate.getLogo()); + bookCate.setDescription(mtBookCate.getDescription()); + bookCate.setStatus(StatusEnum.ENABLED.getKey()); + bookCate.setUpdateTime(new Date()); + bookCate.setCreateTime(new Date()); + bookCate.setSort(mtBookCate.getSort()); + bookCate.setOperator(mtBookCate.getOperator()); + bookCate.setMerchantId(mtBookCate.getMerchantId()); + Integer id = mtBookCateMapper.insert(bookCate); + if (id > 0) { + return bookCate; + } else { + logger.error("新增预约分类失败."); + throw new BusinessCheckException("抱歉,新增预约分类失败!"); + } + } + + /** + * 根据ID获取预约分类信息 + * + * @param id 预约分类ID + * @return + */ + @Override + public MtBookCate getBookCateById(Integer id) { + return mtBookCateMapper.selectById(id); + } + + /** + * 修改预约分类 + * + * @param mtBookCate + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改预约分类") + public MtBookCate updateBookCate(MtBookCate mtBookCate) throws BusinessCheckException { + MtBookCate bookCate = getBookCateById(mtBookCate.getId()); + if (bookCate == null) { + throw new BusinessCheckException("该预约分类状态异常"); + } + + bookCate.setId(mtBookCate.getId()); + if (mtBookCate.getLogo() != null) { + bookCate.setLogo(mtBookCate.getLogo()); + } + if (mtBookCate.getName() != null) { + bookCate.setName(mtBookCate.getName()); + } + if (mtBookCate.getStoreId() != null) { + bookCate.setStoreId(mtBookCate.getStoreId()); + } + if (mtBookCate.getDescription() != null) { + bookCate.setDescription(mtBookCate.getDescription()); + } + if (mtBookCate.getOperator() != null) { + bookCate.setOperator(mtBookCate.getOperator()); + } + if (mtBookCate.getStatus() != null) { + bookCate.setStatus(mtBookCate.getStatus()); + } + if (mtBookCate.getSort() != null) { + bookCate.setSort(mtBookCate.getSort()); + } + bookCate.setUpdateTime(new Date()); + mtBookCateMapper.updateById(bookCate); + + return bookCate; + } + + /** + * 获取可用的预约类别 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @throws BusinessCheckException + * @return + * */ + @Override + public List getAvailableBookCate(Integer merchantId, Integer storeId) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(MtBookCate::getStatus, StatusEnum.ENABLED.getKey()); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtBookCate::getMerchantId, merchantId); + } + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtBookCate::getStoreId, 0) + .or() + .eq(MtBookCate::getStoreId, storeId)); + } + lambdaQueryWrapper.orderByAsc(MtBookCate::getSort); + List dataList = mtBookCateMapper.selectList(lambdaQueryWrapper); + String baseImage = settingService.getUploadBasePath(); + if (dataList.size() > 0) { + for (MtBookCate mtBookCate : dataList) { + mtBookCate.setLogo(baseImage + mtBookCate.getLogo()); + } + } + return dataList; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/BookItemServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/BookItemServiceImpl.java new file mode 100644 index 0000000..0b11676 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/BookItemServiceImpl.java @@ -0,0 +1,369 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.BookItemDto; +import com.fuint.common.enums.BookStatusEnum; +import com.fuint.common.param.BookItemPage; +import com.fuint.common.param.BookableParam; +import com.fuint.common.service.BookItemService; +import com.fuint.common.service.BookService; +import com.fuint.common.service.StoreService; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.*; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.ParseException; +import java.util.*; + +/** + * 预约订单服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class BookItemServiceImpl extends ServiceImpl implements BookItemService { + + private static final Logger logger = LoggerFactory.getLogger(BookItemServiceImpl.class); + + private MtBookItemMapper mtBookItemMapper; + + private MtBookMapper mtBookMapper; + + private MtStoreMapper mtStoreMapper; + + private MtOrderGoodsMapper mtOrderGoodsMapper; + + private MtGoodsMapper mtGoodsMapper; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 预约项目服务接口 + * */ + private BookService bookService; + + /** + * 分页查询预约订单列表 + * + * @param bookItemPage + * @return + */ + @Override + public PaginationResponse queryBookItemListByPagination(BookItemPage bookItemPage) { + Page pageHelper = PageHelper.startPage(bookItemPage.getPage(), bookItemPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBookItem::getStatus, StatusEnum.DISABLE.getKey()); + + String mobile = bookItemPage.getMobile(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.like(MtBookItem::getMobile, mobile); + } + String contact = bookItemPage.getContact(); + if (StringUtils.isNotBlank(contact)) { + lambdaQueryWrapper.like(MtBookItem::getContact, contact); + } + String status = bookItemPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBookItem::getStatus, status); + } + if (bookItemPage.getMerchantId() != null) { + lambdaQueryWrapper.eq(MtBookItem::getMerchantId, bookItemPage.getMerchantId()); + } + if (bookItemPage.getStoreId() != null) { + lambdaQueryWrapper.eq(MtBookItem::getStoreId, bookItemPage.getStoreId()); + } + if (bookItemPage.getUserId() != null) { + lambdaQueryWrapper.eq(MtBookItem::getUserId, bookItemPage.getUserId()); + } + if (bookItemPage.getCateId() != null) { + lambdaQueryWrapper.eq(MtBookItem::getCateId, bookItemPage.getCateId()); + } + + lambdaQueryWrapper.orderByDesc(MtBookItem::getId); + List bookItemList = mtBookItemMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (bookItemList != null && bookItemList.size() > 0) { + for (MtBookItem mtBookItem : bookItemList) { + BookItemDto bookItemDto = new BookItemDto(); + BeanUtils.copyProperties(mtBookItem, bookItemDto); + MtBook mtBook = mtBookMapper.selectById(mtBookItem.getBookId()); + if (mtBook != null) { + bookItemDto.setBookName(mtBook.getName()); + } + if (mtBookItem.getGoodsId() != null && mtBookItem.getGoodsId() > 0) { + MtOrderGoods mtOrderGoods = mtOrderGoodsMapper.selectById(mtBookItem.getGoodsId()); + if (mtOrderGoods != null) { + MtGoods mtGoods = mtGoodsMapper.selectById(mtOrderGoods.getGoodsId()); + if (mtGoods != null) { + bookItemDto.setGoodsName(mtGoods.getName()); + } + } + } + bookItemDto.setStatusName(BookStatusEnum.getValue(bookItemDto.getStatus())); + dataList.add(bookItemDto); + } + } + + PageRequest pageRequest = PageRequest.of(bookItemPage.getPage(), bookItemPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, BookItemDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 新增预约订单 + * + * @param mtBookItem 预约信息 + * @return + */ + @Override + @OperationServiceLog(description = "新增预约订单") + public MtBookItem addBookItem(MtBookItem mtBookItem) throws BusinessCheckException, ParseException { + Integer storeId = mtBookItem.getStoreId() == null ? 0 : mtBookItem.getStoreId(); + if (mtBookItem.getMerchantId() == null || mtBookItem.getMerchantId() <= 0) { + throw new BusinessCheckException("新增预约订单失败:所属商户不能为空!"); + } + if (mtBookItem.getMerchantId() == null || mtBookItem.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + mtBookItem.setMerchantId(mtStore.getMerchantId()); + } + } + + BookableParam param = new BookableParam(); + param.setBookId(mtBookItem.getBookId()); + param.setDate(mtBookItem.getServiceDate()); + param.setTime(mtBookItem.getServiceTime()); + List bookable = bookService.isBookable(param); + if (bookable.size() <= 0) { + throw new BusinessCheckException("当前时间段不可预约,请重新选择!"); + } + + Map params = new HashMap<>(); + params.put("merchantId", mtBookItem.getMerchantId()); + params.put("storeId", mtBookItem.getMerchantId()); + params.put("bookId", mtBookItem.getBookId()); + params.put("mobile", mtBookItem.getMobile()); + if (mtBookItem.getGoodsId() != null && mtBookItem.getGoodsId() > 0) { + params.put("goodsId", mtBookItem.getGoodsId()); + } + params.put("status", BookStatusEnum.CREATED.getKey()); + List data = queryBookItemListByParams(params); + if (data != null && data.size() > 0) { + throw new BusinessCheckException("您已提交预约,请等待确认!"); + } + + mtBookItem.setStatus(BookStatusEnum.CREATED.getKey()); + mtBookItem.setUpdateTime(new Date()); + mtBookItem.setCreateTime(new Date()); + mtBookItem.setVerifyCode(SeqUtil.getRandomNumber(4)); + Integer id = mtBookItemMapper.insert(mtBookItem); + if (id > 0) { + return mtBookItem; + } else { + logger.error("新增预约记录失败."); + throw new BusinessCheckException("抱歉,新增预约记录失败!"); + } + } + + /** + * 根据ID获取预约订单信息 + * + * @param id 预约订单ID + * @return + */ + @Override + public MtBookItem getBookItemById(Integer id) { + return mtBookItemMapper.selectById(id); + } + + /** + * 获取用户预约订单信息 + * + * @param bookId 预约项目ID + * @param userId 用户ID + * @param orderGoodsId 订单商品ID + * @return + */ + public MtBookItem getUserBookItem(Integer bookId, Integer userId, Integer orderGoodsId) { + Map params = new HashMap<>(); + params.put("bookId", bookId); + params.put("userId", userId); + params.put("goodsId", orderGoodsId); + List bookItemList = queryBookItemListByParams(params); + if (bookItemList != null && bookItemList.size() > 0) { + return bookItemList.get(0); + } + return null; + } + + /** + * 根据ID获取预约订单详情 + * + * @param id 预约订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public BookItemDto getBookDetail(Integer id) throws BusinessCheckException { + MtBookItem mtBookItem = mtBookItemMapper.selectById(id); + if (mtBookItem == null) { + throw new BusinessCheckException("预约不存在."); + } + BookItemDto bookItemDto = new BookItemDto(); + BeanUtils.copyProperties(mtBookItem, bookItemDto); + + MtBook mtBook = mtBookMapper.selectById(mtBookItem.getBookId()); + if (mtBook != null) { + bookItemDto.setBookName(mtBook.getName()); + } + + if (mtBookItem.getStoreId() != null) { + MtStore mtStore = mtStoreMapper.selectById(mtBookItem.getStoreId()); + if (mtStore != null) { + bookItemDto.setStoreInfo(mtStore); + } + } + bookItemDto.setStatusName(BookStatusEnum.getValue(bookItemDto.getStatus())); + return bookItemDto; + } + + /** + * 修改预约订单 + * + * @param mtBookItem + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改预约订单") + public MtBookItem updateBookItem(MtBookItem mtBookItem) throws BusinessCheckException { + MtBookItem bookItem = getBookItemById(mtBookItem.getId()); + if (bookItem == null) { + throw new BusinessCheckException("该预约订单信息异常"); + } + + bookItem.setId(mtBookItem.getId()); + if (mtBookItem.getBookId() != null) { + bookItem.setBookId(mtBookItem.getBookId()); + } + if (mtBookItem.getStoreId() != null) { + bookItem.setStoreId(mtBookItem.getStoreId()); + } + if (mtBookItem.getRemark() != null) { + bookItem.setRemark(mtBookItem.getRemark()); + } + if (mtBookItem.getOperator() != null) { + bookItem.setOperator(mtBookItem.getOperator()); + } + if (mtBookItem.getStatus() != null) { + bookItem.setStatus(mtBookItem.getStatus()); + } + if (mtBookItem.getMobile() != null) { + bookItem.setMobile(mtBookItem.getMobile()); + } + + bookItem.setUpdateTime(new Date()); + mtBookItemMapper.updateById(bookItem); + return bookItem; + } + + /** + * 根据条件搜索预约订单 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryBookItemListByParams(Map params) { + String status = params.get("status") == null ? "" : params.get("status").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + String mobile = params.get("mobile") == null ? "" : params.get("mobile").toString(); + String contact = params.get("contact") == null ? "" : params.get("contact").toString(); + String bookId = params.get("bookId") == null ? "" : params.get("bookId").toString(); + String userId = params.get("userId") == null ? "" : params.get("userId").toString(); + String goodsId = params.get("goodsId") == null ? "" : params.get("goodsId").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBookItem::getStatus, BookStatusEnum.DELETE.getKey()); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtBookItem::getMobile, mobile); + } + if (StringUtils.isNotBlank(contact)) { + lambdaQueryWrapper.like(MtBookItem::getContact, contact); + } + if (StringUtils.isNotBlank(bookId)) { + lambdaQueryWrapper.like(MtBookItem::getBookId, bookId); + } + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.like(MtBookItem::getUserId, userId); + } + if (StringUtils.isNotBlank(goodsId)) { + lambdaQueryWrapper.like(MtBookItem::getGoodsId, goodsId); + } + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtBookItem::getStatus, status); + } + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtBookItem::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtBookItem::getStoreId, storeId); + } + lambdaQueryWrapper.orderByDesc(MtBookItem::getId); + return mtBookItemMapper.selectList(lambdaQueryWrapper); + } + + /** + * 取消预约 + * + * @param id 预约ID + * @param remark 备注信息 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional + public Boolean cancelBook(Integer id, String remark) throws BusinessCheckException { + MtBookItem mtBookItem = getBookItemById(id); + if (mtBookItem == null) { + throw new BusinessCheckException("该预约订单信息异常"); + } + if (StringUtil.isNotEmpty(remark)) { + mtBookItem.setRemark(mtBookItem.getRemark() == null ? remark : mtBookItem.getRemark() + remark); + } + mtBookItem.setStatus(BookStatusEnum.CANCEL.getKey()); + mtBookItemMapper.updateById(mtBookItem); + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/BookServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/BookServiceImpl.java new file mode 100644 index 0000000..f7a7ade --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/BookServiceImpl.java @@ -0,0 +1,403 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.BookDto; +import com.fuint.common.dto.DayDto; +import com.fuint.common.dto.TimeDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.BookPage; +import com.fuint.common.param.BookableParam; +import com.fuint.common.service.BookService; +import com.fuint.common.service.SettingService; +import com.fuint.common.service.StoreService; +import com.fuint.common.util.DateUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtBookItemMapper; +import com.fuint.repository.mapper.MtBookMapper; +import com.fuint.repository.model.MtBanner; +import com.fuint.repository.model.MtBook; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; + +/** + * 预约服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class BookServiceImpl extends ServiceImpl implements BookService { + + private static final Logger logger = LoggerFactory.getLogger(BookServiceImpl.class); + + private MtBookMapper mtBookMapper; + + private MtBookItemMapper mtBookItemMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 分页查询预约列表 + * + * @param bookPage + * @return + */ + @Override + public PaginationResponse queryBookListByPagination(BookPage bookPage) { + Page pageHelper = PageHelper.startPage(bookPage.getPage(), bookPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtBook::getStatus, StatusEnum.DISABLE.getKey()); + + String name = bookPage.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtBook::getName, name); + } + Integer cateId = bookPage.getCateId(); + if (cateId != null && cateId > 0) { + lambdaQueryWrapper.like(MtBook::getCateId, cateId); + } + if (StringUtils.isNotBlank(bookPage.getStatus())) { + lambdaQueryWrapper.eq(MtBook::getStatus, bookPage.getStatus()); + } + Integer merchantId = bookPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtBook::getMerchantId, merchantId); + } + if (bookPage.getStoreId() != null) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtBook::getStoreId, 0) + .or() + .eq(MtBook::getStoreId, bookPage.getStoreId())); + } + + lambdaQueryWrapper.orderByAsc(MtBook::getSort); + List bookList = mtBookMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + String baseImage = settingService.getUploadBasePath(); + if (bookList != null && bookList.size() > 0) { + for (MtBook mtBook : bookList) { + BookDto bookDto = new BookDto(); + BeanUtils.copyProperties(mtBook, bookDto); + bookDto.setLogo(baseImage + mtBook.getLogo()); + dataList.add(bookDto); + } + } + + PageRequest pageRequest = PageRequest.of(bookPage.getPage(), bookPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, BookDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加预约项目 + * + * @param mtBook 预约信息 + * @return + */ + @Override + @OperationServiceLog(description = "添加预约项目") + public MtBook addBook(MtBook mtBook) throws BusinessCheckException { + Integer storeId = mtBook.getStoreId() == null ? 0 : mtBook.getStoreId(); + if (mtBook.getMerchantId() == null || mtBook.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + mtBook.setMerchantId(mtStore.getMerchantId()); + } + } + if (mtBook.getMerchantId() == null || mtBook.getMerchantId() <= 0) { + throw new BusinessCheckException("新增预约失败:所属商户不能为空!"); + } + if (StringUtil.isEmpty(mtBook.getName())) { + throw new BusinessCheckException("新增预约失败:项目名称不能为空!"); + } + if (StringUtil.isEmpty(mtBook.getLogo())) { + throw new BusinessCheckException("新增预约失败:封面图片不能为空!"); + } + mtBook.setStoreId(storeId); + mtBook.setStatus(StatusEnum.ENABLED.getKey()); + mtBook.setUpdateTime(new Date()); + mtBook.setCreateTime(new Date()); + Integer id = mtBookMapper.insert(mtBook); + if (id > 0) { + return mtBook; + } else { + logger.error("新增预约失败."); + throw new BusinessCheckException("抱歉,新增预约失败!"); + } + } + + /** + * 根据ID获取预约项目信息 + * + * @param id 预约项目ID + * @param fillDate 填充日期 + * @return + */ + @Override + public BookDto getBookById(Integer id, boolean fillDate) throws ParseException { + BookDto bookDto = new BookDto(); + MtBook mtBook = mtBookMapper.selectById(id); + if (mtBook == null) { + return null; + } + BeanUtils.copyProperties(mtBook, bookDto); + + List dateList = new ArrayList<>(); + String serviceDates = mtBook.getServiceDates(); + + // 未填写日期,则未来7天都可以预约 + if (StringUtil.isEmpty(serviceDates)) { + List dates = new ArrayList<>(); + LocalDate today = LocalDate.now(); + for (int i = 0; i < 7; i++) { + LocalDate date = today.plusDays(i + 1); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String dateString = date.format(formatter); + dates.add(dateString); + } + serviceDates = String.join(",", dates); + if (fillDate) { + bookDto.setServiceDates(serviceDates); + } + } + + if (StringUtil.isNotEmpty(serviceDates)) { + List dates = Arrays.asList(serviceDates.split(",").clone()); + if (dates.size() > 0) { + for (String date : dates) { + Date currentDate = DateUtil.parseDate(date + " 23:59:59"); + Date now = new Date(); + SimpleDateFormat format = new SimpleDateFormat("EEEE", Locale.CHINA); + String week = format.format(currentDate); + DayDto day = new DayDto(); + day.setWeek(week); + day.setDate(DateUtil.formatDate(currentDate, "MM-dd")); + if (now.compareTo(currentDate) <= 0) { + day.setEnable(true); + } else { + day.setEnable(false); + } + dateList.add(day); + } + } + } + bookDto.setDateList(dateList); + + List timeList = new ArrayList<>(); + String serviceTimes = mtBook.getServiceTimes(); + + // 未填写时段,则未来 + if (StringUtil.isEmpty(serviceTimes)) { + serviceTimes = "08:30-12:00-1,14:00-18:00-1"; + } + + if (StringUtil.isNotEmpty(serviceTimes) && bookDto.getDateList().size() > 0) { + List times = Arrays.asList(serviceTimes.split(",").clone()); + if (times.size() > 0) { + for (String time : times) { + TimeDto timeDto = new TimeDto(); + String arr[] = time.split("-"); + timeDto.setTime(arr[0] + "-" + arr[1]); + timeDto.setEnable(true); + timeList.add(timeDto); + } + } + } + bookDto.setTimeList(timeList); + + return bookDto; + } + + /** + * 修改预约项目 + * + * @param mtBook + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改预约项目") + public MtBook updateBook(MtBook mtBook) throws BusinessCheckException { + MtBook book = mtBookMapper.selectById(mtBook.getId()); + if (book == null) { + throw new BusinessCheckException("该预约项目状态异常"); + } + if (mtBook.getLogo() != null) { + book.setLogo(mtBook.getLogo()); + } + if (mtBook.getCateId() != null) { + book.setCateId(mtBook.getCateId()); + } + if (book.getName() != null) { + book.setName(mtBook.getName()); + } + if (mtBook.getStoreId() != null) { + book.setStoreId(mtBook.getStoreId()); + } + if (mtBook.getDescription() != null) { + book.setDescription(mtBook.getDescription()); + } + if (mtBook.getOperator() != null) { + book.setOperator(mtBook.getOperator()); + } + if (mtBook.getStatus() != null) { + book.setStatus(mtBook.getStatus()); + } + if (mtBook.getGoodsId() != null) { + book.setGoodsId(mtBook.getGoodsId()); + } + if (mtBook.getSort() != null) { + book.setSort(mtBook.getSort()); + } + if (mtBook.getServiceDates() != null) { + book.setServiceDates(mtBook.getServiceDates()); + } + if (mtBook.getServiceTimes() != null) { + book.setServiceTimes(mtBook.getServiceTimes()); + } + if (mtBook.getServiceStaffIds() != null) { + book.setServiceStaffIds(mtBook.getServiceStaffIds()); + } + book.setUpdateTime(new Date()); + mtBookMapper.updateById(book); + return book; + } + + /** + * 是否可预约 + * + * @param param + * @throws BusinessCheckException + * @return + * */ + @Override + public List isBookable(BookableParam param) throws BusinessCheckException, ParseException { + MtBook mtBook = mtBookMapper.selectById(param.getBookId()); + List result = new ArrayList<>(); + if (mtBook == null) { + throw new BusinessCheckException("预约项目不存在"); + } + + List bookList = new ArrayList<>(); + if (StringUtil.isNotEmpty(param.getDate())) { + bookList = mtBookItemMapper.getBookList(param.getBookId(), param.getDate(), param.getTime()); + } + Integer bookNum = bookList.size(); + + Integer limit = 0; + String serviceTime = mtBook.getServiceTimes(); + + // 未填写时段,则未来 + if (StringUtil.isEmpty(serviceTime)) { + serviceTime = "08:30-12:00-1,14:00-18:00-1"; + } + + if (StringUtil.isNotEmpty(serviceTime)) { + String[] times = serviceTime.split(","); + if (times.length > 0) { + for (String str : times) { + if (str.indexOf(param.getTime()) >= 0) { + String[] timeArr = str.split("-"); + if (timeArr.length > 2) { + limit = Integer.parseInt(timeArr[2]); + } + } + } + } + } + Date now = new Date(); + if (bookNum < limit) { + if (StringUtil.isNotEmpty(param.getTime())) { + String[] arr = param.getTime().split("-"); + String dateTime = param.getDate() + " " + arr[1]+":00"; + Date currentDate = DateUtil.parseDate(dateTime); + if (now.compareTo(currentDate) < 0) { + result.add(param.getTime()); + } + } else { + String[] times = mtBook.getServiceTimes().split(","); + if (times.length > 0) { + for (String str : times) { + String[] arr = str.split("-"); + if (arr.length > 2) { + String item = arr[0] + "-" + arr[1]; + String dateTime = param.getDate() + " " + arr[1]+":00"; + Date currentDate = DateUtil.parseDate(dateTime); + if (!bookList.contains(item) && now.compareTo(currentDate) < 0) { + result.add(item); + } + } + } + } + } + } + return result; + } + + /** + * 获取预约项目列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + public List getBookList(Integer merchantId, Integer storeId) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(MtBook::getStatus, StatusEnum.ENABLED.getKey()); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtBook::getMerchantId, merchantId); + } + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtBook::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByAsc(MtBook::getSort); + List dataList = mtBookMapper.selectList(lambdaQueryWrapper); + String baseImage = settingService.getUploadBasePath(); + + if (dataList.size() > 0) { + for (MtBook book : dataList) { + book.setLogo(baseImage + book.getLogo()); + } + } + + return dataList; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CaptchaServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CaptchaServiceImpl.java new file mode 100644 index 0000000..87df6a6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CaptchaServiceImpl.java @@ -0,0 +1,107 @@ +package com.fuint.common.service.impl; + +import com.fuint.common.util.RedisUtil; +import com.fuint.common.service.CaptchaService; +import com.google.code.kaptcha.Constants; +import com.google.code.kaptcha.Producer; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import javax.servlet.http.HttpSession; +import java.awt.image.BufferedImage; + +/** + * 图形验证码插件服务类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CaptchaServiceImpl implements CaptchaService { + + private static final Logger logger = LoggerFactory.getLogger(CaptchaServiceImpl.class); + + /** + * 图形验证码生成器 + * */ + private Producer captchaProducer; + + /** + * 生成图形验证码,并保存至Session + * @param session Session + * @return BufferedImage + */ + public BufferedImage getCode(HttpSession session){ + // 生成验证码 + String codeText = captchaProducer.createText(); + BufferedImage codeImage = captchaProducer.createImage(codeText); + logger.info("生成验证码{}", codeText); + + // 设置Session信息 + if (session != null) { + session.setAttribute(Constants.KAPTCHA_SESSION_KEY, codeText); + } + + return codeImage; + } + + /** + * 图形验证码校验 + * @param code 输入的验证码 + * @param session Session + * @return Boolean + */ + public Boolean checkCode(String code, HttpSession session){ + String sessionCode = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY); + if (StringUtil.isEmpty(code) || StringUtil.isEmpty(sessionCode)) { + return false; + } else { + if (code.equalsIgnoreCase(sessionCode)) { + return true; + } else { + return false; + } + } + } + + /** + * 生成图形验证码 + * @return BufferedImage + */ + public BufferedImage getCodeByUuid(String uuid) { + // 生成验证码 + String codeText = captchaProducer.createText(); + BufferedImage codeImage = captchaProducer.createImage(codeText); + logger.info("生成验证码 = {}, uuid = {}", codeText, uuid); + + if (codeText != null) { + RedisUtil.set(uuid, codeText, 1800); + } + + return codeImage; + } + + /** + * 图形验证码校验 + * @param code 输入的验证码 + * @param uuid uuid + * @return Boolean + */ + public Boolean checkCodeByUuid(String code, String uuid){ + String vCode = RedisUtil.get(uuid); + logger.info("checkCodeByUuid vCode = {}, code = {}, uuid = {}", vCode, code, uuid); + if (StringUtil.isEmpty(code) || StringUtil.isEmpty(vCode)) { + return false; + } else { + if (code.equalsIgnoreCase(vCode)) { + return true; + } else { + return false; + } + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CartServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CartServiceImpl.java new file mode 100644 index 0000000..7a9d601 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CartServiceImpl.java @@ -0,0 +1,322 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.CartService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.repository.mapper.MtCartMapper; +import com.fuint.repository.mapper.MtGoodsMapper; +import com.fuint.repository.mapper.MtGoodsSkuMapper; +import com.fuint.repository.model.MtCart; +import com.fuint.repository.model.MtGoods; +import com.fuint.repository.model.MtGoodsSku; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Date; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 购物车业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CartServiceImpl extends ServiceImpl implements CartService { + + private MtCartMapper mtCartMapper; + + private MtGoodsMapper mtGoodsMapper; + + private MtGoodsSkuMapper mtGoodsSkuMapper; + + /** + * 切换购物车给会员 + * + * @param userId 会员ID + * @param cartIds 购物车ID + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean switchCartIds(Integer userId, String cartIds) { + if (userId == null || userId < 1 || StringUtil.isEmpty(cartIds)) { + return false; + } + List cartIdList = Arrays.asList(cartIds.split(",")); + if (cartIdList != null && cartIdList.size() > 0) { + for (String cartId : cartIdList) { + if (StringUtil.isNotEmpty(cartId)) { + MtCart mtCart = mtCartMapper.selectById(Integer.parseInt(cartId)); + if (mtCart != null) { + mtCart.setUserId(userId); + this.updateById(mtCart); + } + } + } + } + return true; + } + + /** + * 保存购物车 + * + * @param reqDto 购物车参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Integer saveCart(MtCart reqDto, String action) throws BusinessCheckException { + if (reqDto.getId() == null && (reqDto.getMerchantId() == null || reqDto.getMerchantId() < 1)) { + throw new BusinessCheckException("商户不能为空"); + } + if (reqDto.getId() == null && (reqDto.getStoreId() == null || reqDto.getStoreId() < 1)) { + throw new BusinessCheckException("店铺不能为空"); + } + + MtCart mtCart = new MtCart(); + Integer cartId = 1; + + // 检查库存是否充足 + if (action.equals("+") || action.equals("=") && reqDto.getNum() > 0) { + MtGoods mtGoods = mtGoodsMapper.selectById(reqDto.getGoodsId()); + Map param = new HashMap<>(); + param.put("status", StatusEnum.ENABLED.getKey()); + param.put("USER_ID", reqDto.getUserId()); + param.put("GOODS_ID", reqDto.getGoodsId()); + param.put("MERCHANT_ID", reqDto.getMerchantId()); + if (reqDto.getSkuId() != null && reqDto.getSkuId() > 0) { + param.put("SKU_ID", reqDto.getSkuId()); + } + List cartList = mtCartMapper.selectByMap(param); + Double cartNum = 0.0; + if (cartList != null && cartList.size() > 0) { + cartNum = cartList.get(0).getNum(); + } + // 剩余库存数量 + Double totalStock = 0.0; + if (reqDto.getSkuId() != null && reqDto.getSkuId() > 0) { + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(reqDto.getSkuId()); + if (mtGoodsSku != null && mtGoodsSku.getStock() != null) { + totalStock = mtGoodsSku.getStock(); + } + } else { + totalStock = mtGoods.getStock(); + } + // 判断库存,库存小于要添加的购物车数量、已添加的购物车数量大于库存 + if (totalStock < reqDto.getNum() || totalStock <= cartNum) { + if (action.equals("=") && reqDto.getNum() < cartNum) { + // empty + } else { + throw new BusinessCheckException(mtGoods.getName() + "库存不足了"); + } + } + } + + if (reqDto.getGoodsId() > 0) { + mtCart.setGoodsId(reqDto.getGoodsId()); + } + if (reqDto.getUserId() > 0) { + mtCart.setUserId(reqDto.getUserId()); + } + + // 数量为0,删除购物车 + if (reqDto.getNum() == 0 && reqDto.getId() > 0) { + this.removeCart(reqDto.getId()+""); + } else if (reqDto.getNum() == 0 && action.equals("-")) { + mtCartMapper.deleteCartItem(reqDto.getUserId(), reqDto.getGoodsId(), reqDto.getSkuId()); + } + + // 校验skuId是否正确 + if (reqDto.getSkuId() != null) { + if (reqDto.getSkuId() > 0) { + Map param = new HashMap<>(); + param.put("goods_id", reqDto.getGoodsId().toString()); + param.put("id", reqDto.getSkuId().toString()); + List skuList = mtGoodsSkuMapper.selectByMap(param); + // 该skuId不正常 + if (skuList.size() < 1) { + reqDto.setSkuId(0); + } + } + } + + mtCart.setMerchantId(reqDto.getMerchantId()); + mtCart.setStoreId(reqDto.getStoreId() == null ? 0 : reqDto.getStoreId()); + mtCart.setStatus(StatusEnum.ENABLED.getKey()); + mtCart.setUpdateTime(new Date()); + mtCart.setSkuId(reqDto.getSkuId()); + mtCart.setNum(reqDto.getNum()); + mtCart.setHangNo(reqDto.getHangNo()); + mtCart.setIsVisitor(reqDto.getIsVisitor()); + + Map params = new HashMap<>(); + params.put("userId", mtCart.getUserId()); + params.put("storeId", mtCart.getStoreId()); + params.put("goodsId", mtCart.getGoodsId()); + params.put("skuId", mtCart.getSkuId()); + params.put("hangNo", reqDto.getHangNo() == null ? "" : reqDto.getHangNo()); + + List cartList = queryCartListByParams(params); + if (action.equals("-") && cartList.size() == 0) { + return cartId; + } + // 已存在,仅操作数量增加或减少 + if (cartList.size() > 0 && (mtCart.getId() == null || mtCart.getId() < 1)) { + mtCart = cartList.get(0); + mtCart.setMerchantId(reqDto.getMerchantId()); + if (action.equals("+")) { + mtCart.setNum(mtCart.getNum() + reqDto.getNum()); + } else if (action.equals("=")) { + mtCart.setNum(reqDto.getNum()); + } else { + Double num = mtCart.getNum() - 1; + if (num <= 0) { + this.removeCart(mtCart.getId()+""); + return mtCart.getId(); + } else { + mtCart.setNum(mtCart.getNum() - 1); + } + } + this.updateById(mtCart); + } else { + mtCart.setCreateTime(new Date()); + this.save(mtCart); + } + + return mtCart.getId(); + } + + /** + * 删除购物车 + * + * @param cartIds 购物车ID + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void removeCart(String cartIds) { + String[] ids = cartIds.split(","); + if (ids.length < 1) { + return; + } + for (int i = 0; i < ids.length; i++) { + MtCart mtCart = mtCartMapper.selectById(Integer.parseInt(ids[i].trim())); + if (mtCart != null) { + mtCartMapper.deleteById(mtCart.getId()); + } + } + } + + /** + * 删除挂单购物车 + * + * @param hangNo 挂单序号 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除挂单") + @Transactional(rollbackFor = Exception.class) + public void removeCartByHangNo(String hangNo) { + if (hangNo != null && StringUtil.isNotEmpty(hangNo)) { + mtCartMapper.deleteCartByHangNo(hangNo); + } + } + + /** + * 清空会员购物车 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void clearCart(Integer userId) { + mtCartMapper.clearCart(userId); + } + + /** + * 根据条件查找 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryCartListByParams(Map params) { + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey() : params.get("status").toString(); + String userId = params.get("userId") == null ? "" : params.get("userId").toString(); + String ids = params.get("ids") == null ? "" : params.get("ids").toString(); + String hangNo = params.get("hangNo") == null ? "" : params.get("hangNo").toString(); + String goodsId = params.get("goodsId") == null ? "" : params.get("goodsId").toString(); + String skuId = params.get("skuId") == null ? "" : params.get("skuId").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(MtCart::getStatus, status); + + if (StringUtil.isNotEmpty(userId)) { + lambdaQueryWrapper.eq(MtCart::getUserId, userId); + } + if (StringUtil.isNotEmpty(ids)) { + List idList = Arrays.asList(ids.split(",")); + lambdaQueryWrapper.in(MtCart::getId, idList); + if (StringUtil.isNotEmpty(hangNo)) { + lambdaQueryWrapper.eq(MtCart::getHangNo, hangNo); + } + } else { + lambdaQueryWrapper.eq(MtCart::getHangNo, hangNo); + } + if (StringUtil.isNotEmpty(goodsId)) { + lambdaQueryWrapper.eq(MtCart::getGoodsId, goodsId); + } + if (StringUtil.isNotEmpty(merchantId) && Integer.parseInt(merchantId) > 0) { + lambdaQueryWrapper.eq(MtCart::getMerchantId, merchantId); + } + if (StringUtil.isNotEmpty(storeId) && Integer.parseInt(storeId) > 0) { + lambdaQueryWrapper.eq(MtCart::getStoreId, storeId); + } + if (StringUtil.isNotEmpty(skuId)) { + lambdaQueryWrapper.eq(MtCart::getSkuId, skuId); + } + + return mtCartMapper.selectList(lambdaQueryWrapper); + } + + /** + * 更新购物车 + * + * @param cartId ID + * @param hangNo 挂单序号 + * @param isVisitor 是否游客 + * @return + */ + @Override + @OperationServiceLog(description = "执行挂单") + @Transactional(rollbackFor = Exception.class) + public MtCart setHangNo(Integer cartId, String hangNo, String isVisitor) throws BusinessCheckException { + MtCart mtCart = mtCartMapper.selectById(cartId); + if (mtCart != null) { + mtCart.setHangNo(hangNo); + mtCart.setUpdateTime(new Date()); + mtCart.setIsVisitor(isVisitor); + this.updateById(mtCart); + } else { + throw new BusinessCheckException("执行挂单失败"); + } + return mtCart; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CateServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CateServiceImpl.java new file mode 100644 index 0000000..c12f0af --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CateServiceImpl.java @@ -0,0 +1,287 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.GoodsCateDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.GoodsCatePage; +import com.fuint.common.service.CateService; +import com.fuint.common.service.StoreService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtGoodsCateMapper; +import com.fuint.repository.mapper.MtGoodsMapper; +import com.fuint.repository.model.MtGoods; +import com.fuint.repository.model.MtGoodsCate; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 商品分类业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CateServiceImpl extends ServiceImpl implements CateService { + + private static final Logger log = LoggerFactory.getLogger(CateServiceImpl.class); + + private MtGoodsMapper mtGoodsMapper; + + private MtGoodsCateMapper cateMapper; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 分页查询分类列表 + * + * @param catePage + * @return + */ + @Override + public PaginationResponse queryCateListByPagination(GoodsCatePage catePage) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(catePage.getPage(), catePage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtGoodsCate::getStatus, StatusEnum.DISABLE.getKey()); + + String name = catePage.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtGoodsCate::getName, name); + } + String status = catePage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtGoodsCate::getStatus, status); + } + Integer merchantId = catePage.getMerchantId(); + if (merchantId != null) { + lambdaQueryWrapper.eq(MtGoodsCate::getMerchantId, merchantId); + } + Integer storeId = catePage.getStoreId(); + if (storeId != null) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtGoodsCate::getStoreId, 0) + .or() + .eq(MtGoodsCate::getStoreId, storeId)); + } + lambdaQueryWrapper.orderByAsc(MtGoodsCate::getSort); + List dataList = new ArrayList<>(); + List cateList = cateMapper.selectList(lambdaQueryWrapper); + for (MtGoodsCate mtCate : cateList) { + GoodsCateDto cateDto = new GoodsCateDto(); + BeanUtils.copyProperties(mtCate, cateDto); + if (mtCate.getStoreId() != null && mtCate.getStoreId() > 0) { + MtStore storeInfo = storeService.queryStoreById(mtCate.getStoreId()); + if (storeInfo != null) { + cateDto.setStoreName(storeInfo.getName()); + } + } + dataList.add(cateDto); + } + PageRequest pageRequest = PageRequest.of(catePage.getPage(), catePage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, GoodsCateDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加商品分类 + * + * @param reqDto 商品分类参数 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "新增商品分类") + public MtGoodsCate addCate(MtGoodsCate reqDto) throws BusinessCheckException { + MtGoodsCate mtCate = new MtGoodsCate(); + if (null != reqDto.getId()) { + mtCate.setId(reqDto.getId()); + } + Integer storeId = reqDto.getStoreId() == null ? 0 : reqDto.getStoreId(); + if (storeId > 0 && (reqDto.getMerchantId() == null || reqDto.getMerchantId() <= 0)) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + reqDto.setMerchantId(mtStore.getMerchantId()); + } + } + if (reqDto.getMerchantId() == null || reqDto.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + mtCate.setName(reqDto.getName()); + mtCate.setStatus(StatusEnum.ENABLED.getKey()); + mtCate.setLogo(reqDto.getLogo()); + mtCate.setDescription(reqDto.getDescription()); + mtCate.setOperator(reqDto.getOperator()); + mtCate.setMerchantId(reqDto.getMerchantId()); + mtCate.setStoreId(storeId); + mtCate.setUpdateTime(new Date()); + mtCate.setCreateTime(new Date()); + this.save(mtCate); + return mtCate; + } + + /** + * 根据ID获取分类信息 + * + * @param id 分类ID + * @throws BusinessCheckException + */ + @Override + public MtGoodsCate queryCateById(Integer id) { + return cateMapper.selectById(id); + } + + /** + * 根据ID删除分类信息 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + @Override + @OperationServiceLog(description = "删除商品分类") + public void deleteCate(Integer id, String operator) throws BusinessCheckException { + MtGoodsCate cateInfo = queryCateById(id); + + Map params = new HashMap<>(); + params.put("cate_id", id); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("merchant_id", cateInfo.getMerchantId()); + List goodsList = mtGoodsMapper.selectByMap(params); + if (goodsList != null && goodsList.size() > 0) { + throw new BusinessCheckException("删除失败,该分类有商品存在"); + } + if (null == cateInfo) { + return; + } + cateInfo.setStatus(StatusEnum.DISABLE.getKey()); + cateInfo.setUpdateTime(new Date()); + + this.updateById(cateInfo); + } + + /** + * 修改分类 + * + * @param reqDto + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新商品分类") + public MtGoodsCate updateCate(MtGoodsCate reqDto) throws BusinessCheckException { + MtGoodsCate mtCate = queryCateById(reqDto.getId()); + if (null == mtCate) { + log.error("该分类状态异常"); + throw new BusinessCheckException("该分类状态异常"); + } + if (mtCate.getMerchantId() == null || mtCate.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + mtCate.setId(reqDto.getId()); + if (reqDto.getLogo() != null) { + mtCate.setLogo(reqDto.getLogo()); + } + if (reqDto.getName() != null) { + mtCate.setName(reqDto.getName()); + } + if (reqDto.getDescription() != null) { + mtCate.setDescription(reqDto.getDescription()); + } + mtCate.setUpdateTime(new Date()); + if (StringUtil.isNotEmpty(reqDto.getOperator())) { + mtCate.setOperator(reqDto.getOperator()); + } + if (reqDto.getStatus() != null) { + if (reqDto.getStatus().equals(StatusEnum.DISABLE.getKey())) { + deleteCate(mtCate.getId(), reqDto.getOperator()); + } + mtCate.setStatus(reqDto.getStatus()); + } + if (reqDto.getSort() != null) { + mtCate.setSort(reqDto.getSort()); + } + if (reqDto.getMerchantId() != null && reqDto.getMerchantId() > 0) { + mtCate.setMerchantId(reqDto.getMerchantId()); + } + if (reqDto.getStoreId() != null) { + mtCate.setStoreId(reqDto.getStoreId()); + } + this.updateById(mtCate); + return mtCate; + } + + /** + * 获取分类列表 + * + * @param merchantId 商户 + * @param storeId 店铺ID + * @param name 店铺名称 + * @param status 状态 + * @return + * */ + @Override + public List getCateList(Integer merchantId, Integer storeId, String name, String status) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtGoodsCate::getStatus, StatusEnum.DISABLE.getKey()); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtGoodsCate::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtGoodsCate::getName, name); + } + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtGoodsCate::getStatus, status); + } + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtGoodsCate::getStoreId, 0) + .or() + .eq(MtGoodsCate::getStoreId, storeId)); + } + lambdaQueryWrapper.orderByAsc(MtGoodsCate::getSort); + return cateMapper.selectList(lambdaQueryWrapper); + } + + /** + * 获取分类ID + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param name 分类名称 + * @return + * */ + @Override + public Integer getGoodsCateId(Integer merchantId, Integer storeId, String name) { + Integer cateId = 0; + List cateList = getCateList(merchantId, storeId, name, StatusEnum.ENABLED.getKey()); + if (cateList != null && cateList.size() > 0) { + cateId = cateList.get(0).getId(); + } + return cateId; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionCashServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionCashServiceImpl.java new file mode 100644 index 0000000..5eae852 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionCashServiceImpl.java @@ -0,0 +1,434 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.CommissionCashDto; +import com.fuint.common.dto.OrderUserDto; +import com.fuint.common.enums.CommissionCashStatusEnum; +import com.fuint.common.enums.CommissionStatusEnum; +import com.fuint.common.enums.CommissionTargetEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.CommissionCashPage; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.CommissionCashRequest; +import com.fuint.module.backendApi.request.CommissionLogRequest; +import com.fuint.module.backendApi.request.CommissionSettleConfirmRequest; +import com.fuint.module.backendApi.request.CommissionSettleRequest; +import com.fuint.repository.mapper.MtCommissionCashMapper; +import com.fuint.repository.mapper.MtCommissionLogMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +/** + * 分销提成提现服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CommissionCashServiceImpl extends ServiceImpl implements CommissionCashService { + + private static final Logger logger = LoggerFactory.getLogger(CommissionCashServiceImpl.class); + + private MtCommissionCashMapper mtCommissionCashMapper; + + private MtCommissionLogMapper mtCommissionLogMapper; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 员工服务接口 + * */ + private StaffService staffService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 分销提成记录业务接口 + */ + private CommissionLogService commissionLogService; + + /** + * 余额服务接口 + * */ + private BalanceService balanceService; + + /** + * 分页查询提现列表 + * + * @param commissionCashPage + * @return + */ + @Override + public PaginationResponse queryCommissionCashByPagination(CommissionCashPage commissionCashPage) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(commissionCashPage.getPage(), commissionCashPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + String status = commissionCashPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCommissionCash::getStatus, status); + } + Integer merchantId = commissionCashPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtCommissionCash::getMerchantId, merchantId); + } + Integer storeId = commissionCashPage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtCommissionCash::getStoreId, storeId); + } + String realName = commissionCashPage.getRealName(); + if (StringUtils.isNotEmpty(realName)) { + Map params = new HashMap<>(); + params.put("REAL_NAME", realName); + params.put("AUDITED_STATUS", StatusEnum.ENABLED.getKey()); + List staffList = staffService.queryStaffByParams(params); + if (staffList != null && staffList.size() > 0) { + lambdaQueryWrapper.eq(MtCommissionCash::getStaffId, staffList.get(0).getId()); + } else { + lambdaQueryWrapper.eq(MtCommissionCash::getStaffId, -1); + } + } + String mobile = commissionCashPage.getMobile(); + if (StringUtils.isNotEmpty(mobile)) { + MtStaff mtStaff = staffService.queryStaffByMobile(mobile); + if (mtStaff != null) { + lambdaQueryWrapper.eq(MtCommissionCash::getStaffId, mtStaff.getId()); + } else { + lambdaQueryWrapper.eq(MtCommissionCash::getStaffId, -1); + } + } + String uuid = commissionCashPage.getUuid(); + if (StringUtils.isNotBlank(uuid)) { + lambdaQueryWrapper.eq(MtCommissionCash::getUuid, uuid); + } + // 开始时间、结束时间 + String startTime = commissionCashPage.getStartTime(); + String endTime = commissionCashPage.getEndTime(); + if (StringUtil.isNotEmpty(startTime)) { + lambdaQueryWrapper.ge(MtCommissionCash::getCreateTime, startTime); + } + if (StringUtil.isNotEmpty(endTime)) { + lambdaQueryWrapper.le(MtCommissionCash::getCreateTime, endTime); + } + lambdaQueryWrapper.orderByDesc(MtCommissionCash::getId); + List commissionCashList = mtCommissionCashMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (commissionCashList != null && commissionCashList.size() > 0) { + for (MtCommissionCash mtCommissionCash : commissionCashList) { + CommissionCashDto commissionCashDto = new CommissionCashDto(); + BeanUtils.copyProperties(mtCommissionCash, commissionCashDto); + MtStore mtStore = storeService.getById(mtCommissionCash.getStoreId()); + commissionCashDto.setStoreInfo(mtStore); + MtStaff mtStaff = staffService.getById(mtCommissionCash.getStaffId()); + if (mtCommissionCash.getUserId() != null && mtCommissionCash.getUserId() > 0) { + MtUser userInfo = memberService.queryMemberById(mtCommissionCash.getUserId()); + if (userInfo != null) { + OrderUserDto userDto = new OrderUserDto(); + userDto.setNo(userInfo.getUserNo()); + userDto.setId(userInfo.getId()); + userDto.setName(userInfo.getName()); + userDto.setCardNo(userInfo.getIdcard()); + userDto.setAddress(userInfo.getAddress()); + userDto.setMobile(CommonUtil.hidePhone(userInfo.getMobile())); + commissionCashDto.setUserInfo(userDto); + } + } + if (mtStaff != null) { + mtStaff.setMobile(CommonUtil.hidePhone(mtStaff.getMobile())); + commissionCashDto.setStaffInfo(mtStaff); + } + dataList.add(commissionCashDto); + } + } + PageRequest pageRequest = PageRequest.of(commissionCashPage.getPage(), commissionCashPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, CommissionCashDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 分销提成结算 + * + * @param commissionSettleRequest 结算参数 + * @return + */ + @Override + @Transactional + public String settleCommission(CommissionSettleRequest commissionSettleRequest) throws BusinessCheckException { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(MtCommissionLog::getStatus, CommissionStatusEnum.NORMAL.getKey()); + if (commissionSettleRequest.getMerchantId() != null && StringUtils.isNotBlank(commissionSettleRequest.getMerchantId().toString())) { + lambdaQueryWrapper.eq(MtCommissionLog::getMerchantId, commissionSettleRequest.getMerchantId()); + } + if (commissionSettleRequest.getStoreId() != null && StringUtils.isNotBlank(commissionSettleRequest.getStoreId().toString())) { + lambdaQueryWrapper.eq(MtCommissionLog::getStoreId, commissionSettleRequest.getStoreId()); + } + String realName = commissionSettleRequest.getRealName(); + if (StringUtils.isNotBlank(realName)) { + Map params = new HashMap<>(); + params.put("REAL_NAME", realName); + params.put("AUDITED_STATUS", StatusEnum.ENABLED.getKey()); + List staffList = staffService.queryStaffByParams(params); + if (staffList != null && staffList.size() > 0) { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, staffList.get(0).getId()); + } + } + String mobile = commissionSettleRequest.getMobile(); + if (StringUtils.isNotBlank(mobile)) { + MtStaff mtStaff = staffService.queryStaffByMobile(mobile); + if (mtStaff != null) { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, mtStaff.getId()); + } + } + lambdaQueryWrapper.orderByDesc(MtCommissionLog::getId); + List commissionLogList = mtCommissionLogMapper.selectList(lambdaQueryWrapper); + List staffIds = new ArrayList<>(); + List userIds = new ArrayList<>(); + String uuid = SeqUtil.getUUID(); + if (commissionLogList != null && commissionLogList.size() > 0) { + for (MtCommissionLog mtCommissionLog : commissionLogList) { + if (mtCommissionLog.getStaffId() != null && mtCommissionLog.getStaffId() > 0 && !staffIds.contains(CommissionTargetEnum.STAFF.getKey() + mtCommissionLog.getStaffId())) { + staffIds.add(CommissionTargetEnum.STAFF.getKey() + mtCommissionLog.getStaffId()); + } else if (mtCommissionLog.getUserId() != null && mtCommissionLog.getUserId() > 0 && !userIds.contains(CommissionTargetEnum.MEMBER.getKey() + mtCommissionLog.getUserId())){ + userIds.add(CommissionTargetEnum.MEMBER.getKey() + mtCommissionLog.getUserId()); + } + } + } + staffIds.addAll(userIds); + // 生成结算数据 + if (staffIds.size() > 0) { + for (String staffId : staffIds) { + BigDecimal totalAmount = new BigDecimal("0"); + Integer cashMerchantId = 0; + Integer cashStoreId = 0; + String settleNo = CommonUtil.createSettlementNo(); + Integer targetId; + if (staffId.indexOf(CommissionTargetEnum.STAFF.getKey()) >= 0) { + targetId = Integer.parseInt(staffId.replaceAll(CommissionTargetEnum.STAFF.getKey(), "")); + } else { + targetId = Integer.parseInt(staffId.replaceAll(CommissionTargetEnum.MEMBER.getKey(), "")); + } + for (MtCommissionLog mtCommissionLog : commissionLogList) { + if (mtCommissionLog.getStaffId().equals(targetId) || mtCommissionLog.getUserId().equals(targetId)) { + if (mtCommissionLog.getType().equals(CommissionTargetEnum.STAFF.getKey()) && staffId.indexOf(CommissionTargetEnum.STAFF.getKey()) < 0) { + continue; + } + if (mtCommissionLog.getType().equals(CommissionTargetEnum.MEMBER.getKey()) && staffId.indexOf(CommissionTargetEnum.MEMBER.getKey()) < 0) { + continue; + } + totalAmount = totalAmount.add(mtCommissionLog.getAmount()); + if (mtCommissionLog.getMerchantId() != null && mtCommissionLog.getMerchantId() > 0) { + cashMerchantId = mtCommissionLog.getMerchantId(); + } + if (mtCommissionLog.getStoreId() != null && mtCommissionLog.getStoreId() > 0) { + cashStoreId = mtCommissionLog.getStoreId(); + } + CommissionLogRequest commissionLogRequest = new CommissionLogRequest(); + commissionLogRequest.setId(mtCommissionLog.getId()); + commissionLogRequest.setSettleUuid(uuid); + commissionLogRequest.setOperator(commissionSettleRequest.getOperator()); + commissionLogRequest.setStatus(CommissionStatusEnum.SETTLED.getKey()); + commissionLogService.updateCommissionLog(commissionLogRequest); + } + } + MtCommissionCash mtCommissionCash = new MtCommissionCash(); + mtCommissionCash.setSettleNo(settleNo); + mtCommissionCash.setUuid(uuid); + if (staffId.indexOf(CommissionTargetEnum.STAFF.getKey()) >= 0) { + mtCommissionCash.setStaffId(targetId); + mtCommissionCash.setUserId(0); + } else { + mtCommissionCash.setUserId(targetId); + mtCommissionCash.setStaffId(0); + } + if (cashStoreId > 0) { + mtCommissionCash.setStoreId(cashStoreId); + } + if (cashMerchantId > 0) { + mtCommissionCash.setMerchantId(cashMerchantId); + } + mtCommissionCash.setAmount(totalAmount); + Date time = new Date(); + mtCommissionCash.setCreateTime(time); + mtCommissionCash.setUpdateTime(time); + mtCommissionCash.setOperator(commissionSettleRequest.getOperator()); + mtCommissionCash.setStatus(CommissionCashStatusEnum.WAIT.getKey()); + this.save(mtCommissionCash); + } + } + return uuid; + } + + /** + * 根据ID获取记录信息 + * + * @param id 分佣提成提现ID + * @return + */ + @Override + public CommissionCashDto queryCommissionCashById(Integer id) { + MtCommissionCash mtCommissionCash = mtCommissionCashMapper.selectById(id); + CommissionCashDto commissionCashDto = null; + if (mtCommissionCash != null) { + commissionCashDto = new CommissionCashDto(); + BeanUtils.copyProperties(mtCommissionCash, commissionCashDto); + } + return commissionCashDto; + } + + /** + * 更新分销提成提现 + * + * @param requestParam 请求参数 + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "更新分销提成提现") + public void updateCommissionCash(CommissionCashRequest requestParam) throws BusinessCheckException { + MtCommissionCash mtCommissionCash = mtCommissionCashMapper.selectById(requestParam.getId()); + if (mtCommissionCash == null) { + logger.error("更新分销提成提现失败..."); + throw new BusinessCheckException("更新分销提成提现失败,数据不存在"); + } + mtCommissionCash.setUpdateTime(new Date()); + if (requestParam.getAmount() != null) { + mtCommissionCash.setAmount(new BigDecimal(requestParam.getAmount())); + } + if (requestParam.getDescription() != null) { + mtCommissionCash.setDescription(requestParam.getDescription()); + } + if (requestParam.getStatus() != null) { + mtCommissionCash.setStatus(requestParam.getStatus()); + } + mtCommissionCash.setOperator(requestParam.getOperator()); + mtCommissionCashMapper.updateById(mtCommissionCash); + } + + /** + * 结算确认 + * + * @param requestParam 确认参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "结算确认") + public void confirmCommissionCash(CommissionSettleConfirmRequest requestParam) throws BusinessCheckException { + if (StringUtil.isEmpty(requestParam.getUuid())) { + throw new BusinessCheckException("请求有误."); + } + boolean flag = mtCommissionCashMapper.confirmCommissionCash(requestParam.getMerchantId(), requestParam.getUuid(), requestParam.getOperator()); + if (flag) { + mtCommissionLogMapper.confirmCommissionLog(requestParam.getMerchantId(), requestParam.getUuid(), requestParam.getOperator()); + } + } + + /** + * 结算确认 + * + * @param requestParam 取消参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "取消结算") + public void cancelCommissionCash(CommissionSettleConfirmRequest requestParam) throws BusinessCheckException { + if (StringUtil.isEmpty(requestParam.getUuid())) { + throw new BusinessCheckException("请求参数有误"); + } + boolean flag = mtCommissionCashMapper.cancelCommissionCash(requestParam.getMerchantId(), requestParam.getUuid(), requestParam.getOperator()); + if (flag) { + mtCommissionLogMapper.cancelCommissionLog(requestParam.getMerchantId(), requestParam.getUuid(), requestParam.getOperator()); + } + } + + /** + * 支付结算金额到用户余额 + * + * @param commissionCashRequest 请求参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "支付结算金额到用户余额") + public void payToBalance(CommissionCashRequest commissionCashRequest) throws BusinessCheckException { + MtCommissionCash mtCommissionCash = mtCommissionCashMapper.selectById(commissionCashRequest.getId()); + if (mtCommissionCash == null) { + throw new BusinessCheckException("请求参数有误"); + } + if (mtCommissionCash.getStatus().equals(CommissionCashStatusEnum.PAYED.getKey())) { + throw new BusinessCheckException("该记录已经支付过了"); + } + if (mtCommissionCash.getStatus().equals(CommissionCashStatusEnum.CANCEL.getKey())) { + throw new BusinessCheckException("该记录已经作废了"); + } + BigDecimal amount = mtCommissionCash.getAmount(); + if (StringUtil.isNotBlank(commissionCashRequest.getAmount()) && (new BigDecimal(commissionCashRequest.getAmount()).compareTo(new BigDecimal("0")) > 0)) { + if (new BigDecimal(commissionCashRequest.getAmount()).compareTo(amount) > 0) { + throw new BusinessCheckException("付款金额不能大于" + amount); + } + amount = new BigDecimal(commissionCashRequest.getAmount()); + } + mtCommissionCash.setOperator(commissionCashRequest.getOperator()); + mtCommissionCash.setStatus(CommissionCashStatusEnum.PAYED.getKey()); + mtCommissionCash.setAmount(amount); + mtCommissionCash.setUpdateTime(new Date()); + mtCommissionCash.setDescription(commissionCashRequest.getDescription()); + Integer i = mtCommissionCashMapper.updateById(mtCommissionCash); + if (i > 0 && mtCommissionCash.getUserId() != null) { + MtUser mtUser = memberService.queryMemberById(mtCommissionCash.getUserId()); + if (mtCommissionCash.getStaffId() != null && mtCommissionCash.getStaffId() > 0) { + MtStaff mtStaff = staffService.queryStaffById(mtCommissionCash.getStaffId()); + mtUser = memberService.queryMemberByMobile(mtCommissionCash.getMerchantId(), mtStaff.getMobile()); + } + if (mtUser != null) { + MtBalance mtBalance = new MtBalance(); + mtBalance.setMerchantId(mtCommissionCash.getMerchantId()); + mtBalance.setStoreId(mtCommissionCash.getStoreId()); + mtBalance.setUserId(mtUser.getId()); + mtBalance.setAmount(amount); + mtBalance.setStatus(StatusEnum.ENABLED.getKey()); + mtBalance.setMobile(mtUser.getMobile()); + mtBalance.setDescription("发放分享佣金"); + balanceService.addBalance(mtBalance, true); + } else { + throw new BusinessCheckException("付款失败,未找到会员信息"); + } + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionLogServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionLogServiceImpl.java new file mode 100644 index 0000000..d9e4567 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionLogServiceImpl.java @@ -0,0 +1,377 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.CommissionLogDto; +import com.fuint.common.dto.OrderUserDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.CommissionLogPage; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.CommissionLogRequest; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +/** + * 分销提成记录服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CommissionLogServiceImpl extends ServiceImpl implements CommissionLogService { + + private static final Logger logger = LoggerFactory.getLogger(CommissionLogServiceImpl.class); + + private MtCommissionLogMapper mtCommissionLogMapper; + + private MtCommissionRuleMapper mtCommissionRuleMapper; + + private MtCommissionRuleItemMapper mtCommissionRuleItemMapper; + + private MtOrderGoodsMapper mtOrderGoodsMapper; + + private MtCommissionRelationMapper mtCommissionRelationMapper; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 员工服务接口 + * */ + private StaffService staffService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 提成方案规则服务接口 + * */ + private CommissionRuleService commissionRuleService; + + /** + * 分页查询分销提成列表 + * + * @param commissionLogPage + * @return + */ + @Override + public PaginationResponse queryCommissionLogByPagination(CommissionLogPage commissionLogPage) throws BusinessCheckException { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCommissionLog::getStatus, StatusEnum.DISABLE.getKey()); + String target = commissionLogPage.getTarget(); + if (StringUtils.isNotBlank(target)) { + lambdaQueryWrapper.eq(MtCommissionLog::getTarget, target); + } + String realName = commissionLogPage.getRealName(); + if (StringUtils.isNotBlank(realName)) { + Map params = new HashMap<>(); + params.put("REAL_NAME", realName); + params.put("AUDITED_STATUS", StatusEnum.ENABLED.getKey()); + List staffList = staffService.queryStaffByParams(params); + if (staffList != null && staffList.size() > 0) { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, staffList.get(0).getId()); + } else { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, -1); + } + } + String mobile = commissionLogPage.getMobile(); + if (StringUtils.isNotBlank(mobile)) { + MtStaff mtStaff = staffService.queryStaffByMobile(mobile); + if (mtStaff != null) { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, mtStaff.getId()); + } else { + lambdaQueryWrapper.eq(MtCommissionLog::getStaffId, -1); + } + } + String uuid = commissionLogPage.getUuid(); + if (StringUtils.isNotBlank(uuid)) { + lambdaQueryWrapper.eq(MtCommissionLog::getSettleUuid, uuid); + } + String status = commissionLogPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCommissionLog::getStatus, status); + } + Integer merchantId = commissionLogPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtCommissionLog::getMerchantId, merchantId); + } + Integer storeId = commissionLogPage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtCommissionLog::getStoreId, storeId); + } + // 开始时间、结束时间 + String startTime = commissionLogPage.getStartTime(); + String endTime = commissionLogPage.getEndTime(); + if (StringUtil.isNotEmpty(startTime)) { + lambdaQueryWrapper.ge(MtCommissionLog::getCreateTime, startTime); + } + if (StringUtil.isNotEmpty(endTime)) { + lambdaQueryWrapper.le(MtCommissionLog::getCreateTime, endTime); + } + + lambdaQueryWrapper.orderByDesc(MtCommissionLog::getId); + Page pageHelper = PageHelper.startPage(commissionLogPage.getPage(), commissionLogPage.getPageSize()); + List commissionLogList = mtCommissionLogMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (commissionLogList != null && commissionLogList.size() > 0) { + for (MtCommissionLog mtCommissionLog : commissionLogList) { + CommissionLogDto commissionLogDto = new CommissionLogDto(); + BeanUtils.copyProperties(mtCommissionLog, commissionLogDto); + commissionLogDto.setTypeName(CommissionTypeEnum.getName(mtCommissionLog.getType())); + MtOrder mtOrder = orderService.getById(mtCommissionLog.getOrderId()); + commissionLogDto.setOrderInfo(mtOrder); + MtStore mtStore = storeService.getById(mtCommissionLog.getStoreId()); + commissionLogDto.setStoreInfo(mtStore); + MtStaff mtStaff = staffService.getById(mtCommissionLog.getStaffId()); + if (mtStaff != null) { + mtStaff.setMobile(CommonUtil.hidePhone(mtStaff.getMobile())); + commissionLogDto.setStaffInfo(mtStaff); + } + MtCommissionRule mtCommissionRule = commissionRuleService.getById(mtCommissionLog.getRuleId()); + commissionLogDto.setRuleInfo(mtCommissionRule); + if (mtCommissionLog.getUserId() != null && mtCommissionLog.getUserId() > 0) { + MtUser userInfo = memberService.queryMemberById(mtCommissionLog.getUserId()); + if (userInfo != null) { + OrderUserDto userDto = new OrderUserDto(); + userDto.setNo(userInfo.getUserNo()); + userDto.setId(userInfo.getId()); + userDto.setName(userInfo.getName()); + userDto.setCardNo(userInfo.getIdcard()); + userDto.setAddress(userInfo.getAddress()); + userDto.setMobile(CommonUtil.hidePhone(userInfo.getMobile())); + commissionLogDto.setUserInfo(userDto); + } + } + dataList.add(commissionLogDto); + } + } + PageRequest pageRequest = PageRequest.of(commissionLogPage.getPage(), commissionLogPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, CommissionLogDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 计算订单分销提成 + * + * @param orderId 订单ID + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "计算订单分销提成") + public void calculateCommission(Integer orderId) throws BusinessCheckException { + if (orderId != null && orderId > 0) { + MtOrder mtOrder = orderService.getById(orderId); + // 获取邀请关系 + Integer commissionUserId = mtCommissionRelationMapper.getCommissionUserId(mtOrder.getMerchantId(), mtOrder.getUserId()); + if (commissionUserId != null && commissionUserId > 0) { + mtOrder.setCommissionUserId(commissionUserId); + orderService.updateOrder(mtOrder); + } + // 商品订单佣金计算 + if (mtOrder != null && mtOrder.getType().equals(CommissionTypeEnum.GOODS.getKey())) { + Map params = new HashMap<>(); + params.put("ORDER_ID", mtOrder.getId()); + params.put("STATUS", StatusEnum.ENABLED.getKey()); + List goodsList = mtOrderGoodsMapper.selectByMap(params); + if (goodsList != null && goodsList.size() > 0) { + for (MtOrderGoods orderGoods : goodsList) { + List commissionRuleItemList = mtCommissionRuleItemMapper.getEffectiveCommissionList(mtOrder.getMerchantId(), orderGoods.getGoodsId(), CommissionTypeEnum.GOODS.getKey()); + if (commissionRuleItemList != null && commissionRuleItemList.size() > 0) { + for (MtCommissionRuleItem mtCommissionRuleItem : commissionRuleItemList) { + MtCommissionRule mtCommissionRule = mtCommissionRuleMapper.selectById(mtCommissionRuleItem.getRuleId()); + // 规则状态正常 + if (mtCommissionRule != null && mtCommissionRule.getStatus().equals(StatusEnum.ENABLED.getKey())) { + // 分佣金额计算,散客和会员佣金比例不同 + BigDecimal rate = mtCommissionRuleItem.getMember(); + if (mtOrder.getStaffId() != null && mtOrder.getStaffId() > 0 && mtOrder.getIsVisitor().equals(YesOrNoEnum.YES.getKey())) { + rate = mtCommissionRuleItem.getGuest(); + } + if (orderGoods.getNum() == null || orderGoods.getNum() < 1) { + orderGoods.setNum(1d); + } + BigDecimal amount = orderGoods.getPrice().multiply(rate.divide(new BigDecimal("100"))).multiply(new BigDecimal(orderGoods.getNum())); + addCommissionLog(mtOrder, mtCommissionRule, amount, mtCommissionRuleItem, mtOrder.getCommissionUserId()); + } + } + } + } + } + } + + // 充值订单计算佣金 + if (mtOrder != null && mtOrder.getType().equals(CommissionTypeEnum.RECHARGE.getKey())) { + List commissionRuleItemList = mtCommissionRuleItemMapper.getEffectiveCommissionList(mtOrder.getMerchantId(), null, CommissionTypeEnum.RECHARGE.getKey()); + if (commissionRuleItemList != null && commissionRuleItemList.size() > 0) { + for (MtCommissionRuleItem mtCommissionRuleItem : commissionRuleItemList) { + MtCommissionRule mtCommissionRule = mtCommissionRuleMapper.selectById(mtCommissionRuleItem.getRuleId()); + // 分佣金额计算,散客和会员佣金比例不同 + BigDecimal rate = mtCommissionRuleItem.getMember(); + if (mtOrder.getStaffId() != null && mtOrder.getStaffId() > 0 && mtOrder.getIsVisitor().equals(YesOrNoEnum.YES.getKey())) { + rate = mtCommissionRuleItem.getGuest(); + } + BigDecimal amount = mtOrder.getAmount().multiply(rate.divide(new BigDecimal("100"))); + addCommissionLog(mtOrder, mtCommissionRule, amount, mtCommissionRuleItem, mtOrder.getCommissionUserId()); + } + } + } + + // 付款订单计算佣金 + if (mtOrder != null && mtOrder.getType().equals(CommissionTypeEnum.PAYMENT.getKey())) { + List commissionRuleItemList = mtCommissionRuleItemMapper.getEffectiveCommissionList(mtOrder.getMerchantId(), null, CommissionTypeEnum.PAYMENT.getKey()); + if (commissionRuleItemList != null && commissionRuleItemList.size() > 0) { + for (MtCommissionRuleItem mtCommissionRuleItem : commissionRuleItemList) { + MtCommissionRule mtCommissionRule = mtCommissionRuleMapper.selectById(mtCommissionRuleItem.getRuleId()); + // 分佣金额计算,散客和会员佣金比例不同 + BigDecimal rate = mtCommissionRuleItem.getMember(); + if (mtOrder.getStaffId() != null && mtOrder.getStaffId() > 0 && mtOrder.getIsVisitor().equals(YesOrNoEnum.YES.getKey())) { + rate = mtCommissionRuleItem.getGuest(); + } + BigDecimal amount = mtOrder.getPayAmount().multiply(rate.divide(new BigDecimal("100"))); + addCommissionLog(mtOrder, mtCommissionRule, amount, mtCommissionRuleItem, mtOrder.getCommissionUserId()); + } + } + } + + // 订单更新为已结算 + if (mtOrder != null) { + mtOrder.setCommissionStatus(CommissionStatusEnum.SETTLED.getKey()); + orderService.updateOrder(mtOrder); + } + } else { + logger.error("计算分销提成订单不能ID为空..."); + } + } + + /** + * 根据ID获取记录信息 + * + * @param id 分佣提成记录ID + * @return + */ + @Override + public CommissionLogDto queryCommissionLogById(Integer id) { + MtCommissionLog mtCommissionLog = mtCommissionLogMapper.selectById(id); + CommissionLogDto commissionLogDto = null; + if (mtCommissionLog != null) { + BeanUtils.copyProperties(mtCommissionLog, commissionLogDto); + } + return commissionLogDto; + } + + /** + * 更新分销提成记录 + * + * @param requestParam 请求参数 + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "更新分销提成记录") + public void updateCommissionLog(CommissionLogRequest requestParam) throws BusinessCheckException { + MtCommissionLog mtCommissionLog = mtCommissionLogMapper.selectById(requestParam.getId()); + if (mtCommissionLog == null) { + logger.error("更新分销提成记录失败..."); + throw new BusinessCheckException("更新分销提成记录失败,该记录不存在"); + } + if (requestParam.getAmount() != null) { + mtCommissionLog.setAmount(new BigDecimal(requestParam.getAmount())); + } + if (requestParam.getDescription() != null) { + mtCommissionLog.setDescription(requestParam.getDescription()); + } + if (requestParam.getStatus() != null) { + mtCommissionLog.setStatus(requestParam.getStatus()); + } + if (requestParam.getSettleUuid() != null) { + mtCommissionLog.setSettleUuid(requestParam.getSettleUuid()); + } + mtCommissionLog.setOperator(requestParam.getOperator()); + mtCommissionLog.setUpdateTime(new Date()); + mtCommissionLogMapper.updateById(mtCommissionLog); + } + + /** + * 新增分佣记录 + * + * @param mtOrder 订单信息 + * @param mtCommissionRule 分佣方案 + * @param amount 分佣金额 + * @param mtCommissionRuleItem 分佣规则 + * @param userId 会员ID + * @return + * */ + @Transactional + @OperationServiceLog(description = "新增分销提成记录") + public void addCommissionLog(MtOrder mtOrder, MtCommissionRule mtCommissionRule, BigDecimal amount, MtCommissionRuleItem mtCommissionRuleItem, Integer userId) { + if (amount.compareTo(BigDecimal.ZERO) > 0) { + MtCommissionLog mtCommissionLog = new MtCommissionLog(); + mtCommissionLog.setType(mtOrder.getType()); + mtCommissionLog.setTarget(mtCommissionRule.getTarget()); + mtCommissionLog.setLevel(0); + mtCommissionLog.setOrderId(mtOrder.getId()); + mtCommissionLog.setMerchantId(mtOrder.getMerchantId()); + mtCommissionLog.setStoreId(mtOrder.getStoreId()); + if (mtCommissionRule.getTarget().equals(CommissionTargetEnum.STAFF.getKey())) { + if (mtOrder.getStaffId() == null || mtOrder.getStaffId() <= 0) { + return; + } + mtCommissionLog.setStaffId(mtOrder.getStaffId()); + mtCommissionLog.setUserId(0); + } else { + if (userId == null || userId <= 0) { + return; + } + mtCommissionLog.setStaffId(0); + mtCommissionLog.setUserId(userId); + } + mtCommissionLog.setAmount(amount); + mtCommissionLog.setRuleId(mtCommissionRuleItem.getRuleId()); + mtCommissionLog.setRuleItemId(mtCommissionRuleItem.getId()); + mtCommissionLog.setCashId(0); + mtCommissionLog.setCashTime(null); + Date dateTime = new Date(); + mtCommissionLog.setCreateTime(dateTime); + mtCommissionLog.setUpdateTime(dateTime); + mtCommissionLog.setStatus(StatusEnum.ENABLED.getKey()); + mtCommissionLog.setOperator(null); + mtCommissionLogMapper.insert(mtCommissionLog); + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRelationServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRelationServiceImpl.java new file mode 100644 index 0000000..c0a0f24 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRelationServiceImpl.java @@ -0,0 +1,173 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.CommissionRelationDto; +import com.fuint.common.param.CommissionRelationPage; +import com.fuint.common.service.CommissionRelationService; +import com.fuint.common.service.MemberService; +import com.fuint.common.service.MerchantService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtCommissionRelationMapper; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.model.MtCommissionRelation; +import com.fuint.repository.model.MtUser; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import java.util.*; + +/** + * 分销提成关系服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CommissionRelationServiceImpl extends ServiceImpl implements CommissionRelationService { + + private static final Logger logger = LoggerFactory.getLogger(CommissionRelationServiceImpl.class); + + private MtCommissionRelationMapper mtCommissionRelationMapper; + + /** + * 会员服务接口 + */ + private MemberService memberService; + + /** + * 商户服务接口 + */ + private MerchantService merchantService; + + /** + * 分页查询关系列表 + * + * @param commissionRelationPage + * @return + */ + @Override + public PaginationResponse queryRelationByPagination(CommissionRelationPage commissionRelationPage) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(commissionRelationPage.getPage(), commissionRelationPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCommissionRelation::getStatus, StatusEnum.DISABLE.getKey()); + String status = commissionRelationPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCommissionRelation::getStatus, status); + } + Integer userId = commissionRelationPage.getUserId(); + if (userId != null && userId > 0) { + lambdaQueryWrapper.eq(MtCommissionRelation::getUserId, userId); + } + String subUserId = commissionRelationPage.getSubUserId(); + if (StringUtils.isNotBlank(subUserId)) { + lambdaQueryWrapper.eq(MtCommissionRelation::getSubUserId, subUserId); + } + Integer merchantId = commissionRelationPage.getMerchantId(); + String merchantNo = commissionRelationPage.getMerchantNo(); + if (StringUtils.isNotBlank(merchantNo) && (merchantId == null || merchantId <= 0)) { + Integer mchId = merchantService.getMerchantId(merchantNo); + if (mchId != null && mchId > 0) { + merchantId = mchId; + } + } + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtCommissionRelation::getMerchantId, merchantId); + } + + lambdaQueryWrapper.orderByDesc(MtCommissionRelation::getId); + List relationList = mtCommissionRelationMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (relationList != null && relationList.size() > 0) { + for (MtCommissionRelation mtCommissionRelation : relationList) { + CommissionRelationDto commissionRelationDto = new CommissionRelationDto(); + BeanUtils.copyProperties(mtCommissionRelation, commissionRelationDto); + MtUser userInfo = memberService.queryMemberById(mtCommissionRelation.getUserId()); + MtUser subUserInfo = memberService.queryMemberById(mtCommissionRelation.getSubUserId()); + if (userInfo != null && subUserInfo != null) { + commissionRelationDto.setUserInfo(userInfo); + commissionRelationDto.setSubUserInfo(subUserInfo); + dataList.add(commissionRelationDto); + } + } + } + + PageRequest pageRequest = PageRequest.of(commissionRelationPage.getPage(), commissionRelationPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, CommissionRelationDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 设置分销提成关系 + * + * @param userInfo 会员信息 + * @param shareId 分享者ID + * @throws BusinessCheckException + * @retrurn + */ + @Override + public void setCommissionRelation(MtUser userInfo, String shareId) throws BusinessCheckException { + if (userInfo == null || StringUtil.isBlank(shareId) || Integer.parseInt(shareId) <= 0) { + return; + } + + MtUser shareUserInfo = memberService.queryMemberById(Integer.parseInt(shareId)); + if (shareUserInfo == null) { + return; + } + + Map param = new HashMap(); + param.put("USER_ID", Integer.parseInt(shareId)); + param.put("SUB_USER_ID", userInfo.getId()); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + List dataList = mtCommissionRelationMapper.selectByMap(param); + if (dataList == null || dataList.size() <= 0) { + MtCommissionRelation mtCommissionRelation = new MtCommissionRelation(); + mtCommissionRelation.setCreateTime(new Date()); + mtCommissionRelation.setUpdateTime(new Date()); + mtCommissionRelation.setStatus(StatusEnum.ENABLED.getKey()); + mtCommissionRelation.setUserId(Integer.parseInt(shareId)); + mtCommissionRelation.setSubUserId(userInfo.getId()); + mtCommissionRelation.setMerchantId(userInfo.getMerchantId()); + mtCommissionRelation.setInviteCode(shareUserInfo.getUserNo()); + mtCommissionRelation.setLevel(1); + mtCommissionRelationMapper.insert(mtCommissionRelation); + } + + Map params = new HashMap(); + params.put("SUB_USER_ID", Integer.parseInt(shareId)); + params.put("LEVEL", 1); + params.put("STATUS", StatusEnum.ENABLED.getKey()); + List data = mtCommissionRelationMapper.selectByMap(params); + if (data != null && data.size() > 0) { + MtCommissionRelation mtCommissionRelation = new MtCommissionRelation(); + mtCommissionRelation.setCreateTime(new Date()); + mtCommissionRelation.setUpdateTime(new Date()); + mtCommissionRelation.setStatus(StatusEnum.ENABLED.getKey()); + mtCommissionRelation.setUserId(data.get(0).getUserId()); + mtCommissionRelation.setSubUserId(userInfo.getId()); + mtCommissionRelation.setMerchantId(userInfo.getMerchantId()); + mtCommissionRelation.setInviteCode(data.get(0).getInviteCode()); + mtCommissionRelation.setLevel(2); + mtCommissionRelationMapper.insert(mtCommissionRelation); + } + logger.info("记录分佣关系成功,shareId = {}, userId = {}", shareId, userInfo.getId()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRuleServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRuleServiceImpl.java new file mode 100644 index 0000000..bc89994 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CommissionRuleServiceImpl.java @@ -0,0 +1,357 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.CommissionRuleDto; +import com.fuint.common.dto.CommissionRuleItemDto; +import com.fuint.common.enums.CommissionTypeEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.CommissionRuleItemParam; +import com.fuint.common.param.CommissionRulePage; +import com.fuint.common.param.CommissionRuleParam; +import com.fuint.common.service.CommissionRuleService; +import com.fuint.common.service.GoodsService; +import com.fuint.common.service.SettingService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtCommissionRuleItemMapper; +import com.fuint.repository.mapper.MtCommissionRuleMapper; +import com.fuint.repository.model.MtCommissionRule; +import com.fuint.repository.model.MtCommissionRuleItem; +import com.fuint.repository.model.MtGoods; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * 分销提成服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CommissionRuleServiceImpl extends ServiceImpl implements CommissionRuleService { + + private static final Logger logger = LoggerFactory.getLogger(CommissionRuleServiceImpl.class); + + private MtCommissionRuleMapper mtCommissionRuleMapper; + + private MtCommissionRuleItemMapper mtCommissionRuleItemMapper; + + /** + * 商品服务接口 + * */ + private GoodsService goodsService; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 分页查询规则列表 + * + * @param commissionRulePage + * @return + */ + @Override + public PaginationResponse queryDataByPagination(CommissionRulePage commissionRulePage) { + Page pageHelper = PageHelper.startPage(commissionRulePage.getPage(), commissionRulePage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCommissionRule::getStatus, StatusEnum.DISABLE.getKey()); + + String name = commissionRulePage.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtCommissionRule::getName, name); + } + String status = commissionRulePage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCommissionRule::getStatus, status); + } + String target = commissionRulePage.getTarget(); + if (StringUtils.isNotBlank(target)) { + lambdaQueryWrapper.eq(MtCommissionRule::getTarget, target); + } + String type = commissionRulePage.getType(); + if (StringUtils.isNotBlank(type)) { + lambdaQueryWrapper.eq(MtCommissionRule::getType, type); + } + Integer merchantId = commissionRulePage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtCommissionRule::getMerchantId, merchantId); + } + Integer storeId = commissionRulePage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtCommissionRule::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtCommissionRule::getId); + List dataList = mtCommissionRuleMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(commissionRulePage.getPage(), commissionRulePage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtCommissionRule.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加分销提成规则 + * + * @param commissionRule + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增分销提成规则") + public MtCommissionRule addCommissionRule(CommissionRuleParam commissionRule) throws BusinessCheckException { + MtCommissionRule mtCommissionRule = new MtCommissionRule(); + BeanUtils.copyProperties(commissionRule, mtCommissionRule); + mtCommissionRule.setStatus(StatusEnum.ENABLED.getKey()); + Date date = new Date(); + mtCommissionRule.setCreateTime(date); + mtCommissionRule.setUpdateTime(date); + mtCommissionRule.setMerchantId(mtCommissionRule.getMerchantId()== null ? 0 : mtCommissionRule.getMerchantId()); + String storeIds = StringUtil.join(commissionRule.getStoreIdList().toArray(), ","); + mtCommissionRule.setStoreIds(storeIds); + boolean result = save(mtCommissionRule); + if (result) { + if (mtCommissionRule.getType().equals(CommissionTypeEnum.RECHARGE.getKey()) || mtCommissionRule.getType().equals(CommissionTypeEnum.PAYMENT.getKey())) { + if (commissionRule.getMemberVal() != null || commissionRule.getVisitorVal() != null) { + List detailList = new ArrayList<>(); + CommissionRuleItemParam detailItem = new CommissionRuleItemParam(); + detailItem.setMethod("percent"); + detailItem.setGoodsId(0); + detailItem.setMemberVal(commissionRule.getMemberVal()); + detailItem.setVisitorVal(commissionRule.getVisitorVal()); + detailList.add(detailItem); + commissionRule.setDetailList(detailList); + } + } + if (commissionRule.getDetailList() != null && commissionRule.getDetailList().size() > 0) { + for (CommissionRuleItemParam itemParam : commissionRule.getDetailList()) { + MtCommissionRuleItem mtCommissionRuleItem = new MtCommissionRuleItem(); + mtCommissionRuleItem.setRuleId(mtCommissionRule.getId()); + mtCommissionRuleItem.setType(mtCommissionRule.getType()); + mtCommissionRuleItem.setTarget(mtCommissionRule.getTarget()); + mtCommissionRuleItem.setMerchantId(mtCommissionRule.getMerchantId()); + mtCommissionRuleItem.setStoreId(mtCommissionRule.getStoreId()); + mtCommissionRuleItem.setStoreIds(storeIds); + mtCommissionRuleItem.setCreateTime(date); + mtCommissionRuleItem.setUpdateTime(date); + mtCommissionRuleItem.setOperator(commissionRule.getOperator()); + mtCommissionRuleItem.setStatus(mtCommissionRule.getStatus()); + mtCommissionRuleItem.setMethod(itemParam.getMethod()); + mtCommissionRuleItem.setTarget(commissionRule.getTarget()); + mtCommissionRuleItem.setTargetId(itemParam.getGoodsId()); + mtCommissionRuleItem.setMember(itemParam.getMemberVal()); + mtCommissionRuleItem.setGuest(itemParam.getVisitorVal()); + mtCommissionRuleItemMapper.insert(mtCommissionRuleItem); + } + } + } else { + logger.error("新增分销提成规则失败..."); + throw new BusinessCheckException("新增分销方案规则失败"); + } + return mtCommissionRule; + } + + /** + * 根据ID获取规则信息 + * + * @param id 规则ID + * @return + */ + @Override + public CommissionRuleDto queryCommissionRuleById(Integer id) throws BusinessCheckException { + MtCommissionRule mtCommissionRule = mtCommissionRuleMapper.selectById(id); + if (mtCommissionRule == null) { + return null; + } + CommissionRuleDto commissionRuleDto = new CommissionRuleDto(); + BeanUtils.copyProperties(mtCommissionRule, commissionRuleDto); + + Map param = new HashMap(); + param.put("RULE_ID", id); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + List mtCommissionRuleItems = mtCommissionRuleItemMapper.selectByMap(param); + List detailList = new ArrayList<>(); + String basePath = settingService.getUploadBasePath(); + if (mtCommissionRuleItems != null && mtCommissionRuleItems.size() > 0) { + for (MtCommissionRuleItem item : mtCommissionRuleItems) { + CommissionRuleItemDto commissionRuleItemDto = new CommissionRuleItemDto(); + commissionRuleItemDto.setGoodsId(item.getTargetId()); + MtGoods mtGoods = goodsService.queryGoodsById(item.getTargetId()); + if (mtGoods != null) { + commissionRuleItemDto.setGoodsName(mtGoods.getName()); + commissionRuleItemDto.setLogo(basePath + mtGoods.getLogo()); + commissionRuleItemDto.setPrice(mtGoods.getPrice()); + } + commissionRuleItemDto.setType(item.getType()); + commissionRuleItemDto.setMemberVal(item.getMember()); + commissionRuleItemDto.setMethod(item.getMethod()); + commissionRuleItemDto.setVisitorVal(item.getGuest()); + detailList.add(commissionRuleItemDto); + } + } + commissionRuleDto.setDetailList(detailList); + if (mtCommissionRule.getType().equals(CommissionTypeEnum.RECHARGE.getKey()) || mtCommissionRule.getType().equals(CommissionTypeEnum.PAYMENT.getKey())) { + commissionRuleDto.setDetailList(null); + Map params = new HashMap(); + params.put("RULE_ID", id); + params.put("STATUS", StatusEnum.ENABLED.getKey()); + List mtCommissionRuleItemList = mtCommissionRuleItemMapper.selectByMap(params); + if (mtCommissionRuleItemList != null && mtCommissionRuleItemList.size() > 0) { + commissionRuleDto.setMemberVal(mtCommissionRuleItemList.get(0).getMember()); + commissionRuleDto.setVisitorVal(mtCommissionRuleItemList.get(0).getGuest()); + } + } + List storeIds = new ArrayList<>(); + if (StringUtil.isNotEmpty(mtCommissionRule.getStoreIds())) { + List storeIdList = Arrays.asList(mtCommissionRule.getStoreIds().split(",")); + if (storeIdList != null && storeIdList.size() > 0) { + for (String storeId : storeIdList) { + storeIds.add(Integer.parseInt(storeId)); + } + } + } + commissionRuleDto.setStoreIdList(storeIds); + return commissionRuleDto; + } + + /** + * 更新分销提成规则 + * + * @param commissionRule 规则参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新分销提成规则") + public MtCommissionRule updateCommissionRule(CommissionRuleParam commissionRule) throws BusinessCheckException { + MtCommissionRule mtCommissionRule = mtCommissionRuleMapper.selectById(commissionRule.getId()); + if (mtCommissionRule == null) { + logger.error("更新分销提成规则失败..."); + throw new BusinessCheckException("该数据状态异常"); + } + mtCommissionRule.setId(commissionRule.getId()); + if (commissionRule.getName() != null) { + mtCommissionRule.setName(commissionRule.getName()); + } + if (commissionRule.getTarget() != null) { + mtCommissionRule.setTarget(commissionRule.getTarget()); + } + if (commissionRule.getType() != null) { + mtCommissionRule.setType(commissionRule.getType()); + } + if (commissionRule.getStoreId() != null) { + mtCommissionRule.setStoreId(commissionRule.getStoreId()); + } + if (commissionRule.getDescription() != null) { + mtCommissionRule.setDescription(commissionRule.getDescription()); + } + if (commissionRule.getOperator() != null) { + mtCommissionRule.setOperator(commissionRule.getOperator()); + } + if (commissionRule.getStatus() != null) { + mtCommissionRule.setStatus(commissionRule.getStatus()); + if (commissionRule.getStatus().equals(StatusEnum.DISABLE.getKey())) { + mtCommissionRuleItemMapper.deleteByRuleId(commissionRule.getId(), new Date()); + } + } + String storeIds = ""; + if (commissionRule.getStoreIdList() != null && commissionRule.getStoreIdList().size() > 0) { + storeIds = StringUtil.join(commissionRule.getStoreIdList().toArray(), ","); + mtCommissionRule.setStoreIds(storeIds); + } + + if (mtCommissionRule.getType().equals(CommissionTypeEnum.RECHARGE.getKey()) || mtCommissionRule.getType().equals(CommissionTypeEnum.PAYMENT.getKey())) { + if (commissionRule.getMemberVal() != null || commissionRule.getVisitorVal() != null) { + List detailList = new ArrayList<>(); + CommissionRuleItemParam detailItem = new CommissionRuleItemParam(); + detailItem.setMethod("percent"); + detailItem.setGoodsId(0); + detailItem.setMemberVal(commissionRule.getMemberVal()); + detailItem.setVisitorVal(commissionRule.getVisitorVal()); + detailList.add(detailItem); + commissionRule.setDetailList(detailList); + } + } + + // 更新或插入 + Date date = new Date(); + List itemIds = new ArrayList<>(); + if (commissionRule.getDetailList() != null && commissionRule.getDetailList().size() > 0) { + for (CommissionRuleItemParam itemParam : commissionRule.getDetailList()) { + MtCommissionRuleItem mtCommissionRuleItem = new MtCommissionRuleItem(); + mtCommissionRuleItem.setRuleId(mtCommissionRule.getId()); + mtCommissionRuleItem.setType(mtCommissionRule.getType()); + mtCommissionRuleItem.setMerchantId(mtCommissionRule.getMerchantId()); + mtCommissionRuleItem.setStoreId(mtCommissionRule.getStoreId()); + mtCommissionRuleItem.setStoreIds(storeIds); + mtCommissionRuleItem.setCreateTime(date); + mtCommissionRuleItem.setUpdateTime(date); + mtCommissionRuleItem.setOperator(commissionRule.getOperator()); + mtCommissionRuleItem.setStatus(mtCommissionRule.getStatus()); + mtCommissionRuleItem.setMethod(itemParam.getMethod()); + mtCommissionRuleItem.setTarget(commissionRule.getTarget()); + mtCommissionRuleItem.setTargetId(itemParam.getGoodsId()); + mtCommissionRuleItem.setMember(itemParam.getMemberVal()); + mtCommissionRuleItem.setGuest(itemParam.getVisitorVal()); + // 判断是否已经存在,存在则更新 + if (itemParam.getGoodsId() != null && itemParam.getGoodsId() >= 0) { + Map param = new HashMap(); + param.put("RULE_ID", commissionRule.getId()); + param.put("TARGET_ID", itemParam.getGoodsId()); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + List items = mtCommissionRuleItemMapper.selectByMap(param); + if (items != null && items.size() > 0) { + mtCommissionRuleItem.setId(items.get(0).getId()); + itemIds.add(items.get(0).getId()); + } + } + if (mtCommissionRuleItem.getId() != null && mtCommissionRuleItem.getId() > 0) { + mtCommissionRuleItemMapper.updateById(mtCommissionRuleItem); + } else { + mtCommissionRuleItemMapper.insert(mtCommissionRuleItem); + itemIds.add(mtCommissionRuleItem.getId()); + } + } + } + + // 删除 + Map params = new HashMap(); + params.put("RULE_ID", commissionRule.getId()); + params.put("STATUS", StatusEnum.ENABLED.getKey()); + List mtCommissionRuleItems = mtCommissionRuleItemMapper.selectByMap(params); + for (MtCommissionRuleItem item : mtCommissionRuleItems) { + if (!itemIds.contains(item.getId())) { + item.setStatus(StatusEnum.DISABLE.getKey()); + mtCommissionRuleItemMapper.updateById(item); + } + } + + mtCommissionRule.setUpdateTime(new Date()); + mtCommissionRuleMapper.updateById(mtCommissionRule); + return mtCommissionRule; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/ConfirmLogServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/ConfirmLogServiceImpl.java new file mode 100644 index 0000000..cbbba36 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/ConfirmLogServiceImpl.java @@ -0,0 +1,167 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.ConfirmLogDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.ConfirmLogPage; +import com.fuint.common.service.ConfirmLogService; +import com.fuint.common.service.CouponService; +import com.fuint.common.service.MemberService; +import com.fuint.common.service.StoreService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtConfirmLogMapper; +import com.fuint.repository.model.MtConfirmLog; +import com.fuint.repository.model.MtCoupon; +import com.fuint.repository.model.MtStore; +import com.fuint.repository.model.MtUser; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * 核销卡券服务 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class ConfirmLogServiceImpl extends ServiceImpl implements ConfirmLogService { + + private MtConfirmLogMapper mtConfirmLogMapper; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 分页查询卡券核销列表 + * + * @param confirmLogPage + * @return + */ + @Override + public PaginationResponse queryConfirmLogListByPagination(ConfirmLogPage confirmLogPage) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(confirmLogPage.getPage(), confirmLogPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtConfirmLog::getStatus, StatusEnum.DISABLE.getKey()); + + String status = confirmLogPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtConfirmLog::getStatus, status); + } + Integer userId = confirmLogPage.getUserId(); + if (userId != null) { + lambdaQueryWrapper.eq(MtConfirmLog::getUserId, userId); + } + Integer couponId = confirmLogPage.getCouponId(); + if (couponId != null && couponId > 0) { + lambdaQueryWrapper.eq(MtConfirmLog::getCouponId, couponId); + } + Integer merchantId = confirmLogPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtConfirmLog::getMerchantId, merchantId); + } + Integer storeId = confirmLogPage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtConfirmLog::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtConfirmLog::getId); + List confirmLogList = mtConfirmLogMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + for (MtConfirmLog log : confirmLogList) { + MtUser userInfo = memberService.queryMemberById(log.getUserId()); + MtStore storeInfo = storeService.queryStoreById(log.getStoreId()); + MtCoupon couponInfo = couponService.queryCouponById(log.getCouponId()); + ConfirmLogDto item = new ConfirmLogDto(); + item.setId(log.getId()); + item.setCode(log.getCode()); + item.setUserInfo(userInfo); + item.setStoreInfo(storeInfo); + item.setCouponInfo(couponInfo); + item.setUserCouponId(log.getUserCouponId()); + item.setAmount(log.getAmount()); + item.setCreateTime(log.getCreateTime()); + item.setUpdateTime(log.getUpdateTime()); + item.setStatus(log.getStatus()); + item.setRemark(log.getRemark()); + item.setOperator(log.getOperator()); + dataList.add(item); + } + + PageRequest pageRequest = PageRequest.of(confirmLogPage.getPage(), confirmLogPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, ConfirmLogDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 获取卡券(计次卡)核销次数 + * @param userCouponId 会员卡券ID + * @return + * */ + @Override + public Long getConfirmNum(Integer userCouponId) { + if (userCouponId > 0) { + return mtConfirmLogMapper.getConfirmNum(userCouponId); + } else { + return 0L; + } + } + + /** + * 获取卡券核销列表 + * @param userCouponId + * @return + * */ + @Override + public List getConfirmList(Integer userCouponId) { + if (userCouponId == null || userCouponId <= 0) { + return new ArrayList<>(); + } + Map params = new HashMap<>(); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("USER_COUPON_ID", userCouponId.toString()); + return mtConfirmLogMapper.selectByMap(params); + } + + /** + * 获取卡券核销数量 + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public Long getConfirmCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + return mtConfirmLogMapper.getConfirmLogCount(merchantId, storeId, beginTime, endTime); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CouponGroupServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CouponGroupServiceImpl.java new file mode 100644 index 0000000..3d23255 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CouponGroupServiceImpl.java @@ -0,0 +1,489 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.CouponCellDto; +import com.fuint.common.dto.ReqCouponGroupDto; +import com.fuint.common.dto.ReqSendLogDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.common.util.XlsUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtCouponGroupMapper; +import com.fuint.repository.mapper.MtCouponMapper; +import com.fuint.repository.mapper.MtUserCouponMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.math.BigDecimal; +import java.lang.String; +import java.util.*; +import java.util.regex.Pattern; + +/** + * 卡券分组业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CouponGroupServiceImpl extends ServiceImpl implements CouponGroupService { + + private static final Logger log = LoggerFactory.getLogger(CouponGroupServiceImpl.class); + + private MtCouponGroupMapper mtCouponGroupMapper; + + private MtCouponMapper mtCouponMapper; + + private MtUserCouponMapper mtUserCouponMapper; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 卡券发放记录服务接口 + * */ + private SendLogService sendLogService; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 分页查询卡券分组列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryCouponGroupListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCouponGroup::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtCouponGroup::getName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCouponGroup::getStatus, status); + } + String id = paginationRequest.getSearchParams().get("id") == null ? "" : paginationRequest.getSearchParams().get("id").toString(); + if (StringUtils.isNotBlank(id)) { + lambdaQueryWrapper.eq(MtCouponGroup::getId, id); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtCouponGroup::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtCouponGroup::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtCouponGroup::getId); + List dataList = mtCouponGroupMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtCouponGroup.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加卡券分组 + * + * @param reqCouponGroupDto + * @throws BusinessCheckException + */ + @Override + @OperationServiceLog(description = "新增卡券分组") + public MtCouponGroup addCouponGroup(ReqCouponGroupDto reqCouponGroupDto) { + MtCouponGroup couponGroup = new MtCouponGroup(); + couponGroup.setMerchantId(reqCouponGroupDto.getMerchantId()); + couponGroup.setStoreId(reqCouponGroupDto.getStoreId()); + couponGroup.setName(CommonUtil.replaceXSS(reqCouponGroupDto.getName())); + couponGroup.setMoney(new BigDecimal("0")); + couponGroup.setTotal(0); + couponGroup.setDescription(CommonUtil.replaceXSS(reqCouponGroupDto.getDescription())); + couponGroup.setStatus(StatusEnum.ENABLED.getKey()); + couponGroup.setCreateTime(new Date()); + couponGroup.setUpdateTime(new Date()); + couponGroup.setNum(0); + couponGroup.setOperator(reqCouponGroupDto.getOperator()); + + this.save(couponGroup); + return couponGroup; + } + + /** + * 根据分组ID获取卡券分组信息 + * + * @param id 卡券分组ID + * @throws BusinessCheckException + */ + @Override + public MtCouponGroup queryCouponGroupById(Integer id) { + return mtCouponGroupMapper.selectById(id); + } + + /** + * 根据ID删除卡券分组 + * + * @param id 分组ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + @Override + @OperationServiceLog(description = "删除卡券分组") + public void deleteCouponGroup(Integer id, String operator) { + MtCouponGroup couponGroup = queryCouponGroupById(id); + if (null == couponGroup) { + return; + } + + couponGroup.setStatus(StatusEnum.DISABLE.getKey()); + couponGroup.setUpdateTime(new Date()); + couponGroup.setOperator(operator); + + this.updateById(couponGroup); + } + + /** + * 修改卡券分组 + * + * @param reqCouponGroupDto + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新卡券分组") + public MtCouponGroup updateCouponGroup(ReqCouponGroupDto reqCouponGroupDto) throws BusinessCheckException { + MtCouponGroup couponGroup = queryCouponGroupById(reqCouponGroupDto.getId()); + if (null == couponGroup || StatusEnum.DISABLE.getKey().equalsIgnoreCase(couponGroup.getStatus())) { + throw new BusinessCheckException("该分组不存在或已被删除"); + } + if (reqCouponGroupDto.getName() != null) { + couponGroup.setName(CommonUtil.replaceXSS(reqCouponGroupDto.getName())); + } + if (reqCouponGroupDto.getDescription() != null) { + couponGroup.setDescription(CommonUtil.replaceXSS(reqCouponGroupDto.getDescription())); + } + if (couponGroup.getTotal() == null) { + couponGroup.setTotal(0); + } + if (reqCouponGroupDto.getStatus() != null) { + couponGroup.setStatus(reqCouponGroupDto.getStatus()); + } + couponGroup.setUpdateTime(new Date()); + couponGroup.setOperator(reqCouponGroupDto.getOperator()); + this.updateById(couponGroup); + return couponGroup; + } + + /** + * 获取卡券种类数量 + * + * @param id + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Integer getCouponNum(Integer id) { + Long num = mtCouponMapper.queryNumByGroupId(id); + return num.intValue(); + } + + /** + * 获取卡券总价值 + * + * @param groupId + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + public BigDecimal getCouponMoney(Integer groupId) { + List couponList = mtCouponMapper.queryByGroupId(groupId.intValue()); + MtCouponGroup groupInfo = queryCouponGroupById(groupId); + BigDecimal money = BigDecimal.valueOf(0); + if (couponList.size() > 0) { + for (int i = 0; iuploadFile:{}", "文件类型不正确"); + throw new BusinessCheckException("文件类型不正确"); + } + + List> content = new ArrayList<>(); + try { + content = XlsUtil.readExcelContent(file.getInputStream(), isExcel2003, 0,1, null, null, null); + } catch (IOException e) { + log.error("CouponGroupServiceImpl->parseExcelContent{}", e); + throw new BusinessCheckException("导入失败"+e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + + StringBuffer errorMsg = new StringBuffer(); + StringBuffer errorMsgNoGroup = new StringBuffer(); + StringBuffer errorMsgNoNum = new StringBuffer(); + StringBuffer errorMsgNoRegister = new StringBuffer(); + + List rows = new ArrayList<>(); + + for (int i = 0; i < content.size(); i++) { + List groupIdArr = new ArrayList<>(); + List numArr = new ArrayList<>(); + + List rowContent = content.get(i); + String mobile = rowContent.get(0); + String merchantId = rowContent.get(1); + + if (StringUtil.isBlank(mobile) || mobile.length() < 11 || mobile.length() > 11) { + errorMsg.append("第" + i + "行错误,手机号有误:"+mobile); + continue; + } + + for (int j = 1; j < rowContent.size(); j++) { + Integer item = 0; + String cellContent = rowContent.get(j); + if (null == cellContent || cellContent.equals("")) { + continue; + } + + Pattern pattern = Pattern.compile("^[1-9]\\d*$"); + if ((j%2) != 0) { + if (item == null || (!pattern.matcher(cellContent).matches())) { + throw new BusinessCheckException("第" + (i+1) + "行第"+ j +"列错误, 卡券ID异常"); + } + + item = Integer.parseInt(cellContent); + if (item < 0) { + errorMsg.append("第" + (i+1) + "行第"+ j +"列错误, 卡券ID异常"); + continue; + } + groupIdArr.add(item); + } else { + if (item == null || (!pattern.matcher(rowContent.get(j)).matches())) { + throw new BusinessCheckException("第" + (i+1) + "行第"+ j +"列错误, 数量异常"); + } + + item = Integer.parseInt(rowContent.get(j)); + if (item < 0) { + errorMsg.append("第" + (i+1) + "行第"+ j +"列错误, 数量异常"); + continue; + } + numArr.add(item); + } + } + + if (groupIdArr.size() != numArr.size()) { + throw new BusinessCheckException("表格数据有问题导致无法导入"); + } + + CouponCellDto item = new CouponCellDto(); + item.setMobile(mobile); + item.setGroupId(groupIdArr); + item.setNum(numArr); + item.setMerchantId(Integer.parseInt(merchantId)); + rows.add(item); + } + + if (rows.size() < 1) { + throw new BusinessCheckException("表格数据为空导致无法导入"); + } + + if (rows.size() > 1000) { + throw new BusinessCheckException("每次导入最多不能超过1000人"); + } + + // 获取每个分组的总数 + Map couponIdMap = new HashMap<>(); + for (CouponCellDto dto : rows) { + MtUser userInfo = memberService.queryMemberByMobile(dto.getMerchantId(), dto.getMobile()); + if (userInfo == null) { + userInfo = memberService.addMemberByMobile(dto.getMerchantId(), dto.getMobile(), "0", ""); + } + + if (null == userInfo || !userInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + if (StringUtil.isNotBlank(errorMsgNoGroup.toString())) { + errorMsgNoGroup.append("," + dto.getMobile()); + } else { + errorMsgNoGroup.append("手机号没有注册或已禁用:"+dto.getMobile()); + } + } + + for (int k = 0; k < dto.getGroupId().size(); k++) { + Integer num = dto.getNum().get(k); + Integer total = couponIdMap.get(dto.getGroupId().get(k).toString()) == null ? 0 : couponIdMap.get(dto.getGroupId().get(k).toString()); + couponIdMap.put(dto.getGroupId().get(k).toString(), (total+num)); + } + } + + if (StringUtil.isNotBlank(errorMsgNoRegister.toString())) { + throw new BusinessCheckException(errorMsgNoRegister.toString()); + } + + for (String couponId : couponIdMap.keySet()) { + MtCoupon couponInfo = couponService.queryCouponById(Integer.parseInt(couponId)); + if (null == couponInfo) { + if (StringUtil.isNotBlank(errorMsgNoGroup.toString())) { + errorMsgNoGroup.append("," + couponId); + } else { + errorMsgNoGroup.append("卡券ID不存在:"+couponId); + } + continue; + } + + if (!couponInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("卡券ID"+couponId+"可能已删除或禁用"); + } + + Integer totalNum = couponInfo.getTotal() == null ? 0 : couponInfo.getTotal(); + Integer sendNum = couponIdMap.get(couponId); + Integer hasSendNum = getSendNum(Integer.parseInt(couponId)); + if (totalNum > 0 && ((totalNum - hasSendNum) < sendNum)) { + Integer needNum = sendNum - (totalNum - hasSendNum); + if (StringUtil.isNotBlank(errorMsgNoNum.toString())) { + errorMsgNoNum.append(";卡券ID:" + couponId + "存量不足,至少再添加" + needNum + "套"); + } else { + errorMsgNoNum.append("卡券ID:" + couponId + "存量不足,至少再添加" + needNum + "套"); + } + } + } + + if (StringUtil.isNotBlank(errorMsgNoGroup.toString())) { + throw new BusinessCheckException(errorMsgNoGroup.toString()); + } + + if (StringUtil.isNotBlank(errorMsgNoNum.toString())) { + throw new BusinessCheckException(errorMsgNoNum.toString()); + } + + if (StringUtil.isNotBlank(errorMsg.toString())) { + throw new BusinessCheckException(errorMsg.toString()); + } + + // 导入批次 + String uuid = SeqUtil.getUUID(); + + // 至此,验证都通过了,开始发券 + try { + for (CouponCellDto cellDto : rows) { + // 发送张数 + Integer totalNum = 0; + // 发送总价值 + BigDecimal totalMoney = new BigDecimal("0.0"); + for (int gid = 0; gid < cellDto.getGroupId().size(); gid++) { + MtCouponGroup mtCouponGroup = getById(cellDto.getGroupId().get(gid).intValue()); + MtUser mtUser = memberService.queryMemberByMobile(mtCouponGroup.getMerchantId(), cellDto.getMobile()); + couponService.sendCoupon(cellDto.getGroupId().get(gid).intValue(), mtUser.getId(), cellDto.getNum().get(gid), false, uuid, operator); + List couponList = couponService.queryCouponListByGroupId(cellDto.getGroupId().get(gid).intValue()); + // 累加总张数、总价值 + for (MtCoupon coupon : couponList) { + totalNum = totalNum + (coupon.getSendNum()*cellDto.getNum().get(gid)); + totalMoney = totalMoney.add((coupon.getAmount().multiply(new BigDecimal(cellDto.getNum().get(gid)).multiply(new BigDecimal(coupon.getSendNum()))))); + } + } + + MtUser mtUser = memberService.queryMemberByMobile(cellDto.getMerchantId(), cellDto.getMobile()); + + // 发放记录 + ReqSendLogDto dto = new ReqSendLogDto(); + dto.setMerchantId(cellDto.getMerchantId()); + dto.setType(2); + dto.setMobile(cellDto.getMobile()); + dto.setUserId(mtUser.getId()); + dto.setFileName(originalFileName); + dto.setFilePath(filePath); + dto.setGroupId(0); + dto.setCouponId(0); + dto.setGroupName(""); + dto.setSendNum(0); + dto.setOperator(operator); + dto.setUuid(uuid); + sendLogService.addSendLog(dto); + + // 发送短信 + try { + List mobileList = new ArrayList<>(); + mobileList.add(cellDto.getMobile()); + Map params = new HashMap<>(); + params.put("totalNum", totalNum+""); + params.put("totalMoney", totalMoney+""); + sendSmsService.sendSms(cellDto.getMerchantId(), "received-coupon", mobileList, params); + } catch (Exception e) { + log.error("发券发送短信出错:", e.getMessage()); + } + } + } catch (BusinessCheckException e) { + throw new BusinessCheckException(e.getMessage()); + } + return uuid; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/CouponServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/CouponServiceImpl.java new file mode 100644 index 0000000..69602c8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/CouponServiceImpl.java @@ -0,0 +1,1303 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.dto.CouponDto; +import com.fuint.common.dto.ReqCouponDto; +import com.fuint.common.dto.ReqSendLogDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.CouponListParam; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.bean.CouponNumBean; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 卡券业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class CouponServiceImpl extends ServiceImpl implements CouponService { + + private static final Logger logger = LoggerFactory.getLogger(CouponServiceImpl.class); + + private MtCouponMapper mtCouponMapper; + + private MtUserCouponMapper mtUserCouponMapper; + + private MtConfirmLogMapper mtConfirmLogMapper; + + private MtSendLogMapper mtSendLogMapper; + + private MtStoreMapper mtStoreMapper; + + private MtCouponGoodsMapper mtCouponGoodsMapper; + + private MtOrderMapper mtOrderMapper; + + private MtGoodsMapper mtGoodsMapper; + + /** + * 会员卡券服务接口 + * */ + private UserCouponService userCouponService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 会员等级服务接口 + * */ + private UserGradeService userGradeService; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 核销记录服务接口 + * */ + private ConfirmLogService confirmLogService; + + /** + * 卡券发放记录服务接口 + * */ + private SendLogService sendLogService; + + /** + * 卡券分组服务接口 + * */ + private CouponGroupService couponGroupService; + + /** + * 系统配置服务接口 + * */ + private SettingService settingService; + + /** + * 微信相关服务接口 + * */ + private WeixinService weixinService; + + /** + * 分页查询券列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryCouponListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCoupon::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtCoupon::getName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtCoupon::getStatus, status); + } + String groupId = paginationRequest.getSearchParams().get("groupId") == null ? "" : paginationRequest.getSearchParams().get("groupId").toString(); + if (StringUtils.isNotBlank(groupId)) { + lambdaQueryWrapper.eq(MtCoupon::getGroupId, groupId); + } + String type = paginationRequest.getSearchParams().get("type") == null ? "" : paginationRequest.getSearchParams().get("type").toString(); + if (StringUtils.isNotBlank(type)) { + lambdaQueryWrapper.eq(MtCoupon::getType, type); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtCoupon::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtCoupon::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtCoupon::getUpdateTime); + List dataList = mtCouponMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtCoupon.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存卡券信息 + * + * @param reqCouponDto 卡券实体 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存卡券信息") + public MtCoupon saveCoupon(ReqCouponDto reqCouponDto) throws BusinessCheckException, ParseException { + MtCoupon mtCoupon; + + if (reqCouponDto.getId() != null) { + mtCoupon = mtCouponMapper.selectById(reqCouponDto.getId()); + } else { + mtCoupon = new MtCoupon(); + if (reqCouponDto.getMerchantId() == null || reqCouponDto.getMerchantId() <= 0) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + } + // 固定有效期验证 + if (reqCouponDto.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + if (StringUtil.isNotBlank(reqCouponDto.getBeginTime()) && StringUtil.isNotBlank(reqCouponDto.getEndTime())) { + Date startTime = DateUtil.parseDate(reqCouponDto.getBeginTime()); + Date endTime = DateUtil.parseDate(reqCouponDto.getEndTime()); + if (endTime.after(new Date())) { + if (mtCoupon != null && mtCoupon.getId() != null && mtCoupon.getStatus().equals(StatusEnum.EXPIRED.getKey())) { + reqCouponDto.setStatus(StatusEnum.ENABLED.getKey()); + } + } + if (endTime.before(startTime)) { + throw new BusinessCheckException("生效期结束时间不能早于开始时间"); + } + } + } + if (reqCouponDto.getMerchantId() != null) { + mtCoupon.setMerchantId(reqCouponDto.getMerchantId()); + } + if (reqCouponDto.getStoreId() != null) { + mtCoupon.setStoreId(reqCouponDto.getStoreId()); + } + mtCoupon.setGroupId(reqCouponDto.getGroupId()); + if (reqCouponDto.getType() != null) { + mtCoupon.setType(reqCouponDto.getType()); + } + if (reqCouponDto.getContent() != null) { + mtCoupon.setContent(reqCouponDto.getContent()); + } + if (reqCouponDto.getName() != null) { + mtCoupon.setName(CommonUtil.replaceXSS(reqCouponDto.getName())); + } + if (reqCouponDto.getIsGive() != null) { + mtCoupon.setIsGive(reqCouponDto.getIsGive().equals(1) ? true : false); + } + if (reqCouponDto.getPoint() != null) { + mtCoupon.setPoint(reqCouponDto.getPoint()); + } + if (mtCoupon.getPoint() == null) { + mtCoupon.setPoint(0); + } + if (reqCouponDto.getLimitNum() != null) { + mtCoupon.setLimitNum(reqCouponDto.getLimitNum()); + } + if (mtCoupon.getLimitNum() == null) { + mtCoupon.setLimitNum(1); + } + if (reqCouponDto.getReceiveCode() != null) { + mtCoupon.setReceiveCode(reqCouponDto.getReceiveCode()); + } + if (mtCoupon.getReceiveCode() == null) { + mtCoupon.setReceiveCode(""); + } + + if (mtCoupon.getType().equals(CouponTypeEnum.TIMER.getKey())) { + if (reqCouponDto.getTimerPoint() != null) { + mtCoupon.setPoint(reqCouponDto.getTimerPoint()); + } + if (reqCouponDto.getTimerReceiveCode() != null) { + mtCoupon.setReceiveCode(reqCouponDto.getTimerReceiveCode()); + } + } + + mtCoupon.setStoreIds(reqCouponDto.getStoreIds()); + mtCoupon.setGradeIds(reqCouponDto.getGradeIds()); + + if (reqCouponDto.getSendNum() == null) { + reqCouponDto.setSendNum(1); + } + + mtCoupon.setSendWay(reqCouponDto.getSendWay()); + mtCoupon.setSendNum(reqCouponDto.getSendNum()); + + if (reqCouponDto.getTotal() == null) { + reqCouponDto.setTotal(0); + } + mtCoupon.setTotal(reqCouponDto.getTotal()); + + if (reqCouponDto.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + mtCoupon.setBeginTime(DateUtil.parseDate(reqCouponDto.getBeginTime())); + mtCoupon.setEndTime(DateUtil.parseDate(reqCouponDto.getEndTime())); + } + if (reqCouponDto.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + if (reqCouponDto.getExpireTime() == null || reqCouponDto.getExpireTime() < 0) { + throw new BusinessCheckException("请输入正确的有效天数"); + } + mtCoupon.setExpireTime(reqCouponDto.getExpireTime()); + } + mtCoupon.setExpireType(reqCouponDto.getExpireType()); + mtCoupon.setExceptTime(CommonUtil.replaceXSS(reqCouponDto.getExceptTime())); + mtCoupon.setDescription(CommonUtil.replaceXSS(reqCouponDto.getDescription())); + mtCoupon.setRemarks(CommonUtil.replaceXSS(reqCouponDto.getRemarks())); + mtCoupon.setInRule(CommonUtil.replaceXSS(reqCouponDto.getInRule())); + mtCoupon.setOutRule(CommonUtil.replaceXSS(reqCouponDto.getOutRule())); + mtCoupon.setApplyGoods(reqCouponDto.getApplyGoods()); + mtCoupon.setUseFor(reqCouponDto.getUseFor()); + + if (null == reqCouponDto.getAmount()) { + reqCouponDto.setAmount(new BigDecimal(0)); + } + mtCoupon.setAmount(reqCouponDto.getAmount()); + if (StringUtil.isNotBlank(reqCouponDto.getImage())) { + mtCoupon.setImage(reqCouponDto.getImage()); + } + mtCoupon.setRemarks(CommonUtil.replaceXSS(reqCouponDto.getRemarks())); + if (reqCouponDto.getStatus() == null || StringUtil.isEmpty(reqCouponDto.getStatus())) { + mtCoupon.setStatus(StatusEnum.ENABLED.getKey()); + } else { + mtCoupon.setStatus(reqCouponDto.getStatus()); + } + + // 创建时间 + if (reqCouponDto.getId() == null) { + mtCoupon.setCreateTime(new Date()); + } + + // 更新时间 + mtCoupon.setUpdateTime(new Date()); + + // 操作人 + mtCoupon.setOperator(reqCouponDto.getOperator()); + + if (mtCoupon.getId() == null) { + this.save(mtCoupon); + } else { + mtCouponMapper.updateById(mtCoupon); + } + + MtCoupon couponInfo = mtCouponMapper.selectById(mtCoupon.getId()); + + // 更新已下发的会员卡券有效期 + if (couponInfo.getId() != null && reqCouponDto.getEndTime() != null && StringUtil.isNotEmpty(reqCouponDto.getEndTime())) { + mtUserCouponMapper.updateExpireTime(couponInfo.getId(), reqCouponDto.getEndTime()); + } + + // 适用商品 + if (StringUtil.isNotBlank(reqCouponDto.getGoodsIds())) { + String[] goodsIds = reqCouponDto.getGoodsIds().split(","); + if (goodsIds.length > 0) { + // 1.先删除 + List couponGoodsList = mtCouponGoodsMapper.getCouponGoods(couponInfo.getId()); + for (MtCouponGoods cg : couponGoodsList) { + mtCouponGoodsMapper.deleteById(cg.getId()); + } + // 2.再添加 + for (int n = 0; n < goodsIds.length; n++) { + boolean isNumeric = CommonUtil.isNumeric(goodsIds[n]); + if (!isNumeric) { + throw new BusinessCheckException("适用商品ID必须为正整数!"); + } else { + MtGoods mtGoods = mtGoodsMapper.selectById(Integer.parseInt(goodsIds[n])); + if (mtGoods == null) { + throw new BusinessCheckException("适用商品不存在,请确认!"); + } + } + if (StringUtil.isNotEmpty(goodsIds[n])) { + MtCouponGoods mtCouponGoods = new MtCouponGoods(); + mtCouponGoods.setCouponId(couponInfo.getId()); + mtCouponGoods.setGoodsId(Integer.parseInt(goodsIds[n])); + mtCouponGoods.setStatus(StatusEnum.ENABLED.getKey()); + mtCouponGoods.setCreateTime(new Date()); + mtCouponGoods.setUpdateTime(new Date()); + mtCouponGoodsMapper.insert(mtCouponGoods); + } + } + } + } + + // 如果是优惠券或储值卡,并且是线下发放,生成会员卡券 + if (reqCouponDto.getId() == null && !mtCoupon.getType().equals(CouponTypeEnum.TIMER.getKey()) && mtCoupon.getSendWay().equals(SendWayEnum.OFFLINE.getKey())) { + Integer total = mtCoupon.getTotal() * mtCoupon.getSendNum(); + if (mtCoupon.getSendNum() == null || mtCoupon.getSendNum() <= 0) { + total = mtCoupon.getTotal(); + } + if (total > 0) { + String uuid = SeqUtil.getUUID(); + for (int i = 1; i <= total; i++) { + MtUserCoupon userCoupon = new MtUserCoupon(); + userCoupon.setMerchantId(mtCoupon.getMerchantId()); + userCoupon.setStoreId(mtCoupon.getStoreId()); + userCoupon.setCouponId(couponInfo.getId()); + userCoupon.setGroupId(mtCoupon.getGroupId()); + userCoupon.setMobile(""); + userCoupon.setUserId(0); + userCoupon.setStatus(UserCouponStatusEnum.UNSEND.getKey()); + userCoupon.setCreateTime(new Date()); + userCoupon.setUpdateTime(new Date()); + userCoupon.setExpireTime(couponInfo.getEndTime()); + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + userCoupon.setExpireTime(couponInfo.getEndTime()); + } + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, couponInfo.getExpireTime()); + expireTime = c.getTime(); + userCoupon.setExpireTime(expireTime); + } + userCoupon.setUuid(uuid); + userCoupon.setType(couponInfo.getType()); + + // 储值卡金额 + if (couponInfo.getAmount() == null || couponInfo.getAmount().compareTo(new BigDecimal("0")) <= 0) { + if (StringUtil.isNotEmpty(couponInfo.getInRule())) { + String[] arr = couponInfo.getInRule().split(","); + if (arr.length > 0) { + String[] values = arr[0].split("_"); + if (values.length > 1 && (StringUtil.isNotEmpty(values[1]))) { + couponInfo.setAmount(new BigDecimal(values[1])); + } else { + couponInfo.setAmount(new BigDecimal(values[0])); + } + } + } + } + + userCoupon.setAmount(couponInfo.getAmount()); + userCoupon.setBalance(couponInfo.getAmount()); + userCoupon.setStoreId(0); + userCoupon.setOperator(reqCouponDto.getOperator()); + userCoupon.setImage(couponInfo.getImage()); + + // 16位随机数 + userCoupon.setCode(SeqUtil.getRandomNumber(16)); + mtUserCouponMapper.insert(userCoupon); + } + } + } + + return mtCoupon; + } + + /** + * 根据ID获取券信息 + * + * @param id 券ID + * @return + */ + @Override + public MtCoupon queryCouponById(Integer id) { + return mtCouponMapper.selectById(id); + } + + /** + * 删除卡券 + * + * @param id 券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除卡券") + @Transactional(rollbackFor = Exception.class) + public void deleteCoupon(Long id, String operator) throws BusinessCheckException { + MtCoupon couponInfo = queryCouponById(id.intValue()); + if (null == couponInfo) { + throw new BusinessCheckException("卡券不存在"); + } + couponInfo.setStatus(StatusEnum.DISABLE.getKey()); + // 修改时间 + couponInfo.setUpdateTime(new Date()); + // 操作人 + couponInfo.setOperator(operator); + // 删除会员关联的卡券 + userCouponService.removeUserCouponByCouponId(couponInfo.getId()); + + mtCouponMapper.updateById(couponInfo); + } + + /** + * 获取卡券列表 + * + * @param couponListParam 查询参数 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject findCouponList(CouponListParam couponListParam) throws BusinessCheckException { + Integer pageNumber = couponListParam.getPage() == null ? Constants.PAGE_NUMBER : couponListParam.getPage(); + Integer pageSize = couponListParam.getPageSize() == null ? Constants.PAGE_SIZE : couponListParam.getPageSize(); + String status = couponListParam.getStatus() == null ? StatusEnum.ENABLED.getKey() : couponListParam.getStatus(); + String type = couponListParam.getType() == null ? "" : couponListParam.getType(); + Integer userId = couponListParam.getUserId() == null ? 0 : couponListParam.getUserId(); + Integer needPoint = couponListParam.getNeedPoint() == null ? 0 : couponListParam.getNeedPoint(); + String sendWay = couponListParam.getSendWay() == null ? "front" : couponListParam.getSendWay(); + Integer merchantId = couponListParam.getMerchantId() == null ? 0 : couponListParam.getMerchantId(); + Integer storeId = couponListParam.getStoreId() == null ? 0 : couponListParam.getStoreId(); + String keyword = couponListParam.getKeyword() == null ? "" : couponListParam.getKeyword(); + String sortType = couponListParam.getSortType() == null ? "" : couponListParam.getSortType(); + String sortPrice = couponListParam.getSortPrice() == null ? "0" : couponListParam.getSortPrice(); + + Page pageHelper = PageHelper.startPage(pageNumber, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtCoupon::getStatus, StatusEnum.DISABLE.getKey()); + if (StringUtil.isNotEmpty(status)) { + lambdaQueryWrapper.eq(MtCoupon::getStatus, status); + } + if (StringUtil.isNotEmpty(sendWay)) { + lambdaQueryWrapper.eq(MtCoupon::getSendWay, sendWay); + } + if (StringUtil.isNotEmpty(keyword)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtCoupon::getId, keyword) + .or() + .like(MtCoupon::getName, keyword)); + } + if (StringUtil.isNotEmpty(type)) { + lambdaQueryWrapper.eq(MtCoupon::getType, type); + } + if (needPoint != null && needPoint > 0) { + lambdaQueryWrapper.eq(MtCoupon::getPoint, 0); + } + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtCoupon::getMerchantId, merchantId); + } + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtCoupon::getStoreId, storeId); + } + if (StringUtil.isNotEmpty(sortType)) { + if (sortType.equals("price")) { + if (sortPrice.equals("0")) { + lambdaQueryWrapper.orderByDesc(MtCoupon::getAmount); + } else { + lambdaQueryWrapper.orderByAsc(MtCoupon::getAmount); + } + } + } else { + lambdaQueryWrapper.orderByAsc(MtCoupon::getId); + } + List dataList = mtCouponMapper.selectList(lambdaQueryWrapper); + + // 处理已过期 + for (MtCoupon coupon : dataList) { + // 固定期限 + if (coupon.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey()) && (coupon.getEndTime() != null) && coupon.getEndTime().before(new Date())) { + coupon.setStatus(StatusEnum.EXPIRED.getKey()); + coupon.setUpdateTime(new Date()); + mtCouponMapper.updateById(coupon); + } + // 领取后生效 + if (coupon.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey()) && (coupon.getExpireTime() != null)) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, coupon.getExpireTime()); + expireTime = c.getTime(); + if (expireTime.before(new Date())) { + coupon.setStatus(StatusEnum.EXPIRED.getKey()); + coupon.setUpdateTime(new Date()); + mtCouponMapper.updateById(coupon); + } + } + } + + List content = new ArrayList<>(); + String baseImage = settingService.getUploadBasePath(); + for (int i = 0; i < dataList.size(); i++) { + CouponDto item = new CouponDto(); + BeanUtils.copyProperties(dataList.get(i), item); + item.setIsReceive(false); + item.setImage(baseImage + item.getImage()); + + // 是否领取,且领取量大于限制数 + List statusList = Arrays.asList(UserCouponStatusEnum.UNUSED.getKey(), UserCouponStatusEnum.USED.getKey(), UserCouponStatusEnum.EXPIRE.getKey()); + List userCoupon = mtUserCouponMapper.getUserCouponListByCouponId(userId, item.getId(), statusList); + if ((userCoupon.size() >= dataList.get(i).getLimitNum()) && (dataList.get(i).getLimitNum() > 0)) { + item.setIsReceive(true); + item.setUserCouponId(userCoupon.get(0).getId()); + } + + // 领取或预存数量 + CouponNumBean numData = mtUserCouponMapper.getPeopleNumByCouponId(item.getId()); + Long num; + if (null == numData) { + num = 0l; + } else { + num = numData.getNum(); + } + item.setGotNum(num.intValue()); + + // 剩余数量 + Integer leftNum = dataList.get(i).getTotal() - item.getGotNum(); + item.setLeftNum(leftNum >= 0 ? leftNum : 0); + + String sellingPoint = ""; + + // 优惠券卖点 + if (item.getType().equals(CouponTypeEnum.COUPON.getKey())) { + if (StringUtil.isNotEmpty(item.getOutRule()) && Integer.parseInt(item.getOutRule()) > 0) { + sellingPoint = "满" + item.getOutRule() + "元可用"; + } else { + sellingPoint = "无门槛券"; + } + } + + // 储值卡卖点 + if (item.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + if (StringUtil.isNotEmpty(item.getInRule())) { + String inRuleArr[] = item.getInRule().split(","); + if (inRuleArr.length > 0) { + for (int n = 0; n < inRuleArr.length; n++) { + String store[] = inRuleArr[n].split("_"); + sellingPoint = "预存" + store[0] + "到账" + store[1]; + } + } + } + } + + // 计次卡提示 + if (item.getType().equals(CouponTypeEnum.TIMER.getKey()) && StringUtil.isNotEmpty(item.getOutRule())) { + sellingPoint = "累计" + item.getOutRule() + "次卡"; + } + + item.setSellingPoint(sellingPoint); + content.add(item); + } + + PageRequest pageRequest = PageRequest.of(pageNumber, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, CouponDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(content); + + return new ResponseObject(200, "查询成功", paginationResponse); + } + + /** + * 根据分组ID获取卡券列表 + * + * @param groupId 查询参数 + * @return + * */ + public List queryCouponListByGroupId(Integer groupId) { + return mtCouponMapper.queryByGroupId(groupId.intValue()); + } + + /** + * 发放卡券 + * + * @param couponId 卡券ID + * @param userId 会员ID + * @param num 发放套数 + * @param sendMessage 是否发送消息 + * @param uuid 批次号 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "发放卡券") + public ResponseObject sendCoupon(Integer couponId, Integer userId, Integer num, Boolean sendMessage, String uuid, String operator) throws BusinessCheckException { + ResponseObject response = new ResponseObject(200, "发放成功", null); + if (StringUtil.isEmpty(uuid)) { + uuid = SeqUtil.getUUID(); + } + MtCoupon couponInfo = queryCouponById(couponId); + MtUser userInfo = memberService.queryMemberById(userId); + + if (null == userInfo || !userInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + response.setMessage("该会员不存在或已禁用,请先注册会员"); + response.setCode(201); + return response; + } + + String mobile = StringUtil.isNotEmpty(userInfo.getMobile()) ? userInfo.getMobile() : ""; + + // 判断券是否有效 + if (!couponInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + response.setMessage("卡券“"+couponInfo.getName()+"”已停用,不能发放"); + response.setCode(201); + return response; + } + + // 判断是否过期 + Date now = new Date(); + if (couponInfo.getEndTime() != null && couponInfo.getEndTime().before(now)) { + response.setMessage("卡券“"+ couponInfo.getName() +"”已过期,不能发放"); + response.setCode(201); + return response; + } + + // 是否超过拥有数量 + if (couponInfo.getLimitNum() != null && couponInfo.getLimitNum() > 0) { + if (num > couponInfo.getLimitNum()) { + response.setMessage("该卡券每个会员最多拥有数量是" + couponInfo.getLimitNum()); + response.setCode(201); + return response; + } + } + + // 发放总数量是否已经超额 + if (couponInfo.getTotal() != null && couponInfo.getTotal() > 0) { + Long sendNum = mtUserCouponMapper.getSendNum(couponId); + Long total = Long.parseLong(couponInfo.getTotal().toString()); + if (sendNum.compareTo(total) >= 0) { + response.setMessage("该卡券发行总数量是" + couponInfo.getTotal() + ",现已超额!"); + response.setCode(201); + return response; + } + } + + // 发放的是储值卡 + if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + if (StringUtil.isNotEmpty(couponInfo.getInRule())) { + String storeParams = ""; + String[] paramArr = couponInfo.getInRule().split(","); + for (int i = 0; i < paramArr.length; i++) { + if (StringUtil.isNotEmpty(storeParams)) { + storeParams = storeParams + "," + paramArr[i] + "_" + num; + } else { + storeParams = paramArr[i] + "_" + num; + } + } + Map param = new HashMap<>(); + param.put("couponId", couponInfo.getId()); + param.put("userId", userInfo.getId()); + param.put("param", storeParams); + param.put("orderId", 0); + userCouponService.preStore(param); + } + return response; + } + + // 优惠券或计次卡,发放num套 + for (int k = 1; k <= num; k++) { + for (int j = 1; j <= couponInfo.getSendNum(); j++) { + MtUserCoupon userCoupon = new MtUserCoupon(); + userCoupon.setCouponId(couponInfo.getId()); + userCoupon.setType(couponInfo.getType()); + userCoupon.setImage(couponInfo.getImage()); + userCoupon.setMerchantId(couponInfo.getMerchantId()); + userCoupon.setStoreId(userInfo.getStoreId()); + userCoupon.setAmount(couponInfo.getAmount()); + userCoupon.setBalance(couponInfo.getAmount()); + userCoupon.setOperator(operator); + userCoupon.setGroupId(couponInfo.getGroupId()); + userCoupon.setMobile(mobile); + userCoupon.setUserId(userInfo.getId()); + userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + userCoupon.setCreateTime(new Date()); + userCoupon.setUpdateTime(new Date()); + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + userCoupon.setExpireTime(couponInfo.getEndTime()); + } + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, couponInfo.getExpireTime()); + expireTime = c.getTime(); + userCoupon.setExpireTime(expireTime); + } + // 12位随机数 + userCoupon.setCode(SeqUtil.getRandomNumber(12)); + userCoupon.setUuid(uuid); + mtUserCouponMapper.insert(userCoupon); + } + } + + // 发放记录 + MtCouponGroup mtCouponGroup = couponGroupService.queryCouponGroupById(couponInfo.getGroupId()); + ReqSendLogDto sendLogDto = new ReqSendLogDto(); + sendLogDto.setMerchantId(couponInfo.getMerchantId()); + sendLogDto.setType(1); + sendLogDto.setMobile(mobile); + sendLogDto.setUserId(userInfo.getId()); + sendLogDto.setFileName(""); + sendLogDto.setGroupId(couponInfo.getGroupId()); + sendLogDto.setGroupName(mtCouponGroup.getName()); + sendLogDto.setCouponId(couponInfo.getId()); + sendLogDto.setSendNum(num); + sendLogDto.setOperator(operator); + sendLogDto.setUuid(uuid); + sendLogDto.setMerchantId(couponInfo.getMerchantId()); + sendLogDto.setStoreId(couponInfo.getStoreId()); + sendLogService.addSendLog(sendLogDto); + + if (sendMessage && couponInfo.getAmount() != null && couponInfo.getAmount().compareTo(new BigDecimal("0")) > 0) { + try { + // 发送手机短信 + if (StringUtil.isNotEmpty(mobile)) { + List mobileList = new ArrayList<>(); + mobileList.add(mobile); + BigDecimal totalMoney = (couponInfo.getAmount() == null) ? (new BigDecimal("0.00")) : couponInfo.getAmount(); + Map params = new HashMap<>(); + params.put("totalNum", num.toString()); + params.put("totalMoney", totalMoney.toString()); + sendSmsService.sendSms(couponInfo.getMerchantId(), "received-coupon", mobileList, params); + } + // 发送小程序订阅消息 + if (userInfo != null && couponInfo != null && couponInfo.getAmount().compareTo(new BigDecimal("0")) > 0) { + Date nowTime = new Date(); + Date sendTime = new Date(nowTime.getTime()); + Map params = new HashMap<>(); + params.put("name", couponInfo.getName()); + params.put("amount", couponInfo.getAmount()); + params.put("tips", "您的卡券已到账,请查收~"); + weixinService.sendSubscribeMessage(userInfo.getMerchantId(), userInfo.getId(), userInfo.getOpenId(), WxMessageEnum.COUPON_ARRIVAL.getKey(), "pages/user/index", params, sendTime); + } + } catch (Exception e) { + logger.error("卡券发放消息发送失败:{}", e.getMessage()); + } + } + return response; + } + + /** + * 发放卡券 + * + * @param couponId 券ID + * @param userIds 会员ID + * @param num 发放套数 + * @param uuid 批次号 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "发放卡券") + public Boolean batchSendCoupon(Integer couponId, List userIds, Integer num, String uuid, String operator) throws BusinessCheckException { + if (userIds == null || userIds.size() < 1) { + throw new BusinessCheckException("发放对象异常,卡券发放失败"); + } + // 发放人数大于10就不发送消息了 + Boolean sendMsg = userIds.size() >= 10 ? false : true; + if (userIds != null && userIds.size() > 0) { + for (Integer userId : userIds) { + ResponseObject result = sendCoupon(couponId, userId, num, sendMsg, uuid, operator); + if (result.getCode() != 200) { + throw new BusinessCheckException("发放卡券失败:" + result.getMessage()); + } + } + } + return true; + } + + /** + * 核销卡券 + * + * @param userCouponId 用户卡券ID + * @param userId 员工会员ID + * @param storeId 店铺ID + * @param orderId 订单ID + * @param amount 核销金额 + * @param remark 核销备注 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "核销卡券") + public String useCoupon(Integer userCouponId, Integer userId, Integer storeId, Integer orderId, BigDecimal amount, String remark) throws BusinessCheckException { + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(userCouponId.intValue()); + MtOrder orderInfo = null; + if (orderId != null && orderId > 0) { + orderInfo = mtOrderMapper.selectById(orderId); + } + + if (userCoupon == null) { + throw new BusinessCheckException("该卡券不存在!"); + } else if (!userCoupon.getStatus().equals(UserCouponStatusEnum.UNUSED.getKey()) && !userCoupon.getStatus().equals(UserCouponStatusEnum.UNSEND.getKey())) { + throw new BusinessCheckException("该卡券状态有误,可能已使用或已过期!"); + } + + MtStore mtStore = null; + if (storeId != null && storeId > 0) { + mtStore = mtStoreMapper.selectById(storeId); + if (null == mtStore) { + throw new BusinessCheckException("该店铺不存在!"); + } else if (!mtStore.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("该店铺状态有误,可能已禁用"); + } + } + + // 判断有效期 + MtCoupon couponInfo = queryCouponById(userCoupon.getCouponId()); + Date begin = couponInfo.getBeginTime(); + Date end = couponInfo.getEndTime(); + // 领取后有效天数 + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + begin = userCoupon.getCreateTime(); + end = userCoupon.getExpireTime(); + } + Date now = new Date(); + if (now.before(begin)) { + throw new BusinessCheckException("该卡券还没到使用日期"); + } + if (end.before(now)) { + throw new BusinessCheckException("该卡券已过期"); + } + + // 是否在例外日期 + Calendar cal = Calendar.getInstance(); + Boolean isWeekend = false; + if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { + isWeekend = true; + } + + String exceptTime = couponInfo.getExceptTime(); + if (null != exceptTime && !exceptTime.equals("")) { + String[] exceptTimeList = exceptTime.split(","); + if (exceptTimeList.length > 0) { + for (String timeStr : exceptTimeList) { + if (timeStr.equals("weekend")) { + if (isWeekend) { + throw new BusinessCheckException("该卡券在当前日期不可用"); + } + } else { + String[] timeItem = exceptTime.split("_"); + if (timeItem.length == 2) { + try { + Date startTime = DateUtil.parseDate(timeItem[0], "yyyy-MM-dd HH:mm"); + Date endTime = DateUtil.parseDate(timeItem[1], "yyyy-MM-dd HH:mm"); + if (now.before(endTime) && now.after(startTime)) { + throw new BusinessCheckException("该卡券在当前日期不可用"); + } + } catch (ParseException pe) { + throw new BusinessCheckException("该卡券在当前日期不可用."); + } + } + } + } + } + } + + // 使用优惠券,判断满多少可用 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey()) && StringUtil.isNotEmpty(couponInfo.getOutRule())) { + if (orderInfo != null) { + if (orderInfo.getAmount().compareTo(new BigDecimal(couponInfo.getOutRule())) < 0) { + throw new BusinessCheckException("该卡券满"+ couponInfo.getOutRule() +"元才能使用"); + } + } + } + + // 判断可用店铺 + if (StringUtil.isNotEmpty(couponInfo.getStoreIds())) { + if (StringUtil.isNotEmpty(couponInfo.getStoreIds())) { + String[] storeIds = couponInfo.getStoreIds().split(","); + String useStoreId = (orderInfo != null) ? orderInfo.getStoreId().toString() : (storeId > 0 ? storeId.toString() : ""); + if (StringUtil.isNotEmpty(useStoreId) && storeIds.length > 0 && !Arrays.asList(storeIds).contains(useStoreId)) { + throw new BusinessCheckException("该卡券不能在当前门店使用"); + } + } + } + + // 判断适用会员等级 + if (userCoupon.getUserId() != null && userCoupon.getUserId() > 0 && StringUtil.isNotEmpty(couponInfo.getGradeIds())) { + MtUser mtUser = memberService.queryMemberById(userCoupon.getUserId()); + if (mtUser.getGradeId() == null) { + MtUserGrade defaultGrade = userGradeService.getInitUserGrade(mtUser.getMerchantId()); + if (defaultGrade != null) { + mtUser.setGradeId(defaultGrade.getId()); + } else { + mtUser.setGradeId(0); + } + } + String[] gradeIds = couponInfo.getGradeIds().split(","); + if (gradeIds.length > 0 && !Arrays.asList(gradeIds).contains(mtUser.getGradeId().toString())) { + throw new BusinessCheckException("该卡券不适用于该会员等级"); + } + } + + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + // 优惠券核销直接修改状态 + userCoupon.setStatus(UserCouponStatusEnum.USED.getKey()); + } else if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + // 储值卡核销,修改余额 + BigDecimal balance = userCoupon.getBalance(); + BigDecimal newBalance = balance.subtract(amount); + + if (newBalance.compareTo(new BigDecimal("0")) == -1) { + throw new BusinessCheckException("余额不足,无法核销"); + } + + if (newBalance.compareTo(new BigDecimal("0")) == 0) { + userCoupon.setStatus(UserCouponStatusEnum.USED.getKey()); + } + + userCoupon.setBalance(newBalance); + } else if (couponInfo.getType().equals(CouponTypeEnum.TIMER.getKey())) { + // 计次卡核销,增加核销次数至满 + Long confirmCount = confirmLogService.getConfirmNum(userCouponId); + if ((confirmCount.intValue() + 1) >= Integer.parseInt(couponInfo.getOutRule())) { + userCoupon.setStatus(UserCouponStatusEnum.USED.getKey()); + } + } + + userCoupon.setUpdateTime(new Date()); + userCoupon.setUsedTime(new Date()); + if (storeId != null && storeId > 0) { + userCoupon.setStoreId(storeId); + } + mtUserCouponMapper.updateById(userCoupon); + + // 生成核销流水 + MtConfirmLog confirmLog = new MtConfirmLog(); + confirmLog.setMerchantId(couponInfo.getMerchantId()); + StringBuilder code = new StringBuilder(); + String sStoreId="00000"+storeId.toString(); + code.append(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); + code.append(sStoreId.substring(sStoreId.length()-4)); + code.append(SeqUtil.getRandomNumber(6)); + confirmLog.setCode(code.toString()); + confirmLog.setCouponId(couponInfo.getId()); + confirmLog.setUserCouponId(userCouponId.intValue()); + confirmLog.setOrderId(orderId); + confirmLog.setCreateTime(new Date()); + confirmLog.setUpdateTime(new Date()); + confirmLog.setUserId(userCoupon.getUserId()); + confirmLog.setOperatorUserId(userId); + MtUser userInfo = null; + if (userId > 0) { + userInfo = memberService.queryMemberById(userId); + if (userInfo != null) { + confirmLog.setOperator(userInfo.getName()); + } + } + confirmLog.setStoreId(storeId); + confirmLog.setStatus(StatusEnum.ENABLED.getKey()); + + // 优惠券核销金额 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + amount = userCoupon.getAmount(); + } + + confirmLog.setAmount(amount); + confirmLog.setRemark(remark); + mtConfirmLogMapper.insert(confirmLog); + + try { + // 发送核销短信 + List mobileList = new ArrayList<>(); + mobileList.add(userCoupon.getMobile()); + Map params = new HashMap<>(); + params.put("couponName", couponInfo.getName()); + if (mtStore != null){ + params.put("storeName", mtStore.getName()); + } + params.put("sn", code.toString()); + sendSmsService.sendSms(couponInfo.getMerchantId(), "confirm-coupon", mobileList, params); + + // 发送小程序订阅消息 + Date nowTime = new Date(); + Date sendTime = new Date(nowTime.getTime()); + Map param = new HashMap<>(); + String dateTime = DateUtil.formatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm"); + param.put("name", couponInfo.getName()); + param.put("time", dateTime); + weixinService.sendSubscribeMessage(userInfo.getMerchantId(), userInfo.getId(), userInfo.getOpenId(), WxMessageEnum.COUPON_CONFIRM.getKey(), "pages/user/index", param, sendTime); + } catch (Exception e) { + logger.error("核销卡券发送通知消息出错:", e.getMessage()); + } + + return confirmLog.getCode(); + } + + /** + * 根据券ID删除会员卡券 + * + * @param id 券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除会员卡券") + public void deleteUserCoupon(Integer id, String operator) throws BusinessCheckException { + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(id); + if (null == userCoupon) { + return; + } + + // 未使用状态才能作废删除 + if(!userCoupon.getStatus().equals(UserCouponStatusEnum.UNUSED.getKey())) { + throw new BusinessCheckException("未使用状态的卡券才能作废"); + } + userCoupon.setStatus(UserCouponStatusEnum.DISABLE.getKey()); + + // 修改时间 + userCoupon.setUpdateTime(new Date()); + + // 操作人 + userCoupon.setOperator(operator); + + // 更新发券日志为部分作废状态 + mtSendLogMapper.updateSingleForRemove(userCoupon.getUuid(),UserCouponStatusEnum.USED.getKey()); + + mtUserCouponMapper.updateById(userCoupon); + } + + /** + * 根据券ID 撤销卡券核销 + * + * @param id 核销流水ID + * @param userCouponId 用户卡券ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "撤销卡券核销") + public void rollbackUserCoupon(Integer id, Integer userCouponId,String operator) throws BusinessCheckException { + MtConfirmLog mtConfirmLog = mtConfirmLogMapper.selectById(id); + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(userCouponId); + + if (null == mtConfirmLog || !mtConfirmLog.getUserCouponId().equals(userCouponId)) { + throw new BusinessCheckException("卡券核销流水不存在!"); + } + + if (null == userCoupon) { + throw new BusinessCheckException("用户卡券不存在"); + } + + // 卡券未过期才能撤销,当前时间小于过期日期才能删除,48小时 + Calendar endTimecal = Calendar.getInstance(); + endTimecal.setTime(mtConfirmLog.getCreateTime()); + endTimecal.add(Calendar.DAY_OF_MONTH, 2); + + if (endTimecal.getTime().before(new Date())) { + throw new BusinessCheckException("卡券核销已经超过48小时,无法撤销"); + } + + MtCoupon mtCoupon = mtCouponMapper.selectById(userCoupon.getCouponId()); + + // 卡券未过期才能撤销,当前时间小于过期日期才能删除 + if (mtCoupon.getEndTime().before(new Date())) { + throw new BusinessCheckException("卡券未过期才能撤销"); + } + + // 优惠券只有是使用状态且核销流水正常状态才能撤销 + if(userCoupon.getType().equals(CouponTypeEnum.COUPON.getKey())) { + if ((!userCoupon.getStatus().equals(UserCouponStatusEnum.USED.getKey())) || (!mtConfirmLog.getStatus().equals(StatusEnum.ENABLED.getKey()))) { + throw new BusinessCheckException("该劵状态异常,请稍后重试"); + } + } + + // 回退至可用状态 + userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + userCoupon.setStoreId(null); + userCoupon.setUsedTime(null); + userCoupon.setUpdateTime(new Date()); + + // 如果是储值卡则返回余额 + if (userCoupon.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + BigDecimal balance = userCoupon.getBalance(); + BigDecimal amount = mtConfirmLog.getAmount(); + if (amount.compareTo(new BigDecimal("0")) > 0) { + BigDecimal newBalance = balance.add(amount); + userCoupon.setBalance(newBalance); + } + } + + // 更新用户卡券 + mtUserCouponMapper.updateById(userCoupon); + + // 更新流水 + mtConfirmLog.setOperator(operator); + mtConfirmLog.setStatus(StatusEnum.DISABLE.getKey()); + mtConfirmLog.setUpdateTime(new Date()); + mtConfirmLog.setCancelTime(new Date()); + + mtConfirmLogMapper.updateById(mtConfirmLog); + } + + /** + * 根据ID获取用户卡券信息 + * @param userCouponId 查询参数 + * @throws BusinessCheckException + * @return + * */ + @Override + public MtUserCoupon queryUserCouponById(Integer userCouponId) { + return mtUserCouponMapper.selectById(userCouponId); + } + + /** + * 根据批次撤销卡券 + * + * @param uuid 批次ID + * @param operator 操作人 + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "根据批次撤销卡券") + public void removeUserCoupon(Long id, String uuid, String operator) { + Map searchParams = new HashMap<>(); + searchParams.put("uuid", uuid); + List paginationResponse = mtUserCouponMapper.selectByMap(searchParams); + + Integer total = paginationResponse.size(); + + List coupondIdList = mtUserCouponMapper.getCouponIdsByUuid(uuid); + List couponIds = new ArrayList<>(); + couponIds.add(0); + + Date nowDate = new Date(); + + for (int i = 0; i < coupondIdList.size(); i++) { + Integer couponId = coupondIdList.get(i); + MtCoupon couponInfo = queryCouponById(couponId); + if (couponInfo.getStatus().equals(StatusEnum.ENABLED.getKey()) && couponInfo.getEndTime().after(nowDate)) { + couponIds.add(couponId); + } + } + + Integer row = mtUserCouponMapper.removeUserCoupon(uuid, couponIds, operator); + if (row.compareTo( total.intValue()) != -1) { + mtSendLogMapper.updateForRemove(uuid, UserCouponStatusEnum.DISABLE.getKey(), total.intValue(), 0); + } else { + mtSendLogMapper.updateForRemove(uuid, UserCouponStatusEnum.USED.getKey(), row, (total.intValue()-row)); + } + } + + /** + * 判断卡券码是否过期 + * @param code 12位券码 + * @return + * */ + @Override + public boolean codeExpired(String code) { + if (StringUtil.isEmpty(code)) { + return true; + } + try { + Date dateTime = DateUtil.parseDate(code.substring(0, 14), "yyyyMMddHHmmss"); + + Long time = dateTime.getTime(); + Long nowTime = System.currentTimeMillis(); + + Long seconds = (nowTime - time) / 1000; + // 超过1小时 + if (seconds > 3600) { + return true; + } + } catch (Exception e) { + return true; + } + + return false; + } + + /** + * 判断卡券是否过期 + * + * @param coupon 卡券信息 + * @param userCoupon 会员卡券信息 + * @return + * */ + @Override + public boolean isCouponEffective(MtCoupon coupon, MtUserCoupon userCoupon) { + Date begin = coupon.getBeginTime(); + Date end = coupon.getEndTime(); + + if (coupon.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + begin = userCoupon.getCreateTime(); + end = userCoupon.getExpireTime(); + } + + Date now = new Date(); + + // 未生效 + if (begin != null) { + if (now.before(begin)) { + return false; + } + } + + // 已过期 + if (end != null) { + if (now.after(end)) { + return false; + } + } + + if (coupon.getStatus() == null) { + return false; + } + + // 状态异常 + if (!coupon.getStatus().equals(StatusEnum.ENABLED.getKey())) { + return false; + } + + return true; + } + + /** + * 删除我的卡券 + * + * @param userCouponId + * @param userId + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean removeCoupon(Integer userCouponId, Integer userId) throws BusinessCheckException { + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(userCouponId); + if (null == userCoupon) { + throw new BusinessCheckException("删除失败:该卡券不存在!"); + } + if (!userId.equals(userCoupon.getUserId())) { + throw new BusinessCheckException("删除失败:无操作权限!"); + } + userCoupon.setStatus(UserCouponStatusEnum.DISABLE.getKey()); + userCoupon.setUpdateTime(new Date()); + mtUserCouponMapper.updateById(userCoupon); + logger.info("删除卡券成功!"); + + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/DutyServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/DutyServiceImpl.java new file mode 100644 index 0000000..c3f122b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/DutyServiceImpl.java @@ -0,0 +1,305 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.DutyService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.common.domain.TreeNode; +import com.fuint.framework.exception.BusinessRuntimeException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.DutyStatusRequest; +import com.fuint.repository.mapper.TDutyMapper; +import com.fuint.repository.mapper.TDutySourceMapper; +import com.fuint.repository.model.TDuty; +import com.fuint.repository.model.TDutySource; +import com.fuint.repository.model.TSource; +import com.fuint.utils.ArrayUtil; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; + +/** + * 角色服务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class DutyServiceImpl extends ServiceImpl implements DutyService { + + private TDutyMapper tDutyMapper; + + private TDutySourceMapper tDutySourceMapper; + + /** + * 获取有效的角色集合 + * + * @param merchantId 商户ID + * @param accountId 账号ID + * @return + */ + @Override + public List getAvailableRoles(Integer merchantId, Integer accountId) { + List result = tDutyMapper.findByStatus(merchantId, StatusEnum.ENABLED.getKey()); + List ids = new ArrayList<>(); + if (result != null && result.size() > 0) { + for (TDuty tDuty : result) { + ids.add(tDuty.getDutyId().longValue()); + } + } + List roleIds = findDutiesByAccountId(accountId); + if (roleIds.size() > 0) { + for (Long roleId : roleIds) { + if (!ids.contains(roleId)) { + TDuty duty = getRoleById(roleId); + result.add(duty); + } + } + } + return result; + } + + /** + * 根据ID获取角色实体 + * + * @param roleId 角色ID + * @return + */ + @Override + public TDuty getRoleById(Long roleId) { + return tDutyMapper.selectById(roleId); + } + + /** + * 根据ID数组获取角色集合 + * + * @param ids 角色ID + * @return + */ + @Override + public List findDatasByIds(String[] ids) { + Long[] arrays = new Long[ids.length]; + for (int i = 0; i < ids.length; i++) { + arrays[i] = Long.parseLong(ids[i]); + } + return tDutyMapper.findByIdIn(ArrayUtil.toList(arrays)); + } + + /** + * 删除角色 + * + * @param dutyId 角色ID + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除后台角色") + public void deleteDuty(Integer merchantId, long dutyId) { + TDuty tDuty = getRoleById(dutyId); + if (!merchantId.equals(tDuty.getMerchantId()) && merchantId > 0) { + throw new BusinessRuntimeException("抱歉,您没有删除的权限"); + } + tDutySourceMapper.deleteSourcesByDutyId((int) dutyId); + tDutyMapper.deleteById(dutyId); + } + + /** + * 更新角色状态 + * + * @param merchantId 商户ID + * @param dutyStatusRequest 请求参数 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新后台角色状态") + public void updateStatus(Integer merchantId, DutyStatusRequest dutyStatusRequest) throws BusinessCheckException { + TDuty tDuty = tDutyMapper.selectById(dutyStatusRequest.getRoleId()); + + if (!merchantId.equals(tDuty.getMerchantId()) && merchantId > 0) { + throw new BusinessRuntimeException("抱歉,您没有操作的权限"); + } + + if (tDuty != null) { + tDuty.setStatus(dutyStatusRequest.getStatus()); + tDutyMapper.updateById(tDuty); + } else { + throw new BusinessCheckException("角色不存在."); + } + } + + /** + * 修改角色 + * + * @param tduty 角色信息 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新后台角色") + public void updateDuty(TDuty tduty, List sources) throws BusinessCheckException { + TDuty existsDuty = tDutyMapper.selectById(tduty.getDutyId()); + if (existsDuty == null) { + throw new BusinessCheckException("角色不存在."); + } + if (!StringUtil.equals(tduty.getDutyName(), existsDuty.getDutyName())) { + TDuty tDuty = findByName(existsDuty.getMerchantId(), tduty.getDutyName()); + if (tDuty != null) { + throw new BusinessCheckException("角色名已存在."); + } + } + + existsDuty.setDescription(tduty.getDescription()); + existsDuty.setDutyType(tduty.getDutyType()); + existsDuty.setDutyName(tduty.getDutyName()); + existsDuty.setStatus(tduty.getStatus()); + + if (sources != null && sources.size() > 0) { + tDutySourceMapper.deleteSourcesByDutyId(tduty.getDutyId()); + for (TSource tSource : sources) { + TDutySource dutySource = new TDutySource(); + dutySource.setDutyId(tduty.getDutyId()); + dutySource.setSourceId(tSource.getSourceId()); + tDutySourceMapper.insert(dutySource); + } + } + + tDutyMapper.updateById(existsDuty); + } + + /** + * 根据角色名称合状态查询角色 + * + * @param merchantId 商户ID + * @param name 角色名称 + * @return + */ + @Override + public TDuty findByName(Integer merchantId, String name) { + return this.tDutyMapper.findByName(merchantId, name); + } + + /** + * 根据角色名称获取已经分配的菜单ID集合 + * + * @param dutyId 角色ID + * @return + */ + @Override + public List getSourceIdsByDutyId(Integer dutyId) { + return tDutySourceMapper.findSourceIdsByDutyId(dutyId); + } + + /** + * 角色保存方法 + * + * @param duty 角色信息 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增后台角色") + public void saveDuty(TDuty duty, List sources) throws BusinessCheckException { + TDuty existsDuty = tDutyMapper.findByName(duty.getMerchantId(), duty.getDutyName()); + if (existsDuty != null) { + throw new BusinessCheckException("角色名称已经存在."); + } + this.tDutyMapper.insert(duty); + if (sources != null && sources.size() > 0) { + for (TSource tSource : sources) { + TDutySource dutySource = new TDutySource(); + dutySource.setDutyId(duty.getDutyId()); + dutySource.setSourceId(tSource.getSourceId()); + tDutySourceMapper.insert(dutySource); + } + } + } + + /** + * 分页查询后台角色 + * @param paginationRequest + * @return + * */ + @Override + public PaginationResponse findDutiesByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(TDuty::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(TDuty::getDutyName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(TDuty::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.and(wq -> wq + .eq(TDuty::getMerchantId, 0) + .or() + .eq(TDuty::getMerchantId, merchantId)); + } + + lambdaQueryWrapper.orderByDesc(TDuty::getDutyId); + List dataList = tDutyMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, TDuty.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 获取菜单的属性结构 + * + * @param merchantId 商户ID + * @return + */ + @Override + public List getDutyTree(Integer merchantId) { + List tDuties = getAvailableRoles(merchantId, 0); + List trees = new ArrayList(); + if (tDuties != null && tDuties.size() > 0) { + TreeNode sourceTreeNode; + for (TDuty tDuty : tDuties) { + sourceTreeNode = new TreeNode(); + sourceTreeNode.setName(tDuty.getDutyName()); + sourceTreeNode.setId(tDuty.getDutyId()); + sourceTreeNode.setLevel(1); + sourceTreeNode.setPId(0); + trees.add(sourceTreeNode); + } + } + return trees; + } + + /** + * 根据账户获取角色 + * + * @param accountId 账号ID + * @return + */ + @Override + public List findDutiesByAccountId(Integer accountId) { + return tDutyMapper.getRoleIdsByAccountId(accountId); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/GenCodeServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/GenCodeServiceImpl.java new file mode 100644 index 0000000..9dd043a --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/GenCodeServiceImpl.java @@ -0,0 +1,186 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.GenCodeService; +import com.fuint.common.util.VelocityInitializer; +import com.fuint.common.util.VelocityUtils; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.exception.BusinessRuntimeException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.bean.ColumnBean; +import com.fuint.repository.mapper.TGenCodeMapper; +import com.fuint.repository.model.TGenCode; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.io.FileUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Date; +import java.util.List; + +/** + * 代码生成服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class GenCodeServiceImpl implements GenCodeService { + + private static final Logger logger = LoggerFactory.getLogger(GenCodeServiceImpl.class); + + private TGenCodeMapper tGenCodeMapper; + + /** + * 分页查询生成代码列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryGenCodeListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(TGenCode::getStatus, StatusEnum.DISABLE.getKey()); + + String tableName = paginationRequest.getSearchParams().get("tableName") == null ? "" : paginationRequest.getSearchParams().get("tableName").toString(); + if (org.apache.commons.lang.StringUtils.isNotBlank(tableName)) { + lambdaQueryWrapper.like(TGenCode::getTableName, tableName); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (org.apache.commons.lang.StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(TGenCode::getStatus, status); + } + + lambdaQueryWrapper.orderByAsc(TGenCode::getId); + List dataList = tGenCodeMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, TGenCode.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加生成代码 + * + * @param tGenCode 生成代码 + * @return + */ + @Override + @OperationServiceLog(description = "新增生成代码") + public TGenCode addGenCode(TGenCode tGenCode) throws BusinessCheckException { + tGenCode.setStatus(StatusEnum.ENABLED.getKey()); + Date dateTime = new Date(); + tGenCode.setCreateTime(dateTime); + tGenCode.setUpdateTime(dateTime); + Integer id = tGenCodeMapper.insert(tGenCode); + if (id > 0) { + return tGenCode; + } else { + logger.error("新增生成代码失败."); + throw new BusinessCheckException("新增生成代码失败."); + } + } + + /** + * 根据ID获取生成代码 + * + * @param id 生成代码ID + */ + @Override + public TGenCode queryGenCodeById(Integer id) { + return tGenCodeMapper.selectById(id); + } + + /** + * 修改生成代码 + * + * @param tGenCode + * @throws BusinessCheckException + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改生成代码") + public TGenCode updateGenCode(TGenCode tGenCode) { + Date dateTime = new Date(); + tGenCode.setUpdateTime(dateTime); + tGenCodeMapper.updateById(tGenCode); + return tGenCode; + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return + */ + @Override + public void generatorCode(String tableName) throws BusinessRuntimeException { + // 查询表信息 + TGenCode table = tGenCodeMapper.findGenCodeByTableName(tableName); + if (table == null) { + throw new BusinessRuntimeException("渲染模板失败,该表不存在."); + } + + List columns = tGenCodeMapper.getTableColumnList(table.getTablePrefix() + table.getTableName()); + + VelocityInitializer.initVelocity(); + VelocityContext context = VelocityUtils.prepareContext(table, columns); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(); + for (String template : templates) { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm")) { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, "UTF-8"); + tpl.merge(context, sw); + try { + String path = getGenPath(table, template); + logger.info("path ====== {}", path); + FileUtils.writeStringToFile(new File(path), sw.toString(), "UTF-8"); + } catch (IOException e) { + throw new BusinessRuntimeException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(TGenCode table, String template) { + String genPath = table.getBackendPath(); + if (StringUtils.equals(genPath, "/")) { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/GiveServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/GiveServiceImpl.java new file mode 100644 index 0000000..9635cbc --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/GiveServiceImpl.java @@ -0,0 +1,332 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.GiveDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.param.GiveParam; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.MtGiveItemMapper; +import com.fuint.repository.mapper.MtGiveMapper; +import com.fuint.repository.mapper.MtUserCouponMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.*; + +/** + * 转赠业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class GiveServiceImpl extends ServiceImpl implements GiveService { + + private static final Logger logger = LoggerFactory.getLogger(GiveServiceImpl.class); + + private MtGiveMapper mtGiveMapper; + + private MtUserCouponMapper mtUserCouponMapper; + + private MtGiveItemMapper mtGiveItemMapper; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 会员等级服务接口 + * */ + private UserGradeService userGradeService; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 卡券分组服务接口 + * */ + private CouponGroupService couponGroupService; + + /** + * 分页查询转赠列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryGiveListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtGive::getStatus, StatusEnum.DISABLE.getKey()); + + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtGive::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtGive::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtGive::getStoreId, storeId); + } + String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString(); + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.eq(MtGive::getUserId, userId); + } + String giveUserId = paginationRequest.getSearchParams().get("giveUserId") == null ? "" : paginationRequest.getSearchParams().get("giveUserId").toString(); + if (StringUtils.isNotBlank(giveUserId)) { + lambdaQueryWrapper.eq(MtGive::getGiveUserId, giveUserId); + } + String couponId = paginationRequest.getSearchParams().get("couponId") == null ? "" : paginationRequest.getSearchParams().get("couponId").toString(); + if (StringUtils.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtGive::getCouponIds, couponId); + } + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtGive::getMobile, mobile); + } + String userMobile = paginationRequest.getSearchParams().get("userMobile") == null ? "" : paginationRequest.getSearchParams().get("userMobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtGive::getUserMobile, userMobile); + } + + lambdaQueryWrapper.orderByDesc(MtGive::getId); + List giveList = mtGiveMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + for (MtGive mtGive : giveList) { + GiveDto giveDto = new GiveDto(); + BeanUtils.copyProperties(mtGive, giveDto); + giveDto.setCreateTime(DateUtil.formatDate(mtGive.getCreateTime(), "yyyy-MM-dd HH:mm:ss")); + giveDto.setUpdateTime(DateUtil.formatDate(mtGive.getUpdateTime(), "yyyy-MM-dd HH:mm:ss")); + giveDto.setMobile(CommonUtil.hidePhone(giveDto.getMobile())); + giveDto.setUserMobile(CommonUtil.hidePhone(giveDto.getUserMobile())); + dataList.add(giveDto); + } + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, GiveDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 卡券转赠 + * + * @param giveParam + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject addGive(GiveParam giveParam) throws BusinessCheckException { + MtGive give = new MtGive(); + + String mobile = giveParam.getMobile() == null ? "" : giveParam.getMobile(); + String couponId = giveParam.getCouponId() == null ? "" : giveParam.getCouponId(); + String note = giveParam.getNote() == null ? "" : giveParam.getNote(); + String message = giveParam.getMessage() == null ? "" : giveParam.getMessage(); + Integer userId = giveParam.getUserId() == null ? 0 : giveParam.getUserId(); + Integer storeId = giveParam.getStoreId() == null ? 0 : giveParam.getStoreId(); + Integer merchantId = giveParam.getMerchantId() == null ? 0 : giveParam.getMerchantId(); + + if (StringUtil.isEmpty(mobile) || mobile.length() > 11 || mobile.length() < 11) { + throw new BusinessCheckException("转增对象手机号有误"); + } + + if (couponId == null) { + throw new BusinessCheckException("转增卡券不能为空"); + } + + String[] couponIds = couponId.split(","); + if (couponIds.length > 10) { + throw new BusinessCheckException("转增卡券数量不能超过10张"); + } + + // 如果赠予对象为空,则注册 + MtUser user = memberService.queryMemberByMobile(merchantId, mobile); + if (null == user) { + MtUser userInfo = new MtUser(); + userInfo.setMerchantId(merchantId); + userInfo.setName(mobile); + userInfo.setMobile(mobile); + MtUserGrade grade = userGradeService.getInitUserGrade(merchantId); + if (grade != null) { + userInfo.setGradeId(grade.getId()); + } + userInfo.setBalance(new BigDecimal(0)); + userInfo.setStatus(StatusEnum.ENABLED.getKey()); + user = memberService.addMember(userInfo, "0"); + } else { + if (!user.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("转增对象可能已被禁用"); + } + } + + if (null == user) { + throw new BusinessCheckException("创建转增对象用户信息失败"); + } + + if (user.getId() == userId) { + throw new BusinessCheckException("转增对象不能是自己"); + } + + BigDecimal money = new BigDecimal(0); + List couponIdList = new ArrayList<>(); + List couponNames = new ArrayList<>(); + List groupIds = new ArrayList<>(); + List groupNames = new ArrayList<>(); + + for (String id : couponIds) { + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(Integer.parseInt(id)); + MtCoupon coupon = couponService.queryCouponById(userCoupon.getCouponId()); + if (!couponIdList.contains(coupon.getId().toString())) { + couponIdList.add(coupon.getId().toString()); + } + if (!couponNames.contains(coupon.getName())) { + couponNames.add(coupon.getName()); + } + MtCouponGroup group = couponGroupService.queryCouponGroupById(coupon.getGroupId()); + if (!groupIds.contains(group.getId().toString())) { + groupIds.add(group.getId().toString()); + } + if (!groupNames.contains(group.getName())) { + groupNames.add(group.getName()); + } + money = money.add(userCoupon.getAmount()); + if (null == userCoupon) { + throw new BusinessCheckException("转增卡券不存在"); + } else { + if (!userCoupon.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("转增卡券必须是未使用状态"); + } + if (!userCoupon.getUserId().toString().equals(userId.toString())) { + throw new BusinessCheckException("您的券可能已经转赠出去了"); + } + } + } + + MtUser myUser = memberService.queryMemberById(userId); + + give.setMobile(mobile); + give.setGiveUserId(userId); + give.setUserId(user.getId()); + give.setMerchantId(merchantId); + give.setStoreId(storeId); + give.setMoney(money); + give.setNum(couponIds.length); + give.setNote(note); + give.setMessage(message); + give.setUserMobile(myUser.getMobile()); + String couponIdsStr = StringUtil.join(couponIdList.toArray(), ","); + give.setGroupIds(StringUtil.join(groupIds.toArray(), ",")); + give.setGroupNames(StringUtil.join(groupNames.toArray(), ",")); + give.setCouponIds(couponIdsStr); + give.setCouponNames(StringUtil.join(couponNames.toArray(), ",")); + give.setStatus(StatusEnum.ENABLED.getKey()); + Date createTime = new Date(); + give.setCreateTime(createTime); + give.setUpdateTime(createTime); + + // 防止网络延迟,检查是否重复 + List uniqueData = mtGiveMapper.queryForUnique(give.getUserId(), give.getGiveUserId(), couponIdsStr, createTime); + if (uniqueData != null) { + if (uniqueData.size() > 0) { + throw new BusinessCheckException("当前网络延迟,不可重复操作"); + } + } + + this.save(give); + MtGive giveInfo = mtGiveMapper.selectById(give.getId()); + + for (String id : couponIds) { + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(Integer.parseInt(id)); + userCoupon.setUserId(user.getId()); + userCoupon.setUpdateTime(new Date()); + userCoupon.setMobile(user.getMobile()); + mtUserCouponMapper.updateById(userCoupon); + + MtGiveItem item = new MtGiveItem(); + item.setCreateTime(new Date()); + item.setGiveId(giveInfo.getId()); + item.setStatus(StatusEnum.ENABLED.getKey()); + item.setUpdateTime(new Date()); + item.setUserCouponId(Integer.parseInt(id)); + + mtGiveItemMapper.insert(item); + } + + try { + List mobileList = new ArrayList<>(); + mobileList.add(mobile); + Map params = new HashMap<>(); + params.put("totalNum", couponIds.length+""); + params.put("totalMoney", money+""); + sendSmsService.sendSms(merchantId, "received-coupon", mobileList, params); + } catch (Exception e) { + logger.error("核销卡券发送通知消息出错:", e.getMessage()); + } + + return new ResponseObject(200, "", giveInfo); + } + + /** + * 根据ID获取转赠信息 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtGive queryGiveById(Long id) { + return mtGiveMapper.selectById(id.intValue()); + } + + /** + * 根据条件搜索转赠详情 + * + * @param params 转赠查询条件 + * @return + * */ + @Override + public List queryItemByParams(Map params) { + if (params == null) { + params = new HashMap<>(); + } + return mtGiveItemMapper.selectByMap(params); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/GoodsServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/GoodsServiceImpl.java new file mode 100644 index 0000000..1a247e6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/GoodsServiceImpl.java @@ -0,0 +1,1074 @@ +package com.fuint.common.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.GoodsDto; +import com.fuint.common.dto.GoodsSpecValueDto; +import com.fuint.common.dto.GoodsTopDto; +import com.fuint.common.enums.GoodsTypeEnum; +import com.fuint.common.enums.PlatformTypeEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.param.GoodsListParam; +import com.fuint.common.service.*; +import com.fuint.common.util.SeqUtil; +import com.fuint.common.util.XlsUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.bean.GoodsBean; +import com.fuint.repository.bean.GoodsTopBean; +import com.fuint.repository.mapper.MtGoodsMapper; +import com.fuint.repository.mapper.MtGoodsSkuMapper; +import com.fuint.repository.mapper.MtGoodsSpecMapper; +import com.fuint.repository.mapper.MtStoreGoodsMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 商品业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class GoodsServiceImpl extends ServiceImpl implements GoodsService { + + private static final Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class); + + private MtGoodsMapper mtGoodsMapper; + + private MtGoodsSpecMapper mtGoodsSpecMapper; + + private MtGoodsSkuMapper mtGoodsSkuMapper; + + private MtStoreGoodsMapper mtStoreGoodsMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 商品分类服务接口 + * */ + private CateService cateService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 分页查询商品列表 + * + * @param param + * @return + */ + @Override + public PaginationResponse queryGoodsListByPagination(GoodsListParam param) throws BusinessCheckException { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtGoods::getStatus, StatusEnum.DISABLE.getKey()); + + String name = param.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtGoods::getName, name); + } + String status = param.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtGoods::getStatus, status); + } + String goodsNo = param.getGoodsNo(); + if (StringUtils.isNotBlank(goodsNo)) { + lambdaQueryWrapper.eq(MtGoods::getGoodsNo, goodsNo); + } + String isSingleSpec = param.getIsSingleSpec(); + if (StringUtils.isNotBlank(isSingleSpec)) { + lambdaQueryWrapper.eq(MtGoods::getIsSingleSpec, isSingleSpec); + } + Integer merchantId = param.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtGoods::getMerchantId, merchantId); + } + Integer storeId = param.getStoreId(); + if (storeId != null && storeId > 0 ) { + lambdaQueryWrapper.and(qw -> qw.eq(MtGoods::getStoreId, storeId) + .or(qw2 -> qw2.eq(MtGoods::getStoreId, 0) + .inSql(MtGoods::getId, "SELECT s.GOODS_ID FROM mt_store_goods s WHERE s.STORE_ID = "+storeId+" AND s.status = 'A'"))); + } + String type = param.getType(); + if (StringUtils.isNotBlank(type)) { + lambdaQueryWrapper.eq(MtGoods::getType, type); + } + Integer cateId = param.getCateId(); + if (cateId != null) { + lambdaQueryWrapper.eq(MtGoods::getCateId, cateId); + } + String hasStock = param.getStock(); + if (StringUtils.isNotBlank(hasStock)) { + if (hasStock.equals(YesOrNoEnum.YES.getKey())) { + lambdaQueryWrapper.gt(MtGoods::getStock, 0); + } else { + lambdaQueryWrapper.lt(MtGoods::getStock, 1); + } + } + String hasPrice = param.getHasPrice(); + if (StringUtils.isNotBlank(hasPrice)) { + if (hasPrice.equals(YesOrNoEnum.YES.getKey())) { + lambdaQueryWrapper.gt(MtGoods::getPrice, 0); + } + } + String platform = param.getPlatform(); + if (StringUtils.isNotBlank(platform)) { + if (platform.equals(PlatformTypeEnum.H5.getCode()) || platform.equals(PlatformTypeEnum.MP_WEIXIN.getCode())) { + // 会员端 + lambdaQueryWrapper.in(MtGoods::getPlatform, new ArrayList<>(Arrays.asList("0", "1"))); + } else if(platform.equals(PlatformTypeEnum.PC.getCode())) { + // PC端 + lambdaQueryWrapper.in(MtGoods::getPlatform, new ArrayList<>(Arrays.asList("0", "2"))); + } else if(platform.equals("0")) { + // 不限制 + lambdaQueryWrapper.eq(MtGoods::getPlatform, 0); + } else if(platform.equals("1")) { + // 仅会员端 + lambdaQueryWrapper.eq(MtGoods::getPlatform, 1); + } else if (platform.equals("2")) { + // 仅PC端 + lambdaQueryWrapper.eq(MtGoods::getPlatform, 2); + } + } + String sortType = param.getSortType(); + String sortPrice = param.getSortPrice(); + if (StringUtil.isNotEmpty(sortType)) { + if (sortType.equals("price")) { + if (sortPrice.equals("0")) { + lambdaQueryWrapper.orderByDesc(MtGoods::getPrice).orderByAsc(MtGoods::getId); + } else { + lambdaQueryWrapper.orderByAsc(MtGoods::getPrice).orderByAsc(MtGoods::getId); + } + } else if (sortType.equals("sales")) { + lambdaQueryWrapper.orderByDesc(MtGoods::getInitSale).orderByAsc(MtGoods::getId); + } else { + lambdaQueryWrapper.orderByAsc(MtGoods::getSort).orderByAsc(MtGoods::getId); + } + } else { + lambdaQueryWrapper.orderByAsc(MtGoods::getSort).orderByAsc(MtGoods::getId); + } + lambdaQueryWrapper.select( + MtGoods::getId, + MtGoods::getGoodsNo, + MtGoods::getMerchantId, + MtGoods::getStoreId, + MtGoods::getName, + MtGoods::getCanUsePoint, + MtGoods::getCateId, + MtGoods::getCostPrice, + MtGoods::getCouponIds, + MtGoods::getCreateTime, + MtGoods::getUpdateTime, + MtGoods::getInitSale, + MtGoods::getIsMemberDiscount, + MtGoods::getIsSingleSpec, + MtGoods::getPlatform, + MtGoods::getPrice, + MtGoods::getLinePrice, + MtGoods::getImages, + MtGoods::getLogo, + MtGoods::getCostPrice, + MtGoods::getSort, + MtGoods::getStatus, + MtGoods::getStock, + MtGoods::getType, + MtGoods::getOperator, + MtGoods::getWeight); + Page pageHelper = PageHelper.startPage(param.getPage(), param.getPageSize()); + List goodsList = mtGoodsMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + String basePath = settingService.getUploadBasePath(); + for (MtGoods mtGoods : goodsList) { + MtGoodsCate cateInfo = null; + if (mtGoods.getCateId() != null) { + cateInfo = cateService.queryCateById(mtGoods.getCateId()); + } + GoodsDto item = new GoodsDto(); + item.setId(mtGoods.getId()); + item.setInitSale(mtGoods.getInitSale()); + if (StringUtil.isNotEmpty(mtGoods.getLogo())) { + item.setLogo(basePath + mtGoods.getLogo()); + } + item.setStoreId(mtGoods.getStoreId()); + if (mtGoods.getStoreId() != null) { + MtStore storeInfo = storeService.queryStoreById(mtGoods.getStoreId()); + item.setStoreInfo(storeInfo); + } + item.setName(mtGoods.getName()); + item.setGoodsNo(mtGoods.getGoodsNo()); + item.setCateId(mtGoods.getCateId()); + item.setStock(mtGoods.getStock()); + item.setCateInfo(cateInfo); + item.setType(mtGoods.getType()); + item.setPrice(mtGoods.getPrice()); + item.setLinePrice(mtGoods.getLinePrice()); + item.setSalePoint(mtGoods.getSalePoint()); + item.setCreateTime(mtGoods.getCreateTime()); + item.setUpdateTime(mtGoods.getUpdateTime()); + item.setStatus(mtGoods.getStatus()); + item.setOperator(mtGoods.getOperator()); + item.setWeight(mtGoods.getWeight()); + item.setSort(mtGoods.getSort()); + dataList.add(item); + } + + PageRequest pageRequest = PageRequest.of(param.getPage(), param.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, GoodsDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存商品信息 + * + * @param reqDto 商品参数 + * @param storeIds 分配店铺 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存商品信息") + public MtGoods saveGoods(MtGoods reqDto, String storeIds) throws BusinessCheckException { + MtGoods mtGoods = new MtGoods(); + if (reqDto.getId() != null && reqDto.getId() > 0) { + mtGoods = queryGoodsById(reqDto.getId()); + reqDto.setMerchantId(mtGoods.getMerchantId()); + } + if (reqDto.getMerchantId() != null) { + mtGoods.setMerchantId(reqDto.getMerchantId() >= 0 ? reqDto.getMerchantId() : 0); + } + if (reqDto.getStoreId() != null) { + mtGoods.setStoreId(reqDto.getStoreId() >= 0 ? reqDto.getStoreId() : 0); + } + Integer storeId = reqDto.getStoreId() == null ? 0 : reqDto.getStoreId(); + if (reqDto.getMerchantId() == null || reqDto.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + mtGoods.setMerchantId(mtStore.getMerchantId()); + } + } + if (mtGoods.getMerchantId() == null || mtGoods.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + if (StringUtil.isNotEmpty(reqDto.getIsSingleSpec())) { + mtGoods.setIsSingleSpec(reqDto.getIsSingleSpec()); + } + if (reqDto.getId() <= 0 && StringUtil.isEmpty(reqDto.getIsSingleSpec())) { + mtGoods.setIsSingleSpec(YesOrNoEnum.YES.getKey()); + } + if (StringUtil.isNotEmpty(reqDto.getName())) { + mtGoods.setName(reqDto.getName()); + } + if (StringUtil.isNotEmpty(reqDto.getStatus())) { + mtGoods.setStatus(reqDto.getStatus()); + } + if (StringUtil.isNotEmpty(reqDto.getLogo())) { + mtGoods.setLogo(reqDto.getLogo()); + } + if (StringUtil.isNotEmpty(reqDto.getIsSingleSpec())) { + mtGoods.setIsSingleSpec(reqDto.getIsSingleSpec()); + } + if (StringUtil.isNotEmpty(reqDto.getDescription())) { + mtGoods.setDescription(reqDto.getDescription()); + } + if (StringUtil.isNotEmpty(reqDto.getOperator())) { + mtGoods.setOperator(reqDto.getOperator()); + } + if (StringUtil.isNotEmpty(reqDto.getType())) { + mtGoods.setType(reqDto.getType()); + } + if (reqDto.getPlatform() != null) { + mtGoods.setPlatform(reqDto.getPlatform()); + } + if (reqDto.getCateId() != null && reqDto.getCateId() > 0) { + mtGoods.setCateId(reqDto.getCateId()); + } + if (reqDto.getBookId() != null && reqDto.getBookId() > 0) { + mtGoods.setBookId(reqDto.getBookId()); + } + if (reqDto.getServiceTime() != null && reqDto.getServiceTime() > 0) { + mtGoods.setServiceTime(reqDto.getServiceTime()); + } + if (StringUtil.isNotEmpty(reqDto.getGoodsNo())) { + mtGoods.setGoodsNo(reqDto.getGoodsNo()); + } + if (reqDto.getSort() != null) { + mtGoods.setSort(reqDto.getSort()); + } + if (reqDto.getId() == null && (mtGoods.getSort().equals("") || mtGoods.getSort() == null )) { + mtGoods.setSort(0); + } + if (reqDto.getPrice() != null) { + mtGoods.setPrice(reqDto.getPrice()); + } + if (reqDto.getPrice() == null && reqDto.getId() <= 0) { + mtGoods.setPrice(new BigDecimal("0.00")); + } + if (reqDto.getLinePrice() != null) { + mtGoods.setLinePrice(reqDto.getLinePrice()); + } + if (reqDto.getLinePrice() == null && reqDto.getId() <= 0) { + mtGoods.setLinePrice(new BigDecimal("0.00")); + } + if (reqDto.getCostPrice() != null) { + mtGoods.setCostPrice(reqDto.getCostPrice()); + } + if (reqDto.getCostPrice() == null && reqDto.getId() <= 0) { + mtGoods.setCostPrice(new BigDecimal("0.00")); + } + if (StringUtil.isNotEmpty(reqDto.getCouponIds())) { + mtGoods.setCouponIds(reqDto.getCouponIds()); + } + if (reqDto.getWeight() != null) { + mtGoods.setWeight(reqDto.getWeight()); + } + if (reqDto.getInitSale() != null) { + mtGoods.setInitSale(reqDto.getInitSale()); + } + if (reqDto.getStock() != null) { + mtGoods.setStock(reqDto.getStock()); + } + if (StringUtil.isNotEmpty(reqDto.getSalePoint())) { + mtGoods.setSalePoint(reqDto.getSalePoint()); + } + if (StringUtil.isEmpty(reqDto.getSalePoint()) && reqDto.getId() <= 0) { + reqDto.setSalePoint(""); + } + if (StringUtil.isNotEmpty(reqDto.getCanUsePoint())) { + mtGoods.setCanUsePoint(reqDto.getCanUsePoint()); + } + if (StringUtil.isNotEmpty(reqDto.getIsMemberDiscount())) { + mtGoods.setIsMemberDiscount(reqDto.getIsMemberDiscount()); + } + if (StringUtil.isNotEmpty(reqDto.getImages())) { + mtGoods.setImages(reqDto.getImages()); + } + if (!mtGoods.getType().equals(GoodsTypeEnum.COUPON.getKey())) { + mtGoods.setCouponIds(""); + } + if (mtGoods.getCouponIds() != null && StringUtil.isNotEmpty(mtGoods.getCouponIds())) { + String str = mtGoods.getCouponIds().replace(",", ",").trim(); + String couponIds[] = str.split(","); + if (couponIds.length > 0) { + for (int i = 0; i < couponIds.length; i++) { + MtCoupon mtCoupon = couponService.queryCouponById(Integer.parseInt(couponIds[i])); + if (mtCoupon == null) { + throw new BusinessCheckException("卡券ID等于“"+couponIds[i]+"”的虚拟卡券不存在."); + } + } + } + } + Date dateTime = new Date(); + mtGoods.setUpdateTime(dateTime); + if (reqDto.getId() == null || reqDto.getId() <= 0) { + mtGoods.setCreateTime(dateTime); + this.save(mtGoods); + } else { + this.updateById(mtGoods); + } + + // 维护分配的店铺 + if (StringUtil.isNotEmpty(storeIds)) { + List storeIdList = Arrays.asList(storeIds.split(",").clone()); + Map param = new HashMap<>(); + param.put("goods_id", mtGoods.getId()); + param.put("status", StatusEnum.ENABLED.getKey()); + List storeGoodsList = mtStoreGoodsMapper.selectByMap(param); + // 判断是否有删除 + if (storeGoodsList != null && storeGoodsList.size() > 0) { + for (MtStoreGoods mtStoreGoods : storeGoodsList) { + if (!storeIdList.contains(mtStoreGoods.getStoreId().toString())) { + mtStoreGoods.setStatus(StatusEnum.DISABLE.getKey()); + mtStoreGoods.setUpdateTime(dateTime); + mtStoreGoods.setOperator(mtGoods.getOperator()); + mtStoreGoodsMapper.updateById(mtStoreGoods); + } + } + } + // 新增或更新 + if (storeIdList != null && storeIdList.size() > 0) { + for (String id : storeIdList) { + if (StringUtil.isNotEmpty(id) && Integer.parseInt(id) > 0) { + MtStoreGoods mtStoreGoods = new MtStoreGoods(); + mtStoreGoods.setMerchantId(mtGoods.getMerchantId()); + mtStoreGoods.setStoreId(Integer.parseInt(id)); + mtStoreGoods.setGoodsId(mtGoods.getId()); + mtStoreGoods.setCreateTime(dateTime); + mtStoreGoods.setUpdateTime(dateTime); + mtStoreGoods.setStatus(StatusEnum.ENABLED.getKey()); + mtStoreGoods.setOperator(reqDto.getOperator()); + Map params = new HashMap<>(); + params.put("goods_id", mtGoods.getId()); + params.put("store_id", id); + List goodsList = mtStoreGoodsMapper.selectByMap(params); + if (goodsList != null && goodsList.size() > 0) { + mtStoreGoods = goodsList.get(0); + mtStoreGoods.setUpdateTime(dateTime); + mtStoreGoods.setStatus(StatusEnum.ENABLED.getKey()); + mtStoreGoods.setOperator(reqDto.getOperator()); + mtStoreGoodsMapper.updateById(mtStoreGoods); + } else { + mtStoreGoodsMapper.insert(mtStoreGoods); + } + } + } + } + } + return mtGoods; + } + + /** + * 更新商品状态 + * + * @param goodsId 商品ID + * @param status 状态 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + public Boolean updateStatus(Integer goodsId, String status, String operator) throws BusinessCheckException { + MtGoods mtGoods = queryGoodsById(goodsId); + if (null == mtGoods) { + throw new BusinessCheckException("该商品不存在"); + } + mtGoods.setStatus(status); + mtGoods.setUpdateTime(new Date()); + mtGoods.setOperator(operator); + mtGoodsMapper.updateById(mtGoods); + // 删除商品 + if (status.equals(StatusEnum.DISABLE.getKey())) { + Map param = new HashMap<>(); + param.put("goods_id", goodsId); + param.put("status", StatusEnum.ENABLED.getKey()); + List goodsSpecList = mtGoodsSpecMapper.selectByMap(param); + if (goodsSpecList != null && goodsSpecList.size() > 0) { + for (MtGoodsSpec mtGoodsSpec : goodsSpecList) { + mtGoodsSpec.setStatus(StatusEnum.DISABLE.getKey()); + mtGoodsSpecMapper.updateById(mtGoodsSpec); + } + } + Map param1 = new HashMap<>(); + param1.put("goods_id", goodsId); + param1.put("status", StatusEnum.ENABLED.getKey()); + List goodsSkuList = mtGoodsSkuMapper.selectByMap(param1); + if (goodsSkuList != null && goodsSkuList.size() > 0) { + for (MtGoodsSku mtGoodsSku : goodsSkuList) { + mtGoodsSku.setStatus(StatusEnum.DISABLE.getKey()); + mtGoodsSkuMapper.updateById(mtGoodsSku); + } + } + } + return true; + } + + /** + * 根据ID获取商品信息 + * + * @param id 商品ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtGoods queryGoodsById(Integer id) { + MtGoods mtGoods = mtGoodsMapper.selectById(id); + if (mtGoods == null) { + return null; + } + return mtGoods; + } + + /** + * 根据编码获取商品信息 + * + * @param merchantId 商户ID + * @param goodsNo 商品编码 + * @throws BusinessCheckException + * @return + */ + @Override + public MtGoods queryGoodsByGoodsNo(Integer merchantId, String goodsNo) { + return mtGoodsMapper.getByGoodsNo(merchantId, goodsNo); + } + + /** + * 根据条码获取sku信息 + * + * @param skuNo skuNo + * @throws BusinessCheckException + * */ + @Override + public MtGoodsSku getSkuInfoBySkuNo(String skuNo) { + List mtGoodsSkuList = mtGoodsSkuMapper.getBySkuNo(skuNo); + if (mtGoodsSkuList.size() > 0) { + return mtGoodsSkuList.get(0); + } + return null; + } + + /** + * 根据ID获取商品详情 + * + * @param id 商品ID + * @return + */ + @Override + public GoodsDto getGoodsDetail(Integer id, boolean getDeleteSpec) { + if (id == null || id < 1) { + return null; + } + + MtGoods mtGoods = mtGoodsMapper.selectById(id); + GoodsDto goodsInfo = new GoodsDto(); + + if (mtGoods != null) { + try { + BeanUtils.copyProperties(mtGoods, goodsInfo); + } catch (Exception e) { + goodsInfo.setId(mtGoods.getId()); + goodsInfo.setType(mtGoods.getType()); + goodsInfo.setStoreId(mtGoods.getStoreId()); + goodsInfo.setName(mtGoods.getName()); + goodsInfo.setCateId(mtGoods.getCateId()); + goodsInfo.setGoodsNo(mtGoods.getGoodsNo()); + goodsInfo.setIsSingleSpec(mtGoods.getIsSingleSpec()); + goodsInfo.setLogo(mtGoods.getLogo()); + goodsInfo.setImages(mtGoods.getImages()); + goodsInfo.setStatus(mtGoods.getStatus()); + goodsInfo.setSort(mtGoods.getSort()); + goodsInfo.setPrice(mtGoods.getPrice()); + goodsInfo.setLinePrice(mtGoods.getLinePrice()); + goodsInfo.setServiceTime(mtGoods.getServiceTime()); + goodsInfo.setCouponIds(mtGoods.getCouponIds()); + } + } + + String basePath = settingService.getUploadBasePath(); + if (StringUtil.isNotEmpty(goodsInfo.getLogo())) { + goodsInfo.setLogo(basePath + goodsInfo.getLogo()); + } + + // 规格列表 + Map param = new HashMap<>(); + param.put("goods_id", id.toString()); + if (getDeleteSpec == false) { + param.put("status", StatusEnum.ENABLED.getKey()); + } + List goodsSpecList = mtGoodsSpecMapper.selectByMap(param); + goodsInfo.setSpecList(goodsSpecList); + + // sku列表 + if (goodsInfo.getIsSingleSpec().equals(YesOrNoEnum.NO.getKey())) { + List goodsSkuList = mtGoodsSkuMapper.selectByMap(param); + goodsInfo.setSkuList(goodsSkuList); + // 多规格商品的价格、库存数量 + if (goodsSkuList.size() > 0) { + goodsInfo.setPrice(goodsSkuList.get(0).getPrice()); + goodsInfo.setLinePrice(goodsSkuList.get(0).getLinePrice()); + Double stock = 0.0; + for (MtGoodsSku mtGoodsSku : goodsSkuList) { + stock = stock + mtGoodsSku.getStock(); + } + goodsInfo.setStock(stock); + } else { + goodsInfo.setStock(0.0); + } + } else { + goodsInfo.setSkuList(new ArrayList<>()); + } + + // 获取分配的店铺 + String storeIds = getStoreIds(mtGoods.getId()); + goodsInfo.setStoreIds(storeIds); + + return goodsInfo; + } + + /** + * 获取店铺的商品列表 + * + * @param storeId 店铺ID + * @param keyword 关键字 + * @param platform 平台 + * @param cateId 分类ID + * @param page 当前页码 + * @param pageSize 每页页数 + * @throws BusinessCheckException + * @return + * */ + @Override + public Map getStoreGoodsList(Integer storeId, String keyword, String platform, Integer cateId, Integer page, Integer pageSize) throws BusinessCheckException { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore == null) { + Map result = new HashMap<>(); + result.put("goodsList", new ArrayList<>()); + result.put("total", 0); + return result; + } + Integer merchantId = mtStore.getMerchantId() == null ? 0 : mtStore.getMerchantId(); + + Page pageHelper = PageHelper.startPage(page, pageSize); + List goodsList = new ArrayList<>(); + List skuList = new ArrayList<>(); + if (StringUtil.isNotEmpty(keyword)) { + skuList = mtGoodsSkuMapper.getBySkuNo(keyword); + } + if (skuList != null && skuList.size() > 0) { + MtGoods goods = mtGoodsMapper.selectById(skuList.get(0).getGoodsId()); + goodsList.add(goods); + } else { + pageHelper = PageHelper.startPage(page, pageSize); + if (keyword != null && StringUtil.isNotEmpty(keyword)) { + goodsList = mtGoodsMapper.searchStoreGoodsList(merchantId, storeId, keyword, platform); + } else { + goodsList = mtGoodsMapper.getStoreGoodsList(merchantId, storeId, cateId, platform); + } + } + List dataList = new ArrayList<>(); + if (goodsList.size() > 0) { + for (MtGoods mtGoods : goodsList) { + // 多规格商品价格、库存数量 + if (mtGoods != null && mtGoods.getIsSingleSpec().equals(YesOrNoEnum.NO.getKey())) { + Map param = new HashMap<>(); + param.put("goods_id", mtGoods.getId().toString()); + param.put("status", StatusEnum.ENABLED.getKey()); + List goodsSkuList = mtGoodsSkuMapper.selectByMap(param); + if (goodsSkuList.size() > 0) { + mtGoods.setPrice(goodsSkuList.get(0).getPrice()); + mtGoods.setLinePrice(goodsSkuList.get(0).getLinePrice()); + Double stock = 0.0; + for (MtGoodsSku mtGoodsSku : goodsSkuList) { + stock = stock + mtGoodsSku.getStock(); + } + mtGoods.setStock(stock); + } else { + mtGoods.setStock(0.0); + } + } + dataList.add(mtGoods); + } + } + + Map data = new HashMap<>(); + data.put("goodsList", dataList); + data.put("total", pageHelper.getTotal()); + + return data; + } + + /** + * 通过SKU获取规格列表 + * + * @param skuId skuID + * @return + * */ + @Override + public List getSpecListBySkuId(Integer skuId) { + if (skuId < 0 || skuId == null) { + return new ArrayList<>(); + } + List result = new ArrayList<>(); + + MtGoodsSku goodsSku = mtGoodsSkuMapper.selectById(skuId); + if (goodsSku == null) { + return result; + } + + String specIds = goodsSku.getSpecIds(); + String specIdArr[] = specIds.split("-"); + for (String specId : specIdArr) { + MtGoodsSpec mtGoodsSpec = mtGoodsSpecMapper.selectById(Integer.parseInt(specId)); + if (mtGoodsSpec != null) { + GoodsSpecValueDto dto = new GoodsSpecValueDto(); + dto.setSpecValueId(mtGoodsSpec.getId()); + dto.setSpecName(mtGoodsSpec.getName()); + dto.setSpecValue(mtGoodsSpec.getValue()); + result.add(dto); + } + } + + return result; + } + + /** + * 获取商品规格详情 + * + * @param specId 规格ID + * @return + * */ + @Override + public MtGoodsSpec getSpecDetail(Integer specId) { + return mtGoodsSpecMapper.selectById(specId); + } + + /** + * 更新已售数量 + * + * @param goodsId 商品ID + * @param saleNum 销售数量 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateInitSale(Integer goodsId, Double saleNum) { + return mtGoodsMapper.updateInitSale(goodsId, saleNum); + } + + /** + * 获取选择商品列表 + * + * @param params 查询参数 + * @return + */ + @Override + public PaginationResponse selectGoodsList(Map params) throws BusinessCheckException { + Integer page = params.get("page") == null ? Constants.PAGE_NUMBER : Integer.parseInt(params.get("page").toString()); + Integer pageSize = params.get("pageSize") == null ? Constants.PAGE_SIZE : Integer.parseInt(params.get("pageSize").toString()); + Integer merchantId = (params.get("merchantId") == null || StringUtil.isEmpty(params.get("merchantId").toString())) ? 0 : Integer.parseInt(params.get("merchantId").toString()); + Integer storeId = (params.get("storeId") == null || StringUtil.isEmpty(params.get("storeId").toString())) ? 0 : Integer.parseInt(params.get("storeId").toString()); + Integer cateId = (params.get("cateId") == null || StringUtil.isEmpty(params.get("cateId").toString())) ? 0 : Integer.parseInt(params.get("cateId").toString()); + String keyword = params.get("keyword") == null ? "" : params.get("keyword").toString(); + + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null && mtStore.getMerchantId() != null) { + merchantId = mtStore.getMerchantId(); + } + Page pageHelper = PageHelper.startPage(page, pageSize); + List dataList = new ArrayList<>(); + + List goodsList = mtGoodsMapper.selectGoodsList(merchantId, storeId, cateId, keyword); + + for (GoodsBean goodsBean : goodsList) { + GoodsDto goodsDto = new GoodsDto(); + goodsDto.setId(goodsBean.getGoodsId()); + goodsDto.setLogo(goodsBean.getLogo()); + goodsDto.setName(goodsBean.getName()); + goodsDto.setGoodsNo(goodsBean.getGoodsNo()); + goodsDto.setStoreId(goodsBean.getStoreId()); + goodsDto.setPrice(goodsBean.getPrice()); + goodsDto.setCateId(goodsBean.getCateId()); + goodsDto.setStock(goodsBean.getStock()); + if (goodsBean.getSpecIds() != null) { + Map param = new HashMap<>(); + param.put("GOODS_ID", goodsBean.getGoodsId()); + param.put("SPEC_IDS", goodsBean.getSpecIds()); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + List goodsSkuList = mtGoodsSkuMapper.selectByMap(param); + if (goodsSkuList != null && goodsSkuList.size() > 0) { + goodsDto.setSkuId(goodsSkuList.get(0).getId()); + goodsDto.setPrice(goodsSkuList.get(0).getPrice()); + if (goodsSkuList.get(0).getLogo() != null && StringUtil.isNotEmpty(goodsSkuList.get(0).getLogo())) { + goodsDto.setLogo(goodsSkuList.get(0).getLogo()); + } + goodsDto.setStock(goodsSkuList.get(0).getStock()); + List specList = new ArrayList<>(); + String[] specIds = goodsBean.getSpecIds().split("-"); + if (specIds.length > 0) { + for (String specId : specIds) { + MtGoodsSpec mtGoodsSpec = mtGoodsSpecMapper.selectById(Integer.parseInt(specId)); + if (mtGoodsSpec != null) { + specList.add(mtGoodsSpec); + } + } + } + goodsDto.setSpecList(specList); + } + } + dataList.add(goodsDto); + } + + PageRequest pageRequest = PageRequest.of(page, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, GoodsDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 获取商品销售排行榜 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public List getGoodsSaleTopList(Integer merchantId, Integer storeId, Date startTime, Date endTime) { + List dataList = mtGoodsMapper.getGoodsSaleTopList(merchantId, storeId, startTime, endTime); + List goodsList = new ArrayList<>(); + if (dataList != null && dataList.size() > 0) { + for (GoodsTopBean bean : dataList) { + GoodsTopDto dto = new GoodsTopDto(); + BeanUtils.copyProperties(bean, dto); + goodsList.add(dto); + } + } + return goodsList; + } + + /** + * 获取商品分配的店铺 + * + * @param goodsId 商品ID + * @return + * */ + @Override + public String getStoreIds(Integer goodsId) { + if (goodsId == null || goodsId <= 0) { + return ""; + } + Map params = new HashMap<>(); + params.put("goods_id", goodsId); + params.put("status", StatusEnum.ENABLED.getKey()); + List goodsList = mtStoreGoodsMapper.selectByMap(params); + List storeIds = new ArrayList<>(); + if (goodsList != null && goodsList.size() > 0) { + for (MtStoreGoods mtStoreGoods : goodsList) { + if (!storeIds.contains(mtStoreGoods.getStoreId().toString())) { + storeIds.add(mtStoreGoods.getStoreId().toString()); + } + } + } else { + storeIds.add("0"); + } + return storeIds.stream().collect(Collectors.joining(",")); + } + + /** + * 导入商品 + * + * @param file excel文件 + * @param accountInfo 操作者 + * @param filePath 文件路径 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "导入商品列表") + public Boolean importGoods(MultipartFile file, AccountInfo accountInfo, String filePath) throws BusinessCheckException { + String originalFileName = file.getOriginalFilename(); + boolean isExcel2003 = XlsUtil.isExcel2003(originalFileName); + boolean isExcel2007 = XlsUtil.isExcel2007(originalFileName); + + if (!isExcel2003 && !isExcel2007) { + logger.error("importGoods->uploadFile:{}", "文件类型不正确"); + throw new BusinessCheckException("文件类型不正确"); + } + + if (accountInfo == null || accountInfo.getMerchantId() == null || accountInfo.getMerchantId() <= 0) { + throw new BusinessCheckException("没有操作权限"); + } + + // 1、录入商品信息 + List> goodsList = new ArrayList<>(); + List> skuList = new ArrayList<>(); + try { + goodsList = XlsUtil.readExcelContent(file.getInputStream(), isExcel2003, 0, 1, null, null, null); + skuList = XlsUtil.readExcelContent(file.getInputStream(), isExcel2003, 1, 1, null, null, null); + } catch (IOException e) { + logger.error("GoodsServiceImpl->parseExcelContent{}", e); + throw new BusinessCheckException("商品导入失败" + e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + + if (goodsList != null && goodsList.size() > 0) { + if (goodsList.size() > 1500) { + throw new BusinessCheckException("商品导入失败,单次导入商品数量不能大于1500"); + } + for (int i = 0; i < goodsList.size(); i++) { + List goods = goodsList.get(i); + MtGoods mtGoods = new MtGoods(); + mtGoods.setId(0); + mtGoods.setName(goods.get(0)); + mtGoods.setType(GoodsTypeEnum.getKey(goods.get(1))); + mtGoods.setGoodsNo(StringUtil.isBlank(goods.get(2)) ? SeqUtil.getRandomNumber(15) : goods.get(2)); + mtGoods.setMerchantId(accountInfo.getMerchantId()); + mtGoods.setStoreId(accountInfo.getStoreId()); + Integer cateId = cateService.getGoodsCateId(accountInfo.getMerchantId(), accountInfo.getStoreId(), goods.get(3)); + if ((cateId == null || cateId <= 0) && StringUtil.isNotBlank(goods.get(3))) { + MtGoodsCate mtCate = new MtGoodsCate(); + mtCate.setMerchantId(accountInfo.getMerchantId()); + mtCate.setStoreId(accountInfo.getStoreId()); + mtCate.setName(goods.get(3)); + mtCate.setOperator(accountInfo.getAccountName()); + mtCate.setDescription("导入商品并创建商品分类"); + MtGoodsCate mtGoodsCate = cateService.addCate(mtCate); + if (mtGoodsCate != null) { + cateId = mtGoodsCate.getId(); + } + } + mtGoods.setCateId(cateId); + mtGoods.setOperator(accountInfo.getAccountName()); + String storeIds = storeService.getStoreIds(accountInfo.getMerchantId(), goods.get(4)); + String images = goods.get(5); + if (StringUtil.isNotBlank(images)) { + String[] imgArr = images.split(","); + if (imgArr.length > 0) { + mtGoods.setLogo(imgArr[0]); + String imagesJson = JSONObject.toJSONString(images.split(",")); + mtGoods.setImages(imagesJson); + } + } else { + mtGoods.setLogo("/static/defaultImage/none.png"); + } + mtGoods.setSort(Integer.parseInt(goods.get(6))); + mtGoods.setCanUsePoint(YesOrNoEnum.getKey(goods.get(7))); + mtGoods.setIsMemberDiscount(YesOrNoEnum.getKey(goods.get(8))); + if (goods.get(9).equals(YesOrNoEnum.YES.getKey()) || goods.get(9).equals("单规格")) { + mtGoods.setIsSingleSpec(YesOrNoEnum.YES.getKey()); + } else { + mtGoods.setIsSingleSpec(YesOrNoEnum.NO.getKey()); + } + mtGoods.setInitSale(Double.parseDouble(goods.get(10))); + mtGoods.setSalePoint(goods.get(11)); + mtGoods.setDescription(goods.get(12)); + mtGoods.setPrice(new BigDecimal("0")); + mtGoods.setLinePrice(new BigDecimal("0")); + mtGoods.setStock(0.0); + mtGoods.setStatus(StatusEnum.FORBIDDEN.getKey()); + saveGoods(mtGoods, storeIds); + } + } + + // 2、录入规格信息 + if (skuList != null && skuList.size() > 0) { + MtGoods mtGoods = null; + Double totalStock = 0d; + BigDecimal price = new BigDecimal("0"); + for (int j = 0; j < skuList.size(); j++) { + List sku = skuList.get(j); + List goodsList1 = mtGoodsMapper.getByGoodsName(accountInfo.getMerchantId(), sku.get(0)); + if (goodsList1.size() == 1) { + mtGoods = goodsList1.get(0); + } else if (goodsList1.size() > 1) { + throw new BusinessCheckException("商品导入失败,存在重复商品名称:" + sku.get(0)); + } + if (mtGoods != null) { + // 单规格 + if (mtGoods.getIsSingleSpec().equals(YesOrNoEnum.YES.getKey())) { + mtGoods.setPrice(new BigDecimal(sku.get(4))); + mtGoods.setLinePrice(new BigDecimal(sku.get(5))); + mtGoods.setStock(Double.parseDouble(sku.get(6))); + mtGoods.setWeight(new BigDecimal(sku.get(7))); + mtGoodsMapper.updateById(mtGoods); + } + // 多规格 + if (mtGoods.getIsSingleSpec().equals(YesOrNoEnum.NO.getKey())) { + List specIds = new ArrayList<>(); + if (StringUtil.isNotEmpty(sku.get(2)) && StringUtil.isNotEmpty(sku.get(3))) { + String[] specNameList = sku.get(2).split(","); + String[] specValueList = sku.get(3).split(","); + if (specNameList.length == specValueList.length) { + for (int y = 0; y < specNameList.length; y++) { + Integer specId = getSpecId(mtGoods.getId(), specNameList[y], specValueList[y]); + specIds.add(specId.toString()); + } + } + } + if (StringUtil.isNotEmpty(sku.get(1))) { + MtGoodsSku mtGoodsSku = new MtGoodsSku(); + mtGoodsSku.setSkuNo(sku.get(1)); + mtGoodsSku.setGoodsId(mtGoods.getId()); + mtGoodsSku.setSpecIds(String.join("-", specIds)); + BigDecimal skuPrice = new BigDecimal(sku.get(4)); + mtGoodsSku.setPrice(skuPrice); + mtGoodsSku.setLinePrice(new BigDecimal(sku.get(5))); + Double stock = Double.parseDouble(sku.get(6)); + mtGoodsSku.setStock(stock); + mtGoodsSku.setWeight(new BigDecimal(sku.get(7))); + mtGoodsSku.setStatus(StatusEnum.ENABLED.getKey()); + mtGoodsSkuMapper.insert(mtGoodsSku); + totalStock = totalStock + stock; + if (((skuPrice.compareTo(price) <= 0) || (price.compareTo(new BigDecimal("0")) <= 0)) && skuPrice.compareTo(new BigDecimal("0")) > 0) { + price = skuPrice; + } + } + } + } + } + // 更新商品价格和库存 + if (mtGoods != null) { + mtGoods.setStock(totalStock); + mtGoods.setPrice(price); + mtGoodsMapper.updateById(mtGoods); + } + } + return true; + } + + /** + * 获取规格ID + * + * @param goodsId 商品ID + * @param specName 规格名称 + * @param specValue 规格值 + * */ + @Override + public Integer getSpecId(Integer goodsId, String specName, String specValue) { + Map params = new HashMap<>(); + params.put("goods_id", goodsId); + params.put("name", specName); + params.put("value", specValue); + params.put("status", StatusEnum.ENABLED.getKey()); + Integer specId; + List specList = mtGoodsSpecMapper.selectByMap(params); + if (specList != null && specList.size() > 0) { + specId = specList.get(0).getId(); + } else { + MtGoodsSpec mtGoodsSpec = new MtGoodsSpec(); + mtGoodsSpec.setGoodsId(goodsId); + mtGoodsSpec.setName(specName); + mtGoodsSpec.setValue(specValue); + mtGoodsSpec.setStatus(StatusEnum.ENABLED.getKey()); + mtGoodsSpecMapper.insert(mtGoodsSpec); + specId = mtGoodsSpec.getId(); + } + return specId; + } + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/InvoiceServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/InvoiceServiceImpl.java new file mode 100644 index 0000000..99141b8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/InvoiceServiceImpl.java @@ -0,0 +1,241 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.param.InvoiceParam; +import com.fuint.common.service.OrderService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtInvoice; +import com.fuint.common.service.InvoiceService; +import com.fuint.common.enums.StatusEnum; +import com.fuint.repository.mapper.MtInvoiceMapper; +import com.fuint.repository.model.MtOrder; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +/** + * 发票服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class InvoiceServiceImpl extends ServiceImpl implements InvoiceService { + + private static final Logger logger = LoggerFactory.getLogger(InvoiceServiceImpl.class); + + private MtInvoiceMapper mtInvoiceMapper; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 分页查询数据列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryInvoiceListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtInvoice::getStatus, StatusEnum.DISABLE.getKey()); + + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.like(MtInvoice::getMobile, mobile); + } + String orderSn = paginationRequest.getSearchParams().get("orderSn") == null ? "" : paginationRequest.getSearchParams().get("orderSn").toString(); + if (StringUtils.isNotBlank(orderSn)) { + lambdaQueryWrapper.like(MtInvoice::getOrderSn, orderSn); + } + String title = paginationRequest.getSearchParams().get("title") == null ? "" : paginationRequest.getSearchParams().get("title").toString(); + if (StringUtils.isNotBlank(title)) { + lambdaQueryWrapper.like(MtInvoice::getTitle, title); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtInvoice::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtInvoice::getMerchantId, merchantId); + } + + lambdaQueryWrapper.orderByAsc(MtInvoice::getId); + List dataList = mtInvoiceMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtInvoice.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加发票 + * + * @param invoice 发票信息 + * @return + */ + @Override + @OperationServiceLog(description = "新增发票") + public MtInvoice addInvoice(InvoiceParam invoice) throws BusinessCheckException { + MtInvoice mtInvoice = new MtInvoice(); + if ((invoice.getOrderId() == null || invoice.getOrderId() <= 0) && StringUtil.isBlank(invoice.getOrderSn())) { + throw new BusinessCheckException("新增发票数据失败,订单参数不能为空"); + } + MtOrder order; + if (invoice.getOrderId() != null) { + order = orderService.getOrderInfo(invoice.getOrderId()); + } else { + order = orderService.getOrderInfoByOrderSn(invoice.getOrderSn()); + } + if (order == null) { + throw new BusinessCheckException("新增发票数据失败,订单信息不存在"); + } + + BeanUtils.copyProperties(invoice, mtInvoice); + Date nowTime = new Date(); + mtInvoice.setStatus(StatusEnum.ENABLED.getKey()); + mtInvoice.setUpdateTime(nowTime); + mtInvoice.setCreateTime(nowTime); + mtInvoice.setMerchantId(order.getMerchantId()); + mtInvoice.setStoreId(order.getStoreId()); + Integer id = mtInvoiceMapper.insert(mtInvoice); + if (id > 0) { + return mtInvoice; + } else { + logger.error("新增发票数据失败."); + throw new BusinessCheckException("新增发票数据失败"); + } + } + + /** + * 根据ID获取发票取息 + * + * @param id 发票ID + * @return + */ + @Override + public MtInvoice queryInvoiceById(Integer id) { + return mtInvoiceMapper.selectById(id); + } + + /** + * 根据ID删除发票 + * + * @param id 发票ID + * @param operator 操作人 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除发票") + public void deleteInvoice(Integer id, String operator) { + MtInvoice mtInvoice = queryInvoiceById(id); + if (null == mtInvoice) { + return; + } + mtInvoice.setStatus(StatusEnum.DISABLE.getKey()); + mtInvoice.setUpdateTime(new Date()); + mtInvoice.setOperator(operator); + mtInvoiceMapper.updateById(mtInvoice); + logger.info("删除发票信息"); + } + + /** + * 修改发票数据 + * + * @param invoice + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新发票") + public MtInvoice updateInvoice(InvoiceParam invoice) throws BusinessCheckException { + MtInvoice mtInvoice = queryInvoiceById(invoice.getId()); + if (mtInvoice == null) { + throw new BusinessCheckException("该发票状态异常"); + } + BeanUtils.copyProperties(invoice, mtInvoice); + mtInvoice.setUpdateTime(new Date()); + mtInvoiceMapper.updateById(mtInvoice); + return mtInvoice; + } + + /** + * 根据条件搜索发票 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + @Override + public List queryInvoiceListByParams(Map params) { + String orderSn = params.get("orderSn") == null ? "" : params.get("orderSn").toString(); + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey() : params.get("status").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtInvoice::getStatus, status); + } + if (StringUtils.isNotBlank(orderSn)) { + lambdaQueryWrapper.eq(MtInvoice::getOrderSn, orderSn); + } + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtInvoice::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtInvoice::getStoreId, 0) + .or() + .eq(MtInvoice::getStoreId, storeId)); + } + + lambdaQueryWrapper.orderByAsc(MtInvoice::getId); + List dataList = mtInvoiceMapper.selectList(lambdaQueryWrapper); + return dataList; + } + + /** + * 获取开票金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + */ + @Override + public BigDecimal getInvoiceTotalAmount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + return mtInvoiceMapper.getInvoiceTotalAmount(merchantId, storeId, beginTime, endTime); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/MemberGroupServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/MemberGroupServiceImpl.java new file mode 100644 index 0000000..32dd9d9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/MemberGroupServiceImpl.java @@ -0,0 +1,265 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.MemberGroupDto; +import com.fuint.common.dto.UserGroupDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtUserGroupMapper; +import com.fuint.repository.model.*; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.lang.String; +import java.util.*; + +/** + * 会员分组业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class MemberGroupServiceImpl extends ServiceImpl implements MemberGroupService { + + private static final Logger logger = LoggerFactory.getLogger(CouponGroupServiceImpl.class); + + private MtUserGroupMapper mtUserGroupMapper; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 分页查询会员分组列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryMemberGroupListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUserGroup::getStatus, StatusEnum.DISABLE.getKey()); + lambdaQueryWrapper.eq(MtUserGroup::getParentId, 0); + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtUserGroup::getName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtUserGroup::getStatus, status); + } + String id = paginationRequest.getSearchParams().get("id") == null ? "" : paginationRequest.getSearchParams().get("id").toString(); + if (StringUtils.isNotBlank(id)) { + lambdaQueryWrapper.eq(MtUserGroup::getId, id); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtUserGroup::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtUserGroup::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtUserGroup::getId); + List dataList = mtUserGroupMapper.selectList(lambdaQueryWrapper); + List userGroupList = new ArrayList<>(); + if (dataList != null && dataList.size() > 0) { + for (MtUserGroup mtUserGroup : dataList) { + UserGroupDto userGroupDto = new UserGroupDto(); + BeanUtils.copyProperties(mtUserGroup, userGroupDto); + userGroupDto.setChildren(getChildren(mtUserGroup.getId())); + userGroupDto.setMemberNum(getMemberNum(mtUserGroup.getId())); + userGroupList.add(userGroupDto); + } + } + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, UserGroupDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(userGroupList); + + return paginationResponse; + } + + /** + * 添加会员分组 + * + * @param memberGroupDto 会员分组 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "新增会员分组") + public MtUserGroup addMemberGroup(MemberGroupDto memberGroupDto) throws BusinessCheckException { + MtUserGroup userGroup = new MtUserGroup(); + Integer storeId = memberGroupDto.getStoreId() == null ? 0 : memberGroupDto.getStoreId(); + if (memberGroupDto.getMerchantId() == null || memberGroupDto.getMerchantId() <= 0) { + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null) { + memberGroupDto.setMerchantId(mtStore.getMerchantId()); + } + } + userGroup.setMerchantId(memberGroupDto.getMerchantId()); + userGroup.setStoreId(storeId); + userGroup.setParentId(memberGroupDto.getParentId()); + userGroup.setName(CommonUtil.replaceXSS(memberGroupDto.getName())); + userGroup.setDescription(CommonUtil.replaceXSS(memberGroupDto.getDescription())); + userGroup.setStatus(StatusEnum.ENABLED.getKey()); + userGroup.setCreateTime(new Date()); + userGroup.setUpdateTime(new Date()); + userGroup.setOperator(memberGroupDto.getOperator()); + this.save(userGroup); + return userGroup; + } + + /** + * 根据分组ID获取分组信息 + * + * @param id 分组ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtUserGroup queryMemberGroupById(Integer id) { + return mtUserGroupMapper.selectById(id); + } + + /** + * 根据ID删除会员分组 + * + * @param id 分组ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除会员分组") + public void deleteMemberGroup(Integer id, String operator) { + MtUserGroup userGroup = queryMemberGroupById(id); + if (null == userGroup) { + return; + } + + userGroup.setStatus(StatusEnum.DISABLE.getKey()); + userGroup.setUpdateTime(new Date()); + userGroup.setOperator(operator); + + this.updateById(userGroup); + } + + /** + * 修改会员分组 + * + * @param memberGroupDto + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新会员分组") + public MtUserGroup updateMemberGroup(MemberGroupDto memberGroupDto) throws BusinessCheckException { + MtUserGroup userGroup = queryMemberGroupById(memberGroupDto.getId()); + if (null == userGroup || StatusEnum.DISABLE.getKey().equalsIgnoreCase(userGroup.getStatus())) { + logger.error("该分组不存在或已被删除"); + throw new BusinessCheckException("该分组不存在或已被删除"); + } + if (memberGroupDto.getName() != null) { + userGroup.setName(CommonUtil.replaceXSS(memberGroupDto.getName())); + } + if (memberGroupDto.getDescription() != null) { + userGroup.setDescription(CommonUtil.replaceXSS(memberGroupDto.getDescription())); + } + if (memberGroupDto.getStatus() != null) { + userGroup.setStatus(memberGroupDto.getStatus()); + } + + userGroup.setUpdateTime(new Date()); + userGroup.setOperator(memberGroupDto.getOperator()); + this.updateById(userGroup); + return userGroup; + } + + /** + * 获取会员分组子类 + * + * @param groupId 分组ID + * @return + * */ + public List getChildren(Integer groupId) { + Map param = new HashMap<>(); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + param.put("PARENT_ID", groupId); + List dataList = mtUserGroupMapper.selectByMap(param); + List children = new ArrayList<>(); + if (dataList != null && dataList.size() > 0) { + for (MtUserGroup userGroup : dataList) { + UserGroupDto userGroupDto = new UserGroupDto(); + BeanUtils.copyProperties(userGroup, userGroupDto); + userGroupDto.setChildren(getChildren(userGroup.getId())); + userGroupDto.setMemberNum(getMemberNum(userGroup.getId())); + children.add(userGroupDto); + } + } + return children; + } + + /** + * 获取分组会员数量 + * + * @param groupId 分组ID + * @return + * */ + public Long getMemberNum(Integer groupId) { + List groupIds = getGroupIds(groupId); + Long totalMember = mtUserGroupMapper.getMemberNum(groupIds); + return totalMember; + } + + /** + * 获取会员分组子类ID + * + * @param groupId 分组ID + * @return + * */ + public List getGroupIds(Integer groupId) { + Map param = new HashMap<>(); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + param.put("PARENT_ID", groupId); + List dataList = mtUserGroupMapper.selectByMap(param); + List groupIds = new ArrayList<>(); + groupIds.add(groupId); + if (dataList != null && dataList.size() > 0) { + for (MtUserGroup userGroup : dataList) { + groupIds.add(userGroup.getId()); + List childrenIds = getGroupIds(userGroup.getId()); + if (childrenIds.size() > 0) { + groupIds.addAll(childrenIds); + } + } + } + return groupIds; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/MemberServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/MemberServiceImpl.java new file mode 100644 index 0000000..ca14924 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/MemberServiceImpl.java @@ -0,0 +1,1137 @@ +package com.fuint.common.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.AccountInfo; +import com.fuint.common.dto.GroupMemberDto; +import com.fuint.common.dto.MemberTopDto; +import com.fuint.common.dto.UserDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.MemberPage; +import com.fuint.common.service.*; +import com.fuint.common.util.*; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.bean.MemberTopBean; +import com.fuint.repository.mapper.MtUserActionMapper; +import com.fuint.repository.mapper.MtUserGradeMapper; +import com.fuint.repository.mapper.MtUserMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.math.BigDecimal; +import java.text.ParseException; +import java.util.*; + +/** + * 会员业务接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class MemberServiceImpl extends ServiceImpl implements MemberService { + + private static final Logger logger = LoggerFactory.getLogger(MemberServiceImpl.class); + + private MtUserMapper mtUserMapper; + + private MtUserGradeMapper mtUserGradeMapper; + + private MtUserActionMapper mtUserActionMapper; + + /** + * 短信发送接口 + */ + private SendSmsService sendSmsService; + + /** + * 会员等级接口 + * */ + private UserGradeService userGradeService; + + /** + * 会员等级接口 + * */ + private OpenGiftService openGiftService; + + /** + * 后台账户服务接口 + */ + private AccountService accountService; + + /** + * 员工接口 + */ + private StaffService staffService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 会员行为接口 + */ + private UserActionService userActionService; + + /** + * 系统配置服务接口 + * */ + private SettingService settingService; + + /** + * 分佣提成关系服务接口 + * */ + private CommissionRelationService commissionRelationService; + + /** + * 更新活跃时间 + * @param userId 会员ID + * @param ip IP地址 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateActiveTime(Integer userId, String ip) throws BusinessCheckException { + MtUser mtUser = queryMemberById(userId); + if (mtUser != null) { + if (!mtUser.getStatus().equals(StatusEnum.ENABLED.getKey())) { + return false; + } + if (StringUtil.isEmpty(mtUser.getIp())) { + mtUser.setIp(ip); + mtUserMapper.updateById(mtUser); + } + Date lastUpdateTime = mtUser.getUpdateTime(); + Date registerTime = mtUser.getCreateTime(); + if (lastUpdateTime != null) { + Long timestampLast = Long.valueOf(TimeUtils.date2timeStamp(lastUpdateTime)); + Long timestampNow = System.currentTimeMillis() / 1000; + Long minute = timestampNow - timestampLast; + + // 5分钟更新一次 + if (minute >= 300 || registerTime.equals(lastUpdateTime)) { + synchronized(MemberServiceImpl.class) { + Date activeTime = new Date(); + mtUserMapper.updateActiveTime(mtUser.getId(), activeTime); + // 记录会员行为 + MtUserAction mtUserAction = new MtUserAction(); + mtUserAction.setUserId(mtUser.getId()); + mtUserAction.setStoreId(mtUser.getStoreId()); + mtUserAction.setMerchantId(mtUser.getMerchantId()); + mtUserAction.setParam(TimeUtils.formatDate(activeTime, "yyyy-MM-dd HH:mm:ss")); + mtUserAction.setAction(UserActionEnum.LOGIN.getKey()); + mtUserAction.setDescription(UserActionEnum.LOGIN.getValue()); + userActionService.addUserAction(mtUserAction); + } + } + } + } + + return true; + } + + /** + * 获取当前操作会员信息 + * + * @param userId 会员ID + * @param token 登录token + * @return + * */ + @Override + public MtUser getCurrentUserInfo(HttpServletRequest request, Integer userId, String token) throws BusinessCheckException { + MtUser mtUser = null; + + // 没有会员信息,则查询是否是后台收银员下单 + AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token); + if (accountInfo != null) { + // 输入了会员ID就用会员的账号下单,否则用员工账号下单 + if (userId != null && userId > 0) { + mtUser = queryMemberById(userId); + } else { + Integer accountId = accountInfo.getId(); + TAccount account = accountService.getAccountInfoById(accountId); + if (account != null) { + if (account.getStaffId() > 0) { + MtStaff staff = staffService.queryStaffById(account.getStaffId()); + if (staff != null) { + mtUser = queryMemberById(staff.getUserId()); + if (mtUser != null) { + if (staff.getStoreId() != null && staff.getStoreId() > 0) { + mtUser.setStoreId(staff.getStoreId()); + } + if (account.getMerchantId() != null && account.getMerchantId() > 0 && !account.getMerchantId().equals(mtUser.getMerchantId())) { + mtUser.setMerchantId(account.getMerchantId()); + } + mtUser.setUpdateTime(new Date()); + updateById(mtUser); + } + } + } + } + } + } + return mtUser; + } + + /** + * 分页查询会员列表 + * + * @param memberPage + * @return + */ + @Override + public PaginationResponse queryMemberListByPagination(MemberPage memberPage) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(memberPage.getPage(), memberPage.getPageSize()); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.ne(MtUser::getStatus, StatusEnum.DISABLE.getKey()); + wrapper.eq(MtUser::getIsStaff, YesOrNoEnum.NO.getKey()); + String name = memberPage.getName(); + if (StringUtils.isNotBlank(name)) { + wrapper.like(MtUser::getName, name); + } + Integer userId = memberPage.getId(); + if (userId != null && userId > 0) { + wrapper.eq(MtUser::getId, userId); + } + String keyword = memberPage.getKeyword(); + if (StringUtils.isNotBlank(keyword)) { + wrapper.and(wq -> wq + .eq(MtUser::getMobile, keyword) + .or() + .eq(MtUser::getUserNo, keyword) + .or() + .eq(MtUser::getName, keyword)); + } + String mobile = memberPage.getMobile(); + if (StringUtils.isNotBlank(mobile)) { + wrapper.like(MtUser::getMobile, mobile); + } + String birthday = memberPage.getBirthday(); + if (StringUtils.isNotBlank(birthday)) { + wrapper.like(MtUser::getBirthday, birthday); + } + String userNo = memberPage.getUserNo(); + if (StringUtils.isNotBlank(userNo)) { + wrapper.eq(MtUser::getUserNo, userNo); + } + Integer gradeId = memberPage.getGradeId(); + if (gradeId != null && gradeId > 0) { + wrapper.eq(MtUser::getGradeId, gradeId); + } + Integer merchantId = memberPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + wrapper.eq(MtUser::getMerchantId, merchantId); + } + Integer storeId = memberPage.getStoreId(); + if (storeId != null && storeId > 0) { + wrapper.eq(MtUser::getStoreId, storeId); + } + String storeIds = memberPage.getStoreIds(); + if (StringUtils.isNotBlank(storeIds)) { + List idList = Arrays.asList(storeIds.split(",")); + if (idList.size() > 0) { + wrapper.in(MtUser::getStoreId, idList); + } + } + String groupIds = memberPage.getGroupIds(); + if (StringUtils.isNotBlank(groupIds)) { + List idList = Arrays.asList(groupIds.split(",")); + if (idList.size() > 0) { + wrapper.in(MtUser::getGroupId, idList); + } + } + String status = memberPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + wrapper.eq(MtUser::getStatus, status); + } + // 注册开始、结束时间 + String startTime = memberPage.getStartTime(); + String endTime = memberPage.getEndTime(); + if (StringUtil.isNotEmpty(startTime)) { + wrapper.ge(MtUser::getCreateTime, startTime); + } + if (StringUtil.isNotEmpty(endTime)) { + wrapper.le(MtUser::getCreateTime, endTime); + } + // 注册时间 + String regTime = memberPage.getRegTime(); + if (StringUtil.isNotEmpty(regTime)) { + String[] dateTime = regTime.split("~"); + if (dateTime.length == 2) { + wrapper.ge(MtUser::getCreateTime, dateTime[0]); + wrapper.le(MtUser::getCreateTime, dateTime[1]); + } + } + // 活跃时间 + String activeTime = memberPage.getActiveTime(); + if (StringUtil.isNotEmpty(activeTime)) { + String[] dateTime = activeTime.split("~"); + if (dateTime.length == 2) { + wrapper.ge(MtUser::getUpdateTime, dateTime[0]); + wrapper.le(MtUser::getUpdateTime, dateTime[1]); + } + } + // 会员有效期 + String memberTime = memberPage.getMemberTime(); + if (StringUtil.isNotEmpty(memberTime)) { + String[] dateTime = memberTime.split("~"); + if (dateTime.length == 2) { + wrapper.ge(MtUser::getStartTime, dateTime[0]); + wrapper.le(MtUser::getEndTime, dateTime[1]); + } + } + wrapper.orderByDesc(MtUser::getUpdateTime); + List userList = mtUserMapper.selectList(wrapper); + List dataList = new ArrayList<>(); + for (MtUser mtUser : userList) { + UserDto userDto = new UserDto(); + BeanUtils.copyProperties(mtUser, userDto); + userDto.setMobile(CommonUtil.hidePhone(mtUser.getMobile())); + if (userDto.getStoreId() != null && userDto.getStoreId() > 0) { + MtStore mtStore = storeService.queryStoreById(userDto.getStoreId()); + if (mtStore != null) { + userDto.setStoreName(mtStore.getName()); + } + } + if (userDto.getGradeId() != null) { + Integer mchId = merchantId != null ? merchantId : 0; + MtUserGrade mtGrade = userGradeService.queryUserGradeById(mchId, userDto.getGradeId(), mtUser.getId()); + if (mtGrade != null) { + userDto.setGradeName(mtGrade.getName()); + } + } + if (mtUser.getUserNo() == null || StringUtil.isEmpty(mtUser.getUserNo())) { + mtUser.setUserNo(CommonUtil.createUserNo()); + updateById(mtUser); + } + userDto.setLastLoginTime(TimeUtil.showTime(new Date(), mtUser.getUpdateTime())); + dataList.add(userDto); + } + + PageRequest pageRequest = PageRequest.of(memberPage.getPage(), memberPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, UserDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加会员 + * + * @param mtUser 会员信息 + * @param shareId 分享用户ID + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "新增会员信息") + public MtUser addMember(MtUser mtUser, String shareId) throws BusinessCheckException { + // 用户名就是手机号 + if (StringUtil.isNotEmpty(mtUser.getName()) && StringUtil.isEmpty(mtUser.getMobile()) && PhoneFormatCheckUtils.isChinaPhoneLegal(mtUser.getName())) { + mtUser.setMobile(mtUser.getName()); + String name = mtUser.getName().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"); + mtUser.setName(name); + } + + // 手机号已存在 + if (StringUtil.isNotEmpty(mtUser.getMobile())) { + MtUser userInfo = queryMemberByMobile(mtUser.getMerchantId(), mtUser.getMobile()); + if (userInfo != null) { + return userInfo; + } + } + + String userNo = CommonUtil.createUserNo(); + if (StringUtil.isNotEmpty(mtUser.getUserNo())) { + userNo = mtUser.getUserNo(); + } + // 会员名称已存在 + List userList = mtUserMapper.queryMemberByName(mtUser.getMerchantId(), mtUser.getName()); + if (userList.size() > 0) { + mtUser.setName(userNo); + } + // 默认会员等级 + if (mtUser.getGradeId() == null || mtUser.getGradeId() <= 0) { + MtUserGrade grade = userGradeService.getInitUserGrade(mtUser.getMerchantId()); + if (grade != null) { + mtUser.setGradeId(grade.getId()); + } + } + mtUser.setUserNo(userNo); + if (mtUser.getBalance() == null) { + mtUser.setBalance(new BigDecimal(0)); + } + if (mtUser.getPoint() == null || mtUser.getPoint() < 1) { + mtUser.setPoint(0); + } + if (StringUtil.isEmpty(mtUser.getIdcard())) { + mtUser.setIdcard(""); + } + mtUser.setSex(mtUser.getSex()); + mtUser.setStatus(StatusEnum.ENABLED.getKey()); + Date time = new Date(); + mtUser.setCreateTime(time); + mtUser.setUpdateTime(time); + mtUser.setStartTime(mtUser.getStartTime()); + mtUser.setEndTime(mtUser.getEndTime()); + if (mtUser.getIsStaff() == null) { + mtUser.setIsStaff(YesOrNoEnum.NO.getKey()); + } + if (mtUser.getStoreId() != null && mtUser.getStoreId() > 0) { + mtUser.setStoreId(mtUser.getStoreId()); + } else { + List stores = storeService.getMyStoreList(mtUser.getMerchantId(), 0, StatusEnum.ENABLED.getKey()); + if (stores != null && stores.size() > 0) { + mtUser.setStoreId(stores.get(0).getId()); + } + } + // 密码加密 + if (mtUser.getPassword() != null && StringUtil.isNotEmpty(mtUser.getPassword())) { + String salt = SeqUtil.getRandomLetter(4); + mtUser.setSalt(salt); + String password = enCodePassword(mtUser.getPassword(), salt); + mtUser.setPassword(password); + mtUser.setSource(MemberSourceEnum.REGISTER_BY_ACCOUNT.getKey()); + } + if (mtUser.getSource() == null || StringUtil.isEmpty(mtUser.getSource())) { + mtUser.setSource(MemberSourceEnum.BACKEND_ADD.getKey()); + } + + boolean result = save(mtUser); + if (!result) { + return null; + } + + mtUser = queryMemberById(mtUser.getId()); + + // 开卡赠礼 + openGiftService.openGift(mtUser.getId(), mtUser.getGradeId(), true); + + // 分佣关系 + commissionRelationService.setCommissionRelation(mtUser, shareId); + + // 新增用户发短信通知 + if (mtUser.getId() > 0 && mtUser.getStatus().equals(StatusEnum.ENABLED.getKey())) { + // 发送短信 + List mobileList = new ArrayList<>(); + mobileList.add(mtUser.getMobile()); + // 短信模板 + try { + Map params = new HashMap<>(); + sendSmsService.sendSms(mtUser.getMerchantId(), "register-sms", mobileList, params); + } catch (BusinessCheckException e) { + logger.error(e.getMessage()); + } + } + + return mtUser; + } + + /** + * 更新会员信息 + * + * @param mtUser 会员信息 + * @param modifyPassword 修改密码 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改会员信息") + public MtUser updateMember(MtUser mtUser, boolean modifyPassword) throws BusinessCheckException { + mtUser.setUpdateTime(new Date()); + + MtUser oldUserInfo = mtUserMapper.selectById(mtUser.getId()); + String mobile = mtUser.getMobile(); + if (PhoneFormatCheckUtils.isChinaPhoneLegal(mobile)) { + mtUserMapper.resetMobile(mtUser.getMerchantId(), mobile, mtUser.getId()); + mtUser.setMobile(mobile); + } else { + mtUser.setMobile(oldUserInfo.getMobile()); + } + + // 检查会员号是否重复 + if (StringUtil.isNotEmpty(mtUser.getUserNo())) { + List userList = mtUserMapper.findMembersByUserNo(mtUser.getMerchantId(), mtUser.getUserNo()); + if (userList.size() > 0) { + for(MtUser user: userList) { + MtUser userInfo = user; + if (userInfo.getId().intValue() != mtUser.getId().intValue()) { + throw new BusinessCheckException("该会员号与会员ID等于" + userInfo.getId() + "重复啦"); + } + } + } + } + if (mtUser.getPassword() != null && modifyPassword) { + String salt = SeqUtil.getRandomLetter(4); + mtUser.setSalt(salt); + mtUser.setPassword(enCodePassword(mtUser.getPassword(), salt)); + } + Integer gradeId = mtUser.getGradeId(); + mtUser.setGradeId(oldUserInfo.getGradeId()); + mtUser.setMerchantId(oldUserInfo.getMerchantId()); + if (mtUser.getStoreId() == null || mtUser.getStoreId() <= 0) { + mtUser.setStoreId(oldUserInfo.getStoreId()); + } + Boolean result = updateById(mtUser); + if (result && mtUser.getGradeId() != null) { + // 修改了会员等级,开卡赠礼 + if (!gradeId.equals(oldUserInfo.getGradeId())) { + openGiftService.openGift(mtUser.getId(), gradeId, false); + } + } + return mtUser; + } + + /** + * 通过手机号新增会员 + * + * @param merchantId 商户ID + * @param mobile 手机号 + * @param shareId 分享用户ID + * @param ip IP地址 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "通过手机号新增会员") + public MtUser addMemberByMobile(Integer merchantId, String mobile, String shareId, String ip) throws BusinessCheckException { + MtUser mtUser = new MtUser(); + mtUser.setUserNo(CommonUtil.createUserNo()); + String nickName = mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"); + mtUser.setName(nickName); + mtUser.setMobile(mobile); + MtUserGrade grade = userGradeService.getInitUserGrade(merchantId); + if (grade != null) { + mtUser.setGradeId(grade.getId()); + } + Date time = new Date(); + mtUser.setCreateTime(time); + mtUser.setUpdateTime(time); + mtUser.setBalance(new BigDecimal(0)); + mtUser.setPoint(0); + mtUser.setDescription("手机号登录自动注册"); + mtUser.setIdcard(""); + mtUser.setStatus(StatusEnum.ENABLED.getKey()); + mtUser.setMerchantId(merchantId); + mtUser.setStoreId(0); + mtUser.setSource(MemberSourceEnum.MOBILE_LOGIN.getKey()); + mtUser.setIp(ip); + mtUser.setIsStaff(YesOrNoEnum.NO.getKey()); + mtUserMapper.insert(mtUser); + mtUser = queryMemberByMobile(merchantId, mobile); + + // 开卡赠礼 + openGiftService.openGift(mtUser.getId(), mtUser.getGradeId(), true); + + // 分佣关系 + commissionRelationService.setCommissionRelation(mtUser, shareId); + + return mtUser; + } + + /** + * 根据手机号获取会员信息 + * + * @param merchantId 商户ID + * @param mobile 手机号 + * @throws BusinessCheckException + * @return + */ + @Override + public MtUser queryMemberByMobile(Integer merchantId, String mobile) { + if (mobile == null || StringUtil.isEmpty(mobile)) { + return null; + } + List mtUser = mtUserMapper.queryMemberByMobile(merchantId, mobile); + if (mtUser.size() > 0) { + return mtUser.get(0); + } else { + return null; + } + } + + /** + * 根据会员号号获取会员信息 + * + * @param merchantId 商户ID + * @param userNo 会员号 + * @return + */ + @Override + public MtUser queryMemberByUserNo(Integer merchantId, String userNo) { + if (userNo == null || StringUtil.isEmpty(userNo)) { + return null; + } + List mtUser = mtUserMapper.findMembersByUserNo(merchantId, userNo); + if (mtUser.size() > 0) { + return mtUser.get(0); + } else { + return null; + } + } + + /** + * 根据会员ID获取会员信息 + * + * @param id 会员ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtUser queryMemberById(Integer id) throws BusinessCheckException { + MtUser mtUser = mtUserMapper.selectById(id); + + if (mtUser != null) { + // 检查会员是否过期,过期就把会员等级置为初始等级 + MtUserGrade initGrade = userGradeService.getInitUserGrade(mtUser.getMerchantId()); + if (initGrade != null) { + Date endTime = mtUser.getEndTime(); + if (endTime != null) { + Date now = new Date(); + if (endTime.before(now)) { + if (!mtUser.getGradeId().equals(initGrade.getId())) { + mtUser.setGradeId(initGrade.getId()); + updateById(mtUser); + } + } + } + // 会员等级为空,就把会员等级置为初始等级 + Integer userGradeId = mtUser.getGradeId(); + if (userGradeId == null && initGrade != null) { + mtUser.setGradeId(initGrade.getId()); + updateById(mtUser); + openGiftService.openGift(mtUser.getId(), initGrade.getId(), false); + } else { + // 会员等级不存在或已禁用、删除,就把会员等级置为初始等级 + MtUserGrade myGrade = userGradeService.queryUserGradeById(mtUser.getMerchantId(), userGradeId, id); + if (myGrade == null || !myGrade.getStatus().equals(StatusEnum.ENABLED.getKey())) { + mtUser.setGradeId(initGrade.getId()); + updateById(mtUser); + } + } + } + if (mtUser.getIsStaff() == null) { + mtUser.setIsStaff(YesOrNoEnum.NO.getKey()); + } + } + return mtUser; + } + + /** + * 根据会员名称获取会员信息 + * + * @param merchantId 商户ID + * @param name 会员名称 + * @throws BusinessCheckException + * @return + */ + @Override + public MtUser queryMemberByName(Integer merchantId, String name) { + if (StringUtil.isNotEmpty(name)) { + List userList = mtUserMapper.queryMemberByName(merchantId, name); + if (userList.size() == 1) { + return userList.get(0); + } + } + return null; + } + + /** + * 根据openId获取会员信息(为空就注册) + * + * @param merchantId 商户ID + * @param openId 微信openId + * @throws BusinessCheckException + * @return + */ + @Override + public MtUser queryMemberByOpenId(Integer merchantId, String openId, JSONObject userInfo) throws BusinessCheckException { + MtUser user = mtUserMapper.queryMemberByOpenId(merchantId, openId); + if (user != null && !user.getStatus().equals(StatusEnum.ENABLED.getKey())) { + return null; + } + + String avatar = StringUtil.isNotEmpty(userInfo.getString("avatarUrl")) ? userInfo.getString("avatarUrl") : ""; + String gender = StringUtil.isNotEmpty(userInfo.getString("gender")) ? userInfo.getString("gender") : GenderEnum.MAN.getKey().toString(); + String country = StringUtil.isNotEmpty(userInfo.getString("country")) ? userInfo.getString("country") : ""; + String province = StringUtil.isNotEmpty(userInfo.getString("province")) ? userInfo.getString("province") : ""; + String city = StringUtil.isNotEmpty(userInfo.getString("city")) ? userInfo.getString("city") : ""; + String storeId = StringUtil.isNotEmpty(userInfo.getString("storeId")) ? userInfo.getString("storeId") : "0"; + String nickName = StringUtil.isNotEmpty(userInfo.getString("nickName")) ? userInfo.getString("nickName") : ""; + String mobile = StringUtil.isNotEmpty(userInfo.getString("phone")) ? userInfo.getString("phone") : ""; + String shareId = StringUtil.isNotEmpty(userInfo.getString("shareId")) ? userInfo.getString("shareId") : "0"; + String source = StringUtil.isNotEmpty(userInfo.getString("source")) ? userInfo.getString("source") : MemberSourceEnum.WECHAT_LOGIN.getKey(); + String platform = StringUtil.isNotEmpty(userInfo.getString("platform")) ? userInfo.getString("platform") : ""; + String ip = StringUtil.isNotEmpty(userInfo.getString("ip")) ? userInfo.getString("ip") : ""; + + // 需要手机号登录 + if (StringUtil.isEmpty(mobile) && user == null && !platform.equals(PlatformTypeEnum.H5.getCode())) { + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.USER.getKey(), UserSettingEnum.LOGIN_NEED_PHONE.getKey()); + if (mtSetting != null) { + if (mtSetting.getValue().equals(YesOrNoEnum.TRUE.getKey())) { + MtUser tempUser = new MtUser(); + tempUser.setOpenId(openId); + tempUser.setId(0); + return tempUser; + } + } + } + + // 手机号已经存在 + if (StringUtil.isNotEmpty(mobile) && user == null) { + user = queryMemberByMobile(merchantId, mobile); + if (user != null) { + user.setOpenId(openId); + } + } + + if (user == null) { + MtUser mtUser = new MtUser(); + if (StringUtil.isNotEmpty(mobile)) { + MtUser mtUserMobile = queryMemberByMobile(merchantId, mobile); + if (mtUserMobile != null) { + mtUser = mtUserMobile; + } + } + + // 昵称为空,用手机号 + if (StringUtil.isEmpty(nickName) && StringUtil.isNotEmpty(mobile)) { + nickName = mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"); + } + mtUser.setMerchantId(merchantId); + String userNo = CommonUtil.createUserNo(); + mobile = CommonUtil.replaceXSS(mobile); + avatar = CommonUtil.replaceXSS(avatar); + nickName = CommonUtil.replaceXSS(nickName); + mtUser.setUserNo(userNo); + mtUser.setMobile(mobile); + mtUser.setAvatar(avatar); + if (StringUtil.isNotEmpty(nickName)) { + mtUser.setName(nickName); + } else { + mtUser.setName(userNo); + } + mtUser.setOpenId(openId); + MtUserGrade grade = userGradeService.getInitUserGrade(merchantId); + if (grade != null) { + mtUser.setGradeId(grade.getId()); + } + Date time = new Date(); + mtUser.setUpdateTime(time); + mtUser.setBalance(new BigDecimal(0)); + mtUser.setPoint(0); + mtUser.setDescription("微信登录自动注册"); + mtUser.setIdcard(""); + mtUser.setStatus(StatusEnum.ENABLED.getKey()); + mtUser.setAddress(country + province + city); + // 微信用户 1:男;2:女 0:未知 + if (gender.equals(GenderEnum.FEMALE.getKey().toString())) { + gender = GenderEnum.UNKNOWN.getKey().toString(); + } else if (gender.equals(GenderEnum.UNKNOWN.getKey().toString())) { + gender = GenderEnum.FEMALE.getKey().toString(); + } + mtUser.setSex(Integer.parseInt(gender)); + if (StringUtil.isNotEmpty(storeId)) { + mtUser.setStoreId(Integer.parseInt(storeId)); + } else { + mtUser.setStoreId(0); + } + mtUser.setSource(source); + if (mtUser.getId() == null || mtUser.getId() <= 0) { + mtUser.setCreateTime(time); + mtUser.setIp(ip); + save(mtUser); + } else { + updateById(mtUser); + } + user = mtUserMapper.queryMemberByOpenId(merchantId, openId); + + // 开卡赠礼 + openGiftService.openGift(user.getId(), user.getGradeId(), true); + + // 分佣关系 + commissionRelationService.setCommissionRelation(mtUser, shareId); + } else { + // 已被禁用 + if (user.getStatus().equals(StatusEnum.DISABLE.getKey())) { + return null; + } + // 补充手机号 + if (StringUtil.isNotEmpty(mobile) && PhoneFormatCheckUtils.isChinaPhoneLegal(mobile)) { + user.setMobile(mobile); + updateById(user); + } + // 补充会员号 + if (StringUtil.isEmpty(user.getUserNo())) { + user.setUserNo(CommonUtil.createUserNo()); + updateById(user); + } + } + + return user; + } + + /** + * 根据等级ID获取会员等级信息 + * + * @param id 等级ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtUserGrade queryMemberGradeByGradeId(Integer id) { + return mtUserGradeMapper.selectById(id); + } + + /** + * 删除会员 + * + * @param id 会员ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除会员信息") + public Integer deleteMember(Integer id, String operator) throws BusinessCheckException { + MtUser mtUser = mtUserMapper.selectById(id); + if (null == mtUser) { + throw new BusinessCheckException("该会员不存在,请确认"); + } + // 是否是店铺员工 + MtStaff mtStaff = staffService.queryStaffByUserId(id); + if (mtStaff != null && mtStaff.getAuditedStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("该会员已关联店铺员工”"+ mtStaff.getRealName()+"“,若要删除请先删除该员工信息"); + } + mtUser.setStatus(StatusEnum.DISABLE.getKey()); + mtUser.setUpdateTime(new Date()); + mtUser.setOperator(operator); + updateById(mtUser); + return mtUser.getId(); + } + + /** + * 根据条件搜索会员分组 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryMemberGradeByParams(Map params) { + if (params == null) { + params = new HashMap<>(); + } + return mtUserGradeMapper.selectByMap(params); + } + + /** + * 获取会员数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + @Override + public Long getUserCount(Integer merchantId, Integer storeId) { + if (storeId != null && storeId > 0) { + return mtUserMapper.getStoreUserCount(storeId); + } else { + return mtUserMapper.getUserCount(merchantId); + } + } + + /** + * 获取会员数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public Long getUserCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + if (storeId != null && storeId > 0) { + return mtUserMapper.getStoreUserCountByTime(storeId, beginTime, endTime); + } else { + return mtUserMapper.getUserCountByTime(merchantId, beginTime, endTime); + } + } + + /** + * 获取会员数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public Long getActiveUserCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + if (storeId != null && storeId > 0) { + return mtUserActionMapper.getStoreActiveUserCount(storeId, beginTime, endTime); + } else { + return mtUserActionMapper.getActiveUserCount(merchantId, beginTime, endTime); + } + } + + /** + * 重置手机号 + * + * @param mobile 手机号码 + * @param userId 会员ID + * @return + */ + @Override + public void resetMobile(String mobile, Integer userId) { + if (mobile == null || StringUtil.isEmpty(mobile)) { + return; + } + MtUser mtUser = mtUserMapper.selectById(userId); + if (mtUser != null) { + mtUserMapper.resetMobile(mtUser.getMerchantId(), mobile, userId); + } + } + + /** + * 获取会员消费排行榜 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public List getMemberConsumeTopList(Integer merchantId, Integer storeId, Date startTime, Date endTime) { + List memberList = mtUserMapper.getMemberConsumeTopList(merchantId, storeId, startTime, endTime); + List dataList = new ArrayList<>(); + if (memberList != null && memberList.size() > 0) { + for (MemberTopBean bean : memberList) { + MemberTopDto dto = new MemberTopDto(); + BeanUtils.copyProperties(bean, dto); + dataList.add(dto); + } + } + return dataList; + } + + /** + * 查找会员列表 + * + * @param merchantId 商户ID + * @param keyword 关键字 + * @param groupIds 分组ID + * @param page 当前页码 + * @param pageSize 每页数量 + * @return + * */ + @Override + public List searchMembers(Integer merchantId, String keyword, String groupIds, Integer page, Integer pageSize) { + PageHelper.startPage(page, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUser::getStatus, StatusEnum.DISABLE.getKey()); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtUser::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(groupIds)) { + List idList = Arrays.asList(groupIds.split(",")); + if (idList.size() > 0) { + lambdaQueryWrapper.in(MtUser::getGroupId, idList); + } + } + if (StringUtil.isNotEmpty(keyword)) { + List itemList = Arrays.asList(keyword.split(",")); + lambdaQueryWrapper.and(wq -> wq + .in(MtUser::getUserNo, itemList) + .or() + .in(MtUser::getMobile, itemList)); + } + lambdaQueryWrapper.orderByDesc(MtUser::getUpdateTime); + List userList = mtUserMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (userList != null && userList.size() > 0) { + for (MtUser mtUser : userList) { + GroupMemberDto memberDto = new GroupMemberDto(); + memberDto.setId(mtUser.getId()); + memberDto.setName(mtUser.getName()); + memberDto.setUserNo(mtUser.getUserNo()); + memberDto.setMobile(CommonUtil.hidePhone(mtUser.getMobile())); + dataList.add(memberDto); + } + } + return dataList; + } + + /** + * 查找会员列表 + * + * @param merchantId 商户ID + * @param keyword 关键字 + * @return + * */ + @Override + public List searchMembers(Integer merchantId, String keyword) { + return mtUserMapper.searchMembers(merchantId, keyword); + } + + /** + * 设定安全的密码 + * + * @param password 密码明文 + * @param salt 加密因子 + * @return + */ + @Override + public String enCodePassword(String password, String salt) { + return MD5Util.getMD5(password + salt); + } + + /** + * 获取加密密码 + * + * @param password 密码密文 + * @param salt 加密因子 + * @return + * */ + @Override + public String deCodePassword(String password, String salt) { + return MD5Util.getMD5(password + salt); + } + + /** + * 获取会员ID列表 + * + * @param merchantId 商户号 + * @param storeId 店铺ID + * @return + * */ + @Override + public List getUserIdList(Integer merchantId, Integer storeId) { + return mtUserMapper.getUserIdList(merchantId, storeId); + } + + /** + * 导入会员 + * + * @param file excel文件 + * @param accountInfo 操作者 + * @param filePath 文件路径 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "导入会员列表") + public Boolean importMember(MultipartFile file, AccountInfo accountInfo, String filePath) throws BusinessCheckException, ParseException { + String originalFileName = file.getOriginalFilename(); + boolean isExcel2003 = XlsUtil.isExcel2003(originalFileName); + boolean isExcel2007 = XlsUtil.isExcel2007(originalFileName); + + if (!isExcel2003 && !isExcel2007) { + logger.error("importMember->uploadFile:{}", "文件类型不正确"); + throw new BusinessCheckException("文件类型不正确"); + } + + if (accountInfo == null || accountInfo.getMerchantId() == null || accountInfo.getMerchantId() <= 0) { + throw new BusinessCheckException("没有操作权限"); + } + + List> memberList = new ArrayList<>(); + try { + memberList = XlsUtil.readExcelContent(file.getInputStream(), isExcel2003, 0, 1, null, null, null); + } catch (IOException e) { + logger.error("MemberServiceImpl->parseExcelContent{}", e); + throw new BusinessCheckException("会员导入失败" + e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + + if (memberList != null && memberList.size() > 0) { + if (memberList.size() > 5000) { + throw new BusinessCheckException("会员导入失败,单次导入会员数量不能大于5000"); + } + // 先校验,是否已存在,是否为空,是否重复 + List userList = new ArrayList<>(); + List userGrades = userGradeService.getMerchantGradeList(accountInfo.getMerchantId(), null); + for (int i = 0; i < memberList.size(); i++) { + List userInfo = memberList.get(i); + String username = userInfo.get(0); + String userNo = userInfo.get(1); + Integer sex = userInfo.get(3).equals("男") ? 1 : 0; + MtUser mtUser = new MtUser(); + mtUser.setMerchantId(accountInfo.getMerchantId()); + mtUser.setStoreId(accountInfo.getStoreId()); + mtUser.setName(username); + mtUser.setUserNo(userNo); + mtUser.setIdcard(userInfo.get(2)); + mtUser.setSex(sex); + mtUser.setMobile(userInfo.get(4)); + mtUser.setBirthday(userInfo.get(5)); + mtUser.setDescription(userInfo.get(6)); + mtUser.setCarNo(userInfo.get(7)); + String gradeName = userInfo.get(8); + Integer gradeId = 0; + if (StringUtil.isNotEmpty(gradeName)) { + for (MtUserGrade userGrade : userGrades) { + if (userGrade.getName().equals(gradeName)) { + gradeId = userGrade.getId(); + } + } + } + mtUser.setGradeId(gradeId); + mtUser.setStartTime(new Date()); + String gradeDate = userInfo.get(9); + if (StringUtil.isNotEmpty(gradeDate)) { + mtUser.setEndTime(DateUtil.parseDate(userInfo.get(9))); + } + if (StringUtil.isNotBlank(userInfo.get(10))) { + mtUser.setPoint(Integer.parseInt(userInfo.get(10))); + } else { + mtUser.setPoint(0); + } + if (StringUtil.isNotBlank(userInfo.get(11))) { + mtUser.setBalance(new BigDecimal(userInfo.get(11))); + } + String status = userInfo.get(12).equals("正常") ? StatusEnum.ENABLED.getKey() : StatusEnum.FORBIDDEN.getKey(); + mtUser.setStatus(status); + if (StringUtil.isNotBlank(userInfo.get(13))) { + mtUser.setPassword(userInfo.get(13)); + } + userList.add(mtUser); + } + + for (MtUser mtUser : userList) { + addMember(mtUser, null); + } + } + + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/MerchantServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/MerchantServiceImpl.java new file mode 100644 index 0000000..4b4b9d2 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/MerchantServiceImpl.java @@ -0,0 +1,435 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.MerchantDto; +import com.fuint.common.dto.MerchantSettingDto; +import com.fuint.common.dto.StoreDto; +import com.fuint.common.enums.OrderSettingEnum; +import com.fuint.common.enums.SettingTypeEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.MerchantService; +import com.fuint.common.service.SettingService; +import com.fuint.common.service.StoreService; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.RegexUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.merchantApi.request.MerchantSettingParam; +import com.fuint.repository.mapper.MtGoodsMapper; +import com.fuint.repository.mapper.MtMerchantMapper; +import com.fuint.repository.mapper.MtStoreMapper; +import com.fuint.repository.model.MtGoods; +import com.fuint.repository.model.MtMerchant; +import com.fuint.repository.model.MtSetting; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 商户业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class MerchantServiceImpl extends ServiceImpl implements MerchantService { + + private static final Logger logger = LoggerFactory.getLogger(MerchantServiceImpl.class); + + private MtMerchantMapper mtMerchantMapper; + + private MtStoreMapper mtStoreMapper; + + private MtGoodsMapper mtGoodsMapper; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 分页查询商户列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryMerchantListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtMerchant::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtMerchant::getName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtMerchant::getStatus, status); + } + String id = paginationRequest.getSearchParams().get("id") == null ? "" : paginationRequest.getSearchParams().get("id").toString(); + if (StringUtils.isNotBlank(id)) { + lambdaQueryWrapper.eq(MtMerchant::getId, id); + } + + lambdaQueryWrapper.orderByAsc(MtMerchant::getStatus).orderByDesc(MtMerchant::getId); + List merchantList = mtMerchantMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (merchantList != null && merchantList.size() > 0) { + for (MtMerchant mtMerchant : merchantList) { + MerchantDto merchantDto = new MerchantDto(); + BeanUtils.copyProperties(mtMerchant, merchantDto); + merchantDto.setPhone(CommonUtil.hidePhone(mtMerchant.getPhone())); + dataList.add(merchantDto); + } + } + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtMerchant.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存商户信息 + * + * @param merchant 商户信息 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "保存商户信息") + public MtMerchant saveMerchant(MtMerchant merchant) throws BusinessCheckException { + MtMerchant mtMerchant = queryMerchantByName(merchant.getName()); + if (mtMerchant != null) { + if ((merchant.getId() != null && !merchant.getId().equals(mtMerchant.getId())) || (merchant.getId() == null || merchant.getId() <= 0)) { + throw new BusinessCheckException("该商户名称已经存在"); + } + } + mtMerchant = queryMerchantByNo(merchant.getNo()); + if (mtMerchant != null) { + if ((merchant.getId() != null && !merchant.getId().equals(mtMerchant.getId())) || (merchant.getId() == null || merchant.getId() <= 0)) { + throw new BusinessCheckException("该商户名称已经存在"); + } + } + + mtMerchant = new MtMerchant(); + // 商户号不能含有中文 + if (RegexUtil.containsChinese(merchant.getNo())) { + throw new BusinessCheckException("商户号不能含有中文字符"); + } + + // 编辑商户 + if (merchant.getId() != null) { + mtMerchant = queryMerchantById(merchant.getId()); + } + + if (merchant.getNo() == null || StringUtil.isEmpty(merchant.getNo())) { + mtMerchant.setNo(CommonUtil.createMerchantNo()); + } else { + mtMerchant.setNo(merchant.getNo()); + } + if (merchant.getType() != null) { + mtMerchant.setType(merchant.getType()); + } + mtMerchant.setName(merchant.getName()); + mtMerchant.setLogo(merchant.getLogo()); + mtMerchant.setContact(merchant.getContact()); + mtMerchant.setOperator(merchant.getOperator()); + mtMerchant.setUpdateTime(new Date()); + if (merchant.getId() == null) { + mtMerchant.setCreateTime(new Date()); + } + mtMerchant.setWxAppId(merchant.getWxAppId()); + mtMerchant.setWxAppSecret(merchant.getWxAppSecret()); + mtMerchant.setWxOfficialAppId(merchant.getWxOfficialAppId()); + mtMerchant.setWxOfficialAppSecret(merchant.getWxOfficialAppSecret()); + if (merchant.getSettleRate() != null) { + mtMerchant.setSettleRate(merchant.getSettleRate()); + } + mtMerchant.setDescription(merchant.getDescription()); + mtMerchant.setPhone(merchant.getPhone()); + mtMerchant.setAddress(merchant.getAddress()); + mtMerchant.setStatus(merchant.getStatus()); + + if (mtMerchant.getStatus() == null) { + mtMerchant.setStatus(StatusEnum.ENABLED.getKey()); + } + if (mtMerchant.getId() == null || mtMerchant.getId() < 1) { + this.save(mtMerchant); + } else { + mtMerchantMapper.updateById(mtMerchant); + } + return mtMerchant; + } + + /** + * 根据ID获取商户信息 + * + * @param id 商户ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtMerchant queryMerchantById(Integer id) { + if (id == null || id < 1) { + return null; + } + return mtMerchantMapper.selectById(id); + } + + /** + * 根据名称获取商户信息 + * + * @param name 商户名称 + * @throws BusinessCheckException + * @return + */ + @Override + public MtMerchant queryMerchantByName(String name) { + return mtMerchantMapper.queryMerchantByName(name); + } + + /** + * 根据商户号获取商户信息 + * + * @param merchantNo 商户号 + * @return + */ + @Override + public MtMerchant queryMerchantByNo(String merchantNo) { + return mtMerchantMapper.queryMerchantByNo(merchantNo); + } + + /** + * 根据商户号获取商户ID + * + * @param merchantNo 商户号 + * @return + */ + @Override + public Integer getMerchantId(String merchantNo) { + if (merchantNo == null || StringUtil.isEmpty(merchantNo)) { + return 0; + } + MtMerchant mtMerchant = queryMerchantByNo(merchantNo); + if (mtMerchant != null) { + return mtMerchant.getId(); + } else { + return 0; + } + } + + /** + * 更新商户状态 + * + * @param id 商户ID + * @param operator 操作人 + * @param status 状态 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional + @OperationServiceLog(description = "修改商户状态") + public void updateStatus(Integer id, String operator, String status) throws BusinessCheckException { + MtMerchant mtMerchant = queryMerchantById(id); + if (null == mtMerchant) { + throw new BusinessCheckException("该商户不存在."); + } + + // 如果是删除,检查是否有商品等数据 + if (status.equals(StatusEnum.DISABLE.getKey())) { + // 删除店铺 + storeService.deleteStoreByMerchant(id); + + // 删除商品 + Map params = new HashMap<>(); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("merchant_id", id); + List goodsList = mtGoodsMapper.selectByMap(params); + if (goodsList != null && goodsList.size() > 0) { + logger.info("删除商户,连同商品一起删除", mtMerchant.getId()); + mtGoodsMapper.removeMerchantGoods(mtMerchant.getId()); + } + } + + mtMerchant.setStatus(status); + mtMerchant.setUpdateTime(new Date()); + mtMerchant.setOperator(operator); + + mtMerchantMapper.updateById(mtMerchant); + } + + /** + * 根据条件查询商户列表 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryMerchantByParams(Map params) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtMerchant::getStatus, StatusEnum.DISABLE.getKey()); + + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtMerchant::getId, merchantId); + } + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + if (StringUtils.isNotBlank(storeId) && StringUtil.isEmpty(merchantId)) { + MtStore mtStore = mtStoreMapper.selectById(storeId); + if (mtStore != null && mtStore.getMerchantId() > 0) { + lambdaQueryWrapper.eq(MtMerchant::getId, mtStore.getMerchantId()); + } + } + String name = params.get("name") == null ? "" : params.get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtMerchant::getName, name); + } + String status = params.get("status") == null ? "" : params.get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtMerchant::getStatus, status); + } + + lambdaQueryWrapper.orderByAsc(MtMerchant::getStatus).orderByDesc(MtMerchant::getId); + return mtMerchantMapper.selectList(lambdaQueryWrapper); + } + + /** + * 查询我的商户列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + @Override + public List getMyMerchantList(Integer merchantId, Integer storeId, String status) { + Map param = new HashMap<>(); + if (merchantId != null && merchantId > 0) { + param.put("merchantId", merchantId); + } + if (storeId != null && storeId > 0) { + param.put("storeId", storeId); + } + if (StringUtils.isNotBlank(status)) { + param.put("status", status); + } + return queryMerchantByParams(param); + } + + /** + * 获取商户设置信息 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + @Override + public MerchantSettingDto getMerchantSettingInfo(Integer merchantId, Integer storeId) throws BusinessCheckException { + String name = ""; + Integer id = merchantId; + String contact = ""; + String logo = ""; + String phone = ""; + if (storeId != null && storeId > 0) { + MtStore storeInfo = storeService.queryStoreById(storeId); + if (storeInfo != null) { + id = storeInfo.getId(); + name = storeInfo.getName(); + contact = storeInfo.getContact(); + logo = storeInfo.getLogo(); + phone = storeInfo.getPhone(); + } + } else { + MtMerchant merchantInfo = getById(merchantId); + if (merchantInfo != null) { + name = merchantInfo.getName(); + contact = merchantInfo.getContact(); + logo = merchantInfo.getLogo(); + phone = merchantInfo.getPhone(); + } + } + MtSetting mtSetting = settingService.querySettingByName(merchantId, storeId, SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.IS_CLOSE.getKey()); + MerchantSettingDto merchantSettingDto = new MerchantSettingDto(); + merchantSettingDto.setName(name); + merchantSettingDto.setId(id); + merchantSettingDto.setContact(contact); + merchantSettingDto.setLogo(logo); + merchantSettingDto.setPhone(phone); + if (mtSetting != null) { + merchantSettingDto.setStatus(mtSetting.getValue()); + } else { + merchantSettingDto.setStatus(YesOrNoEnum.YES.getKey()); + } + return merchantSettingDto; + } + + /** + * 保存商户设置信息 + * + * @param params 商户设置项 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存商户设置信息") + public MerchantSettingDto saveMerchantSetting(MerchantSettingParam params) throws BusinessCheckException { + if (params.getStoreId() != null && params.getStoreId() > 0) { + MtStore storeInfo = storeService.queryStoreById(params.getStoreId()); + if (storeInfo != null) { + StoreDto storeDto = new StoreDto(); + storeDto.setId(storeInfo.getId()); + storeDto.setName(params.getName()); + storeDto.setContact(params.getContact()); + storeDto.setPhone(params.getPhone()); + storeDto.setLogo(params.getLogo()); + storeService.saveStore(storeDto); + } + } else { + MtMerchant merchantInfo = getById(params.getMerchantId()); + if (merchantInfo != null) { + merchantInfo.setName(params.getName()); + merchantInfo.setContact(params.getContact()); + merchantInfo.setPhone(params.getPhone()); + merchantInfo.setLogo(params.getLogo()); + updateById(merchantInfo); + } + } + MtSetting mtSetting = settingService.querySettingByName(params.getMerchantId(), params.getStoreId(), SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.IS_CLOSE.getKey()); + if (mtSetting != null && StringUtil.isNotEmpty(params.getStatus())) { + mtSetting.setValue(params.getStatus()); + settingService.saveSetting(mtSetting); + } + return getMerchantSettingInfo(params.getMerchantId(), params.getStoreId()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/MessageServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/MessageServiceImpl.java new file mode 100644 index 0000000..dda0002 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/MessageServiceImpl.java @@ -0,0 +1,133 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.enums.MessageEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.MessageService; +import com.fuint.repository.mapper.MtMessageMapper; +import com.fuint.repository.model.MtMessage; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Date; +import java.util.List; + +/** + * 消息业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class MessageServiceImpl extends ServiceImpl implements MessageService { + + private MtMessageMapper messageRepository; + + /** + * 添加消息 + * + * @param mtMsg 消息参数 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void addMessage(MtMessage mtMsg) { + if (mtMsg.getUserId() < 0 || StringUtil.isEmpty(mtMsg.getContent())) { + return; + } + + mtMsg.setStatus(StatusEnum.ENABLED.getKey()); + mtMsg.setIsRead(YesOrNoEnum.NO.getKey()); + mtMsg.setCreateTime(new Date()); + mtMsg.setUpdateTime(new Date()); + + this.save(mtMsg); + } + + /** + * 将消息置为已读 + * + * @param msgId 消息ID + * @param + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void readMessage(Integer msgId) { + if (msgId < 0) { + return; + } + + MtMessage mtMsg = messageRepository.selectById(msgId); + if (mtMsg == null) { + return; + } + + mtMsg.setIsRead(YesOrNoEnum.YES.getKey()); + mtMsg.setUpdateTime(new Date()); + + messageRepository.updateById(mtMsg); + } + + /** + * 消息置为发送 + * + * @param msgId 消息ID + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void sendMessage(Integer msgId, boolean isRead) { + if (msgId < 0 ) { + return; + } + + MtMessage mtMsg = messageRepository.selectById(msgId); + if (mtMsg == null) { + return; + } + + mtMsg.setIsSend(YesOrNoEnum.YES.getKey()); + + // 订阅消息发送成功就算是已读了 + if (isRead) { + mtMsg.setIsRead(YesOrNoEnum.YES.getKey()); + } else { + mtMsg.setIsRead(YesOrNoEnum.NO.getKey()); + } + + mtMsg.setUpdateTime(new Date()); + + messageRepository.updateById(mtMsg); + } + + /** + * 获取最新一条未读弹框消息 + * + * @param userId 会员ID + * @return + */ + @Override + public MtMessage getOne(Integer userId) { + List messageList = messageRepository.findNewMessage(userId, MessageEnum.POP_MSG.getKey()); + + if (messageList.size() > 0) { + return messageList.get(0); + } + + return null; + } + + /** + * 获取需要发送的消息 + * + * @return + */ + @Override + public List getNeedSendList() { + return messageRepository.findNeedSendMessage(MessageEnum.SUB_MSG.getKey()); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/OpenGiftServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/OpenGiftServiceImpl.java new file mode 100644 index 0000000..ce6f277 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/OpenGiftServiceImpl.java @@ -0,0 +1,365 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.dto.OpenGiftDto; +import com.fuint.common.enums.MessageEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.param.CouponReceiveParam; +import com.fuint.common.service.*; +import com.fuint.common.util.DateUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.MtOpenGiftMapper; +import com.fuint.repository.mapper.MtUserMapper; +import com.fuint.repository.model.*; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +/** + * 开卡赠礼接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class OpenGiftServiceImpl extends ServiceImpl implements OpenGiftService { + + private static final Logger logger = LoggerFactory.getLogger(OpenGiftServiceImpl.class); + + private MtOpenGiftMapper mtOpenGiftMapper; + + private MtUserMapper mtUserMapper; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 会员等级服务接口 + * */ + private UserGradeService userGradeService; + + /** + * 会员积分服务接口 + * */ + private PointService pointService; + + /** + * 系统消息服务接口 + * */ + private MessageService messageService; + + /** + * 获取开卡赠礼列表 + * @param paramMap + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject getOpenGiftList(Map paramMap) throws BusinessCheckException { + Integer pageNumber = paramMap.get("pageNumber") == null ? Constants.PAGE_NUMBER : Integer.parseInt(paramMap.get("pageNumber").toString()); + Integer pageSize = paramMap.get("pageSize") == null ? Constants.PAGE_SIZE : Integer.parseInt(paramMap.get("pageSize").toString()); + + Page pageHelper = PageHelper.startPage(pageNumber, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtOpenGift::getStatus, StatusEnum.DISABLE.getKey()); + String merchantId = paramMap.get("merchantId") == null ? "" : paramMap.get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtOpenGift::getMerchantId, merchantId); + } + String couponId = paramMap.get("couponId") == null ? "" : paramMap.get("couponId").toString(); + if (StringUtils.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtOpenGift::getCouponId, couponId); + } + String gradeId = paramMap.get("gradeId") == null ? "" : paramMap.get("gradeId").toString(); + if (StringUtils.isNotBlank(gradeId)) { + lambdaQueryWrapper.eq(MtOpenGift::getGradeId, Integer.parseInt(gradeId)); + } + String status = paramMap.get("status") == null ? "" : paramMap.get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtOpenGift::getStatus, status); + } + + lambdaQueryWrapper.orderByDesc(MtOpenGift::getId); + List openGiftList = mtOpenGiftMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + for (MtOpenGift item : openGiftList) { + OpenGiftDto dto = dealDetail(item); + dataList.add(dto); + } + + PageRequest pageRequest = PageRequest.of(pageNumber, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, OpenGiftDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return new ResponseObject(200, "", paginationResponse); + } + + /** + * 新增开卡赠礼 + * + * @param mtOpenGift 赠礼信息 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增开卡赠礼") + public MtOpenGift addOpenGift(MtOpenGift mtOpenGift) throws BusinessCheckException { + if (mtOpenGift.getMerchantId() == null || mtOpenGift.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + mtOpenGift.setUpdateTime(new Date()); + mtOpenGift.setCreateTime(new Date()); + if (mtOpenGift.getCouponNum() != null && mtOpenGift.getCouponNum() > 100) { + throw new BusinessCheckException("开卡赠礼卡券数量不能大于100"); + } + + this.save(mtOpenGift); + return mtOpenGift; + } + + /** + * 根据ID获取开卡赠礼详情 + * + * @param id 开卡赠礼ID + * @throws BusinessCheckException + * @return + */ + @Override + public OpenGiftDto getOpenGiftDetail(Integer id) throws BusinessCheckException { + MtOpenGift openGift = mtOpenGiftMapper.selectById(id); + return dealDetail(openGift); + } + + /** + * 根据ID删除数据 + * + * @param id 开卡赠礼ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除开卡赠礼") + public void deleteOpenGift(Integer id, String operator) { + MtOpenGift MtOpenGift = mtOpenGiftMapper.selectById(id); + if (null == MtOpenGift) { + return; + } + + MtOpenGift.setStatus(StatusEnum.DISABLE.getKey()); + MtOpenGift.setUpdateTime(new Date()); + + mtOpenGiftMapper.updateById(MtOpenGift); + } + + /** + * 更新开卡赠礼 + * + * @param reqDto 实体参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新开卡赠礼") + public MtOpenGift updateOpenGift(MtOpenGift reqDto) throws BusinessCheckException { + MtOpenGift mtOpenGift = mtOpenGiftMapper.selectById(reqDto.getId()); + if (mtOpenGift == null) { + throw new BusinessCheckException("该数据状态异常"); + } + + mtOpenGift.setId(reqDto.getId()); + mtOpenGift.setUpdateTime(new Date()); + + if (null != reqDto.getOperator()) { + mtOpenGift.setOperator(reqDto.getOperator()); + } + + if (null != reqDto.getStatus()) { + mtOpenGift.setStatus(reqDto.getStatus()); + } + + if (null != reqDto.getCouponId()) { + mtOpenGift.setCouponId(reqDto.getCouponId()); + } + + if (null != reqDto.getGradeId()) { + mtOpenGift.setGradeId(reqDto.getGradeId()); + } + + if (null != reqDto.getPoint()) { + mtOpenGift.setPoint(reqDto.getPoint()); + } + + if (null != reqDto.getCouponNum()) { + if (reqDto.getCouponNum() > 100) { + throw new BusinessCheckException("开卡赠礼卡券数量不能大于100"); + } + mtOpenGift.setCouponNum(reqDto.getCouponNum()); + } + + mtOpenGiftMapper.updateById(mtOpenGift); + return mtOpenGift; + } + + /** + * 开卡赠礼 + * + * @param userId 会员ID + * @param gradeId 等级ID + * @return + * */ + @Override + public Boolean openGift(Integer userId, Integer gradeId, boolean isNewMember) throws BusinessCheckException { + if (gradeId == null || gradeId.compareTo(0) <= 0) { + return false; + } + MtUser user = mtUserMapper.selectById(userId); + if (user == null) { + throw new BusinessCheckException("会员状态异常"); + } + if (user.getIsStaff().equals(YesOrNoEnum.YES.getKey())) { + return false; + } + if (user.getGradeId() == null) { + user.setGradeId(0); + } + MtUserGrade oldGrade = userGradeService.queryUserGradeById(user.getMerchantId(), user.getGradeId(), user.getId()); + MtUserGrade gradeInfo = userGradeService.queryUserGradeById(user.getMerchantId(), gradeId, user.getId()); + // 设置有效期 + if (gradeInfo.getValidDay() >= 0) { + user.setStartTime(new Date()); + Date endDate = new Date(); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(endDate); + calendar.add(calendar.DATE, gradeInfo.getValidDay()); + endDate = calendar.getTime(); + user.setEndTime(endDate); + if (gradeInfo.getValidDay() == 0) { + user.setStartTime(null); + user.setEndTime(null); + } + } + user.setGradeId(gradeId); + user.setUpdateTime(new Date()); + mtUserMapper.updateById(user); + // 会员往低了改变,没有开卡赠礼 + if (!isNewMember && oldGrade != null && oldGrade.getGrade() >= gradeInfo.getGrade()) { + return false; + } + Map params = new HashMap<>(); + params.put("grade_id", gradeId.toString()); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("merchant_id", user.getMerchantId()); + List openGiftList = mtOpenGiftMapper.selectByMap(params); + if (openGiftList.size() > 0) { + Integer totalPoint = 0; + BigDecimal totalAmount = new BigDecimal("0"); + for (MtOpenGift item : openGiftList) { + // 加积分 + if (item.getPoint() > 0) { + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setUserId(userId); + reqPointDto.setAmount(item.getPoint()); + reqPointDto.setDescription("开卡赠送"+ item.getPoint() +"积分"); + reqPointDto.setOperator("系统"); + pointService.addPoint(reqPointDto); + totalPoint = totalPoint + item.getPoint(); + } + // 返卡券 + if (item.getCouponId() > 0) { + MtCoupon mtCoupon = couponService.queryCouponById(item.getCouponId()); + if (mtCoupon != null && mtCoupon.getStatus().equals(StatusEnum.ENABLED.getKey())) { + try { + CouponReceiveParam param = new CouponReceiveParam(); + param.setCouponId(item.getCouponId()); + param.setUserId(userId); + param.setNum(item.getCouponNum() == null ? 1 : item.getCouponNum()); + ResponseObject result = couponService.sendCoupon(item.getCouponId(), userId, param.getNum(), true, SeqUtil.getUUID(), ""); + if (!result.getCode().equals(200)) { + logger.error("会员开卡赠礼赠送卡券失败:", result.getMessage()); + } + totalAmount = totalAmount.add(mtCoupon.getAmount()); + } catch (Exception e) { + logger.error("会员开卡赠礼异常:", e.getMessage()); + } + } + } + } + // 弹框消息 + MtMessage msg = new MtMessage(); + msg.setMerchantId(user.getMerchantId()); + msg.setType(MessageEnum.POP_MSG.getKey()); + msg.setUserId(userId); + msg.setTitle("温馨提示"); + msg.setSendTime(new Date()); + msg.setIsSend(YesOrNoEnum.YES.getKey()); + msg.setParams(""); + if (totalAmount.compareTo(new BigDecimal("0")) > 0 && totalPoint > 0) { + msg.setContent("系统赠送您价值¥" + totalAmount + "卡券和" + totalPoint + "积分,请注意查收!"); + messageService.addMessage(msg); + } else if(totalAmount.compareTo(new BigDecimal("0")) > 0) { + msg.setContent("系统赠送您价值" + totalAmount + "卡券,请注意查收!"); + messageService.addMessage(msg); + } else if(totalPoint > 0) { + msg.setContent("系统赠送您" + totalPoint + "积分,请注意查收!"); + messageService.addMessage(msg); + } + } + return true; + } + + /** + * 赠礼详情 + * + * @param openGiftInfo 赠礼详情 + * @throws BusinessCheckException + * @return OpenGiftDto + * */ + private OpenGiftDto dealDetail(MtOpenGift openGiftInfo) throws BusinessCheckException { + OpenGiftDto dto = new OpenGiftDto(); + + dto.setId(openGiftInfo.getId()); + dto.setCreateTime(DateUtil.formatDate(openGiftInfo.getCreateTime(), "yyyy.MM.dd HH:mm")); + dto.setUpdateTime(DateUtil.formatDate(openGiftInfo.getUpdateTime(), "yyyy.MM.dd HH:mm")); + dto.setStatus(openGiftInfo.getStatus()); + dto.setCouponNum(openGiftInfo.getCouponNum()); + dto.setPoint(openGiftInfo.getPoint()); + dto.setOperator(openGiftInfo.getOperator()); + + MtCoupon couponInfo = couponService.queryCouponById(openGiftInfo.getCouponId()); + dto.setCouponInfo(couponInfo); + + MtUserGrade gradeInfo = userGradeService.queryUserGradeById(openGiftInfo.getMerchantId(), openGiftInfo.getGradeId(), 0); + dto.setGradeInfo(gradeInfo); + + return dto; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/OrderServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..c175157 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/OrderServiceImpl.java @@ -0,0 +1,2433 @@ +package com.fuint.common.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.dto.*; +import com.fuint.common.enums.*; +import com.fuint.common.param.OrderListParam; +import com.fuint.common.param.RechargeParam; +import com.fuint.common.param.SettlementParam; +import com.fuint.common.service.*; +import com.fuint.common.util.*; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.PropertiesUtil; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import weixin.popular.util.JsonUtil; +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 订单接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class OrderServiceImpl extends ServiceImpl implements OrderService { + + private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); + + private MtOrderMapper mtOrderMapper; + + private MtGoodsMapper mtGoodsMapper; + + private MtOrderGoodsMapper mtOrderGoodsMapper; + + private MtCartMapper mtCartMapper; + + private MtOrderAddressMapper mtOrderAddressMapper; + + private MtConfirmLogMapper mtConfirmLogMapper; + + private MtUserCouponMapper mtUserCouponMapper; + + private MtGoodsSkuMapper mtGoodsSkuMapper; + + private MtRegionMapper mtRegionMapper; + + private MtUserGradeMapper mtUserGradeMapper; + + private MtCouponGoodsMapper mtCouponGoodsMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 会员卡券服务接口 + * */ + private UserCouponService userCouponService; + + /** + * 收货地址服务接口 + * */ + private AddressService addressService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 积分服务接口 + * */ + private PointService pointService; + + /** + * 购物车服务接口 + * */ + private CartService cartService; + + /** + * 商品服务接口 + * */ + private GoodsService goodsService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 会员等级服务接口 + * */ + private UserGradeService userGradeService; + + /** + * 售后服务接口 + * */ + private RefundService refundService; + + /** + * 余额服务接口 + * */ + private BalanceService balanceService; + + /** + * 微信相关服务接口 + * */ + private WeixinService weixinService; + + /** + * 支付宝服务接口 + * */ + private AlipayService alipayService; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 开卡赠礼服务接口 + * */ + private OpenGiftService openGiftService; + + /** + * 商户服务接口 + * */ + private MerchantService merchantService; + + /** + * 店铺员工服务接口 + * */ + private StaffService staffService; + + /** + * 支付服务接口 + * */ + private PaymentService paymentService; + + /** + * 云打印服务接口 + * */ + private PrinterService printerService; + + /** + * 商品分类服务接口 + */ + private StockService stockService; + + /** + * 预约单服务接口 + */ + private BookItemService bookItemService; + + /** + * 获取用户订单列表 + * @param orderListParam + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public PaginationResponse getUserOrderList(OrderListParam orderListParam) throws BusinessCheckException { + Integer pageNumber = orderListParam.getPage() == null ? Constants.PAGE_NUMBER : orderListParam.getPage(); + Integer pageSize = orderListParam.getPageSize() == null ? Constants.PAGE_SIZE : orderListParam.getPageSize(); + String userId = orderListParam.getUserId() == null ? "" : orderListParam.getUserId(); + Integer merchantId = orderListParam.getMerchantId() == null ? 0 : orderListParam.getMerchantId(); + Integer storeId = orderListParam.getStoreId() == null ? 0 : orderListParam.getStoreId(); + String status = orderListParam.getStatus() == null ? "": orderListParam.getStatus(); + String payStatus = orderListParam.getPayStatus() == null ? "": orderListParam.getPayStatus(); + String settleStatus = orderListParam.getSettleStatus() == null ? "": orderListParam.getSettleStatus(); + String dataType = orderListParam.getDataType() == null ? "": orderListParam.getDataType(); + String type = orderListParam.getType() == null ? "": orderListParam.getType(); + String orderSn = orderListParam.getOrderSn() == null ? "": orderListParam.getOrderSn(); + String mobile = orderListParam.getMobile() == null ? "": orderListParam.getMobile(); + String orderMode = orderListParam.getOrderMode() == null ? "" : orderListParam.getOrderMode(); + String staffId = orderListParam.getStaffId() == null ? "" : orderListParam.getStaffId(); + String couponId = orderListParam.getCouponId() == null ? "" : orderListParam.getCouponId(); + String storeIds = orderListParam.getStoreIds() == null ? "" : orderListParam.getStoreIds(); + String startTime = orderListParam.getStartTime() == null ? "" : orderListParam.getStartTime(); + String endTime = orderListParam.getEndTime() == null ? "" : orderListParam.getEndTime(); + String keyword = orderListParam.getKeyword() == null ? "" : orderListParam.getKeyword(); + String confirmStatus = orderListParam.getConfirmStatus() == null ? "" : orderListParam.getConfirmStatus(); + List payType = orderListParam.getPayType(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtOrder::getStatus, OrderStatusEnum.DELETED.getKey()); + + if (dataType.equals("toPay")) { + status = OrderStatusEnum.CREATED.getKey(); // 待支付 + } else if (dataType.equals("paid")) { + status = ""; + payStatus = PayStatusEnum.SUCCESS.getKey(); // 已支付 + } else if(dataType.equals("cancel")) { + status = OrderStatusEnum.CANCEL.getKey(); // 已取消 + } else if (dataType.equals("todo")) { + // 待核销 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getConfirmStatus, YesOrNoEnum.NO.getKey()); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getOrderMode, OrderModeEnum.ONESELF.getKey()); + } else if (dataType.equals("confirm")) { + // 已核销 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getConfirmStatus, YesOrNoEnum.YES.getKey()); + lambdaQueryWrapper.eq(MtOrder::getOrderMode, OrderModeEnum.ONESELF.getKey()); + } else if (dataType.equals("unShipped")) { + // 待发货 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getStatus, OrderStatusEnum.DELIVERY.getKey()); + lambdaQueryWrapper.eq(MtOrder::getOrderMode, OrderModeEnum.EXPRESS.getKey()); + } else if (dataType.equals("received")) { + // 已收货 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getStatus, OrderStatusEnum.RECEIVED.getKey()); + lambdaQueryWrapper.eq(MtOrder::getOrderMode, OrderModeEnum.EXPRESS.getKey()); + } else if (dataType.equals("shipped")) { + // 已发货 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getStatus, OrderStatusEnum.DELIVERED.getKey()); + lambdaQueryWrapper.eq(MtOrder::getOrderMode, OrderModeEnum.EXPRESS.getKey()); + } else if (dataType.equals("completed")) { + // 已完成 + payStatus = PayStatusEnum.SUCCESS.getKey(); + lambdaQueryWrapper.eq(MtOrder::getStatus, OrderStatusEnum.COMPLETE.getKey()); + } + + if (StringUtil.isNotEmpty(orderSn)) { + lambdaQueryWrapper.eq(MtOrder::getOrderSn, orderSn); + } + if (StringUtil.isNotEmpty(status)) { + lambdaQueryWrapper.eq(MtOrder::getStatus, status); + } + if (StringUtil.isNotEmpty(payStatus)) { + lambdaQueryWrapper.eq(MtOrder::getPayStatus, payStatus); + } + if (StringUtil.isNotEmpty(settleStatus)) { + lambdaQueryWrapper.eq(MtOrder::getSettleStatus, settleStatus); + } + if (StringUtil.isNotEmpty(keyword)) { + MtUser userInfo = memberService.queryMemberByMobile(merchantId, keyword); + if (userInfo != null) { + lambdaQueryWrapper.and(wq -> wq + .like(MtOrder::getOrderSn, keyword) + .or() + .eq(MtOrder::getUserId, userInfo.getId().toString())); + } else { + lambdaQueryWrapper.like(MtOrder::getOrderSn, keyword); + } + } + if (StringUtil.isNotEmpty(mobile)) { + MtUser userInfo = memberService.queryMemberByMobile(merchantId, mobile); + if (userInfo != null) { + userId = userInfo.getId().toString(); + } + } + if (StringUtil.isNotBlank(userId) && Integer.parseInt(userId) > 0) { + lambdaQueryWrapper.eq(MtOrder::getUserId, userId); + } + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtOrder::getMerchantId, merchantId); + } + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.eq(MtOrder::getStoreId, storeId); + } + if (StringUtil.isNotEmpty(staffId)) { + lambdaQueryWrapper.eq(MtOrder::getStaffId, staffId); + } + if (StringUtil.isNotEmpty(type)) { + lambdaQueryWrapper.eq(MtOrder::getType, type); + } + if (StringUtil.isNotEmpty(orderMode)) { + lambdaQueryWrapper.eq(MtOrder::getOrderMode, orderMode); + } + if (StringUtils.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtOrder::getCouponId, couponId); + } + if (StringUtils.isNotBlank(storeIds)) { + List idList = Arrays.asList(storeIds.split(",")); + if (idList.size() > 0) { + lambdaQueryWrapper.in(MtOrder::getStoreId, idList); + } + } + if (StringUtil.isNotEmpty(startTime)) { + lambdaQueryWrapper.ge(MtOrder::getCreateTime, startTime); + } + if (StringUtil.isNotEmpty(endTime)) { + lambdaQueryWrapper.le(MtOrder::getCreateTime, endTime); + } + if (payType != null && payType.size() > 0) { + lambdaQueryWrapper.in(MtOrder::getPayType, payType); + } + if (StringUtil.isNotEmpty(confirmStatus)) { + lambdaQueryWrapper.eq(MtOrder::getConfirmStatus, confirmStatus); + lambdaQueryWrapper.eq(MtOrder::getPayStatus, PayStatusEnum.SUCCESS.getKey()); + lambdaQueryWrapper.eq(MtOrder::getType, OrderTypeEnum.GOODS.getKey()); + } + lambdaQueryWrapper.orderByDesc(MtOrder::getId); + Page pageHelper = PageHelper.startPage(pageNumber, pageSize); + List orderList = mtOrderMapper.selectList(lambdaQueryWrapper); + + List dataList = new ArrayList<>(); + if (orderList.size() > 0) { + for (MtOrder order : orderList) { + UserOrderDto dto = getOrderDetail(order,false, false); + dataList.add(dto); + } + } + + PageRequest pageRequest = PageRequest.of(pageNumber, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, UserOrderDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存订单信息 + * + * @param orderDto 订单参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "提交订单信息") + public MtOrder saveOrder(OrderDto orderDto) throws BusinessCheckException { + logger.info("orderService.saveOrder orderDto = {}", JsonUtil.toJSONString(orderDto)); + MtOrder mtOrder; + if (null != orderDto.getId() && orderDto.getId() > 0) { + mtOrder = mtOrderMapper.selectById(orderDto.getId()); + } else { + mtOrder = new MtOrder(); + } + + // 检查店铺是否已被禁用 + if (orderDto.getStoreId() != null && orderDto.getStoreId() > 0) { + MtStore storeInfo = storeService.queryStoreById(orderDto.getStoreId()); + if (storeInfo != null) { + if (!storeInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + orderDto.setStoreId(0); + } + } + } + + String orderSn; + if (orderDto.getId() == null || orderDto.getId() < 1) { + orderSn = CommonUtil.createOrderSN(orderDto.getUserId() + ""); + mtOrder.setOrderSn(orderSn); + } else { + orderSn = mtOrder.getOrderSn(); + } + + mtOrder.setUserId(orderDto.getUserId()); + mtOrder.setMerchantId(orderDto.getMerchantId()); + mtOrder.setStoreId(orderDto.getStoreId()); + mtOrder.setCouponId(orderDto.getCouponId()); + mtOrder.setParam(orderDto.getParam()); + mtOrder.setRemark(orderDto.getRemark()); + if (orderDto.getStatus() != null) { + mtOrder.setStatus(orderDto.getStatus()); + } else { + mtOrder.setStatus(OrderStatusEnum.CREATED.getKey()); + } + mtOrder.setType(orderDto.getType()); + mtOrder.setAmount(orderDto.getAmount()); + mtOrder.setPayAmount(orderDto.getPayAmount()); + mtOrder.setDiscount(orderDto.getDiscount()); + if (orderDto.getPayStatus() != null) { + mtOrder.setPayStatus(orderDto.getPayStatus()); + } else { + mtOrder.setPayStatus(PayStatusEnum.WAIT.getKey()); + } + mtOrder.setPlatform(orderDto.getPlatform()); + mtOrder.setPointAmount(orderDto.getPointAmount()); + mtOrder.setUsePoint(orderDto.getUsePoint()); + mtOrder.setOrderMode(orderDto.getOrderMode()); + mtOrder.setPayType(orderDto.getPayType()); + mtOrder.setOperator(orderDto.getOperator()); + mtOrder.setStaffId(orderDto.getStaffId()); + mtOrder.setIsVisitor(orderDto.getIsVisitor()); + mtOrder.setUpdateTime(new Date()); + mtOrder.setDeliveryFee(orderDto.getDeliveryFee() == null ? new BigDecimal(0) : orderDto.getDeliveryFee()); + mtOrder.setSettleStatus(SettleStatusEnum.WAIT.getKey()); + mtOrder.setConfirmStatus(YesOrNoEnum.NO.getKey()); + + if (mtOrder.getId() == null || mtOrder.getId() <= 0) { + mtOrder.setCreateTime(new Date()); + } + if (orderDto.getPlatform() == null) { + orderDto.setPlatform(""); + } + // 核销码 + if (mtOrder.getVerifyCode() == null && !orderDto.getPlatform().equals(PlatformTypeEnum.PC.getCode())) { + mtOrder.setVerifyCode(SeqUtil.getRandomNumber(4)); + } else { + mtOrder.setVerifyCode(""); + if (mtOrder.getPayStatus().equals(PayStatusEnum.SUCCESS.getKey())) { + mtOrder.setConfirmStatus(YesOrNoEnum.YES.getKey()); + } + } + + // 首先生成订单 + mtOrderMapper.insert(mtOrder); + MtOrder orderInfo = mtOrderMapper.selectById(mtOrder.getId()); + mtOrder.setId(orderInfo.getId()); + + // 会员相关信息 + MtUser userInfo = memberService.queryMemberById(orderDto.getUserId()); + MtUserGrade userGrade = userGradeService.queryUserGradeById(orderDto.getMerchantId(), userInfo.getGradeId() != null ? userInfo.getGradeId() : 1, orderDto.getUserId()); + BigDecimal percent = new BigDecimal("0"); + if (userGrade != null && userGrade.getDiscount() != null && userGrade.getDiscount() > 0 && !userInfo.getIsStaff().equals(YesOrNoEnum.YES.getKey())) { + // 会员折扣 + percent = new BigDecimal(userGrade.getDiscount()).divide(new BigDecimal("10"), BigDecimal.ROUND_CEILING, 4); + if (percent.compareTo(new BigDecimal("0")) <= 0) { + percent = new BigDecimal("1"); + } + } + + // 如果没有指定店铺,则读取默认的店铺 + if (orderDto.getStoreId() == null || orderDto.getStoreId() <= 0) { + Map params = new HashMap<>(); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("is_default", YesOrNoEnum.YES.getKey()); + List storeList = storeService.queryStoresByParams(params); + if (storeList.size() > 0) { + mtOrder.setStoreId(storeList.get(0).getId()); + } else { + mtOrder.setStoreId(0); + } + } + + mtOrder.setUpdateTime(new Date()); + if (mtOrder.getCreateTime() == null) { + mtOrder.setCreateTime(new Date()); + } + + // 计算商品订单总金额 + List cartList = new ArrayList<>(); + Map cartData = new HashMap<>(); + if (orderDto.getType().equals(OrderTypeEnum.GOODS.getKey())) { + if (StringUtil.isNotEmpty(orderDto.getCartIds())) { + Map param = new HashMap<>(); + param.put("status", StatusEnum.ENABLED.getKey()); + param.put("ids", orderDto.getCartIds()); + cartList = cartService.queryCartListByParams(param); + if (cartList.size() < 1) { + throw new BusinessCheckException("生成订单失败,请稍后重试"); + } + } else { + if (orderDto.getGoodsId() == null || orderDto.getGoodsId() <= 0) { + throw new BusinessCheckException("生成订单失败,请稍后重试"); + } + // 直接购买 + MtCart mtCart = new MtCart(); + mtCart.setGoodsId(orderDto.getGoodsId()); + mtCart.setSkuId(orderDto.getSkuId()); + mtCart.setNum(orderDto.getBuyNum()); + mtCart.setId(0); + mtCart.setUserId(orderDto.getUserId()); + mtCart.setStatus(StatusEnum.ENABLED.getKey()); + cartList.add(mtCart); + } + + boolean isUsePoint = orderDto.getUsePoint() > 0 ? true : false; + cartData = calculateCartGoods(orderInfo.getMerchantId(), orderDto.getUserId(), cartList, orderDto.getCouponId(), isUsePoint, orderDto.getPlatform(), orderInfo.getOrderMode()); + + mtOrder.setAmount(new BigDecimal(cartData.get("totalPrice").toString())); + mtOrder.setUsePoint(Integer.parseInt(cartData.get("usePoint").toString())); + mtOrder.setDiscount(new BigDecimal(cartData.get("couponAmount").toString())); + + // 实付金额 + BigDecimal payAmount = mtOrder.getAmount().subtract(mtOrder.getPointAmount()).subtract(mtOrder.getDiscount()); + if (payAmount.compareTo(new BigDecimal("0")) > 0) { + mtOrder.setPayAmount(payAmount); + } else { + mtOrder.setPayAmount(new BigDecimal("0")); + } + + // 购物使用了卡券 + if (mtOrder.getCouponId() > 0) { + // 查询是否适用商品 + MtUserCoupon userCoupon = mtUserCouponMapper.selectById(mtOrder.getCouponId()); + if (userCoupon != null) { + MtCoupon couponInfo = couponService.queryCouponById(userCoupon.getCouponId()); + if (couponInfo.getApplyGoods() != null && couponInfo.getApplyGoods().equals(ApplyGoodsEnum.PARK_GOODS.getKey())) { + List couponGoodsList = mtCouponGoodsMapper.getCouponGoods(couponInfo.getId()); + if (couponGoodsList != null && couponGoodsList.size() > 0 && cartList.size() > 0) { + List applyGoodsIds = new ArrayList<>(); + List goodsIds = new ArrayList<>(); + for (MtCouponGoods mtCouponGoods : couponGoodsList) { + applyGoodsIds.add(mtCouponGoods.getGoodsId()); + } + for (MtCart mtCart : cartList) { + goodsIds.add(mtCart.getGoodsId()); + } + List intersection = applyGoodsIds.stream() + .filter(goodsIds::contains) + .collect(Collectors.toList()); + if (intersection.size() == 0) { + throw new BusinessCheckException("该卡券不适用于购买的商品列表"); + } + } + } + } + updateOrder(mtOrder); + String useCode = couponService.useCoupon(mtOrder.getCouponId(), mtOrder.getUserId(), mtOrder.getStoreId(), mtOrder.getId(), mtOrder.getDiscount(), "购物使用卡券"); + // 卡券使用失败 + if (StringUtil.isEmpty(useCode)) { + mtOrder.setDiscount(new BigDecimal("0")); + mtOrder.setCouponId(0); + } + } + } + + // 会员付款类订单 + if (orderDto.getType().equals(OrderTypeEnum.PAYMENT.getKey())) { + if (userInfo != null && userInfo.getGradeId() != null && orderDto.getIsVisitor().equals(YesOrNoEnum.NO.getKey())) { + if (percent.compareTo(new BigDecimal("0")) > 0 && !userInfo.getIsStaff().equals(YesOrNoEnum.YES.getKey())) { + // 会员折扣 + BigDecimal payAmountDiscount = mtOrder.getAmount().multiply(percent); + if (payAmountDiscount.compareTo(new BigDecimal("0")) > 0) { + mtOrder.setDiscount(mtOrder.getDiscount().add(mtOrder.getAmount().subtract(payAmountDiscount))); + mtOrder.setPayAmount(payAmountDiscount); + } else { + mtOrder.setPayAmount(new BigDecimal("0")); + } + } + } + } + + // 再次更新订单 + try { + orderInfo = updateOrder(mtOrder); + } catch (Exception e) { + logger.error("OrderService 生成订单失败..."); + throw new BusinessCheckException("生成订单失败,请稍后重试"); + } + + // 扣减积分 + if (orderDto.getUsePoint() != null && orderDto.getUsePoint() > 0) { + try { + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setUserId(orderDto.getUserId()); + reqPointDto.setAmount(-orderDto.getUsePoint()); + reqPointDto.setOrderSn(orderSn); + reqPointDto.setDescription("支付扣除" + orderDto.getUsePoint() + "积分"); + reqPointDto.setOperator(""); + pointService.addPoint(reqPointDto); + } catch (BusinessCheckException e) { + logger.error("OrderService 扣减积分失败...{}", e.getMessage()); + throw new BusinessCheckException("扣减积分失败,请稍后重试"); + } + } + + // 如果是商品订单,生成订单商品 + if (orderDto.getType().equals(OrderTypeEnum.GOODS.getKey()) && cartList.size() > 0) { + Object listObject = cartData.get("list"); + List lists =(ArrayList)listObject; + BigDecimal memberDiscount = new BigDecimal("0"); + for (ResCartDto cart : lists) { + MtOrderGoods orderGoods = new MtOrderGoods(); + orderGoods.setOrderId(orderInfo.getId()); + orderGoods.setGoodsId(cart.getGoodsId()); + orderGoods.setSkuId(cart.getSkuId()); + orderGoods.setNum(cart.getNum()); + // 计算会员折扣 + BigDecimal price = cart.getGoodsInfo().getPrice(); + boolean isDiscount = cart.getGoodsInfo().getIsMemberDiscount().equals(YesOrNoEnum.YES.getKey()) ? true : false; + if (percent.compareTo(new BigDecimal("0")) > 0 && isDiscount) { + orderGoods.setPrice(price.multiply(percent)); + BigDecimal discount = price.subtract(price.multiply(percent)).multiply(new BigDecimal(cart.getNum())); + orderGoods.setDiscount(discount); + memberDiscount = memberDiscount.add(discount); + } else { + orderGoods.setPrice(price); + orderGoods.setDiscount(new BigDecimal("0")); + } + orderGoods.setStatus(StatusEnum.ENABLED.getKey()); + orderGoods.setCreateTime(new Date()); + orderGoods.setUpdateTime(new Date()); + mtOrderGoodsMapper.insert(orderGoods); + // 扣减库存 + MtGoods goodsInfo = mtGoodsMapper.selectById(cart.getGoodsId()); + if (goodsInfo.getIsSingleSpec().equals(YesOrNoEnum.YES.getKey())) { + // 单规格减去库存 + Double stock = goodsInfo.getStock() - cart.getNum(); + if (stock < 0) { + throw new BusinessCheckException("商品“" + goodsInfo.getName() + "”库存不足,订单提交失败"); + } + goodsInfo.setStock(stock); + mtGoodsMapper.updateById(goodsInfo); + } else { + // 多规格减去库存 + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(cart.getSkuId()); + if (mtGoodsSku != null) { + Double stock = mtGoodsSku.getStock() - cart.getNum(); + if (stock < 0) { + throw new BusinessCheckException("商品sku编码“" + mtGoodsSku.getSkuNo() +"”库存不足,订单提交失败"); + } + mtGoodsSku.setStock(stock); + mtGoodsSkuMapper.updateById(mtGoodsSku); + + if (goodsInfo.getStock() != null && goodsInfo.getStock() > 0) { + Double goodsStock = goodsInfo.getStock() - cart.getNum(); + if (goodsStock >= 0) { + goodsInfo.setStock(goodsStock); + mtGoodsMapper.updateById(goodsInfo); + } + } + } + } + // 生成库存记录 + stockService.addStockRecord(orderInfo.getMerchantId(), orderInfo.getStoreId(), cart.getGoodsId(), cart.getSkuId(), "reduce", cart.getNum(), "订单扣减库存,订单号:"+orderInfo.getOrderSn()); + + // 删除购物车 + if (cart.getId() > 0) { + mtCartMapper.deleteById(cart.getId()); + } + } + + // 会员折扣 + if (memberDiscount.compareTo(new BigDecimal("0")) > 0 && !userInfo.getIsStaff().equals(YesOrNoEnum.YES.getKey())) { + orderInfo.setDiscount(orderInfo.getDiscount().add(memberDiscount)); + if (orderInfo.getPayAmount().subtract(memberDiscount).compareTo(new BigDecimal("0")) > 0) { + orderInfo.setPayAmount(orderInfo.getPayAmount().subtract(memberDiscount)); + } else { + orderInfo.setPayAmount(new BigDecimal("0")); + } + orderInfo.setUpdateTime(new Date()); + orderInfo = updateOrder(orderInfo); + } + + // 需要配送的订单,生成配送地址 + if (orderDto.getOrderMode().equals(OrderModeEnum.EXPRESS.getKey())) { + Map params = new HashMap<>(); + params.put("userId", orderDto.getUserId().toString()); + params.put("isDefault", YesOrNoEnum.YES.getKey()); + List addressList = addressService.queryListByParams(params); + MtAddress mtAddress; + if (addressList.size() > 0) { + mtAddress = addressList.get(0); + } else { + throw new BusinessCheckException("配送地址出错了,请重新选择配送地址"); + } + + // 是否超出起送范围 + MtSetting deliveryRange = settingService.querySettingByName(orderInfo.getMerchantId(), SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.DELIVERY_RANGE.getKey()); + if (deliveryRange != null && StringUtil.isNotEmpty(deliveryRange.getValue()) && (Double.parseDouble(deliveryRange.getValue()) > 0)) { + MtStore mtStore = storeService.queryStoreById(orderInfo.getStoreId()); + if (mtStore != null && StringUtil.isNotEmpty(mtStore.getLatitude()) && StringUtil.isNotEmpty(mtStore.getLongitude())) { + String address = ""; + if (mtAddress.getProvinceId() != null && mtAddress.getProvinceId() > 0) { + MtRegion mtProvince = mtRegionMapper.selectById(mtAddress.getProvinceId()); + if (mtProvince != null) { + address = mtProvince.getName(); + } + } + if (mtAddress.getCityId() != null && mtAddress.getCityId() > 0) { + MtRegion mtCity = mtRegionMapper.selectById(mtAddress.getCityId()); + if (mtCity != null) { + address = address + mtCity.getName(); + } + } + if (mtAddress.getRegionId() != null && mtAddress.getRegionId() > 0) { + MtRegion mtRegion = mtRegionMapper.selectById(mtAddress.getRegionId()); + if (mtRegion != null) { + address = address + mtRegion.getName(); + } + } + address = address + mtAddress.getDetail(); + Map latAndLng = storeService.getLatAndLngByAddress(address); + if (StringUtil.isNotEmpty(latAndLng.get("lat").toString()) && StringUtil.isNotEmpty(latAndLng.get("lng").toString())) { + Double distance = storeService.getDistance(mtStore.getLongitude() + "," + mtStore.getLatitude(), latAndLng.get("lng").toString() + "," + latAndLng.get("lat").toString()); + Double limitDistance = Double.parseDouble(deliveryRange.getValue()); + logger.info("订单地址:{},配送距离为:{}", address, distance); + if (distance > limitDistance) { + throw new BusinessCheckException("抱歉,配送距离超过了" + limitDistance + "公里,请重新选择配送地址!"); + } + } + } + } + + MtOrderAddress orderAddress = new MtOrderAddress(); + orderAddress.setOrderId(orderInfo.getId()); + orderAddress.setUserId(orderDto.getUserId()); + orderAddress.setName(mtAddress.getName()); + orderAddress.setMobile(mtAddress.getMobile()); + orderAddress.setCityId(mtAddress.getCityId()); + orderAddress.setProvinceId(mtAddress.getProvinceId()); + orderAddress.setRegionId(mtAddress.getRegionId()); + orderAddress.setDetail(mtAddress.getDetail()); + orderAddress.setCreateTime(new Date()); + mtOrderAddressMapper.insert(orderAddress); + } + } + + return orderInfo; + } + + /** + * 订单结算 + * @param request + * @param param 结算参数 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Map doSettle(HttpServletRequest request, SettlementParam param) throws BusinessCheckException { + String token = request.getHeader("Access-Token"); + String isWechat = request.getHeader("isWechat") == null ? YesOrNoEnum.NO.getKey() : request.getHeader("isWechat"); + Integer storeId = StringUtil.isEmpty(request.getHeader("storeId")) ? 0 : Integer.parseInt(request.getHeader("storeId")); + String platform = request.getHeader("platform") == null ? "" : request.getHeader("platform"); + String merchantNo = request.getHeader("merchantNo") == null ? "" : request.getHeader("merchantNo"); + String ip = CommonUtil.getIPFromHttpRequest(request); + String cartIds = param.getCartIds() == null ? "" : param.getCartIds(); + Integer targetId = param.getTargetId() == null ? 0 : Integer.parseInt(param.getTargetId()); // 储值卡、升级等级必填 + String selectNum = param.getSelectNum() == null ? "" : param.getSelectNum(); // 储值卡必填 + String remark = param.getRemark() == null ? "" : param.getRemark(); + String type = param.getType() == null ? "" : param.getType(); // 订单类型 + String payAmount = param.getPayAmount() == null ? "0" : StringUtil.isEmpty(param.getPayAmount()) ? "0" : param.getPayAmount(); // 支付金额 + Integer usePoint = param.getUsePoint() == null ? 0 : param.getUsePoint(); // 使用积分数量 + Integer couponId = param.getCouponId() == null ? 0 : param.getCouponId(); // 会员卡券ID + String payType = param.getPayType() == null ? PayTypeEnum.JSAPI.getKey() : param.getPayType(); + String authCode = param.getAuthCode() == null ? "" : param.getAuthCode(); + Integer userId = param.getUserId() == null ? 0 : param.getUserId(); // 指定下单会员 eg:收银功能 + String cashierPayAmount = param.getCashierPayAmount() == null ? "" : param.getCashierPayAmount(); // 收银台实付金额 + String cashierDiscountAmount = param.getCashierDiscountAmount() == null ? "" : param.getCashierDiscountAmount(); // 收银台优惠金额 + Integer goodsId = param.getGoodsId() == null ? 0 : param.getGoodsId(); // 立即购买商品ID + Integer skuId = param.getSkuId() == null ? 0 : param.getSkuId(); // 立即购买商品skuId + Double buyNum = param.getBuyNum() == null ? 1.0 : param.getBuyNum(); // 立即购买商品数量 + String orderMode = StringUtil.isEmpty(param.getOrderMode()) ? OrderModeEnum.ONESELF.getKey() : param.getOrderMode(); // 订单模式(配送or自取) + Integer orderId = param.getOrderId() == null ? null : param.getOrderId(); // 订单ID + Integer merchantId = merchantService.getMerchantId(merchantNo); + UserInfo loginInfo = TokenUtil.getUserInfoByToken(token); + MtUser userInfo = null; + if (loginInfo != null) { + userInfo = memberService.queryMemberById(loginInfo.getId()); + } + + // 后台管理员或店员操作 + String operator = null; + Integer staffId = 0; + String isVisitor = YesOrNoEnum.NO.getKey(); + AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token); + if (accountInfo != null) { + operator = accountInfo.getAccountName(); + staffId = accountInfo.getStaffId() == null ? 0 : accountInfo.getStaffId(); + + if (param.getStaffId() != null && param.getStaffId() > 0) { + staffId = param.getStaffId(); + } + + storeId = accountInfo.getStoreId(); + merchantId = accountInfo.getMerchantId(); + if (storeId <= 0) { + MtMerchant mtMerchant = merchantService.queryMerchantById(merchantId); + if (mtMerchant != null) { + MtStore mtStore = storeService.getDefaultStore(mtMerchant.getNo()); + if (mtStore != null) { + storeId = mtStore.getId(); + } + } + } + if (userId < 1) { + isVisitor = YesOrNoEnum.YES.getKey(); + } + } + + if (userInfo == null) { + MtUser user = memberService.getCurrentUserInfo(request, userId, token); + if (user != null) { + userInfo = memberService.queryMemberById(user.getId()); + } + } else { + MtStaff mtStaff = staffService.queryStaffByUserId(userInfo.getId()); + if (mtStaff == null) { + mtStaff = staffService.queryStaffByMobile(userInfo.getMobile()); + } + if (mtStaff != null) { + operator = mtStaff.getRealName(); + } + } + + MtSetting config = settingService.querySettingByName(merchantId, storeId, SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.IS_CLOSE.getKey()); + if (config != null && config.getValue().equals(YesOrNoEnum.TRUE.getKey())) { + throw new BusinessCheckException("系统已关闭交易功能,请稍后再试!"); + } + + // 收银台通过手机号自动注册会员信息 + if ((userInfo == null || StringUtil.isEmpty(token))) { + String mobile = param.getMobile() == null ? "" : param.getMobile(); + if (StringUtil.isNotEmpty(operator) && StringUtil.isNotEmpty(mobile)) { + userInfo = memberService.queryMemberByMobile(merchantId, mobile); + // 自动注册会员 + if (userInfo == null) { + userInfo = memberService.addMemberByMobile(merchantId, mobile, "0", ip); + } + } + } + + if (userInfo == null) { + if (StringUtil.isNotEmpty(operator)) { + throw new BusinessCheckException("该管理员还未关联店铺员工"); + } else { + throw new BusinessCheckException("请先登录"); + } + } + + if (userId <= 0) { + userId = userInfo.getId(); + } else { + if (StringUtil.isNotEmpty(operator)) { + userInfo = memberService.queryMemberById(userId); + } + } + param.setUserId(userId); + + // 订单所属店铺 + if (storeId < 1) { + if (userInfo.getStoreId() > 0) { + storeId = userInfo.getStoreId(); + } + } + + if (merchantId == null || merchantId <= 0) { + throw new BusinessCheckException("系统异常,商户ID不能为空"); + } + + // 生成订单数据 + OrderDto orderDto = new OrderDto(); + orderDto.setId(orderId); + orderDto.setRemark(remark); + orderDto.setUserId(userId); + orderDto.setMerchantId(merchantId); + orderDto.setStoreId(storeId); + orderDto.setType(type); + orderDto.setGoodsId(goodsId); + orderDto.setSkuId(skuId); + orderDto.setBuyNum(buyNum); + orderDto.setOrderMode(orderMode); + orderDto.setOperator(operator); + orderDto.setPayType(payType); + orderDto.setCouponId(0); + orderDto.setStaffId(staffId); + orderDto.setIsVisitor(isVisitor); + orderDto.setPlatform(platform); + + MtSetting pointSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.POINT.getKey(), PointSettingEnum.CAN_USE_AS_MONEY.getKey()); + // 使用积分数量 + if (pointSetting != null && pointSetting.getValue().equals(YesOrNoEnum.TRUE.getKey())) { + orderDto.setUsePoint(usePoint); + } else { + orderDto.setUsePoint(0); + usePoint = 0; + } + + orderDto.setPointAmount(new BigDecimal("0")); + orderDto.setDiscount(new BigDecimal("0")); + orderDto.setPayAmount(new BigDecimal("0")); + orderDto.setAmount(new BigDecimal("0")); + orderDto.setCartIds(cartIds); + + // 储值卡的订单 + if (orderDto.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + orderDto.setCouponId(targetId); + String orderParam = ""; + BigDecimal totalAmount = new BigDecimal(0); + + MtCoupon couponInfo = couponService.queryCouponById(targetId); + String inRule = couponInfo.getInRule(); + String[] selectNumArr = selectNum.split(","); + String[] ruleArr = inRule.split(","); + for (int i = 0; i < ruleArr.length; i++) { + String item = ruleArr[i] + "_" + (StringUtil.isNotEmpty(selectNumArr[i]) ? selectNumArr[i] : 0); + String[] itemArr = item.split("_"); + // 预存金额 + BigDecimal price = new BigDecimal(itemArr[0]); + // 预存数量 + BigDecimal num = new BigDecimal(selectNumArr[i]); + BigDecimal amount = price.multiply(num); + totalAmount = totalAmount.add(amount); + orderParam = StringUtil.isEmpty(orderParam) ? item : orderParam + ","+item; + } + + orderDto.setParam(orderParam); + orderDto.setAmount(totalAmount); + payAmount = totalAmount.toString(); + } + + // 付款订单 + if (orderDto.getType().equals(OrderTypeEnum.PAYMENT.getKey())) { + orderDto.setAmount(new BigDecimal(payAmount)); + orderDto.setPayAmount(new BigDecimal(payAmount)); + orderDto.setDiscount(new BigDecimal("0")); + orderDto.setDeliveryFee(new BigDecimal("0")); + } + + // 会员升级订单 + if (orderDto.getType().equals(OrderTypeEnum.MEMBER.getKey())) { + orderDto.setParam(targetId.toString()); + orderDto.setCouponId(couponId); + MtUserGrade userGrade = userGradeService.queryUserGradeById(merchantId, targetId, orderDto.getUserId()); + if (userGrade != null) { + orderDto.setRemark("付费升级" + userGrade.getName()); + orderDto.setAmount(new BigDecimal(userGrade.getCatchValue().toString())); + } + } + + // 商品订单 + if (orderDto.getType().equals(OrderTypeEnum.GOODS.getKey())) { + orderDto.setCouponId(couponId); + } + + // 商品订单且配送要加上配送费用 + if (orderDto.getType().equals(OrderTypeEnum.GOODS.getKey()) && orderDto.getOrderMode().equals(OrderModeEnum.EXPRESS.getKey())) { + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.DELIVERY_FEE.getKey()); + if (mtSetting != null && StringUtil.isNotEmpty(mtSetting.getValue())) { + BigDecimal deliveryFee = new BigDecimal(mtSetting.getValue()); + if (deliveryFee.compareTo(new BigDecimal("0")) > 0) { + orderDto.setDeliveryFee(deliveryFee); + } + } + } + + // 使用积分抵扣 + if (usePoint > 0) { + List settingList = settingService.getSettingList(merchantId, SettingTypeEnum.POINT.getKey()); + String canUsedAsMoney = YesOrNoEnum.FALSE.getKey(); + String exchangeNeedPoint = "0"; + for (MtSetting setting : settingList) { + if (setting.getName().equals("canUsedAsMoney")) { + canUsedAsMoney = setting.getValue(); + } else if (setting.getName().equals("exchangeNeedPoint")) { + exchangeNeedPoint = setting.getValue(); + } + } + // 是否可以使用积分,并且积分数量足够 + if (canUsedAsMoney.equals(YesOrNoEnum.TRUE.getKey()) && Float.parseFloat(exchangeNeedPoint) > 0 && (userInfo.getPoint() >= usePoint)) { + orderDto.setUsePoint(usePoint); + orderDto.setPointAmount(new BigDecimal(usePoint).divide(new BigDecimal(exchangeNeedPoint), BigDecimal.ROUND_CEILING, 4)); + if (orderDto.getPayAmount().compareTo(orderDto.getPointAmount()) > 0) { + orderDto.setPayAmount(orderDto.getPayAmount().subtract(orderDto.getPointAmount())); + } else { + orderDto.setPayAmount(new BigDecimal("0")); + } + } + } + + // 首先生成订单,拿到订单ID + MtOrder orderInfo; + try { + orderInfo = saveOrder(orderDto); + } catch (BusinessCheckException e) { + throw new BusinessCheckException(e.getMessage() == null ? "生成订单失败" : e.getMessage()); + } + + orderDto.setId(orderInfo.getId()); + param.setOrderId(orderInfo.getId()); + + // 收银台实付金额、优惠金额 + if ((StringUtil.isNotEmpty(cashierPayAmount) || StringUtil.isNotEmpty(cashierDiscountAmount)) && StringUtil.isNotEmpty(operator)) { + OrderDto reqOrder = new OrderDto(); + reqOrder.setId(orderInfo.getId()); + if (orderInfo.getAmount().compareTo(new BigDecimal("0")) <= 0) { + reqOrder.setAmount(new BigDecimal(cashierPayAmount).add(new BigDecimal(cashierDiscountAmount))); + } else { + reqOrder.setAmount(orderInfo.getAmount()); + } + if (new BigDecimal(cashierDiscountAmount).compareTo(new BigDecimal("0")) > 0) { + reqOrder.setDiscount(new BigDecimal(cashierDiscountAmount).add(orderInfo.getDiscount())); + } else { + reqOrder.setDiscount(orderInfo.getDiscount()); + } + BigDecimal realPayAmount = reqOrder.getAmount().subtract(reqOrder.getDiscount()); + if (realPayAmount.compareTo(new BigDecimal("0")) < 0) { + realPayAmount = new BigDecimal("0"); + } + reqOrder.setPayAmount(realPayAmount); + updateOrder(reqOrder); + orderInfo = getOrderInfo(orderInfo.getId()); + } + + // 订单中使用卡券抵扣(付款订单、会员升级订单) + if (couponId > 0 && (orderDto.getType().equals(OrderTypeEnum.PAYMENT.getKey())) || orderDto.getType().equals(OrderTypeEnum.MEMBER.getKey())) { + if (orderDto.getAmount().compareTo(new BigDecimal("0")) > 0) { + MtUserCoupon userCouponInfo = userCouponService.getUserCouponDetail(couponId); + if (userCouponInfo != null) { + MtCoupon couponInfo = couponService.queryCouponById(userCouponInfo.getCouponId()); + if (couponInfo != null) { + boolean isEffective = couponService.isCouponEffective(couponInfo, userCouponInfo); + if (isEffective && userCouponInfo.getUserId().equals(orderDto.getUserId())) { + // 优惠券,直接减去优惠券金额 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + // 检查是否会员升级专用卡券 + boolean canUse = true; + if (couponInfo.getUseFor() != null && StringUtil.isNotEmpty(couponInfo.getUseFor())) { + if (orderDto.getType().equals(OrderTypeEnum.MEMBER.getKey())) { + if (!couponInfo.getUseFor().equals(CouponUseForEnum.MEMBER_GRADE.getKey())) { + canUse = false; + } + } + } + if (canUse) { + String useCode = couponService.useCoupon(couponId, orderDto.getUserId(), orderDto.getStoreId(), orderInfo.getId(), userCouponInfo.getAmount(), "核销"); + if (StringUtil.isNotEmpty(useCode)) { + orderDto.setCouponId(couponId); + // 折扣券 + if (couponInfo.getContent().equals(CouponContentEnum.PERCENT.getKey())) { + BigDecimal discount = new BigDecimal("0"); + BigDecimal percent = userCouponInfo.getAmount().divide(new BigDecimal("100"), BigDecimal.ROUND_CEILING, 4); + discount = discount.multiply(new BigDecimal("1").subtract(percent)); + if (discount.compareTo(new BigDecimal("0")) > 0) { + orderDto.setDiscount(orderInfo.getDiscount().add(discount)); + } + } else { + // 满减券 + orderDto.setDiscount(orderInfo.getDiscount().add(userCouponInfo.getAmount())); + } + updateOrder(orderDto); + } + } + } else if(couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + // 储值卡,减去余额 + BigDecimal useCouponAmount = userCouponInfo.getBalance(); + if (orderInfo.getPayAmount().compareTo(userCouponInfo.getBalance()) <= 0) { + useCouponAmount = orderInfo.getPayAmount(); + } + try { + String useCode = couponService.useCoupon(couponId, orderDto.getUserId(), orderDto.getStoreId(), orderInfo.getId(), useCouponAmount, "核销"); + if (StringUtil.isNotEmpty(useCode)) { + orderDto.setCouponId(couponId); + orderDto.setDiscount(orderInfo.getDiscount().add(useCouponAmount)); + orderDto.setPayAmount(orderInfo.getPayAmount().subtract(useCouponAmount)); + updateOrder(orderDto); + } + } catch (BusinessCheckException e) { + throw new BusinessCheckException(e.getMessage() == null ? "生成订单失败" : e.getMessage()); + } + } + } + } + } + } + } + + // 生成支付订单 + orderInfo = getOrderInfo(orderInfo.getId()); + BigDecimal realPayAmount = orderInfo.getAmount().subtract(new BigDecimal(orderInfo.getDiscount().toString())).subtract(new BigDecimal(orderInfo.getPointAmount().toString())).add(orderInfo.getDeliveryFee()); + + // 支付类的订单,检查余额是否充足 + if (type.equals(OrderTypeEnum.PAYMENT.getKey()) && payType.equals(PayTypeEnum.BALANCE.getKey())) { + if (userInfo.getBalance() == null || realPayAmount.compareTo(userInfo.getBalance()) > 0) { + throw new BusinessCheckException("会员余额不足"); + } + if (StringUtil.isNotEmpty(cashierPayAmount)) { + if (userInfo.getBalance() == null || new BigDecimal(cashierPayAmount).compareTo(userInfo.getBalance()) > 0) { + throw new BusinessCheckException("会员余额不足"); + } + } + } + + MtSetting delivery = settingService.querySettingByName(merchantId, SettingTypeEnum.ORDER.getKey(),OrderSettingEnum.DELIVERY_MIN_AMOUNT.getKey()); + if (delivery != null && orderInfo.getOrderMode().equals(OrderModeEnum.EXPRESS.getKey())) { + BigDecimal deliveryMinAmount = new BigDecimal(delivery.getValue()); + if (deliveryMinAmount.compareTo(new BigDecimal("0")) > 0 && deliveryMinAmount.compareTo(orderInfo.getAmount()) > 0) { + throw new BusinessCheckException("订单起送金额:" + deliveryMinAmount + "元"); + } + } + + ResponseObject paymentInfo = null; + String errorMessage = ""; + + // 应付金额大于0才提交微信支付 + if (realPayAmount.compareTo(new BigDecimal("0")) > 0) { + if (payType.equals(PayTypeEnum.CASH.getKey()) && StringUtil.isNotEmpty(operator)) { + // 收银台现金支付,更新为已支付 + setOrderPayed(orderInfo.getId(), null); + } else if (payType.equals(PayTypeEnum.STORE.getKey())) { + // 门店支付,不做任何操作 + } else if(payType.equals(PayTypeEnum.BALANCE.getKey())) { + // 余额支付 + MtBalance balance = new MtBalance(); + balance.setMobile(userInfo.getMobile()); + balance.setOrderSn(orderInfo.getOrderSn()); + balance.setUserId(userInfo.getId()); + balance.setMerchantId(userInfo.getMerchantId()); + balance.setStoreId(orderInfo.getStoreId()); + BigDecimal balanceAmount = realPayAmount.subtract(realPayAmount).subtract(realPayAmount); + balance.setAmount(balanceAmount); + boolean isPay = balanceService.addBalance(balance, true); + if (isPay) { + setOrderPayed(orderInfo.getId(), realPayAmount); + } else { + errorMessage = PropertiesUtil.getResponseErrorMessageByCode(5001); + } + } else { + BigDecimal wxPayAmount = realPayAmount.multiply(new BigDecimal("100")); + // 扫码支付,先返回不处理,后面拿到支付二维码再处理 + if ((payType.equals(PayTypeEnum.MICROPAY.getKey()) || payType.equals(PayTypeEnum.ALISCAN.getKey())) && StringUtil.isEmpty(authCode)) { + paymentInfo = new ResponseObject(200, "请求成功", new HashMap<>()); + } else { + paymentInfo = paymentService.createPrepayOrder(userInfo, orderInfo, (wxPayAmount.intValue()), authCode, 0, ip, platform, isWechat); + } + if (paymentInfo.getData() == null) { + errorMessage = StringUtil.isNotEmpty(paymentInfo.getMessage()) ? paymentInfo.getMessage() : PropertiesUtil.getResponseErrorMessageByCode(3000); + } + } + } else { + // 应付金额是0,直接更新为已支付 + setOrderPayed(orderInfo.getId(), null); + } + + orderInfo = getOrderInfo(orderInfo.getId()); + Map outParams = new HashMap(); + outParams.put("isCreated", true); + outParams.put("orderInfo", orderInfo); + outParams.put("payType", payType); + + if (paymentInfo != null) { + outParams.put("payment", paymentInfo.getData()); + } else { + outParams.put("payment", null); + } + + // 发送小程序订阅消息 + Date nowTime = new Date(); + Map params = new HashMap<>(); + String dateTime = DateUtil.formatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm"); + params.put("time", dateTime); + params.put("orderSn", orderInfo.getOrderSn()); + params.put("remark", "您的订单已生成,请留意~"); + weixinService.sendSubscribeMessage(merchantId, userInfo.getId(), userInfo.getOpenId(), WxMessageEnum.ORDER_CREATED.getKey(), "pages/order/index", params, nowTime); + + if (StringUtil.isNotEmpty(errorMessage)) { + throw new BusinessCheckException(errorMessage); + } else { + return outParams; + } + } + + /** + * 获取订单详情 + * + * @param orderId 订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtOrder getOrderInfo(Integer orderId) { + if (orderId == null || orderId <= 0) { + return null; + } + return mtOrderMapper.selectById(orderId); + } + + /** + * 根据ID获取订单详情 + * + * @param orderId 订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public UserOrderDto getOrderById(Integer orderId) throws BusinessCheckException { + if (orderId == null || orderId <= 0) { + return null; + } + MtOrder mtOrder = mtOrderMapper.selectById(orderId); + return getOrderDetail(mtOrder, true, true); + } + + /** + * 根据ID获取我的订单详情 + * + * @param orderId 订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public UserOrderDto getMyOrderById(Integer orderId) throws BusinessCheckException { + if (orderId == null || orderId <= 0) { + return null; + } + MtOrder mtOrder = mtOrderMapper.selectById(orderId); + UserOrderDto orderInfo = getOrderDetail(mtOrder, true, true); + + // 售后订单 + MtRefund refund = refundService.getRefundByOrderId(orderId); + orderInfo.setRefundInfo(refund); + + orderInfo.setVerifyCode(mtOrder.getVerifyCode()); + return orderInfo; + } + + /** + * 取消订单 + * + * @param orderId 订单ID + * @param remark 取消备注 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "取消订单") + public MtOrder cancelOrder(Integer orderId, String remark) throws BusinessCheckException { + MtOrder mtOrder = mtOrderMapper.selectById(orderId); + logger.info("orderService.cancelOrder orderId = {}, remark = {}", orderId, remark); + + if (mtOrder != null && mtOrder.getStatus().equals(OrderStatusEnum.CREATED.getKey()) && mtOrder.getPayStatus().equals(PayStatusEnum.WAIT.getKey())) { + if (StringUtil.isNotEmpty(remark)) { + mtOrder.setRemark(remark); + } + + mtOrder.setStatus(OrderStatusEnum.CANCEL.getKey()); + mtOrderMapper.updateById(mtOrder); + + // 返还积分 + if (mtOrder.getPointAmount() != null && mtOrder.getUsePoint() > 0) { + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setUserId(mtOrder.getUserId()); + reqPointDto.setAmount(mtOrder.getUsePoint()); + reqPointDto.setDescription("订单取消" + mtOrder.getOrderSn() + "退回"+ mtOrder.getUsePoint() +"积分"); + reqPointDto.setOrderSn(mtOrder.getOrderSn()); + reqPointDto.setOperator(""); + pointService.addPoint(reqPointDto); + } + + // 返还卡券 + List confirmLogList = mtConfirmLogMapper.getOrderConfirmLogList(mtOrder.getId()); + if (confirmLogList.size() > 0) { + for (MtConfirmLog log : confirmLogList) { + MtCoupon couponInfo = couponService.queryCouponById(log.getCouponId()); + MtUserCoupon userCouponInfo = mtUserCouponMapper.selectById(log.getUserCouponId()); + + if (userCouponInfo != null) { + // 优惠券直接置为未使用 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + userCouponInfo.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + mtUserCouponMapper.updateById(userCouponInfo); + } + + // 储值卡把余额加回去 + if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + BigDecimal balance = userCouponInfo.getBalance(); + BigDecimal newBalance = balance.add(log.getAmount()); + if (newBalance.compareTo(userCouponInfo.getAmount()) <= 0) { + userCouponInfo.setBalance(newBalance); + userCouponInfo.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + } + mtUserCouponMapper.updateById(userCouponInfo); + } + + // 撤销核销记录 + log.setStatus(StatusEnum.DISABLE.getKey()); + mtConfirmLogMapper.updateById(log); + } + } + } + + // 返还库存 + Map params = new HashMap<>(); + params.put("ORDER_ID", mtOrder.getId()); + List orderGoodsList = mtOrderGoodsMapper.selectByMap(params); + if (orderGoodsList != null && orderGoodsList.size() > 0) { + for (MtOrderGoods mtOrderGoods : orderGoodsList) { + MtGoods mtGoods = mtGoodsMapper.selectById(mtOrderGoods.getGoodsId()); + // 商品已不存在 + if (mtGoods == null) { + continue; + } + mtGoods.setStock(mtOrderGoods.getNum() + mtGoods.getStock()); + mtGoodsMapper.updateById(mtGoods); + if (mtOrderGoods.getSkuId() != null && mtOrderGoods.getSkuId() > 0) { + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(mtOrderGoods.getSkuId()); + if (mtGoodsSku != null && mtGoodsSku.getStock() != null && mtOrderGoods.getNum() != null) { + mtGoodsSku.setStock(mtGoodsSku.getStock() + mtOrderGoods.getNum()); + mtGoodsSkuMapper.updateById(mtGoodsSku); + } + } + } + } + } + + return mtOrder; + } + + /** + * 根据订单ID删除 + * + * @param orderId 订单ID + * @param operator 操作人 + * @return + */ + @Override + @OperationServiceLog(description = "删除订单信息") + public void deleteOrder(Integer orderId, String operator) { + logger.info("orderService.deleteOrder orderId = {}, operator = {}", orderId, operator); + MtOrder mtOrder = mtOrderMapper.selectById(orderId); + if (mtOrder == null) { + return; + } + + mtOrder.setStatus(OrderStatusEnum.DELETED.getKey()); + mtOrder.setUpdateTime(new Date()); + mtOrder.setOperator(operator); + + mtOrderMapper.updateById(mtOrder); + } + + /** + * 根据订单号获取订单详情 + * + * @param orderSn 订单号 + * @throws BusinessCheckException + * @return + */ + @Override + public UserOrderDto getOrderByOrderSn(String orderSn) throws BusinessCheckException { + MtOrder orderInfo = mtOrderMapper.findByOrderSn(orderSn); + if (orderInfo == null) { + return null; + } + return getOrderDetail(orderInfo, true, true); + } + + /** + * 根据订单号获取订单信息 + * + * @param orderSn 订单号 + * @return + */ + @Override + public MtOrder getOrderInfoByOrderSn(String orderSn) { + return mtOrderMapper.findByOrderSn(orderSn); + } + + /** + * 更新订单 + * + * @param orderDto 订单参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新订单信息") + public MtOrder updateOrder(OrderDto orderDto) throws BusinessCheckException { + logger.info("orderService.updateOrder orderDto = {}", JsonUtil.toJSONString(orderDto)); + MtOrder mtOrder = mtOrderMapper.selectById(orderDto.getId()); + if (null == mtOrder || OrderStatusEnum.DELETED.getKey().equals(mtOrder.getStatus())) { + throw new BusinessCheckException("该订单状态异常"); + } + + mtOrder.setId(orderDto.getId()); + mtOrder.setUpdateTime(new Date()); + + if (null != orderDto.getOperator()) { + mtOrder.setOperator(orderDto.getOperator()); + } + + if (null != orderDto.getStatus()) { + if (orderDto.getStatus().equals(OrderStatusEnum.CANCEL.getKey()) || orderDto.getStatus().equals(OrderStatusEnum.CREATED.getKey())) { + orderDto.setPayStatus(PayStatusEnum.WAIT.getKey()); + } + if (orderDto.getStatus().equals(OrderStatusEnum.CANCEL.getKey())) { + cancelOrder(orderDto.getId(), "取消订单"); + } else { + mtOrder.setStatus(orderDto.getStatus()); + } + if (orderDto.getStatus().equals(OrderStatusEnum.PAID.getKey())) { + mtOrder.setPayStatus(PayStatusEnum.SUCCESS.getKey()); + mtOrder.setPayTime(new Date()); + } + } + + if (null != orderDto.getPayAmount()) { + mtOrder.setPayAmount(orderDto.getPayAmount()); + } + + if (null != orderDto.getAmount()) { + mtOrder.setAmount(orderDto.getAmount()); + } + + if (StringUtil.isNotBlank(orderDto.getVerifyCode())) { + if (orderDto.getVerifyCode().equals(mtOrder.getVerifyCode()) || StringUtil.isEmpty(mtOrder.getVerifyCode())) { + mtOrder.setStatus(OrderStatusEnum.DELIVERED.getKey()); + mtOrder.setVerifyCode(""); + mtOrder.setConfirmStatus(YesOrNoEnum.YES.getKey()); + mtOrder.setConfirmTime(new Date()); + mtOrder.setConfirmRemark(orderDto.getConfirmRemark()); + mtOrder.setStatus(OrderStatusEnum.COMPLETE.getKey()); + } else { + throw new BusinessCheckException("核销码错误,请确认!"); + } + } + + if (null != orderDto.getDiscount()) { + mtOrder.setDiscount(orderDto.getDiscount()); + } + + if (null != orderDto.getPayTime()) { + mtOrder.setPayTime(orderDto.getPayTime()); + } + + if (null != orderDto.getPayType()) { + mtOrder.setPayType(orderDto.getPayType()); + } + + if (null != orderDto.getPayStatus()) { + mtOrder.setPayStatus(orderDto.getPayStatus()); + } + + if (null != orderDto.getExpressInfo()) { + mtOrder.setExpressInfo(JSONObject.toJSONString(orderDto.getExpressInfo())); + } + + if (null != orderDto.getOrderMode()) { + mtOrder.setOrderMode(orderDto.getOrderMode()); + } + + if (null != orderDto.getRemark()) { + mtOrder.setRemark(orderDto.getRemark()); + } + + mtOrderMapper.updateById(mtOrder); + return mtOrder; + } + + /** + * 更新订单 + * + * @param mtOrder 订单信息 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public MtOrder updateOrder(MtOrder mtOrder) { + mtOrder.setUpdateTime(new Date()); + Integer id = mtOrderMapper.updateById(mtOrder); + if (id > 0) { + mtOrder = mtOrderMapper.selectById(mtOrder.getId()); + } + return mtOrder; + } + + /** + * 把订单置为已支付 + * + * @param orderId 订单ID + * @param payAmount 支付金额 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改订单为已支付") + public Boolean setOrderPayed(Integer orderId, BigDecimal payAmount) throws BusinessCheckException { + MtOrder mtOrder = mtOrderMapper.selectById(orderId); + if (mtOrder == null) { + return false; + } + if (mtOrder.getPayStatus().equals(PayStatusEnum.SUCCESS.getKey())) { + return true; + } + OrderDto reqDto = new OrderDto(); + Date nowDate = new Date(); + reqDto.setId(orderId); + reqDto.setStatus(OrderStatusEnum.PAID.getKey()); + reqDto.setPayStatus(PayStatusEnum.SUCCESS.getKey()); + if (payAmount != null) { + reqDto.setPayAmount(payAmount); + } + if (mtOrder.getPlatform().equals(PlatformTypeEnum.PC.getCode())) { + reqDto.setConfirmStatus(YesOrNoEnum.YES.getKey()); + reqDto.setConfirmTime(nowDate); + } + reqDto.setPayTime(nowDate); + reqDto.setUpdateTime(nowDate); + updateOrder(reqDto); + + // 处理会员升级订单 + if (mtOrder.getType().equals(OrderTypeEnum.MEMBER.getKey())) { + openGiftService.openGift(mtOrder.getUserId(), Integer.parseInt(mtOrder.getParam()), false); + } + + // 处理购物订单 + UserOrderDto orderInfo = getOrderByOrderSn(mtOrder.getOrderSn()); + if (orderInfo.getType().equals(OrderTypeEnum.GOODS.getKey())) { + try { + List goodsList = orderInfo.getGoods(); + if (goodsList != null && goodsList.size() > 0) { + for (OrderGoodsDto goodsDto : goodsList) { + MtGoods mtGoods = goodsService.queryGoodsById(goodsDto.getGoodsId()); + if (mtGoods != null) { + // 购买虚拟卡券商品发放处理 + if (mtGoods.getType().equals(GoodsTypeEnum.COUPON.getKey()) && mtGoods.getCouponIds() != null && StringUtil.isNotEmpty(mtGoods.getCouponIds())) { + String couponIds[] = mtGoods.getCouponIds().split(","); + if (couponIds.length > 0) { + for (int i = 0; i < couponIds.length; i++) { + userCouponService.buyCouponItem(orderInfo.getId(), Integer.parseInt(couponIds[i]), orderInfo.getUserId(), orderInfo.getUserInfo().getMobile(), goodsDto.getNum()); + } + } + } + // 将已销售数量+1 + goodsService.updateInitSale(mtGoods.getId(), goodsDto.getNum()); + } + } + } + } catch (BusinessCheckException e) { + logger.error("会员购买的卡券发送给会员失败......" + e.getMessage()); + } + } + + // 处理消费返积分,查询返1积分所需消费金额 + MtSetting setting = settingService.querySettingByName(mtOrder.getMerchantId(), SettingTypeEnum.POINT.getKey(), PointSettingEnum.POINT_NEED_CONSUME.getKey()); + if (setting != null && !orderInfo.getPayType().equals(PayTypeEnum.BALANCE.getKey()) && orderInfo.getIsVisitor().equals(YesOrNoEnum.NO.getKey())) { + String needPayAmount = setting.getValue(); + Integer needPayAmountInt = Math.round(Integer.parseInt(needPayAmount)); + Double pointNum = 0d; + if (needPayAmountInt > 0 && orderInfo.getPayAmount().compareTo(new BigDecimal(needPayAmountInt)) >= 0) { + BigDecimal point = orderInfo.getPayAmount().divide(new BigDecimal(needPayAmountInt), BigDecimal.ROUND_CEILING, 4); + pointNum = Math.ceil(point.doubleValue()); + } + logger.info("PaymentService paymentCallback Point orderSn = {} , pointNum ={}", orderInfo.getOrderSn(), pointNum); + if (pointNum > 0) { + // 充值是否加倍返积分 + if (orderInfo.getType().equals(OrderTypeEnum.RECHARGE.getKey())) { + MtSetting pointSpeedSetting = settingService.querySettingByName(mtOrder.getMerchantId(), SettingTypeEnum.POINT.getKey(), PointSettingEnum.RECHARGE_POINT_SPEED.getKey()); + if (pointSpeedSetting != null && StringUtil.isNotEmpty(pointSpeedSetting.getValue())) { + BigDecimal pointSpeed = new BigDecimal(pointSpeedSetting.getValue()); + if (pointSpeed.compareTo(new BigDecimal("0")) > 0) { + pointNum = pointNum * new Double(pointSpeedSetting.getValue()); + } + } + } + MtUser userInfo = memberService.queryMemberById(orderInfo.getUserId()); + MtUserGrade userGrade = userGradeService.queryUserGradeById(orderInfo.getMerchantId(), userInfo.getGradeId(), orderInfo.getUserId()); + // 是否会员积分加倍 + if (userGrade != null && userGrade.getSpeedPoint() > 1) { + pointNum = pointNum * userGrade.getSpeedPoint(); + } + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setAmount(pointNum.intValue()); + reqPointDto.setUserId(orderInfo.getUserId()); + reqPointDto.setOrderSn(orderInfo.getOrderSn()); + reqPointDto.setDescription("支付¥"+orderInfo.getPayAmount()+"返"+pointNum+"积分"); + reqPointDto.setOperator("系统"); + pointService.addPoint(reqPointDto); + } + } + + // 计算是否要升级(购物订单、付款订单、充值订单) + if (orderInfo.getIsVisitor().equals(YesOrNoEnum.NO.getKey()) && orderInfo.getType().equals(OrderTypeEnum.GOODS.getKey()) || orderInfo.getType().equals(OrderTypeEnum.PAYMENT.getKey()) || orderInfo.getType().equals(OrderTypeEnum.RECHARGE.getKey())) { + try { + if (orderInfo.getIsVisitor().equals(YesOrNoEnum.NO.getKey())) { + Map param = new HashMap<>(); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + param.put("MERCHANT_ID", mtOrder.getMerchantId()); + MtUser mtUser = memberService.queryMemberById(orderInfo.getUserId()); + MtUserGrade mtUserGrade = mtUserGradeMapper.selectById(mtUser.getGradeId()); + if (mtUserGrade == null) { + mtUserGrade = userGradeService.getInitUserGrade(orderInfo.getMerchantId()); + } + List userGradeList = mtUserGradeMapper.selectByMap(param); + if (mtUserGrade != null && userGradeList != null && userGradeList.size() > 0) { + // 会员已支付金额 + BigDecimal payMoney = getUserPayMoney(orderInfo.getUserId()); + // 会员支付订单笔数 + Integer payOrderCount = getUserPayOrderCount(orderInfo.getUserId()); + BigDecimal payOrderCountValue = new BigDecimal(payOrderCount); + for (MtUserGrade grade : userGradeList) { + if (grade.getCatchValue() != null && grade.getCatchType() != null) { + // 累计消费金额已达到 + if (grade.getCatchType().equals(UserGradeCatchTypeEnum.AMOUNT.getKey())) { + if (grade.getGrade().compareTo(mtUserGrade.getGrade()) > 0 && payMoney.compareTo(grade.getCatchValue()) >= 0) { + openGiftService.openGift(mtOrder.getUserId(), grade.getId(), false); + } + } + // 累计消费次数已达到 + if (grade.getCatchType().equals(UserGradeCatchTypeEnum.FREQUENCY.getKey()) && payOrderCountValue.compareTo(grade.getCatchValue()) >= 0) { + if (grade.getGrade().compareTo(mtUserGrade.getGrade()) > 0) { + openGiftService.openGift(mtOrder.getUserId(), grade.getId(), false); + } + } + } + } + } + } + } catch (Exception ex) { + logger.error("会员升级出错啦,userId = {},message = {}", orderInfo.getUserId(), ex.getMessage()); + } + } + + try { + // 打印订单 + printerService.printOrder(orderInfo, true); + + // 给商家发送通知短信 + MtStore mtStore = storeService.queryStoreById(mtOrder.getStoreId()); + if (mtStore != null && orderInfo.getIsVisitor().equals(YesOrNoEnum.NO.getKey())) { + Map params = new HashMap<>(); + params.put("orderSn", mtOrder.getOrderSn()); + List mobileList = new ArrayList<>(); + mobileList.add(mtStore.getPhone()); + sendSmsService.sendSms(mtOrder.getMerchantId(), "new-order", mobileList, params); + } + } catch (Exception e) { + logger.info("打印订单或给商家发送短信出错啦,message = {}", e.getMessage()); + } + + return true; + } + + /** + * 根据条件搜索订单 + * + * @param params 查询参数 + * @return + * */ + @Override + public List getOrderListByParams(Map params) { + return mtOrderMapper.selectByMap(params); + } + + /** + * 处理订单详情 + * + * @param orderInfo 订单信息 + * @param needAddress 是否获取订单地址 + * @param getPayStatus 是否获取支付状态 + * @return UserOrderDto + * */ + private UserOrderDto getOrderDetail(MtOrder orderInfo, boolean needAddress, boolean getPayStatus) throws BusinessCheckException { + UserOrderDto userOrderDto = new UserOrderDto(); + + userOrderDto.setId(orderInfo.getId()); + userOrderDto.setMerchantId(orderInfo.getMerchantId()); + userOrderDto.setStoreId(orderInfo.getStoreId()); + userOrderDto.setUserId(orderInfo.getUserId()); + userOrderDto.setCouponId(orderInfo.getCouponId()); + userOrderDto.setOrderSn(orderInfo.getOrderSn()); + userOrderDto.setRemark(orderInfo.getRemark()); + userOrderDto.setType(orderInfo.getType()); + userOrderDto.setPayType(orderInfo.getPayType()); + userOrderDto.setOrderMode(orderInfo.getOrderMode()); + userOrderDto.setCreateTime(DateUtil.formatDate(orderInfo.getCreateTime(), "yyyy.MM.dd HH:mm")); + userOrderDto.setUpdateTime(DateUtil.formatDate(orderInfo.getUpdateTime(), "yyyy.MM.dd HH:mm")); + userOrderDto.setAmount(orderInfo.getAmount()); + userOrderDto.setIsVisitor(orderInfo.getIsVisitor()); + userOrderDto.setStaffId(orderInfo.getStaffId()); + userOrderDto.setVerifyCode(""); + userOrderDto.setDeliveryFee(orderInfo.getDeliveryFee()); + userOrderDto.setPlatform(orderInfo.getPlatform()); + userOrderDto.setConfirmRemark(orderInfo.getConfirmRemark()); + userOrderDto.setConfirmStatus(orderInfo.getConfirmStatus()); + if (orderInfo.getConfirmTime() != null) { + userOrderDto.setConfirmTime(DateUtil.formatDate(orderInfo.getConfirmTime(), "yyyy.MM.dd HH:mm")); + } + + if (orderInfo.getType().equals(OrderTypeEnum.GOODS.getKey()) && orderInfo.getPayStatus().equals(PayStatusEnum.SUCCESS.getKey()) && orderInfo.getConfirmStatus().equals(YesOrNoEnum.NO.getKey())) { + userOrderDto.setIsVerify(false); + } else { + userOrderDto.setIsVerify(true); + } + + if (orderInfo.getPayAmount() != null) { + userOrderDto.setPayAmount(orderInfo.getPayAmount()); + } else { + userOrderDto.setPayAmount(new BigDecimal("0")); + } + + if (orderInfo.getDiscount() != null) { + userOrderDto.setDiscount(orderInfo.getDiscount()); + } else { + userOrderDto.setDiscount(new BigDecimal("0")); + } + + if (orderInfo.getPointAmount() != null) { + userOrderDto.setPointAmount(orderInfo.getPointAmount()); + } else { + userOrderDto.setPointAmount(new BigDecimal("0")); + } + + userOrderDto.setStatus(orderInfo.getStatus()); + userOrderDto.setParam(orderInfo.getParam()); + userOrderDto.setPayStatus(orderInfo.getPayStatus()); + + if (orderInfo.getUsePoint() != null) { + userOrderDto.setUsePoint(orderInfo.getUsePoint()); + } else { + userOrderDto.setUsePoint(0); + } + if (orderInfo.getPayTime() != null) { + userOrderDto.setPayTime(DateUtil.formatDate(orderInfo.getPayTime(), "yyyy.MM.dd HH:mm")); + } + + userOrderDto.setTypeName(OrderTypeEnum.getValue(userOrderDto.getType())); + userOrderDto.setStatusText(OrderStatusEnum.getValue(userOrderDto.getStatus())); + + // 订单所属店铺 + MtStore storeInfo = storeService.queryStoreById(orderInfo.getStoreId()); + userOrderDto.setStoreInfo(storeInfo); + + // 所属员工 + if (orderInfo.getStaffId() != null && orderInfo.getStaffId() > 0) { + MtStaff staffInfo = staffService.queryStaffById(orderInfo.getStaffId()); + userOrderDto.setStaffInfo(staffInfo); + } + + // 下单用户信息直接取会员个人信息 + OrderUserDto userInfo = new OrderUserDto(); + MtUser user = memberService.queryMemberById(orderInfo.getUserId()); + if (user != null) { + userInfo.setId(user.getId()); + userInfo.setNo(user.getUserNo()); + userInfo.setName(user.getName()); + if (StringUtil.isNotBlank(user.getMobile())) { + userInfo.setMobile(CommonUtil.hidePhone(user.getMobile())); + } + userInfo.setCardNo(user.getIdcard()); + userInfo.setAddress(user.getAddress()); + userInfo.setOpenId(user.getOpenId()); + userOrderDto.setUserInfo(userInfo); + } + + List goodsList = new ArrayList<>(); + String baseImage = settingService.getUploadBasePath(); + + // 储值卡的订单 + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + MtCoupon coupon = couponService.queryCouponById(orderInfo.getCouponId()); + if (coupon != null) { + String[] paramArr = orderInfo.getParam().split(","); + for (int i = 0; i < paramArr.length; i++) { + String[] item = paramArr[i].split("_"); + if (Integer.parseInt(item[2]) > 0) { + OrderGoodsDto goodsDto = new OrderGoodsDto(); + goodsDto.setId(coupon.getId()); + goodsDto.setType(OrderTypeEnum.PRESTORE.getKey()); + goodsDto.setName("预存¥" + item[0] + "到账¥" + item[1]); + goodsDto.setNum(Double.parseDouble(item[2])); + goodsDto.setPrice(item[0]); + goodsDto.setDiscount("0"); + if (coupon.getImage().indexOf(baseImage) == -1) { + goodsDto.setImage(baseImage + coupon.getImage()); + } + goodsList.add(goodsDto); + } + } + } + } + + // 商品订单 + if (orderInfo.getType().equals(OrderTypeEnum.GOODS.getKey())) { + Map params = new HashMap<>(); + params.put("ORDER_ID", orderInfo.getId()); + List orderGoodsList = mtOrderGoodsMapper.selectByMap(params); + for (MtOrderGoods orderGoods : orderGoodsList) { + MtGoods goodsInfo = mtGoodsMapper.selectById(orderGoods.getGoodsId()); + if (goodsInfo != null) { + OrderGoodsDto orderGoodsDto = new OrderGoodsDto(); + orderGoodsDto.setId(orderGoods.getId()); + orderGoodsDto.setName(goodsInfo.getName()); + if (goodsInfo.getLogo().indexOf(baseImage) == -1) { + orderGoodsDto.setImage(baseImage + goodsInfo.getLogo()); + } + orderGoodsDto.setType(OrderTypeEnum.GOODS.getKey()); + orderGoodsDto.setNum(orderGoods.getNum()); + orderGoodsDto.setSkuId(orderGoods.getSkuId()); + orderGoodsDto.setPrice(orderGoods.getPrice().toString()); + orderGoodsDto.setDiscount(orderGoods.getDiscount().toString()); + orderGoodsDto.setGoodsId(orderGoods.getGoodsId()); + orderGoodsDto.setBookId(goodsInfo.getBookId()); + if (goodsInfo.getBookId() != null && goodsInfo.getBookId() > 0) { + MtBookItem bookItem = bookItemService.getUserBookItem(goodsInfo.getBookId(), orderInfo.getUserId(), orderGoods.getId()); + if (bookItem != null) { + orderGoodsDto.setMyBookId(bookItem.getId()); + } + } + if (orderGoods.getSkuId() > 0) { + List specList = goodsService.getSpecListBySkuId(orderGoods.getSkuId()); + orderGoodsDto.setSpecList(specList); + } + goodsList.add(orderGoodsDto); + } + } + } + + // 配送地址 + if (orderInfo.getOrderMode().equals(OrderModeEnum.EXPRESS.getKey()) && needAddress) { + List orderAddressList = mtOrderAddressMapper.getOrderAddress(orderInfo.getId()); + MtOrderAddress orderAddress = null; + if (orderAddressList.size() > 0) { + orderAddress = orderAddressList.get(0); + } + if (orderAddress != null) { + AddressDto address = new AddressDto(); + address.setId(orderAddress.getId()); + address.setName(orderAddress.getName()); + address.setMobile(orderAddress.getMobile()); + address.setDetail(orderAddress.getDetail()); + address.setProvinceId(orderAddress.getProvinceId()); + address.setCityId(orderAddress.getCityId()); + address.setRegionId(orderAddress.getRegionId()); + + if (orderAddress.getProvinceId() > 0) { + MtRegion mtProvince = mtRegionMapper.selectById(orderAddress.getProvinceId()); + if (mtProvince != null) { + address.setProvinceName(mtProvince.getName()); + } + } + if (orderAddress.getCityId() > 0) { + MtRegion mtCity = mtRegionMapper.selectById(orderAddress.getCityId()); + if (mtCity != null) { + address.setCityName(mtCity.getName()); + } + } + if (orderAddress.getRegionId() > 0) { + MtRegion mtRegion = mtRegionMapper.selectById(orderAddress.getRegionId()); + if (mtRegion != null) { + address.setRegionName(mtRegion.getName()); + } + } + + userOrderDto.setAddress(address); + } + } + + // 物流信息 + if (StringUtil.isNotEmpty(orderInfo.getExpressInfo())) { + JSONObject express = JSONObject.parseObject(orderInfo.getExpressInfo()); + ExpressDto expressInfo = new ExpressDto(); + expressInfo.setExpressNo(express.get("expressNo").toString()); + expressInfo.setExpressCompany(express.get("expressCompany").toString()); + expressInfo.setExpressTime(express.get("expressTime").toString()); + expressInfo.setExpressCode(express.get("expressCode") == null ? "" : express.get("expressCode").toString()); + userOrderDto.setExpressInfo(expressInfo); + } + + // 使用的卡券 + if (userOrderDto.getCouponId() != null && userOrderDto.getCouponId() > 0) { + MtUserCoupon mtUserCoupon = userCouponService.getUserCouponDetail(userOrderDto.getCouponId()); + if (mtUserCoupon != null) { + MtCoupon mtCoupon = couponService.queryCouponById(mtUserCoupon.getCouponId()); + if (mtCoupon != null) { + UserCouponDto couponInfo = new UserCouponDto(); + couponInfo.setId(mtUserCoupon.getId()); + couponInfo.setCouponId(mtCoupon.getId()); + couponInfo.setName(mtCoupon.getName()); + couponInfo.setAmount(mtUserCoupon.getAmount()); + couponInfo.setBalance(mtUserCoupon.getBalance()); + couponInfo.setStatus(mtUserCoupon.getStatus()); + couponInfo.setType(mtCoupon.getType()); + couponInfo.setContent(mtCoupon.getContent()); + userOrderDto.setCouponInfo(couponInfo); + } + } + } + + // 查询支付状态 + if (getPayStatus && !orderInfo.getPayStatus().equals(PayStatusEnum.SUCCESS.getKey())) { + // 微信支付 + if (orderInfo.getPayType().equals(PayTypeEnum.MICROPAY.getKey()) || orderInfo.getPayType().equals(PayTypeEnum.JSAPI.getKey())) { + try { + Map payResult = weixinService.queryPaidOrder(orderInfo.getStoreId(), "", orderInfo.getOrderSn()); + if (payResult != null && payResult.get("trade_state").equals("SUCCESS")) { + BigDecimal payAmount = new BigDecimal(payResult.get("total_fee")).divide(new BigDecimal("100")); + setOrderPayed(orderInfo.getId(), payAmount); + userOrderDto.setPayStatus(PayStatusEnum.SUCCESS.getKey()); + } + } catch (Exception e) { + // empty + } + } + // 支付宝支付 + if (orderInfo.getPayType().equals(PayTypeEnum.ALISCAN.getKey())) { + try { + Map payResult = alipayService.queryPaidOrder(orderInfo.getStoreId(), "", orderInfo.getOrderSn()); + if (payResult != null) { + BigDecimal payAmount = new BigDecimal(payResult.get("payAmount")); + setOrderPayed(orderInfo.getId(), payAmount); + userOrderDto.setPayStatus(PayStatusEnum.SUCCESS.getKey()); + } + } catch (Exception e) { + // empty + } + } + } + userOrderDto.setGoods(goodsList); + return userOrderDto; + } + + /** + * 获取订单总数 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + @Override + public BigDecimal getOrderCount(Integer merchantId, Integer storeId) { + if (storeId != null && storeId > 0) { + return mtOrderMapper.getStoreOrderCount(storeId); + } else { + return mtOrderMapper.getOrderCount(merchantId); + } + } + + /** + * 获取订单数量 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public BigDecimal getOrderCount(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + if (storeId != null && storeId > 0) { + return mtOrderMapper.getStoreOrderCountByTime(storeId, beginTime, endTime); + } else { + return mtOrderMapper.getOrderCountByTime(merchantId, beginTime, endTime); + } + } + + /** + * 获取支付金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public BigDecimal getPayMoney(Integer merchantId, Integer storeId, Date beginTime, Date endTime) { + BigDecimal payMoney; + if (storeId != null && storeId > 0) { + payMoney = mtOrderMapper.getStorePayMoneyByTime(storeId, beginTime, endTime); + } else { + payMoney = mtOrderMapper.getPayMoneyByTime(merchantId, beginTime, endTime); + } + if (payMoney == null) { + return new BigDecimal("0"); + } + return payMoney; + } + + /** + * 获取支付人数 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + @Override + public Integer getPayUserCount(Integer merchantId, Integer storeId) { + if (storeId != null && storeId > 0) { + return mtOrderMapper.getStorePayUserCount(storeId); + } else { + return mtOrderMapper.getPayUserCount(merchantId); + } + } + + /** + * 获取支付总金额 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @return + * */ + @Override + public BigDecimal getPayMoney(Integer merchantId, Integer storeId) { + if (storeId != null && storeId > 0) { + return mtOrderMapper.getStorePayMoney(storeId); + } else { + return mtOrderMapper.getPayMoney(merchantId); + } + } + + /** + * 计算商品总价 + * + * @param merchantId 商户ID + * @param userId 会员ID + * @param cartList 购物车列表 + * @param couponId 卡券ID + * @param isUsePoint 使用积分数量 + * @param orderMode 订单模式 + * @throws BusinessCheckException + * @return + * */ + @Override + public Map calculateCartGoods(Integer merchantId, Integer userId, List cartList, Integer couponId, boolean isUsePoint, String platform, String orderMode) throws BusinessCheckException { + MtUser userInfo = memberService.queryMemberById(userId); + + // 设置是否不能用积分抵扣 + MtSetting pointSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.POINT.getKey(), PointSettingEnum.CAN_USE_AS_MONEY.getKey()); + if (pointSetting != null && !pointSetting.getValue().equals(YesOrNoEnum.TRUE.getKey())) { + isUsePoint = false; + } + + List cartDtoList = new ArrayList<>(); + String basePath = settingService.getUploadBasePath(); + Double totalNum = 0.0; + BigDecimal totalPrice = new BigDecimal("0"); + BigDecimal totalCanUsePointAmount = new BigDecimal("0"); + BigDecimal memberDiscount = new BigDecimal("0"); + BigDecimal percent = new BigDecimal("0"); + Integer storeId = 0; + if (cartList.size() > 0) { + // 会员折扣 + MtUserGrade userGrade = userGradeService.queryUserGradeById(userInfo.getMerchantId(), userInfo.getGradeId() != null ? userInfo.getGradeId() : 1, userId); + if (userGrade != null && userGrade.getDiscount() != null && userGrade.getDiscount() > 0 && !userInfo.getIsStaff().equals(YesOrNoEnum.YES.getKey())) { + percent = new BigDecimal(userGrade.getDiscount()).divide(new BigDecimal("10"), BigDecimal.ROUND_CEILING, 4); + if (percent.compareTo(new BigDecimal("0")) <= 0) { + percent = new BigDecimal("1"); + } + } + for (MtCart cart : cartList) { + if (storeId <= 0 && cart.getStoreId() != null) { + storeId = cart.getStoreId(); + } + // 购物车商品信息 + MtGoods mtGoodsInfo = goodsService.queryGoodsById(cart.getGoodsId()); + if (mtGoodsInfo == null || !mtGoodsInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + continue; + } + // 取对应sku的价格 + if (cart.getSkuId() != null && cart.getSkuId() > 0) { + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(cart.getSkuId()); + if (mtGoodsSku != null && mtGoodsSku.getPrice().compareTo(new BigDecimal("0")) > 0) { + mtGoodsInfo.setPrice(mtGoodsSku.getPrice()); + } + } + // 会员支付折扣 + boolean isDiscount = mtGoodsInfo.getIsMemberDiscount().equals(YesOrNoEnum.YES.getKey()) ? true : false; + if (percent.compareTo(new BigDecimal("0")) > 0 && isDiscount) { + BigDecimal discount = mtGoodsInfo.getPrice().subtract(mtGoodsInfo.getPrice().multiply(percent)).multiply(new BigDecimal(cart.getNum())); + memberDiscount = memberDiscount.add(discount); + } + totalNum = totalNum + cart.getNum(); + ResCartDto cartDto = new ResCartDto(); + cartDto.setId(cart.getId()); + cartDto.setGoodsId(cart.getGoodsId()); + cartDto.setNum(cart.getNum()); + cartDto.setSkuId(cart.getSkuId()); + cartDto.setUserId(cart.getUserId()); + // 购物车是否有效 + Boolean isEffect = true; + if (cart.getSkuId() > 0) { + List specList = goodsService.getSpecListBySkuId(cart.getSkuId()); + cartDto.setSpecList(specList); + } + if (StringUtil.isNotEmpty(mtGoodsInfo.getLogo()) && (mtGoodsInfo.getLogo().indexOf(basePath) == -1)) { + mtGoodsInfo.setLogo(basePath + mtGoodsInfo.getLogo()); + } + // 读取sku的数据 + if (cart.getSkuId() > 0) { + MtGoods mtGoods = new MtGoods(); + BeanUtils.copyProperties(mtGoodsInfo, mtGoods); + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(cart.getSkuId()); + if (mtGoodsSku != null) { + if (StringUtil.isNotEmpty(mtGoodsSku.getLogo()) && (mtGoodsSku.getLogo().indexOf(basePath) == -1)) { + mtGoods.setLogo(basePath + mtGoodsSku.getLogo()); + } + if (mtGoodsSku.getWeight().compareTo(new BigDecimal("0")) > 0) { + mtGoods.setWeight(mtGoodsSku.getWeight()); + } + mtGoods.setPrice(mtGoodsSku.getPrice()); + mtGoods.setLinePrice(mtGoodsSku.getLinePrice()); + mtGoods.setStock(mtGoodsSku.getStock()); + } + cartDto.setGoodsInfo(mtGoods); + } else { + cartDto.setGoodsInfo(mtGoodsInfo); + } + if (mtGoodsInfo.getStock() != null && mtGoodsInfo.getStock() < cartDto.getNum()) { + isEffect = false; + } + cartDto.setIsEffect(isEffect); + // 计算总价 + totalPrice = totalPrice.add(cartDto.getGoodsInfo().getPrice().multiply(new BigDecimal(cart.getNum()))); + // 累加可用积分去抵扣的金额 + if (mtGoodsInfo.getCanUsePoint() != null && mtGoodsInfo.getCanUsePoint().equals(YesOrNoEnum.YES.getKey())) { + totalCanUsePointAmount = totalCanUsePointAmount.add(cartDto.getGoodsInfo().getPrice().multiply(new BigDecimal(cart.getNum()))); + } + cartDtoList.add(cartDto); + } + } + + Map result = new HashMap<>(); + + // 可用卡券列表 + List couponList = new ArrayList<>(); + List statusList = Arrays.asList(UserCouponStatusEnum.UNUSED.getKey()); + List userCouponList = userCouponService.getUserCouponList(userId, statusList); + if (userCouponList.size() > 0) { + for (MtUserCoupon userCoupon : userCouponList) { + MtCoupon couponInfo = couponService.queryCouponById(userCoupon.getCouponId()); + // 优惠券和储值卡才能使用 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey()) || couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + CouponDto couponDto = new CouponDto(); + couponDto.setId(couponInfo.getId()); + couponDto.setUserCouponId(userCoupon.getId()); + couponDto.setName(couponInfo.getName()); + couponDto.setAmount(userCoupon.getAmount()); + couponDto.setStatus(UserCouponStatusEnum.DISABLE.getKey()); + couponDto.setContent(couponInfo.getContent()); + // 购物不能用专用的卡券 + if (couponInfo.getUseFor() != null && StringUtil.isNotEmpty(couponInfo.getUseFor())) { + if (couponInfo.getUseFor().equals(CouponUseForEnum.MEMBER_GRADE.getKey())) { + continue; + } + if (couponInfo.getUseFor().equals(CouponUseForEnum.OFF_LINE_PAYMENT.getKey())) { + // 只有PC收银端能用 + if (!platform.equals(PlatformTypeEnum.PC.getCode())) { + continue; + } + } + } + // 判断在当前门店是否适用 + if (StringUtil.isNotEmpty(couponInfo.getStoreIds())) { + String[] storeIds = couponInfo.getStoreIds().split(","); + if (storeIds.length > 0 && storeId != null && !Arrays.asList(storeIds).contains(storeId.toString())) { + continue; + } + } + boolean isEffective = couponService.isCouponEffective(couponInfo, userCoupon); + // 优惠券 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + couponDto.setType(CouponTypeEnum.COUPON.getValue()); + if (StringUtil.isEmpty(couponInfo.getOutRule()) || couponInfo.getOutRule().equals("0")) { + couponDto.setDescription("无使用门槛"); + if (isEffective) { + couponDto.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + } + } else { + couponDto.setDescription("满" + couponInfo.getOutRule() + "元可用"); + BigDecimal conditionAmount = new BigDecimal(couponInfo.getOutRule()); + if (totalPrice.compareTo(conditionAmount) >= 0 && isEffective) { + couponDto.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + } + } + } else if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + // 储值卡 + couponDto.setType(CouponTypeEnum.PRESTORE.getValue()); + couponDto.setDescription("无使用门槛"); + couponDto.setAmount(userCoupon.getBalance()); + // 余额须大于0 + if (isEffective && (userCoupon.getBalance().compareTo(new BigDecimal("0")) > 0)) { + couponDto.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + } + } + // 适用商品 + if (userCoupon != null) { + if (couponInfo.getApplyGoods() != null && couponInfo.getApplyGoods().equals(ApplyGoodsEnum.PARK_GOODS.getKey())) { + List couponGoodsList = mtCouponGoodsMapper.getCouponGoods(couponInfo.getId()); + if (couponGoodsList != null && couponGoodsList.size() > 0 && cartList.size() > 0) { + List applyGoodsIds = new ArrayList<>(); + List goodsIds = new ArrayList<>(); + for (MtCouponGoods mtCouponGoods : couponGoodsList) { + applyGoodsIds.add(mtCouponGoods.getGoodsId()); + } + for (MtCart mtCart : cartList) { + goodsIds.add(mtCart.getGoodsId()); + } + List intersection = applyGoodsIds.stream() + .filter(goodsIds::contains) + .collect(Collectors.toList()); + if (intersection.size() == 0) { + couponDto.setStatus(UserCouponStatusEnum.DISABLE.getKey()); + } + } + } + } + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + couponDto.setEffectiveDate(DateUtil.formatDate(couponInfo.getBeginTime(), "yyyy.MM.dd HH:mm") + "~" + DateUtil.formatDate(couponInfo.getEndTime(), "yyyy.MM.dd HH:mm")); + } + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + couponDto.setEffectiveDate(DateUtil.formatDate(userCoupon.getCreateTime(), "yyyy.MM.dd HH:mm") + "~" + DateUtil.formatDate(userCoupon.getExpireTime(), "yyyy.MM.dd HH:mm")); + } + if (couponDto.getStatus().equals(UserCouponStatusEnum.UNUSED.getKey())) { + couponList.add(couponDto); + } + } + } + } + + // 使用的卡券 + MtCoupon useCouponInfo = null; + BigDecimal couponAmount = new BigDecimal("0"); + if (couponId > 0) { + MtUserCoupon userCouponInfo = userCouponService.getUserCouponDetail(couponId); + if (userCouponInfo != null) { + useCouponInfo = couponService.queryCouponById(userCouponInfo.getCouponId()); + boolean isEffective = couponService.isCouponEffective(useCouponInfo, userCouponInfo); + if (isEffective) { + if (useCouponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + couponAmount = useCouponInfo.getAmount(); + // 折扣券 + if (useCouponInfo.getContent().equals(CouponContentEnum.PERCENT.getKey())) { + BigDecimal disc = userCouponInfo.getAmount().divide(new BigDecimal("100"), BigDecimal.ROUND_CEILING, 4); + couponAmount = totalPrice.multiply(new BigDecimal(1).subtract(disc)); + } + } else if (useCouponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + BigDecimal couponTotalAmount = userCouponInfo.getBalance(); + if (couponTotalAmount.compareTo(totalPrice) > 0) { + couponAmount = totalPrice; + useCouponInfo.setAmount(totalPrice); + } else { + couponAmount = couponTotalAmount; + useCouponInfo.setAmount(couponTotalAmount); + } + } + } + } + } + + // 支付金额 = 商品总额 - 卡券抵扣金额 + BigDecimal payPrice = totalPrice.subtract(couponAmount); + + // 可用积分、可用积分金额 + Integer myPoint = userInfo.getPoint() == null ? 0 : userInfo.getPoint(); + Integer usePoint = 0; + BigDecimal usePointAmount = new BigDecimal("0"); + MtSetting setting = settingService.querySettingByName(merchantId, SettingTypeEnum.POINT.getKey(), PointSettingEnum.EXCHANGE_NEED_POINT.getKey()); + if (myPoint > 0 && setting != null && isUsePoint) { + if (StringUtil.isNotEmpty(setting.getValue()) && !setting.getValue().equals("0")) { + BigDecimal usePoints = new BigDecimal(myPoint); + usePointAmount = usePoints.divide(new BigDecimal(setting.getValue()), BigDecimal.ROUND_CEILING, 4); + usePoint = myPoint; + if (usePointAmount.compareTo(totalCanUsePointAmount) >= 0) { + usePointAmount = totalCanUsePointAmount; + usePoint = totalCanUsePointAmount.multiply(new BigDecimal(setting.getValue())).intValue(); + } + } + } + + // 积分金额不能大于支付金额 + if (usePointAmount.compareTo(payPrice) > 0 && isUsePoint) { + usePointAmount = payPrice; + BigDecimal usePoints = payPrice.multiply(new BigDecimal(setting.getValue())); + usePoint = usePoints.intValue(); + } + + // 支付金额 = 商品总额 - 积分抵扣金额 + payPrice = payPrice.subtract(usePointAmount); + + // 配送费用 + BigDecimal deliveryFee = new BigDecimal("0"); + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.DELIVERY_FEE.getKey()); + if (mtSetting != null && StringUtil.isNotEmpty(mtSetting.getValue()) && orderMode.equals(OrderModeEnum.EXPRESS.getKey())) { + deliveryFee = new BigDecimal(mtSetting.getValue()); + } + + payPrice = payPrice.add(deliveryFee).subtract(memberDiscount); + BigDecimal discount = totalPrice.subtract(payPrice).divide(new BigDecimal("10"), BigDecimal.ROUND_CEILING, 2); + + if (payPrice.compareTo(new BigDecimal("0")) < 0) { + payPrice = new BigDecimal("0"); + } + + result.put("list", cartDtoList); + result.put("totalNum", totalNum); + result.put("totalPrice", totalPrice); + result.put("payPrice", payPrice); + result.put("couponList", couponList); + result.put("useCouponInfo", useCouponInfo); + result.put("usePoint", usePoint); + result.put("myPoint", myPoint); + result.put("couponAmount", couponAmount); + result.put("usePointAmount", usePointAmount); + result.put("deliveryFee", deliveryFee); + result.put("discount", discount); + if (memberDiscount.compareTo(new BigDecimal("0")) > 0) { + result.put("memberDiscount", (new BigDecimal("10").multiply(percent))); + } else { + result.put("memberDiscount", 0); + } + + return result; + } + + /** + * 获取会员支付金额 + * + * @param userId 会员ID + * @return + * */ + @Override + public BigDecimal getUserPayMoney(Integer userId) { + return mtOrderMapper.getUserPayMoney(userId); + } + + /** + * 获取会员订单数 + * + * @param userId 会员ID + * @return + * */ + @Override + public Integer getUserPayOrderCount(Integer userId) { + return mtOrderMapper.getUserPayOrderCount(userId); + } + + /** + * 获取等待分佣的订单列表 + * + * @param dateTime 时间 + * @return + * */ + @Override + public List getTobeCommissionOrderList(String dateTime) { + return mtOrderMapper.getTobeCommissionOrderList(dateTime); + } + + /** + * 提交充值订单 + * */ + @Override + public MtOrder doRecharge(HttpServletRequest request, RechargeParam rechargeParam) throws BusinessCheckException { + Integer storeId = StringUtil.isEmpty(request.getHeader("storeId")) ? 0 : Integer.parseInt(request.getHeader("storeId")); + String platform = request.getHeader("platform") == null ? "" : request.getHeader("platform"); + String merchantNo = request.getHeader("merchantNo") == null ? "" : request.getHeader("merchantNo"); + + String rechargeAmount = rechargeParam.getRechargeAmount() == null ? "" : rechargeParam.getRechargeAmount(); + String customAmount = rechargeParam.getCustomAmount() == null ? "" : rechargeParam.getCustomAmount(); + if (StringUtil.isEmpty(rechargeAmount) && StringUtil.isEmpty(customAmount)) { + throw new BusinessCheckException("请确认充值金额"); + } + if (rechargeParam.getMemberId() == null || rechargeParam.getMemberId() < 1) { + throw new BusinessCheckException("请确认充值会员信息"); + } + + Integer merchantId = merchantService.getMerchantId(merchantNo); + + // 充值赠送金额 + String ruleParam = ""; + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.BALANCE.getKey(), BalanceSettingEnum.RECHARGE_RULE.getKey()); + if (StringUtil.isNotEmpty(rechargeAmount) && mtSetting != null) { + if (!mtSetting.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("当前未开启充值功能"); + } + if (mtSetting.getValue() != null && StringUtil.isNotEmpty(mtSetting.getValue())) { + String rules[] = mtSetting.getValue().split(","); + for (String rule : rules) { + String amountArr[] = rule.split("_"); + if (amountArr.length >= 2) { + if (amountArr[0].equals(rechargeAmount)) { + ruleParam = rule; + break; + } + } + } + } + } + + // 自定义充值没有赠送金额 + if (StringUtil.isNotEmpty(customAmount) && Integer.parseInt(customAmount) > 0 && (StringUtil.isEmpty(rechargeAmount) || Integer.parseInt(rechargeAmount) <= 0)) { + rechargeAmount = customAmount; + ruleParam = customAmount + "_0"; + } + + if (StringUtil.isEmpty(ruleParam)) { + ruleParam = rechargeAmount + "_0"; + } + + BigDecimal amount = new BigDecimal(rechargeAmount); + if (amount.compareTo(new BigDecimal("0")) <= 0) { + throw new BusinessCheckException("请确认充值金额"); + } + + OrderDto orderDto = new OrderDto(); + orderDto.setType(OrderTypeEnum.RECHARGE.getKey()); + orderDto.setUserId(rechargeParam.getMemberId()); + orderDto.setStoreId(storeId); + orderDto.setAmount(amount); + orderDto.setUsePoint(0); + orderDto.setRemark("会员充值"); + orderDto.setParam(ruleParam); + orderDto.setStatus(OrderStatusEnum.CREATED.getKey()); + orderDto.setPayStatus(PayStatusEnum.WAIT.getKey()); + orderDto.setPointAmount(new BigDecimal("0")); + orderDto.setOrderMode(""); + orderDto.setCouponId(0); + orderDto.setPlatform(platform); + orderDto.setMerchantId(merchantId); + + return saveOrder(orderDto); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/PaymentServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/PaymentServiceImpl.java new file mode 100644 index 0000000..2c49971 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/PaymentServiceImpl.java @@ -0,0 +1,331 @@ +package com.fuint.common.service.impl; + +import com.fuint.common.dto.*; +import com.fuint.common.enums.OrderTypeEnum; +import com.fuint.common.enums.PayTypeEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.TokenUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.MtOrderMapper; +import com.fuint.repository.model.MtBalance; +import com.fuint.repository.model.MtOrder; +import com.fuint.repository.model.MtUser; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 支付相关接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class PaymentServiceImpl implements PaymentService { + + private static final Logger logger = LoggerFactory.getLogger(PaymentServiceImpl.class); + + private MtOrderMapper mtOrderMapper; + + /** + * 微信服务接口 + * */ + private WeixinService weixinService; + + /** + * 支付宝服务接口 + * */ + private AlipayService alipayService; + + /** + * 云闪付服务接口 + * */ + private UnionPayService unionPayService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 余额服务接口 + * */ + private BalanceService balanceService; + + /** + * 会员卡券服务接口 + * */ + private UserCouponService userCouponService; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @param isWechat 是否微信客户端 + * @return + * */ + @Override + public ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform, String isWechat) throws BusinessCheckException { + logger.info("PaymentService createPrepayOrder inParams userInfo={} payAmount={} giveAmount={} goodsInfo={}", userInfo, payAmount, giveAmount, orderInfo); + + ResponseObject responseObject; + if (orderInfo.getPayType().equals(PayTypeEnum.ALISCAN.getKey())) { + // 支付宝支付 + responseObject = alipayService.createPrepayOrder(userInfo, orderInfo, payAmount, authCode, giveAmount, ip, platform); + } else if (orderInfo.getPayType().equals(PayTypeEnum.UNIONPAY.getKey())) { + // 云闪付支付 + responseObject = unionPayService.createPrepayOrder(userInfo, orderInfo, payAmount, authCode, giveAmount, ip, platform); + } else { + // 微信支付 + responseObject = weixinService.createPrepayOrder(userInfo, orderInfo, payAmount, authCode, giveAmount, ip, platform, isWechat); + } + + logger.info("PaymentService createPrepayOrder outParams {}", responseObject.toString()); + return responseObject; + } + + /** + * 支付成功回调 + * + * @param orderInfo 订单信息 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean paymentCallback(UserOrderDto orderInfo) throws BusinessCheckException { + logger.info("paymentCallback outParams {}", orderInfo.toString()); + MtOrder mtOrder = mtOrderMapper.selectById(orderInfo.getId()); + + // 更新订单状态为已支付 + Boolean isPay = orderService.setOrderPayed(orderInfo.getId(), null); + if (mtOrder == null || !isPay) { + return false; + } + + // 储值卡订单 + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + Map param = new HashMap<>(); + param.put("couponId", orderInfo.getCouponId()); + param.put("userId", orderInfo.getUserId()); + param.put("param", orderInfo.getParam()); + param.put("orderId", orderInfo.getId()); + userCouponService.preStore(param); + } + + // 充值订单 + if (orderInfo.getType().equals(OrderTypeEnum.RECHARGE.getKey())) { + // 余额支付 + MtBalance mtBalance = new MtBalance(); + OrderUserDto userDto = orderInfo.getUserInfo(); + if (userDto.getMobile() != null && StringUtil.isNotEmpty(userDto.getMobile())) { + mtBalance.setMobile(userDto.getMobile()); + } + mtBalance.setOrderSn(orderInfo.getOrderSn()); + mtBalance.setUserId(orderInfo.getUserId()); + mtBalance.setMerchantId(orderInfo.getMerchantId()); + String param = orderInfo.getParam(); + if (StringUtil.isNotEmpty(param)) { + String params[] = param.split("_"); + if (params.length >= 2) { + BigDecimal amount = new BigDecimal(params[0]).add(new BigDecimal(params[1])); + mtBalance.setAmount(amount); + balanceService.addBalance(mtBalance, true); + } + // 充值赠送卡券 + if (params.length == 3) { + try { + String[] couponIds = params[2].split("\\|"); + if (couponIds != null && couponIds.length > 0) { + for (int i = 0; i < couponIds.length; i++) { + ResponseObject result = couponService.sendCoupon(Integer.parseInt(couponIds[i]), orderInfo.getUserId(), 1, true, null, null); + if (!result.getCode().equals(200)) { + logger.error("充值赠送卡券失败:", result.getMessage()); + } + } + } + } catch (Exception e) { + logger.error("sendCoupon error", e); + } + } + } + } + + logger.info("PaymentService paymentCallback Success orderSn {}", orderInfo.getOrderSn()); + return true; + } + + /** + * 发起支付 + * + * @param request 请求参数 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Map doPay(HttpServletRequest request) throws BusinessCheckException { + String token = request.getHeader("Access-Token"); + String platform = request.getHeader("platform") == null ? "" : request.getHeader("platform"); + String isWechat = request.getHeader("isWechat") == null ? "" : request.getHeader("isWechat"); + String payType = request.getParameter("payType") == null ? PayTypeEnum.JSAPI.getKey() : request.getParameter("payType"); + String cashierPayAmount = request.getParameter("cashierPayAmount") == null ? "" : request.getParameter("cashierPayAmount"); // 收银台实付金额 + String cashierDiscountAmount = request.getParameter("cashierDiscountAmount") == null ? "" : request.getParameter("cashierDiscountAmount"); // 收银台优惠金额 + UserInfo loginInfo = TokenUtil.getUserInfoByToken(token); + String orderId = request.getParameter("orderId"); + String userId = request.getParameter("userId"); + String authCode = request.getParameter("authCode"); + if (StringUtil.isEmpty(orderId)) { + throw new BusinessCheckException("订单不能为空"); + } + if (orderId.length() >= 12) { + MtOrder mtOrder = orderService.getOrderInfoByOrderSn(orderId); + if (mtOrder != null) { + orderId = mtOrder.getId().toString(); + } + } + MtOrder orderInfo = mtOrderMapper.selectById(Integer.parseInt(orderId)); + if (orderInfo == null) { + throw new BusinessCheckException("该订单不存在"); + } + MtUser mtUser = null; + if (loginInfo != null) { + mtUser = memberService.queryMemberById(loginInfo.getId()); + } + + // 重新生成订单号 + String orderSn = CommonUtil.createOrderSN(orderInfo.getUserId().toString()); + orderInfo.setOrderSn(orderSn); + orderInfo.setPayType(payType); + orderInfo.setPlatform(platform); + orderInfo = orderService.updateOrder(orderInfo); + + // 收银员操作 + AccountInfo accountInfo = TokenUtil.getAccountInfoByToken(token); + if (loginInfo == null && accountInfo != null) { + // 游客订单绑定到会员 + if (orderInfo.getIsVisitor().equals(YesOrNoEnum.YES.getKey()) && StringUtil.isNotEmpty(userId)) { + mtUser = memberService.queryMemberById(Integer.parseInt(userId)); + orderInfo.setUserId(Integer.parseInt(userId)); + orderInfo.setIsVisitor(YesOrNoEnum.NO.getKey()); + orderService.updateOrder(orderInfo); + } else { + mtUser = memberService.queryMemberById(orderInfo.getUserId()); + } + } + + if (mtUser == null) { + throw new BusinessCheckException("登录信息失效"); + } + + if (accountInfo != null && StringUtil.isNotEmpty(cashierPayAmount) && StringUtil.isNotEmpty(cashierDiscountAmount)) { + orderInfo.setDiscount(new BigDecimal(cashierDiscountAmount)); + if (loginInfo == null) { + MtUser user = memberService.queryMemberById(orderInfo.getUserId()); + if (user != null) { + loginInfo = new UserInfo(); + loginInfo.setId(user.getId()); + } + } + } + + // 实付金额 = 总金额 - 优惠金额 - 积分金额 + BigDecimal realPayAmount = orderInfo.getAmount().subtract(new BigDecimal(orderInfo.getDiscount().toString())).subtract(new BigDecimal(orderInfo.getPointAmount().toString())).add(orderInfo.getDeliveryFee()); + Object payment = null; + Boolean isPaying = false; + if (payType.equals(PayTypeEnum.BALANCE.getKey())) { + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey()) || orderInfo.getType().equals(OrderTypeEnum.RECHARGE.getKey())) { + throw new BusinessCheckException("抱歉,不能使用余额支付"); + } + // 余额支付 + MtBalance balance = new MtBalance(); + balance.setMobile(mtUser.getMobile()); + balance.setOrderSn(orderInfo.getOrderSn()); + balance.setStoreId(orderInfo.getStoreId()); + balance.setUserId(mtUser.getId()); + BigDecimal balanceAmount = realPayAmount.subtract(realPayAmount).subtract(realPayAmount); + balance.setAmount(balanceAmount); + boolean isPay = balanceService.addBalance(balance, true); + if (isPay) { + orderService.setOrderPayed(orderInfo.getId(), balanceAmount); + OrderDto reqOrder = new OrderDto(); + reqOrder.setId(orderInfo.getId()); + reqOrder.setPayAmount(realPayAmount); + reqOrder.setDiscount(orderInfo.getDiscount()); + reqOrder.setPayType(PayTypeEnum.BALANCE.getKey()); + if (accountInfo != null) { + reqOrder.setOperator(accountInfo.getAccountName()); + } + orderService.updateOrder(reqOrder); + orderInfo = orderService.getOrderInfo(orderInfo.getId()); + } else { + throw new BusinessCheckException("会员余额不足"); + } + } else if (payType.equals(PayTypeEnum.CASH.getKey()) && accountInfo != null) { + // 现金支付 + OrderDto reqOrder = new OrderDto(); + reqOrder.setId(orderInfo.getId()); + reqOrder.setAmount(new BigDecimal(cashierPayAmount).add(new BigDecimal(cashierDiscountAmount))); + reqOrder.setDiscount(new BigDecimal(cashierDiscountAmount)); + reqOrder.setPayAmount(new BigDecimal(cashierPayAmount)); + reqOrder.setPayTime(new Date()); + reqOrder.setPayType(PayTypeEnum.CASH.getKey()); + reqOrder.setOperator(accountInfo.getAccountName()); + orderService.updateOrder(reqOrder); + orderService.setOrderPayed(orderInfo.getId(), null); + orderInfo = orderService.getOrderInfo(orderInfo.getId()); + } else { + String ip = CommonUtil.getIPFromHttpRequest(request); + BigDecimal pay = realPayAmount.multiply(new BigDecimal("100")); + orderInfo.setPayType(payType); + ResponseObject paymentInfo = createPrepayOrder(mtUser, orderInfo, (pay.intValue()), authCode, 0, ip, platform, isWechat); + if (paymentInfo.getData() == null) { + if (paymentInfo.getCode() == 3000) { + logger.info("需要用户输入密码.."); + isPaying = true; + } else { + throw new BusinessCheckException("抱歉,支付失败"); + } + } + payment = paymentInfo.getData(); + } + + Map result = new HashMap(); + result.put("isCreated", true); + result.put("payType", payType); + result.put("orderInfo", orderInfo); + result.put("payment", payment); + result.put("isPaying", isPaying); + + return result; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/PointServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/PointServiceImpl.java new file mode 100644 index 0000000..e899d55 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/PointServiceImpl.java @@ -0,0 +1,274 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.PointDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.WxMessageEnum; +import com.fuint.common.service.MemberService; +import com.fuint.common.service.PointService; +import com.fuint.common.service.SendSmsService; +import com.fuint.common.service.WeixinService; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtPointMapper; +import com.fuint.repository.mapper.MtUserMapper; +import com.fuint.repository.model.MtPoint; +import com.fuint.repository.model.MtUser; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import com.github.pagehelper.Page; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 积分管理业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class PointServiceImpl extends ServiceImpl implements PointService { + + private static final Logger logger = LoggerFactory.getLogger(PointServiceImpl.class); + + private MtPointMapper mtPointMapper; + + private MtUserMapper mtUserMapper; + + /** + * 短信发送服务接口 + * */ + private SendSmsService sendSmsService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 微信相关服务接口 + * */ + private WeixinService weixinService; + + /** + * 分页查询积分列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryPointListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtPoint::getStatus, StatusEnum.DISABLE.getKey()); + + String description = paginationRequest.getSearchParams().get("description") == null ? "" : paginationRequest.getSearchParams().get("description").toString(); + if (StringUtils.isNotBlank(description)) { + lambdaQueryWrapper.like(MtPoint::getDescription, description); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtPoint::getStatus, status); + } + String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString(); + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.eq(MtPoint::getUserId, userId); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtPoint::getMerchantId, merchantId); + } + String userNo = paginationRequest.getSearchParams().get("userNo") == null ? "" : paginationRequest.getSearchParams().get("userNo").toString(); + if (StringUtil.isNotEmpty(userNo)) { + if (StringUtil.isEmpty(merchantId)) { + merchantId = "0"; + } + MtUser userInfo = memberService.queryMemberByUserNo(Integer.parseInt(merchantId), userNo); + if (userInfo != null) { + lambdaQueryWrapper.eq(MtPoint::getUserId, userInfo.getId()); + } else { + lambdaQueryWrapper.eq(MtPoint::getUserId, -1); + } + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtPoint::getStoreId, storeId); + } + + lambdaQueryWrapper.orderByDesc(MtPoint::getId); + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + List pointList = mtPointMapper.selectList(lambdaQueryWrapper); + + List dataList = new ArrayList<>(); + for (MtPoint point : pointList) { + MtUser userInfo = memberService.queryMemberById(point.getUserId()); + if (userInfo != null) { + userInfo.setMobile(CommonUtil.hidePhone(userInfo.getMobile())); + } + PointDto item = new PointDto(); + BeanUtils.copyProperties(point, item); + item.setUserInfo(userInfo); + dataList.add(item); + } + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, PointDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加积分记录 + * + * @param mtPoint 积分参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改会员积分") + public void addPoint(MtPoint mtPoint) throws BusinessCheckException { + if (mtPoint.getUserId() < 0) { + return; + } + mtPoint.setStatus(StatusEnum.ENABLED.getKey()); + mtPoint.setCreateTime(new Date()); + mtPoint.setUpdateTime(new Date()); + if (mtPoint.getOperator() != null) { + mtPoint.setOperator(mtPoint.getOperator()); + } + + if (mtPoint.getOrderSn() != null) { + mtPoint.setOrderSn(mtPoint.getOrderSn()); + } + + MtUser mtUser = mtUserMapper.selectById(mtPoint.getUserId()); + Integer newAmount = mtUser.getPoint() + mtPoint.getAmount(); + if (newAmount < 0) { + return; + } + mtUser.setPoint(newAmount); + if (mtUser.getStoreId() != null) { + mtPoint.setStoreId(mtUser.getStoreId()); + } + mtPoint.setMerchantId(mtUser.getMerchantId()); + mtUserMapper.updateById(mtUser); + mtPointMapper.insert(mtPoint); + + try { + List mobileList = new ArrayList<>(); + mobileList.add(mtUser.getMobile()); + Map params = new HashMap<>(); + String action = ""; + if (mtPoint.getAmount() > 0) { + action = "+"; + } + params.put("amount", action + mtPoint.getAmount().toString()); + params.put("balance", mtUser.getPoint().toString()); + sendSmsService.sendSms(mtUser.getMerchantId(), "points-change", mobileList, params); + } catch (Exception e) { + logger.error("积分变动短信发送失败:{}", e.getMessage()); + } + + // 发送小程序订阅消息 + Date nowTime = new Date(); + Map params = new HashMap<>(); + String dateTime = DateUtil.formatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm"); + params.put("amount", mtPoint.getAmount()); + params.put("time", dateTime); + params.put("remark", "您的积分发生了变动,请留意~"); + weixinService.sendSubscribeMessage(mtPoint.getMerchantId(), mtPoint.getUserId(), mtUser.getOpenId(), WxMessageEnum.POINT_CHANGE.getKey(), "pages/user/index", params, nowTime); + } + + /** + * 转赠积分 + * + * @param userId 会员ID + * @param mobile 会员手机 + * @param amount 积分数 + * @param remark 备注 + * @throws BusinessCheckException + * @return boolean + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean doGift(Integer userId, String mobile, Integer amount, String remark) throws BusinessCheckException { + if (userId < 0 || StringUtil.isEmpty(mobile) || amount <= 0) { + return false; + } + + MtUser userInfo = memberService.queryMemberById(userId); + MtUser fUserInfo = memberService.queryMemberByMobile(userInfo.getMerchantId(), mobile); + // 自动注册会员 + if (fUserInfo == null) { + fUserInfo = memberService.addMemberByMobile(userInfo.getMerchantId(), mobile, userId.toString(), ""); + } + + if (fUserInfo == null) { + throw new BusinessCheckException("转赠的好友信息不存在"); + } + + if (fUserInfo.getId().equals(userInfo.getId())) { + throw new BusinessCheckException("积分不能转赠给自己"); + } + + Integer newAmount = fUserInfo.getPoint() + amount; + if (newAmount < 0) { + throw new BusinessCheckException("积分赠送失败"); + } + fUserInfo.setPoint(newAmount); + + Integer myNewAmount = userInfo.getPoint() - amount; + if (myNewAmount < 0) { + throw new BusinessCheckException("您的积分不足"); + } + userInfo.setPoint(myNewAmount); + + mtUserMapper.updateById(fUserInfo); + mtUserMapper.updateById(userInfo); + + MtPoint fMtPoint = new MtPoint(); + fMtPoint.setStatus(StatusEnum.ENABLED.getKey()); + fMtPoint.setAmount(amount); + fMtPoint.setCreateTime(new Date()); + fMtPoint.setUpdateTime(new Date()); + fMtPoint.setOperator(userInfo.getName()); + fMtPoint.setOrderSn(""); + fMtPoint.setDescription(remark); + fMtPoint.setUserId(fUserInfo.getId()); + fMtPoint.setMerchantId(fUserInfo.getMerchantId()); + mtPointMapper.insert(fMtPoint); + + MtPoint mtPoint = new MtPoint(); + mtPoint.setUserId(userId); + mtPoint.setAmount(-amount); + mtPoint.setStatus(StatusEnum.ENABLED.getKey()); + mtPoint.setCreateTime(new Date()); + mtPoint.setUpdateTime(new Date()); + mtPoint.setOperator(userInfo.getName()); + mtPoint.setOrderSn(""); + mtPoint.setDescription("转赠好友"); + mtPoint.setMerchantId(userInfo.getMerchantId()); + mtPointMapper.insert(mtPoint); + + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/PrinterServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/PrinterServiceImpl.java new file mode 100644 index 0000000..047c672 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/PrinterServiceImpl.java @@ -0,0 +1,419 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.GoodsSpecValueDto; +import com.fuint.common.dto.OrderGoodsDto; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.PrinterPage; +import com.fuint.common.service.SettingService; +import com.fuint.common.util.HashSignUtil; +import com.fuint.common.util.NoteFormatter; +import com.fuint.common.util.PrinterUtil; +import com.fuint.common.vo.printer.*; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.model.MtPrinter; +import com.fuint.common.service.PrinterService; +import com.fuint.repository.mapper.MtPrinterMapper; +import com.fuint.repository.model.MtSetting; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.github.pagehelper.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 打印机服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class PrinterServiceImpl extends ServiceImpl implements PrinterService { + + private static final Logger logger = LoggerFactory.getLogger(PrinterServiceImpl.class); + + private MtPrinterMapper mtPrinterMapper; + + /** + * 系统配置服务接口 + * */ + private SettingService settingService; + + /** + * 环境变量 + * */ + private Environment env; + + /** + * 分页查询数据列表 + * + * @param printerPage + * @return + */ + @Override + public PaginationResponse queryPrinterListByPagination(PrinterPage printerPage) { + Page pageHelper = PageHelper.startPage(printerPage.getPage(), printerPage.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtPrinter::getStatus, StatusEnum.DISABLE.getKey()); + + String status = printerPage.getStatus(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtPrinter::getStatus, status); + } + Integer merchantId = printerPage.getMerchantId(); + if (merchantId != null && merchantId > 0) { + lambdaQueryWrapper.eq(MtPrinter::getMerchantId, merchantId); + } + Integer storeId = printerPage.getStoreId(); + if (storeId != null && storeId > 0) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtPrinter::getStoreId, 0) + .or() + .eq(MtPrinter::getStoreId, storeId)); + } + String sn = printerPage.getSn(); + if (StringUtils.isNotBlank(sn)) { + lambdaQueryWrapper.eq(MtPrinter::getSn, sn); + } + String name = printerPage.getName(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtPrinter::getName, name); + } + String autoPrint = printerPage.getAutoPrint(); + if (StringUtils.isNotBlank(autoPrint)) { + lambdaQueryWrapper.eq(MtPrinter::getAutoPrint, autoPrint); + } + + lambdaQueryWrapper.orderByAsc(MtPrinter::getId); + List dataList = mtPrinterMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(printerPage.getPage(), printerPage.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtPrinter.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加打印机 + * + * @param mtPrinter 打印机信息 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增打印机") + public MtPrinter addPrinter(MtPrinter mtPrinter) throws BusinessCheckException { + mtPrinter.setStatus(StatusEnum.ENABLED.getKey()); + mtPrinter.setUpdateTime(new Date()); + mtPrinter.setCreateTime(new Date()); + if (mtPrinter.getMerchantId() == null || mtPrinter.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + + Integer printerId = mtPrinterMapper.insert(mtPrinter); + if (printerId > 0) { + // 添加云打印机 + if (mtPrinter.getSn() != null && mtPrinter.getName() != null) { + AddPrinterRequest restRequest = new AddPrinterRequest(); + createRequestHeader(mtPrinter.getMerchantId(), restRequest); + AddPrinterRequestItem item = new AddPrinterRequestItem(); + item.setName(mtPrinter.getName()); + item.setSn(mtPrinter.getSn()); + AddPrinterRequestItem[] items = { item }; + restRequest.setItems(items); + PrinterUtil.addPrinters(restRequest); + } + return mtPrinter; + } else { + logger.error("新增打印机数据失败."); + throw new BusinessCheckException("新增打印机数据失败"); + } + } + + /** + * 打印订单 + * + * @param orderInfo 订单信息 + * @param autoPrint 自动打印 + * @return + * */ + @Override + public Boolean printOrder(UserOrderDto orderInfo, boolean autoPrint) throws Exception { + PrintRequest printRequest = new PrintRequest(); + createRequestHeader(orderInfo.getMerchantId(), printRequest); + if (orderInfo.getStoreInfo() == null) { + throw new BusinessCheckException("打印失败:订单所属店铺信息为空!"); + } + + // 获取打印机列表 + Map params = new HashMap<>(); + params.put("storeId", orderInfo.getStoreInfo().getId()); + params.put("status", StatusEnum.ENABLED.getKey()); + if (autoPrint) { + params.put("autoPrint", YesOrNoEnum.YES.getKey()); + } + List printers = queryPrinterListByParams(params); + if (printers == null || printers.size() < 1) { + throw new BusinessCheckException("打印失败:该店铺还没有添加云打印机!"); + } + + MtStore storeInfo = orderInfo.getStoreInfo(); + for (MtPrinter mtPrinter : printers) { + printRequest.setSn(mtPrinter.getSn()); + + StringBuilder printContent = new StringBuilder(); + printContent.append("").append("" + storeInfo.getName() + "").append("
"); + printContent.append("
"); + + // 分割线 + printContent.append(org.apache.commons.lang3.StringUtils.repeat("-", 32)).append("
"); + + // 订单号 + printContent.append("订单号:").append(orderInfo.getOrderSn()).append(""); + + // 分割线 + printContent.append(org.apache.commons.lang3.StringUtils.repeat("-", 32)).append("
"); + + printContent.append("品名").append(org.apache.commons.lang3.StringUtils.repeat(" ", 16)) + .append("数量").append(org.apache.commons.lang3.StringUtils.repeat(" ", 2)) + .append("单价").append(org.apache.commons.lang3.StringUtils.repeat(" ", 2)) + .append("
"); + + // 分割线 + printContent.append(org.apache.commons.lang3.StringUtils.repeat("-", 32)).append("
"); + + // 商品列表 + if (orderInfo.getGoods() != null && orderInfo.getGoods().size() > 0) { + for (OrderGoodsDto goodsDto : orderInfo.getGoods()) { + List specList = goodsDto.getSpecList(); + String name = goodsDto.getName(); + List specValue = new ArrayList<>(); + if (specList != null && specList.size() > 0) { + for (GoodsSpecValueDto spec : specList) { + if (StringUtil.isNotEmpty(spec.getSpecValue())) { + specValue.add(spec.getSpecValue()); + } + } + if (specValue.size() > 0) { + name = name + "(" + String.join(",", specValue) + ")"; + } + } + printContent.append(NoteFormatter.formatPrintOrderItemForNewLine80(name, goodsDto.getNum(), Double.parseDouble(goodsDto.getPrice()))); + } + } + + // 配送订单,打印配送信息 + if (orderInfo.getOrderMode().equals(OrderModeEnum.EXPRESS.getKey())) { + // 分割线 + printContent.append(org.apache.commons.lang3.StringUtils.repeat("-", 32)).append("
"); + printContent.append("") + .append("配送姓名:").append(orderInfo.getAddress().getName()).append("
") + .append("联系电话:").append(orderInfo.getAddress().getMobile()).append("
") + .append("详细地址:").append(orderInfo.getAddress().getProvinceName() + orderInfo.getAddress().getCityName() + orderInfo.getAddress().getRegionName() + orderInfo.getAddress().getDetail()).append("
"); + } + + // 分割线 + printContent.append(org.apache.commons.lang3.StringUtils.repeat("-", 32)).append("
"); + + printContent.append("").append("合计:").append(orderInfo.getPayAmount()).append("元").append("
"); + + printContent.append("
"); + printContent.append("") + .append("店铺地址:").append((orderInfo.getStoreInfo().getAddress() == null) ? "无" : orderInfo.getStoreInfo().getAddress()).append("
") + .append("联系电话:").append((orderInfo.getStoreInfo().getPhone() == null) ? "无" : orderInfo.getStoreInfo().getPhone()).append("
") + .append("下单时间:").append(orderInfo.getCreateTime()).append("
") + .append("订单备注:").append(StringUtil.isEmpty(orderInfo.getRemark()) ? "无" : orderInfo.getRemark()).append("
"); + + // 网站二维码 + String webSite = env.getProperty("website.url"); + if (StringUtil.isNotEmpty(webSite)) { + printContent.append("").append("" + webSite + "").append(""); + } + + printRequest.setContent(printContent.toString()); + printRequest.setCopies(1); + printRequest.setVoice(2); + printRequest.setMode(0); + ObjectRestResponse result = PrinterUtil.print(printRequest); + if (result != null && result.getCode() != 0) { + throw new BusinessCheckException("打印失败:" + result.getMsg()); + } + } + + return true; + } + + /** + * 根据ID获打印机取息 + * + * @param id 打印机ID + * @return + */ + @Override + public MtPrinter queryPrinterById(Integer id) { + return mtPrinterMapper.selectById(id); + } + + /** + * 根据ID删除打印机 + * + * @param id 打印机ID + * @param operator 操作人 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除打印机") + public void deletePrinter(Integer id, String operator) throws BusinessCheckException { + MtPrinter mtPrinter = queryPrinterById(id); + if (null == mtPrinter) { + return; + } + // 删除云打印机 + if (StringUtil.isNotEmpty(mtPrinter.getSn())) { + DelPrinterRequest restRequest = new DelPrinterRequest(); + createRequestHeader(mtPrinter.getMerchantId(), restRequest); + String[] snList = { mtPrinter.getSn() }; + restRequest.setSnlist(snList); + PrinterUtil.delPrinters(restRequest); + } + mtPrinter.setStatus(StatusEnum.DISABLE.getKey()); + mtPrinter.setUpdateTime(new Date()); + mtPrinterMapper.updateById(mtPrinter); + } + + /** + * 修改打印机数据 + * + * @param mtPrinter 打印机参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新打印机") + public MtPrinter updatePrinter(MtPrinter mtPrinter) throws BusinessCheckException { + MtPrinter printer = queryPrinterById(mtPrinter.getId()); + BeanUtils.copyProperties(mtPrinter, printer); + if (mtPrinter == null) { + throw new BusinessCheckException("该打印机状态异常"); + } + if (printer.getMerchantId() == null || printer.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + + if (mtPrinter.getSn() != null && mtPrinter.getName() != null && !mtPrinter.getStatus().equals(StatusEnum.DISABLE.getKey())) { + UpdPrinterRequest restRequest = new UpdPrinterRequest(); + createRequestHeader(mtPrinter.getMerchantId(), restRequest); + restRequest.setName(mtPrinter.getName()); + restRequest.setSn(mtPrinter.getSn()); + PrinterUtil.updPrinter(restRequest); + } + if (mtPrinter.getStatus().equals(StatusEnum.DISABLE.getKey())) { + deletePrinter(mtPrinter.getId(), mtPrinter.getOperator()); + } + + mtPrinter.setUpdateTime(new Date()); + mtPrinterMapper.updateById(printer); + return printer; + } + + /** + * 根据条件搜索打印机 + * + * @param params 查询参数 + * @throws BusinessCheckException + * @return + * */ + @Override + public List queryPrinterListByParams(Map params) { + String status = params.get("status") == null ? StatusEnum.ENABLED.getKey(): params.get("status").toString(); + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + String sn = params.get("sn") == null ? "" : params.get("sn").toString(); + String name = params.get("name") == null ? "" : params.get("name").toString(); + String autoPrint = params.get("autoPrint") == null ? "" : params.get("autoPrint").toString(); + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtPrinter::getStatus, StatusEnum.DISABLE.getKey()); + + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtPrinter::getStatus, status); + } + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtPrinter::getMerchantId, merchantId); + } + if (StringUtils.isNotBlank(sn)) { + lambdaQueryWrapper.eq(MtPrinter::getSn, sn); + } + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.eq(MtPrinter::getName, name); + } + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtPrinter::getStoreId, 0) + .or() + .eq(MtPrinter::getStoreId, storeId)); + } + if (StringUtils.isNotBlank(autoPrint)) { + lambdaQueryWrapper.eq(MtPrinter::getAutoPrint, autoPrint); + } + lambdaQueryWrapper.orderByAsc(MtPrinter::getId); + + return mtPrinterMapper.selectList(lambdaQueryWrapper); + } + + /** + * 创建接口请求header + * + * @param merchantId 商户ID + * @param request RestRequest + * @return + * */ + public void createRequestHeader(Integer merchantId, RestRequest request) throws BusinessCheckException { + List settings = settingService.getSettingList(merchantId, SettingTypeEnum.PRINTER.getKey()); + if (settings != null && settings.size() > 0) { + String userName = ""; + String userKey = ""; + for (MtSetting mtSetting : settings) { + if (mtSetting.getName().equals(PrinterSettingEnum.USER_NAME.getKey())) { + userName = mtSetting.getValue(); + } + if (mtSetting.getName().equals(PrinterSettingEnum.USER_KEY.getKey())) { + userKey = mtSetting.getValue(); + } + } + if (StringUtil.isNotEmpty(userName) && StringUtil.isNotEmpty(userKey)) { + request.setUser(userName); + request.setTimestamp(System.currentTimeMillis() + ""); + request.setSign(HashSignUtil.sign(request.getUser() + userKey + request.getTimestamp())); + request.setDebug("0"); + } else { + throw new BusinessCheckException("请先设置芯烨云打印账号!"); + } + } else { + throw new BusinessCheckException("请先设置芯烨云打印账号!"); + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/RefundServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/RefundServiceImpl.java new file mode 100644 index 0000000..2dc82fb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/RefundServiceImpl.java @@ -0,0 +1,666 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.dto.*; +import com.fuint.common.enums.*; +import com.fuint.common.service.*; +import com.fuint.common.util.DateUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.*; + +/** + * 售后接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class RefundServiceImpl extends ServiceImpl implements RefundService { + + private static final Logger logger = LoggerFactory.getLogger(RefundServiceImpl.class); + + private MtPointMapper mtPointMapper; + + private MtRefundMapper mtRefundMapper; + + private MtConfirmLogMapper mtConfirmLogMapper; + + private MtUserCouponMapper mtUserCouponMapper; + + private MtGoodsSkuMapper mtGoodsSkuMapper; + + private MtGoodsMapper mtGoodsMapper; + + private MtOrderGoodsMapper mtOrderGoodsMapper; + + /** + * 卡券接口 + * */ + private CouponService couponService; + + /** + * 积分相关接口 + * */ + private PointService pointService; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 余额服务接口 + * */ + private BalanceService balanceService; + + /** + * 微信服务接口 + * */ + private WeixinService weixinService; + + /** + * 支付宝服务接口 + * */ + private AlipayService alipayService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 分页查询售后订单列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse getRefundListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtRefund::getStatus, StatusEnum.DISABLE.getKey()); + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtRefund::getMerchantId, merchantId); + } + String remark = paginationRequest.getSearchParams().get("remark") == null ? "" : paginationRequest.getSearchParams().get("remark").toString(); + if (StringUtils.isNotBlank(remark)) { + lambdaQueryWrapper.like(MtRefund::getRemark, remark); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtRefund::getStatus, status); + } + String orderId = paginationRequest.getSearchParams().get("orderId") == null ? "" : paginationRequest.getSearchParams().get("orderId").toString(); + if (StringUtils.isNotBlank(orderId)) { + lambdaQueryWrapper.eq(MtRefund::getOrderId, orderId); + } + String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString(); + if (StringUtils.isNotBlank(userId) && Integer.parseInt(userId) > 0) { + lambdaQueryWrapper.eq(MtRefund::getUserId, userId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtRefund::getStoreId, storeId); + } + String startTime = paginationRequest.getSearchParams().get("startTime") == null ? "" : paginationRequest.getSearchParams().get("startTime").toString(); + String endTime = paginationRequest.getSearchParams().get("endTime") == null ? "" : paginationRequest.getSearchParams().get("endTime").toString(); + if (StringUtil.isNotEmpty(startTime)) { + lambdaQueryWrapper.ge(MtRefund::getCreateTime, startTime); + } + if (StringUtil.isNotEmpty(endTime)) { + lambdaQueryWrapper.le(MtRefund::getCreateTime, endTime); + } + lambdaQueryWrapper.orderByDesc(MtRefund::getId); + List refundList = mtRefundMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + if (refundList != null && refundList.size() > 0) { + for (MtRefund mtRefund : refundList) { + RefundDto refundDto = new RefundDto(); + BeanUtils.copyProperties(mtRefund, refundDto); + refundDto.setCreateTime(DateUtil.formatDate(mtRefund.getCreateTime(), "yyyy-MM-dd HH:mm")); + refundDto.setUpdateTime(DateUtil.formatDate(mtRefund.getCreateTime(), "yyyy-MM-dd HH:mm")); + if (refundDto.getStoreId() != null && refundDto.getStoreId() > 0) { + MtStore mtStore = storeService.queryStoreById(refundDto.getStoreId()); + refundDto.setStoreInfo(mtStore); + } + if (refundDto.getOrderId() != null && refundDto.getOrderId() > 0) { + UserOrderDto orderDto = orderService.getOrderById(refundDto.getOrderId()); + refundDto.setOrderInfo(orderDto); + } + dataList.add(refundDto); + } + } + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, RefundDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 获取用户售后订单列表 + * + * @param paramMap 查询参数 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject getUserRefundList(Map paramMap) throws BusinessCheckException { + Integer pageNumber = paramMap.get("pageNumber") == null ? Constants.PAGE_NUMBER : Integer.parseInt(paramMap.get("pageNumber").toString()); + Integer pageSize = paramMap.get("pageSize") == null ? Constants.PAGE_SIZE : Integer.parseInt(paramMap.get("pageSize").toString()); + String userId = paramMap.get("userId") == null ? "0" : paramMap.get("userId").toString(); + String status = paramMap.get("status") == null ? "": paramMap.get("status").toString(); + + Page pageHelper = PageHelper.startPage(pageNumber, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.like(MtRefund::getUserId, userId); + } + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtRefund::getStatus, status); + } + + lambdaQueryWrapper.orderByDesc(MtRefund::getId); + List refundList = mtRefundMapper.selectList(lambdaQueryWrapper); + + List dataList = new ArrayList<>(); + if (refundList != null && refundList.size() > 0) { + for (MtRefund mtRefund : refundList) { + RefundDto refundDto = new RefundDto(); + BeanUtils.copyProperties(mtRefund, refundDto); + UserOrderDto orderDto = orderService.getOrderById(mtRefund.getOrderId()); + if (mtRefund.getImages() != null && StringUtil.isNotEmpty(mtRefund.getImages())) { + List images = Arrays.asList(mtRefund.getImages().split(",").clone()); + refundDto.setImageList(images); + } + refundDto.setOrderInfo(orderDto); + refundDto.setCreateTime(DateUtil.formatDate(mtRefund.getCreateTime(), "yyyy.MM.dd HH:mm")); + refundDto.setUpdateTime(DateUtil.formatDate(mtRefund.getUpdateTime(), "yyyy.MM.dd HH:mm")); + + if (mtRefund.getStatus().equals(RefundStatusEnum.CREATED.getKey())) { + refundDto.setStatusText(RefundStatusEnum.CREATED.getValue()); + } + if (mtRefund.getStatus().equals(RefundStatusEnum.APPROVED.getKey())) { + refundDto.setStatusText(RefundStatusEnum.APPROVED.getValue()); + } + if (mtRefund.getStatus().equals(RefundStatusEnum.REJECT.getKey())) { + refundDto.setStatusText(RefundStatusEnum.REJECT.getValue()); + } + if (mtRefund.getStatus().equals(RefundStatusEnum.CANCEL.getKey())) { + refundDto.setStatusText(RefundStatusEnum.CANCEL.getValue()); + } + if (mtRefund.getStatus().equals(RefundStatusEnum.COMPLETE.getKey())) { + refundDto.setStatusText(RefundStatusEnum.COMPLETE.getValue()); + } + dataList.add(refundDto); + } + } + + PageRequest pageRequest = PageRequest.of(pageNumber, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, RefundDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return new ResponseObject(200, "查询成功", paginationResponse); + } + + /** + * 创建售后订单 + * + * @param refundDto 订单参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "提交售后订单") + public MtRefund createRefund(RefundDto refundDto) { + MtRefund refund = new MtRefund(); + if (refundDto.getId() != null) { + refund.setId(refund.getId()); + } + refund.setMerchantId(refundDto.getMerchantId()); + refund.setStoreId(refundDto.getStoreId()); + + // 检查是否已存在 + Map params = new HashMap<>(); + params.put("USER_ID", refundDto.getUserId().toString()); + params.put("ORDER_ID", refundDto.getOrderId().toString()); + List result = mtRefundMapper.selectByMap(params); + + if (result.size() > 0) { + refund = result.get(0); + refund.setUpdateTime(new Date()); + if (refundDto.getRemark() != null && StringUtil.isNotEmpty(refundDto.getRemark())) { + refund.setRemark(refund.getRemark() + "|" + refundDto.getRemark()); + } + mtRefundMapper.updateById(refund); + return refund; + } + + refund.setOrderId(refundDto.getOrderId()); + refund.setUserId(refundDto.getUserId()); + refund.setRemark(refundDto.getRemark()); + refund.setType(refundDto.getType()); + refund.setMerchantId(refundDto.getMerchantId()); + refund.setStoreId(refundDto.getStoreId()); + refund.setAmount(refundDto.getAmount()); + if (refundDto.getImages() != null && StringUtil.isNotEmpty(refundDto.getImages()) && refundDto.getImages().length() > 5) { + refund.setImages(String.join(",", refundDto.getImages())); + } + refund.setStatus(RefundStatusEnum.CREATED.getKey()); + refund.setUpdateTime(new Date()); + refund.setCreateTime(new Date()); + + mtRefundMapper.insert(refund); + return refund; + } + + /** + * 根据ID获取订单详情 + * + * @param id 售后订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public RefundDto getRefundById(Integer id) throws BusinessCheckException { + MtRefund mtRefund = mtRefundMapper.selectById(id); + if (mtRefund != null) { + RefundDto refundDto = new RefundDto(); + BeanUtils.copyProperties(mtRefund, refundDto); + UserOrderDto orderDto = orderService.getOrderById(mtRefund.getOrderId()); + if (mtRefund.getImages() != null && StringUtil.isNotEmpty(mtRefund.getImages())) { + List images = Arrays.asList(mtRefund.getImages().split(",").clone()); + refundDto.setImageList(images); + } + refundDto.setOrderInfo(orderDto); + // 退货地址 + AddressDto address = new AddressDto(); + if (orderDto.getStoreInfo() != null) { + address.setMobile(orderDto.getStoreInfo().getPhone()); + address.setName(orderDto.getStoreInfo().getContact()); + address.setDetail(orderDto.getStoreInfo().getAddress()); + } + refundDto.setAddress(address); + return refundDto; + } + return null; + } + + /** + * 根据订单ID获取售后订单信息 + * + * @param orderId 订单ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtRefund getRefundByOrderId(Integer orderId) { + Map params = new HashMap<>(); + params.put("ORDER_ID", orderId.toString()); + List refunds = mtRefundMapper.selectByMap(params); + if (refunds != null && refunds.size() > 0) { + return refunds.get(0); + } + return null; + } + + /** + * 修改售后订单 + * + * @param refundDto + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "更新售后订单") + public MtRefund updateRefund(RefundDto refundDto) throws BusinessCheckException { + MtRefund mtRefund = mtRefundMapper.selectById(refundDto.getId()); + if (mtRefund == null) { + throw new BusinessCheckException("该售后订单状态异常"); + } + + // 已同意的不能再设置为已拒绝 + if ((refundDto.getStatus() != null) && (!refundDto.getStatus().equals(RefundStatusEnum.COMPLETE.getKey())) && (mtRefund.getStatus().equals(RefundStatusEnum.COMPLETE.getKey()))) { + throw new BusinessCheckException("该售后订单已完成,不能再改成其他状态"); + } + + mtRefund.setId(refundDto.getId()); + mtRefund.setUpdateTime(new Date()); + + if (null != refundDto.getOperator()) { + mtRefund.setOperator(refundDto.getOperator()); + } + if (null != refundDto.getStatus()) { + mtRefund.setStatus(refundDto.getStatus()); + } + if (null != refundDto.getRemark()) { + mtRefund.setRemark(refundDto.getRemark()); + } + if (null != refundDto.getExpressName()) { + mtRefund.setExpressName(refundDto.getExpressName()); + } + if (null != refundDto.getExpressNo()) { + mtRefund.setExpressNo(refundDto.getExpressNo()); + } + if (null != refundDto.getRejectReason()) { + mtRefund.setRejectReason(refundDto.getRejectReason()); + } + + mtRefundMapper.updateById(mtRefund); + return mtRefund; + } + + /** + * 同意售后订单 + * + * @param refundDto + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "同意售后订单") + public MtRefund agreeRefund(RefundDto refundDto) throws BusinessCheckException { + MtRefund refund = mtRefundMapper.selectById(refundDto.getId()); + if (null == refund) { + throw new BusinessCheckException("该售后订单状态异常"); + } + + // 已经同意过了 + if (refund.getStatus().equals(RefundStatusEnum.COMPLETE.getKey())) { + if (StringUtil.isNotEmpty(refundDto.getRemark())) { + refund.setRemark(refundDto.getRemark()); + } + mtRefundMapper.updateById(refund); + return refund; + } + + refund.setId(refundDto.getId()); + refund.setUpdateTime(new Date()); + + if (null != refundDto.getOperator()) { + refund.setOperator(refundDto.getOperator()); + } + + if (null != refundDto.getStatus()) { + refund.setStatus(refundDto.getStatus()); + } + + mtRefundMapper.updateById(refund); + MtRefund mtRefund = mtRefundMapper.selectById(refund.getId()); + UserOrderDto orderInfo = orderService.getOrderById(mtRefund.getOrderId()); + + if (mtRefund.getAmount().compareTo(orderInfo.getAmount()) > 0) { + throw new BusinessCheckException("退款金额不能大于订单总金额"); + } + + OrderDto reqDto = new OrderDto(); + reqDto.setId(orderInfo.getId()); + reqDto.setStatus(OrderStatusEnum.REFUND.getKey()); + orderService.updateOrder(reqDto); + + // 换货 + if (refund.getType().equals(RefundTypeEnum.EXCHANGE.getKey())) { + return refund; + } + + // 如果是余额支付,返还余额 + if (orderInfo.getPayType().equals(PayTypeEnum.BALANCE.getKey())) { + List balanceList = balanceService.getBalanceListByOrderSn(orderInfo.getOrderSn()); + if (balanceList.size() > 0) { + BigDecimal refundAmount = new BigDecimal("0"); + for (MtBalance mtBalance : balanceList) { + if (mtBalance.getAmount().compareTo(new BigDecimal("0")) < 0) { + refundAmount = refundAmount.add(mtBalance.getAmount()); + } + } + MtBalance balanceReq = new MtBalance(); + balanceReq.setUserId(orderInfo.getUserId()); + balanceReq.setMerchantId(orderInfo.getMerchantId()); + balanceReq.setStoreId(orderInfo.getStoreId()); + balanceReq.setOrderSn(orderInfo.getOrderSn()); + balanceReq.setMobile(orderInfo.getUserInfo().getMobile()); + balanceReq.setOrderSn(orderInfo.getOrderSn()); + if (mtRefund.getAmount() != null && mtRefund.getAmount().compareTo(new BigDecimal("0")) > 0) { + balanceReq.setAmount(mtRefund.getAmount()); + } else { + balanceReq.setAmount(refundAmount.negate()); + } + balanceService.addBalance(balanceReq, true); + } + } + + // 充值订单退款 + if (orderInfo.getType().equals(OrderTypeEnum.RECHARGE.getKey())) { + String param = orderInfo.getParam(); + MtBalance mtBalance = new MtBalance(); + mtBalance.setMerchantId(orderInfo.getMerchantId()); + mtBalance.setUserId(orderInfo.getUserId()); + mtBalance.setStoreId(orderInfo.getStoreId()); + mtBalance.setMobile(orderInfo.getUserInfo().getMobile()); + mtBalance.setOrderSn(orderInfo.getOrderSn()); + mtBalance.setCreateTime(new Date()); + mtBalance.setUpdateTime(new Date()); + BigDecimal amount = new BigDecimal("0"); + if (StringUtil.isNotEmpty(param)) { + String params[] = param.split("_"); + if (params.length == 2) { + amount = new BigDecimal(params[0]).add(new BigDecimal(params[1])); + } + } else { + amount = orderInfo.getPayAmount(); + } + MtUser mtUser = memberService.queryMemberById(orderInfo.getUserId()); + if (mtUser.getBalance().compareTo(amount) < 0) { + throw new BusinessCheckException("当前用户余额不足以退款"); + } + mtBalance.setAmount(amount.negate()); + mtBalance.setOperator(refundDto.getOperator()); + balanceService.addBalance(mtBalance, true); + } + + // 返还积分 + if (orderInfo.getUsePoint() != null && orderInfo.getUsePoint() > 0) { + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setUserId(orderInfo.getUserId()); + reqPointDto.setAmount(orderInfo.getUsePoint()); + reqPointDto.setDescription("售后订单" + orderInfo.getOrderSn() + "退回"+ orderInfo.getUsePoint() +"积分"); + reqPointDto.setOrderSn(orderInfo.getOrderSn()); + reqPointDto.setOperator(""); + pointService.addPoint(reqPointDto); + } + + // 返还卡券 + List confirmLogList = mtConfirmLogMapper.getOrderConfirmLogList(orderInfo.getId()); + if (confirmLogList.size() > 0) { + for (MtConfirmLog log : confirmLogList) { + MtCoupon couponInfo = couponService.queryCouponById(log.getCouponId()); + MtUserCoupon userCouponInfo = mtUserCouponMapper.selectById(log.getUserCouponId()); + if (userCouponInfo != null) { + // 优惠券直接置为未使用 + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + userCouponInfo.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + mtUserCouponMapper.updateById(userCouponInfo); + } + // 储值卡把余额加回去 + if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + BigDecimal balance = userCouponInfo.getBalance(); + BigDecimal newBalance = balance.add(log.getAmount()); + if (newBalance.compareTo(userCouponInfo.getAmount()) <= 0) { + userCouponInfo.setBalance(newBalance); + userCouponInfo.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + } + mtUserCouponMapper.updateById(userCouponInfo); + } + // 撤销核销记录 + log.setStatus(StatusEnum.DISABLE.getKey()); + mtConfirmLogMapper.updateById(log); + } + } + } + + // 退回积分 + Map params = new HashMap<>(); + params.put("USER_ID", orderInfo.getUserId()); + params.put("ORDER_SN", orderInfo.getOrderSn()); + List pointList = mtPointMapper.selectByMap(params); + if (pointList != null && pointList.size() > 0) { + Integer pointNum = pointList.get(0).getAmount(); + if (pointNum > 0) { + Integer amount = pointNum - (pointNum) * 2; + MtPoint mtPoint = new MtPoint(); + mtPoint.setAmount(amount.intValue()); + mtPoint.setUserId(orderInfo.getUserId()); + mtPoint.setOrderSn(orderInfo.getOrderSn()); + mtPoint.setDescription("退款¥" + orderInfo.getPayAmount() + "退回" + pointNum + "积分"); + mtPoint.setOperator(refundDto.getOperator() == null ? "系统" : refundDto.getOperator()); + pointService.addPoint(mtPoint); + } + } + + // 返还库存 + Map eParam = new HashMap<>(); + eParam.put("ORDER_ID", orderInfo.getId()); + List orderGoodsList = mtOrderGoodsMapper.selectByMap(eParam); + if (orderGoodsList != null && orderGoodsList.size() > 0) { + for (MtOrderGoods mtOrderGoods : orderGoodsList) { + MtGoods mtGoods = mtGoodsMapper.selectById(mtOrderGoods.getGoodsId()); + mtGoods.setStock(mtOrderGoods.getNum() + mtGoods.getStock()); + mtGoodsMapper.updateById(mtGoods); + if (mtOrderGoods.getSkuId() != null && mtOrderGoods.getSkuId() > 0) { + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(mtOrderGoods.getSkuId()); + mtGoodsSku.setStock(mtGoodsSku.getStock() + mtOrderGoods.getNum()); + mtGoodsSkuMapper.updateById(mtGoodsSku); + } + } + } + + // 微信支付发起退款 + if (orderInfo.getPayType().equals(PayTypeEnum.JSAPI.getKey()) || orderInfo.getPayType().equals(PayTypeEnum.MICROPAY.getKey())) { + weixinService.doRefund(orderInfo.getStoreInfo() != null ? orderInfo.getStoreInfo().getId() : 0, orderInfo.getOrderSn(), orderInfo.getPayAmount(), mtRefund.getAmount(), PlatformTypeEnum.MP_WEIXIN.getCode()); + } + + // 支付宝发起退款 + if (orderInfo.getPayType().equals(PayTypeEnum.ALISCAN.getKey())) { + alipayService.doRefund(orderInfo.getStoreInfo() != null ? orderInfo.getStoreInfo().getId() : 0, orderInfo.getOrderSn(), orderInfo.getPayAmount(), mtRefund.getAmount(), PlatformTypeEnum.PC.getCode()); + } + + return mtRefund; + } + + /** + * 发起退款 + * @param orderId 订单ID + * @param refundAmount 售后金额 + * @param remark 备注 + * @param accountInfo 后台管理信息 + * throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "发起退款") + public Boolean doRefund(Integer orderId, String refundAmount, String remark, AccountInfo accountInfo) throws BusinessCheckException { + UserOrderDto orderInfo = orderService.getOrderById(orderId); + if (orderInfo == null) { + logger.error("退款订单为空,orderId = " + orderId + orderInfo.getId()); + throw new BusinessCheckException("该订单状态异常!"); + } + + MtRefund refund = mtRefundMapper.findByOrderId(orderId); + if (refund != null) { + logger.error("售后订单已存在,orderId = " + orderId); + throw new BusinessCheckException("该售后订单已存在,请查询售后订单列表!"); + } + + if (new BigDecimal(refundAmount).compareTo(orderInfo.getAmount()) > 0) { + throw new BusinessCheckException("退款金额不能大于订单总金额!"); + } + + // 创建售后订单 + RefundDto refundDto = new RefundDto(); + refundDto.setUserId(orderInfo.getUserId()); + refundDto.setOrderId(orderInfo.getId()); + refundDto.setMerchantId(orderInfo.getMerchantId()); + if (orderInfo.getStoreInfo() != null) { + refundDto.setStoreId(orderInfo.getStoreInfo().getId()); + } + refundDto.setRemark(remark); + refundDto.setType(RefundTypeEnum.RETURN.getKey()); + if (orderInfo.getStoreInfo() != null) { + refundDto.setStoreId(orderInfo.getStoreInfo().getId()); + } + refundDto.setAmount(new BigDecimal(refundAmount)); + refundDto.setOperator(accountInfo.getAccountName()); + refundDto.setImages(null); + MtRefund mtRefund = createRefund(refundDto); + if (mtRefund != null) { + // 审核同意 + RefundDto agreeDto = new RefundDto(); + agreeDto.setId(mtRefund.getId()); + agreeDto.setOperator(accountInfo.getAccountName()); + agreeDto.setStatus(RefundStatusEnum.COMPLETE.getKey()); + MtRefund refundInfo = agreeRefund(agreeDto); + if (refundInfo == null) { + logger.error("退款审核失败,orderId = " + orderId + ", refundId = " + mtRefund.getId()); + throw new BusinessCheckException("退款审核失败!"); + } + } else { + logger.error("退款生成售后订单失败,orderId = " + orderId); + throw new BusinessCheckException("生成售后订单失败!"); + } + return true; + } + + /** + * 获取售后订单数量 + * + * @param beginTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public Long getRefundCount(Date beginTime, Date endTime) { + return mtRefundMapper.getRefundCount(beginTime, endTime); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SendLogServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SendLogServiceImpl.java new file mode 100644 index 0000000..8f4bf7f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SendLogServiceImpl.java @@ -0,0 +1,149 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.ReqSendLogDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.SendLogService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtSendLogMapper; +import com.fuint.repository.model.MtSendLog; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** + * 发送卡券记录业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SendLogServiceImpl extends ServiceImpl implements SendLogService { + + private MtSendLogMapper mtSendLogMapper; + + /** + * 分页查询列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse querySendLogListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtSendLog::getStatus, StatusEnum.DISABLE.getKey()); + + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtSendLog::getStatus, status); + } + String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString(); + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.eq(MtSendLog::getUserId, userId); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtSendLog::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtSendLog::getStoreId, storeId); + } + String couponId = paginationRequest.getSearchParams().get("couponId") == null ? "" : paginationRequest.getSearchParams().get("couponId").toString(); + if (StringUtils.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtSendLog::getCouponId, couponId); + } + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtSendLog::getMobile, mobile); + } + + lambdaQueryWrapper.orderByDesc(MtSendLog::getId); + List dataList = mtSendLogMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtSendLog.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加发放记录 + * + * @param reqSendLogDto + * @throws BusinessCheckException + * @return + */ + @Override + public MtSendLog addSendLog(ReqSendLogDto reqSendLogDto) { + MtSendLog mtLog = new MtSendLog(); + mtLog.setMerchantId(reqSendLogDto.getMerchantId()); + mtLog.setStoreId(reqSendLogDto.getStoreId()); + mtLog.setType(reqSendLogDto.getType()); + mtLog.setUserId(reqSendLogDto.getUserId()); + mtLog.setFileName(reqSendLogDto.getFileName()); + mtLog.setFilePath(reqSendLogDto.getFilePath()); + mtLog.setMobile(reqSendLogDto.getMobile()); + mtLog.setCouponId(reqSendLogDto.getCouponId()); + mtLog.setGroupId(reqSendLogDto.getGroupId()); + mtLog.setGroupName(reqSendLogDto.getGroupName()); + mtLog.setSendNum(reqSendLogDto.getSendNum()); + mtLog.setRemoveSuccessNum(0); + mtLog.setRemoveFailNum(0); + mtLog.setStatus(StatusEnum.ENABLED.getKey()); + mtLog.setCreateTime(new Date()); + mtLog.setOperator(reqSendLogDto.getOperator()); + mtLog.setUuid(reqSendLogDto.getUuid()); + mtSendLogMapper.insert(mtLog); + return mtLog; + } + + /** + * 根据ID查询发券记录 + * + * @param id 发券记录ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtSendLog querySendLogById(Long id) { + return mtSendLogMapper.selectById(id.intValue()); + } + + /** + * 根据ID删除发券记录 + * + * @param id 发券记录ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + public void deleteSendLog(Long id, String operator) { + MtSendLog mtSendLog = querySendLogById(id); + if (null == mtSendLog) { + return; + } + mtSendLog.setStatus(StatusEnum.DISABLE.getKey()); + mtSendLog.setOperator(operator); + mtSendLogMapper.updateById(mtSendLog); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SendSmsServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SendSmsServiceImpl.java new file mode 100644 index 0000000..2f918fe --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SendSmsServiceImpl.java @@ -0,0 +1,310 @@ +package com.fuint.common.service.impl; + +import com.alibaba.fastjson.JSON; +import com.aliyuncs.CommonRequest; +import com.aliyuncs.CommonResponse; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.exceptions.ServerException; +import com.aliyuncs.http.MethodType; +import com.aliyuncs.profile.DefaultProfile; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuint.common.dto.MessageResDto; +import com.fuint.common.enums.SettingTypeEnum; +import com.fuint.common.enums.SmsSettingEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.SendSmsService; +import com.fuint.common.service.SettingService; +import com.fuint.common.service.SmsTemplateService; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtSmsSendedLogMapper; +import com.fuint.repository.model.MtSetting; +import com.fuint.repository.model.MtSmsSendedLog; +import com.fuint.repository.model.MtSmsTemplate; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 发送手机短信服务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SendSmsServiceImpl implements SendSmsService { + + private static final Logger logger = LoggerFactory.getLogger(SendSmsServiceImpl.class); + + /** + * 系统环境变量 + * */ + private Environment env; + + private MtSmsSendedLogMapper mtSmsSendedLogMapper; + + /** + * 短信模板服务接口 + * */ + private SmsTemplateService smsTemplateService; + + /** + * 配置服务接口 + * */ + private SettingService settingService; + + /** + * 发送短信 + * + * @param merchantId 商户ID + * @param templateUname 模板名 + * @param phones 发送手机号 + * @param contentParams 发送参数 + * @return + * */ + @Override + public Map> sendSms(Integer merchantId, String templateUname, List phones, Map contentParams) throws BusinessCheckException { + logger.info("使用短信平台发送短信....."); + Map> result = new HashMap<>(); + Integer mode = Integer.parseInt(env.getProperty("aliyun.sms.mode")); + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.SMS_CONFIG.getKey(), SmsSettingEnum.IS_CLOSE.getKey()); + if (mode.intValue() == 1 && mtSetting != null && StringUtil.isNotEmpty(mtSetting.getValue())) { + mode = Integer.parseInt(mtSetting.getValue()); + logger.info("商户短信设置 mtSetting = {}", JSON.toJSONString(mtSetting)); + } + if (mode.intValue() != 1) { + logger.info("短信平台未开启 mode = {}", mode); + return result; + } + if (templateUname != null && !CollectionUtils.isEmpty(phones)) { + try { + if (mode != null && mode.intValue() == 1) { + // 手机号以","分隔拼接 + String mobilePhones = phones.stream().collect(Collectors.joining(",")); + MessageResDto res = sendMessage(merchantId, mobilePhones, templateUname, contentParams); + result.put(res.getResult(), phones); + } else { + result.put(Boolean.TRUE,phones); + logger.info("模拟短信平台发送短信....."); + } + } catch (Exception e) { + result.put(Boolean.FALSE,phones); + logger.error("推送至短信平台出错,参数[templateUname={},phones={}]", templateUname, phones); + logger.error(e.getMessage(),e); + } + } else { + logger.error("手机号码和短信内容不能为空,请确认!"); + } + return result; + } + + /** + * 发送短信 + * + * @param phoneNo 短信发送手机号,多个手机号以英文半角逗号隔开,最多支持200个手机号 + * @param templateUname 短信模板英文名称 + * @return + */ + public MessageResDto sendMessage(Integer merchantId, String phoneNo, String templateUname, Map contentParams) throws BusinessCheckException { + MessageResDto resInfo = new MessageResDto(); + logger.info("sendMessage inParams:phoneNo={}, message={}", phoneNo, templateUname); + if (StringUtil.isBlank(phoneNo) || phoneNo.split(",").length > 200) { + logger.error("手机号列表不符合要求"); + resInfo.setResult(Boolean.FALSE); + return resInfo; + } + + String accessKeyId = env.getProperty("aliyun.sms.accessKeyId"); + String secret = env.getProperty("aliyun.sms.accessKeySecret"); + String signName = env.getProperty("aliyun.sms.signName"); + + List settings = settingService.getSettingList(merchantId, SettingTypeEnum.SMS_CONFIG.getKey()); + if (settings != null && settings.size() > 0) { + logger.info("商户短信设置 mtSetting = {}", JSON.toJSONString(settings.get(0))); + String accessKeyId1 = ""; + String secret1 = ""; + String signName1 = ""; + for (MtSetting mtSetting : settings) { + if (mtSetting.getName().equals(SmsSettingEnum.ACCESS_KEY_ID.getKey()) && StringUtil.isNotEmpty(mtSetting.getValue())) { + accessKeyId1 = mtSetting.getValue(); + } + if (mtSetting.getName().equals(SmsSettingEnum.ACCESS_KEY_SECRET.getKey()) && StringUtil.isNotEmpty(mtSetting.getValue())) { + secret1 = mtSetting.getValue(); + } + if (mtSetting.getName().equals(SmsSettingEnum.SIGN_NAME.getKey()) && StringUtil.isNotEmpty(mtSetting.getValue())) { + signName1 = mtSetting.getValue(); + } + } + if (StringUtil.isNotEmpty(accessKeyId1) && StringUtil.isNotEmpty(secret1) && StringUtil.isNotEmpty(signName1)) { + accessKeyId = accessKeyId1; + secret = secret1; + signName = signName1; + } + } + + MtSmsTemplate templateInfo = new MtSmsTemplate(); + try { + Map params = new HashMap<>(); + params.put("uname", templateUname); + params.put("merchant_id", merchantId); + List templateList = smsTemplateService.querySmsTemplateByParams(params); + if (templateList.size() < 1) { + throw new BusinessCheckException("该短信模板不存在!"); + } + templateInfo = templateList.get(0); + if (!templateInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException("该短信模板未启用!"); + } + } catch (BusinessCheckException e) { + e.getStackTrace(); + } + + boolean flag = false; + try { + // 解决中文乱码 + if (!CommonUtil.isUtf8(signName) || CommonUtil.isErrCode(signName)) { + signName = new String(signName.getBytes("ISO8859-1"), "UTF-8"); + } + + // 阿里云短信 + DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, secret); + IAcsClient client = new DefaultAcsClient(profile); + + // 装配参数 + String smsContent = templateInfo.getContent(); + if (smsContent == null || StringUtil.isEmpty(smsContent)) { + resInfo.setResult(Boolean.FALSE); + return resInfo; + } + String paramJson = ""; + if (contentParams.size() > 0) { + for (Map.Entry entry : contentParams.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + smsContent = smsContent.replace("{"+key+"}", value); + } + try { + ObjectMapper mapper = new ObjectMapper(); + paramJson = mapper.writeValueAsString(contentParams); + } catch(Exception e){ + e.printStackTrace(); + } + } + + CommonRequest request = new CommonRequest(); + request.setSysMethod(MethodType.POST); + request.setSysDomain("dysmsapi.aliyuncs.com"); + request.setSysVersion("2017-05-25"); + request.setSysAction("SendSms"); + request.putQueryParameter("RegionId", "cn-hangzhou"); + request.putQueryParameter("PhoneNumbers", phoneNo); + request.putQueryParameter("SignName", signName); + request.putQueryParameter("TemplateCode", templateInfo.getCode()); + request.putQueryParameter("TemplateParam", paramJson); + + String res = ""; + try { + CommonResponse response = client.getCommonResponse(request); + logger.info("sendMessage response:{}", response.toString()); + res = response.getData(); + System.out.println(response.getData()); + } catch (ServerException e) { + e.printStackTrace(); + } catch (ClientException e) { + e.printStackTrace(); + } + logger.info("sendMessage outParams:{}", res); + saveSendLog(merchantId, phoneNo, smsContent); + flag = true; + } catch (Exception e) { + flag = false; + logger.error(e.getMessage(), e); + } finally { + resInfo.setResult(flag); + } + return resInfo; + } + + /** + * 发送短信日志记录 + * + * @param merchantId 商户ID + * @param phoneNo 短信发送手机号 + * @param message 短信内容 + * @return + */ + public void saveSendLog(Integer merchantId, String phoneNo, String message) { + MtSmsSendedLog mtSmsSendedLog = new MtSmsSendedLog(); + mtSmsSendedLog.setMerchantId(merchantId); + mtSmsSendedLog.setMobilePhone(phoneNo); + mtSmsSendedLog.setContent(message); + Date time = new Date(); + mtSmsSendedLog.setCreateTime(time); + mtSmsSendedLog.setSendTime(time); + mtSmsSendedLog.setUpdateTime(time); + mtSmsSendedLogMapper.insert(mtSmsSendedLog); + } + + /** + * 分页查询已发短信列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse querySmsListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtSmsSendedLog::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtSmsSendedLog::getStoreId, storeId); + } + String content = paginationRequest.getSearchParams().get("content") == null ? "" : paginationRequest.getSearchParams().get("content").toString(); + if (StringUtils.isNotBlank(content)) { + lambdaQueryWrapper.like(MtSmsSendedLog::getContent, content); + } + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtSmsSendedLog::getMobilePhone, mobile); + } + + lambdaQueryWrapper.orderByDesc(MtSmsSendedLog::getLogId); + List dataList = mtSmsSendedLogMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtSmsSendedLog.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SettingServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SettingServiceImpl.java new file mode 100644 index 0000000..bc8fddb --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SettingServiceImpl.java @@ -0,0 +1,231 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuint.common.dto.NavigationDto; +import com.fuint.common.dto.ParamDto; +import com.fuint.common.enums.*; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.repository.mapper.MtSettingMapper; +import com.fuint.repository.model.MtSetting; +import com.fuint.common.service.SettingService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 配置业务接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SettingServiceImpl extends ServiceImpl implements SettingService { + + /** + * 系统环境变量 + * */ + private Environment env; + + private MtSettingMapper mtSettingMapper; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 删除配置 + * + * @param merchantId 商户ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除配置信息") + public void removeSetting(Integer merchantId, String type, String name) { + MtSetting info = querySettingByName(merchantId, type, name); + if (info != null) { + mtSettingMapper.deleteById(info.getId()); + } + } + + /** + * 保存配置 + * + * @param mtSetting 配置参数 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存配置信息") + public MtSetting saveSetting(MtSetting mtSetting) { + MtSetting settingInfo = querySettingByName(mtSetting.getMerchantId(), mtSetting.getType(), mtSetting.getName()); + if (null != settingInfo) { + if (mtSetting.getValue() != null) { + settingInfo.setValue(mtSetting.getValue()); + } + if (mtSetting.getDescription() != null) { + settingInfo.setDescription(mtSetting.getDescription()); + } + if (StringUtil.isNotEmpty(mtSetting.getOperator())) { + settingInfo.setOperator(mtSetting.getOperator()); + } + if (mtSetting.getUpdateTime() != null) { + settingInfo.setUpdateTime(mtSetting.getUpdateTime()); + } + if (mtSetting.getStatus() != null) { + settingInfo.setStatus(mtSetting.getStatus()); + } + if (mtSetting.getType() != null) { + settingInfo.setType(mtSetting.getType()); + } + mtSettingMapper.updateById(settingInfo); + } else { + // 创建配置 + if (mtSetting.getName() != null && mtSetting.getValue() != null) { + mtSetting.setCreateTime(new Date()); + mtSetting.setStatus(StatusEnum.ENABLED.getKey()); + mtSettingMapper.insert(mtSetting); + } + } + + return mtSetting; + } + + /** + * 获取配置列表 + * + * @param merchantId 商户ID + * @param type 配置类型 + * @throws BusinessCheckException + * @return + */ + @Override + public List getSettingList(Integer merchantId, String type) { + return mtSettingMapper.querySettingByType(merchantId, type); + } + + /** + * 根据ID获取配置信息 + * + * @param merchantId 商户ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + * @return + */ + @Override + public MtSetting querySettingByName(Integer merchantId, String type, String name) { + return mtSettingMapper.querySettingByName(merchantId, 0, type, name); + } + + /** + * 根据ID获取配置信息 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param type 类型 + * @param name 配置名称 + * @throws BusinessCheckException + * @return + */ + @Override + public MtSetting querySettingByName(Integer merchantId, Integer storeId, String type, String name) { + return mtSettingMapper.querySettingByName(merchantId, storeId, type, name); + } + + /** + * 获取系统上传的根路径 + * + * @return + * */ + @Override + public String getUploadBasePath() { + String basePath = env.getProperty("images.upload.url"); + String mode = env.getProperty("aliyun.oss.mode"); + + if (mode == null) { + return basePath; + } else { + if (mode.equals("1")) { + String domain = env.getProperty("aliyun.oss.domain"); + if (StringUtil.isNotEmpty(domain)) { + basePath = domain; + } + } + } + + return basePath; + } + + /** + * 获取支付方式列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param platform 平台 + * @return + * */ + @Override + public List getPayTypeList(Integer merchantId, Integer storeId, String platform) throws BusinessCheckException { + List payTypeList = new ArrayList<>(); + + // 微信jsapi + ParamDto jsApi = new ParamDto(PayTypeEnum.JSAPI.getKey(), PayTypeEnum.JSAPI.getValue(), PayTypeEnum.JSAPI.getKey()); + payTypeList.add(jsApi); + + // 余额支付 + ParamDto balance = new ParamDto(PayTypeEnum.BALANCE.getKey(), PayTypeEnum.BALANCE.getValue(), PayTypeEnum.BALANCE.getKey()); + payTypeList.add(balance); + + // 前台支付 + MtSetting mtSetting = settingService.querySettingByName(merchantId, storeId, SettingTypeEnum.ORDER.getKey(), OrderSettingEnum.PAY_OFF_LINE.getKey()); + if (mtSetting != null && mtSetting.getValue().equals(YesOrNoEnum.YES.getKey())) { + ParamDto store = new ParamDto(PayTypeEnum.STORE.getKey(), PayTypeEnum.STORE.getValue(), PayTypeEnum.STORE.getKey()); + payTypeList.add(store); + } + + return payTypeList; + } + + /** + * 获取导航栏 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + @Override + public List getNavigation(Integer merchantId, Integer storeId, String status) throws JsonProcessingException { + MtSetting mtSetting = mtSettingMapper.querySettingByName(merchantId, storeId, SettingTypeEnum.NAVIGATION.getKey(), SettingTypeEnum.NAVIGATION.getKey()); + List navigation = new ArrayList<>(); + if (mtSetting != null && StringUtil.isNotBlank(mtSetting.getValue())) { + ObjectMapper objectMapper = new ObjectMapper(); + navigation = objectMapper.readValue(mtSetting.getValue(), new TypeReference>() {}); + } + if (StringUtil.isNotBlank(status)) { + navigation = navigation.stream().filter(nav -> status.equals(nav.getStatus())).collect(Collectors.toList()); + } + String basePath = getUploadBasePath(); + navigation.stream().forEach(p -> p.setIconUrl(basePath + p.getIcon())); + Collections.sort(navigation, (p1, p2) -> Integer.compare(p2.getSort(), p1.getSort())); + return navigation; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SettlementServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SettlementServiceImpl.java new file mode 100644 index 0000000..8535d48 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SettlementServiceImpl.java @@ -0,0 +1,255 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.fuint.common.Constants; +import com.fuint.common.dto.SettlementDto; +import com.fuint.common.dto.SettlementOrderDto; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.OrderListParam; +import com.fuint.common.service.MerchantService; +import com.fuint.common.service.OrderService; +import com.fuint.common.service.SettlementService; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.module.backendApi.request.SettlementRequest; +import com.fuint.repository.mapper.MtSettlementMapper; +import com.fuint.repository.mapper.MtSettlementOrderMapper; +import com.fuint.repository.model.*; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 订单结算相关业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SettlementServiceImpl implements SettlementService { + + private MtSettlementMapper mtSettlementMapper; + + private MtSettlementOrderMapper mtSettlementOrderMapper; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 商户服务接口 + * */ + private MerchantService merchantService; + + /** + * 分页查询结算列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse querySettlementListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtSettlement::getStatus, StatusEnum.DISABLE.getKey()); + + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtSettlement::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtSettlement::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtSettlement::getStoreId, storeId); + } + String description = paginationRequest.getSearchParams().get("description") == null ? "" : paginationRequest.getSearchParams().get("description").toString(); + if (StringUtils.isNotBlank(description)) { + lambdaQueryWrapper.like(MtSettlement::getDescription, description); + } + lambdaQueryWrapper.orderByDesc(MtSettlement::getId); + List dataList = mtSettlementMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtSettlement.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 提交结算 + * + * @param requestParam + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "发起结算") + public Boolean submitSettlement(SettlementRequest requestParam) throws BusinessCheckException { + OrderListParam orderParam = new OrderListParam(); + orderParam.setMerchantId(requestParam.getMerchantId()); + orderParam.setStoreId(requestParam.getStoreId()); + orderParam.setDataType("paid"); + orderParam.setStartTime(requestParam.getStartTime()); + orderParam.setEndTime(requestParam.getEndTime()); + orderParam.setSettleStatus(SettleStatusEnum.WAIT.getKey()); + orderParam.setStatus(OrderStatusEnum.COMPLETE.getKey()); + List payType = new ArrayList<>(); + payType.add(PayTypeEnum.JSAPI.getKey()); + payType.add(PayTypeEnum.MICROPAY.getKey()); + payType.add(PayTypeEnum.ALISCAN.getKey()); + orderParam.setPayType(payType); + + orderParam.setPage(Constants.PAGE_NUMBER); + orderParam.setPageSize(Constants.ALL_ROWS); + + PaginationResponse response = orderService.getUserOrderList(orderParam); + List orderList = response.getContent(); + if (orderList == null || orderList.size() < 1) { + throw new BusinessCheckException("暂无符合结算条件的订单"); + } + + BigDecimal amount = new BigDecimal("0"); + BigDecimal totalOrderAmount = new BigDecimal("0"); + if (orderList != null && orderList.size() > 0) { + for (UserOrderDto orderDto : orderList) { + amount = amount.add(orderDto.getPayAmount()); + totalOrderAmount = totalOrderAmount.add(orderDto.getPayAmount()); + } + } + MtSettlement mtSettlement = new MtSettlement(); + mtSettlement.setMerchantId(requestParam.getMerchantId()); + mtSettlement.setStoreId(requestParam.getStoreId()); + mtSettlement.setSettlementNo(CommonUtil.createSettlementNo()); + + MtMerchant mtMerchant = merchantService.queryMerchantById(requestParam.getMerchantId()); + BigDecimal percent = new BigDecimal("1"); + if (mtMerchant.getSettleRate() != null && mtMerchant.getSettleRate().compareTo(new BigDecimal("0")) > 0) { + percent = mtMerchant.getSettleRate().divide(new BigDecimal("100"), BigDecimal.ROUND_CEILING, 4); + } + mtSettlement.setAmount(amount.multiply(percent)); + mtSettlement.setSettleRate(percent.multiply(new BigDecimal("100"))); + mtSettlement.setTotalOrderAmount(totalOrderAmount); + mtSettlement.setStatus(StatusEnum.ENABLED.getKey()); + mtSettlement.setOperator(requestParam.getOperator()); + mtSettlement.setCreateTime(new Date()); + mtSettlement.setUpdateTime(new Date()); + mtSettlementMapper.insert(mtSettlement); + if (orderList != null && orderList.size() > 0) { + for (UserOrderDto orderDto : orderList) { + MtSettlementOrder mtSettlementOrder = new MtSettlementOrder(); + mtSettlementOrder.setSettlementId(mtSettlement.getId()); + mtSettlementOrder.setOrderId(orderDto.getId()); + mtSettlementOrder.setCreateTime(new Date()); + mtSettlementOrder.setUpdateTime(new Date()); + mtSettlement.setStatus(StatusEnum.ENABLED.getKey()); + mtSettlementOrder.setOperator(mtSettlement.getOperator()); + mtSettlementOrderMapper.insert(mtSettlementOrder); + // 把订单设置为已结算 + MtOrder mtOrder = orderService.getById(orderDto.getId()); + mtOrder.setSettleStatus(SettleStatusEnum.COMPLETE.getKey()); + orderService.updateOrder(mtOrder); + } + } + return true; + } + + /** + * 结算确认 + * + * @param settlementId 结算ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "结算确认") + public Boolean doConfirm(Integer settlementId, String operator) throws BusinessCheckException { + MtSettlement mtSettlement = mtSettlementMapper.selectById(settlementId); + if (mtSettlement == null) { + throw new BusinessCheckException("结算数据不存在"); + } + mtSettlement.setStatus(SettleStatusEnum.COMPLETE.getKey()); + mtSettlement.setPayStatus(PayStatusEnum.SUCCESS.getKey()); + mtSettlement.setUpdateTime(new Date()); + mtSettlement.setOperator(operator); + mtSettlementMapper.updateById(mtSettlement); + return true; + } + + /** + * 获取结算详情 + * + * @param settlementId 结算ID + * @param page 当前页码 + * @param pageSize 每页数量 + * @return + * */ + @Override + public SettlementDto getSettlementInfo(Integer settlementId, Integer page, Integer pageSize) throws BusinessCheckException { + MtSettlement mtSettlement = mtSettlementMapper.selectById(settlementId); + if (mtSettlement == null) { + throw new BusinessCheckException("结算单不存在"); + } + + SettlementDto settlementDto = new SettlementDto(); + BeanUtils.copyProperties(mtSettlement, settlementDto); + + Page pageHelper = PageHelper.startPage(page, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtSettlementOrder::getStatus, StatusEnum.DISABLE.getKey()); + lambdaQueryWrapper.eq(MtSettlementOrder::getSettlementId, settlementId); + lambdaQueryWrapper.orderByDesc(MtSettlementOrder::getId); + List dataList = mtSettlementOrderMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(page, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, SettlementOrderDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + + List orderList = new ArrayList<>(); + if (dataList != null && dataList.size() > 0) { + for (MtSettlementOrder mtSettlementOrder : dataList) { + SettlementOrderDto settlementOrderDto = new SettlementOrderDto(); + BeanUtils.copyProperties(mtSettlementOrder, settlementOrderDto); + UserOrderDto orderDto = orderService.getOrderById(settlementOrderDto.getOrderId()); + if (orderDto != null) { + settlementOrderDto.setOrderInfo(orderDto); + } + orderList.add(settlementOrderDto); + } + } + paginationResponse.setContent(orderList); + + settlementDto.setOrderList(paginationResponse); + return settlementDto; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SmsTemplateServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SmsTemplateServiceImpl.java new file mode 100644 index 0000000..e5904e6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SmsTemplateServiceImpl.java @@ -0,0 +1,170 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.SmsTemplateDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.SmsTemplateService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtSmsTemplateMapper; +import com.fuint.repository.model.MtSmsTemplate; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 短信模板业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SmsTemplateServiceImpl extends ServiceImpl implements SmsTemplateService { + + private MtSmsTemplateMapper mtSmsTemplateMapper; + + /** + * 分页查询模板列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse querySmsTemplateListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtSmsTemplate::getStatus, StatusEnum.DISABLE.getKey()); + + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.like(MtSmsTemplate::getMerchantId, merchantId); + } + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtSmsTemplate::getName, name); + } + String uname = paginationRequest.getSearchParams().get("uname") == null ? "" : paginationRequest.getSearchParams().get("uname").toString(); + if (StringUtils.isNotBlank(uname)) { + lambdaQueryWrapper.eq(MtSmsTemplate::getUname, uname); + } + String code = paginationRequest.getSearchParams().get("code") == null ? "" : paginationRequest.getSearchParams().get("code").toString(); + if (StringUtils.isNotBlank(code)) { + lambdaQueryWrapper.eq(MtSmsTemplate::getCode, code); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtSmsTemplate::getStatus, status); + } + + lambdaQueryWrapper.orderByDesc(MtSmsTemplate::getId); + List dataList = mtSmsTemplateMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtSmsTemplate.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存模板信息 + * + * @param mtSmsTemplateDto 短信模板 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存短信模板") + public MtSmsTemplate saveSmsTemplate(SmsTemplateDto mtSmsTemplateDto) throws BusinessCheckException { + MtSmsTemplate mtSmsTemplate = new MtSmsTemplate(); + mtSmsTemplate.setMerchantId(mtSmsTemplateDto.getMerchantId()); + mtSmsTemplate.setCode(mtSmsTemplateDto.getCode()); + mtSmsTemplate.setName(mtSmsTemplateDto.getName()); + mtSmsTemplate.setUname(mtSmsTemplateDto.getUname()); + mtSmsTemplate.setContent(mtSmsTemplateDto.getContent()); + mtSmsTemplate.setStatus(mtSmsTemplateDto.getStatus()); + mtSmsTemplate.setOperator(mtSmsTemplate.getOperator()); + + if (mtSmsTemplateDto.getId() == null) { + mtSmsTemplate.setCreateTime(new Date()); + mtSmsTemplate.setUpdateTime(new Date()); + mtSmsTemplateMapper.insert(mtSmsTemplate); + } else { + MtSmsTemplate oldSmsTemplate = getById(mtSmsTemplateDto.getId()); + if (oldSmsTemplate == null) { + throw new BusinessCheckException("该短信模板不存在"); + } + mtSmsTemplate.setMerchantId(oldSmsTemplate.getMerchantId()); + mtSmsTemplate.setId(mtSmsTemplateDto.getId()); + mtSmsTemplate.setUpdateTime(new Date()); + this.updateById(mtSmsTemplate); + } + + return mtSmsTemplate; + } + + /** + * 根据ID删除数据 + * + * @param id 模板ID + * @param operator 操作人 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除短信模板") + public void deleteTemplate(Integer id, String operator) { + MtSmsTemplate mtTemplate = mtSmsTemplateMapper.selectById(id); + if (null == mtTemplate) { + return; + } + + mtTemplate.setStatus(StatusEnum.DISABLE.getKey()); + mtTemplate.setUpdateTime(new Date()); + + mtSmsTemplateMapper.updateById(mtTemplate); + } + + /** + * 根据D获取信息 + * + * @param id 模板ID + * @return + */ + @Override + public MtSmsTemplate querySmsTemplateById(Integer id) { + return mtSmsTemplateMapper.selectById(id); + } + + /** + * 根据参数查询短信模板 + * + * @param params 查询参数 + * @return + * */ + @Override + public List querySmsTemplateByParams(Map params) { + if (params == null) { + params = new HashMap<>(); + } + return mtSmsTemplateMapper.selectByMap(params); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/SourceServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/SourceServiceImpl.java new file mode 100644 index 0000000..fe920a8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/SourceServiceImpl.java @@ -0,0 +1,340 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.domain.TreeSelect; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.AccountService; +import com.fuint.common.service.SourceService; +import com.fuint.common.vo.MetaVo; +import com.fuint.common.vo.RouterVo; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.repository.mapper.TDutySourceMapper; +import com.fuint.repository.mapper.TSourceMapper; +import com.fuint.repository.model.TDutySource; +import com.fuint.repository.model.TSource; +import com.fuint.common.domain.TreeNode; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.utils.ArrayUtil; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 菜单管理接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class SourceServiceImpl extends ServiceImpl implements SourceService { + + private TSourceMapper tSourceMapper; + + private TDutySourceMapper tDutySourceMapper; + + /** + * 后台账户服务接口 + */ + private AccountService accountService; + + /** + * 获取有效的菜单集合 + * + * @param merchantId 商户ID + * @param status + * @return + */ + @Override + public List getAvailableSources(Integer merchantId, String status) { + return tSourceMapper.findByStatus(merchantId, status); + } + + /** + * 获取菜单的属性结构 + * + * @param merchantId 商户ID + * @param status 状态 + * @return + */ + @Override + public List getSourceTree(Integer merchantId, String status) { + List tSources = getAvailableSources(merchantId, status); + List trees = new ArrayList<>(); + if (tSources != null && tSources.size() > 0) { + TreeNode sourceTreeNode; + for (TSource tSource : tSources) { + sourceTreeNode = new TreeNode(); + sourceTreeNode.setName(tSource.getSourceName()); + sourceTreeNode.setId(tSource.getSourceId()); + sourceTreeNode.setLevel(tSource.getSourceLevel()); + sourceTreeNode.setSort((tSource.getSourceStyle() == null || StringUtil.isEmpty(tSource.getSourceStyle())) ? 0 : Integer.parseInt(tSource.getSourceStyle())); + sourceTreeNode.setPath(tSource.getPath()); + sourceTreeNode.setIcon(tSource.getNewIcon()); + sourceTreeNode.setIsMenu(tSource.getIsMenu()); + sourceTreeNode.setStatus(tSource.getStatus()); + sourceTreeNode.setPerms(tSource.getPath().replaceAll("/", ":")); + if (tSource.getParentId() != null) { + sourceTreeNode.setPId(tSource.getParentId()); + } else { + sourceTreeNode.setPId(0); + } + trees.add(sourceTreeNode); + } + } + return trees; + } + + /** + * 根据菜单ID集合查询菜单列表信息 + * + * @param ids 菜单ID + * @return + */ + @Override + public List findDatasByIds(String[] ids) { + Long[] arrays = new Long[ids.length]; + for (int i = 0; i < ids.length; i++) { + arrays[i] = Long.parseLong(ids[i]); + } + return tSourceMapper.findByIdIn(ArrayUtil.toList(arrays)); + } + + /** + * 根据账号ID获取菜单列表 + * + * @param merchantId 商户ID + * @param accountId 账号ID + * @throws BusinessCheckException + * @return + */ + @Override + public List getMenuListByUserId(Integer merchantId, Integer accountId) { + if (merchantId == null) { + merchantId = 0; + } + List sourceList = tSourceMapper.findSourcesByAccountId(merchantId, accountId); + return delRepeated(sourceList); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param treeNodes 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List treeNodes) { + List routers = new LinkedList<>(); + + for (TreeNode menu : treeNodes) { + RouterVo router = new RouterVo(); + if (menu.getIsMenu() == 0) { + router.setHidden(true); + } else { + router.setHidden(false); + } + router.setName(menu.getEname()); + if (menu.getLevel() == 1) { + router.setComponent("Layout"); + router.setPath("/" + menu.getEname().toLowerCase()); + router.setRedirect("noRedirect"); + router.setAlwaysShow(true); + } else { + if (menu.getIsMenu() == 2) { + router.setAlwaysShow(true); + } else { + router.setAlwaysShow(false); + } + router.setComponent(menu.getPath()); + router.setPath('/' + menu.getPath()); + } + router.setMeta(new MetaVo(menu.getName(), menu.getNewIcon(), false, null)); + List cMenus = menu.getChildrens(); + if (cMenus != null && !cMenus.isEmpty() && cMenus.size() > 0) { + router.setChildren(buildMenus(cMenus)); + } + routers.add(router); + } + + return routers; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) { + List returnList = new ArrayList(); + List tempList = new ArrayList(); + for (TreeNode dept : menus) { + tempList.add(dept.getId()); + } + for (Iterator iterator = menus.iterator(); iterator.hasNext();) { + TreeNode menu = (TreeNode) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getPId())) { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) { + returnList = menus; + } + return returnList; + } + + /** + * 新增后台菜单 + * + * @param tSource + * @param accountId + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增后台菜单") + public void addSource(TSource tSource, Integer accountId) { + this.save(tSource); + // 赋访问权限 + List dutyIds = accountService.getDutyIdsByAccountId(accountId); + if (dutyIds != null && dutyIds.size() > 0) { + for (Integer dutyId : dutyIds) { + TDutySource dutySource = new TDutySource(); + dutySource.setDutyId(dutyId); + dutySource.setSourceId(tSource.getSourceId()); + tDutySourceMapper.insert(dutySource); + } + } + } + + /** + * 修改后台菜单 + * + * @param source + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改后台菜单") + public void editSource(TSource source) { + // 禁用或删除菜单处理 + if (source.getStatus().equals(StatusEnum.FORBIDDEN.getKey()) || source.getStatus().equals(StatusEnum.DISABLE.getKey())) { + deleteSource(source, source.getStatus()); + } else { + tSourceMapper.updateById(source); + } + } + + /** + * 删除或禁用菜单 + * + * @param source + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除后台菜单") + public void deleteSource(TSource source, String status) { + if (StringUtil.isEmpty(status)) { + status = StatusEnum.DISABLE.getKey(); + } + source.setStatus(status); + tSourceMapper.updateById(source); + + Map param = new HashMap<>(); + param.put("STATUS", StatusEnum.ENABLED.getKey()); + param.put("PARENT_ID", source.getSourceId()); + List dataList = tSourceMapper.selectByMap(param); + if (dataList != null && dataList.size() > 0) { + for (TSource tSource : dataList) { + deleteSource(tSource, status); + } + } + } + + /** + * 菜单去重 + * + * @param sources 菜单列表 + * @return + */ + private List delRepeated(List sources) { + List distinct = new ArrayList<>(); + if (sources != null) { + Map sourceMap = new HashMap<>(); + for (TSource tSource : sources) { + if (sourceMap.get(tSource.getSourceId()) == null) { + sourceMap.put(tSource.getSourceId().longValue(), true); + distinct.add(tSource); + } + } + } + return distinct; + } + + /** + * 递归列表 + * + * @param list + * @param t + */ + private void recursionFn(List list, TreeNode t) { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildrens(childList); + for (TreeNode tChild : childList) { + if (hasChild(list, tChild)) { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + * + * @param list 菜单列表 + * @param t 当前节点 + * @return + */ + private List getChildList(List list, TreeNode t) { + List tList = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) { + TreeNode n = it.next(); + if (n.getPId() == t.getId()) { + tList.add(n); + } + } + return tList; + } + + /** + * 判断是否有子节点 + * + * @param list 菜单列表 + * @param t 当前节点 + * @return + */ + private boolean hasChild(List list, TreeNode t) { + return getChildList(list, t).size() > 0; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/StaffServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/StaffServiceImpl.java new file mode 100644 index 0000000..5b08630 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/StaffServiceImpl.java @@ -0,0 +1,330 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.StaffDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtStaffMapper; +import com.fuint.repository.model.MtMerchant; +import com.fuint.repository.model.MtStaff; +import com.fuint.repository.model.MtStore; +import com.fuint.repository.model.MtUser; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * 员工管理接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class StaffServiceImpl extends ServiceImpl implements StaffService { + + private static final Logger logger = LoggerFactory.getLogger(StaffServiceImpl.class); + + private MtStaffMapper mtStaffMapper; + + /** + * 会员服务接口 + */ + private MemberService memberService; + + /** + * 短信发送接口 + */ + private SendSmsService sendSmsService; + + /** + * 店铺接口 + */ + private StoreService storeService; + + /** + * 商户接口 + */ + private MerchantService merchantService; + + /** + * 员工查询列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryStaffListByPagination(PaginationRequest paginationRequest) throws BusinessCheckException { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtStaff::getAuditedStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtStaff::getRealName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtStaff::getAuditedStatus, status); + } + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtStaff::getMobile, mobile); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtStaff::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtStaff::getStoreId, storeId); + } + String category = paginationRequest.getSearchParams().get("category") == null ? "" : paginationRequest.getSearchParams().get("category").toString(); + if (StringUtils.isNotBlank(category)) { + lambdaQueryWrapper.eq(MtStaff::getCategory, category); + } + String keyword = paginationRequest.getSearchParams().get("keyword") == null ? "" : paginationRequest.getSearchParams().get("keyword").toString(); + if (StringUtils.isNotBlank(keyword)) { + lambdaQueryWrapper.and(wq -> wq + .eq(MtStaff::getMobile, keyword) + .or() + .eq(MtStaff::getRealName, keyword)); + } + lambdaQueryWrapper.orderByDesc(MtStaff::getId); + List staffList = mtStaffMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + if (staffList != null && staffList.size() > 0) { + for (MtStaff mtStaff : staffList) { + StaffDto staffDto = new StaffDto(); + mtStaff.setMobile(CommonUtil.hidePhone(mtStaff.getMobile())); + BeanUtils.copyProperties(mtStaff, staffDto); + if (mtStaff.getStoreId() != null && mtStaff.getStoreId() > 0) { + MtStore mtStore = storeService.queryStoreById(mtStaff.getStoreId()); + staffDto.setStoreInfo(mtStore); + } + dataList.add(staffDto); + } + } + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, StaffDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存员工信息 + * + * @param mtStaff 员工参数 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存店铺员工") + public MtStaff saveStaff(MtStaff mtStaff, String operator) throws BusinessCheckException { + mtStaff.setUpdateTime(new Date()); + if (mtStaff.getId() == null || mtStaff.getId() <= 0) { + mtStaff.setCreateTime(new Date()); + if (mtStaff.getAuditedStatus() == null) { + mtStaff.setAuditedStatus(StatusEnum.UnAudited.getKey()); + } else { + mtStaff.setAuditedStatus(mtStaff.getAuditedStatus()); + } + this.save(mtStaff); + } else { + Integer id = mtStaff.getId(); + MtStaff mtStaffOld = mtStaffMapper.selectById(id); + if (mtStaffOld.getAuditedStatus().equals(StatusEnum.ENABLED.getKey())) { + mtStaff.setAuditedTime(new Date()); + } + mtStaff.setMerchantId(mtStaffOld.getMerchantId()); + } + + MtUser mtUser = null; + if (mtStaff.getUserId() != null) { + mtUser = memberService.queryMemberById(mtStaff.getUserId()); + } + + // 关联会员信息 + if (mtStaff.getUserId() == null || mtUser == null) { + MtUser userInfo = new MtUser(); + userInfo.setName(mtStaff.getRealName()); + userInfo.setDescription("系统自动注册店铺员工账号"); + userInfo.setStoreId(mtStaff.getStoreId()); + userInfo.setMerchantId(mtStaff.getMerchantId()); + userInfo.setIsStaff(YesOrNoEnum.YES.getKey()); + userInfo.setOperator(operator); + mtUser = memberService.addMember(userInfo, "0"); + if (mtUser != null) { + mtStaff.setUserId(mtUser.getId()); + } else { + throw new BusinessCheckException("新增员工失败"); + } + } else { + mtUser.setIsStaff(YesOrNoEnum.YES.getKey()); + mtUser.setOperator(operator); + memberService.updateMember(mtUser, false); + } + + // 更新员工 + this.updateById(mtStaff); + logger.info("operator:{} 保存员工信息mtStaff:{}", operator, mtStaff); + return mtStaff; + } + + /** + * 根据ID获取员工信息 + * + * @param id 员工ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtStaff queryStaffById(Integer id) { + if (id == null || id <= 0) { + return null; + } + return mtStaffMapper.selectById(id); + } + + /** + * 修改店铺员工状态 + * + * @param staffId 员工ID + * @param status 状态 + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "修改店铺员工状态") + public Integer updateAuditedStatus(Integer staffId, String status, String operator) throws BusinessCheckException { + MtStaff mtStaff = mtStaffMapper.selectById(staffId); + if (mtStaff != null) { + mtStaff.setAuditedStatus(status); + mtStaff.setUpdateTime(new Date()); + mtStaff.setAuditedTime(new Date()); + mtStaffMapper.updateById(mtStaff); + + // 发送短信通知 + MtStore mtStore = storeService.queryStoreById(mtStaff.getStoreId()); + if (mtStore == null) { + mtStore = new MtStore(); + mtStore.setName("全部店铺"); + } + List mobileList = new ArrayList<>(); + mobileList.add(mtStaff.getMobile()); + + try { + Map params = new HashMap<>(); + params.put("name", mtStaff.getRealName()); + params.put("storeId", mtStaff.getStoreId().toString()); + sendSmsService.sendSms(mtStaff.getMerchantId(), "confirmer-authed", mobileList, params); + } catch (Exception e) { + logger.error("修改店铺员工状态发送短信出错:", e.getMessage()); + } + } else { + return 0; + } + + return staffId; + } + + /** + * 根据条件搜索员工 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryStaffByParams(Map params) { + if (params == null) { + params = new HashMap<>(); + } + return mtStaffMapper.selectByMap(params); + } + + /** + * 根据手机号获取员工信息 + * + * @param mobile 手机号 + * @throws BusinessCheckException + * @return + */ + @Override + public MtStaff queryStaffByMobile(String mobile) { + if (StringUtil.isBlank(mobile)) { + return null; + } + return mtStaffMapper.queryStaffByMobile(mobile); + } + + /** + * 根据会员ID获取员工信息 + * + * @param userId 会员ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtStaff queryStaffByUserId(Integer userId) { + return mtStaffMapper.queryStaffByUserId(userId); + } + + /** + * 根据手机号获取员工信息 + * + * @param mobile 手机号 + * @throws BusinessCheckException + * @return + */ + @Override + public StaffDto getStaffInfoByMobile(String mobile) throws BusinessCheckException { + MtStaff mtStaff = mtStaffMapper.queryStaffByMobile(mobile); + StaffDto staffDto = new StaffDto(); + if (mtStaff != null) { + BeanUtils.copyProperties(mtStaff, staffDto); + if (staffDto.getStoreId() != null && staffDto.getStoreId() > 0) { + MtStore mtStore = storeService.queryStoreById(staffDto.getStoreId()); + if (mtStore != null) { + staffDto.setStoreInfo(mtStore); + } + } + if (staffDto.getMerchantId() != null && staffDto.getMerchantId() > 0) { + MtMerchant mtMerchant = merchantService.getById(staffDto.getMerchantId()); + if (mtMerchant != null) { + staffDto.setMerchantInfo(mtMerchant); + } + } + } else { + return null; + } + return staffDto; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/StockServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/StockServiceImpl.java new file mode 100644 index 0000000..f03a825 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/StockServiceImpl.java @@ -0,0 +1,257 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.StockGoodsDto; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.*; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.*; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.*; + +/** + * 库存业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class StockServiceImpl extends ServiceImpl implements StockService { + + private MtStockMapper mtStockMapper; + + private MtStockItemMapper mtStockItemMapper; + + private MtGoodsMapper mtGoodsMapper; + + private MtGoodsSkuMapper mtGoodsSkuMapper; + + /** + * 分页查询库存管理记录列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryStockListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtStock::getStatus, StatusEnum.DISABLE.getKey()); + + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtStock::getStatus, status); + } + String type = paginationRequest.getSearchParams().get("type") == null ? "" : paginationRequest.getSearchParams().get("type").toString(); + if (StringUtils.isNotBlank(type)) { + lambdaQueryWrapper.eq(MtStock::getType, type); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtStock::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtStock::getStoreId, storeId); + } + String description = paginationRequest.getSearchParams().get("description") == null ? "" : paginationRequest.getSearchParams().get("description").toString(); + if (StringUtils.isNotBlank(description)) { + lambdaQueryWrapper.like(MtStock::getDescription, description); + } + + lambdaQueryWrapper.orderByDesc(MtStock::getId); + List dataList = mtStockMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtStock.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 新增库存管理记录 (操作库存) + * + * @param stockParam 库存参数 + * @param goodsList 商品列表 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增库存管理记录") + public ResponseObject addStock(MtStock stockParam, List goodsList) throws BusinessCheckException { + MtStock mtStock = new MtStock(); + mtStock.setMerchantId(stockParam.getMerchantId()); + mtStock.setStoreId(stockParam.getStoreId()); + mtStock.setStatus(StatusEnum.ENABLED.getKey()); + mtStock.setType(stockParam.getType()); + Date createTime = new Date(); + mtStock.setCreateTime(createTime); + mtStock.setUpdateTime(createTime); + mtStock.setDescription(stockParam.getDescription()); + mtStock.setOperator(stockParam.getOperator()); + this.save(mtStock); + + Integer stockId = mtStock.getId(); + for (StockGoodsDto goods : goodsList) { + MtStockItem mtStockItem = new MtStockItem(); + mtStockItem.setStockId(stockId); + Integer goodsId = goods.getId(); + Integer skuId = goods.getSkuId(); + Double num = goods.getNum(); + mtStockItem.setGoodsId(goodsId); + if (goods.getSkuId() != null) { + mtStockItem.setSkuId(skuId); + } + mtStockItem.setStatus(StatusEnum.ENABLED.getKey()); + mtStockItem.setNum(num); + mtStockItem.setCreateTime(createTime); + mtStockItem.setUpdateTime(createTime); + mtStockItemMapper.insert(mtStockItem); + + // 库存操作 + MtGoods goodsInfo = mtGoodsMapper.selectById(goodsId); + if (goodsInfo.getIsSingleSpec().equals(YesOrNoEnum.YES.getKey())) { + // 单规格库存 + Double stock; + if (mtStock.getType().equals("increase")) { + stock = goodsInfo.getStock() + num; + } else { + stock = goodsInfo.getStock() - num; + } + if (stock < 0) { + throw new BusinessCheckException("商品“" + goodsInfo.getName() + "”库存不足,提交失败"); + } + goodsInfo.setStock(stock); + mtGoodsMapper.updateById(goodsInfo); + } else { + // 多规格库存 + MtGoodsSku mtGoodsSku = mtGoodsSkuMapper.selectById(skuId); + if (mtGoodsSku != null) { + Double stock; + if (mtStock.getType().equals("increase")) { + stock = mtGoodsSku.getStock() + num; + } else { + stock = mtGoodsSku.getStock() - num; + } + if (stock < 0) { + throw new BusinessCheckException("商品sku编码“" + mtGoodsSku.getSkuNo() +"”库存不足,提交失败"); + } + mtGoodsSku.setStock(stock); + mtGoodsSkuMapper.updateById(mtGoodsSku); + } + } + } + return new ResponseObject(200, "", mtStock); + } + + /** + * 删除库存管理记录 + * + * @param id ID + * @param operator 操作人 + * @throws BusinessCheckException + * @return + */ + @Override + @OperationServiceLog(description = "删除库存管理记录") + public void delete(Integer id, String operator) throws BusinessCheckException { + MtStock mtStock = mtStockMapper.selectById(id); + if (mtStock == null) { + return; + } + mtStock.setStatus(StatusEnum.DISABLE.getKey()); + mtStock.setUpdateTime(new Date()); + mtStock.setOperator(operator); + this.updateById(mtStock); + } + + /** + * 根据ID获取库存管理记录 + * + * @param id ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtStock queryStockById(Long id) { + return mtStockMapper.selectById(id.intValue()); + } + + /** + * 根据条件查询库存项 + * + * @param params 查询条件 + * @return + * */ + @Override + public List queryItemByParams(Map params) { + if (params == null) { + params = new HashMap<>(); + } + return mtStockItemMapper.selectByMap(params); + } + + /** + * 生成出入库记录 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param goodsId 商品ID + * @param skuId 商品SKU ID + * @param type 类型,increase:入库,reduce:出库 + * @param num 数量 + * @param description 说明 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean addStockRecord(Integer merchantId, Integer storeId, Integer goodsId, Integer skuId, String type, Double num, String description) { + MtStock mtStock = new MtStock(); + mtStock.setMerchantId(merchantId); + mtStock.setStoreId(storeId); + mtStock.setStatus(StatusEnum.ENABLED.getKey()); + mtStock.setType(type); + Date createTime = new Date(); + mtStock.setCreateTime(createTime); + mtStock.setUpdateTime(createTime); + mtStock.setDescription(description); + mtStockMapper.insert(mtStock); + // 生成库存明细 + MtStockItem mtStockItem = new MtStockItem(); + mtStockItem.setStockId(mtStock.getId()); + mtStockItem.setGoodsId(goodsId); + if (skuId != null) { + mtStockItem.setSkuId(skuId); + } + mtStockItem.setStatus(StatusEnum.ENABLED.getKey()); + mtStockItem.setNum(num); + mtStockItem.setDescription(description); + mtStockItem.setCreateTime(createTime); + mtStockItem.setUpdateTime(createTime); + mtStockItemMapper.insert(mtStockItem); + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/StoreServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/StoreServiceImpl.java new file mode 100644 index 0000000..5197af6 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/StoreServiceImpl.java @@ -0,0 +1,629 @@ +package com.fuint.common.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.dto.StoreDto; +import com.fuint.common.dto.StoreInfo; +import com.fuint.common.enums.QrCodeEnum; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.YesOrNoEnum; +import com.fuint.common.service.MerchantService; +import com.fuint.common.service.StoreService; +import com.fuint.common.service.WeixinService; +import com.fuint.common.util.CommonUtil; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.bean.StoreDistanceBean; +import com.fuint.repository.mapper.MtMerchantMapper; +import com.fuint.repository.mapper.MtStoreGoodsMapper; +import com.fuint.repository.mapper.MtStoreMapper; +import com.fuint.repository.model.MtMerchant; +import com.fuint.repository.model.MtStore; +import com.fuint.utils.HttpUtil; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.core.env.Environment; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.util.*; +import java.net.URL; +import java.net.URLConnection; + +/** + * 店铺管理业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class StoreServiceImpl extends ServiceImpl implements StoreService { + + private static final Logger logger = LoggerFactory.getLogger(StoreServiceImpl.class); + + /** + * 系统环境变量 + * */ + private Environment env; + + private MtStoreMapper mtStoreMapper; + + private MtMerchantMapper mtMerchantMapper; + + private MtStoreGoodsMapper mtStoreGoodsMapper; + + /** + * 商户接口 + */ + private MerchantService merchantService; + + /** + * 微信服务接口 + * */ + private WeixinService weixinService; + + /** + * 分页查询店铺列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryStoreListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtStore::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtStore::getName, name); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtStore::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtStore::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtStore::getId, storeId); + } + + lambdaQueryWrapper.orderByAsc(MtStore::getStatus).orderByDesc(MtStore::getIsDefault); + List storeList = mtStoreMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + for (MtStore mtStore : storeList) { + StoreDto storeDto = new StoreDto(); + BeanUtils.copyProperties(mtStore, storeDto); + storeDto.setPhone(CommonUtil.hidePhone(mtStore.getPhone())); + MtMerchant mtMerchant = mtMerchantMapper.selectById(mtStore.getMerchantId()); + if (mtMerchant != null) { + storeDto.setMerchantName(mtMerchant.getName()); + } + dataList.add(storeDto); + } + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, StoreDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 保存店铺信息 + * + * @param storeDto 店铺信息 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "保存店铺信息") + public MtStore saveStore(StoreDto storeDto) throws BusinessCheckException { + MtStore mtStore = new MtStore(); + + // 编辑店铺 + if (storeDto.getId() != null) { + mtStore = queryStoreById(storeDto.getId()); + if (mtStore == null) { + throw new BusinessCheckException("该店铺不存在"); + } + } + + mtStore.setName(storeDto.getName()); + mtStore.setLogo(storeDto.getLogo()); + mtStore.setContact(storeDto.getContact()); + mtStore.setOperator(storeDto.getOperator()); + if (storeDto.getWxMchId() != null) { + mtStore.setWxMchId(storeDto.getWxMchId()); + } + if (storeDto.getWxApiV2() != null) { + mtStore.setWxApiV2(storeDto.getWxApiV2()); + } + if (storeDto.getWxCertPath() != null) { + mtStore.setWxCertPath(storeDto.getWxCertPath()); + } + if (storeDto.getAlipayAppId() != null) { + mtStore.setAlipayAppId(storeDto.getAlipayAppId()); + } + if (storeDto.getAlipayPrivateKey() != null) { + mtStore.setAlipayPrivateKey(storeDto.getAlipayPrivateKey()); + } + if (storeDto.getAlipayPublicKey() != null) { + mtStore.setAlipayPublicKey(storeDto.getAlipayPublicKey()); + } + mtStore.setLicense(storeDto.getLicense()); + mtStore.setCreditCode(storeDto.getCreditCode()); + mtStore.setBankName(storeDto.getBankName()); + mtStore.setBankCardName(storeDto.getBankCardName()); + mtStore.setBankCardNo(storeDto.getBankCardNo()); + mtStore.setUpdateTime(new Date()); + if (storeDto.getId() == null) { + mtStore.setCreateTime(new Date()); + } + mtStore.setDescription(storeDto.getDescription()); + mtStore.setPhone(storeDto.getPhone()); + + if (storeDto.getIsDefault() != null) { + if (storeDto.getIsDefault().equals(YesOrNoEnum.YES.getKey())) { + mtStoreMapper.resetDefaultStore(storeDto.getMerchantId()); + } + } + + mtStore.setIsDefault(storeDto.getIsDefault()); + mtStore.setAddress(storeDto.getAddress()); + mtStore.setHours(storeDto.getHours()); + + if (StringUtil.isNotBlank(storeDto.getLatitude()) && StringUtil.isNotBlank(storeDto.getLongitude())) { + boolean isValid = CommonUtil.isValidGlobalCoordinate(Double.parseDouble(storeDto.getLongitude()), Double.parseDouble(storeDto.getLatitude())); + if (!isValid) { + throw new BusinessCheckException("店铺经纬度格式不正确,请确认!"); + } else { + mtStore.setLatitude(storeDto.getLatitude()); + mtStore.setLongitude(storeDto.getLongitude()); + } + } + mtStore.setStatus(storeDto.getStatus()); + if (storeDto.getMerchantId() != null) { + mtStore.setMerchantId(storeDto.getMerchantId()); + } + + if (mtStore.getStatus() == null) { + mtStore.setStatus(StatusEnum.ENABLED.getKey()); + } + if (mtStore.getId() == null || mtStore.getId() < 1) { + this.save(mtStore); + } else { + mtStoreMapper.updateById(mtStore); + } + + // 保存二维码 + try { + String page = QrCodeEnum.STORE.getPage() + "?" + QrCodeEnum.STORE.getKey() + "Id=" + mtStore.getId(); + String qr = weixinService.createQrCode(mtStore.getMerchantId(), QrCodeEnum.STORE.getKey(), mtStore.getId(), page, 320); + mtStore.setQrCode(qr); + } catch (Exception e) { + logger.error(e.getMessage()); + } + + mtStoreMapper.updateById(mtStore); + return mtStore; + } + + /** + * 根据店铺ID获取店铺信息 + * + * @param id 店铺ID + * @throws BusinessCheckException + * @return + */ + @Override + public MtStore queryStoreById(Integer id) { + if (id == null || id < 1) { + return null; + } + return mtStoreMapper.selectById(id); + } + + /** + * 获取系统默认店铺 + * + * @param merchantNo 商户号 + * @return + */ + @Override + public MtStore getDefaultStore(String merchantNo) { + Map params = new HashMap<>(); + params.put("status", StatusEnum.ENABLED.getKey()); + params.put("is_default", YesOrNoEnum.YES.getKey()); + if (StringUtil.isNotEmpty(merchantNo)) { + MtMerchant mtMerchant = merchantService.queryMerchantByNo(merchantNo); + if (mtMerchant != null) { + params.put("merchantId", mtMerchant.getId()); + } + } + List storeList = queryStoresByParams(params); + if (storeList.size() > 0) { + return storeList.get(0); + } else { + Map param = new HashMap<>(); + param.put("status", StatusEnum.ENABLED.getKey()); + List dataList = queryStoresByParams(param); + if (dataList.size() > 0) { + return dataList.get(0); + } else { + return null; + } + } + } + + /** + * 根据店铺名称获取店铺信息 + * + * @param storeName 店铺名称 + * @return + */ + @Override + public StoreDto queryStoreByName(String storeName) { + MtStore mtStore = mtStoreMapper.queryStoreByName(storeName); + StoreDto storeDto = null; + + if (mtStore != null) { + storeDto = new StoreDto(); + BeanUtils.copyProperties(mtStore, storeDto); + } + + return storeDto; + } + + /** + * 根据店铺ID获取店铺信息 + * + * @param id 店铺ID + * @throws BusinessCheckException + * @return + */ + @Override + public StoreDto queryStoreDtoById(Integer id) throws BusinessCheckException { + MtStore mtStore = queryStoreById(id); + if (null == mtStore || StatusEnum.DISABLE.getKey().equals(mtStore.getStatus())) { + throw new BusinessCheckException("该店铺状态异常"); + } + + StoreDto mtStoreDto = new StoreDto(); + BeanUtils.copyProperties(mtStore, mtStoreDto); + + if (StringUtil.isEmpty(mtStore.getQrCode())) { + try { + String page = QrCodeEnum.STORE.getPage() + "?" + QrCodeEnum.STORE.getKey() + "Id = " + mtStore.getId(); + String qr = weixinService.createQrCode(mtStore.getMerchantId(), QrCodeEnum.STORE.getKey(), mtStore.getId(), page, 320); + mtStoreDto.setQrCode(qr); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + return mtStoreDto; + } + + /** + * 更新店铺状态 + * + * @param id 店铺ID + * @param operator 操作人 + * @param status 状态 + * @throws BusinessCheckException + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改店铺状态") + public void updateStatus(Integer id, String operator, String status) throws BusinessCheckException { + MtStore mtStore = queryStoreById(id); + if (null == mtStore) { + throw new BusinessCheckException("该店铺不存在."); + } + + mtStore.setStatus(status); + mtStore.setUpdateTime(new Date()); + mtStore.setOperator(operator); + + // 删除店铺 + if (status.equals(StatusEnum.DISABLE.getKey())) { + mtStoreGoodsMapper.removeStoreGoods(id); + } + + mtStoreMapper.updateById(mtStore); + } + + /** + * 根据条件查询店铺列表 + * + * @param params 查询参数 + * @return + * */ + @Override + public List queryStoresByParams(Map params) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtStore::getStatus, StatusEnum.DISABLE.getKey()); + + String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtStore::getId, storeId); + } + + String name = params.get("name") == null ? "" : params.get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtStore::getName, name); + } + String status = params.get("status") == null ? "" : params.get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtStore::getStatus, status); + } + String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtStore::getMerchantId, merchantId); + } + + lambdaQueryWrapper.orderByAsc(MtStore::getStatus).orderByDesc(MtStore::getIsDefault); + return mtStoreMapper.selectList(lambdaQueryWrapper); + } + + /** + * 获取我的店铺列表 + * + * @param merchantId 商户ID + * @param storeId 店铺ID + * @param status 状态 + * @return + * */ + @Override + public List getMyStoreList(Integer merchantId, Integer storeId, String status) { + return mtStoreMapper.getMyStoreList(merchantId, storeId, status); + } + + /** + * 根据距离远近获取店铺列表 + * + * @param merchantNo 商户号 + * @param keyword 关键字 + * @param latitude 维度 + * @param longitude 经度 + * @return + * */ + @Override + public List queryByDistance(String merchantNo, String keyword, String latitude, String longitude) { + List dataList = new ArrayList<>(); + + MtMerchant mtMerchant = merchantService.queryMerchantByNo(merchantNo); + Integer merchantId = (mtMerchant == null) ? 0 : mtMerchant.getId(); + + List distanceList = mtStoreMapper.queryByDistance(merchantId, keyword, latitude, longitude); + Map param = new HashMap<>(); + param.put("status", StatusEnum.ENABLED.getKey()); + if (merchantId != null && merchantId > 0) { + param.put("merchant_id", merchantId); + } + List storeList = mtStoreMapper.selectByMap(param); + + if (distanceList != null) { + for (StoreDistanceBean bean : distanceList) { + for (MtStore mtStore : storeList) { + if (mtStore.getId().equals(bean.getId())) { + if (StringUtil.isNotEmpty(latitude) && StringUtil.isNotEmpty(longitude)) { + mtStore.setDistance(new BigDecimal(bean.getDistance())); + } else { + mtStore.setDistance(new BigDecimal("0.0")); + } + StoreInfo storeInfo = new StoreInfo(); + BeanUtils.copyProperties(mtStore, storeInfo); + dataList.add(storeInfo); + } + } + } + } + + return dataList; + } + + /** + * 获取店铺名称 + * + * @param storeIds 店铺ID + * @return + * */ + @Override + public String getStoreNames(String storeIds) { + if (StringUtil.isEmpty(storeIds)) { + return ""; + } + String[] ids = storeIds.split(","); + List storeNames = new ArrayList<>(); + if (ids.length > 0) { + for (int i = 0; i < ids.length; i++) { + MtStore mtStore = mtStoreMapper.selectById(Integer.parseInt(ids[i])); + if (mtStore != null) { + storeNames.add(mtStore.getName()); + } + } + } + return String.join(",", storeNames); + } + + /** + * 获取店铺名称 + * + * @param merchantId 商户ID + * @param storeNames 店铺名称 + * @return + * */ + @Override + public String getStoreIds(Integer merchantId, String storeNames) { + if (StringUtil.isEmpty(storeNames)) { + return ""; + } + String[] names = storeNames.split(","); + List storeIds = new ArrayList<>(); + if (names.length > 0) { + for (int i = 0; i < names.length; i++) { + MtStore mtStore = mtStoreMapper.queryStoreByName(names[i]); + if (mtStore != null) { + storeIds.add(mtStore.getId().toString()); + } + } + } + return String.join(",", storeIds); + } + + /** + * 根据商户ID删除店铺信息 + * + * @param merchantId 商户ID + * @return + * */ + @Override + public void deleteStoreByMerchant(Integer merchantId) { + if (merchantId == null || merchantId <= 0) { + return; + } + mtStoreMapper.deleteStoreByMerchant(merchantId); + } + + /** + * 根据地址获取经纬度 + * + * @param addr 地址 + * @return + * */ + public Map getLatAndLngByAddress(String addr) { + String key = env.getProperty("amap.key"); + Map map = new HashMap<>(); + if (StringUtil.isEmpty(key) || key.length() < 10) { + map.put("lat", ""); + map.put("lng", ""); + return map; + } + + String address = ""; + try { + address = java.net.URLEncoder.encode(addr,"UTF-8"); + } catch (UnsupportedEncodingException e1) { + e1.printStackTrace(); + } + + // key如果失效了就去高德地图官网申请 + String url = "https://restapi.amap.com/v3/geocode/geo?address="+address+"&output=JSON&key="+key; + + URL myURL = null; + URLConnection httpsConn; + // 进行转码 + try { + myURL = new URL(url); + } catch (MalformedURLException e) { + // empty + } + StringBuffer sb = new StringBuffer(); + try { + httpsConn = myURL.openConnection(); + if (httpsConn != null) { + InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8"); + BufferedReader br = new BufferedReader(insr); + String data = null; + while ((data = br.readLine()) != null) { + sb.append(data); + } + insr.close(); + } + } catch (IOException e) { + logger.error("根据地址获取经纬度失败:{}", e.getMessage()); + } + + JSONObject resultJson = JSON.parseObject(sb.toString()); + JSONArray geocodes = resultJson.getJSONArray("geocodes"); + + String lat = ""; + String lng = ""; + + if (geocodes != null) { + JSONObject jsonObject = geocodes.getJSONObject(0); + String location = jsonObject.getString("location"); + if (org.apache.commons.lang.StringUtils.isNotEmpty(location)) { + String latAndLng[] = location.split(","); + if (latAndLng.length == 2) { + lat = latAndLng[1]; + lng = latAndLng[0]; + } + } + } + + map.put("lat", lat); + map.put("lng", lng); + + return map; + } + + /** + * 测量步行距离 + * + * @param origin 起点经纬度 格式如:116.434446,39.90816 + * @param destination 终点经纬度 格式如:116.434307,39.90909 + * @return + * */ + public Double getDistance(String origin, String destination) { + String key = env.getProperty("amap.key"); + if (StringUtil.isEmpty(key)) { + return 0d; + } + String url = "https://restapi.amap.com/v3/direction/walking?origin="+origin+"&destination="+destination+"&key="+key; + String response = HttpUtil.sendRequest(url); + if (StringUtil.isEmpty(response)) { + return 0d; + } + JSONObject resultJson = JSON.parseObject(response); + if (resultJson != null && "1".equals(resultJson.getString("status"))) { + JSONObject route = resultJson.getJSONObject("route"); + if (route != null) { + JSONArray paths = route.getJSONArray("paths"); + if (paths != null && paths.size() > 0) { + JSONObject path = paths.getJSONObject(0); + String distance = path.getString("distance"); + if (distance != null) { + return Double.parseDouble(distance)/1000; + } + } + } + + } + return 0d; + } + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/UnionPayServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/UnionPayServiceImpl.java new file mode 100644 index 0000000..86d56f3 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/UnionPayServiceImpl.java @@ -0,0 +1,271 @@ +package com.fuint.common.service.impl; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradeQueryModel; +import com.alipay.api.domain.AlipayTradeRefundModel; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.response.AlipayTradeQueryResponse; +import com.alipay.api.response.AlipayTradeRefundResponse; +import com.ijpay.unionpay.UnionPayApi; +import com.fuint.common.bean.UnionPayBean; +import com.fuint.common.dto.OrderDto; +import com.fuint.common.dto.UserOrderDto; +import com.fuint.common.enums.*; +import com.fuint.common.service.*; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.ijpay.alipay.AliPayApi; +import com.ijpay.alipay.AliPayApiConfig; +import com.ijpay.alipay.AliPayApiConfigKit; +import com.ijpay.core.enums.SignType; +import com.ijpay.core.kit.WxPayKit; +import com.ijpay.unionpay.enums.ServiceEnum; +import com.ijpay.unionpay.model.MicroPayModel; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.*; + +/** + * 云闪付相关接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class UnionPayServiceImpl implements UnionPayService { + + private static final Logger logger = LoggerFactory.getLogger(UnionPayServiceImpl.class); + + private UnionPayBean unionPayBean; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 创建预支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP地址 + * @param platform 支付平台 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform) throws BusinessCheckException { + logger.info("UnionPayService createPrepayOrder inParams userInfo={} payAmount={} giveAmount={} goodsInfo={}", userInfo, payAmount, giveAmount, orderInfo); + + String goodsInfo = orderInfo.getOrderSn(); + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + goodsInfo = OrderTypeEnum.PRESTORE.getValue(); + } + + // 更新支付金额 + BigDecimal payAmount1 = new BigDecimal(payAmount).divide(new BigDecimal("100")); + OrderDto reqDto = new OrderDto(); + reqDto.setId(orderInfo.getId()); + reqDto.setPayAmount(payAmount1); + reqDto.setPayType(orderInfo.getPayType()); + reqDto.setOrderSn(orderInfo.getOrderSn()); + orderService.updateOrder(reqDto); + + getApiConfig(orderInfo.getStoreId()); + Map params = MicroPayModel.builder() + .service(ServiceEnum.MICRO_PAY.toString()) + .mch_id(unionPayBean.getMachId()) + .out_trade_no(WxPayKit.generateStr()) + .body(goodsInfo) + .attach("云闪付支付") + .total_fee(payAmount1.toString()) + .mch_create_ip(ip) + .auth_code(authCode) + .nonce_str(WxPayKit.generateStr()) + .build() + .createSign(unionPayBean.getKey(), SignType.MD5); + String returnCode = "0"; + try { + String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params); + Map result = WxPayKit.xmlToMap(xmlResult); + returnCode = result.get("status"); + String resultCode = result.get("result_code"); + String errMsg = result.get("err_msg"); + String errCode = result.get("err_code"); + + logger.info("UnionPayService createPrepayOrder xmlResult: {} ", xmlResult); + if (!"0".equals(returnCode) || !"0".equals(resultCode)) { + if (returnCode.equals("10003")) { + // 需要会员输入支付密码,等待10秒后查询订单 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Map payResult = queryPaidOrder(orderInfo.getStoreId(), "云闪付单号", orderInfo.getOrderSn()); + if (payResult == null) { + throw new BusinessCheckException("云闪付支付失败"); + } + } else { + throw new BusinessCheckException("云闪付支付出错:" + errCode + errMsg); + } + } + } catch (Exception e) { + logger.error("UnionPayService createPrepayOrder exception {}", e.getMessage()); + throw new BusinessCheckException("云闪付支付出错,请检查配置项"); + } + + Map respData = new HashMap<>(); + respData.put("result", returnCode); + + ResponseObject responseObject = new ResponseObject(200, "云闪付支付接口返回成功", respData); + logger.info("UnionPayService createPrepayOrder outParams {}", responseObject.toString()); + + return responseObject; + } + + /** + * 支付回调 + * + * @param params 请求参数 + * @return + * */ + @Override + public Boolean checkCallBack(Map params) throws Exception { + String orderSn = params.get("out_trade_no") != null ? params.get("out_trade_no") : ""; + Integer storeId = 0; + UserOrderDto orderDto = orderService.getOrderByOrderSn(orderSn); + if (orderDto != null && orderDto.getStoreInfo() != null) { + storeId = orderDto.getStoreInfo().getId(); + } + getApiConfig(storeId); + return AlipaySignature.rsaCheckV1(params, unionPayBean.getKey(), "UTF-8", "RSA2"); + } + + /** + * 获取支付配置 + * + * @param storeId 店铺ID + * @return + * */ + public AliPayApiConfig getApiConfig(Integer storeId) throws BusinessCheckException { + AliPayApiConfig aliPayApiConfig; + String appId = unionPayBean.getMachId(); + String privateKey = unionPayBean.getMachId(); + String publicKey = unionPayBean.getKey(); + + // 优先读取店铺的支付账号 + MtStore mtStore = storeService.queryStoreById(storeId); + if (mtStore != null && StringUtil.isNotEmpty(mtStore.getAlipayAppId()) && StringUtil.isNotEmpty(mtStore.getAlipayPrivateKey()) && StringUtil.isNotEmpty(mtStore.getAlipayPublicKey())) { + appId = mtStore.getAlipayAppId(); + privateKey = mtStore.getAlipayPrivateKey(); + publicKey = mtStore.getAlipayPublicKey(); + } + + aliPayApiConfig = AliPayApiConfig.builder() + .setAppId(appId) + .setAliPayPublicKey(publicKey) + .setCharset("UTF-8") + .setPrivateKey(privateKey) + .setServiceUrl(unionPayBean.getServerUrl()) + .setSignType("RSA2") + .build(); + + AliPayApiConfigKit.setThreadLocalAppId(appId); + AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig); + + return aliPayApiConfig; + } + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param tradeNo 交易单号 + * @param orderSn 订单号 + * @return + * */ + @Override + public Map queryPaidOrder(Integer storeId, String tradeNo, String orderSn) throws BusinessCheckException { + try { + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + if (StringUtil.isNotEmpty(orderSn)) { + model.setOutTradeNo(orderSn); + } + if (StringUtil.isNotEmpty(tradeNo)) { + model.setTradeNo(tradeNo); + } + getApiConfig(storeId); + AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(model); + if (response != null) { + // TradeStatus:TRADE_SUCCESS(交易支付成功,可进行退款)或 TRADE_FINISHED(交易结束,不可退款) + if (response.getTradeStatus() != null && response.getTradeStatus().equals("TRADE_SUCCESS")) { + Map result = new HashMap<>(); + result.put("tradeNo", response.getTradeNo()); + result.put("status", response.getTradeStatus()); + result.put("payAmount", response.getBuyerPayAmount()); + return result; + } + } + } catch (AlipayApiException e) { + logger.info("UnionPayService queryPaidOrder response", e.getMessage()); + } + + return null; + } + + /** + * 发起售后退款 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 订单总金额 + * @param refundAmount 售后金额 + * @param platform 订单平台 + * @return + * */ + public Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException { + try { + logger.info("UnionPayService.doRefund orderSn = {}, totalFee = {}, refundFee = {}", orderSn, totalAmount, refundAmount); + if (StringUtil.isEmpty(orderSn)) { + throw new BusinessCheckException("退款订单号不能为空..."); + } + if (refundAmount.compareTo(totalAmount) > 0) { + throw new BusinessCheckException("退款金额不能大于总金额..."); + } + getApiConfig(storeId); + AlipayTradeRefundModel model = new AlipayTradeRefundModel(); + model.setOutTradeNo(orderSn); + model.setRefundAmount(refundAmount.toString()); + model.setRefundReason("申请退款"); + AlipayTradeRefundResponse refundResponse = AliPayApi.tradeRefundToResponse(model); + String code = refundResponse.getCode(); + String msg = refundResponse.getMsg(); + String subMsg = refundResponse.getSubMsg() == null ? msg : refundResponse.getSubMsg(); + logger.info("UnionPayService refundResult response Body = {}", refundResponse.getBody()); + if (!code.equals("10000") || !msg.equalsIgnoreCase("Success")) { + throw new BusinessCheckException("云闪付退款失败," + subMsg); + } + } catch (AlipayApiException e) { + logger.error("UnionPayService.doRefund error = {}", e.getMessage()); + e.printStackTrace(); + } + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/UploadServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/UploadServiceImpl.java new file mode 100644 index 0000000..08d7386 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/UploadServiceImpl.java @@ -0,0 +1,74 @@ +package com.fuint.common.service.impl; + +import com.fuint.common.service.UploadService; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.utils.StringUtil; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.Date; + +/** + * 文件上传服务类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class UploadServiceImpl implements UploadService { + + private static final Logger logger = LoggerFactory.getLogger(UploadServiceImpl.class); + + /** + * 环境变量 + * */ + private Environment env; + + /** + * 保存文件 + * + * @param file excel文件 + * @param request + * @return + * */ + public String saveUploadFile(HttpServletRequest request, MultipartFile file) throws Exception { + if (file == null) { + throw new BusinessCheckException("上传文件出错!"); + } + String fileName = file.getOriginalFilename(); + String uploadPath = fileName.substring(fileName.lastIndexOf(".")); + String pathRoot = env.getProperty("images.root"); + if (pathRoot == null || StringUtil.isEmpty(pathRoot)) { + pathRoot = ResourceUtils.getURL("classpath:").getPath(); + } + String uuid = SeqUtil.getUUID(); + + String filePath = "/static/uploadFiles/"+ DateUtil.formatDate(new Date(), "yyyyMMdd")+"/"; + String path = filePath + uuid + uploadPath; + + try { + File tempFile = new File(pathRoot + path); + if (!tempFile.getParentFile().exists()) { + tempFile.getParentFile().mkdirs(); + } + CommonUtil.saveMultipartFile(file, pathRoot + path); + } catch (Exception e) { + logger.error("上传文件保存出错:", e.getMessage()); + } + + return path; + } + +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/UserActionServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/UserActionServiceImpl.java new file mode 100644 index 0000000..571994f --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/UserActionServiceImpl.java @@ -0,0 +1,147 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.service.UserActionService; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtUserActionMapper; +import com.fuint.repository.model.MtUserAction; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 会员行为业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class UserActionServiceImpl extends ServiceImpl implements UserActionService { + + private MtUserActionMapper mtUserActionMapper; + + /** + * 分页查询会员行为记录列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryUserActionListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUserAction::getStatus, StatusEnum.DISABLE.getKey()); + + String description = paginationRequest.getSearchParams().get("description") == null ? "" : paginationRequest.getSearchParams().get("description").toString(); + if (StringUtils.isNotBlank(description)) { + lambdaQueryWrapper.like(MtUserAction::getDescription, description); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtUserAction::getMerchantId, merchantId); + } + String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString(); + if (StringUtils.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtUserAction::getStoreId, storeId); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtUserAction::getStatus, status); + } + + lambdaQueryWrapper.orderByDesc(MtUserAction::getId); + List dataList = mtUserActionMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtUserAction.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 新增会员行为 + * + * @param reqUserAction 会员行为 + * @return + */ + @Override + public boolean addUserAction(MtUserAction reqUserAction) { + if (reqUserAction.getAction() == null || reqUserAction.getUserId() == null) { + return false; + } + + Map params = new HashMap<>(); + params.put("USER_ID", reqUserAction.getUserId()); + params.put("action", reqUserAction.getAction()); + if (reqUserAction.getParam() != null) { + params.put("param", reqUserAction.getParam()); + } + + List dataList = mtUserActionMapper.selectByMap(params); + + // 防止重复 + if (dataList.size() == 0) { + MtUserAction mtUserAction = new MtUserAction(); + mtUserAction.setAction(reqUserAction.getAction()); + mtUserAction.setUserId(reqUserAction.getUserId()); + mtUserAction.setMerchantId(reqUserAction.getMerchantId()); + mtUserAction.setStoreId(reqUserAction.getStoreId()); + mtUserAction.setParam(reqUserAction.getParam()); + mtUserAction.setOperator(reqUserAction.getOperator()); + mtUserAction.setDescription(reqUserAction.getDescription()); + mtUserAction.setStatus(StatusEnum.ENABLED.getKey()); + mtUserAction.setCreateTime(new Date()); + mtUserAction.setUpdateTime(new Date()); + mtUserActionMapper.insert(mtUserAction); + } + + return true; + } + + /** + * 根据ID获取信息 + * + * @param id + * @return + */ + @Override + public MtUserAction getUserActionDetail(Integer id) { + return mtUserActionMapper.selectById(id); + } + + /** + * 根据ID删除 + * + * @param id + * @param operator 操作人 + * @return + */ + @Override + public void deleteUserAction(Integer id, String operator) { + MtUserAction mtUserAction = this.getUserActionDetail(id); + if (mtUserAction == null) { + return; + } + mtUserAction.setStatus(StatusEnum.DISABLE.getKey()); + mtUserAction.setUpdateTime(new Date()); + mtUserActionMapper.updateById(mtUserAction); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/UserCouponServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/UserCouponServiceImpl.java new file mode 100644 index 0000000..ce92f6b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/UserCouponServiceImpl.java @@ -0,0 +1,766 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.Constants; +import com.fuint.common.config.Message; +import com.fuint.common.dto.CouponDto; +import com.fuint.common.dto.MyCouponDto; +import com.fuint.common.enums.*; +import com.fuint.common.param.CouponReceiveParam; +import com.fuint.common.service.*; +import com.fuint.common.util.CommonUtil; +import com.fuint.common.util.DateUtil; +import com.fuint.common.util.SeqUtil; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.framework.web.ResponseObject; +import com.fuint.repository.mapper.MtUserCouponMapper; +import com.fuint.repository.model.*; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.*; + +/** + * 会员卡券业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class UserCouponServiceImpl extends ServiceImpl implements UserCouponService { + + private MtUserCouponMapper mtUserCouponMapper; + + /** + * 卡券服务接口 + * */ + private CouponService couponService; + + /** + * 卡券分组服务接口 + * */ + private CouponGroupService couponGroupService; + + /** + * 会员服务接口 + * */ + private MemberService memberService; + + /** + * 积分服务接口 + * */ + private PointService pointService; + + /** + * 卡券核销记录服务接口 + * */ + private ConfirmLogService confirmLogService; + + /** + * 店铺服务接口 + * */ + private StoreService storeService; + + /** + * 系统设置服务接口 + * */ + private SettingService settingService; + + /** + * 订单服务接口 + * */ + private OrderService orderService; + + /** + * 分页查询券列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryUserCouponListByPagination(PaginationRequest paginationRequest) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUserCoupon::getStatus, StatusEnum.DISABLE.getKey()); + + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtUserCoupon::getStatus, status); + } + String userCouponId = paginationRequest.getSearchParams().get("userCouponId") == null ? "" : paginationRequest.getSearchParams().get("userCouponId").toString(); + if (StringUtils.isNotBlank(userCouponId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getId, userCouponId); + } + String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString(); + if (StringUtils.isNotBlank(userId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getUserId, userId); + } + String couponId = paginationRequest.getSearchParams().get("couponId") == null ? "" : paginationRequest.getSearchParams().get("couponId").toString(); + if (StringUtils.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getCouponId, couponId); + } + String code = paginationRequest.getSearchParams().get("code") == null ? "" : paginationRequest.getSearchParams().get("code").toString(); + if (StringUtils.isNotBlank(code)) { + lambdaQueryWrapper.eq(MtUserCoupon::getCode, code); + } + String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString(); + if (StringUtils.isNotBlank(mobile)) { + lambdaQueryWrapper.eq(MtUserCoupon::getMobile, mobile); + } + + lambdaQueryWrapper.orderByDesc(MtUserCoupon::getId); + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + List dataList = mtUserCouponMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtUserCoupon.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 领取卡券(优惠券、计次卡) + * + * @param receiveParam 领取参数 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean receiveCoupon(CouponReceiveParam receiveParam) throws BusinessCheckException { + Integer couponId = receiveParam.getCouponId() == null ? 0 : receiveParam.getCouponId(); + Integer userId = receiveParam.getUserId() == null ? 0 : receiveParam.getUserId(); + Integer num = receiveParam.getNum() == null ? 1 : receiveParam.getNum(); + String receiveCode = receiveParam.getReceiveCode() == null ? "" : receiveParam.getReceiveCode(); + Integer userCouponId = 0; + MtCoupon couponInfo = couponService.queryCouponById(couponId); + if (couponInfo == null) { + MtUserCoupon userCoupon = mtUserCouponMapper.findByCode(receiveCode); + if (userCoupon != null) { + if (userCoupon.getUserId() != null && userCoupon.getUserId() > 0) { + if (userCoupon.getUserId().compareTo(userId) == 0) { + throw new BusinessCheckException(Message.HAS_COUPON); + } else { + throw new BusinessCheckException(Message.CODE_ERROR); + } + } + couponInfo = couponService.queryCouponById(userCoupon.getCouponId()); + userCouponId = userCoupon.getId(); + } else { + throw new BusinessCheckException(Message.CODE_ERROR_1); + } + if (couponInfo == null) { + throw new BusinessCheckException(Message.COUPON_NOT_EXIST); + } + } + if (!couponInfo.getStatus().equals(StatusEnum.ENABLED.getKey())) { + throw new BusinessCheckException(Message.COUPON_NOT_EXIST); + } + + MtCouponGroup groupInfo = couponGroupService.queryCouponGroupById(couponInfo.getGroupId()); + MtUser userInfo = memberService.queryMemberById(userId); + if (null == userInfo) { + throw new BusinessCheckException(Message.USER_NOT_EXIST); + } + + // 校验后台领取 + if (couponInfo.getSendWay().equals(SendWayEnum.BACKEND.getKey())) { + throw new BusinessCheckException(Message.SEND_WAY_ERROR); + } + + // 会员等级限制 + if (couponInfo.getGradeIds() != null && StringUtil.isNotEmpty(couponInfo.getGradeIds())) { + String gradeIds[] = couponInfo.getGradeIds().split(","); + if (gradeIds.length > 0) { + boolean isContains = Arrays.asList(gradeIds).contains(userInfo.getGradeId()+""); + if (!isContains) { + throw new BusinessCheckException(Message.GRADE_ERROR); + } + } + } + + // 是否需要领取码 + if (couponInfo.getReceiveCode() != null && StringUtil.isNotEmpty(couponInfo.getReceiveCode())) { + if (StringUtil.isEmpty(receiveCode)) { + throw new BusinessCheckException(Message.NEED_CODE); + } + // 线下发放的领取码 + if (couponInfo.getSendWay().equals(SendWayEnum.OFFLINE.getKey())) { + MtUserCoupon userCoupon = mtUserCouponMapper.findByCode(receiveCode); + if (userCoupon == null || !userCoupon.getCode().equals(receiveCode)) { + throw new BusinessCheckException(Message.CODE_ERROR_1); + } else { + userCouponId = userCoupon.getId(); + } + } + // 前台领取的领取码 + if (couponInfo.getSendWay().equals(SendWayEnum.FRONT.getKey()) && !receiveCode.equals(couponInfo.getReceiveCode())) { + throw new BusinessCheckException(Message.CODE_ERROR); + } + } + + // 是否已经领取 + List statusList = Arrays.asList(UserCouponStatusEnum.UNUSED.getKey(), UserCouponStatusEnum.USED.getKey(), UserCouponStatusEnum.EXPIRE.getKey()); + List userCouponData = mtUserCouponMapper.getUserCouponListByCouponId(userId, couponId, statusList); + if ((userCouponData.size() >= couponInfo.getLimitNum()) && (couponInfo.getLimitNum() > 0)) { + throw new BusinessCheckException(Message.MAX_COUPON_LIMIT); + } + + // 积分不足以领取 + if (couponInfo.getPoint() != null && couponInfo.getPoint() > 0) { + if (userInfo.getPoint() < couponInfo.getPoint()) { + throw new BusinessCheckException(Message.POINT_LIMIT); + } + } + + // 可领取多张 + String uuid = SeqUtil.getRandomNumber(16); + for (int i = 1; i <= num; i++) { + MtUserCoupon userCoupon = new MtUserCoupon(); + if (userCouponId > 0) { + userCoupon = mtUserCouponMapper.selectById(userCouponId); + } + userCoupon.setMerchantId(userInfo.getMerchantId()); + userCoupon.setStoreId(couponInfo.getStoreId()); + userCoupon.setCouponId(couponInfo.getId()); + userCoupon.setType(couponInfo.getType()); + if (couponInfo.getAmount() != null && couponInfo.getAmount().compareTo(new BigDecimal("0")) > 0) { + userCoupon.setAmount(couponInfo.getAmount()); + } + userCoupon.setGroupId(groupInfo.getId()); + userCoupon.setMobile(userInfo.getMobile()); + userCoupon.setUserId(userInfo.getId()); + userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + userCoupon.setCreateTime(new Date()); + userCoupon.setUpdateTime(new Date()); + userCoupon.setExpireTime(couponInfo.getEndTime()); + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, couponInfo.getExpireTime()); + expireTime = c.getTime(); + userCoupon.setExpireTime(expireTime); + } + // 16位随机数核销码 + userCoupon.setCode(SeqUtil.getRandomNumber(16)); + userCoupon.setUuid(uuid); + if (userCoupon.getId() != null) { + mtUserCouponMapper.updateById(userCoupon); + } else { + mtUserCouponMapper.insert(userCoupon); + } + } + + // 是否需要扣除相应积分 + if (couponInfo.getPoint() != null && couponInfo.getPoint() > 0) { + MtPoint reqPointDto = new MtPoint(); + reqPointDto.setUserId(userId); + reqPointDto.setAmount(-couponInfo.getPoint()); + reqPointDto.setDescription("领取"+ couponInfo.getName() + "扣除" +couponInfo.getPoint() +"积分"); + reqPointDto.setOperator(""); + pointService.addPoint(reqPointDto); + } + + return true; + } + + /** + * 储值卡券 + * + * @param paramMap 储值参数 + * @return + * */ + public boolean preStore(Map paramMap) throws BusinessCheckException { + Integer couponId = paramMap.get("couponId") == null ? 0 : Integer.parseInt(paramMap.get("couponId").toString()); + Integer userId = paramMap.get("userId") == null ? 0 : Integer.parseInt(paramMap.get("userId").toString()); + String param = paramMap.get("param") == null ? "" : paramMap.get("param").toString(); + Integer orderId = paramMap.get("orderId") == null ? 0 : Integer.parseInt(paramMap.get("orderId").toString()); + + if (StringUtil.isEmpty(param) || couponId <= 0 || userId <= 0) { + throw new BusinessCheckException(Message.PARAM_ERROR); + } + + MtCoupon couponInfo = couponService.queryCouponById(couponId); + if (couponInfo == null) { + throw new BusinessCheckException(Message.COUPON_NOT_EXIST); + } + + MtUser userInfo = memberService.queryMemberById(userId); + if (userInfo == null) { + throw new BusinessCheckException(Message.USER_NOT_EXIST); + } + + String[] paramArr = param.split(","); + + for (int i = 0; i < paramArr.length; i++) { + String item = paramArr[i]; + if (StringUtil.isNotEmpty(item)) { + String buyItem = paramArr[i]; // 100_200_1 + String[] buyItemArr = buyItem.split("_"); + if (StringUtil.isNotEmpty(buyItemArr[2])) { + Integer numInt = Integer.parseInt(buyItemArr[2]); + for (int j = 1; j <= numInt; j++) { + if (StringUtil.isNotEmpty(buyItemArr[1])) { + preStoreItem(couponInfo, userInfo, orderId, new BigDecimal(buyItemArr[1])); + } + } + } + } + } + + return true; + } + + /** + * 获取会员卡券列表 + * + * @param userId 会员ID + * @param status 状态 + * @return + * */ + @Override + public List getUserCouponList(Integer userId, List status) { + return mtUserCouponMapper.getUserCouponList(userId, status); + } + + /** + * 获取会员卡券列表 + * + * @param paramMap + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject getUserCouponList(Map paramMap) throws BusinessCheckException { + Integer pageNumber = paramMap.get("pageNumber") == null ? Constants.PAGE_NUMBER : Integer.parseInt(paramMap.get("pageNumber").toString()); + Integer pageSize = paramMap.get("pageSize") == null ? Constants.PAGE_SIZE : Integer.parseInt(paramMap.get("pageSize").toString()); + String userId = paramMap.get("userId") == null ? "" : paramMap.get("userId").toString(); + String userNo = paramMap.get("userNo") == null ? "" : paramMap.get("userNo").toString(); + String status = paramMap.get("status") == null ? "" : paramMap.get("status").toString(); + String type = paramMap.get("type") == null ? "": paramMap.get("type").toString(); + String mobile = paramMap.get("mobile") == null ? "" : paramMap.get("mobile").toString(); + String merchantId = paramMap.get("merchantId") == null ? "" : paramMap.get("merchantId").toString(); + String storeId = paramMap.get("storeId") == null ? "" : paramMap.get("storeId").toString(); + String couponId = paramMap.get("couponId") == null ? "" : paramMap.get("couponId").toString(); + String code = paramMap.get("code") == null ? "" : paramMap.get("code").toString(); + String id = paramMap.get("id") == null ? "" : paramMap.get("id").toString(); + + // 处理已失效 + if (pageNumber <= 1 && StringUtil.isNotBlank(userId)) { + List statusList = Arrays.asList(UserCouponStatusEnum.UNUSED.getKey()); + List data = mtUserCouponMapper.getUserCouponList(Integer.parseInt(userId), statusList); + for (MtUserCoupon uc : data) { + MtCoupon coupon = couponService.queryCouponById(uc.getCouponId()); + // 已过期 + if (coupon.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey()) && coupon.getEndTime() != null && coupon.getEndTime().before(new Date())) { + uc.setStatus(UserCouponStatusEnum.EXPIRE.getKey()); + uc.setUpdateTime(new Date()); + mtUserCouponMapper.updateById(uc); + } + // 已过期 + if (coupon.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey()) && uc.getExpireTime() != null && uc.getExpireTime().before(new Date())) { + uc.setStatus(UserCouponStatusEnum.EXPIRE.getKey()); + uc.setUpdateTime(new Date()); + mtUserCouponMapper.updateById(uc); + } + // 已删除 + if (coupon.getStatus().equals(StatusEnum.DISABLE.getKey())) { + uc.setStatus(UserCouponStatusEnum.DISABLE.getKey()); + uc.setUpdateTime(new Date()); + mtUserCouponMapper.updateById(uc); + } + } + } + + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUserCoupon::getStatus, StatusEnum.DISABLE.getKey()); + if (StringUtil.isNotBlank(mobile)) { + MtUser mtUser = memberService.queryMemberByMobile(Integer.parseInt(merchantId), mobile); + if (mtUser != null) { + userId = mtUser.getId().toString(); + } else { + lambdaQueryWrapper.eq(MtUserCoupon::getUserId, -1); + } + } + if (StringUtil.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtUserCoupon::getStatus, status); + } + if (StringUtil.isNotBlank(userId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getUserId, userId); + } + if (StringUtil.isNotBlank(userNo)) { + if (StringUtil.isBlank(merchantId)) { + merchantId = "0"; + } + MtUser userInfo = memberService.queryMemberByUserNo(Integer.parseInt(merchantId), userNo); + if (userInfo != null) { + lambdaQueryWrapper.eq(MtUserCoupon::getUserId, userInfo.getId()); + } else { + lambdaQueryWrapper.eq(MtUserCoupon::getUserId, -1); + } + } + if (StringUtil.isNotBlank(type)) { + lambdaQueryWrapper.eq(MtUserCoupon::getType, type); + } + if (StringUtil.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getMerchantId, merchantId); + } + if (StringUtil.isNotBlank(storeId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getStoreId, storeId); + } + if (StringUtil.isNotBlank(couponId)) { + lambdaQueryWrapper.eq(MtUserCoupon::getCouponId, couponId); + } + if (StringUtil.isNotBlank(code)) { + lambdaQueryWrapper.eq(MtUserCoupon::getCode, code); + } + if (StringUtil.isNotBlank(id)) { + lambdaQueryWrapper.eq(MtUserCoupon::getId, id); + } + + lambdaQueryWrapper.orderByDesc(MtUserCoupon::getId); + Page pageHelper = PageHelper.startPage(pageNumber, pageSize); + List userCouponList = mtUserCouponMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + if (userCouponList.size() > 0) { + for (MtUserCoupon userCouponDto : userCouponList) { + MtCoupon couponInfo = couponService.queryCouponById(userCouponDto.getCouponId()); + MtUser userInfo = memberService.queryMemberById(userCouponDto.getUserId()); + MtStore storeInfo = storeService.queryStoreById(userCouponDto.getStoreId()); + if (couponInfo == null) { + continue; + } + if (userInfo != null) { + userInfo.setMobile(CommonUtil.hidePhone(userInfo.getMobile())); + } + MyCouponDto dto = new MyCouponDto(); + dto.setId(userCouponDto.getId()); + dto.setName(couponInfo.getName()); + dto.setCode(userCouponDto.getCode()); + dto.setCouponId(couponInfo.getId()); + dto.setUseRule(couponInfo.getOutRule()); + String image = couponInfo.getImage(); + String baseImage = settingService.getUploadBasePath(); + dto.setImage(baseImage + image); + dto.setStatus(userCouponDto.getStatus()); + dto.setAmount(userCouponDto.getAmount()); + dto.setBalance(userCouponDto.getBalance()); + dto.setType(couponInfo.getType()); + dto.setContent(couponInfo.getContent()); + dto.setUsedTime(userCouponDto.getUsedTime()); + dto.setCreateTime(userCouponDto.getCreateTime()); + dto.setUserInfo(userInfo); + dto.setStoreInfo(storeInfo); + dto.setNum(0); + + // 次卡核销情况 + if (dto.getType().equals(CouponTypeEnum.TIMER.getKey())) { + if (StringUtil.isNotEmpty(couponInfo.getOutRule())) { + dto.setAmount(new BigDecimal(couponInfo.getOutRule())); + } + Long confirmCount = confirmLogService.getConfirmNum(dto.getId()); + dto.setBalance(new BigDecimal(confirmCount)); + } + + boolean canUse = couponService.isCouponEffective(couponInfo, userCouponDto); + if (!userCouponDto.getStatus().equals(UserCouponStatusEnum.UNUSED.getKey())) { + canUse = false; + } + dto.setCanUse(canUse); + + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FIX.getKey())) { + String effectiveDate = DateUtil.formatDate(couponInfo.getBeginTime(), "yyyy.MM.dd HH:mm") + "-" + DateUtil.formatDate(couponInfo.getEndTime(), "yyyy.MM.dd HH:mm"); + dto.setEffectiveDate(effectiveDate); + } + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + String effectiveDate = DateUtil.formatDate(userCouponDto.getCreateTime(), "yyyy.MM.dd HH:mm") + "-" + DateUtil.formatDate(userCouponDto.getExpireTime(), "yyyy.MM.dd HH:mm"); + dto.setEffectiveDate(effectiveDate); + } + + String tips = ""; + + // 优惠券tips + if (couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + if (StringUtil.isNotEmpty(couponInfo.getOutRule()) && Float.parseFloat(couponInfo.getOutRule()) > 0) { + tips = "满" + couponInfo.getOutRule() + "可用"; + } else { + tips = "无门槛券"; + } + } + + // 储值卡tips + if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + tips = "¥" + userCouponDto .getAmount() + ",余额¥" + userCouponDto.getBalance(); + } + + // 计次卡tips + if (couponInfo.getType().equals(CouponTypeEnum.TIMER.getKey())) { + Long confirmNum = confirmLogService.getConfirmNum(userCouponDto.getId()); + tips = "已使用"+ confirmNum +"次,可使用" + couponInfo.getOutRule() + "次"; + dto.setNum(Integer.parseInt(couponInfo.getOutRule()) - confirmNum.intValue()); + } + + dto.setTips(tips); + dataList.add(dto); + } + } + + PageRequest pageRequest = PageRequest.of(pageNumber, pageSize); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MyCouponDto.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + if (dataList.size() == 0) { + paginationResponse.setTotalPages(0); + paginationResponse.setTotalElements(0); + } + paginationResponse.setContent(dataList); + + return new ResponseObject(200, "查询成功", paginationResponse); + } + + /** + * 获取会员可支付使用的卡券 + * + * @param userId 会员ID + * @param storeId 使用门店 + * @param useFor 用途 + * @return + * */ + @Override + public List getPayAbleCouponList(Integer userId, Integer storeId, String useFor) throws BusinessCheckException { + List statusList = Arrays.asList(UserCouponStatusEnum.UNUSED.getKey()); + List userCouponList = mtUserCouponMapper.getUserCouponList(userId, statusList); + List dataList = new ArrayList<>(); + + if (userCouponList.size() > 0) { + for (MtUserCoupon userCoupon : userCouponList) { + MtCoupon couponInfo = couponService.queryCouponById(userCoupon.getCouponId()); + // 适用门店 + if (storeId != null && storeId > 0 && StringUtil.isNotEmpty(couponInfo.getStoreIds())) { + String[] storeIds = couponInfo.getStoreIds().split(","); + if (!Arrays.asList(storeIds).contains(storeId.toString())) { + continue; + } + } + // 只取专用卡券 + if (StringUtil.isNotEmpty(useFor) && !couponInfo.getUseFor().equals(useFor)) { + continue; + } + // 不取专用卡券 + if (StringUtil.isEmpty(useFor) && couponInfo.getUseFor() != null && StringUtil.isNotEmpty(couponInfo.getUseFor())) { + continue; + } + CouponDto couponDto = new CouponDto(); + couponDto.setId(couponInfo.getId()); + couponDto.setUserCouponId(userCoupon.getId()); + couponDto.setName(couponInfo.getName()); + couponDto.setAmount(userCoupon.getAmount()); + couponDto.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + boolean isEffective = couponService.isCouponEffective(couponInfo, userCoupon); + // 1.储值卡可用 + if (isEffective && couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey())) { + if (userCoupon.getBalance().compareTo(new BigDecimal("0")) > 0) { + couponDto.setType(CouponTypeEnum.PRESTORE.getValue()); + couponDto.setAmount(userCoupon.getBalance()); + dataList.add(couponDto); + } + } else if(isEffective && couponInfo.getType().equals(CouponTypeEnum.COUPON.getKey())) { + // 2.无门槛的优惠券可用 + if (StringUtil.isEmpty(couponInfo.getOutRule()) || couponInfo.getOutRule().equals("0")) { + couponDto.setType(CouponTypeEnum.COUPON.getValue()); + dataList.add(couponDto); + } + } + } + } + + return dataList; + } + + /** + * 获取会员卡券详情 + * + * @param userId 会员ID + * @param couponId 卡券ID + * @return + * */ + @Override + public List getUserCouponDetail(Integer userId, Integer couponId) { + return mtUserCouponMapper.findUserCouponDetail(couponId, userId); + } + + /** + * 获取会员卡券详情 + * + * @param userCouponId 会员卡券ID + * @return + * */ + @Override + public MtUserCoupon getUserCouponDetail(Integer userCouponId) { + return mtUserCouponMapper.selectById(userCouponId); + } + + /** + * 根据过期时间查询会员卡券 + * + * @param userId 会员ID + * @param status 状态 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return + * */ + @Override + public List getUserCouponListByExpireTime(Integer userId, String status, String startTime, String endTime) { + return mtUserCouponMapper.getUserCouponListByExpireTime(userId, status, startTime, endTime); + } + + /** + * 会员发送卡券 + * + * @param orderId 订单ID + * @param couponId 卡券ID + * @param userId 会员ID + * @param mobile 手机号 + * @param num 购买数量 + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean buyCouponItem(Integer orderId, Integer couponId, Integer userId, String mobile, Double num) throws BusinessCheckException { + if (num == null || num <= 0) { + num = 1.0; + } + for (int j = 0; j < num; j++) { + MtCoupon couponInfo = couponService.queryCouponById(couponId); + MtUserCoupon userCoupon = new MtUserCoupon(); + userCoupon.setCouponId(couponId); + userCoupon.setMerchantId(couponInfo.getMerchantId()); + userCoupon.setStoreId(couponInfo.getStoreId()); + userCoupon.setType(couponInfo.getType()); + userCoupon.setGroupId(couponInfo.getGroupId()); + userCoupon.setMobile(mobile); + userCoupon.setUserId(userId); + userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + userCoupon.setCreateTime(new Date()); + userCoupon.setUpdateTime(new Date()); + userCoupon.setExpireTime(couponInfo.getEndTime()); + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, couponInfo.getExpireTime()); + expireTime = c.getTime(); + userCoupon.setExpireTime(expireTime); + } + userCoupon.setOrderId(orderId); + + // 如果购买的是储值卡 + if (couponInfo.getType().equals(CouponTypeEnum.PRESTORE.getKey()) && couponInfo.getInRule() != null) { + String[] paramArr = couponInfo.getInRule().split(","); // 100_200,300_500 + MtOrder orderInfo = orderService.getOrderInfo(orderId); + if (orderInfo != null) { + BigDecimal payAmount = orderInfo.getPayAmount(); + BigDecimal totalAmount = new BigDecimal(0); + if (paramArr.length > 0) { + for (int i = 0; i < paramArr.length; i++) { + String[] storeItem = paramArr[i].split("_"); + if (storeItem.length > 0) { + BigDecimal amount = new BigDecimal(paramArr[i].split("_")[0]); + if (payAmount.compareTo(amount) >= 0) { + totalAmount = new BigDecimal(paramArr[i].split("_")[1]); + payAmount = payAmount.subtract(amount); + } + } + } + } + couponInfo.setAmount(totalAmount); + } + } + + userCoupon.setAmount(couponInfo.getAmount()); + userCoupon.setBalance(couponInfo.getAmount()); + + // 16位随机数 + String code = SeqUtil.getRandomNumber(16); + userCoupon.setCode(code); + userCoupon.setUuid(code); + + mtUserCouponMapper.insert(userCoupon); + } + return true; + } + + /** + * 通过卡券ID删除会员卡券 + * + * @param couponId 卡券ID + * @return + * */ + public void removeUserCouponByCouponId(Integer couponId) { + if (couponId == null || couponId <= 0) { + return; + } + mtUserCouponMapper.removeUserCouponByCouponId(couponId); + } + + /** + * 预存单张 + * + * @param couponInfo 卡券信息 + * @param userInfo 会员信息 + * @return + * */ + private boolean preStoreItem(MtCoupon couponInfo, MtUser userInfo, Integer orderId, BigDecimal amount) { + MtUserCoupon userCoupon = new MtUserCoupon(); + userCoupon.setCouponId(couponInfo.getId()); + userCoupon.setType(couponInfo.getType()); + userCoupon.setGroupId(couponInfo.getGroupId()); + userCoupon.setMobile(userInfo.getMobile()); + userCoupon.setMerchantId(couponInfo.getMerchantId()); + userCoupon.setStoreId(couponInfo.getStoreId()); + userCoupon.setUserId(userInfo.getId()); + userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getKey()); + userCoupon.setCreateTime(new Date()); + userCoupon.setUpdateTime(new Date()); + userCoupon.setExpireTime(couponInfo.getEndTime()); + if (couponInfo.getExpireType().equals(CouponExpireTypeEnum.FLEX.getKey())) { + Date expireTime = new Date(); + Calendar c = Calendar.getInstance(); + c.setTime(expireTime); + c.add(Calendar.DATE, couponInfo.getExpireTime()); + expireTime = c.getTime(); + userCoupon.setExpireTime(expireTime); + } + + userCoupon.setOrderId(orderId); + userCoupon.setAmount(amount); + userCoupon.setBalance(amount); + + // 16位随机数 + String code = SeqUtil.getRandomNumber(16); + userCoupon.setCode(code); + userCoupon.setUuid(code); + + mtUserCouponMapper.insert(userCoupon); + return true; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/UserGradeServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/UserGradeServiceImpl.java new file mode 100644 index 0000000..cf05a14 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/UserGradeServiceImpl.java @@ -0,0 +1,264 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.enums.StatusEnum; +import com.fuint.common.enums.UserGradeCatchTypeEnum; +import com.fuint.common.service.UserGradeService; +import com.fuint.framework.annoation.OperationServiceLog; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.pagination.PaginationRequest; +import com.fuint.framework.pagination.PaginationResponse; +import com.fuint.repository.mapper.MtStaffMapper; +import com.fuint.repository.mapper.MtUserGradeMapper; +import com.fuint.repository.model.MtBanner; +import com.fuint.repository.model.MtStaff; +import com.fuint.repository.model.MtUser; +import com.fuint.repository.model.MtUserGrade; +import com.fuint.utils.StringUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 会员等级业务接口实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class UserGradeServiceImpl extends ServiceImpl implements UserGradeService { + + private MtUserGradeMapper mtUserGradeMapper; + + private MtStaffMapper mtStaffMapper; + + /** + * 分页查询会员等级列表 + * + * @param paginationRequest + * @return + */ + @Override + public PaginationResponse queryUserGradeListByPagination(PaginationRequest paginationRequest) { + Page pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.ne(MtUserGrade::getStatus, StatusEnum.DISABLE.getKey()); + + String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString(); + if (StringUtils.isNotBlank(name)) { + lambdaQueryWrapper.like(MtUserGrade::getName, name); + } + String catchType = paginationRequest.getSearchParams().get("catchType") == null ? "" : paginationRequest.getSearchParams().get("catchType").toString(); + if (StringUtils.isNotBlank(catchType)) { + lambdaQueryWrapper.like(MtUserGrade::getCatchType, catchType); + } + String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString(); + if (StringUtils.isNotBlank(status)) { + lambdaQueryWrapper.eq(MtUserGrade::getStatus, status); + } + String merchantId = paginationRequest.getSearchParams().get("merchantId") == null ? "" : paginationRequest.getSearchParams().get("merchantId").toString(); + if (StringUtils.isNotBlank(merchantId)) { + lambdaQueryWrapper.eq(MtUserGrade::getMerchantId, merchantId); + } + + lambdaQueryWrapper.orderByDesc(MtUserGrade::getGrade); + List dataList = mtUserGradeMapper.selectList(lambdaQueryWrapper); + + PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize()); + PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal()); + PaginationResponse paginationResponse = new PaginationResponse(pageImpl, MtBanner.class); + paginationResponse.setTotalPages(pageHelper.getPages()); + paginationResponse.setTotalElements(pageHelper.getTotal()); + paginationResponse.setContent(dataList); + + return paginationResponse; + } + + /** + * 添加会员等级信息 + * + * @param mtUserGrade 会员等级 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "新增会员等级") + public MtUserGrade addUserGrade(MtUserGrade mtUserGrade) throws BusinessCheckException { + if (mtUserGrade.getMerchantId() == null || mtUserGrade.getMerchantId() < 1) { + throw new BusinessCheckException("平台方帐号无法执行该操作,请使用商户帐号操作"); + } + if (mtUserGrade.getGrade() != null && (mtUserGrade.getGrade() <= 0)) { + throw new BusinessCheckException("会员等级需大于0"); + } + if (mtUserGrade.getDiscount() != null && (mtUserGrade.getDiscount() > 10 || mtUserGrade.getDiscount() < 0)) { + throw new BusinessCheckException("会员折扣需在0和10之间"); + } + mtUserGradeMapper.insert(mtUserGrade); + return mtUserGrade; + } + + /** + * 根据ID获取会员等级信息 + * + * @param merchantId 商户ID + * @param gradeId 会员等级ID + * @param userId 会员ID + * @return + */ + @Override + public MtUserGrade queryUserGradeById(Integer merchantId, Integer gradeId, Integer userId) { + if (userId != null && userId > 0) { + Map params = new HashMap<>(); + params.put("AUDITED_STATUS", StatusEnum.ENABLED.getKey()); + params.put("USER_ID", userId); + List staffList = mtStaffMapper.selectByMap(params); + // 如果是员工关联的会员,就返回默认的会员等级 + if (staffList != null && staffList.size() > 0) { + return getInitUserGrade(merchantId); + } + } + return mtUserGradeMapper.selectById(gradeId); + } + + /** + * 修改会员等级 + * + * @param mtUserGrade 会员等级 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "修改会员等级") + public MtUserGrade updateUserGrade(MtUserGrade mtUserGrade) throws BusinessCheckException { + if (mtUserGrade.getDiscount() != null && (mtUserGrade.getDiscount() > 10 || mtUserGrade.getDiscount() < 0)) { + throw new BusinessCheckException("会员折扣需在0和10之间"); + } + if (mtUserGrade.getGrade() != null && (mtUserGrade.getGrade() <= 0)) { + throw new BusinessCheckException("会员等级需大于0"); + } + MtUserGrade userGrade = mtUserGradeMapper.selectById(mtUserGrade.getId()); + if (null != userGrade) { + mtUserGrade.setMerchantId(userGrade.getMerchantId()); + mtUserGradeMapper.updateById(mtUserGrade); + } + return mtUserGrade; + } + + /** + * 根据ID删除会员等级 + * + * @param id ID + * @param operator 操作人 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @OperationServiceLog(description = "删除会员等级") + public Integer deleteUserGrade(Integer id, String operator) { + MtUserGrade mtUserGrade = queryUserGradeById(0, id, 0); + if (null == mtUserGrade) { + return 0; + } + mtUserGrade.setStatus(StatusEnum.DISABLE.getKey()); + mtUserGradeMapper.updateById(mtUserGrade); + return mtUserGrade.getId(); + } + + /** + * 获取默认的会员等级 + * + * @param merchantId 商户ID + * @return + */ + @Override + public MtUserGrade getInitUserGrade(Integer merchantId) { + Map param = new HashMap<>(); + param.put("status", StatusEnum.ENABLED.getKey()); + param.put("CATCH_TYPE", UserGradeCatchTypeEnum.INIT.getKey()); + param.put("MERCHANT_ID", merchantId); + + List dataList = mtUserGradeMapper.selectByMap(param); + MtUserGrade initGrade; + if (dataList != null && dataList.size() > 0) { + initGrade = dataList.get(0); + } else { + initGrade = new MtUserGrade(); + initGrade.setId(0); + initGrade.setStatus(StatusEnum.ENABLED.getKey()); + initGrade.setGrade(0); + initGrade.setMerchantId(0); + initGrade.setSpeedPoint(1f); + initGrade.setDiscount(0f); + } + return initGrade; + } + + /** + * 获取付费会员等级列表 + * + * @param merchantId 商户ID + * @param userInfo 会员信息 + * @return + * */ + @Override + public List getPayUserGradeList(Integer merchantId, MtUser userInfo) { + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(MtUserGrade::getStatus, StatusEnum.ENABLED.getKey()); + lambdaQueryWrapper.eq(MtUserGrade::getCatchType, UserGradeCatchTypeEnum.PAY.getKey()); + lambdaQueryWrapper.eq(MtUserGrade::getMerchantId, merchantId); + lambdaQueryWrapper.orderByAsc(MtUserGrade::getGrade); + + List userGrades = mtUserGradeMapper.selectList(lambdaQueryWrapper); + List dataList = new ArrayList<>(); + + Integer userGradeId = 0; + if (userInfo != null) { + if (userInfo.getGradeId() != null && userInfo.getGradeId() > 0) { + userGradeId = userInfo.getGradeId(); + } + } + + if (userGrades.size() > 0) { + MtUserGrade myGradeInfo = mtUserGradeMapper.selectById(userGradeId); + if (myGradeInfo != null) { + Integer myGrade = myGradeInfo.getGrade(); + for (MtUserGrade grade : userGrades) { + if (!myGrade.equals(grade.getGrade().toString()) && (grade.getGrade() > myGrade)) { + dataList.add(grade); + } + } + } else { + for (MtUserGrade grade : userGrades) { + dataList.add(grade); + } + } + } + + return dataList; + } + + /** + * 获取商户会员等级列表 + * + * @param merchantId 商户ID + * @param status 状态 + * @return + * */ + @Override + public List getMerchantGradeList(Integer merchantId, String status) { + return mtUserGradeMapper.getMerchantGradeList(merchantId, status); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/service/impl/VerifyCodeServiceImpl.java b/fuint-application/src/main/java/com/fuint/common/service/impl/VerifyCodeServiceImpl.java new file mode 100644 index 0000000..c73c7a8 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/service/impl/VerifyCodeServiceImpl.java @@ -0,0 +1,125 @@ +package com.fuint.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuint.common.service.VerifyCodeService; +import com.fuint.framework.exception.BusinessCheckException; +import com.fuint.framework.exception.BusinessRuntimeException; +import com.fuint.repository.mapper.MtVerifyCodeMapper; +import com.fuint.repository.model.MtVerifyCode; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 验证码业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +@AllArgsConstructor(onConstructor_= {@Lazy}) +public class VerifyCodeServiceImpl extends ServiceImpl implements VerifyCodeService { + + private MtVerifyCodeMapper mtVerifyCodeMapper; + + /** + * 添加验证码 + * + * @param mobile + * @param verifyCode + * @throws BusinessCheckException + * @return + */ + public MtVerifyCode addVerifyCode(String mobile, String verifyCode, Integer expireSecond) { + if (null == expireSecond || expireSecond<0) { + expireSecond=0; + } + + MtVerifyCode reqVerifyCodeDto = new MtVerifyCode(); + reqVerifyCodeDto.setMobile(mobile); + reqVerifyCodeDto.setVerifyCode(verifyCode); + reqVerifyCodeDto.setValidFlag("0"); + + Date now = new Date(); + reqVerifyCodeDto.setAddTime(now); + + // 验证码过期时间5分钟 + Date expireTime = new Date(); + expireTime.setTime(expireTime.getTime()+5*60*1000); + reqVerifyCodeDto.setExpireTime(expireTime); + + // 发送验证码2分钟后才能继续发送,取最后一条 + List verifyCodeList = mtVerifyCodeMapper.queryVerifyCodeLastRecord(mobile); + if (null == verifyCodeList || verifyCodeList.size() == 0) { + // 没发过短信 + this.save(reqVerifyCodeDto); + return reqVerifyCodeDto; + } + MtVerifyCode verifyCodeLastRecord = verifyCodeList.get(0); + Long curInt = reqVerifyCodeDto.getAddTime().getTime(); //时间毫秒,长整型 + Long lastInt = verifyCodeLastRecord.getAddTime().getTime(); + Integer diffSecond = (int)((curInt-lastInt) / 1000); //间隔秒数 + if (diffSecond 0) { + MtMerchant mtMerchant = merchantService.queryMerchantById(merchantId); + if (mtMerchant != null && StringUtil.isNotEmpty(mtMerchant.getWxAppId()) && StringUtil.isNotEmpty(mtMerchant.getWxAppSecret())) { + wxAppId = mtMerchant.getWxAppId(); + wxAppSecret = mtMerchant.getWxAppSecret(); + tokenKey = tokenKey + merchantId; + } + } + + String wxTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; + String url = String.format(wxTokenUrl, wxAppId, wxAppSecret); + String token = ""; + + if (useCache) { + token = RedisUtil.get(tokenKey); + } + + if (token == null || StringUtil.isEmpty(token)) { + try { + String response = HttpRESTDataClient.requestGet(url); + JSONObject json = (JSONObject) JSONObject.parse(response); + if (!json.containsKey("errcode")) { + RedisUtil.set(tokenKey, json.get("access_token"), 7200); + token = (String) json.get("access_token"); + } else { + logger.error("获取微信accessToken出错:" + json.get("errmsg")); + } + } catch (Exception e) { + logger.error("获取微信accessToken异常:" + e.getMessage()); + } + } + + return token; + } + + /** + * 创建支付订单 + * + * @param userInfo 会员信息 + * @param orderInfo 订单信息 + * @param payAmount 支付金额 + * @param authCode 付款码 + * @param giveAmount 赠送金额 + * @param ip 支付IP + * @param platform 支付平台 + * @param isWechat 是否微信客户端 + * @throws BusinessCheckException + * @return + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform, String isWechat) throws BusinessCheckException { + logger.info("WeixinService createPrepayOrder inParams userInfo={} payAmount={} giveAmount={} goodsInfo={}", userInfo, payAmount, giveAmount, orderInfo); + + String goodsInfo = orderInfo.getOrderSn(); + if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) { + goodsInfo = OrderTypeEnum.PRESTORE.getValue(); + } + + // 1. 调用微信接口生成预支付订单 + Map reqData = new HashMap<>(); + reqData.put("body", goodsInfo); + reqData.put("out_trade_no", orderInfo.getOrderSn()); + reqData.put("device_info", ""); + reqData.put("fee_type", "CNY"); + reqData.put("total_fee", payAmount.toString()); + reqData.put("spbill_create_ip", ip); + if (orderInfo.getType() != null && orderInfo.getType().equals(OrderTypeEnum.GOODS.getKey())) { + Map params = new HashMap<>(); + params.put("ORDER_ID", orderInfo.getId()); + params.put("STATUS", StatusEnum.ENABLED.getKey()); + List goodsList = mtOrderGoodsMapper.selectByMap(params); + if (goodsList != null && goodsList.size() > 0) { + Integer goodsId = goodsList.get(0).getGoodsId(); + if (goodsId != null && goodsId > 0) { + MtGoods mtGoods = mtGoodsMapper.selectById(goodsId); + if (mtGoods != null) { + reqData.put("description", mtGoods.getName()); + } + } + } + } + + // JSAPI支付 + if (orderInfo.getPayType().equals(PayTypeEnum.JSAPI.getKey())) { + reqData.put("trade_type", PayTypeEnum.JSAPI.getKey()); + reqData.put("openid", userInfo.getOpenId() == null ? "" : userInfo.getOpenId()); + } + + // 刷卡支付 + if (StringUtil.isNotEmpty(authCode)) { + reqData.put("auth_code", authCode); + } + + // 更新支付金额 + BigDecimal payAmount1 = new BigDecimal(payAmount).divide(new BigDecimal("100")); + OrderDto reqDto = new OrderDto(); + reqDto.setId(orderInfo.getId()); + reqDto.setPayAmount(payAmount1); + reqDto.setPayType(orderInfo.getPayType()); + reqDto.setOrderSn(orderInfo.getOrderSn()); + orderService.updateOrder(reqDto); + + Map respData; + if (reqData.get("auth_code") != null && StringUtil.isNotEmpty(reqData.get("auth_code"))) { + respData = microPay(orderInfo.getStoreId(), reqData, ip, platform); + } else { + if (platform.equals(PlatformTypeEnum.H5.getCode()) && isWechat.equals(YesOrNoEnum.NO.getKey())) { + respData = wapPay(orderInfo.getStoreId(), reqData, ip, platform); + } else { + respData = jsapiPay(orderInfo.getStoreId(), reqData, ip, platform); + } + } + logger.info("微信支付接口调用返回:{}", JsonUtil.toJSONString(respData)); + + if (respData == null || respData.get("return_code").equals("FAIL")) { + logger.error("微信支付接口调用异常......"); + return new ResponseObject(3000, "微信支付接口调用异常", null); + } + + // 2.更新预支付订单号 + if (respData.get("result_code").equals("SUCCESS")) { + if (respData.get("trade_type").equals(PayTypeEnum.JSAPI.getKey())) { + String prepayId = respData.get("prepay_id"); + getApiConfig(orderInfo.getStoreId(), platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + respData = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId, wxPayApiConfig.getPartnerKey(), SignType.MD5); + String jsonStr = JSON.toJSONString(respData); + logger.info("小程序支付的参数:" + jsonStr); + } + } else { + logger.error("微信支付接口返回状态失败......" + respData.toString() + "...reason"); + return new ResponseObject(3000, "微信支付失败:" + (respData.get("err_code_des") != null ? respData.get("err_code_des") : "未知错误"), null); + } + + ResponseObject responseObject = new ResponseObject(200, "微信支付接口返回成功", respData); + logger.info("WXService createPrepayOrder outParams {}", responseObject.toString()); + + return responseObject; + } + + /** + * 处理支付回调 + * + * @param request 请求参数 + * @return + * */ + public Map processResXml(HttpServletRequest request) { + try { + String xmlMsg = HttpKit.readData(request); + Map result = WxPayKit.xmlToMap(xmlMsg); + String returnCode = result.get("return_code"); + String orderSn = result.get("out_trade_no"); + logger.info("支付通知,xml = {}, orderSn = {}", xmlMsg, orderSn); + + Integer storeId = 0; + String platform = PlatformTypeEnum.MP_WEIXIN.getCode(); + if (StringUtil.isNotEmpty(orderSn)) { + MtOrder mtOrder = orderService.getOrderInfoByOrderSn(orderSn); + if (mtOrder != null) { + storeId = mtOrder.getStoreId(); + platform = mtOrder.getPlatform(); + } + } + + getApiConfig(storeId, platform); + if (WxPayKit.verifyNotify(result, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.MD5)) { + if (WxPayKit.codeIsOk(returnCode)) { + return result; + } + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * 处理回调xml + * + * @param response 响应参数 + * @param flag 标记 + * @return + * */ + public void processRespXml(HttpServletResponse response, boolean flag){ + Map respData = new HashMap<>(); + if (flag) { + respData.put("return_code", "SUCCESS"); + respData.put("return_msg", "OK"); + }else{ + respData.put("return_code", "FAIL"); + respData.put("return_msg", "FAIL"); + } + OutputStream outputStream = null; + try { + String respXml = WxPayKit.toXml(respData); + outputStream = response.getOutputStream(); + outputStream.write(respXml.getBytes("UTF-8")); + outputStream.flush(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if(outputStream!=null){ + try { + outputStream.close(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + } + } + + /** + * 获取微信个人信息 + * + * @param merchantId 商户ID + * @param code 微信返回编码 + * @throws BusinessCheckException + * @return + * */ + @Override + public JSONObject getWxProfile(Integer merchantId, String code) throws BusinessCheckException { + String wxAppId = env.getProperty("wxpay.appId"); + String wxAppSecret = env.getProperty("wxpay.appSecret"); + + if (merchantId != null && merchantId > 0) { + MtMerchant mtMerchant = merchantService.queryMerchantById(merchantId); + if (mtMerchant != null && StringUtil.isNotEmpty(mtMerchant.getWxAppId()) && StringUtil.isNotEmpty(mtMerchant.getWxAppSecret())) { + wxAppId = mtMerchant.getWxAppId(); + wxAppSecret = mtMerchant.getWxAppSecret(); + } + } + + String wxAccessUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"; + String url = String.format(wxAccessUrl, wxAppId, wxAppSecret, code); + try { + String response = HttpRESTDataClient.requestGet(url); + JSONObject json = (JSONObject) JSONObject.parse(response); + if (!json.containsKey("errcode")) { + return json; + } else { + logger.error("获取微信getWxProfile出错:code = " + json.containsKey("errcode") + ",msg="+ json.get("errmsg")); + } + } catch (Exception e) { + logger.error("获取微信getWxProfile异常:" + e.getMessage()); + } + + return null; + } + + /** + * 获取公众号openId + * + * @param merchantId 商户ID + * @param code 微信返回编码 + * @throws BusinessCheckException + * @return + * */ + @Override + public JSONObject getWxOpenId(Integer merchantId, String code) throws BusinessCheckException { + String wxAppId = env.getProperty("weixin.official.appId"); + String wxAppSecret = env.getProperty("weixin.official.appSecret"); + + if (merchantId != null && merchantId > 0) { + MtMerchant mtMerchant = merchantService.queryMerchantById(merchantId); + if (mtMerchant != null && StringUtil.isNotEmpty(mtMerchant.getWxOfficialAppId()) && StringUtil.isNotEmpty(mtMerchant.getWxOfficialAppSecret())) { + wxAppId = mtMerchant.getWxOfficialAppId(); + wxAppSecret = mtMerchant.getWxOfficialAppSecret(); + } + } + + String wxAccessUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"; + String url = String.format(wxAccessUrl, wxAppId, wxAppSecret, code); + try { + String response = HttpRESTDataClient.requestGet(url); + JSONObject json = (JSONObject) JSONObject.parse(response); + if (!json.containsKey("errcode")) { + return json; + } else { + logger.error("获取openId出错:code = " + json.containsKey("errcode") + ",msg="+ json.get("errmsg")); + } + } catch (Exception e) { + logger.error("获取微信openId异常:" + e.getMessage()); + } + + return null; + } + + /** + * 获取微信绑定手机号 + * + * @param encryptedData 微信返回加密字符串 + * @param sessionKey session键值 + * @param iv 微信IV + * @return + * */ + @Override + public String getPhoneNumber(String encryptedData, String sessionKey, String iv) { + // 被加密的数据 + byte[] dataByte = Base64.getDecoder().decode(encryptedData); + // 加密秘钥 + byte[] keyByte = Base64.getDecoder().decode(sessionKey); + // 偏移量 + byte[] ivByte = Base64.getDecoder().decode(iv); + try { + // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 + int base = 16; + if (keyByte.length % base != 0) { + int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyByte, 0, temp, 0, keyByte.length); + keyByte = temp; + } + // 初始化 + Security.addProvider(new BouncyCastleProvider()); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); + AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); + parameters.init(new IvParameterSpec(ivByte)); + cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 + byte[] resultByte = cipher.doFinal(dataByte); + if (null != resultByte && resultByte.length > 0) { + String result = new String(resultByte, "UTF-8"); + JSONObject object = JSONObject.parseObject(result); + return object.getString("phoneNumber"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * 发送小程序订阅消息 + * + * @param merchantId 商户ID + * @param userId 会员ID + * @param toUserOpenId 接受者openId + * @param key 消息key + * @param page 跳转页面 + * @param params 发送参数 + * @param sendTime 发送时间 + * @throws BusinessCheckException + * @return + * */ + @Override + public Boolean sendSubscribeMessage(Integer merchantId, Integer userId, String toUserOpenId, String key, String page, Map params, Date sendTime) throws BusinessCheckException { + if (StringUtil.isEmpty(toUserOpenId) || StringUtil.isEmpty(key) || userId < 1) { + return false; + } + + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.SUB_MESSAGE.getKey(), key); + if (mtSetting == null) { + return false; + } + + JSONObject jsonObject = null; + String templateId = ""; + JSONArray paramArray = null; + try { + if (mtSetting != null && mtSetting.getValue().indexOf('}') > 0) { + jsonObject = JSONObject.parseObject(mtSetting.getValue()); + } + if (jsonObject != null) { + templateId = jsonObject.get("templateId").toString(); + paramArray = (JSONArray) JSONObject.parse(jsonObject.get("params").toString()); + } + } catch (Exception e) { + logger.info("WeixinService sendSubscribeMessage parse setting error={}", mtSetting); + } + + if (StringUtil.isEmpty(templateId) || paramArray.size() < 1) { + logger.info("WeixinService sendSubscribeMessage setting error={}", mtSetting); + return false; + } + + JSONObject jsonData = new JSONObject(); + jsonData.put("touser", toUserOpenId); // 接收者的openid + jsonData.put("template_id", templateId); + + if (StringUtil.isEmpty(page)) { + page = "pages/index/index"; + } + jsonData.put("page", page); + + // 组装参数 + JSONObject data = new JSONObject(); + for (int i = 0; i < paramArray.size(); i++) { + JSONObject para = paramArray.getJSONObject(i); + String value = para.get("value").toString().replaceAll("\\{", "").replaceAll(".DATA}}", ""); + String paraKey = para.get("key").toString(); + String paraValue = params.get(paraKey).toString(); + JSONObject arg = new JSONObject(); + arg.put("value", paraValue); + data.put(value, arg); + } + jsonData.put("data", data); + + String reqDataJsonStr = JSON.toJSONString(jsonData); + + // 存储到消息表里,后续通过定时任务发送 + MtMessage mtMessage = new MtMessage(); + mtMessage.setMerchantId(merchantId); + mtMessage.setUserId(userId); + mtMessage.setType(MessageEnum.SUB_MSG.getKey()); + mtMessage.setTitle(WxMessageEnum.getValue(key)); + mtMessage.setContent(WxMessageEnum.getValue(key)); + mtMessage.setIsRead(YesOrNoEnum.NO.getKey()); + mtMessage.setIsSend(YesOrNoEnum.NO.getKey()); + mtMessage.setSendTime(sendTime); + mtMessage.setStatus(StatusEnum.ENABLED.getKey()); + mtMessage.setParams(reqDataJsonStr); + messageService.addMessage(mtMessage); + + return true; + } + + /** + * 发送订阅消息 + * + * @param merchantId 商户ID + * @param reqDataJsonStr 请求参数 + * @return + * */ + @Override + public Boolean doSendSubscribeMessage(Integer merchantId, String reqDataJsonStr) { + try { + String token = getAccessToken(merchantId, true,true); + if (StringUtil.isEmpty(token)) { + return false; + } + String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token; + String response = HttpRESTDataClient.requestPost(url, "application/json; charset=utf-8", reqDataJsonStr); + logger.info("WeixinService sendSubscribeMessage response={}", response); + JSONObject json = (JSONObject) JSONObject.parse(response); + if (json.get("errcode").toString().equals("40001")) { + getAccessToken(merchantId, true,true); + logger.error("发送订阅消息出错error1:" + json.get("errcode").toString()); + return false; + } else if (!json.get("errcode").toString().equals("0")) { + logger.error("发送订阅消息出错error2:" + json.get("errcode").toString()); + return false; + } else { + return true; + } + } catch (Exception e) { + logger.error("发送订阅消息出错:" + e.getMessage()); + } + + return true; + } + + /** + * 查询支付订单 + * + * @param storeId 店铺ID + * @param transactionId 支付流水ID + * @param orderSn 订单号 + * @return + * */ + @Override + public Map queryPaidOrder(Integer storeId, String transactionId, String orderSn) { + try { + MtOrder mtOrder = orderService.getOrderInfoByOrderSn(orderSn); + String platform = PlatformTypeEnum.MP_WEIXIN.getCode(); + if (mtOrder != null) { + platform = mtOrder.getPlatform(); + } + getApiConfig(storeId, platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + Map params = OrderQueryModel.builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .transaction_id(transactionId) + .out_trade_no(orderSn) + .nonce_str(WxPayKit.generateStr()) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5); + logger.info("请求参数:{}", WxPayKit.toXml(params)); + String query = WxPayApi.orderQuery(params); + Map result = WxPayKit.xmlToMap(query); + logger.info("查询结果: {}", result); + if (result.get("result_code").equals("FAIL")) { + result.put("trade_state", "FAIL"); + } + return result; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 发起售后 + * + * @param storeId 店铺ID + * @param orderSn 订单号 + * @param totalAmount 支付总金额 + * @param refundAmount 退款金额 + * @param platform 支付平台 + * @throws BusinessCheckException + * @return + * */ + @Override + public Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException { + try { + logger.info("WeixinService.doRefund orderSn = {}, totalFee = {}, refundFee = {}", orderSn, totalAmount, refundAmount); + if (StringUtil.isEmpty(orderSn)) { + throw new BusinessCheckException("退款订单号不能为空..."); + } + + BigDecimal totalFee = totalAmount.multiply(new BigDecimal("100")); + BigDecimal refundFee = refundAmount.multiply(new BigDecimal("100")); + Integer totalFeeInt = totalFee.intValue(); + Integer refundFeeInt = refundFee.intValue(); + if (refundFee.compareTo(totalFee) > 0) { + throw new BusinessCheckException("退款金额不能大于总金额"); + } + + // 支付配置 + getApiConfig(storeId, platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + Map params = RefundModel.builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .nonce_str(WxPayKit.generateStr()) + .transaction_id("") + .out_trade_no(orderSn) + .out_refund_no(orderSn) + .total_fee(totalFeeInt.toString()) + .refund_fee(refundFeeInt.toString()) + .notify_url(wxPayApiConfig.getDomain() + REFUND_NOTIFY_URL) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5); + logger.info("WeixinService doRefund params: {}", params); + String refundStr = WxPayApi.orderRefundByProtocol(false, params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId(), ""); + logger.info("WeixinService doRefund return: {}", refundStr); + Map result = WxPayKit.xmlToMap(refundStr); + String returnCode = result.get("return_code"); + String returnMsg = result.get("return_msg"); + if (!WxPayKit.codeIsOk(returnCode)) { + logger.error(returnMsg); + return false; + } + return true; + } catch (Exception e) { + throw new BusinessCheckException("WeixinService.doRefund 微信退款失败:" + e.getMessage()); + } + } + + /*** + * 生成二维码 + * + * @param merchantId 商户ID + * @param type 类型 + * @param id 数据ID + * @param page 页面 + * @param width 宽度 + * @return + * */ + @Override + public String createQrCode(Integer merchantId, String type, Integer id, String page, Integer width) throws BusinessCheckException { + try { + String accessToken = getAccessToken(merchantId, true,true); + if (StringUtil.isEmpty(accessToken)) { + throw new BusinessCheckException("生成二维码出错,请检查小程序配置"); + } + + String url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + accessToken; + String reqDataJsonStr = ""; + + Map reqData = new HashMap<>(); + reqData.put("access_token", accessToken); + reqData.put("path", page); + reqData.put("width", width); + reqDataJsonStr = JsonUtil.toJSONString(reqData); + + JSONObject jsonParam = new JSONObject(); + jsonParam.put("path", page); + jsonParam.put("width", width); + + InputStream inputStream = HttpRESTDataClient.doWXPost(url, jsonParam); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int n; + while (-1 != (n = inputStream.read(buffer))) { + output.write(buffer, 0, n); + } + byte[] bytes = output.toByteArray(); + String resStr = output.toString(); + logger.info("WechatService createStoreQrCode reqData:{},resStr:{}", reqDataJsonStr, resStr); + try { + JSONObject res = JSON.parseObject(resStr); + String errCode = res.get("errcode").toString(); + if (errCode.equals("40001")) { + getAccessToken(merchantId, true, false); + } + } catch (Exception e) { + String pathRoot = env.getProperty("images.root"); + String baseImage = env.getProperty("images.path"); + + String filePath = "Qr" + type + id + ".png"; + String path = pathRoot + baseImage + filePath; + QRCodeUtil.saveQrCodeToLocal(bytes, path); + + // 上传阿里云oss + String mode = env.getProperty("aliyun.oss.mode"); + if (mode.equals("1")) { // 检查是否开启上传 + String endpoint = env.getProperty("aliyun.oss.endpoint"); + String accessKeyId = env.getProperty("aliyun.oss.accessKeyId"); + String accessKeySecret = env.getProperty("aliyun.oss.accessKeySecret"); + String bucketName = env.getProperty("aliyun.oss.bucketName"); + String folder = env.getProperty("aliyun.oss.folder"); + OSS ossClient = AliyunOssUtil.getOSSClient(accessKeyId, accessKeySecret, endpoint); + File ossFile = new File(path); + return AliyunOssUtil.upload(ossClient, ossFile, bucketName, folder); + } else { + return baseImage + filePath; + } + } + } catch (Exception e) { + logger.error("生成店铺二维码出错啦:{}", e.getMessage()); + throw new BusinessCheckException("生成二维码出错,请检查小程序配置."); + } + + throw new BusinessCheckException("生成二维码出错,请稍后再试."); + } + + /** + * 开通微信卡券 + * + * @param merchantId 商户ID + * @param wxCardId 微信会员卡ID + * @return + * */ + @Override + public String createWxCard(Integer merchantId, String wxCardId) throws BusinessCheckException { + String cardId = ""; + try { + MtSetting mtSetting = settingService.querySettingByName(merchantId, SettingTypeEnum.USER.getKey(), UserSettingEnum.WX_MEMBER_CARD.getKey()); + if (mtSetting == null) { + return cardId; + } + WxCardDto wxCardDto = JsonUtil.parseObject(mtSetting.getValue(), WxCardDto.class); + + String accessToken = getAccessToken(merchantId, false,true); + String createUrl = "https://api.weixin.qq.com/card/create?access_token=" + accessToken; + String updateUrl = "https://api.weixin.qq.com/card/update?access_token=" + accessToken; + + Map params = new HashMap<>(); + Map card = new HashMap<>(); + if (StringUtil.isEmpty(wxCardId)) { + card.put("card_type", "MEMBER_CARD"); + } + Map memberCard = new HashMap<>(); + String baseImage = settingService.getUploadBasePath(); + if (StringUtil.isNotEmpty(wxCardDto.getBackgroundUrl())) { + // memberCard.put("background_pic_url", baseImage + wxCardDto.getBackgroundUrl()); + } + + // baseInfo + Map baseInfo = new HashMap<>(); + if (StringUtil.isNotEmpty(wxCardDto.getLogoUrl())) { + baseInfo.put("logo_url", baseImage + wxCardDto.getLogoUrl()); + } + if (StringUtil.isEmpty(wxCardId)) { + baseInfo.put("brand_name", wxCardDto.getBrandName()); + } + baseInfo.put("code_type", "CODE_TYPE_TEXT"); + baseInfo.put("title", wxCardDto.getTitle()); + baseInfo.put("color", wxCardDto.getColor()); + baseInfo.put("notice", wxCardDto.getNotice()); + if (StringUtil.isNotEmpty(wxCardDto.getServicePhone())) { + baseInfo.put("service_phone", wxCardDto.getServicePhone()); + } + baseInfo.put("description", wxCardDto.getDescription()); + Map dateInfo = new HashMap<>(); + dateInfo.put("type", "DATE_TYPE_PERMANENT"); + if (StringUtil.isEmpty(wxCardId)) { + baseInfo.put("date_info", dateInfo); + } + Map sku = new HashMap<>(); + sku.put("quantity", Constants.ALL_ROWS); + if (StringUtil.isEmpty(wxCardId)) { + baseInfo.put("sku", sku); + baseInfo.put("get_limit", 1); + } + if (StringUtil.isEmpty(wxCardId)) { + baseInfo.put("use_custom_code", false); + baseInfo.put("bind_openid", false); + } + baseInfo.put("can_give_friend", false); + if (StringUtil.isEmpty(wxCardId)) { + baseInfo.put("location_id_list", null); + } + if (StringUtil.isNotEmpty(wxCardDto.getCustomUrlName())) { + baseInfo.put("custom_url_name", wxCardDto.getCustomUrlName()); + } + if (StringUtil.isNotEmpty(wxCardDto.getCustomUrl())) { + baseInfo.put("custom_url", wxCardDto.getCustomUrl()); + } + if (StringUtil.isNotEmpty(wxCardDto.getCustomUrlSubTitle())) { + baseInfo.put("custom_url_sub_title", wxCardDto.getCustomUrlSubTitle()); + } + baseInfo.put("need_push_on_view", true); + memberCard.put("base_info", baseInfo); + + // 特权说明 + if (StringUtil.isNotEmpty(wxCardDto.getPrerogative())) { + memberCard.put("prerogative", wxCardDto.getPrerogative()); + } + // 自动激活 + memberCard.put("auto_activate", true); + memberCard.put("supply_bonus", wxCardDto.getSupplyBonus()); + if (StringUtil.isNotEmpty(wxCardDto.getBonusUrl())) { + memberCard.put("bonus_url", wxCardDto.getBonusUrl()); + } + if (StringUtil.isEmpty(wxCardId)) { + memberCard.put("supply_balance", wxCardDto.getSupplyBalance()); + } + if (StringUtil.isNotEmpty(wxCardDto.getBalanceUrl())) { + memberCard.put("balance_url", wxCardDto.getBalanceUrl()); + } + card.put("member_card", memberCard); + if (StringUtil.isEmpty(wxCardId)) { + params.put("card", card); + } else { + card.put("card_id", wxCardId); + params = card; + } + + ObjectMapper mapper = new ObjectMapper(); + String reqDataJson = mapper.writeValueAsString(params); + String url = createUrl; + if (StringUtil.isNotEmpty(wxCardId)) { + url = updateUrl; + } + logger.info("开通微信卡券接口url:{},请求参数:{}", url, reqDataJson); + String response = HttpRESTDataClient.requestPost(url, "application/json; charset=utf-8", reqDataJson); + logger.info("开通微信卡券接口返回:{}", response); + JSONObject data = (JSONObject) JSONObject.parse(response); + if (data.get("errcode").toString().equals("0")) { + if (StringUtil.isEmpty(wxCardId)) { + cardId = data.get("card_id").toString(); + } else { + cardId = wxCardId; + } + } else { + // token失效,刷新token + if (data.get("errcode").toString().equals("40014")) { + getAccessToken(merchantId, false,false); + } + logger.error("开通微信卡券出错啦{}", data.get("errmsg").toString()); + throw new BusinessCheckException("开通微信卡券出错啦:" + data.get("errmsg").toString()); + } + } catch (Exception e) { + logger.error("开通微信卡券出错啦:{}", e.getMessage()); + throw new BusinessCheckException("开通微信卡券出错啦:" + e.getMessage()); + } + + return cardId; + } + + /** + * 创建微信卡券领取的二维码 + * + * @param merchantId 商户ID + * @param cardId 微信卡券ID + * @param code 会员卡编码 + * @return + * */ + @Override + public String createCardQrCode(Integer merchantId, String cardId, String code) { + try { + String accessToken = getAccessToken(merchantId, false, true); + String url = "https://api.weixin.qq.com/card/qrcode/create?access_token="+accessToken; + + Map param = new HashMap<>(); + Map actionInfo = new HashMap<>(); + Map card = new HashMap<>(); + card.put("card_id", cardId); + card.put("code", code); + card.put("is_unique_code", false); + card.put("outer_str", "12b"); + actionInfo.put("card", card); + param.put("action_name", "QR_CARD"); + param.put("action_info", actionInfo); + + String reqDataJsonStr = JsonUtil.toJSONString(param); + String response = HttpRESTDataClient.requestPostBody(url, reqDataJsonStr); + logger.info("微信卡券createCardQrCode接口返回:{}", response); + JSONObject data = (JSONObject) JSONObject.parse(response); + String qrCode = ""; + if (data.get("errcode").toString().equals("0")) { + String content = data.get("url").toString(); + try { + // 生成并输出二维码 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + com.fuint.common.util.QRCodeUtil.createQrCode(out, content, 800, 800, "png", ""); + // 对数据进行Base64编码 + qrCode = new String(Base64Util.baseEncode(out.toByteArray()), "UTF-8"); + return "data:image/jpg;base64," + qrCode; + } catch (Exception e) { + logger.error("生成并输出二维码出错:{}", e.getMessage()); + } + } + } catch (Exception e) { + logger.error("创建微信卡券领取二维码出错:{}", e.getMessage()); + return ""; + } + return ""; + } + + /** + * 是否已领取卡券 + * + * @param merchantId 商户ID + * @param cardId 微信卡券ID + * @param openId openId + * @return + * */ + @Override + public Boolean isOpenCard(Integer merchantId, String cardId, String openId) { + try { + String accessToken = getAccessToken(merchantId, false,true); + String url = "https://api.weixin.qq.com/card/user/getcardlist?access_token="+accessToken; + + Map param = new HashMap<>(); + param.put("openid", openId); + param.put("card_id", cardId); + + String reqDataJsonStr = JsonUtil.toJSONString(param); + String response = HttpRESTDataClient.requestPostBody(url, reqDataJsonStr); + logger.info("微信卡券getCardList接口返回:{}", response); + JSONObject data = (JSONObject) JSONObject.parse(response); + if (data.get("errcode").toString().equals("0")) { + Object cards = data.get("card_list"); + logger.info("微信卡券getCardList接口card_list:{}", cards.toString()); + if (cards != null && cards.toString().length() > 6) { + return true; + } + return false; + } + } catch (Exception e) { + logger.error("微信卡券getCardList接口出错:{}", e.getMessage()); + return true; + } + return true; + } + + /** + * 生成小程序链接 + * + * @param merchantId 商户ID + * @param path 页面路径 + * @return + * */ + @Override + public String createMiniAppLink(Integer merchantId, String path) { + String link = ""; + try { + String accessToken = getAccessToken(merchantId, true,true); + if (StringUtil.isEmpty(accessToken)) { + return ""; + } + String url = "https://api.weixin.qq.com/wxa/genwxashortlink?access_token=" + accessToken +"&"; + + Map param = new HashMap<>(); + param.put("page_url", path); + + String reqDataJsonStr = JsonUtil.toJSONString(param); + String response = HttpRESTDataClient.requestPostBody(url, reqDataJsonStr); + logger.info("微信生成链接接口返回:{}", response); + JSONObject data = (JSONObject) JSONObject.parse(response); + + if (data.get("errcode").toString().equals("0")) { + Object linkObject = data.get("link"); + if (linkObject != null && StringUtil.isNotEmpty(linkObject.toString())) { + link = linkObject.toString(); + } + } + } catch (Exception e) { + logger.error("微信生成链接接口出错:{}", e.getMessage()); + return ""; + } + + return link; + } + + /** + * 上传小程序发货信息 + * + * @param orderSn 订单号 + * @return + */ + @Override + public void uploadShippingInfo(String orderSn) throws BusinessCheckException { + UserOrderDto orderInfo = orderService.getOrderByOrderSn(orderSn); + if (orderInfo == null) { + return; + } + if (orderInfo.getExpressInfo() == null || StringUtil.isEmpty(orderInfo.getExpressInfo().getExpressNo())) { + throw new BusinessCheckException("上传发货信息失败,物流信息不能为空!"); + } + if (orderInfo.getUserInfo() == null || StringUtil.isEmpty(orderInfo.getUserInfo().getOpenId())) { + throw new BusinessCheckException("上传发货信息失败,会员的openId不能为空!"); + } + // 是否是微信小程序订单 && 微信支付 + if (orderInfo != null && orderInfo.getPlatform().equals(PlatformTypeEnum.MP_WEIXIN.getCode()) || orderInfo.getPayType().equals(PayTypeEnum.JSAPI.name())) { + String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + getAccessToken(orderInfo.getMerchantId(), true, true); + + // 获取微信支付配置 + getApiConfig(orderInfo.getStoreId(), orderInfo.getPlatform()); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + + // 组织上传参数 + ShippingInfo shippingInfo = new ShippingInfo(); + + // 1、订单参数 + OrderKeyBean orderKeyBean = new OrderKeyBean(); + orderKeyBean.setOrderNumberType(1); + orderKeyBean.setMchId(wxPayApiConfig.getMchId()); + orderKeyBean.setOutTradeNo(orderSn); + shippingInfo.setOrderKey(orderKeyBean); + + // 2、物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提 + shippingInfo.setLogisticsType(1); + + // 3、发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY + shippingInfo.setDeliveryMode(1); + + // 4、物流信息列表,发货物流单列表,支持统一发货(单个物流单)和分拆发货(多个物流单)两种模式 + List shippingList = new ArrayList<>(); + ShippingListBean shippingListBean = new ShippingListBean(); + shippingListBean.setTrackingNo(orderInfo.getExpressInfo().getExpressNo()); + shippingListBean.setExpressCompany(orderInfo.getExpressInfo().getExpressCode()); + ContactBean contact = new ContactBean(); + contact.setConsignorContact(orderInfo.getStoreInfo().getPhone()); + contact.setReceiverContact(orderInfo.getAddress().getMobile()); + shippingListBean.setContact(contact); + + shippingList.add(shippingListBean); + shippingInfo.setShippingList(shippingList); + + // 5、支付者信息 + PayerBean payerBean = new PayerBean(); + payerBean.setOpenid(orderInfo.getUserInfo().getOpenId()); + shippingInfo.setPayer(payerBean); + + try { + String reqJson = JsonUtil.toJSONString(shippingInfo); + String response = HttpRESTDataClient.requestPostBody(url, reqJson); + logger.info("微信上传发货信息接口参数:{},返回:{}", reqJson, response); + JSONObject data = (JSONObject) JSONObject.parse(response); + MtUploadShippingLog mtUploadShippingLog = new MtUploadShippingLog(); + mtUploadShippingLog.setMerchantId(orderInfo.getMerchantId()); + mtUploadShippingLog.setStoreId(orderInfo.getStoreId()); + mtUploadShippingLog.setOrderId(orderInfo.getId()); + mtUploadShippingLog.setOrderSn(orderSn); + mtUploadShippingLog.setMobile(orderInfo.getAddress().getMobile()); + Date time = new Date(); + mtUploadShippingLog.setCreateTime(time); + mtUploadShippingLog.setUpdateTime(time); + if (data.get("errcode").toString().equals("0")) { + logger.info("微信上传发货信息接口成功,订单号:", orderSn); + mtUploadShippingLog.setStatus(OrderStatusType.Completed.getVal()); + } else { + mtUploadShippingLog.setStatus(OrderStatusType.Failed.getVal()); + } + uploadShippingLogMapper.insert(mtUploadShippingLog); + } catch (Exception e) { + logger.error("微信上传发货信息接口失败:", e.getMessage()); + } + } + } + + /** + * 刷卡支付 + * + * @param storeId 店铺ID + * @param reqData 请求参数 + * @param ip 支付IP + * @param platform 支付平台 + * @return + * */ + private Map microPay(Integer storeId, Map reqData, String ip, String platform) { + try { + String orderSn = reqData.get("out_trade_no"); + + logger.info("调用微信刷卡支付下单接口入参{}", JsonUtil.toJSONString(reqData)); + logger.info("请求平台:{}, 订单号:{}", platform, orderSn); + + // 支付配置 + getApiConfig(storeId, platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + Map params = MicroPayModel.builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .nonce_str(WxPayKit.generateStr()) + .body(reqData.get("body")) + .attach(reqData.get("body")) + .out_trade_no(orderSn) + .total_fee(reqData.get("total_fee")) + .spbill_create_ip(ip) + .auth_code(reqData.get("auth_code")) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5); + String xmlResult = WxPayApi.microPay(false, params); + + // 同步返回结果 + logger.info("xmlResult:" + xmlResult); + Map respMap = WxPayKit.xmlToMap(xmlResult); + String returnCode = respMap.get("return_code"); + String returnMsg = respMap.get("return_msg"); + String errCode = respMap.get("err_code"); + if (!WxPayKit.codeIsOk(returnCode)) { + Map payResult = null; + if (StringUtil.isNotEmpty(errCode)) { + // 用户支付中,需要输入密码 + if (errCode.equals("USERPAYING")) { + // 等待10秒后查询订单 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + payResult = queryPaidOrder(storeId, respMap.get("transaction_id"), orderSn); + } + } + if (payResult == null || !payResult.get("trade_state").equals("SUCCESS")) { + logger.info("提交刷卡支付失败>>" + xmlResult); + return respMap; + } + } + + String resultCode = respMap.get("result_code"); + if (!WxPayKit.codeIsOk(resultCode)) { + logger.info("支付失败>>" + xmlResult); + logger.error(returnMsg); + return respMap; + } + + // 支付成功 + logger.info("刷卡支付返回>>" + respMap.toString()); + + if (StringUtil.isNotEmpty(orderSn)) { + UserOrderDto orderInfo = orderService.getOrderByOrderSn(orderSn); + if (orderInfo != null) { + if (!orderInfo.getStatus().equals(OrderStatusEnum.DELETED.getKey())) { + paymentService.paymentCallback(orderInfo); + } + } + } + + return respMap; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * 小程序、公众号支付 + * + * @param storeId 店铺ID + * @param reqData 请求参数 + * @param ip 支付IP + * @param platform 支付平台 + * @return + * */ + private Map jsapiPay(Integer storeId, Map reqData, String ip, String platform) { + try { + logger.info("调用微信支付下单接口入参:{},请求平台:{}", JsonUtil.toJSONString(reqData), platform); + // 获取支付配置 + getApiConfig(storeId, platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + Map params = UnifiedOrderModel + .builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .nonce_str(WxPayKit.generateStr()) + .body(reqData.get("body")) + .attach(reqData.get("body")) + .out_trade_no(reqData.get("out_trade_no")) + .total_fee(reqData.get("total_fee")) + .spbill_create_ip(ip) + .notify_url(wxPayApiConfig.getDomain() + CALL_BACK_URL) + .trade_type(reqData.get("trade_type")) + .openid(reqData.get("openid")) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5); + String xmlResult = WxPayApi.pushOrder(false, params); + + logger.info("调用微信支付回调地址:{}", wxPayApiConfig.getDomain() + CALL_BACK_URL); + logger.info("调用微信支付下单接口返回xml:{}", xmlResult); + Map result = WxPayKit.xmlToMap(xmlResult); + + String returnCode = result.get("return_code"); + String returnMsg = result.get("return_msg"); + if (!WxPayKit.codeIsOk(returnCode)) { + logger.error(returnMsg); + } + String resultCode = result.get("result_code"); + if (!WxPayKit.codeIsOk(resultCode)) { + logger.error(returnMsg); + } + + logger.info("调用微信支付下单接口返回数据:{}", JsonUtil.toJSONString(result)); + return result; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * h5支付 + * + * @param storeId 店铺ID + * @param reqData 请求参数 + * @param ip 支付IP + * @param platform 支付平台 + * @return + * */ + private Map wapPay(Integer storeId, Map reqData, String ip, String platform) { + try { + logger.info("调用微信h5支付下单接口入参{},请求平台:{}", JsonUtil.toJSONString(reqData), platform); + // 支付配置 + getApiConfig(storeId, platform); + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + H5SceneInfo sceneInfo = new H5SceneInfo(); + H5SceneInfo.H5 h5Info = new H5SceneInfo.H5(); + h5Info.setType("Wap"); + // 支付域名必须在商户平台->"产品中心"->"开发配置"中添加 + h5Info.setWap_url(wxPayApiConfig.getDomain()); + h5Info.setWap_name("WEB"); + sceneInfo.setH5Info(h5Info); + Map params = UnifiedOrderModel + .builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .nonce_str(WxPayKit.generateStr()) + .body(reqData.get("body")) + .attach(reqData.get("body")) + .out_trade_no(WxPayKit.generateStr()) + .total_fee(reqData.get("total_fee")) + .spbill_create_ip(ip) + .notify_url(wxPayApiConfig.getDomain() + CALL_BACK_URL) + .trade_type(TradeType.MWEB.getTradeType()) + .scene_info(JSON.toJSONString(sceneInfo)) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256); + + String xmlResult = WxPayApi.pushOrder(false, params); + logger.info("调用微信h5支付接口返回xml:{}", xmlResult); + + Map result = WxPayKit.xmlToMap(xmlResult); + + String return_code = result.get("return_code"); + String return_msg = result.get("return_msg"); + if (!WxPayKit.codeIsOk(return_code)) { + throw new RuntimeException(return_msg); + } + String result_code = result.get("result_code"); + if (!WxPayKit.codeIsOk(result_code)) { + throw new RuntimeException(return_msg); + } + result.put("backUrl", env.getProperty("website.url")); + logger.info("调用微信h5支付接口返回数据:{}", JsonUtil.toJSONString(result)); + return result; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * 获取支付配置 + * + * @param storeId 店铺ID + * @param platform 支付平台 + * @throws BusinessCheckException + * @return + * */ + private WxPayApiConfig getApiConfig(Integer storeId, String platform) throws BusinessCheckException { + WxPayApiConfig apiConfig; + + String mchId = wxPayBean.getMchId(); + String apiV2 = wxPayBean.getApiV2(); + String certPath = wxPayBean.getCertPath(); + String appId = wxPayBean.getAppId(); + + MtStore mtStore = storeService.queryStoreById(storeId); + logger.info("微信支付店铺信息:{}", JsonUtil.toJSONString(mtStore)); + if (mtStore != null && StringUtil.isNotEmpty(mtStore.getWxApiV2()) && StringUtil.isNotEmpty(mtStore.getWxMchId())) { + mchId = mtStore.getWxMchId(); + apiV2 = mtStore.getWxApiV2(); + String basePath = env.getProperty("images.root"); + certPath = basePath + mtStore.getWxCertPath(); + MtMerchant mtMerchant = merchantService.queryMerchantById(mtStore.getMerchantId()); + if (mtMerchant != null && StringUtil.isNotEmpty(mtMerchant.getWxAppId())) { + appId = mtMerchant.getWxAppId(); + } + } + + apiConfig = WxPayApiConfig.builder() + .appId(appId) + .mchId(mchId) + .partnerKey(apiV2) + .certPath(certPath) + .domain(wxPayBean.getDomain()) + .build(); + + // 微信内h5公众号支付 + if (platform.equals(PlatformTypeEnum.H5.getCode()) || StringUtil.isBlank(appId)) { + String wxAppId = env.getProperty("weixin.official.appId"); + String wxAppSecret = env.getProperty("weixin.official.appSecret"); + + if (mtStore != null) { + MtMerchant mtMerchant = merchantService.queryMerchantById(mtStore.getMerchantId()); + if (mtMerchant != null && StringUtil.isNotEmpty(mtMerchant.getWxOfficialAppId()) && StringUtil.isNotEmpty(mtMerchant.getWxOfficialAppSecret())) { + wxAppId = mtMerchant.getWxOfficialAppId(); + wxAppSecret = mtMerchant.getWxOfficialAppSecret(); + } + } + + if (StringUtil.isNotEmpty(wxAppId) && StringUtil.isNotEmpty(wxAppSecret)) { + apiConfig.setAppId(wxAppId); + apiConfig.setApiKey(wxAppSecret); + } + } + + WxPayApiConfigKit.setThreadLocalWxPayApiConfig(apiConfig); + logger.info("微信支付参数:{}", JsonUtil.toJSONString(apiConfig)); + + return apiConfig; + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/util/AliyunOssUtil.java b/fuint-application/src/main/java/com/fuint/common/util/AliyunOssUtil.java new file mode 100644 index 0000000..8bfc919 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/util/AliyunOssUtil.java @@ -0,0 +1,124 @@ +package com.fuint.common.util; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.model.Bucket; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.OSSObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Date; + +/** + * 阿里云OSS存储工具 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class AliyunOssUtil { + + private static final Logger logger = LoggerFactory.getLogger(AliyunOssUtil.class); + + /** + * 获取阿里云OSS客户端对象 + * + * @param accessKeyId 访问键值 + * @param accessKeySecret 访问秘钥 + * @param endpoint 存储endPoint + * @return ossClient + */ + public static OSS getOSSClient(String accessKeyId, String accessKeySecret, String endpoint) { + return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); + } + + /** + * 创建存储空间 + * + * @param ossClient OSS连接 + * @param bucketName 存储空间 + * @return + */ + public static String createBucketName(OSS ossClient, String bucketName) { + // 存储空间 + final String bucketNames = bucketName; + + if (!ossClient.doesBucketExist(bucketName)) { + // 创建存储空间 + Bucket bucket = ossClient.createBucket(bucketName); + logger.info("创建存储空间成功"); + return bucket.getName(); + } + + return bucketNames; + } + + /** + * 创建模拟文件夹 + * + * @param ossClient oss连接 + * @param bucketName 存储bucket + * @param folder 文件夹 + * @return 文件夹名 + */ + public static String createFolder(OSS ossClient, String bucketName, String folder) { + // 文件夹名 + final String keySuffixWithSlash = folder; + + // 判断文件夹是否存在,不存在则创建 + if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) { + // 创建文件夹 + ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0])); + logger.info("创建文件夹成功"); + // 得到文件夹名 + OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash); + String fileDir = object.getKey(); + return fileDir; + } + + return keySuffixWithSlash; + } + + /** + * 上传图片至OSS + * + * @param ossClient oss连接 + * @param file 上传文件(文件全路径如:D:\\image\\cake.jpg) + * @return String 返回文件url + */ + public static String upload(OSS ossClient, File file, String bucketName, String folder) { + String resultStr = null; + + // 先创建存储空间和文件夹 + createBucketName(ossClient, bucketName); + createFolder(ossClient, bucketName, folder); + + try { + InputStream is = new FileInputStream(file); + String fileName = file.getName(); + String date = DateUtil.formatDate(new Date(), "yyyyMMdd"); + ossClient.putObject(bucketName, folder + "/" + date + "/" + fileName, is); + resultStr = "/" + folder + "/" + date +"/" + fileName; + } catch (Exception e) { + e.printStackTrace(); + logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e); + } + + return resultStr; + } + + /** + * 根据key删除OSS上的文件 + * + * @param ossClient oss连接 + * @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg" + */ + public static void deleteFile(OSS ossClient, String bucketName, String folder, String key) { + ossClient.deleteObject(bucketName, folder + key); + + logger.info("删除" + bucketName + "下的文件" + folder + key + "成功"); + } +} + diff --git a/fuint-application/src/main/java/com/fuint/common/util/AuthUserUtil.java b/fuint-application/src/main/java/com/fuint/common/util/AuthUserUtil.java new file mode 100644 index 0000000..24a681c --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/util/AuthUserUtil.java @@ -0,0 +1,29 @@ +package com.fuint.common.util; + +import com.alibaba.ttl.TransmittableThreadLocal; +import com.fuint.common.dto.AccountInfo; + +/** + * 用户认证工具 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class AuthUserUtil { + + private static final ThreadLocal USER_INFO_IN_TOKEN_HOLDER = new TransmittableThreadLocal<>(); + + public static AccountInfo get() { + return USER_INFO_IN_TOKEN_HOLDER.get(); + } + + public static void set(AccountInfo userInfoInTokenBo) { + USER_INFO_IN_TOKEN_HOLDER.set(userInfoInTokenBo); + } + + public static void clean() { + if (USER_INFO_IN_TOKEN_HOLDER.get() != null) { + USER_INFO_IN_TOKEN_HOLDER.remove(); + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/util/Base64Util.java b/fuint-application/src/main/java/com/fuint/common/util/Base64Util.java new file mode 100644 index 0000000..a560bc9 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/util/Base64Util.java @@ -0,0 +1,106 @@ +package com.fuint.common.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.UnsupportedEncodingException; +import java.util.Base64; + +/** + * 编码工具 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Base64Util { + + private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); + + public Base64Util() { + // empty + } + + public static byte[] baseEncode(byte[] bytes) { + return Base64.getEncoder().encode(bytes); + } + + public static String baseEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] baseDecode(byte[] bytes) { + return Base64.getDecoder().decode(bytes); + } + + public static String baseDecode(String s) { + try { + byte[] e = Base64.getDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlEncode(byte[] bytes) { + return Base64.getUrlEncoder().encode(bytes); + } + + public static String urlEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getUrlEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] urlDecode(byte[] bytes) { + return Base64.getUrlDecoder().decode(bytes); + } + + public static String urlDecode(String s) { + byte[] result = Base64.getUrlDecoder().decode(s); + + try { + return new String(result, "UTF-8"); + } catch (UnsupportedEncodingException var3) { + logger.error(var3.getMessage(), var3); + return null; + } + } + + public static byte[] mimeEncode(byte[] bytes) { + return Base64.getMimeEncoder().encode(bytes); + } + + public static String mimeEncode(String s) { + try { + byte[] e = s.getBytes("UTF-8"); + return Base64.getMimeEncoder().encodeToString(e); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static byte[] mimeDecode(byte[] bytes) { + return Base64.getMimeDecoder().decode(bytes); + } + + public static String mimeDecode(String s) { + try { + byte[] e = Base64.getMimeDecoder().decode(s); + return new String(e, "UTF-8"); + } catch (UnsupportedEncodingException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/util/BizCodeGenerator.java b/fuint-application/src/main/java/com/fuint/common/util/BizCodeGenerator.java new file mode 100644 index 0000000..968220b --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/util/BizCodeGenerator.java @@ -0,0 +1,65 @@ +package com.fuint.common.util; + +import com.fuint.utils.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Random; + +/** + * 业务Code生成器 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class BizCodeGenerator { + + private static final Logger logger = LoggerFactory.getLogger(BizCodeGenerator.class); + + private static final String DATE_FORMAT="yyyyMMddHHmmssSSS"; + + /** + * 获取指定前缀的Code字符串 + * @param preString 前缀字符串 + * @return + */ + public synchronized static String getPreCodeString(String preString) { + StringBuffer result = new StringBuffer(); + if(StringUtil.isNotEmpty(preString)){ + result.append(preString); + } + + String dateStr = new SimpleDateFormat(DATE_FORMAT).format(new Date()); + result.append(dateStr); + + String randomStr = SeqUtil.getRandomNumber(2); + result.append(randomStr); + return result.toString(); + } + + + /** + * 生成6位数字短信验证码 + * @param + * @return + */ + public synchronized static String getVerifyCode() { + String verifyCode = getFixLengthString(6); + return verifyCode; + } + + /** + * 返回长度为【strLength】的随机数,在前面补0 + * @return + */ + private static String getFixLengthString(int strLength) { + Random rm = new Random(); + // 获得随机数 + double process = (1 + rm.nextDouble()) * Math.pow(10, strLength); + // 将获得的获得随机数转化为字符串 + String codeStr = String.valueOf(process); + // 返回固定的长度的随机数 + return codeStr.substring(1, strLength + 1); + } +} diff --git a/fuint-application/src/main/java/com/fuint/common/util/CommonUtil.java b/fuint-application/src/main/java/com/fuint/common/util/CommonUtil.java new file mode 100644 index 0000000..32512c1 --- /dev/null +++ b/fuint-application/src/main/java/com/fuint/common/util/CommonUtil.java @@ -0,0 +1,532 @@ +package com.fuint.common.util; + +import com.fuint.utils.StringUtil; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URLDecoder; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 通用工具 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class CommonUtil { + + /** + * 校验经纬度是否是有效的全球坐标 + * + * @param longitude 经度 + * @param latitude 纬度 + * @return true-有效; false-无效 + */ + public static boolean isValidGlobalCoordinate(double longitude, double latitude) { + // 校验纬度范围 (-90 ~ 90) + boolean isLatValid = (latitude >= -90.0 && latitude <= 90.0); + // 校验经度范围 (-180 ~ 180) + boolean isLngValid = (longitude >= -180.0 && longitude <= 180.0); + return isLatValid && isLngValid; + } + + /** + * 对象转化成map + * + * @param obj 对象 + * @return + * */ + public static Map convert(Object obj) throws IllegalAccessException { + Map map = new HashMap<>(); + Class clazz = obj.getClass(); + + for (Field field : clazz.getDeclaredFields()) { + field.setAccessible(true); + map.put(field.getName(), field.get(obj)); + } + + return map; + } + + /** + * 隐藏手机号中间4位 + * + * @param phone + * @return + * */ + public static String hidePhone(String phone) { + if (StringUtil.isBlank(phone)) { + return ""; + } + if (phone.length() < 11) { + return phone; + } + return phone.substring(0, 3) + "****" + phone.substring(7); + } + + + /** + * 功能:将输入字符串的首字母改成大写 + * + * @param str + * @return + */ + public static String firstLetterToUpperCase(String str) { + char[] ch = str.toCharArray(); + if (ch[0] >= 'a' && ch[0] <= 'z') { + ch[0] = (char) (ch[0] - 32); + } + return new String(ch); + } + + /** + * 功能:将输入字符串的首字母改成驼峰格式 + * + * @param str + * @return + */ + public static String toCamelCase(String str) { + if (str == null) { + return null; + } + str = str.toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperCase = false; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '_') { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 判断是否UTF-8编码 + * + * @param str + * @return + * */ + public static boolean isUtf8(String str) { + try { + byte[] bytes = str.getBytes("UTF-8"); + String newStr = new String(bytes, "UTF-8"); + return str.equals(newStr); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 判断是否乱码 + * + * @param str + * @return + * */ + public static boolean isErrCode(String str) { + return !(java.nio.charset.Charset.forName("GBK").newEncoder().canEncode(str)); + } + + /** + * 判断是否数字 + * + * @param str 字符串 + * @return + * */ + public static boolean isNumeric(String str) { + if (StringUtil.isEmpty(str)) { + return false; + } + + Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+"); + Matcher isNum = pattern.matcher(str); + + if (!isNum.matches()) { + return false; + } + + return true; + } + + /** + * 生成随机会员号(13位数) + * + * @return + * */ + public static String createUserNo() { + StringBuilder sb = new StringBuilder("8"); + sb.append(SeqUtil.getRandomNumber(4)); + sb.append(SeqUtil.getRandomNumber(4)); + sb.append(SeqUtil.getRandomNumber(4)); + return sb.toString(); + } + + /** + * 生成随机键值号 + * + * @return + * */ + public static String createAccountKey() { + StringBuilder sb = new StringBuilder("11"); + sb.append(SeqUtil.getRandomNumber(6)); + sb.append(SeqUtil.getRandomNumber(5)); + String t = TimeUtils.formatDate(new Date(), "yyyyMMddHH"); + return t + sb.toString(); + } + + /** + * 生成随机商户号 + * + * @return + * */ + public static String createMerchantNo() { + StringBuilder sb = new StringBuilder("8"); + sb.append(SeqUtil.getRandomNumber(4)); + sb.append(SeqUtil.getRandomNumber(4)); + return sb.toString(); + } + + /** + * 生成随机结算单号(13位数) + * + * @return + * */ + public static String createSettlementNo() { + StringBuilder sb = new StringBuilder("8"); + sb.append(SeqUtil.getRandomNumber(4)); + sb.append(SeqUtil.getRandomNumber(4)); + sb.append(SeqUtil.getRandomNumber(4)); + return sb.toString(); + } + + /** + * 生成随机订单号 + * + * @param userId + * @return + * */ + public static String createOrderSN(String userId) { + // 时间是17位 + String date = DateUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS"); + StringBuilder sb = new StringBuilder(); + sb.append(date); + + // 目前的会员id为9位,不确定后面会不会变更 + if (userId.length() > 9) { + sb.append(userId.substring(userId.length() - 9, 9)); + } + + if (userId.length() == 9) { + sb.append(userId); + } + + // 如果小于9位补位 + if (userId.length() < 9) { + for (int i = 0; i < userId.length() - 9; i++) { + sb.append("0"); + } + } + + // 加上4位随机数 + sb.append(SeqUtil.getRandomNumber(4)); + return sb.toString(); + } + + /** + * 获取IP地址 + * + * @param request + * @return String + */ + public static String getIPFromHttpRequest(HttpServletRequest request) { + String ipAddress; + try { + ipAddress = request.getHeader("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + if (ipAddress.equals("127.0.0.1")) { + // 根据网卡取本机配置的IP + InetAddress inet = null; + try { + inet = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + ipAddress = inet.getHostAddress(); + } + } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > 15) { + if (ipAddress.indexOf(",") > 0) { + ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); + } + } + } catch (Exception e) { + ipAddress = ""; + } + + if (!isValidIP(ipAddress)) { + return "127.0.0.1"; + } + + return ipAddress; + } + + /** + * 验证ip地址是否正确 + * + * @param ip + * @return + * */ + public static boolean isValidIP(String ip) { + if ((ip != null) && (!ip.isEmpty())) { + return Pattern.matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", ip); + } + return false; + } + + /** + * 保存上传文件 + * + * @param file 上传的文件 + * @param filePath 文件路径 + * @return + * */ + public static void saveMultipartFile(MultipartFile file, String filePath) { + if (file != null && !file.isEmpty()) { + try { + FileOutputStream os = new FileOutputStream(new File(filePath)); + //拿到上传文件的输入流 + os.write(file.getBytes()); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 格式化指定的日期 + * + * @param date + * @param formatStr + * @return + */ + public static String formatDate(Date date, String formatStr) { + if (date == null) date = new Date(); + if (StringUtil.isEmpty(formatStr)) formatStr = "yyyy-MM-dd"; + SimpleDateFormat dateFormater = new SimpleDateFormat(formatStr); + return dateFormater.format(date); + } + + /** + * 去除待带script、src的语句,转义替换后的value值 + * + * @param value + * + * @return + */ + public static String replaceXSS(String value) { + if (value != null) { + try { + value = value.replace("+","%2B"); + value = URLDecoder.decode(value, "utf-8"); + } catch(Exception e) { + //empty + } + + StringBuilder buf = new StringBuilder(value.length()); + int len = value.length(); + for (int i = 0; i < len; i++) { + char codePoint = value.charAt(i); + if (isEmojiCharacter(codePoint)) { + buf.append("*"); + } else { + buf.append(codePoint); + } + } + + String emojiStr = buf.toString(); + if (!StringUtil.isEmpty(emojiStr)) { + value = emojiStr; + } + + // Avoid null characters + value = value.replaceAll("\0", ""); + + // Avoid anything between script tags + Pattern scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + + // Avoid anything in a src='...' type of e­xpression + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + + // Remove any lonesome tag + scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + + // Remove any lonesome diff --git a/fuint-application/src/main/resources/vm/vue/index.vue.vm b/fuint-application/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/fuint-application/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/fuint-application/src/main/resources/vm/vue/v3/index-tree.vue.vm b/fuint-application/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/fuint-application/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/fuint-application/src/main/resources/vm/vue/v3/index.vue.vm b/fuint-application/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/fuint-application/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/fuint-application/src/main/resources/vm/xml/mapper.xml.vm b/fuint-application/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..fa50fcf --- /dev/null +++ b/fuint-application/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-framework/pom.xml b/fuint-framework/pom.xml new file mode 100644 index 0000000..ad2d6c5 --- /dev/null +++ b/fuint-framework/pom.xml @@ -0,0 +1,42 @@ + + + + fuint + com.fuint + 1.0.0 + + 4.0.0 + + fuint-framework + 1.0.0 + jar + + + + com.fuint + fuint-utils + 1.0.0 + + + com.fuint + fuint-repository + 1.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/fuint-framework/src/main/java/com/fuint/framework/FrameworkConstants.java b/fuint-framework/src/main/java/com/fuint/framework/FrameworkConstants.java new file mode 100644 index 0000000..ada13d6 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/FrameworkConstants.java @@ -0,0 +1,11 @@ +package com.fuint.framework; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class FrameworkConstants { + + public static final int HTTP_RESPONSE_CODE_SUCCESS = 200; + +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/annoation/OperationServiceLog.java b/fuint-framework/src/main/java/com/fuint/framework/annoation/OperationServiceLog.java new file mode 100644 index 0000000..b0cdaef --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/annoation/OperationServiceLog.java @@ -0,0 +1,16 @@ +package com.fuint.framework.annoation; + +import java.lang.annotation.*; + +/** + * 操作日志记录注解 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Target({ElementType.PARAMETER, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OperationServiceLog { + String description() default ""; +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/dto/ExcelExportDto.java b/fuint-framework/src/main/java/com/fuint/framework/dto/ExcelExportDto.java new file mode 100644 index 0000000..1901da1 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/dto/ExcelExportDto.java @@ -0,0 +1,65 @@ +package com.fuint.framework.dto; + +import java.io.OutputStream; +import java.util.Map; + +/** + * 导出Excel文件DTO + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class ExcelExportDto { + + /** + * 模板文件名称 + */ + private String srcTemplateFileName; + + /** + * 模板文件所在resource路径 + */ + private String srcPath; + + /** + * 数据 + */ + private Map dataMap; + + /** + * 输出流 + */ + private OutputStream out; + + public String getSrcTemplateFileName() { + return srcTemplateFileName; + } + + public void setSrcTemplateFileName(String srcTemplateFileName) { + this.srcTemplateFileName = srcTemplateFileName; + } + + public Map getDataMap() { + return dataMap; + } + + public void setDataMap(Map dataMap) { + this.dataMap = dataMap; + } + + public OutputStream getOut() { + return out; + } + + public void setOut(OutputStream out) { + this.out = out; + } + + public String getSrcPath() { + return srcPath; + } + + public void setSrcPath(String srcPath) { + this.srcPath = srcPath; + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessCheckException.java b/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessCheckException.java new file mode 100644 index 0000000..2d78fe4 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessCheckException.java @@ -0,0 +1,71 @@ +package com.fuint.framework.exception; + +/** + * 业务检查异常 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class BusinessCheckException extends Exception { + private static final long serialVersionUID = 1L; + + private Throwable rootCause; + + public BusinessCheckException(String arg0) { + super(arg0); + this.errorKey = arg0; + rootCause = this; + } + + public BusinessCheckException() { + super(); + } + + public BusinessCheckException(String s, Throwable e) { + this(s); + if (e instanceof BusinessCheckException) { + rootCause = ((BusinessCheckException) e).rootCause; + } else { + rootCause = e; + } + } + + public BusinessCheckException(Throwable e) { + this("", e); + } + + public Throwable getRootCause() { + return rootCause; + } + + private String errorKey; + + public String getErrorKey() { + return errorKey; + } + + private String[] errorParam; + + private Object[] errorObjectParam; + + public Object[] getErrorObjectParam() { + return errorObjectParam; + } + + public void setErrorObjectParam(Object[] errorObjectParam) { + this.errorObjectParam = errorObjectParam; + } + + public BusinessCheckException(String key, Object[] objectParam) { + this(key); + this.errorObjectParam = objectParam; + } + + public String[] getErrorParam() { + return errorParam; + } + + public void setErrorParam(String[] errorParam) { + this.errorParam = errorParam; + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessRuntimeException.java b/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessRuntimeException.java new file mode 100644 index 0000000..8124f5a --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/exception/BusinessRuntimeException.java @@ -0,0 +1,71 @@ +package com.fuint.framework.exception; + +/** + * 业务运行异常 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class BusinessRuntimeException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private Throwable rootCause; + + public BusinessRuntimeException(String arg0) { + super(arg0); + this.errorKey = arg0; + rootCause = this; + } + + public BusinessRuntimeException() { + super(); + } + + public BusinessRuntimeException(String s, Throwable e) { + this(s); + if (e instanceof BusinessRuntimeException) { + rootCause = ((BusinessRuntimeException) e).rootCause; + } else { + rootCause = e; + } + } + + public BusinessRuntimeException(Throwable e) { + this("", e); + } + + public Throwable getRootCause() { + return rootCause; + } + + private String errorKey; + + public String getErrorKey() { + return errorKey; + } + + private String[] errorParam; + + private Object[] errorObjectParam; + + public Object[] getErrorObjectParam() { + return errorObjectParam; + } + + public void setErrorObjectParam(Object[] errorObjectParam) { + this.errorObjectParam = errorObjectParam; + } + + public BusinessRuntimeException(String key, Object[] objectParam) { + this(key); + this.errorObjectParam = objectParam; + } + + public String[] getErrorParam() { + return errorParam; + } + + public void setErrorParam(String[] errorParam) { + this.errorParam = errorParam; + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/exception/GlobalExceptionHandler.java b/fuint-framework/src/main/java/com/fuint/framework/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..8e2bd74 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/exception/GlobalExceptionHandler.java @@ -0,0 +1,106 @@ +package com.fuint.framework.exception; + +import com.fuint.framework.web.ResponseObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import javax.servlet.http.HttpServletRequest; + +/** + * 全局异常处理器 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@RestControllerAdvice +public class GlobalExceptionHandler { + + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public ResponseObject handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return new ResponseObject(201, e.getMessage(), null); + } + + /** + * 业务异常 + */ + @ExceptionHandler(BusinessCheckException.class) + public ResponseObject handleServiceException(BusinessCheckException e) { + log.error(e.getMessage(), e); + return new ResponseObject(201, e.getMessage(), null); + } + + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public ResponseObject handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return new ResponseObject(201, String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()), null); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public ResponseObject handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return new ResponseObject(201, String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()), null); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public ResponseObject handleRuntimeException(RuntimeException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + e.printStackTrace(); + return new ResponseObject(201, e.getMessage(), null); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public ResponseObject handleException(Exception e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + e.printStackTrace(); + return new ResponseObject(201, e.getMessage(), null); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public ResponseObject handleBindException(BindException e) { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return new ResponseObject(201,message, null); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return new ResponseObject(201,message, null); + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationRequest.java b/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationRequest.java new file mode 100644 index 0000000..56c9dc2 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationRequest.java @@ -0,0 +1,97 @@ +package com.fuint.framework.pagination; + +import java.io.Serializable; +import java.util.Map; + +/** + * 分页实体对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class PaginationRequest implements Serializable { + + private static final long serialVersionUID = -344484321130132260L; + + /** + * 当前页码 + */ + private int currentPage; + /** + * 每页大小 + */ + private int pageSize; + /** + * 排序字段 + */ + private String[] sortColumn; + /** + * 排序类型 + */ + private String sortType; + /** + * 分页查询参数 + */ + private Map searchParams; + + // 默认构造函数 + public PaginationRequest() { + this.currentPage = 1; + this.pageSize = 20; + } + + public PaginationRequest(Integer pageNumber, Integer pageSize) { + this.currentPage = pageNumber; + this.pageSize = pageSize; + } + + public PaginationRequest(Integer pageNumber, Integer pageSize, Map searchParams) { + this.currentPage = pageNumber; + this.pageSize = pageSize; + this.searchParams = searchParams; + } + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public String[] getSortColumn() { + return sortColumn; + } + + public void setSortColumn(String sortColumn) { + this.sortColumn = new String[]{sortColumn}; + } + + public void setSortColumn(String[] sortColumns) { + this.sortColumn = sortColumns; + } + + public String getSortType() { + return sortType; + } + + public void setSortType(String sortType) { + this.sortType = sortType; + } + + public Map getSearchParams() { + return searchParams; + } + + public void setSearchParams(Map searchParams) { + this.searchParams = searchParams; + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationResponse.java b/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationResponse.java new file mode 100644 index 0000000..9f59027 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/pagination/PaginationResponse.java @@ -0,0 +1,167 @@ +package com.fuint.framework.pagination; + +import org.springframework.data.domain.Page; +import java.io.Serializable; +import java.util.List; + +/** + * 分页请求响应结果对象 + * + * @param + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class PaginationResponse implements Serializable { + + private static final long serialVersionUID = 1115676724739520700L; + + /** + * 当前页码 + */ + private int currentPage; + /** + * 每页大小 + */ + private int pageSize; + /** + * 总页数 + */ + private int totalPages; + private int numberOfElements; + /** + * 总记录数 + */ + private long totalElements; + /** + * 是否有上一页 + */ + private boolean hasPreviousPage; + /** + * 是否是第一页 + */ + private boolean isFirstPage; + /** + * 是否有下一页 + */ + private boolean hasNextPage; + /** + * 是否是最后一页 + */ + private boolean isLastPage; + /** + * 是否有内容 + */ + private boolean hasContent; + /** + * 结果集合 + */ + private List content; + + /** + * 构造方法 + */ + public PaginationResponse(final Page page, final Class clz) { + this.currentPage = page.getNumber(); + this.pageSize = page.getSize(); + this.totalPages = page.getTotalPages(); + this.numberOfElements = page.getNumberOfElements(); + this.totalElements = page.getTotalElements(); + this.hasPreviousPage = page.hasPrevious(); + this.isFirstPage = page.isFirst(); + this.hasNextPage = page.hasNext(); + this.isLastPage = page.isLast(); + if (page.getContent() != null && page.getContent().size() > 0) { + this.hasContent = true; + } + + } + + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + public int getNumberOfElements() { + return numberOfElements; + } + + public void setNumberOfElements(int numberOfElements) { + this.numberOfElements = numberOfElements; + } + + public long getTotalElements() { + return totalElements; + } + + public void setTotalElements(long totalElements) { + this.totalElements = totalElements; + } + + public boolean isHasPreviousPage() { + return hasPreviousPage; + } + + public void setHasPreviousPage(boolean hasPreviousPage) { + this.hasPreviousPage = hasPreviousPage; + } + + public boolean isFirstPage() { + return isFirstPage; + } + + public void setFirstPage(boolean isFirstPage) { + this.isFirstPage = isFirstPage; + } + + public boolean isHasNextPage() { + return hasNextPage; + } + + public void setHasNextPage(boolean hasNextPage) { + this.hasNextPage = hasNextPage; + } + + public boolean isLastPage() { + return isLastPage; + } + + public void setLastPage(boolean isLastPage) { + this.isLastPage = isLastPage; + } + + public boolean isHasContent() { + return hasContent; + } + + public void setHasContent(boolean hasContent) { + this.hasContent = hasContent; + } + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/service/ExportService.java b/fuint-framework/src/main/java/com/fuint/framework/service/ExportService.java new file mode 100644 index 0000000..ca81e0b --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/service/ExportService.java @@ -0,0 +1,21 @@ +package com.fuint.framework.service; + +import com.fuint.framework.dto.ExcelExportDto; + +/** + * 导出Excel文件业务接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface ExportService { + + /** + * 直接导出本地文件 + * + * @param data srcPath 文件相对路径 + * srcTemplateFileName 文件名称 + * out 输出流 + */ + void exportLocalFile(ExcelExportDto data) throws Exception; +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/service/ExportServiceImpl.java b/fuint-framework/src/main/java/com/fuint/framework/service/ExportServiceImpl.java new file mode 100644 index 0000000..6b0e60a --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/service/ExportServiceImpl.java @@ -0,0 +1,68 @@ +package com.fuint.framework.service; + +import com.fuint.framework.dto.ExcelExportDto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; + +/** + * 导出Excel文件业务实现类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Service +public class ExportServiceImpl implements ExportService { + + private static final Logger logger = LoggerFactory.getLogger(ExportServiceImpl.class); + + private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + @Override + public void exportLocalFile(ExcelExportDto data) throws Exception { + // 下载本地文件 + InputStream inStream = null; + try { + String fileName = data.getSrcTemplateFileName(); + // 读到流中s + inStream = new FileInputStream(data.getSrcPath() + File.separator + fileName);// 文件的存放路径 + // 循环取出流中的数据 + byte[] b = new byte[100]; + int len; + while ((len = inStream.read(b)) > 0) { + data.getOut().write(b, 0, len); + } + inStream.close(); + data.getOut().flush(); + data.getOut().close(); + // 设置输出的格式 + } catch (FileNotFoundException e) { + logger.error("ExportServiceImpl.exportLocalFile{}", e); + throw e; + } catch (IOException e) { + logger.error("ExportServiceImpl.exportLocalFile{}", e); + throw e; + } finally { + try { + if (null != inStream) { + inStream.close(); + } + } catch (IOException e) { + logger.error("ExportServiceImpl.exportLocalFile{}", e); + } + if (null != data.getOut()) { + try { + data.getOut().close(); + } catch (IOException e) { + logger.error("ExportServiceImpl.exportLocalFile{}", e); + } + } + } + } +} diff --git a/fuint-framework/src/main/java/com/fuint/framework/web/BaseController.java b/fuint-framework/src/main/java/com/fuint/framework/web/BaseController.java new file mode 100644 index 0000000..de3a6cb --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/web/BaseController.java @@ -0,0 +1,78 @@ +package com.fuint.framework.web; + +import com.fuint.framework.FrameworkConstants; +import com.fuint.utils.PropertiesUtil; + +/** + * 控制器基类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class BaseController { + + /** + * 获取成功返回结果 + * + * @param data + * @return + */ + public ResponseObject getSuccessResult(Object data) { + return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, "操作成功", data); + } + + /** + * 获取成功返回结果 + * + * @param message + * @param data + * @return + */ + public ResponseObject getSuccessResult(String message, Object data) { + return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, message, data); + } + + /** + * 获取成功返回结果 + * + * @param code + * @param message + * @param data + * @return + */ + public ResponseObject getSuccessResult(int code, String message, Object data) { + return new ResponseObject(code, message, data); + } + + /** + * 获取错返回结果(无参数替换) + * + * @param errorCode + * @return + */ + public ResponseObject getFailureResult(int errorCode) { + return new ResponseObject(errorCode, PropertiesUtil.getResponseErrorMessageByCode(errorCode), null); + } + + /** + * 获取错返回结果(带参数替换) + * + * @param errorCode + * @param message + * @return + */ + public ResponseObject getFailureResult(int errorCode, String message) { + return new ResponseObject(errorCode, message, null); + } + + /** + * 获取错返回结果(带参数替换) + * + * @param errorCode + * @param message + * @return + */ + public ResponseObject getFailureResult(int errorCode, String message, Object data) { + return new ResponseObject(errorCode, message, data); + } +} \ No newline at end of file diff --git a/fuint-framework/src/main/java/com/fuint/framework/web/ResponseObject.java b/fuint-framework/src/main/java/com/fuint/framework/web/ResponseObject.java new file mode 100644 index 0000000..1411364 --- /dev/null +++ b/fuint-framework/src/main/java/com/fuint/framework/web/ResponseObject.java @@ -0,0 +1,55 @@ +package com.fuint.framework.web; + +/** + * 返回数据结构 + * + * Created by FSQ + * + * CopyRight https://www.fuint.cn + */ +public class ResponseObject { + + private Integer code; + private String message; + private Object data; + + public ResponseObject(Integer code, String message, Object data) { + this.code = code; + this.message = message; + this.data = data; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String msg) { + this.message = msg; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("ResponseObject{"); + sb.append("code=").append(code); + sb.append(", message='").append(message).append('\''); + sb.append(", data=").append(data); + sb.append('}'); + return sb.toString(); + } +} diff --git a/fuint-repository/pom.xml b/fuint-repository/pom.xml new file mode 100644 index 0000000..cf2e27b --- /dev/null +++ b/fuint-repository/pom.xml @@ -0,0 +1,30 @@ + + + + fuint + com.fuint + 1.0.0 + + 4.0.0 + + fuint-repository + 1.0.0 + jar + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + + \ No newline at end of file diff --git a/fuint-repository/src/main/java/com/fuint/repository/base/MyMapper.java b/fuint-repository/src/main/java/com/fuint/repository/base/MyMapper.java new file mode 100644 index 0000000..a72d562 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/base/MyMapper.java @@ -0,0 +1,11 @@ +package com.fuint.repository.base; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MyMapper extends BaseMapper { + // empty +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/ColumnBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/ColumnBean.java new file mode 100644 index 0000000..f7d82b1 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/ColumnBean.java @@ -0,0 +1,28 @@ +package com.fuint.repository.bean; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import java.io.Serializable; + +/** + * 表结构字段实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +public class ColumnBean implements Serializable { + + @ApiModelProperty("字段名称") + private String field; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("是否为空") + private String isNull; + + @ApiModelProperty("备注信息") + private String comment; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/CouponNumBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/CouponNumBean.java new file mode 100644 index 0000000..864c80a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/CouponNumBean.java @@ -0,0 +1,26 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 卡券数量对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "卡券数量对象", description = "卡券数量对象") +public class CouponNumBean implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("数量") + private Long num; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsBean.java new file mode 100644 index 0000000..7ca0b54 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsBean.java @@ -0,0 +1,54 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "商品对象", description = "商品对象") +public class GoodsBean implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("商品图片") + private String logo; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("商品编码") + private String goodsNo; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("商品价格") + private BigDecimal price; + + @ApiModelProperty("商品库存") + private Double stock; + + @ApiModelProperty("商品规格") + private String specIds; + + @ApiModelProperty("sku价格") + private String skuPrice; + + @ApiModelProperty("sk库存") + private Integer skuStock; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsTopBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsTopBean.java new file mode 100644 index 0000000..7c6619b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/GoodsTopBean.java @@ -0,0 +1,52 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import java.math.BigDecimal; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品排行对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "商品排行对象", description = "商品排行对象") +public class GoodsTopBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 商品ID + */ + @ApiModelProperty("商品ID") + private Integer id; + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + private String name; + + /** + * 商品条码 + */ + @ApiModelProperty("商品条码") + private String goodsNo; + + /** + * 销售金额 + */ + @ApiModelProperty("销售金额") + private BigDecimal amount; + + /** + * 销售数量 + */ + @ApiModelProperty("销售数量") + private Integer num; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/MemberTopBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/MemberTopBean.java new file mode 100644 index 0000000..98a8fd7 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/MemberTopBean.java @@ -0,0 +1,50 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员排行对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "会员排行对象", description = "会员排行对象") +public class MemberTopBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 会员ID + */ + @ApiModelProperty("卡券ID") + private Integer id; + + /** + * 会员名称 + */ + @ApiModelProperty("卡券ID") + private String name; + + /** + * 会员号 + */ + @ApiModelProperty("卡券ID") + private String userNo; + + /** + * 消费金额 + */ + @ApiModelProperty("卡券ID") + private BigDecimal amount; + + /** + * 购买数量 + */ + private Integer num; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/StoreDistanceBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/StoreDistanceBean.java new file mode 100644 index 0000000..6ac82c4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/StoreDistanceBean.java @@ -0,0 +1,26 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 店铺距离对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "店铺距离对象", description = "店铺距离对象") +public class StoreDistanceBean implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("店铺ID") + private Integer id; + + @ApiModelProperty("数量") + private String distance; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/bean/UploadShippingLogBean.java b/fuint-repository/src/main/java/com/fuint/repository/bean/UploadShippingLogBean.java new file mode 100644 index 0000000..7049ee2 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/bean/UploadShippingLogBean.java @@ -0,0 +1,38 @@ +package com.fuint.repository.bean; + +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 微信小程序上传发货信息对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@ApiModel(value = "微信小程序上传发货信息对象", description = "微信小程序上传发货信息对象") +public class UploadShippingLogBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 订单ID + */ + @ApiModelProperty("订单ID") + private Integer id; + + /** + * 订单号 + */ + @ApiModelProperty("订单号") + private String orderSn; + + /** + * 状态 + */ + @ApiModelProperty("上传状态,A成功;B失败") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtAddressMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtAddressMapper.java new file mode 100644 index 0000000..8fca2f0 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtAddressMapper.java @@ -0,0 +1,15 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtAddress; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 会员地址 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtAddressMapper extends BaseMapper { + int setDefault(@Param("userId") Integer userId, @Param("addressId") Integer addressId); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtArticleMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtArticleMapper.java new file mode 100644 index 0000000..3ffb261 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtArticleMapper.java @@ -0,0 +1,15 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtArticle; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 文章 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtArticleMapper extends BaseMapper { + void increaseClick(@Param("articleId") Integer articleId); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBalanceMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBalanceMapper.java new file mode 100644 index 0000000..8087368 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBalanceMapper.java @@ -0,0 +1,18 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtBalance; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 余额变化表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtBalanceMapper extends BaseMapper { + + List getBalanceListByOrderSn(@Param("orderSn") String orderSn); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBannerMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBannerMapper.java new file mode 100644 index 0000000..e20baa4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBannerMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtBanner; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * banner Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtBannerMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookCateMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookCateMapper.java new file mode 100644 index 0000000..7bdbd4b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookCateMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtBookCate; + +/** + * 预约分类 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtBookCateMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookItemMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookItemMapper.java new file mode 100644 index 0000000..6dc9b94 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookItemMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtBookItem; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 预约订单 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtBookItemMapper extends BaseMapper { + + List getBookList(@Param("bookId") Integer bookId, @Param("date") String date, @Param("time") String time); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookMapper.java new file mode 100644 index 0000000..1ebda99 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtBookMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtBook; + +/** + * 预约 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtBookMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCartMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCartMapper.java new file mode 100644 index 0000000..36a00a3 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCartMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtCart; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 购物车 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCartMapper extends BaseMapper { + + void deleteCartItem(@Param("userId") Integer userId, @Param("goodsId") Integer goodsId, @Param("skuId") Integer skuId); + + void clearCart(@Param("userId") Integer userId); + + void deleteCartByHangNo(@Param("hangNo") String hangNo); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionCashMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionCashMapper.java new file mode 100644 index 0000000..0b45118 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionCashMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtCommissionCash; +import org.apache.ibatis.annotations.Param; + +/** + * 提现记录 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCommissionCashMapper extends BaseMapper { + + Boolean confirmCommissionCash(@Param("merchantId") Integer merchantId, @Param("uuid") String uuid, @Param("operator") String operator); + + Boolean cancelCommissionCash(@Param("merchantId") Integer merchantId, @Param("uuid") String uuid, @Param("operator") String operator); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionLogMapper.java new file mode 100644 index 0000000..6024ccc --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionLogMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtCommissionLog; +import org.apache.ibatis.annotations.Param; + +/** + * 佣金记录 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCommissionLogMapper extends BaseMapper { + + Boolean confirmCommissionLog(@Param("merchantId") Integer merchantId, @Param("uuid") String uuid, @Param("operator") String operator); + + Boolean cancelCommissionLog(@Param("merchantId") Integer merchantId, @Param("uuid") String uuid, @Param("operator") String operator); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRelationMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRelationMapper.java new file mode 100644 index 0000000..aa83c2c --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRelationMapper.java @@ -0,0 +1,17 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtCommissionRelation; +import org.apache.ibatis.annotations.Param; + +/** + * 会员分销关系 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCommissionRelationMapper extends BaseMapper { + + Integer getCommissionUserId(@Param("merchantId") Integer merchantId, @Param("userId") Integer userId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleItemMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleItemMapper.java new file mode 100644 index 0000000..db8a952 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleItemMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtCommissionRuleItem; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 分佣提成规则项目 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCommissionRuleItemMapper extends BaseMapper { + + Boolean deleteByRuleId(@Param("ruleId") Integer ruleId, @Param("updateTime") Date updateTime); + + List getEffectiveCommissionList(@Param("merchantId") Integer merchantId, @Param("targetId") Integer targetId, @Param("type") String type); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleMapper.java new file mode 100644 index 0000000..9e84b7b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCommissionRuleMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtCommissionRule; + +/** + * 方案规则 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCommissionRuleMapper extends BaseMapper { + // empty +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtConfirmLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtConfirmLogMapper.java new file mode 100644 index 0000000..7687d85 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtConfirmLogMapper.java @@ -0,0 +1,23 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtConfirmLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 核销记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtConfirmLogMapper extends BaseMapper { + + Long getConfirmNum(@Param("userCouponId") Integer userCouponId); + + Long getConfirmLogCount(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + List getOrderConfirmLogList(@Param("orderId") Integer orderId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGoodsMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGoodsMapper.java new file mode 100644 index 0000000..1d4e9ee --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGoodsMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtCouponGoods; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 卡券商品表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCouponGoodsMapper extends BaseMapper { + + List getCouponGoods(@Param("couponId") Integer couponId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGroupMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGroupMapper.java new file mode 100644 index 0000000..0e711fd --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponGroupMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtCouponGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 优惠券组 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCouponGroupMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponMapper.java new file mode 100644 index 0000000..f258e8d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtCouponMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtCoupon; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 卡券信息表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtCouponMapper extends BaseMapper { + + Long queryNumByGroupId(@Param("groupId") Integer groupId); + + List queryByGroupId(@Param("groupId") Integer groupId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveItemMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveItemMapper.java new file mode 100644 index 0000000..2c045d4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveItemMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtGiveItem; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 转赠明细表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGiveItemMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveMapper.java new file mode 100644 index 0000000..86015a0 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGiveMapper.java @@ -0,0 +1,20 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtGive; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 转赠记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGiveMapper extends BaseMapper { + + List queryForUnique(@Param("userId") Integer userId, @Param("giveUserId") Integer giveUserId, @Param("couponIds") String couponIds, @Param("createTime") Date createTime); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsCateMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsCateMapper.java new file mode 100644 index 0000000..044c1a7 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsCateMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtGoodsCate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 商品分类 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGoodsCateMapper extends BaseMapper { + // empty +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsMapper.java new file mode 100644 index 0000000..53a4fe2 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsMapper.java @@ -0,0 +1,35 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.GoodsBean; +import com.fuint.repository.bean.GoodsTopBean; +import com.fuint.repository.model.MtGoods; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.Date; +import java.util.List; + +/** + * 商品 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGoodsMapper extends BaseMapper { + + List getStoreGoodsList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("cateId") Integer cateId, @Param("platform") String platform); + + List searchStoreGoodsList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("platform") String platform); + + MtGoods getByGoodsNo(@Param("merchantId") Integer merchantId, @Param("goodsNo") String goodsNo); + + List getByGoodsName(@Param("merchantId") Integer merchantId, @Param("goodsName") String goodsName); + + Boolean updateInitSale(@Param("goodsId") Integer goodsId, @Param("saleNum") Double saleNum); + + List selectGoodsList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("cateId") Integer cateId, @Param("keyword") String keyword); + + List getGoodsSaleTopList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + + void removeMerchantGoods(@Param("merchantId") Integer merchantId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSkuMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSkuMapper.java new file mode 100644 index 0000000..132d649 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSkuMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtGoodsSku; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 商品SKU表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGoodsSkuMapper extends BaseMapper { + + List getBySkuNo(@Param("skuNo") String skuNo); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSpecMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSpecMapper.java new file mode 100644 index 0000000..985701e --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtGoodsSpecMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtGoodsSpec; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 规格表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtGoodsSpecMapper extends BaseMapper { + + List getGoodsSpecCountList(@Param("goodsId") Integer goodsId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtInvoiceMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtInvoiceMapper.java new file mode 100644 index 0000000..6f2088a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtInvoiceMapper.java @@ -0,0 +1,20 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtInvoice; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 发票 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtInvoiceMapper extends BaseMapper { + + BigDecimal getInvoiceTotalAmount(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMerchantMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMerchantMapper.java new file mode 100644 index 0000000..454a80a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMerchantMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtMerchant; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 商户表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtMerchantMapper extends BaseMapper { + + MtMerchant queryMerchantByName(@Param("name") String name); + + MtMerchant queryMerchantByNo(@Param("merchantNo") String merchantNo); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMessageMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMessageMapper.java new file mode 100644 index 0000000..f3ae0f1 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtMessageMapper.java @@ -0,0 +1,20 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtMessage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 消息 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtMessageMapper extends BaseMapper { + + List findNewMessage(@Param("userId") Integer userId, @Param("type") String type); + + List findNeedSendMessage(@Param("type") String type); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftItemMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftItemMapper.java new file mode 100644 index 0000000..9ee2a5d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftItemMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtOpenGiftItem; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 开卡赠礼明细表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtOpenGiftItemMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftMapper.java new file mode 100644 index 0000000..8b6e3d0 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOpenGiftMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtOpenGift; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 会员开卡赠礼 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtOpenGiftMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderAddressMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderAddressMapper.java new file mode 100644 index 0000000..80761c0 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderAddressMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtOrderAddress; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 订单收货地址记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtOrderAddressMapper extends BaseMapper { + + List getOrderAddress(@Param("orderId") Integer orderId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderGoodsMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderGoodsMapper.java new file mode 100644 index 0000000..4574f7a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderGoodsMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtOrderGoods; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 订单商品表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtOrderGoodsMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderMapper.java new file mode 100644 index 0000000..21c12a4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtOrderMapper.java @@ -0,0 +1,46 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtOrder; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 订单表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtOrderMapper extends BaseMapper { + + BigDecimal getOrderCount(@Param("merchantId") Integer merchantId); + + BigDecimal getStoreOrderCount(@Param("storeId") Integer storeId); + + BigDecimal getOrderCountByTime(@Param("merchantId") Integer merchantId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + BigDecimal getStoreOrderCountByTime(@Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + MtOrder findByOrderSn(@Param("orderSn") String orderSn); + + BigDecimal getPayMoney(@Param("merchantId") Integer merchantId); + + BigDecimal getPayMoneyByTime(@Param("merchantId") Integer merchantId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + BigDecimal getStorePayMoneyByTime(@Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + BigDecimal getStorePayMoney(@Param("storeId") Integer storeId); + + Integer getPayUserCount(@Param("merchantId") Integer merchantId); + + Integer getStorePayUserCount(@Param("storeId") Integer storeId); + + BigDecimal getUserPayMoney(@Param("userId") Integer userId); + + Integer getUserPayOrderCount(@Param("userId") Integer userId); + + List getTobeCommissionOrderList(@Param("dateTime") String dateTime); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPointMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPointMapper.java new file mode 100644 index 0000000..ea5e942 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPointMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtPoint; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 积分变化表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtPointMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPrinterMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPrinterMapper.java new file mode 100644 index 0000000..db4ac7b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtPrinterMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtPrinter; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 打印机 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtPrinterMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRefundMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRefundMapper.java new file mode 100644 index 0000000..8bd4c7e --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRefundMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtRefund; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; + +/** + * 售后表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtRefundMapper extends BaseMapper { + + Long getRefundCount(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + MtRefund findByOrderId(@Param("orderId") Integer orderId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRegionMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRegionMapper.java new file mode 100644 index 0000000..7052901 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtRegionMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtRegion; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 省市区数据表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtRegionMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSendLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSendLogMapper.java new file mode 100644 index 0000000..3f93c7b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSendLogMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtSendLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 卡券发放记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSendLogMapper extends BaseMapper { + + Integer updateForRemove(@Param("uuid") String uuid, @Param("status") String status, @Param("removeSuccessNum") Integer removeSuccessNum, @Param("removeFailNum") Integer removeFailNum); + + Integer updateSingleForRemove(@Param("uuid") String uuid, @Param("status") String status); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettingMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettingMapper.java new file mode 100644 index 0000000..5ec9506 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettingMapper.java @@ -0,0 +1,20 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtSetting; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 全局设置表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSettingMapper extends BaseMapper { + + List querySettingByType(@Param("merchantId") Integer merchantId, @Param("type") String type); + + MtSetting querySettingByName(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("type") String type, @Param("name") String name); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementMapper.java new file mode 100644 index 0000000..9299810 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtSettlement; + +/** + * 结算表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSettlementMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementOrderMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementOrderMapper.java new file mode 100644 index 0000000..7ef9032 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSettlementOrderMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtSettlementOrder; + +/** + * 结算订单表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSettlementOrderMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsSendedLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsSendedLogMapper.java new file mode 100644 index 0000000..a916a08 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsSendedLogMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtSmsSendedLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 短信发送记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSmsSendedLogMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsTemplateMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsTemplateMapper.java new file mode 100644 index 0000000..7249af9 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtSmsTemplateMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtSmsTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 短信模板 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtSmsTemplateMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStaffMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStaffMapper.java new file mode 100644 index 0000000..70599dc --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStaffMapper.java @@ -0,0 +1,22 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtStaff; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; + +/** + * 店铺员工表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtStaffMapper extends BaseMapper { + + int updateStatus(@Param("id") Integer id, @Param("status") String status, @Param("updateTime") Date updateTime); + + MtStaff queryStaffByMobile(@Param("mobile") String mobile); + + MtStaff queryStaffByUserId(@Param("userId") Integer userId); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockItemMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockItemMapper.java new file mode 100644 index 0000000..5eee1c8 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockItemMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtStockItem; + +/** + * 库存管理明细表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtStockItemMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockMapper.java new file mode 100644 index 0000000..fed34f8 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStockMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtStock; + +/** + * 库存管理记录表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtStockMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreGoodsMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreGoodsMapper.java new file mode 100644 index 0000000..0e49b31 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreGoodsMapper.java @@ -0,0 +1,17 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtStoreGoods; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * 店铺商品 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtStoreGoodsMapper extends BaseMapper { + + void removeStoreGoods(@Param("storeId") Integer storeId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreMapper.java new file mode 100644 index 0000000..de8dc3d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtStoreMapper.java @@ -0,0 +1,30 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.StoreDistanceBean; +import com.fuint.repository.model.MtStore; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 店铺表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtStoreMapper extends BaseMapper { + + MtStore queryStoreByName(@Param("name") String name); + + void resetDefaultStore(@Param("merchantId") Integer merchantId); + + List findStoresByIds(@Param("ids") List ids); + + List queryByDistance(@Param("merchantId") Integer merchantId, @Param("keyword") String keyword, @Param("latitude") String latitude, @Param("longitude") String longitude); + + void deleteStoreByMerchant(@Param("merchantId") Integer merchantId); + + List getMyStoreList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("status") String status); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUploadShippingLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUploadShippingLogMapper.java new file mode 100644 index 0000000..1358af4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUploadShippingLogMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.UploadShippingLogBean; +import com.fuint.repository.model.MtUploadShippingLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 微信小程序上传发货信息 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUploadShippingLogMapper extends BaseMapper { + + List getUploadShippingLogList(@Param("merchantId") Integer merchantId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserActionMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserActionMapper.java new file mode 100644 index 0000000..e3434b0 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserActionMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.MtUserAction; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; + +/** + * 会员行为 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUserActionMapper extends BaseMapper { + + Long getActiveUserCount(@Param("merchantId") Integer merchantId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + Long getStoreActiveUserCount(@Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserCouponMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserCouponMapper.java new file mode 100644 index 0000000..6c17754 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserCouponMapper.java @@ -0,0 +1,42 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.CouponNumBean; +import com.fuint.repository.model.MtUserCoupon; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 会员卡券表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUserCouponMapper extends BaseMapper { + + Boolean updateExpireTime(@Param("couponId") Integer couponId, @Param("expireTime") String expireTime); + + Long getSendNum(@Param("couponId") Integer couponId); + + CouponNumBean getPeopleNumByCouponId(@Param("couponId") Integer couponId); + + List getUserCouponList(@Param("userId") Integer userId, @Param("statusList") List statusList); + + List getUserCouponListByCouponId(@Param("userId") Integer userId, @Param("couponId") Integer couponId ,@Param("statusList") List statusList); + + MtUserCoupon findByCode(@Param("code") String code); + + int removeUserCoupon(@Param("uuid") String uuid, @Param("couponIds") List couponIds, @Param("operator") String operator); + + List queryExpireNumByGroupId(@Param("groupId") Integer groupId); + + List getCouponIdsByUuid(@Param("uuid") String uuid); + + List findUserCouponDetail(@Param("couponId") Integer couponId, @Param("userId") Integer userId); + + List getUserCouponListByExpireTime(@Param("userId") Integer userId, @Param("status") String status, @Param("startTime") String startTime, @Param("endTime") String endTime); + + Boolean removeUserCouponByCouponId(@Param("couponId") Integer couponId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGradeMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGradeMapper.java new file mode 100644 index 0000000..6b3deac --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGradeMapper.java @@ -0,0 +1,19 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtUserGrade; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUserGradeMapper extends BaseMapper { + + List getMerchantGradeList(@Param("merchantId") Integer merchantId, @Param("status") String status); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGroupMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGroupMapper.java new file mode 100644 index 0000000..c26f49a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserGroupMapper.java @@ -0,0 +1,17 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtUserGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 会员分组 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUserGroupMapper extends BaseMapper { + Long getMemberNum(@Param("groupIds") List groupIds); +} \ No newline at end of file diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserMapper.java new file mode 100644 index 0000000..31d5f04 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtUserMapper.java @@ -0,0 +1,48 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.MemberTopBean; +import com.fuint.repository.model.MtUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 会员个人信息 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtUserMapper extends BaseMapper { + + List queryMemberByMobile(@Param("merchantId") Integer merchantId, @Param("mobile") String mobile); + + List queryMemberByName(@Param("merchantId") Integer merchantId, @Param("name") String name); + + MtUser queryMemberByOpenId(@Param("merchantId") Integer merchantId, @Param("openId") String openId); + + List findMembersByUserNo(@Param("merchantId") Integer merchantId, @Param("userNo") String userNo); + + void updateActiveTime(@Param("userId") Integer userId, @Param("updateTime") Date updateTime); + + void updateUserBalance(@Param("merchantId") Integer merchantId, @Param("userIds") List userIds, @Param("amount") BigDecimal amount); + + void resetMobile(@Param("merchantId") Integer merchantId, @Param("mobile") String mobile, @Param("userId") Integer userId); + + Long getUserCount(@Param("merchantId") Integer merchantId); + + Long getStoreUserCount(@Param("storeId") Integer storeId); + + Long getUserCountByTime(@Param("merchantId") Integer merchantId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + Long getStoreUserCountByTime(@Param("storeId") Integer storeId, @Param("beginTime") Date beginTime, @Param("endTime") Date endTime); + + List getMemberConsumeTopList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + + List getUserIdList(@Param("merchantId") Integer merchantId, @Param("storeId") Integer storeId); + + List searchMembers(@Param("merchantId") Integer merchantId, @Param("keyword") String keyword); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/MtVerifyCodeMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtVerifyCodeMapper.java new file mode 100644 index 0000000..8480250 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/MtVerifyCodeMapper.java @@ -0,0 +1,22 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.MtVerifyCode; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * 短信验证码表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface MtVerifyCodeMapper extends BaseMapper { + + MtVerifyCode queryByMobileVerifyCode(@Param("mobile") String mobile, @Param("verifyCode") String verifyCode, @Param("queryTime") Date queryTime); + + List queryVerifyCodeLastRecord(@Param("mobile") String mobile); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountDutyMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountDutyMapper.java new file mode 100644 index 0000000..96ba839 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountDutyMapper.java @@ -0,0 +1,20 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TAccountDuty; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.util.List; + +/** + * 后台账号角色 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TAccountDutyMapper extends BaseMapper { + + List getDutyIdsByAccountId(Integer accountId); + + void deleteDutiesByAccountId(long accountId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountMapper.java new file mode 100644 index 0000000..287a6e6 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TAccountMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TAccount; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 后台账号 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TAccountMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TActionLogMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TActionLogMapper.java new file mode 100644 index 0000000..5f8c669 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TActionLogMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TActionLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 操作日志 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TActionLogMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutyMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutyMapper.java new file mode 100644 index 0000000..ba88b08 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutyMapper.java @@ -0,0 +1,23 @@ +package com.fuint.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fuint.repository.model.TDuty; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 角色表 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TDutyMapper extends BaseMapper { + + List findByStatus(@Param("merchantId") Integer merchantId, @Param("status") String status); + + List findByIdIn(@Param("ids") List ids); + + TDuty findByName(@Param("merchantId") Integer merchantId, @Param("name") String name); + + List getRoleIdsByAccountId(@Param("accountId") Integer accountId); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutySourceMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutySourceMapper.java new file mode 100644 index 0000000..c7184f7 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TDutySourceMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TDutySource; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 角色菜单 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TDutySourceMapper extends BaseMapper { + + void deleteSourcesByDutyId(@Param("dutyId") Integer dutyId); + + List findSourceIdsByDutyId(@Param("dutyId") Integer dutyId); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TGenCodeMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TGenCodeMapper.java new file mode 100644 index 0000000..af554ae --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TGenCodeMapper.java @@ -0,0 +1,21 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.bean.ColumnBean; +import com.fuint.repository.model.TGenCode; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 代码生成 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TGenCodeMapper extends BaseMapper { + + TGenCode findGenCodeByTableName(@Param("tableName") String tableName); + + List getTableColumnList(@Param("tableName") String tableName); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TPlatformMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TPlatformMapper.java new file mode 100644 index 0000000..3d99a0f --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TPlatformMapper.java @@ -0,0 +1,14 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TPlatform; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统平台 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TPlatformMapper extends BaseMapper { + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/mapper/TSourceMapper.java b/fuint-repository/src/main/java/com/fuint/repository/mapper/TSourceMapper.java new file mode 100644 index 0000000..3216d87 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/mapper/TSourceMapper.java @@ -0,0 +1,22 @@ +package com.fuint.repository.mapper; + +import com.fuint.repository.model.TSource; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 后台菜单 Mapper 接口 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface TSourceMapper extends BaseMapper { + + List findSourcesByAccountId(@Param("merchantId") Integer merchantId, @Param("accountId") Integer accountId); + + List findByIdIn(@Param("ids") List ids); + + List findByStatus(@Param("merchantId") Integer merchantId, @Param("status") String status); + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtAddress.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtAddress.java new file mode 100644 index 0000000..0f15c97 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtAddress.java @@ -0,0 +1,62 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员地址表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_address") +@ApiModel(value = "MtAddress对象", description = "会员地址表") +public class MtAddress implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("收货人姓名") + private String name; + + @ApiModelProperty("收货手机号") + private String mobile; + + @ApiModelProperty("省份ID") + private Integer provinceId; + + @ApiModelProperty("城市ID") + private Integer cityId; + + @ApiModelProperty("区/县ID") + private Integer regionId; + + @ApiModelProperty("详细地址") + private String detail; + + @ApiModelProperty("是否默认") + private String isDefault; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtArticle.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtArticle.java new file mode 100644 index 0000000..235d54f --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtArticle.java @@ -0,0 +1,68 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 文章 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_article") +@ApiModel(value = "MtArticle对象", description = "MtArticle对象") +public class MtArticle implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("简介") + private String brief; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("链接地址") + private String url; + + @ApiModelProperty("图片地址") + private String image; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("点击数") + private Long click; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;N:禁用;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtBalance.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtBalance.java new file mode 100644 index 0000000..f3e703c --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtBalance.java @@ -0,0 +1,63 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 余额变化表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_balance") +@ApiModel(value = "MtBalance对象", description = "余额变化表") +public class MtBalance implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("余额变化数量") + private BigDecimal amount; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtBanner.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtBanner.java new file mode 100644 index 0000000..a7e8072 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtBanner.java @@ -0,0 +1,62 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 首页banner + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_banner") +@ApiModel(value = "MtBanner对象", description = "MtBanner表对象") +public class MtBanner implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("链接地址") + private String url; + + @ApiModelProperty("图片地址") + private String image; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtBook.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtBook.java new file mode 100644 index 0000000..de82d64 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtBook.java @@ -0,0 +1,77 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_book") +@ApiModel(value = "MtBook对象", description = "MtBook表对象") +public class MtBook implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("预约名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("预约类型") + private String type; + + @ApiModelProperty("图片地址") + private String logo; + + @ApiModelProperty("关联商品ID") + private Integer goodsId; + + @ApiModelProperty("类别ID") + private Integer cateId; + + @ApiModelProperty("可预约日期") + private String serviceDates; + + @ApiModelProperty("可预约时间段") + private String serviceTimes; + + @ApiModelProperty("可预约员工ID") + private String serviceStaffIds; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtBookCate.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtBookCate.java new file mode 100644 index 0000000..1710612 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtBookCate.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约分类实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_book_cate") +@ApiModel(value = "MtBookCate对象", description = "MtBookCate表对象") +public class MtBookCate implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("分类名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("图片地址") + private String logo; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtBookItem.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtBookItem.java new file mode 100644 index 0000000..0e0e7d2 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtBookItem.java @@ -0,0 +1,80 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 预约订单实体 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_book_item") +@ApiModel(value = "MtBookItem对象", description = "MtBookItem表对象") +public class MtBookItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("预约分类ID") + private Integer cateId; + + @ApiModelProperty("预约ID") + private Integer bookId; + + @ApiModelProperty("预约用户ID") + private Integer userId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("核销码") + private String verifyCode; + + @ApiModelProperty("预约联系人") + private String contact; + + @ApiModelProperty("预约手机号") + private String mobile; + + @ApiModelProperty("预约日期") + private String serviceDate; + + @ApiModelProperty("预约时间段") + private String serviceTime; + + @ApiModelProperty("预约备注") + private String remark; + + @ApiModelProperty("预约员工ID") + private Integer serviceStaffId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("A:已提交;B:审核通过;C:审核未通过;D:删除;E:已完成") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCart.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCart.java new file mode 100644 index 0000000..ca0ae63 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCart.java @@ -0,0 +1,61 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 购物车 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_cart") +@ApiModel(value = "MtCart对象", description = "购物车对象") +public class MtCart implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("是否游客") + private String isVisitor; + + @ApiModelProperty("挂单号") + private String hangNo; + + @ApiModelProperty("skuID") + private Integer skuId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("数量") + private Double num; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态") + private String status; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionCash.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionCash.java new file mode 100644 index 0000000..5abac08 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionCash.java @@ -0,0 +1,66 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 分佣提现记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_commission_cash") +@ApiModel(value = "MtCommissionCash对象", description = "分佣提现记录表") +public class MtCommissionCash implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("结算单号") + private String settleNo; + + @ApiModelProperty("结算uuid") + private String uuid; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("金额") + private BigDecimal amount; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionLog.java new file mode 100644 index 0000000..926054d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionLog.java @@ -0,0 +1,90 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 佣金记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_commission_log") +@ApiModel(value = "MtCommissionLog对象", description = "佣金记录表") +public class MtCommissionLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("分佣对象,member:会员分销;staff:员工提成") + private String target; + + @ApiModelProperty("分佣类型") + private String type; + + @ApiModelProperty("分佣等级") + private Integer level; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("员工ID") + private Integer staffId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("分佣金额") + private BigDecimal amount; + + @ApiModelProperty("规则ID") + private Integer ruleId; + + @ApiModelProperty("规则项ID") + private Integer ruleItemId; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("结算uuid") + private String settleUuid; + + @ApiModelProperty("提现记录ID") + private Integer cashId; + + @ApiModelProperty("最后操作人") + private String isCash; + + @ApiModelProperty("提现时间") + private Date cashTime; + + @ApiModelProperty("是否提现") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A:待结算;B:已结算;C:已作废") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRelation.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRelation.java new file mode 100644 index 0000000..aa0ecd2 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRelation.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员分销关系表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_commission_relation") +@ApiModel(value = "MtCommissionRelation对象", description = "会员分销关系表") +public class MtCommissionRelation implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("邀请码") + private String inviteCode; + + @ApiModelProperty("被邀请会员ID") + private Integer subUserId; + + @ApiModelProperty("等级") + private Integer level; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRule.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRule.java new file mode 100644 index 0000000..24c0efc --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRule.java @@ -0,0 +1,62 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 分佣提成规则表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_commission_rule") +@ApiModel(value = "MtCommissionRule对象", description = "分佣提成规则表") +public class MtCommissionRule implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("规则名称") + private String name; + + @ApiModelProperty("方案类型,goods:商品销售;coupon:卡券销售;recharge:会员充值") + private String type; + + @ApiModelProperty("分佣对象,member:会员分销;staff:员工提成") + private String target; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("适用店铺ID,逗号隔开") + private String storeIds; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRuleItem.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRuleItem.java new file mode 100644 index 0000000..592dc70 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCommissionRuleItem.java @@ -0,0 +1,80 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + * 分佣提成规则项目表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_commission_rule_item") +@ApiModel(value = "MtCommissionRuleItem对象", description = "分佣提成规则项目表") +public class MtCommissionRuleItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("方案类型,goods:商品销售;coupon:卡券销售;recharge:会员充值") + private String type; + + @ApiModelProperty("分佣对象,member:会员分销;staff:员工提成") + private String target; + + @ApiModelProperty("规则ID") + private Integer ruleId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("分佣对象ID") + private Integer targetId; + + @ApiModelProperty("提成方式(按比例/固定金额)") + private String method; + + @ApiModelProperty("适用店铺ID,逗号隔开") + private String storeIds; + + @ApiModelProperty("散客佣金") + private BigDecimal guest; + + @ApiModelProperty("二级散客佣金") + private BigDecimal subGuest; + + @ApiModelProperty("会员佣金") + private BigDecimal member; + + @ApiModelProperty("二级会员佣金") + private BigDecimal subMember; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtConfirmLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtConfirmLog.java new file mode 100644 index 0000000..44e5c2d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtConfirmLog.java @@ -0,0 +1,79 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 核销记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_confirm_log") +@ApiModel(value = "MtConfirmLog对象", description = "核销记录表") +public class MtConfirmLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("编码") + private String code; + + @ApiModelProperty("核销金额") + private BigDecimal amount; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("用户券ID") + private Integer userCouponId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("卡券所属用户ID") + private Integer userId; + + @ApiModelProperty("核销者用户ID") + private Integer operatorUserId; + + @ApiModelProperty("核销店铺ID") + private Integer storeId; + + @ApiModelProperty("状态,A正常核销;D:撤销使用") + private String status; + + @ApiModelProperty("撤销时间") + private Date cancelTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("操作来源user_id对应表t_account 还是 mt_user") + private String operatorFrom; + + @ApiModelProperty("备注信息") + private String remark; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCoupon.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCoupon.java new file mode 100644 index 0000000..0f77be9 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCoupon.java @@ -0,0 +1,127 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 卡券信息表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_coupon") +@ApiModel(value = "MtCoupon对象", description = "卡券信息表") +public class MtCoupon implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("券组ID") + private Integer groupId; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("券类型,C优惠券;P储值卡;T计次卡") + private String type; + + @ApiModelProperty("券内容,如:0表示满减券、1表示折扣券") + private Integer content; + + @ApiModelProperty("券名称") + private String name; + + @ApiModelProperty("是否允许转赠") + private Boolean isGive; + + @ApiModelProperty("获得卡券所消耗积分") + private Integer point; + + @ApiModelProperty("适用商品:allGoods、parkGoods") + private String applyGoods; + + @ApiModelProperty("领取码") + private String receiveCode; + + @ApiModelProperty("使用专项") + private String useFor; + + @ApiModelProperty("过期类型") + private String expireType; + + @ApiModelProperty("有效天数") + private Integer expireTime; + + @ApiModelProperty("开始有效期") + private Date beginTime; + + @ApiModelProperty("结束有效期") + private Date endTime; + + @ApiModelProperty("面额") + private BigDecimal amount; + + @ApiModelProperty("发放方式") + private String sendWay; + + @ApiModelProperty("每次发放数量") + private Integer sendNum; + + @ApiModelProperty("发行数量") + private Integer total; + + @ApiModelProperty("每人拥有数量限制") + private Integer limitNum; + + @ApiModelProperty("不可用日期,逗号隔开。周末:weekend;其他:2019-01-02_2019-02-09") + private String exceptTime; + + @ApiModelProperty("适用店铺ID,逗号隔开") + private String storeIds; + + @ApiModelProperty("适用会员等级,逗号隔开") + private String gradeIds; + + @ApiModelProperty("描述信息") + private String description; + + @ApiModelProperty("效果图片") + private String image; + + @ApiModelProperty("后台备注") + private String remarks; + + @ApiModelProperty("获取券的规则") + private String inRule; + + @ApiModelProperty("核销券的规则") + private String outRule; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("A:正常;D:删除") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGoods.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGoods.java new file mode 100644 index 0000000..4aebca1 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGoods.java @@ -0,0 +1,44 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 卡券商品表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_coupon_goods") +@ApiModel(value = "MtCouponGoods对象", description = "卡券商品表") +public class MtCouponGoods implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGroup.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGroup.java new file mode 100644 index 0000000..6b3101b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtCouponGroup.java @@ -0,0 +1,64 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 优惠券组 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_coupon_group") +@ApiModel(value = "MtCouponGroup对象", description = "优惠券组") +public class MtCouponGroup implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("券组名称") + private String name; + + @ApiModelProperty("价值金额") + private BigDecimal money; + + @ApiModelProperty("券种类数量") + private Integer num; + + @ApiModelProperty("发行数量") + private Integer total; + + @ApiModelProperty("备注") + private String description; + + @ApiModelProperty("创建日期") + private Date createTime; + + @ApiModelProperty("更新日期") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("A:正常;D:删除") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGive.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGive.java new file mode 100644 index 0000000..893f75d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGive.java @@ -0,0 +1,82 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 转赠记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_give") +@ApiModel(value = "MtGive对象", description = "转赠记录表") +public class MtGive implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("获赠者用户ID") + private Integer userId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("赠送者用户ID") + private Integer giveUserId; + + @ApiModelProperty("赠予对象手机号") + private String mobile; + + @ApiModelProperty("用户手机") + private String userMobile; + + @ApiModelProperty("券组ID,逗号隔开") + private String groupIds; + + @ApiModelProperty("券组名称,逗号隔开") + private String groupNames; + + @ApiModelProperty("券ID,逗号隔开") + private String couponIds; + + @ApiModelProperty("券名称,逗号隔开") + private String couponNames; + + @ApiModelProperty("数量") + private Integer num; + + @ApiModelProperty("总金额") + private BigDecimal money; + + @ApiModelProperty("备注") + private String note; + + @ApiModelProperty("留言") + private String message; + + @ApiModelProperty("赠送时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A正常;C取消") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGiveItem.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGiveItem.java new file mode 100644 index 0000000..4e4d536 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGiveItem.java @@ -0,0 +1,44 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 转赠明细表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_give_item") +@ApiModel(value = "MtGiveItem对象", description = "转赠明细表") +public class MtGiveItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("转赠ID") + private Integer giveId; + + @ApiModelProperty("用户电子券ID") + private Integer userCouponId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGoods.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoods.java new file mode 100644 index 0000000..efdcda1 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoods.java @@ -0,0 +1,115 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 商品表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_goods") +@ApiModel(value = "MtGoods对象", description = "MtGoods对象") +public class MtGoods implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("商品名称") + private String name; + + @ApiModelProperty("商品类型") + private String type; + + @ApiModelProperty("分类ID") + private Integer cateId; + + @ApiModelProperty("预约项目ID") + private Integer bookId; + + @ApiModelProperty("商品编码") + private String goodsNo; + + @ApiModelProperty("可用平台,0:不限,1:仅会员端(小程序和h5);2:仅收银端") + private Integer platform; + + @ApiModelProperty("是否单规格") + private String isSingleSpec; + + @ApiModelProperty("主图地址") + private String logo; + + @ApiModelProperty("图片地址") + private String images; + + @ApiModelProperty("销售价格") + private BigDecimal price; + + @ApiModelProperty("划线价格") + private BigDecimal linePrice; + + @ApiModelProperty("成本价格") + private BigDecimal costPrice; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("关联卡券") + private String couponIds; + + @ApiModelProperty("服务时长") + private Integer serviceTime; + + @ApiModelProperty("重量") + private BigDecimal weight; + + @ApiModelProperty("初始销量") + private Double initSale; + + @ApiModelProperty("商品卖点") + private String salePoint; + + @ApiModelProperty("可否使用积分抵扣") + private String canUsePoint; + + @ApiModelProperty("会员是否有折扣") + private String isMemberDiscount; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("商品描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsCate.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsCate.java new file mode 100644 index 0000000..2e4ab0e --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsCate.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品分类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_goods_cate") +@ApiModel(value = "MtGoodsCate对象", description = "") +public class MtGoodsCate implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("分类名称") + private String name; + + @ApiModelProperty("LOGO地址") + private String logo; + + @ApiModelProperty("分类描述") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSku.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSku.java new file mode 100644 index 0000000..e01488f --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSku.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商品SKU表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_goods_sku") +@ApiModel(value = "MtGoodsSku对象", description = "商品SKU表") +public class MtGoodsSku implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("sku编码") + private String skuNo; + + @ApiModelProperty("图片") + private String logo; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("规格ID") + private String specIds; + + @ApiModelProperty("库存") + private Double stock; + + @ApiModelProperty("价格") + private BigDecimal price; + + @ApiModelProperty("划线价格") + private BigDecimal linePrice; + + @ApiModelProperty("成本价格") + private BigDecimal costPrice; + + @ApiModelProperty("重量") + private BigDecimal weight; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSpec.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSpec.java new file mode 100644 index 0000000..1152936 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtGoodsSpec.java @@ -0,0 +1,41 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 规格表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_goods_spec") +@ApiModel(value = "MtGoodsSpec对象", description = "规格表") +public class MtGoodsSpec implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("规格名称") + private String name; + + @ApiModelProperty("规格值") + private String value; + + @ApiModelProperty("状态") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtInvoice.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtInvoice.java new file mode 100644 index 0000000..8101362 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtInvoice.java @@ -0,0 +1,93 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 发票实体 + * + * @Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_invoice") +@ApiModel(value = "invoice表对象", description = "invoice表对象") +public class MtInvoice implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("开票时间") + private Date InvoiceTime; + + @ApiModelProperty("开票金额") + private BigDecimal invoiceAmount; + + @ApiModelProperty("发票抬头") + private String title; + + @ApiModelProperty("发票下载地址") + private String downloadUrl; + + @ApiModelProperty("发票类型") + private String type; + + @ApiModelProperty("纳税人识别码") + private String taxCode; + + @ApiModelProperty("开户行") + private String bankName; + + @ApiModelProperty("开户卡号") + private String bankCardNo; + + @ApiModelProperty("开户户名") + private String bankCardName; + + @ApiModelProperty("开票备注") + private String description; + + @ApiModelProperty("接收邮箱") + private String email; + + @ApiModelProperty("联系电话") + private String mobile; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A开票中,B开票成功,C已冲红") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtMerchant.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtMerchant.java new file mode 100644 index 0000000..7851e28 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtMerchant.java @@ -0,0 +1,81 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 商户表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_merchant") +@ApiModel(value = "MtMerchant对象", description = "商户表") +public class MtMerchant implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("微信小程序appId") + private String wxAppId; + + @ApiModelProperty("微信小程序秘钥") + private String wxAppSecret; + + @ApiModelProperty("微信公众号appId") + private String wxOfficialAppId; + + @ApiModelProperty("微信公众号秘钥") + private String wxOfficialAppSecret; + + @ApiModelProperty(value="结算比例") + private BigDecimal settleRate; + + @ApiModelProperty("商户号") + private String no; + + @ApiModelProperty("商户名称") + private String name; + + @ApiModelProperty("商户logo") + private String logo; + + @ApiModelProperty("联系人姓名") + private String contact; + + @ApiModelProperty("联系电话") + private String phone; + + @ApiModelProperty("联系地址") + private String address; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:有效/启用;D:无效") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtMessage.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtMessage.java new file mode 100644 index 0000000..42737bf --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtMessage.java @@ -0,0 +1,65 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 系统消息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_message") +@ApiModel(value = "MtMessage对象", description = "系统消息") +public class MtMessage implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("消息类型") + private String type; + + @ApiModelProperty("消息标题") + private String title; + + @ApiModelProperty("消息内容") + private String content; + + @ApiModelProperty("是否已读") + private String isRead; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("参数信息") + private String params; + + @ApiModelProperty("是否已发送") + private String isSend; + + @ApiModelProperty("发送时间") + private Date sendTime; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGift.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGift.java new file mode 100644 index 0000000..4fe28d3 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGift.java @@ -0,0 +1,58 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员开卡赠礼 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_open_gift") +@ApiModel(value = "MtOpenGift对象", description = "会员开卡赠礼") +public class MtOpenGift implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("会员等级ID") + private Integer gradeId; + + @ApiModelProperty("赠送积分") + private Integer point; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("卡券数量") + private Integer couponNum; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGiftItem.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGiftItem.java new file mode 100644 index 0000000..8c090d7 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtOpenGiftItem.java @@ -0,0 +1,42 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 开卡赠礼明细表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_open_gift_item") +@ApiModel(value = "MtOpenGiftItem对象", description = "开卡赠礼明细表") +public class MtOpenGiftItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("会用ID") + private Integer userId; + + @ApiModelProperty("赠礼ID") + private Integer openGiftId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("状态") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtOrder.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrder.java new file mode 100644 index 0000000..cd82d3f --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrder.java @@ -0,0 +1,129 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 订单表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_order") +@ApiModel(value = "MtOrder对象", description = "订单表") +public class MtOrder implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("订单类型") + private String type; + + @ApiModelProperty("支付类型") + private String payType; + + @ApiModelProperty("订单模式") + private String orderMode; + + @ApiModelProperty("下单平台") + private String platform; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("核销验证码") + private String verifyCode; + + @ApiModelProperty("是否游客") + private String isVisitor; + + @ApiModelProperty("订单金额") + private BigDecimal amount; + + @ApiModelProperty("支付金额") + private BigDecimal payAmount; + + @ApiModelProperty(value="结算状态") + private String settleStatus; + + @ApiModelProperty("使用积分数量") + private Integer usePoint; + + @ApiModelProperty("积分金额") + private BigDecimal pointAmount; + + @ApiModelProperty("折扣金额") + private BigDecimal discount; + + @ApiModelProperty("配送费用") + private BigDecimal deliveryFee; + + @ApiModelProperty("订单参数") + private String param; + + @ApiModelProperty("物流信息") + private String expressInfo; + + @ApiModelProperty("用户备注") + private String remark; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("订单状态") + private String status; + + @ApiModelProperty("支付时间") + private Date payTime; + + @ApiModelProperty("支付状态") + private String payStatus; + + @ApiModelProperty("操作员工") + private Integer staffId; + + @ApiModelProperty("核销状态") + private String confirmStatus; + + @ApiModelProperty("核销时间") + private Date confirmTime; + + @ApiModelProperty("核销备注") + private String confirmRemark; + + @ApiModelProperty("分佣提成用户ID") + private Integer commissionUserId; + + @ApiModelProperty("分佣提成计算状态") + private String commissionStatus; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderAddress.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderAddress.java new file mode 100644 index 0000000..6d7988a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderAddress.java @@ -0,0 +1,57 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 订单收货地址记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_order_address") +@ApiModel(value = "MtOrderAddress对象", description = "订单收货地址记录表") +public class MtOrderAddress implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("地址ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("收货人姓名") + private String name; + + @ApiModelProperty("联系电话") + private String mobile; + + @ApiModelProperty("省份ID") + private Integer provinceId; + + @ApiModelProperty("城市ID") + private Integer cityId; + + @ApiModelProperty("区/县ID") + private Integer regionId; + + @ApiModelProperty("详细地址") + private String detail; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("创建时间") + private Date createTime; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderGoods.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderGoods.java new file mode 100644 index 0000000..055b7d9 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtOrderGoods.java @@ -0,0 +1,57 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 订单商品表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_order_goods") +@ApiModel(value = "MtOrderGoods对象", description = "订单商品表") +public class MtOrderGoods implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("skuID") + private Integer skuId; + + @ApiModelProperty("价格") + private BigDecimal price; + + @ApiModelProperty("优惠价") + private BigDecimal discount; + + @ApiModelProperty("商品数量") + private Double num; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("A:正常;D:删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtPoint.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtPoint.java new file mode 100644 index 0000000..9c45973 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtPoint.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员积分记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_point") +@ApiModel(value = "MtPoint对象", description = "会员积分记录表") +public class MtPoint implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("积分变化数量") + private Integer amount; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtPrinter.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtPrinter.java new file mode 100644 index 0000000..4d70f7c --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtPrinter.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 打印机实体 + * + * @Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_printer") +@ApiModel(value = "printer表对象", description = "printer表对象") +public class MtPrinter implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("打印机编号") + private String sn; + + @ApiModelProperty("打印机名称") + private String name; + + @ApiModelProperty("是否自动打印机") + private String autoPrint; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D作废") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtRefund.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtRefund.java new file mode 100644 index 0000000..f56e69a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtRefund.java @@ -0,0 +1,75 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 售后表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_refund") +@ApiModel(value = "MtRefund对象", description = "售后表") +public class MtRefund implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("退款金额") + private BigDecimal amount; + + @ApiModelProperty("售后类型") + private String type; + + @ApiModelProperty("退款备注") + private String remark; + + @ApiModelProperty("物流公司名称") + private String expressName; + + @ApiModelProperty("物流单号") + private String expressNo; + + @ApiModelProperty("拒绝原因") + private String rejectReason; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态") + private String status; + + @ApiModelProperty("图片") + private String images; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtRegion.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtRegion.java new file mode 100644 index 0000000..3313a68 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtRegion.java @@ -0,0 +1,41 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 省市区数据表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_region") +@ApiModel(value = "MtRegion对象", description = "省市区数据表") +public class MtRegion implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("区划信息ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("区划名称") + private String name; + + @ApiModelProperty("父级ID") + private Integer pid; + + @ApiModelProperty("区划编码") + private String code; + + @ApiModelProperty("层级(1省级 2市级 3区/县级)") + private Integer level; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSendLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSendLog.java new file mode 100644 index 0000000..4db4704 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSendLog.java @@ -0,0 +1,81 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 卡券发放记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_send_log") +@ApiModel(value = "MtSendLog对象", description = "卡券发放记录表") +public class MtSendLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("1:单用户发券;2:批量发券") + private Integer type; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("导入excel文件名") + private String fileName; + + @ApiModelProperty("导入excel文件路径") + private String filePath; + + @ApiModelProperty("用户手机") + private String mobile; + + @ApiModelProperty("券组ID") + private Integer groupId; + + @ApiModelProperty("券组名称") + private String groupName; + + @ApiModelProperty("卡券ID") + private Integer couponId; + + @ApiModelProperty("发放套数") + private Integer sendNum; + + @ApiModelProperty("操作时间") + private Date createTime; + + @ApiModelProperty("操作人") + private String operator; + + @ApiModelProperty("导入UUID") + private String uuid; + + @ApiModelProperty("作废成功张数") + private Integer removeSuccessNum; + + @ApiModelProperty("作废失败张数") + private Integer removeFailNum; + + @ApiModelProperty("状态,A正常;B:部分作废;D全部作废") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSetting.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSetting.java new file mode 100644 index 0000000..beb25de --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSetting.java @@ -0,0 +1,60 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 全局设置表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_setting") +@ApiModel(value = "MtSetting对象", description = "全局设置表") +public class MtSetting implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("类型") + private String type; + + @ApiModelProperty("配置项") + private String name; + + @ApiModelProperty("配置值") + private String value; + + @ApiModelProperty("配置说明") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态 A启用;D禁用") + private String status; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlement.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlement.java new file mode 100644 index 0000000..3ec3a57 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlement.java @@ -0,0 +1,66 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 结算表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_settlement") +@ApiModel(value = "MtSettlement对象", description = "结算表") +public class MtSettlement implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("结算单号") + private String settlementNo; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("结算比例") + private BigDecimal settleRate; + + @ApiModelProperty("订单总金额") + private BigDecimal totalOrderAmount; + + @ApiModelProperty("结算金额") + private BigDecimal amount; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("支付状态,A待支付;B已支付") + private String payStatus; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlementOrder.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlementOrder.java new file mode 100644 index 0000000..4c28ec3 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSettlementOrder.java @@ -0,0 +1,50 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 结算订单表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_settlement_order") +@ApiModel(value = "MtSettlementOrder对象", description = "结算订单表") +public class MtSettlementOrder implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("结算ID") + private Integer settlementId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsSendedLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsSendedLog.java new file mode 100644 index 0000000..45affef --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsSendedLog.java @@ -0,0 +1,51 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 短信发送记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_sms_sended_log") +@ApiModel(value = "MtSmsSendedLog对象", description = "短信发送记录表") +public class MtSmsSendedLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("日志ID") + @TableId(value = "LOG_ID", type = IdType.AUTO) + private Integer logId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("手机号") + private String mobilePhone; + + @ApiModelProperty("短信内容") + private String content; + + @ApiModelProperty("发送时间") + private Date sendTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsTemplate.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsTemplate.java new file mode 100644 index 0000000..63abb12 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtSmsTemplate.java @@ -0,0 +1,59 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 短信模板 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_sms_template") +@ApiModel(value = "MtSmsTemplate对象", description = "短信模板") +public class MtSmsTemplate implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("名称") + private String name; + + @ApiModelProperty("英文名称") + private String uname; + + @ApiModelProperty("编码") + private String code; + + @ApiModelProperty("内容") + private String content; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态:A激活;N禁用") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtStaff.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtStaff.java new file mode 100644 index 0000000..169d70a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtStaff.java @@ -0,0 +1,65 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 店铺员工表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_staff") +@ApiModel(value = "MtStaff对象", description = "店铺员工表") +public class MtStaff implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("员工类别") + private Integer category; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("手机号码") + private String mobile; + + @ApiModelProperty("真实姓名") + private String realName; + + @ApiModelProperty("微信号") + private String wechat; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("审核状态,A:审核通过;U:未审核;D:无效; ") + private String auditedStatus; + + @ApiModelProperty("审核时间") + private Date auditedTime; + + @ApiModelProperty("备注") + private String description; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtStock.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtStock.java new file mode 100644 index 0000000..c7392a3 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtStock.java @@ -0,0 +1,53 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 库存管理记录表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_stock") +@ApiModel(value = "MtStock对象", description = "库存管理记录表") +public class MtStock implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("类型,increase:入库,reduce:出库") + private String type; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("赠送时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A正常;C取消") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtStockItem.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtStockItem.java new file mode 100644 index 0000000..b92e261 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtStockItem.java @@ -0,0 +1,53 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 库存管理明细表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_stock_item") +@ApiModel(value="MtStockItem对象", description="库存管理明细表") +public class MtStockItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("库存管理ID") + private Integer stockId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("SKU") + private Integer skuId; + + @ApiModelProperty("数量") + private Double num; + + @ApiModelProperty("备注说明") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A正常;D删除") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtStore.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtStore.java new file mode 100644 index 0000000..5a0917e --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtStore.java @@ -0,0 +1,114 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 店铺表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_store") +@ApiModel(value = "MtStore对象", description = "店铺表") +public class MtStore implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺名称") + private String name; + + @ApiModelProperty("商户logo") + private String logo; + + @ApiModelProperty("店铺二维码") + private String qrCode; + + @ApiModelProperty("是否默认") + private String isDefault; + + @ApiModelProperty("联系人姓名") + private String contact; + + @ApiModelProperty("微信支付商户号") + private String wxMchId; + + @ApiModelProperty("微信支付APIv2密钥") + private String wxApiV2; + + @ApiModelProperty("微信支付证书") + private String wxCertPath; + + @ApiModelProperty("支付宝appId") + private String alipayAppId; + + @ApiModelProperty("支付宝应用私钥") + private String alipayPrivateKey; + + @ApiModelProperty("支付宝应用公钥") + private String alipayPublicKey; + + @ApiModelProperty("联系电话") + private String phone; + + @ApiModelProperty("地址") + private String address; + + @ApiModelProperty("经度") + private String latitude; + + @ApiModelProperty("维度") + private String longitude; + + @ApiModelProperty("距离") + private BigDecimal distance; + + @ApiModelProperty("营业时间") + private String hours; + + @ApiModelProperty("营业执照") + private String license; + + @ApiModelProperty("统一社会信用代码") + private String creditCode; + + @ApiModelProperty("银行名称") + private String bankName; + + @ApiModelProperty("银行卡账户名") + private String bankCardName; + + @ApiModelProperty("银行卡卡号") + private String bankCardNo; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:有效/启用;D:无效") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtStoreGoods.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtStoreGoods.java new file mode 100644 index 0000000..fc1085c --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtStoreGoods.java @@ -0,0 +1,50 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 店铺商品实体 + * + * @Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_store_goods") +@ApiModel(value = "store_goods表对象", description = "store_goods表对象") +public class MtStoreGoods implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("所属商户") + private Integer merchantId; + + @ApiModelProperty("所属店铺") + private Integer storeId; + + @ApiModelProperty("商品ID") + private Integer goodsId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:有效/启用;D:无效") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUploadShippingLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUploadShippingLog.java new file mode 100644 index 0000000..6d27bb4 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUploadShippingLog.java @@ -0,0 +1,56 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 微信小程序上传发货信息实体 + * + * @Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_upload_shipping_log") +@ApiModel(value = "upload_shipping_log表对象", description = "微信小程序上传发货信息对象") +public class MtUploadShippingLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("订单ID") + private Integer orderId; + + @ApiModelProperty("订单号") + private String orderSn; + + @ApiModelProperty("订单手机号") + private String mobile; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("状态,A成功;B失败") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUser.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUser.java new file mode 100644 index 0000000..9fedc27 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUser.java @@ -0,0 +1,118 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.*; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员个人信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_user") +@ApiModel(value = "MtUser对象", description = "会员个人信息") +public class MtUser implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("会员ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("会员号") + private String userNo; + + @ApiModelProperty("头像") + private String avatar; + + @ApiModelProperty("分组ID") + private Integer groupId; + + @ApiModelProperty("称呼") + private String name; + + @ApiModelProperty("微信open_id") + private String openId; + + @ApiModelProperty("手机号码") + private String mobile; + + @ApiModelProperty("证件号码") + private String idcard; + + @ApiModelProperty("等级ID") + private Integer gradeId; + + @ApiModelProperty("会员开始时间") + @TableField(strategy = FieldStrategy.IGNORED) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date startTime; + + @ApiModelProperty("会员结束时间") + @TableField(strategy=FieldStrategy.IGNORED) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date endTime; + + @ApiModelProperty("余额") + private BigDecimal balance; + + @ApiModelProperty("积分") + private Integer point; + + @ApiModelProperty("性别 1男;0女") + private Integer sex; + + @ApiModelProperty("出生日期") + private String birthday; + + @ApiModelProperty("车牌号") + private String carNo; + + @ApiModelProperty("来源渠道") + private String source; + + @ApiModelProperty("密码") + private String password; + + @ApiModelProperty("salt") + private String salt; + + @ApiModelProperty("地址") + private String address; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("默认店铺") + private Integer storeId; + + @ApiModelProperty("是否员工") + private String isStaff; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("注册IP") + private String ip; + + @ApiModelProperty("最后操作人") + private String operator; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUserAction.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserAction.java new file mode 100644 index 0000000..565428d --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserAction.java @@ -0,0 +1,58 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员行为信息 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_user_action") +@ApiModel(value = "MtUserAction对象", description = "会员行为信息") +public class MtUserAction implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("会员ID") + private Integer userId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("店铺ID") + private Integer storeId; + + @ApiModelProperty("行为类别") + private String action; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("参数") + private String param; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("最后操作人") + private String operator; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUserCoupon.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserCoupon.java new file mode 100644 index 0000000..654b601 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserCoupon.java @@ -0,0 +1,87 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员卡券表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_user_coupon") +@ApiModel(value = "MtUserCoupon对象", description = "会员卡券表") +public class MtUserCoupon implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("核销码") + private String code; + + @ApiModelProperty("券类型,C优惠券;P储值卡;T计次卡") + private String type; + + @ApiModelProperty("效果图") + private String image; + + @ApiModelProperty("券组ID") + private Integer groupId; + + @ApiModelProperty("券ID") + private Integer couponId; + + @ApiModelProperty("用户手机号码") + private String mobile; + + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("使用店铺ID") + private Integer storeId; + + @ApiModelProperty("面额") + private BigDecimal amount; + + @ApiModelProperty("余额") + private BigDecimal balance; + + @ApiModelProperty("状态:A:未使用;B:已使用;C:已过期; D:已删除;E:未领取") + private String status; + + @ApiModelProperty("使用时间") + private Date usedTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("过期时间") + private Date expireTime; + + @ApiModelProperty("最后操作人") + private String operator; + + @ApiModelProperty("导入UUID") + private String uuid; + + @ApiModelProperty("订单ID") + private Integer orderId; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGrade.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGrade.java new file mode 100644 index 0000000..6b44821 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGrade.java @@ -0,0 +1,62 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员等级表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_user_grade") +@ApiModel(value = "MtUserGrade对象", description = "") +public class MtUserGrade implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("等级") + private Integer grade; + + @ApiModelProperty("等级名称") + private String name; + + @ApiModelProperty("升级会员等级条件描述") + private String catchCondition; + + @ApiModelProperty("升级会员等级条件,init:默认获取;pay:付费升级;frequency:消费次数;amount:累积消费金额升级") + private String catchType; + + @ApiModelProperty("达到升级条件的值") + private BigDecimal catchValue; + + @ApiModelProperty("会员权益描述") + private String userPrivilege; + + @ApiModelProperty("有效期") + private Integer validDay; + + @ApiModelProperty("享受折扣") + private Float discount; + + @ApiModelProperty("积分加速") + private Float speedPoint; + + @ApiModelProperty("状态") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGroup.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGroup.java new file mode 100644 index 0000000..b4683ab --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtUserGroup.java @@ -0,0 +1,54 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.*; + +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 会员分组 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_user_group") +@ApiModel(value = "MtUserGroup对象", description = "会员分组") +public class MtUserGroup implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("分组ID") + @TableId(value = "ID", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("分组名称") + private String name; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("默认店铺") + private Integer storeId; + + @ApiModelProperty("父ID") + private Integer parentId; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("状态,A:激活;N:禁用;D:删除") + private String status; + + @ApiModelProperty("备注信息") + private String description; + + @ApiModelProperty("最后操作人") + private String operator; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/MtVerifyCode.java b/fuint-repository/src/main/java/com/fuint/repository/model/MtVerifyCode.java new file mode 100644 index 0000000..7d01050 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/MtVerifyCode.java @@ -0,0 +1,48 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 短信验证码表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("mt_verify_code") +@ApiModel(value = "MtVerifyCode对象", description = "短信验证码表") +public class MtVerifyCode implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("自增id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("手机号") + private String mobile; + + @ApiModelProperty("验证码") + private String verifyCode; + + @ApiModelProperty("创建时间") + private Date addTime; + + @ApiModelProperty("过期时间") + private Date expireTime; + + @ApiModelProperty("使用时间") + private Date usedTime; + + @ApiModelProperty("可用状态 0未用 1已用 2置为失效") + private String validFlag; + + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TAccount.java b/fuint-repository/src/main/java/com/fuint/repository/model/TAccount.java new file mode 100644 index 0000000..7eebf69 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TAccount.java @@ -0,0 +1,70 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 后台管理员表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_account") +@ApiModel(value = "TAccount对象", description = "后台管理员表") +public class TAccount implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键id") + @TableId(value = "acct_id", type = IdType.AUTO) + private Integer acctId; + + @ApiModelProperty("账户编码") + private String accountKey; + + @ApiModelProperty("账户名称") + private String accountName; + + @ApiModelProperty("密码") + private String password; + + @ApiModelProperty("0 无效 1 有效") + private Integer accountStatus; + + @ApiModelProperty("0 未激活 1已激活") + private Integer isActive; + + @ApiModelProperty("创建时间") + private Date createDate; + + @ApiModelProperty("修改时间") + private Date modifyDate; + + @ApiModelProperty("随机码") + private String salt; + + private String roleIds; + + private Integer locked; + + @ApiModelProperty("所属平台") + private Integer ownerId; + + private String realName; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("所属商户ID") + private Integer merchantId; + + @ApiModelProperty("员工ID") + private Integer staffId; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TAccountDuty.java b/fuint-repository/src/main/java/com/fuint/repository/model/TAccountDuty.java new file mode 100644 index 0000000..d6a990b --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TAccountDuty.java @@ -0,0 +1,34 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 后台账号角色表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_account_duty") +@ApiModel(value = "TAccountDuty对象", description = "后台账号角色表") +public class TAccountDuty implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("账户角色ID") + @TableId(value = "acc_duty_id", type = IdType.AUTO) + private Integer accDutyId; + + @ApiModelProperty("账户ID") + private Integer acctId; + + @ApiModelProperty("角色ID") + private Integer dutyId; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TActionLog.java b/fuint-repository/src/main/java/com/fuint/repository/model/TActionLog.java new file mode 100644 index 0000000..e324f12 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TActionLog.java @@ -0,0 +1,62 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 后台操作日志表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_action_log") +@ApiModel(value = "TActionLog对象", description = "后台操作日志表") +public class TActionLog implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("所属店铺ID") + private Integer storeId; + + @ApiModelProperty("操作时间") + private Date actionTime; + + @ApiModelProperty("耗时") + private BigDecimal timeConsuming; + + @ApiModelProperty("客户端IP") + private String clientIp; + + @ApiModelProperty("操作模块") + private String module; + + @ApiModelProperty("请求URL") + private String url; + + @ApiModelProperty("操作用户账户") + private String acctName; + + @ApiModelProperty("用户系统以及浏览器信息") + private String userAgent; + + @ApiModelProperty("端口号") + private Integer clientPort; + + @ApiModelProperty("操作参数") + private String param; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TDuty.java b/fuint-repository/src/main/java/com/fuint/repository/model/TDuty.java new file mode 100644 index 0000000..3cbb3d8 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TDuty.java @@ -0,0 +1,42 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 角色表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_duty") +@ApiModel(value = "TDuty对象", description = "角色表") +public class TDuty implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("角色ID") + @TableId(value = "duty_id", type = IdType.AUTO) + private Integer dutyId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("角色名称") + private String dutyName; + + @ApiModelProperty("状态(A: 可用 D: 禁用)") + private String status; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("角色类型") + private String dutyType; +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TDutySource.java b/fuint-repository/src/main/java/com/fuint/repository/model/TDutySource.java new file mode 100644 index 0000000..47fca97 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TDutySource.java @@ -0,0 +1,30 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * 角色权限对象 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_duty_source") +@ApiModel(value = "TDutySource对象", description = "角色权限对象") +public class TDutySource implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "duty_source_id", type = IdType.AUTO) + private Integer dutySourceId; + + private Integer dutyId; + + private Integer sourceId; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TGenCode.java b/fuint-repository/src/main/java/com/fuint/repository/model/TGenCode.java new file mode 100644 index 0000000..429f11e --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TGenCode.java @@ -0,0 +1,65 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 生成代码实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_gen_code") +@ApiModel(value = "TGenCode对象", description = "生成代码实体") +public class TGenCode implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty("服务名称") + private String serviceName; + + @ApiModelProperty("模块名称") + private String moduleName; + + @ApiModelProperty("表名称") + private String tableName; + + @ApiModelProperty("表前缀") + private String tablePrefix; + + @ApiModelProperty("主键名") + private String pkName; + + @ApiModelProperty("后端包名") + private String packageName; + + @ApiModelProperty("后端路径") + private String backendPath; + + @ApiModelProperty("前端路径") + private String frontPath; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("更新时间") + private Date updateTime; + + @ApiModelProperty("作者") + private String author; + + @ApiModelProperty("状态 0 无效 1 有效") + private String status; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TPlatform.java b/fuint-repository/src/main/java/com/fuint/repository/model/TPlatform.java new file mode 100644 index 0000000..cdb2be6 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TPlatform.java @@ -0,0 +1,40 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 平台实体类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_platform") +@ApiModel(value = "TPlatform对象", description = "平台") +public class TPlatform implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键") + @TableId(value = "owner_id", type = IdType.AUTO) + private Integer ownerId; + + @ApiModelProperty("平台名称") + private String name; + + @ApiModelProperty("状态 0 无效 1 有效") + private Integer status; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("平台类型") + private Integer platformType; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/TSource.java b/fuint-repository/src/main/java/com/fuint/repository/model/TSource.java new file mode 100644 index 0000000..14e46d5 --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/TSource.java @@ -0,0 +1,69 @@ +package com.fuint.repository.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 菜单表 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Data +@TableName("t_source") +@ApiModel(value = "TSource对象", description = "菜单表") +public class TSource implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("菜单Id") + @TableId(value = "source_id", type = IdType.AUTO) + private Integer sourceId; + + @ApiModelProperty("商户ID") + private Integer merchantId; + + @ApiModelProperty("菜单名称") + private String sourceName; + + @ApiModelProperty("菜单对应url") + private String sourceCode; + + @ApiModelProperty("路径") + private String path; + + @ApiModelProperty("字母名称") + private String ename; + + @ApiModelProperty("新图标") + private String newIcon; + + @ApiModelProperty("状态(A:可用 D:禁用)") + private String status; + + @ApiModelProperty("菜单级别") + private Integer sourceLevel; + + @ApiModelProperty("样式") + private String sourceStyle; + + @ApiModelProperty("是否显示") + private Integer isMenu; + + @ApiModelProperty("描述") + private String description; + + @ApiModelProperty("上级菜单ID") + private Integer parentId; + + private Integer isLog; + + @ApiModelProperty("菜单图标") + private String icon; + +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/base/AutoIncrementIdModel.java b/fuint-repository/src/main/java/com/fuint/repository/model/base/AutoIncrementIdModel.java new file mode 100644 index 0000000..6199cdf --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/base/AutoIncrementIdModel.java @@ -0,0 +1,18 @@ +package com.fuint.repository.model.base; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class AutoIncrementIdModel { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/base/ElasticSearchModel.java b/fuint-repository/src/main/java/com/fuint/repository/model/base/ElasticSearchModel.java new file mode 100644 index 0000000..feb14ec --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/base/ElasticSearchModel.java @@ -0,0 +1,26 @@ +package com.fuint.repository.model.base; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public interface ElasticSearchModel { + + /** + * 在ElasticSearch中的Index + * @return + */ + String elasticSearchIndex(); + + /** + * 在ElasticSearch中的Type + * @return + */ + String elasticSearchType(); + + /** + * 获取ID + * @return + */ + String elasticSearchId(); +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/base/OpsExercise.java b/fuint-repository/src/main/java/com/fuint/repository/model/base/OpsExercise.java new file mode 100644 index 0000000..0c665fd --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/base/OpsExercise.java @@ -0,0 +1,38 @@ +package com.fuint.repository.model.base; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class OpsExercise { + + private String exerId; + + private int courseId; + + private int difficultyLv; + + public String getExerId() { + return exerId; + } + + public void setExerId(String exerId) { + this.exerId = exerId; + } + + public int getCourseId() { + return courseId; + } + + public void setCourseId(int courseId) { + this.courseId = courseId; + } + + public int getDifficultyLv() { + return difficultyLv; + } + + public void setDifficultyLv(int difficultyLv) { + this.difficultyLv = difficultyLv; + } +} diff --git a/fuint-repository/src/main/java/com/fuint/repository/model/base/RedisCache.java b/fuint-repository/src/main/java/com/fuint/repository/model/base/RedisCache.java new file mode 100644 index 0000000..427d75a --- /dev/null +++ b/fuint-repository/src/main/java/com/fuint/repository/model/base/RedisCache.java @@ -0,0 +1,17 @@ +package com.fuint.repository.model.base; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RedisCache { + String prefix() default ""; + String key() default ""; +} diff --git a/fuint-repository/src/main/resources/mapper/MtAddressMapper.xml b/fuint-repository/src/main/resources/mapper/MtAddressMapper.xml new file mode 100644 index 0000000..bcc358f --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtAddressMapper.xml @@ -0,0 +1,7 @@ + + + + + update mt_address p set p.IS_DEFAULT = 'N' where p.USER_ID = #{userId} and p.ID != #{addressId} + + diff --git a/fuint-repository/src/main/resources/mapper/MtArticleMapper.xml b/fuint-repository/src/main/resources/mapper/MtArticleMapper.xml new file mode 100644 index 0000000..4da55a9 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtArticleMapper.xml @@ -0,0 +1,7 @@ + + + + + update mt_article t set t.CLICK = t.CLICK + 1 where t.ID = #{articleId} + + diff --git a/fuint-repository/src/main/resources/mapper/MtBalanceMapper.xml b/fuint-repository/src/main/resources/mapper/MtBalanceMapper.xml new file mode 100644 index 0000000..3784157 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtBalanceMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtBannerMapper.xml b/fuint-repository/src/main/resources/mapper/MtBannerMapper.xml new file mode 100644 index 0000000..ac12cb3 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtBannerMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtBookItemMapper.xml b/fuint-repository/src/main/resources/mapper/MtBookItemMapper.xml new file mode 100644 index 0000000..5aa401f --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtBookItemMapper.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCartMapper.xml b/fuint-repository/src/main/resources/mapper/MtCartMapper.xml new file mode 100644 index 0000000..317ffc5 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCartMapper.xml @@ -0,0 +1,15 @@ + + + + + delete from mt_cart where USER_ID = #{userId} and GOODS_ID = #{goodsId} and SKU_ID = #{skuId} + + + + delete from mt_cart where USER_ID = #{userId} + + + + delete from mt_cart where HANG_NO = #{hangNo} + + diff --git a/fuint-repository/src/main/resources/mapper/MtCommissionCashMapper.xml b/fuint-repository/src/main/resources/mapper/MtCommissionCashMapper.xml new file mode 100644 index 0000000..ab78b9f --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCommissionCashMapper.xml @@ -0,0 +1,17 @@ + + + + + update mt_commission_cash t set t.STATUS = 'B',t.OPERATOR = #{operator} where t.uuid = #{uuid} + + AND t.MERCHANT_ID = #{merchantId} + + + + + update mt_commission_cash t set t.STATUS = 'D',t.OPERATOR = #{operator} where t.uuid = #{uuid} + + AND t.MERCHANT_ID = #{merchantId} + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCommissionLogMapper.xml b/fuint-repository/src/main/resources/mapper/MtCommissionLogMapper.xml new file mode 100644 index 0000000..a9d6b45 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCommissionLogMapper.xml @@ -0,0 +1,17 @@ + + + + + update mt_commission_log t set t.STATUS = 'B',t.OPERATOR = #{operator} where t.SETTLE_UUID = #{uuid} + + AND t.MERCHANT_ID = #{merchantId} + + + + + update mt_commission_log t set t.STATUS = 'A',t.OPERATOR = #{operator} where t.SETTLE_UUID = #{uuid} + + AND t.MERCHANT_ID = #{merchantId} + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCommissionRelationMapper.xml b/fuint-repository/src/main/resources/mapper/MtCommissionRelationMapper.xml new file mode 100644 index 0000000..4cb3122 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCommissionRelationMapper.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCommissionRuleItemMapper.xml b/fuint-repository/src/main/resources/mapper/MtCommissionRuleItemMapper.xml new file mode 100644 index 0000000..56196e0 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCommissionRuleItemMapper.xml @@ -0,0 +1,23 @@ + + + + + update mt_commission_rule_item set STATUS = 'D',UPDATE_TIME=#{updateTime} where RULE_ID = #{ruleId} + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCommissionRuleMapper.xml b/fuint-repository/src/main/resources/mapper/MtCommissionRuleMapper.xml new file mode 100644 index 0000000..a909346 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCommissionRuleMapper.xml @@ -0,0 +1,4 @@ + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtConfirmLogMapper.xml b/fuint-repository/src/main/resources/mapper/MtConfirmLogMapper.xml new file mode 100644 index 0000000..8cc1c4d --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtConfirmLogMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCouponGoodsMapper.xml b/fuint-repository/src/main/resources/mapper/MtCouponGoodsMapper.xml new file mode 100644 index 0000000..99d579f --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCouponGoodsMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCouponGroupMapper.xml b/fuint-repository/src/main/resources/mapper/MtCouponGroupMapper.xml new file mode 100644 index 0000000..9c0c217 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCouponGroupMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtCouponMapper.xml b/fuint-repository/src/main/resources/mapper/MtCouponMapper.xml new file mode 100644 index 0000000..7ec97c8 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtCouponMapper.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtGiveItemMapper.xml b/fuint-repository/src/main/resources/mapper/MtGiveItemMapper.xml new file mode 100644 index 0000000..fda3c04 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGiveItemMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtGiveMapper.xml b/fuint-repository/src/main/resources/mapper/MtGiveMapper.xml new file mode 100644 index 0000000..d984ada --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGiveMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtGoodsCateMapper.xml b/fuint-repository/src/main/resources/mapper/MtGoodsCateMapper.xml new file mode 100644 index 0000000..a3add51 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGoodsCateMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtGoodsMapper.xml b/fuint-repository/src/main/resources/mapper/MtGoodsMapper.xml new file mode 100644 index 0000000..19eb3b4 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGoodsMapper.xml @@ -0,0 +1,100 @@ + + + + + `ID`, `TYPE`, `MERCHANT_ID`, `STORE_ID`, `NAME`, `CATE_ID`, `GOODS_NO`, `PLATFORM`, `IS_SINGLE_SPEC`, + `LOGO`, `PRICE`, `LINE_PRICE`, `COST_PRICE`, `STOCK`, `WEIGHT`, `COUPON_IDS`, `INIT_SALE`, `SALE_POINT`, + `CAN_USE_POINT`, `IS_MEMBER_DISCOUNT`, `SORT`, `CREATE_TIME`, `UPDATE_TIME`, `OPERATOR`, `STATUS` + + + + + + + + + + + update mt_goods t set t.INIT_SALE = t.INIT_SALE + #{saleNum} where t.ID = #{goodsId} + + + + + + + + update mt_goods t set t.STATUS = 'D' where t.MERCHANT_ID = #{merchantId} + + diff --git a/fuint-repository/src/main/resources/mapper/MtGoodsSkuMapper.xml b/fuint-repository/src/main/resources/mapper/MtGoodsSkuMapper.xml new file mode 100644 index 0000000..2d45414 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGoodsSkuMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtGoodsSpecMapper.xml b/fuint-repository/src/main/resources/mapper/MtGoodsSpecMapper.xml new file mode 100644 index 0000000..bef3054 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtGoodsSpecMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtInvoiceMapper.xml b/fuint-repository/src/main/resources/mapper/MtInvoiceMapper.xml new file mode 100644 index 0000000..4719bbf --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtInvoiceMapper.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtMerchantMapper.xml b/fuint-repository/src/main/resources/mapper/MtMerchantMapper.xml new file mode 100644 index 0000000..ddf9e1d --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtMerchantMapper.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtMessageMapper.xml b/fuint-repository/src/main/resources/mapper/MtMessageMapper.xml new file mode 100644 index 0000000..da81642 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtMessageMapper.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtOpenGiftItemMapper.xml b/fuint-repository/src/main/resources/mapper/MtOpenGiftItemMapper.xml new file mode 100644 index 0000000..67dba73 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtOpenGiftItemMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtOpenGiftMapper.xml b/fuint-repository/src/main/resources/mapper/MtOpenGiftMapper.xml new file mode 100644 index 0000000..ccdb2b3 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtOpenGiftMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtOrderAddressMapper.xml b/fuint-repository/src/main/resources/mapper/MtOrderAddressMapper.xml new file mode 100644 index 0000000..6261d57 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtOrderAddressMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtOrderGoodsMapper.xml b/fuint-repository/src/main/resources/mapper/MtOrderGoodsMapper.xml new file mode 100644 index 0000000..cfe7104 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtOrderGoodsMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtOrderMapper.xml b/fuint-repository/src/main/resources/mapper/MtOrderMapper.xml new file mode 100644 index 0000000..299ae0c --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtOrderMapper.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtPointMapper.xml b/fuint-repository/src/main/resources/mapper/MtPointMapper.xml new file mode 100644 index 0000000..75e2393 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtPointMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtPrinterMapper.xml b/fuint-repository/src/main/resources/mapper/MtPrinterMapper.xml new file mode 100644 index 0000000..bbe3968 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtPrinterMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtRefundMapper.xml b/fuint-repository/src/main/resources/mapper/MtRefundMapper.xml new file mode 100644 index 0000000..0086b0a --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtRefundMapper.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtRegionMapper.xml b/fuint-repository/src/main/resources/mapper/MtRegionMapper.xml new file mode 100644 index 0000000..0ac2103 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtRegionMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtSendLogMapper.xml b/fuint-repository/src/main/resources/mapper/MtSendLogMapper.xml new file mode 100644 index 0000000..d9b89ee --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSendLogMapper.xml @@ -0,0 +1,11 @@ + + + + + update mt_send_log p set p.STATUS =#{status},p.REMOVE_SUCCESS_NUM =#{removeSuccessNum},p.REMOVE_FAIL_NUM =#{removeFailNum} where p.UUID = #{uuid} + + + + update mt_send_log p set p.STATUS =#{status},p.REMOVE_SUCCESS_NUM =p.REMOVE_SUCCESS_NUM+1 where p.UUID =#{uuid} + + diff --git a/fuint-repository/src/main/resources/mapper/MtSettingMapper.xml b/fuint-repository/src/main/resources/mapper/MtSettingMapper.xml new file mode 100644 index 0000000..052918d --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSettingMapper.xml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtSettlementMapper.xml b/fuint-repository/src/main/resources/mapper/MtSettlementMapper.xml new file mode 100644 index 0000000..75e2393 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSettlementMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtSettlementOrderMapper.xml b/fuint-repository/src/main/resources/mapper/MtSettlementOrderMapper.xml new file mode 100644 index 0000000..75e2393 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSettlementOrderMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtSmsSendedLogMapper.xml b/fuint-repository/src/main/resources/mapper/MtSmsSendedLogMapper.xml new file mode 100644 index 0000000..8325cc9 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSmsSendedLogMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtSmsTemplateMapper.xml b/fuint-repository/src/main/resources/mapper/MtSmsTemplateMapper.xml new file mode 100644 index 0000000..6be0cd8 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtSmsTemplateMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtStaffMapper.xml b/fuint-repository/src/main/resources/mapper/MtStaffMapper.xml new file mode 100644 index 0000000..7361ca6 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtStaffMapper.xml @@ -0,0 +1,15 @@ + + + + + update mt_staff p set p.AUDITED_STATUS = #{status}, p.UPDATE_TIME = #{updateTime} where p.ID = #{id} + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtStoreGoodsMapper.xml b/fuint-repository/src/main/resources/mapper/MtStoreGoodsMapper.xml new file mode 100644 index 0000000..71f5870 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtStoreGoodsMapper.xml @@ -0,0 +1,7 @@ + + + + + update mt_store_goods set STATUS = 'D' where STORE_ID = #{storeId} + + diff --git a/fuint-repository/src/main/resources/mapper/MtStoreMapper.xml b/fuint-repository/src/main/resources/mapper/MtStoreMapper.xml new file mode 100644 index 0000000..b5c5360 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtStoreMapper.xml @@ -0,0 +1,51 @@ + + + + + + + update mt_store p set p.IS_DEFAULT = 'N' where p.STATUS != 'D' + + AND p.MERCHANT_ID = #{merchantId} + + + + + + + + + update mt_store set STATUS = 'D' where MERCHANT_ID = #{merchantId} + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtUploadShippingLogMapper.xml b/fuint-repository/src/main/resources/mapper/MtUploadShippingLogMapper.xml new file mode 100644 index 0000000..2c21882 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUploadShippingLogMapper.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtUserActionMapper.xml b/fuint-repository/src/main/resources/mapper/MtUserActionMapper.xml new file mode 100644 index 0000000..b148eb6 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUserActionMapper.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtUserCouponMapper.xml b/fuint-repository/src/main/resources/mapper/MtUserCouponMapper.xml new file mode 100644 index 0000000..828fa3a --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUserCouponMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + update mt_user_coupon p set p.STATUS ='D',p.OPERATOR = #{operator} where p.UUID = #{uuid} and p.COUPON_ID in + + #{couponId} + + and p.status='A' + + + + + + + + + + + + update mt_user_coupon set EXPIRE_TIME = #{expireTime} where COUPON_ID = #{couponId} + + + + update mt_user_coupon set STATUS = 'D' where COUPON_ID = #{couponId} + + diff --git a/fuint-repository/src/main/resources/mapper/MtUserGradeMapper.xml b/fuint-repository/src/main/resources/mapper/MtUserGradeMapper.xml new file mode 100644 index 0000000..0905218 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUserGradeMapper.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtUserGroupMapper.xml b/fuint-repository/src/main/resources/mapper/MtUserGroupMapper.xml new file mode 100644 index 0000000..eea58ed --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUserGroupMapper.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtUserMapper.xml b/fuint-repository/src/main/resources/mapper/MtUserMapper.xml new file mode 100644 index 0000000..7c37060 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtUserMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + update mt_user t set t.UPDATE_TIME = #{updateTime} where t.ID = #{userId} + + + + update mt_user t set t.BALANCE = (t.BALANCE + #{amount}) where t.STATUS = 'A' + + AND t.ID IN + + #{userId} + + + + AND t.MERCHANT_ID = #{merchantId} + + + + + update mt_user t set t.MOBILE = '' where t.MOBILE = #{mobile} and t.ID != #{userId} + + AND t.MERCHANT_ID = #{merchantId} + + + + + + + + + + + + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/MtVerifyCodeMapper.xml b/fuint-repository/src/main/resources/mapper/MtVerifyCodeMapper.xml new file mode 100644 index 0000000..6bd5382 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/MtVerifyCodeMapper.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TAccountDutyMapper.xml b/fuint-repository/src/main/resources/mapper/TAccountDutyMapper.xml new file mode 100644 index 0000000..85ed1bd --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TAccountDutyMapper.xml @@ -0,0 +1,11 @@ + + + + + + + delete from t_account_duty where acct_id = #{accountId} + + diff --git a/fuint-repository/src/main/resources/mapper/TAccountMapper.xml b/fuint-repository/src/main/resources/mapper/TAccountMapper.xml new file mode 100644 index 0000000..74fe457 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TAccountMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TActionLogMapper.xml b/fuint-repository/src/main/resources/mapper/TActionLogMapper.xml new file mode 100644 index 0000000..2378f52 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TActionLogMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TDutyMapper.xml b/fuint-repository/src/main/resources/mapper/TDutyMapper.xml new file mode 100644 index 0000000..9f64f43 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TDutyMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TDutySourceMapper.xml b/fuint-repository/src/main/resources/mapper/TDutySourceMapper.xml new file mode 100644 index 0000000..255f251 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TDutySourceMapper.xml @@ -0,0 +1,12 @@ + + + + + + + delete from t_duty_source where duty_id = #{dutyId} + + diff --git a/fuint-repository/src/main/resources/mapper/TGenCodeMapper.xml b/fuint-repository/src/main/resources/mapper/TGenCodeMapper.xml new file mode 100644 index 0000000..04cbb8e --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TGenCodeMapper.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TPlatformMapper.xml b/fuint-repository/src/main/resources/mapper/TPlatformMapper.xml new file mode 100644 index 0000000..a089ad1 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TPlatformMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/fuint-repository/src/main/resources/mapper/TSourceMapper.xml b/fuint-repository/src/main/resources/mapper/TSourceMapper.xml new file mode 100644 index 0000000..41b2af4 --- /dev/null +++ b/fuint-repository/src/main/resources/mapper/TSourceMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/fuint-utils/pom.xml b/fuint-utils/pom.xml new file mode 100644 index 0000000..aebf27a --- /dev/null +++ b/fuint-utils/pom.xml @@ -0,0 +1,70 @@ + + + + fuint + com.fuint + 1.0.0 + + 4.0.0 + + fuint-utils + 1.0.0 + jar + + + + com.google.zxing + core + 3.3.0 + + + com.google.zxing + javase + 3.3.0 + + + org.bouncycastle + bcprov-jdk15on + 1.58 + + + commons-lang + commons-lang + 2.6 + + + + org.apache.poi + poi + 3.14 + + + org.apache.poi + poi-ooxml + 3.14 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + + diff --git a/fuint-utils/src/main/java/com/fuint/exception/Exceptions.java b/fuint-utils/src/main/java/com/fuint/exception/Exceptions.java new file mode 100644 index 0000000..d50ad40 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/exception/Exceptions.java @@ -0,0 +1,70 @@ +package com.fuint.exception; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 关于异常的工具类. + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Exceptions { + + /** + * 将CheckedException转换为UncheckedException. + */ + public static RuntimeException unchecked(Throwable ex) { + if (ex instanceof RuntimeException) { + return (RuntimeException) ex; + } else { + return new RuntimeException(ex); + } + } + + /** + * 将ErrorStack转化为String. + */ + public static String getStackTraceAsString(Throwable ex) { + StringWriter stringWriter = new StringWriter(); + ex.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + + /** + * 获取组合本异常信息与底层异常信息的异常描述, 适用于本异常为统一包装异常类,底层异常才是根本原因的情况。 + */ + public static String getErrorMessageWithNestedException(Throwable ex) { + Throwable nestedException = ex.getCause(); + return new StringBuilder().append(ex.getMessage()).append(" nested exception is ") + .append(nestedException.getClass().getName()).append(":") + .append(nestedException.getMessage()).toString(); + } + + /** + * 获取异常的Root Cause. + */ + public static Throwable getRootCause(Throwable ex) { + Throwable cause; + while ((cause = ex.getCause()) != null) { + ex = cause; + } + return ex; + } + + /** + * 判断异常是否由某些底层的异常引起. + */ + public static boolean isCausedBy(Exception ex, Class... causeExceptionClasses) { + Throwable cause = ex; + while (cause != null) { + for (Class causeClass : causeExceptionClasses) { + if (causeClass.isInstance(cause)) { + return true; + } + } + cause = cause.getCause(); + } + return false; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/text/CharsetKit.java b/fuint-utils/src/main/java/com/fuint/text/CharsetKit.java new file mode 100644 index 0000000..77b4c0e --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/text/CharsetKit.java @@ -0,0 +1,87 @@ +package com.fuint.text; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * 字符集工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class CharsetKit { + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/text/Convert.java b/fuint-utils/src/main/java/com/fuint/text/Convert.java new file mode 100644 index 0000000..ff12a5f --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/text/Convert.java @@ -0,0 +1,1007 @@ +package com.fuint.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * 类型转换器 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Convert { + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else if (obj instanceof Byte[]) + { + byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj); + return str(bytes, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + // 优化double计算精度丢失问题 + BigDecimal nNum = new BigDecimal(n); + BigDecimal decimal = new BigDecimal(10); + BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN); + double d = scale.doubleValue(); + s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/text/StrFormatter.java b/fuint-utils/src/main/java/com/fuint/text/StrFormatter.java new file mode 100644 index 0000000..4e15dcd --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/text/StrFormatter.java @@ -0,0 +1,93 @@ +package com.fuint.text; + +import com.fuint.utils.StringUtil; + +/** + * 字符串格式化 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class StrFormatter { + + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtil.isEmpty(strPattern) || argArray == null) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/AES.java b/fuint-utils/src/main/java/com/fuint/utils/AES.java new file mode 100644 index 0000000..a73bfba --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/AES.java @@ -0,0 +1,99 @@ +package com.fuint.utils; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.util.Arrays; + +/** + * 加密算法 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class AES { + // 算法名称 + final String KEY_ALGORITHM = "AES"; + // 加解密算法/模式/填充方式 + final String algorithmStr = "AES/CBC/PKCS7Padding"; + private Key key; + private Cipher cipher; + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + final byte[] iv = {0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38}; + + public void init(byte[] keyBytes) { + + // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 + int base = 16; + if (keyBytes.length % base != 0) { + int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); + keyBytes = temp; + } + // 初始化 + // 转化成JAVA的密钥格式 + key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); + try { + // 初始化cipher + cipher = Cipher.getInstance(algorithmStr, "BC"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } + } + + /** + * 加密方法 + * + * @param content 要加密的字符串 + * @param keyBytes 加密密钥 + * @return + */ + public byte[] encrypt(byte[] content, byte[] keyBytes) { + byte[] encryptedText = null; + init(keyBytes); + System.out.println("IV:" + new String(iv)); + try { + cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); + encryptedText = cipher.doFinal(content); + } catch (Exception e) { + e.printStackTrace(); + } + return encryptedText; + } + + /** + * 解密方法 + * + * @param encryptedData 要解密的字符串 + * @param keyBytes 解密密钥 + * @return + */ + public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) { + byte[] encryptedText = null; + init(keyBytes); + System.out.println("IV:" + new String(iv)); + try { + cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); + encryptedText = cipher.doFinal(encryptedData); + } catch (Exception e) { + e.printStackTrace(); + } + return encryptedText; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/ArrayUtil.java b/fuint-utils/src/main/java/com/fuint/utils/ArrayUtil.java new file mode 100644 index 0000000..ce15379 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ArrayUtil.java @@ -0,0 +1,5546 @@ +package com.fuint.utils; + +import java.lang.reflect.Array; +import java.util.*; + +/** + * 有关数组处理的工具类。 + * + * 这个类中的每个方法都可以“安全”地处理null,而不会抛出NullPointerException。 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class ArrayUtil { + + /* ============================================================================ */ + /* 常量和singleton。 */ + /* ============================================================================ */ + + /** 空的Object数组。 */ + public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + + /** 空的Class数组。 */ + public static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + + /** 空的String数组。 */ + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + + /** 空的long数组。 */ + public static final long[] EMPTY_LONG_ARRAY = new long[0]; + + /** 空的Long数组。 */ + public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0]; + + /** 空的int数组。 */ + public static final int[] EMPTY_INT_ARRAY = new int[0]; + + /** 空的Integer数组。 */ + public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0]; + + /** 空的short数组。 */ + public static final short[] EMPTY_SHORT_ARRAY = new short[0]; + + /** 空的Short数组。 */ + public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0]; + + /** 空的byte数组。 */ + public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + /** 空的Byte数组。 */ + public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0]; + + /** 空的double数组。 */ + public static final double[] EMPTY_DOUBLE_ARRAY = new double[0]; + + /** 空的Double数组。 */ + public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0]; + + /** 空的float数组。 */ + public static final float[] EMPTY_FLOAT_ARRAY = new float[0]; + + /** 空的Float数组。 */ + public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0]; + + /** 空的boolean数组。 */ + public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; + + /** 空的Boolean数组。 */ + public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0]; + + /** 空的char数组。 */ + public static final char[] EMPTY_CHAR_ARRAY = new char[0]; + + /** 空的Character数组。 */ + public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0]; + + /** 计算hashcode所用的常量。 */ + private static final int INITIAL_NON_ZERO_ODD_NUMBER = 17; + + /** 计算hashcode所用的常量。 */ + private static final int MULTIPLIER_NON_ZERO_ODD_NUMBER = 37; + + /* ============================================================================ */ + /* 判空函数。 */ + /* */ + /* 判断一个数组是否为null或包含0个元素。 */ + /* ============================================================================ */ + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new String[0])     = true
+     * ArrayUtil.isEmpty(new String[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(Object[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new long[0])     = true
+     * ArrayUtil.isEmpty(new long[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(long[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new int[0])     = true
+     * ArrayUtil.isEmpty(new int[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(int[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new short[0])     = true
+     * ArrayUtil.isEmpty(new short[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(short[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new byte[0])     = true
+     * ArrayUtil.isEmpty(new byte[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(byte[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new double[0])     = true
+     * ArrayUtil.isEmpty(new double[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(double[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new float[0])     = true
+     * ArrayUtil.isEmpty(new float[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(float[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new boolean[0])     = true
+     * ArrayUtil.isEmpty(new boolean[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(boolean[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否为null或空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = true
+     * ArrayUtil.isEmpty(new char[0])     = true
+     * ArrayUtil.isEmpty(new char[10])    = false
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(char[] array) { + return ((array == null) || (array.length == 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new String[0])     = false
+     * ArrayUtil.isEmpty(new String[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(Object[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new long[0])     = false
+     * ArrayUtil.isEmpty(new long[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(long[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new int[0])     = false
+     * ArrayUtil.isEmpty(new int[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(int[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new short[0])     = false
+     * ArrayUtil.isEmpty(new short[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(short[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new byte[0])     = false
+     * ArrayUtil.isEmpty(new byte[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(byte[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new double[0])     = false
+     * ArrayUtil.isEmpty(new double[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(double[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new float[0])     = false
+     * ArrayUtil.isEmpty(new float[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(float[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new boolean[0])     = false
+     * ArrayUtil.isEmpty(new boolean[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(boolean[] array) { + return ((array != null) && (array.length > 0)); + } + + /** + * 检查数组是否不是null和空数组[]。 + *
+     * ArrayUtil.isEmpty(null)              = false
+     * ArrayUtil.isEmpty(new char[0])     = false
+     * ArrayUtil.isEmpty(new char[10])    = true
+     * 
+ * + * @param array 要检查的数组 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(char[] array) { + return ((array != null) && (array.length > 0)); + } + + /* ============================================================================ */ + /* 默认值函数。 */ + /* */ + /* 当数组为null或empty时,将数组转换成指定的默认数组。 */ + /* ============================================================================ */ + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new String[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new String[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static Object[] defaultIfNull(Object[] array) { + return (array == null) ? EMPTY_OBJECT_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new long[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new long[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static long[] defaultIfNull(long[] array) { + return (array == null) ? EMPTY_LONG_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new int[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new int[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static int[] defaultIfNull(int[] array) { + return (array == null) ? EMPTY_INT_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new short[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new short[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static short[] defaultIfNull(short[] array) { + return (array == null) ? EMPTY_SHORT_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new byte[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new byte[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static byte[] defaultIfNull(byte[] array) { + return (array == null) ? EMPTY_BYTE_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new double[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new double[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static double[] defaultIfNull(double[] array) { + return (array == null) ? EMPTY_DOUBLE_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new float[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new float[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static float[] defaultIfNull(float[] array) { + return (array == null) ? EMPTY_FLOAT_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new boolean[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new boolean[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static boolean[] defaultIfNull(boolean[] array) { + return (array == null) ? EMPTY_BOOLEAN_ARRAY : array; + } + + /** + * 如果数组是null,则返回空数组[],否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null)           = []
+     * ArrayUtil.defaultIfNull(new char[0])  = 数组本身
+     * ArrayUtil.defaultIfNull(new char[10]) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static char[] defaultIfNull(char[] array) { + return (array == null) ? EMPTY_CHAR_ARRAY : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfNull(new String[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new String[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static Object[] defaultIfNull(Object[] array, Object[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)         = defaultArray
+     * ArrayUtil.defaultIfNull(new long[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new long[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static long[] defaultIfNull(long[] array, long[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)        = defaultArray
+     * ArrayUtil.defaultIfNull(new int[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new int[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static int[] defaultIfNull(int[] array, int[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)          = defaultArray
+     * ArrayUtil.defaultIfNull(new short[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new short[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static short[] defaultIfNull(short[] array, short[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)         = defaultArray
+     * ArrayUtil.defaultIfNull(new byte[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new byte[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static byte[] defaultIfNull(byte[] array, byte[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)         = defaultArray
+     * ArrayUtil.defaultIfNull(new double[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new double[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static double[] defaultIfNull(double[] array, double[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)          = defaultArray
+     * ArrayUtil.defaultIfNull(new float[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new float[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static float[] defaultIfNull(float[] array, float[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)            = defaultArray
+     * ArrayUtil.defaultIfNull(new boolean[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new boolean[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static boolean[] defaultIfNull(boolean[] array, boolean[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, defaultArray)         = defaultArray
+     * ArrayUtil.defaultIfNull(new char[0], defaultArray)  = 数组本身
+     * ArrayUtil.defaultIfNull(new char[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static char[] defaultIfNull(char[] array, char[] defaultArray) { + return (array == null) ? defaultArray : array; + } + + /** + * 如果数组是null,则返回指定元素类型的空数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, String.class)           = new String[0]
+     * ArrayUtil.defaultIfNull(new String[0], String.class)  = 数组本身
+     * ArrayUtil.defaultIfNull(new String[10], String.class) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultComponentType 默认数组的元素类型 + * + * @return 数组本身或指定类型的空数组 + */ + public static Object[] defaultIfNull(Object[] array, Class defaultComponentType) { + return (array == null) ? (Object[]) Array.newInstance( + ClassUtil.getNonPrimitiveType(defaultComponentType), 0) : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)           = []
+     * ArrayUtil.defaultIfEmpty(new String[0])  = 数组本身
+     * ArrayUtil.defaultIfEmpty(new String[10]) = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static Object[] defaultIfEmpty(Object[] array) { + return (array == null) ? EMPTY_OBJECT_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)           = []
+     * ArrayUtil.defaultIfEmpty(new long[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new long[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static long[] defaultIfEmpty(long[] array) { + return (array == null) ? EMPTY_LONG_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)          = []
+     * ArrayUtil.defaultIfEmpty(new int[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new int[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static int[] defaultIfEmpty(int[] array) { + return (array == null) ? EMPTY_INT_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)               = []
+     * ArrayUtil.defaultIfEmpty(new short[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new short[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static short[] defaultIfEmpty(short[] array) { + return (array == null) ? EMPTY_SHORT_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)           = []
+     * ArrayUtil.defaultIfEmpty(new byte[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new byte[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static byte[] defaultIfEmpty(byte[] array) { + return (array == null) ? EMPTY_BYTE_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)               = []
+     * ArrayUtil.defaultIfEmpty(new double[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new double[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static double[] defaultIfEmpty(double[] array) { + return (array == null) ? EMPTY_DOUBLE_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)               = []
+     * ArrayUtil.defaultIfEmpty(new float[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new float[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static float[] defaultIfEmpty(float[] array) { + return (array == null) ? EMPTY_FLOAT_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)               = []
+     * ArrayUtil.defaultIfEmpty(new boolean[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new boolean[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static boolean[] defaultIfEmpty(boolean[] array) { + return (array == null) ? EMPTY_BOOLEAN_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回空数组[],否则返回数组本身。 + * + *

+ * 此方法实际上和defaultIfNull(Object[])等效。 + *

+     * ArrayUtil.defaultIfEmpty(null)           = []
+     * ArrayUtil.defaultIfEmpty(new char[0])    = 数组本身
+     * ArrayUtil.defaultIfEmpty(new char[10])   = 数组本身
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 数组本身或空数组[] + */ + public static char[] defaultIfEmpty(char[] array) { + return (array == null) ? EMPTY_CHAR_ARRAY : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new String[0], defaultArray)  = defaultArray
+     * ArrayUtil.defaultIfEmpty(new String[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static Object[] defaultIfEmpty(Object[] array, Object[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new long[0], defaultArray)    = defaultArray
+     * ArrayUtil.defaultIfEmpty(new long[10], defaultArray)   = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static long[] defaultIfEmpty(long[] array, long[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new int[0], defaultArray)     = defaultArray
+     * ArrayUtil.defaultIfEmpty(new int[10], defaultArray)    = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static int[] defaultIfEmpty(int[] array, int[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new short[0], defaultArray)   = defaultArray
+     * ArrayUtil.defaultIfEmpty(new short[10], defaultArray)  = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static short[] defaultIfEmpty(short[] array, short[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new byte[0], defaultArray)    = defaultArray
+     * ArrayUtil.defaultIfEmpty(new byte[10], defaultArray)   = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static byte[] defaultIfEmpty(byte[] array, byte[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new double[0], defaultArray)  = defaultArray
+     * ArrayUtil.defaultIfEmpty(new double[10], defaultArray) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static double[] defaultIfEmpty(double[] array, double[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new float[0], defaultArray)   = defaultArray
+     * ArrayUtil.defaultIfEmpty(new float[10], defaultArray)  = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static float[] defaultIfEmpty(float[] array, float[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)              = defaultArray
+     * ArrayUtil.defaultIfEmpty(new boolean[0], defaultArray)    = defaultArray
+     * ArrayUtil.defaultIfEmpty(new boolean[10], defaultArray)   = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static boolean[] defaultIfEmpty(boolean[] array, boolean[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定默认数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
+     * ArrayUtil.defaultIfEmpty(new char[0], defaultArray)    = defaultArray
+     * ArrayUtil.defaultIfEmpty(new char[10], defaultArray)   = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultArray 默认数组 + * + * @return 数组本身或指定的默认数组 + */ + public static char[] defaultIfEmpty(char[] array, char[] defaultArray) { + return ((array == null) || (array.length == 0)) ? defaultArray : array; + } + + /** + * 如果数组是null或空数组[],则返回指定元素类型的空数组,否则返回数组本身。 + *
+     * ArrayUtil.defaultIfNull(null, String.class)           = new String[0]
+     * ArrayUtil.defaultIfNull(new String[0], String.class)  = new String[0]
+     * ArrayUtil.defaultIfNull(new String[10], String.class) = 数组本身
+     * 
+ * + * @param array 要转换的数组 + * @param defaultComponentType 默认数组的元素类型 + * + * @return 数组本身或指定类型的空数组 + */ + public static Object[] defaultIfEmpty(Object[] array, Class defaultComponentType) { + return ((array == null) || (array.length == 0)) ? (Object[]) Array.newInstance( + ClassUtil.getNonPrimitiveType(defaultComponentType), 0) : array; + } + + /* ============================================================================ */ + /* 比较函数。 */ + /* */ + /* 以下方法用来比较两个数组是否完全相同,支持多维数组。 */ + /* ============================================================================ */ + + /** + * 递归地比较两个数组是否相同,支持多维数组。 + * + *

+ * 如果比较的对象不是数组,则此方法的结果同ObjectUtil.equals。 + *

+ * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果相等, 则返回true + */ + public static boolean equals(Object array1, Object array2) { + if (array1 == array2) { + return true; + } + + if ((array1 == null) || (array2 == null)) { + return false; + } + + Class clazz = array1.getClass(); + + if (!clazz.equals(array2.getClass())) { + return false; + } + + if (!clazz.isArray()) { + return array1.equals(array2); + } + + // array1和array2为同类型的数组 + if (array1 instanceof long[]) { + long[] longArray1 = (long[]) array1; + long[] longArray2 = (long[]) array2; + + if (longArray1.length != longArray2.length) { + return false; + } + + for (int i = 0; i < longArray1.length; i++) { + if (longArray1[i] != longArray2[i]) { + return false; + } + } + + return true; + } else if (array1 instanceof int[]) { + int[] intArray1 = (int[]) array1; + int[] intArray2 = (int[]) array2; + + if (intArray1.length != intArray2.length) { + return false; + } + + for (int i = 0; i < intArray1.length; i++) { + if (intArray1[i] != intArray2[i]) { + return false; + } + } + + return true; + } else if (array1 instanceof short[]) { + short[] shortArray1 = (short[]) array1; + short[] shortArray2 = (short[]) array2; + + if (shortArray1.length != shortArray2.length) { + return false; + } + + for (int i = 0; i < shortArray1.length; i++) { + if (shortArray1[i] != shortArray2[i]) { + return false; + } + } + + return true; + } else if (array1 instanceof byte[]) { + byte[] byteArray1 = (byte[]) array1; + byte[] byteArray2 = (byte[]) array2; + + if (byteArray1.length != byteArray2.length) { + return false; + } + + for (int i = 0; i < byteArray1.length; i++) { + if (byteArray1[i] != byteArray2[i]) { + return false; + } + } + + return true; + } else if (array1 instanceof double[]) { + double[] doubleArray1 = (double[]) array1; + double[] doubleArray2 = (double[]) array2; + + if (doubleArray1.length != doubleArray2.length) { + return false; + } + + for (int i = 0; i < doubleArray1.length; i++) { + if (Double.doubleToLongBits(doubleArray1[i]) != Double + .doubleToLongBits(doubleArray2[i])) { + return false; + } + } + + return true; + } else if (array1 instanceof float[]) { + float[] floatArray1 = (float[]) array1; + float[] floatArray2 = (float[]) array2; + + if (floatArray1.length != floatArray2.length) { + return false; + } + + for (int i = 0; i < floatArray1.length; i++) { + if (Float.floatToIntBits(floatArray1[i]) != Float.floatToIntBits(floatArray2[i])) { + return false; + } + } + + return true; + } else if (array1 instanceof boolean[]) { + boolean[] booleanArray1 = (boolean[]) array1; + boolean[] booleanArray2 = (boolean[]) array2; + + if (booleanArray1.length != booleanArray2.length) { + return false; + } + + for (int i = 0; i < booleanArray1.length; i++) { + if (booleanArray1[i] != booleanArray2[i]) { + return false; + } + } + + return true; + } else if (array1 instanceof char[]) { + char[] charArray1 = (char[]) array1; + char[] charArray2 = (char[]) array2; + + if (charArray1.length != charArray2.length) { + return false; + } + + for (int i = 0; i < charArray1.length; i++) { + if (charArray1[i] != charArray2[i]) { + return false; + } + } + + return true; + } else { + Object[] objectArray1 = (Object[]) array1; + Object[] objectArray2 = (Object[]) array2; + + if (objectArray1.length != objectArray2.length) { + return false; + } + + for (int i = 0; i < objectArray1.length; i++) { + if (!equals(objectArray1[i], objectArray2[i])) { + return false; + } + } + + return true; + } + } + + /* ============================================================================ */ + /* Hashcode函数。 */ + /* */ + /* 以下方法用来取得数组的hash code。 */ + /* ============================================================================ */ + + /** + * 取得数组的hash值, 如果数组为null, 则返回0。 + * + *

+ * 如果对象不是数组,则此方法的结果同ObjectUtil.hashCode。 + *

+ * + * @param array 数组 + * + * @return hash值 + */ + public static int hashCode(Object array) { + if (array == null) { + return 0; + } + + if (!array.getClass().isArray()) { + return array.hashCode(); + } + + int hashCode = INITIAL_NON_ZERO_ODD_NUMBER; + + // array是数组 + if (array instanceof long[]) { + long[] longArray = (long[]) array; + + for (int i = 0; i < longArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + + ((int) (longArray[i] ^ (longArray[i] >> 32))); + } + } else if (array instanceof int[]) { + int[] intArray = (int[]) array; + + for (int i = 0; i < intArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + intArray[i]; + } + } else if (array instanceof short[]) { + short[] shortArray = (short[]) array; + + for (int i = 0; i < shortArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + shortArray[i]; + } + } else if (array instanceof byte[]) { + byte[] byteArray = (byte[]) array; + + for (int i = 0; i < byteArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + byteArray[i]; + } + } else if (array instanceof double[]) { + double[] doubleArray = (double[]) array; + + for (int i = 0; i < doubleArray.length; i++) { + long longBits = Double.doubleToLongBits(doubleArray[i]); + + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + + ((int) (longBits ^ (longBits >> 32))); + } + } else if (array instanceof float[]) { + float[] floatArray = (float[]) array; + + for (int i = 0; i < floatArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + + Float.floatToIntBits(floatArray[i]); + } + } else if (array instanceof boolean[]) { + boolean[] booleanArray = (boolean[]) array; + + for (int i = 0; i < booleanArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + (booleanArray[i] ? 1 : 0); + } + } else if (array instanceof char[]) { + char[] charArray = (char[]) array; + + for (int i = 0; i < charArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + charArray[i]; + } + } else { + Object[] objectArray = (Object[]) array; + + for (int i = 0; i < objectArray.length; i++) { + hashCode = (hashCode * MULTIPLIER_NON_ZERO_ODD_NUMBER) + hashCode(objectArray[i]); + } + } + + return hashCode; + } + + /* ============================================================================ */ + /* 将数组转换成集合类。 */ + /* ============================================================================ */ + + /** + * 将数组映射成固定长度的List,当改变这个List中的值时。数组中的相应值也被改变。 + * + *

+ * 如果输入数组为null,则返回null。 + *

+ * + *

+ * 该方法内部调用java.util.Arrays.asList方法所返回的列表为指定数组的映像(固定长度),因此性能和内存占用上比toList方法更优。 + *

+ * + *

+ * 这个方法常被用于初始化,例如: + *

+     * List myList = ArrayUtil.toFixedList(new String[] { "aaa", "bbb", "ccc" });
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 以数组本身为映射的list + */ + public static List toFixedList(Object[] array) { + if (array == null) { + return null; + } + + return Arrays.asList(array); + } + + /** + * 将数组转换成List。 + * + *

+ * 如果输入数组为null,则返回null。 + *

+ * + *

+ * 该方法返回的列表为指定数组的复本,而java.util.Arrays.asList方法所返回的列表为指定数组的映像(固定长度)。 + *

+ * + *

+ * 这个方法常被用于初始化,例如: + *

+     * List myList      = ArrayUtil.toList(new String[] { "aaa", "bbb", "ccc" });
+     * List singleList  = ArrayUtil.toList("hello");     // 返回单个元素的列表["hello"]
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 被创建的list + */ + public static List toList(Object array) { + return toList(array, null); + } + + /** + * 将数组转换成List。 + * + *

+ * 如果输入数组为null,则返回null。 + *

+ * + *

+ * 该方法返回的列表为指定数组的复本,而java.util.Arrays.asList方法所返回的列表为指定数组的映像(固定长度)。 + *

+ * + *

+ * 这个方法常被用于初始化,例如: + *

+     * List myList      = ArrayUtil.toList(new String[] { "aaa", "bbb", "ccc" }, new ArrayList());
+     * List singleList  = ArrayUtil.toList("hello", new ArrayList());     // 返回单个元素的列表["hello"]
+     * 
+ *

+ * + * @param array 要转换的数组 + * @param list 要填充的列表,如果是null,则创建之 + * + * @return 被创建或填充的list + */ + public static List toList(Object array, List list) { + if (array == null) { + return list; + } + + // 非array,创建一个只有一个元素的列表 + if (!array.getClass().isArray()) { + if (list == null) { + list = new ArrayList(1); + } + + list.add(array); + } else if (array instanceof long[]) { + long[] longArray = (long[]) array; + + if (list == null) { + list = new ArrayList(longArray.length); + } + + for (int i = 0; i < longArray.length; i++) { + list.add(new Long(longArray[i])); + } + } else if (array instanceof int[]) { + int[] intArray = (int[]) array; + + if (list == null) { + list = new ArrayList(intArray.length); + } + + for (int i = 0; i < intArray.length; i++) { + list.add(new Integer(intArray[i])); + } + } else if (array instanceof short[]) { + short[] shortArray = (short[]) array; + + if (list == null) { + list = new ArrayList(shortArray.length); + } + + for (int i = 0; i < shortArray.length; i++) { + list.add(new Short(shortArray[i])); + } + } else if (array instanceof byte[]) { + byte[] byteArray = (byte[]) array; + + if (list == null) { + list = new ArrayList(byteArray.length); + } + + for (int i = 0; i < byteArray.length; i++) { + list.add(new Byte(byteArray[i])); + } + } else if (array instanceof double[]) { + double[] doubleArray = (double[]) array; + + if (list == null) { + list = new ArrayList(doubleArray.length); + } + + for (int i = 0; i < doubleArray.length; i++) { + list.add(new Double(doubleArray[i])); + } + } else if (array instanceof float[]) { + float[] floatArray = (float[]) array; + + if (list == null) { + list = new ArrayList(floatArray.length); + } + + for (int i = 0; i < floatArray.length; i++) { + list.add(new Float(floatArray[i])); + } + } else if (array instanceof boolean[]) { + boolean[] booleanArray = (boolean[]) array; + + if (list == null) { + list = new ArrayList(booleanArray.length); + } + + for (int i = 0; i < booleanArray.length; i++) { + list.add(booleanArray[i] ? Boolean.TRUE : Boolean.FALSE); + } + } else if (array instanceof char[]) { + char[] charArray = (char[]) array; + + if (list == null) { + list = new ArrayList(charArray.length); + } + + for (int i = 0; i < charArray.length; i++) { + list.add(new Character(charArray[i])); + } + } else { + Object[] objectArray = (Object[]) array; + + if (list == null) { + list = new ArrayList(objectArray.length); + } + + for (int i = 0; i < objectArray.length; i++) { + list.add(objectArray[i]); + } + } + + return list; + } + + /** + * 将数组转换成Map。数组的元素必须是Map.Entry或元素个数多于2的子数组。 + * + *

+ * 如果输入数组为null,则返回null。 + *

+ * + *

+ * 这个方法常被用于初始化,例如: + *

+     * Map colorMap = ArrayUtil.toMap(new String[][] {
+     *     {"RED", "#FF0000"},
+     *     {"GREEN", "#00FF00"},
+     *     {"BLUE", "#0000FF"}});
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 被创建的map + * + * @throws IllegalArgumentException 如果有一个子数组元素个数小于2或不是Map.Entry实例 + */ + public static Map toMap(Object[] array) { + return toMap(array, null); + } + + /** + * 将数组转换成Map。数组的元素必须是Map.Entry或元素个数多于2的子数组。 + * + *

+ * 如果输入数组为null,则返回null。 + *

+ * + *

+ * 这个方法常被用于初始化,例如: + *

+     * Map colorMap = ArrayUtil.toMap(new String[][] {{
+     *     {"RED", "#FF0000"},
+     *     {"GREEN", "#00FF00"},
+     *     {"BLUE", "#0000FF"}}, new HashMap());
+     * 
+ *

+ * + * @param array 要转换的数组 + * @param map 要填充的map,如果为null则自动创建之 + * + * @return 被创建或填充的map + * + * @throws IllegalArgumentException 如果有一个子数组元素个数小于2或不是Map.Entry实例 + */ + public static Map toMap(Object[] array, Map map) { + if (array == null) { + return map; + } + + if (map == null) { + map = new HashMap((int) (array.length * 1.5)); + } + + for (int i = 0; i < array.length; i++) { + Object object = array[i]; + + if (object instanceof Map.Entry) { + Map.Entry entry = (Map.Entry) object; + + map.put(entry.getKey(), entry.getValue()); + } else if (object instanceof Object[]) { + Object[] entry = (Object[]) object; + + if (entry.length < 2) { + throw new IllegalArgumentException("Array element " + i + ", '" + object + + "', has a length less than 2"); + } + + map.put(entry[0], entry[1]); + } else { + throw new IllegalArgumentException("Array element " + i + ", '" + object + + "', is neither of type Map.Entry nor an Array"); + } + } + + return map; + } + + /* ============================================================================ */ + /* Clone函数。 */ + /* */ + /* 以下方法调用Object.clone方法,进行“浅复制”(shallow copy)。 */ + /* ============================================================================ */ + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法只进行“浅复制”,也就是说,数组中的对象本身不会被复制。 另外,此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static Object[] clone(Object[] array) { + if (array == null) { + return null; + } + + return (Object[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static long[] clone(long[] array) { + if (array == null) { + return null; + } + + return (long[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static int[] clone(int[] array) { + if (array == null) { + return null; + } + + return (int[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static short[] clone(short[] array) { + if (array == null) { + return null; + } + + return (short[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static byte[] clone(byte[] array) { + if (array == null) { + return null; + } + + return (byte[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static double[] clone(double[] array) { + if (array == null) { + return null; + } + + return (double[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static float[] clone(float[] array) { + if (array == null) { + return null; + } + + return (float[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static boolean[] clone(boolean[] array) { + if (array == null) { + return null; + } + + return (boolean[]) array.clone(); + } + + /** + * 复制一个数组。如果数组为null,则返回null。 + * + *

+ * 此方法也不处理多维数组。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static char[] clone(char[] array) { + if (array == null) { + return null; + } + + return (char[]) array.clone(); + } + + /* ============================================================================ */ + /* 比较数组的长度。 */ + /* ============================================================================ */ + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(Object[] array1, Object[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(long[] array1, long[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(int[] array1, int[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(short[] array1, short[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(byte[] array1, byte[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(double[] array1, double[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(float[] array1, float[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(boolean[] array1, boolean[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /** + * 判断两个数组是否具有相同的长度。如果数组为null则被看作长度为0。 + * + * @param array1 数组1 + * @param array2 数组2 + * + * @return 如果两个数组长度相同,则返回true + */ + public static boolean isSameLength(char[] array1, char[] array2) { + int length1 = (array1 == null) ? 0 : array1.length; + int length2 = (array2 == null) ? 0 : array2.length; + + return length1 == length2; + } + + /* ============================================================================ */ + /* 反转数组的元素顺序。 */ + /* ============================================================================ */ + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(Object[] array) { + if (array == null) { + return; + } + + Object tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(long[] array) { + if (array == null) { + return; + } + + long tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(int[] array) { + if (array == null) { + return; + } + + int tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(short[] array) { + if (array == null) { + return; + } + + short tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(byte[] array) { + if (array == null) { + return; + } + + byte tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(double[] array) { + if (array == null) { + return; + } + + double tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(float[] array) { + if (array == null) { + return; + } + + float tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(boolean[] array) { + if (array == null) { + return; + } + + boolean tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /** + * 反转数组的元素顺序。如果数组为null,则什么也不做。 + * + * @param array 要反转的数组 + */ + public static void reverse(char[] array) { + if (array == null) { + return; + } + + char tmp; + + for (int i = 0, j = array.length - 1; j > i; i++, j--) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:Object[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param objectToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(Object[] array, Object objectToFind) { + return indexOf(array, objectToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(Object[] array, Object[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param objectToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(Object[] array, Object objectToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (objectToFind == null) { + for (int i = startIndex; i < array.length; i++) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i < array.length; i++) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(Object[] array, Object[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + Object first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && !ObjectUtil.equals(array[i], first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (!ObjectUtil.equals(array[j++], arrayToFind[k++])) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param objectToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(Object[] array, Object objectToFind) { + return lastIndexOf(array, objectToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(Object[] array, Object[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param objectToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + if (objectToFind == null) { + for (int i = startIndex; i >= 0; i--) { + if (array[i] == null) { + return i; + } + } + } else { + for (int i = startIndex; i >= 0; i--) { + if (objectToFind.equals(array[i])) { + return i; + } + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(Object[] array, Object[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + Object last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && !ObjectUtil.equals(array[i], last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (!ObjectUtil.equals(array[j--], arrayToFind[k--])) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param objectToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(Object[] array, Object objectToFind) { + return indexOf(array, objectToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(Object[] array, Object[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:long[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param longToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(long[] array, long longToFind) { + return indexOf(array, longToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(long[] array, long[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param longToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(long[] array, long longToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (longToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(long[] array, long[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + long first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param longToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(long[] array, long longToFind) { + return lastIndexOf(array, longToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(long[] array, long[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param longToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(long[] array, long longToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (longToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(long[] array, long[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + long last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param longToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(long[] array, long longToFind) { + return indexOf(array, longToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(long[] array, long[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:int[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param intToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(int[] array, int intToFind) { + return indexOf(array, intToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(int[] array, int[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param intToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(int[] array, int intToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (intToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(int[] array, int[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + int first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param intToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(int[] array, int intToFind) { + return lastIndexOf(array, intToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(int[] array, int[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param intToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(int[] array, int intToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (intToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(int[] array, int[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + int last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param intToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(int[] array, int intToFind) { + return indexOf(array, intToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(int[] array, int[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:short[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param shortToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(short[] array, short shortToFind) { + return indexOf(array, shortToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(short[] array, short[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param shortToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(short[] array, short shortToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (shortToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(short[] array, short[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + short first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param shortToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(short[] array, short shortToFind) { + return lastIndexOf(array, shortToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(short[] array, short[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param shortToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(short[] array, short shortToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (shortToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(short[] array, short[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + short last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param shortToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(short[] array, short shortToFind) { + return indexOf(array, shortToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(short[] array, short[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:byte[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param byteToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(byte[] array, byte byteToFind) { + return indexOf(array, byteToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(byte[] array, byte[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param byteToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(byte[] array, byte byteToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (byteToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(byte[] array, byte[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + byte first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param byteToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(byte[] array, byte byteToFind) { + return lastIndexOf(array, byteToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(byte[] array, byte[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param byteToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(byte[] array, byte byteToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (byteToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(byte[] array, byte[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + byte last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param byteToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(byte[] array, byte byteToFind) { + return indexOf(array, byteToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(byte[] array, byte[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:double[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double doubleToFind) { + return indexOf(array, doubleToFind, 0, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double doubleToFind, double tolerance) { + return indexOf(array, doubleToFind, 0, tolerance); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double[] arrayToFind) { + return indexOf(array, arrayToFind, 0, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double[] arrayToFind, double tolerance) { + return indexOf(array, arrayToFind, 0, tolerance); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double doubleToFind, int startIndex) { + return indexOf(array, doubleToFind, startIndex, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double doubleToFind, int startIndex, double tolerance) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + double min = doubleToFind - tolerance; + double max = doubleToFind + tolerance; + + for (int i = startIndex; i < array.length; i++) { + if ((array[i] >= min) && (array[i] <= max)) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double[] arrayToFind, int startIndex) { + return indexOf(array, arrayToFind, startIndex, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(double[] array, double[] arrayToFind, int startIndex, double tolerance) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + double firstMin = arrayToFind[0] - tolerance; + double firstMax = arrayToFind[0] + tolerance; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && ((array[i] < firstMin) || (array[i] > firstMax))) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double doubleToFind) { + return lastIndexOf(array, doubleToFind, Integer.MAX_VALUE, 0); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double doubleToFind, double tolerance) { + return lastIndexOf(array, doubleToFind, Integer.MAX_VALUE, tolerance); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double[] arrayToFind, double tolerance) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double doubleToFind, int startIndex) { + return lastIndexOf(array, doubleToFind, startIndex, 0); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double doubleToFind, int startIndex, + double tolerance) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + double min = doubleToFind - tolerance; + double max = doubleToFind + tolerance; + + for (int i = startIndex; i >= 0; i--) { + if ((array[i] >= min) && (array[i] <= max)) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double[] arrayToFind, int startIndex) { + return lastIndexOf(array, arrayToFind, startIndex, 0); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(double[] array, double[] arrayToFind, int startIndex, + double tolerance) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + double lastMin = arrayToFind[lastIndex] - tolerance; + double lastMax = arrayToFind[lastIndex] + tolerance; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && ((array[i] < lastMin) || (array[i] > lastMax))) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(double[] array, double doubleToFind) { + return indexOf(array, doubleToFind) != -1; + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param doubleToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 如果找到则返回true + */ + public static boolean contains(double[] array, double doubleToFind, double tolerance) { + return indexOf(array, doubleToFind, tolerance) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(double[] array, double[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 如果找到则返回true + */ + public static boolean contains(double[] array, double[] arrayToFind, double tolerance) { + return indexOf(array, arrayToFind, tolerance) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:float[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float floatToFind) { + return indexOf(array, floatToFind, 0, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float floatToFind, float tolerance) { + return indexOf(array, floatToFind, 0, tolerance); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float[] arrayToFind) { + return indexOf(array, arrayToFind, 0, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float[] arrayToFind, float tolerance) { + return indexOf(array, arrayToFind, 0, tolerance); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float floatToFind, int startIndex) { + return indexOf(array, floatToFind, startIndex, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float floatToFind, int startIndex, float tolerance) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + float min = floatToFind - tolerance; + float max = floatToFind + tolerance; + + for (int i = startIndex; i < array.length; i++) { + if ((array[i] >= min) && (array[i] <= max)) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float[] arrayToFind, int startIndex) { + return indexOf(array, arrayToFind, startIndex, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(float[] array, float[] arrayToFind, int startIndex, float tolerance) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + float firstMin = arrayToFind[0] - tolerance; + float firstMax = arrayToFind[0] + tolerance; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && ((array[i] < firstMin) || (array[i] > firstMax))) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float floatToFind) { + return lastIndexOf(array, floatToFind, Integer.MAX_VALUE, 0); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float floatToFind, float tolerance) { + return lastIndexOf(array, floatToFind, Integer.MAX_VALUE, tolerance); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float[] arrayToFind, float tolerance) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float floatToFind, int startIndex) { + return lastIndexOf(array, floatToFind, startIndex, 0); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float floatToFind, int startIndex, float tolerance) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + float min = floatToFind - tolerance; + float max = floatToFind + tolerance; + + for (int i = startIndex; i >= 0; i--) { + if ((array[i] >= min) && (array[i] <= max)) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float[] arrayToFind, int startIndex) { + return lastIndexOf(array, arrayToFind, startIndex, 0); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * @param tolerance 误差 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(float[] array, float[] arrayToFind, int startIndex, + float tolerance) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + float lastMin = arrayToFind[lastIndex] - tolerance; + float lastMax = arrayToFind[lastIndex] + tolerance; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && ((array[i] < lastMin) || (array[i] > lastMax))) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(float[] array, float floatToFind) { + return indexOf(array, floatToFind) != -1; + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param floatToFind 要查找的元素 + * @param tolerance 误差 + * + * @return 如果找到则返回true + */ + public static boolean contains(float[] array, float floatToFind, float tolerance) { + return indexOf(array, floatToFind, tolerance) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(float[] array, float[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param tolerance 误差 + * + * @return 如果找到则返回true + */ + public static boolean contains(float[] array, float[] arrayToFind, float tolerance) { + return indexOf(array, arrayToFind, tolerance) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:boolean[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param booleanToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(boolean[] array, boolean booleanToFind) { + return indexOf(array, booleanToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(boolean[] array, boolean[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param booleanToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(boolean[] array, boolean booleanToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (booleanToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(boolean[] array, boolean[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + boolean first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param booleanToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(boolean[] array, boolean booleanToFind) { + return lastIndexOf(array, booleanToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(boolean[] array, boolean[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param booleanToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(boolean[] array, boolean booleanToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (booleanToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(boolean[] array, boolean[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + boolean last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param booleanToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(boolean[] array, boolean booleanToFind) { + return indexOf(array, booleanToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(boolean[] array, boolean[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 在数组中查找一个元素或一个元素序列。 */ + /* */ + /* 类型:char[] */ + /* ============================================================================ */ + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param charToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(char[] array, char charToFind) { + return indexOf(array, charToFind, 0); + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(char[] array, char[] arrayToFind) { + return indexOf(array, arrayToFind, 0); + } + + /** + * 在数组中查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param charToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(char[] array, char charToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + startIndex = 0; + } + + for (int i = startIndex; i < array.length; i++) { + if (charToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则看作0,超出数组长度的起始索引则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int indexOf(char[] array, char[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + if (startIndex >= sourceLength) { + return (targetLength == 0) ? sourceLength : (-1); + } + + if (startIndex < 0) { + startIndex = 0; + } + + if (targetLength == 0) { + return startIndex; + } + + char first = arrayToFind[0]; + int i = startIndex; + int max = sourceLength - targetLength; + + startSearchForFirst: while (true) { + // 查找第一个元素 + while ((i <= max) && (array[i] != first)) { + i++; + } + + if (i > max) { + return -1; + } + + // 已经找到第一个元素,接着找 + int j = i + 1; + int end = (j + targetLength) - 1; + int k = 1; + + while (j < end) { + if (array[j++] != arrayToFind[k++]) { + i++; + + // 重新查找第一个元素 + continue startSearchForFirst; + } + } + + // 找到了 + return i; + } + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param charToFind 要查找的元素 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(char[] array, char charToFind) { + return lastIndexOf(array, charToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(char[] array, char[] arrayToFind) { + return lastIndexOf(array, arrayToFind, Integer.MAX_VALUE); + } + + /** + * 在数组中从末尾开始查找一个元素。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param charToFind 要查找的元素 + * @param startIndex 起始索引 + * + * @return 该元素在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(char[] array, char charToFind, int startIndex) { + if (array == null) { + return -1; + } + + if (startIndex < 0) { + return -1; + } else if (startIndex >= array.length) { + startIndex = array.length - 1; + } + + for (int i = startIndex; i >= 0; i--) { + if (charToFind == array[i]) { + return i; + } + } + + return -1; + } + + /** + * 在数组中从末尾开始查找一个元素序列。 + * + *

+ * 如果未找到或数组为null则返回-1。 + *

+ * + *

+ * 起始索引小于0则返回-1,超出数组长度的起始索引则从数组末尾开始找。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * @param startIndex 起始索引 + * + * @return 该元素序列在数组中的序号,如果数组为null或未找到,则返回-1。 + */ + public static int lastIndexOf(char[] array, char[] arrayToFind, int startIndex) { + if ((array == null) || (arrayToFind == null)) { + return -1; + } + + int sourceLength = array.length; + int targetLength = arrayToFind.length; + + int rightIndex = sourceLength - targetLength; + + if (startIndex < 0) { + return -1; + } + + if (startIndex > rightIndex) { + startIndex = rightIndex; + } + + if (targetLength == 0) { + return startIndex; + } + + int lastIndex = targetLength - 1; + char last = arrayToFind[lastIndex]; + int min = targetLength - 1; + int i = min + startIndex; + + startSearchForLast: while (true) { + while ((i >= min) && (array[i] != last)) { + i--; + } + + if (i < min) { + return -1; + } + + int j = i - 1; + int start = j - (targetLength - 1); + int k = lastIndex - 1; + + while (j > start) { + if (array[j--] != arrayToFind[k--]) { + i--; + continue startSearchForLast; + } + } + + return start + 1; + } + } + + /** + * 判断指定对象是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param charToFind 要查找的元素 + * + * @return 如果找到则返回true + */ + public static boolean contains(char[] array, char charToFind) { + return indexOf(array, charToFind) != -1; + } + + /** + * 判断指定元素序列是否存在于指定数组中。 + * + *

+ * 如果数组为null则返回false。 + *

+ * + * @param array 要扫描的数组 + * @param arrayToFind 要查找的元素序列 + * + * @return 如果找到则返回true + */ + public static boolean contains(char[] array, char[] arrayToFind) { + return indexOf(array, arrayToFind) != -1; + } + + /* ============================================================================ */ + /* 将数组转换成易于阅读的字符串表示。 */ + /* */ + /* 支持多维数组。 */ + /* ============================================================================ */ + + /** + * 将数组转换成易于阅读的字符串表示。 + * + *

+ * 如果数组是null则返回[],支持多维数组。 + * 如果数组元素为null,则显示<null>。 + *

+     * ArrayUtil.toString(null)                              = "[]"
+     * ArrayUtil.toString(new int[] {1, 2, 3})               = "[1, 2, 3]"
+     * ArrayUtil.toString(new boolean[] {true, false, true}) = "[true, false, true]"
+     * ArrayUtil.toString(new Object[] {
+     *                       {1, 2, 3},  // 嵌套数组
+     *                       hello,      // 嵌套非数组
+     *                       null,       // 嵌套null
+     *                       {},         // 嵌套空数组
+     *                       {2, 3, 4}   // 嵌套数组
+     *                    })                                 = "[[1, 2, 3], hello, , [], [2, 3, 4]]"
+     * 
+ *

+ * + * @param array 要转换的数组 + * + * @return 字符串表示,"[]"表示空数组或null + */ + public static String toString(Object array) { + return toString(array, "[]", ""); + } + + /** + * 将数组转换成易于阅读的字符串表示。 + * + *

+ * 如果数组是null则返回指定字符串,支持多维数组。 + * 如果数组元素为null,则显示<null>。 + *

+     * ArrayUtil.toString(null, "null")                              = "null"
+     * ArrayUtil.toString(new int[] {1, 2, 3}, "null")               = "[1, 2, 3]"
+     * ArrayUtil.toString(new boolean[] {true, false, true}, "null") = "[true, false, true]"
+     * ArrayUtil.toString(new Object[] {
+     *                       {1, 2, 3},  // 嵌套数组
+     *                       hello,      // 嵌套非数组
+     *                       null,       // 嵌套null
+     *                       {},         // 嵌套空数组
+     *                       {2, 3, 4}   // 嵌套数组
+     *                    }, "null")                                 = "[[1, 2, 3], hello, , [], [2, 3, 4]]"
+     * 
+ *

+ * + * @param array 要转换的数组 + * @param nullArrayStr 如果数组是null,则返回此字符串 + * + * @return 字符串表示,或返回指定字符串表示null + */ + public static String toString(Object array, String nullArrayStr) { + return toString(array, nullArrayStr, ""); + } + + /** + * 将数组转换成易于阅读的字符串表示。 + * + *

+ * 如果数组是null则返回指定字符串,支持多维数组。 如果数组元素为null,则显示指定字符串。 + *

+     * ArrayUtil.toString(null, "null", "NULL")                              = "null"
+     * ArrayUtil.toString(new int[] {1, 2, 3}, "null", "NULL")               = "[1, 2, 3]"
+     * ArrayUtil.toString(new boolean[] {true, false, true}, "null", "NULL") = "[true, false, true]"
+     * ArrayUtil.toString(new Object[] {
+     *                       {1, 2, 3},  // 嵌套数组
+     *                       hello,      // 嵌套非数组
+     *                       null,       // 嵌套null
+     *                       {},         // 嵌套空数组
+     *                       {2, 3, 4}   // 嵌套数组
+     *                    }, "null", "NULL")                                 = "[[1, 2, 3], hello, NULL, [], [2, 3, 4]]"
+     * 
+ *

+ * + * @param array 要转换的数组 + * @param nullArrayStr 如果数组是null,则返回此字符串 + * @param nullElementStr 如果数组中的元素为null,则返回此字符串 + * + * @return 字符串表示,或返回指定字符串表示null + */ + public static String toString(Object array, String nullArrayStr, String nullElementStr) { + if (array == null) { + return nullArrayStr; + } + + StringBuffer buffer = new StringBuffer(); + + toString(buffer, array, nullArrayStr, nullElementStr); + + return buffer.toString(); + } + + /** + * 将数组转换成易于阅读的字符串表示。null将被看作空数组。 支持多维数组。 + * + * @param buffer 将转换后的字符串加入到这个StringBuffer中 + * @param array 要转换的数组 + * @param nullArrayStr 如果数组是null,则返回此字符串 + * @param nullElementStr 如果数组中的元素为null,则返回此字符串 + */ + private static void toString(StringBuffer buffer, Object array, String nullArrayStr, + String nullElementStr) { + if (array == null) { + buffer.append(nullElementStr); + return; + } + + if (!array.getClass().isArray()) { + buffer.append(ObjectUtil.toString(array, nullElementStr)); + return; + } + + buffer.append('['); + + // array为数组 + if (array instanceof long[]) { + long[] longArray = (long[]) array; + int length = longArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(longArray[i]); + } + } else if (array instanceof int[]) { + int[] intArray = (int[]) array; + int length = intArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(intArray[i]); + } + } else if (array instanceof short[]) { + short[] shortArray = (short[]) array; + int length = shortArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(shortArray[i]); + } + } else if (array instanceof byte[]) { + byte[] byteArray = (byte[]) array; + int length = byteArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } else { + buffer.append("0x"); + } + + String hexStr = Integer.toHexString(0xFF & byteArray[i]).toUpperCase(); + + if (hexStr.length() == 0) { + buffer.append("00"); + } else if (hexStr.length() == 1) { + buffer.append("0"); + } + + buffer.append(hexStr); + } + } else if (array instanceof double[]) { + double[] doubleArray = (double[]) array; + int length = doubleArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(doubleArray[i]); + } + } else if (array instanceof float[]) { + float[] floatArray = (float[]) array; + int length = floatArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(floatArray[i]); + } + } else if (array instanceof boolean[]) { + boolean[] booleanArray = (boolean[]) array; + int length = booleanArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(booleanArray[i]); + } + } else if (array instanceof char[]) { + char[] charArray = (char[]) array; + int length = charArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + buffer.append(charArray[i]); + } + } else { + Object[] objectArray = (Object[]) array; + int length = objectArray.length; + + for (int i = 0; i < length; i++) { + if (i > 0) { + buffer.append(", "); + } + + toString(buffer, objectArray[i], nullArrayStr, nullElementStr); + } + } + + buffer.append(']'); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/Base64Util.java b/fuint-utils/src/main/java/com/fuint/utils/Base64Util.java new file mode 100644 index 0000000..bb2b433 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/Base64Util.java @@ -0,0 +1,175 @@ +package com.fuint.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.UnsupportedEncodingException; + +/** + * 基于Java8的Base64工具类实现,不依赖第三方包 + * [Basic编码:适用于标准编码] + * [URL编码:适用于URL地址编码,自动替换掉URL中不能出现的"/"等字符] + * [MIME编码:适用于MIME编码,使用基本的字母数字产生BASE64输出,每一行输出不超过76个字符,而且每行以“\r\n”符结束] + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Base64Util { + private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); + + private static final String CHARSET = "UTF-8";//默认字符集 + + /** + * 基本Base64编码 + * @param bytes + * @return byte[] + */ + public static byte[] baseEncode(byte[] bytes) { + return java.util.Base64.getEncoder().encode(bytes); + } + + /** + * 基本Base64编码 + * + * @param s + * @return String + */ + public static String baseEncode(String s) { + try { + byte[] bytes = s.getBytes(CHARSET); + return java.util.Base64.getEncoder().encodeToString(bytes); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + /** + * 基本Base64解码 + * + * @param bytes + * @return byte[] + */ + public static byte[] baseDecode(byte[] bytes) { + return java.util.Base64.getDecoder().decode(bytes); + } + + /** + * 基本Base64解码 + * + * @param s + * @return String + */ + public static String baseDecode(String s) { + try { + byte[] result = java.util.Base64.getDecoder().decode(s); + return new String(result, CHARSET); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + /** + * URL编码 + * + * @param bytes + * @return byte[] + */ + public static byte[] urlEncode(byte[] bytes) { + return java.util.Base64.getUrlEncoder().encode(bytes); + } + + /** + * URL编码 + * + * @param s + * @return String + */ + public static String urlEncode(String s) { + try { + byte[] bytes = s.getBytes(CHARSET); + return java.util.Base64.getUrlEncoder().encodeToString(bytes); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + /** + * URL解码 + * + * @param bytes + * @return byte[] + */ + public static byte[] urlDecode(byte[] bytes) { + return java.util.Base64.getUrlDecoder().decode(bytes); + } + + /** + * URL解码 + * + * @param s + * @return String + */ + public static String urlDecode(String s) { + byte[] result = java.util.Base64.getUrlDecoder().decode(s); + try { + return new String(result, CHARSET); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + /** + * MIME编码 + * + * @param bytes + * @return byte[] + */ + public static byte[] mimeEncode(byte[] bytes) { + return java.util.Base64.getMimeEncoder().encode(bytes); + } + + /** + * MIME编码 + * + * @param s + * @return String + */ + public static String mimeEncode(String s) { + try { + byte[] bytes = s.getBytes(CHARSET); + return java.util.Base64.getMimeEncoder().encodeToString(bytes); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + /** + * MIME解码 + * + * @param bytes + * @return byte[] + */ + public static byte[] mimeDecode(byte[] bytes) { + return java.util.Base64.getMimeDecoder().decode(bytes); + } + + /** + * MIME解码 + * + * @param s + * @return String + */ + public static String mimeDecode(String s) { + try { + byte[] result = java.util.Base64.getMimeDecoder().decode(s); + return new String(result, CHARSET); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage(), e); + return null; + } + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/BeanToMapUtil.java b/fuint-utils/src/main/java/com/fuint/utils/BeanToMapUtil.java new file mode 100644 index 0000000..7963afc --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/BeanToMapUtil.java @@ -0,0 +1,83 @@ +package com.fuint.utils; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class BeanToMapUtil { + /** + * 将一个 Map 对象转化为一个 JavaBean + * + * @param type 要转化的类型 + * @param map 包含属性值的 map + * @return 转化出来的 JavaBean 对象 + * @throws IntrospectionException 如果分析类属性失败 + * @throws IllegalAccessException 如果实例化 JavaBean 失败 + * @throws InstantiationException 如果实例化 JavaBean 失败 + * @throws InvocationTargetException 如果调用属性的 setter 方法失败 + */ + public static Object convertMap(Class type, Map map) + throws IntrospectionException, IllegalAccessException, + InstantiationException, InvocationTargetException { + BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性 + Object obj = type.newInstance(); // 创建 JavaBean 对象 + + // 给 JavaBean 对象的属性赋值 + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + String propertyName = descriptor.getName(); + + if (map.containsKey(propertyName)) { + // 下面一句可以 try 起来,这样当一个属性赋值失败的时候就不会影响其他属性赋值。 + Object value = map.get(propertyName); + + Object[] args = new Object[1]; + args[0] = value; + + descriptor.getWriteMethod().invoke(obj, args); + } + } + return obj; + } + + /** + * 将一个 JavaBean 对象转化为一个 Map + * + * @param bean 要转化的JavaBean 对象 + * @return 转化出来的 Map 对象 + * @throws IntrospectionException 如果分析类属性失败 + * @throws IllegalAccessException 如果实例化 JavaBean 失败 + * @throws InvocationTargetException 如果调用属性的 setter 方法失败 + */ + public static Map convertBean(Object bean) throws IntrospectionException, IllegalAccessException, InvocationTargetException { + Class type = bean.getClass(); + Map returnMap = new HashMap(); + BeanInfo beanInfo = Introspector.getBeanInfo(type); + + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + String propertyName = descriptor.getName(); + if (!propertyName.equals("class")) { + Method readMethod = descriptor.getReadMethod(); + Object result = readMethod.invoke(bean, new Object[0]); + if (result != null) { + returnMap.put(propertyName, result); + } else { + returnMap.put(propertyName, ""); + } + } + } + return returnMap; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/ClassUtil.java b/fuint-utils/src/main/java/com/fuint/utils/ClassUtil.java new file mode 100644 index 0000000..0857a57 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ClassUtil.java @@ -0,0 +1,1250 @@ +package com.fuint.utils; + +import java.lang.reflect.Array; +import java.util.*; + +/** + * 有关 Class 处理的工具类。 + * + * + * 这个类中的每个方法都可以“安全”地处理 null ,而不会抛出 NullPointerException。 + * + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class ClassUtil { + /* ============================================================================ */ + /* 常量和singleton。 */ + /* ============================================================================ */ + + /** 资源文件的分隔符: '/'。 */ + public static final char RESOURCE_SEPARATOR_CHAR = '/'; + + /** Java类名的分隔符: '.'。 */ + public static final char PACKAGE_SEPARATOR_CHAR = '.'; + + /** Java类名的分隔符: "."。 */ + public static final String PACKAGE_SEPARATOR = String.valueOf(PACKAGE_SEPARATOR_CHAR); + + /** 内联类的分隔符: '$'。 */ + public static final char INNER_CLASS_SEPARATOR_CHAR = '$'; + + /** 内联类的分隔符: "$"。 */ + public static final String INNER_CLASS_SEPARATOR = String.valueOf(INNER_CLASS_SEPARATOR_CHAR); + + /** 所有类的信息表,包括父类, 接口, 数组的维数等信息。 */ + private static final Map TYPE_MAP = Collections.synchronizedMap(new WeakHashMap()); + + /* ============================================================================ */ + /* 取得类名和package名的方法。 */ + /* ============================================================================ */ + + /** + * 取得对象所属的类的直观类名。 + * + *

+ * 相当于 object.getClass().getName() ,但不同的是,该方法用更直观的方式显示数组类型。 例如: + *

+     *  int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
+     *
+     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
+     *  
+ *

+ * + *

+ * 对于非数组的类型,该方法等效于 Class.getName() 方法。 + *

+ * + *

+ * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 + *

+ * + * @param object 要显示类名的对象 + * + * @return 用于显示的直观类名,如果原类名为空或非法,则返回 null + */ + public static String getClassNameForObject(Object object) { + if (object == null) { + return null; + } + + return getClassName(object.getClass().getName(), true); + } + + /** + * 取得直观的类名。 + * + *

+ * 相当于 clazz.getName() ,但不同的是,该方法用更直观的方式显示数组类型。 例如: + *

+     *  int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
+     *
+     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
+     *  
+ *

+ * + *

+ * 对于非数组的类型,该方法等效于 Class.getName() 方法。 + *

+ * + *

+ * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 + *

+ * + * @param clazz 要显示类名的类 + * + * @return 用于显示的直观类名,如果原始类为 null ,则返回 null + */ + public static String getClassName(Class clazz) { + if (clazz == null) { + return null; + } + + return getClassName(clazz.getName(), true); + } + + /** + * 取得直观的类名。 + * + *

+ * className 必须是从 clazz.getName() 所返回的合法类名。该方法用更直观的方式显示数组类型。 例如: + *

+     *  int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
+     *
+     *  Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
+     *  
+ *

+ * + *

+ * 对于非数组的类型,该方法等效于 Class.getName() 方法。 + *

+ * + *

+ * 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 Class.forName 操作。 + *

+ * + * @param className 要显示的类名 + * + * @return 用于显示的直观类名,如果原类名为 null ,则返回 null ,如果原类名是非法的,则返回原类名 + */ + public static String getClassName(String className) { + return getClassName(className, true); + } + + /** + * 取得直观的类名。 + * + * @param className 类名 + * @param processInnerClass 是否将内联类分隔符 '$' 转换成 '.' + * + * @return 直观的类名,或 null + */ + private static String getClassName(String className, boolean processInnerClass) { + if (StringUtil.isEmpty(className)) { + return className; + } + + if (processInnerClass) { + className = className.replace(INNER_CLASS_SEPARATOR_CHAR, PACKAGE_SEPARATOR_CHAR); + } + + int length = className.length(); + int dimension = 0; + + // 取得数组的维数,如果不是数组,维数为0 + for (int i = 0; i < length; i++, dimension++) { + if (className.charAt(i) != '[') { + break; + } + } + + // 如果不是数组,则直接返回 + if (dimension == 0) { + return className; + } + + // 确保类名合法 + if (length <= dimension) { + return className; // 非法类名 + } + + // 处理数组 + StringBuffer componentTypeName = new StringBuffer(); + + switch (className.charAt(dimension)) { + case 'Z': + componentTypeName.append("boolean"); + break; + + case 'B': + componentTypeName.append("byte"); + break; + + case 'C': + componentTypeName.append("char"); + break; + + case 'D': + componentTypeName.append("double"); + break; + + case 'F': + componentTypeName.append("float"); + break; + + case 'I': + componentTypeName.append("int"); + break; + + case 'J': + componentTypeName.append("long"); + break; + + case 'S': + componentTypeName.append("short"); + break; + + case 'L': + + if ((className.charAt(length - 1) != ';') || (length <= (dimension + 2))) { + return className; // 非法类名 + } + + componentTypeName.append(className.substring(dimension + 1, length - 1)); + break; + + default: + return className; // 非法类名 + } + + for (int i = 0; i < dimension; i++) { + componentTypeName.append("[]"); + } + + return componentTypeName.toString(); + } + + /** + * 取得指定对象所属的类的短类名,不包括package名。 + * + *

+ * 此方法可以正确显示数组和内联类的名称。 + *

+ * + *

+ * 例如: + *

+     *  ClassUtil.getShortClassNameForObject(Boolean.TRUE) = "Boolean" ClassUtil.getShortClassNameForObject(new Boolean[10]) = "Boolean[]" ClassUtil.getShortClassNameForObject(new int[1][2]) = "int[][]"
+     *  
+ *

+ * + * @param object 要查看的对象 + * + * @return 短类名,如果对象为 null ,则返回 null + */ + public static String getShortClassNameForObject(Object object) { + if (object == null) { + return null; + } + + return getShortClassName(object.getClass().getName()); + } + + /** + * 取得短类名,不包括package名。 + * + *

+ * 此方法可以正确显示数组和内联类的名称。 + *

+ * + *

+ * 例如: + *

+     *  ClassUtil.getShortClassName(Boolean.class) = "Boolean" ClassUtil.getShortClassName(Boolean[].class) = "Boolean[]" ClassUtil.getShortClassName(int[][].class) = "int[][]" ClassUtil.getShortClassName(Map.Entry.class) = "Map.Entry"
+     *  
+ *

+ * + * @param clazz 要查看的类 + * + * @return 短类名,如果类为 null ,则返回 null + */ + public static String getShortClassName(Class clazz) { + if (clazz == null) { + return null; + } + + return getShortClassName(clazz.getName()); + } + + /** + * 取得类名,不包括package名。 + * + *

+ * 此方法可以正确显示数组和内联类的名称。 + *

+ * + *

+ * 例如: + *

+     *  ClassUtil.getShortClassName(Boolean.class.getName()) = "Boolean" ClassUtil.getShortClassName(Boolean[].class.getName()) = "Boolean[]" ClassUtil.getShortClassName(int[][].class.getName()) = "int[][]" ClassUtil.getShortClassName(Map.Entry.class.getName()) = "Map.Entry"
+     *  
+ *

+ * + * @param className 要查看的类名 + * + * @return 短类名,如果类名为空,则返回 null + */ + public static String getShortClassName(String className) { + if (StringUtil.isEmpty(className)) { + return className; + } + + // 转换成直观的类名 + className = getClassName(className, false); + + char[] chars = className.toCharArray(); + int lastDot = 0; + + for (int i = 0; i < chars.length; i++) { + if (chars[i] == PACKAGE_SEPARATOR_CHAR) { + lastDot = i + 1; + } else if (chars[i] == INNER_CLASS_SEPARATOR_CHAR) { + chars[i] = PACKAGE_SEPARATOR_CHAR; + } + } + + return new String(chars, lastDot, chars.length - lastDot); + } + + /** + * 取得指定对象所属的类的package名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param object 要查看的对象 + * + * @return package名,如果对象为 null ,则返回 null + */ + public static String getPackageNameForObject(Object object) { + if (object == null) { + return null; + } + + return getPackageName(object.getClass().getName()); + } + + /** + * 取得指定类的package名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param clazz 要查看的类 + * + * @return package名,如果类为 null ,则返回 null + */ + public static String getPackageName(Class clazz) { + if (clazz == null) { + return null; + } + + return getPackageName(clazz.getName()); + } + + /** + * 取得指定类名的package名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param className 要查看的类名 + * + * @return package名,如果类名为空,则返回 null + */ + public static String getPackageName(String className) { + if (StringUtil.isEmpty(className)) { + return null; + } + + // 转换成直观的类名 + className = getClassName(className, false); + + int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); + + if (i == -1) { + return ""; + } + + return className.substring(0, i); + } + + /* ============================================================================ */ + /* 取得类名和package名的resource名的方法。 */ + /* */ + /* 和类名、package名不同的是,resource名符合文件名命名规范,例如: */ + /* java/lang/String.class */ + /* com/alibaba/commons/lang */ + /* etc. */ + /* ============================================================================ */ + + /** + * 取得对象所属的类的资源名。 + * + *

+ * 例如: + *

+     * ClassUtil.getClassNameForObjectAsResource("This is a string")    = "java/lang/String.class"
+     * 
+ *

+ * + * @param object 要显示类名的对象 + * + * @return 指定对象所属类的资源名,如果对象为空,则返回null + */ + public static String getClassNameForObjectAsResource(Object object) { + if (object == null) { + return null; + } + + return object.getClass().getName().replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR) + + ".class"; + } + + /** + * 取得指定类的资源名。 + * + *

+ * 例如: + *

+     * ClassUtil.getClassNameAsResource(String.class)   = "java/lang/String.class"
+     * 
+ *

+ * + * @param clazz 要显示类名的类 + * + * @return 指定类的资源名,如果指定类为空,则返回null + */ + public static String getClassNameAsResource(Class clazz) { + if (clazz == null) { + return null; + } + + return clazz.getName().replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR) + ".class"; + } + + /** + * 取得指定类的资源名。 + * + *

+ * 例如: + *

+     * ClassUtil.getClassNameAsResource("java.lang.String") = "java/lang/String.class"
+     * 
+ *

+ * + * @param className 要显示的类名 + * + * @return 指定类名对应的资源名,如果指定类名为空,则返回null + */ + public static String getClassNameAsResource(String className) { + if (className == null) { + return null; + } + + return className.replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR) + ".class"; + } + + /** + * 取得指定对象所属的类的package名的资源名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param object 要查看的对象 + * + * @return package名,如果对象为 null ,则返回 null + */ + public static String getPackageNameForObjectAsResource(Object object) { + if (object == null) { + return null; + } + + return getPackageNameForObject(object).replace(PACKAGE_SEPARATOR_CHAR, + RESOURCE_SEPARATOR_CHAR); + } + + /** + * 取得指定类的package名的资源名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param clazz 要查看的类 + * + * @return package名,如果类为 null ,则返回 null + */ + public static String getPackageNameAsResource(Class clazz) { + if (clazz == null) { + return null; + } + + return getPackageName(clazz).replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR); + } + + /** + * 取得指定类名的package名的资源名。 + * + *

+ * 对于数组,此方法返回的是数组元素类型的package名。 + *

+ * + * @param className 要查看的类名 + * + * @return package名,如果类名为空,则返回 null + */ + public static String getPackageNameAsResource(String className) { + if (className == null) { + return null; + } + + return getPackageName(className).replace(PACKAGE_SEPARATOR_CHAR, RESOURCE_SEPARATOR_CHAR); + } + + /* ============================================================================ */ + /* 取得类的信息,如父类, 接口, 数组的维数等。 */ + /* ============================================================================ */ + + /** + * 取得指定维数的 Array类. + * + * @param componentType 数组的基类 + * @param dimension 维数,如果小于 0 则看作 0 + * + * @return 如果维数为0, 则返回基类本身, 否则返回数组类,如果数组的基类为 null ,则返回 null + */ + public static Class getArrayClass(Class componentType, int dimension) { + if (dimension <= 0) { + return componentType; + } + + if (componentType == null) { + return null; + } + + return Array.newInstance(componentType, new int[dimension]).getClass(); + } + + /** + * 取得数组元素的类型。 + * + * @param type 要查找的类 + * + * @return 如果是数组, 则返回数组元素的类型, 否则返回 null + */ + public static Class getArrayComponentType(Class type) { + if (type == null) { + return null; + } + + return getTypeInfo(type).getArrayComponentType(); + } + + /** + * 取得数组的维数。 + * + * @param clazz 要查找的类 + * + * @return 数组的维数. 如果不是数组, 则返回 0 ,如果数组为 null ,是返回 -1 + */ + public static int getArrayDimension(Class clazz) { + if (clazz == null) { + return -1; + } + + return getTypeInfo(clazz).getArrayDimension(); + } + + /** + * 取得指定类的所有父类。 + * + *

+ * 对于一个 Class 实例,如果它不是接口,也不是数组,此方法依次列出从该类的父类开始直到 Object 的所有类。 + *

+ * + *

+ * 例如 ClassUtil.getSuperclasses(java.util.ArrayList.class) 返回以下列表: + * + *

    + *
  1. + * java.util.AbstractList + *
  2. + *
  3. + * java.util.AbstractCollection + *
  4. + *
  5. + * java.lang.Object + *
  6. + *
+ *

+ * + *

+ * 对于一个接口,此方法返回一个空列表。 + *

+ * + *

+ * 例如ClassUtil.getSuperclasses(java.util.List.class)将返回一个空列表。 + *

+ * + *

+ * 对于一个数组,此方法返回一个列表,列出所有component类型的父类的相同维数的数组类型。 例如: + * ClassUtil.getSuperclasses(java.util.ArrayList[][].class) 返回以下列表: + * + *

    + *
  1. + * java.util.AbstractList[][] + *
  2. + *
  3. + * java.util.AbstractCollection[][] + *
  4. + *
  5. + * java.lang.Object[][] + *
  6. + *
  7. + * java.lang.Object[] + *
  8. + *
  9. + * java.lang.Object + *
  10. + *
+ * + * 注意,原子类型及其数组,将被转换成相应的包装类来处理。 例如: ClassUtil.getSuperclasses(int[][].class) + * 返回以下列表: + * + *
    + *
  1. + * java.lang.Number[][] + *
  2. + *
  3. + * java.lang.Object[][] + *
  4. + *
  5. + * java.lang.Object[] + *
  6. + *
  7. + * java.lang.Object + *
  8. + *
+ *

+ * + * @param clazz 要查找的类 + * + * @return 所有父类的列表,如果指定类为 null ,则返回 null + */ + public static List getSuperclasses(Class clazz) { + if (clazz == null) { + return null; + } + + return getTypeInfo(clazz).getSuperclasses(); + } + + /** + * 取得指定类的所有接口。 + * + *

+ * 对于一个 Class 实例,如果它不是接口,也不是数组,此方法依次列出从该类的父类开始直到 Object 的所有类。 + *

+ * + *

+ * 例如 ClassUtil.getInterfaces(java.util.ArrayList.class) 返回以下列表: + * + *

    + *
  1. + * java.util.List + *
  2. + *
  3. + * java.util.Collection + *
  4. + *
  5. + * java.util.RandomAccess + *
  6. + *
  7. + * java.lang.Cloneable + *
  8. + *
  9. + * java.io.Serializable + *
  10. + *
+ *

+ * + *

+ * 对于一个数组,此方法返回一个列表,列出所有component类型的接口的相同维数的数组类型。 例如: + * ClassUtil.getInterfaces(java.util.ArrayList[][].class) 返回以下列表: + * + *

    + *
  1. + * java.util.List[][] + *
  2. + *
  3. + * java.util.Collection[][] + *
  4. + *
  5. + * java.util.RandomAccess[][] + *
  6. + *
  7. + * java.lang.Cloneable[][] + *
  8. + *
  9. + * java.io.Serializable[][] + *
  10. + *
+ *

+ * + *

+ * 注意,原子类型及其数组,将被转换成相应的包装类来处理。 例如: ClassUtil.getInterfaces(int[][].class) 返回以下列表: + * + *

    + *
  1. + * java.lang.Comparable[][] + *
  2. + *
  3. + * java.io.Serializable[][] + *
  4. + *
+ *

+ * + * @param clazz 要查找的类 + * + * @return 所有接口的列表,如果指定类为 null ,则返回 null + */ + public static List getInterfaces(Class clazz) { + if (clazz == null) { + return null; + } + + return getTypeInfo(clazz).getInterfaces(); + } + + /** + * 判断指定类是否为内联类。 + * + * @param clazz 要查找的类 + * + * @return 如果是,则返回 true + */ + public static boolean isInnerClass(Class clazz) { + if (clazz == null) { + return false; + } + + return StringUtil.contains(clazz.getName(), INNER_CLASS_SEPARATOR_CHAR); + } + + /** + * 检查一组指定类型 fromClasses 的对象是否可以赋值给另一组类型 classes。 + * + *

+ * 此方法可以用来确定指定类型的参数 object1, object2, ... 是否可以用来调用确定参数类型为 class1, class2, + * ... 的方法。 + *

+ * + *

+ * 对于 fromClasses 的每个元素 fromClassclasses 的每个元素 + * clazz, 按照如下规则: + * + *

    + *
  1. + * 如果目标类 clazznull ,总是返回 false。 + *
  2. + *
  3. + * 如果参数类型 fromClassnull ,并且目标类型 clazz 为非原子类型,则返回 + * true。 因为 null 可以被赋给任何引用类型。 + *
  4. + *
  5. + * 调用 Class.isAssignableFrom 方法来确定目标类 clazz 是否和参数类 + * fromClass 相同或是其父类、接口,如果是,则返回 true。 + *
  6. + *
  7. + * 如果目标类型 clazz 为原子类型,那么根据 The Java + * Language Specification ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive + * Conversion规则,参数类型 fromClass 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, clazz 为 + * long ,那么参数类型可以是 byte、 + * shortintlongchar 及其包装类 + * java.lang.Bytejava.lang.Shortjava.lang.Integer、 + * java.lang.Longjava.lang.Character 。如果满足这个条件,则返回 + * true。 + *
  8. + *
  9. + * 不满足上述所有条件,则返回 false。 + *
  10. + *
+ *

+ * + * @param classes 目标类型列表,如果是 null 总是返回 false + * @param fromClasses 参数类型列表, null 表示可赋值给任意非原子类型 + * + * @return 如果可以被赋值,则返回 true + */ + public static boolean isAssignable(Class[] classes, Class[] fromClasses) { + if (!ArrayUtil.isSameLength(fromClasses, classes)) { + return false; + } + + if (fromClasses == null) { + fromClasses = ArrayUtil.EMPTY_CLASS_ARRAY; + } + + if (classes == null) { + classes = ArrayUtil.EMPTY_CLASS_ARRAY; + } + + for (int i = 0; i < fromClasses.length; i++) { + if (isAssignable(classes[i], fromClasses[i]) == false) { + return false; + } + } + + return true; + } + + /** + * 检查指定类型 fromClass 的对象是否可以赋值给另一种类型 clazz。 + * + *

+ * 此方法可以用来确定指定类型的参数 object1, object2, ... 是否可以用来调用确定参数类型 class1, class2, + * ... 的方法。 + *

+ * + *

+ * 按照如下规则: + * + *

    + *
  1. + * 如果目标类 clazznull ,总是返回 false。 + *
  2. + *
  3. + * 如果参数类型 fromClassnull ,并且目标类型 clazz 为非原子类型,则返回 + * true。 因为 null 可以被赋给任何引用类型。 + *
  4. + *
  5. + * 调用 Class.isAssignableFrom 方法来确定目标类 clazz 是否和参数类 + * fromClass 相同或是其父类、接口,如果是,则返回 true。 + *
  6. + *
  7. + * 如果目标类型 clazz 为原子类型,那么根据 The Java + * Language Specification ,sections 5.1.1, 5.1.2, 5.1.4定义的Widening Primitive + * Conversion规则,参数类型 fromClass 可以是任何能扩展成该目标类型的原子类型及其包装类。 例如, clazz 为 + * long ,那么参数类型可以是 byte、 + * shortintlongchar 及其包装类 + * java.lang.Bytejava.lang.Shortjava.lang.Integer、 + * java.lang.Longjava.lang.Character 。如果满足这个条件,则返回 + * true。 + *
  8. + *
  9. + * 不满足上述所有条件,则返回 false。 + *
  10. + *
+ *

+ * + * @param clazz 目标类型,如果是 null 总是返回 false + * @param fromClass 参数类型, null 表示可赋值给任意非原子类型 + * + * @return 如果可以被赋值,则返回 null + */ + public static boolean isAssignable(Class clazz, Class fromClass) { + if (clazz == null) { + return false; + } + + // 如果fromClass是null,只要clazz不是原子类型如int,就一定可以赋值 + if (fromClass == null) { + return !clazz.isPrimitive(); + } + + // 如果类相同或有父子关系,当然可以赋值 + if (clazz.isAssignableFrom(fromClass)) { + return true; + } + + // 对于原子类型,根据JLS的规则进行扩展 + // 目标class为原子类型时,fromClass可以为原子类型和原子类型的包装类型。 + if (clazz.isPrimitive()) { + // boolean可以接受:boolean + if (Boolean.TYPE.equals(clazz)) { + return Boolean.class.equals(fromClass); + } + + // byte可以接受:byte + if (Byte.TYPE.equals(clazz)) { + return Byte.class.equals(fromClass); + } + + // char可以接受:char + if (Character.TYPE.equals(clazz)) { + return Character.class.equals(fromClass); + } + + // short可以接受:short, byte + if (Short.TYPE.equals(clazz)) { + return Short.class.equals(fromClass) || Byte.TYPE.equals(fromClass) + || Byte.class.equals(fromClass); + } + + // int可以接受:int、byte、short、char + if (Integer.TYPE.equals(clazz)) { + return Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass) + || Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass) + || Short.class.equals(fromClass) || Character.TYPE.equals(fromClass) + || Character.class.equals((fromClass)); + } + + // long可以接受:long、int、byte、short、char + if (Long.TYPE.equals(clazz)) { + return Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass) + || Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass) + || Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass) + || Short.class.equals(fromClass) || Character.TYPE.equals(fromClass) + || Character.class.equals((fromClass)); + } + + // float可以接受:float, long, int, byte, short, char + if (Float.TYPE.equals(clazz)) { + return Float.class.equals(fromClass) || Long.TYPE.equals(fromClass) + || Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass) + || Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass) + || Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass) + || Short.class.equals(fromClass) || Character.TYPE.equals(fromClass) + || Character.class.equals((fromClass)); + } + + // double可以接受:double, float, long, int, byte, short, char + if (Double.TYPE.equals(clazz)) { + return Double.class.equals(fromClass) || Float.TYPE.equals(fromClass) + || Float.class.equals(fromClass) || Long.TYPE.equals(fromClass) + || Long.class.equals(fromClass) || Integer.TYPE.equals(fromClass) + || Integer.class.equals(fromClass) || Byte.TYPE.equals(fromClass) + || Byte.class.equals(fromClass) || Short.TYPE.equals(fromClass) + || Short.class.equals(fromClass) || Character.TYPE.equals(fromClass) + || Character.class.equals((fromClass)); + } + } + + return false; + } + + /** + * 取得指定类的 TypeInfo。 + * + * @param type 指定类或接口 + * + * @return TypeInfo 对象. + */ + protected static TypeInfo getTypeInfo(Class type) { + if (type == null) { + throw new IllegalArgumentException("Parameter clazz should not be null"); + } + + TypeInfo classInfo; + + synchronized (TYPE_MAP) { + classInfo = (TypeInfo) TYPE_MAP.get(type); + + if (classInfo == null) { + classInfo = new TypeInfo(type); + TYPE_MAP.put(type, classInfo); + } + } + + return classInfo; + } + + /** + * 代表一个类的信息, 包括父类, 接口, 数组的维数等. + */ + protected static class TypeInfo { + private Class type; + private Class componentType; + private int dimension; + private List superclasses = new ArrayList(2); + private List interfaces = new ArrayList(2); + + /** + * 创建 TypeInfo。 + * + * @param type 创建指定类的 TypeInfo + */ + private TypeInfo(Class type) { + this.type = type; + + // 如果是array, 设置componentType和dimension + Class componentType = null; + + if (type.isArray()) { + componentType = type; + + do { + componentType = componentType.getComponentType(); + dimension++; + } while (componentType.isArray()); + } + + this.componentType = componentType; + + // 取得所有superclass + if (dimension > 0) { + // 将primitive类型转换成对应的包装类 + componentType = getNonPrimitiveType(componentType); + + Class superComponentType = componentType.getSuperclass(); + + // 如果是primitive, interface, 则设置其基类为Object. + if ((superComponentType == null) && !Object.class.equals(componentType)) { + superComponentType = Object.class; + } + + if (superComponentType != null) { + Class superclass = getArrayClass(superComponentType, dimension); + + superclasses.add(superclass); + superclasses.addAll(getTypeInfo(superclass).superclasses); + } else { + for (int i = dimension - 1; i >= 0; i--) { + superclasses.add(getArrayClass(Object.class, i)); + } + } + } else { + // 将primitive类型转换成对应的包装类 + type = getNonPrimitiveType(type); + + Class superclass = type.getSuperclass(); + + if (superclass != null) { + superclasses.add(superclass); + superclasses.addAll(getTypeInfo(superclass).superclasses); + } + } + + // 取得所有interface + if (dimension == 0) { + Class[] typeInterfaces = type.getInterfaces(); + List set = new ArrayList(); + + for (int i = 0; i < typeInterfaces.length; i++) { + Class typeInterface = typeInterfaces[i]; + + set.add(typeInterface); + set.addAll(getTypeInfo(typeInterface).interfaces); + } + + for (Iterator i = superclasses.iterator(); i.hasNext();) { + Class typeInterface = (Class) i.next(); + + set.addAll(getTypeInfo(typeInterface).interfaces); + } + + for (Iterator i = set.iterator(); i.hasNext();) { + Class interfaceClass = (Class) i.next(); + + if (!interfaces.contains(interfaceClass)) { + interfaces.add(interfaceClass); + } + } + } else { + for (Iterator i = getTypeInfo(componentType).interfaces.iterator(); i.hasNext();) { + Class componentInterface = (Class) i.next(); + + interfaces.add(getArrayClass(componentInterface, dimension)); + } + } + } + + /** + * 将所有的原子类型转换成对应的包装类,其它类型不变。 + * + * @param type 要转换的类型 + * + * @return 非原子类型 + */ + private Class getNonPrimitiveType(Class type) { + if (type.isPrimitive()) { + if (Integer.TYPE.equals(type)) { + type = Integer.class; + } else if (Long.TYPE.equals(type)) { + type = Long.class; + } else if (Short.TYPE.equals(type)) { + type = Short.class; + } else if (Byte.TYPE.equals(type)) { + type = Byte.class; + } else if (Float.TYPE.equals(type)) { + type = Float.class; + } else if (Double.TYPE.equals(type)) { + type = Double.class; + } else if (Boolean.TYPE.equals(type)) { + type = Boolean.class; + } else if (Character.TYPE.equals(type)) { + type = Character.class; + } + } + + return type; + } + + /** + * 取得 TypeInfo 所代表的java类。 + * + * @return TypeInfo 所代表的java类 + */ + public Class getType() { + return type; + } + + /** + * 取得数组元素的类型。 + * + * @return 如果是数组, 则返回数组元素的类型, 否则返回 null + */ + public Class getArrayComponentType() { + return componentType; + } + + /** + * 取得数组的维数。 + * + * @return 数组的维数. 如果不是数组, 则返回 0 + */ + public int getArrayDimension() { + return dimension; + } + + /** + * 取得所有的父类。 + * + * @return 所有的父类 + */ + public List getSuperclasses() { + return Collections.unmodifiableList(superclasses); + } + + /** + * 取得所有的接口。 + * + * @return 所有的接口 + */ + public List getInterfaces() { + return Collections.unmodifiableList(interfaces); + } + } + + /* ============================================================================ */ + /* 有关primitive类型的方法。 */ + /* ============================================================================ */ + + /** + * 返回指定类型所对应的primitive类型。 + * + * @param clazz 要检查的类型 + * + * @return 如果指定类型为null或不是primitive类型的包装类,则返回null,否则返回相应的primitive类型。 + */ + public static Class getPrimitiveType(Class clazz) { + if (clazz == null) { + return null; + } + + if (clazz.isPrimitive()) { + return clazz; + } + + if (clazz.equals(Long.class)) { + return long.class; + } + + if (clazz.equals(Integer.class)) { + return int.class; + } + + if (clazz.equals(Short.class)) { + return short.class; + } + + if (clazz.equals(Byte.class)) { + return byte.class; + } + + if (clazz.equals(Double.class)) { + return double.class; + } + + if (clazz.equals(Float.class)) { + return float.class; + } + + if (clazz.equals(Boolean.class)) { + return boolean.class; + } + + if (clazz.equals(Character.class)) { + return char.class; + } + + return null; + } + + /** + * 返回指定类型所对应的非primitive类型。 + * + * @param clazz 要检查的类型 + * + * @return 如果指定类型为null,则返回null,如果是primitive类型,则返回相应的包装类,否则返回原始的类型。 + */ + public static Class getNonPrimitiveType(Class clazz) { + if (clazz == null) { + return null; + } + + if (!clazz.isPrimitive()) { + return clazz; + } + + if (clazz.equals(long.class)) { + return Long.class; + } + + if (clazz.equals(int.class)) { + return Integer.class; + } + + if (clazz.equals(short.class)) { + return Short.class; + } + + if (clazz.equals(byte.class)) { + return Byte.class; + } + + if (clazz.equals(double.class)) { + return Double.class; + } + + if (clazz.equals(float.class)) { + return Float.class; + } + + if (clazz.equals(boolean.class)) { + return Boolean.class; + } + + if (clazz.equals(char.class)) { + return Character.class; + } + + return null; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/CommonUtil.java b/fuint-utils/src/main/java/com/fuint/utils/CommonUtil.java new file mode 100644 index 0000000..e82d149 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/CommonUtil.java @@ -0,0 +1,28 @@ +package com.fuint.utils; + +import org.apache.commons.lang.StringUtils; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class CommonUtil { + + /** + * 格式化指定的日期 + * + * @param date + * @param formatStr + * @return + */ + public static String formatDate(Date date, String formatStr) { + if (date == null) date = new Date(); + if (StringUtils.isEmpty(formatStr)) formatStr = "yyyy-MM-dd"; + SimpleDateFormat dateFormater = new SimpleDateFormat(formatStr); + return dateFormater.format(date); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/ContextUtils.java b/fuint-utils/src/main/java/com/fuint/utils/ContextUtils.java new file mode 100644 index 0000000..0e9d970 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ContextUtils.java @@ -0,0 +1,42 @@ +package com.fuint.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * Context 工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +@Component +public class ContextUtils implements ApplicationContextAware { + public static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + ContextUtils.applicationContext = applicationContext; + } + + public static Object getBean(String name) { + return applicationContext.getBean(name); + } + + public static T getBean(String name, Class requiredType) { + return applicationContext.getBean(name, requiredType); + } + + public static boolean containsBean(String name) { + return applicationContext.containsBean(name); + } + + public static boolean isSingleton(String name) { + return applicationContext.isSingleton(name); + } + + public static Class getType(String name) { + return applicationContext.getType(name); + } +} \ No newline at end of file diff --git a/fuint-utils/src/main/java/com/fuint/utils/Digests.java b/fuint-utils/src/main/java/com/fuint/utils/Digests.java new file mode 100644 index 0000000..f4c0389 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/Digests.java @@ -0,0 +1,110 @@ +package com.fuint.utils; + +import com.fuint.exception.Exceptions; +import org.apache.commons.lang.Validate; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.SecureRandom; + +/** + * 支持SHA-1/MD5消息摘要的工具类. + * + * 返回ByteSource,可进一步被编码为Hex, Base64或UrlSafeBase64 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Digests { + + private static final String SHA1 = "SHA-1"; + private static final String MD5 = "MD5"; + + private static SecureRandom random = new SecureRandom(); + + /** + * 对输入字符串进行sha1散列. + */ + public static byte[] sha1(byte[] input) { + return digest(input, SHA1, null, 1); + } + + public static byte[] sha1(byte[] input, byte[] salt) { + return digest(input, SHA1, salt, 1); + } + + public static byte[] sha1(byte[] input, byte[] salt, int iterations) { + return digest(input, SHA1, salt, iterations); + } + + /** + * 对字符串进行散列, 支持md5与sha1算法. + */ + private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) { + try { + MessageDigest digest = MessageDigest.getInstance(algorithm); + + if (salt != null) { + digest.update(salt); + } + + byte[] result = digest.digest(input); + + for (int i = 1; i < iterations; i++) { + digest.reset(); + result = digest.digest(result); + } + return result; + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 生成随机的Byte[]作为salt. + * + * @param numBytes byte数组的大小 + */ + public static byte[] generateSalt(int numBytes) { + Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", + numBytes); + + byte[] bytes = new byte[numBytes]; + random.nextBytes(bytes); + return bytes; + } + + /** + * 对文件进行md5散列. + */ + public static byte[] md5(InputStream input) throws IOException { + return digest(input, MD5); + } + + /** + * 对文件进行sha1散列. + */ + public static byte[] sha1(InputStream input) throws IOException { + return digest(input, SHA1); + } + + private static byte[] digest(InputStream input, String algorithm) throws IOException { + try { + MessageDigest messageDigest = MessageDigest.getInstance(algorithm); + int bufferLength = 8 * 1024; + byte[] buffer = new byte[bufferLength]; + int read = input.read(buffer, 0, bufferLength); + + while (read > -1) { + messageDigest.update(buffer, 0, read); + read = input.read(buffer, 0, bufferLength); + } + + return messageDigest.digest(); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/Encodes.java b/fuint-utils/src/main/java/com/fuint/utils/Encodes.java new file mode 100644 index 0000000..1b0f436 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/Encodes.java @@ -0,0 +1,125 @@ +package com.fuint.utils; + +import com.fuint.exception.Exceptions; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang.StringEscapeUtils; + +/** + * 编码转换工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class Encodes { + + private static final String DEFAULT_URL_ENCODING = "UTF-8"; + private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + .toCharArray(); + + /** + * Hex编码. + */ + public static String encodeHex(byte[] input) { + return Hex.encodeHexString(input); + } + + /** + * Hex解码. + */ + public static byte[] decodeHex(String input) { + try { + return Hex.decodeHex(input.toCharArray()); + } catch (DecoderException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * Base64编码. + */ + public static String encodeBase64(byte[] input) { + return Base64.encodeBase64String(input); + } + + /** + * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548). + */ + public static String encodeUrlSafeBase64(byte[] input) { + return Base64.encodeBase64URLSafeString(input); + } + + /** + * Base64解码. + */ + public static byte[] decodeBase64(String input) { + return Base64.decodeBase64(input); + } + + /** + * Base62编码。 + */ + public static String encodeBase62(byte[] input) { + char[] chars = new char[input.length]; + for (int i = 0; i < input.length; i++) { + chars[i] = BASE62[(input[i] & 0xFF) % BASE62.length]; + } + return new String(chars); + } + + /** + * Html 转码. + */ + public static String escapeHtml(String html) { + return StringEscapeUtils.escapeHtml(html); + } + + /** + * Html 解码. + */ + public static String unescapeHtml(String htmlEscaped) { + return StringEscapeUtils.unescapeHtml(htmlEscaped); + } + + /** + * Xml 转码. + */ + @SuppressWarnings("deprecation") + public static String escapeXml(String xml) { + return StringEscapeUtils.escapeXml(xml); + } + + /** + * Xml 解码. + */ + public static String unescapeXml(String xmlEscaped) { + return StringEscapeUtils.unescapeXml(xmlEscaped); + } + + /** + * URL 编码, Encode默认为UTF-8. + */ + public static String urlEncode(String part) { + try { + return URLEncoder.encode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw com.fuint.exception.Exceptions.unchecked(e); + } + } + + /** + * URL 解码, Encode默认为UTF-8. + */ + public static String urlDecode(String part) { + + try { + return URLDecoder.decode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw com.fuint.exception.Exceptions.unchecked(e); + } + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/ExportExcelUtil.java b/fuint-utils/src/main/java/com/fuint/utils/ExportExcelUtil.java new file mode 100644 index 0000000..26f2f1f --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ExportExcelUtil.java @@ -0,0 +1,363 @@ +package com.fuint.utils; + +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.hssf.util.HSSFColor; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.sql.Timestamp; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 利用开源组件POI3.0.2动态导出EXCEL文档 转载时请保留以下信息,注明出处! + * + * Created by FSQ + * CopyRight https://www.fuint.cn + * @param + * 应用泛型,代表任意一个符合javabean风格的类 + * 注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx() + * byte[]表jpg格式的图片数据 + */ +public class ExportExcelUtil { + + public void exportExcel(String title,Collection dataset, OutputStream out) { + exportExcel(title, null, dataset, out, "yyyy-MM-dd"); + } + + + public void exportExcel(String title, + String[] headers, + Collection dataset, + OutputStream out, + String pattern) { + exportExcel(title, headers, dataset, out, pattern); + } + + + public void exportExcel(String title, + String[] headers, + String[] fields, + Collection dataset, + OutputStream out) { + + exportExcel(title, + headers, + fields, + dataset, + out, + "yyyy-MM-dd"); + } + + + /** + * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上 + * + * @param title + * 表格标题名 + * @param headers + * 表格属性列名数组 + * @param dataset + * 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的 + * javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据) + * @param out + * 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 + * @param pattern + * 如果有时间数据,设定输出格式。默认为"yyy-MM-dd" + */ + @SuppressWarnings("unchecked") + public void exportExcel(String title, + String[] headers, + String[] ofields, + Collection dataset, + OutputStream out, + String pattern) { + // 声明一个工作薄 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 生成一个表格 + HSSFSheet sheet = workbook.createSheet(title); + // 设置表格默认列宽度为15个字节 + sheet.setDefaultColumnWidth((short) 15); + // 生成一个样式 + + HSSFCellStyle hssfCellStyle = workbook.createCellStyle(); + HSSFFont font = workbook.createFont(); + font.setColor(HSSFColor.BLACK.index); + hssfCellStyle.setFont(font); + // 产生表格标题行 + HSSFRow row = sheet.createRow(0); + for (int i = 0; i < headers.length; i++) { + HSSFCell cell = row.createCell(i); + // cell.setCellStyle(style); + HSSFRichTextString text = new HSSFRichTextString(headers[i]); + cell.setCellValue(text); + cell.setCellStyle(hssfCellStyle); + } + + // 遍历集合数据,产生数据行 + DecimalFormat df = new DecimalFormat("0.00"); + Iterator it = dataset.iterator(); + int index = 0; + while (it.hasNext()) { + index++; + row = sheet.createRow(index); + T t = (T) it.next(); + // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 + if (ofields != null) { + for (int i = 0; i < ofields.length; i++) { + HSSFCell cell = row.createCell(i); + // cell.setCellStyle(style2); + String fieldName = ofields[i]; + + String getMethodName = "get" + + fieldName.substring(0, 1) + .toUpperCase() + + fieldName.substring(1); + try { + Class tCls = t.getClass(); + Object value = null; + try { + Method getMethod = tCls.getMethod(getMethodName, + new Class[]{}); + value = getMethod.invoke(t, new Object[]{}); + } + catch (Exception e) { + // e.printStackTrace(); + } + // 判断值的类型后进行强制类型转换 + String textValue; + if (value == null) + continue; + textValue = convertTextValue(pattern, df, value); + // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 + if (textValue != null) { + Pattern p = Pattern.compile("^//d+(//.//d+)?$"); + Matcher matcher = p.matcher(textValue); + if (matcher.matches()) { + // 是数字当作double处理 + cell.setCellValue(Double.parseDouble(textValue)); + } else { + HSSFRichTextString richString = new HSSFRichTextString(textValue); + HSSFFont font3 = workbook.createFont(); + font3.setColor(HSSFColor.BLACK.index); + richString.applyFont(font3); + cell.setCellValue(richString); + } + } + + } + catch (SecurityException e) { + e.printStackTrace(); + } + catch (IllegalArgumentException e) { + e.printStackTrace(); + } + finally { + // 清理资源 + } + } + } else { + Field[] fields = t.getClass().getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + HSSFCell cell = row.createCell(i); + // cell.setCellStyle(style2); + Field field = fields[i]; + String fieldName = field.getName(); + + String getMethodName = "get" + + fieldName.substring(0, 1) + .toUpperCase() + + fieldName.substring(1); + try { + Class tCls = t.getClass(); + Object value = null; + try { + Method getMethod = tCls.getMethod(getMethodName, + new Class[]{}); + value = getMethod.invoke(t, new Object[]{}); + } + catch (Exception e) { + e.printStackTrace(); + } + // 判断值的类型后进行强制类型转换 + String textValue = null; + + if (value == null) + continue; + textValue = convertTextValue(pattern, df, value); + // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 + if (textValue != null) { + Pattern p = Pattern.compile("^//d+(//.//d+)?$"); + Matcher matcher = p.matcher(textValue); + if (matcher.matches()) { + // 是数字当作double处理 + cell.setCellValue(Double.parseDouble(textValue)); + } else { + HSSFRichTextString richString = new HSSFRichTextString(textValue); + // HSSFFont font3 = workbook.createFont(); + font.setColor(HSSFColor.BLACK.index); + richString.applyFont(font); + cell.setCellValue(richString); + } + } + + } + catch (SecurityException e) { + e.printStackTrace(); + } + catch (IllegalArgumentException e) { + e.printStackTrace(); + } + finally { + // 清理资源 + } + } + } + } + try { + workbook.write(out); + } + catch (IOException e) { + e.printStackTrace(); + } + + } + + private String convertTextValue(String pattern, DecimalFormat df, Object value) { + String textValue; + if (value instanceof Date) { + Date date = (Date) value; + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + textValue = sdf.format(date); + } else if(value instanceof Timestamp){ + Timestamp timestamp = (Timestamp) value; + Date date = new Date(timestamp.getTime()); + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + textValue = sdf.format(date); + } else if (value instanceof Number) { + if (((Number) value).intValue() != 0) { + textValue = df.format((float) ((Number) value).intValue() / 100); + } else { + textValue = "0.00"; + } + } + /* + * else if (value instanceof byte[]) { // + * 有图片时,设置行高为60px; row.setHeightInPoints(60); // + * 设置图片所在列宽度为80px,注意这里单位的一个换算 sheet.setColumnWidth(i, + * (short) (35.7 * 80)); // sheet.autoSizeColumn(i); + * byte[] bsValue = (byte[]) value; HSSFClientAnchor + * anchor = new HSSFClientAnchor(0, 0, 1023, 255, + * (short) 6, index, (short) 6, index); + * anchor.setAnchorType(2); + * patriarch.createPicture(anchor, workbook.addPicture( + * bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG)); } + */ + else { + // 其它数据类型都当作字符串简单处理 + textValue = value.toString(); + } + return textValue; + } + + @SuppressWarnings("unchecked") + public static void exportExcel(String title, + String[] headers, + Collection dataset, + OutputStream out) { + // 声明一个工作薄 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 生成一个表格 + HSSFSheet sheet = workbook.createSheet(title); + // 设置表格默认列宽度为15个字节 + sheet.setDefaultColumnWidth((short) 15); + // 生成一个样式 + HSSFCellStyle style = workbook.createCellStyle(); + // 设置这些样式 + style.setFillForegroundColor(HSSFColor.SKY_BLUE.index); + style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style.setBorderBottom(HSSFCellStyle.BORDER_THIN); + style.setBorderLeft(HSSFCellStyle.BORDER_THIN); + style.setBorderRight(HSSFCellStyle.BORDER_THIN); + style.setBorderTop(HSSFCellStyle.BORDER_THIN); + style.setAlignment(HSSFCellStyle.ALIGN_CENTER); + // 生成一个字体 + HSSFFont font = workbook.createFont(); + font.setColor(HSSFColor.VIOLET.index); + font.setFontHeightInPoints((short) 12); + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + // 把字体应用到当前的样式 + style.setFont(font); + // 生成并设置另一个样式 + HSSFCellStyle style2 = workbook.createCellStyle(); + style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index); + style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); + style2.setBorderLeft(HSSFCellStyle.BORDER_THIN); + style2.setBorderRight(HSSFCellStyle.BORDER_THIN); + style2.setBorderTop(HSSFCellStyle.BORDER_THIN); + style2.setAlignment(HSSFCellStyle.ALIGN_CENTER); + style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); + // 生成另一个字体 + HSSFFont font2 = workbook.createFont(); + font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); + // 把字体应用到当前的样式 + style2.setFont(font2); + + // 声明一个画图的顶级管理器 + HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); + // 定义注释的大小和位置,详见文档 + HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, + 0, + 0, + 0, + (short) 4, + 2, + (short) 6, + 5)); + // 设置注释内容 + comment.setString(new HSSFRichTextString("可以在POI中添加注释!")); + // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容. + comment.setAuthor("leno"); + + // 产生表格标题行 + HSSFRow row = sheet.createRow(0); + for (int i = 0; i < headers.length; i++) { + HSSFCell cell = row.createCell(i); + cell.setCellStyle(style); + HSSFRichTextString text = new HSSFRichTextString(headers[i]); + cell.setCellValue(text); + } + + // 遍历集合数据,产生数据行 + Iterator it = dataset.iterator(); + int index = 0; + while (it.hasNext()) { + index++; + row = sheet.createRow(index);// 行 + String[] t = (String[]) it.next(); + + for (int i = 0; i < t.length; i++) { + HSSFCell cell = row.createCell(i);// 行的格 + cell.setCellStyle(style2);// 行的样式 + HSSFRichTextString richString = new HSSFRichTextString(t[i]); + HSSFFont font3 = workbook.createFont(); + font3.setColor(HSSFColor.BLUE.index); + richString.applyFont(font3); + cell.setCellValue(richString); + } + } + try { + workbook.write(out); + } + catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/HttpUtil.java b/fuint-utils/src/main/java/com/fuint/utils/HttpUtil.java new file mode 100644 index 0000000..7433fc3 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/HttpUtil.java @@ -0,0 +1,147 @@ +package com.fuint.utils; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.HttpURLConnection; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.Map; + +/** + * http请求工具 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class HttpUtil { + + public static final int CONNECT_TIMEOUT = 30000; + public static final int READ_TIMEOUT = 60000; + public static final Charset UTF8 = Charset.forName("UTF-8"); + + public static byte[] toByteArray(Object obj) { + byte[] bytes = null; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + bytes = bos.toByteArray(); + oos.close(); + bos.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return bytes; + } + + /** + * 发送http请求 + * + * @param url + * @return + * @throws IOException + */ + public static String sendRequest(String url) { + URL myURL = null; + URLConnection httpsConn; + // 进行转码 + try { + myURL = new URL(url); + } catch (MalformedURLException e) { + // empty + } + StringBuffer sb = new StringBuffer(); + try { + httpsConn = myURL.openConnection(); + if (httpsConn != null) { + InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(), "UTF-8"); + BufferedReader br = new BufferedReader(insr); + String data = null; + while ((data = br.readLine()) != null) { + sb.append(data); + } + insr.close(); + } + } catch (IOException e) { + return ""; + } + + return sb.toString(); + } + + public static String sendRequest(URL url, String data, Method method, Map headers) throws IOException { + HttpURLConnection client = (HttpURLConnection) url.openConnection(); + client.setConnectTimeout(CONNECT_TIMEOUT); + client.setReadTimeout(READ_TIMEOUT); + client.setRequestMethod(method.value); + if (headers != null && headers.size() > 0) { + Iterator iter = headers.keySet().iterator(); + while (iter.hasNext()) { + String key = iter.next().toString(); + client.setRequestProperty(key, headers.get(key)); + } + } + if (Method.POST.equals(method)) { + // 发送数据 + if (data != null) { + client.setDoOutput(true); + OutputStreamWriter osw = new OutputStreamWriter(client.getOutputStream(), "UTF-8"); + osw.write(data); + osw.flush(); + osw.close(); + } + } + // 发送请求 + client.connect(); + if (client.getResponseCode() >= 300) { + throw new ServerUnavailable(url, client.getResponseCode(), client.getResponseMessage()); + } + + // 获取响应 + BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream(), UTF8)); + StringBuilder response = new StringBuilder(); + for (String line = in.readLine(); line != null; line = in.readLine()) { + response.append(line); + } + return response.toString(); + } + + public enum Method { + GET("GET"), + POST("POST"), + DELETE("DELETE"), + PUT("PUT"); + + /** + * 值 + */ + private String value; + + private Method(String value) { + this.value = value; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + } + + public static class ServerUnavailable extends RuntimeException { + /** + * serialVersionUID + */ + private static final long serialVersionUID = 1L; + + public ServerUnavailable(URL url, int code, String msg) { + super("url: " + url + ", code: " + code + ", msg: " + msg); + } + } + +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/IDCard.java b/fuint-utils/src/main/java/com/fuint/utils/IDCard.java new file mode 100644 index 0000000..95348f1 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/IDCard.java @@ -0,0 +1,416 @@ +package com.fuint.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.regex.Pattern; + +/** + * 身份证工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class IDCard { + + /** + * 省,直辖市代码表: { 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古", + * 21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏", + * 33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南", + * 42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆", + * 51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃", + * 63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"} + */ + protected String codeAndCity[][] = {{"11", "北京"}, {"12", "天津"}, + {"13", "河北"}, {"14", "山西"}, {"15", "内蒙古"}, {"21", "辽宁"}, + {"22", "吉林"}, {"23", "黑龙江"}, {"31", "上海"}, {"32", "江苏"}, + {"33", "浙江"}, {"34", "安徽"}, {"35", "福建"}, {"36", "江西"}, + {"37", "山东"}, {"41", "河南"}, {"42", "湖北"}, {"43", "湖南"}, + {"44", "广东"}, {"45", "广西"}, {"46", "海南"}, {"50", "重庆"}, + {"51", "四川"}, {"52", "贵州"}, {"53", "云南"}, {"54", "西藏"}, + {"61", "陕西"}, {"62", "甘肃"}, {"63", "青海"}, {"64", "宁夏"}, + {"65", "新疆"}, {"71", "台湾"}, {"81", "香港"}, {"82", "澳门"}, + {"91", "国外"}}; + + private final String cityCode[] = {"11", "12", "13", "14", "15", "21", "22", + "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43", + "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", + "64", "65", "71", "81", "82", "91"}; + + // 每位加权因子 + private int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + + // 第18位校检码 + private final String verifyCode[] = {"1", "0", "X", "9", "8", "7", "6", "5", + "4", "3", "2"}; + + /** + * 验证所有的身份证的合法性 + * + * @param idcard + * @return + */ + public boolean isValidatedAllIdcard(String idcard) { + if (idcard.length() == 15) { + idcard = this.convertIdcarBy15bit(idcard); + } + return this.isValidate18Idcard(idcard); + } + + /** + *

+ * 判断18位身份证的合法性 + *

+ * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。 + * 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 + *

+ * 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。 + *

+ *

+ * 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码; + * 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码; + * 6.第17位数字表示性别:奇数表示男性,偶数表示女性; + * 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。 + *

+ *

+ * 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 + * 2 1 6 3 7 9 10 5 8 4 2 + *

+ *

+ * 2.将这17位数字和系数相乘的结果相加。 + *

+ *

+ * 3.用加出来和除以11,看余数是多少? + *

+ * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 + * 2。 + *

+ * 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。 + *

+ * + * @param idcard + * @return + */ + public boolean isValidate18Idcard(String idcard) { + // 非18位为假 + if (idcard.length() != 18) { + return false; + } + // 获取前17位 + String idcard17 = idcard.substring(0, 17); + // 获取第18位 + String idcard18Code = idcard.substring(17, 18); + char c[] = null; + String checkCode = ""; + // 是否都为数字 + if (isDigital(idcard17)) { + c = idcard17.toCharArray(); + } else { + return false; + } + + if (null != c) { + int bit[] = new int[idcard17.length()]; + + bit = converCharToInt(c); + + int sum17 = 0; + + sum17 = getPowerSum(bit); + + // 将和值与11取模得到余数进行校验码判断 + checkCode = getCheckCodeBySum(sum17); + if (null == checkCode) { + return false; + } + // 将身份证的第18位与算出来的校码进行匹配,不相等就为假 + if (!idcard18Code.equalsIgnoreCase(checkCode)) { + return false; + } + } + return true; + } + + /** + * 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。 + * + * @param idcard + * @return + */ + public boolean isValidate15Idcard(String idcard) { + // 非15位为假 + if (idcard.length() != 15) { + return false; + } + + // 是否全都为数字 + if (isDigital(idcard)) { + String provinceid = idcard.substring(0, 2); + String birthday = idcard.substring(6, 12); + int year = Integer.parseInt(idcard.substring(6, 8)); + int month = Integer.parseInt(idcard.substring(8, 10)); + int day = Integer.parseInt(idcard.substring(10, 12)); + + // 判断是否为合法的省份 + boolean flag = false; + for (String id : cityCode) { + if (id.equals(provinceid)) { + flag = true; + break; + } + } + if (!flag) { + return false; + } + // 该身份证生出日期在当前日期之后时为假 + Date birthdate = null; + try { + birthdate = new SimpleDateFormat("yyMMdd").parse(birthday); + } catch (ParseException e) { + e.printStackTrace(); + } + if (birthdate == null || new Date().before(birthdate)) { + return false; + } + + // 判断是否为合法的年份 + GregorianCalendar curDay = new GregorianCalendar(); + int curYear = curDay.get(Calendar.YEAR); + int year2bit = Integer.parseInt(String.valueOf(curYear) + .substring(2)); + + // 判断该年份的两位表示法,小于50的和大于当前年份的,为假 + if ((year < 50 && year > year2bit)) { + return false; + } + + // 判断是否为合法的月份 + if (month < 1 || month > 12) { + return false; + } + + // 判断是否为合法的日期 + boolean mflag = false; + curDay.setTime(birthdate); // 将该身份证的出生日期赋于对象curDay + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + mflag = (day >= 1 && day <= 31); + break; + case 2: // 公历的2月非闰年有28天,闰年的2月是29天。 + if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) { + mflag = (day >= 1 && day <= 29); + } else { + mflag = (day >= 1 && day <= 28); + } + break; + case 4: + case 6: + case 9: + case 11: + mflag = (day >= 1 && day <= 30); + break; + } + if (!mflag) { + return false; + } + } else { + return false; + } + return true; + } + + /** + * 将15位的身份证转成18位身份证 + * + * @param idcard + * @return + */ + public String convertIdcarBy15bit(String idcard) { + String idcard17 = null; + // 非15位身份证 + if (idcard.length() != 15) { + return null; + } + + if (isDigital(idcard)) { + // 获取出生年月日 + String birthday = idcard.substring(6, 12); + Date birthdate = null; + try { + birthdate = new SimpleDateFormat("yyMMdd").parse(birthday); + } catch (ParseException e) { + e.printStackTrace(); + } + Calendar cday = Calendar.getInstance(); + cday.setTime(birthdate); + String year = String.valueOf(cday.get(Calendar.YEAR)); + + idcard17 = idcard.substring(0, 6) + year + idcard.substring(8); + + char c[] = idcard17.toCharArray(); + String checkCode = ""; + + if (null != c) { + int bit[] = new int[idcard17.length()]; + + // 将字符数组转为整型数组 + bit = converCharToInt(c); + int sum17 = 0; + sum17 = getPowerSum(bit); + + // 获取和值与11取模得到余数进行校验码 + checkCode = getCheckCodeBySum(sum17); + // 获取不到校验位 + if (null == checkCode) { + return null; + } + + // 将前17位与第18位校验码拼接 + idcard17 += checkCode; + } + } else { // 身份证包含数字 + return null; + } + return idcard17; + } + + /** + * 15位和18位身份证号码的基本数字和位数验校 + * + * @param idcard + * @return + */ + public boolean isIdcard(String idcard) { + return idcard == null || "".equals(idcard) ? false : Pattern.matches( + "(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)", idcard); + } + + /** + * 15位身份证号码的基本数字和位数验校 + * + * @param idcard + * @return + */ + public boolean is15Idcard(String idcard) { + return idcard == null || "".equals(idcard) ? false : Pattern.matches( + "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$", + idcard); + } + + /** + * 18位身份证号码的基本数字和位数验校 + * + * @param idcard + * @return + */ + public boolean is18Idcard(String idcard) { + return Pattern + .matches( + "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})$", + idcard); + } + + /** + * 数字验证 + * + * @param str + * @return + */ + public boolean isDigital(String str) { + return str == null || "".equals(str) ? false : str.matches("^[0-9]*$"); + } + + /** + * 将身份证的每位和对应位的加权因子相乘之后,再得到和值 + * + * @param bit + * @return + */ + public int getPowerSum(int[] bit) { + + int sum = 0; + + if (power.length != bit.length) { + return sum; + } + + for (int i = 0; i < bit.length; i++) { + for (int j = 0; j < power.length; j++) { + if (i == j) { + sum = sum + bit[i] * power[j]; + } + } + } + return sum; + } + + /** + * 将和值与11取模得到余数进行校验码判断 + * + * @param sum17 + * @return 校验位 + */ + public String getCheckCodeBySum(int sum17) { + String checkCode = null; + switch (sum17 % 11) { + case 10: + checkCode = "2"; + break; + case 9: + checkCode = "3"; + break; + case 8: + checkCode = "4"; + break; + case 7: + checkCode = "5"; + break; + case 6: + checkCode = "6"; + break; + case 5: + checkCode = "7"; + break; + case 4: + checkCode = "8"; + break; + case 3: + checkCode = "9"; + break; + case 2: + checkCode = "x"; + break; + case 1: + checkCode = "0"; + break; + case 0: + checkCode = "1"; + break; + } + return checkCode; + } + + /** + * 将字符数组转为整型数组 + * + * @param c + * @return + * @throws NumberFormatException + */ + public int[] converCharToInt(char[] c) throws NumberFormatException { + int[] a = new int[c.length]; + int k = 0; + for (char temp : c) { + a[k++] = Integer.parseInt(String.valueOf(temp)); + } + return a; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/IpUtil.java b/fuint-utils/src/main/java/com/fuint/utils/IpUtil.java new file mode 100644 index 0000000..19734b2 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/IpUtil.java @@ -0,0 +1,72 @@ +package com.fuint.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址工具类 + * + * Created by: FSQ + * CopyRight https://www.fuint.cn + */ +public class IpUtil { + + public static final Logger logger = LoggerFactory.getLogger(IpUtil.class); + + /** + * 校验IP是否在指定的段 + * + * @param ipSection IP网段,如: 10.167.7.1-10.167.7.255 + * @param ip Ip地址,如:10.167.7.56 + * @return boolean + */ + public static boolean ipIsValid(String ipSection, String ip) { + if (ipSection == null) { + throw new NullPointerException("IP段不能为空!"); + } + + if (ip == null) { + throw new NullPointerException("IP不能为空!"); + } + + ipSection = ipSection.trim(); + ip = ip.trim(); + final String REGX_IP = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + final String REGX_IPB = REGX_IP + "\\-" + REGX_IP; + if (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP)) + return false; + int idx = ipSection.indexOf('-'); + String[] sips = ipSection.substring(0, idx).split("\\."); + String[] sipe = ipSection.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验IP是否在指定的段列表 + * + * @param ip + * @param ipSections + * @return boolean + */ + public static boolean ipIsValid(String ip, String... ipSections) { + for (String ipSection : ipSections) { + if (ipIsValid(ipSection, ip)) { + return true; + } + } + return false; + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/MD5Util.java b/fuint-utils/src/main/java/com/fuint/utils/MD5Util.java new file mode 100644 index 0000000..112b102 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/MD5Util.java @@ -0,0 +1,41 @@ +package com.fuint.utils; + +import java.security.MessageDigest; + +/** + * MD5加密工具 + * + * Created by: FSQ + * CopyRight https://www.fuint.cn + */ +public class MD5Util { + private final static char[] hexDigits = {'0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + private static String bytesToHex(byte[] bytes) { + StringBuffer sb = new StringBuffer(); + int t; + for (int i = 0; i < 16; i++) {// 16 == bytes.length; + + t = bytes[i]; + if (t < 0) + t += 256; + sb.append(hexDigits[(t >>> 4)]); + sb.append(hexDigits[(t % 16)]); + } + return sb.toString(); + } + + public static String code(String input) { + byte[] bytes = null; + MessageDigest md = null; + try { + bytes = input.getBytes("utf-8"); + md = MessageDigest.getInstance(System.getProperty( + "MD5.algorithm", "MD5")); + } catch (Exception e) { + e.printStackTrace(); + } + return bytesToHex(md.digest(bytes)); + } +} \ No newline at end of file diff --git a/fuint-utils/src/main/java/com/fuint/utils/ObjectUtil.java b/fuint-utils/src/main/java/com/fuint/utils/ObjectUtil.java new file mode 100644 index 0000000..89942e3 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ObjectUtil.java @@ -0,0 +1,376 @@ +package com.fuint.utils; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * 有关Object处理的工具类。 + * + * 这个类中的每个方法都可以“安全”地处理null,而不会抛出NullPointerException。 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class ObjectUtil { + /* ============================================================================ */ + /* 常量和singleton。 */ + /* ============================================================================ */ + + /** + * 用于表示null的常量。 + * + *

+ * 例如,HashMap.get(Object)方法返回null有两种可能: + * 值不存在或值为null。而这个singleton可用来区别这两种情形。 + *

+ * + *

+ * 另一个例子是,Hashtable的值不能为null。 + *

+ */ + public static final Object NULL = new Serializable() { + private static final long serialVersionUID = 7092611880189329093L; + + private Object readResolve() { + return NULL; + } + }; + + /* ============================================================================ */ + /* 默认值函数。 */ + /* */ + /* 当对象为null时,将对象转换成指定的默认对象。 */ + /* ============================================================================ */ + + /** + * 如果对象为null,则返回指定默认对象,否则返回对象本身。 + *
+     * ObjectUtil.defaultIfNull(null, null)      = null
+     * ObjectUtil.defaultIfNull(null, "")        = ""
+     * ObjectUtil.defaultIfNull(null, "zz")      = "zz"
+     * ObjectUtil.defaultIfNull("abc", *)        = "abc"
+     * ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
+     * 
+ * + * @param object 要测试的对象 + * @param defaultValue 默认值 + * + * @return 对象本身或默认对象 + */ + public static Object defaultIfNull(Object object, Object defaultValue) { + return (object != null) ? object : defaultValue; + } + + /* ============================================================================ */ + /* 比较函数。 */ + /* */ + /* 以下方法用来比较两个对象是否相同。 */ + /* ============================================================================ */ + + /** + * 比较两个对象是否完全相等。 + * + *

+ * 此方法可以正确地比较多维数组。 + *

+     * ObjectUtil.equals(null, null)                  = true
+     * ObjectUtil.equals(null, "")                    = false
+     * ObjectUtil.equals("", null)                    = false
+     * ObjectUtil.equals("", "")                      = true
+     * ObjectUtil.equals(Boolean.TRUE, null)          = false
+     * ObjectUtil.equals(Boolean.TRUE, "true")        = false
+     * ObjectUtil.equals(Boolean.TRUE, Boolean.TRUE)  = true
+     * ObjectUtil.equals(Boolean.TRUE, Boolean.FALSE) = false
+     * 
+ *

+ * + * @param object1 对象1 + * @param object2 对象2 + * + * @return 如果相等, 则返回true + */ + public static boolean equals(Object object1, Object object2) { + return ArrayUtil.equals(object1, object2); + } + + /* ============================================================================ */ + /* Hashcode函数。 */ + /* */ + /* 以下方法用来取得对象的hash code。 */ + /* ============================================================================ */ + + /** + * 取得对象的hash值, 如果对象为null, 则返回0。 + * + *

+ * 此方法可以正确地处理多维数组。 + *

+ * + * @param object 对象 + * + * @return hash值 + */ + public static int hashCode(Object object) { + return ArrayUtil.hashCode(object); + } + + /** + * 取得对象的原始的hash值, 如果对象为null, 则返回0。 + * + *

+ * 该方法使用System.identityHashCode来取得hash值,该值不受对象本身的hashCode方法的影响。 + *

+ * + * @param object 对象 + * + * @return hash值 + */ + public static int identityHashCode(Object object) { + return (object == null) ? 0 : System.identityHashCode(object); + } + + /* ============================================================================ */ + /* 取得对象的identity。 */ + /* ============================================================================ */ + + /** + * 取得对象自身的identity,如同对象没有覆盖toString()方法时,Object.toString()的原始输出。 + *
+     * ObjectUtil.identityToString(null)          = null
+     * ObjectUtil.identityToString("")            = "java.lang.String@1e23"
+     * ObjectUtil.identityToString(Boolean.TRUE)  = "java.lang.Boolean@7fa"
+     * ObjectUtil.identityToString(new int[0])    = "int[]@7fa"
+     * ObjectUtil.identityToString(new Object[0]) = "java.lang.Object[]@7fa"
+     * 
+ * + * @param object 对象 + * + * @return 对象的identity,如果对象是null,则返回null + */ + public static String identityToString(Object object) { + if (object == null) { + return null; + } + + return appendIdentityToString(null, object).toString(); + } + + /** + * 取得对象自身的identity,如同对象没有覆盖toString()方法时,Object.toString()的原始输出。 + *
+     * ObjectUtil.identityToString(null, "NULL")            = "NULL"
+     * ObjectUtil.identityToString("", "NULL")              = "java.lang.String@1e23"
+     * ObjectUtil.identityToString(Boolean.TRUE, "NULL")    = "java.lang.Boolean@7fa"
+     * ObjectUtil.identityToString(new int[0], "NULL")      = "int[]@7fa"
+     * ObjectUtil.identityToString(new Object[0], "NULL")   = "java.lang.Object[]@7fa"
+     * 
+ * + * @param object 对象 + * @param nullStr 如果对象为null,则返回该字符串 + * + * @return 对象的identity,如果对象是null,则返回指定字符串 + */ + public static String identityToString(Object object, String nullStr) { + if (object == null) { + return nullStr; + } + + return appendIdentityToString(null, object).toString(); + } + + /** + * 将对象自身的identity——如同对象没有覆盖toString()方法时,Object.toString()的原始输出——追加到StringBuffer中。 + *
+     * ObjectUtil.appendIdentityToString(*, null)            = null
+     * ObjectUtil.appendIdentityToString(null, "")           = "java.lang.String@1e23"
+     * ObjectUtil.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
+     * ObjectUtil.appendIdentityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
+     * ObjectUtil.appendIdentityToString(buf, new int[0])    = buf.append("int[]@7fa")
+     * ObjectUtil.appendIdentityToString(buf, new Object[0]) = buf.append("java.lang.Object[]@7fa")
+     * 
+ * + * @param buffer StringBuffer对象,如果是null,则创建新的 + * @param object 对象 + * + * @return StringBuffer对象,如果对象为null,则返回null + */ + public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) { + if (object == null) { + return null; + } + + if (buffer == null) { + buffer = new StringBuffer(); + } + + buffer.append(ClassUtil.getClassNameForObject(object)); + + return buffer.append('@').append(Integer.toHexString(identityHashCode(object))); + } + + /* ============================================================================ */ + /* Clone函数。 */ + /* */ + /* 以下方法调用Object.clone方法,默认是“浅复制”(shallow copy)。 */ + /* ============================================================================ */ + + /** + * 复制一个对象。如果对象为null,则返回null。 + * + *

+ * 此方法调用Object.clone方法,默认只进行“浅复制”。 对于数组,调用ArrayUtil.clone方法更高效。 + *

+ * + * @param array 要复制的数组 + * + * @return 数组的复本,如果原始数组为null,则返回null + */ + public static Object clone(Object array) { + if (array == null) { + return null; + } + + // 对数组特殊处理 + if (array instanceof Object[]) { + return ArrayUtil.clone((Object[]) array); + } + + if (array instanceof long[]) { + return ArrayUtil.clone((long[]) array); + } + + if (array instanceof int[]) { + return ArrayUtil.clone((int[]) array); + } + + if (array instanceof short[]) { + return ArrayUtil.clone((short[]) array); + } + + if (array instanceof byte[]) { + return ArrayUtil.clone((byte[]) array); + } + + if (array instanceof double[]) { + return ArrayUtil.clone((double[]) array); + } + + if (array instanceof float[]) { + return ArrayUtil.clone((float[]) array); + } + + if (array instanceof boolean[]) { + return ArrayUtil.clone((boolean[]) array); + } + + if (array instanceof char[]) { + return ArrayUtil.clone((char[]) array); + } + + // Not cloneable + if (!(array instanceof Cloneable)) { + throw new RuntimeException("Object of class " + array.getClass().getName() + + " is not Cloneable"); + } + + // 用reflection调用clone方法 + Class clazz = array.getClass(); + + try { + Method cloneMethod = clazz.getMethod("clone", ArrayUtil.EMPTY_CLASS_ARRAY); + + return cloneMethod.invoke(array, ArrayUtil.EMPTY_OBJECT_ARRAY); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + /* ============================================================================ */ + /* 比较对象的类型。 */ + /* ============================================================================ */ + + /** + * 检查两个对象是否属于相同类型。null将被看作任意类型。 + * + * @param object1 对象1 + * @param object2 对象2 + * + * @return 如果两个对象有相同的类型,则返回true + */ + public static boolean isSameType(Object object1, Object object2) { + if ((object1 == null) || (object2 == null)) { + return true; + } + + return object1.getClass().equals(object2.getClass()); + } + + /* ============================================================================ */ + /* toString方法。 */ + /* ============================================================================ */ + + /** + * 取得对象的toString()的值,如果对象为null,则返回空字符串""。 + *
+     * ObjectUtil.toString(null)         = ""
+     * ObjectUtil.toString("")           = ""
+     * ObjectUtil.toString("bat")        = "bat"
+     * ObjectUtil.toString(Boolean.TRUE) = "true"
+     * ObjectUtil.toString([1, 2, 3])    = "[1, 2, 3]"
+     * 
+ * + * @param object 对象 + * + * @return 对象的toString()的返回值,或空字符串"" + */ + public static String toString(Object object) { + return (object == null) ? StringUtil.EMPTY_STRING + : (object.getClass().isArray() ? ArrayUtil.toString(object) : object.toString()); + } + + /** + * 取得对象的toString()的值,如果对象为null,则返回指定字符串。 + *
+     * ObjectUtil.toString(null, null)           = null
+     * ObjectUtil.toString(null, "null")         = "null"
+     * ObjectUtil.toString("", "null")           = ""
+     * ObjectUtil.toString("bat", "null")        = "bat"
+     * ObjectUtil.toString(Boolean.TRUE, "null") = "true"
+     * ObjectUtil.toString([1, 2, 3], "null")    = "[1, 2, 3]"
+     * 
+ * + * @param object 对象 + * @param nullStr 如果对象为null,则返回该字符串 + * + * @return 对象的toString()的返回值,或指定字符串 + */ + public static String toString(Object object, String nullStr) { + return (object == null) ? nullStr : (object.getClass().isArray() ? ArrayUtil + .toString(object) : object.toString()); + } + /** + * 数字格式化方法 为thyleaf服务 + * + * @param num + * @return + */ + public static String toNum(Double num){ + java.text.DecimalFormat df = new java.text.DecimalFormat("#.##"); + try{ + if(num == null){ + return ""; + }else{ + return df.format(num); + } + }catch(Exception e){ + return "" ; + } + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/PropertiesUtil.java b/fuint-utils/src/main/java/com/fuint/utils/PropertiesUtil.java new file mode 100644 index 0000000..c8b14ff --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/PropertiesUtil.java @@ -0,0 +1,57 @@ +package com.fuint.utils; + +import org.apache.commons.lang.StringUtils; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class PropertiesUtil { + + public static final ResourceBundle messageResource = ResourceBundle.getBundle("international.message", Locale.getDefault()); + + /** + * 获取请求返回Code对应的Message + * @param code + * @param params + * @return + */ + public static String getResponseErrorMessageByCode(int code, String...params) { + if (messageResource == null) { + return ""; + } + String pStr = messageResource.getString("response.error." + code); + if (StringUtils.isEmpty(pStr) || pStr == null) { + return ""; + } + if (params == null || params.length == 0) { + return pStr; + } + MessageFormat format = new MessageFormat(pStr, Locale.getDefault()); + return format.format(params); + } + + /** + * 根据Key值获取Value + * @param key + * @param params + * @return + */ + public static String getValueByKey(String key, String...params) { + String pStr = messageResource.getString(key); + if (messageResource == null) { + return ""; + } + if (StringUtils.isEmpty(pStr)) { + return ""; + } + if (params == null || params.length == 0) { + return pStr; + } + MessageFormat format = new MessageFormat(pStr, Locale.getDefault()); + return format.format(params); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/QRCodeUtil.java b/fuint-utils/src/main/java/com/fuint/utils/QRCodeUtil.java new file mode 100644 index 0000000..6e138dd --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/QRCodeUtil.java @@ -0,0 +1,40 @@ +package com.fuint.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.*; + +/** + * 二维码生成工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class QRCodeUtil { + + public static final Logger logger = LoggerFactory.getLogger(QRCodeUtil.class); + + /** + * 保存二维码 + * + * @param bytes + * @return + * */ + public static void saveQrCodeToLocal(byte[] bytes, String path) { + try { + InputStream inputStream = new ByteArrayInputStream(bytes); + FileOutputStream out = new FileOutputStream(path); + + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) { + out.write(buffer, 0, bytesRead); + } + out.flush(); + inputStream.close(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/RSAKeys.java b/fuint-utils/src/main/java/com/fuint/utils/RSAKeys.java new file mode 100644 index 0000000..5c6ff42 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/RSAKeys.java @@ -0,0 +1,15 @@ +package com.fuint.utils; +/** + * RSA公钥&私钥. + * */ +public interface RSAKeys { + /** + * 公钥 + * */ + public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxtLcYtsxohITlqO24KehQgJlq9k43XdpbIgjQXOht9eA9ypJKSlo1WbJUrJrKPGZ+2iELGe7dOQDL4Q+q1RGOXbBNRFQFqi8HZTHOz/krcQIuZYt7wjDu2P09zvgIvS+N6LaYrT7jddx+vN+Nk/ZZMcg/3ks/HAg7fBnCr2VcbQIDAQAB"; + + /** + * 私钥 + * */ + public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALG0txi2zGiEhOWo7bgp6FCAmWr2Tjdd2lsiCNBc6G314D3KkkpKWjVZslSsmso8Zn7aIQsZ7t05AMvhD6rVEY5dsE1EVAWqLwdlMc7P+StxAi5li3vCMO7Y/T3O+Ai9L43otpitPuN13H68342T9lkxyD/eSz8cCDt8GcKvZVxtAgMBAAECgYA+pbbmv4rQTeeMD0G+6wc7Whq72pk4a53PAvCYhChsm4GyRvfLuOqUZEq6Dx+CrEh17/A2Oa47zxy4w18CmprVPpdiM+mSUgcqMxVMJJSJPh5uuN3uw/6B6+NvD81gfDiwHrh5Irh2gJMTah52jMcguCce6OaZa6DG+jSYDaSPAQJBAOsuTAjEPxnpzRrbTZWGgoC9ftfXsdsZCu6wmKfDd2lWHf/Kf6+sNjWN6Hf1gG1tJVYpRS1o9e2yxTfPqrqJnZMCQQDBb+m0sb7Pz41S2mnk/STU4Z5GpeA4JJbbs+GSUzwfzZl9ZGMmJ1Ej1c+9n/BORgoGyrDDQrQPMidAyvR5gV3/AkBRfeBg5UeMPiSRGs6eclaEL6VlO1totRvBq7Wp5CRbfri0asGl6MF7+ylDb/FJeZmHapOK8aTN8bU+6pmZO5g7AkBMjIww3LJFLL6hjhuf6em8cPigvp3nudsVYK8gp93APC3EqIhwHdkHVGKciQGhCCiJnYasDuaQqOlNw8NRnjdjAkEAwh3THsHJArsSKmZYIM98+qgYpgQZVm7KNNxbKGu5IZPh0IV3NsxQYspE0cRBmzr3P3mAWPwPzh1sFHfFRw3UKQ=="; +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/SeqUtil.java b/fuint-utils/src/main/java/com/fuint/utils/SeqUtil.java new file mode 100644 index 0000000..1a01307 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/SeqUtil.java @@ -0,0 +1,122 @@ +package com.fuint.utils; + +import java.math.BigInteger; +import java.util.Calendar; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 序列工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class SeqUtil { + + /** + * 产生字符串序列(长度:32) + * + * @return String 32位字符串序列 + */ + public static String getUUID() { + String uuid = UUID.randomUUID().toString(); + return uuid.replaceAll("\\-", "").toUpperCase(); + } + + /** + * 产生日期序列(长度:32) + * [yyyyMMddHHmmssSSS+15位随机数] + * + * @return Long + */ + public static BigInteger getTimeSeq() { + String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS"); + StringBuilder sb = new StringBuilder(); + sb.append(date); + int length = 32 - sb.length(); + String randNum = getRandomNumber(length); + sb.append(randNum); + return new BigInteger(sb.toString()); + } + + /** + * 产生日期序列(长度:大于17位) + * [yyyyMMddHHmmssSSS+15位随机数] + * + * @return Long + */ + public static String getTimeSeq(int length) { + String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS"); + StringBuilder sb = new StringBuilder(); + sb.append(date); + length = length - sb.length(); + if (length > 0) { + String randNum = getRandomNumber(length); + sb.append(randNum); + } + return sb.toString(); + } + + /** + * 根据客户自定义前缀获取序列(长度:32) + * [前缀+yyyyMMddHHmmssSSS+随机数] + * + * @param prefix + * @return String + */ + public static String getCustSeq(String prefix) { + String date = CommonUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddHHmmssSSS"); + StringBuilder sb = new StringBuilder(prefix); + sb.append(date); + int length = 32 - sb.length(); + String randNum = getRandomNumber(length); + sb.append(randNum); + return sb.toString(); + } + + /** + * 产生指定长度随机字母 + * + * @param length + * @return String + */ + public static String getRandomLetter(int length) { + String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int rang = 26; + ThreadLocalRandom rand = ThreadLocalRandom.current(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + sb.append(base.charAt(rand.nextInt(rang))); + } + return sb.toString(); + } + + /** + * 产生指定长度随机数字 + * + * @param length + * @return String + */ + public static String getRandomNumber(int length) { + String base = "0123456789"; + int rang = 10; + ThreadLocalRandom rand = ThreadLocalRandom.current(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < length; i++) { + sb.append(base.charAt(rand.nextInt(rang))); + } + return sb.toString(); + } + + /** + * 产生指定区间的随机整数 + * + * @param min + * @param max + * @return int + */ + public static int getRandomNumber(int min, int max) { + ThreadLocalRandom rand = ThreadLocalRandom.current(); + return rand.nextInt(min, max); + } +} \ No newline at end of file diff --git a/fuint-utils/src/main/java/com/fuint/utils/StringUtil.java b/fuint-utils/src/main/java/com/fuint/utils/StringUtil.java new file mode 100644 index 0000000..f2d7e95 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/StringUtil.java @@ -0,0 +1,4210 @@ +package com.fuint.utils; + +import com.fuint.text.StrFormatter; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * 有关字符串处理的工具类。 + * + * 这个类中的每个方法都可以“安全”地处理null,而不会抛出NullPointerException。 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class StringUtil { + + /* ============================================================================ */ + /* 常量和singleton。 */ + /* ============================================================================ */ + + /** 空字符串。 */ + public static final String EMPTY_STRING = ""; + + /* ============================================================================ */ + /* 判空函数。 */ + /* */ + /* 以下方法用来判定一个字符串是否为: */ + /* 1. null */ + /* 2. empty - "" */ + /* 3. blank - "全部是空白" - 空白由Character.isWhitespace所定义。 */ + /* ============================================================================ */ + + /** + * 检查字符串是否为null或空字符串""。 + *
+     * StringUtil.isEmpty(null)      = true
+     * StringUtil.isEmpty("")        = true
+     * StringUtil.isEmpty(" ")       = false
+     * StringUtil.isEmpty("bob")     = false
+     * StringUtil.isEmpty("  bob  ") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果为空, 则返回true + */ + public static boolean isEmpty(String str) { + return ((str == null) || (str.length() == 0)); + } + + /** + * 检查字符串是否不是null和空字符串""。 + *
+     * StringUtil.isEmpty(null)      = false
+     * StringUtil.isEmpty("")        = false
+     * StringUtil.isEmpty(" ")       = true
+     * StringUtil.isEmpty("bob")     = true
+     * StringUtil.isEmpty("  bob  ") = true
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果不为空, 则返回true + */ + public static boolean isNotEmpty(String str) { + return ((str != null) && (str.length() > 0)); + } + + /** + * 检查字符串是否是空白:null、空字符串""或只有空白字符。 + *
+     * StringUtil.isBlank(null)      = true
+     * StringUtil.isBlank("")        = true
+     * StringUtil.isBlank(" ")       = true
+     * StringUtil.isBlank("bob")     = false
+     * StringUtil.isBlank("  bob  ") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果为空白, 则返回true + */ + public static boolean isBlank(String str) { + int length; + + if ((str == null) || ((length = str.length()) == 0)) { + return true; + } + + for (int i = 0; i < length; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return false; + } + } + + return true; + } + + /** + * 检查字符串是否不是空白:null、空字符串""或只有空白字符。 + *
+     * StringUtil.isBlank(null)      = false
+     * StringUtil.isBlank("")        = false
+     * StringUtil.isBlank(" ")       = false
+     * StringUtil.isBlank("bob")     = true
+     * StringUtil.isBlank("  bob  ") = true
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果为空白, 则返回true + */ + public static boolean isNotBlank(String str) { + int length; + + if ((str == null) || ((length = str.length()) == 0)) { + return false; + } + + for (int i = 0; i < length; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return true; + } + } + + return false; + } + + /** + * 如果字符串是null,则返回空字符串"",否则返回字符串本身。 + *
+     * StringUtil.defaultIfNull(null)  = ""
+     * StringUtil.defaultIfNull("")    = ""
+     * StringUtil.defaultIfNull("  ")  = "  "
+     * StringUtil.defaultIfNull("bat") = "bat"
+     * 
+ * + * @param str 要转换的字符串 + * + * @return 字符串本身或空字符串"" + */ + public static String defaultIfNull(String str) { + return (str == null) ? EMPTY_STRING : str; + } + + /** + * 如果字符串是null,则返回指定默认字符串,否则返回字符串本身。 + *
+     * StringUtil.defaultIfNull(null, "default")  = "default"
+     * StringUtil.defaultIfNull("", "default")    = ""
+     * StringUtil.defaultIfNull("  ", "default")  = "  "
+     * StringUtil.defaultIfNull("bat", "default") = "bat"
+     * 
+ * + * @param str 要转换的字符串 + * @param defaultStr 默认字符串 + * + * @return 字符串本身或指定的默认字符串 + */ + public static String defaultIfNull(String str, String defaultStr) { + return (str == null) ? defaultStr : str; + } + + /** + * 如果字符串是null或空字符串"",则返回空字符串"",否则返回字符串本身。 + * + *

+ * 此方法实际上和defaultIfNull(String)等效。 + *

+     * StringUtil.defaultIfEmpty(null)  = ""
+     * StringUtil.defaultIfEmpty("")    = ""
+     * StringUtil.defaultIfEmpty("  ")  = "  "
+     * StringUtil.defaultIfEmpty("bat") = "bat"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 字符串本身或空字符串"" + */ + public static String defaultIfEmpty(String str) { + return (str == null) ? EMPTY_STRING : str; + } + + /** + * 如果字符串是null或空字符串"",则返回指定默认字符串,否则返回字符串本身。 + *
+     * StringUtil.defaultIfEmpty(null, "default")  = "default"
+     * StringUtil.defaultIfEmpty("", "default")    = "default"
+     * StringUtil.defaultIfEmpty("  ", "default")  = "  "
+     * StringUtil.defaultIfEmpty("bat", "default") = "bat"
+     * 
+ * + * @param str 要转换的字符串 + * @param defaultStr 默认字符串 + * + * @return 字符串本身或指定的默认字符串 + */ + public static String defaultIfEmpty(String str, String defaultStr) { + return ((str == null) || (str.length() == 0)) ? defaultStr : str; + } + + /** + * 如果字符串是空白:null、空字符串""或只有空白字符,则返回空字符串"",否则返回字符串本身。 + *
+     * StringUtil.defaultIfBlank(null)  = ""
+     * StringUtil.defaultIfBlank("")    = ""
+     * StringUtil.defaultIfBlank("  ")  = ""
+     * StringUtil.defaultIfBlank("bat") = "bat"
+     * 
+ * + * @param str 要转换的字符串 + * + * @return 字符串本身或空字符串"" + */ + public static String defaultIfBlank(String str) { + return isBlank(str) ? EMPTY_STRING : str; + } + + /** + * 如果字符串是null或空字符串"",则返回指定默认字符串,否则返回字符串本身。 + *
+     * StringUtil.defaultIfBlank(null, "default")  = "default"
+     * StringUtil.defaultIfBlank("", "default")    = "default"
+     * StringUtil.defaultIfBlank("  ", "default")  = "default"
+     * StringUtil.defaultIfBlank("bat", "default") = "bat"
+     * 
+ * + * @param str 要转换的字符串 + * @param defaultStr 默认字符串 + * + * @return 字符串本身或指定的默认字符串 + */ + public static String defaultIfBlank(String str, String defaultStr) { + return isBlank(str) ? defaultStr : str; + } + + /* ============================================================================ */ + /* 去空白(或指定字符)的函数。 */ + /* */ + /* 以下方法用来除去一个字串中的空白或指定字符。 */ + /* ============================================================================ */ + + /** + * 除去字符串头尾部的空白,如果字符串是null,依然返回null。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trim(null)          = null
+     * StringUtil.trim("")            = ""
+     * StringUtil.trim("     ")       = ""
+     * StringUtil.trim("abc")         = "abc"
+     * StringUtil.trim("    abc    ") = "abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null,则返回null + */ + public static String trim(String str) { + return trim(str, null, 0); + } + + /** + * 除去字符串头尾部的指定字符,如果字符串是null,依然返回null。 + *
+     * StringUtil.trim(null, *)          = null
+     * StringUtil.trim("", *)            = ""
+     * StringUtil.trim("abc", null)      = "abc"
+     * StringUtil.trim("  abc", null)    = "abc"
+     * StringUtil.trim("abc  ", null)    = "abc"
+     * StringUtil.trim(" abc ", null)    = "abc"
+     * StringUtil.trim("  abcyx", "xyz") = "  abc"
+     * 
+ * + * @param str 要处理的字符串 + * @param stripChars 要除去的字符,如果为null表示除去空白字符 + * + * @return 除去指定字符后的的字符串,如果原字串为null,则返回null + */ + public static String trim(String str, String stripChars) { + return trim(str, stripChars, 0); + } + + /** + * 除去字符串头部的空白,如果字符串是null,则返回null。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trimStart(null)         = null
+     * StringUtil.trimStart("")           = ""
+     * StringUtil.trimStart("abc")        = "abc"
+     * StringUtil.trimStart("  abc")      = "abc"
+     * StringUtil.trimStart("abc  ")      = "abc  "
+     * StringUtil.trimStart(" abc ")      = "abc "
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimStart(String str) { + return trim(str, null, -1); + } + + /** + * 除去字符串头部的指定字符,如果字符串是null,依然返回null。 + *
+     * StringUtil.trimStart(null, *)          = null
+     * StringUtil.trimStart("", *)            = ""
+     * StringUtil.trimStart("abc", "")        = "abc"
+     * StringUtil.trimStart("abc", null)      = "abc"
+     * StringUtil.trimStart("  abc", null)    = "abc"
+     * StringUtil.trimStart("abc  ", null)    = "abc  "
+     * StringUtil.trimStart(" abc ", null)    = "abc "
+     * StringUtil.trimStart("yxabc  ", "xyz") = "abc  "
+     * 
+ * + * @param str 要处理的字符串 + * @param stripChars 要除去的字符,如果为null表示除去空白字符 + * + * @return 除去指定字符后的的字符串,如果原字串为null,则返回null + */ + public static String trimStart(String str, String stripChars) { + return trim(str, stripChars, -1); + } + + /** + * 除去字符串尾部的空白,如果字符串是null,则返回null。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trimEnd(null)       = null
+     * StringUtil.trimEnd("")         = ""
+     * StringUtil.trimEnd("abc")      = "abc"
+     * StringUtil.trimEnd("  abc")    = "  abc"
+     * StringUtil.trimEnd("abc  ")    = "abc"
+     * StringUtil.trimEnd(" abc ")    = " abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimEnd(String str) { + return trim(str, null, 1); + } + + /** + * 除去字符串尾部的指定字符,如果字符串是null,依然返回null。 + *
+     * StringUtil.trimEnd(null, *)          = null
+     * StringUtil.trimEnd("", *)            = ""
+     * StringUtil.trimEnd("abc", "")        = "abc"
+     * StringUtil.trimEnd("abc", null)      = "abc"
+     * StringUtil.trimEnd("  abc", null)    = "  abc"
+     * StringUtil.trimEnd("abc  ", null)    = "abc"
+     * StringUtil.trimEnd(" abc ", null)    = " abc"
+     * StringUtil.trimEnd("  abcyx", "xyz") = "  abc"
+     * 
+ * + * @param str 要处理的字符串 + * @param stripChars 要除去的字符,如果为null表示除去空白字符 + * + * @return 除去指定字符后的的字符串,如果原字串为null,则返回null + */ + public static String trimEnd(String str, String stripChars) { + return trim(str, stripChars, 1); + } + + /** + * 除去字符串头尾部的空白,如果结果字符串是空字符串"",则返回null。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trimToNull(null)          = null
+     * StringUtil.trimToNull("")            = null
+     * StringUtil.trimToNull("     ")       = null
+     * StringUtil.trimToNull("abc")         = "abc"
+     * StringUtil.trimToNull("    abc    ") = "abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimToNull(String str) { + return trimToNull(str, null); + } + + /** + * 除去字符串头尾部的空白,如果结果字符串是空字符串"",则返回null。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trim(null, *)          = null
+     * StringUtil.trim("", *)            = null
+     * StringUtil.trim("abc", null)      = "abc"
+     * StringUtil.trim("  abc", null)    = "abc"
+     * StringUtil.trim("abc  ", null)    = "abc"
+     * StringUtil.trim(" abc ", null)    = "abc"
+     * StringUtil.trim("  abcyx", "xyz") = "  abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * @param stripChars 要除去的字符,如果为null表示除去空白字符 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimToNull(String str, String stripChars) { + String result = trim(str, stripChars); + + if ((result == null) || (result.length() == 0)) { + return null; + } + + return result; + } + + /** + * 除去字符串头尾部的空白,如果字符串是null,则返回空字符串""。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trimToEmpty(null)          = ""
+     * StringUtil.trimToEmpty("")            = ""
+     * StringUtil.trimToEmpty("     ")       = ""
+     * StringUtil.trimToEmpty("abc")         = "abc"
+     * StringUtil.trimToEmpty("    abc    ") = "abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimToEmpty(String str) { + return trimToEmpty(str, null); + } + + /** + * 除去字符串头尾部的空白,如果字符串是null,则返回空字符串""。 + * + *

+ * 注意,和String.trim不同,此方法使用Character.isWhitespace来判定空白, + * 因而可以除去英文字符集之外的其它空白,如中文空格。 + *

+     * StringUtil.trim(null, *)          = ""
+     * StringUtil.trim("", *)            = ""
+     * StringUtil.trim("abc", null)      = "abc"
+     * StringUtil.trim("  abc", null)    = "abc"
+     * StringUtil.trim("abc  ", null)    = "abc"
+     * StringUtil.trim(" abc ", null)    = "abc"
+     * StringUtil.trim("  abcyx", "xyz") = "  abc"
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 除去空白的字符串,如果原字串为null或结果字符串为"",则返回null + */ + public static String trimToEmpty(String str, String stripChars) { + String result = trim(str, stripChars); + + if (result == null) { + return EMPTY_STRING; + } + + return result; + } + + /** + * 除去字符串头尾部的指定字符,如果字符串是null,依然返回null。 + *
+     * StringUtil.trim(null, *)          = null
+     * StringUtil.trim("", *)            = ""
+     * StringUtil.trim("abc", null)      = "abc"
+     * StringUtil.trim("  abc", null)    = "abc"
+     * StringUtil.trim("abc  ", null)    = "abc"
+     * StringUtil.trim(" abc ", null)    = "abc"
+     * StringUtil.trim("  abcyx", "xyz") = "  abc"
+     * 
+ * + * @param str 要处理的字符串 + * @param stripChars 要除去的字符,如果为null表示除去空白字符 + * @param mode -1表示trimStart,0表示trim全部,1表示trimEnd + * + * @return 除去指定字符后的的字符串,如果原字串为null,则返回null + */ + private static String trim(String str, String stripChars, int mode) { + if (str == null) { + return null; + } + + int length = str.length(); + int start = 0; + int end = length; + + // 扫描字符串头部 + if (mode <= 0) { + if (stripChars == null) { + while ((start < end) && (Character.isWhitespace(str.charAt(start)))) { + start++; + } + } else if (stripChars.length() == 0) { + return str; + } else { + while ((start < end) && (stripChars.indexOf(str.charAt(start)) != -1)) { + start++; + } + } + } + + // 扫描字符串尾部 + if (mode >= 0) { + if (stripChars == null) { + while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) { + end--; + } + } else if (stripChars.length() == 0) { + return str; + } else { + while ((start < end) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) { + end--; + } + } + } + + if ((start > 0) || (end < length)) { + return str.substring(start, end); + } + + return str; + } + + /* ============================================================================ */ + /* 比较函数。 */ + /* */ + /* 以下方法用来比较两个字符串是否相同。 */ + /* ============================================================================ */ + + /** + * 比较两个字符串(大小写敏感)。 + *
+     * StringUtil.equals(null, null)   = true
+     * StringUtil.equals(null, "abc")  = false
+     * StringUtil.equals("abc", null)  = false
+     * StringUtil.equals("abc", "abc") = true
+     * StringUtil.equals("abc", "ABC") = false
+     * 
+ * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * + * @return 如果两个字符串相同,或者都是null,则返回true + */ + public static boolean equals(String str1, String str2) { + if (str1 == null) { + return str2 == null; + } + + return str1.equals(str2); + } + + /** + * 比较两个字符串(大小写不敏感)。 + *
+     * StringUtil.equalsIgnoreCase(null, null)   = true
+     * StringUtil.equalsIgnoreCase(null, "abc")  = false
+     * StringUtil.equalsIgnoreCase("abc", null)  = false
+     * StringUtil.equalsIgnoreCase("abc", "abc") = true
+     * StringUtil.equalsIgnoreCase("abc", "ABC") = true
+     * 
+ * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * + * @return 如果两个字符串相同,或者都是null,则返回true + */ + public static boolean equalsIgnoreCase(String str1, String str2) { + if (str1 == null) { + return str2 == null; + } + + return str1.equalsIgnoreCase(str2); + } + + /* ============================================================================ */ + /* 字符串类型判定函数。 */ + /* */ + /* 判定字符串的类型是否为:字母、数字、空白等 */ + /* ============================================================================ */ + + /** + * 判断字符串是否只包含unicode字母。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isAlpha(null)   = false
+     * StringUtil.isAlpha("")     = true
+     * StringUtil.isAlpha("  ")   = false
+     * StringUtil.isAlpha("abc")  = true
+     * StringUtil.isAlpha("ab2c") = false
+     * StringUtil.isAlpha("ab-c") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode字母组成,则返回true + */ + public static boolean isAlpha(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isLetter(str.charAt(i))) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode字母和空格' '。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isAlphaSpace(null)   = false
+     * StringUtil.isAlphaSpace("")     = true
+     * StringUtil.isAlphaSpace("  ")   = true
+     * StringUtil.isAlphaSpace("abc")  = true
+     * StringUtil.isAlphaSpace("ab c") = true
+     * StringUtil.isAlphaSpace("ab2c") = false
+     * StringUtil.isAlphaSpace("ab-c") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode字母和空格组成,则返回true + */ + public static boolean isAlphaSpace(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isLetter(str.charAt(i)) && (str.charAt(i) != ' ')) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode字母和数字。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isAlphanumeric(null)   = false
+     * StringUtil.isAlphanumeric("")     = true
+     * StringUtil.isAlphanumeric("  ")   = false
+     * StringUtil.isAlphanumeric("abc")  = true
+     * StringUtil.isAlphanumeric("ab c") = false
+     * StringUtil.isAlphanumeric("ab2c") = true
+     * StringUtil.isAlphanumeric("ab-c") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode字母数字组成,则返回true + */ + public static boolean isAlphanumeric(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isLetterOrDigit(str.charAt(i))) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode字母数字和空格' '。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isAlphanumericSpace(null)   = false
+     * StringUtil.isAlphanumericSpace("")     = true
+     * StringUtil.isAlphanumericSpace("  ")   = true
+     * StringUtil.isAlphanumericSpace("abc")  = true
+     * StringUtil.isAlphanumericSpace("ab c") = true
+     * StringUtil.isAlphanumericSpace("ab2c") = true
+     * StringUtil.isAlphanumericSpace("ab-c") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode字母数字和空格组成,则返回true + */ + public static boolean isAlphanumericSpace(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isLetterOrDigit(str.charAt(i)) && (str.charAt(i) != ' ')) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode数字。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isNumeric(null)   = false
+     * StringUtil.isNumeric("")     = true
+     * StringUtil.isNumeric("  ")   = false
+     * StringUtil.isNumeric("123")  = true
+     * StringUtil.isNumeric("12 3") = false
+     * StringUtil.isNumeric("ab2c") = false
+     * StringUtil.isNumeric("12-3") = false
+     * StringUtil.isNumeric("12.3") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode数字组成,则返回true + */ + public static boolean isNumeric(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isDigit(str.charAt(i))) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode数字和空格' '。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isNumericSpace(null)   = false
+     * StringUtil.isNumericSpace("")     = true
+     * StringUtil.isNumericSpace("  ")   = true
+     * StringUtil.isNumericSpace("123")  = true
+     * StringUtil.isNumericSpace("12 3") = true
+     * StringUtil.isNumericSpace("ab2c") = false
+     * StringUtil.isNumericSpace("12-3") = false
+     * StringUtil.isNumericSpace("12.3") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode数字和空格组成,则返回true + */ + public static boolean isNumericSpace(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isDigit(str.charAt(i)) && (str.charAt(i) != ' ')) { + return false; + } + } + + return true; + } + + /** + * 判断字符串是否只包含unicode空白。 + * + *

+ * null将返回false,空字符串""将返回true。 + *

+ *
+     * StringUtil.isWhitespace(null)   = false
+     * StringUtil.isWhitespace("")     = true
+     * StringUtil.isWhitespace("  ")   = true
+     * StringUtil.isWhitespace("abc")  = false
+     * StringUtil.isWhitespace("ab2c") = false
+     * StringUtil.isWhitespace("ab-c") = false
+     * 
+ * + * @param str 要检查的字符串 + * + * @return 如果字符串非null并且全由unicode空白组成,则返回true + */ + public static boolean isWhitespace(String str) { + if (str == null) { + return false; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return false; + } + } + + return true; + } + + /* ============================================================================ */ + /* 大小写转换。 */ + /* ============================================================================ */ + + /** + * 将字符串转换成大写。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toUpperCase(null)  = null
+     * StringUtil.toUpperCase("")    = ""
+     * StringUtil.toUpperCase("aBc") = "ABC"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 大写字符串,如果原字符串为null,则返回null + */ + public static String toUpperCase(String str) { + if (str == null) { + return null; + } + + return str.toUpperCase(); + } + + /** + * 将字符串转换成小写。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toLowerCase(null)  = null
+     * StringUtil.toLowerCase("")    = ""
+     * StringUtil.toLowerCase("aBc") = "abc"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 大写字符串,如果原字符串为null,则返回null + */ + public static String toLowerCase(String str) { + if (str == null) { + return null; + } + + return str.toLowerCase(); + } + + /** + * 将字符串的首字符转成大写(Character.toTitleCase),其它字符不变。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.capitalize(null)  = null
+     * StringUtil.capitalize("")    = ""
+     * StringUtil.capitalize("cat") = "Cat"
+     * StringUtil.capitalize("cAt") = "CAt"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 首字符为大写的字符串,如果原字符串为null,则返回null + */ + public static String capitalize(String str) { + int strLen; + + if ((str == null) || ((strLen = str.length()) == 0)) { + return str; + } + + return new StringBuffer(strLen).append(Character.toTitleCase(str.charAt(0))) + .append(str.substring(1)).toString(); + } + + /** + * 将字符串的首字符转成小写,其它字符不变。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.uncapitalize(null)  = null
+     * StringUtil.uncapitalize("")    = ""
+     * StringUtil.uncapitalize("Cat") = "cat"
+     * StringUtil.uncapitalize("CAT") = "cAT"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 首字符为小写的字符串,如果原字符串为null,则返回null + */ + public static String uncapitalize(String str) { + int strLen; + + if ((str == null) || ((strLen = str.length()) == 0)) { + return str; + } + + return new StringBuffer(strLen).append(Character.toLowerCase(str.charAt(0))) + .append(str.substring(1)).toString(); + } + + /** + * 反转字符串的大小写。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.swapCase(null)                 = null
+     * StringUtil.swapCase("")                   = ""
+     * StringUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+     * 
+ *

+ * + * @param str 要转换的字符串 + * + * @return 大小写被反转的字符串,如果原字符串为null,则返回null + */ + public static String swapCase(String str) { + int strLen; + + if ((str == null) || ((strLen = str.length()) == 0)) { + return str; + } + + StringBuffer buffer = new StringBuffer(strLen); + + char ch = 0; + + for (int i = 0; i < strLen; i++) { + ch = str.charAt(i); + + if (Character.isUpperCase(ch)) { + ch = Character.toLowerCase(ch); + } else if (Character.isTitleCase(ch)) { + ch = Character.toLowerCase(ch); + } else if (Character.isLowerCase(ch)) { + ch = Character.toUpperCase(ch); + } + + buffer.append(ch); + } + + return buffer.toString(); + } + + /** + * 将字符串转换成camel case。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toCamelCase(null)  = null
+     * StringUtil.toCamelCase("")    = ""
+     * StringUtil.toCamelCase("aBc") = "aBc"
+     * StringUtil.toCamelCase("aBc def") = "aBcDef"
+     * StringUtil.toCamelCase("aBc def_ghi") = "aBcDefGhi"
+     * StringUtil.toCamelCase("aBc def_ghi 123") = "aBcDefGhi123"
+     * 
+ *

+ * + *

+ * 此方法会保留除了下划线和空白以外的所有分隔符。 + *

+ * + * @param str 要转换的字符串 + * + * @return camel case字符串,如果原字符串为null,则返回null + */ + public static String toCamelCase(String str) { + return CAMEL_CASE_TOKENIZER.parse(str); + } + + /** + * 将字符串转换成pascal case。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toPascalCase(null)  = null
+     * StringUtil.toPascalCase("")    = ""
+     * StringUtil.toPascalCase("aBc") = "ABc"
+     * StringUtil.toPascalCase("aBc def") = "ABcDef"
+     * StringUtil.toPascalCase("aBc def_ghi") = "ABcDefGhi"
+     * StringUtil.toPascalCase("aBc def_ghi 123") = "aBcDefGhi123"
+     * 
+ *

+ * + *

+ * 此方法会保留除了下划线和空白以外的所有分隔符。 + *

+ * + * @param str 要转换的字符串 + * + * @return pascal case字符串,如果原字符串为null,则返回null + */ + public static String toPascalCase(String str) { + return PASCAL_CASE_TOKENIZER.parse(str); + } + + /** + * 将字符串转换成下划线分隔的大写字符串。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toUpperCaseWithUnderscores(null)  = null
+     * StringUtil.toUpperCaseWithUnderscores("")    = ""
+     * StringUtil.toUpperCaseWithUnderscores("aBc") = "A_BC"
+     * StringUtil.toUpperCaseWithUnderscores("aBc def") = "A_BC_DEF"
+     * StringUtil.toUpperCaseWithUnderscores("aBc def_ghi") = "A_BC_DEF_GHI"
+     * StringUtil.toUpperCaseWithUnderscores("aBc def_ghi 123") = "A_BC_DEF_GHI_123"
+     * StringUtil.toUpperCaseWithUnderscores("__a__Bc__") = "__A__BC__"
+     * 
+ *

+ * + *

+ * 此方法会保留除了空白以外的所有分隔符。 + *

+ * + * @param str 要转换的字符串 + * + * @return 下划线分隔的大写字符串,如果原字符串为null,则返回null + */ + public static String toUpperCaseWithUnderscores(String str) { + return UPPER_CASE_WITH_UNDERSCORES_TOKENIZER.parse(str); + } + + /** + * 将字符串转换成下划线分隔的小写字符串。 + * + *

+ * 如果字符串是null则返回null。 + *

+     * StringUtil.toLowerCaseWithUnderscores(null)  = null
+     * StringUtil.toLowerCaseWithUnderscores("")    = ""
+     * StringUtil.toLowerCaseWithUnderscores("aBc") = "a_bc"
+     * StringUtil.toLowerCaseWithUnderscores("aBc def") = "a_bc_def"
+     * StringUtil.toLowerCaseWithUnderscores("aBc def_ghi") = "a_bc_def_ghi"
+     * StringUtil.toLowerCaseWithUnderscores("aBc def_ghi 123") = "a_bc_def_ghi_123"
+     * StringUtil.toLowerCaseWithUnderscores("__a__Bc__") = "__a__bc__"
+     * 
+ *

+ * + *

+ * 此方法会保留除了空白以外的所有分隔符。 + *

+ * + * @param str 要转换的字符串 + * + * @return 下划线分隔的小写字符串,如果原字符串为null,则返回null + */ + public static String toLowerCaseWithUnderscores(String str) { + return LOWER_CASE_WITH_UNDERSCORES_TOKENIZER.parse(str); + } + + /** 解析单词的解析器。 */ + private static final WordTokenizer CAMEL_CASE_TOKENIZER = new WordTokenizer() { + protected void startSentence(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void startWord(StringBuffer buffer, + char ch) { + if (!isDelimiter(buffer + .charAt(buffer + .length() - 1))) { + buffer + .append(Character + .toUpperCase(ch)); + } else { + buffer + .append(Character + .toLowerCase(ch)); + } + } + + protected void inWord(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void startDigitSentence(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void startDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDelimiter(StringBuffer buffer, + char ch) { + if (ch != UNDERSCORE) { + buffer + .append(ch); + } + } + }; + + private static final WordTokenizer PASCAL_CASE_TOKENIZER = new WordTokenizer() { + protected void startSentence(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toUpperCase(ch)); + } + + protected void startWord(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toUpperCase(ch)); + } + + protected void inWord(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void startDigitSentence(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void startDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDelimiter(StringBuffer buffer, + char ch) { + if (ch != UNDERSCORE) { + buffer + .append(ch); + } + } + }; + + private static final WordTokenizer UPPER_CASE_WITH_UNDERSCORES_TOKENIZER = new WordTokenizer() { + protected void startSentence(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toUpperCase(ch)); + } + + protected void startWord(StringBuffer buffer, + char ch) { + if (!isDelimiter(buffer + .charAt(buffer + .length() - 1))) { + buffer + .append(UNDERSCORE); + } + + buffer + .append(Character + .toUpperCase(ch)); + } + + protected void inWord(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toUpperCase(ch)); + } + + protected void startDigitSentence(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void startDigitWord(StringBuffer buffer, + char ch) { + if (!isDelimiter(buffer + .charAt(buffer + .length() - 1))) { + buffer + .append(UNDERSCORE); + } + + buffer + .append(ch); + } + + protected void inDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDelimiter(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + }; + + private static final WordTokenizer LOWER_CASE_WITH_UNDERSCORES_TOKENIZER = new WordTokenizer() { + protected void startSentence(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void startWord(StringBuffer buffer, + char ch) { + if (!isDelimiter(buffer + .charAt(buffer + .length() - 1))) { + buffer + .append(UNDERSCORE); + } + + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void inWord(StringBuffer buffer, + char ch) { + buffer + .append(Character + .toLowerCase(ch)); + } + + protected void startDigitSentence(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void startDigitWord(StringBuffer buffer, + char ch) { + if (!isDelimiter(buffer + .charAt(buffer + .length() - 1))) { + buffer + .append(UNDERSCORE); + } + + buffer + .append(ch); + } + + protected void inDigitWord(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + + protected void inDelimiter(StringBuffer buffer, + char ch) { + buffer + .append(ch); + } + }; + + /** + * 解析出下列语法所构成的SENTENCE。 + *
+     *  SENTENCE = WORD (DELIMITER* WORD)*
+     *
+     *  WORD = UPPER_CASE_WORD | LOWER_CASE_WORD | TITLE_CASE_WORD | DIGIT_WORD
+     *
+     *  UPPER_CASE_WORD = UPPER_CASE_LETTER+
+     *  LOWER_CASE_WORD = LOWER_CASE_LETTER+
+     *  TITLE_CASE_WORD = UPPER_CASE_LETTER LOWER_CASE_LETTER+
+     *  DIGIT_WORD      = DIGIT+
+     *
+     *  UPPER_CASE_LETTER = Character.isUpperCase()
+     *  LOWER_CASE_LETTER = Character.isLowerCase()
+     *  DIGIT             = Character.isDigit()
+     *  NON_LETTER_DIGIT  = !Character.isUpperCase() && !Character.isLowerCase() && !Character.isDigit()
+     *
+     *  DELIMITER = WHITESPACE | NON_LETTER_DIGIT
+     * 
+ */ + private abstract static class WordTokenizer { + protected static final char UNDERSCORE = '_'; + + /** + * Parse sentence。 + */ + public String parse(String str) { + if (StringUtil.isEmpty(str)) { + return str; + } + + int length = str.length(); + StringBuffer buffer = new StringBuffer(length); + + for (int index = 0; index < length; index++) { + char ch = str.charAt(index); + + // 忽略空白。 + if (Character.isWhitespace(ch)) { + continue; + } + + // 大写字母开始:UpperCaseWord或是TitleCaseWord。 + if (Character.isUpperCase(ch)) { + int wordIndex = index + 1; + + while (wordIndex < length) { + char wordChar = str.charAt(wordIndex); + + if (Character.isUpperCase(wordChar)) { + wordIndex++; + } else if (Character.isLowerCase(wordChar)) { + wordIndex--; + break; + } else { + break; + } + } + + // 1. wordIndex == length,说明最后一个字母为大写,以upperCaseWord处理之。 + // 2. wordIndex == index,说明index处为一个titleCaseWord。 + // 3. wordIndex > index,说明index到wordIndex - 1处全部是大写,以upperCaseWord处理。 + if ((wordIndex == length) || (wordIndex > index)) { + index = parseUpperCaseWord(buffer, str, index, wordIndex); + } else { + index = parseTitleCaseWord(buffer, str, index); + } + + continue; + } + + // 小写字母开始:LowerCaseWord。 + if (Character.isLowerCase(ch)) { + index = parseLowerCaseWord(buffer, str, index); + continue; + } + + // 数字开始:DigitWord。 + if (Character.isDigit(ch)) { + index = parseDigitWord(buffer, str, index); + continue; + } + + // 非字母数字开始:Delimiter。 + inDelimiter(buffer, ch); + } + + return buffer.toString(); + } + + private int parseUpperCaseWord(StringBuffer buffer, String str, int index, int length) { + char ch = str.charAt(index++); + + // 首字母,必然存在且为大写。 + if (buffer.length() == 0) { + startSentence(buffer, ch); + } else { + startWord(buffer, ch); + } + + // 后续字母,必为小写。 + for (; index < length; index++) { + ch = str.charAt(index); + inWord(buffer, ch); + } + + return index - 1; + } + + private int parseLowerCaseWord(StringBuffer buffer, String str, int index) { + char ch = str.charAt(index++); + + // 首字母,必然存在且为小写。 + if (buffer.length() == 0) { + startSentence(buffer, ch); + } else { + startWord(buffer, ch); + } + + // 后续字母,必为小写。 + int length = str.length(); + + for (; index < length; index++) { + ch = str.charAt(index); + + if (Character.isLowerCase(ch)) { + inWord(buffer, ch); + } else { + break; + } + } + + return index - 1; + } + + private int parseTitleCaseWord(StringBuffer buffer, String str, int index) { + char ch = str.charAt(index++); + + // 首字母,必然存在且为大写。 + if (buffer.length() == 0) { + startSentence(buffer, ch); + } else { + startWord(buffer, ch); + } + + // 后续字母,必为小写。 + int length = str.length(); + + for (; index < length; index++) { + ch = str.charAt(index); + + if (Character.isLowerCase(ch)) { + inWord(buffer, ch); + } else { + break; + } + } + + return index - 1; + } + + private int parseDigitWord(StringBuffer buffer, String str, int index) { + char ch = str.charAt(index++); + + // 首字符,必然存在且为数字。 + if (buffer.length() == 0) { + startDigitSentence(buffer, ch); + } else { + startDigitWord(buffer, ch); + } + + // 后续字符,必为数字。 + int length = str.length(); + + for (; index < length; index++) { + ch = str.charAt(index); + + if (Character.isDigit(ch)) { + inDigitWord(buffer, ch); + } else { + break; + } + } + + return index - 1; + } + + protected boolean isDelimiter(char ch) { + return !Character.isUpperCase(ch) && !Character.isLowerCase(ch) + && !Character.isDigit(ch); + } + + protected abstract void startSentence(StringBuffer buffer, char ch); + + protected abstract void startWord(StringBuffer buffer, char ch); + + protected abstract void inWord(StringBuffer buffer, char ch); + + protected abstract void startDigitSentence(StringBuffer buffer, char ch); + + protected abstract void startDigitWord(StringBuffer buffer, char ch); + + protected abstract void inDigitWord(StringBuffer buffer, char ch); + + protected abstract void inDelimiter(StringBuffer buffer, char ch); + } + + /* ============================================================================ */ + /* 字符串分割函数。 */ + /* */ + /* 将字符串按指定分隔符分割。 */ + /* ============================================================================ */ + + /** + * 将字符串按空白字符分割。 + * + *

+ * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为null,则返回null。 + *

+     * StringUtil.split(null)       = null
+     * StringUtil.split("")         = []
+     * StringUtil.split("abc def")  = ["abc", "def"]
+     * StringUtil.split("abc  def") = ["abc", "def"]
+     * StringUtil.split(" abc ")    = ["abc"]
+     * 
+ *

+ * + * @param str 要分割的字符串 + * + * @return 分割后的字符串数组,如果原字符串为null,则返回null + */ + public static String[] split(String str) { + return split(str, null, -1); + } + + /** + * 将字符串按指定字符分割。 + * + *

+ * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为null,则返回null。 + *

+     * StringUtil.split(null, *)         = null
+     * StringUtil.split("", *)           = []
+     * StringUtil.split("a.b.c", '.')    = ["a", "b", "c"]
+     * StringUtil.split("a..b.c", '.')   = ["a", "b", "c"]
+     * StringUtil.split("a:b:c", '.')    = ["a:b:c"]
+     * StringUtil.split("a b c", ' ')    = ["a", "b", "c"]
+     * 
+ *

+ * + * @param str 要分割的字符串 + * @param separatorChar 分隔符 + * + * @return 分割后的字符串数组,如果原字符串为null,则返回null + */ + public static String[] split(String str, char separatorChar) { + if (str == null) { + return null; + } + + int length = str.length(); + + if (length == 0) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + List list = new ArrayList(); + int i = 0; + int start = 0; + boolean match = false; + + while (i < length) { + if (str.charAt(i) == separatorChar) { + if (match) { + list.add(str.substring(start, i)); + match = false; + } + + start = ++i; + continue; + } + + match = true; + i++; + } + + if (match) { + list.add(str.substring(start, i)); + } + + return (String[]) list.toArray(new String[list.size()]); + } + + /** + * 将字符串按指定字符分割。 + * + *

+ * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为null,则返回null。 + *

+     * StringUtil.split(null, *)                = null
+     * StringUtil.split("", *)                  = []
+     * StringUtil.split("abc def", null)        = ["abc", "def"]
+     * StringUtil.split("abc def", " ")         = ["abc", "def"]
+     * StringUtil.split("abc  def", " ")        = ["abc", "def"]
+     * StringUtil.split(" ab:  cd::ef  ", ":")  = ["ab", "cd", "ef"]
+     * StringUtil.split("abc.def", "")          = ["abc.def"]
+     *  
+ *

+ * + * @param str 要分割的字符串 + * @param separatorChars 分隔符 + * + * @return 分割后的字符串数组,如果原字符串为null,则返回null + */ + public static String[] split(String str, String separatorChars) { + return split(str, separatorChars, -1); + } + + /** + * 将字符串按指定字符分割。 + * + *

+ * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为null,则返回null。 + *

+     * StringUtil.split(null, *, *)                 = null
+     * StringUtil.split("", *, *)                   = []
+     * StringUtil.split("ab cd ef", null, 0)        = ["ab", "cd", "ef"]
+     * StringUtil.split("  ab   cd ef  ", null, 0)  = ["ab", "cd", "ef"]
+     * StringUtil.split("ab:cd::ef", ":", 0)        = ["ab", "cd", "ef"]
+     * StringUtil.split("ab:cd:ef", ":", 2)         = ["ab", "cdef"]
+     * StringUtil.split("abc.def", "", 2)           = ["abc.def"]
+     * 
+ *

+ * + * @param str 要分割的字符串 + * @param separatorChars 分隔符 + * @param max 返回的数组的最大个数,如果小于等于0,则表示无限制 + * + * @return 分割后的字符串数组,如果原字符串为null,则返回null + */ + public static String[] split(String str, String separatorChars, int max) { + if (str == null) { + return null; + } + + int length = str.length(); + + if (length == 0) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + List list = new ArrayList(); + int sizePlus1 = 1; + int i = 0; + int start = 0; + boolean match = false; + + if (separatorChars == null) { + // null表示使用空白作为分隔符 + while (i < length) { + if (Character.isWhitespace(str.charAt(i))) { + if (match) { + if (sizePlus1++ == max) { + i = length; + } + + list.add(str.substring(start, i)); + match = false; + } + + start = ++i; + continue; + } + + match = true; + i++; + } + } else if (separatorChars.length() == 1) { + // 优化分隔符长度为1的情形 + char sep = separatorChars.charAt(0); + + while (i < length) { + if (str.charAt(i) == sep) { + if (match) { + if (sizePlus1++ == max) { + i = length; + } + + list.add(str.substring(start, i)); + match = false; + } + + start = ++i; + continue; + } + + match = true; + i++; + } + } else { + // 一般情形 + while (i < length) { + if (separatorChars.indexOf(str.charAt(i)) >= 0) { + if (match) { + if (sizePlus1++ == max) { + i = length; + } + + list.add(str.substring(start, i)); + match = false; + } + + start = ++i; + continue; + } + + match = true; + i++; + } + } + + if (match) { + list.add(str.substring(start, i)); + } + + return (String[]) list.toArray(new String[list.size()]); + } + + /* ============================================================================ */ + /* 字符串连接函数。 */ + /* */ + /* 将多个对象按指定分隔符连接成字符串。 */ + /* ============================================================================ */ + + /** + * 将数组中的元素连接成一个字符串。 + *
+     * StringUtil.join(null)            = null
+     * StringUtil.join([])              = ""
+     * StringUtil.join([null])          = ""
+     * StringUtil.join(["a", "b", "c"]) = "abc"
+     * StringUtil.join([null, "", "a"]) = "a"
+     * 
+ * + * @param array 要连接的数组 + * + * @return 连接后的字符串,如果原数组为null,则返回null + */ + public static String join(Object[] array) { + return join(array, null); + } + + /** + * 将数组中的元素连接成一个字符串。 + *
+     * StringUtil.join(null, *)               = null
+     * StringUtil.join([], *)                 = ""
+     * StringUtil.join([null], *)             = ""
+     * StringUtil.join(["a", "b", "c"], ';')  = "a;b;c"
+     * StringUtil.join(["a", "b", "c"], null) = "abc"
+     * StringUtil.join([null, "", "a"], ';')  = ";;a"
+     * 
+ * + * @param array 要连接的数组 + * @param separator 分隔符 + * + * @return 连接后的字符串,如果原数组为null,则返回null + */ + public static String join(Object[] array, char separator) { + if (array == null) { + return null; + } + + int arraySize = array.length; + int bufSize = (arraySize == 0) ? 0 : ((((array[0] == null) ? 16 : array[0].toString() + .length()) + 1) * arraySize); + StringBuffer buf = new StringBuffer(bufSize); + + for (int i = 0; i < arraySize; i++) { + if (i > 0) { + buf.append(separator); + } + + if (array[i] != null) { + buf.append(array[i]); + } + } + + return buf.toString(); + } + + /** + * 将数组中的元素连接成一个字符串。 + *
+     * StringUtil.join(null, *)                = null
+     * StringUtil.join([], *)                  = ""
+     * StringUtil.join([null], *)              = ""
+     * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtil.join(["a", "b", "c"], null)  = "abc"
+     * StringUtil.join(["a", "b", "c"], "")    = "abc"
+     * StringUtil.join([null, "", "a"], ',')   = ",,a"
+     * 
+ * + * @param array 要连接的数组 + * @param separator 分隔符 + * + * @return 连接后的字符串,如果原数组为null,则返回null + */ + public static String join(Object[] array, String separator) { + if (array == null) { + return null; + } + + if (separator == null) { + separator = EMPTY_STRING; + } + + int arraySize = array.length; + + // ArraySize == 0: Len = 0 + // ArraySize > 0: Len = NofStrings *(len(firstString) + len(separator)) + // (估计大约所有的字符串都一样长) + int bufSize = (arraySize == 0) ? 0 : (arraySize * (((array[0] == null) ? 16 : array[0] + .toString().length()) + ((separator != null) ? separator.length() : 0))); + + StringBuffer buf = new StringBuffer(bufSize); + + for (int i = 0; i < arraySize; i++) { + if ((separator != null) && (i > 0)) { + buf.append(separator); + } + + if (array[i] != null) { + buf.append(array[i]); + } + } + + return buf.toString(); + } + + /** + * 将Iterator中的元素连接成一个字符串。 + *
+     * StringUtil.join(null, *)                = null
+     * StringUtil.join([], *)                  = ""
+     * StringUtil.join([null], *)              = ""
+     * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtil.join(["a", "b", "c"], null)  = "abc"
+     * StringUtil.join(["a", "b", "c"], "")    = "abc"
+     * StringUtil.join([null, "", "a"], ',')   = ",,a"
+     * 
+ * + * @param iterator 要连接的Iterator + * @param separator 分隔符 + * + * @return 连接后的字符串,如果原数组为null,则返回null + */ + public static String join(Iterator iterator, char separator) { + if (iterator == null) { + return null; + } + + StringBuffer buf = new StringBuffer(256); // Java默认值是16, 可能偏小 + + while (iterator.hasNext()) { + Object obj = iterator.next(); + + if (obj != null) { + buf.append(obj); + } + + if (iterator.hasNext()) { + buf.append(separator); + } + } + + return buf.toString(); + } + + /** + * 将Iterator中的元素连接成一个字符串。 + *
+     * StringUtil.join(null, *)                = null
+     * StringUtil.join([], *)                  = ""
+     * StringUtil.join([null], *)              = ""
+     * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtil.join(["a", "b", "c"], null)  = "abc"
+     * StringUtil.join(["a", "b", "c"], "")    = "abc"
+     * StringUtil.join([null, "", "a"], ',')   = ",,a"
+     * 
+ * + * @param iterator 要连接的Iterator + * @param separator 分隔符 + * + * @return 连接后的字符串,如果原数组为null,则返回null + */ + public static String join(Iterator iterator, String separator) { + if (iterator == null) { + return null; + } + + StringBuffer buf = new StringBuffer(256); // Java默认值是16, 可能偏小 + + while (iterator.hasNext()) { + Object obj = iterator.next(); + + if (obj != null) { + buf.append(obj); + } + + if ((separator != null) && iterator.hasNext()) { + buf.append(separator); + } + } + + return buf.toString(); + } + + /* ============================================================================ */ + /* 字符串查找函数 —— 字符或字符串。 */ + /* */ + /* 在字符串中查找指定字符或字符串。 */ + /* ============================================================================ */ + + /** + * 在字符串中查找指定字符,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.indexOf(null, *)         = -1
+     * StringUtil.indexOf("", *)           = -1
+     * StringUtil.indexOf("aabaabaa", 'a') = 0
+     * StringUtil.indexOf("aabaabaa", 'b') = 2
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChar 要查找的字符 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOf(String str, char searchChar) { + if ((str == null) || (str.length() == 0)) { + return -1; + } + + return str.indexOf(searchChar); + } + + /** + * 在字符串中查找指定字符,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.indexOf(null, *, *)          = -1
+     * StringUtil.indexOf("", *, *)            = -1
+     * StringUtil.indexOf("aabaabaa", 'b', 0)  = 2
+     * StringUtil.indexOf("aabaabaa", 'b', 3)  = 5
+     * StringUtil.indexOf("aabaabaa", 'b', 9)  = -1
+     * StringUtil.indexOf("aabaabaa", 'b', -1) = 2
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChar 要查找的字符 + * @param startPos 开始搜索的索引值,如果小于0,则看作0 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOf(String str, char searchChar, int startPos) { + if ((str == null) || (str.length() == 0)) { + return -1; + } + + return str.indexOf(searchChar, startPos); + } + + /** + * 在字符串中查找指定字符串,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.indexOf(null, *)          = -1
+     * StringUtil.indexOf(*, null)          = -1
+     * StringUtil.indexOf("", "")           = 0
+     * StringUtil.indexOf("aabaabaa", "a")  = 0
+     * StringUtil.indexOf("aabaabaa", "b")  = 2
+     * StringUtil.indexOf("aabaabaa", "ab") = 1
+     * StringUtil.indexOf("aabaabaa", "")   = 0
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStr 要查找的字符串 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOf(String str, String searchStr) { + if ((str == null) || (searchStr == null)) { + return -1; + } + + return str.indexOf(searchStr); + } + + /** + * 在字符串中查找指定字符串,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.indexOf(null, *, *)          = -1
+     * StringUtil.indexOf(*, null, *)          = -1
+     * StringUtil.indexOf("", "", 0)           = 0
+     * StringUtil.indexOf("aabaabaa", "a", 0)  = 0
+     * StringUtil.indexOf("aabaabaa", "b", 0)  = 2
+     * StringUtil.indexOf("aabaabaa", "ab", 0) = 1
+     * StringUtil.indexOf("aabaabaa", "b", 3)  = 5
+     * StringUtil.indexOf("aabaabaa", "b", 9)  = -1
+     * StringUtil.indexOf("aabaabaa", "b", -1) = 2
+     * StringUtil.indexOf("aabaabaa", "", 2)   = 2
+     * StringUtil.indexOf("abc", "", 9)        = 3
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStr 要查找的字符串 + * @param startPos 开始搜索的索引值,如果小于0,则看作0 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOf(String str, String searchStr, int startPos) { + if ((str == null) || (searchStr == null)) { + return -1; + } + + // JDK1.3及以下版本的bug:不能正确处理下面的情况 + if ((searchStr.length() == 0) && (startPos >= str.length())) { + return str.length(); + } + + return str.indexOf(searchStr, startPos); + } + + /** + * 在字符串中查找指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符集合为null或空,也返回-1。 + *
+     * StringUtil.indexOfAny(null, *)                = -1
+     * StringUtil.indexOfAny("", *)                  = -1
+     * StringUtil.indexOfAny(*, null)                = -1
+     * StringUtil.indexOfAny(*, [])                  = -1
+     * StringUtil.indexOfAny("zzabyycdxx",['z','a']) = 0
+     * StringUtil.indexOfAny("zzabyycdxx",['b','y']) = 3
+     * StringUtil.indexOfAny("aba", ['z'])           = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChars 要搜索的字符集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOfAny(String str, char[] searchChars) { + if ((str == null) || (str.length() == 0) || (searchChars == null) + || (searchChars.length == 0)) { + return -1; + } + + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + + for (int j = 0; j < searchChars.length; j++) { + if (searchChars[j] == ch) { + return i; + } + } + } + + return -1; + } + + /** + * 在字符串中查找指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符集合为null或空,也返回-1。 + *
+     * StringUtil.indexOfAny(null, *)            = -1
+     * StringUtil.indexOfAny("", *)              = -1
+     * StringUtil.indexOfAny(*, null)            = -1
+     * StringUtil.indexOfAny(*, "")              = -1
+     * StringUtil.indexOfAny("zzabyycdxx", "za") = 0
+     * StringUtil.indexOfAny("zzabyycdxx", "by") = 3
+     * StringUtil.indexOfAny("aba","z")          = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChars 要搜索的字符集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOfAny(String str, String searchChars) { + if ((str == null) || (str.length() == 0) || (searchChars == null) + || (searchChars.length() == 0)) { + return -1; + } + + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + + for (int j = 0; j < searchChars.length(); j++) { + if (searchChars.charAt(j) == ch) { + return i; + } + } + } + + return -1; + } + + /** + * 在字符串中查找指定字符串集合中的字符串,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符串集合为null或空,也返回-1。 + * 如果字符串集合包括"",并且字符串不为null,则返回str.length() + *
+     * StringUtil.indexOfAny(null, *)                     = -1
+     * StringUtil.indexOfAny(*, null)                     = -1
+     * StringUtil.indexOfAny(*, [])                       = -1
+     * StringUtil.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
+     * StringUtil.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
+     * StringUtil.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
+     * StringUtil.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
+     * StringUtil.indexOfAny("zzabyycdxx", [""])          = 0
+     * StringUtil.indexOfAny("", [""])                    = 0
+     * StringUtil.indexOfAny("", ["a"])                   = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStrs 要搜索的字符串集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOfAny(String str, String[] searchStrs) { + if ((str == null) || (searchStrs == null)) { + return -1; + } + + int sz = searchStrs.length; + + // String's can't have a MAX_VALUEth index. + int ret = Integer.MAX_VALUE; + + int tmp = 0; + + for (int i = 0; i < sz; i++) { + String search = searchStrs[i]; + + if (search == null) { + continue; + } + + tmp = str.indexOf(search); + + if (tmp == -1) { + continue; + } + + if (tmp < ret) { + ret = tmp; + } + } + + return (ret == Integer.MAX_VALUE) ? (-1) : ret; + } + + /** + * 在字符串中查找不在指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符集合为null或空,也返回-1。 + *
+     * StringUtil.indexOfAnyBut(null, *)             = -1
+     * StringUtil.indexOfAnyBut("", *)               = -1
+     * StringUtil.indexOfAnyBut(*, null)             = -1
+     * StringUtil.indexOfAnyBut(*, [])               = -1
+     * StringUtil.indexOfAnyBut("zzabyycdxx",'za')   = 3
+     * StringUtil.indexOfAnyBut("zzabyycdxx", 'by')  = 0
+     * StringUtil.indexOfAnyBut("aba", 'ab')         = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChars 要搜索的字符集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOfAnyBut(String str, char[] searchChars) { + if ((str == null) || (str.length() == 0) || (searchChars == null) + || (searchChars.length == 0)) { + return -1; + } + + outer: for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + + for (int j = 0; j < searchChars.length; j++) { + if (searchChars[j] == ch) { + continue outer; + } + } + + return i; + } + + return -1; + } + + /** + * 在字符串中查找不在指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符集合为null或空,也返回-1。 + *
+     * StringUtil.indexOfAnyBut(null, *)            = -1
+     * StringUtil.indexOfAnyBut("", *)              = -1
+     * StringUtil.indexOfAnyBut(*, null)            = -1
+     * StringUtil.indexOfAnyBut(*, "")              = -1
+     * StringUtil.indexOfAnyBut("zzabyycdxx", "za") = 3
+     * StringUtil.indexOfAnyBut("zzabyycdxx", "by") = 0
+     * StringUtil.indexOfAnyBut("aba","ab")         = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChars 要搜索的字符集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int indexOfAnyBut(String str, String searchChars) { + if ((str == null) || (str.length() == 0) || (searchChars == null) + || (searchChars.length() == 0)) { + return -1; + } + + for (int i = 0; i < str.length(); i++) { + if (searchChars.indexOf(str.charAt(i)) < 0) { + return i; + } + } + + return -1; + } + + /** + * 从字符串尾部开始查找指定字符,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.lastIndexOf(null, *)         = -1
+     * StringUtil.lastIndexOf("", *)           = -1
+     * StringUtil.lastIndexOf("aabaabaa", 'a') = 7
+     * StringUtil.lastIndexOf("aabaabaa", 'b') = 5
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChar 要查找的字符 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int lastIndexOf(String str, char searchChar) { + if ((str == null) || (str.length() == 0)) { + return -1; + } + + return str.lastIndexOf(searchChar); + } + + /** + * 从字符串尾部开始查找指定字符,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.lastIndexOf(null, *, *)          = -1
+     * StringUtil.lastIndexOf("", *,  *)           = -1
+     * StringUtil.lastIndexOf("aabaabaa", 'b', 8)  = 5
+     * StringUtil.lastIndexOf("aabaabaa", 'b', 4)  = 2
+     * StringUtil.lastIndexOf("aabaabaa", 'b', 0)  = -1
+     * StringUtil.lastIndexOf("aabaabaa", 'b', 9)  = 5
+     * StringUtil.lastIndexOf("aabaabaa", 'b', -1) = -1
+     * StringUtil.lastIndexOf("aabaabaa", 'a', 0)  = 0
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChar 要查找的字符 + * @param startPos 从指定索引开始向前搜索 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int lastIndexOf(String str, char searchChar, int startPos) { + if ((str == null) || (str.length() == 0)) { + return -1; + } + + return str.lastIndexOf(searchChar, startPos); + } + + /** + * 从字符串尾部开始查找指定字符串,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.lastIndexOf(null, *)         = -1
+     * StringUtil.lastIndexOf("", *)           = -1
+     * StringUtil.lastIndexOf("aabaabaa", 'a') = 7
+     * StringUtil.lastIndexOf("aabaabaa", 'b') = 5
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStr 要查找的字符串 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int lastIndexOf(String str, String searchStr) { + if ((str == null) || (searchStr == null)) { + return -1; + } + + return str.lastIndexOf(searchStr); + } + + /** + * 从字符串尾部开始查找指定字符串,并返回第一个匹配的索引值。如果字符串为null或未找到,则返回-1。 + *
+     * StringUtil.lastIndexOf(null, *, *)          = -1
+     * StringUtil.lastIndexOf(*, null, *)          = -1
+     * StringUtil.lastIndexOf("aabaabaa", "a", 8)  = 7
+     * StringUtil.lastIndexOf("aabaabaa", "b", 8)  = 5
+     * StringUtil.lastIndexOf("aabaabaa", "ab", 8) = 4
+     * StringUtil.lastIndexOf("aabaabaa", "b", 9)  = 5
+     * StringUtil.lastIndexOf("aabaabaa", "b", -1) = -1
+     * StringUtil.lastIndexOf("aabaabaa", "a", 0)  = 0
+     * StringUtil.lastIndexOf("aabaabaa", "b", 0)  = -1
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStr 要查找的字符串 + * @param startPos 从指定索引开始向前搜索 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int lastIndexOf(String str, String searchStr, int startPos) { + if ((str == null) || (searchStr == null)) { + return -1; + } + + return str.lastIndexOf(searchStr, startPos); + } + + /** + * 从字符串尾部开始查找指定字符串集合中的字符串,并返回第一个匹配的起始索引。 如果字符串为null,则返回-1。 + * 如果字符串集合为null或空,也返回-1。 + * 如果字符串集合包括"",并且字符串不为null,则返回str.length() + *
+     * StringUtil.lastIndexOfAny(null, *)                   = -1
+     * StringUtil.lastIndexOfAny(*, null)                   = -1
+     * StringUtil.lastIndexOfAny(*, [])                     = -1
+     * StringUtil.lastIndexOfAny(*, [null])                 = -1
+     * StringUtil.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
+     * StringUtil.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
+     * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStrs 要搜索的字符串集合 + * + * @return 第一个匹配的索引值。如果字符串为null或未找到,则返回-1 + */ + public static int lastIndexOfAny(String str, String[] searchStrs) { + if ((str == null) || (searchStrs == null)) { + return -1; + } + + int searchStrsLength = searchStrs.length; + int index = -1; + int tmp = 0; + + for (int i = 0; i < searchStrsLength; i++) { + String search = searchStrs[i]; + + if (search == null) { + continue; + } + + tmp = str.lastIndexOf(search); + + if (tmp > index) { + index = tmp; + } + } + + return index; + } + + /** + * 检查字符串中是否包含指定的字符。如果字符串为null,将返回false。 + *
+     * StringUtil.contains(null, *)    = false
+     * StringUtil.contains("", *)      = false
+     * StringUtil.contains("abc", 'a') = true
+     * StringUtil.contains("abc", 'z') = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchChar 要查找的字符 + * + * @return 如果找到,则返回true + */ + public static boolean contains(String str, char searchChar) { + if ((str == null) || (str.length() == 0)) { + return false; + } + + return str.indexOf(searchChar) >= 0; + } + + /** + * 检查字符串中是否包含指定的字符串。如果字符串为null,将返回false。 + *
+     * StringUtil.contains(null, *)     = false
+     * StringUtil.contains(*, null)     = false
+     * StringUtil.contains("", "")      = true
+     * StringUtil.contains("abc", "")   = true
+     * StringUtil.contains("abc", "a")  = true
+     * StringUtil.contains("abc", "z")  = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param searchStr 要查找的字符串 + * + * @return 如果找到,则返回true + */ + public static boolean contains(String str, String searchStr) { + if ((str == null) || (searchStr == null)) { + return false; + } + + return str.indexOf(searchStr) >= 0; + } + + /** + * 检查字符串是是否只包含指定字符集合中的字符。 + * + *

+ * 如果字符串为null,则返回false。 + * 如果字符集合为null则返回false。 但是空字符串永远返回true. + *

+ *
+     * StringUtil.containsOnly(null, *)       = false
+     * StringUtil.containsOnly(*, null)       = false
+     * StringUtil.containsOnly("", *)         = true
+     * StringUtil.containsOnly("ab", '')      = false
+     * StringUtil.containsOnly("abab", 'abc') = true
+     * StringUtil.containsOnly("ab1", 'abc')  = false
+     * StringUtil.containsOnly("abz", 'abc')  = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param valid 要查找的字符串 + * + * @return 如果找到,则返回true + */ + public static boolean containsOnly(String str, char[] valid) { + if ((valid == null) || (str == null)) { + return false; + } + + if (str.length() == 0) { + return true; + } + + if (valid.length == 0) { + return false; + } + + return indexOfAnyBut(str, valid) == -1; + } + + /** + * 检查字符串是是否只包含指定字符集合中的字符。 + * + *

+ * 如果字符串为null,则返回false。 + * 如果字符集合为null则返回false。 但是空字符串永远返回true. + *

+ *
+     * StringUtil.containsOnly(null, *)       = false
+     * StringUtil.containsOnly(*, null)       = false
+     * StringUtil.containsOnly("", *)         = true
+     * StringUtil.containsOnly("ab", "")      = false
+     * StringUtil.containsOnly("abab", "abc") = true
+     * StringUtil.containsOnly("ab1", "abc")  = false
+     * StringUtil.containsOnly("abz", "abc")  = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param valid 要查找的字符串 + * + * @return 如果找到,则返回true + */ + public static boolean containsOnly(String str, String valid) { + if ((str == null) || (valid == null)) { + return false; + } + + return containsOnly(str, valid.toCharArray()); + } + + /** + * 检查字符串是是否不包含指定字符集合中的字符。 + * + *

+ * 如果字符串为null,则返回false。 如果字符集合为null则返回true。 + * 但是空字符串永远返回true. + *

+ *
+     * StringUtil.containsNone(null, *)       = true
+     * StringUtil.containsNone(*, null)       = true
+     * StringUtil.containsNone("", *)         = true
+     * StringUtil.containsNone("ab", '')      = true
+     * StringUtil.containsNone("abab", 'xyz') = true
+     * StringUtil.containsNone("ab1", 'xyz')  = true
+     * StringUtil.containsNone("abz", 'xyz')  = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param invalid 要查找的字符串 + * + * @return 如果找到,则返回true + */ + public static boolean containsNone(String str, char[] invalid) { + if ((str == null) || (invalid == null)) { + return true; + } + + int strSize = str.length(); + int validSize = invalid.length; + + for (int i = 0; i < strSize; i++) { + char ch = str.charAt(i); + + for (int j = 0; j < validSize; j++) { + if (invalid[j] == ch) { + return false; + } + } + } + + return true; + } + + /** + * 检查字符串是是否不包含指定字符集合中的字符。 + * + *

+ * 如果字符串为null,则返回false。 如果字符集合为null则返回true。 + * 但是空字符串永远返回true. + *

+ *
+     * StringUtil.containsNone(null, *)       = true
+     * StringUtil.containsNone(*, null)       = true
+     * StringUtil.containsNone("", *)         = true
+     * StringUtil.containsNone("ab", "")      = true
+     * StringUtil.containsNone("abab", "xyz") = true
+     * StringUtil.containsNone("ab1", "xyz")  = true
+     * StringUtil.containsNone("abz", "xyz")  = false
+     * 
+ * + * @param str 要扫描的字符串 + * @param invalidChars 要查找的字符串 + * + * @return 如果找到,则返回true + */ + public static boolean containsNone(String str, String invalidChars) { + if ((str == null) || (invalidChars == null)) { + return true; + } + + return containsNone(str, invalidChars.toCharArray()); + } + + /** + * 取得指定子串在字符串中出现的次数。 + * + *

+ * 如果字符串为null或空,则返回0。 + *

+     * StringUtil.countMatches(null, *)       = 0
+     * StringUtil.countMatches("", *)         = 0
+     * StringUtil.countMatches("abba", null)  = 0
+     * StringUtil.countMatches("abba", "")    = 0
+     * StringUtil.countMatches("abba", "a")   = 2
+     * StringUtil.countMatches("abba", "ab")  = 1
+     * StringUtil.countMatches("abba", "xxx") = 0
+     * 
+ *

+ * + * @param str 要扫描的字符串 + * @param subStr 子字符串 + * + * @return 子串在字符串中出现的次数,如果字符串为null或空,则返回0 + */ + public static int countMatches(String str, String subStr) { + if ((str == null) || (str.length() == 0) || (subStr == null) || (subStr.length() == 0)) { + return 0; + } + + int count = 0; + int index = 0; + + while ((index = str.indexOf(subStr, index)) != -1) { + count++; + index += subStr.length(); + } + + return count; + } + + /* ============================================================================ */ + /* 取子串函数。 */ + /* ============================================================================ */ + + /** + * 取指定字符串的子串。 + * + *

+ * 负的索引代表从尾部开始计算。如果字符串为null,则返回null。 + *

+     * StringUtil.substring(null, *)   = null
+     * StringUtil.substring("", *)     = ""
+     * StringUtil.substring("abc", 0)  = "abc"
+     * StringUtil.substring("abc", 2)  = "c"
+     * StringUtil.substring("abc", 4)  = ""
+     * StringUtil.substring("abc", -2) = "bc"
+     * StringUtil.substring("abc", -4) = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param start 起始索引,如果为负数,表示从尾部查找 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substring(String str, int start) { + if (str == null) { + return null; + } + + if (start < 0) { + start = str.length() + start; + } + + if (start < 0) { + start = 0; + } + + if (start > str.length()) { + return EMPTY_STRING; + } + + return str.substring(start); + } + + /** + * 取指定字符串的子串。 + * + *

+ * 负的索引代表从尾部开始计算。如果字符串为null,则返回null。 + *

+     * StringUtil.substring(null, *, *)    = null
+     * StringUtil.substring("", * ,  *)    = "";
+     * StringUtil.substring("abc", 0, 2)   = "ab"
+     * StringUtil.substring("abc", 2, 0)   = ""
+     * StringUtil.substring("abc", 2, 4)   = "c"
+     * StringUtil.substring("abc", 4, 6)   = ""
+     * StringUtil.substring("abc", 2, 2)   = ""
+     * StringUtil.substring("abc", -2, -1) = "b"
+     * StringUtil.substring("abc", -4, 2)  = "ab"
+     * 
+ *

+ * + * @param str 字符串 + * @param start 起始索引,如果为负数,表示从尾部计算 + * @param end 结束索引(不含),如果为负数,表示从尾部计算 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substring(String str, int start, int end) { + if (str == null) { + return null; + } + + if (end < 0) { + end = str.length() + end; + } + + if (start < 0) { + start = str.length() + start; + } + + if (end > str.length()) { + end = str.length(); + } + + if (start > end) { + return EMPTY_STRING; + } + + if (start < 0) { + start = 0; + } + + if (end < 0) { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 取得长度为指定字符数的最左边的子串。 + *
+     * StringUtil.left(null, *)    = null
+     * StringUtil.left(*, -ve)     = ""
+     * StringUtil.left("", *)      = ""
+     * StringUtil.left("abc", 0)   = ""
+     * StringUtil.left("abc", 2)   = "ab"
+     * StringUtil.left("abc", 4)   = "abc"
+     * 
+ * + * @param str 字符串 + * @param len 最左子串的长度 + * + * @return 子串,如果原始字串为null,则返回null + */ + public static String left(String str, int len) { + if (str == null) { + return null; + } + + if (len < 0) { + return EMPTY_STRING; + } + + if (str.length() <= len) { + return str; + } else { + return str.substring(0, len); + } + } + + /** + * 取得长度为指定字符数的最右边的子串。 + *
+     * StringUtil.right(null, *)    = null
+     * StringUtil.right(*, -ve)     = ""
+     * StringUtil.right("", *)      = ""
+     * StringUtil.right("abc", 0)   = ""
+     * StringUtil.right("abc", 2)   = "bc"
+     * StringUtil.right("abc", 4)   = "abc"
+     * 
+ * + * @param str 字符串 + * @param len 最右子串的长度 + * + * @return 子串,如果原始字串为null,则返回null + */ + public static String right(String str, int len) { + if (str == null) { + return null; + } + + if (len < 0) { + return EMPTY_STRING; + } + + if (str.length() <= len) { + return str; + } else { + return str.substring(str.length() - len); + } + } + + /** + * 取得从指定索引开始计算的、长度为指定字符数的子串。 + *
+     * StringUtil.mid(null, *, *)    = null
+     * StringUtil.mid(*, *, -ve)     = ""
+     * StringUtil.mid("", 0, *)      = ""
+     * StringUtil.mid("abc", 0, 2)   = "ab"
+     * StringUtil.mid("abc", 0, 4)   = "abc"
+     * StringUtil.mid("abc", 2, 4)   = "c"
+     * StringUtil.mid("abc", 4, 2)   = ""
+     * StringUtil.mid("abc", -2, 2)  = "ab"
+     * 
+ * + * @param str 字符串 + * @param pos 起始索引,如果为负数,则看作0 + * @param len 子串的长度,如果为负数,则看作长度为0 + * + * @return 子串,如果原始字串为null,则返回null + */ + public static String mid(String str, int pos, int len) { + if (str == null) { + return null; + } + + if ((len < 0) || (pos > str.length())) { + return EMPTY_STRING; + } + + if (pos < 0) { + pos = 0; + } + + if (str.length() <= (pos + len)) { + return str.substring(pos); + } else { + return str.substring(pos, pos + len); + } + } + + /* ============================================================================ */ + /* 搜索并取子串函数。 */ + /* ============================================================================ */ + + /** + * 取得第一个出现的分隔子串之前的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null或未找到该子串,则返回原字符串。 + *

+     * StringUtil.substringBefore(null, *)      = null
+     * StringUtil.substringBefore("", *)        = ""
+     * StringUtil.substringBefore("abc", "a")   = ""
+     * StringUtil.substringBefore("abcba", "b") = "a"
+     * StringUtil.substringBefore("abc", "c")   = "ab"
+     * StringUtil.substringBefore("abc", "d")   = "abc"
+     * StringUtil.substringBefore("abc", "")    = ""
+     * StringUtil.substringBefore("abc", null)  = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param separator 要搜索的分隔子串 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substringBefore(String str, String separator) { + if ((str == null) || (separator == null) || (str.length() == 0)) { + return str; + } + + if (separator.length() == 0) { + return EMPTY_STRING; + } + + int pos = str.indexOf(separator); + + if (pos == -1) { + return str; + } + + return str.substring(0, pos); + } + + /** + * 取得第一个出现的分隔子串之后的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null或未找到该子串,则返回原字符串。 + *

+     * StringUtil.substringAfter(null, *)      = null
+     * StringUtil.substringAfter("", *)        = ""
+     * StringUtil.substringAfter(*, null)      = ""
+     * StringUtil.substringAfter("abc", "a")   = "bc"
+     * StringUtil.substringAfter("abcba", "b") = "cba"
+     * StringUtil.substringAfter("abc", "c")   = ""
+     * StringUtil.substringAfter("abc", "d")   = ""
+     * StringUtil.substringAfter("abc", "")    = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param separator 要搜索的分隔子串 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substringAfter(String str, String separator) { + if ((str == null) || (str.length() == 0)) { + return str; + } + + if (separator == null) { + return EMPTY_STRING; + } + + int pos = str.indexOf(separator); + + if (pos == -1) { + return EMPTY_STRING; + } + + return str.substring(pos + separator.length()); + } + + /** + * 取得最后一个的分隔子串之前的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null或未找到该子串,则返回原字符串。 + *

+     * StringUtil.substringBeforeLast(null, *)      = null
+     * StringUtil.substringBeforeLast("", *)        = ""
+     * StringUtil.substringBeforeLast("abcba", "b") = "abc"
+     * StringUtil.substringBeforeLast("abc", "c")   = "ab"
+     * StringUtil.substringBeforeLast("a", "a")     = ""
+     * StringUtil.substringBeforeLast("a", "z")     = "a"
+     * StringUtil.substringBeforeLast("a", null)    = "a"
+     * StringUtil.substringBeforeLast("a", "")      = "a"
+     * 
+ *

+ * + * @param str 字符串 + * @param separator 要搜索的分隔子串 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substringBeforeLast(String str, String separator) { + if ((str == null) || (separator == null) || (str.length() == 0) + || (separator.length() == 0)) { + return str; + } + + int pos = str.lastIndexOf(separator); + + if (pos == -1) { + return str; + } + + return str.substring(0, pos); + } + + /** + * 取得最后一个的分隔子串之后的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null或未找到该子串,则返回原字符串。 + *

+     * StringUtil.substringAfterLast(null, *)      = null
+     * StringUtil.substringAfterLast("", *)        = ""
+     * StringUtil.substringAfterLast(*, "")        = ""
+     * StringUtil.substringAfterLast(*, null)      = ""
+     * StringUtil.substringAfterLast("abc", "a")   = "bc"
+     * StringUtil.substringAfterLast("abcba", "b") = "a"
+     * StringUtil.substringAfterLast("abc", "c")   = ""
+     * StringUtil.substringAfterLast("a", "a")     = ""
+     * StringUtil.substringAfterLast("a", "z")     = ""
+     * 
+ *

+ * + * @param str 字符串 + * @param separator 要搜索的分隔子串 + * + * @return 子串,如果原始串为null,则返回null + */ + public static String substringAfterLast(String str, String separator) { + if ((str == null) || (str.length() == 0)) { + return str; + } + + if ((separator == null) || (separator.length() == 0)) { + return EMPTY_STRING; + } + + int pos = str.lastIndexOf(separator); + + if ((pos == -1) || (pos == (str.length() - separator.length()))) { + return EMPTY_STRING; + } + + return str.substring(pos + separator.length()); + } + + /** + * 取得指定分隔符的前两次出现之间的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null,则返回null。 + *

+     * StringUtil.substringBetween(null, *)            = null
+     * StringUtil.substringBetween("", "")             = ""
+     * StringUtil.substringBetween("", "tag")          = null
+     * StringUtil.substringBetween("tagabctag", null)  = null
+     * StringUtil.substringBetween("tagabctag", "")    = ""
+     * StringUtil.substringBetween("tagabctag", "tag") = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param tag 要搜索的分隔子串 + * + * @return 子串,如果原始串为null或未找到分隔子串,则返回null + */ + public static String substringBetween(String str, String tag) { + return substringBetween(str, tag, tag, 0); + } + + /** + * 取得两个分隔符之间的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null,则返回null。 + *

+     * StringUtil.substringBetween(null, *, *)          = null
+     * StringUtil.substringBetween("", "", "")          = ""
+     * StringUtil.substringBetween("", "", "tag")       = null
+     * StringUtil.substringBetween("", "tag", "tag")    = null
+     * StringUtil.substringBetween("yabcz", null, null) = null
+     * StringUtil.substringBetween("yabcz", "", "")     = ""
+     * StringUtil.substringBetween("yabcz", "y", "z")   = "abc"
+     * StringUtil.substringBetween("yabczyabcz", "y", "z")   = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param open 要搜索的分隔子串1 + * @param close 要搜索的分隔子串2 + * + * @return 子串,如果原始串为null或未找到分隔子串,则返回null + */ + public static String substringBetween(String str, String open, String close) { + return substringBetween(str, open, close, 0); + } + + /** + * 取得两个分隔符之间的子串。 + * + *

+ * 如果字符串为null,则返回null。 如果分隔子串为null,则返回null。 + *

+     * StringUtil.substringBetween(null, *, *)          = null
+     * StringUtil.substringBetween("", "", "")          = ""
+     * StringUtil.substringBetween("", "", "tag")       = null
+     * StringUtil.substringBetween("", "tag", "tag")    = null
+     * StringUtil.substringBetween("yabcz", null, null) = null
+     * StringUtil.substringBetween("yabcz", "", "")     = ""
+     * StringUtil.substringBetween("yabcz", "y", "z")   = "abc"
+     * StringUtil.substringBetween("yabczyabcz", "y", "z")   = "abc"
+     * 
+ *

+ * + * @param str 字符串 + * @param open 要搜索的分隔子串1 + * @param close 要搜索的分隔子串2 + * @param fromIndex 从指定index处搜索 + * + * @return 子串,如果原始串为null或未找到分隔子串,则返回null + */ + public static String substringBetween(String str, String open, String close, int fromIndex) { + if ((str == null) || (open == null) || (close == null)) { + return null; + } + + int start = str.indexOf(open, fromIndex); + + if (start != -1) { + int end = str.indexOf(close, start + open.length()); + + if (end != -1) { + return str.substring(start + open.length(), end); + } + } + + return null; + } + + /* ============================================================================ */ + /* 删除字符。 */ + /* ============================================================================ */ + + /** + * 删除所有在Character.isWhitespace(char)中所定义的空白。 + *
+     * StringUtil.deleteWhitespace(null)         = null
+     * StringUtil.deleteWhitespace("")           = ""
+     * StringUtil.deleteWhitespace("abc")        = "abc"
+     * StringUtil.deleteWhitespace("   ab  c  ") = "abc"
+     * 
+ * + * @param str 要处理的字符串 + * + * @return 去空白后的字符串,如果原始字符串为null,则返回null + */ + public static String deleteWhitespace(String str) { + if (str == null) { + return null; + } + + int sz = str.length(); + StringBuffer buffer = new StringBuffer(sz); + + for (int i = 0; i < sz; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + buffer.append(str.charAt(i)); + } + } + + return buffer.toString(); + } + + /* ============================================================================ */ + /* 替换子串。 */ + /* ============================================================================ */ + + /** + * 替换指定的子串,只替换第一个出现的子串。 + * + *

+ * 如果字符串为null则返回null,如果指定子串为null,则返回原字符串。 + *

+     * StringUtil.replaceOnce(null, *, *)        = null
+     * StringUtil.replaceOnce("", *, *)          = ""
+     * StringUtil.replaceOnce("aba", null, null) = "aba"
+     * StringUtil.replaceOnce("aba", null, null) = "aba"
+     * StringUtil.replaceOnce("aba", "a", null)  = "aba"
+     * StringUtil.replaceOnce("aba", "a", "")    = "ba"
+     * StringUtil.replaceOnce("aba", "a", "z")   = "zba"
+     * 
+ *

+ * + * @param text 要扫描的字符串 + * @param repl 要搜索的子串 + * @param with 替换字符串 + * + * @return 被替换后的字符串,如果原始字符串为null,则返回null + */ + public static String replaceOnce(String text, String repl, String with) { + return replace(text, repl, with, 1); + } + + /** + * 替换指定的子串,替换所有出现的子串。 + * + *

+ * 如果字符串为null则返回null,如果指定子串为null,则返回原字符串。 + *

+     * StringUtil.replace(null, *, *)        = null
+     * StringUtil.replace("", *, *)          = ""
+     * StringUtil.replace("aba", null, null) = "aba"
+     * StringUtil.replace("aba", null, null) = "aba"
+     * StringUtil.replace("aba", "a", null)  = "aba"
+     * StringUtil.replace("aba", "a", "")    = "b"
+     * StringUtil.replace("aba", "a", "z")   = "zbz"
+     * 
+ *

+ * + * @param text 要扫描的字符串 + * @param repl 要搜索的子串 + * @param with 替换字符串 + * + * @return 被替换后的字符串,如果原始字符串为null,则返回null + */ + public static String replace(String text, String repl, String with) { + return replace(text, repl, with, -1); + } + + /** + * 替换指定的子串,替换指定的次数。 + * + *

+ * 如果字符串为null则返回null,如果指定子串为null,则返回原字符串。 + *

+     * StringUtil.replace(null, *, *, *)         = null
+     * StringUtil.replace("", *, *, *)           = ""
+     * StringUtil.replace("abaa", null, null, 1) = "abaa"
+     * StringUtil.replace("abaa", null, null, 1) = "abaa"
+     * StringUtil.replace("abaa", "a", null, 1)  = "abaa"
+     * StringUtil.replace("abaa", "a", "", 1)    = "baa"
+     * StringUtil.replace("abaa", "a", "z", 0)   = "abaa"
+     * StringUtil.replace("abaa", "a", "z", 1)   = "zbaa"
+     * StringUtil.replace("abaa", "a", "z", 2)   = "zbza"
+     * StringUtil.replace("abaa", "a", "z", -1)  = "zbzz"
+     * 
+ *

+ * + * @param text 要扫描的字符串 + * @param repl 要搜索的子串 + * @param with 替换字符串 + * @param max maximum number of values to replace, or -1 if no maximum + * + * @return 被替换后的字符串,如果原始字符串为null,则返回null + */ + public static String replace(String text, String repl, String with, int max) { + if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0) + || (max == 0)) { + return text; + } + + StringBuffer buf = new StringBuffer(text.length()); + int start = 0; + int end = 0; + + while ((end = text.indexOf(repl, start)) != -1) { + buf.append(text.substring(start, end)).append(with); + start = end + repl.length(); + + if (--max == 0) { + break; + } + } + + buf.append(text.substring(start)); + return buf.toString(); + } + + /** + * 将字符串中所有指定的字符,替换成另一个。 + * + *

+ * 如果字符串为null则返回null。 + *

+     * StringUtil.replaceChars(null, *, *)        = null
+     * StringUtil.replaceChars("", *, *)          = ""
+     * StringUtil.replaceChars("abcba", 'b', 'y') = "aycya"
+     * StringUtil.replaceChars("abcba", 'z', 'y') = "abcba"
+     * 
+ *

+ * + * @param str 要扫描的字符串 + * @param searchChar 要搜索的字符 + * @param replaceChar 替换字符 + * + * @return 被替换后的字符串,如果原始字符串为null,则返回null + */ + public static String replaceChars(String str, char searchChar, char replaceChar) { + if (str == null) { + return null; + } + + return str.replace(searchChar, replaceChar); + } + + /** + * 将字符串中所有指定的字符,替换成另一个。 + * + *

+ * 如果字符串为null则返回null。如果搜索字符串为null或空,则返回原字符串。 + *

+ * + *

+ * 例如: replaceChars("hello", "ho", "jy") = jelly。 + *

+ * + *

+ * 通常搜索字符串和替换字符串是等长的,如果搜索字符串比替换字符串长,则多余的字符将被删除。 如果搜索字符串比替换字符串短,则缺少的字符将被忽略。 + *

+     * StringUtil.replaceChars(null, *, *)           = null
+     * StringUtil.replaceChars("", *, *)             = ""
+     * StringUtil.replaceChars("abc", null, *)       = "abc"
+     * StringUtil.replaceChars("abc", "", *)         = "abc"
+     * StringUtil.replaceChars("abc", "b", null)     = "ac"
+     * StringUtil.replaceChars("abc", "b", "")       = "ac"
+     * StringUtil.replaceChars("abcba", "bc", "yz")  = "ayzya"
+     * StringUtil.replaceChars("abcba", "bc", "y")   = "ayya"
+     * StringUtil.replaceChars("abcba", "bc", "yzx") = "ayzya"
+     * 
+ *

+ * + * @param str 要扫描的字符串 + * @param searchChars 要搜索的字符串 + * @param replaceChars 替换字符串 + * + * @return 被替换后的字符串,如果原始字符串为null,则返回null + */ + public static String replaceChars(String str, String searchChars, String replaceChars) { + if ((str == null) || (str.length() == 0) || (searchChars == null) + || (searchChars.length() == 0)) { + return str; + } + + char[] chars = str.toCharArray(); + int len = chars.length; + boolean modified = false; + + for (int i = 0, isize = searchChars.length(); i < isize; i++) { + char searchChar = searchChars.charAt(i); + + if ((replaceChars == null) || (i >= replaceChars.length())) { + // 删除 + int pos = 0; + + for (int j = 0; j < len; j++) { + if (chars[j] != searchChar) { + chars[pos++] = chars[j]; + } else { + modified = true; + } + } + + len = pos; + } else { + // 替换 + for (int j = 0; j < len; j++) { + if (chars[j] == searchChar) { + chars[j] = replaceChars.charAt(i); + modified = true; + } + } + } + } + + if (!modified) { + return str; + } + + return new String(chars, 0, len); + } + + /** + * 将指定的子串用另一指定子串覆盖。 + * + *

+ * 如果字符串为null,则返回null。 负的索引值将被看作0,越界的索引值将被设置成字符串的长度相同的值。 + *

+     * StringUtil.overlay(null, *, *, *)            = null
+     * StringUtil.overlay("", "abc", 0, 0)          = "abc"
+     * StringUtil.overlay("abcdef", null, 2, 4)     = "abef"
+     * StringUtil.overlay("abcdef", "", 2, 4)       = "abef"
+     * StringUtil.overlay("abcdef", "", 4, 2)       = "abef"
+     * StringUtil.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
+     * StringUtil.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
+     * StringUtil.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
+     * StringUtil.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
+     * StringUtil.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
+     * StringUtil.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
+     * 
+ *

+ * + * @param str 要扫描的字符串 + * @param overlay 用来覆盖的字符串 + * @param start 起始索引 + * @param end 结束索引 + * + * @return 被覆盖后的字符串,如果原始字符串为null,则返回null + */ + public static String overlay(String str, String overlay, int start, int end) { + if (str == null) { + return null; + } + + if (overlay == null) { + overlay = EMPTY_STRING; + } + + int len = str.length(); + + if (start < 0) { + start = 0; + } + + if (start > len) { + start = len; + } + + if (end < 0) { + end = 0; + } + + if (end > len) { + end = len; + } + + if (start > end) { + int temp = start; + + start = end; + end = temp; + } + + return new StringBuffer((len + start) - end + overlay.length() + 1) + .append(str.substring(0, start)).append(overlay).append(str.substring(end)).toString(); + } + + /* ============================================================================ */ + /* Perl风格的chomp和chop函数。 */ + /* ============================================================================ */ + + /** + * 删除字符串末尾的换行符。如果字符串不以换行结尾,则什么也不做。 + * + *

+ * 换行符有三种情形:"\n"、"\r"、"\r\n"。 + *

+     * StringUtil.chomp(null)          = null
+     * StringUtil.chomp("")            = ""
+     * StringUtil.chomp("abc \r")      = "abc "
+     * StringUtil.chomp("abc\n")       = "abc"
+     * StringUtil.chomp("abc\r\n")     = "abc"
+     * StringUtil.chomp("abc\r\n\r\n") = "abc\r\n"
+     * StringUtil.chomp("abc\n\r")     = "abc\n"
+     * StringUtil.chomp("abc\n\rabc")  = "abc\n\rabc"
+     * StringUtil.chomp("\r")          = ""
+     * StringUtil.chomp("\n")          = ""
+     * StringUtil.chomp("\r\n")        = ""
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 不以换行结尾的字符串,如果原始字串为null,则返回null + */ + public static String chomp(String str) { + if ((str == null) || (str.length() == 0)) { + return str; + } + + if (str.length() == 1) { + char ch = str.charAt(0); + + if ((ch == '\r') || (ch == '\n')) { + return EMPTY_STRING; + } else { + return str; + } + } + + int lastIdx = str.length() - 1; + char last = str.charAt(lastIdx); + + if (last == '\n') { + if (str.charAt(lastIdx - 1) == '\r') { + lastIdx--; + } + } else if (last == '\r') { + } else { + lastIdx++; + } + + return str.substring(0, lastIdx); + } + + /** + * 删除字符串末尾的指定字符串。如果字符串不以该字符串结尾,则什么也不做。 + *
+     * StringUtil.chomp(null, *)         = null
+     * StringUtil.chomp("", *)           = ""
+     * StringUtil.chomp("foobar", "bar") = "foo"
+     * StringUtil.chomp("foobar", "baz") = "foobar"
+     * StringUtil.chomp("foo", "foo")    = ""
+     * StringUtil.chomp("foo ", "foo")   = "foo "
+     * StringUtil.chomp(" foo", "foo")   = " "
+     * StringUtil.chomp("foo", "foooo")  = "foo"
+     * StringUtil.chomp("foo", "")       = "foo"
+     * StringUtil.chomp("foo", null)     = "foo"
+     * 
+ * + * @param str 要处理的字符串 + * @param separator 要删除的字符串 + * + * @return 不以指定字符串结尾的字符串,如果原始字串为null,则返回null + */ + public static String chomp(String str, String separator) { + if ((str == null) || (str.length() == 0) || (separator == null)) { + return str; + } + + if (str.endsWith(separator)) { + return str.substring(0, str.length() - separator.length()); + } + + return str; + } + + /** + * 删除最后一个字符。 + * + *

+ * 如果字符串以\r\n结尾,则同时删除它们。 + *

+     * StringUtil.chop(null)          = null
+     * StringUtil.chop("")            = ""
+     * StringUtil.chop("abc \r")      = "abc "
+     * StringUtil.chop("abc\n")       = "abc"
+     * StringUtil.chop("abc\r\n")     = "abc"
+     * StringUtil.chop("abc")         = "ab"
+     * StringUtil.chop("abc\nabc")    = "abc\nab"
+     * StringUtil.chop("a")           = ""
+     * StringUtil.chop("\r")          = ""
+     * StringUtil.chop("\n")          = ""
+     * StringUtil.chop("\r\n")        = ""
+     * 
+ *

+ * + * @param str 要处理的字符串 + * + * @return 删除最后一个字符的字符串,如果原始字符串为null,则返回null + */ + public static String chop(String str) { + if (str == null) { + return null; + } + + int strLen = str.length(); + + if (strLen < 2) { + return EMPTY_STRING; + } + + int lastIdx = strLen - 1; + String ret = str.substring(0, lastIdx); + char last = str.charAt(lastIdx); + + if (last == '\n') { + if (ret.charAt(lastIdx - 1) == '\r') { + return ret.substring(0, lastIdx - 1); + } + } + + return ret; + } + + /* ============================================================================ */ + /* 重复/对齐字符串。 */ + /* ============================================================================ */ + + /** + * 将指定字符串重复n遍。 + *
+     * StringUtil.repeat(null, 2)   = null
+     * StringUtil.repeat("", 0)     = ""
+     * StringUtil.repeat("", 2)     = ""
+     * StringUtil.repeat("a", 3)    = "aaa"
+     * StringUtil.repeat("ab", 2)   = "abab"
+     * StringUtil.repeat("abcd", 2) = "abcdabcd"
+     * StringUtil.repeat("a", -2)   = ""
+     * 
+ * + * @param str 要重复的字符串 + * @param repeat 重复次数,如果小于0,则看作0 + * + * @return 重复n次的字符串,如果原始字符串为null,则返回null + */ + public static String repeat(String str, int repeat) { + if (str == null) { + return null; + } + + if (repeat <= 0) { + return EMPTY_STRING; + } + + int inputLength = str.length(); + + if ((repeat == 1) || (inputLength == 0)) { + return str; + } + + int outputLength = inputLength * repeat; + + switch (inputLength) { + case 1: + + char ch = str.charAt(0); + char[] output1 = new char[outputLength]; + + for (int i = repeat - 1; i >= 0; i--) { + output1[i] = ch; + } + + return new String(output1); + + case 2: + + char ch0 = str.charAt(0); + char ch1 = str.charAt(1); + char[] output2 = new char[outputLength]; + + for (int i = (repeat * 2) - 2; i >= 0; i--, i--) { + output2[i] = ch0; + output2[i + 1] = ch1; + } + + return new String(output2); + + default: + + StringBuffer buf = new StringBuffer(outputLength); + + for (int i = 0; i < repeat; i++) { + buf.append(str); + } + + return buf.toString(); + } + } + + /** + * 扩展并左对齐字符串,用空格' '填充右边。 + *
+     * StringUtil.alignLeft(null, *)   = null
+     * StringUtil.alignLeft("", 3)     = "   "
+     * StringUtil.alignLeft("bat", 3)  = "bat"
+     * StringUtil.alignLeft("bat", 5)  = "bat  "
+     * StringUtil.alignLeft("bat", 1)  = "bat"
+     * StringUtil.alignLeft("bat", -1) = "bat"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignLeft(String str, int size) { + return alignLeft(str, size, ' '); + } + + /** + * 扩展并左对齐字符串,用指定字符填充右边。 + *
+     * StringUtil.alignLeft(null, *, *)     = null
+     * StringUtil.alignLeft("", 3, 'z')     = "zzz"
+     * StringUtil.alignLeft("bat", 3, 'z')  = "bat"
+     * StringUtil.alignLeft("bat", 5, 'z')  = "batzz"
+     * StringUtil.alignLeft("bat", 1, 'z')  = "bat"
+     * StringUtil.alignLeft("bat", -1, 'z') = "bat"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padChar 填充字符 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignLeft(String str, int size, char padChar) { + if (str == null) { + return null; + } + + int pads = size - str.length(); + + if (pads <= 0) { + return str; + } + + return alignLeft(str, size, String.valueOf(padChar)); + } + + /** + * 扩展并左对齐字符串,用指定字符串填充右边。 + *
+     * StringUtil.alignLeft(null, *, *)      = null
+     * StringUtil.alignLeft("", 3, "z")      = "zzz"
+     * StringUtil.alignLeft("bat", 3, "yz")  = "bat"
+     * StringUtil.alignLeft("bat", 5, "yz")  = "batyz"
+     * StringUtil.alignLeft("bat", 8, "yz")  = "batyzyzy"
+     * StringUtil.alignLeft("bat", 1, "yz")  = "bat"
+     * StringUtil.alignLeft("bat", -1, "yz") = "bat"
+     * StringUtil.alignLeft("bat", 5, null)  = "bat  "
+     * StringUtil.alignLeft("bat", 5, "")    = "bat  "
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padStr 填充字符串 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignLeft(String str, int size, String padStr) { + if (str == null) { + return null; + } + + if ((padStr == null) || (padStr.length() == 0)) { + padStr = " "; + } + + int padLen = padStr.length(); + int strLen = str.length(); + int pads = size - strLen; + + if (pads <= 0) { + return str; + } + + if (pads == padLen) { + return str.concat(padStr); + } else if (pads < padLen) { + return str.concat(padStr.substring(0, pads)); + } else { + char[] padding = new char[pads]; + char[] padChars = padStr.toCharArray(); + + for (int i = 0; i < pads; i++) { + padding[i] = padChars[i % padLen]; + } + + return str.concat(new String(padding)); + } + } + + /** + * 扩展并右对齐字符串,用空格' '填充左边。 + *
+     * StringUtil.alignRight(null, *)   = null
+     * StringUtil.alignRight("", 3)     = "   "
+     * StringUtil.alignRight("bat", 3)  = "bat"
+     * StringUtil.alignRight("bat", 5)  = "  bat"
+     * StringUtil.alignRight("bat", 1)  = "bat"
+     * StringUtil.alignRight("bat", -1) = "bat"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignRight(String str, int size) { + return alignRight(str, size, ' '); + } + + /** + * 扩展并右对齐字符串,用指定字符填充左边。 + *
+     * StringUtil.alignRight(null, *, *)     = null
+     * StringUtil.alignRight("", 3, 'z')     = "zzz"
+     * StringUtil.alignRight("bat", 3, 'z')  = "bat"
+     * StringUtil.alignRight("bat", 5, 'z')  = "zzbat"
+     * StringUtil.alignRight("bat", 1, 'z')  = "bat"
+     * StringUtil.alignRight("bat", -1, 'z') = "bat"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padChar 填充字符 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignRight(String str, int size, char padChar) { + if (str == null) { + return null; + } + + int pads = size - str.length(); + + if (pads <= 0) { + return str; + } + + return alignRight(str, size, String.valueOf(padChar)); + } + + /** + * 扩展并右对齐字符串,用指定字符串填充左边。 + *
+     * StringUtil.alignRight(null, *, *)      = null
+     * StringUtil.alignRight("", 3, "z")      = "zzz"
+     * StringUtil.alignRight("bat", 3, "yz")  = "bat"
+     * StringUtil.alignRight("bat", 5, "yz")  = "yzbat"
+     * StringUtil.alignRight("bat", 8, "yz")  = "yzyzybat"
+     * StringUtil.alignRight("bat", 1, "yz")  = "bat"
+     * StringUtil.alignRight("bat", -1, "yz") = "bat"
+     * StringUtil.alignRight("bat", 5, null)  = "  bat"
+     * StringUtil.alignRight("bat", 5, "")    = "  bat"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padStr 填充字符串 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String alignRight(String str, int size, String padStr) { + if (str == null) { + return null; + } + + if ((padStr == null) || (padStr.length() == 0)) { + padStr = " "; + } + + int padLen = padStr.length(); + int strLen = str.length(); + int pads = size - strLen; + + if (pads <= 0) { + return str; + } + + if (pads == padLen) { + return padStr.concat(str); + } else if (pads < padLen) { + return padStr.substring(0, pads).concat(str); + } else { + char[] padding = new char[pads]; + char[] padChars = padStr.toCharArray(); + + for (int i = 0; i < pads; i++) { + padding[i] = padChars[i % padLen]; + } + + return new String(padding).concat(str); + } + } + + /** + * 扩展并居中字符串,用空格' '填充两边。 + *
+     * StringUtil.center(null, *)   = null
+     * StringUtil.center("", 4)     = "    "
+     * StringUtil.center("ab", -1)  = "ab"
+     * StringUtil.center("ab", 4)   = " ab "
+     * StringUtil.center("abcd", 2) = "abcd"
+     * StringUtil.center("a", 4)    = " a  "
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String center(String str, int size) { + return center(str, size, ' '); + } + + /** + * 扩展并居中字符串,用指定字符填充两边。 + *
+     * StringUtil.center(null, *, *)     = null
+     * StringUtil.center("", 4, ' ')     = "    "
+     * StringUtil.center("ab", -1, ' ')  = "ab"
+     * StringUtil.center("ab", 4, ' ')   = " ab "
+     * StringUtil.center("abcd", 2, ' ') = "abcd"
+     * StringUtil.center("a", 4, ' ')    = " a  "
+     * StringUtil.center("a", 4, 'y')    = "yayy"
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padChar 填充字符 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String center(String str, int size, char padChar) { + if ((str == null) || (size <= 0)) { + return str; + } + + int strLen = str.length(); + int pads = size - strLen; + + if (pads <= 0) { + return str; + } + + str = alignRight(str, strLen + (pads / 2), padChar); + str = alignLeft(str, size, padChar); + return str; + } + + /** + * 扩展并居中字符串,用指定字符串填充两边。 + *
+     * StringUtil.center(null, *, *)     = null
+     * StringUtil.center("", 4, " ")     = "    "
+     * StringUtil.center("ab", -1, " ")  = "ab"
+     * StringUtil.center("ab", 4, " ")   = " ab "
+     * StringUtil.center("abcd", 2, " ") = "abcd"
+     * StringUtil.center("a", 4, " ")    = " a  "
+     * StringUtil.center("a", 4, "yz")   = "yayz"
+     * StringUtil.center("abc", 7, null) = "  abc  "
+     * StringUtil.center("abc", 7, "")   = "  abc  "
+     * 
+ * + * @param str 要对齐的字符串 + * @param size 扩展字符串到指定宽度 + * @param padStr 填充字符串 + * + * @return 扩展后的字符串,如果字符串为null,则返回null + */ + public static String center(String str, int size, String padStr) { + if ((str == null) || (size <= 0)) { + return str; + } + + if ((padStr == null) || (padStr.length() == 0)) { + padStr = " "; + } + + int strLen = str.length(); + int pads = size - strLen; + + if (pads <= 0) { + return str; + } + + str = alignRight(str, strLen + (pads / 2), padStr); + str = alignLeft(str, size, padStr); + return str; + } + + /* ============================================================================ */ + /* 反转字符串。 */ + /* ============================================================================ */ + + /** + * 反转字符串中的字符顺序。 + * + *

+ * 如果字符串为null,则返回null。 + *

+ *
+     * StringUtil.reverse(null)  = null
+     * StringUtil.reverse("")    = ""
+     * StringUtil.reverse("bat") = "tab"
+     * 
+ * + * @param str 要反转的字符串 + * + * @return 反转后的字符串,如果原字符串为null,则返回null + */ + public static String reverse(String str) { + if ((str == null) || (str.length() == 0)) { + return str; + } + + return new StringBuffer(str).reverse().toString(); + } + + /** + * 反转指定分隔符分隔的各子串的顺序。 + * + *

+ * 如果字符串为null,则返回null。 + *

+ *
+     * StringUtil.reverseDelimited(null, *, *)          = null
+     * StringUtil.reverseDelimited("", *, *)            = ""
+     * StringUtil.reverseDelimited("a.b.c", null, null) = "a.b.c"
+     * StringUtil.reverseDelimited("a.b.c", "", null)   = "a.b.c"
+     * StringUtil.reverseDelimited("a.b.c", ".", ",")   = "c,b,a"
+     * StringUtil.reverseDelimited("a.b.c", ".", null)  = "c b a"
+     * 
+ * + * @param str 要反转的字符串 + * @param separatorChars 分隔符,如果为null,则默认使用空白字符 + * @param separator 用来连接子串的分隔符,如果为null,默认使用空格 + * + * @return 反转后的字符串,如果原字符串为null,则返回null + */ + public static String reverseDelimited(String str, String separatorChars, String separator) { + if (str == null) { + return null; + } + + String[] strs = split(str, separatorChars); + + ArrayUtil.reverse(strs); + + if (separator == null) { + return join(strs, ' '); + } + + return join(strs, separator); + } + + /* ============================================================================ */ + /* 取得字符串的缩略。 */ + /* ============================================================================ */ + + /** + * 将字符串转换成指定长度的缩略,例如: 将"Now is the time for all good men"转换成"Now is the time for..."。 + * + *
    + *
  • + * 如果strmaxWidth短,直接返回; + *
  • + *
  • + * 否则将它转换成缩略:substring(str, 0, max-3) + "..."; + *
  • + *
  • + * 如果maxWidth小于4抛出IllegalArgumentException; + *
  • + *
  • + * 返回的字符串不可能长于指定的maxWidth。 + *
  • + *
+ * + *
+     * StringUtil.abbreviate(null, *)      = null
+     * StringUtil.abbreviate("", 4)        = ""
+     * StringUtil.abbreviate("abcdefg", 6) = "abc..."
+     * StringUtil.abbreviate("abcdefg", 7) = "abcdefg"
+     * StringUtil.abbreviate("abcdefg", 8) = "abcdefg"
+     * StringUtil.abbreviate("abcdefg", 4) = "a..."
+     * StringUtil.abbreviate("abcdefg", 3) = IllegalArgumentException
+     * 
+ * + * @param str 要检查的字符串 + * @param maxWidth 最大长度,不小于4,如果小于4,则看作4 + * + * @return 字符串缩略,如果原始字符串为null则返回null + */ + public static String abbreviate(String str, int maxWidth) { + return abbreviate(str, 0, maxWidth); + } + + /** + * 将字符串转换成指定长度的缩略,例如: 将"Now is the time for all good men"转换成"...is the time for..."。 + * + *

+ * 和abbreviate(String, int)类似,但是增加了一个“左边界”偏移量。 + * 注意,“左边界”处的字符未必出现在结果字符串的最左边,但一定出现在结果字符串中。 + *

+ * + *

+ * 返回的字符串不可能长于指定的maxWidth。 + *

+     * StringUtil.abbreviate(null, *, *)                = null
+     * StringUtil.abbreviate("", 0, 4)                  = ""
+     * StringUtil.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
+     * StringUtil.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
+     * StringUtil.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
+     * StringUtil.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
+     * StringUtil.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
+     * StringUtil.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
+     * StringUtil.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
+     * StringUtil.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
+     * StringUtil.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
+     * StringUtil.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
+     * StringUtil.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
+     * 
+ *

+ * + * @param str 要检查的字符串 + * @param offset 左边界偏移量 + * @param maxWidth 最大长度,不小于4,如果小于4,则看作4 + * + * @return 字符串缩略,如果原始字符串为null则返回null + */ + public static String abbreviate(String str, int offset, int maxWidth) { + if (str == null) { + return null; + } + + // 调整最大宽度 + if (maxWidth < 4) { + maxWidth = 4; + } + + if (str.length() <= maxWidth) { + return str; + } + + if (offset > str.length()) { + offset = str.length(); + } + + if ((str.length() - offset) < (maxWidth - 3)) { + offset = str.length() - (maxWidth - 3); + } + + if (offset <= 4) { + return str.substring(0, maxWidth - 3) + "..."; + } + + // 调整最大宽度 + if (maxWidth < 7) { + maxWidth = 7; + } + + if ((offset + (maxWidth - 3)) < str.length()) { + return "..." + abbreviate(str.substring(offset), maxWidth - 3); + } + + return "..." + str.substring(str.length() - (maxWidth - 3)); + } + + /** + * 比较两个字符串,取得两字符串开始不同的索引值。 + *
+     * StringUtil.indexOfDifference("i am a machine", "i am a robot")   = 7
+     * StringUtil.indexOfDifference(null, null)                         = -1
+     * StringUtil.indexOfDifference("", null)                           = -1
+     * StringUtil.indexOfDifference("", "")                             = -1
+     * StringUtil.indexOfDifference("", "abc")                          = 0
+     * StringUtil.indexOfDifference("abc", "")                          = 0
+     * StringUtil.indexOfDifference("abc", "abc")                       = -1
+     * StringUtil.indexOfDifference("ab", "abxyz")                      = 2
+     * StringUtil.indexOfDifference("abcde", "abxyz")                   = 2
+     * StringUtil.indexOfDifference("abcde", "xyz")                     = 0
+     * 
+ * + * @param str1 字符串1 + * @param str2 字符串2 + * + * @return 两字符串开始产生差异的索引值,如果两字符串相同,则返回-1 + */ + public static int indexOfDifference(String str1, String str2) { + if (StringUtil.equals(str1, str2)|| (StringUtil.isBlank(str1)) || (StringUtil.isBlank(str2))) { + return -1; + } + + int i; + + for (i = 0; (i < str1.length()) && (i < str2.length()); ++i) { + if (str1.charAt(i) != str2.charAt(i)) { + break; + } + } + + if ((i < str2.length()) || (i < str1.length())) { + return i; + } + + return -1; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) + { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) { + if (params == null || isEmpty(template)) { + return template; + } + return StrFormatter.format(template, params); + } + +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/TimeUtils.java b/fuint-utils/src/main/java/com/fuint/utils/TimeUtils.java new file mode 100644 index 0000000..7ea8a86 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/TimeUtils.java @@ -0,0 +1,82 @@ +package com.fuint.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 时间相关的工具类 + * + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class TimeUtils { + /** + * 日期转换为时间戳,时间戳为秒 + * + * @param day + * @param format + * @return + * @throws ParseException + */ + public static int date2timeStamp(String day, String format) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(format); + return Integer.parseInt("" + sdf.parse(day).getTime() / 1000); + } catch (ParseException e) { + e.printStackTrace(); + } + return 0; + } + + public static int date2timeStamp(Date date){ + return Integer.parseInt("" + date.getTime()/1000); + } + /** + * 时间戳(秒)转换为字符日期 + * + * @param seconds + * @param format + * @return + */ + public static String timeStamp2Date(int seconds, String format) { + if (seconds == 0) { + return null; + } + if (format == null || format.isEmpty()) { + format = "yyyy-MM-dd HH:mm:ss"; + } + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(new Date(Long.valueOf(seconds + "000"))); + } + + /** + * 获取当前系统时间戳(秒) + * + * @return + */ + public static int timeStamp() { + return Integer.parseInt(System.currentTimeMillis() / 1000 + ""); + } + + /** + * 判断指定日期是否在起始日期区间内 + * + * @param startDate + * @param endDate + * @param date + * @return boolean + */ + public static boolean isSection(Date startDate, Date endDate, Date date) { + if (startDate.getTime() <= date.getTime() && endDate.getTime() >= date.getTime()) { + return true; + } else { + return false; + } + } + + public static String formatDate(Date date, String format){ + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } +} diff --git a/fuint-utils/src/main/java/com/fuint/utils/ValidationUtil.java b/fuint-utils/src/main/java/com/fuint/utils/ValidationUtil.java new file mode 100644 index 0000000..30047c7 --- /dev/null +++ b/fuint-utils/src/main/java/com/fuint/utils/ValidationUtil.java @@ -0,0 +1,138 @@ +package com.fuint.utils; + +import org.apache.commons.lang.StringUtils; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 校验工具类 + * + * 统一返回值: true-校验成功(合法) false-校验失败(非法) + * Created by FSQ + * CopyRight https://www.fuint.cn + */ +public class ValidationUtil { + + public static boolean isNumeric(String str){ + Pattern pattern = Pattern.compile("[0-9]*"); + Matcher isNum = pattern.matcher(str); + if ( !isNum.matches() ) { + return false; + } + return true; + } + + /** + * 空校验 + * + * @param param + * @return + */ + public static boolean validateEmpty(String param) { + return !StringUtils.isEmpty(param); + } + + /** + * 长度校验 + * + * @param param + * @param minLen + * @param maxLen + * @return + */ + public static boolean validateLength(String param, int minLen, int maxLen) { + if (StringUtils.isEmpty(param)) param = ""; + return param.length() >= minLen && param.length() <= maxLen; + } + + /** + * 密码格式校验 + * @param param + * @return + */ + public static boolean validatePwdPattern(String param) { + boolean flag = false; + try { + String check = "^(?![^a-zA-Z]+$)(?!\\D+$).{6,20}$"; + Pattern regex = Pattern.compile(check); + Matcher matcher = regex.matcher(param); + flag = matcher.matches(); + } catch (Exception e) { + flag = false; + } + return flag; + } + + /** + * 校验手机号 + * + * @param param + * @return + */ + public static boolean validateMobile(String param) { + boolean flag = false; + try { + String check = "^[1][3,4,5,7,8][0-9]{9}$"; + Pattern regex = Pattern.compile(check); + Matcher matcher = regex.matcher(param); + flag = matcher.matches(); + } catch (Exception e) { + flag = false; + } + return flag; + } + + /** + * 校验邮箱 + * + * @param param + * @return + */ + public static boolean validateEmail(String param) { + boolean flag = false; + try { + String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; + Pattern regex = Pattern.compile(check); + Matcher matcher = regex.matcher(param); + flag = matcher.matches(); + } catch (Exception e) { + flag = false; + } + return flag; + } + + /** + * 校验身份证号 + * @param param + * @return + */ + public static boolean validateIdCard(String param) { + if (StringUtils.isEmpty(param)) return false; + IDCard iv = new IDCard(); + return iv.isValidatedAllIdcard(param); + } + + /** + * 校验Url + * + * @param param + * @return + */ + public static boolean validateUrl(String param) { + boolean flag = false; + try { + String check = "^(http|https|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.[a-zA-Z]{2,4})(\\:[0-9]+)?(/[^/][a-zA-Z0-9\\.\\,\\?\\'\\\\/\\+&%\\$#\\=~_\\-@]*)*$"; + Pattern regex = Pattern.compile(check); + Matcher matcher = regex.matcher(param); + flag = matcher.matches(); + } catch (Exception e) { + flag = false; + } + return flag; + } + + public static boolean isInteger(String str) { + Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); + return pattern.matcher(str).matches(); + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8e34e3e --- /dev/null +++ b/pom.xml @@ -0,0 +1,186 @@ + + + 4.0.0 + + com.fuint + fuint + pom + 1.0.0 + fuint project root + + fuint-utils + fuint-repository + fuint-application + fuint-framework + + + + org.springframework.boot + spring-boot-dependencies + 2.5.12 + + + + + UTF-8 + 1.8 + 2.9.0 + 4.0.2 + 8.0.25 + 3.1.0 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty + + + org.springframework.boot + spring-boot-actuator + + + com.zaxxer + HikariCP + + + + javax.xml.soap + javax.xml.soap-api + 1.4.0 + + + + com.sun.xml.messaging.saaj + saaj-impl + 1.5.1 + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.baomidou + mybatis-plus + ${mybatis-plus.version} + + + + com.baomidou + mybatis-plus-generator + 3.1.0 + + + + io.swagger + swagger-annotations + 1.5.21 + + + + io.swagger + swagger-models + 1.5.21 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.2.5 + + + org.mybatis + mybatis + + + + + + org.springframework + spring-context-support + + + + net.sf.ehcache + ehcache + 2.10.2 + + + + com.esotericsoftware + kryo + ${kryo.version} + + + + org.springframework + spring-aop + + + org.aspectj + aspectjweaver + + + + mysql + mysql-connector-java + ${mysql.version} + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.session + spring-session-data-redis + + + + com.github.liyiorg + weixin-popular + 2.8.0 + + + org.tuckey + urlrewritefilter + 4.0.3 + + + + org.projectlombok + lombok + provided + + + + com.squareup.okhttp3 + okhttp + 3.8.1 + + + + com.aliyun + aliyun-java-sdk-core + 4.4.6 + + + diff --git a/sbin/kill.sh b/sbin/kill.sh new file mode 100644 index 0000000..0614ada --- /dev/null +++ b/sbin/kill.sh @@ -0,0 +1,8 @@ +#!/bin/sh +APP_NAME=fuint-server + +tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [ ${tpid} ]; then + echo 'Kill Process!' + kill -9 $tpid +fi diff --git a/sbin/restart.sh b/sbin/restart.sh new file mode 100644 index 0000000..9533dbc --- /dev/null +++ b/sbin/restart.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +workdir=$(cd `dirname $0`;pwd) +cd $workdir || (echo "change to $workdir failed" && exit 1) + +./stop.sh || { echo "stop server failed" && exit 1; } +sleep 1 +./start.sh diff --git a/sbin/start.sh b/sbin/start.sh new file mode 100644 index 0000000..8eefbb9 --- /dev/null +++ b/sbin/start.sh @@ -0,0 +1,8 @@ +#!/bin/sh +rm -f tpid + +java -Dfile.encoding=UTF-8 -Xmx2048m -Xms2048m -Xss256k -Xmn1024m -jar $1 & + +echo $! > tpid + +echo Start Success! diff --git a/sbin/stop.sh b/sbin/stop.sh new file mode 100644 index 0000000..b0950c3 --- /dev/null +++ b/sbin/stop.sh @@ -0,0 +1,16 @@ +#!/bin/sh +APP_NAME=fuint-server + +tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [ ${tpid} ]; then + echo 'Stop Process...' + kill -15 $tpid +fi +sleep 5 +tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [ ${tpid} ]; then + echo 'Kill Process!' + kill -9 $tpid +else + echo 'Stop Success!' +fi diff --git a/sbin/yanhe.fuint b/sbin/yanhe.fuint new file mode 100644 index 0000000..b18aed9 --- /dev/null +++ b/sbin/yanhe.fuint @@ -0,0 +1,132 @@ +#!/bin/bash +# +# yanhe-fuint +# +# chkconfig: 2345 80 20 +# description: Starts and stops a single elasticsearch instance on this system +# + +### BEGIN INIT INFO +# Provides: yanhe-fuint +# Required-Start: $network $named +# Required-Stop: $network $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +### END INIT INFO + +# Source function library. +if [ -f /etc/rc.d/init.d/functions ]; then + . /etc/rc.d/init.d/functions +fi + +# Sets the default values for yanhe-fuint variables used in this script +FUINT_HOME="/opt/yanhe/fuint-server/target/" +LOG_DIR="/var/log/" +PID_DIR="/var/run/" + +prog="fuint-server" +pidfile="$PID_DIR/${prog}.pid" + +export FUINT_JAVA_OPTS +export JAVA_HOME + +lockfile=/var/lock/subsys/$prog + +checkJava() { + if [ -x "$JAVA_HOME/bin/java" ]; then + JAVA="$JAVA_HOME/bin/java" + else + JAVA=`which java` + fi + + if [ ! -x "$JAVA" ]; then + echo "Could not find any executable java binary. Please install java in your PATH or set JAVA_HOME" + exit 1 + fi +} + +start() { + checkJava + # Ensure that the PID_DIR exists (it is cleaned at OS startup time) + if [ -n "$PID_DIR" ] && [ ! -e "$PID_DIR" ]; then + mkdir -p "$PID_DIR" + fi + if [ -n "$pidfile" ] && [ ! -e "$pidfile" ]; then + touch "$pidfile" + fi + + cd $FUINT_HOME + echo -n $"Starting $prog: " + # if not running, start it up here, usually something like "daemon $exec" + java -Dfile.encoding=UTF-8 -Xmx2048m -Xms2048m -Xss256k -Xmn1024m -jar fuint-application.jar >> $LOG_DIR/yanhe-fuint.log + echo $! > $pidfile + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + # stop it here, often "killproc $prog" + killproc -p $pidfile -d 86400 $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + # run checks to determine if the service is running or use generic status + status -p $pidfile $prog +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/screenshots/cashier.png b/screenshots/cashier.png new file mode 100644 index 0000000..0e5517d Binary files /dev/null and b/screenshots/cashier.png differ diff --git a/screenshots/coupon-list.png b/screenshots/coupon-list.png new file mode 100644 index 0000000..4ff4196 Binary files /dev/null and b/screenshots/coupon-list.png differ diff --git a/screenshots/create.png b/screenshots/create.png new file mode 100644 index 0000000..9c4e1b2 Binary files /dev/null and b/screenshots/create.png differ diff --git a/screenshots/f1.png b/screenshots/f1.png new file mode 100644 index 0000000..3fa0dec Binary files /dev/null and b/screenshots/f1.png differ diff --git a/screenshots/f2.png b/screenshots/f2.png new file mode 100644 index 0000000..eca2a9b Binary files /dev/null and b/screenshots/f2.png differ diff --git a/screenshots/f3.png b/screenshots/f3.png new file mode 100644 index 0000000..68f5994 Binary files /dev/null and b/screenshots/f3.png differ diff --git a/screenshots/f4.png b/screenshots/f4.png new file mode 100644 index 0000000..1fac08b Binary files /dev/null and b/screenshots/f4.png differ diff --git a/screenshots/g1.png b/screenshots/g1.png new file mode 100644 index 0000000..4c42b2b Binary files /dev/null and b/screenshots/g1.png differ diff --git a/screenshots/g2.png b/screenshots/g2.png new file mode 100644 index 0000000..4506e4d Binary files /dev/null and b/screenshots/g2.png differ diff --git a/screenshots/g3.png b/screenshots/g3.png new file mode 100644 index 0000000..01c6f69 Binary files /dev/null and b/screenshots/g3.png differ diff --git a/screenshots/g4.png b/screenshots/g4.png new file mode 100644 index 0000000..85e6eab Binary files /dev/null and b/screenshots/g4.png differ diff --git a/screenshots/g5.png b/screenshots/g5.png new file mode 100644 index 0000000..c196cb2 Binary files /dev/null and b/screenshots/g5.png differ diff --git a/screenshots/home.png b/screenshots/home.png new file mode 100644 index 0000000..dcc7181 Binary files /dev/null and b/screenshots/home.png differ diff --git a/screenshots/homeV1.png b/screenshots/homeV1.png new file mode 100644 index 0000000..ca2d831 Binary files /dev/null and b/screenshots/homeV1.png differ diff --git a/screenshots/homeV2.png b/screenshots/homeV2.png new file mode 100644 index 0000000..e34a94d Binary files /dev/null and b/screenshots/homeV2.png differ diff --git a/screenshots/login.png b/screenshots/login.png new file mode 100644 index 0000000..54181f0 Binary files /dev/null and b/screenshots/login.png differ diff --git a/screenshots/miniapp.png b/screenshots/miniapp.png new file mode 100644 index 0000000..bbab07a Binary files /dev/null and b/screenshots/miniapp.png differ diff --git a/screenshots/mp.jpg b/screenshots/mp.jpg new file mode 100644 index 0000000..c10cb80 Binary files /dev/null and b/screenshots/mp.jpg differ diff --git a/screenshots/qr.png b/screenshots/qr.png new file mode 100644 index 0000000..1edbfca Binary files /dev/null and b/screenshots/qr.png differ diff --git a/screenshots/system.png b/screenshots/system.png new file mode 100644 index 0000000..8104440 Binary files /dev/null and b/screenshots/system.png differ