|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
|
@ -0,0 +1,8 @@
|
|||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-auth/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-auth/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-common/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-common/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-es/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-gateway/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-gateway/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/yuan-purchaseorder/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/yuan-user/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/yuan-user/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-modules/yuan-volume-code/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/yuan-rabbitmq/src/main/java" charset="UTF-8" />
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>maven-month</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>yuan-auth</module>
|
||||
<module>yuan-common</module>
|
||||
<module>yuan-modules</module>
|
||||
<module>yuan-gateway</module>
|
||||
<module>yuan-es</module>
|
||||
<module>yuan-rabbitmq</module>
|
||||
<module>yuan-modules/yuan-purchaseorder</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<!-- 规定SpringBoot版本 -->
|
||||
<!-- 父级pom文件 主要用于规定项目依赖的各个版本,用于进行项目版本约束 -->
|
||||
<parent>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<version>2.6.2</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- SpringCloud 微服务 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>2021.0.0</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- SpringCloud Alibaba 微服务 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2021.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- Alibaba Nacos 配置 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 系统公共 依赖 版本号定义-->
|
||||
<dependency>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>yuan-common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function toButList(data) {
|
||||
return request({
|
||||
url: '/es/toBuyList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function addPurchaseOrder (data) {
|
||||
return request({
|
||||
url: '/es/toBuyOrder',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function selectPurchaseOrderList () {
|
||||
return request({
|
||||
url: '/es/selectPurchaseOrderList',
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
export function payAnOrder (data) {
|
||||
return request({
|
||||
url: '/es/payAnOrder',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getList(params) {
|
||||
return request({
|
||||
url: '/vue-admin-template/table/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/auth/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function register(data) {
|
||||
return request({
|
||||
url: '/auth/register',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function sendCode(data) {
|
||||
return request({
|
||||
url: '/auth/sendCode',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(token) {
|
||||
return request({
|
||||
url: '/auth/info',
|
||||
method: 'get',
|
||||
params: { token }
|
||||
})
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return request({
|
||||
url: '/vue-admin-template/user/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getVolumeCodeList(data) {
|
||||
return request({
|
||||
url: '/es/list',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function findByType(data) {
|
||||
return request({
|
||||
url: '/es/findByType',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function addvc(data) {
|
||||
return request({
|
||||
url: '/es/addvc',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>
|
After Width: | Height: | Size: 497 B |
|
@ -0,0 +1 @@
|
|||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>
|
After Width: | Height: | Size: 944 B |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>
|
After Width: | Height: | Size: 285 B |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>
|
After Width: | Height: | Size: 821 B |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>
|
After Width: | Height: | Size: 623 B |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>
|
After Width: | Height: | Size: 597 B |
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1 @@
|
|||
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>
|
After Width: | Height: | Size: 440 B |
|
@ -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'
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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 { userTel, code } = userInfo
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ userTel: userTel.trim(), code: code }).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
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import defaultSettings from '@/settings'
|
||||
|
||||
const title = defaultSettings.title || 'Vue Admin Template'
|
||||
|
||||
export default function getPageTitle(pageTitle) {
|
||||
if (pageTitle) {
|
||||
return `${pageTitle} - ${title}`
|
||||
}
|
||||
return `${title}`
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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['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 !== 200) {
|
||||
Message({
|
||||
message: res.msg || '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 || res.code === 500) {
|
||||
// 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.msg || 'Error'))
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('err' + error) // for debug
|
||||
Message({
|
||||
message: error.msg,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default service
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 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
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div class="wscn-http404-container">
|
||||
<div class="wscn-http404">
|
||||
<div class="pic-404">
|
||||
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
|
||||
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
|
||||
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
|
||||
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
|
||||
</div>
|
||||
<div class="bullshit">
|
||||
<div class="bullshit__oops">OOPS!</div>
|
||||
<div class="bullshit__info">All rights reserved
|
||||
<a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
|
||||
</div>
|
||||
<div class="bullshit__headline">{{ message }}</div>
|
||||
<div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
|
||||
<a href="" class="bullshit__return-home">Back to home</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Page404',
|
||||
computed: {
|
||||
message() {
|
||||
return 'The webmaster said that you can not enter this page...'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wscn-http404-container{
|
||||
transform: translate(-50%,-50%);
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
.wscn-http404 {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
padding: 0 50px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__child {
|
||||
position: absolute;
|
||||
&.left {
|
||||
width: 80px;
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
&.mid {
|
||||
width: 46px;
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
&.right {
|
||||
width: 62px;
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
&__oops {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
margin-bottom: 20px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
margin-bottom: 10px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
margin-bottom: 30px;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(60px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-form ref="form" :model="form" label-width="120px">
|
||||
<el-form-item label="Activity name">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Activity zone">
|
||||
<el-select v-model="form.region" placeholder="please select your zone">
|
||||
<el-option label="Zone one" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Activity time">
|
||||
<el-col :span="11">
|
||||
<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
|
||||
</el-col>
|
||||
<el-col :span="2" class="line">-</el-col>
|
||||
<el-col :span="11">
|
||||
<el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="Instant delivery">
|
||||
<el-switch v-model="form.delivery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Activity type">
|
||||
<el-checkbox-group v-model="form.type">
|
||||
<el-checkbox label="Online activities" name="type" />
|
||||
<el-checkbox label="Promotion activities" name="type" />
|
||||
<el-checkbox label="Offline activities" name="type" />
|
||||
<el-checkbox label="Simple brand exposure" name="type" />
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="Resources">
|
||||
<el-radio-group v-model="form.resource">
|
||||
<el-radio label="Sponsor" />
|
||||
<el-radio label="Venue" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="Activity form">
|
||||
<el-input v-model="form.desc" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Create</el-button>
|
||||
<el-button @click="onCancel">Cancel</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
region: '',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$message('submit!')
|
||||
},
|
||||
onCancel() {
|
||||
this.$message({
|
||||
message: 'cancel!',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.line{
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
<template>
|
||||
<div class="login-container">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
|
||||
|
||||
<div class="title-container">
|
||||
<h3 class="title">Login Form</h3>
|
||||
</div>
|
||||
|
||||
<el-form-item prop="userTel">
|
||||
<span class="svg-container">
|
||||
<svg-icon icon-class="user" />
|
||||
</span>
|
||||
<el-input
|
||||
ref="userTel"
|
||||
v-model="loginForm.userTel"
|
||||
placeholder="userTel"
|
||||
name="userTel"
|
||||
type="text"
|
||||
tabindex="1"
|
||||
auto-complete="on"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="code">
|
||||
<span class="svg-container">
|
||||
<svg-icon icon-class="password" />
|
||||
</span>
|
||||
<el-input
|
||||
:key="code"
|
||||
ref="password"
|
||||
v-model="loginForm.code"
|
||||
:type="passwordType"
|
||||
placeholder="code"
|
||||
name="code"
|
||||
tabindex="2"
|
||||
auto-complete="on"
|
||||
@keyup.enter.native="handleLogin"
|
||||
/>
|
||||
<span class="show-pwd" @click="showPwd">
|
||||
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-button :loading="loading" type="primary" style="width:48%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
|
||||
<el-button :loading="loading" type="primary" style="width:48%;margin-bottom:30px;" @click.native.prevent="handleSendCode">SendCode</el-button>
|
||||
<el-button type="text" @click="dialogVisible = true">还没有账号? 点击注册</el-button>
|
||||
<div class="tips">
|
||||
<span style="margin-right:20px;">username: admin</span>
|
||||
<span> password: any</span>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
title="注册用户"
|
||||
:visible.sync="dialogVisible"
|
||||
width="50%">
|
||||
<span>
|
||||
<el-form label-width="80px" :model="userRegisterReq">
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="userRegisterReq.userTel"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称">
|
||||
<el-input v-model="userRegisterReq.name"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</span>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleRegister">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { validUsername } from '@/utils/validate'
|
||||
import { register, sendCode } from '@/api/user'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
data() {
|
||||
const validateUsername = (rule, value, callback) => {
|
||||
if (value === null) {
|
||||
callback(new Error('手机号不能为空'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePassword = (rule, value, callback) => {
|
||||
if (value.length === 0) {
|
||||
callback(new Error('验证码不能为空'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
loginForm: {
|
||||
userTel: '',
|
||||
code: ''
|
||||
},
|
||||
userRegisterReq: {
|
||||
userTel: '',
|
||||
name: '',
|
||||
},
|
||||
loginRules: {
|
||||
userTel: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
||||
code: [{ required: true, trigger: 'blur', validator: validatePassword }]
|
||||
},
|
||||
loading: false,
|
||||
passwordType: 'password',
|
||||
redirect: undefined,
|
||||
dialogVisible: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler: function(route) {
|
||||
this.redirect = route.query && route.query.redirect
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showPwd() {
|
||||
if (this.passwordType === 'password') {
|
||||
this.passwordType = ''
|
||||
} else {
|
||||
this.passwordType = 'password'
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.password.focus()
|
||||
})
|
||||
},
|
||||
//发送验证码
|
||||
handleSendCode(){
|
||||
sendCode(this.loginForm).then(response => {
|
||||
this.$message(response.msg);
|
||||
})
|
||||
},
|
||||
handleLogin() {
|
||||
this.$refs.loginForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store.dispatch('user/login', this.loginForm).then(() => {
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
//注册账号
|
||||
handleRegister(){
|
||||
register(this.userRegisterReq).then(response => {
|
||||
this.$message(response.msg);
|
||||
this.dialogVisible = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 修复input 背景不协调 和光标变色 */
|
||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||
|
||||
$bg:#283443;
|
||||
$light_gray:#fff;
|
||||
$cursor: #fff;
|
||||
|
||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||
.login-container .el-input input {
|
||||
color: $cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset element-ui css */
|
||||
.login-container {
|
||||
.el-input {
|
||||
display: inline-block;
|
||||
height: 47px;
|
||||
width: 85%;
|
||||
|
||||
input {
|
||||
background: transparent;
|
||||
border: 0px;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0px;
|
||||
padding: 12px 5px 12px 15px;
|
||||
color: $light_gray;
|
||||
height: 47px;
|
||||
caret-color: $cursor;
|
||||
|
||||
&:-webkit-autofill {
|
||||
box-shadow: 0 0 0px 1000px $bg inset !important;
|
||||
-webkit-text-fill-color: $cursor !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
color: #454545;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$bg:#2d3a4b;
|
||||
$dark_gray:#889aa4;
|
||||
$light_gray:#eee;
|
||||
|
||||
.login-container {
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
background-color: $bg;
|
||||
overflow: hidden;
|
||||
|
||||
.login-form {
|
||||
position: relative;
|
||||
width: 520px;
|
||||
max-width: 100%;
|
||||
padding: 160px 35px 0;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
padding: 6px 5px 6px 15px;
|
||||
color: $dark_gray;
|
||||
vertical-align: middle;
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.title-container {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
color: $light_gray;
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 7px;
|
||||
font-size: 16px;
|
||||
color: $dark_gray;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1">
|
||||
<router-view />
|
||||
</el-alert>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1-1" type="success">
|
||||
<router-view />
|
||||
</el-alert>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1-2" type="success">
|
||||
<router-view />
|
||||
</el-alert>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,5 @@
|
|||
<template functional>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,5 @@
|
|||
<template functional>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,5 @@
|
|||
<template functional>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 1-3" type="success" />
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div style="padding:30px;">
|
||||
<el-alert :closable="false" title="menu 2" />
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="list"
|
||||
element-loading-text="Loading"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column align="center" label="ID" width="95">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Title">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.title }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Author" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Pageviews" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.pageviews }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column class-name="status-col" label="Status" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="created_at" label="Display_time" width="200">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-time" />
|
||||
<span>{{ scope.row.display_time }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getList } from '@/api/table'
|
||||
|
||||
export default {
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'gray',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.listLoading = true
|
||||
getList().then(response => {
|
||||
this.list = response.data.items
|
||||
this.listLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
|
||||
|
||||
<el-tree
|
||||
ref="tree2"
|
||||
:data="data2"
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
class="filter-tree"
|
||||
default-expand-all
|
||||
/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
filterText: '',
|
||||
data2: [{
|
||||
id: 1,
|
||||
label: 'Level one 1',
|
||||
children: [{
|
||||
id: 4,
|
||||
label: 'Level two 1-1',
|
||||
children: [{
|
||||
id: 9,
|
||||
label: 'Level three 1-1-1'
|
||||
}, {
|
||||
id: 10,
|
||||
label: 'Level three 1-1-2'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
id: 2,
|
||||
label: 'Level one 2',
|
||||
children: [{
|
||||
id: 5,
|
||||
label: 'Level two 2-1'
|
||||
}, {
|
||||
id: 6,
|
||||
label: 'Level two 2-2'
|
||||
}]
|
||||
}, {
|
||||
id: 3,
|
||||
label: 'Level one 3',
|
||||
children: [{
|
||||
id: 7,
|
||||
label: 'Level two 3-1'
|
||||
}, {
|
||||
id: 8,
|
||||
label: 'Level two 3-2'
|
||||
}]
|
||||
}],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree2.filter(val)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>maven-month</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>yuan-auth</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>yuan-auth</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- 项目公共 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>yuan-common</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringBoot Web-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- kafka -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,20 @@
|
|||
package com.bwie.auth;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth
|
||||
* @Project:maven-month
|
||||
* @name:YuanAuthApplication
|
||||
* @Date:2024/8/12 上午10:56
|
||||
*/
|
||||
@EnableFeignClients
|
||||
@SpringBootApplication
|
||||
public class YuanAuthApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(YuanAuthApplication.class,args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.bwie.auth.config;
|
||||
|
||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* RabbitAdmin是RabbitMQ的一个Java客户端库,它提供了管理RabbitMQ资源的功能。它是通过与RabbitMQ服务器进行交互来执行管理操作的。
|
||||
*/
|
||||
@Configuration
|
||||
public class RabbitAdminConfig {
|
||||
|
||||
@Value("${spring.rabbitmq.host}")
|
||||
private String host;
|
||||
@Value("${spring.rabbitmq.username}")
|
||||
private String username;
|
||||
@Value("${spring.rabbitmq.password}")
|
||||
private String password;
|
||||
@Value("${spring.rabbitmq.virtualhost}")
|
||||
private String virtualhost;
|
||||
|
||||
/**
|
||||
* 构建 RabbitMQ的连接工厂
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ConnectionFactory connectionFactory() {
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||
connectionFactory.setAddresses(host);
|
||||
connectionFactory.setUsername(username);
|
||||
connectionFactory.setPassword(password);
|
||||
connectionFactory.setVirtualHost(virtualhost);
|
||||
// 配置发送确认回调时,次配置必须配置,否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
|
||||
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
|
||||
connectionFactory.setPublisherReturns(true);
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自己初始化 RabbitAdmin
|
||||
* @param connectionFactory
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
|
||||
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
|
||||
rabbitAdmin.setAutoStartup(true);
|
||||
return rabbitAdmin;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.bwie.auth.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bwie.auth.service.AuthService;
|
||||
import com.bwie.common.domain.User;
|
||||
import com.bwie.common.domain.response.JwtResponse;
|
||||
import com.bwie.common.domain.request.UserSendCodeReq;
|
||||
import com.bwie.common.result.Result;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth.controller
|
||||
* @Project:maven-month
|
||||
* @name:AuthController
|
||||
* @Date:2024/8/12 上午10:27
|
||||
*/
|
||||
@Log4j2
|
||||
@RestController
|
||||
@RequestMapping("/auth")
|
||||
public class AuthController {
|
||||
|
||||
@Autowired private AuthService authService;
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param user 用户信息
|
||||
* @return 登录结果
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public Result<JwtResponse> login(@RequestBody User user){
|
||||
log.info("执行登录...");
|
||||
log.info("登录人信息:[{}]", JSON.toJSONString(user));
|
||||
Result<JwtResponse> result = authService.login(user);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param user 注册用户信息
|
||||
* @return 注册结果
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public Result<Object> register(@RequestBody User user){
|
||||
log.info("执行注册");
|
||||
log.info("注册信息:[{}]",JSON.toJSONString(user));
|
||||
Result<Object> result = authService.register(user);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送手机验证码
|
||||
* @param userSendCodeReq 手机信息
|
||||
* @return 发送结果
|
||||
*/
|
||||
@PostMapping("/sendCode")
|
||||
public Result<String> sendCode(@RequestBody UserSendCodeReq userSendCodeReq){
|
||||
log.info("执行发送验证码");
|
||||
log.info("信息:[{}]",JSON.toJSONString(userSendCodeReq));
|
||||
Result<String> result = authService.sendCode(userSendCodeReq);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* info
|
||||
* @return user
|
||||
*/
|
||||
@GetMapping("info")
|
||||
public Result info(){
|
||||
User user = authService.info();
|
||||
return Result.success(user);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.bwie.auth.feign;
|
||||
|
||||
import com.bwie.common.domain.User;
|
||||
import com.bwie.common.result.Result;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth.feign
|
||||
* @Project:maven-month
|
||||
* @name:AuthFeign
|
||||
* @Date:2024/8/12 上午10:22
|
||||
*/
|
||||
@FeignClient("bwie-user")
|
||||
public interface AuthFeign {
|
||||
/**
|
||||
* 查询用户数据
|
||||
* @param tel 手机号
|
||||
* @return 用户信息
|
||||
*/
|
||||
@PostMapping("/user/selectByTel")
|
||||
public Result<User> selectByTel(@RequestParam String tel);
|
||||
|
||||
/**
|
||||
* 录入新用户
|
||||
* @param user 用户信息
|
||||
* @return 录入结果
|
||||
*/
|
||||
@PostMapping("/user/add")
|
||||
public Result<String> save(@RequestBody User user);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.bwie.auth.feign.impl;
|
||||
|
||||
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
|
||||
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
|
||||
import com.bwie.auth.feign.AuthFeign;
|
||||
import com.bwie.common.domain.User;
|
||||
import com.bwie.common.result.Result;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth.feign.impl
|
||||
* @Project:maven-month
|
||||
* @name:AuthFeignImpl
|
||||
* @Date:2024/8/12 上午10:25
|
||||
*/
|
||||
@Component
|
||||
public class AuthFeignImpl implements FallbackFactory<AuthFeign> {
|
||||
@Override
|
||||
public AuthFeign create(Throwable cause) {
|
||||
return new AuthFeign() {
|
||||
@Override
|
||||
public Result<User> selectByTel(String tel) {
|
||||
return Result.error("网络开小差了...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> save(User user) {
|
||||
return Result.error("网络出差中...");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.bwie.auth.service;
|
||||
|
||||
import com.bwie.common.domain.User;
|
||||
import com.bwie.common.domain.request.UserSendCodeReq;
|
||||
import com.bwie.common.domain.response.JwtResponse;
|
||||
import com.bwie.common.result.Result;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth.service
|
||||
* @Project:maven-month
|
||||
* @name:AuthService
|
||||
* @Date:2024/8/12 上午10:26
|
||||
*/
|
||||
public interface AuthService {
|
||||
Result<JwtResponse> login(User user);
|
||||
|
||||
Result<Object> register(User user);
|
||||
|
||||
User info();
|
||||
|
||||
Result<String> sendCode(UserSendCodeReq userSendCodeReq);
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package com.bwie.auth.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bwie.auth.feign.AuthFeign;
|
||||
import com.bwie.auth.service.AuthService;
|
||||
import com.bwie.common.constants.JwtConstants;
|
||||
import com.bwie.common.constants.TokenConstants;
|
||||
import com.bwie.common.domain.User;
|
||||
import com.bwie.common.domain.request.UserSendCodeReq;
|
||||
import com.bwie.common.domain.response.JwtResponse;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.common.utils.JwtUtils;
|
||||
import com.bwie.common.utils.StringUtils;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.auth.service.impl
|
||||
* @Project:maven-month
|
||||
* @name:AuthServiceImpl
|
||||
* @Date:2024/8/12 上午10:26
|
||||
*/
|
||||
@Log4j2
|
||||
@Service
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
@Autowired private AuthFeign authFeign;
|
||||
@Autowired private RedisTemplate redisTemplate;
|
||||
@Autowired private HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param user 用户信息
|
||||
* @return 登录结果
|
||||
*/
|
||||
@Override
|
||||
public Result<JwtResponse> login(User user) {
|
||||
log.info("验证:验证码...");
|
||||
String code = (String) redisTemplate.opsForValue().get(user.getUserTel());
|
||||
if (!Objects.equals(user.getCode(), code)){
|
||||
log.info("验证码错误");
|
||||
return Result.error("验证码错误");
|
||||
}
|
||||
log.info("检查登录账号在系统中是否存在...");
|
||||
Result<User> result = authFeign.selectByTel(user.getUserTel());
|
||||
User data = result.getData();
|
||||
if (StringUtils.isNull(data)) {
|
||||
log.info("系统中无此账号");
|
||||
log.info("新用户信息为:[{}],正在录入用户信息中....", JSONObject.toJSONString(user));
|
||||
authFeign.save(user);
|
||||
log.info("录入新用户信息成功");
|
||||
}
|
||||
log.info("登录成功");
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
String userKey = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
map.put(JwtConstants.USER_KEY,userKey);
|
||||
String token = JwtUtils.createToken(map);
|
||||
redisTemplate.opsForValue().set(
|
||||
TokenConstants.LOGIN_TOKEN_KEY+userKey,
|
||||
JSONObject.toJSONString(data),
|
||||
30,
|
||||
TimeUnit.MINUTES
|
||||
);
|
||||
JwtResponse jwtResponse = new JwtResponse();
|
||||
jwtResponse.setToken(token);
|
||||
jwtResponse.setStorageTime("30MIN");
|
||||
return Result.success(jwtResponse,"登录成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param user 注册用户信息
|
||||
* @return 注册结果
|
||||
*/
|
||||
@Override
|
||||
public Result<Object> register(User user) {
|
||||
Result<String> save = authFeign.save(user);
|
||||
return Result.success(save.getMsg());
|
||||
}
|
||||
|
||||
/**
|
||||
* info
|
||||
* @return user
|
||||
*/
|
||||
@Override
|
||||
public User info() {
|
||||
String token = request.getHeader(TokenConstants.TOKEN);
|
||||
String userKey = JwtUtils.getUserKey(token);
|
||||
String o = (String) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
|
||||
return JSONObject.parseObject(o,User.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送手机验证码
|
||||
* @param userSendCodeReq 手机信息
|
||||
* @return 发送结果
|
||||
*/
|
||||
@Override
|
||||
public Result<String> sendCode(UserSendCodeReq userSendCodeReq) {
|
||||
log.info("开始校验手机号格式...");
|
||||
if (!authenticationPhoneNumber(userSendCodeReq.getUserTel())){
|
||||
log.info("手机号:[{}]格式错误",userSendCodeReq.getUserTel());
|
||||
return Result.error("请输入正确手机号");
|
||||
}
|
||||
String code = String.valueOf(new Random().nextInt(10000));
|
||||
redisTemplate.opsForValue().set(
|
||||
userSendCodeReq.getUserTel(),
|
||||
code,
|
||||
5,
|
||||
TimeUnit.MINUTES);
|
||||
log.info("发送成功,验证码:[{}]",code);
|
||||
return Result.success("验证码:"+code,"验证码:"+code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验手机号格式
|
||||
* @param tel 手机号
|
||||
* @return 校验结果
|
||||
*/
|
||||
public static boolean authenticationPhoneNumber(String tel){
|
||||
return Pattern.matches("^(?:(?:\\+|00)86)?1[3-9]\\d{9}$",tel);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.bwie.auth.utils;
|
||||
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class DLXQueue {
|
||||
// routingKey
|
||||
private static final String DEAD_ROUTING_KEY = "dead.routingkey";
|
||||
private static final String ROUTING_KEY = "routingkey";
|
||||
private static final String DEAD_EXCHANGE = "dead.exchange";
|
||||
private static final String EXCHANGE = "common.exchange";
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
@Resource
|
||||
RabbitAdmin rabbitAdmin;
|
||||
|
||||
/**
|
||||
* 发送死信队列,过期后进入死信交换机,进入死信队列
|
||||
*
|
||||
* @param queueName 队列名称
|
||||
* @param deadQueueName 死信队列名称
|
||||
* @param params 消息内容
|
||||
* @param expiration 过期时间 毫秒
|
||||
*/
|
||||
public void sendDLXQueue(String queueName, String deadQueueName, Object params, Integer expiration) {
|
||||
/**
|
||||
* ----------------------------------先创建一个ttl队列和死信队列--------------------------------------------
|
||||
*/
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
// 队列设置存活时间,单位ms, 必须是整形数据。
|
||||
map.put("x-message-ttl", expiration);
|
||||
// 设置死信交换机
|
||||
map.put("x-dead-letter-exchange", DEAD_EXCHANGE);
|
||||
// 设置死信交换器路由
|
||||
map.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY);
|
||||
/*参数1:队列名称 参数2:持久化 参数3:是否排他 参数4:自动删除队列 参数5:队列参数*/
|
||||
Queue queue = new Queue(queueName, true, false, false, map);
|
||||
rabbitAdmin.declareQueue(queue);
|
||||
/**
|
||||
* ---------------------------------创建交换机---------------------------------------------
|
||||
*/
|
||||
DirectExchange directExchange = new DirectExchange(EXCHANGE, true, false);
|
||||
rabbitAdmin.declareExchange(directExchange);
|
||||
/**
|
||||
* ---------------------------------队列绑定交换机---------------------------------------------
|
||||
*/
|
||||
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(ROUTING_KEY);
|
||||
rabbitAdmin.declareBinding(binding);
|
||||
/**
|
||||
* ---------------------------------在创建一个死信交换机和队列,接收死信队列---------------------------------------------
|
||||
*/
|
||||
DirectExchange deadExchange = new DirectExchange(DEAD_EXCHANGE, true, false);
|
||||
rabbitAdmin.declareExchange(deadExchange);
|
||||
|
||||
Queue deadQueue = new Queue(deadQueueName, true, false, false);
|
||||
rabbitAdmin.declareQueue(deadQueue);
|
||||
/**
|
||||
* ---------------------------------队列绑定死信交换机---------------------------------------------
|
||||
*/
|
||||
// 将队列和交换机绑定
|
||||
Binding deadbinding = BindingBuilder.bind(deadQueue).to(deadExchange).with(DEAD_ROUTING_KEY);
|
||||
rabbitAdmin.declareBinding(deadbinding);
|
||||
// 发送消息
|
||||
rabbitTemplate.convertAndSend(EXCHANGE, ROUTING_KEY, params);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.bwie.auth.utils;
|
||||
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.CustomExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 发送延迟队列的工具类
|
||||
*/
|
||||
@Component
|
||||
public class DelayedQueue {
|
||||
|
||||
// routingKey
|
||||
private static final String DELAYED_ROUTING_KEY = "delayed.routingkey";
|
||||
|
||||
// 延迟队列交换机
|
||||
private static final String DELAYED_EXCHANGE = "delayed.exchange";
|
||||
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Resource
|
||||
RabbitAdmin rabbitAdmin;
|
||||
|
||||
/**
|
||||
* 发送延迟队列
|
||||
*
|
||||
* @param queueName 队列名称
|
||||
* @param params 消息内容
|
||||
* @param expiration 延迟时间 毫秒
|
||||
*/
|
||||
public void sendDelayedQueue(String queueName, Object params, Integer expiration) {
|
||||
// 先创建一个队列
|
||||
Queue queue = new Queue(queueName);
|
||||
rabbitAdmin.declareQueue(queue);
|
||||
|
||||
// 创建延迟队列交换机
|
||||
CustomExchange customExchange = createCustomExchange();
|
||||
rabbitAdmin.declareExchange(customExchange);
|
||||
|
||||
// 将队列和交换机绑定
|
||||
Binding binding = BindingBuilder.bind(queue).to(customExchange).with(DELAYED_ROUTING_KEY).noargs();
|
||||
rabbitAdmin.declareBinding(binding);
|
||||
|
||||
// 发送延迟消息
|
||||
rabbitTemplate.convertAndSend(DELAYED_EXCHANGE, DELAYED_ROUTING_KEY, params, msg -> {
|
||||
// 发送消息的时候 延迟时长
|
||||
msg.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
|
||||
msg.getMessageProperties().setDelay(expiration);
|
||||
return msg;
|
||||
});
|
||||
}
|
||||
|
||||
private CustomExchange createCustomExchange() {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
/**
|
||||
* 参数说明:
|
||||
* 1.交换机的名称
|
||||
* 2.交换机的类型
|
||||
* 3.是否需要持久化
|
||||
* 4.是否自动删除
|
||||
* 5.其它参数
|
||||
*/
|
||||
arguments.put("x-delayed-type", "direct");
|
||||
return new CustomExchange(DELAYED_EXCHANGE, "x-delayed-message", true, false, arguments);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.bwie.auth.utils;
|
||||
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 发送TTL队列 设置 消息的存活时间 如果超过了存活时间
|
||||
* 该条消息还没有被消费 则自动从队列中消息 ,如果配置了死信队列则消息会进入死信队列
|
||||
*/
|
||||
@Component
|
||||
public class TtlQueue {
|
||||
// routingKey
|
||||
private static final String TTL_KEY = "ttl.routingkey";
|
||||
private static final String TTL_EXCHANGE = "ttl.exchange";
|
||||
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Resource
|
||||
RabbitAdmin rabbitAdmin;
|
||||
|
||||
/**
|
||||
* 发送TTL队列
|
||||
*
|
||||
* @param queueName 队列名称
|
||||
* @param params 消息内容
|
||||
* @param expiration 过期时间 毫秒
|
||||
*/
|
||||
public void sendTtlQueue(String queueName, Object params, Integer expiration) {
|
||||
/**
|
||||
* ----------------------------------先创建一个ttl队列--------------------------------------------
|
||||
*/
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
// 队列设置存活时间,单位ms,必须是整形数据。
|
||||
map.put("x-message-ttl", expiration);
|
||||
/*参数1:队列名称 参数2:持久化 参数3:是否排他 参数4:自动删除队列 参数5:队列参数*/
|
||||
Queue queue = new Queue(queueName, true, false, false, map);
|
||||
rabbitAdmin.declareQueue(queue);
|
||||
|
||||
/**
|
||||
* ---------------------------------创建交换机---------------------------------------------
|
||||
*/
|
||||
DirectExchange directExchange = new DirectExchange(TTL_EXCHANGE, true, false);
|
||||
rabbitAdmin.declareExchange(directExchange);
|
||||
/**
|
||||
* ---------------------------------队列绑定交换机---------------------------------------------
|
||||
*/
|
||||
// 将队列和交换机绑定
|
||||
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(TTL_KEY);
|
||||
rabbitAdmin.declareBinding(binding);
|
||||
|
||||
// 发送消息
|
||||
rabbitTemplate.convertAndSend(TTL_EXCHANGE, TTL_KEY, params);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9001
|
||||
# Spring
|
||||
spring:
|
||||
main:
|
||||
allow-circular-references: true
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
time-zone: GMT+8
|
||||
application:
|
||||
# 应用名称
|
||||
name: bwie-auth
|
||||
kafka:
|
||||
producer:
|
||||
# Kafka服务器
|
||||
bootstrap-servers: 111.229.195.89:9092
|
||||
# 开启事务,必须在开启了事务的方法中发送,否则报错
|
||||
transaction-id-prefix: kafkaTx-
|
||||
# 发生错误后,消息重发的次数,开启事务必须设置大于0。
|
||||
retries: 3
|
||||
# acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
|
||||
# acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
|
||||
# acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
|
||||
# 开启事务时,必须设置为all
|
||||
acks: all
|
||||
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
|
||||
batch-size: 16384
|
||||
# 生产者内存缓冲区的大小。
|
||||
buffer-memory: 1024000
|
||||
# 键的序列化方式
|
||||
key-serializer: org.springframework.kafka.support.serializer.JsonSerializer
|
||||
# 值的序列化方式(建议使用Json,这种序列化方式可以无需额外配置传输实体类)
|
||||
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
|
||||
|
||||
consumer:
|
||||
# Kafka服务器
|
||||
bootstrap-servers: 111.229.195.89:9092
|
||||
group-id: firstGroup
|
||||
# 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D
|
||||
#auto-commit-interval: 2s
|
||||
# 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
|
||||
# earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费分区的记录
|
||||
# latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据(在消费者启动之后生成的记录)
|
||||
# none:当各分区都存在已提交的offset时,从提交的offset开始消费;只要有一个分区不存在已提交的offset,则抛出异常
|
||||
auto-offset-reset: latest
|
||||
# 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
|
||||
enable-auto-commit: false
|
||||
# 键的反序列化方式
|
||||
#key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
|
||||
key-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
|
||||
# 值的反序列化方式(建议使用Json,这种序列化方式可以无需额外配置传输实体类)
|
||||
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
|
||||
# 配置消费者的 Json 反序列化的可信赖包,反序列化实体类需要
|
||||
properties:
|
||||
spring:
|
||||
json:
|
||||
trusted:
|
||||
packages: "*"
|
||||
# 这个参数定义了poll方法最多可以拉取多少条消息,默认值为500。如果在拉取消息的时候新消息不足500条,那有多少返回多少;如果超过500条,每次只返回500。
|
||||
# 这个默认值在有些场景下太大,有些场景很难保证能够在5min内处理完500条消息,
|
||||
# 如果消费者无法在5分钟内处理完500条消息的话就会触发reBalance,
|
||||
# 然后这批消息会被分配到另一个消费者中,还是会处理不完,这样这批消息就永远也处理不完。
|
||||
# 要避免出现上述问题,提前评估好处理一条消息最长需要多少时间,然后覆盖默认的max.poll.records参数
|
||||
# 注:需要开启BatchListener批量监听才会生效,如果不开启BatchListener则不会出现reBalance情况
|
||||
max-poll-records: 3
|
||||
properties:
|
||||
# 两次poll之间的最大间隔,默认值为5分钟。如果超过这个间隔会触发reBalance
|
||||
max:
|
||||
poll:
|
||||
interval:
|
||||
ms: 600000
|
||||
# 当broker多久没有收到consumer的心跳请求后就触发reBalance,默认值是10s
|
||||
session:
|
||||
timeout:
|
||||
ms: 10000
|
||||
listener:
|
||||
# 在侦听器容器中运行的线程数,一般设置为 机器数*分区数
|
||||
concurrency: 4
|
||||
# 自动提交关闭,需要设置手动消息确认
|
||||
ack-mode: manual_immediate
|
||||
# 消费监听接口监听的主题不存在时,默认会报错,所以设置为false忽略错误
|
||||
missing-topics-fatal: false
|
||||
# 两次poll之间的最大间隔,默认值为5分钟。如果超过这个间隔会触发reBalance
|
||||
poll-timeout: 600000
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 111.229.195.89:8848
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 111.229.195.89:8848
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
rabbitmq:
|
||||
username: root
|
||||
password: zzh123
|
||||
virtualHost: /
|
||||
port: 5672
|
||||
host: 111.229.195.89
|
||||
listener:
|
||||
simple:
|
||||
prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条
|
||||
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
|
||||
publisher-returns: true #确认消息已发送到队列(Queue)
|
|
@ -0,0 +1,38 @@
|
|||
package com.yuan;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
extends TestCase
|
||||
{
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public AppTest( String testName )
|
||||
{
|
||||
super( testName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
return new TestSuite( AppTest.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rigourous Test :-)
|
||||
*/
|
||||
public void testApp()
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>maven-month</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>yuan-common</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>yuan-common</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- bootstrap 启动器 -->
|
||||
<!-- Java Servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
<!-- 负载均衡-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringCloud Openfeign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
<!-- Alibaba Fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.80</version>
|
||||
</dependency>
|
||||
<!-- SpringBoot Boot Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- Hibernate Validator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<!-- Apache Lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<!-- lombok依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<!-- hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.3</version>
|
||||
</dependency>
|
||||
<!-- 阿里大鱼 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
<!-- rabbitMQ -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,18 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* @description: 系统常量
|
||||
* @author DongZl
|
||||
*/
|
||||
public class Constants {
|
||||
/**
|
||||
* 成功标记
|
||||
*/
|
||||
public static final Integer SUCCESS = 200;
|
||||
public static final String SUCCESS_MSG = "操作成功";
|
||||
/**
|
||||
* 失败标记
|
||||
*/
|
||||
public static final Integer ERROR = 500;
|
||||
public static final String ERROR_MSG = "操作异常";
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: Jwt常量
|
||||
*/
|
||||
public class JwtConstants {
|
||||
|
||||
/**
|
||||
* 用户ID字段
|
||||
*/
|
||||
public static final String DETAILS_USER_ID = "user_id";
|
||||
|
||||
/**
|
||||
* 用户名字段
|
||||
*/
|
||||
public static final String DETAILS_USERNAME = "username";
|
||||
|
||||
/**
|
||||
* 用户标识
|
||||
*/
|
||||
public static final String USER_KEY = "user_key";
|
||||
|
||||
/**
|
||||
* 令牌秘钥
|
||||
*/
|
||||
public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* @Project boot-month
|
||||
* @Author 张子豪
|
||||
* @Date 2023/9/6 10:06-+
|
||||
* @Description
|
||||
*/
|
||||
public class QueueConstants {
|
||||
|
||||
public static final String SEND_CODE_QUEUE = "send_code_queue";
|
||||
public static final String SEND_CODE_PREVENT_REPEAT_ID = "send_code_prevent_repeat_id:";
|
||||
public static final String BLOG_UPDATE_QUEUE = "blog_update_queue";
|
||||
public static final String BLOG_UPDATE_PREVENT_REPEAT_ID = "blog_update_prevent_repeat_id:";
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* Clazz:2103A
|
||||
* Name :FYSN
|
||||
* Desc :世界上只有一种英雄主义。那就是认清生活的真相后,仍然热爱生活。--罗曼·罗兰
|
||||
* Date :2023-08-20 20:37:02
|
||||
*/
|
||||
|
||||
public class RabbitMQOneConstants {
|
||||
|
||||
//发送短消息队列名称
|
||||
public static final String SEND_SHORT_MESSAGE_QUEUE_NAME = "send_short_message";
|
||||
|
||||
//查看的日志队列名称
|
||||
public static final String QUERY_LOG_QUEUE_NAME = "query_log_message";
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* Clazz:2103A
|
||||
* Name :FYSN
|
||||
* Desc :世界上只有一种英雄主义。那就是认清生活的真相后,仍然热爱生活。--罗曼·罗兰
|
||||
* Date :2023-08-20 20:37:02
|
||||
*/
|
||||
|
||||
public class RabbitMQTwoConstants {
|
||||
|
||||
//发送消息队列名称
|
||||
public static final String SEND_SMS_QUEUE = "send_sms_queue";
|
||||
|
||||
//添加消息队列名称日志
|
||||
public static final String ADD_MESSAGE_QUEUE_NAME_LOG = "add_message_log";
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.bwie.common.constants;
|
||||
|
||||
/**
|
||||
* @author DongZl
|
||||
* @description: 令牌常量
|
||||
*/
|
||||
public class TokenConstants {
|
||||
/**
|
||||
* 缓存有效期,默认720(分钟)
|
||||
*/
|
||||
public final static long EXPIRATION = 720;
|
||||
/**
|
||||
* 缓存刷新时间,默认120(分钟)
|
||||
*/
|
||||
public final static long REFRESH_TIME = 120;
|
||||
/**
|
||||
* 权限缓存前缀
|
||||
*/
|
||||
public final static String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||
/**
|
||||
* token标识
|
||||
*/
|
||||
public static final String TOKEN = "token";
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.bwie.common.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain
|
||||
* @Project:maven-month
|
||||
* @name:PurchaseOrder
|
||||
* @Date:2024/8/12 下午12:11
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PurchaseOrder {
|
||||
|
||||
/**
|
||||
* 购买订单编号
|
||||
*/
|
||||
private Integer purchaseOrderId ;
|
||||
/**
|
||||
* 卷码编号
|
||||
*/
|
||||
private Integer volumeCodeId ;
|
||||
/**
|
||||
* 购买人
|
||||
*/
|
||||
private Integer userId ;
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
private Integer purchaseQuantity ;
|
||||
/**
|
||||
* 购买总价
|
||||
*/
|
||||
private BigDecimal purchasePrice ;
|
||||
/**
|
||||
* 购买订单状态 0未收货 1已收货
|
||||
*/
|
||||
private Integer purchaseOrderStatus ;
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.bwie.common.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain
|
||||
* @Project:maven-month
|
||||
* @name:User
|
||||
* @Date:2024/8/12 上午9:48
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class User {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private String userId ;
|
||||
/**
|
||||
* 用户手机号
|
||||
*/
|
||||
private String userTel ;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String name ;
|
||||
/**
|
||||
* 余额
|
||||
*/
|
||||
private String balance ;
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String code ;
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.bwie.common.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCode
|
||||
* @Date:2024/8/12 下午12:10
|
||||
* 寄售卷码
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolumeCode {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer volumeCodeId ;
|
||||
/**
|
||||
* 卷码名称
|
||||
*/
|
||||
private String volumeCodeName ;
|
||||
/**
|
||||
* 卷码图片
|
||||
*/
|
||||
private String volumeCodePic ;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId ;
|
||||
/**
|
||||
* 卷码类型编号
|
||||
*/
|
||||
private Integer volumeCodeTypeId ;
|
||||
/**
|
||||
* 卷码价格
|
||||
*/
|
||||
private BigDecimal volumeCodeMoney ;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer volumeCodeNum ;
|
||||
/**
|
||||
* 转让时间
|
||||
*/
|
||||
private String volumeCodeCreateTime ;
|
||||
/**
|
||||
* 订单状态 0 寄售中 1 已销售 2 待使用 3 待打款 4完成 5关闭
|
||||
*/
|
||||
private Integer orderStatus ;
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bwie.common.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeType
|
||||
* @Date:2024/8/12 下午12:08
|
||||
* 卷码类型
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolumeCodeType {
|
||||
|
||||
/**
|
||||
* 类型编号
|
||||
*/
|
||||
private Integer volumeCodeTypeId ;
|
||||
/**
|
||||
* 类型名称
|
||||
*/
|
||||
private String volumeCodeTypeName ;
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:PurchaseOrderAddReq
|
||||
* @Date:2024/8/12 下午6:20
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PurchaseOrderAddReq {
|
||||
|
||||
/**
|
||||
* 购买订单编号
|
||||
*/
|
||||
private Integer purchaseOrderId ;
|
||||
/**
|
||||
* 卷码编号
|
||||
*/
|
||||
private Integer volumeCodeId ;
|
||||
/**
|
||||
* 购买人
|
||||
*/
|
||||
private Integer userId ;
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
private Integer purchaseQuantity ;
|
||||
/**
|
||||
* 购买总价
|
||||
*/
|
||||
private BigDecimal purchasePrice ;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:PurchaseOrderPayReq
|
||||
* @Date:2024/8/12 下午8:03
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PurchaseOrderPayReq {
|
||||
|
||||
/**
|
||||
* 购买订单编号
|
||||
*/
|
||||
private Integer purchaseOrderId ;
|
||||
/**
|
||||
* 卷码编号
|
||||
*/
|
||||
private Integer volumeCodeId ;
|
||||
/**
|
||||
* 购买人
|
||||
*/
|
||||
private Integer buyUserId ;
|
||||
/**
|
||||
* 贩卖人
|
||||
*/
|
||||
private Integer peddleUserId ;
|
||||
/**
|
||||
* 购买总价
|
||||
*/
|
||||
private BigDecimal purchasePrice ;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:UserRegisterReq
|
||||
* @Date:2024/8/12 上午11:52
|
||||
* 用户注册
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserRegisterReq {
|
||||
|
||||
/**
|
||||
* 用户手机号
|
||||
*/
|
||||
private String userTel ;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String name ;
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.response
|
||||
* @Project:maven-month
|
||||
* @name:UserSendCodeRes
|
||||
* @Date:2024/8/12 上午11:22
|
||||
* 发送验证
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserSendCodeReq {
|
||||
|
||||
private String userTel ;
|
||||
private String code ;
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeAddReq
|
||||
* @Date:2024/8/12 下午4:24
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolumeCodeAddReq {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer volumeCodeId ;
|
||||
/**
|
||||
* 卷码名称
|
||||
*/
|
||||
private String volumeCodeName ;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer userId ;
|
||||
/**
|
||||
* 卷码类型编号
|
||||
*/
|
||||
private Integer volumeCodeTypeId ;
|
||||
/**
|
||||
* 卷码价格
|
||||
*/
|
||||
private BigDecimal volumeCodeMoney ;
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bwie.common.domain.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeReq
|
||||
* @Date:2024/8/12 下午1:54
|
||||
* 卷码查询
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolumeCodeSelectReq {
|
||||
|
||||
/**
|
||||
* 卷码名称
|
||||
*/
|
||||
private String volumeCodeName ;
|
||||
/**
|
||||
* 卷码类型编号
|
||||
*/
|
||||
private Integer volumeCodeTypeId ;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.bwie.common.domain.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.response
|
||||
* @Project:maven-month
|
||||
* @name:JwtResponse
|
||||
* @Date:2024/8/12 上午9:49
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class JwtResponse {
|
||||
|
||||
private String token;
|
||||
private String storageTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.bwie.common.domain.response;
|
||||
|
||||
import com.bwie.common.domain.PurchaseOrder;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.request
|
||||
* @Project:maven-month
|
||||
* @name:PurchaseOrderSelectReq
|
||||
* @Date:2024/8/12 下午7:29
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PurchaseOrderListRes extends PurchaseOrder {
|
||||
|
||||
/**
|
||||
* 卷码名称
|
||||
*/
|
||||
private String volumeCodeName ;
|
||||
/**
|
||||
* 卷码图片
|
||||
*/
|
||||
private String volumeCodePic ;
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.bwie.common.domain.response;
|
||||
|
||||
import com.bwie.common.domain.VolumeCode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.common.domain.response
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeListRes
|
||||
* @Date:2024/8/12 下午1:00
|
||||
* 卷码列表
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VolumeCodeListRes extends VolumeCode {
|
||||
|
||||
/**
|
||||
* 类型名称
|
||||
*/
|
||||
private String volumeCodeTypeName ;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.bwie.common.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PageResult<T> implements Serializable {
|
||||
/**
|
||||
* 总条数
|
||||
*/
|
||||
private long total;
|
||||
/**
|
||||
* 结果集合
|
||||
*/
|
||||
private List<T> list;
|
||||
public PageResult() {
|
||||
}
|
||||
public PageResult(long total, List<T> list) {
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
public static <T> PageResult<T> toPageResult(long total, List<T> list){
|
||||
return new PageResult(total , list);
|
||||
}
|
||||
public static <T> Result<PageResult<T>> toResult(long total, List<T> list){
|
||||
return Result.success(PageResult.toPageResult(total,list));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.bwie.common.result;
|
||||
|
||||
import com.bwie.common.constants.Constants;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class Result<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
public static final int SUCCESS = Constants.SUCCESS;
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
public static final int FAIL = Constants.ERROR;
|
||||
/**
|
||||
* 返回状态码
|
||||
*/
|
||||
private int code;
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String msg;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
public static <T> Result<T> success() {
|
||||
return restResult(null, SUCCESS, Constants.SUCCESS_MSG);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
return restResult(data, SUCCESS, Constants.SUCCESS_MSG);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data, String msg) {
|
||||
return restResult(data, SUCCESS, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error() {
|
||||
return restResult(null, FAIL, Constants.ERROR_MSG);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String msg) {
|
||||
return restResult(null, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(T data) {
|
||||
return restResult(data, FAIL, Constants.ERROR_MSG);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(T data, String msg) {
|
||||
return restResult(data, FAIL, msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(int code, String msg) {
|
||||
return restResult(null, code, msg);
|
||||
}
|
||||
|
||||
private static <T> Result<T> restResult(T data, int code, String msg) {
|
||||
Result<T> apiResult = new Result<>();
|
||||
apiResult.setCode(code);
|
||||
apiResult.setData(data);
|
||||
apiResult.setMsg(msg);
|
||||
return apiResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
package com.bwie.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
|
||||
public class IpUtils {
|
||||
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
|
||||
// 匹配 ip
|
||||
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
|
||||
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
|
||||
// 匹配网段
|
||||
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
|
||||
|
||||
/**
|
||||
* 获取客户端IP
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
if (request == null) {
|
||||
return "unknown";
|
||||
}
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为内部IP地址
|
||||
*
|
||||
* @param ip IP地址
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean internalIp(String ip) {
|
||||
byte[] addr = textToNumericFormatV4(ip);
|
||||
return internalIp(addr) || "127.0.0.1".equals(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为内部IP地址
|
||||
*
|
||||
* @param addr byte地址
|
||||
* @return 结果
|
||||
*/
|
||||
private static boolean internalIp(byte[] addr) {
|
||||
if (StringUtils.isNull(addr) || addr.length < 2) {
|
||||
return true;
|
||||
}
|
||||
final byte b0 = addr[0];
|
||||
final byte b1 = addr[1];
|
||||
// 10.x.x.x/8
|
||||
final byte SECTION_1 = 0x0A;
|
||||
// 172.16.x.x/12
|
||||
final byte SECTION_2 = (byte) 0xAC;
|
||||
final byte SECTION_3 = (byte) 0x10;
|
||||
final byte SECTION_4 = (byte) 0x1F;
|
||||
// 192.168.x.x/16
|
||||
final byte SECTION_5 = (byte) 0xC0;
|
||||
final byte SECTION_6 = (byte) 0xA8;
|
||||
switch (b0) {
|
||||
case SECTION_1:
|
||||
return true;
|
||||
case SECTION_2:
|
||||
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
|
||||
return true;
|
||||
}
|
||||
case SECTION_5:
|
||||
switch (b1) {
|
||||
case SECTION_6:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将IPv4地址转换成字节
|
||||
*
|
||||
* @param text IPv4地址
|
||||
* @return byte 字节
|
||||
*/
|
||||
public static byte[] textToNumericFormatV4(String text) {
|
||||
if (text.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
String[] elements = text.split("\\.", -1);
|
||||
try {
|
||||
long l;
|
||||
int i;
|
||||
switch (elements.length) {
|
||||
case 1:
|
||||
l = Long.parseLong(elements[0]);
|
||||
if ((l < 0L) || (l > 4294967295L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
|
||||
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 2:
|
||||
l = Integer.parseInt(elements[0]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l & 0xFF);
|
||||
l = Integer.parseInt(elements[1]);
|
||||
if ((l < 0L) || (l > 16777215L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 3:
|
||||
for (i = 0; i < 2; ++i) {
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
l = Integer.parseInt(elements[2]);
|
||||
if ((l < 0L) || (l > 65535L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 4:
|
||||
for (i = 0; i < 4; ++i) {
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L)) {
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* @return 本地IP地址
|
||||
*/
|
||||
public static String getHostIp() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主机名
|
||||
*
|
||||
* @return 本地主机名
|
||||
*/
|
||||
public static String getHostName() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
return "未知";
|
||||
}
|
||||
|
||||
/**
|
||||
* 从多级反向代理中获得第一个非unknown IP地址
|
||||
*
|
||||
* @param ip 获得的IP地址
|
||||
* @return 第一个非unknown IP地址
|
||||
*/
|
||||
public static String getMultistageReverseProxyIp(String ip) {
|
||||
// 多级反向代理检测
|
||||
if (ip != null && ip.indexOf(",") > 0) {
|
||||
final String[] ips = ip.trim().split(",");
|
||||
for (String subIp : ips) {
|
||||
if (false == isUnknown(subIp)) {
|
||||
ip = subIp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.substring(ip, 0, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测给定字符串是否为未知,多用于检测HTTP请求相关
|
||||
*
|
||||
* @param checkString 被检测的字符串
|
||||
* @return 是否未知
|
||||
*/
|
||||
public static boolean isUnknown(String checkString) {
|
||||
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为IP
|
||||
*/
|
||||
public static boolean isIP(String ip) {
|
||||
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为IP,或 *为间隔的通配符地址
|
||||
*/
|
||||
public static boolean isIpWildCard(String ip) {
|
||||
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测参数是否在ip通配符里
|
||||
*/
|
||||
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) {
|
||||
String[] s1 = ipWildCard.split("\\.");
|
||||
String[] s2 = ip.split("\\.");
|
||||
boolean isMatchedSeg = true;
|
||||
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) {
|
||||
if (!s1[i].equals(s2[i])) {
|
||||
isMatchedSeg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isMatchedSeg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
|
||||
*/
|
||||
public static boolean isIPSegment(String ipSeg) {
|
||||
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断ip是否在指定网段中
|
||||
*/
|
||||
public static boolean ipIsInNetNoCheck(String iparea, String ip) {
|
||||
int idx = iparea.indexOf('-');
|
||||
String[] sips = iparea.substring(0, idx).split("\\.");
|
||||
String[] sipe = iparea.substring(idx + 1).split("\\.");
|
||||
String[] sipt = ip.split("\\.");
|
||||
long ips = 0L, ipe = 0L, ipt = 0L;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ips = ips << 8 | Integer.parseInt(sips[i]);
|
||||
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
||||
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
||||
}
|
||||
if (ips > ipe) {
|
||||
long t = ips;
|
||||
ips = ipe;
|
||||
ipe = t;
|
||||
}
|
||||
return ips <= ipt && ipt <= ipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验ip是否符合过滤串规则
|
||||
*
|
||||
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
|
||||
* @param ip 校验IP地址
|
||||
* @return boolean 结果
|
||||
*/
|
||||
public static boolean isMatchedIp(String filter, String ip) {
|
||||
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) {
|
||||
return false;
|
||||
}
|
||||
String[] ips = filter.split(";");
|
||||
for (String iStr : ips) {
|
||||
if (isIP(iStr) && iStr.equals(ip)) {
|
||||
return true;
|
||||
} else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) {
|
||||
return true;
|
||||
} else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.bwie.common.utils;
|
||||
|
||||
import com.bwie.common.constants.JwtConstants;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class JwtUtils {
|
||||
|
||||
/**
|
||||
* 秘钥
|
||||
*/
|
||||
public static String secret = JwtConstants.SECRET;
|
||||
|
||||
/**
|
||||
* 从数据声明生成令牌
|
||||
*
|
||||
* @param claims 数据声明
|
||||
* @return 令牌
|
||||
*/
|
||||
public static String createToken(Map<String, Object> claims){
|
||||
String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取数据声明
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 数据声明
|
||||
*/
|
||||
public static Claims parseToken(String token){
|
||||
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||
}
|
||||
/**
|
||||
* 根据令牌获取用户标识
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 用户ID
|
||||
*/
|
||||
public static String getUserKey(String token){
|
||||
Claims claims = parseToken(token);
|
||||
return getValue(claims, JwtConstants.USER_KEY);
|
||||
}
|
||||
/**
|
||||
* 根据令牌获取用户标识
|
||||
*
|
||||
* @param claims 身份信息
|
||||
* @return 用户ID
|
||||
*/
|
||||
public static String getUserKey(Claims claims){
|
||||
return getValue(claims, JwtConstants.USER_KEY);
|
||||
}
|
||||
/**
|
||||
* 根据令牌获取用户ID
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 用户ID
|
||||
*/
|
||||
public static String getUserId(String token){
|
||||
Claims claims = parseToken(token);
|
||||
return getValue(claims, JwtConstants.DETAILS_USER_ID);
|
||||
}
|
||||
/**
|
||||
* 根据身份信息获取用户ID
|
||||
*
|
||||
* @param claims 身份信息
|
||||
* @return 用户ID
|
||||
*/
|
||||
public static String getUserId(Claims claims){
|
||||
return getValue(claims, JwtConstants.DETAILS_USER_ID);
|
||||
}
|
||||
/**
|
||||
* 根据令牌获取用户名
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 用户名
|
||||
*/
|
||||
public static String getUserName(String token){
|
||||
Claims claims = parseToken(token);
|
||||
return getValue(claims, JwtConstants.DETAILS_USERNAME);
|
||||
}
|
||||
/**
|
||||
* 根据身份信息获取用户名
|
||||
*
|
||||
* @param claims 身份信息
|
||||
* @return 用户名
|
||||
*/
|
||||
public static String getUserName(Claims claims){
|
||||
return getValue(claims, JwtConstants.DETAILS_USERNAME);
|
||||
}
|
||||
/**
|
||||
* 根据身份信息获取键值
|
||||
*
|
||||
* @param claims 身份信息
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public static String getValue(Claims claims, String key){
|
||||
Object obj = claims.get(key);
|
||||
return obj == null ? "" : obj.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.bwie.common.utils;
|
||||
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否为空
|
||||
*
|
||||
* @param object Object
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isNull(Object object) {
|
||||
return object == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个Collection是否为空, 包含List,Set,Queue
|
||||
*
|
||||
* @param coll 要判断的Collection
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isEmpty(Collection<?> coll) {
|
||||
return isNull(coll) || coll.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
|
||||
*
|
||||
* @param str 指定字符串
|
||||
* @param strs 需要检查的字符串数组
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public static boolean matches(String str, List<String> strs) {
|
||||
if (isEmpty(str) || isEmpty(strs)) {
|
||||
return false;
|
||||
}
|
||||
for (String pattern : strs) {
|
||||
if (isMatch(pattern, str))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否与规则配置:
|
||||
* ? 表示单个字符;
|
||||
* * 表示一层路径内的任意字符串,不可跨层级;
|
||||
* ** 表示任意层路径;
|
||||
*
|
||||
* @param pattern 匹配规则
|
||||
* @param url 需要匹配的url
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMatch(String pattern, String url) {
|
||||
AntPathMatcher matcher = new AntPathMatcher();
|
||||
return matcher.match(pattern, url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.bwie.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Log4j2
|
||||
public class TelSmsUtils {
|
||||
|
||||
/**
|
||||
* 阿里云主账号AccessKey,accessKeySecret拥有所有API的访问权限
|
||||
*/
|
||||
private static String accessKeyId = "LTAI5tQWdAodc1EJ1doShoW4";
|
||||
private static String accessKeySecret = "9MbfDBJ3Efqc6iN5yPFX0zq3ZErsII";
|
||||
private static String templateCode = "SMS0001";
|
||||
|
||||
/**
|
||||
* 短信访问域名
|
||||
*/
|
||||
private static String endpoint = "dysmsapi.aliyuncs.com";
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
private static String signName = "登录验证";
|
||||
|
||||
/**
|
||||
* 实例化短信对象
|
||||
*/
|
||||
private static Client client;
|
||||
|
||||
static {
|
||||
log.info("初始化短信服务开始");
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
client = initClient();
|
||||
log.info("初始化短信成功:{}",signName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info("初始化短信服务结束:耗时:{}MS",(System.currentTimeMillis()-startTime));
|
||||
}
|
||||
/**
|
||||
* 初始化短信对象
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Client initClient() throws Exception{
|
||||
Config config = new Config()
|
||||
// 您的AccessKey ID
|
||||
.setAccessKeyId(accessKeyId)
|
||||
// 您的AccessKey Secret
|
||||
.setAccessKeySecret(accessKeySecret);
|
||||
// 访问的域名
|
||||
config.endpoint = endpoint;
|
||||
return new Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送单条短信
|
||||
* @param tel
|
||||
* @param templateCode SMS_153991546
|
||||
* @param sendDataMap
|
||||
*/
|
||||
public static String sendSms(String tel, String templateCode,Map<String,String> sendDataMap){
|
||||
SendSmsRequest sendSmsRequest = new SendSmsRequest()
|
||||
.setPhoneNumbers(tel)
|
||||
.setSignName(signName)
|
||||
.setTemplateCode(templateCode)
|
||||
.setTemplateParam(JSONObject.toJSONString(sendDataMap));
|
||||
SendSmsResponse sendSmsResponse = null;
|
||||
try {
|
||||
log.info("发送短信验证码:消息内容是:【{}】", JSONObject.toJSONString(sendDataMap));
|
||||
sendSmsResponse = client.sendSms(sendSmsRequest);
|
||||
} catch (Exception e) {
|
||||
log.error("短信发送异常,手机号:【{}】,短信内容:【{}】,异常信息:【{}】", tel, sendDataMap, e);
|
||||
}
|
||||
return JSONObject.toJSONString(sendSmsResponse.getBody());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.yuan;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
extends TestCase
|
||||
{
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public AppTest( String testName )
|
||||
{
|
||||
super( testName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
return new TestSuite( AppTest.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rigourous Test :-)
|
||||
*/
|
||||
public void testApp()
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>maven-month</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>yuan-es</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>yuan-es</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>yuan-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>elasticsearch-rest-high-level-client</artifactId>
|
||||
</dependency>
|
||||
<!-- es:-->
|
||||
<!-- hostname: 106.54.222.192-->
|
||||
<!-- port: 9200-->
|
||||
<!-- scheme: http-->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,20 @@
|
|||
package com.bwie.es;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es
|
||||
* @Project:maven-month
|
||||
* @name:YuanEsApplication
|
||||
* @Date:2024/8/12 下午1:35
|
||||
*/
|
||||
@EnableFeignClients
|
||||
@SpringBootApplication
|
||||
public class YuanEsApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(YuanEsApplication.class,args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.bwie.es.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "es")
|
||||
@Data
|
||||
public class InitEsRes {
|
||||
private String host;
|
||||
private int port;
|
||||
private String scheme;
|
||||
|
||||
@Bean
|
||||
public RestHighLevelClient restHighLevelClient(){
|
||||
return new RestHighLevelClient(
|
||||
RestClient.builder(new HttpHost(host,port,scheme))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package com.bwie.es.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.bwie.common.domain.VolumeCodeType;
|
||||
import com.bwie.common.domain.request.PurchaseOrderAddReq;
|
||||
import com.bwie.common.domain.request.PurchaseOrderPayReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeAddReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeSelectReq;
|
||||
import com.bwie.common.domain.response.PurchaseOrderListRes;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.es.service.EsVolumeCodeService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.controller
|
||||
* @Project:maven-month
|
||||
* @name:EsVolumeCodeController
|
||||
* @Date:2024/8/12 下午1:52
|
||||
*/
|
||||
@Log4j2
|
||||
@RestController
|
||||
@RequestMapping("/es")
|
||||
public class EsVolumeCodeController {
|
||||
|
||||
@Autowired private EsVolumeCodeService esVolumeCodeService;
|
||||
|
||||
/**
|
||||
* 查询Es中同步MySQL卷码数据
|
||||
* @param volumeCodeSelectReq 卷码查询条件
|
||||
* @return 卷码数据
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public Result<List<VolumeCodeListRes>> list(@RequestBody VolumeCodeSelectReq volumeCodeSelectReq){
|
||||
log.info("Es列表查询中...");
|
||||
Result<List<VolumeCodeListRes>> result = esVolumeCodeService.list(volumeCodeSelectReq);
|
||||
log.info("查询信息:[{}]",result.getData());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询卷码种类
|
||||
* @return 种类信息
|
||||
*/
|
||||
@PostMapping("/findByType")
|
||||
public Result<List<VolumeCodeType>> findByType(){
|
||||
log.info("查询卷码种类");
|
||||
Result<List<VolumeCodeType>> result = esVolumeCodeService.findByType();
|
||||
log.info("卷码类型:[{}]", JSON.toJSONString(result.getData()));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加卷码信息
|
||||
* @param volumeCodeAddReq 添加卷码信息
|
||||
* @return 添加结果
|
||||
*/
|
||||
@PostMapping("/addvc")
|
||||
public Result<String> addvc(@RequestBody VolumeCodeAddReq volumeCodeAddReq){
|
||||
log.info("执行添加");
|
||||
log.info("添加卷码信息:[{}]",JSON.toJSONString(volumeCodeAddReq));
|
||||
Result<String> result = esVolumeCodeService.addvc(volumeCodeAddReq);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* mq异步 同步添加es
|
||||
* @param volumeCodeAddReq 添加信息
|
||||
* @return 添加结果
|
||||
*/
|
||||
@PostMapping("/addVolumeCode")
|
||||
public Result<String> addVolumeCode(@RequestBody VolumeCodeAddReq volumeCodeAddReq){
|
||||
return esVolumeCodeService.addVolumeCode(volumeCodeAddReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 买卷列表
|
||||
* @param volumeCodeSelectReq
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/toBuyList")
|
||||
public Result<List<VolumeCodeListRes>> RequestBody(@RequestBody VolumeCodeSelectReq volumeCodeSelectReq){
|
||||
log.info("Es列表查询中...");
|
||||
Result<List<VolumeCodeListRes>> result = esVolumeCodeService.RequestBody(volumeCodeSelectReq);
|
||||
log.info("查询信息:[{}]",result.getData());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行购买订单
|
||||
* @param purchaseOrderAddReq 购买信息
|
||||
* @return 购买结果
|
||||
*/
|
||||
@PostMapping("/toBuyOrder")
|
||||
public Result<String> toBuyOrder(@RequestBody PurchaseOrderAddReq purchaseOrderAddReq){
|
||||
log.info("正在购买卷码...");
|
||||
log.info("购买信息:[{}]",JSON.toJSONString(purchaseOrderAddReq));
|
||||
Result<String> result = esVolumeCodeService.toBuyOrder(purchaseOrderAddReq);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询购买订单信息
|
||||
* @return 订单信息
|
||||
*/
|
||||
@PostMapping("/selectPurchaseOrderList")
|
||||
public Result<List<PurchaseOrderListRes>> selectPurchaseOrderList(){
|
||||
log.info("查询购买订单列表...");
|
||||
Result<List<PurchaseOrderListRes>> result = esVolumeCodeService.selectPurchaseOrderList();
|
||||
log.info("购买订单信息:[{}]",JSON.toJSONString(result.getData()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/payAnOrder")
|
||||
public Result<String> payAnOrder(@RequestBody PurchaseOrderPayReq purchaseOrderPayReq){
|
||||
log.info("正在执行收货");
|
||||
Result<String> result = esVolumeCodeService.payAnOrder(purchaseOrderPayReq);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.bwie.es.feign;
|
||||
|
||||
import com.bwie.common.domain.request.PurchaseOrderAddReq;
|
||||
import com.bwie.common.domain.request.PurchaseOrderPayReq;
|
||||
import com.bwie.common.domain.response.PurchaseOrderListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.feign
|
||||
* @Project:maven-month
|
||||
* @name:EsPurchaseOrderFeign
|
||||
* @Date:2024/8/12 下午6:36
|
||||
*/
|
||||
@FeignClient("bwie-purchaseorder")
|
||||
public interface EsPurchaseOrderFeign {
|
||||
/**
|
||||
* 添加购买订单
|
||||
* @param purchaseOrderAddReq 订单信息
|
||||
* @return 购买结果
|
||||
*/
|
||||
@PostMapping("/purchaseOrder/addPurchaseOrder")
|
||||
public Result<String> addPurchaseOrder(@RequestBody PurchaseOrderAddReq purchaseOrderAddReq);
|
||||
|
||||
/**
|
||||
* 查询购买订单信息
|
||||
* @return 订单信息
|
||||
*/
|
||||
@PostMapping("/purchaseOrder/list")
|
||||
public Result<List<PurchaseOrderListRes>> selectPurchaseOrderList();
|
||||
|
||||
/**
|
||||
* 收货支付订单
|
||||
* @param purchaseOrderPayReq 修改订单参数
|
||||
* @return 修改订单信息
|
||||
*/
|
||||
@PostMapping("/purchaseOrder/payAnOrder")
|
||||
public Result<String> payAnOrder(@RequestBody PurchaseOrderPayReq purchaseOrderPayReq);
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.bwie.es.feign;
|
||||
|
||||
import com.bwie.common.domain.VolumeCodeType;
|
||||
import com.bwie.common.domain.request.VolumeCodeAddReq;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.feign
|
||||
* @Project:maven-month
|
||||
* @name:EsVolumeCodeFeign
|
||||
* @Date:2024/8/12 下午1:14
|
||||
*/
|
||||
@FeignClient("bwie-volumecode")
|
||||
public interface EsVolumeCodeFeign {
|
||||
/**
|
||||
* 卷码信息列表
|
||||
* @return 卷码信息
|
||||
*/
|
||||
@PostMapping("/volumeCode/list")
|
||||
public Result<List<VolumeCodeListRes>> all();
|
||||
|
||||
/**
|
||||
* 查询卷码种类
|
||||
* @return 种类信息
|
||||
*/
|
||||
@PostMapping("/volumeCode/findByType")
|
||||
public Result<List<VolumeCodeType>> findByType();
|
||||
|
||||
/**
|
||||
* 添加卷码
|
||||
* @param volumeCodeAddReq 添加信息
|
||||
* @return 添加结果
|
||||
*/
|
||||
@PostMapping("/volumeCode/add")
|
||||
public Result<String> add(@RequestBody VolumeCodeAddReq volumeCodeAddReq);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.bwie.es.feign.impl;
|
||||
|
||||
import com.bwie.common.domain.request.PurchaseOrderAddReq;
|
||||
import com.bwie.common.domain.request.PurchaseOrderPayReq;
|
||||
import com.bwie.common.domain.response.PurchaseOrderListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.es.feign.EsPurchaseOrderFeign;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.feign.impl
|
||||
* @Project:maven-month
|
||||
* @name:EsPurchaseOrderFeignImpl
|
||||
* @Date:2024/8/12 下午7:19
|
||||
*/
|
||||
@Component
|
||||
public class EsPurchaseOrderFeignImpl implements FallbackFactory<EsPurchaseOrderFeign> {
|
||||
@Override
|
||||
public EsPurchaseOrderFeign create(Throwable cause) {
|
||||
return new EsPurchaseOrderFeign() {
|
||||
@Override
|
||||
public Result<String> addPurchaseOrder(PurchaseOrderAddReq purchaseOrderAddReq) {
|
||||
return Result.error("网络迷瞪中...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<PurchaseOrderListRes>> selectPurchaseOrderList() {
|
||||
return Result.error("网络跑路了...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> payAnOrder(PurchaseOrderPayReq purchaseOrderPayReq) {
|
||||
return Result.error("网络要死了...");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.bwie.es.feign.impl;
|
||||
|
||||
import com.bwie.common.domain.VolumeCodeType;
|
||||
import com.bwie.common.domain.request.VolumeCodeAddReq;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.es.feign.EsVolumeCodeFeign;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.feign.impl
|
||||
* @Project:maven-month
|
||||
* @name:EsVolumeCodeFeignImpl
|
||||
* @Date:2024/8/12 下午1:16
|
||||
*/
|
||||
@Component
|
||||
public class EsVolumeCodeFeignImpl implements FallbackFactory<EsVolumeCodeFeign> {
|
||||
@Override
|
||||
public EsVolumeCodeFeign create(Throwable cause) {
|
||||
return new EsVolumeCodeFeign() {
|
||||
@Override
|
||||
public Result<List<VolumeCodeListRes>> all() {
|
||||
return Result.error("网络出去玩了...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<VolumeCodeType>> findByType() {
|
||||
return Result.error("网络生气不干了...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> add(VolumeCodeAddReq volumeCodeAddReq) {
|
||||
return Result.error("网络傻掉了...");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.bwie.es.service;
|
||||
|
||||
import com.bwie.common.domain.VolumeCodeType;
|
||||
import com.bwie.common.domain.request.PurchaseOrderAddReq;
|
||||
import com.bwie.common.domain.request.PurchaseOrderPayReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeAddReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeSelectReq;
|
||||
import com.bwie.common.domain.response.PurchaseOrderListRes;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.service
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeService
|
||||
* @Date:2024/8/12 下午1:19
|
||||
*/
|
||||
public interface EsVolumeCodeService {
|
||||
void syncAdd(List<VolumeCodeListRes> volumeCodeListResList);
|
||||
|
||||
Result<List<VolumeCodeListRes>> list(VolumeCodeSelectReq volumeCodeSelectReq);
|
||||
|
||||
Result<List<VolumeCodeType>> findByType();
|
||||
|
||||
Result<String> addvc(VolumeCodeAddReq volumeCodeAddReq);
|
||||
|
||||
Result<String> addVolumeCode(VolumeCodeAddReq volumeCodeAddReq);
|
||||
|
||||
Result<List<VolumeCodeListRes>> RequestBody(VolumeCodeSelectReq volumeCodeSelectReq);
|
||||
|
||||
Result<String> toBuyOrder(PurchaseOrderAddReq purchaseOrderAddReq);
|
||||
|
||||
Result<List<PurchaseOrderListRes>> selectPurchaseOrderList();
|
||||
|
||||
Result<String> payAnOrder(PurchaseOrderPayReq purchaseOrderPayReq);
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
package com.bwie.es.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bwie.common.domain.VolumeCodeType;
|
||||
import com.bwie.common.domain.request.PurchaseOrderAddReq;
|
||||
import com.bwie.common.domain.request.PurchaseOrderPayReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeAddReq;
|
||||
import com.bwie.common.domain.request.VolumeCodeSelectReq;
|
||||
import com.bwie.common.domain.response.PurchaseOrderListRes;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.common.utils.StringUtils;
|
||||
import com.bwie.es.feign.EsPurchaseOrderFeign;
|
||||
import com.bwie.es.feign.EsVolumeCodeFeign;
|
||||
import com.bwie.es.service.EsVolumeCodeService;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHits;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.service.impl
|
||||
* @Project:maven-month
|
||||
* @name:VolumeCodeServiceImpl
|
||||
* @Date:2024/8/12 下午1:19
|
||||
*/
|
||||
@Service
|
||||
public class EsVolumeCodeServiceImpl implements EsVolumeCodeService {
|
||||
|
||||
@Autowired private EsVolumeCodeFeign esVolumeCodeFeign;
|
||||
@Autowired private EsPurchaseOrderFeign esPurchaseOrderFeign;
|
||||
@Autowired private RestHighLevelClient restHighLevelClient;
|
||||
|
||||
private static final String INDEX_NAME = "volumecode";
|
||||
|
||||
@Override
|
||||
public void syncAdd(List<VolumeCodeListRes> volumeCodeListResList) {
|
||||
try {
|
||||
BulkRequest bulkRequest = new BulkRequest(INDEX_NAME);
|
||||
volumeCodeListResList.forEach(volumeCodeListRes -> {
|
||||
bulkRequest.add(
|
||||
new IndexRequest(INDEX_NAME)
|
||||
.id(volumeCodeListRes.getVolumeCodeId()+"")
|
||||
.source(JSONObject.toJSONString(volumeCodeListRes),XContentType.JSON));
|
||||
});
|
||||
restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<VolumeCodeListRes>> list(VolumeCodeSelectReq volumeCodeSelectReq) {
|
||||
ArrayList<VolumeCodeListRes> list = new ArrayList<>();
|
||||
try {
|
||||
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
if (StringUtils.isNotBlank(volumeCodeSelectReq.getVolumeCodeName())){
|
||||
boolQueryBuilder.must(QueryBuilders.matchQuery("volumeCodeName",volumeCodeSelectReq.getVolumeCodeName()));
|
||||
}
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchSourceBuilder.highlighter(new HighlightBuilder()
|
||||
.field("volumeCodeName")
|
||||
.preTags("<span style=\"color:red\">")
|
||||
.postTags("</span>")
|
||||
);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
|
||||
SearchHits hits = searchResponse.getHits();
|
||||
SearchHit[] searchHits = hits.getHits();
|
||||
for (SearchHit searchHit : searchHits) {
|
||||
String sourceAsString = searchHit.getSourceAsString();
|
||||
VolumeCodeListRes volumeCodeListRes = JSONObject.parseObject(sourceAsString, VolumeCodeListRes.class);
|
||||
volumeCodeListRes.setVolumeCodeId(Integer.valueOf(searchHit.getId()));
|
||||
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
|
||||
if (highlightFields != null) {
|
||||
HighlightField highlightField = highlightFields.get("volumeCodeName");
|
||||
if (highlightField != null){
|
||||
Text[] fragments = highlightField.getFragments();
|
||||
String str = "";
|
||||
for (Text fragment : fragments) {
|
||||
str += fragment;
|
||||
}
|
||||
volumeCodeListRes.setVolumeCodeName(str);
|
||||
}
|
||||
}
|
||||
list.add(volumeCodeListRes);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<VolumeCodeType>> findByType() {
|
||||
return esVolumeCodeFeign.findByType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> addvc(VolumeCodeAddReq volumeCodeAddReq) {
|
||||
esVolumeCodeFeign.add(volumeCodeAddReq);
|
||||
return Result.success("操作成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> addVolumeCode(VolumeCodeAddReq volumeCodeAddReq) {
|
||||
try {
|
||||
IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
|
||||
indexRequest.id(volumeCodeAddReq.getVolumeCodeId()+"");
|
||||
indexRequest.source(JSONObject.toJSONString(volumeCodeAddReq),XContentType.JSON);
|
||||
restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.success("操作成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<VolumeCodeListRes>> RequestBody(VolumeCodeSelectReq volumeCodeSelectReq) {
|
||||
ArrayList<VolumeCodeListRes> list = new ArrayList<>();
|
||||
try {
|
||||
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
if (StringUtils.isNotBlank(volumeCodeSelectReq.getVolumeCodeName())){
|
||||
boolQueryBuilder.must(QueryBuilders.matchQuery("volumeCodeName",volumeCodeSelectReq.getVolumeCodeName()));
|
||||
}
|
||||
if (volumeCodeSelectReq.getVolumeCodeTypeId()!=null){
|
||||
boolQueryBuilder.must(QueryBuilders.matchQuery("volumeCodeTypeId",volumeCodeSelectReq.getVolumeCodeTypeId()));
|
||||
}
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchSourceBuilder.highlighter(new HighlightBuilder()
|
||||
.field("volumeCodeName")
|
||||
.preTags("<span style=\"color:red\">")
|
||||
.postTags("</span>")
|
||||
);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
|
||||
SearchHits hits = searchResponse.getHits();
|
||||
SearchHit[] searchHits = hits.getHits();
|
||||
for (SearchHit searchHit : searchHits) {
|
||||
String sourceAsString = searchHit.getSourceAsString();
|
||||
VolumeCodeListRes volumeCodeListRes = JSONObject.parseObject(sourceAsString, VolumeCodeListRes.class);
|
||||
volumeCodeListRes.setVolumeCodeId(Integer.valueOf(searchHit.getId()));
|
||||
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
|
||||
if (highlightFields != null) {
|
||||
HighlightField highlightField = highlightFields.get("volumeCodeName");
|
||||
if (highlightField != null){
|
||||
Text[] fragments = highlightField.getFragments();
|
||||
String str = "";
|
||||
for (Text fragment : fragments) {
|
||||
str += fragment;
|
||||
}
|
||||
volumeCodeListRes.setVolumeCodeName(str);
|
||||
}
|
||||
}
|
||||
list.add(volumeCodeListRes);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> toBuyOrder(PurchaseOrderAddReq purchaseOrderAddReq) {
|
||||
esPurchaseOrderFeign.addPurchaseOrder(purchaseOrderAddReq);
|
||||
return Result.success("","操作成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<PurchaseOrderListRes>> selectPurchaseOrderList() {
|
||||
Result<List<PurchaseOrderListRes>> result = esPurchaseOrderFeign.selectPurchaseOrderList();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> payAnOrder(PurchaseOrderPayReq purchaseOrderPayReq) {
|
||||
Result<String> result = esPurchaseOrderFeign.payAnOrder(purchaseOrderPayReq);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.bwie.es.sync;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bwie.common.domain.response.VolumeCodeListRes;
|
||||
import com.bwie.common.result.Result;
|
||||
import com.bwie.es.feign.EsVolumeCodeFeign;
|
||||
import com.bwie.es.service.EsVolumeCodeService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:蓬叁
|
||||
* @Package:com.bwie.es.sync
|
||||
* @Project:maven-month
|
||||
* @name:EsSyncVolumeCode
|
||||
* @Date:2024/8/12 下午1:17
|
||||
*/
|
||||
@Log4j2
|
||||
@Component
|
||||
public class EsSyncVolumeCode implements ApplicationRunner {
|
||||
|
||||
@Autowired private EsVolumeCodeFeign esVolumeCodeFeign;
|
||||
@Autowired private EsVolumeCodeService esVolumeCodeService;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("--------Es模块启动--------");
|
||||
log.info("启动任务:mysql同步Es正在执行,正在查询数据库......");
|
||||
Result<List<VolumeCodeListRes>> all = esVolumeCodeFeign.all();
|
||||
List<VolumeCodeListRes> volumeCodeListResList = all.getData();
|
||||
log.info("启动任务:mysql同步Es正在执行,查询数据:[{}]", JSON.toJSONString(volumeCodeListResList));
|
||||
try {
|
||||
esVolumeCodeService.syncAdd(volumeCodeListResList);
|
||||
log.info("启动任务:mysql同步Es正在执行,同步成功");
|
||||
} catch (Exception exception){
|
||||
exception.printStackTrace();
|
||||
log.info("启动任务:mysql同步Es正在执行,同步失败");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//package com.bwie.es.sync;
|
||||
//
|
||||
//import com.alibaba.fastjson.JSON;
|
||||
//import com.bwie.common.domain.Shop;
|
||||
//import com.bwie.common.result.Result;
|
||||
//import com.bwie.es.feign.EsFeignService;
|
||||
//import com.bwie.es.service.EsShopService;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.scheduling.annotation.Scheduled;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import java.util.List;
|
||||
//
|
||||
///**
|
||||
// * @Project boot-month
|
||||
// * @Author 王方俞
|
||||
// * @Date 2023/9/6 10:55
|
||||
// * @Description
|
||||
// */
|
||||
//@Component
|
||||
//@Log4j2
|
||||
//public class SyncBlog2Es {
|
||||
//
|
||||
// @Autowired
|
||||
// private EsFeignService esFeignService;
|
||||
// @Autowired
|
||||
// private EsShopService esShopService;
|
||||
//
|
||||
// @Scheduled(cron = "0 0/5 * * * ?")
|
||||
// public void SyncBlog2EsPerMinute(){
|
||||
// log.info("定时器---->博客从mysql全量同步到es的定时器正在执行,开始查询数据库...");
|
||||
// Result<List<Shop>> result = esFeignService.shopList();
|
||||
// List<Shop> list = result.getData();
|
||||
// log.info("定时器---->博客从mysql全量同步到es的定时器正在执行,mysql查询到的博客数据为:{},开始同步...",
|
||||
// JSON.toJSONString(list));
|
||||
// try {
|
||||
// esShopService.insertBatch(list);
|
||||
// log.info("定时器---->博客从mysql全量同步到es的定时器正在执行,同步成功...");
|
||||
// } catch (Exception exception) {
|
||||
// exception.printStackTrace();
|
||||
// log.error("定时器---->博客从mysql全量同步到es的定时器正在执行,同步失败!"+exception.getMessage());
|
||||
// }
|
||||
// }
|
||||
//}
|
|
@ -0,0 +1,33 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9005
|
||||
# Spring
|
||||
spring:
|
||||
main:
|
||||
allow-circular-references: true
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
time-zone: GMT+8
|
||||
application:
|
||||
# 应用名称
|
||||
name: bwie-es
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 111.229.195.89:8848
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 111.229.195.89:8848
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
es:
|
||||
host: 111.229.195.89
|
||||
port: 9200
|
||||
scheme: http
|
|
@ -0,0 +1,38 @@
|
|||
package com.yuan;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
extends TestCase
|
||||
{
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public AppTest( String testName )
|
||||
{
|
||||
super( testName );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
return new TestSuite( AppTest.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rigourous Test :-)
|
||||
*/
|
||||
public void testApp()
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>maven-month</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>yuan-gateway</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>yuan-gateway</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- 公共模块 -->
|
||||
<dependency>
|
||||
<groupId>com.yuan</groupId>
|
||||
<artifactId>yuan-common</artifactId>
|
||||
</dependency>
|
||||
<!-- 网关依赖 -->
|
||||
<!-- SpringCloud Gateway -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringCloud Alibaba Sentinel Gateway -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
|
||||
</dependency>
|
||||
<!-- 引入阿里巴巴sentinel限流 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|