├── LICENSE ├── README.md ├── db_reggie.sql ├── server ├── .gitignore ├── LICENSE ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── image │ ├── 00874a5e-0df2-446b-8f69-a30eb7d88ee8.png │ ├── 057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg │ ├── 0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg │ ├── 0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg │ ├── 0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg │ ├── 1405081e-f545-42e1-86a2-f7559ae2e276.jpeg │ ├── 1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg │ ├── 2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg │ ├── 2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg │ ├── 2e96a7e3-affb-438e-b7c3-e1430df425c9.jpeg │ ├── 3fabb83a-1c09-4fd9-892b-4ef7457daafa.jpeg │ ├── 583df4b7-a159-4cfc-9543-4f666120b25f.jpeg │ ├── 5b8d2da3-3744-4bb3-acdc-329056b8259d.jpeg │ ├── 740c79ce-af29-41b8-b78d-5f49c96e38c4.jpg │ ├── 8dcfda14-5712-4d28-82f7-ae905b3c2308.jpg │ ├── 9ec6fc2d-50d2-422e-b954-de87dcd04198.jpeg │ ├── a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg │ ├── c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png │ ├── d2f61d70-ac85-4529-9b74-6d9a2255c6d7.jpg │ ├── e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg │ ├── ee04a05a-1230-46b6-8ad5-1a95b140fff3.png │ ├── ef2b73f2-75d1-4d3a-beea-22da0e1421bd.jpg │ └── f966a38e-0780-40be-bb52-5699d13cb3d9.jpg ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── enaium │ │ │ └── reggie │ │ │ ├── ServerApplication.java │ │ │ ├── common │ │ │ ├── CustomException.java │ │ │ ├── GlobalExceptionHandler.java │ │ │ ├── JacksonObjectMapper.java │ │ │ ├── MyMetaObjecthandler.java │ │ │ └── R.java │ │ │ ├── config │ │ │ ├── MybatisPlusConfig.java │ │ │ └── SaTokenConfig.java │ │ │ ├── controller │ │ │ ├── AddressBookController.java │ │ │ ├── CategoryController.java │ │ │ ├── CommonController.java │ │ │ ├── DishController.java │ │ │ ├── EmployeeController.java │ │ │ ├── OrderController.java │ │ │ ├── OrderDetailController.java │ │ │ ├── SetmealController.java │ │ │ ├── ShoppingCartController.java │ │ │ └── UserController.java │ │ │ ├── dto │ │ │ ├── DishDto.java │ │ │ └── SetmealDto.java │ │ │ ├── entity │ │ │ ├── AddressBook.java │ │ │ ├── Category.java │ │ │ ├── Dish.java │ │ │ ├── DishFlavor.java │ │ │ ├── Employee.java │ │ │ ├── OrderDetail.java │ │ │ ├── Orders.java │ │ │ ├── Setmeal.java │ │ │ ├── SetmealDish.java │ │ │ ├── ShoppingCart.java │ │ │ └── User.java │ │ │ ├── mapper │ │ │ ├── AddressBookMapper.java │ │ │ ├── CategoryMapper.java │ │ │ ├── DishFlavorMapper.java │ │ │ ├── DishMapper.java │ │ │ ├── EmployeeMapper.java │ │ │ ├── OrderDetailMapper.java │ │ │ ├── OrderMapper.java │ │ │ ├── SetmealDishMapper.java │ │ │ ├── SetmealMapper.java │ │ │ ├── ShoppingCartMapper.java │ │ │ └── UserMapper.java │ │ │ ├── service │ │ │ ├── AddressBookService.java │ │ │ ├── CategoryService.java │ │ │ ├── DishFlavorService.java │ │ │ ├── DishService.java │ │ │ ├── EmployeeService.java │ │ │ ├── OrderDetailService.java │ │ │ ├── OrderService.java │ │ │ ├── SetmealDishService.java │ │ │ ├── SetmealService.java │ │ │ ├── ShoppingCartService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── AddressBookServiceImpl.java │ │ │ │ ├── CategoryServiceImpl.java │ │ │ │ ├── DishFlavorServiceImpl.java │ │ │ │ ├── DishServiceImpl.java │ │ │ │ ├── EmployeeServiceImpl.java │ │ │ │ ├── OrderDetailServiceImpl.java │ │ │ │ ├── OrderServiceImpl.java │ │ │ │ ├── SetmealDishServiceImpl.java │ │ │ │ ├── SetmealServiceImpl.java │ │ │ │ ├── ShoppingCartServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils │ │ │ ├── SMSUtils.java │ │ │ └── ValidateCodeUtils.java │ └── resources │ │ └── application.yaml │ └── test │ └── java │ └── cn │ └── enaium │ └── reggie │ └── ServerApplicationTests.java └── website ├── .gitignore ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── index.html ├── package.json ├── public ├── favicon.ico └── vite.svg ├── src ├── App.vue ├── api │ ├── backend │ │ ├── category.js │ │ ├── combo.js │ │ ├── food.js │ │ ├── login.js │ │ ├── member.js │ │ └── order.js │ └── frontend │ │ ├── address.js │ │ ├── login.js │ │ ├── main.js │ │ └── order.js ├── assets │ ├── backend │ │ ├── 404-images │ │ │ ├── 404-cloud.png │ │ │ └── 404.png │ │ ├── icons │ │ │ ├── btn_back@2x.png │ │ │ ├── btn_clean@2x.png │ │ │ ├── btn_close@2x.png │ │ │ ├── icon_index.png │ │ │ ├── icon_upload@2x.png │ │ │ ├── jine_m-2@2x.png │ │ │ ├── renshu@2x.png │ │ │ └── xiangmujine@2x.png │ │ ├── img_brand01@2x.png │ │ ├── img_denglu_bj.jpg │ │ ├── login │ │ │ ├── login-l.png │ │ │ ├── login-logo.png │ │ │ └── logo.png │ │ ├── logo.png │ │ └── noImg.png │ ├── fonts │ │ ├── DIN-Bold.otf │ │ ├── DIN-Medium.otf │ │ ├── PingFangSC-Medium.ttf │ │ ├── PingFangSC-Regular.ttf │ │ ├── PingFangSC-Semibold.ttf │ │ ├── element-icons.ttf │ │ └── element-icons.woff │ └── frontend │ │ ├── add.png │ │ ├── cart.png │ │ ├── cart_active.png │ │ ├── checked_false.png │ │ ├── checked_true.png │ │ ├── close.png │ │ ├── demo1.png │ │ ├── demo2.png │ │ ├── demo3.png │ │ ├── demo4.png │ │ ├── edit.png │ │ ├── favico.ico │ │ ├── headPage.png │ │ ├── home.png │ │ ├── location.png │ │ ├── locations.png │ │ ├── logo.png │ │ ├── mainBg.png │ │ ├── money.png │ │ ├── noImg.png │ │ ├── no_order.png │ │ ├── no_wifi.png │ │ ├── orders.png │ │ ├── subtract.png │ │ ├── success.png │ │ ├── time.png │ │ ├── user.png │ │ └── women.png ├── js │ ├── backend │ │ ├── index.js │ │ ├── request.js │ │ └── validate.js │ └── frontend │ │ ├── base.js │ │ ├── common.js │ │ └── request.js ├── layouts │ ├── backend │ │ └── Backend.vue │ └── frontend │ │ └── Frontend.vue ├── main.js ├── pages │ ├── backend │ │ ├── Login.vue │ │ ├── category │ │ │ └── List.vue │ │ ├── combo │ │ │ ├── Add.vue │ │ │ └── List.vue │ │ ├── food │ │ │ ├── Add.vue │ │ │ └── List.vue │ │ ├── member │ │ │ ├── Add.vue │ │ │ └── List.vue │ │ └── order │ │ │ └── List.vue │ └── frontend │ │ ├── AddOrder.vue │ │ ├── Address.vue │ │ ├── AddressEdit.vue │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── NoNetwork.vue │ │ ├── Order.vue │ │ ├── PaySuccess.vue │ │ └── User.vue ├── router │ └── index.js └── styles │ ├── backend │ ├── icon │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── index.css │ ├── login.css │ └── page.css │ └── frontend │ ├── add-order.css │ ├── address-edit.css │ ├── address.css │ ├── index.css │ ├── login.css │ ├── main.css │ ├── no-wify.css │ ├── order.css │ ├── pay-success.css │ └── user.css ├── vite.config.js └── yarn.lock /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reggie-takeout 瑞吉外卖 2 | 3 | 来自黑马程序员:https://www.bilibili.com/video/BV13a411q753 4 | 5 | 修改为前后端分离,前端使用vue3:element plus、vant -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /server/LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /server/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '2.7.7' 4 | id 'io.spring.dependency-management' version '1.0.15.RELEASE' 5 | } 6 | 7 | group = 'cn.enaium' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '8' 10 | 11 | configurations { 12 | compileOnly { 13 | extendsFrom annotationProcessor 14 | } 15 | } 16 | 17 | repositories { 18 | mavenCentral() 19 | } 20 | 21 | dependencies { 22 | implementation 'com.baomidou:mybatis-plus-boot-starter:3.5.3.1' 23 | implementation 'cn.dev33:sa-token-spring-boot-starter:1.33.0' 24 | implementation 'cn.dev33:sa-token-dao-redis-jackson:1.33.0' 25 | implementation 'org.apache.commons:commons-pool2' 26 | implementation 'com.aliyun:aliyun-java-sdk-core:4.5.16' 27 | implementation 'com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0' 28 | implementation 'commons-lang:commons-lang:2.6' 29 | implementation 'com.alibaba:druid-spring-boot-starter:1.1.23' 30 | 31 | implementation 'org.springframework.boot:spring-boot-starter-web' 32 | implementation 'org.jetbrains:annotations:23.0.0' 33 | compileOnly 'org.projectlombok:lombok' 34 | runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' 35 | annotationProcessor 'org.projectlombok:lombok' 36 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 37 | } 38 | 39 | tasks.named('test') { 40 | useJUnitPlatform() 41 | } 42 | -------------------------------------------------------------------------------- /server/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /server/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /server/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if %ERRORLEVEL% equ 0 goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if %ERRORLEVEL% equ 0 goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | set EXIT_CODE=%ERRORLEVEL% 84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86 | exit /b %EXIT_CODE% 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /server/image/00874a5e-0df2-446b-8f69-a30eb7d88ee8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/00874a5e-0df2-446b-8f69-a30eb7d88ee8.png -------------------------------------------------------------------------------- /server/image/057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg -------------------------------------------------------------------------------- /server/image/0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg -------------------------------------------------------------------------------- /server/image/0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg -------------------------------------------------------------------------------- /server/image/0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg -------------------------------------------------------------------------------- /server/image/1405081e-f545-42e1-86a2-f7559ae2e276.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/1405081e-f545-42e1-86a2-f7559ae2e276.jpeg -------------------------------------------------------------------------------- /server/image/1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg -------------------------------------------------------------------------------- /server/image/2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg -------------------------------------------------------------------------------- /server/image/2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg -------------------------------------------------------------------------------- /server/image/2e96a7e3-affb-438e-b7c3-e1430df425c9.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/2e96a7e3-affb-438e-b7c3-e1430df425c9.jpeg -------------------------------------------------------------------------------- /server/image/3fabb83a-1c09-4fd9-892b-4ef7457daafa.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/3fabb83a-1c09-4fd9-892b-4ef7457daafa.jpeg -------------------------------------------------------------------------------- /server/image/583df4b7-a159-4cfc-9543-4f666120b25f.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/583df4b7-a159-4cfc-9543-4f666120b25f.jpeg -------------------------------------------------------------------------------- /server/image/5b8d2da3-3744-4bb3-acdc-329056b8259d.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/5b8d2da3-3744-4bb3-acdc-329056b8259d.jpeg -------------------------------------------------------------------------------- /server/image/740c79ce-af29-41b8-b78d-5f49c96e38c4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/740c79ce-af29-41b8-b78d-5f49c96e38c4.jpg -------------------------------------------------------------------------------- /server/image/8dcfda14-5712-4d28-82f7-ae905b3c2308.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/8dcfda14-5712-4d28-82f7-ae905b3c2308.jpg -------------------------------------------------------------------------------- /server/image/9ec6fc2d-50d2-422e-b954-de87dcd04198.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/9ec6fc2d-50d2-422e-b954-de87dcd04198.jpeg -------------------------------------------------------------------------------- /server/image/a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg -------------------------------------------------------------------------------- /server/image/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png -------------------------------------------------------------------------------- /server/image/d2f61d70-ac85-4529-9b74-6d9a2255c6d7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/d2f61d70-ac85-4529-9b74-6d9a2255c6d7.jpg -------------------------------------------------------------------------------- /server/image/e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg -------------------------------------------------------------------------------- /server/image/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png -------------------------------------------------------------------------------- /server/image/ef2b73f2-75d1-4d3a-beea-22da0e1421bd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/ef2b73f2-75d1-4d3a-beea-22da0e1421bd.jpg -------------------------------------------------------------------------------- /server/image/f966a38e-0780-40be-bb52-5699d13cb3d9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/server/image/f966a38e-0780-40be-bb52-5699d13cb3d9.jpg -------------------------------------------------------------------------------- /server/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'reggie' 2 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/ServerApplication.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @Slf4j 8 | @SpringBootApplication 9 | public class ServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServerApplication.class, args); 13 | log.info("项目启动成功..."); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/common/CustomException.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.common; 2 | 3 | /** 4 | * 自定义业务异常类 5 | */ 6 | public class CustomException extends RuntimeException { 7 | public CustomException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/common/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.common; 2 | 3 | import cn.dev33.satoken.exception.NotLoginException; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.ControllerAdvice; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.sql.SQLIntegrityConstraintViolationException; 12 | 13 | /** 14 | * 全局异常处理 15 | */ 16 | @ControllerAdvice(annotations = {RestController.class, Controller.class}) 17 | @ResponseBody 18 | @Slf4j 19 | public class GlobalExceptionHandler { 20 | 21 | /** 22 | * 异常处理方法 23 | * 24 | * @return 25 | */ 26 | @ExceptionHandler(SQLIntegrityConstraintViolationException.class) 27 | public R exceptionHandler(SQLIntegrityConstraintViolationException ex) { 28 | log.error(ex.getMessage()); 29 | 30 | if (ex.getMessage().contains("Duplicate entry")) { 31 | String[] split = ex.getMessage().split(" "); 32 | String msg = split[2] + "已存在"; 33 | return R.error(msg); 34 | } 35 | 36 | return R.error("未知错误"); 37 | } 38 | 39 | /** 40 | * 异常处理方法 41 | * 42 | * @return 43 | */ 44 | @ExceptionHandler(CustomException.class) 45 | public R exceptionHandler(CustomException ex) { 46 | log.error(ex.getMessage()); 47 | 48 | return R.error(ex.getMessage()); 49 | } 50 | 51 | @ExceptionHandler(NotLoginException.class) 52 | public R exceptionHandler(NotLoginException e) { 53 | return R.error("NOTLOGIN"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/common/JacksonObjectMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.common; 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.module.SimpleModule; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 9 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 11 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 12 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 13 | 14 | import java.math.BigInteger; 15 | import java.time.LocalDate; 16 | import java.time.LocalDateTime; 17 | import java.time.LocalTime; 18 | import java.time.format.DateTimeFormatter; 19 | 20 | import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; 21 | 22 | /** 23 | * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 24 | * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] 25 | * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] 26 | */ 27 | public class JacksonObjectMapper extends ObjectMapper { 28 | 29 | public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; 30 | public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; 31 | public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; 32 | 33 | public JacksonObjectMapper() { 34 | super(); 35 | //收到未知属性时不报异常 36 | this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); 37 | 38 | //反序列化时,属性不存在的兼容处理 39 | this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 40 | 41 | 42 | SimpleModule simpleModule = new SimpleModule() 43 | .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) 44 | .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) 45 | .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) 46 | 47 | .addSerializer(BigInteger.class, ToStringSerializer.instance) 48 | .addSerializer(Long.class, ToStringSerializer.instance) 49 | .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) 50 | .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) 51 | .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); 52 | 53 | //注册功能模块 例如,可以添加自定义序列化器和反序列化器 54 | this.registerModule(simpleModule); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/common/MyMetaObjecthandler.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.common; 2 | 3 | import cn.dev33.satoken.stp.StpUtil; 4 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.apache.ibatis.reflection.MetaObject; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * 自定义元数据对象处理器 13 | */ 14 | @Component 15 | @Slf4j 16 | public class MyMetaObjecthandler implements MetaObjectHandler { 17 | /** 18 | * 插入操作,自动填充 19 | * 20 | * @param metaObject 21 | */ 22 | @Override 23 | public void insertFill(MetaObject metaObject) { 24 | log.info("公共字段自动填充[insert]..."); 25 | log.info(metaObject.toString()); 26 | 27 | metaObject.setValue("createTime", LocalDateTime.now()); 28 | metaObject.setValue("updateTime", LocalDateTime.now()); 29 | metaObject.setValue("createUser", StpUtil.getLoginIdAsLong()); 30 | metaObject.setValue("updateUser", StpUtil.getLoginIdAsLong()); 31 | } 32 | 33 | /** 34 | * 更新操作,自动填充 35 | * 36 | * @param metaObject 37 | */ 38 | @Override 39 | public void updateFill(MetaObject metaObject) { 40 | log.info("公共字段自动填充[update]..."); 41 | log.info(metaObject.toString()); 42 | 43 | long id = Thread.currentThread().getId(); 44 | log.info("线程id为:{}", id); 45 | 46 | metaObject.setValue("updateTime", LocalDateTime.now()); 47 | metaObject.setValue("updateUser", StpUtil.getLoginIdAsLong()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/common/R.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 通用返回结果,服务端响应的数据最终都会封装成此对象 10 | * 11 | * @param 12 | */ 13 | @Data 14 | public class R { 15 | 16 | private Integer code; //编码:1成功,0和其它数字为失败 17 | 18 | private String msg; //错误信息 19 | 20 | private T data; //数据 21 | 22 | private Map map = new HashMap(); //动态数据 23 | 24 | public static R success(T object) { 25 | R r = new R(); 26 | r.data = object; 27 | r.code = 1; 28 | return r; 29 | } 30 | 31 | public static R error(String msg) { 32 | R r = new R(); 33 | r.msg = msg; 34 | r.code = 0; 35 | return r; 36 | } 37 | 38 | public R add(String key, Object value) { 39 | this.map.put(key, value); 40 | return this; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * 配置MP的分页插件 10 | */ 11 | @Configuration 12 | public class MybatisPlusConfig { 13 | 14 | @Bean 15 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 16 | MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); 17 | mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 18 | return mybatisPlusInterceptor; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/config/SaTokenConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | package cn.enaium.reggie.config; 10 | 11 | import cn.dev33.satoken.interceptor.SaInterceptor; 12 | import cn.dev33.satoken.router.SaRouter; 13 | import cn.dev33.satoken.stp.StpUtil; 14 | import cn.enaium.reggie.common.JacksonObjectMapper; 15 | import lombok.extern.slf4j.Slf4j; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.springframework.context.annotation.Configuration; 18 | import org.springframework.http.converter.HttpMessageConverter; 19 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 20 | import org.springframework.web.servlet.HandlerInterceptor; 21 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 22 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 23 | 24 | import javax.servlet.http.HttpServletRequest; 25 | import javax.servlet.http.HttpServletResponse; 26 | import java.util.List; 27 | 28 | /** 29 | * @author Enaium 30 | */ 31 | @Slf4j 32 | @Configuration 33 | public class SaTokenConfig implements WebMvcConfigurer { 34 | @Override 35 | public void addInterceptors(InterceptorRegistry registry) { 36 | registry.addInterceptor(new HandlerInterceptor() { 37 | @Override 38 | public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception { 39 | response.setHeader("Access-Control-Allow-Origin", "*"); 40 | response.setHeader("Access-Control-Allow-Credentials", "true"); 41 | response.setHeader("Access-Control-Allow-Methods", "*"); 42 | response.setHeader("Access-Control-Max-Age", "3600"); 43 | response.setHeader("Access-Control-Allow-Headers", "*"); 44 | return true; 45 | } 46 | }); 47 | registry.addInterceptor(new SaInterceptor(handle -> SaRouter.match("/**") 48 | .notMatchMethod("OPTIONS") 49 | .notMatch("/employee/login", "/employee/logout", "/common/**", "/user/sendMsg", "/user/login") 50 | .check(r -> StpUtil.checkLogin()))).addPathPatterns("/**"); 51 | } 52 | 53 | @Override 54 | public void extendMessageConverters(List> converters) { 55 | log.info("扩展消息转换器..."); 56 | //创建消息转换器对象 57 | MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); 58 | //设置对象转换器,底层使用Jackson将Java对象转为json 59 | messageConverter.setObjectMapper(new JacksonObjectMapper()); 60 | //将上面的消息转换器对象追加到mvc框架的转换器集合中 61 | converters.add(0, messageConverter); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/AddressBookController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.dev33.satoken.stp.StpUtil; 4 | import cn.enaium.reggie.common.R; 5 | import cn.enaium.reggie.entity.AddressBook; 6 | import cn.enaium.reggie.service.AddressBookService; 7 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 8 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * 地址簿管理 16 | */ 17 | @Slf4j 18 | @RestController 19 | @RequestMapping("/addressBook") 20 | public class AddressBookController { 21 | 22 | private final AddressBookService addressBookService; 23 | 24 | public AddressBookController(AddressBookService addressBookService) { 25 | this.addressBookService = addressBookService; 26 | } 27 | 28 | /** 29 | * 新增 30 | */ 31 | @PostMapping 32 | public R save(@RequestBody AddressBook addressBook) { 33 | addressBook.setUserId(StpUtil.getLoginIdAsLong()); 34 | log.info("addressBook:{}", addressBook); 35 | addressBookService.save(addressBook); 36 | return R.success(addressBook); 37 | } 38 | 39 | /** 40 | * 设置默认地址 41 | */ 42 | @PutMapping("default") 43 | public R setDefault(@RequestBody AddressBook addressBook) { 44 | log.info("addressBook:{}", addressBook); 45 | LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); 46 | wrapper.eq(AddressBook::getUserId, StpUtil.getLoginIdAsLong()); 47 | wrapper.set(AddressBook::getIsDefault, 0); 48 | //SQL:update address_book set is_default = 0 where user_id = ? 49 | addressBookService.update(wrapper); 50 | 51 | addressBook.setIsDefault(1); 52 | //SQL:update address_book set is_default = 1 where id = ? 53 | addressBookService.updateById(addressBook); 54 | return R.success(addressBook); 55 | } 56 | 57 | /** 58 | * 根据id查询地址 59 | */ 60 | @GetMapping("/{id}") 61 | public R get(@PathVariable Long id) { 62 | AddressBook addressBook = addressBookService.getById(id); 63 | if (addressBook != null) { 64 | return R.success(addressBook); 65 | } else { 66 | return R.error("没有找到该对象"); 67 | } 68 | } 69 | 70 | /** 71 | * 查询默认地址 72 | */ 73 | @GetMapping("default") 74 | public R getDefault() { 75 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 76 | queryWrapper.eq(AddressBook::getUserId, StpUtil.getLoginIdAsLong()); 77 | queryWrapper.eq(AddressBook::getIsDefault, 1); 78 | 79 | //SQL:select * from address_book where user_id = ? and is_default = 1 80 | AddressBook addressBook = addressBookService.getOne(queryWrapper); 81 | 82 | if (null == addressBook) { 83 | return R.error("没有找到该对象"); 84 | } else { 85 | return R.success(addressBook); 86 | } 87 | } 88 | 89 | /** 90 | * 查询指定用户的全部地址 91 | */ 92 | @GetMapping("/list") 93 | public R> list(AddressBook addressBook) { 94 | addressBook.setUserId(StpUtil.getLoginIdAsLong()); 95 | log.info("addressBook:{}", addressBook); 96 | 97 | //条件构造器 98 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 99 | queryWrapper.eq(null != addressBook.getUserId(), AddressBook::getUserId, addressBook.getUserId()); 100 | queryWrapper.orderByDesc(AddressBook::getUpdateTime); 101 | 102 | //SQL:select * from address_book where user_id = ? order by update_time desc 103 | return R.success(addressBookService.list(queryWrapper)); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/CategoryController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.common.R; 4 | import cn.enaium.reggie.entity.Category; 5 | import cn.enaium.reggie.service.CategoryService; 6 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * 分类管理 16 | */ 17 | @RestController 18 | @RequestMapping("/category") 19 | @Slf4j 20 | public class CategoryController { 21 | private final CategoryService categoryService; 22 | 23 | public CategoryController(CategoryService categoryService) { 24 | this.categoryService = categoryService; 25 | } 26 | 27 | /** 28 | * 新增分类 29 | * 30 | * @param category 31 | * @return 32 | */ 33 | @PostMapping 34 | public R save(@RequestBody Category category) { 35 | log.info("category:{}", category); 36 | categoryService.save(category); 37 | return R.success("新增分类成功"); 38 | } 39 | 40 | /** 41 | * 分页查询 42 | * 43 | * @param page 44 | * @param pageSize 45 | * @return 46 | */ 47 | @GetMapping("/page") 48 | public R page(int page, int pageSize) { 49 | //分页构造器 50 | Page pageInfo = new Page<>(page, pageSize); 51 | //条件构造器 52 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 53 | //添加排序条件,根据sort进行排序 54 | queryWrapper.orderByAsc(Category::getSort); 55 | 56 | //分页查询 57 | categoryService.page(pageInfo, queryWrapper); 58 | return R.success(pageInfo); 59 | } 60 | 61 | /** 62 | * 根据id删除分类 63 | * 64 | * @param id 65 | * @return 66 | */ 67 | @DeleteMapping 68 | public R delete(Long id) { 69 | log.info("删除分类,id为:{}", id); 70 | 71 | //categoryService.removeById(id); 72 | categoryService.remove(id); 73 | 74 | return R.success("分类信息删除成功"); 75 | } 76 | 77 | /** 78 | * 根据id修改分类信息 79 | * 80 | * @param category 81 | * @return 82 | */ 83 | @PutMapping 84 | public R update(@RequestBody Category category) { 85 | log.info("修改分类信息:{}", category); 86 | 87 | categoryService.updateById(category); 88 | 89 | return R.success("修改分类信息成功"); 90 | } 91 | 92 | /** 93 | * 根据条件查询分类数据 94 | * 95 | * @param category 96 | * @return 97 | */ 98 | @GetMapping("/list") 99 | public R> list(Category category) { 100 | //条件构造器 101 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 102 | //添加条件 103 | queryWrapper.eq(category.getType() != null, Category::getType, category.getType()); 104 | //添加排序条件 105 | queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime); 106 | 107 | List list = categoryService.list(queryWrapper); 108 | return R.success(list); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/CommonController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.common.R; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import javax.servlet.ServletOutputStream; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.File; 15 | import java.io.FileInputStream; 16 | import java.io.IOException; 17 | import java.util.UUID; 18 | 19 | /** 20 | * 文件上传和下载 21 | */ 22 | @RestController 23 | @RequestMapping("/common") 24 | @Slf4j 25 | public class CommonController { 26 | 27 | @Value("${reggie.path}") 28 | private String basePath; 29 | 30 | /** 31 | * 文件上传 32 | * 33 | * @param file 34 | * @return 35 | */ 36 | @PostMapping("/upload") 37 | public R upload(MultipartFile file) { 38 | //file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除 39 | log.info(file.toString()); 40 | 41 | //原始文件名 42 | String originalFilename = file.getOriginalFilename();//abc.jpg 43 | String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); 44 | 45 | //使用UUID重新生成文件名,防止文件名称重复造成文件覆盖 46 | String fileName = UUID.randomUUID().toString() + suffix;//dfsdfdfd.jpg 47 | 48 | //创建一个目录对象 49 | File dir = new File(System.getProperty("user.dir"), basePath); 50 | //判断当前目录是否存在 51 | if (!dir.exists()) { 52 | //目录不存在,需要创建 53 | dir.mkdirs(); 54 | } 55 | 56 | try { 57 | //将临时文件转存到指定位置 58 | file.transferTo(new File(System.getProperty("user.dir"), basePath + File.separator + fileName)); 59 | } catch (IOException e) { 60 | e.printStackTrace(); 61 | } 62 | return R.success(fileName); 63 | } 64 | 65 | /** 66 | * 文件下载 67 | * 68 | * @param name 69 | * @param response 70 | */ 71 | @GetMapping("/download") 72 | public void download(String name, HttpServletResponse response) { 73 | 74 | try { 75 | //输入流,通过输入流读取文件内容 76 | FileInputStream fileInputStream = new FileInputStream(new File(System.getProperty("user.dir"), basePath + File.separator + name)); 77 | //输出流,通过输出流将文件写回浏览器 78 | ServletOutputStream outputStream = response.getOutputStream(); 79 | 80 | response.setContentType("image/jpeg"); 81 | 82 | int len = 0; 83 | byte[] bytes = new byte[1024]; 84 | while ((len = fileInputStream.read(bytes)) != -1) { 85 | outputStream.write(bytes, 0, len); 86 | outputStream.flush(); 87 | } 88 | 89 | //关闭资源 90 | outputStream.close(); 91 | fileInputStream.close(); 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.common.R; 4 | import cn.enaium.reggie.entity.Orders; 5 | import cn.enaium.reggie.service.OrderService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * 订单 15 | */ 16 | @Slf4j 17 | @RestController 18 | @RequestMapping("/order") 19 | public class OrderController { 20 | 21 | private final OrderService orderService; 22 | 23 | public OrderController(OrderService orderService) { 24 | this.orderService = orderService; 25 | } 26 | 27 | /** 28 | * 用户下单 29 | * 30 | * @param orders 31 | * @return 32 | */ 33 | @PostMapping("/submit") 34 | public R submit(@RequestBody Orders orders) { 35 | log.info("订单数据:{}", orders); 36 | orderService.submit(orders); 37 | return R.success("下单成功"); 38 | } 39 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/OrderDetailController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.service.OrderDetailService; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * 订单明细 11 | */ 12 | @Slf4j 13 | @RestController 14 | @RequestMapping("/orderDetail") 15 | public class OrderDetailController { 16 | 17 | private final OrderDetailService orderDetailService; 18 | 19 | public OrderDetailController(OrderDetailService orderDetailService) { 20 | this.orderDetailService = orderDetailService; 21 | } 22 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/SetmealController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.common.R; 4 | import cn.enaium.reggie.dto.SetmealDto; 5 | import cn.enaium.reggie.entity.Category; 6 | import cn.enaium.reggie.entity.Setmeal; 7 | import cn.enaium.reggie.service.CategoryService; 8 | import cn.enaium.reggie.service.SetmealDishService; 9 | import cn.enaium.reggie.service.SetmealService; 10 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 11 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.BeanUtils; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.List; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * 套餐管理 21 | */ 22 | 23 | @RestController 24 | @RequestMapping("/setmeal") 25 | @Slf4j 26 | public class SetmealController { 27 | 28 | 29 | private final SetmealService setmealService; 30 | 31 | 32 | private final CategoryService categoryService; 33 | 34 | 35 | private final SetmealDishService setmealDishService; 36 | 37 | public SetmealController(SetmealService setmealService, CategoryService categoryService, SetmealDishService setmealDishService) { 38 | this.setmealService = setmealService; 39 | this.categoryService = categoryService; 40 | this.setmealDishService = setmealDishService; 41 | } 42 | 43 | /** 44 | * 新增套餐 45 | * 46 | * @param setmealDto 47 | * @return 48 | */ 49 | @PostMapping 50 | public R save(@RequestBody SetmealDto setmealDto) { 51 | log.info("套餐信息:{}", setmealDto); 52 | 53 | setmealService.saveWithDish(setmealDto); 54 | 55 | return R.success("新增套餐成功"); 56 | } 57 | 58 | /** 59 | * 套餐分页查询 60 | * 61 | * @param page 62 | * @param pageSize 63 | * @param name 64 | * @return 65 | */ 66 | @GetMapping("/page") 67 | public R page(int page, int pageSize, String name) { 68 | //分页构造器对象 69 | Page pageInfo = new Page<>(page, pageSize); 70 | Page dtoPage = new Page<>(); 71 | 72 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 73 | //添加查询条件,根据name进行like模糊查询 74 | queryWrapper.like(name != null, Setmeal::getName, name); 75 | //添加排序条件,根据更新时间降序排列 76 | queryWrapper.orderByDesc(Setmeal::getUpdateTime); 77 | 78 | setmealService.page(pageInfo, queryWrapper); 79 | 80 | //对象拷贝 81 | BeanUtils.copyProperties(pageInfo, dtoPage, "records"); 82 | List records = pageInfo.getRecords(); 83 | 84 | List list = records.stream().map((item) -> { 85 | SetmealDto setmealDto = new SetmealDto(); 86 | //对象拷贝 87 | BeanUtils.copyProperties(item, setmealDto); 88 | //分类id 89 | Long categoryId = item.getCategoryId(); 90 | //根据分类id查询分类对象 91 | Category category = categoryService.getById(categoryId); 92 | if (category != null) { 93 | //分类名称 94 | String categoryName = category.getName(); 95 | setmealDto.setCategoryName(categoryName); 96 | } 97 | return setmealDto; 98 | }).collect(Collectors.toList()); 99 | 100 | dtoPage.setRecords(list); 101 | return R.success(dtoPage); 102 | } 103 | 104 | /** 105 | * 删除套餐 106 | * 107 | * @param ids 108 | * @return 109 | */ 110 | @DeleteMapping 111 | public R delete(@RequestParam List ids) { 112 | log.info("ids:{}", ids); 113 | 114 | setmealService.removeWithDish(ids); 115 | 116 | return R.success("套餐数据删除成功"); 117 | } 118 | 119 | /** 120 | * 根据条件查询套餐数据 121 | * 122 | * @param setmeal 123 | * @return 124 | */ 125 | @GetMapping("/list") 126 | public R> list(Setmeal setmeal) { 127 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 128 | queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId()); 129 | queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus()); 130 | queryWrapper.orderByDesc(Setmeal::getUpdateTime); 131 | 132 | List list = setmealService.list(queryWrapper); 133 | 134 | return R.success(list); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/ShoppingCartController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.dev33.satoken.stp.StpUtil; 4 | import cn.enaium.reggie.common.R; 5 | import cn.enaium.reggie.entity.ShoppingCart; 6 | import cn.enaium.reggie.service.ShoppingCartService; 7 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.time.LocalDateTime; 12 | import java.util.List; 13 | 14 | /** 15 | * 购物车 16 | */ 17 | @Slf4j 18 | @RestController 19 | @RequestMapping("/shoppingCart") 20 | public class ShoppingCartController { 21 | 22 | private final ShoppingCartService shoppingCartService; 23 | 24 | public ShoppingCartController(ShoppingCartService shoppingCartService) { 25 | this.shoppingCartService = shoppingCartService; 26 | } 27 | 28 | /** 29 | * 添加购物车 30 | * 31 | * @param shoppingCart 32 | * @return 33 | */ 34 | @PostMapping("/add") 35 | public R add(@RequestBody ShoppingCart shoppingCart) { 36 | log.info("购物车数据:{}", shoppingCart); 37 | 38 | //设置用户id,指定当前是哪个用户的购物车数据 39 | Long currentId = StpUtil.getLoginIdAsLong(); 40 | shoppingCart.setUserId(currentId); 41 | 42 | Long dishId = shoppingCart.getDishId(); 43 | 44 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 45 | queryWrapper.eq(ShoppingCart::getUserId, currentId); 46 | 47 | if (dishId != null) { 48 | //添加到购物车的是菜品 49 | queryWrapper.eq(ShoppingCart::getDishId, dishId); 50 | 51 | } else { 52 | //添加到购物车的是套餐 53 | queryWrapper.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId()); 54 | } 55 | 56 | //查询当前菜品或者套餐是否在购物车中 57 | //SQL:select * from shopping_cart where user_id = ? and dish_id/setmeal_id = ? 58 | ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper); 59 | 60 | if (cartServiceOne != null) { 61 | //如果已经存在,就在原来数量基础上加一 62 | Integer number = cartServiceOne.getNumber(); 63 | cartServiceOne.setNumber(number + 1); 64 | shoppingCartService.updateById(cartServiceOne); 65 | } else { 66 | //如果不存在,则添加到购物车,数量默认就是一 67 | shoppingCart.setNumber(1); 68 | shoppingCart.setCreateTime(LocalDateTime.now()); 69 | shoppingCartService.save(shoppingCart); 70 | cartServiceOne = shoppingCart; 71 | } 72 | 73 | return R.success(cartServiceOne); 74 | } 75 | 76 | /** 77 | * 查看购物车 78 | * 79 | * @return 80 | */ 81 | @GetMapping("/list") 82 | public R> list() { 83 | log.info("查看购物车..."); 84 | 85 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 86 | queryWrapper.eq(ShoppingCart::getUserId, StpUtil.getLoginIdAsLong()); 87 | queryWrapper.orderByAsc(ShoppingCart::getCreateTime); 88 | 89 | List list = shoppingCartService.list(queryWrapper); 90 | 91 | return R.success(list); 92 | } 93 | 94 | /** 95 | * 清空购物车 96 | * 97 | * @return 98 | */ 99 | @DeleteMapping("/clean") 100 | public R clean() { 101 | //SQL:delete from shopping_cart where user_id = ? 102 | 103 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 104 | queryWrapper.eq(ShoppingCart::getUserId, StpUtil.getLoginIdAsLong()); 105 | 106 | shoppingCartService.remove(queryWrapper); 107 | 108 | return R.success("清空购物车成功"); 109 | } 110 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.controller; 2 | 3 | import cn.enaium.reggie.common.R; 4 | import cn.enaium.reggie.entity.User; 5 | import cn.enaium.reggie.service.UserService; 6 | import cn.enaium.reggie.utils.ValidateCodeUtils; 7 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.commons.lang.StringUtils; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestBody; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import javax.servlet.http.HttpSession; 17 | import java.util.Map; 18 | 19 | @RestController 20 | @RequestMapping("/user") 21 | @Slf4j 22 | public class UserController { 23 | 24 | private final UserService userService; 25 | 26 | public UserController(UserService userService) { 27 | this.userService = userService; 28 | } 29 | 30 | /** 31 | * 发送手机短信验证码 32 | * 33 | * @param user 34 | * @return 35 | */ 36 | @PostMapping("/sendMsg") 37 | public R sendMsg(@RequestBody User user, HttpSession session) { 38 | //获取手机号 39 | String phone = user.getPhone(); 40 | 41 | if (StringUtils.isNotEmpty(phone)) { 42 | //生成随机的4位验证码 43 | String code = ValidateCodeUtils.generateValidateCode(4).toString(); 44 | log.info("code={}", code); 45 | 46 | //调用阿里云提供的短信服务API完成发送短信 47 | //SMSUtils.sendMessage("瑞吉外卖","",phone,code); 48 | 49 | //需要将生成的验证码保存到Session 50 | session.setAttribute(phone, code); 51 | 52 | return R.success("手机验证码短信发送成功"); 53 | } 54 | 55 | return R.error("短信发送失败"); 56 | } 57 | 58 | /** 59 | * 移动端用户登录 60 | * 61 | * @param map 62 | * @param session 63 | * @return 64 | */ 65 | @PostMapping("/login") 66 | public R login(@RequestBody Map map, HttpSession session) { 67 | log.info(map.toString()); 68 | 69 | //获取手机号 70 | String phone = map.get("phone").toString(); 71 | 72 | //获取验证码 73 | String code = map.get("code").toString(); 74 | 75 | //从Session中获取保存的验证码 76 | Object codeInSession = session.getAttribute(phone); 77 | 78 | //进行验证码的比对(页面提交的验证码和Session中保存的验证码比对) 79 | if (codeInSession != null && codeInSession.equals(code)) { 80 | //如果能够比对成功,说明登录成功 81 | 82 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 83 | queryWrapper.eq(User::getPhone, phone); 84 | 85 | User user = userService.getOne(queryWrapper); 86 | if (user == null) { 87 | //判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册 88 | user = new User(); 89 | user.setPhone(phone); 90 | user.setStatus(1); 91 | userService.save(user); 92 | } 93 | session.setAttribute("user", user.getId()); 94 | return R.success(user); 95 | } 96 | return R.error("登录失败"); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/dto/DishDto.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.dto; 2 | 3 | import cn.enaium.reggie.entity.Dish; 4 | import cn.enaium.reggie.entity.DishFlavor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @EqualsAndHashCode(callSuper=false) 12 | @Data 13 | public class DishDto extends Dish { 14 | 15 | //菜品对应的口味数据 16 | private List flavors = new ArrayList<>(); 17 | 18 | private String categoryName; 19 | 20 | private Integer copies; 21 | } 22 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/dto/SetmealDto.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.dto; 2 | 3 | import cn.enaium.reggie.entity.Setmeal; 4 | import cn.enaium.reggie.entity.SetmealDish; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import java.util.List; 9 | 10 | @EqualsAndHashCode(callSuper=false) 11 | @Data 12 | public class SetmealDto extends Setmeal { 13 | 14 | private List setmealDishes; 15 | 16 | private String categoryName; 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/AddressBook.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * 地址簿 12 | */ 13 | @Data 14 | public class AddressBook implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private Long id; 19 | 20 | 21 | //用户id 22 | private Long userId; 23 | 24 | 25 | //收货人 26 | private String consignee; 27 | 28 | 29 | //手机号 30 | private String phone; 31 | 32 | 33 | //性别 0 女 1 男 34 | private String sex; 35 | 36 | 37 | //省级区划编号 38 | private String provinceCode; 39 | 40 | 41 | //省级名称 42 | private String provinceName; 43 | 44 | 45 | //市级区划编号 46 | private String cityCode; 47 | 48 | 49 | //市级名称 50 | private String cityName; 51 | 52 | 53 | //区级区划编号 54 | private String districtCode; 55 | 56 | 57 | //区级名称 58 | private String districtName; 59 | 60 | 61 | //详细地址 62 | private String detail; 63 | 64 | 65 | //标签 66 | private String label; 67 | 68 | //是否默认 0 否 1是 69 | private Integer isDefault; 70 | 71 | //创建时间 72 | @TableField(fill = FieldFill.INSERT) 73 | private LocalDateTime createTime; 74 | 75 | 76 | //更新时间 77 | @TableField(fill = FieldFill.INSERT_UPDATE) 78 | private LocalDateTime updateTime; 79 | 80 | 81 | //创建人 82 | @TableField(fill = FieldFill.INSERT) 83 | private Long createUser; 84 | 85 | 86 | //修改人 87 | @TableField(fill = FieldFill.INSERT_UPDATE) 88 | private Long updateUser; 89 | 90 | 91 | //是否删除 92 | private Integer isDeleted; 93 | } 94 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/Category.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * 分类 12 | */ 13 | @Data 14 | public class Category implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private Long id; 19 | 20 | 21 | //类型 1 菜品分类 2 套餐分类 22 | private Integer type; 23 | 24 | 25 | //分类名称 26 | private String name; 27 | 28 | 29 | //顺序 30 | private Integer sort; 31 | 32 | 33 | //创建时间 34 | @TableField(fill = FieldFill.INSERT) 35 | private LocalDateTime createTime; 36 | 37 | 38 | //更新时间 39 | @TableField(fill = FieldFill.INSERT_UPDATE) 40 | private LocalDateTime updateTime; 41 | 42 | 43 | //创建人 44 | @TableField(fill = FieldFill.INSERT) 45 | private Long createUser; 46 | 47 | 48 | //修改人 49 | @TableField(fill = FieldFill.INSERT_UPDATE) 50 | private Long updateUser; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/Dish.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * 菜品 13 | */ 14 | @Data 15 | public class Dish implements Serializable { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private Long id; 20 | 21 | 22 | //菜品名称 23 | private String name; 24 | 25 | 26 | //菜品分类id 27 | private Long categoryId; 28 | 29 | 30 | //菜品价格 31 | private BigDecimal price; 32 | 33 | 34 | //商品码 35 | private String code; 36 | 37 | 38 | //图片 39 | private String image; 40 | 41 | 42 | //描述信息 43 | private String description; 44 | 45 | 46 | //0 停售 1 起售 47 | private Integer status; 48 | 49 | 50 | //顺序 51 | private Integer sort; 52 | 53 | 54 | @TableField(fill = FieldFill.INSERT) 55 | private LocalDateTime createTime; 56 | 57 | 58 | @TableField(fill = FieldFill.INSERT_UPDATE) 59 | private LocalDateTime updateTime; 60 | 61 | 62 | @TableField(fill = FieldFill.INSERT) 63 | private Long createUser; 64 | 65 | 66 | @TableField(fill = FieldFill.INSERT_UPDATE) 67 | private Long updateUser; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/DishFlavor.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * 菜品口味 12 | */ 13 | @Data 14 | public class DishFlavor implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private Long id; 19 | 20 | 21 | //菜品id 22 | private Long dishId; 23 | 24 | 25 | //口味名称 26 | private String name; 27 | 28 | 29 | //口味数据list 30 | private String value; 31 | 32 | 33 | @TableField(fill = FieldFill.INSERT) 34 | private LocalDateTime createTime; 35 | 36 | 37 | @TableField(fill = FieldFill.INSERT_UPDATE) 38 | private LocalDateTime updateTime; 39 | 40 | 41 | @TableField(fill = FieldFill.INSERT) 42 | private Long createUser; 43 | 44 | 45 | @TableField(fill = FieldFill.INSERT_UPDATE) 46 | private Long updateUser; 47 | 48 | 49 | //是否删除 50 | private Integer isDeleted; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/Employee.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * 员工实体 12 | */ 13 | @Data 14 | public class Employee implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private Long id; 19 | 20 | private String username; 21 | 22 | private String name; 23 | 24 | private String password; 25 | 26 | private String phone; 27 | 28 | private String sex; 29 | 30 | private String idNumber;//身份证号码 31 | 32 | private Integer status; 33 | 34 | @TableField(fill = FieldFill.INSERT) //插入时填充字段 35 | private LocalDateTime createTime; 36 | 37 | @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段 38 | private LocalDateTime updateTime; 39 | 40 | @TableField(fill = FieldFill.INSERT) //插入时填充字段 41 | private Long createUser; 42 | 43 | @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段 44 | private Long updateUser; 45 | 46 | @TableField(exist = false) 47 | private String token; 48 | } 49 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/OrderDetail.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | 8 | /** 9 | * 订单明细 10 | */ 11 | @Data 12 | public class OrderDetail implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | private Long id; 17 | 18 | //名称 19 | private String name; 20 | 21 | //订单id 22 | private Long orderId; 23 | 24 | 25 | //菜品id 26 | private Long dishId; 27 | 28 | 29 | //套餐id 30 | private Long setmealId; 31 | 32 | 33 | //口味 34 | private String dishFlavor; 35 | 36 | 37 | //数量 38 | private Integer number; 39 | 40 | //金额 41 | private BigDecimal amount; 42 | 43 | //图片 44 | private String image; 45 | } 46 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/Orders.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 订单 11 | */ 12 | @Data 13 | public class Orders implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | private Long id; 18 | 19 | //订单号 20 | private String number; 21 | 22 | //订单状态 1待付款,2待派送,3已派送,4已完成,5已取消 23 | private Integer status; 24 | 25 | 26 | //下单用户id 27 | private Long userId; 28 | 29 | //地址id 30 | private Long addressBookId; 31 | 32 | 33 | //下单时间 34 | private LocalDateTime orderTime; 35 | 36 | 37 | //结账时间 38 | private LocalDateTime checkoutTime; 39 | 40 | 41 | //支付方式 1微信,2支付宝 42 | private Integer payMethod; 43 | 44 | 45 | //实收金额 46 | private BigDecimal amount; 47 | 48 | //备注 49 | private String remark; 50 | 51 | //用户名 52 | private String userName; 53 | 54 | //手机号 55 | private String phone; 56 | 57 | //地址 58 | private String address; 59 | 60 | //收货人 61 | private String consignee; 62 | } 63 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/Setmeal.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * 套餐 13 | */ 14 | @Data 15 | public class Setmeal implements Serializable { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private Long id; 20 | 21 | 22 | //分类id 23 | private Long categoryId; 24 | 25 | 26 | //套餐名称 27 | private String name; 28 | 29 | 30 | //套餐价格 31 | private BigDecimal price; 32 | 33 | 34 | //状态 0:停用 1:启用 35 | private Integer status; 36 | 37 | 38 | //编码 39 | private String code; 40 | 41 | 42 | //描述信息 43 | private String description; 44 | 45 | 46 | //图片 47 | private String image; 48 | 49 | 50 | @TableField(fill = FieldFill.INSERT) 51 | private LocalDateTime createTime; 52 | 53 | 54 | @TableField(fill = FieldFill.INSERT_UPDATE) 55 | private LocalDateTime updateTime; 56 | 57 | 58 | @TableField(fill = FieldFill.INSERT) 59 | private Long createUser; 60 | 61 | 62 | @TableField(fill = FieldFill.INSERT_UPDATE) 63 | private Long updateUser; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/SetmealDish.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * 套餐菜品关系 13 | */ 14 | @Data 15 | public class SetmealDish implements Serializable { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private Long id; 20 | 21 | 22 | //套餐id 23 | private Long setmealId; 24 | 25 | 26 | //菜品id 27 | private Long dishId; 28 | 29 | 30 | //菜品名称 (冗余字段) 31 | private String name; 32 | 33 | //菜品原价 34 | private BigDecimal price; 35 | 36 | //份数 37 | private Integer copies; 38 | 39 | 40 | //排序 41 | private Integer sort; 42 | 43 | 44 | @TableField(fill = FieldFill.INSERT) 45 | private LocalDateTime createTime; 46 | 47 | 48 | @TableField(fill = FieldFill.INSERT_UPDATE) 49 | private LocalDateTime updateTime; 50 | 51 | 52 | @TableField(fill = FieldFill.INSERT) 53 | private Long createUser; 54 | 55 | 56 | @TableField(fill = FieldFill.INSERT_UPDATE) 57 | private Long updateUser; 58 | 59 | 60 | //是否删除 61 | private Integer isDeleted; 62 | } 63 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/ShoppingCart.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 购物车 11 | */ 12 | @Data 13 | public class ShoppingCart implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | private Long id; 18 | 19 | //名称 20 | private String name; 21 | 22 | //用户id 23 | private Long userId; 24 | 25 | //菜品id 26 | private Long dishId; 27 | 28 | //套餐id 29 | private Long setmealId; 30 | 31 | //口味 32 | private String dishFlavor; 33 | 34 | //数量 35 | private Integer number; 36 | 37 | //金额 38 | private BigDecimal amount; 39 | 40 | //图片 41 | private String image; 42 | 43 | private LocalDateTime createTime; 44 | } 45 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/entity/User.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 用户信息 9 | */ 10 | @Data 11 | public class User implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | private Long id; 16 | 17 | 18 | //姓名 19 | private String name; 20 | 21 | 22 | //手机号 23 | private String phone; 24 | 25 | 26 | //性别 0 女 1 男 27 | private String sex; 28 | 29 | 30 | //身份证号 31 | private String idNumber; 32 | 33 | 34 | //头像 35 | private String avatar; 36 | 37 | 38 | //状态 0:禁用,1:正常 39 | private Integer status; 40 | } 41 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/AddressBookMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.AddressBook; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface AddressBookMapper extends BaseMapper { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/CategoryMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.Category; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface CategoryMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/DishFlavorMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.DishFlavor; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface DishFlavorMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/DishMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.Dish; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface DishMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/EmployeeMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.Employee; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface EmployeeMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/OrderDetailMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.OrderDetail; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface OrderDetailMapper extends BaseMapper { 9 | 10 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/OrderMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.Orders; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface OrderMapper extends BaseMapper { 9 | 10 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/SetmealDishMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.SetmealDish; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface SetmealDishMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/SetmealMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.Setmeal; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface SetmealMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/ShoppingCartMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.ShoppingCart; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface ShoppingCartMapper extends BaseMapper { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.mapper; 2 | 3 | import cn.enaium.reggie.entity.User; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface UserMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/AddressBookService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.AddressBook; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface AddressBookService extends IService { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/CategoryService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.Category; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface CategoryService extends IService { 7 | 8 | public void remove(Long id); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/DishFlavorService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.DishFlavor; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface DishFlavorService extends IService { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/DishService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.dto.DishDto; 4 | import cn.enaium.reggie.entity.Dish; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | public interface DishService extends IService { 8 | 9 | //新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor 10 | public void saveWithFlavor(DishDto dishDto); 11 | 12 | //根据id查询菜品信息和对应的口味信息 13 | public DishDto getByIdWithFlavor(Long id); 14 | 15 | //更新菜品信息,同时更新对应的口味信息 16 | public void updateWithFlavor(DishDto dishDto); 17 | } 18 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/EmployeeService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.Employee; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface EmployeeService extends IService { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/OrderDetailService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.OrderDetail; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface OrderDetailService extends IService { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.Orders; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface OrderService extends IService { 7 | 8 | /** 9 | * 用户下单 10 | * 11 | * @param orders 12 | */ 13 | public void submit(Orders orders); 14 | } 15 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/SetmealDishService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.SetmealDish; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface SetmealDishService extends IService { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/SetmealService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.dto.SetmealDto; 4 | import cn.enaium.reggie.entity.Setmeal; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | import java.util.List; 8 | 9 | public interface SetmealService extends IService { 10 | /** 11 | * 新增套餐,同时需要保存套餐和菜品的关联关系 12 | * 13 | * @param setmealDto 14 | */ 15 | public void saveWithDish(SetmealDto setmealDto); 16 | 17 | /** 18 | * 删除套餐,同时需要删除套餐和菜品的关联数据 19 | * 20 | * @param ids 21 | */ 22 | public void removeWithDish(List ids); 23 | } 24 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/ShoppingCartService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.ShoppingCart; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface ShoppingCartService extends IService { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/UserService.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service; 2 | 3 | import cn.enaium.reggie.entity.User; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | public interface UserService extends IService { 7 | } 8 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/AddressBookServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.AddressBook; 4 | import cn.enaium.reggie.mapper.AddressBookMapper; 5 | import cn.enaium.reggie.service.AddressBookService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class AddressBookServiceImpl extends ServiceImpl implements AddressBookService { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/CategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.common.CustomException; 4 | import cn.enaium.reggie.entity.Category; 5 | import cn.enaium.reggie.entity.Dish; 6 | import cn.enaium.reggie.entity.Setmeal; 7 | import cn.enaium.reggie.mapper.CategoryMapper; 8 | import cn.enaium.reggie.service.CategoryService; 9 | import cn.enaium.reggie.service.DishService; 10 | import cn.enaium.reggie.service.SetmealService; 11 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 12 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 13 | import org.springframework.stereotype.Service; 14 | 15 | @Service 16 | public class CategoryServiceImpl extends ServiceImpl implements CategoryService { 17 | 18 | 19 | private final DishService dishService; 20 | 21 | 22 | private final SetmealService setmealService; 23 | 24 | public CategoryServiceImpl(DishService dishService, SetmealService setmealService) { 25 | this.dishService = dishService; 26 | this.setmealService = setmealService; 27 | } 28 | 29 | /** 30 | * 根据id删除分类,删除之前需要进行判断 31 | * 32 | * @param id 33 | */ 34 | @Override 35 | public void remove(Long id) { 36 | LambdaQueryWrapper dishLambdaQueryWrapper = new LambdaQueryWrapper<>(); 37 | //添加查询条件,根据分类id进行查询 38 | dishLambdaQueryWrapper.eq(Dish::getCategoryId, id); 39 | long count1 = dishService.count(dishLambdaQueryWrapper); 40 | 41 | //查询当前分类是否关联了菜品,如果已经关联,抛出一个业务异常 42 | if (count1 > 0) { 43 | //已经关联菜品,抛出一个业务异常 44 | throw new CustomException("当前分类下关联了菜品,不能删除"); 45 | } 46 | 47 | //查询当前分类是否关联了套餐,如果已经关联,抛出一个业务异常 48 | LambdaQueryWrapper setmealLambdaQueryWrapper = new LambdaQueryWrapper<>(); 49 | //添加查询条件,根据分类id进行查询 50 | setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId, id); 51 | long count2 = setmealService.count(); 52 | if (count2 > 0) { 53 | //已经关联套餐,抛出一个业务异常 54 | throw new CustomException("当前分类下关联了套餐,不能删除"); 55 | } 56 | 57 | //正常删除分类 58 | super.removeById(id); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/DishFlavorServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.DishFlavor; 4 | import cn.enaium.reggie.mapper.DishFlavorMapper; 5 | import cn.enaium.reggie.service.DishFlavorService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class DishFlavorServiceImpl extends ServiceImpl implements DishFlavorService { 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/DishServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.dto.DishDto; 4 | import cn.enaium.reggie.entity.Dish; 5 | import cn.enaium.reggie.entity.DishFlavor; 6 | import cn.enaium.reggie.mapper.DishMapper; 7 | import cn.enaium.reggie.service.DishFlavorService; 8 | import cn.enaium.reggie.service.DishService; 9 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 10 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | 20 | @Service 21 | @Slf4j 22 | public class DishServiceImpl extends ServiceImpl implements DishService { 23 | 24 | private final DishFlavorService dishFlavorService; 25 | 26 | public DishServiceImpl(DishFlavorService dishFlavorService) { 27 | this.dishFlavorService = dishFlavorService; 28 | } 29 | 30 | /** 31 | * 新增菜品,同时保存对应的口味数据 32 | * 33 | * @param dishDto 34 | */ 35 | @Transactional 36 | public void saveWithFlavor(DishDto dishDto) { 37 | //保存菜品的基本信息到菜品表dish 38 | this.save(dishDto); 39 | 40 | Long dishId = dishDto.getId();//菜品id 41 | 42 | //菜品口味 43 | List flavors = dishDto.getFlavors(); 44 | flavors = flavors.stream().map((item) -> { 45 | item.setDishId(dishId); 46 | return item; 47 | }).collect(Collectors.toList()); 48 | 49 | //保存菜品口味数据到菜品口味表dish_flavor 50 | dishFlavorService.saveBatch(flavors); 51 | 52 | } 53 | 54 | /** 55 | * 根据id查询菜品信息和对应的口味信息 56 | * 57 | * @param id 58 | * @return 59 | */ 60 | public DishDto getByIdWithFlavor(Long id) { 61 | //查询菜品基本信息,从dish表查询 62 | Dish dish = this.getById(id); 63 | 64 | DishDto dishDto = new DishDto(); 65 | BeanUtils.copyProperties(dish, dishDto); 66 | 67 | //查询当前菜品对应的口味信息,从dish_flavor表查询 68 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); 69 | queryWrapper.eq(DishFlavor::getDishId, dish.getId()); 70 | List flavors = dishFlavorService.list(queryWrapper); 71 | dishDto.setFlavors(flavors); 72 | 73 | return dishDto; 74 | } 75 | 76 | @Override 77 | @Transactional 78 | public void updateWithFlavor(DishDto dishDto) { 79 | //更新dish表基本信息 80 | this.updateById(dishDto); 81 | 82 | //清理当前菜品对应口味数据---dish_flavor表的delete操作 83 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); 84 | queryWrapper.eq(DishFlavor::getDishId, dishDto.getId()); 85 | 86 | dishFlavorService.remove(queryWrapper); 87 | 88 | //添加当前提交过来的口味数据---dish_flavor表的insert操作 89 | List flavors = dishDto.getFlavors(); 90 | 91 | flavors = flavors.stream().map((item) -> { 92 | item.setDishId(dishDto.getId()); 93 | return item; 94 | }).collect(Collectors.toList()); 95 | 96 | dishFlavorService.saveBatch(flavors); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/EmployeeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.Employee; 4 | import cn.enaium.reggie.mapper.EmployeeMapper; 5 | import cn.enaium.reggie.service.EmployeeService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class EmployeeServiceImpl extends ServiceImpl implements EmployeeService { 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/OrderDetailServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.OrderDetail; 4 | import cn.enaium.reggie.mapper.OrderDetailMapper; 5 | import cn.enaium.reggie.service.OrderDetailService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class OrderDetailServiceImpl extends ServiceImpl implements OrderDetailService { 11 | 12 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.dev33.satoken.stp.StpUtil; 4 | import cn.enaium.reggie.common.CustomException; 5 | import cn.enaium.reggie.entity.*; 6 | import cn.enaium.reggie.mapper.OrderMapper; 7 | import cn.enaium.reggie.service.*; 8 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 9 | import com.baomidou.mybatisplus.core.toolkit.IdWorker; 10 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | import java.math.BigDecimal; 16 | import java.time.LocalDateTime; 17 | import java.util.List; 18 | import java.util.concurrent.atomic.AtomicInteger; 19 | import java.util.stream.Collectors; 20 | 21 | @Service 22 | @Slf4j 23 | public class OrderServiceImpl extends ServiceImpl implements OrderService { 24 | 25 | 26 | private final ShoppingCartService shoppingCartService; 27 | 28 | 29 | private final UserService userService; 30 | 31 | 32 | private final AddressBookService addressBookService; 33 | 34 | 35 | private final OrderDetailService orderDetailService; 36 | 37 | public OrderServiceImpl(ShoppingCartService shoppingCartService, UserService userService, AddressBookService addressBookService, OrderDetailService orderDetailService) { 38 | this.shoppingCartService = shoppingCartService; 39 | this.userService = userService; 40 | this.addressBookService = addressBookService; 41 | this.orderDetailService = orderDetailService; 42 | } 43 | 44 | /** 45 | * 用户下单 46 | * 47 | * @param orders 48 | */ 49 | @Transactional 50 | public void submit(Orders orders) { 51 | //获得当前用户id 52 | Long userId = StpUtil.getLoginIdAsLong(); 53 | 54 | //查询当前用户的购物车数据 55 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); 56 | wrapper.eq(ShoppingCart::getUserId, userId); 57 | List shoppingCarts = shoppingCartService.list(wrapper); 58 | 59 | if (shoppingCarts == null || shoppingCarts.size() == 0) { 60 | throw new CustomException("购物车为空,不能下单"); 61 | } 62 | 63 | //查询用户数据 64 | User user = userService.getById(userId); 65 | 66 | //查询地址数据 67 | Long addressBookId = orders.getAddressBookId(); 68 | AddressBook addressBook = addressBookService.getById(addressBookId); 69 | if (addressBook == null) { 70 | throw new CustomException("用户地址信息有误,不能下单"); 71 | } 72 | 73 | long orderId = IdWorker.getId();//订单号 74 | 75 | AtomicInteger amount = new AtomicInteger(0); 76 | 77 | List orderDetails = shoppingCarts.stream().map((item) -> { 78 | OrderDetail orderDetail = new OrderDetail(); 79 | orderDetail.setOrderId(orderId); 80 | orderDetail.setNumber(item.getNumber()); 81 | orderDetail.setDishFlavor(item.getDishFlavor()); 82 | orderDetail.setDishId(item.getDishId()); 83 | orderDetail.setSetmealId(item.getSetmealId()); 84 | orderDetail.setName(item.getName()); 85 | orderDetail.setImage(item.getImage()); 86 | orderDetail.setAmount(item.getAmount()); 87 | amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue()); 88 | return orderDetail; 89 | }).collect(Collectors.toList()); 90 | 91 | 92 | orders.setId(orderId); 93 | orders.setOrderTime(LocalDateTime.now()); 94 | orders.setCheckoutTime(LocalDateTime.now()); 95 | orders.setStatus(2); 96 | orders.setAmount(new BigDecimal(amount.get()));//总金额 97 | orders.setUserId(userId); 98 | orders.setNumber(String.valueOf(orderId)); 99 | orders.setUserName(user.getName()); 100 | orders.setConsignee(addressBook.getConsignee()); 101 | orders.setPhone(addressBook.getPhone()); 102 | orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName()) 103 | + (addressBook.getCityName() == null ? "" : addressBook.getCityName()) 104 | + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName()) 105 | + (addressBook.getDetail() == null ? "" : addressBook.getDetail())); 106 | //向订单表插入数据,一条数据 107 | this.save(orders); 108 | 109 | //向订单明细表插入数据,多条数据 110 | orderDetailService.saveBatch(orderDetails); 111 | 112 | //清空购物车数据 113 | shoppingCartService.remove(wrapper); 114 | } 115 | } -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/SetmealDishServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.SetmealDish; 4 | import cn.enaium.reggie.mapper.SetmealDishMapper; 5 | import cn.enaium.reggie.service.SetmealDishService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @Slf4j 12 | public class SetmealDishServiceImpl extends ServiceImpl implements SetmealDishService { 13 | } 14 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/SetmealServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.common.CustomException; 4 | import cn.enaium.reggie.dto.SetmealDto; 5 | import cn.enaium.reggie.entity.Setmeal; 6 | import cn.enaium.reggie.entity.SetmealDish; 7 | import cn.enaium.reggie.mapper.SetmealMapper; 8 | import cn.enaium.reggie.service.SetmealDishService; 9 | import cn.enaium.reggie.service.SetmealService; 10 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 11 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | 20 | @Service 21 | @Slf4j 22 | public class SetmealServiceImpl extends ServiceImpl implements SetmealService { 23 | 24 | private final SetmealDishService setmealDishService; 25 | 26 | public SetmealServiceImpl(SetmealDishService setmealDishService) { 27 | this.setmealDishService = setmealDishService; 28 | } 29 | 30 | /** 31 | * 新增套餐,同时需要保存套餐和菜品的关联关系 32 | * 33 | * @param setmealDto 34 | */ 35 | @Transactional 36 | public void saveWithDish(SetmealDto setmealDto) { 37 | //保存套餐的基本信息,操作setmeal,执行insert操作 38 | this.save(setmealDto); 39 | 40 | List setmealDishes = setmealDto.getSetmealDishes(); 41 | setmealDishes.stream().map((item) -> { 42 | item.setSetmealId(setmealDto.getId()); 43 | return item; 44 | }).collect(Collectors.toList()); 45 | 46 | //保存套餐和菜品的关联信息,操作setmeal_dish,执行insert操作 47 | setmealDishService.saveBatch(setmealDishes); 48 | } 49 | 50 | /** 51 | * 删除套餐,同时需要删除套餐和菜品的关联数据 52 | * 53 | * @param ids 54 | */ 55 | @Transactional 56 | public void removeWithDish(List ids) { 57 | //select count(*) from setmeal where id in (1,2,3) and status = 1 58 | //查询套餐状态,确定是否可用删除 59 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); 60 | queryWrapper.in(Setmeal::getId, ids); 61 | queryWrapper.eq(Setmeal::getStatus, 1); 62 | 63 | long count = this.count(queryWrapper); 64 | if (count > 0) { 65 | //如果不能删除,抛出一个业务异常 66 | throw new CustomException("套餐正在售卖中,不能删除"); 67 | } 68 | 69 | //如果可以删除,先删除套餐表中的数据---setmeal 70 | this.removeByIds(ids); 71 | 72 | //delete from setmeal_dish where setmeal_id in (1,2,3) 73 | LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); 74 | lambdaQueryWrapper.in(SetmealDish::getSetmealId, ids); 75 | //删除关系表中的数据----setmeal_dish 76 | setmealDishService.remove(lambdaQueryWrapper); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/ShoppingCartServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.ShoppingCart; 4 | import cn.enaium.reggie.mapper.ShoppingCartMapper; 5 | import cn.enaium.reggie.service.ShoppingCartService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class ShoppingCartServiceImpl extends ServiceImpl implements ShoppingCartService { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.service.impl; 2 | 3 | import cn.enaium.reggie.entity.User; 4 | import cn.enaium.reggie.mapper.UserMapper; 5 | import cn.enaium.reggie.service.UserService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class UserServiceImpl extends ServiceImpl implements UserService { 11 | } 12 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/utils/SMSUtils.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.utils; 2 | 3 | import com.aliyuncs.DefaultAcsClient; 4 | import com.aliyuncs.IAcsClient; 5 | import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; 6 | import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; 7 | import com.aliyuncs.exceptions.ClientException; 8 | import com.aliyuncs.profile.DefaultProfile; 9 | 10 | /** 11 | * 短信发送工具类 12 | */ 13 | public class SMSUtils { 14 | 15 | /** 16 | * 发送短信 17 | * 18 | * @param signName 签名 19 | * @param templateCode 模板 20 | * @param phoneNumbers 手机号 21 | * @param param 参数 22 | */ 23 | public static void sendMessage(String signName, String templateCode, String phoneNumbers, String param) { 24 | DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", ""); 25 | IAcsClient client = new DefaultAcsClient(profile); 26 | 27 | SendSmsRequest request = new SendSmsRequest(); 28 | request.setSysRegionId("cn-hangzhou"); 29 | request.setPhoneNumbers(phoneNumbers); 30 | request.setSignName(signName); 31 | request.setTemplateCode(templateCode); 32 | request.setTemplateParam("{\"code\":\"" + param + "\"}"); 33 | try { 34 | SendSmsResponse response = client.getAcsResponse(request); 35 | System.out.println("短信发送成功"); 36 | } catch (ClientException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /server/src/main/java/cn/enaium/reggie/utils/ValidateCodeUtils.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * 随机生成验证码工具类 7 | */ 8 | public class ValidateCodeUtils { 9 | /** 10 | * 随机生成验证码 11 | * 12 | * @param length 长度为4位或者6位 13 | * @return 14 | */ 15 | public static Integer generateValidateCode(int length) { 16 | Integer code = null; 17 | if (length == 4) { 18 | code = new Random().nextInt(9999);//生成随机数,最大为9999 19 | if (code < 1000) { 20 | code = code + 1000;//保证随机数为4位数字 21 | } 22 | } else if (length == 6) { 23 | code = new Random().nextInt(999999);//生成随机数,最大为999999 24 | if (code < 100000) { 25 | code = code + 100000;//保证随机数为6位数字 26 | } 27 | } else { 28 | throw new RuntimeException("只能生成4位或6位数字验证码"); 29 | } 30 | return code; 31 | } 32 | 33 | /** 34 | * 随机生成指定长度字符串验证码 35 | * 36 | * @param length 长度 37 | * @return 38 | */ 39 | public static String generateValidateCode4String(int length) { 40 | Random rdm = new Random(); 41 | String hash1 = Integer.toHexString(rdm.nextInt()); 42 | String capstr = hash1.substring(0, length); 43 | return capstr; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /server/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | spring: 4 | application: 5 | name: reggie-takeout 6 | datasource: 7 | druid: 8 | driver-class-name: org.mariadb.jdbc.Driver 9 | url: jdbc:mariadb://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true 10 | username: root 11 | password: root 12 | mybatis-plus: 13 | configuration: 14 | map-underscore-to-camel-case: true 15 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 16 | global-config: 17 | db-config: 18 | id-type: ASSIGN_ID 19 | reggie: 20 | path: image 21 | sa-token: 22 | token-name: token -------------------------------------------------------------------------------- /server/src/test/java/cn/enaium/reggie/ServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.enaium.reggie; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ServerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /website/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /website/LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "axios": "^1.2.2", 13 | "element-plus": "^2.2.28", 14 | "vant": "^4.0.7", 15 | "vue": "^3.2.45", 16 | "vue-router": "4" 17 | }, 18 | "devDependencies": { 19 | "@vitejs/plugin-vue": "^4.0.0", 20 | "vite": "^4.0.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/public/favicon.ico -------------------------------------------------------------------------------- /website/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /website/src/api/backend/category.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | // 查询列表接口 4 | export const getCategoryPage = (params) => 5 | request({ 6 | url: '/category/page', 7 | method: 'get', 8 | params 9 | }) 10 | 11 | // 编辑页面反查详情接口 12 | export const queryCategoryById = (id) => 13 | request({ 14 | url: `/category/${id}`, 15 | method: 'get' 16 | }) 17 | 18 | // 删除当前列的接口 19 | export const deleCategory = (id) => 20 | request({ 21 | url: '/category', 22 | method: 'delete', 23 | params: {id} 24 | }) 25 | 26 | // 修改接口 27 | export const editCategory = (params) => 28 | request({ 29 | url: '/category', 30 | method: 'put', 31 | data: {...params} 32 | }) 33 | 34 | // 新增接口 35 | export const addCategory = (params) => 36 | request({ 37 | url: '/category', 38 | method: 'post', 39 | data: {...params} 40 | }) -------------------------------------------------------------------------------- /website/src/api/backend/combo.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | // 查询列表数据 4 | export const getSetmealPage = (params) => 5 | request({ 6 | url: '/setmeal/page', 7 | method: 'get', 8 | params 9 | }) 10 | 11 | // 删除数据接口 12 | export const deleteSetmeal = (ids) => 13 | request({ 14 | url: '/setmeal', 15 | method: 'delete', 16 | params: {ids} 17 | }) 18 | 19 | // 修改数据接口 20 | export const editSetmeal = (params) => 21 | request({ 22 | url: '/setmeal', 23 | method: 'put', 24 | data: {...params} 25 | }) 26 | 27 | // 新增数据接口 28 | export const addSetmeal = (params) => 29 | request({ 30 | url: '/setmeal', 31 | method: 'post', 32 | data: {...params} 33 | }) 34 | 35 | // 查询详情接口 36 | export const querySetmealById = (id) => 37 | request({ 38 | url: `/setmeal/${id}`, 39 | method: 'get' 40 | }) 41 | 42 | // 批量起售禁售 43 | export const setmealStatusByStatus = (params) => 44 | request({ 45 | url: `/setmeal/status/${params.status}`, 46 | method: 'post', 47 | params: {ids: params.ids} 48 | }) 49 | -------------------------------------------------------------------------------- /website/src/api/backend/food.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | 4 | // 查询列表接口 5 | export const getDishPage = (params) => { 6 | return request({ 7 | url: '/dish/page', 8 | method: 'get', 9 | params 10 | }) 11 | } 12 | 13 | // 删除接口 14 | export const deleteDish = (ids) => { 15 | return request({ 16 | url: '/dish', 17 | method: 'delete', 18 | params: {ids} 19 | }) 20 | } 21 | 22 | // 修改接口 23 | export const editDish = (params) => { 24 | return request({ 25 | url: '/dish', 26 | method: 'put', 27 | data: {...params} 28 | }) 29 | } 30 | 31 | // 新增接口 32 | export const addDish = (params) => { 33 | return request({ 34 | url: '/dish', 35 | method: 'post', 36 | data: {...params} 37 | }) 38 | } 39 | 40 | // 查询详情 41 | export const queryDishById = (id) => { 42 | return request({ 43 | url: `/dish/${id}`, 44 | method: 'get' 45 | }) 46 | } 47 | 48 | // 获取菜品分类列表 49 | export const getCategoryList = (params) => { 50 | return request({ 51 | url: '/category/list', 52 | method: 'get', 53 | params 54 | }) 55 | } 56 | 57 | // 查菜品列表的接口 58 | export const queryDishList = (params) => 59 | request({ 60 | url: '/dish/list', 61 | method: 'get', 62 | params 63 | }) 64 | 65 | // 文件down预览 66 | export const commonDownload = (params) => 67 | request({ 68 | headers: { 69 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 70 | }, 71 | url: '/common/download', 72 | method: 'get', 73 | params 74 | }) 75 | 76 | // 起售停售---批量起售停售接口 77 | export const dishStatusByStatus = (params) => 78 | request({ 79 | url: `/dish/status/${params.status}`, 80 | method: 'post', 81 | params: {ids: params.id} 82 | }) -------------------------------------------------------------------------------- /website/src/api/backend/login.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | 4 | export const loginApi = (data) => 5 | request({ 6 | 'url': '/employee/login', 7 | 'method': 'post', 8 | data 9 | }) 10 | 11 | export const logoutApi = () => 12 | request({ 13 | 'url': '/employee/logout', 14 | 'method': 'post', 15 | }) 16 | -------------------------------------------------------------------------------- /website/src/api/backend/member.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | export const getMemberList = params => 4 | request({ 5 | url: '/employee/page', 6 | method: 'get', 7 | params 8 | }); 9 | 10 | // 修改---启用禁用接口 11 | export const enableOrDisableEmployee = params => 12 | request({ 13 | url: '/employee', 14 | method: 'put', 15 | data: {...params} 16 | }); 17 | 18 | // 新增---添加员工 19 | export const addEmployee = params => 20 | request({ 21 | url: '/employee', 22 | method: 'post', 23 | data: {...params} 24 | }); 25 | 26 | // 修改---添加员工 27 | export const editEmployee = params => 28 | request({ 29 | url: '/employee', 30 | method: 'put', 31 | data: {...params} 32 | }); 33 | 34 | // 修改页面反查详情接口 35 | export const queryEmployeeById = id => 36 | request({ 37 | url: `/employee/${id}`, 38 | method: 'get' 39 | }); -------------------------------------------------------------------------------- /website/src/api/backend/order.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/backend/request.js"; 2 | 3 | 4 | // 查询列表页接口 5 | export const getOrderDetailPage = (params) => 6 | request({ 7 | url: '/order/page', 8 | method: 'get', 9 | params 10 | }) 11 | 12 | // 查看接口 13 | export const queryOrderDetailById = (id) => 14 | request({ 15 | url: `/orderDetail/${id}`, 16 | method: 'get' 17 | }) 18 | 19 | // 取消,派送,完成接口 20 | export const editOrderDetail = (params) => 21 | request({ 22 | url: '/order', 23 | method: 'put', 24 | data: {...params} 25 | }) 26 | -------------------------------------------------------------------------------- /website/src/api/frontend/address.js: -------------------------------------------------------------------------------- 1 | //获取所有地址 2 | import request from "@/js/frontend/request.js"; 3 | 4 | export const addressListApi = () => request({ 5 | 'url': '/addressBook/list', 6 | 'method': 'get', 7 | }); 8 | 9 | //获取最新地址 10 | export const addressLastUpdateApi = () => request({ 11 | 'url': '/addressBook/lastUpdate', 12 | 'method': 'get', 13 | }); 14 | 15 | //新增地址 16 | export const addAddressApi = data => request({ 17 | 'url': '/addressBook', 18 | 'method': 'post', 19 | data 20 | }); 21 | 22 | //修改地址 23 | export const updateAddressApi = data => request({ 24 | 'url': '/addressBook', 25 | 'method': 'put', 26 | data 27 | }); 28 | 29 | //删除地址 30 | export const deleteAddressApi = params => request({ 31 | 'url': '/addressBook', 32 | 'method': 'delete', 33 | params 34 | }); 35 | 36 | //查询单个地址 37 | export const addressFindOneApi = id => request({ 38 | 'url': `/addressBook/${id}`, 39 | 'method': 'get', 40 | }); 41 | 42 | //设置默认地址 43 | export const setDefaultAddressApi = data => request({ 44 | 'url': '/addressBook/default', 45 | 'method': 'put', 46 | data 47 | }); 48 | 49 | //获取默认地址 50 | export const getDefaultAddressApi = () => request({ 51 | 'url': `/addressBook/default`, 52 | 'method': 'get', 53 | }); -------------------------------------------------------------------------------- /website/src/api/frontend/login.js: -------------------------------------------------------------------------------- 1 | import request from "@/js/frontend/request.js"; 2 | 3 | export const loginApi = data => request({ 4 | 'url': '/user/login', 5 | 'method': 'post', 6 | data 7 | }); 8 | 9 | export const sendMsgApi = data => request({ 10 | 'url': '/user/sendMsg', 11 | 'method': 'post', 12 | data 13 | }); 14 | 15 | export const loginoutApi = () => request({ 16 | 'url': '/user/loginout', 17 | 'method': 'post', 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /website/src/api/frontend/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | //获取所有的菜品分类 10 | import request from "@/js/frontend/request.js"; 11 | 12 | export const categoryListApi = () => request({ 13 | 'url': '/category/list', 14 | 'method': 'get', 15 | }); 16 | 17 | //获取菜品分类对应的菜品 18 | export const dishListApi = data => request({ 19 | 'url': '/dish/list', 20 | 'method': 'get', 21 | params: {...data} 22 | }); 23 | 24 | //获取菜品分类对应的套餐 25 | export const setmealListApi = data => request({ 26 | 'url': '/setmeal/list', 27 | 'method': 'get', 28 | params: {...data} 29 | }); 30 | 31 | //获取购物车内商品的集合 32 | export const cartListApi = data => request({ 33 | 'url': '/shoppingCart/list', 34 | //'url': '/front/cartData.json', 35 | 'method': 'get', 36 | params: {...data} 37 | }); 38 | 39 | //购物车中添加商品 40 | export const addCartApi = data => request({ 41 | 'url': '/shoppingCart/add', 42 | 'method': 'post', 43 | data 44 | }); 45 | 46 | //购物车中修改商品 47 | export const updateCartApi = data => request({ 48 | 'url': '/shoppingCart/sub', 49 | 'method': 'post', 50 | data 51 | }); 52 | 53 | //删除购物车的商品 54 | export const clearCartApi = () => request({ 55 | 'url': '/shoppingCart/clean', 56 | 'method': 'delete', 57 | }); 58 | 59 | //获取套餐的全部菜品 60 | export const setMealDishDetailsApi = id => request({ 61 | 'url': `/setmeal/dish/${id}`, 62 | 'method': 'get', 63 | }); 64 | 65 | 66 | -------------------------------------------------------------------------------- /website/src/api/frontend/order.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | //提交订单 10 | import request from "@/js/frontend/request.js"; 11 | 12 | export const addOrderApi = data => request({ 13 | 'url': '/order/submit', 14 | 'method': 'post', 15 | data 16 | }); 17 | 18 | //查询所有订单 19 | export const orderListApi = () => request({ 20 | 'url': '/order/list', 21 | 'method': 'get', 22 | }); 23 | 24 | //分页查询订单 25 | export const orderPagingApi = data => request({ 26 | 'url': '/order/userPage', 27 | 'method': 'get', 28 | params: {...data} 29 | }); 30 | 31 | //再来一单 32 | export const orderAgainApi = data => request({ 33 | 'url': '/order/again', 34 | 'method': 'post', 35 | data 36 | }); -------------------------------------------------------------------------------- /website/src/assets/backend/404-images/404-cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/404-images/404-cloud.png -------------------------------------------------------------------------------- /website/src/assets/backend/404-images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/404-images/404.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/btn_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/btn_back@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/btn_clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/btn_clean@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/btn_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/btn_close@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/icon_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/icon_index.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/icon_upload@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/icon_upload@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/jine_m-2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/jine_m-2@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/renshu@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/renshu@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/icons/xiangmujine@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/icons/xiangmujine@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/img_brand01@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/img_brand01@2x.png -------------------------------------------------------------------------------- /website/src/assets/backend/img_denglu_bj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/img_denglu_bj.jpg -------------------------------------------------------------------------------- /website/src/assets/backend/login/login-l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/login/login-l.png -------------------------------------------------------------------------------- /website/src/assets/backend/login/login-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/login/login-logo.png -------------------------------------------------------------------------------- /website/src/assets/backend/login/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/login/logo.png -------------------------------------------------------------------------------- /website/src/assets/backend/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/logo.png -------------------------------------------------------------------------------- /website/src/assets/backend/noImg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/backend/noImg.png -------------------------------------------------------------------------------- /website/src/assets/fonts/DIN-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/DIN-Bold.otf -------------------------------------------------------------------------------- /website/src/assets/fonts/DIN-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/DIN-Medium.otf -------------------------------------------------------------------------------- /website/src/assets/fonts/PingFangSC-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/PingFangSC-Medium.ttf -------------------------------------------------------------------------------- /website/src/assets/fonts/PingFangSC-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/PingFangSC-Regular.ttf -------------------------------------------------------------------------------- /website/src/assets/fonts/PingFangSC-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/PingFangSC-Semibold.ttf -------------------------------------------------------------------------------- /website/src/assets/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/element-icons.ttf -------------------------------------------------------------------------------- /website/src/assets/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/fonts/element-icons.woff -------------------------------------------------------------------------------- /website/src/assets/frontend/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/add.png -------------------------------------------------------------------------------- /website/src/assets/frontend/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/cart.png -------------------------------------------------------------------------------- /website/src/assets/frontend/cart_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/cart_active.png -------------------------------------------------------------------------------- /website/src/assets/frontend/checked_false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/checked_false.png -------------------------------------------------------------------------------- /website/src/assets/frontend/checked_true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/checked_true.png -------------------------------------------------------------------------------- /website/src/assets/frontend/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/close.png -------------------------------------------------------------------------------- /website/src/assets/frontend/demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/demo1.png -------------------------------------------------------------------------------- /website/src/assets/frontend/demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/demo2.png -------------------------------------------------------------------------------- /website/src/assets/frontend/demo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/demo3.png -------------------------------------------------------------------------------- /website/src/assets/frontend/demo4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/demo4.png -------------------------------------------------------------------------------- /website/src/assets/frontend/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/edit.png -------------------------------------------------------------------------------- /website/src/assets/frontend/favico.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/favico.ico -------------------------------------------------------------------------------- /website/src/assets/frontend/headPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/headPage.png -------------------------------------------------------------------------------- /website/src/assets/frontend/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/home.png -------------------------------------------------------------------------------- /website/src/assets/frontend/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/location.png -------------------------------------------------------------------------------- /website/src/assets/frontend/locations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/locations.png -------------------------------------------------------------------------------- /website/src/assets/frontend/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/logo.png -------------------------------------------------------------------------------- /website/src/assets/frontend/mainBg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/mainBg.png -------------------------------------------------------------------------------- /website/src/assets/frontend/money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/money.png -------------------------------------------------------------------------------- /website/src/assets/frontend/noImg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/noImg.png -------------------------------------------------------------------------------- /website/src/assets/frontend/no_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/no_order.png -------------------------------------------------------------------------------- /website/src/assets/frontend/no_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/no_wifi.png -------------------------------------------------------------------------------- /website/src/assets/frontend/orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/orders.png -------------------------------------------------------------------------------- /website/src/assets/frontend/subtract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/subtract.png -------------------------------------------------------------------------------- /website/src/assets/frontend/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/success.png -------------------------------------------------------------------------------- /website/src/assets/frontend/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/time.png -------------------------------------------------------------------------------- /website/src/assets/frontend/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/user.png -------------------------------------------------------------------------------- /website/src/assets/frontend/women.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/assets/frontend/women.png -------------------------------------------------------------------------------- /website/src/js/backend/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | /* 自定义trim */ 10 | export const trim = str => { //删除左右两端的空格,自定义的trim()方法 11 | return str === undefined ? "" : str.replace(/(^\s*)|(\s*$)/g, "") 12 | }; 13 | 14 | //获取url地址上面的参数 15 | export const requestUrlParam = argname => { 16 | const url = location.href; //获取完整的请求url路径 17 | const arrStr = url.substring(url.indexOf("?") + 1).split("&"); 18 | for (let i = 0; i < arrStr.length; i++) { 19 | const loc = arrStr[i].indexOf(argname + "="); 20 | if (loc !== -1) { 21 | return arrStr[i].replace(argname + "=", "").replace("?", "") 22 | } 23 | } 24 | return "" 25 | }; 26 | -------------------------------------------------------------------------------- /website/src/js/backend/request.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | import axios from "axios"; 10 | 11 | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' 12 | // 创建axios实例 13 | const service = axios.create({ 14 | // axios中请求配置有baseURL选项,表示请求URL公共部分 15 | baseURL: 'http://localhost:8080', 16 | // 超时 17 | timeout: 1000000 18 | }) 19 | // request拦截器 20 | service.interceptors.request.use(config => { 21 | // 是否需要设置 token 22 | // const isToken = (config.headers || {}).isToken === false 23 | // if (getToken() && !isToken) { 24 | // config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 25 | // } 26 | // get请求映射params参数 27 | 28 | if (localStorage.getItem("token")) { 29 | config.headers.token = localStorage.getItem("token") 30 | } 31 | 32 | 33 | if (config.method === 'get' && config.params) { 34 | let url = config.url + '?'; 35 | for (const propName of Object.keys(config.params)) { 36 | const value = config.params[propName]; 37 | let part = encodeURIComponent(propName) + "="; 38 | if (value !== null && typeof (value) !== "undefined") { 39 | if (typeof value === 'object') { 40 | for (const key of Object.keys(value)) { 41 | let params = propName + '[' + key + ']'; 42 | let subPart = encodeURIComponent(params) + "="; 43 | url += subPart + encodeURIComponent(value[key]) + "&"; 44 | } 45 | } else { 46 | url += part + encodeURIComponent(value) + "&"; 47 | } 48 | } 49 | } 50 | url = url.slice(0, -1); 51 | config.params = {}; 52 | config.url = url; 53 | } 54 | return config 55 | }, error => { 56 | console.log(error) 57 | Promise.reject(error).then(ignored => ignored) 58 | }) 59 | 60 | // 响应拦截器 61 | service.interceptors.response.use(res => { 62 | console.log('---响应拦截器---', res) 63 | // 未设置状态码则默认成功状态 64 | const code = res.data.code; 65 | // 获取错误信息 66 | const msg = res.data.msg 67 | console.log('---code---', code) 68 | if (res.data.code === 0 && res.data.msg === 'NOTLOGIN') {// 返回登录页面 69 | console.log('---/backend/login---', code) 70 | localStorage.removeItem('userInfo') 71 | $router.push({path: "/backend/login"}).then(ignored => ignored) 72 | } else { 73 | return res.data 74 | } 75 | }, 76 | error => { 77 | console.log('err' + error) 78 | let {message} = error; 79 | if (message == "Network Error") { 80 | message = "后端接口连接异常"; 81 | } else if (message.includes("timeout")) { 82 | message = "系统接口请求超时"; 83 | } else if (message.includes("Request failed with status code")) { 84 | message = "系统接口" + message.substr(message.length - 3) + "异常"; 85 | } 86 | 87 | $message({ 88 | message: message, 89 | type: 'error', 90 | duration: 5 * 1000 91 | }) 92 | return Promise.reject(error) 93 | } 94 | ) 95 | 96 | export default service -------------------------------------------------------------------------------- /website/src/js/backend/validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | export const isValidUsername = str => ['admin', 'editor'].indexOf(str.trim()) >= 0; 10 | 11 | export function isExternal(path) { 12 | return /^(https?:|mailto:|tel:)/.test(path); 13 | } 14 | 15 | export const isCellPhone = val => { 16 | if (!/^1(3|4|5|6|7|8)\d{9}$/.test(val)) { 17 | return false 18 | } else { 19 | return true 20 | } 21 | }; 22 | 23 | //校验账号 24 | export const checkUserName = (rule, value, callback) => { 25 | if (value == "") { 26 | callback(new Error("请输入账号")) 27 | } else if (value.length > 20 || value.length < 3) { 28 | callback(new Error("账号长度应是3-20")) 29 | } else { 30 | callback() 31 | } 32 | }; 33 | 34 | //校验姓名 35 | export const checkName = (rule, value, callback) => { 36 | if (value == "") { 37 | callback(new Error("请输入姓名")) 38 | } else if (value.length > 12) { 39 | callback(new Error("账号长度应是1-12")) 40 | } else { 41 | callback() 42 | } 43 | }; 44 | 45 | export const checkPhone = (rule, value, callback) => { 46 | // let phoneReg = /(^1[3|4|5|6|7|8|9]\d{9}$)|(^09\d{8}$)/; 47 | if (value == "") { 48 | callback(new Error("请输入手机号")) 49 | } else if (!isCellPhone(value)) {//引入methods中封装的检查手机格式的方法 50 | callback(new Error("请输入正确的手机号!")) 51 | } else { 52 | callback() 53 | } 54 | }; 55 | 56 | 57 | export const validID = (rule, value, callback) => { 58 | // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X 59 | let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/ 60 | if (value == '') { 61 | callback(new Error('请输入身份证号码')) 62 | } else if (reg.test(value)) { 63 | callback() 64 | } else { 65 | callback(new Error('身份证号码不正确')) 66 | } 67 | }; -------------------------------------------------------------------------------- /website/src/js/frontend/base.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | export const base = () => { 10 | const docEl = document.documentElement, 11 | resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', 12 | recalc = function () { 13 | var clientWidth = docEl.clientWidth; 14 | if (!clientWidth) return; 15 | if (clientWidth > 750) { 16 | docEl.style.fontSize = '28px'; 17 | } else { 18 | docEl.style.fontSize = (clientWidth / 375) + 'px'; 19 | } 20 | }; 21 | 22 | if (!document.addEventListener) return; 23 | window.addEventListener(resizeEvt, recalc, false); 24 | document.addEventListener('DOMContentLoaded', recalc, false); 25 | } -------------------------------------------------------------------------------- /website/src/js/frontend/common.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | const web_prefix = '/front'; 10 | 11 | export const imgPath = path => 'http://localhost:8080/common/download?name=' + path; 12 | 13 | //将url传参转换为数组 14 | export const parseUrl = url => { 15 | // 找到url中的第一个?号 16 | let parse = url.substring(url.indexOf("?") + 1), 17 | params = parse.split("&"), 18 | len = params.length, 19 | item = [], 20 | param = {}; 21 | 22 | for (let i = 0; i < len; i++) { 23 | item = params[i].split("="); 24 | param[item[0]] = item[1]; 25 | } 26 | 27 | return param; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /website/src/js/frontend/request.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | import axios from "axios"; 10 | 11 | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' 12 | // 创建axios实例 13 | const service = axios.create({ 14 | // axios中请求配置有baseURL选项,表示请求URL公共部分 15 | baseURL: 'http://localhost:8080', 16 | // 超时 17 | timeout: 1000000 18 | }) 19 | // request拦截器 20 | service.interceptors.request.use(config => { 21 | // 是否需要设置 token 22 | // const isToken = (config.headers || {}).isToken === false 23 | // if (getToken() && !isToken) { 24 | // config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 25 | // } 26 | // get请求映射params参数 27 | 28 | if (localStorage.getItem("token")) { 29 | config.headers.token = localStorage.getItem("token") 30 | } 31 | if (config.method === 'get' && config.params) { 32 | let url = config.url + '?'; 33 | for (const propName of Object.keys(config.params)) { 34 | const value = config.params[propName]; 35 | const part = encodeURIComponent(propName) + "="; 36 | if (value !== null && typeof (value) !== "undefined") { 37 | if (typeof value === 'object') { 38 | for (const key of Object.keys(value)) { 39 | let params = propName + '[' + key + ']'; 40 | const subPart = encodeURIComponent(params) + "="; 41 | url += subPart + encodeURIComponent(value[key]) + "&"; 42 | } 43 | } else { 44 | url += part + encodeURIComponent(value) + "&"; 45 | } 46 | } 47 | } 48 | url = url.slice(0, -1); 49 | config.params = {}; 50 | config.url = url; 51 | } 52 | return config 53 | }, error => { 54 | Promise.reject(error).then(ignored => ignored) 55 | }) 56 | 57 | // 响应拦截器 58 | service.interceptors.response.use(res => { 59 | console.log('---响应拦截器---', res) 60 | if (res.data.code === 0 && res.data.msg === 'NOTLOGIN') {// 返回登录页面 61 | $router.push({path: "/backend/login"}).then(ignored => ignored) 62 | } else { 63 | return res.data 64 | } 65 | }, 66 | error => { 67 | let {message} = error; 68 | if (message === "Network Error") { 69 | message = "后端接口连接异常"; 70 | } else if (message.includes("timeout")) { 71 | message = "系统接口请求超时"; 72 | } else if (message.includes("Request failed with status code")) { 73 | message = "系统接口" + message.substr(message.length - 3) + "异常"; 74 | } 75 | $notify({ 76 | message: message, 77 | type: 'warning', 78 | duration: 5 * 1000 79 | }) 80 | //window.top.location.href = '/front/page/no-wify.html' 81 | return Promise.reject(error) 82 | } 83 | ) 84 | export default service -------------------------------------------------------------------------------- /website/src/layouts/backend/Backend.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 119 | 120 | 171 | 172 | -------------------------------------------------------------------------------- /website/src/layouts/frontend/Frontend.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /website/src/main.js: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue' 2 | import App from '@/App.vue' 3 | import router from "@/router/index.js" 4 | import ElementPlus from 'element-plus' 5 | import 'element-plus/dist/index.css' 6 | import 'vant/lib/index.css'; 7 | 8 | createApp(App).use(router).use(ElementPlus).mount('#app') 9 | -------------------------------------------------------------------------------- /website/src/pages/backend/Login.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 65 | 66 | 96 | 97 | -------------------------------------------------------------------------------- /website/src/pages/backend/member/List.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 93 | 94 | 135 | 136 | -------------------------------------------------------------------------------- /website/src/pages/frontend/Address.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 111 | 112 | 144 | 145 | -------------------------------------------------------------------------------- /website/src/pages/frontend/AddressEdit.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 99 | 100 | 140 | 141 | -------------------------------------------------------------------------------- /website/src/pages/frontend/Login.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 58 | 59 | 75 | 76 | -------------------------------------------------------------------------------- /website/src/pages/frontend/NoNetwork.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 27 | 28 | 42 | 43 | -------------------------------------------------------------------------------- /website/src/pages/frontend/Order.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 106 | 107 | 150 | 151 | -------------------------------------------------------------------------------- /website/src/pages/frontend/PaySuccess.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 51 | 52 | 70 | 71 | -------------------------------------------------------------------------------- /website/src/pages/frontend/User.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 119 | 120 | 175 | 176 | -------------------------------------------------------------------------------- /website/src/router/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Enaium 3 | * 4 | * This work is free. You can redistribute it and/or modify it under the 5 | * terms of the Do What The Fuck You Want To Public License, Version 2, 6 | * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. 7 | */ 8 | 9 | import {createRouter, createWebHistory} from "vue-router"; 10 | import Backend from "@/layouts/backend/Backend.vue"; 11 | import MemberList from "@/pages/backend/member/List.vue" 12 | import MemberAdd from "@/pages/backend/member/Add.vue" 13 | import CategoryList from "@/pages/backend/category/List.vue" 14 | import FoodList from "@/pages/backend/food/List.vue" 15 | import FoodAdd from "@/pages/backend/food/Add.vue" 16 | import ComboList from "@/pages/backend/combo/List.vue" 17 | import ComboAdd from "@/pages/backend/combo/Add.vue" 18 | import OrderList from "@/pages/backend/order/List.vue" 19 | import BackendLogin from "@/pages/backend/Login.vue"; 20 | import Frontend from "@/layouts/frontend/Frontend.vue"; 21 | import Home from "@/pages/frontend/Home.vue"; 22 | import Login from "@/pages/frontend/Login.vue"; 23 | import AddOrder from "@/pages/frontend/AddOrder.vue"; 24 | import User from "@/pages/frontend/User.vue"; 25 | import Address from "@/pages/frontend/Address.vue"; 26 | import AddressEdit from "@/pages/frontend/AddressEdit.vue"; 27 | import Order from "@/pages/frontend/Order.vue"; 28 | import NoNetwork from "@/pages/frontend/NoNetwork.vue"; 29 | import PaySuccess from "@/pages/frontend/PaySuccess.vue"; 30 | 31 | export default createRouter({ 32 | history: createWebHistory(), 33 | routes: [ 34 | { 35 | path: "/frontend", 36 | name: "frontend", 37 | component: Frontend, 38 | children: [ 39 | { 40 | path: "", 41 | name: "home", 42 | component: Home 43 | }, 44 | { 45 | path: "login", 46 | name: "login", 47 | component: Login 48 | }, 49 | { 50 | path: "user", 51 | name: "user", 52 | component: User 53 | }, 54 | { 55 | path: "address", 56 | name: "address", 57 | component: Address 58 | }, 59 | { 60 | path: "address-edit", 61 | name: "address-edit", 62 | component: AddressEdit 63 | }, 64 | { 65 | path: "order", 66 | name: "order", 67 | component: Order 68 | }, 69 | { 70 | path: "add-order", 71 | name: "add-order", 72 | component: AddOrder 73 | }, 74 | { 75 | path: "no-network", 76 | name: "no-network", 77 | component: NoNetwork 78 | }, 79 | { 80 | path: "pay-success", 81 | name: "pay-success", 82 | component: PaySuccess 83 | }, 84 | ] 85 | }, 86 | { 87 | path: "/backend", 88 | name: "backend", 89 | component: Backend, 90 | redirect: "/backend/member/list", 91 | children: [ 92 | { 93 | path: "member/list", 94 | name: "backend-member-list", 95 | component: MemberList 96 | }, 97 | { 98 | path: "member/add", 99 | name: "backend-member-add", 100 | component: MemberAdd 101 | }, 102 | { 103 | path: "category/list", 104 | name: "backend-category-list", 105 | component: CategoryList 106 | }, 107 | { 108 | path: "food/list", 109 | name: "backend-food-list", 110 | component: FoodList 111 | }, 112 | { 113 | path: "food/add", 114 | name: "backend-food-add", 115 | component: FoodAdd 116 | }, 117 | { 118 | path: "combo/list", 119 | name: "backend-combo-list", 120 | component: ComboList 121 | }, 122 | { 123 | path: "combo/add", 124 | name: "backend-combo-add", 125 | component: ComboAdd 126 | }, 127 | { 128 | path: "order/list", 129 | name: "backend-order-list", 130 | component: OrderList 131 | } 132 | ] 133 | }, 134 | { 135 | path: "/backend/login", 136 | name: "backend-login", 137 | component: BackendLogin, 138 | } 139 | ] 140 | }) -------------------------------------------------------------------------------- /website/src/styles/backend/icon/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; /* Project id 2552591 */ 3 | src: url('iconfont.woff2?t=1621231825060') format('woff2'), 4 | url('iconfont.woff?t=1621231825060') format('woff'), 5 | url('iconfont.ttf?t=1621231825060') format('truetype'); 6 | } 7 | 8 | .iconfont { 9 | font-family: "iconfont" !important; 10 | font-size: 16px; 11 | font-style: normal; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | .icon-category:before { 17 | content: "\e606"; 18 | } 19 | 20 | .icon-member:before { 21 | content: "\e607"; 22 | } 23 | 24 | .icon-user:before { 25 | content: "\e608"; 26 | } 27 | 28 | .icon-order:before { 29 | content: "\e609"; 30 | } 31 | 32 | .icon-combo:before { 33 | content: "\e60a"; 34 | } 35 | 36 | .icon-lock:before { 37 | content: "\e60b"; 38 | } 39 | 40 | .icon-food:before { 41 | content: "\e60c"; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /website/src/styles/backend/icon/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2552591", 3 | "name": "rjwm", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "21641541", 10 | "name": "category", 11 | "font_class": "category", 12 | "unicode": "e606", 13 | "unicode_decimal": 58886 14 | }, 15 | { 16 | "icon_id": "21641542", 17 | "name": "member", 18 | "font_class": "member", 19 | "unicode": "e607", 20 | "unicode_decimal": 58887 21 | }, 22 | { 23 | "icon_id": "21641545", 24 | "name": "user", 25 | "font_class": "user", 26 | "unicode": "e608", 27 | "unicode_decimal": 58888 28 | }, 29 | { 30 | "icon_id": "21641546", 31 | "name": "order", 32 | "font_class": "order", 33 | "unicode": "e609", 34 | "unicode_decimal": 58889 35 | }, 36 | { 37 | "icon_id": "21641547", 38 | "name": "combo", 39 | "font_class": "combo", 40 | "unicode": "e60a", 41 | "unicode_decimal": 58890 42 | }, 43 | { 44 | "icon_id": "21641548", 45 | "name": "lock", 46 | "font_class": "lock", 47 | "unicode": "e60b", 48 | "unicode_decimal": 58891 49 | }, 50 | { 51 | "icon_id": "21641611", 52 | "name": "food", 53 | "font_class": "food", 54 | "unicode": "e60c", 55 | "unicode_decimal": 58892 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /website/src/styles/backend/icon/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/styles/backend/icon/iconfont.ttf -------------------------------------------------------------------------------- /website/src/styles/backend/icon/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/styles/backend/icon/iconfont.woff -------------------------------------------------------------------------------- /website/src/styles/backend/icon/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/practice-reggie-takeout/1e0256edf879be97381c1dbb8684aacf7c863c13/website/src/styles/backend/icon/iconfont.woff2 -------------------------------------------------------------------------------- /website/src/styles/backend/login.css: -------------------------------------------------------------------------------- 1 | .login { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | height: 100%; 6 | background-color: #333; 7 | } 8 | 9 | .login-box { 10 | width: 1000px; 11 | height: 474.38px; 12 | border-radius: 8px; 13 | display: flex; 14 | } 15 | 16 | .login-box img { 17 | width: 60%; 18 | height: auto; 19 | } 20 | 21 | .title { 22 | margin: 0px auto 30px auto; 23 | text-align: center; 24 | color: #707070; 25 | } 26 | 27 | .login-form { 28 | background: #ffffff; 29 | width: 40%; 30 | border-radius: 0px 8px 8px 0px; 31 | display: flex; 32 | justify-content: center; 33 | align-items: center; 34 | } 35 | 36 | .login-form .el-form { 37 | width: 214px; 38 | height: 307px; 39 | } 40 | 41 | .login-form .el-form-item { 42 | margin-bottom: 30px; 43 | } 44 | 45 | .login-form .el-form-item.is-error .el-input__inner { 46 | border: 0 !important; 47 | border-bottom: 1px solid #fd7065 !important; 48 | background: #fff !important; 49 | } 50 | 51 | .login-form .input-icon { 52 | height: 32px; 53 | width: 18px; 54 | margin-left: -2px; 55 | } 56 | 57 | .login-form .el-input__inner { 58 | border: 0; 59 | border-bottom: 1px solid #e9e9e8; 60 | border-radius: 0; 61 | font-size: 14px; 62 | font-weight: 400; 63 | color: #333333; 64 | height: 32px; 65 | line-height: 32px; 66 | } 67 | 68 | .login-form .el-input__prefix { 69 | left: 0; 70 | } 71 | 72 | .login-form .el-input--prefix .el-input__inner { 73 | padding-left: 26px; 74 | } 75 | 76 | .login-form .el-input__inner::placeholder { 77 | color: #aeb5c4; 78 | } 79 | 80 | .login-form .el-form-item--medium .el-form-item__content { 81 | line-height: 32px; 82 | } 83 | 84 | .login-form .el-input--medium .el-input__icon { 85 | line-height: 32px; 86 | } 87 | 88 | .login-btn { 89 | border-radius: 17px; 90 | padding: 11px 20px !important; 91 | margin-top: 10px; 92 | font-weight: 500; 93 | font-size: 14px; 94 | border: 0; 95 | background-color: #ffc200; 96 | } 97 | 98 | .login-btn:hover, 99 | .login-btn:focus { 100 | /* background: #FFC200; */ 101 | /* color: #ffffff; */ 102 | } 103 | 104 | .login-form-title { 105 | height: 36px; 106 | display: flex; 107 | justify-content: center; 108 | align-items: center; 109 | margin-bottom: 40px; 110 | } 111 | 112 | .login-form-title .title-label { 113 | font-weight: 500; 114 | font-size: 20px; 115 | color: #333333; 116 | margin-left: 10px; 117 | } 118 | -------------------------------------------------------------------------------- /website/src/styles/backend/page.css: -------------------------------------------------------------------------------- 1 | .dashboard-container { 2 | padding: 20px; 3 | } 4 | 5 | .dashboard-container .container { 6 | background: #fff; 7 | position: relative; 8 | z-index: 1; 9 | padding: 30px 28px; 10 | border-radius: 4px; 11 | } 12 | 13 | .dashboard-container .container .tableBar { 14 | display: flex; 15 | margin-bottom: 20px; 16 | justify-content: space-between; 17 | } 18 | 19 | .dashboard-container .container .tableBox { 20 | width: 100%; 21 | border: solid 2px #f3f4f7; 22 | border-radius: 2px; 23 | } 24 | 25 | .dashboard-container .container .tableBox .el-image img { 26 | width: 40px; 27 | border-radius: 5px; 28 | } 29 | 30 | .dashboard-container .container .pageList { 31 | text-align: center; 32 | margin-top: 30px; 33 | } 34 | 35 | .dashboard-container .container .tableLab .span-btn { 36 | cursor: pointer; 37 | display: inline-block; 38 | font-size: 14px; 39 | padding: 0 20px; 40 | color: #818693; 41 | border-right: solid 1px #d8dde3; 42 | } 43 | 44 | .dashboard-container .container .tableLab .el-button { 45 | margin-left: 10px; 46 | } 47 | 48 | .el-table-column--selection .cell { 49 | padding-left: 10px; 50 | } 51 | 52 | /* 添加 */ 53 | .addBrand-container .avatar-uploader .el-upload { 54 | border: 1px dashed #d9d9d9; 55 | border-radius: 6px; 56 | cursor: pointer; 57 | position: relative; 58 | overflow: hidden; 59 | } 60 | 61 | .addBrand-container .avatar-uploader .el-upload:hover { 62 | border-color: #409eff; 63 | } 64 | 65 | .addBrand-container .avatar-uploader-icon { 66 | font-size: 28px; 67 | color: #8c939d; 68 | width: 200px; 69 | height: 160px; 70 | line-height: 160px; 71 | text-align: center; 72 | } 73 | 74 | .addBrand-container .avatar { 75 | width: 160px; 76 | height: 160px; 77 | display: block; 78 | } 79 | 80 | .addBrand-container .el-form--inline .el-form-item__content { 81 | width: 293px; 82 | } 83 | 84 | .addBrand-container .el-input { 85 | width: 293px; 86 | } 87 | 88 | .addBrand-container { 89 | margin: 30px; 90 | } 91 | 92 | .addBrand-container .container { 93 | position: relative; 94 | z-index: 1; 95 | background: #fff; 96 | padding: 30px; 97 | border-radius: 4px; 98 | min-height: 500px; 99 | } 100 | 101 | .addBrand-container .container .subBox { 102 | padding-top: 30px; 103 | text-align: center; 104 | border-top: solid 1px #f3f4f7; 105 | } 106 | 107 | .flavorBox { 108 | width: 777px; 109 | } 110 | 111 | .flavorBox .addBut { 112 | background: #ffc200; 113 | display: inline-block; 114 | padding: 0px 20px; 115 | border-radius: 3px; 116 | line-height: 40px; 117 | cursor: pointer; 118 | border-radius: 4px; 119 | color: #333333; 120 | font-weight: 500; 121 | } 122 | 123 | .flavorBox .flavor { 124 | border: solid 1px #dfe2e8; 125 | border-radius: 3px; 126 | padding: 15px; 127 | background: #fafafb; 128 | } 129 | 130 | .flavorBox .flavor .title { 131 | color: #606168; 132 | } 133 | 134 | .flavorBox .flavor .cont .items { 135 | display: flex; 136 | margin: 10px 0; 137 | } 138 | 139 | .flavorBox .flavor .cont .items .itTit { 140 | width: 150px; 141 | margin-right: 15px; 142 | } 143 | 144 | .flavorBox .flavor .cont .items .itTit input { 145 | width: 100%; 146 | line-height: 40px; 147 | border-radius: 3px; 148 | padding: 0 10px; 149 | } 150 | 151 | .flavorBox .flavor .cont .items .labItems { 152 | flex: 1; 153 | display: flex; 154 | flex-wrap: wrap; 155 | border-radius: 3px; 156 | min-height: 39px; 157 | border: solid 1px #d8dde3; 158 | background: #fff; 159 | padding: 0 5px; 160 | } 161 | 162 | .flavorBox .flavor .cont .items .labItems span { 163 | display: inline-block; 164 | color: #f19c59; 165 | margin: 5px; 166 | line-height: 26px; 167 | height: 26px; 168 | padding: 0 10px; 169 | background: #fdf4eb; 170 | border-radius: 3px; 171 | border: solid 1px #fae2cd; 172 | } 173 | 174 | .flavorBox .flavor .cont .items .labItems span i { 175 | cursor: pointer; 176 | font-style: normal; 177 | } 178 | 179 | .flavorBox .flavor .cont .items .labItems .inputBox { 180 | display: inline-block; 181 | width: 100%; 182 | height: 36px; 183 | line-height: 36px; 184 | overflow: hidden; 185 | } 186 | 187 | .flavorBox .flavor .cont .items .delFlavor { 188 | display: inline-block; 189 | padding: 0 10px; 190 | color: #f19c59; 191 | cursor: pointer; 192 | } 193 | 194 | .addBrand-container .address .el-form-item__content { 195 | width: 777px !important; 196 | } 197 | 198 | .el-button--text { 199 | font-weight: 400 !important; 200 | font-size: 13px !important; 201 | } 202 | 203 | .el-table td { 204 | font-size: 13px !important; 205 | } 206 | 207 | .el-table .cell, 208 | .el-table th div, 209 | .el-table--border td:first-child .cell, 210 | .el-table--border th:first-child .cell { 211 | padding-left: 12px; 212 | } 213 | -------------------------------------------------------------------------------- /website/src/styles/frontend/address-edit.css: -------------------------------------------------------------------------------- 1 | #address_edit { 2 | height: 100%; 3 | } 4 | 5 | #address_edit .divHead { 6 | width: 100%; 7 | height: 88rem; 8 | opacity: 1; 9 | background: #333333; 10 | position: relative; 11 | } 12 | 13 | #address_edit .divHead .divTitle { 14 | font-size: 18rem; 15 | font-family: PingFangSC, PingFangSC-Regular; 16 | font-weight: 500; 17 | text-align: center; 18 | color: #ffffff; 19 | line-height: 25rem; 20 | letter-spacing: 0; 21 | position: absolute; 22 | bottom: 13rem; 23 | width: 100%; 24 | } 25 | 26 | #address_edit .divHead .divTitle i { 27 | position: absolute; 28 | left: 16rem; 29 | top: 50%; 30 | transform: translate(0, -50%); 31 | } 32 | 33 | #address_edit .divContent { 34 | height: 100%; 35 | opacity: 1; 36 | background: #ffffff; 37 | padding-left: 9rem; 38 | padding-right: 9rem; 39 | } 40 | 41 | #address_edit .divContent .divItem { 42 | height: 55rem; 43 | line-height: 55rem; 44 | font-size: 14rem; 45 | font-family: PingFangSC, PingFangSC-Regular; 46 | font-weight: 500; 47 | text-align: left; 48 | color: #333333; 49 | line-height: 20rem; 50 | letter-spacing: 0rem; 51 | border-bottom: 1px solid #efefef; 52 | display: flex; 53 | align-items: center; 54 | } 55 | 56 | #address_edit .divContent .divItem .el-input { 57 | width: auto; 58 | } 59 | 60 | #address_edit .divContent .divItem input { 61 | border: 0; 62 | padding: 0; 63 | } 64 | 65 | #address_edit .divContent .divItem .inputUser { 66 | width: 150rem; 67 | } 68 | 69 | #address_edit .divContent .divItem span { 70 | display: block; 71 | } 72 | 73 | #address_edit .divContent .divItem span:first-child { 74 | margin-right: 12rem; 75 | white-space: nowrap; 76 | width: 69rem; 77 | } 78 | 79 | #address_edit .divContent .divItem .spanChecked { 80 | width: 50rem; 81 | } 82 | 83 | #address_edit .divContent .divItem span i { 84 | width: 16rem; 85 | height: 16rem; 86 | background: url(./../images/checked_false.png); 87 | display: inline-block; 88 | background-size: cover; 89 | vertical-align: sub; 90 | } 91 | 92 | #address_edit .divContent .divItem span .iActive { 93 | background: url(./../images/checked_true.png); 94 | background-size: cover; 95 | } 96 | 97 | #address_edit .divContent .divItem .spanItem { 98 | width: 34rem; 99 | height: 20rem; 100 | opacity: 1; 101 | border: 1px solid #e5e4e4; 102 | border-radius: 3rem; 103 | text-align: center; 104 | margin-right: 10rem; 105 | border-radius: 2px; 106 | font-family: PingFangSC, PingFangSC-Regular; 107 | font-weight: 400; 108 | color: #333333; 109 | } 110 | 111 | #address_edit .divContent .divItem .spanActiveCompany { 112 | background: #e1f1fe; 113 | } 114 | 115 | #address_edit .divContent .divItem .spanActiveHome { 116 | background: #fef8e7; 117 | } 118 | 119 | #address_edit .divContent .divItem .spanActiveSchool { 120 | background: #e7fef8; 121 | } 122 | 123 | #address_edit .divContent .divItem .el-input__inner { 124 | font-size: 13px; 125 | font-family: PingFangSC, PingFangSC-Regular; 126 | font-weight: 400; 127 | text-align: left; 128 | color: #333333; 129 | } 130 | 131 | #address_edit .divContent .divSave { 132 | height: 36rem; 133 | opacity: 1; 134 | background: #ffc200; 135 | border-radius: 18rem; 136 | font-size: 15rem; 137 | font-family: PingFangSC, PingFangSC-Regular; 138 | font-weight: 500; 139 | text-align: center; 140 | color: #333333; 141 | line-height: 36rem; 142 | margin-top: 20rem; 143 | } 144 | 145 | #address_edit .divContent .divDelete { 146 | height: 36rem; 147 | opacity: 1; 148 | background: #f6f6f6; 149 | border-radius: 18rem; 150 | font-size: 15rem; 151 | font-family: PingFangSC, PingFangSC-Regular; 152 | font-weight: 500; 153 | text-align: center; 154 | color: #333333; 155 | line-height: 36rem; 156 | margin-top: 20rem; 157 | } 158 | -------------------------------------------------------------------------------- /website/src/styles/frontend/address.css: -------------------------------------------------------------------------------- 1 | #address .divHead { 2 | width: 100%; 3 | height: 88rem; 4 | opacity: 1; 5 | background: #333333; 6 | position: relative; 7 | } 8 | 9 | #address .divHead .divTitle { 10 | font-size: 18rem; 11 | font-family: PingFangSC, PingFangSC-Regular; 12 | font-weight: 500; 13 | text-align: center; 14 | color: #ffffff; 15 | line-height: 25rem; 16 | letter-spacing: 0; 17 | position: absolute; 18 | bottom: 13rem; 19 | width: 100%; 20 | } 21 | 22 | #address .divHead .divTitle i { 23 | position: absolute; 24 | left: 16rem; 25 | top: 50%; 26 | transform: translate(0, -50%); 27 | } 28 | 29 | #address .divContent { 30 | height: calc(100vh - 157rem); 31 | overflow: auto; 32 | } 33 | 34 | #address .divContent .divItem { 35 | height: 128rem; 36 | opacity: 1; 37 | background: #ffffff; 38 | border-radius: 6rem; 39 | margin-top: 10rem; 40 | margin-left: 10rem; 41 | margin-right: 9rem; 42 | padding-left: 12rem; 43 | position: relative; 44 | } 45 | 46 | #address .divContent .divItem > img { 47 | width: 16rem; 48 | height: 16rem; 49 | position: absolute; 50 | top: 40rem; 51 | right: 24rem; 52 | } 53 | 54 | #address .divContent .divItem .divDefault img { 55 | width: 16rem; 56 | height: 16rem; 57 | opacity: 1; 58 | } 59 | 60 | #address .divContent .divItem .divAddress { 61 | font-size: 14rem; 62 | font-family: PingFangSC, PingFangSC-Regular; 63 | font-weight: 400; 64 | text-align: left; 65 | color: #333333; 66 | line-height: 20rem; 67 | letter-spacing: 0; 68 | padding-top: 21rem; 69 | overflow: hidden; 70 | text-overflow: ellipsis; 71 | white-space: nowrap; 72 | width: 280rem; 73 | } 74 | 75 | #address .divContent .divItem .divAddress span { 76 | width: 34rem; 77 | height: 20rem; 78 | opacity: 1; 79 | font-size: 12rem; 80 | display: inline-block; 81 | text-align: center; 82 | margin-right: 4rem; 83 | margin-bottom: 10rem; 84 | } 85 | 86 | #address .divContent .divItem .divUserPhone span { 87 | height: 20rem; 88 | opacity: 1; 89 | font-size: 14rem; 90 | font-family: PingFangSC, PingFangSC-Regular; 91 | font-weight: 400; 92 | text-align: left; 93 | color: #999999; 94 | line-height: 20rem; 95 | letter-spacing: 0; 96 | margin-right: 10rem; 97 | } 98 | 99 | #address .divContent .divItem .divUserPhone span:first-child { 100 | margin-right: 2rem; 101 | } 102 | 103 | #address .divContent .divItem .divAddress .spanCompany { 104 | background-color: #e1f1fe; 105 | } 106 | 107 | #address .divContent .divItem .divAddress .spanHome { 108 | background: #fef8e7; 109 | } 110 | 111 | #address .divContent .divItem .divAddress .spanSchool { 112 | background: #e7fef8; 113 | } 114 | 115 | #address .divContent .divItem .divSplit { 116 | height: 1px; 117 | opacity: 1; 118 | background: #efefef; 119 | border: 0; 120 | margin-top: 16rem; 121 | margin-bottom: 10rem; 122 | margin-right: 10rem; 123 | } 124 | 125 | #address .divContent .divItem .divDefault { 126 | height: 18rem; 127 | opacity: 1; 128 | font-size: 13rem; 129 | font-family: PingFangSC, PingFangSC-Regular; 130 | font-weight: 400; 131 | text-align: left; 132 | color: #333333; 133 | line-height: 18rem; 134 | letter-spacing: 0; 135 | } 136 | 137 | #address .divContent .divItem .divDefault img { 138 | height: 18rem; 139 | width: 18rem; 140 | margin-right: 5rem; 141 | vertical-align: bottom; 142 | } 143 | 144 | #address .divBottom { 145 | height: 36rem; 146 | opacity: 1; 147 | background: #ffc200; 148 | border-radius: 18rem; 149 | opacity: 1; 150 | font-size: 15rem; 151 | font-family: PingFangSC, PingFangSC-Regular; 152 | font-weight: 500; 153 | text-align: center; 154 | color: #333333; 155 | line-height: 36rem; 156 | letter-spacing: 0; 157 | position: absolute; 158 | bottom: 23rem; 159 | left: 50%; 160 | transform: translate(-50%, 0); 161 | width: 334rem; 162 | } 163 | -------------------------------------------------------------------------------- /website/src/styles/frontend/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | max-width: 750px; 4 | height: 100%; 5 | background: #f3f2f7; 6 | font-family: Helvetica; 7 | overflow: hidden; 8 | } 9 | 10 | html, 11 | body, 12 | h1, 13 | h2, 14 | h3, 15 | h4, 16 | h5, 17 | h6, 18 | p, 19 | ul, 20 | li { 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | ul, 26 | li { 27 | list-style: none; 28 | } 29 | 30 | h1, 31 | h2, 32 | h3, 33 | h4, 34 | h5, 35 | h6 { 36 | font-weight: normal; 37 | } 38 | 39 | h3 { 40 | font-size: 16px; 41 | } 42 | 43 | h4 { 44 | font-size: 14px; 45 | } 46 | 47 | p { 48 | font-size: 12px; 49 | } 50 | 51 | em, 52 | i { 53 | font-style: normal; 54 | } 55 | 56 | @font-face { 57 | font-family: "DIN-Medium"; 58 | src: url("@/assets/fonts/DIN-Medium.otf"); 59 | font-weight: normal; 60 | font-style: normal; 61 | } 62 | 63 | @font-face { 64 | font-family: "DIN"; 65 | src: url("@/assets/fonts/DIN-Bold.otf"); 66 | font-weight: normal; 67 | font-style: normal; 68 | } 69 | 70 | @font-face { 71 | font-family: "PingFangSC-Regular"; 72 | src: url("@/assets/fonts/PingFangSC-Regular.ttf"); 73 | font-weight: normal; 74 | font-style: normal; 75 | } 76 | 77 | @font-face { 78 | font-family: "PingFangSC-Regular"; 79 | src: url("@/assets/fonts/PingFangSC-Regular.ttf"); 80 | font-weight: normal; 81 | font-style: normal; 82 | } 83 | 84 | @font-face { 85 | font-family: "PingFangSC-Semibold"; 86 | src: url("@/assets/fonts/PingFangSC-Semibold.ttf"); 87 | font-weight: normal; 88 | font-style: normal; 89 | } 90 | 91 | .app { 92 | height: 100%; 93 | } 94 | 95 | .van-overlay { 96 | background-color: rgba(0, 0, 0, 0.3); 97 | } 98 | 99 | .van-dialog { 100 | overflow: inherit; 101 | } 102 | 103 | ::-webkit-input-placeholder { 104 | font-size: 13rem; 105 | font-family: PingFangSC, PingFangSC-Regular; 106 | font-weight: 400; 107 | text-align: left; 108 | color: #999999; 109 | } 110 | 111 | :-moz-placeholder { 112 | /* Firefox 18- */ 113 | font-size: 13rem; 114 | font-family: PingFangSC, PingFangSC-Regular; 115 | font-weight: 400; 116 | text-align: left; 117 | color: #999999; 118 | } 119 | 120 | ::-moz-placeholder { 121 | /* Firefox 19+ */ 122 | font-size: 13rem; 123 | font-family: PingFangSC, PingFangSC-Regular; 124 | font-weight: 400; 125 | text-align: left; 126 | color: #999999; 127 | } 128 | 129 | :-ms-input-placeholder { 130 | font-size: 13rem; 131 | font-family: PingFangSC, PingFangSC-Regular; 132 | font-weight: 400; 133 | text-align: left; 134 | color: #999999; 135 | } 136 | -------------------------------------------------------------------------------- /website/src/styles/frontend/login.css: -------------------------------------------------------------------------------- 1 | #login .divHead { 2 | opacity: 1; 3 | background: #333333; 4 | height: 88rem; 5 | width: 100%; 6 | font-size: 18rem; 7 | font-family: PingFangSC, PingFangSC-Regular; 8 | font-weight: 500; 9 | text-align: center; 10 | color: #ffffff; 11 | line-height: 88rem; 12 | } 13 | 14 | #login .divContainer { 15 | width: 356rem; 16 | height: 128rem; 17 | opacity: 1; 18 | background: #ffffff; 19 | border-radius: 6rem; 20 | margin: 0 auto; 21 | margin-top: 10rem; 22 | position: relative; 23 | } 24 | 25 | #login .divContainer input { 26 | border: 0; 27 | height: 63rem; 28 | } 29 | 30 | #login .divContainer .divSplit { 31 | height: 1px; 32 | background-color: #efefef; 33 | border: 0; 34 | margin-left: 10rem; 35 | margin-right: 10rem; 36 | } 37 | 38 | #login .divContainer span { 39 | position: absolute; 40 | right: 20rem; 41 | top: 20rem; 42 | cursor: pointer; 43 | opacity: 1; 44 | font-size: 12rem; 45 | font-family: PingFangSC, PingFangSC-Regular; 46 | font-weight: 400; 47 | text-align: left; 48 | color: #ffc200; 49 | letter-spacing: 0px; 50 | } 51 | 52 | #login .divMsg { 53 | width: 168px; 54 | height: 17px; 55 | opacity: 1; 56 | font-size: 12px; 57 | font-family: PingFangSC, PingFangSC-Regular; 58 | font-weight: 400; 59 | text-align: center; 60 | color: #e94e3c; 61 | line-height: 17px; 62 | margin-left: 26rem; 63 | margin-top: 10rem; 64 | } 65 | 66 | #login .btnSubmit { 67 | width: 356rem; 68 | height: 40rem; 69 | margin: 20rem 10rem 0 10rem; 70 | border-radius: 20px; 71 | border: 0; 72 | 73 | font-size: 15rem; 74 | font-family: PingFangSC, PingFangSC-Regular; 75 | font-weight: 500; 76 | text-align: center; 77 | } 78 | 79 | #login .btnNoPhone { 80 | color: #666666; 81 | background: #d8d8d8; 82 | } 83 | 84 | #login .btnNoPhone:active { 85 | background: #afafaf; 86 | } 87 | 88 | #login .btnPhone { 89 | background: #ffc200; 90 | color: #333333; 91 | } 92 | 93 | #login .btnPhone:active { 94 | background: rgba(255, 142, 0, 1); 95 | color: #333333; 96 | } 97 | -------------------------------------------------------------------------------- /website/src/styles/frontend/no-wify.css: -------------------------------------------------------------------------------- 1 | #no_wifi .divHead { 2 | width: 100%; 3 | height: 88rem; 4 | opacity: 1; 5 | background: #333333; 6 | position: relative; 7 | } 8 | 9 | #no_wifi .divHead .divTitle { 10 | font-size: 18rem; 11 | font-family: PingFangSC, PingFangSC-Regular; 12 | font-weight: 500; 13 | text-align: center; 14 | color: #ffffff; 15 | line-height: 25rem; 16 | letter-spacing: 0; 17 | position: absolute; 18 | bottom: 13rem; 19 | width: 100%; 20 | } 21 | 22 | #no_wifi .divHead .divTitle i { 23 | position: absolute; 24 | left: 16rem; 25 | top: 50%; 26 | transform: translate(0, -50%); 27 | } 28 | 29 | #no_wifi .divContent { 30 | height: calc(100vh - 88rem); 31 | width: 100%; 32 | background: #ffffff; 33 | display: flex; 34 | flex-direction: column; 35 | text-align: center; 36 | align-items: center; 37 | } 38 | 39 | #no_wifi .divContent img { 40 | width: 239rem; 41 | height: 130rem; 42 | margin-top: 104rem; 43 | margin-bottom: 19rem; 44 | } 45 | 46 | #no_wifi .divContent .divDesc { 47 | height: 33rem; 48 | opacity: 1; 49 | font-size: 24rem; 50 | font-family: PingFangSC, PingFangSC-Regular; 51 | font-weight: 500; 52 | text-align: center; 53 | color: #333333; 54 | line-height: 33rem; 55 | letter-spacing: 0; 56 | margin-bottom: 20rem; 57 | } 58 | 59 | #no_wifi .divContent .btnRefresh { 60 | width: 124rem; 61 | height: 36rem; 62 | opacity: 1; 63 | background: #ffc200; 64 | border-radius: 18px; 65 | opacity: 1; 66 | font-size: 15rem; 67 | font-family: PingFangSC, PingFangSC-Regular; 68 | font-weight: 500; 69 | text-align: center; 70 | color: #333333; 71 | line-height: 21rem; 72 | letter-spacing: 0; 73 | line-height: 36rem; 74 | } 75 | -------------------------------------------------------------------------------- /website/src/styles/frontend/order.css: -------------------------------------------------------------------------------- 1 | #order { 2 | height: 100%; 3 | } 4 | 5 | #order .divHead { 6 | width: 100%; 7 | height: 88rem; 8 | opacity: 1; 9 | background: #333333; 10 | position: relative; 11 | } 12 | 13 | #order .divHead .divTitle { 14 | font-size: 18rem; 15 | font-family: PingFangSC, PingFangSC-Regular; 16 | font-weight: 500; 17 | text-align: center; 18 | color: #ffffff; 19 | line-height: 25rem; 20 | letter-spacing: 0; 21 | position: absolute; 22 | bottom: 13rem; 23 | width: 100%; 24 | } 25 | 26 | #order .divHead .divTitle i { 27 | position: absolute; 28 | left: 16rem; 29 | top: 50%; 30 | transform: translate(0, -50%); 31 | } 32 | 33 | #order .divBody { 34 | margin: 10rem 12rem 10rem 12rem; 35 | background: #ffffff; 36 | border-radius: 6rem; 37 | padding-left: 10rem; 38 | padding-right: 10rem; 39 | height: calc(100% - 108rem); 40 | overflow-y: auto; 41 | } 42 | 43 | #order .divBody .van-list .van-cell::after { 44 | border: 0; 45 | } 46 | 47 | #order .divBody .item .timeStatus { 48 | height: 46rem; 49 | line-height: 16rem; 50 | font-size: 14rem; 51 | font-family: PingFangSC, PingFangSC-Regular; 52 | font-weight: 400; 53 | text-align: left; 54 | color: #666666; 55 | line-height: 20rem; 56 | letter-spacing: 0; 57 | display: flex; 58 | justify-content: space-between; 59 | align-items: center; 60 | border-bottom: 2rem dashed #efefef; 61 | border-top: 1px solid #efefef; 62 | } 63 | 64 | #order .divBody .item .timeStatus span:first-child { 65 | color: #333333; 66 | } 67 | 68 | #order .divBody .item .dishList { 69 | padding-top: 10rem; 70 | padding-bottom: 11rem; 71 | } 72 | 73 | #order .divBody .item .dishList .item { 74 | padding-top: 5rem; 75 | padding-bottom: 5rem; 76 | display: flex; 77 | justify-content: space-between; 78 | height: 20rem; 79 | opacity: 1; 80 | font-size: 14rem; 81 | font-family: PingFangSC, PingFangSC-Regular; 82 | font-weight: 400; 83 | text-align: left; 84 | color: #666666; 85 | line-height: 20rem; 86 | letter-spacing: 0; 87 | } 88 | 89 | #order .divBody .item .result { 90 | display: flex; 91 | justify-content: flex-end; 92 | height: 20rem; 93 | opacity: 1; 94 | font-size: 14rem; 95 | font-family: PingFangSC, PingFangSC-Regular; 96 | font-weight: 400; 97 | text-align: left; 98 | color: #666666; 99 | line-height: 20rem; 100 | } 101 | 102 | #order .divBody .item .result .price { 103 | color: #343434; 104 | } 105 | 106 | #order .divBody .item .btn { 107 | display: flex; 108 | justify-content: flex-end; 109 | margin-bottom: 17rem; 110 | margin-top: 20rem; 111 | } 112 | 113 | #order .divBody .btn .btnAgain { 114 | width: 124rem; 115 | height: 36rem; 116 | opacity: 1; 117 | border: 1px solid #e5e4e4; 118 | border-radius: 19rem; 119 | opacity: 1; 120 | font-size: 14rem; 121 | font-family: PingFangSC, PingFangSC-Regular; 122 | font-weight: 500; 123 | text-align: center; 124 | color: #333333; 125 | line-height: 36rem; 126 | letter-spacing: 0; 127 | position: relative; 128 | } 129 | 130 | #order .divNoData { 131 | width: 100%; 132 | height: calc(100% - 88rem); 133 | display: flex; 134 | flex-direction: column; 135 | align-items: center; 136 | justify-content: center; 137 | } 138 | 139 | #order .divNoData .divContainer img { 140 | width: 240rem; 141 | height: 129rem; 142 | } 143 | 144 | #order .divNoData .divContainer div { 145 | font-size: 24rem; 146 | font-family: PingFangSC, PingFangSC-Medium; 147 | font-weight: 500; 148 | text-align: center; 149 | color: #333333; 150 | line-height: 33rem; 151 | height: 33rem; 152 | margin-top: 20rem; 153 | } 154 | -------------------------------------------------------------------------------- /website/src/styles/frontend/pay-success.css: -------------------------------------------------------------------------------- 1 | #pay_success .divHead { 2 | width: 100%; 3 | height: 88rem; 4 | opacity: 1; 5 | background: #333333; 6 | position: relative; 7 | } 8 | 9 | #pay_success .divHead .divTitle { 10 | font-size: 18rem; 11 | font-family: PingFangSC, PingFangSC-Regular; 12 | font-weight: 500; 13 | text-align: center; 14 | color: #ffffff; 15 | line-height: 25rem; 16 | letter-spacing: 0; 17 | position: absolute; 18 | bottom: 13rem; 19 | width: 100%; 20 | display: flex; 21 | justify-content: space-between; 22 | align-items: center; 23 | } 24 | 25 | #pay_success .divHead .divTitle i { 26 | margin-left: 16rem; 27 | } 28 | 29 | #pay_success .divHead .divTitle img { 30 | width: 18rem; 31 | height: 18rem; 32 | margin-right: 19rem; 33 | } 34 | 35 | #pay_success .divContent { 36 | height: calc(100vh - 88rem); 37 | width: 100%; 38 | background: #ffffff; 39 | display: flex; 40 | flex-direction: column; 41 | text-align: center; 42 | align-items: center; 43 | } 44 | 45 | #pay_success .divContent img { 46 | margin-top: 148rem; 47 | margin-bottom: 19rem; 48 | width: 90rem; 49 | height: 86rem; 50 | } 51 | 52 | #pay_success .divContent .divSuccess { 53 | height: 33rem; 54 | opacity: 1; 55 | font-size: 24rem; 56 | font-family: PingFangSC, PingFangSC-Regular; 57 | font-weight: 500; 58 | text-align: center; 59 | color: #333333; 60 | line-height: 33rem; 61 | margin-top: 19rem; 62 | margin-bottom: 10rem; 63 | } 64 | 65 | #pay_success .divContent .divDesc, 66 | .divDesc1 { 67 | height: 22rem; 68 | opacity: 1; 69 | font-size: 16rem; 70 | font-family: PingFangSC, PingFangSC-Regular; 71 | font-weight: 400; 72 | text-align: center; 73 | color: #666666; 74 | line-height: 22rem; 75 | } 76 | 77 | #pay_success .divContent .divDesc1 { 78 | margin-top: 7rem; 79 | margin-bottom: 20rem; 80 | } 81 | 82 | #pay_success .divContent .btnView { 83 | width: 124rem; 84 | height: 36rem; 85 | opacity: 1; 86 | background: #ffc200; 87 | border-radius: 18px; 88 | opacity: 1; 89 | font-size: 15rem; 90 | font-family: PingFangSC, PingFangSC-Regular; 91 | font-weight: 500; 92 | text-align: center; 93 | color: #333333; 94 | line-height: 21rem; 95 | letter-spacing: 0; 96 | line-height: 36rem; 97 | } 98 | -------------------------------------------------------------------------------- /website/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import path from 'path' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve: { 9 | alias: { 10 | '@': path.resolve(__dirname, 'src'), 11 | } 12 | } 13 | }) 14 | --------------------------------------------------------------------------------