首次提交

main
liwenyao 5 months ago
parent f0730bd53a
commit cadb4889e8

34
.gitignore vendored

@ -0,0 +1,34 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

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

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.qsd</groupId>
<artifactId>orangecar</artifactId>
<version>1.0</version>
<name>orange_car</name>
<description>橘子汽车出租系统</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- springboot基础 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 持久层框架 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!-- 表单验证 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- hutool工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.2</version>
</dependency>
<!-- 权限 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,15 @@
package com.qsd.orange;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

@ -0,0 +1,82 @@
package com.qsd.orange.config;
import com.qsd.orange.security.AccessFailureHandler;
import com.qsd.orange.security.LoginFailureHandler;
import com.qsd.orange.security.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsServiceImpl")
private UserDetailsService userDetailsService;
@Autowired
private LoginSuccessHandler loginSuccessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
@Autowired
private AccessFailureHandler accessFailureHandler;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
//授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
//拦截规则
http.authorizeRequests()
.antMatchers("/user/login").permitAll()
.antMatchers("/login.html").permitAll()
.antMatchers("/image/**").permitAll()
.antMatchers("/system/**").hasRole("1")
.antMatchers("/statistics/**").hasRole("1")
.anyRequest().authenticated();
//登录配置
http.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/user/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(loginSuccessHandler)
.failureHandler(loginFailureHandler);
//注销配置
http.logout()
.logoutUrl("/user/logout")
.logoutSuccessUrl("/login.html");
//关闭csrf防护
http.csrf().disable();
//配置iframe请求
http.headers().frameOptions().disable();
//处理认证失败请求
http.exceptionHandling().accessDeniedHandler(accessFailureHandler);
}
//认证配置
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}

@ -0,0 +1,9 @@
package com.qsd.orange.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
}

@ -0,0 +1,26 @@
package com.qsd.orange.controller;
import com.qsd.orange.service.AnnouncementService;
import com.qsd.orange.global.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("announcement")
public class AnnouncementController {
@Autowired
private AnnouncementService announcementService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit
){
return R.success().page(announcementService.all(page, limit));
}
}

@ -0,0 +1,56 @@
package com.qsd.orange.controller;
import com.qsd.orange.po.BusCar;
import com.qsd.orange.service.CarService;
import com.qsd.orange.global.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("car")
public class CarController {
@Autowired
private CarService carService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
@RequestParam(value = "status", required = false, defaultValue = "-1")Integer status
){
return R.success().page(carService.queryAllCar(page, limit, status));
}
@GetMapping("search")
public R search(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
@RequestParam(value = "status", required = false, defaultValue = "-1") Integer status,
@RequestParam(value = "brand", required = false, defaultValue = "") String brand,
@RequestParam(value = "color", required = false, defaultValue = "") String color
){
return R.success().page(carService.queryCar(page, limit, status, brand, color));
}
@GetMapping("search/number")
public R number(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
@RequestParam(value = "number", required = false, defaultValue = "") String number
){
return R.success().page(carService.queryCarByNumber(page, limit, number));
}
@PostMapping("add")
public R add(@Valid BusCar car, Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
return R.choose(carService.add(username, car) > 0);
}
}

@ -0,0 +1,32 @@
package com.qsd.orange.controller;
import com.qsd.orange.service.CheckService;
import com.qsd.orange.global.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("check")
public class CheckController {
@Autowired
private CheckService checkService;
@PostMapping("add")
public R add(
String id,
@RequestParam(value = "problem", required = false, defaultValue = "无") String problem,
@RequestParam(value = "compensate", required = false, defaultValue = "0") Double compensate,
@RequestParam(value = "description", required = false, defaultValue = "无") String description,
Authentication authentication
){
User users = (User)authentication.getPrincipal();
return R.choose(checkService.add(id, problem, compensate, description, users.getUsername()) > 0);
}
}

@ -0,0 +1,63 @@
package com.qsd.orange.controller;
import com.qsd.orange.po.BusCustomer;
import com.qsd.orange.service.CustomerService;
import com.qsd.orange.global.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("customer")
public class CustomerController {
@Autowired
private CustomerService customerService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit
){
return R.success().page(customerService.queryCustomers(page, limit));
}
@GetMapping("search/identity")
public R searchByIdentity(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
String keyword
){
return R.success().page(customerService.queryByCustomer(page, limit, "identity", keyword));
}
@GetMapping("search/name")
public R searchByName(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
String keyword
){
return R.success().page(customerService.queryByCustomer(page, limit, "name", keyword));
}
@GetMapping("search/one/identity")
public R searchOneIdentity(String identity){
return R.success().data("item", customerService.queryOne(identity));
}
@PostMapping("add")
public R add(@Valid BusCustomer customer, Authentication authentication){
User user = (User)authentication.getPrincipal();
String username = user.getUsername();
return R.choose(customerService.addCustomer(username, customer) > 0);
}
@PostMapping("update")
public R update(@Valid BusCustomer customer){
return R.choose(customerService.updateCustomer(customer) > 0);
}
}

@ -0,0 +1,97 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import com.qsd.orange.service.RentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("rent")
public class RentController {
@Autowired
private RentService rentService;
@PostMapping("add")
public R add(String identity, String number, String returnTime, Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
int add = rentService.add(identity, number, returnTime, username);
switch (add){
case -1:
return R.error(HttpResult.CAR_IS_RENTING);
case 0:
return R.error(HttpResult.USER_INFO_ERROR);
case 1:
return R.success();
default:
return R.error(HttpResult.SERVER_ERROR);
}
}
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit
){
return R.success().page(rentService.all(page, limit));
}
@GetMapping("search")
public R search(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
String keyword,
Integer type
){
switch (type){
case 0:
return R.success().page(rentService.search(page, limit, "id", keyword));
case 1:
return R.success().page(rentService.search(page, limit, "customer_identity", keyword));
case 2:
return R.success().page(rentService.search(page, limit, "car_number", keyword));
default:
return R.error(HttpResult.PARAM_ERROR);
}
}
@PostMapping("update/returnTime")
public R update(String id, String returnTime){
int i = rentService.updateReturnTime(id, returnTime);
switch (i){
case -3:
return R.error(HttpResult.PARAM_ERROR);
case -2:
case -1:
return R.error(HttpResult.DATE_ERROR);
case 0:
return R.error(HttpResult.NOT_FOUND);
case 1:
return R.success();
default:
return R.error(HttpResult.SERVER_ERROR);
}
}
@GetMapping("info")
public R info(String id){
Map<String, Object> info = rentService.info(id);
int status = (Integer) info.get("status");
info.remove("status");
switch (status){
case -1:
return R.error(HttpResult.CAR_IS_RETURN);
case 0:
return R.error(HttpResult.NOT_FOUND);
default:
return R.success().data(info);
}
}
}

@ -0,0 +1,35 @@
package com.qsd.orange.controller;
import com.qsd.orange.po.SysUser;
import com.qsd.orange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class RouteController {
@Autowired
private UserService userService;
@GetMapping("")
public String index(Model model, Authentication authentication){
User users = (User)authentication.getPrincipal();
SysUser user = userService.getInfo(users.getUsername());
model.addAttribute("name", user.getName());
model.addAttribute("type", user.getType());
return "index";
}
@GetMapping("self")
public String self(Model model, Authentication authentication){
User users = (User)authentication.getPrincipal();
SysUser user = userService.getInfo(users.getUsername());
model.addAttribute("user", user);
return "self";
}
}

@ -0,0 +1,32 @@
package com.qsd.orange.controller;
import com.qsd.orange.dao.StatisticsDao;
import com.qsd.orange.global.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("statistics")
public class StatisticsController {
@Autowired
private StatisticsDao statisticsDao;
@GetMapping("region")
public R region(){
return R.success().data("items", statisticsDao.getRegionVo());
}
@GetMapping("salesman/{year}")
public R salesman(@PathVariable("year") String year){
return R.success().data("items", statisticsDao.getSalesman(year));
}
@GetMapping("company/{year}")
public R company(@PathVariable("year") String year){
return R.success().data("items", statisticsDao.getCompany(year));
}
}

@ -0,0 +1,34 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.R;
import com.qsd.orange.po.SysAnnouncement;
import com.qsd.orange.service.AnnouncementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("system/announcement")
public class SystemAnnouncementController {
@Autowired
private AnnouncementService announcementService;
@PostMapping("add")
public R add(@Valid SysAnnouncement announcement, Authentication authentication){
User user = (User)authentication.getPrincipal();
String username = user.getUsername();
return R.choose(announcementService.add(announcement, username) > 0);
}
@PostMapping("update")
public R update(SysAnnouncement announcement){
return R.choose(announcementService.update(announcement) > 0);
}
}

@ -0,0 +1,62 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.R;
import com.qsd.orange.po.BusCar;
import com.qsd.orange.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("system/car")
public class SystemCarController {
@Autowired
private CarService carService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
@RequestParam(value = "status", required = false, defaultValue = "-1")Integer status
){
return R.success().page(carService.queryAllCarSys(page, limit, status));
}
@GetMapping("search")
public R search(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
@RequestParam(value = "status", required = false, defaultValue = "-1") Integer status,
@RequestParam(value = "brand", required = false, defaultValue = "") String brand,
@RequestParam(value = "color", required = false, defaultValue = "") String color
){
return R.success().page(carService.queryCarSys(page, limit, status, brand, color));
}
@PostMapping("add")
public R add(@Valid BusCar car, Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
return R.choose(carService.add(username, car) > 0);
}
@PostMapping("update/all")
public R add(@Valid BusCar car){
return R.choose(carService.update(car) > 0);
}
@PostMapping("update/exist/enable")
public R enable(String number){
return R.choose(carService.updateExist(number, 1) > 0);
}
@PostMapping("update/exist/unable")
public R unable(String number){
return R.choose(carService.updateExist(number, 0) > 0);
}
}

@ -0,0 +1,31 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.R;
import com.qsd.orange.service.CheckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("system/check")
public class SystemCheckController {
@Autowired
private CheckService checkService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit
){
return R.success().page(checkService.all(page, limit));
}
@GetMapping("search")
public R search(String id){
return R.success().data("item", checkService.search(id));
}
}

@ -0,0 +1,49 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import com.qsd.orange.service.RentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("system/rent")
public class SystemRentController {
@Autowired
private RentService rentService;
@GetMapping("all")
public R all(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit
){
return R.success().page(rentService.sysAll(page, limit));
}
@GetMapping("search")
public R search(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "limit", required = false, defaultValue = "9") Integer limit,
Integer status,
String keyword,
Integer type
){
switch (type){
case 0:
return R.success().page(rentService.sysSearch(page, limit, status, "id", keyword));
case 1:
return R.success().page(rentService.sysSearch(page, limit, status, "customer_identity", keyword));
case 2:
return R.success().page(rentService.sysSearch(page, limit, status, "car_number", keyword));
default:
return R.error(HttpResult.PARAM_ERROR);
}
}
}

@ -0,0 +1,67 @@
package com.qsd.orange.controller;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.system.SystemUtil;
import com.qsd.orange.global.R;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@RestController
@RequestMapping("system/resource/image")
public class SystemResourceController {
public static final String IMAGE_PATH = SystemUtil.get("user.dir");
@PostMapping
public R updateImage(MultipartFile file){
String temp = file.getName();
System.out.println(temp);
temp = "png";
String name = System.currentTimeMillis() + "." + temp;
BufferedOutputStream outputStream = null;
try(InputStream inputStream = file.getInputStream();) {
File f = new File(IMAGE_PATH, name);
if (!f.exists()){
f.createNewFile();
}
FileWriter fileWriter = new FileWriter(f);
outputStream = fileWriter.getOutputStream();
IoUtil.copy(inputStream, outputStream);
} catch (IOException e) {
e.printStackTrace();
return R.error();
}finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return R.success().data("image", name);
}
@GetMapping("{name}")
public void show(@PathVariable("name") String name, HttpServletResponse response) {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(IMAGE_PATH, name));
response.setContentType("image/png");
IoUtil.copy(inputStream, response.getOutputStream());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

@ -0,0 +1,41 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.R;
import com.qsd.orange.po.SysUser;
import com.qsd.orange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("system/user")
public class SystemUserController {
@Autowired
private UserService userService;
@GetMapping("all")
public R all(){
return R.success().data("items", userService.all());
}
@PostMapping("add")
public R add(@Valid SysUser user){
return R.choose(userService.add(user) > 0);
}
@PostMapping("update")
public R update(@Valid SysUser user){
return R.choose(userService.update(user) > 0);
}
@GetMapping("reset")
public R reset(String username){
return R.choose(userService.reset(username) > 0);
}
}

@ -0,0 +1,54 @@
package com.qsd.orange.controller;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import com.qsd.orange.po.SysUser;
import com.qsd.orange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("info")
public R info(Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
SysUser info = userService.getInfo(username);
return R.success().data("item", info);
}
@PostMapping("update/info")
public R updateInfo(SysUser user, Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
user.setUsername(username);
return R.choose(userService.update(user) > 0);
}
@PostMapping("update/password")
public R updatePassword(String oldPassword, String newPassword, Authentication authentication){
User users = (User)authentication.getPrincipal();
String username = users.getUsername();
int i = userService.updatePassword(username, oldPassword, newPassword);
switch (i){
case -2:
return R.error(HttpResult.USERNAME_OR_PASSWORD_ERROR);
case -1:
return R.error(HttpResult.PASSWORD_NOT_SAME);
case 1:
return R.success();
default:
return R.error();
}
}
}

@ -0,0 +1,9 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.SysAnnouncement;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AnnouncementDao extends BaseMapper<SysAnnouncement> {
}

@ -0,0 +1,10 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.BusCar;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CarDao extends BaseMapper<BusCar> {
}

@ -0,0 +1,9 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.BusCheck;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CheckDao extends BaseMapper<BusCheck> {
}

@ -0,0 +1,9 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.BusCustomer;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CustomerDao extends BaseMapper<BusCustomer> {
}

@ -0,0 +1,13 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.BusRent;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RentDao extends BaseMapper<BusRent> {
String selectCarNumber(String id);
}

@ -0,0 +1,23 @@
package com.qsd.orange.dao;
import com.qsd.orange.vo.StatisticsVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface StatisticsDao {
/**
*
* */
List<StatisticsVo> getRegionVo();
/**
*
* @param year
* */
List<StatisticsVo> getSalesman(@Param("year") String year);
List<Integer> getCompany(@Param("year") String year);
}

@ -0,0 +1,13 @@
package com.qsd.orange.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qsd.orange.po.SysUser;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDao extends BaseMapper<SysUser> {
SysUser selectOneById(String username);
}

@ -0,0 +1,18 @@
package com.qsd.orange.exception;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class LoginException {
@ExceptionHandler(UsernameNotFoundException.class)
public R usernameNotFoundException(){
return R.error(HttpResult.USERNAME_OR_PASSWORD_ERROR);
}
}

@ -0,0 +1,17 @@
package com.qsd.orange.exception;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ParamException {
@ExceptionHandler(MissingServletRequestParameterException.class)
public R missingServletRequestParameterException(MissingServletRequestParameterException e){
return R.error(HttpResult.PARAM_LACK);
}
}

@ -0,0 +1,24 @@
package com.qsd.orange.exception;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.UnexpectedTypeException;
@RestControllerAdvice
public class ValidationException {
@ExceptionHandler({
MethodArgumentNotValidException.class,
BindException.class,
UnexpectedTypeException.class
})
public R validation(){
return R.error(HttpResult.PARAM_ERROR);
}
}

@ -0,0 +1,41 @@
package com.qsd.orange.global;
public enum HttpResult {
SUCCESS(200, "成功"),
UN_AUTHORIZED(403, "权限错误"),
NOT_FOUND(404, "资源未找到"),
SERVER_ERROR(500, "服务器错误"),
USERNAME_OR_PASSWORD_ERROR(501, "用户名或密码错误"),
CAR_IS_RENTING(502, "车辆已被出租"),
USER_INFO_ERROR(503, "用户信息错误"),
PARAM_ERROR(504, "参数错误"),
DATE_ERROR(505, "参数日期错误"),
CAR_IS_RETURN(506, "车辆已归还"),
PARAM_LACK(507, "参数缺少"),
PASSWORD_NOT_SAME(508, "新密码与旧密码不能相同");
private Integer code;
private String message;
HttpResult(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

@ -0,0 +1,113 @@
package com.qsd.orange.global;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.core.metadata.IPage;
public class R {
private Boolean success;
private Integer code;
private String message;
private Map<String, Object> data = new HashMap<String, Object>();
private R() {
}
public R success(Boolean success) {
this.setSuccess(success);
return this;
}
public R message(String message) {
this.setMessage(message);
return this;
}
public R code(Integer code) {
this.setCode(code);
return this;
}
public R data(String key, Object value) {
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map) {
this.setData(map);
return this;
}
public <T> R page(IPage<T> page) {
this.data("total", page.getTotal()).data("record", page.getRecords());
return this;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
public static R choose(boolean flag) {
if (flag) {
return success();
} else {
return error();
}
}
public static R success() {
R r = new R();
r.setSuccess(true);
r.setCode(200);
r.setMessage("成功");
return r;
}
public static R error() {
R r = new R();
r.setSuccess(false);
r.setCode(500);
r.setMessage("失败");
return r;
}
public static R error(HttpResult result) {
R r = new R();
r.setSuccess(false);
r.setCode(result.getCode());
r.setMessage(result.getMessage());
return r;
}
}

@ -0,0 +1,125 @@
package com.qsd.orange.po;
import java.io.Serializable;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
*
*/
@TableName("bus_car")
public class BusCar implements Serializable {
private static final long serialVersionUID = 7074654537514458969L;
@TableId(type = IdType.NONE)
@NotBlank
private String number;
@NotBlank
private String brand;
@NotBlank
private String color;
@TableField("buy_price")
@NotNull
private Double buyPrice;
@TableField("rent_price")
@NotNull
private Double rentPrice;
//押金
@NotNull
private Double deposit;
//出租状态
@Null
private Integer status;
@NotBlank
private String description;
@NotBlank
private String image;
@Null
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
private Timestamp created;
@Null
private String operator;
@Null
private Integer exist;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Double getBuyPrice() {
return buyPrice;
}
public void setBuyPrice(Double buyPrice) {
this.buyPrice = buyPrice;
}
public Double getRentPrice() {
return rentPrice;
}
public void setRentPrice(Double rentPrice) {
this.rentPrice = rentPrice;
}
public Double getDeposit() {
return deposit;
}
public void setDeposit(Double deposit) {
this.deposit = deposit;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public Integer getExist() {
return exist;
}
public void setExist(Integer exist) {
this.exist = exist;
}
}

@ -0,0 +1,74 @@
package com.qsd.orange.po;
import java.io.Serializable;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
*
*/
@TableName("bus_check")
public class BusCheck implements Serializable {
private static final long serialVersionUID = 7083995801146703176L;
@TableId(type = IdType.NONE)
private String id;
@TableField("check_date")
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
private Timestamp checkDate;
private String description;
private String problem;
private Double compensate;
private String operator;
@TableField("rent_id")
private String rentId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Timestamp getCheckDate() {
return checkDate;
}
public void setCheckDate(Timestamp checkDate) {
this.checkDate = checkDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getProblem() {
return problem;
}
public void setProblem(String problem) {
this.problem = problem;
}
public Double getCompensate() {
return compensate;
}
public void setCompensate(Double compensate) {
this.compensate = compensate;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getRentId() {
return rentId;
}
public void setRentId(String rentId) {
this.rentId = rentId;
}
}

@ -0,0 +1,96 @@
package com.qsd.orange.po;
import java.io.Serializable;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Null;
/**
*
*/
@TableName("bus_customer")
public class BusCustomer implements Serializable {
private static final long serialVersionUID = 6658064314710608402L;
@TableId(type = IdType.NONE)
@NotBlank
private String identity;
@NotBlank
private String name;
private Integer gender;
private String address;
private String phone;
private String career;
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
@Null
private Timestamp created;
@Null
private Boolean exist;
@Null
private String operator;
public String getIdentity() {
return identity;
}
public void setIdentity(String identity) {
this.identity = identity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCareer() {
return career;
}
public void setCareer(String career) {
this.career = career;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
public Boolean getExist() {
return exist;
}
public void setExist(Boolean exist) {
this.exist = exist;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
}

@ -0,0 +1,102 @@
package com.qsd.orange.po;
import java.io.Serializable;
import java.sql.Date;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
*
*/
@TableName("bus_rent")
public class BusRent implements Serializable {
private static final long serialVersionUID = 6129197607180087634L;
@TableId(type = IdType.NONE)
private String id;
private Double price;
@TableField("begin_time")
@JsonFormat(pattern="yyyy-MM-dd", timezone="GMT+8")
private Date beginTime;
@TableField("return_time")
@JsonFormat(pattern="yyyy-MM-dd", timezone="GMT+8")
private Date returnTime;
@TableField("real_time")
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
private Timestamp realTime;
@TableField("rent_status")
private Integer rentStatus;
@TableField("customer_identity")
private String customerIdentity;
@TableField("car_number")
private String carNumber;
private String operator;
private Timestamp created;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getReturnTime() {
return returnTime;
}
public void setReturnTime(Date returnTime) {
this.returnTime = returnTime;
}
public Timestamp getRealTime() {
return realTime;
}
public void setRealTime(Timestamp realTime) {
this.realTime = realTime;
}
public Integer getRentStatus() {
return rentStatus;
}
public void setRentStatus(Integer rentStatus) {
this.rentStatus = rentStatus;
}
public String getCustomerIdentity() {
return customerIdentity;
}
public void setCustomerIdentity(String customerIdentity) {
this.customerIdentity = customerIdentity;
}
public String getCarNumber() {
return carNumber;
}
public void setCarNumber(String carNumber) {
this.carNumber = carNumber;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
}

@ -0,0 +1,64 @@
package com.qsd.orange.po;
import java.io.Serializable;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Null;
/**
*
*/
@TableName("sys_announcement")
public class SysAnnouncement implements Serializable {
private static final long serialVersionUID = 4845165626198699466L;
@TableId(type = IdType.AUTO)
@Null
private Integer id;
@NotBlank
private String title;
@NotBlank
private String content;
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
@Null
private Timestamp created;
@Null
private String operator;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
}

@ -0,0 +1,92 @@
package com.qsd.orange.po;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Null;
/**
*
*/
@TableName("sys_user")
public class SysUser implements Serializable {
private static final long serialVersionUID = 5546148053917409573L;
@TableId(type = IdType.NONE)
@NotBlank
private String username;
@Null
private String password;
@NotBlank
private String identity;
@NotBlank
private String name;
private Integer gender;
private String address;
private String phone;
private String position;
@Null
private Integer type;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getIdentity() {
return identity;
}
public void setIdentity(String identity) {
this.identity = identity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}

@ -0,0 +1,28 @@
package com.qsd.orange.security;
import cn.hutool.json.JSONUtil;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*
*/
@Component
public class AccessFailureHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
accessDeniedException.printStackTrace();
response.setHeader("Content-Type", "application/json;charset=utf-8");
response.getWriter().print(JSONUtil.parseObj(R.error(HttpResult.UN_AUTHORIZED)).toJSONString(4));
}
}

@ -0,0 +1,25 @@
package com.qsd.orange.security;
import cn.hutool.json.JSONUtil;
import com.qsd.orange.global.HttpResult;
import com.qsd.orange.global.R;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class LoginFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(JSONUtil.toJsonStr(R.error(HttpResult.USERNAME_OR_PASSWORD_ERROR)));
}
}

@ -0,0 +1,26 @@
package com.qsd.orange.security;
import cn.hutool.json.JSONUtil;
import com.qsd.orange.global.R;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(JSONUtil.toJsonStr(R.success()));
}
}

@ -0,0 +1,15 @@
package com.qsd.orange.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qsd.orange.po.SysAnnouncement;
public interface AnnouncementService {
//查询全部公告
IPage<SysAnnouncement> all(Integer page, Integer limit);
//新增一条公告
int add(SysAnnouncement announcement, String username);
//更新一条公告
int update(SysAnnouncement announcement);
}

@ -0,0 +1,53 @@
package com.qsd.orange.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qsd.orange.po.BusCar;
public interface CarService {
/**
*
* @param page
* @param limit
* @param status
* */
IPage<BusCar> queryAllCar(Integer page, Integer limit, Integer status);
/**
*
* @param page
* @param limit
* @param status
* @param brand
* @param color
* */
IPage<BusCar> queryCar(Integer page, Integer limit, Integer status, String brand, String color);
/**
*
*
* */
IPage<BusCar> queryAllCarSys(Integer page, Integer limit, Integer status);
/**
*
*
* */
IPage<BusCar> queryCarSys(Integer page, Integer limit, Integer status, String brand, String color);
IPage<BusCar> queryCarByNumber(Integer page, Integer limit, String number);
/**
*
* @param username
* @param car
* */
int add(String username, BusCar car);
/**
*
* @param car
* */
int update(BusCar car);
/**
* /
* @param number
* @param exist
* */
int updateExist(String number, Integer exist);
}

@ -0,0 +1,29 @@
package com.qsd.orange.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qsd.orange.po.BusCheck;
public interface CheckService {
/**
*
* @param id
* @param problem
* @param compensate
* @param description
* @param operator
* */
int add(String id, String problem, Double compensate, String description, String operator);
/**
*
* @param page
* @param limit
* */
IPage<BusCheck> all(Integer page, Integer limit);
/**
*
* @param id
* */
BusCheck search(String id);
}

@ -0,0 +1,36 @@
package com.qsd.orange.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qsd.orange.po.BusCustomer;
public interface CustomerService {
/**
*
* */
IPage<BusCustomer> queryCustomers(Integer page, Integer limit);
/**
*
* @param page
* @param limit
* @param type
* @param keyword
* */
IPage<BusCustomer> queryByCustomer(Integer page, Integer limit, String type, String keyword);
/**
*
* */
BusCustomer queryOne(String identity);
/**
*
* @param operator
* @param customer
* */
int addCustomer(String operator, BusCustomer customer);
/**
*
* @param customer
* */
int updateCustomer(BusCustomer customer);
}

@ -0,0 +1,62 @@
package com.qsd.orange.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qsd.orange.po.BusRent;
import java.util.Map;
public interface RentService {
/**
*
*
* -2-101
* @param identity
* @param number
* @param username
* @return
* */
int add(String identity, String number, String returnTime, String username);
/**
*
* @param page
* @param limit
* */
IPage<BusRent> all(Integer page, Integer limit);
/**
*
* @param page
* @param limit
* @param type
* @param keyword
* */
IPage<BusRent> search(Integer page, Integer limit, String type, String keyword);
/**
*
* @param id
* @param returnTime
* @return 0-1-21-3
* */
int updateReturnTime(String id, String returnTime);
/**
*
* @param id
* */
Map<String, Object> info(String id);
/**
*
* @param page
* @param limit
* */
IPage<BusRent> sysAll(Integer page, Integer limit);
/**
*
* @param page
* @param limit
* @param status
* @param type
* @param keyword
* */
IPage<BusRent> sysSearch(Integer page, Integer limit, Integer status, String type, String keyword);
}

@ -0,0 +1,45 @@
package com.qsd.orange.service;
import com.qsd.orange.po.SysUser;
import java.util.List;
public interface UserService {
/**
*
* @param user
* @return 10
* */
int add(SysUser user);
/**
*
* @param user
* @return 10
* */
int update(SysUser user);
/***
*
* @param username
* @param oldPassword
* @param newPassword
* @return 01-1:-2
*/
int updatePassword(String username, String oldPassword, String newPassword);
/**
*
* @param username
* */
SysUser getInfo(String username);
/**
*
* */
List<SysUser> all();
/**
* 123456
* @param username
* */
int reset(String username);
}

@ -0,0 +1,40 @@
package com.qsd.orange.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsd.orange.dao.AnnouncementDao;
import com.qsd.orange.po.SysAnnouncement;
import com.qsd.orange.service.AnnouncementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AnnouncementServiceImpl implements AnnouncementService {
@Autowired
private AnnouncementDao announcementDao;
@Override
public IPage<SysAnnouncement> all(Integer page, Integer limit) {
return announcementDao.selectPage(new Page<>(page, limit), new QueryWrapper<SysAnnouncement>().orderByDesc("created"));
}
@Override
public int add(SysAnnouncement announcement, String username) {
announcement.setOperator(username);
announcement.setCreated(DateUtil.date().toTimestamp());
return announcementDao.insert(announcement);
}
@Override
public int update(SysAnnouncement announcement) {
SysAnnouncement temp = new SysAnnouncement();
temp.setId(announcement.getId());
temp.setTitle(announcement.getTitle());
temp.setContent(announcement.getContent());
return announcementDao.updateById(temp);
}
}

@ -0,0 +1,97 @@
package com.qsd.orange.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsd.orange.dao.CarDao;
import com.qsd.orange.po.BusCar;
import com.qsd.orange.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CarServiceImpl implements CarService {
@Autowired
private CarDao carDao;
@Override
public IPage<BusCar> queryAllCar(Integer page, Integer limit, Integer status) {
return carDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCar>()
.and(true, i -> i
.eq(status >= 0, "status", status)
.eq("exist", 1)
).orderByDesc("created"));
}
@Override
public IPage<BusCar> queryCar(Integer page, Integer limit, Integer status, String brand, String color) {
return carDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCar>()
.and(true, i -> i
.like(brand != "", "brand", brand)
.like(color != "", "color", color)
.eq("exist", 1)
)
.orderByDesc("created"));
}
@Override
public IPage<BusCar> queryAllCarSys(Integer page, Integer limit, Integer status) {
return carDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCar>().eq(status >= 0, "status", status).orderByDesc("created"));
}
@Override
public IPage<BusCar> queryCarSys(Integer page, Integer limit, Integer status, String brand, String color) {
return carDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCar>()
.and(true, i -> i
.like(brand != "", "brand", brand)
.like(color != "", "color", color)
)
.orderByDesc("created"));
}
@Override
public IPage<BusCar> queryCarByNumber(Integer page, Integer limit, String number) {
return carDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCar>()
.and(true, i -> i
.eq(true, "status", 0)
.eq(!number.equals(""), "number", number)
.eq("exist", 1)
)
.orderByDesc("created"));
}
@Override
public int add(String username, BusCar car) {
car.setCreated(DateUtil.date().toTimestamp());
car.setOperator(username);
car.setStatus(0);
car.setExist(1);
return carDao.insert(car);
}
@Override
public int update(BusCar car) {
return carDao.updateById(car);
}
@Override
public int updateExist(String number, Integer exist) {
BusCar car = new BusCar();
car.setNumber(number);
car.setExist(exist);
return carDao.updateById(car);
}
}

@ -0,0 +1,78 @@
package com.qsd.orange.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsd.orange.dao.CarDao;
import com.qsd.orange.dao.CheckDao;
import com.qsd.orange.dao.RentDao;
import com.qsd.orange.po.BusCar;
import com.qsd.orange.po.BusCheck;
import com.qsd.orange.po.BusRent;
import com.qsd.orange.service.CheckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
@Service
public class CheckServiceImpl implements CheckService {
@Autowired
private CheckDao checkDao;
@Autowired
private RentDao rentDao;
@Autowired
private CarDao carDao;
@Override
@Transactional
public int add(String id, String problem, Double compensate, String description, String operator) {
String number = rentDao.selectCarNumber(id);
if(StrUtil.isEmpty(number)){
return 0;
}
BusCheck check = new BusCheck();
Timestamp returnTime = DateUtil.date().toTimestamp();
check.setId("JC_" + DateUtil.date().toString("yyyyMMdd") + "_" + System.currentTimeMillis() + "_" + RandomUtil.randomNumbers(4));
check.setCheckDate(returnTime);
check.setCompensate(compensate);
check.setDescription(description);
check.setProblem(problem);
check.setRentId(id);
check.setOperator(operator);
int insert = checkDao.insert(check);
if (insert > 0){
//修改出租单状态
BusRent rent = new BusRent();
rent.setId(id);
rent.setRentStatus(1);
rent.setRealTime(returnTime);
rentDao.updateById(rent);
//修改车辆状态
BusCar car = new BusCar();
car.setNumber(number);
car.setStatus(0);
carDao.updateById(car);
}
return insert;
}
@Override
public IPage<BusCheck> all(Integer page, Integer limit) {
return checkDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusCheck>().orderByDesc("check_date")
);
}
@Override
public BusCheck search(String id) {
return checkDao.selectById(id);
}
}

@ -0,0 +1,48 @@
package com.qsd.orange.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsd.orange.dao.CustomerDao;
import com.qsd.orange.po.BusCustomer;
import com.qsd.orange.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerDao customerDao;
@Override
public IPage<BusCustomer> queryCustomers(Integer page, Integer limit) {
return customerDao.selectPage(new Page<>(page, limit), new QueryWrapper<BusCustomer>().orderByDesc(true, "created"));
}
@Override
public IPage<BusCustomer> queryByCustomer(Integer page, Integer limit, String type, String keyword) {
return customerDao.selectPage(new Page<>(page, limit), new QueryWrapper<BusCustomer>().like(true, type, keyword).orderByDesc(true, "created"));
}
@Override
public BusCustomer queryOne(String identity) {
return customerDao.selectOne(new QueryWrapper<BusCustomer>().eq("identity", identity));
}
@Override
public int addCustomer(String operator, BusCustomer customer) {
customer.setCreated(DateUtil.date().toTimestamp());
customer.setOperator(operator);
return customerDao.insert(customer);
}
@Override
public int updateCustomer(BusCustomer customer) {
return customerDao.updateById(customer);
}
}

@ -0,0 +1,154 @@
package com.qsd.orange.service.impl;
import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsd.orange.dao.CarDao;
import com.qsd.orange.dao.CustomerDao;
import com.qsd.orange.dao.RentDao;
import com.qsd.orange.po.BusCar;
import com.qsd.orange.po.BusCustomer;
import com.qsd.orange.po.BusRent;
import com.qsd.orange.service.RentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class RentServiceImpl implements RentService {
@Autowired
private CarDao carDao;
@Autowired
private RentDao rentDao;
@Autowired
private CustomerDao customerDao;
@Override
public int add(String identity, String number, String returnTime, String username) {
//查找车辆信息
BusCar car = carDao.selectById(number);
if (car == null){
return -2;
}
if (car.getStatus() == 1){
return -1;
}
BusRent rent = new BusRent();
rent.setCreated(DateUtil.date().toTimestamp());
rent.setBeginTime(DateUtil.date().toSqlDate());
rent.setRentStatus(0);
rent.setCarNumber(number);
rent.setReturnTime(DateUtil.parse(returnTime).toSqlDate());
rent.setOperator(username);
rent.setPrice(car.getRentPrice());
rent.setCustomerIdentity(identity);
rent.setId("CZ_" + DateUtil.date().toString("yyyyMMdd") + "_" + System.currentTimeMillis() + "_" + RandomUtil.randomNumbers(4));
int insert = rentDao.insert(rent);
if (insert == 0){
return 0;
}
//修改汽车状态
BusCar busCar = new BusCar();
busCar.setNumber(number);
busCar.setStatus(1);
return carDao.updateById(busCar);
}
@Override
public IPage<BusRent> all(Integer page, Integer limit) {
return rentDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusRent>()
.eq("rent_status", 0)
.orderByDesc("created"));
}
@Override
public IPage<BusRent> search(Integer page, Integer limit, String type, String keyword) {
return rentDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusRent>()
.and(true, i -> i
.eq("rent_status", 0)
.like(type, keyword))
.orderByDesc("created"));
}
@Override
public int updateReturnTime(String id, String returnTime) {
//首先获取原本开始日期、归还日期
BusRent rent = rentDao.selectById(id);
if (rent == null){
return 0;
}
DateTime returnDate = null;
try {
returnDate = DateUtil.parse(returnTime);
}catch (DateException e){
return -3;
}
if (returnDate.isBefore(rent.getBeginTime())){
return -1;
}
if (returnDate.isBefore(DateUtil.date())){
return -2;
}
if (returnDate.compareTo(rent.getReturnTime()) == 0){
return 1;
}
BusRent newRent = new BusRent();
newRent.setId(id);
newRent.setReturnTime(returnDate.toSqlDate());
//进行比对
return rentDao.updateById(newRent);
}
@Override
public Map<String, Object> info(String id) {
Map<String, Object> info = new HashMap<>();
//出租单、车辆信息、客户信息
BusRent rent = rentDao.selectById(id);
if (rent == null){
info.put("status", 0);
return info;
}
if (rent.getRentStatus() == 1){
info.put("status", -1);
return info;
}
info.put("status", 1);
info.put("rent", rent);
BusCustomer customer = customerDao.selectById(rent.getCustomerIdentity());
info.put("customer", customer);
BusCar car = carDao.selectById(rent.getCarNumber());
info.put("car", car);
return info;
}
@Override
public IPage<BusRent> sysAll(Integer page, Integer limit) {
return rentDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusRent>()
.orderByDesc("created"));
}
@Override
public IPage<BusRent> sysSearch(Integer page, Integer limit, Integer status, String type, String keyword) {
return rentDao.selectPage(
new Page<>(page, limit),
new QueryWrapper<BusRent>()
.and(true, i -> i
.eq(status != 2, "rent_status", status)
.like(type, keyword))
.orderByDesc("created"));
}
}

@ -0,0 +1,30 @@
package com.qsd.orange.service.impl;
import com.qsd.orange.dao.UserDao;
import com.qsd.orange.po.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userDao.selectById(username);
if (user == null){
throw new UsernameNotFoundException("用户名没有找到");
}
return new User(username,
user.getPassword(),
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_" + user.getType().toString()));
}
}

@ -0,0 +1,73 @@
package com.qsd.orange.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qsd.orange.dao.UserDao;
import com.qsd.orange.po.SysUser;
import com.qsd.orange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
public int add(SysUser user) {
user.setType(0);
//设置密码
String password = passwordEncoder.encode("123456");
user.setPassword(password);
return userDao.insert(user);
}
@Override
public int update(SysUser user) {
return userDao.updateById(user);
}
@Override
public int updatePassword(String username, String oldPassword, String newPassword) {
SysUser user = userDao.selectById(username);
//真实密码
String password = user.getPassword();
//判断原密码是否正确
if (!passwordEncoder.matches(oldPassword, password)){
return -2;
}
newPassword = passwordEncoder.encode(newPassword);
//判断新密码与原密码是否相同
if (password.equals(newPassword)){
return -1;
}
SysUser up = new SysUser();
up.setUsername(username);
up.setPassword(newPassword);
return userDao.updateById(up);
}
@Override
public SysUser getInfo(String username) {
return userDao.selectOneById(username);
}
@Override
public List<SysUser> all() {
return userDao.selectList(new QueryWrapper<SysUser>().eq("type", 0));
}
@Override
public int reset(String username) {
SysUser user = new SysUser();
user.setUsername(username);
user.setPassword(passwordEncoder.encode("123456"));
return userDao.updateById(user);
}
}

@ -0,0 +1,26 @@
package com.qsd.orange.vo;
import java.io.Serializable;
public class StatisticsVo implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Integer value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}

@ -0,0 +1,23 @@
server:
port: 8081
spring:
application:
name: orangecar
datasource:
url: jdbc:mysql://localhost:3306/carrent?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
username: root
password: 599377
driver-class-name: com.mysql.cj.jdbc.Driver
thymeleaf:
cache: false
encoding: UTF-8
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.qsd.orange.po

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qsd.orange.dao.RentDao">
<select id="selectCarNumber" resultType="java.lang.String">
select car_number
from bus_rent
where id = #{id}
</select>
</mapper>

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qsd.orange.dao.StatisticsDao">
<select id="getRegionVo" resultType="com.qsd.orange.vo.StatisticsVo">
select address as name, count(1) as value from bus_customer group by address;
</select>
<select id="getSalesman" resultType="com.qsd.orange.vo.StatisticsVo">
select operator as name, sum(price) as value from bus_rent where date_format(created, '%Y') = #{year} group by operator;
</select>
<select id="getCompany" resultType="java.lang.Integer">
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '01')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '02')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '03')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '04')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '05')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '06')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '07')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '08')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '09')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '10')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '11')
union all
select ifnull(sum(price), 0) from bus_rent where date_format(created, '%Y%m') = concat(#{year}, '12');
</select>
</mapper>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qsd.orange.dao.UserDao">
<select id="selectOneById" resultType="com.qsd.orange.po.SysUser">
select username, identity, name, gender, address, phone, position, type
from sys_user
where username = #{username}
</select>
</mapper>

@ -0,0 +1,277 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row">
<div class="layui-row" style="margin: 20px;">
<div class="layui-card">
<div class="layui-card-header"><i class="layui-icon layui-icon-search"></i>查询条件</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane layui-col-xs6">
<div class="demoTable">
<label class="layui-form-label">出租单号</label>
<div class="layui-inline">
<input class="layui-input" name="id" autocomplete="off">
</div>
<button class="layui-btn" lay-submit lay-filter="search">搜索</button>
</div>
</form>
</div>
</div>
</div>
<div class="layui-row" style="margin-left: 20px;margin-right: 20px;">
<!-- 生成检查单 -->
<div class="layui-row">
<div class="layui-card">
<div class="layui-card-header">生成检查单</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane" lay-filter="check">
<div class="layui-row">
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">出租单号</label>
<div class="layui-input-block">
<input type="text" id="number" class="layui-input" disabled>
</div>
</div>
</div>
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">检查日期</label>
<div class="layui-input-block">
<input id="checkTime" type="text" class="layui-input" disabled>
</div>
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">存在问题</label>
<div class="layui-input-block">
<input type="text" name="problem" class="layui-input" lay-verify="required" required>
</div>
</div>
</div>
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">赔付金额</label>
<div class="layui-input-block">
<input type="text" name="compensate" class="layui-input" lay-verify="required" required>
</div>
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">问题描述</label>
<div class="layui-input-block">
<textarea name="description" required lay-verify="required" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="addCheck">还车</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- 相关信息 -->
<div class="layui-row layui-col-space15" id="otherInfo" style="margin-top: 20px;">
<div class="layui-col-xs4">
<div class="layui-card">
<div class="layui-card-header">车辆信息</div>
<div class="layui-card-body layui-row">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">车牌</label>
<div class="layui-input-block">
<input type="text" v-model="car.number" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">品牌</label>
<div class="layui-input-block">
<input type="text" v-model="car.brand" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">颜色</label>
<div class="layui-input-block">
<input type="text" v-model="car.color" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">图片</label>
<div class="layui-input-block">
<button class="layui-btn" @click="show(car.image)">查看</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-card">
<div class="layui-card-header">出租单信息</div>
<div class="layui-card-body layui-row">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">单号</label>
<div class="layui-input-block">
<input type="text" v-model="rent.id" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">出租价格</label>
<div class="layui-input-block">
<input type="text" v-model="rent.price" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">起租时间</label>
<div class="layui-input-block">
<input type="text" v-model="rent.beginTime" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">还车时间</label>
<div class="layui-input-block">
<input type="text" v-model="rent.returnTime" class="layui-input" disabled>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-card">
<div class="layui-card-header">客户信息</div>
<div class="layui-card-body layui-row">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">身份证还</label>
<div class="layui-input-block">
<input type="text" v-model="customer.identity" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" v-model="customer.name" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
<input type="text" v-if="customer.gender == 1" value="男" class="layui-input" disabled>
<input type="text" v-else-if="customer.gender == 2" value="男" class="layui-input" disabled>
<input type="text" v-else value="未知" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" v-model="customer.phone" class="layui-input" disabled>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="application/javascript">
let rentId = '';
let vue = new Vue({
el: '#otherInfo',
data: {
car: {},
rent: {},
customer: {}
},
methods: {
show: function (image) {
layer.open({
type: 1,
content: '<img src="/system/resource/image/' + image + '" title="汽车图片">' //这里content是一个普通的String
});
}
}
})
layui.use(['layer', 'form', 'laydate'], function () {
let layer = layui.layer;
let form = layui.form;
let laydate = layui.laydate;
form.on('submit(search)', function (data) {
let id = data.field.id;
$.getJSON('../rent/info', {
id: id
}, function (res) {
if (res.code == 200){
rentId = id
$("#number").val(id);
laydate.render({
elem: '#checkTime', //指定元素
value: new Date()
});
vue.car = res.data.car;
vue.customer = res.data.customer;
vue.rent = res.data.rent;
}else if (res.code == 404){
layer.alert('出租单号错误')
}else if (res.code == 506){
layer.alert('车辆已归还')
}
});
return false;
});
form.val("check", {
problem: '无',
compensate: 0.0,
description: '无'
});
form.on('submit(addCheck)', function (data) {
let problem = data.field.problem;
let compensate = data.field.compensate;
let description = data.field.description;
if(rentId == ''){
layer.alert('未填写正确的出租单号');
return false;
}
$.post('../check/add', {
id: rentId,
problem: problem,
compensate: compensate,
description: description
}, function (res) {
if(res.code == 200){
layer.alert('还车成功', function () {
location.reload();
})
}else {
layer.alert('服务器错误')
}
}, 'json');
return false;
})
});
</script>
</html>

@ -0,0 +1,336 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row">
<div class="layui-row" style="margin: 20px;">
<div class="layui-card">
<div class="layui-card-header"><i class="layui-icon layui-icon-search"></i>查询条件</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane layui-col-xs6">
<div class="demoTable">
<label class="layui-form-label">身份证号</label>
<div class="layui-inline">
<input class="layui-input" name="identity" autocomplete="off">
</div>
<button class="layui-btn" lay-submit lay-filter="search">搜索</button>
</div>
</form>
</div>
</div>
</div>
<div class="layui-row" style="margin-left: 20px;margin-right: 20px;">
<div class="layui-card">
<div class="layui-card-header">车辆列表</div>
<div class="layui-card-body layui-row">
<!-- 搜索条件 -->
<form class="layui-form layui-form-pane layui-row">
<div class="demoTable">
<label class="layui-form-label">汽车牌照</label>
<div class="layui-inline">
<input class="layui-input" name="number" autocomplete="off">
</div>
<button class="layui-btn" lay-submit lay-filter="searchCar">搜索</button>
</div>
</form>
<!-- 显示 -->
<table id="cars" lay-filter="cars"></table>
</div>
</div>
</div>
</div>
</body>
<script type="text/html" id="rightBar">
<a class="layui-btn layui-btn-xs" lay-event="info">详情</a>
<a class="layui-btn layui-btn-xs" lay-event="choose">选择</a>
</script>
<script type="text/html" id="rentDialog">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" value="{{ d.identity }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">客户姓名</label>
<div class="layui-input-block">
<input type="text" value="{{ d.name }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">车辆车牌</label>
<div class="layui-input-block">
<input type="text" value="{{ d.number }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">出租价格</label>
<div class="layui-input-block">
<input type="text" value="{{ d.rentPrice }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">起租时间</label>
<div class="layui-input-block">
<input type="text" id="beginTime" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">还车时间</label>
<div class="layui-input-block">
<input type="text" name="returnTime" class="layui-input" id="returnTime" lay-verify="required">
</div>
</div>
</div>
</script>
<!-- 用户信息 -->
<script type="text/html" id="customerDialog">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" value="{{ d.identity }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" value="{{ d.name }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
{{# if(d.gender === 1){ }}
<input type="text" value="男" class="layui-input" disabled>
{{# } else if(d.gender === 2){ }}
<input type="text" value="女" class="layui-input" disabled>
{{# } }}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-block">
<input type="text" value="{{ d.address }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" value="{{ d.phone }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">职位</label>
<div class="layui-input-block">
<input type="text" value="{{ d.career }}" class="layui-input" disabled>
</div>
</div>
</div>
</script>
<script type="application/javascript">
let addDialog = -1;
let isShow = false;
let customer = {};
layui.use(['layer', 'form', 'table', 'laytpl', 'laydate'], function () {
let layer = layui.layer;
let form = layui.form;
let table = layui.table;
let laytpl = layui.laytpl;
let laydate = layui.laydate;
//搜索汽车
form.on('submit(searchCar)', function (data){
let number = data.field.number;
console.log(data.field)
if(!isShow){
layer.alert('请先选择用户');
return false;
}
table.reload('car', {
url: '../car/search/number',
page: {
curr: 1 //重新从第 1 页开始
},
where: {
number: number
}
});
return false;
})
//查询
form.on('submit(search)', function(data){
let identity = data.field.identity;
$.getJSON('../customer/search/one/identity', {
identity: identity
}, function (res) {
if(res.code == 200){
//用户信息展示
let customerDialog = $('#customerDialog').html();
laytpl(customerDialog).render(res.data.item, function(html){
layer.open({
type: 1,
area: ['500px', '450px'],
title: '用户信息',
closeBtn: 0,
shadeClose: true,
content: html,
btn: ['确定', '取消'],
yes: function (index){
customer = res.data.item;
layer.close(index);
if(isShow){
table.reload('car', {
url: '../car/search/number',
page: {
curr: 1 //重新从第 1 页开始
},
where: {
number: ''
}
});
}else{
isShow = true;
table.render({
id: 'car',
elem: '#cars',
url: '../car/search/number', //数据接口
title: '客户数据表',
page: true, //开启分页
limit: 9,
limits: [9, 18, 27, 35, 45, 54],
defaultToolbar: ['filter', 'print', 'exports'],//工具条
cols: [ [ //表头
{field: 'number', title: '车牌号', width:180, sort: true},
{field: 'brand', title: '品牌', width:120},
{field: 'color', title: '颜色', width:120},
{field: 'buyPrice', title: '购买价格', width:120},
{field: 'rentPrice', title: '出租价格', width:120},
{field: 'deposit', title: '押金', width:120},
{field: 'status', title: '状态', width:100, templet: function(d){
let status = d.status;
switch (status){
case 0:
return '<span style="color: forestgreen">未出租</span>';
case 1:
return '<span style="color: red">已出租</span>';
default:
return '<span style="color: cornflowerblue">未知</span>';
}
}
},
{field: 'description', title: '描述'},
{fixed: 'right', title:'操作', toolbar: '#rightBar', width:150}
] ],
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.data.record //解析数据列表
};
}
});
//监听行工具事件
table.on('tool(cars)', function(obj){
var data = obj.data;
//console.log(obj)
if(obj.event === 'info'){
layer.open({
type: 1,
title: '汽车图片',
content: '<img src="/system/resource/image/' + data.image + '" title="汽车图片">' //这里content是一个普通的String
});
}else if(obj.event == 'choose'){
let rent = {
identity: customer.identity,
name: customer.name,
number: data.number,
rentPrice: data.rentPrice
}
let rentDialog = $('#rentDialog').html();
laytpl(rentDialog).render(rent, function(html) {
layer.open({
type: 1,
area: ['500px', '450px'],
title: '车辆出租',
closeBtn: 0,
shadeClose: true,
content: html,
btn: ['确定', '取消'],
yes: function (index) {
layer.close(index);
let returnTime = $('#returnTime').val();
$.post('../rent/add', {
identity: rent.identity,
number: rent.number,
returnTime: returnTime
}, function (res) {
if(res.code == 200){
layer.msg('添加成功', {
icon: 1
});
}else if(res.code == 502){
layer.msg('汽车已被出租,请重新选择', {
icon: 0
});
}else if(res.code == 404){
layer.msg('汽车未找到,请重新选择', {
icon: 0
});
}else{
layer.msg('服务器异常', {
icon: 0
});
}
table.reload('car', {
page: {
curr: 1
}
})
});
},
success: function(layero, index){
//执行一个laydate实例
laydate.render({
elem: '#beginTime', //指定元素
value: new Date()
});
laydate.render({
elem: '#returnTime' //指定元素
});
}
});
});
}
});
}
},
btn2: function (index) {
layer.close(index)
}
})
});
}else if(res.code == 404){
layer.alert("身份证号错误!");
}
});
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
})
</script>
</html>

@ -0,0 +1,212 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row" style="margin: 20px;">
<div class="layui-card">
<div class="layui-card-header"><i class="layui-icon layui-icon-search"></i>查询条件</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">关键字</label>
<div class="layui-input-block">
<input type="text" class="layui-input" name="keyword" autocomplete="off">
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">类型</label>
<div class="layui-input-block">
<input type="radio" name="type" autocomplete="off" value="0" title="出租单号" checked>
<input type="radio" name="type" autocomplete="off" value="1" title="身份证号">
<input type="radio" name="type" autocomplete="off" value="2" title="汽车牌照">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="search">搜索</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-row" style="margin-left: 20px;margin-right: 20px;">
<div class="layui-card">
<div class="layui-card-header">出租单管理</div>
<div class="layui-card-body layui-row">
<table id="rents" lay-filter="rents"></table>
</div>
</div>
</div>
</div>
</body>
<script type="text/html" id="rightBar">
<a class="layui-btn layui-btn-xs" lay-event="update">修改归还日期</a>
</script>
<script type="text/html" id="rentDialog">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">单号</label>
<div class="layui-input-block">
<input type="text" value="{{ d.id }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" value="{{ d.customerIdentity }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">车辆车牌</label>
<div class="layui-input-block">
<input type="text" value="{{ d.carNumber }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">出租价格</label>
<div class="layui-input-block">
<input type="text" value="{{ d.price }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">起租时间</label>
<div class="layui-input-block">
<input type="text" id="beginTime" value="{{ d.beginTime }}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">还车时间</label>
<div class="layui-input-block">
<input type="text" id="returnTime" value="{{ d.returnTime }}" class="layui-input">
</div>
</div>
</div>
</script>
<script type="application/javascript">
layui.use(['table', 'layer', 'form', 'laytpl', 'laydate'], function () {
let table = layui.table;
let layer = layui.layer;
let form = layui.form;
let laytpl = layui.laytpl;
let laydate = layui.laydate;
table.render({
id: 'rents',
elem: '#rents',
url: '../rent/all', //数据接口
title: '客户数据表',
page: true, //开启分页
limit: 9,
limits: [9, 18, 27, 35, 45, 54],
toolbar: true,
defaultToolbar: ['filter', 'print', 'exports'],//工具条
cols: [ [ //表头
{field: 'id', title: '出租表单号', width:280},
{field: 'customerIdentity', title: '身份证号', width:220},
{field: 'carNumber', title: '车牌号', width:120},
{field: 'price', title: '出租价格', width:120, sort: true},
{field: 'beginTime', title: '起租时间', width:120, sort: true},
{field: 'returnTime', title: '还车时间', width:120, sort: true},
{fixed: 'right', title:'操作', toolbar: '#rightBar'}
] ],
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.data.record //解析数据列表
};
}
});
//监听行工具事件
table.on('tool(rents)', function(obj) {
var data = obj.data;
if (obj.event === 'update') {
let rentDialog = $('#rentDialog').html();
laytpl(rentDialog).render(data, function(html) {
layer.open({
type: 1,
area: ['500px', '450px'],
title: '出租单号',
closeBtn: 0,
shadeClose: true,
content: html,
btn: ['确定', '取消'],
yes: function (index) {
let initTime = data.returnTime;
let returnTime = $("#returnTime").val();
if(initTime == returnTime){
layer.msg("日期相同,未做修改");
layer.close(index);
return true;
}
$.post('../rent/update/returnTime', {
id: data.id,
returnTime: returnTime
}, function (res) {
if (res.code == 200){
obj.update({
returnTime: returnTime
})
layer.msg('修改成功', {
icon: 1
})
}else if (res.code == 504){
layer.layer('修改日期解析错误');
}else if (res.code == 505){
layer.alert("修改日期错误");
}else if (res.code == 404){
layer.alert("出租单未找到");
}else if (res.code == 500){
layer.alert('服务器错误')
}
}, 'json');
layer.close(index);
return true;
},
btn2: function (index) {
layer.close(index);
},
success: function () {
laydate.render({
elem: '#beginTime' //指定元素
});
laydate.render({
elem: '#returnTime',
min: new Date().getTime()
});
}
});
});
}
});
form.on('submit(search)', function (data){
let keyword = data.field.keyword;
let type = data.field.type;
table.reload('rents', {
url: '../rent/search',
where: {
type: type,
keyword: keyword
},
page: {
curr: 1
}
})
return false;
})
})
</script>
</html>

@ -0,0 +1,172 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row">
<div class="layui-row" style="margin: 20px;">
<div class="layui-card">
<div class="layui-card-header"><i class="layui-icon layui-icon-search"></i>查询条件</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane layui-col-xs6">
<div class="layui-form-item" pane>
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" lay-filter="status" value="-1" title="全部" checked>
<input type="radio" name="status" lay-filter="status" value="0" title="未出租" style="margin-left: 20px;">
<input type="radio" name="status" lay-filter="status" value="1" title="已出租" style="margin-left: 20px;">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">品牌</label>
<div class="layui-input-block">
<input type="text" name="brand" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">颜色</label>
<div class="layui-input-block">
<input type="text" name="color" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="search"><i class="layui-icon layui-icon-search"></i>查询</button>
<button type="reset" class="layui-btn layui-btn-primary"><i class="layui-icon layui-icon-refresh"></i>重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-row" style="margin-left: 20px;margin-right: 20px;">
<div class="layui-card">
<div class="layui-card-header">车辆列表</div>
<div class="layui-card-body layui-row">
<!-- 显示 -->
<table id="cars" lay-filter="cars"></table>
</div>
</div>
</div>
</div>
</body>
<script type="text/html" id="rightBar">
<a class="layui-btn layui-btn-xs" lay-event="info">详情</a>
</script>
<script type="application/javascript">
let addDialog = -1;
layui.use(['layer', 'form', 'table', 'laytpl'], function () {
let layer = layui.layer;
let form = layui.form;
let table = layui.table;
let laytpl = layui.laytpl;
table.render({
id: 'car',
elem: '#cars',
url: 'car/all', //数据接口
where: {
status: -1
},
title: '客户数据表',
page: true, //开启分页
limit: 9,
limits: [9, 18, 27, 35, 45, 54],
toolbar: true,
defaultToolbar: ['filter', 'print', 'exports'],//工具条
cols: [ [ //表头
{field: 'number', title: '车牌号', width:180, sort: true},
{field: 'brand', title: '品牌', width:120},
{field: 'color', title: '颜色', width:120},
{field: 'buyPrice', title: '购买价格', width:120},
{field: 'rentPrice', title: '出租价格', width:120},
{field: 'deposit', title: '押金', width:120},
{field: 'status', title: '状态', width:100, templet: function(d){
let status = d.status;
switch (status){
case 0:
return '<span style="color: forestgreen">未出租</span>';
case 1:
return '<span style="color: red">已出租</span>';
default:
return '<span style="color: cornflowerblue">未知</span>';
}
}
},
{field: 'description', title: '描述'},
{fixed: 'right', title:'操作', toolbar: '#rightBar', width:100}
] ],
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.data.record //解析数据列表
};
}
});
//监听行工具事件
table.on('tool(cars)', function(obj){
var data = obj.data;
//console.log(obj)
if(obj.event === 'info'){
layer.open({
type: 1,
content: '<img src="/system/resource/image/' + data.image + '" title="汽车图片">' //这里content是一个普通的String
});
}
});
//出租状态监听
form.on('radio(status)', function(data){
let status = data.value;
table.reload('car', {
where: {
status: status
}
})
});
//查询
form.on('submit(search)', function(data){
let brand = data.field.brand;
let color = data.field.color;
let status = data.field.status;
if(brand == "" && color == ""){
table.reload('car', {
url: 'car/all',
page: {
curr: 1 //重新从第 1 页开始
},
where: {
status: -1
}
});
}else{
table.reload('car', {
url: 'car/search',
page: {
curr: 1 //重新从第 1 页开始
},
where: {
brand: brand,
color: color,
status: status
}
});
}
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
})
</script>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,299 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
body{
width: 100%;
height: 100%;
}
</style>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row">
<div class="layui-row" style="margin: 20px;">
<div class="layui-card">
<div class="layui-card-header"><i class="layui-icon layui-icon-search"></i>查询条件</div>
<div class="layui-card-body layui-row">
<form class="layui-form layui-form-pane layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">关键字</label>
<div class="layui-input-block">
<input type="text" name="keyword" class="layui-input">
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">查询类型</label>
<div class="layui-input-block">
<input type="radio" name="type" value="identity" title="身份证号" checked>
<input type="radio" name="type" value="name" title="客户姓名">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="search"><i class="layui-icon layui-icon-search"></i>查询</button>
<button type="reset" class="layui-btn layui-btn-primary"><i class="layui-icon layui-icon-refresh"></i>重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-row" style="margin-left: 20px;margin-right: 20px;">
<div class="layui-card">
<div class="layui-card-header">客户列表</div>
<div class="layui-card-body layui-row">
<!-- 显示 -->
<table id="customers" lay-filter="customers"></table>
</div>
</div>
</div>
</div>
</div>
</body>
<!-- 表格头部工具栏 -->
<script type="text/html" id="leftBar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add">添加客户</button>
</div>
</script>
<!-- 右侧工具栏 -->
<script type="text/html" id="rightBar">
<a class="layui-btn layui-btn-xs" lay-event="update">修改</a>
</script>
<!-- 增加客户模板 -->
<script type="text/html" id="customerTemp">
<form class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">身份证号</label>
<div class="layui-input-block">
<input type="text" name="identity" value="{{ d.identity }}" class="layui-input" lay-verify="identity">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" name="name" value="{{ d.name }}" class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
{{# if(d.gender === 1){ }}
<input type="radio" name="gender" value="1" title="男" checked>
<input type="radio" name="gender" value="2" title="女">
{{# } else if (d.gender === 2){ }}
<input type="radio" name="gender" value="1" title="男">
<input type="radio" name="gender" value="2" title="女" checked>
{{# } }}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-block">
<input type="text" name="address" value="{{ d.address }}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话</label>
<div class="layui-input-block">
<input type="text" name="phone" value="{{ d.phone }}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">职位</label>
<div class="layui-input-block">
<input type="text" name="career" value="{{ d.career }}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
{{# if(d.type === 0){ }}
<button class="layui-btn" lay-submit lay-filter="add"><i class="layui-icon layui-icon-search"></i>新增</button>
{{# } else if (d.type === 1){ }}
<button class="layui-btn" lay-submit lay-filter="update"><i class="layui-icon layui-icon-search"></i>修改</button>
{{# } }}
<button type="reset" class="layui-btn layui-btn-primary"><i class="layui-icon layui-icon-refresh"></i>重置</button>
</div>
</div>
</form>
</script>
<script type="application/javascript">
let addDialog = -1;
layui.use(['layer', 'form', 'table', 'laytpl'], function () {
let layer = layui.layer;
let form = layui.form;
let table = layui.table;
let laytpl = layui.laytpl;
table.render({
id: 'customer',
elem: '#customers',
url: 'customer/all', //数据接口
toolbar: '#leftBar',
title: '客户数据表',
page: true, //开启分页
limit: 9,
limits: [9, 18, 27, 35, 45, 54],
defaultToolbar: ['filter', 'print', 'exports'],//工具条
cols: [ [ //表头
{field: 'identity', title: '身份证号', width:180, sort: true},
{field: 'name', title: '姓名', width:120},
{field: 'gender', title: '性别', width:80, templet: function(d){
return d.gender == 1 ? '男' : '女';
}
},
{field: 'address', title: '地址'},
{field: 'phone', title: '电话', width:180},
{field: 'career', title: '职位', width:80},
{field: 'created', title: '录入时间', width:180},
{fixed: 'right', title:'操作', toolbar: '#rightBar', width:100}
] ],
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.data.record //解析数据列表
};
}
});
//头工具栏事件
table.on('toolbar(customers)', function(obj){
let checkStatus = table.checkStatus(obj.config.id);
//新增数据
if(obj.event == 'add'){
if(addDialog != -1){
layer.close(addDialog);
}
let cus = {
identity: '',
name: '',
gender: 1,
address: '',
phone: '',
career: '',
type: 0
}
let customerTemp = $('#customerTemp').html();
laytpl(customerTemp).render(cus, function(html) {
addDialog = layer.open({
type: 1,
title: '新增客户',
area: ['500px', '500px'],
content: html,
success: function () {
form.render('radio');
}
});
});
}
});
//监听行工具事件
table.on('tool(customers)', function(obj){
let data = obj.data;
data.type = 1;
if(obj.event === 'update'){
let customerTemp = $('#customerTemp').html();
laytpl(customerTemp).render(data, function(html) {
addDialog = layer.open({
type: 1,
title: '新增客户',
area: ['500px', '500px'],
content: html,
success: function () {
form.render('radio');
}
});
});
}
});
//查询
form.on('submit(search)', function(data){
let keyword = data.field.keyword;
let type = data.field.type;
table.reload('customer', {
url: 'customer/search/' + type,
page: {
curr: 1 //重新从第 1 页开始
},
where: {
keyword: keyword
}
});
return false; // 阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//修改
form.on('submit(update)', function(data){
let identity = data.field.identity;
let name = data.field.name;
let gender = data.field.gender;
let address = data.field.address;
let phone = data.field.phone;
let career = data.field.career;
$.post('customer/update', {
identity: identity,
name: name,
gender: gender,
address: address,
phone: phone,
career: career
}, function (res) {
if(res.code == 200){
layer.close(addDialog);
addDialog = -1;
layer.msg('修改成功');
table.reload('customer', {
page: {
curr: 1 //重新从第 1 页开始
}
})
}
}, 'json');
return false;
});
//新增
form.on('submit(add)', function(data){
let identity = data.field.identity;
let name = data.field.name;
let gender = data.field.gender;
let address = data.field.address;
let phone = data.field.phone;
let career = data.field.career;
$.post('customer/add', {
identity: identity,
name: name,
gender: gender,
address: address,
phone: phone,
career: career
}, function (res) {
if(res.code == 200){
layer.close(addDialog);
addDialog = -1;
layer.msg('添加成功');
table.reload('customer', {
page: {
curr: 1 //重新从第 1 页开始
}
})
}
}, 'json');
//return false; 阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//修改
})
</script>
</html>

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
没有权限
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>橘子汽车租赁</title>
<script type='text/javascript' charset='utf-8' src='https://www.layuicdn.com/layui-v2.5.6/layui.js'></script>
<link rel='stylesheet' type='text/css' href='https://www.layuicdn.com/layui-v2.5.6/css/layui.css' />
<script type="text/javascript" charset='utf-8' src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body style="background-color: #F2F2F2">
<div class="layui-row layui-col-space15" style="margin: 20px;">
<div class="layui-col-xs6">
<div class="layui-card">
<div class="layui-card-header">公司公告</div>
<div class="layui-card-body layui-row">
<table id="announcements" lay-filter="announcements"></table>
</div>
</div>
</div>
<div class="layui-inline">
<div class="layui-card">
<div class="layui-card-header">当前日历</div>
<div class="layui-card-body layui-row">
<div class="layui-inline" id="calendar"></div>
</div>
</div>
</div>
<div class="layui-inline">
<div class="layui-card">
<div class="layui-card-header">当前时间</div>
<div class="layui-card-body layui-row">
<div class="layui-inline" id="time"></div>
</div>
</div>
</div>
</div>
</body>
<script type="text/html" id="announcementsDialog">
<h1 align="center">{{ d.title }}</h1>
<blockquote class="layui-elem-quote" style="margin-top: 20px;">{{ d.operator }}</blockquote>
<p style="margin-top: 20px;"><b>发布时间:</b>{{ d.created }}</p>
<p style="margin-top: 20px;">{{ d.content }}</p>
</script>
<script>
layui.use(['laydate', 'table', 'layer', 'laytpl'], function() {
let laydate = layui.laydate;
let table = layui.table;
let layer = layui.layer;
let laytpl = layui.laytpl;
//直接嵌套显示
laydate.render({
elem: '#calendar',
position: 'static',
calendar: true
});
laydate.render({
elem: '#time',
type: 'time',
position: 'static',
value: new Date()
});
table.render({
id: 'announcement',
elem: '#announcements',
url: 'announcement/all', //数据接口
where: {
status: -1
},
title: '公司通知',
page: true, //开启分页
limit: 9,
limits: [9, 18, 27, 35, 45, 54],
defaultToolbar: ['filter', 'print', 'exports'],//工具条
cols: [ [ //表头
{field: 'title', title: '标题', style:'cursor: pointer;'},
{field: 'created', title: '创建时间', width:200, sort: true},
{field: 'operator', title: '操作人', width:120},
] ],
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.message, //解析提示文本
"count": res.total, //解析数据长度
"data": res.data.record //解析数据列表
};
}
});
//监听单元格事件
table.on('row(announcements)', function(obj){
let data = obj.data;
let announcementsDialog = $('#announcementsDialog').html();
data.type = 1;
laytpl(announcementsDialog).render(data, function(html) {
layer.open({
type: 1,
title: '公告详情',
area: ['400px', '460px'],
content: html,
});
});
});
});
</script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Loading…
Cancel
Save