diff --git a/doc/03-05-“饮食规划”-段学强.docx b/doc/03-05-“饮食规划”-段学强.docx new file mode 100644 index 0000000..ed8c17f Binary files /dev/null and b/doc/03-05-“饮食规划”-段学强.docx differ diff --git a/doc/03_软件需求规格说明书.docx b/doc/03_软件需求规格说明书.docx new file mode 100644 index 0000000..3876b70 Binary files /dev/null and b/doc/03_软件需求规格说明书.docx differ diff --git a/doc/04_软件设计规格说明书.docx b/doc/04_软件设计规格说明书.docx new file mode 100644 index 0000000..957cc0d Binary files /dev/null and b/doc/04_软件设计规格说明书.docx differ diff --git a/doc/设计模型_饮食规划_段学强(v2.0).docx b/doc/设计模型_饮食规划_段学强(v2.0).docx new file mode 100644 index 0000000..13dd432 Binary files /dev/null and b/doc/设计模型_饮食规划_段学强(v2.0).docx differ diff --git a/doc/设计模型_饮食规划_段学强.docx b/doc/设计模型_饮食规划_段学强.docx new file mode 100644 index 0000000..fbb174c Binary files /dev/null and b/doc/设计模型_饮食规划_段学强.docx differ diff --git a/doc/需求模型_饮食规划_段学强(v2.0).doc b/doc/需求模型_饮食规划_段学强(v2.0).doc new file mode 100644 index 0000000..d902ddd Binary files /dev/null and b/doc/需求模型_饮食规划_段学强(v2.0).doc differ diff --git a/doc/需求模型_饮食规划_段学强(修改后).doc b/doc/需求模型_饮食规划_段学强(修改后).doc new file mode 100644 index 0000000..1025573 Binary files /dev/null and b/doc/需求模型_饮食规划_段学强(修改后).doc differ diff --git a/doc/需求模型_饮食规划_段学强.docx b/doc/需求模型_饮食规划_段学强.docx new file mode 100644 index 0000000..3762be6 Binary files /dev/null and b/doc/需求模型_饮食规划_段学强.docx differ diff --git a/1.txt b/model/2.txt similarity index 100% rename from 1.txt rename to model/2.txt diff --git a/other/05_开发软件系统实践的汇报.pptx b/other/05_开发软件系统实践的汇报.pptx new file mode 100644 index 0000000..d991587 Binary files /dev/null and b/other/05_开发软件系统实践的汇报.pptx differ diff --git a/other/06_软件开发项目的个人自评报告.xlsx b/other/06_软件开发项目的个人自评报告.xlsx new file mode 100644 index 0000000..e024806 Binary files /dev/null and b/other/06_软件开发项目的个人自评报告.xlsx differ diff --git a/other/07_软件开发项目的团队自评报告.xlsx b/other/07_软件开发项目的团队自评报告.xlsx new file mode 100644 index 0000000..c196ee0 Binary files /dev/null and b/other/07_软件开发项目的团队自评报告.xlsx differ diff --git a/other/08_210340096董志尚-实践总结报告.docx b/other/08_210340096董志尚-实践总结报告.docx new file mode 100644 index 0000000..d219c47 Binary files /dev/null and b/other/08_210340096董志尚-实践总结报告.docx differ diff --git a/other/08_210340097段学强-实践总结报告.docx b/other/08_210340097段学强-实践总结报告.docx new file mode 100644 index 0000000..26a0abd Binary files /dev/null and b/other/08_210340097段学强-实践总结报告.docx differ diff --git a/other/08_210340099何昀臻_实践总结报告.docx b/other/08_210340099何昀臻_实践总结报告.docx new file mode 100644 index 0000000..b2c7696 Binary files /dev/null and b/other/08_210340099何昀臻_实践总结报告.docx differ diff --git a/other/08_210340123王秋林-实践总结报告.docx b/other/08_210340123王秋林-实践总结报告.docx new file mode 100644 index 0000000..53dc779 Binary files /dev/null and b/other/08_210340123王秋林-实践总结报告.docx differ diff --git a/other/08_210340124王仕豪-实践总结报告.docx b/other/08_210340124王仕豪-实践总结报告.docx new file mode 100644 index 0000000..dfdb290 Binary files /dev/null and b/other/08_210340124王仕豪-实践总结报告.docx differ diff --git a/other/09_“饮食规划”系统演示视频.mp4 b/other/09_“饮食规划”系统演示视频.mp4 new file mode 100644 index 0000000..bd25b5c Binary files /dev/null and b/other/09_“饮食规划”系统演示视频.mp4 differ diff --git a/other/10_“饮食规划“系统宣传海报.jpg b/other/10_“饮食规划“系统宣传海报.jpg new file mode 100644 index 0000000..0ecfe2f Binary files /dev/null and b/other/10_“饮食规划“系统宣传海报.jpg differ diff --git a/other/3.txt b/other/3.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/4.txt b/src/4.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/dxq-rjgcks/.gitignore b/src/dxq-rjgcks/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/src/dxq-rjgcks/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/src/dxq-rjgcks/build.gradle b/src/dxq-rjgcks/build.gradle new file mode 100644 index 0000000..98df2f7 --- /dev/null +++ b/src/dxq-rjgcks/build.gradle @@ -0,0 +1,28 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '2.7.17-SNAPSHOT' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' +} + +group = 'com.example' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +repositories { + mavenCentral() + maven { url 'https://repo.spring.io/milestone' } + maven { url 'https://repo.spring.io/snapshot' } +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.jar b/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..033e24c Binary files /dev/null and b/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.properties b/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..9f4197d --- /dev/null +++ b/src/dxq-rjgcks/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/src/dxq-rjgcks/gradlew b/src/dxq-rjgcks/gradlew new file mode 100644 index 0000000..fcb6fca --- /dev/null +++ b/src/dxq-rjgcks/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/src/dxq-rjgcks/gradlew.bat b/src/dxq-rjgcks/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/src/dxq-rjgcks/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/dxq-rjgcks/package-lock.json b/src/dxq-rjgcks/package-lock.json new file mode 100644 index 0000000..9a77c44 --- /dev/null +++ b/src/dxq-rjgcks/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "dxq-rjgcks", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/src/dxq-rjgcks/settings.gradle b/src/dxq-rjgcks/settings.gradle new file mode 100644 index 0000000..d294bd1 --- /dev/null +++ b/src/dxq-rjgcks/settings.gradle @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + maven { url 'https://repo.spring.io/milestone' } + maven { url 'https://repo.spring.io/snapshot' } + gradlePluginPortal() + } +} +rootProject.name = 'demo' diff --git a/src/dxq-rjgcks/src/main/java/com/dxq/DxqRjgcksApplication.java b/src/dxq-rjgcks/src/main/java/com/dxq/DxqRjgcksApplication.java new file mode 100644 index 0000000..ba2984a --- /dev/null +++ b/src/dxq-rjgcks/src/main/java/com/dxq/DxqRjgcksApplication.java @@ -0,0 +1,13 @@ +package com.dxq; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DxqRjgcksApplication { + + public static void main(String[] args) { + SpringApplication.run(DxqRjgcksApplication.class, args); + } + +} diff --git a/src/dxq-rjgcks/src/main/java/com/example/demo/DemoApplication.java b/src/dxq-rjgcks/src/main/java/com/example/demo/DemoApplication.java new file mode 100644 index 0000000..64b538a --- /dev/null +++ b/src/dxq-rjgcks/src/main/java/com/example/demo/DemoApplication.java @@ -0,0 +1,13 @@ +package com.example.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/src/dxq-rjgcks/src/main/resources/application.yml b/src/dxq-rjgcks/src/main/resources/application.yml new file mode 100644 index 0000000..1dc1acf --- /dev/null +++ b/src/dxq-rjgcks/src/main/resources/application.yml @@ -0,0 +1,18 @@ + +server: + port:9999 + +spring: + datasource: + username: root + password: 123456 + url:jdbc: mysql:///xdb + + redis: + port: 6379 + host: localhost + +logging: + level: + com.example: debug + diff --git a/src/dxq-rjgcks/src/test/java/com/dxq/DxqRjgcksApplicationTests.java b/src/dxq-rjgcks/src/test/java/com/dxq/DxqRjgcksApplicationTests.java new file mode 100644 index 0000000..3125576 --- /dev/null +++ b/src/dxq-rjgcks/src/test/java/com/dxq/DxqRjgcksApplicationTests.java @@ -0,0 +1,13 @@ +package com.dxq; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DxqRjgcksApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/dxq-rjgcks/src/test/java/com/example/demo/DemoApplicationTests.java b/src/dxq-rjgcks/src/test/java/com/example/demo/DemoApplicationTests.java new file mode 100644 index 0000000..2778a6a --- /dev/null +++ b/src/dxq-rjgcks/src/test/java/com/example/demo/DemoApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.demo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DemoApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/dxq-rjgcks/x-admin-web/.editorconfig b/src/dxq-rjgcks/x-admin-web/.editorconfig new file mode 100644 index 0000000..ea6e20f --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.editorconfig @@ -0,0 +1,14 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/src/dxq-rjgcks/x-admin-web/.env.development b/src/dxq-rjgcks/x-admin-web/.env.development new file mode 100644 index 0000000..de583d0 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.env.development @@ -0,0 +1,5 @@ +# just a flag +ENV = 'development' + +# base api +VUE_APP_BASE_API = '/dev-api' diff --git a/src/dxq-rjgcks/x-admin-web/.env.production b/src/dxq-rjgcks/x-admin-web/.env.production new file mode 100644 index 0000000..80c8103 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.env.production @@ -0,0 +1,6 @@ +# just a flag +ENV = 'production' + +# base api +VUE_APP_BASE_API = '/prod-api' + diff --git a/src/dxq-rjgcks/x-admin-web/.env.staging b/src/dxq-rjgcks/x-admin-web/.env.staging new file mode 100644 index 0000000..a8793a0 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.env.staging @@ -0,0 +1,8 @@ +NODE_ENV = production + +# just a flag +ENV = 'staging' + +# base api +VUE_APP_BASE_API = '/stage-api' + diff --git a/src/dxq-rjgcks/x-admin-web/.eslintignore b/src/dxq-rjgcks/x-admin-web/.eslintignore new file mode 100644 index 0000000..e6529fc --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.eslintignore @@ -0,0 +1,4 @@ +build/*.js +src/assets +public +dist diff --git a/src/dxq-rjgcks/x-admin-web/.eslintrc.js b/src/dxq-rjgcks/x-admin-web/.eslintrc.js new file mode 100644 index 0000000..c977505 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.eslintrc.js @@ -0,0 +1,198 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/src/dxq-rjgcks/x-admin-web/.gitignore b/src/dxq-rjgcks/x-admin-web/.gitignore new file mode 100644 index 0000000..9ad28d2 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +package-lock.json +tests/**/coverage/ + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/src/dxq-rjgcks/x-admin-web/.travis.yml b/src/dxq-rjgcks/x-admin-web/.travis.yml new file mode 100644 index 0000000..f4be7a0 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: 10 +script: npm run test +notifications: + email: false diff --git a/src/dxq-rjgcks/x-admin-web/LICENSE b/src/dxq-rjgcks/x-admin-web/LICENSE new file mode 100644 index 0000000..6151575 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-present PanJiaChen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/dxq-rjgcks/x-admin-web/README-zh.md b/src/dxq-rjgcks/x-admin-web/README-zh.md new file mode 100644 index 0000000..1beec9b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/README-zh.md @@ -0,0 +1,111 @@ +# vue-admin-template + +> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。 + +[线上地址](http://panjiachen.github.io/vue-admin-template) + +[国内访问](https://panjiachen.gitee.io/vue-admin-template) + +目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。 + +

+ SPONSORED BY +

+

+ + + +

+ +## Extra + +如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control) + +## 相关项目 + +- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) + +- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) + +- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) + +- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) + +写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目: + +- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2) +- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac) +- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35) +- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56) +- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836) + +## Build Setup + +```bash +# 克隆项目 +git clone https://github.com/PanJiaChen/vue-admin-template.git + +# 进入项目目录 +cd vue-admin-template + +# 安装依赖 +npm install + +# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 +npm install --registry=https://registry.npm.taobao.org + +# 启动服务 +npm run dev +``` + +浏览器访问 [http://localhost:9528](http://localhost:9528) + +## 发布 + +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` + +## 其它 + +```bash +# 预览发布环境效果 +npm run preview + +# 预览发布环境效果 + 静态资源分析 +npm run preview -- --report + +# 代码格式检查 +npm run lint + +# 代码格式检查并自动修复 +npm run lint -- --fix +``` + +更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) + +## 购买贴纸 + +你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。 + +## Demo + +![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif) + +## Browsers support + +Modern browsers and Internet Explorer 10+. + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| --------- | --------- | --------- | --------- | +| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions + +## License + +[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license. + +Copyright (c) 2017-present PanJiaChen diff --git a/src/dxq-rjgcks/x-admin-web/README.md b/src/dxq-rjgcks/x-admin-web/README.md new file mode 100644 index 0000000..74d819d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/README.md @@ -0,0 +1,99 @@ +# vue-admin-template + +English | [简体中文](./README-zh.md) + +> A minimal 中国民航大学营养菜谱生成系统 with Element UI & axios & iconfont & permission control & lint + +**Live demo:** http://panjiachen.github.io/vue-admin-template + + +**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`** + +

+ SPONSORED BY +

+

+ + + +

+ +## Build Setup + +```bash +# clone the project +git clone https://github.com/PanJiaChen/vue-admin-template.git + +# enter the project directory +cd vue-admin-template + +# install dependency +npm install + +# develop +npm run dev +``` + +This will automatically open http://localhost:9528 + +## Build + +```bash +# build for test environment +npm run build:stage + +# build for production environment +npm run build:prod +``` + +## Advanced + +```bash +# preview the release environment effect +npm run preview + +# preview the release environment effect + static resource analysis +npm run preview -- --report + +# code format check +npm run lint + +# code format check and auto fix +npm run lint -- --fix +``` + +Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information + +## Demo + +![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif) + +## Extra + +If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control) + +For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour)) + +## Related Project + +- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) + +- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) + +- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) + +- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) + +## Browsers support + +Modern browsers and Internet Explorer 10+. + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| --------- | --------- | --------- | --------- | +| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions + +## License + +[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license. + +Copyright (c) 2017-present PanJiaChen diff --git a/src/dxq-rjgcks/x-admin-web/app.js b/src/dxq-rjgcks/x-admin-web/app.js new file mode 100644 index 0000000..0c8ae81 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/app.js @@ -0,0 +1,53 @@ +const express = require('express'); +const cors = require('cors'); + +const mysql = require('mysql2/promise'); // 使用mysql2库 + +const app = express(); +app.use(cors()); +app.use(express.json()); // Add this line to enable JSON parsing + +const port = 3000; + +// 创建MySQL数据库连接池 +const pool = mysql.createPool({ + host: 'localhost', + user: 'root', + password: 'wql17623243339', + database: 'custom', + connectionLimit: 10, // 适当设置连接池大小 +}); + +// 创建API端点来执行数据库查询 +app.get('/api/data', async (req, res) => { + try { + // 从数据库中查询数据的示例 + const [rows] = await pool.query('SELECT * FROM yonghu'); + res.json(rows); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +app.post('/api/data', async (req, res) => { + try { + const { idyonghu, feedback } = req.body; + + console.log('Received data:', idyonghu, feedback); + + const [result] = await pool.query('INSERT INTO yonghu (idyonghu, feedback) VALUES (?, ?)', [idyonghu, feedback]); + + console.log('Insert result:', result); + + res.json({ success: true, insertedId: result.insertId }); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +app.listen(port, () => { + console.log(`Server is running on port ${port}`); +}); + diff --git a/src/dxq-rjgcks/x-admin-web/app1.js b/src/dxq-rjgcks/x-admin-web/app1.js new file mode 100644 index 0000000..150d13a --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/app1.js @@ -0,0 +1,52 @@ +const express = require('express'); +const cors = require('cors'); + +const mysql = require('mysql2/promise'); // 使用mysql2库 + +const app = express(); +app.use(cors()); +app.use(express.json()); // Add this line to enable JSON parsing + +const port = 3000; + +// 创建MySQL数据库连接池 +const pool = mysql.createPool({ + host: 'localhost', + user: 'root', + password: 'wql17623243339', + database: 'sys', + connectionLimit: 100, // 适当设置连接池大小 +}); + +// 创建API端点来执行数据库查询 +app.get('/api/data', async (req, res) => { + try { + // 从数据库中查询数据的示例 + const [rows] = await pool.query('SELECT * FROM new_table'); + res.json(rows); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +app.post('/api/data', async (req, res) => { + try { + const { idnew_table, new_tablecol, new_tablecol1, new_tablecol2, new_tablecol3, new_tablecol4, new_tablecol5, new_tablecol6, new_tablecol7, new_tablecol8, new_tablecol9 } = req.body; + + console.log('Received data:', idnew_table, new_tablecol, new_tablecol1, new_tablecol2, new_tablecol3, new_tablecol4, new_tablecol5, new_tablecol6, new_tablecol7, new_tablecol8, new_tablecol9); + + const [result] = await pool.query('INSERT INTO new_table ( idnew_table, new_tablecol, new_tablecol1, new_tablecol2, new_tablecol3, new_tablecol4, new_tablecol5, new_tablecol6, new_tablecol7, new_tablecol8, new_tablecol9) VALUES (?, ?,?, ?,?, ?,?, ?,?, ?,?)', [ idnew_table, new_tablecol, new_tablecol1, new_tablecol2, new_tablecol3, new_tablecol4, new_tablecol5, new_tablecol6, new_tablecol7, new_tablecol8, new_tablecol9]); + + console.log('Insert result:', result); + + res.json({ success: true, insertedId: result.insertId }); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +app.listen(port, () => { + console.log(`Server is running on port ${port}`); +}); \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/babel.config.js b/src/dxq-rjgcks/x-admin-web/babel.config.js new file mode 100644 index 0000000..fb82b27 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/babel.config.js @@ -0,0 +1,14 @@ +module.exports = { + presets: [ + // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app + '@vue/cli-plugin-babel/preset' + ], + 'env': { + 'development': { + // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). + // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. + // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html + 'plugins': ['dynamic-import-node'] + } + } +} diff --git a/src/dxq-rjgcks/x-admin-web/jest.config.js b/src/dxq-rjgcks/x-admin-web/jest.config.js new file mode 100644 index 0000000..143cdc8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/jest.config.js @@ -0,0 +1,24 @@ +module.exports = { + moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': + 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: ['jest-serializer-vue'], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], + coverageDirectory: '/tests/unit/coverage', + // 'collectCoverage': true, + 'coverageReporters': [ + 'lcov', + 'text-summary' + ], + testURL: 'http://localhost/' +} diff --git a/src/dxq-rjgcks/x-admin-web/jsconfig.json b/src/dxq-rjgcks/x-admin-web/jsconfig.json new file mode 100644 index 0000000..ed079e2 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "exclude": ["node_modules", "dist"] +} diff --git a/src/dxq-rjgcks/x-admin-web/mock/index.js b/src/dxq-rjgcks/x-admin-web/mock/index.js new file mode 100644 index 0000000..c514c13 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/mock/index.js @@ -0,0 +1,57 @@ +const Mock = require('mockjs') +const { param2Obj } = require('./utils') + +const user = require('./user') +const table = require('./table') + +const mocks = [ + ...user, + ...table +] + +// for front mock +// please use it cautiously, it will redefine XMLHttpRequest, +// which will cause many of your third-party libraries to be invalidated(like progress event). +function mockXHR() { + // mock patch + // https://github.com/nuysoft/Mock/issues/300 + Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send + Mock.XHR.prototype.send = function() { + if (this.custom.xhr) { + this.custom.xhr.withCredentials = this.withCredentials || false + + if (this.responseType) { + this.custom.xhr.responseType = this.responseType + } + } + this.proxy_send(...arguments) + } + + function XHR2ExpressReqWrap(respond) { + return function(options) { + let result = null + if (respond instanceof Function) { + const { body, type, url } = options + // https://expressjs.com/en/4x/api.html#req + result = respond({ + method: type, + body: JSON.parse(body), + query: param2Obj(url) + }) + } else { + result = respond + } + return Mock.mock(result) + } + } + + for (const i of mocks) { + Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) + } +} + +module.exports = { + mocks, + mockXHR +} + diff --git a/src/dxq-rjgcks/x-admin-web/mock/mock-server.js b/src/dxq-rjgcks/x-admin-web/mock/mock-server.js new file mode 100644 index 0000000..8941ec0 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/mock/mock-server.js @@ -0,0 +1,81 @@ +const chokidar = require('chokidar') +const bodyParser = require('body-parser') +const chalk = require('chalk') +const path = require('path') +const Mock = require('mockjs') + +const mockDir = path.join(process.cwd(), 'mock') + +function registerRoutes(app) { + let mockLastIndex + const { mocks } = require('./index.js') + const mocksForServer = mocks.map(route => { + return responseFake(route.url, route.type, route.response) + }) + for (const mock of mocksForServer) { + app[mock.type](mock.url, mock.response) + mockLastIndex = app._router.stack.length + } + const mockRoutesLength = Object.keys(mocksForServer).length + return { + mockRoutesLength: mockRoutesLength, + mockStartIndex: mockLastIndex - mockRoutesLength + } +} + +function unregisterRoutes() { + Object.keys(require.cache).forEach(i => { + if (i.includes(mockDir)) { + delete require.cache[require.resolve(i)] + } + }) +} + +// for mock server +const responseFake = (url, type, respond) => { + return { + url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), + type: type || 'get', + response(req, res) { + console.log('request invoke:' + req.path) + res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) + } + } +} + +module.exports = app => { + // parse app.body + // https://expressjs.com/en/4x/api.html#req.body + app.use(bodyParser.json()) + app.use(bodyParser.urlencoded({ + extended: true + })) + + const mockRoutes = registerRoutes(app) + var mockRoutesLength = mockRoutes.mockRoutesLength + var mockStartIndex = mockRoutes.mockStartIndex + + // watch files, hot reload mock server + chokidar.watch(mockDir, { + ignored: /mock-server/, + ignoreInitial: true + }).on('all', (event, path) => { + if (event === 'change' || event === 'add') { + try { + // remove mock routes stack + app._router.stack.splice(mockStartIndex, mockRoutesLength) + + // clear routes cache + unregisterRoutes() + + const mockRoutes = registerRoutes(app) + mockRoutesLength = mockRoutes.mockRoutesLength + mockStartIndex = mockRoutes.mockStartIndex + + console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) + } catch (error) { + console.log(chalk.redBright(error)) + } + } + }) +} diff --git a/src/dxq-rjgcks/x-admin-web/mock/table.js b/src/dxq-rjgcks/x-admin-web/mock/table.js new file mode 100644 index 0000000..caab53c --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/mock/table.js @@ -0,0 +1,275 @@ +const Mock = require('mockjs') + +const data = Mock.mock({ + 'items|30': [{ + id: '@id', + title: '@sentence(10, 20)', + 'status|1': ['published', 'draft', 'deleted'], + author: 'name', + display_time: '@datetime', + pageviews: '@integer(300, 5000)' + }] +}) + +//从excel手动解析的部分数据,excel转json在线网址 https://www.bejson.com/json/col2json/index.html +const dataAll = +[ +{"menuId":1101,"menuName":"香辣鸡腿堡","price":9,"weight":160,"protein":17.2,"carb":60.6,"fat":14.5,"calories":441}, +{"menuId":1102,"menuName":"岐山臊子面","price":9,"weight":160,"protein":12.8,"carb":72,"fat":14.7,"calories":470}, +{"menuId":1103,"menuName":"鸡肉卷","price":9,"weight":160,"protein":18.9,"carb":37.9,"fat":21.9,"calories":422}, +{"menuId":1104,"menuName":"七喜","price":12,"weight":450,"protein":0,"carb":34.6,"fat":0,"calories":135}, +{"menuId":1105,"menuName":"可乐","price":10,"weight":450,"protein":0,"carb":50.4,"fat":0,"calories":198}, +{"menuId":1106,"menuName":"美年达","price":14,"weight":450,"protein":0,"carb":43.2,"fat":0,"calories":171}, +{"menuId":1107,"menuName":"炸鸡排","price":20.5,"weight":200,"protein":36.8,"carb":11.6,"fat":18.4,"calories":358}, +{"menuId":1108,"menuName":"蜜汁鸡腿","price":16,"weight":130,"protein":22.1,"carb":12.5,"fat":14.4,"calories":267}, +{"menuId":1109,"menuName":"奶香脆","price":10.5,"weight":200,"protein":21.2,"carb":114,"fat":29.6,"calories":806}, +{"menuId":1110,"menuName":"糯糯小年糕","price":19,"weight":250,"protein":5.5,"carb":119.3,"fat":12.8,"calories":612}, +{"menuId":1111,"menuName":"藤椒鸡条","price":17.5,"weight":200,"protein":21.8,"carb":13.4,"fat":16.4,"calories":288}, +{"menuId":1112,"menuName":"锅巴土豆","price":11,"weight":200,"protein":5,"carb":32.3,"fat":20.6,"calories":334}, +{"menuId":1113,"menuName":"爆浆芝士鸡排","price":14,"weight":315,"protein":37.5,"carb":40.6,"fat":51.7,"calories":774}, +{"menuId":1114,"menuName":"现炸酥肉","price":12,"weight":185,"protein":18.4,"carb":17.5,"fat":53.4,"calories":623}, +{"menuId":1115,"menuName":"黑椒鸡块","price":17.5,"weight":150,"protein":12.8,"carb":32.1,"fat":33.8,"calories":483}, +{"menuId":1116,"menuName":"鸡米花","price":12.5,"weight":180,"protein":24.3,"carb":29.7,"fat":23.9,"calories":430}, +{"menuId":1117,"menuName":"薯条","price":8,"weight":220,"protein":12.8,"carb":109.1,"fat":40.3,"calories":849}, +{"menuId":1118,"menuName":"牛肉拉面","price":13.5,"weight":200,"protein":3.6,"carb":156.4,"fat":1.2,"calories":650}, +{"menuId":1119,"menuName":"烤肠","price":15,"weight":150,"protein":20.4,"carb":13.8,"fat":33.5,"calories":436}, +{"menuId":1120,"menuName":"猪肉肠","price":15,"weight":80,"protein":12.5,"carb":2.9,"fat":19.9,"calories":240}, +{"menuId":1121,"menuName":"拉丝芝士棒","price":15,"weight":80,"protein":9,"carb":23,"fat":9.3,"calories":211}, +{"menuId":1122,"menuName":"牛肉串","price":9.5,"weight":200,"protein":29,"carb":47.6,"fat":10.4,"calories":400}, +{"menuId":1123,"menuName":"鱿鱼串","price":10,"weight":200,"protein":27.1,"carb":10.3,"fat":13.7,"calories":272}, +{"menuId":1124,"menuName":"鸡肉串","price":9.5,"weight":200,"protein":38.6,"carb":2.6,"fat":18.8,"calories":334}, +{"menuId":1125,"menuName":"鸭肉串","price":9.5,"weight":200,"protein":65,"carb":3.8,"fat":28.2,"calories":528}, +{"menuId":1126,"menuName":"香辣鸡珍","price":9.5,"weight":200,"protein":51.4,"carb":0,"fat":26.2,"calories":440}, +{"menuId":1127,"menuName":"香酥鸡柳","price":10,"weight":180,"protein":15.8,"carb":43.2,"fat":25.2,"calories":462}, +{"menuId":1201,"menuName":"5个鲜肉包","price":15,"weight":80,"protein":6.4,"carb":32,"fat":3.4,"calories":183}, +{"menuId":1202,"menuName":"4个虾仁三鲜包","price":12,"weight":90,"protein":7.2,"carb":10.8,"fat":11.8,"calories":177}, +{"menuId":1203,"menuName":"4个西葫鸡蛋包","price":10,"weight":100,"protein":6.3,"carb":25.1,"fat":3.1,"calories":153}, +{"menuId":1205,"menuName":"5个小葱鲜肉包","price":10,"weight":90,"protein":10.2,"carb":30.7,"fat":2.4,"calories":184}, +{"menuId":1204,"menuName":"4个牛肉包","price":20,"weight":90,"protein":10.6,"carb":28.9,"fat":4.8,"calories":200}, +// {"menuId":1206,"menuName":"香菇鲜肉包","price":1.8,"weight":90,"protein":6.4,"carb":30.5,"fat":5.5,"calories":196}, +// {"menuId":1207,"menuName":"素三鲜包","price":1.5,"weight":90,"protein":6.6,"carb":33,"fat":11.2,"calories":258}, +// {"menuId":1208,"menuName":"豆角鲜肉包","price":1.5,"weight":90,"protein":6.3,"carb":32.9,"fat":7.5,"calories":223}, +// {"menuId":1209,"menuName":"芹菜鲜肉包","price":1.5,"weight":90,"protein":8.8,"carb":31,"fat":3.1,"calories":2.07}, +// {"menuId":1210,"menuName":"鲜肉煎包","price":2,"weight":60,"protein":7.4,"carb":15.1,"fat":11.2,"calories":190}, +// {"menuId":1211,"menuName":"豆沙包","price":1.5,"weight":80,"protein":7.5,"carb":54.1,"fat":0.9,"calories":253}, +// {"menuId":1212,"menuName":"第一楼汤包","price":5,"weight":220,"protein":13.4,"carb":68.2,"fat":24,"calories":541}, +// {"menuId":1213,"menuName":"素白菜包","price":1,"weight":80,"protein":5.1,"carb":20.7,"fat":1.4,"calories":115}, +// {"menuId":1214,"menuName":"紫薯包","price":2.5,"weight":80,"protein":3.8,"carb":25.6,"fat":0.8,"calories":124}, +// {"menuId":1215,"menuName":"紫薯馒头","price":0.9,"weight":60,"protein":8.1,"carb":35.4,"fat":2.2,"calories":193}, +// {"menuId":1216,"menuName":"花卷","price":0.5,"weight":60,"protein":3.8,"carb":27.4,"fat":0.6,"calories":130}, +// {"menuId":1217,"menuName":"白馒头","price":0.5,"weight":60,"protein":4.1,"carb":36.6,"fat":0.7,"calories":169}, +// {"menuId":1218,"menuName":"白煮蛋","price":0.6,"weight":50,"protein":6,"carb":0.1,"fat":5.3,"calories":71}, +// {"menuId":1219,"menuName":"豆腐脑","price":3,"weight":450,"protein":11.7,"carb":24.3,"fat":8.1,"calories":216}, +// {"menuId":1220,"menuName":"五谷豆浆","price":1,"weight":500,"protein":15,"carb":6,"fat":8,"calories":155}, +// {"menuId":1221,"menuName":"牛奶","price":3,"weight":500,"protein":15,"carb":25,"fat":19,"calories":330}, +// {"menuId":1222,"menuName":"紫米露","price":3.5,"weight":500,"protein":4.5,"carb":80,"fat":4.8,"calories":380}, +// {"menuId":1223,"menuName":"香芋露","price":3.5,"weight":500,"protein":4.5,"carb":80,"fat":4.8,"calories":380}, +// {"menuId":1224,"menuName":"油条","price":1.5,"weight":50,"protein":3.5,"carb":25.5,"fat":8.8,"calories":195}, +// {"menuId":1225,"menuName":"麻球","price":1.5,"weight":50,"protein":2.9,"carb":37,"fat":2.2,"calories":179}, +// {"menuId":1226,"menuName":"烧麦","price":1.8,"weight":50,"protein":3.5,"carb":19.6,"fat":1.5,"calories":106}, +// {"menuId":1227,"menuName":"水果玉米","price":3.5,"weight":400,"protein":12.4,"carb":70,"fat":10.4,"calories":420}, +// {"menuId":1228,"menuName":"糯玉米","price":3.5,"weight":400,"protein":18.8,"carb":133.6,"fat":7.6,"calories":676}, +// {"menuId":1229,"menuName":"地瓜","price":5,"weight":500,"protein":5.5,"carb":147.5,"fat":0.5,"calories":615}, +// {"menuId":1230,"menuName":"甜甜圈","price":2,"weight":30,"protein":2,"carb":5.2,"fat":4.4,"calories":68}, +// {"menuId":1231,"menuName":"卤鸡蛋","price":1.2,"weight":50,"protein":6.1,"carb":2.3,"fat":"4.0 ","calories":69}, +// {"menuId":1232,"menuName":"荷包蛋","price":1.4,"weight":50,"protein":6.1,"carb":1.1,"fat":6.6,"calories":87}, +// {"menuId":1233,"menuName":"脆皮大麻花","price":3.8,"weight":140,"protein":11.8,"carb":82,"fat":4.8,"calories":417}, +// {"menuId":1234,"menuName":"脆皮淀粉肠","price":3,"weight":100,"protein":5,"carb":10.7,"fat":6,"calories":115}, +// {"menuId":1235,"menuName":"黑椒肠","price":4,"weight":70,"protein":10.2,"carb":8.9,"fat":11.8,"calories":182}, +// {"menuId":1236,"menuName":"玉米露汁","price":2.8,"weight":500,"protein":7.6,"carb":71.3,"fat":2.3,"calories":335}, +// {"menuId":1237,"menuName":"铁板煎豆腐","price":7,"weight":400,"protein":25.4,"carb":13.5,"fat":28,"calories":404}, +// {"menuId":1238,"menuName":"烤面筋","price":2.5,"weight":100,"protein":19.8,"carb":12.6,"fat":16.8,"calories":280}, +// {"menuId":1239,"menuName":"发糕","price":2,"weight":70,"protein":5.3,"carb":36.1,"fat":0.7,"calories":170}, +// {"menuId":1240,"menuName":"切糕","price":3,"weight":120,"protein":2.8,"carb":39,"fat":0.4,"calories":170}, +// {"menuId":1241,"menuName":"香肠卷","price":2.5,"weight":110,"protein":9.1,"carb":41.4,"fat":6.6,"calories":260}, +// {"menuId":1301,"menuName":"牛奶燕麦粥","price":2,"weight":450,"protein":2.6,"carb":7.2,"fat":3.6,"calories":71}, +// {"menuId":1302,"menuName":"八宝粥","price":2,"weight":450,"protein":7.9,"carb":39.2,"fat":4.6,"calories":229}, +// {"menuId":1303,"menuName":"金丝南瓜小米粥","price":2,"weight":450,"protein":3.6,"carb":29.4,"fat":1.1,"calories":139}, +// {"menuId":1304,"menuName":"红糖银耳","price":1.5,"weight":450,"protein":0.6,"carb":8.4,"fat":0.2,"calories":36}, +// {"menuId":1305,"menuName":"皮蛋瘦肉粥","price":2,"weight":450,"protein":21.6,"carb":59.6,"fat":11.9,"calories":427}, +// {"menuId":1306,"menuName":"胡辣汤","price":3,"weight":450,"protein":13,"carb":11.6,"fat":7.4,"calories":162}, +// {"menuId":1307,"menuName":"白米粥","price":0.5,"weight":450,"protein":3.1,"carb":35.5,"fat":2.7,"calories":175}, +// {"menuId":1308,"menuName":"疙瘩汤","price":2,"weight":450,"protein":6,"carb":27.2,"fat":1.8,"calories":148}, +// {"menuId":1309,"menuName":"银耳绿豆汤","price":2,"weight":450,"protein":8.7,"carb":32.9,"fat":0.3,"calories":166}, +// {"menuId":1310,"menuName":"马拉糕","price":3,"weight":60,"protein":4.1,"carb":32.4,"fat":2.4,"calories":167}, +// {"menuId":1311,"menuName":"蛋包肠","price":4,"weight":100,"protein":11.9,"carb":5.1,"fat":12.3,"calories":178}, +// {"menuId":1312,"menuName":"白煮蛋","price":0.6,"weight":50,"protein":6,"carb":0.1,"fat":5.3,"calories":71}, +// {"menuId":1313,"menuName":"麻球","price":1.5,"weight":30,"protein":1.8,"carb":22.2,"fat":1.3,"calories":107}, +// {"menuId":1314,"menuName":"茶叶蛋","price":1.2,"weight":50,"protein":6.3,"carb":6.2,"fat":3.1,"calories":77}, +{"menuId":1315,"menuName":"肉末粉丝煎饺","price":12,"weight":50,"protein":3.4,"carb":12.7,"fat":8.3,"calories":139}, +{"menuId":1316,"menuName":"紫米球","price":12,"weight":120,"protein":1.8,"carb":35.8,"fat":2.6,"calories":174}, +{"menuId":1317,"menuName":"三明治","price":8,"weight":135,"protein":14.4,"carb":24,"fat":18,"calories":314}, +{"menuId":1318,"menuName":"赤豆元宵","price":8,"weight":210,"protein":6.9,"carb":63.6,"fat":1.5,"calories":294}, +{"menuId":1319,"menuName":"桂花糯米糕","price":8,"weight":150,"protein":6.2,"carb":78.6,"fat":1.4,"calories":351}, +{"menuId":1320,"menuName":"鸡蛋肉沫汉堡","price":8,"weight":150,"protein":20.2,"carb":45.5,"fat":17.2,"calories":416}, +{"menuId":1321,"menuName":"火腿鸡蛋汉堡","price":7,"weight":150,"protein":15.6,"carb":39.1,"fat":21.5,"calories":411}, +{"menuId":1322,"menuName":"葱油拌面","price":7,"weight":150,"protein":17.4,"carb":6.4,"fat":14.7,"calories":226}, +{"menuId":1323,"menuName":"陕西油泼面","price":7,"weight":150,"protein":16.9,"carb":55.1,"fat":13.1,"calories":405}, +{"menuId":1324,"menuName":"哈尔滨烤冷面","price":7,"weight":350,"protein":23,"carb":82.5,"fat":14.9,"calories":556}, +// {"menuId":1401,"menuName":"杂粮煎饼","price":6,"weight":200,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1402,"menuName":"烤肠","price":2,"weight":20,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1403,"menuName":"辣条","price":3,"weight":50,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1404,"menuName":"火鸡面","price":3,"weight":60,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1405,"menuName":"里脊肉","price":3,"weight":25,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1406,"menuName":"纯肉肠","price":5,"weight":60,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1407,"menuName":"奥尔良鸡肉条","price":4,"weight":50,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1408,"menuName":"玉米肠","price":3.5,"weight":40,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1409,"menuName":"午餐肉","price":3,"weight":40,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1410,"menuName":"骨肉相连","price":3,"weight":30,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1411,"menuName":"培根","price":2,"weight":20,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1412,"menuName":"雪花鸡柳","price":3,"weight":50,"protein":0,"carb":0,"fat":0,"calories":0}, +{"menuId":1501,"menuName":"清汤抄手","price":11,"weight":700,"protein":22,"carb":118,"fat":8.5,"calories":630}, +{"menuId":1502,"menuName":"红油抄手","price":11.6,"weight":700,"protein":24.8,"carb":114.5,"fat":13.5,"calories":678}, +{"menuId":1503,"menuName":"番茄抄手","price":12,"weight":700,"protein":21.6,"carb":118,"fat":7.6,"calories":623}, +{"menuId":1504,"menuName":"鸡汤抄手","price":14,"weight":700,"protein":25.8,"carb":107,"fat":10.3,"calories":623}, +{"menuId":1505,"menuName":"麻辣抄手","price":14,"weight":700,"protein":18.6,"carb":119.5,"fat":18.9,"calories":721}, +{"menuId":1506,"menuName":"香菇菌汤抄手","price":9.8,"weight":700,"protein":17.5,"carb":110.9,"fat":13.5,"calories":630}, +{"menuId":1507,"menuName":"金汤酸菜抄手","price":9.8,"weight":700,"protein":21.8,"carb":106.8,"fat":18.5,"calories":679}, +// {"menuId":1508,"menuName":"鸡汤抄手面","price":9.8,"weight":950,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1509,"menuName":"番茄抄手面","price":9.8,"weight":950,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1510,"menuName":"麻辣抄手面","price":9.8,"weight":950,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1511,"menuName":"香菇菌汤抄手面","price":9.8,"weight":950,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1512,"menuName":"金汤酸菜抄手面","price":9.8,"weight":950,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1513,"menuName":"芹菜鸡蛋素水饺","price":7.6,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1514,"menuName":"胡萝卜鸡蛋素水饺","price":7.6,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1515,"menuName":"萝卜鲜肉水饺","price":8,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1516,"menuName":"茄子鲜肉水饺","price":8,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1517,"menuName":"肉三鲜水饺","price":8.6,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1518,"menuName":"大葱鲜肉水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1519,"menuName":"玉米鲜肉水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1520,"menuName":"茴香鲜肉水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1521,"menuName":"菌菇鲜汤水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1522,"menuName":"豆角鲜肉水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1523,"menuName":"全家福鲜肉水饺","price":9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1524,"menuName":"莲藕玉米鲜肉水饺","price":9.9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1525,"menuName":"香芹蘑菇鲜肉水饺","price":9.9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1526,"menuName":"新奥尔良鲜肉水饺","price":9.9,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1527,"menuName":"虾仁三鲜水饺","price":10.8,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1528,"menuName":"虾仁玉米鲜肉水饺","price":10.8,"weight":250,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1529,"menuName":"鲜肉小馄饨(小份)","price":6.6,"weight":320,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1530,"menuName":"鲜肉小馄饨(大份)","price":8.8,"weight":480,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1531,"menuName":"玉米鲜肉小馄饨(小份)","price":6.6,"weight":320,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1532,"menuName":"玉米鲜肉小馄饨(大份)","price":8.8,"weight":480,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1533,"menuName":"福清多方便面系列","price":3.5,"weight":180,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1534,"menuName":"康师傅方便面系列","price":4.5,"weight":180,"protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1801,"menuName":"飘香拌面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1802,"menuName":"葱油拌面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1803,"menuName":"高汤酸菜面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1804,"menuName":"扁肉","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1805,"menuName":"蒸饺","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1806,"menuName":"罗汉肉炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1807,"menuName":"高汤青菜面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1808,"menuName":"蛋炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1809,"menuName":"蛋炒面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1810,"menuName":"蛋炒粉","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1811,"menuName":"蛋炒泡面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1812,"menuName":"炒饼丝","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1813,"menuName":"泡菜炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1814,"menuName":"扬州炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1815,"menuName":"火腿炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1816,"menuName":"酸菜炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1817,"menuName":"老干妈炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1818,"menuName":"酸豆角炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1819,"menuName":"香菇肉丝炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1820,"menuName":"青椒肉丝炒饭","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1821,"menuName":"香菇肉丝面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1822,"menuName":"榨菜肉丝面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1823,"menuName":"老北京炸酱面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1824,"menuName":"五香罗汉肉面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1825,"menuName":"红烧罗汉肉面","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1826,"menuName":"香肠","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1827,"menuName":"豆干","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1828,"menuName":"鸡腿","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1829,"menuName":"卤蛋","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1901,"menuName":"黄焖鸡米饭套餐","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1902,"menuName":"黄焖鸡全家福套餐","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1903,"menuName":"黄焖全素套餐","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1904,"menuName":"铁锅炒鸡米饭套餐","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":1905,"menuName":"铁锅炒鸡全家福套餐","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2001,"menuName":"纯素饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2002,"menuName":"辣条饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2003,"menuName":"香辣土豆丝饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2004,"menuName":"玉米沙拉饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2005,"menuName":"芒果糯米饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2006,"menuName":"抹茶红豆饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2007,"menuName":"韩式泡菜饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2008,"menuName":"叉烧福袋饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2009,"menuName":"咸蛋黄饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2010,"menuName":"深海鳕鱼饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2011,"menuName":"鸡排饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2012,"menuName":"黑椒鸡柳饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2013,"menuName":"菠萝鸡柳饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2014,"menuName":"培根肉松饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2015,"menuName":"传统鸡蛋饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2016,"menuName":"油条甜饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2017,"menuName":"咖喱嫩鸡饭团","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2018,"menuName":"酸梅汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2019,"menuName":"金桔梨汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2020,"menuName":"芥菜梨汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2021,"menuName":"传统梨汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2022,"menuName":"菠萝梨汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2023,"menuName":"枇杷梨汤","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2024,"menuName":"蟹柳","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2025,"menuName":"辣条","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2026,"menuName":"蛋黄","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2027,"menuName":"芝士碎","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2028,"menuName":"烤肠","price":0,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2101,"menuName":"麻酱拌面","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2102,"menuName":"酸菜肉沫面","price":9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2103,"menuName":"纯汤牛肉面","price":9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2104,"menuName":"青菜面","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2105,"menuName":"葱油拌面","price":6.6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2106,"menuName":"津味炸酱面","price":9.9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2107,"menuName":"番茄鸡蛋面","price":7.7,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2108,"menuName":"尖椒鸡肉丝面","price":9.9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2109,"menuName":"青菜鸡蛋面","price":7.8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2110,"menuName":"榨菜猪肉丝面","price":9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2111,"menuName":"蒜薹鸡肉丝面","price":9.9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2112,"menuName":"武汉热干面","price":9.9,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2113,"menuName":"重庆担担面","price":8.8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2114,"menuName":"椒麻鸡丝面","price":12,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2115,"menuName":"岐山臊子面","price":11,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2116,"menuName":"陕西油泼面","price":11,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2117,"menuName":"红烧排骨","price":8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2118,"menuName":"香辣肥肠","price":8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2119,"menuName":"熟牛肉","price":8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2120,"menuName":"红烧牛肉","price":8,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2121,"menuName":"双椒肉酱","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2122,"menuName":"金汤鸭肉卷","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2123,"menuName":"香菇肉末","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2124,"menuName":"卤鸡腿","price":5,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2125,"menuName":"川味肉末","price":6,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2126,"menuName":"川味牛杂","price":7,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2127,"menuName":"卤蛋","price":1.2,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2128,"menuName":"丸子","price":2,"weight":"","protein":0,"carb":0,"fat":0,"calories":0}, +// {"menuId":2129,"menuName":"豆干","price":2,"weight":"","protein":0,"carb":0,"fat":0,"calories":0} +] +module.exports = [ + { + url: '/vue-admin-template/table/list', + type: 'get', + response: config => { + const items = data.items + return { + code: 20000, + data: { + total: items.length, + items: items + } + } + } + }, + { + url: '/vue-admin-template/table/getEaWhat', + type: 'get', + response: config => { + // const items = data.items + return { + code: 20000, + data: { + list: dataAll, + } + } + } + } +] diff --git a/src/dxq-rjgcks/x-admin-web/mock/user.js b/src/dxq-rjgcks/x-admin-web/mock/user.js new file mode 100644 index 0000000..9a29a14 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/mock/user.js @@ -0,0 +1,86 @@ + + +const tokens = { + admin: { + token: 'admin-token' + }, + editor: { + token: 'editor-token' + } +} + +const users = { + 'admin-token': { + roles: ['admin'], + introduction: 'I am a super administrator', + avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', + name: 'Super Admin' + }, + 'editor-token': { + roles: ['editor'], + introduction: 'I am an editor', + avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', + name: 'Normal Editor' + } +} + +module.exports = [ + // user login + { + url: '/vue-admin-template/user/login', + type: 'post', + response: config => { + const { username } = config.body + console.log(username) + const token = tokens[username] + + // mock error + if (!token) { + return { + code: 60204, + message: 'Account and password are incorrect.' + } + } + + return { + code: 20000, + data: token + } + } + }, + + // get user info + { + url: '/vue-admin-template/user/info\.*', + type: 'get', + response: config => { + const { token } = config.query + const info = users[token] + + // mock error + if (!info) { + return { + code: 50008, + message: 'Login failed, unable to get user details.' + } + } + + return { + code: 20000, + data: info + } + } + }, + + // user logout + { + url: '/vue-admin-template/user/logout', + type: 'post', + response: _ => { + return { + code: 20000, + data: 'success' + } + } + } +] diff --git a/src/dxq-rjgcks/x-admin-web/mock/utils.js b/src/dxq-rjgcks/x-admin-web/mock/utils.js new file mode 100644 index 0000000..95cc27d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/mock/utils.js @@ -0,0 +1,25 @@ +/** + * @param {string} url + * @returns {Object} + */ +function param2Obj(url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +module.exports = { + param2Obj +} diff --git a/src/dxq-rjgcks/x-admin-web/package.json b/src/dxq-rjgcks/x-admin-web/package.json new file mode 100644 index 0000000..d541408 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/package.json @@ -0,0 +1,67 @@ +{ + "name": "vue-admin-template", + "version": "4.4.0", + "description": "A 中国民航大学营养菜谱生成系统 with Element UI & axios & iconfont & permission control & lint", + "author": "Pan ", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", + "lint": "eslint --ext .js,.vue src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "test:ci": "npm run lint && npm run test:unit" + }, + "dependencies": { + "axios": "^0.18.1", + "body-parser": "^1.20.2", + "core-js": "3.6.5", + "cors": "^2.8.5", + "element-ui": "2.13.2", + "express": "^4.18.2", + "js-cookie": "2.2.0", + "mysql": "^2.18.1", + "mysql2": "^3.6.3", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "vue": "2.6.10", + "vue-router": "3.0.6", + "vuex": "3.1.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "4.4.4", + "@vue/cli-plugin-eslint": "4.4.4", + "@vue/cli-plugin-unit-jest": "4.4.4", + "@vue/cli-service": "4.4.4", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "9.5.1", + "babel-eslint": "10.1.0", + "babel-jest": "23.6.0", + "babel-plugin-dynamic-import-node": "2.3.3", + "chalk": "2.4.2", + "connect": "3.6.6", + "eslint": "6.7.2", + "eslint-plugin-vue": "6.2.2", + "html-webpack-plugin": "3.2.0", + "mockjs": "1.0.1-beta3", + "runjs": "4.3.2", + "sass": "1.26.8", + "sass-loader": "8.0.2", + "script-ext-html-webpack-plugin": "2.1.3", + "serve-static": "1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.2", + "vue-template-compiler": "2.6.10" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ], + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "license": "MIT" +} diff --git a/src/dxq-rjgcks/x-admin-web/postcss.config.js b/src/dxq-rjgcks/x-admin-web/postcss.config.js new file mode 100644 index 0000000..10473ef --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/postcss.config.js @@ -0,0 +1,8 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + 'plugins': { + // to edit target browsers: use "browserslist" field in package.json + 'autoprefixer': {} + } +} diff --git a/src/dxq-rjgcks/x-admin-web/public/favicon.ico b/src/dxq-rjgcks/x-admin-web/public/favicon.ico new file mode 100644 index 0000000..34b63ac Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/public/favicon.ico differ diff --git a/src/dxq-rjgcks/x-admin-web/public/index.html b/src/dxq-rjgcks/x-admin-web/public/index.html new file mode 100644 index 0000000..fa2be91 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + <%= webpackConfig.name %> + + + +
+ + + diff --git a/src/dxq-rjgcks/x-admin-web/src/App.vue b/src/dxq-rjgcks/x-admin-web/src/App.vue new file mode 100644 index 0000000..ec9032c --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/api/table.js b/src/dxq-rjgcks/x-admin-web/src/api/table.js new file mode 100644 index 0000000..0c7781b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/api/table.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +export function getList(params) { + return request({ + url: '/vue-admin-template/table/list', + method: 'get', + params + }) +} + +export function getEaWhat(params) { + return request({ + url: '/vue-admin-template/table/getEaWhat', + method: 'get', + params + }) +} + diff --git a/src/dxq-rjgcks/x-admin-web/src/api/user.js b/src/dxq-rjgcks/x-admin-web/src/api/user.js new file mode 100644 index 0000000..8ff4389 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/api/user.js @@ -0,0 +1,24 @@ +import request from '@/utils/request' + +export function login(data) { + return request({ + url: '/vue-admin-template/user/login', + method: 'post', + data + }) +} + +export function getInfo(token) { + return request({ + url: '/vue-admin-template/user/info', + method: 'get', + params: { token } + }) +} + +export function logout() { + return request({ + url: '/vue-admin-template/user/logout', + method: 'post' + }) +} diff --git a/src/dxq-rjgcks/x-admin-web/src/api/userapi.js b/src/dxq-rjgcks/x-admin-web/src/api/userapi.js new file mode 100644 index 0000000..35937c3 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/api/userapi.js @@ -0,0 +1,172 @@ +//userApi.js +var models = require('../db') +var express = require('express') +var router = express.Router() +var mysql = require('mysql') +var $sql = require('../sqlMap') + +// 连接数据库 +var conn = mysql.createConnection(models.mysql) + +conn.connect() +var jsonWrite = function (res, ret) { + if (typeof ret === 'undefined') { + res.json({ + code: '1', + msg: '操作失败' + }) + } else { + res.json(ret) + } +} + +// 左侧导航 +router.get('/addUser', (req, res) => { + var sql = $sql.leftList.search; + var params = req.body; + conn.query(sql, [params.loginname, params.password], function(err, result) { + if (err) { + console.log(err); + } + if (result) { + jsonWrite(res, result); + } + }) +}) + +// 全部 +router.get('/whole', (req, res) => { + var sql = $sql.whole.search; + var params = req.body; + conn.query(sql, [params.loginname, params.password], function(err, result) { + if (err) { + console.log(err); + } + if (result) { + jsonWrite(res, result); + } + }) +}) + +// 其他 +router.post('/project', (req, res) => { + var sql = $sql.project.search + var params = req.body + console.log(params) + console.log(sql); + + conn.query(sql, [params.name], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + + +// 根据某个项目查询系统详情信息 +router.post('/system', (req, res) => { + var sql = $sql.system.search + var params = req.body + console.log(params) + console.log(sql); + + conn.query(sql, [params.entryName], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + +// 根据某个项目查询系统列表信息 +router.post('/systemlist', (req, res) => { + var sql = $sql.systemlist.search + var params = req.body + console.log(sql); + console.log(params) + + conn.query(sql, [params.entryName], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + +// 根据项目名称查询系统入口 +router.post('/detail', (req, res) => { + var sql = $sql.detail.search + var params = req.body + console.log(params) + console.log(sql); + + conn.query(sql, [params.entryName], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + +// 根据ID查询所属领域 +router.post('/businessType', (req, res) => { + var sql = $sql.businessType.search + var params = req.body + console.log(params) + console.log(sql); + + conn.query(sql, [params.entryName], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + + +// 各业务领域下查询 +router.post('/getMessage', (req, res) => { + var sql = $sql.getMessage.search + var params = req.body + console.log(params) + console.log(sql); + + conn.query(sql, [params.oneName,params.twoName,params.NAME], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + + +// 全部情况下,根据项目或者系统名称查询项目 +router.post('/wholeproject', (req, res) => { + var sql = $sql.wholeproject.search + var params = req.body + console.log(params) + conn.query(sql, [params.entryName,params.entryName], function (err, result) { + if (err) { + console.log(err) + } + if (result) { + jsonWrite(res, result) + } + }) +}) + +module.exports = router + diff --git a/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404.png b/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404.png differ diff --git a/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404_cloud.png b/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/assets/404_images/404_cloud.png differ diff --git a/src/dxq-rjgcks/x-admin-web/src/assets/民航大学首页图.jpg b/src/dxq-rjgcks/x-admin-web/src/assets/民航大学首页图.jpg new file mode 100644 index 0000000..8aa1910 Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/assets/民航大学首页图.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/src/components/Breadcrumb/index.vue b/src/dxq-rjgcks/x-admin-web/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..29f9a04 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/components/Breadcrumb/index.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/components/Hamburger/index.vue b/src/dxq-rjgcks/x-admin-web/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/components/SvgIcon/index.vue b/src/dxq-rjgcks/x-admin-web/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..b07ded2 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/components/SvgIcon/index.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/pom.xml b/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/pom.xml new file mode 100644 index 0000000..466c250 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + org.example + dxs-rjgcks + 1.0-SNAPSHOT + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/src/main/java/org/example/Main.java b/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/src/main/java/org/example/Main.java new file mode 100644 index 0000000..3117fda --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/dxs-rjgcks/src/main/java/org/example/Main.java @@ -0,0 +1,7 @@ +package org.example; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/index.js b/src/dxq-rjgcks/x-admin-web/src/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/dashboard.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/example.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye-open.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/form.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/form.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/link.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/nested.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/password.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/password.svg new file mode 100644 index 0000000..e291d85 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/table.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/tree.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svg/user.svg b/src/dxq-rjgcks/x-admin-web/src/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/icons/svgo.yml b/src/dxq-rjgcks/x-admin-web/src/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/AppMain.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/AppMain.vue new file mode 100644 index 0000000..f6a3286 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/AppMain.vue @@ -0,0 +1,40 @@ + + + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Navbar.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Navbar.vue new file mode 100644 index 0000000..42201f0 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Navbar.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/FixiOSBug.js b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/FixiOSBug.js new file mode 100644 index 0000000..bc14856 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/FixiOSBug.js @@ -0,0 +1,26 @@ +export default { + computed: { + device() { + return this.$store.state.app.device + } + }, + mounted() { + // In order to fix the click on menu on the ios device will trigger the mouseleave bug + // https://github.com/PanJiaChen/vue-element-admin/issues/1135 + this.fixBugIniOS() + }, + methods: { + fixBugIniOS() { + const $subMenu = this.$refs.subMenu + if ($subMenu) { + const handleMouseleave = $subMenu.handleMouseleave + $subMenu.handleMouseleave = (e) => { + if (this.device === 'mobile') { + return + } + handleMouseleave(e) + } + } + } + } +} diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Item.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000..aa1f5da --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Item.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Link.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..530b3d5 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,43 @@ + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Logo.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..a0c3991 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/SidebarItem.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..a418c3d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/index.vue b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..da39034 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/Sidebar/index.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/components/index.js b/src/dxq-rjgcks/x-admin-web/src/layout/components/index.js new file mode 100644 index 0000000..97ee3cd --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/components/index.js @@ -0,0 +1,3 @@ +export { default as Navbar } from './Navbar' +export { default as Sidebar } from './Sidebar' +export { default as AppMain } from './AppMain' diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/index.vue b/src/dxq-rjgcks/x-admin-web/src/layout/index.vue new file mode 100644 index 0000000..db22a7b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/index.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/layout/mixin/ResizeHandler.js b/src/dxq-rjgcks/x-admin-web/src/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..e8d0df8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/layout/mixin/ResizeHandler.js @@ -0,0 +1,45 @@ +import store from '@/store' + +const { body } = document +const WIDTH = 992 // refer to Bootstrap's responsive design + +export default { + watch: { + $route(route) { + if (this.device === 'mobile' && this.sidebar.opened) { + store.dispatch('app/closeSideBar', { withoutAnimation: false }) + } + } + }, + beforeMount() { + window.addEventListener('resize', this.$_resizeHandler) + }, + beforeDestroy() { + window.removeEventListener('resize', this.$_resizeHandler) + }, + mounted() { + const isMobile = this.$_isMobile() + if (isMobile) { + store.dispatch('app/toggleDevice', 'mobile') + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_isMobile() { + const rect = body.getBoundingClientRect() + return rect.width - 1 < WIDTH + }, + $_resizeHandler() { + if (!document.hidden) { + const isMobile = this.$_isMobile() + store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') + + if (isMobile) { + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + } + } + } +} diff --git a/src/dxq-rjgcks/x-admin-web/src/main.js b/src/dxq-rjgcks/x-admin-web/src/main.js new file mode 100644 index 0000000..1193099 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/main.js @@ -0,0 +1,58 @@ +import Vue from 'vue' + + +import 'normalize.css/normalize.css' // A modern alternative to CSS resets + +import ElementUI from 'element-ui' +import 'element-ui/lib/theme-chalk/index.css' +import locale from 'element-ui/lib/locale/lang/en' // lang i18n + +import '@/styles/index.scss' // global css + +import App from './App' +import store from './store' +import router from './router' + +import '@/icons' // icon +import '@/permission' // permission control + +/** + * If you don't want to use mock-server + * you want to use MockJs for mock api + * you can execute: mockXHR() + * + * Currently MockJs will be used in the production environment, + * please remove it before going online ! ! ! + */ +if (process.env.NODE_ENV === 'production') { + const { mockXHR } = require('../mock') + mockXHR() +} + +// set ElementUI lang to EN +Vue.use(ElementUI, { locale }) +// 如果想要中文版 element-ui,按如下方式声明 +// Vue.use(ElementUI) + +Vue.config.productionTip = false + +Vue.prototype.$myGlobalVariable = { + age: '20', + weight: '65', + height: '175', + selectedSex: '0', + selectedActivity: '1', + calories:'', + protein:'', + carb:'', + fat:'', + BMR:'', + +}; + +new Vue({ + el: '#app', + router, + store, + render: h => h(App) +}) diff --git a/src/dxq-rjgcks/x-admin-web/src/permission.js b/src/dxq-rjgcks/x-admin-web/src/permission.js new file mode 100644 index 0000000..fa1ea19 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/permission.js @@ -0,0 +1,64 @@ +import router from './router' +import store from './store' +import { Message } from 'element-ui' +import NProgress from 'nprogress' // progress bar +import 'nprogress/nprogress.css' // progress bar style +import { getToken } from '@/utils/auth' // get token from cookie +import getPageTitle from '@/utils/get-page-title' + +NProgress.configure({ showSpinner: false }) // NProgress Configuration + +const whiteList = ['/login'] // no redirect whitelist + +router.beforeEach(async(to, from, next) => { + // start progress bar + NProgress.start() + + // set page title + document.title = getPageTitle(to.meta.title) + + // determine whether the user has logged in + const hasToken = getToken() + + if (hasToken) { + if (to.path === '/login') { + // if is logged in, redirect to the home page + next({ path: '/' }) + NProgress.done() + } else { + const hasGetUserInfo = store.getters.name + if (hasGetUserInfo) { + next() + } else { + try { + // get user info + await store.dispatch('user/getInfo') + + next() + } catch (error) { + // remove token and go to login page to re-login + await store.dispatch('user/resetToken') + Message.error(error || 'Has Error') + next(`/login?redirect=${to.path}`) + NProgress.done() + } + } + } + } else { + /* has no token*/ + + if (whiteList.indexOf(to.path) !== -1) { + // in the free login whitelist, go directly + next() + } else { + // other pages that do not have permission to access are redirected to the login page. + next(`/login?redirect=${to.path}`) + NProgress.done() + } + } +}) + +router.afterEach(() => { + // finish progress bar + NProgress.done() +}) diff --git a/src/dxq-rjgcks/x-admin-web/src/router/index.js b/src/dxq-rjgcks/x-admin-web/src/router/index.js new file mode 100644 index 0000000..273ba41 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/router/index.js @@ -0,0 +1,199 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +/* Layout */ +import Layout from '@/layout' + +/** + * Note: sub-menu only appear when route children.length >= 1 + * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html + * + * hidden: true if set true, item will not show in the sidebar(default is false) + * alwaysShow: true if set true, will always show the root menu + * if not set alwaysShow, when item has more than one children route, + * it will becomes nested mode, otherwise not show the root menu + * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb + * name:'router-name' the name is used by (must set!!!) + * meta : { + roles: ['admin','editor'] control the page roles (you can set multiple roles) + title: 'title' the name show in sidebar and breadcrumb (recommend set) + icon: 'svg-name'/'el-icon-x' the icon show in the sidebar + breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) + activeMenu: '/example/list' if set path, the sidebar will highlight the path you set + } + */ + +/** + * constantRoutes + * a base page that does not have permission requirements + * all roles can be accessed + */ +export const constantRoutes = [ + { + path: '/login', + component: () => import('@/views/login/index'), + hidden: true + }, + + { + path: '/404', + component: () => import('@/views/404'), + hidden: true + }, + + { + path: '/', + component: Layout, + redirect: '/dashboard', + children: [{ + path: 'dashboard', + name: 'Dashboard', + component: () => import('@/views/dashboard/index'), + meta: { title: '首页', icon: 'dashboard' } + }] + }, + + { + // 治理定义左边这栏菜单 + path: '/sys', + component: Layout, + redirect: '/sys/user', + name: 'sysManage', + meta: { title: '饮食规划', icon: 'el-icon-s-help' }, + // 上边的右边是图标,图标要svg格式先不管 + children: [ + // children是二级菜单 + { + path: 'user', + name: '个人信息', + component: () => import('@/views/table/index'), + // 上面是点开后导引到哪个文件 + meta: { title: '个人信息', icon: 'table' } + }, + { + path: 'table', + name: '生成菜谱', + component: () => import('@/views/sys/user2'), + // 上面是点开后导引到哪个文件 + meta: { title: '饮食建议', icon: 'table' } + }, + { + path: 'tree', + name: '查看菜谱', + component: () => import('@/views/tree'), + meta: { title: '每日菜谱', icon: 'tree' } + } + + + ] + }, + + // { + // path: '/form', + // component: Layout, + // children: [ + // { + // path: 'index', + // name: 'Form', + // component: () => import('@/views/form/index'), + // meta: { title: 'Form', icon: 'form' } + // } + // ] + // }, + + { + path: '/nested', + component: Layout, + redirect: '/nested/menu1', + name: 'Nested', + meta: { title: '菜品搜索', icon: 'nested' }, + children: [ + { + path: 'menu1', + component: () => import('@/views/nested/menu1/index'), + name: 'Menu1', + meta: { title: '面食' } + }, + { + path: 'menu4', + component: () => import('@/views/nested/menu4/index'), + name: 'Menu4', + meta: { title: '炒菜' }, + }, + { + path: 'menu3', + component: () => import('@/views/nested/menu3/index'), + name: 'Menu3', + meta: { title: '饮品' } + }, + { + path: 'menu5', + component: () => import('@/views/nested/menu5/index'), + name: 'Menu5', + meta: { title: '其它' } + }, + { + path: 'menu2', + component: () => import('@/views/nested/menu2/index'), + name: 'Menu2', + meta: { title: '直接搜索' } + } + ] + }, + + { + path: '/form', + component: Layout, + children: [ + { + path: 'index', + name: 'Form', + component: () => import('@/views/form/index'), + meta: { title: '修改菜品数据', icon: 'form' } + } + ] + }, + { + path: '/form', + component: Layout, + children: [ + { + path: 'id', + name: 'Form', + component: () => import('@/views/form/id'), + meta: { title: '评价反馈', icon: 'form' } + } + ] + }, + // { + // path: 'external-link', + // component: Layout, + // children: [ + // { + // path: 'https://panjiachen.github.io/vue-element-admin-site/#/', + // meta: { title: 'External Link', icon: 'link' } + // } + // ] + // }, + + // 404 page must be placed at the end !!! + { path: '*', redirect: '/404', hidden: true } +] + +const createRouter = () => new Router({ + // mode: 'hash', // require service support + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes +}) + +const router = createRouter() + +// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 +export function resetRouter() { + const newRouter = createRouter() + router.matcher = newRouter.matcher // reset router +} + +export default router diff --git a/src/dxq-rjgcks/x-admin-web/src/server/db.js b/src/dxq-rjgcks/x-admin-web/src/server/db.js new file mode 100644 index 0000000..a85d75d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/server/db.js @@ -0,0 +1,11 @@ +// 数据库连接配置 db.js +module.exports = { + mysql: { + host: '192.168.×××.××',//mysql连接ip地址 + user: '***', + password: '***',//mySql用户名密码 + database: '***',//mySql数据库名 + port: '3306'//mysql连接端口 + } + } + diff --git a/src/dxq-rjgcks/x-admin-web/src/server/index.js b/src/dxq-rjgcks/x-admin-web/src/server/index.js new file mode 100644 index 0000000..0f4d767 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/server/index.js @@ -0,0 +1,20 @@ +// node 后端服务器 + +const userApi = require('./api/userApi'); +const fs = require('fs'); +const path = require('path'); +const bodyParser = require('body-parser'); +const express = require('express'); +const app = express(); + +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: false})); + +// 后端api路由 +app.use('/api', userApi); + +// 监听端口 +app.listen(3306); + +console.log('success listen at port:3000......'); + diff --git a/src/dxq-rjgcks/x-admin-web/src/server/sqlMap.js b/src/dxq-rjgcks/x-admin-web/src/server/sqlMap.js new file mode 100644 index 0000000..ccb9264 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/server/sqlMap.js @@ -0,0 +1,14 @@ +//sqlMap.js +var sqlMap = { + leftList: { + search:'SELECT `NAME`,SORT,PATH,ICON FROM BUSINESS_AREA ORDER BY SORT;' + }, + whole:{ + search:'SELECT * FROM PROJECT where area_id in (SELECT area_id from BUSINESS_AREA)' + }, + project:{ + search:'SELECT * FROM PROJECT where area_id = (SELECT area_id from BUSINESS_AREA where name=?)' + }, + } + module.exports = sqlMap; + diff --git a/src/dxq-rjgcks/x-admin-web/src/settings.js b/src/dxq-rjgcks/x-admin-web/src/settings.js new file mode 100644 index 0000000..d5131e5 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/settings.js @@ -0,0 +1,16 @@ +module.exports = { + + title: '民航大学营养菜谱生成系统', + + /** + * @type {boolean} true | false + * @description Whether fix the header + */ + fixedHeader: false, + + /** + * @type {boolean} true | false + * @description Whether show the logo in sidebar + */ + sidebarLogo: false +} diff --git a/src/dxq-rjgcks/x-admin-web/src/store/getters.js b/src/dxq-rjgcks/x-admin-web/src/store/getters.js new file mode 100644 index 0000000..5ab7b4c --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/store/getters.js @@ -0,0 +1,8 @@ +const getters = { + sidebar: state => state.app.sidebar, + device: state => state.app.device, + token: state => state.user.token, + avatar: state => state.user.avatar, + name: state => state.user.name +} +export default getters diff --git a/src/dxq-rjgcks/x-admin-web/src/store/index.js b/src/dxq-rjgcks/x-admin-web/src/store/index.js new file mode 100644 index 0000000..6be466a --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/store/index.js @@ -0,0 +1,19 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import getters from './getters' +import app from './modules/app' +import settings from './modules/settings' +import user from './modules/user' + +Vue.use(Vuex) + +const store = new Vuex.Store({ + modules: { + app, + settings, + user + }, + getters +}) + +export default store diff --git a/src/dxq-rjgcks/x-admin-web/src/store/modules/app.js b/src/dxq-rjgcks/x-admin-web/src/store/modules/app.js new file mode 100644 index 0000000..7ea7e33 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/store/modules/app.js @@ -0,0 +1,48 @@ +import Cookies from 'js-cookie' + +const state = { + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + withoutAnimation: false + }, + device: 'desktop' +} + +const mutations = { + TOGGLE_SIDEBAR: state => { + state.sidebar.opened = !state.sidebar.opened + state.sidebar.withoutAnimation = false + if (state.sidebar.opened) { + Cookies.set('sidebarStatus', 1) + } else { + Cookies.set('sidebarStatus', 0) + } + }, + CLOSE_SIDEBAR: (state, withoutAnimation) => { + Cookies.set('sidebarStatus', 0) + state.sidebar.opened = false + state.sidebar.withoutAnimation = withoutAnimation + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device + } +} + +const actions = { + toggleSideBar({ commit }) { + commit('TOGGLE_SIDEBAR') + }, + closeSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + toggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/src/dxq-rjgcks/x-admin-web/src/store/modules/settings.js b/src/dxq-rjgcks/x-admin-web/src/store/modules/settings.js new file mode 100644 index 0000000..b3f33f8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/store/modules/settings.js @@ -0,0 +1,32 @@ +import defaultSettings from '@/settings' + +const { showSettings, fixedHeader, sidebarLogo } = defaultSettings + +const state = { + showSettings: showSettings, + fixedHeader: fixedHeader, + sidebarLogo: sidebarLogo +} + +const mutations = { + CHANGE_SETTING: (state, { key, value }) => { + // eslint-disable-next-line no-prototype-builtins + if (state.hasOwnProperty(key)) { + state[key] = value + } + } +} + +const actions = { + changeSetting({ commit }, data) { + commit('CHANGE_SETTING', data) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/src/dxq-rjgcks/x-admin-web/src/store/modules/user.js b/src/dxq-rjgcks/x-admin-web/src/store/modules/user.js new file mode 100644 index 0000000..2f6423f --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/store/modules/user.js @@ -0,0 +1,97 @@ +import { login, logout, getInfo } from '@/api/user' +import { getToken, setToken, removeToken } from '@/utils/auth' +import { resetRouter } from '@/router' + +const getDefaultState = () => { + return { + token: getToken(), + name: '', + avatar: '' + } +} + +const state = getDefaultState() + +const mutations = { + RESET_STATE: (state) => { + Object.assign(state, getDefaultState()) + }, + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_NAME: (state, name) => { + state.name = name + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + } +} + +const actions = { + // user login + login({ commit }, userInfo) { + const { username, password } = userInfo + return new Promise((resolve, reject) => { + login({ username: username.trim(), password: password }).then(response => { + const { data } = response + commit('SET_TOKEN', data.token) + setToken(data.token) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // get user info + getInfo({ commit, state }) { + return new Promise((resolve, reject) => { + getInfo(state.token).then(response => { + const { data } = response + + if (!data) { + return reject('Verification failed, please Login again.') + } + + const { name, avatar } = data + + commit('SET_NAME', name) + commit('SET_AVATAR', avatar) + resolve(data) + }).catch(error => { + reject(error) + }) + }) + }, + + // user logout + logout({ commit, state }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + removeToken() // must remove token first + resetRouter() + commit('RESET_STATE') + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // remove token + resetToken({ commit }) { + return new Promise(resolve => { + removeToken() // must remove token first + commit('RESET_STATE') + resolve() + }) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/element-ui.scss b/src/dxq-rjgcks/x-admin-web/src/styles/element-ui.scss new file mode 100644 index 0000000..0062411 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/element-ui.scss @@ -0,0 +1,49 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// to fix el-date-picker css style +.el-range-separator { + box-sizing: content-box; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/index.scss b/src/dxq-rjgcks/x-admin-web/src/styles/index.scss new file mode 100644 index 0000000..3b4da51 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/index.scss @@ -0,0 +1,65 @@ +@import './variables.scss'; +@import './mixin.scss'; +@import './transition.scss'; +@import './element-ui.scss'; +@import './sidebar.scss'; + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +// main-container global css +.app-container { + padding: 20px; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/mixin.scss b/src/dxq-rjgcks/x-admin-web/src/styles/mixin.scss new file mode 100644 index 0000000..36b74bb --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/mixin.scss @@ -0,0 +1,28 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/sidebar.scss b/src/dxq-rjgcks/x-admin-web/src/styles/sidebar.scss new file mode 100644 index 0000000..94760cc --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/sidebar.scss @@ -0,0 +1,226 @@ +#app { + + .main-container { + min-height: 100%; + transition: margin-left .28s; + margin-left: $sideBarWidth; + position: relative; + } + + .sidebar-container { + transition: width 0.28s; + width: $sideBarWidth !important; + background-color: $menuBg; + height: 100%; + position: fixed; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + + // reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0px; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .svg-icon { + margin-right: 16px; + } + + .sub-el-icon { + margin-right: 12px; + margin-left: -2px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + // menu hover + .submenu-title-noDropdown, + .el-submenu__title { + &:hover { + background-color: $menuHover !important; + } + } + + .is-active>.el-submenu__title { + color: $subMenuActiveText !important; + } + + & .nest-menu .el-submenu>.el-submenu__title, + & .el-submenu .el-menu-item { + min-width: $sideBarWidth !important; + background-color: $subMenuBg !important; + + &:hover { + background-color: $subMenuHover !important; + } + } + } + + .hideSidebar { + .sidebar-container { + width: 54px !important; + } + + .main-container { + margin-left: 54px; + } + + .submenu-title-noDropdown { + padding: 0 !important; + position: relative; + + .el-tooltip { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + + .sub-el-icon { + margin-left: 19px; + } + } + } + + .el-submenu { + overflow: hidden; + + &>.el-submenu__title { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + + .sub-el-icon { + margin-left: 19px; + } + + .el-submenu__icon-arrow { + display: none; + } + } + } + + .el-menu--collapse { + .el-submenu { + &>.el-submenu__title { + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + .el-menu--collapse .el-menu .el-submenu { + min-width: $sideBarWidth !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform .28s; + width: $sideBarWidth !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$sideBarWidth, 0, 0); + } + } + } + + .withoutAnimation { + + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + &>.el-menu { + .svg-icon { + margin-right: 16px; + } + .sub-el-icon { + margin-right: 12px; + margin-left: -2px; + } + } + + .nest-menu .el-submenu>.el-submenu__title, + .el-menu-item { + &:hover { + // you can use $subMenuHover + background-color: $menuHover !important; + } + } + + // the scroll bar appears when the subMenu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } +} diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/transition.scss b/src/dxq-rjgcks/x-admin-web/src/styles/transition.scss new file mode 100644 index 0000000..4cb27cc --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/transition.scss @@ -0,0 +1,48 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/styles/variables.scss b/src/dxq-rjgcks/x-admin-web/src/styles/variables.scss new file mode 100644 index 0000000..be55772 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/styles/variables.scss @@ -0,0 +1,25 @@ +// sidebar +$menuText:#bfcbd9; +$menuActiveText:#409EFF; +$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 + +$menuBg:#304156; +$menuHover:#263445; + +$subMenuBg:#1f2d3d; +$subMenuHover:#001528; + +$sideBarWidth: 210px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuText: $menuText; + menuActiveText: $menuActiveText; + subMenuActiveText: $subMenuActiveText; + menuBg: $menuBg; + menuHover: $menuHover; + subMenuBg: $subMenuBg; + subMenuHover: $subMenuHover; + sideBarWidth: $sideBarWidth; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/auth.js b/src/dxq-rjgcks/x-admin-web/src/utils/auth.js new file mode 100644 index 0000000..059af18 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/auth.js @@ -0,0 +1,15 @@ +import Cookies from 'js-cookie' + +const TokenKey = 'vue_admin_template_token' + +export function getToken() { + return Cookies.get(TokenKey) +} + +export function setToken(token) { + return Cookies.set(TokenKey, token) +} + +export function removeToken() { + return Cookies.remove(TokenKey) +} diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/base.js b/src/dxq-rjgcks/x-admin-web/src/utils/base.js new file mode 100644 index 0000000..5c47a38 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/base.js @@ -0,0 +1,712 @@ +/** + * @desc 工具类对象 + * @param obj 对象 + * @returns true||false + */ +var Tools = { + isArray: function (obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }, + isObject: function (obj) { + return Object.prototype.toString.call(obj) === "[object Object]"; + }, + isNumber: function (obj) { + return Object.prototype.toString.call(obj) === "[object Number]"; + }, + isString: function (obj) { + return Object.prototype.toString.call(obj) === "[object String]"; + }, + isFunction: function (obj) { + return Object.prototype.toString.call(obj) === "[object Function]"; + }, + isBoolean: function (obj) { + return Object.prototype.toString.call(obj) === "[object Boolean]"; + }, + isNull: function (obj) { + return obj == null || obj == "" || obj == undefined; + }, + isNotNull: function (obj) { + return !this.isNull(obj); + }, + randomNum(min, max) { + return Math.floor(min + Math.random() * (max - min)); + }, +}; + +/** + * @desc 获取系统根路径 + */ +function getRootPath() { + // 获取当前网址,如: http://localhost:8083/uimcardprj/share/meun.jsp + var curWwwPath = window.document.location.href; + // 获取主机地址之后的目录,如: uimcardprj/share/meun.jsp + var pathName = window.document.location.pathname; + var pos = curWwwPath.indexOf(pathName); + // 获取主机地址,如: http://localhost:8083 + var localhostPaht = curWwwPath.substring(0, pos); + // 获取带"/"的项目名,如:/uimcardprj + var projectName = pathName.substring( + 0, + pathName.substring(1).indexOf("/") + 1 + ); + //return (localhostPaht + projectName + "/"); + return localhostPaht; +} + +/** + * @desc 获取访问路径中某个参数 + * @param paramName 参数名 + * @param url 指定要截取参数的url(可以为空,如果为空url指向当前页面) + */ +function getParamter(paramName, url) { + var seachUrl = window.location.search.replace("?", ""); + if (url != null) { + var index = url.indexOf("?"); + url = url.substr(index + 1); + seachUrl = url; + } + var ss = seachUrl.split("&"); + var paramNameStr = ""; + var paramNameIndex = -1; + for (var i = 0; i < ss.length; i++) { + paramNameIndex = ss[i].indexOf("="); + paramNameStr = ss[i].substring(0, paramNameIndex); + if (paramNameStr == paramName) { + var returnValue = ss[i].substring(paramNameIndex + 1, ss[i].length); + if (typeof returnValue == "undefined") { + returnValue = ""; + } + return returnValue; + } + } + return ""; +} + +/** + * + * @desc 判断两个数组是否相等 + * @param {Array} arr1 + * @param {Array} arr2 + * @return {Boolean} + */ +function arrayEqual(arr1, arr2) { + if (arr1 === arr2) return true; + if (arr1.length != arr2.length) return false; + for (var i = 0; i < arr1.length; ++i) { + if (arr1[i] !== arr2[i]) return false; + } + return true; +} + +/** + * + * @desc 数组去重 + * @param {Array} arr + */ +function removeDupthird(arr) { + var newArr = []; + var obj = {}; + for (var i = 0; i < arr.length; i++) { + obj[arr[i]] = arr[i]; + } + var list = []; + for (var i in obj) { + list.push(i); + } + return list; +} + +/** + * + * @desc 获取浏览器类型和版本 + * @return {String} + */ +function getExplore() { + var sys = {}, + ua = navigator.userAgent.toLowerCase(), + s; + (s = ua.match(/rv:([\d.]+)\) like gecko/)) + ? (sys.ie = s[1]) + : (s = ua.match(/msie ([\d\.]+)/)) + ? (sys.ie = s[1]) + : (s = ua.match(/edge\/([\d\.]+)/)) + ? (sys.edge = s[1]) + : (s = ua.match(/firefox\/([\d\.]+)/)) + ? (sys.firefox = s[1]) + : (s = ua.match(/(?:opera|opr).([\d\.]+)/)) + ? (sys.opera = s[1]) + : (s = ua.match(/chrome\/([\d\.]+)/)) + ? (sys.chrome = s[1]) + : (s = ua.match(/version\/([\d\.]+).*safari/)) + ? (sys.safari = s[1]) + : 0; + // 根据关系进行判断 + if (sys.ie) return "IE: " + sys.ie; + if (sys.edge) return "EDGE: " + sys.edge; + if (sys.firefox) return "Firefox: " + sys.firefox; + if (sys.chrome) return "Chrome: " + sys.chrome; + if (sys.opera) return "Opera: " + sys.opera; + if (sys.safari) return "Safari: " + sys.safari; + return "Unkonwn"; +} + +/** + * @desc JS日期格式化转换方法 + * @param fmt 日期时间的格式 + * + * 调用方法 + * 获取当前时间 var time1 = new Date().format("yyyy-MM-dd hh:mm:ss"); console.log(time1); // 2017-12-08 11:55:30 + * 将指定的日期转换为"年月日"的格式 + var oldTime = (new Date("2012/12/25 20:11:11")).getTime(); + var curTime = new Date(oldTime).format("yyyy-MM-dd"); + console.log(curTime); // 2012-12-25 + * 将 "时间戳" 转换为 "年月日" 的格式 + var da = 1402233166999; + da = new Date(da); + var year = da.getFullYear()+'年'; + var month = da.getMonth()+1+'月'; + var date = da.getDate()+'日'; + console.log([year,month,date].join('-')); // 2014年-6月-8日 + * 详情参考 https://www.cnblogs.com/tugenhua0707/p/3776808.html + */ +Date.prototype.format = function (fmt) { + var o = { + "M+": this.getMonth() + 1, //月份 + "d+": this.getDate(), //日 + "h+": this.getHours(), //小时 + "m+": this.getMinutes(), //分 + "s+": this.getSeconds(), //秒 + "q+": Math.floor((this.getMonth() + 3) / 3), //季度 + S: this.getMilliseconds(), //毫秒 + }; + if (/(y+)/.test(fmt)) { + fmt = fmt.replace( + RegExp.$1, + (this.getFullYear() + "").substr(4 - RegExp.$1.length) + ); + } + for (var k in o) { + if (new RegExp("(" + k + ")").test(fmt)) { + fmt = fmt.replace( + RegExp.$1, + RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) + ); + } + } + return fmt; +}; + +//api公共工具类 +export function getUrl(url, params) { + if (params) { + Object.keys(params).map((key, index) => { + const pre = index == 0 ? "?" : "&"; + let val = params[key]; + if (val == null) val = ""; + url += `${pre}${key}=${val}`; + }); + } + return url; + } + +/** + * Parse the time to string + * @param {(Object|string|number)} time + * @param {string} cFormat + * @returns {string | null} + */ +export function parseTime (time, cFormat) { + if (arguments.length === 0 || !time) { + return null + } + const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string')) { + if ((/^[0-9]+$/.test(time))) { + // support "1548221490638" + time = parseInt(time) + } else { + // support safari + // https://stackoverflow.com/questions/4310953/invalid-date-in-safari + time = time.replace(new RegExp(/-/gm), '/') + } + } + + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { + const value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } + return value.toString().padStart(2, '0') + }) + return time_str +} + +//设置cookie +export function setCookie(name, value, day) { + let date = new Date(); + date.setDate(date.getDate() + day); + document.cookie = name + '=' + value + ';expires=' + date; +} +// 获取cookie +export function getCookie(name) { + let reg = RegExp(name + '=([^;]+)'); + let arr = document.cookie.match(reg); + if (arr) { + return arr[1]; + } else { + return ''; + } +} + +// 深拷贝 +export function deepClone (obj) { + let objClone = Array.isArray(obj) ? [] : {}; + if (obj && typeof obj === "object") { + for (let key in obj) { + //判断ojb子元素是否为对象,如果是,递归复制 + if (obj[key] && typeof obj[key] === "object") { + objClone[key] = deepClone(obj[key]); + } else { + //如果不是,简单复制 + objClone[key] = obj[key]; + } + } + } + return objClone; +} +export function getNowTime() { + let date = new Date() + let year = date.getFullYear() + let month = date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 + let dates = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + let hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + let minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + let second = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() + let milliSeconds = date.getMilliseconds() + let currentTime = `${year}${month}${dates}${hour}${minute}${second}${milliSeconds}` + this.formData.name = currentTime + }, +/**防抖: n秒后执行,n秒内触发重新定时 + * + * @param {*} fn + * @param {*} wait + * @param {*} opts {key: 手动赋予key值,或自定义key值前缀, customKey: 自定义key值计算方法,参数为函数参数数组[...arguments]} + * @returns func 防抖函数,只需代入参数执行 + */ + export function debounce(fn, wait, opts = {}) { + let timer = {}; + let key = opts.key || Math.random().toString(36).slice(2); + return function () { + let isCustom = Boolean(opts.customKey); + let index = isCustom + ? opts.key + "." + opts.customKey([...arguments]) + : key; + clearTimeout(timer[index]); + timer[index] = setTimeout(() => { + fn.call(this, ...arguments); + }, wait); + }; + } + +// 请求出错提示框(包含重新登录操作) +export function errorTip(errMsg) { + openPromptBox('error', errMsg +'!').then(() => { + if (errMsg == '用户登录信息过期,请重新登录'){ + store.dispatch('user/logout'); + store.dispatch('setting/removeUrls'); + router.push('/'); + } + }).catch(() => {}); +} + +// 总毫秒转时分秒 +export function changeTime(val){ + let day= Math.floor(val/1000/60/60/24) + let hour= Math.floor(val/1000/60/60-(day*24)) + let min= Math.floor(val/1000/60- (24 * 60 * day) - (60 * hour)) + let second= Math.floor(val/1000-(24 * 60 * 60 * day) - (60 * 60 * hour) - (60 * min)) + return `${day}天${hour}时${min}分${second}秒` + } + + var fun = { + + //#region 数组操作 + // 判断是否为数组 + isArray: function (arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + }, + + // 数组去重,只考虑数组中元素为数字或者字符串 + newarr: function (arr) { + var arrs = []; + for (var i = 0; i < arr.length; i++) { + if (arrs.indexOf(arr[i]) == -1) { + arrs.push(arr[i]) + } + } + return arrs; + }, + + // 数组去重 + removeRepeatArray: function (arr) { + return Array.from(new Set(arr)) + }, + + // 数组filter(搜索功能) + filterItems: function (arr, str) { + return arr.filter(function (el) { + return el.toLowerCase().indexOf(str.toLowerCase()) > -1; + }) + }, + + // 判断数组是否包含某个元素 + contains: function (arr,val) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == val) { + return true; + } + } + return false; + }, + + // 返回数组(字符串)一个元素出现的次数 + getEleCount(arr, str) { + var num = 0; + for (var i = 0, len = arr.length; i < len; i++) { + if (str == arr[i]) { + num++; + } + } + return num; + }, + //#endregion + + //#region 对象 + // 清空对象为空的数据 + filterParams: function (obj) { + let _newPar = {}; + for (let key in obj) { + if ((obj[key] === 0 || obj[key]) && obj[key].toString().replace(/(^\s*)|(\s*$)/g, '') !== '') { + _newPar[key] = obj[key]; + } + } + return _newPar; + }, + + // 判断对象是否含有为空的数据 + filterParams2: function (obj) { + let _newPar = {}; + for (let key in obj) { + if ((obj[key] === 0 || obj[key]) && obj[key].toString().replace(/(^\s*)|(\s*$)/g, '') !== '') { + _newPar[key] = obj[key]; + } + } + return _newPar; + }, + + //#endregion + + //#region 字符串操作 + // 去除字符串空格(type 1-所有空格 2-前后空格 3-前空格 4-后空格) + trim: function (str) { + switch (type) { + case 1: return str.replace(/\s+/g, ""); + case 2: return str.replace(/(^\s*)|(\s*$)/g, ""); + case 3: return str.replace(/(^\s*)/g, ""); + case 4: return str.replace(/(\s*$)/g, ""); + default: return str; + } + }, + + // 字母大小写切换(type: 1:首字母大写 2:首页母小写 3:大小写转换 4:全部大写 5:全部小写) + changeCase: function (str, type) { + function ToggleCase(str) { + var itemText = "" + str.split("").forEach( + function (item) { + if (/^([a-z]+)/.test(item)) { + itemText += item.toUpperCase(); + } + else if (/^([A-Z]+)/.test(item)) { + itemText += item.toLowerCase(); + } + else { + itemText += item; + } + }); + return itemText; + } + + switch (type) { + case 1: + return str.replace(/^(\w)(\w+)/, function (v, v1, v2) { + return v1.toUpperCase() + v2.toLowerCase(); + }); + case 2: + return str.replace(/^(\w)(\w+)/, function (v, v1, v2) { + return v1.toLowerCase() + v2.toUpperCase(); + }); + case 3: + return ToggleCase(str); + case 4: + return str.toUpperCase(); + case 5: + return str.toLowerCase(); + default: + return str; + } + }, + + // 字符串循环复制 + repeatStr: function (str, count) { + var text = ''; + for (var i = 0; i < count; i++) { + text += str; + } + return text; + }, + + //字符串替换(str:字符串,AFindText:要替换的字符,ARepText:替换成什么) + replaceAll: function (str, AFindText, ARepText) { + raRegExp = new RegExp(AFindText, "g"); + return str.replace(raRegExp, ARepText); + }, + + // 随机码 + randomNumber: function (count) { + return Math.random().toString(count).substring(2); + }, + //#endregion + + //#region 时间 + // 倒计时 -》"剩余时间6天 2小时 28 分钟20 秒" + getEndTime: function (endTime) { + var startDate = new Date(); //开始时间,当前时间 + var endDate = new Date(endTime); //结束时间,需传入时间参数 + var t = endDate.getTime() - startDate.getTime(); //时间差的毫秒数 + var d = 0, h = 0, m = 0, s = 0; + if (t >= 0) { + d = Math.floor(t / 1000 / 3600 / 24); + h = Math.floor(t / 1000 / 60 / 60 % 24); + m = Math.floor(t / 1000 / 60 % 60); + s = Math.floor(t / 1000 % 60); + } + return "剩余时间" + d + "天 " + h + "小时 " + m + " 分钟" + s + " 秒"; + }, + + // 时间戳转换时间格式(YY-MM-DD hh:mm:ss) 2021-10-10 10:23:56 + timestampToTim: function (timestamp) { + var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000 + Y = date.getFullYear() + '-'; + M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; + D = date.getDate() + ' '; + h = date.getHours() + ':'; + m = date.getMinutes() + ':'; + s = date.getSeconds(); + return Y + M + D + h + m + s; + }, + + // 获取当月的天数 + getDateCount:function () { + const date = new Date(); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const days = new Date(year, month, 0); + return days.getDate() + }, + + // 获取本月所有日期 + getDate:function() { + let now = new Date(); + let current_month_num = mGetDate(); + let current_month = []; + for (let i = 1; i <= current_month_num; i++) { + let day = now.setDate(i); + let everyDay = formatMonth(day); + current_month.push(everyDay); + } + return current_month; + }, + + + + + //#endregion + + //#region 格式验证 + /**格式验证 + * identity:身份证 + * email=邮箱 + * phone:手机号 + * tel:电话号, + * number:数字 + * english:字母 + * chinese:中文 + * lower:小写字母 + * upper:大写 + * IPv4地址:ip地址 + */ + checkType: function (str, type) { + switch (type) { + case 'identity': + return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str); + case 'email': + return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str); + case 'phone': + return /^1[3|4|5|7|8][0-9]{9}$/.test(str); + case 'tel': + return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str); + case 'number': + return /^[0-9]$/.test(str); + case 'english': + return /^[a-zA-Z]+$/.test(str); + case 'chinese': + return /^[\u4E00-\u9FA5]+$/.test(str); + case 'lower': + return /^[a-z]+$/.test(str); + case 'upper': + return /^[A-Z]+$/.test(str); + case 'ip': + return /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/.test(str); + default: + return true; + } + }, + + // 密码强度(1、2、3) + checkPwd: function (str) { + var nowLv = 0; + if (str.length < 6) { + return nowLv + } + ; + if (/[0-9]/.test(str)) { + nowLv++ + } + ; + if (/[a-z]/.test(str)) { + nowLv++ + } + ; + if (/[A-Z]/.test(str)) { + nowLv++ + } + ; + if (/[\.|-|_]/.test(str)) { + nowLv++ + } + ; + return nowLv; + }, + + //#endregion + + //#region 适配 rem + getFontSize: function () { + var doc = document, win = window; + var docEl = doc.documentElement, + resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', + recalc = function () { + var clientWidth = docEl.clientWidth; + if (!clientWidth) return; + //如果屏幕大于750(750是根据我效果图设置的,具体数值参考效果图),就设置clientWidth=750,防止font-size会超过100px + if (clientWidth > 750) { clientWidth = 750 } + //设置根元素font-size大小 + docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'; + }; + //屏幕大小改变,或者横竖屏切换时,触发函数 + win.addEventListener(resizeEvt, recalc, false); + //文档加载完成时,触发函数 + doc.addEventListener('DOMContentLoaded', recalc, false); + }, + //使用方式很简单,比如效果图上,有张图片。宽高都是100px; + //样式写法就是 + // img{ + // width:1rem; + // height: 1rem; + // } + //这样的设置,比如在屏幕宽度大于等于750px设备上,1rem=100px;图片显示就是宽高都是100px + //比如在iphone6(屏幕宽度:375)上,375/750*100=50px;就是1rem=50px;图片显示就是宽高都是50px; + + + //#endregion + + //#region 文件操作类 + // 获取文件名 + getFileName: function (fileName) { + var pos = fileName.lastIndexOf("."); + if (pos == -1) { + return fileName; + } else { + return fileName.substring(pos, fileName.length); + } + }, + + // 获取文件后缀名 + getExt: function (fileName) { + if (fileName.lastIndexOf(".") == -1) + return fileName; + var pos = fileName.lastIndexOf(".") + 1; + return fileName.substring(pos, fileName.length).toLowerCase(); + }, + + // 验证是否为图片 + tmCheckImage: function (fileName) { + return /(gif|jpg|jpeg|png|GIF|JPG|PNG)$/ig.test(fileName); + }, + + // 验证是否为视频 + tmCheckVideo: function (fileName) { + return /(mp4|mp3|flv|wav)$/ig.test(fileName); + }, + + /*验证是否为文档*/ + tmCheckDocument: function (fileName) { + + return /(doc|docx|xls|xlsx|pdf|txt|ppt|pptx|rar|zip|html|jsp|sql|htm|shtml|xml)$/ig.test(fileName); + }, + + + //#endregion + + //#region 网络请求 + // 将 url 中的参数解析为一个对象 + getUrlPrmt: function (url) { + var str = url.split('?')[1]; + var result = {}; + var temp = str.split('&'); + for (var i = 0; i < temp.length; i++) { + var temp2 = temp[i].split('='); + result[temp2[0]] = temp2[1]; + } + return result; + }, + + // 将 对象 设置成url格式 {'a':1,'b':2} -》 a=1&b=2 + setUrlPrmt: function (obj) { + let _rs = []; + for (let p in obj) { + if (obj[p] != null && obj[p] != '') { + _rs.push(p + '=' + obj[p]) + } + } + return _rs.join('&'); + } +} diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/get-page-title.js b/src/dxq-rjgcks/x-admin-web/src/utils/get-page-title.js new file mode 100644 index 0000000..b2120d7 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/get-page-title.js @@ -0,0 +1,10 @@ +import defaultSettings from '@/settings' + +const title = defaultSettings.title || '中国民航大学饮食规划系统' + +export default function getPageTitle(pageTitle) { + if (pageTitle) { + return `${pageTitle} - ${title}` + } + return `${title}` +} diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/index.js b/src/dxq-rjgcks/x-admin-web/src/utils/index.js new file mode 100644 index 0000000..4830c04 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/index.js @@ -0,0 +1,117 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * Parse the time to string + * @param {(Object|string|number)} time + * @param {string} cFormat + * @returns {string | null} + */ +export function parseTime(time, cFormat) { + if (arguments.length === 0 || !time) { + return null + } + const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string')) { + if ((/^[0-9]+$/.test(time))) { + // support "1548221490638" + time = parseInt(time) + } else { + // support safari + // https://stackoverflow.com/questions/4310953/invalid-date-in-safari + time = time.replace(new RegExp(/-/gm), '/') + } + } + + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { + const value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } + return value.toString().padStart(2, '0') + }) + return time_str +} + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime(time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj(url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/numToChinese.js b/src/dxq-rjgcks/x-admin-web/src/utils/numToChinese.js new file mode 100644 index 0000000..d780f7b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/numToChinese.js @@ -0,0 +1,160 @@ + + +var chnNumChar = ["零","一","二","三","四","五","六","七","八","九"]; +var chnUnitSection = ["","万","亿","万亿","亿亿"]; +var chnUnitChar = ["","十","百","千"]; + +function SectionToChinese(section){ + var strIns = '', chnStr = ''; + var unitPos = 0; + var zero = true; + while(section > 0){ + var v = section % 10; + if(v === 0){ + if(!zero){ + zero = true; + chnStr = chnNumChar[v] + chnStr; + } + }else{ + zero = false; + strIns = chnNumChar[v]; + strIns += chnUnitChar[unitPos]; + chnStr = strIns + chnStr; + } + unitPos++; + section = Math.floor(section / 10); + } + return chnStr; +} + +function NumberToChinese(num){ + var unitPos = 0; + var strIns = '', chnStr = ''; + var needZero = false; + if(num === 0){ + return chnNumChar[0]; + } + while(num > 0){ + var section = num % 10000; + if(needZero){ + chnStr = chnNumChar[0] + chnStr; + } + strIns = SectionToChinese(section); + strIns += (section !== 0) ? chnUnitSection[unitPos] : chnUnitSection[0]; + chnStr = strIns + chnStr; + needZero = (section < 1000) && (section > 0); + num = Math.floor(num / 10000); + unitPos++; + } + return chnStr; +} + +var chnsNumChar = {零:0,一:1,二:2,三:3,四:4,五:5,六:6,七:7,八:8,九:9}; + +var chnNameValue = { + 十:{value:10, secUnit:false}, + 百:{value:100, secUnit:false}, + 千:{value:1000, secUnit:false}, + 万:{value:10000, secUnit:true}, + 亿:{value:100000000, secUnit:true} +} +function ChineseToNumber(chnStr){ + var rtn = 0; + var section = 0; + var number = 0; + var secUnit = false; + var str = chnStr.split(''); + for(var i = 0; i < str.length; i++){ + var num = chnsNumChar[str[i]]; + if(typeof num !== 'undefined'){ + number = num; + if(i === str.length - 1){ + section += number; + } + }else{ + var unit = chnNameValue[str[i]].value; + secUnit = chnNameValue[str[i]].secUnit; + if(secUnit){ + section = (section + number) * unit; + rtn += section; + section = 0; + }else{ + section += (number * unit); + } + number = 0; + } + } + return rtn + section; +} + +var numChian = { + "九":"十", + "十":"十一", + "十一":"十二", + "十二":"十三", + "十三":"十四", + "十四":"十五", + "十五":"十六", + "十六":"十七", + "十七":"十八", + "十八":"十九", + "十九":"二十", +} +export function getNextNo (num) { + if(numChian[num]){ + return numChian[num]; + } + let index = ChineseToNumber(num); + let str = NumberToChinese(index+1); + return str; +} + +// 表单重置 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields() + } + } + + /** + * + * @param data 数据源 + * @param id字段 默认 'id' + * @param parentId 父节点字段 默认 'parentId' + * @param children 孩子节点字段 默认 'children' + * @param rootId 根Id 默认 0 + * @returns {{obj, list: Array}} + */ + export function handleTree(data, id = 'id', parentId = 'parentId', children = 'children', rootId = 0) { + const obj = {} + data.forEach(item => { + item[children] = [] + obj[item[id]] = item + }) + const tree = [] + data.forEach(list => { + if (list[parentId] !== rootId) { + if (obj[list[parentId]]) { + obj[list[parentId]][children].push(list) + } + } else { + tree.push(list) + } + }) + return { + tree, + obj + } + } + + // 回显数据字典 + export function selectDictLabel(datas, value) { + const actions = [] + Object.keys(datas).map((key) => { + if (datas[key].dictValue === ('' + value)) { + actions.push(datas[key].dictLabel) + return false + } + }) + return actions.join('') + } \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/request.js b/src/dxq-rjgcks/x-admin-web/src/utils/request.js new file mode 100644 index 0000000..2fb95ac --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/request.js @@ -0,0 +1,85 @@ +import axios from 'axios' +import { MessageBox, Message } from 'element-ui' +import store from '@/store' +import { getToken } from '@/utils/auth' + +// create an axios instance +const service = axios.create({ + baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url + // withCredentials: true, // send cookies when cross-domain requests + timeout: 5000 // request timeout +}) + +// request interceptor +service.interceptors.request.use( + config => { + // do something before request is sent + + if (store.getters.token) { + // let each request carry token + // ['X-Token'] is a custom headers key + // please modify it according to the actual situation + config.headers['X-Token'] = getToken() + } + return config + }, + error => { + // do something with request error + console.log(error) // for debug + return Promise.reject(error) + } +) + +// response interceptor +service.interceptors.response.use( + /** + * If you want to get http information such as headers or status + * Please return response => response + */ + + /** + * Determine the request status by custom code + * Here is just an example + * You can also judge the status by HTTP Status Code + */ + response => { + const res = response.data + + // if the custom code is not 20000, it is judged as an error. + if (res.code !== 20000) { + Message({ + message: res.message || 'Error', + type: 'error', + duration: 5 * 1000 + }) + + // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; + if (res.code === 50008 || res.code === 50012 || res.code === 50014) { + // to re-login + MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { + confirmButtonText: 'Re-Login', + cancelButtonText: 'Cancel', + type: 'warning' + }).then(() => { + store.dispatch('user/resetToken').then(() => { + location.reload() + }) + }) + } + return Promise.reject(new Error(res.message || 'Error')) + } else { + return res + } + }, + error => { + console.log('err' + error) // for debug + Message({ + message: error.message, + type: 'error', + duration: 5 * 1000 + }) + return Promise.reject(error) + } +) + +export default service diff --git a/src/dxq-rjgcks/x-admin-web/src/utils/validate.js b/src/dxq-rjgcks/x-admin-web/src/utils/validate.js new file mode 100644 index 0000000..0c7f643 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/utils/validate.js @@ -0,0 +1,21 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUsername(str) { + // const valid_map = ['admin', 'editor'] + // return valid_map.indexOf(str.trim()) >= 0 + return true; +} diff --git a/src/dxq-rjgcks/x-admin-web/src/views/404.vue b/src/dxq-rjgcks/x-admin-web/src/views/404.vue new file mode 100644 index 0000000..1791f55 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/404.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/dashboard/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/dashboard/index.vue new file mode 100644 index 0000000..58e22c7 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/dashboard/index.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/dashboard/xinzhi.jpg b/src/dxq-rjgcks/x-admin-web/src/views/dashboard/xinzhi.jpg new file mode 100644 index 0000000..a47c31e Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/dashboard/xinzhi.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/dishes.xls b/src/dxq-rjgcks/x-admin-web/src/views/dishes.xls new file mode 100644 index 0000000..1b16ccf Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/dishes.xls differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/form/Data.vue b/src/dxq-rjgcks/x-admin-web/src/views/form/Data.vue new file mode 100644 index 0000000..17bad5c --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/form/Data.vue @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/form/id.vue b/src/dxq-rjgcks/x-admin-web/src/views/form/id.vue new file mode 100644 index 0000000..49dcddf --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/form/id.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/form/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/form/index.vue new file mode 100644 index 0000000..e46989f --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/form/index.vue @@ -0,0 +1,230 @@ + + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/form/index2.vue b/src/dxq-rjgcks/x-admin-web/src/views/form/index2.vue new file mode 100644 index 0000000..87297d9 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/form/index2.vue @@ -0,0 +1,251 @@ + + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/form/xinzhi.jpg b/src/dxq-rjgcks/x-admin-web/src/views/form/xinzhi.jpg new file mode 100644 index 0000000..a47c31e Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/form/xinzhi.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/login/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/login/index.vue new file mode 100644 index 0000000..63f8047 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/login/index.vue @@ -0,0 +1,244 @@ + + + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/index.vue new file mode 100644 index 0000000..a459076 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/index.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/noodle1.png b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/noodle1.png new file mode 100644 index 0000000..ec17f7c Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu1/noodle1.png differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu2/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu2/index.vue new file mode 100644 index 0000000..d96a889 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu2/index.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu3/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu3/index.vue new file mode 100644 index 0000000..dd0df15 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu3/index.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu4/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu4/index.vue new file mode 100644 index 0000000..466f38d --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu4/index.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/nested/menu5/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu5/index.vue new file mode 100644 index 0000000..f81b3d8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/nested/menu5/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/sys/role.vue b/src/dxq-rjgcks/x-admin-web/src/views/sys/role.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/dxq-rjgcks/x-admin-web/src/views/sys/user.vue b/src/dxq-rjgcks/x-admin-web/src/views/sys/user.vue new file mode 100644 index 0000000..38c19cf --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/sys/user.vue @@ -0,0 +1,102 @@ + + + + + + + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/views/sys/user2.vue b/src/dxq-rjgcks/x-admin-web/src/views/sys/user2.vue new file mode 100644 index 0000000..be51d12 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/sys/user2.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/dxq-rjgcks/x-admin-web/src/views/sys/xinzhi.jpg b/src/dxq-rjgcks/x-admin-web/src/views/sys/xinzhi.jpg new file mode 100644 index 0000000..a47c31e Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/sys/xinzhi.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/table/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/table/index.vue new file mode 100644 index 0000000..c1a7132 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/table/index.vue @@ -0,0 +1,190 @@ + + + + + + + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/views/table/template.vue b/src/dxq-rjgcks/x-admin-web/src/views/table/template.vue new file mode 100644 index 0000000..79d3bb8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/table/template.vue @@ -0,0 +1,1272 @@ + + + + + + 每日总消耗热量(TDEE)和营养素(Macros)计算器 | 健身 | 增肌减脂 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+
+ +
+
+ +
+ +
+
+
+
+
+
+
+

+
+ 计算您每日消耗的总热量(TDEE)和需要摄取的巨量营养素 +
+

+
+ 这个计算器可以帮助您准确地计算出您每天所消耗的总热量,并根据您增肌(bulking)或减脂(cutting)的目标,算出您每天应该摄取的碳水,脂肪和蛋白质(巨量营养素)。 +
+
+
+
+ + +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+ +
+ + +
+
+
+ +
+ +
+ kg +
+
+
+
+ +
+ +
+ cm +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ + +
+
+
+ +
+ +
+ % +
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
    +
  • +
    +
    +
    + 每日消耗总卡路里 +
    +
    +
    +
    + 0 +
    +
    +
    +
  • +
  • +
    +
    +
    + 根据您输入的数据,视乎您有否提供体脂率,我们会选择 + + Katch-McArdle + + 或者 + + Mifflin-St Jeor + + 计算公式来计算您的TDEE。下表将会显示出如果您改变您的闲时运动量,您的TDEE将会有何变化。 +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 闲时运动量 + + TDEE +
    + 很少活动 + + NaN +
    + 稍微走动 + + NaN +
    + 中等活动量 + + NaN +
    + 相当活跃 + + NaN +
    + 极度活跃 + + NaN +
    +
    +
  • +
+
+
+ + 您的BMR约为 + + 0 + + 卡 + +
+ + BMR ( + + Basal Metabolic Rate + + ) 即是基础代谢率,其反映了你的身体在昏睡状态下所需要的最低能量。这些能量主要用于维持身体的基本功能,例如心跳,呼吸,维持体温等等。 + +
+
+
+ + 卡路里和营养素建议摄入量 + +
+ + 根据您的健身目标,建议您应该把 + + 每天总摄入卡路里 + + 控制在 + + 0 + + 卡左右。当然,您也可以根据自己的情况,在下方的输入框调整这个数值: + +
+ +
+ + +
+
+
+
+ 每天蛋白质的摄入量建议为您总摄入卡路里的30%。您可以调整这个百分比,但请注意20% - 25%是促进肌肉生长所需的最低限度。而通常选择一个高蛋白的百分比会令您“强迫”自己吃一些更干净的食物,并避免那些垃圾食品。如果您想调整这个数值,请修改下方的输入框: +
+
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 巨量营养素 + + 克 + + 卡路里 + + 卡路里百分比 +
+ 蛋白质 + + 0 + + g + + 0 + + 30 + + % +
+ 脂肪 + + 0 + + g + + 0 + + 28 + + % +
+ 碳水化合物 + + 0 + + g + + 0 + + 42 + + % +
+
+
+
+
+ 脂肪 +
+
+
+
+ 碳水化合物 +
+
+
+
+
+
+
+
+
+ +
+
+ 脂肪 : 碳水 + + - + + 40 + + : + + 60 +
+
+
+ + 每天的脂肪/碳水(卡路里)摄入比默认设定为40 : 60。但这个比例其实更多是个人喜好,只要不是太极端就不会有太大问题。一般来说,您的活跃程度越高,您的身体就越可能更适应高碳水比例的饮食。 +
+
+ 虽然脂肪/碳水摄入比只是个人选择,但也不应该把比例定得太低。 + + 一般情况下您的脂肪摄入量应占每天总卡路里摄入量的15% - 20%。 + + 当您的脂肪摄入量低于这个水平时,就会出现各种健康问题,例如皮疹,头发干枯,免疫力减退,以及其他缺乏维生素的症状。如果您要调整脂肪/碳水摄入比,请滑动上方的滑条,并观察您的营养素摄入量会如何变化。 +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+ +
+
    +
+
    +
+
    +
+
    +
+
    +
+
    +
+
+ + + + + + + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/views/table/xinzhi.jpg b/src/dxq-rjgcks/x-admin-web/src/views/table/xinzhi.jpg new file mode 100644 index 0000000..a47c31e Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/table/xinzhi.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/src/views/test/test1.vue b/src/dxq-rjgcks/x-admin-web/src/views/test/test1.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/dxq-rjgcks/x-admin-web/src/views/tree/index.vue b/src/dxq-rjgcks/x-admin-web/src/views/tree/index.vue new file mode 100644 index 0000000..422b22a --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/src/views/tree/index.vue @@ -0,0 +1,179 @@ + + + + + \ No newline at end of file diff --git a/src/dxq-rjgcks/x-admin-web/src/views/tree/xinzhi.jpg b/src/dxq-rjgcks/x-admin-web/src/views/tree/xinzhi.jpg new file mode 100644 index 0000000..a47c31e Binary files /dev/null and b/src/dxq-rjgcks/x-admin-web/src/views/tree/xinzhi.jpg differ diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/.eslintrc.js b/src/dxq-rjgcks/x-admin-web/tests/unit/.eslintrc.js new file mode 100644 index 0000000..958d51b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + env: { + jest: true + } +} diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/components/Breadcrumb.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/components/Breadcrumb.spec.js new file mode 100644 index 0000000..1d94c8f --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/components/Breadcrumb.spec.js @@ -0,0 +1,98 @@ +import { mount, createLocalVue } from '@vue/test-utils' +import VueRouter from 'vue-router' +import ElementUI from 'element-ui' +import Breadcrumb from '@/components/Breadcrumb/index.vue' + +const localVue = createLocalVue() +localVue.use(VueRouter) +localVue.use(ElementUI) + +const routes = [ + { + path: '/', + name: 'home', + children: [{ + path: 'dashboard', + name: 'dashboard' + }] + }, + { + path: '/menu', + name: 'menu', + children: [{ + path: 'menu1', + name: 'menu1', + meta: { title: 'menu1' }, + children: [{ + path: 'menu1-1', + name: 'menu1-1', + meta: { title: 'menu1-1' } + }, + { + path: 'menu1-2', + name: 'menu1-2', + redirect: 'noredirect', + meta: { title: 'menu1-2' }, + children: [{ + path: 'menu1-2-1', + name: 'menu1-2-1', + meta: { title: 'menu1-2-1' } + }, + { + path: 'menu1-2-2', + name: 'menu1-2-2' + }] + }] + }] + }] + +const router = new VueRouter({ + routes +}) + +describe('Breadcrumb.vue', () => { + const wrapper = mount(Breadcrumb, { + localVue, + router + }) + it('dashboard', () => { + router.push('/dashboard') + const len = wrapper.findAll('.el-breadcrumb__inner').length + expect(len).toBe(1) + }) + it('normal route', () => { + router.push('/menu/menu1') + const len = wrapper.findAll('.el-breadcrumb__inner').length + expect(len).toBe(2) + }) + it('nested route', () => { + router.push('/menu/menu1/menu1-2/menu1-2-1') + const len = wrapper.findAll('.el-breadcrumb__inner').length + expect(len).toBe(4) + }) + it('no meta.title', () => { + router.push('/menu/menu1/menu1-2/menu1-2-2') + const len = wrapper.findAll('.el-breadcrumb__inner').length + expect(len).toBe(3) + }) + // it('click link', () => { + // router.push('/menu/menu1/menu1-2/menu1-2-2') + // const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') + // const second = breadcrumbArray.at(1) + // console.log(breadcrumbArray) + // const href = second.find('a').attributes().href + // expect(href).toBe('#/menu/menu1') + // }) + // it('noRedirect', () => { + // router.push('/menu/menu1/menu1-2/menu1-2-1') + // const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') + // const redirectBreadcrumb = breadcrumbArray.at(2) + // expect(redirectBreadcrumb.contains('a')).toBe(false) + // }) + it('last breadcrumb', () => { + router.push('/menu/menu1/menu1-2/menu1-2-1') + const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner') + const redirectBreadcrumb = breadcrumbArray.at(3) + expect(redirectBreadcrumb.contains('a')).toBe(false) + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/components/Hamburger.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/components/Hamburger.spec.js new file mode 100644 index 0000000..01ea303 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/components/Hamburger.spec.js @@ -0,0 +1,18 @@ +import { shallowMount } from '@vue/test-utils' +import Hamburger from '@/components/Hamburger/index.vue' +describe('Hamburger.vue', () => { + it('toggle click', () => { + const wrapper = shallowMount(Hamburger) + const mockFn = jest.fn() + wrapper.vm.$on('toggleClick', mockFn) + wrapper.find('.hamburger').trigger('click') + expect(mockFn).toBeCalled() + }) + it('prop isActive', () => { + const wrapper = shallowMount(Hamburger) + wrapper.setProps({ isActive: true }) + expect(wrapper.contains('.is-active')).toBe(true) + wrapper.setProps({ isActive: false }) + expect(wrapper.contains('.is-active')).toBe(false) + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/components/SvgIcon.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/components/SvgIcon.spec.js new file mode 100644 index 0000000..31467a9 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/components/SvgIcon.spec.js @@ -0,0 +1,22 @@ +import { shallowMount } from '@vue/test-utils' +import SvgIcon from '@/components/SvgIcon/index.vue' +describe('SvgIcon.vue', () => { + it('iconClass', () => { + const wrapper = shallowMount(SvgIcon, { + propsData: { + iconClass: 'test' + } + }) + expect(wrapper.find('use').attributes().href).toBe('#icon-test') + }) + it('className', () => { + const wrapper = shallowMount(SvgIcon, { + propsData: { + iconClass: 'test' + } + }) + expect(wrapper.classes().length).toBe(1) + wrapper.setProps({ className: 'test' }) + expect(wrapper.classes().includes('test')).toBe(true) + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/utils/formatTime.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/formatTime.spec.js new file mode 100644 index 0000000..24e165b --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/formatTime.spec.js @@ -0,0 +1,30 @@ +import { formatTime } from '@/utils/index.js' + +describe('Utils:formatTime', () => { + const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" + const retrofit = 5 * 1000 + + it('ten digits timestamp', () => { + expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') + }) + it('test now', () => { + expect(formatTime(+new Date() - 1)).toBe('刚刚') + }) + it('less two minute', () => { + expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') + }) + it('less two hour', () => { + expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') + }) + it('less one day', () => { + expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') + }) + it('more than one day', () => { + expect(formatTime(d)).toBe('7月13日17时54分') + }) + it('format', () => { + expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') + expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') + expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/utils/param2Obj.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/param2Obj.spec.js new file mode 100644 index 0000000..e106ed8 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/param2Obj.spec.js @@ -0,0 +1,14 @@ +import { param2Obj } from '@/utils/index.js' +describe('Utils:param2Obj', () => { + const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95' + + it('param2Obj test', () => { + expect(param2Obj(url)).toEqual({ + name: 'bill', + age: '29', + sex: '1', + field: window.btoa('test'), + key: '测试' + }) + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/utils/parseTime.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/parseTime.spec.js new file mode 100644 index 0000000..56045af --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/parseTime.spec.js @@ -0,0 +1,35 @@ +import { parseTime } from '@/utils/index.js' + +describe('Utils:parseTime', () => { + const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" + it('timestamp', () => { + expect(parseTime(d)).toBe('2018-07-13 17:54:01') + }) + it('timestamp string', () => { + expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01') + }) + it('ten digits timestamp', () => { + expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') + }) + it('new Date', () => { + expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') + }) + it('format', () => { + expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') + expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') + expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') + }) + it('get the day of the week', () => { + expect(parseTime(d, '{a}')).toBe('五') // 星期五 + }) + it('get the day of the week', () => { + expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 + }) + it('empty argument', () => { + expect(parseTime()).toBeNull() + }) + + it('null', () => { + expect(parseTime(null)).toBeNull() + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/tests/unit/utils/validate.spec.js b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/validate.spec.js new file mode 100644 index 0000000..f774905 --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/tests/unit/utils/validate.spec.js @@ -0,0 +1,17 @@ +import { validUsername, isExternal } from '@/utils/validate.js' + +describe('Utils:validate', () => { + it('validUsername', () => { + expect(validUsername('admin')).toBe(true) + expect(validUsername('editor')).toBe(true) + expect(validUsername('xxxx')).toBe(false) + }) + it('isExternal', () => { + expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) + expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) + expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false) + expect(isExternal('/dashboard')).toBe(false) + expect(isExternal('./dashboard')).toBe(false) + expect(isExternal('dashboard')).toBe(false) + }) +}) diff --git a/src/dxq-rjgcks/x-admin-web/vue.config.js b/src/dxq-rjgcks/x-admin-web/vue.config.js new file mode 100644 index 0000000..39450fb --- /dev/null +++ b/src/dxq-rjgcks/x-admin-web/vue.config.js @@ -0,0 +1,123 @@ +'use strict' +const path = require('path') +const defaultSettings = require('./src/settings.js') + +function resolve(dir) { + return path.join(__dirname, dir) +} + +const name = defaultSettings.title || '中国民航大学营养菜谱生成系统' // page title + +// If your port is set to 80, +// use administrator privileges to execute the command line. +// For example, Mac: sudo npm run +// You can change the port by the following methods: +// port = 9528 npm run dev OR npm run dev --port = 9528 +const port = 8888 // dev port 前端的端口已经改动了!!! + +// All configuration item explanations can be find in https://cli.vuejs.org/config/ +module.exports = { + /** + * You will need to set publicPath if you plan to deploy your site under a sub path, + * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, + * then publicPath should be set to "/bar/". + * In most cases please use '/' !!! + * Detail: https://cli.vuejs.org/config/#publicpath + */ + publicPath: '/', + outputDir: 'dist', + assetsDir: 'static', + lintOnSave: false,//语法检查改成FALSE + productionSourceMap: false, + devServer: { + port: port, + open: false,//默认是否打开浏览器改成false + overlay: { + warnings: false, + errors: true + }, + before: require('./mock/mock-server.js') + }, + configureWebpack: { + // provide the app's title in webpack's name field, so that + // it can be accessed in index.html to inject the correct title. + name: name, + resolve: { + alias: { + '@': resolve('src') + } + } + }, + chainWebpack(config) { + // it can improve the speed of the first screen, it is recommended to turn on preload + config.plugin('preload').tap(() => [ + { + rel: 'preload', + // to ignore runtime.js + // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171 + fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/], + include: 'initial' + } + ]) + + // when there are many pages, it will cause too many meaningless requests + config.plugins.delete('prefetch') + + // set svg-sprite-loader + config.module + .rule('svg') + .exclude.add(resolve('src/icons')) + .end() + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]' + }) + .end() + + config + .when(process.env.NODE_ENV !== 'development', + config => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [{ + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/ + }]) + .end() + config + .optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app + test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true + } + } + }) + // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk + config.optimization.runtimeChunk('single') + } + ) + } +}