Initial commit

This commit is contained in:
nuxt_Team 2023-06-28 19:02:53 +08:00
commit 13e74eef49
99 changed files with 16907 additions and 0 deletions

6
.env Normal file
View File

@ -0,0 +1,6 @@
# 后台接口地址(仅开发/预览环境生效)
NUXT_PROXY_API=http://localhost/AERWEN/houde_web/houde_web_api/public/admin.php/
# 后台图片地址(仅开发/预览环境生效)
NUXT_PROXY_UPLOADS=http://localhost/AERWEN/houde_web/houde_web_api/public/uploads/
# 后台富文本上传地址(仅开发/预览环境生效)
NUXT_PROXY_WEB_API=http://localhost:3003/api-v

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
node_modules
*.log*
.nuxt
.nitro
.cache
.output
dist

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 数据源本地存储已忽略文件
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

9
.idea/houde_web_nuxt.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,24 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
<list size="10">
<item index="0" class="java.lang.String" itemvalue="nobr" />
<item index="1" class="java.lang.String" itemvalue="noembed" />
<item index="2" class="java.lang.String" itemvalue="comment" />
<item index="3" class="java.lang.String" itemvalue="noscript" />
<item index="4" class="java.lang.String" itemvalue="embed" />
<item index="5" class="java.lang.String" itemvalue="script" />
<item index="6" class="java.lang.String" itemvalue="carousel" />
<item index="7" class="java.lang.String" itemvalue="tab" />
<item index="8" class="java.lang.String" itemvalue="final" />
<item index="9" class="java.lang.String" itemvalue="components" />
</list>
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
</profile>
</component>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/houde_web_nuxt.iml" filepath="$PROJECT_DIR$/.idea/houde_web_nuxt.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"nuxt.isNuxtApp": false
}

42
README.md Normal file
View File

@ -0,0 +1,42 @@
# Nuxt 3 Minimal Starter
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install the dependencies:
```bash
# yarn
yarn install
# npm
npm install
# pnpm
pnpm install
```
## Development Server
Start the development server on http://localhost:3003
```bash
npm run dev
```
## Production
Build the application for production:
```bash
npm run build
```
Locally preview production build:
```bash
npm run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

View File

@ -0,0 +1,54 @@
.b{
background: black;
}
.Carousel-container{
.carousel-box{
.carousel-items{
color: var(--swipercolor);
height: var(--swiperheight);
width: var(--swiperwidth);
margin: var(--swipermargin);
padding: var(--swiperpadding);
background: var(--swiperbackground);
& > img{
height: 100%;
width: 100%;
object-fit: cover;
}
}
}
}
.swiper::v-deep(.swiper-pagination .swiper-pagination-bullet ){
color: var(--paginationcolor);
height: var(--paginationheight);
width: var(--paginationwidth);
margin: var(--paginationmargin);
padding: var(--paginationpadding);
background: var(--paginationbackground);
}
.swiper::v-deep(.swiper-pagination .swiper-pagination-bullet-active ){
color: var(--paginationActivecolor);
height: var(--paginationActiveheight);
width: var(--paginationActivewidth);
margin: var(--paginationActivemargin);
padding: var(--paginationActivepadding);
background: var(--paginationActivebackground);
}
.swiper::v-deep(.swiper-button-next){
color: var(--buttonNextcolor);
height: var(--buttonNextheight);
width: var(--buttonNextwidth);
margin: var(--buttonNextmargin);
padding: var(--buttonNextpadding);
background: var(--buttonNextbackground);
}
.swiper::v-deep(.swiper-button-prev){
color: var(--buttonPrevcolor);
height: var(--buttonPrevheight);
width: var(--buttonPrevwidth);
margin: var(--buttonPrevmargin);
padding: var(--buttonPrevpadding);
background: var(--buttonPrevbackground);
}

View File

@ -0,0 +1,34 @@
//media.scss
/*480px*/
/*小于*/
@media screen and (max-width: 480px) {
.Carousel-container{
height: 40vw!important;
}
.carousel-items{
height: 40vw!important;
}
}
/*880px*/
/*小于*/
@media screen and (max-width: 880px) {
}
/*1200px*/
/*小于*/
@media screen and (max-width: 1200px) {
}
/*大于*/
@media screen and (min-width: 1200px) {
}
/*1440px*/
/*小于*/
@media screen and (max-width: 1440px) {
}

217
assets/css/Final/index.scss Normal file
View File

@ -0,0 +1,217 @@
//Final.scss
.Final {
a {
text-decoration: none;
}
position: relative;
// margin-top: 100px;
.Final-float-box {
position: relative;
z-index: 99;
width: 100%;
margin: 0 auto;
display: flex;
justify-content: center;
.Final-float {
position: absolute;
height: 13vw;
z-index: 99;
width: 60%;
margin: 0 auto;
top: -50px;
max-height: 80px;
display: flex;
justify-content: space-evenly;
align-items: center;
border-radius: 10px;
padding: 10px 0;
img {
width: 45px;
z-index: 1;
margin-bottom: 5px;
}
.float-items {
text-align: center;
color: white;
cursor: pointer;
}
}
}
.Final-container {
background: #ededed;
position: relative;
color: black;
.Final-big-box {
width: 100%;
display: flex;
justify-content: space-evenly;
flex-direction: column;
margin: 0 auto;
.Final-icon-box {
height: 60px;
width: 120px;
.icon-img {
height: 100%;
width: 100%;
object-fit: contain;
}
}
.Final-middle-box {
display: flex;
justify-content: center;
align-items: flex-start;
.Final-middle-items {
margin: 0 30px;
text-align: center;
.title-head {
font-size: 20px !important;
}
.items {
margin-bottom: 10px;
color: black;
font-size: 15px;
cursor: pointer;
}
.items-title {
font-size: 22px;
margin-bottom: 20px;
color: black;
font-weight: 600;
}
}
}
.Final-code-box {
display: none;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100%;
width: 100%;
margin-top: 50px;
overflow: hidden;
.code-text {
font-size: 20px;
margin-bottom: 10px;
font-weight: bold;
}
img {
width: 50%;
height: 50%;
}
}
}
}
.Final-bottom-box {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 30px 0;
color: black;
font-size: 15px;
font-weight: bold;
background-color: #ededed;
}
}
.phone-text {
font-size: 20px !important;
}
.Final-middle-phone-title-box {
width: 100%;
display: flex;
justify-content: center;
flex-direction: column;
text-align: center;
.Final-middle-phone-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
}
}
.Final-middle-phone-content{
font-size: 20px;
font-family: "CenturyGothic", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", Helvetica, Arial, sans-serif;
}
.Final-middle-phone-box {
// display: none;
justify-content: space-evenly;
align-items: flex-start;
margin-top: 50px;
.Final-middle-items {
margin: 0 30px;
.items {
margin-bottom: 10px;
color: #e9e9e9;
font-size: 15px;
}
.items-title {
font-size: 16px;
margin-bottom: 20px;
color: black;
font-weight: 600;
}
}
}
//share-hide-main
.share-hide-main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: rgba(0, 10, 10, 0.5);
z-index: 99999999;
height: 100vh;
width: 100vw;
position: fixed;
left: 0;
top: 0;
.share-box {
background: white;
border-radius: 10px;
padding: 5px;
height: fit-content;
width: fit-content;
max-width: 430px !important;
max-height: 430px !important;
img {
height: 100%;
width: 100%;
}
}
}

View File

@ -0,0 +1,70 @@
//media.scss
/*480px*/
/*小于*/
@media screen and (max-width: 480px) {
.Final-middle-phone-box{
display: flex!important;
flex-direction: column;
}
.Final-middle-box{
display: none!important;
}
}
/*880px*/
/*小于*/
@media screen and (max-width: 880px) {
.Final-icon-box{
display: none;
}
.Final-container{
flex-direction: column;
}
.Final-middle-box{
flex-direction: column;
}
.Final-middle-items{
display: flex;
.items-title{
margin-right: 28px!important;
font-size: 14px!important;
}
.items{
margin-right: 14px!important;
font-size: 12px!important;
}
.title-head{
font-size: 20px!important;
}
}
.Final-float{
height: 18vw!important;
}
.Final-float-box{
display: none!important;
}
.Final-code-box{
display: flex!important;
}
}
/*1200px*/
/*小于*/
@media screen and (max-width: 1200px) {
.Final-icon-box{
display: none;
}
}
/*大于*/
@media screen and (min-width: 1200px) {
}
/*1440px*/
/*小于*/
@media screen and (max-width: 1440px) {
}

View File

@ -0,0 +1,31 @@
//HeaderIcon.scss
.HeaderIcon {
.HeaderIcon-container {
height: 100%;
width: 100%;
max-width: 180px;
margin-top: 0;
display: flex;
justify-content: center;
align-items: center;
padding-top: 1px;
.HeaderIcon-box {
height: 100%;
width: 100%;
position: relative;
img {
height: 100%;
width: 100%;
object-fit: contain;
// margin-top: 9px;
}
}
}
}
// 手机端
.phone_top_logo{
display: none ;
}

View File

@ -0,0 +1,92 @@
[v-cloak] {
display: none !important;
}
.search-show{
height: 70px!important;
}
.search-input-show{
height: 38px!important;
border:1px solid #ccc!important;
}
.dNone{
display: none!important;
}
.search-have{
border-bottom: 0!important;
border-radius: 20px 20px 0 0 !important;
}
//Header.scss
.Header{
position: relative;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: fixed;
z-index: 99999;
background: rgba($color: #000000, $alpha: .2);
.Header-container{
display: flex;
justify-content: space-evenly;
align-items: center;
height:85px;
font-size: 14px;
}
.search-box{
height: 0;
width: 100%;
transition: 0.4s;
z-index: 9999;
// position: fixed;
top: 60px;
left: 0;
text-align: center;
.search-hide-box{
width: 70%;
background: rgb(250, 250, 250)!important;
margin: 0 auto;
display: block;
overflow: auto;
border-radius: 0 0 20px 20px ;
text-align: left;
max-height: 500px;
.search-hide-items{
padding: 15px 21px;
cursor: pointer;
transition: 0.4s;
color: #757575;
font-weight: 550;
&:hover{
background: rgb(230, 230, 230);
}
}
}
.search-box-input{
background:none;
outline:none;
border-radius: 20px;
width: 40%;
padding: 0 20px;
height: 0;
transition: 0.4s;
margin-top: 20px;
color: #757575;
font-weight: 550;
border: none;
background: rgb(250, 250, 250)!important;
&:focus{
width: 70%;
}
}
}
}
.phone-box{
display: none;
height: 50px;
}

View File

@ -0,0 +1,84 @@
//media.scss
/*480px*/
/*小于*/
@media screen and (max-width: 480px) {
.Header {
position: fixed !important;
z-index: 99;
}
.phone-box {
display: block !important;
}
}
/*1037px*/
@media screen and (min-width:1037px) {
.HeaderSearch {
display: none !important;
}
}
/*小于*/
@media screen and (max-width: 1037px) {
.Header-container {
height: 50px !important;
}
.HeaderSearch-Icon {
display: none !important;
}
.HeaderSearch {
display: flex !important;
}
.HeaderNav {
display: none !important;
}
.HeaderIcon-box {
width: 100% !important;
height: 100% !important;
}
.phone_top_logo {
display: block !important;
margin-bottom: 5px;
}
.Header-container {
display: flex;
justify-content: left !important;
padding-left: 40px;
}
}
/*1333px*/
/*小于*/
@media screen and (max-width: 1333px) {
.Header-container {
width: 100%;
}
.HeaderNav {
padding-left: 5vw !important;
}
.Header-container {
font-size: 12px !important;
}
.HeaderNav-navItems {
padding: 0 20px !important;
}
}
/*大于*/
@media screen and (min-width: 1333px) {}
/*1440px*/
/*小于*/
@media screen and (max-width: 1440px) {}

View File

@ -0,0 +1,84 @@
a {
color: black;
text-decoration: none;
}
[v-cloak] {
display: none !important;
}
//HeaderNav.scss
.HeaderNav {
//margin-right: 10%;
.HeaderNav-container {
display: flex;
justify-content: space-between;
align-items: center;
.nav-active {
display: flex;
align-items: center;
&::before {
content: '';
width: 0;
height: 0;
position: absolute;
bottom: -30px;
text-align: center;
margin: 15px 0 auto;
transition: 0.3s;
border-width: 0 10px 10px;
border-style: solid;
border-color: transparent transparent white!important;
}
span {
color: white !important;
}
// padding: 60px 30px !important;
}
.HeaderNav-navItems {
padding: 0 25px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: 600;
// color: rgb(198, 198, 198);
color: white;
position: relative;
transition: 0.4s;
&::before {
content: '';
width: 0;
height: 0;
position: absolute;
bottom: -30px;
text-align: center;
margin: 15px 0 auto;
transition: 0.3s;
border-width: 0 10px 10px;
border-style: solid;
border-color: transparent transparent transparent;
}
&:hover {
&::before{
border-color: transparent transparent white!important;
}
span {
color: white !important;
}
}
}
}
}

View File

@ -0,0 +1,80 @@
.dNone{
display: none!important;
}
a {
text-decoration: none; /* 去除默认的下划线 */
outline: none; /* 去除旧版浏览器的点击后的外虚线框 */
}
.app-nav{
height: 100vh;
width: 100vw;
position: fixed;
z-index: 99999999999;
background: rgba(0, 0, 0, 0.8);
// backdrop-filter: blur(2px);
left: 0;
top:70px;
padding-top: 1px;
color: white;
user-select: none;
.app-box{
height: 80vh;
overflow-y: auto;
overflow-x: hidden;
.app-nav-items{
padding: 30px;
border-bottom: 1px solid white;
cursor: pointer;
transition: 0.4s;
display: block!important;
color: white!important;
a{
color: white!important;
}
.app-nav-second-items{
padding: 10px 0 10px 20px;
cursor: pointer;
margin-top: 30px;
}
}
}
}
//HeaderSearch.scss
.HeaderSearch{
// margin-right: 14%;
.HeaderSearch-container{
.HeaderSearch-box{
display: flex;
justify-content: center;
align-items: center;
.HeaderSearch-Icon{
cursor: pointer;
}
.HeaderSearch-button{
margin-left: 20px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
cursor: pointer;
div{
height: 3px;
width: 30px;
margin: 4px 0;
background: #ffffff;
}
}
}
.HeaderSearch-search-box{
height: 20px;
width: 50px;
background: black;
}
}
}

View File

@ -0,0 +1,65 @@
.ImgDetail-main {
.ImgDetail-container {
height: 100vh;
width: 100%;
background: rgba(0, 10, 10, 0.5);
z-index: 9999999;
overflow: hidden;
position: fixed;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
left: 0;
top: 0;
.ImgDetail-box {
display: flex;
justify-content: center;
align-items: center;
.left-box {
border-radius: 50%;
height: 60px;
width: 60px;
background: rgba(0, 10, 10, 0.2);
position: absolute;
left: 1vw;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.right-box {
height: 60px;
width: 60px;
border-radius: 50%;
background: rgba(0, 10, 10, 0.2);
position: absolute;
right: 1vw;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.img-box{
height: 80vh;
width: 80vw;
img{
height: 100%;
width: 100%;
object-fit: contain;
}
}
.close-btn{
color: white;
font-size: 28px;
position: absolute;
right: 2vw;
top: 2vw;
cursor: pointer;
}
}
}
}

View File

@ -0,0 +1,61 @@
//media.scss
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
}
/*小于*/
@media screen and (min-width: 1440px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
}
/*小于*/
@media screen and (max-width: 1200px) {
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
}
/*小于*/
@media screen and (max-width: 880px) {
.img-box{
width: 60vw!important;
}
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
}
/*小于*/
@media screen and (max-width: 480px) {
.right-box{
height: 40px!important;
width: 40px!important;
img{
height: 30px!important;
width: 30px!important;
}
}
.left-box{
height: 40px!important;
width: 40px!important;
img{
height: 30px!important;
width: 30px!important;
}
}
}

View File

@ -0,0 +1,29 @@
.Load-main {
opacity: 1;
transition: 0.4s;
.Load-container {
.Load-box {
height: 100vh;
width: 100vw;
background: rgba(255, 255, 255, 1);
fill-opacity: 1;
transition: 0.4s;
position: fixed;
left: 0;
top: 0;
z-index: 9999999999;
display: flex;
justify-content: center;
align-items: center;
background-color: #0a0a0a !important;
span {
font-size: 50px;
letter-spacing: 10px;
color: var(--rootColor);
transition: 0.4s;
}
}
}
}

View File

@ -0,0 +1,46 @@
//media.scss
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
}
/*小于*/
@media screen and (min-width: 1440px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
}
/*小于*/
@media screen and (max-width: 1200px) {
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
}
/*小于*/
@media screen and (max-width: 880px) {
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
}
/*小于*/
@media screen and (max-width: 480px) {
.Load-box{
top: -50px !important;
}
}

76
assets/css/Tab/index.scss Normal file
View File

@ -0,0 +1,76 @@
a{
color: black;
text-decoration: none;
}
.Tab-main{
.Tab-container{
border-radius: 10px;
.Tab-box{
background: #f5f2f0;
box-shadow: 0 5px 25px 3px rgb(0 0 0 / 10%);
padding: 20px 15%;
border-radius: 10px;
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto;
flex-wrap: wrap;
width: 60vw;
.Tab-items{
margin: 15px 0;
cursor: pointer;
text-align: center;
font-size: 18px;
transition: 0.4s;
min-width: 72px;
position: relative;
._Tab-item{
transition: .4s;
&:hover {
color: #a30000;
}
&.active {
color: #a30000;
}
}
.Tab-child-box{
position: absolute;
right: calc(40% - 79px/2);
top: 35px;
z-index: 99;
background: white;
border-radius: 5px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.Tab-child-items{
padding: 3px 8px;
font-size: 14px;
color: #686868;
width: 79px;
}
&:after{
content: '';
width: 0;
height: 0;
position: absolute;
top: -25px;
left: 20px;
text-align: center;
margin: 15px 0 auto;
transition: 0.3s;
border-width: 0 10px 10px;
border-style: solid;
border-color: transparent transparent #ffffff !important;
}
}
}
}
}
}

47
assets/css/Tab/media.scss Normal file
View File

@ -0,0 +1,47 @@
//media.scss
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
}
/*小于*/
@media screen and (min-width: 1440px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
}
/*小于*/
@media screen and (max-width: 1200px) {
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
}
/*小于*/
@media screen and (max-width: 880px) {
.Tab-items{
width: 50%!important;
}
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
}
/*小于*/
@media screen and (max-width: 480px) {
.Tab-box{
box-shadow: 0 0 25px 2px rgb(0 0 0 / 10%)!important;
}
.Tab-items{
width: 100%!important;
}
}

216
assets/css/index/index.scss Normal file
View File

@ -0,0 +1,216 @@
.home-download-button {
background-color: #228df2;
border: none;
color: #fff;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
padding: 10px 24px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
}
// 首页最外部盒子
.home-main-box {
padding-top: 10vw;
overflow: hidden;
// 首页内容盒子
.home-box {
width: 100%;
// background-color: var(--rootColor);
// 顶部内容
.top-content {
// 首页顶部标题盒子
.home-top-title-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
color: white;
h1 {
display: block;
font-size: 2em;
margin-block-start: 0.67em;
margin-block-end: 0.67em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
}
.home-top-title {
font-size: 62px;
letter-spacing: 5px;
}
.home-sub-title {
font-size: 25px;
font-weight: 400;
color: #aaa;
text-align: center;
letter-spacing: 3px;
}
}
// 下载按钮盒子
.home-download-box {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin-top: 3vw;
.svg-content {
width: 20px;
height: 20px;
margin-right: 8px;
}
}
// 顶部展示图片
.top-show-box {
margin-top: 80px;
width: 100%;
height: 30vw;
overflow: hidden;
img {
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
// 中间内容
.middle-box {
h2 {
font-size: 38px;
color: white;
font-weight: bold;
letter-spacing: 10px;
}
h3 {
font-size: 18px;
margin-top: 16px;
margin-bottom: 32px;
font-weight: 400;
color: #aaa;
text-align: center;
line-height: 1.5;
max-width: 500px;
}
.middle-img-box {
position: relative;
margin-top: 0px;
width: 100%;
height: 35vw;
cursor: pointer;
overflow: hidden;
>img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
// 中间盒子
.middle-content-big-box {
margin-top: 10vw;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
// 标题
.middle-content-title-box {
.middle-content-title {}
.middle-content-sub-title {}
}
}
// 一键建表 Navicat 图标
.create-table-navicat-img-box {
width: 100px;
height: 100px;
overflow: hidden;
position: absolute;
right: 30%;
top: 5%;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
// 底部内容
.bottom-box {
margin-top: 8vw;
display: flex;
flex-direction: column;
flex-wrap: wrap;
// gitee源码盒子
.gitee-box {
width: 80%;
margin: 0 auto;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
height: 250px;
.gitee-img-box{
width: 298px;
height: 90px;
overflow: hidden;
img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
.gitee-content-title {
font-size: 32px;
font-weight: 700;
color: #fff;
margin-bottom: 10px;
}
}
}
}
}

View File

@ -0,0 +1,44 @@
//media.scss
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
}
/*小于*/
@media screen and (min-width: 1440px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
}
/*小于*/
@media screen and (max-width: 1200px) {
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
}
/*小于*/
@media screen and (max-width: 880px) {
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
}
/*小于*/
@media screen and (max-width: 480px) {
}

View File

@ -0,0 +1,35 @@
.Poster-main{
position: relative;
.Poster-container{
position: relative;
height: 30vw;
width: 100%;
.Poster-img{
height: 100%;
width: 100%;
position: absolute;
left: 0 ;
bottom: 0 ;
object-fit: cover;
object-position: 0 40%;
}
.Poster-content-box{
position: relative;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: white;
.Poster-title{
font-size: 36px;
font-weight: 900;
margin-bottom: 30px;
}
.Poster-text{
font-size: 20px;
}
}
}
}

View File

@ -0,0 +1,42 @@
//media.scss
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
}
/*小于*/
@media screen and (max-width: 1440px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
}
/*小于*/
@media screen and (max-width: 1440px) {
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
}
/*小于*/
@media screen and (max-width: 880px) {
.Poster-title{
font-size: 22px!important;
}
.Poster-text{
font-size: 12px!important;
}
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
}
/*小于*/
@media screen and (max-width: 480px) {
.Poster-text{
display: none !important;
}
}

View File

@ -0,0 +1,943 @@
//animation.scss
/*动画从右往左进入效果*/
.slide-in-blurred-right {
-webkit-animation: slide-in-blurred-right 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
animation: slide-in-blurred-right 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
}
@-webkit-keyframes slide-in-blurred-right {
0% {
-webkit-transform: translateX(1000px) scaleX(2.5) scaleY(0.2);
transform: translateX(1000px) scaleX(2.5) scaleY(0.2);
-webkit-transform-origin: 0% 50%;
transform-origin: 0% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
}
@keyframes slide-in-blurred-right {
0% {
-webkit-transform: translateX(1000px) scaleX(2.5) scaleY(0.2);
transform: translateX(1000px) scaleX(2.5) scaleY(0.2);
-webkit-transform-origin: 0% 50%;
transform-origin: 0% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
/*动画从左往右出去效果*/
}
.slide-out-blurred-right {
-webkit-animation: slide-out-blurred-right 0.45s cubic-bezier(0.755, 0.050, 0.855, 0.060) both;
animation: slide-out-blurred-right 0.45s cubic-bezier(0.755, 0.050, 0.855, 0.060) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-8 14:24:8
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-out-blurred-right
* ----------------------------------------
*/
@-webkit-keyframes slide-out-blurred-right {
0% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
100% {
-webkit-transform: translateX(1000px) scaleX(2) scaleY(0.2);
transform: translateX(1000px) scaleX(2) scaleY(0.2);
-webkit-transform-origin: 0% 50%;
transform-origin: 0% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
}
@keyframes slide-out-blurred-right {
0% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
100% {
-webkit-transform: translateX(1000px) scaleX(2) scaleY(0.2);
transform: translateX(1000px) scaleX(2) scaleY(0.2);
-webkit-transform-origin: 0% 50%;
transform-origin: 0% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
}
/*动画从上往下进入*/
.slide-in-blurred-top {
-webkit-animation: slide-in-blurred-top 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
animation: slide-in-blurred-top 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-8 15:15:40
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-blurred-top
* ----------------------------------------
*/
@-webkit-keyframes slide-in-blurred-top {
0% {
-webkit-transform: translateY(-1000px) scaleY(2.5) scaleX(0.2);
transform: translateY(-1000px) scaleY(2.5) scaleX(0.2);
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0) scaleY(1) scaleX(1);
transform: translateY(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
}
@keyframes slide-in-blurred-top {
0% {
-webkit-transform: translateY(-1000px) scaleY(2.5) scaleX(0.2);
transform: translateY(-1000px) scaleY(2.5) scaleX(0.2);
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0) scaleY(1) scaleX(1);
transform: translateY(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
}
/*动画从左往右进入效果*/
.slide-in-blurred-left {
-webkit-animation: slide-in-blurred-left 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
animation: slide-in-blurred-left 0.6s cubic-bezier(0.230, 1.000, 0.320, 1.000) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-14 9:41:31
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-blurred-left
* ----------------------------------------
*/
@-webkit-keyframes slide-in-blurred-left {
0% {
-webkit-transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
-webkit-transform-origin: 100% 50%;
transform-origin: 100% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
}
@keyframes slide-in-blurred-left {
0% {
-webkit-transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
-webkit-transform-origin: 100% 50%;
transform-origin: 100% 50%;
-webkit-filter: blur(40px);
filter: blur(40px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0) scaleY(1) scaleX(1);
transform: translateX(0) scaleY(1) scaleX(1);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-filter: blur(0);
filter: blur(0);
opacity: 1;
}
}
// 弹动
.bounce-in-fwd {
-webkit-animation: bounce-in-fwd 1.1s both;
animation: bounce-in-fwd 1.1s both;
}
@-webkit-keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
@keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
// 侧边切入
.tilt-in-fwd-tr {
-webkit-animation: tilt-in-fwd-tr 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: tilt-in-fwd-tr 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-25 11:53:18
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation bounce-in-fwd
* ----------------------------------------
*/
@-webkit-keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
@keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
.slide-in-elliptic-top-fwd {
-webkit-animation: slide-in-elliptic-top-fwd 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-elliptic-top-fwd 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@-webkit-keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
@keyframes bounce-in-fwd {
0% {
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: scale(0.7);
transform: scale(0.7);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: scale(0.84);
transform: scale(0.84);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
89% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: scale(0.95);
transform: scale(0.95);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
// 字体
.tracking-in-expand {
-webkit-animation: tracking-in-expand 0.7s cubic-bezier(0.215, 0.610, 0.355, 1.000) both;
animation: tracking-in-expand 0.7s cubic-bezier(0.215, 0.610, 0.355, 1.000) both;
}
@-webkit-keyframes tracking-in-expand {
0% {
letter-spacing: -0.5em;
opacity: 0;
}
40% {
opacity: 0.6;
}
100% {
opacity: 1;
}
}
@keyframes tracking-in-expand {
0% {
letter-spacing: -0.5em;
opacity: 0;
}
40% {
opacity: 0.6;
}
100% {
opacity: 1;
}
}
.slide-in-elliptic-top-fwd {
-webkit-animation: slide-in-elliptic-top-fwd 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-elliptic-top-fwd 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-27 8:52:52
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-elliptic-top-fwd
* ----------------------------------------
*/
@-webkit-keyframes slide-in-elliptic-top-fwd {
0% {
-webkit-transform: translateY(-600px) rotateX(-30deg) scale(0);
transform: translateY(-600px) rotateX(-30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 0;
}
100% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% 1400px;
transform-origin: 50% 1400px;
opacity: 1;
}
}
@keyframes slide-in-elliptic-top-fwd {
0% {
-webkit-transform: translateY(-600px) rotateX(-30deg) scale(0);
transform: translateY(-600px) rotateX(-30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 0;
}
100% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% 1400px;
transform-origin: 50% 1400px;
opacity: 1;
}
}
.slide-out-elliptic-top-bck {
-webkit-animation: slide-out-elliptic-top-bck 0.7s ease-in both;
animation: slide-out-elliptic-top-bck 0.7s ease-in both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-27 8:55:0
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-out-elliptic-top-bck
* ----------------------------------------
*/
@-webkit-keyframes slide-out-elliptic-top-bck {
0% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% 1400px;
transform-origin: 50% 1400px;
opacity: 1;
}
100% {
-webkit-transform: translateY(-600px) rotateX(-30deg) scale(0);
transform: translateY(-600px) rotateX(-30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 1;
}
}
@keyframes slide-out-elliptic-top-bck {
0% {
-webkit-transform: translateY(0) rotateX(0) scale(1);
transform: translateY(0) rotateX(0) scale(1);
-webkit-transform-origin: 50% 1400px;
transform-origin: 50% 1400px;
opacity: 1;
}
100% {
-webkit-transform: translateY(-600px) rotateX(-30deg) scale(0);
transform: translateY(-600px) rotateX(-30deg) scale(0);
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
opacity: 1;
}
}
/*动画从右到左进入慢速效果*/
.slide-in-right {
-webkit-animation: slide-in-right 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-right 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-25 9:47:38
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-right
* ----------------------------------------
*/
@-webkit-keyframes slide-in-right {
0% {
-webkit-transform: translateX(1000px);
transform: translateX(1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-right {
0% {
-webkit-transform: translateX(1000px);
transform: translateX(1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
/*动画从左到右进入慢速效果*/
.slide-in-left {
-webkit-animation: slide-in-left 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-left 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-25 9:48:33
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-left
* ----------------------------------------
*/
@-webkit-keyframes slide-in-left {
0% {
-webkit-transform: translateX(-1000px);
transform: translateX(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-left {
0% {
-webkit-transform: translateX(-1000px);
transform: translateX(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
/*动画从下往上进入慢速效果*/
.slide-in-bottom {
-webkit-animation: slide-in-bottom 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-bottom 1.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-25 9:49:11
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-bottom
* ----------------------------------------
*/
@-webkit-keyframes slide-in-bottom {
0% {
-webkit-transform: translateY(1000px);
transform: translateY(1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
@keyframes slide-in-bottom {
0% {
-webkit-transform: translateY(1000px);
transform: translateY(1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
/*动画从上往下进入慢速效果*/
.slide-in-top {
-webkit-animation: slide-in-top 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-top 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
/* ----------------------------------------------
* Generated by Animista on 2023-3-25 9:50:5
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-top
* ----------------------------------------
*/
@-webkit-keyframes slide-in-top {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
@keyframes slide-in-top {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}

View File

@ -0,0 +1,92 @@
//media.scss
.--box--{
width: 100%;
}
/*480px*/
/*大于*/
@media screen and (min-width: 480px) {
.--box--{
width: 95%;
margin: 0 auto;
}
}
/*小于*/
@media screen and (max-width: 480px) {
.--box--{
width: 100%;
}
}
/*880px*/
/*大于*/
@media screen and (min-width: 880px) {
.--box--{
width: 840px;
margin: 0 auto;
}
}
/*小于*/
@media screen and (max-width: 880px) {
}
/*1200px*/
/*大于*/
@media screen and (min-width: 1200px) {
.--box--{
width: 1140px;
margin: 0 auto;
}
}
/*小于*/
@media screen and (max-width: 1200px) {
}
/*1440px*/
/*大于*/
@media screen and (min-width: 1440px) {
.--box--{
width: 1380px;
margin: 0 auto;
}
}
/*小于*/
@media screen and (max-width: 1440px) {
}
// media.scss
// /*1440px*/
// /*大于*/
// @media screen and (min-width: 1440px) {
// }
// /*小于*/
// @media screen and (max-width: 1440px) {
// }
// /*1200px*/
// /*大于*/
// @media screen and (min-width: 1200px) {
// }
// /*小于*/
// @media screen and (max-width: 1440px) {
// }
// /*880px*/
// /*大于*/
// @media screen and (min-width: 880px) {
// }
// /*小于*/
// @media screen and (max-width: 880px) {
// }
// /*480px*/
// /*大于*/
// @media screen and (min-width: 480px) {
// }
// /*小于*/
// @media screen and (max-width: 480px) {
// }

67
assets/css/root/root.scss Normal file
View File

@ -0,0 +1,67 @@
$rootColor : #2196f3;
body{
background-color: #0a0a0a;
font-family: Inter;
}
:root{
--rootColor:#2196f3;
}
.dNone{
display: None!important;
}
.f1{
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.f2{
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.f3{
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.f4{
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
}
.f5{
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5;
}
.op0{
opacity: 0;
}
*{
font-family:;
font-weight: 550;
}
.rootBg{
background-color: $rootColor;
}
.rootFc{
color: $rootColor;
}
.list_none animate__animated animate__fadeIn{
width: 100%;
display: flex;
justify-content: center;
}

5
assets/css/test/test.css Normal file
View File

@ -0,0 +1,5 @@
.test_box{
width: 100px;
height: 100px;
background-color: red;
}

BIN
assets/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

121
components/Booth/index.vue Normal file
View File

@ -0,0 +1,121 @@
<template>
<div class="tb-booth"
@mouseover="onMouseOver"
@mouseout="onMouseOut"
@mousemove="onMouseMove"
ref="boothRef"
:style="option"
>
<img :src=modelValue />
<div class="mask" ref="mask" v-show="state.boxShow" />
<div class="big-img_box" ref="bigImgBox" v-show="state.boxShow">
<img class="big-img" ref="bigImg"
:src=modelValue />
</div>
</div>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Object,
default(v) {
return v;
}
},
option: {
type: Object,
default: null
}
});
const boothRef = ref(null);
const mask = ref(null);
const bigImg = ref(null);
const bigImgBox = ref(null);
const state = reactive({
boxShow: false
});
const onMouseOver = () => {
state.boxShow = true;
};
const onMouseOut = () => {
state.boxShow = false;
};
const onMouseMove = (e) => {
let x = e.pageX - boothRef.value.offsetLeft;
let y = e.pageY - boothRef.value.offsetTop;
let maskX = x - mask.value.offsetWidth / 2;
let maskY = y - mask.value.offsetHeight / 2;
// maskx
let maskXMaxMove = boothRef.value.offsetWidth - mask.value.offsetWidth;
let maskYMaxMove = boothRef.value.offsetHeight - mask.value.offsetHeight;
let bigImgXMaxMove =
bigImgBox.value.offsetWidth - bigImg.value.offsetWidth;
let bigImgYMaxMove =
bigImgBox.value.offsetHeight - bigImg.value.offsetHeight;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskXMaxMove) {
maskX = maskXMaxMove;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskYMaxMove) {
maskY = maskYMaxMove;
}
mask.value.style.left = maskX + "px";
mask.value.style.top = maskY + "px";
// = mask* / maskx
let bixImgXMove = (maskX * bigImgXMaxMove) / maskXMaxMove;
let bixImgYMove = (maskY * bigImgYMaxMove) / maskYMaxMove;
bigImg.value.style.left = bixImgXMove + "px";
bigImg.value.style.top = bixImgYMove + "px";
};
</script>
<style lang="scss" scoped>
.tb-booth {
width: 100%;
height: 100%;
position: relative;
border: 1px solid #cccccc;
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background-color: rgb(61, 110, 206);
opacity: 0.5;
cursor: move;
}
.big-img_box {
position: absolute;
top: 0;
left: 530px;
width: 500px;
height: 500px;
background-color: #fff;
border: 1px solid #cccccc;
overflow: hidden;
}
.big-img {
position: absolute;
left: 0;
top: 0;
z-index: 99;
}
</style>

View File

@ -0,0 +1,128 @@
<template>
<div class="Carousel-container" :style="styleContainer">
<!--
initialSlide默认选中第几张
modules引入模块
navigation左右的按钮
pagination分页器导航
autoplay自动播放
loop循环
swiperStyle自定义样式
-->
<swiper id="swiper" ref="swiperRef"
:initialSlide="0"
:modules="modules"
:navigation="{ clickable: true }"
:pagination="{ clickable: true }"
:autoplay="{delay: 10000}"
:loop="true"
:style="swiperStyle"
class="carousel-box"
>
<swiper-slide v-for="item in banner_list">
<div class="carousel-items animate__animated animate__fadeIn animate__slow">
<img alt="" :src="item.banner_img">
</div>
</swiper-slide>
</swiper>
</div>
</template>
<script setup>
//
import { Pagination, Navigation, Autoplay } from 'swiper'
// noinspection ES6CheckImport
import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css'
import 'swiper/css/pagination'
import 'swiper/css/navigation'
//
const banner_list = ref([
{
banner_img:`/img/loading.gif`,
},
])
const params = reactive({
page: 1,
limit: 10
})
// const getBannerListFun = async () => {
// await get("/Banner.Banner/getBannerList", params).then(res => {
// let data = JSON.parse(res.value).data
// banner_list.value = data
// }).catch((err) => {
// })
// }
//
// setTimeout(() => {
// (async () => {
// await getBannerListFun()
// })()
// })
//
useFetch('/api/banner/getBanner').then(res => {
banner_list.value = JSON.parse(res.data.value).data
})
/**整体轮播图样式*/
let styleContainer = reactive({
height: '40vw'
})
const modules = ref([Pagination, Navigation, Autoplay])
const swiperStyle = conversionStyleVal(reactive({
/**轮播图样式*/
color: '', //
height: '40vw', //
width: '100%', //
margin: '0', //margin
padding: '0', //padding
background: '', //
/**右边按钮样式*/
buttonNext: {
color: 'rgb(255, 255, 255,0.5)', //
height: '', //
width: '', //
margin: '0', //margin
padding: '0', //padding
background: '' //
},
/**左边按钮样式*/
buttonPrev: {
color: 'rgb(255, 255, 255,0.5)', //
height: '', //
width: '', //
margin: '0', //margin
padding: '0', //padding
background: '' //
},
/**小圆点样式*/
pagination: {
color: '', //
height: '8px', //
width: '8px', //
margin: '0 10px ', //margin
padding: '0', //padding
background: 'rgb(255, 255, 255)' //
},
/**选中的小圆点样式*/
paginationActive: {
color: '', //
height: '8px', //
width: '8px', //
margin: '0 10px', //margin
padding: '0', //padding
background: 'rgb(255, 255, 255)' //
}
}), 'swiper')
</script>
<style scoped src="~/assets/css/Carousel/index.scss"></style>
<style scoped src="~/assets/css/Carousel/media.scss"></style>

171
components/Final/index.vue Normal file
View File

@ -0,0 +1,171 @@
<template>
<div class="share-hide-main animate__animated animate__fadeIn " @click.self="closeShare" v-show="showShare">
<div class="share-box">
<img id="code-box" src="/img/wx_qrcode.jpg" alt="">
</div>
</div>
<div class="Final op0" data-animation="animate__animated animate__fadeInUp">
<div class="Final-float-box ">
<div class="Final-float rootBg">
<template v-for="item in shareList">
<div class="float-items" @click="createShareCode(item.contact_scancode_img)">
<img :src="item.contact_scancode_icon" alt="">
<div>{{ item.contact_scancode_title }}</div>
</div>
</template>
</div>
</div>
<div class="Final-container" :style="FinalStyle">
<div class="Final-big-box">
<!-- <div class="Final-icon-box" :style="FinalStyle.FinalLeft">
<img src="/img/icon/logo1.ico" class="icon-img" alt="">
</div> -->
<div class="Final-middle-box" :style="FinalStyle.FinalMiddle">
<div class="Final-middle-items">
<div class="items-title">关于我们</div>
<nuxt-link to="/about/intro/0">
<div class="items">厚德简介</div>
</nuxt-link>
<nuxt-link to="/about/env/1-1">
<div class="items">教学环境</div>
</nuxt-link>
<nuxt-link to="/about/history/2">
<div class="items">发展历程</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">招生报名</div>
<nuxt-link to="/signUp/signUp_introduction/0-1">
<div class="items">招生简介</div>
</nuxt-link>
<nuxt-link to="/signUp/classes_intro/1-1">
<div class="items">班型介绍</div>
</nuxt-link>
<nuxt-link to="/signUp/enrol_aq/2">
<div class="items">招生回答</div>
</nuxt-link>
<nuxt-link to="/signUp/signup_way/3">
<div class="items">报名方式</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">师资力量</div>
<nuxt-link to="/teachers/0">
<div class="items">教师列表</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">荣誉成绩</div>
<nuxt-link to="/achievement/school_achievement/0">
<div class="items">录取院校</div>
</nuxt-link>
<nuxt-link to="/achievement/joint_achievement/1-1">
<div class="items">联考成绩</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">作品欣赏</div>
<nuxt-link to="/works/0">
<div class="items">作品列表</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">艺考资讯</div>
<nuxt-link to="/news/0-1">
<div class="items">资讯列表</div>
</nuxt-link>
</div>
<div class="Final-middle-items">
<div class="items-title">联系我们</div>
<nuxt-link to="/contactUs/contact_info/0">
<div class="items">联系方式</div>
</nuxt-link>
<nuxt-link to="/contactUs/signup/1">
<div class="items">在线报名</div>
</nuxt-link>
<nuxt-link to="/contactUs/leave_message/2">
<div class="items">用户留言</div>
</nuxt-link>
<nuxt-link to="/contactUs/join_apply/3">
<div class="items">合作加盟</div>
</nuxt-link>
</div>
</div>
</div>
<div class="Final-middle-phone-box">
<div class="Final-middle-phone-title-box">
<div class="Final-middle-phone-title">全国报名热线</div>
<div class="Final-middle-phone-content-box">
<div v-for="(item, index) in bottomData.hoteline" class="Final-middle-phone-content">
{{ item.consulting_hotline_user }} : {{ item.consulting_hotline_phone }}
</div>
</div>
</div>
</div>
<!-- <div class="Final-code-box">
<div class="code-text">扫描关注微信公众号</div>
<img :src=bottomData.wx_office_accounts_img alt="微信公众号图片">
</div> -->
<div class="Final-bottom-box">©2023 广州厚德艺术教育有限公司 版权所有</div>
</div>
</div>
</template>
<script setup>
//
const FinalStyle = {
padding: "80px 0 0 0",
FinalLeft: {
},
FinalMiddle: {
},
}
let shareList = ref([
// {
// contact_scancode_icon: '',
// contact_scancode_img: '',
// contact_scancode_title: '--'
// },
// {
// contact_scancode_icon: '/img/icon/wbIcon.png',
// contact_scancode_img: '',
// contact_scancode_title: ''
// },
// {
// contact_scancode_icon: '/img/icon/qqIcon.png',
// contact_scancode_img: '',
// contact_scancode_title: 'QQ'
// },
])
let showShare = ref(false)
const closeShare = function () {
showShare.value = false
}
const createShareCode = function (code) {
showShare.value = true
document.getElementById('code-box').src = code
}
//
let bottomData = ref({})
useFetch('/api/contactUs/getContactInfo').then(res => {
let resValue = JSON.parse(res.data.value).data
bottomData.value = resValue
shareList.value = resValue.qrcode
})
onMounted(() => {
htmlAddAnimations()
})
</script>
<style lang="scss" scoped src="~/assets/css/Final/index.scss"></style>
<style lang="scss" scoped src="~/assets/css/Final/media.scss"></style>

View File

@ -0,0 +1,29 @@
<template>
<div class="HeaderIcon" :style="[HeaderIcon]">
<div class="HeaderIcon-container">
<nuxt-link to="/" >
<div class="HeaderIcon-box">
<img class="pc_top_logo" id="top_logo" src="/img/icon/logo_white.png" alt="">
</div>
</nuxt-link>
</div>
</div>
</template>
<script>
export default {
name: "HeaderIcon",
props:{
HeaderIcon:Object
},
setup(prop){
return {
...prop
}
}
}
</script>
<style scoped src="~/assets/css/Header/icon.scss" lang="scss"></style>
<style scoped src="~/assets/css/Header/media.scss" lang="scss"></style>

View File

@ -0,0 +1,23 @@
<template>
<div class="HeaderNav" :style="[props.HeaderNav]">
<div class="HeaderNav-container">
<nuxt-link :to="item.href" :class="currentRoute.indexOf(item.alias) != -1 ? 'HeaderNav-navItems nav-active' : 'HeaderNav-navItems'"
v-for="item in props.navList" v-cloak :key="item.name">
<span>{{ item.name }}</span>
</nuxt-link>
</div>
</div>
</template>
<script setup>
const props = defineProps({
HeaderNav: Object,
navList: Array
})
const route = useRouter()
const currentRoute = route.currentRoute.value.matched[0]['name']
const con = console
</script>
<style scoped src="~/assets/css/Header/nav.scss" lang="scss"></style>
<style scoped src="~/assets/css/Header/media.scss" lang="scss"></style>

View File

@ -0,0 +1,61 @@
<template>
<div class="HeaderSearch" :style="[props.HeaderSearch]">
<div class="HeaderSearch-container">
<div class="HeaderSearch-box">
<!-- <img src="/img/icon/searchIcon.png" @click="showSearchBox" class="HeaderSearch-Icon" alt=""> -->
<div class="HeaderSearch-button" @click="toggleAppNavShow">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div class="app-nav animate__animated animate__fadeIn" v-show="appNavShow" :style="props.appNav" @click="closeAppNavShow($event)">
<div class="app-box" @click="closeAppNavShow($event)">
<nuxt-link :to="item.href" class="app-nav-items" v-for="item in props.navList" :key="item.name" @click="appNavItemEvent(item,$event)">
<div >{{item.name}}</div>
<div class="app-nav-second-items animate__animated animate__fadeIn dNone" v-for="_item in item.children" :key="_item.name" >
<nuxt-link :to="item.href">{{_item.name}}</nuxt-link>
</div>
</nuxt-link>
</div>
</div>
</div>
</template>
<script setup>
const appNavShow = ref(false)
const props = defineProps({
HeaderSearch:Object,
appNav:Object,
navList:Array
})
const emit = defineEmits(['showSearchBox'])
const appNavItemEvent = function (item,e){
if(item.children.length!==0){
let tag = e.target
tag.classList.toggle('active');
[...tag.children].filter(item=>item.nodeName==='DIV').map(item=>{
item.classList.toggle('dNone')
})
}
}
const toggleAppNavShow = function (){
appNavShow.value = !appNavShow.value
}
const closeAppNavShow = function (e){
let tag = e.target
if(tag.className === 'app-nav animate__animated animate__fadeIn' || tag.className==='app-box'){
appNavShow.value = false
document.body.style.overflowY = 'auto'
}
}
const showSearchBox = function (){
emit('showSearchBox')
}
</script>
<style scoped src="~/assets/css/Header/search.scss" lang="scss"></style>

123
components/Header/index.vue Normal file
View File

@ -0,0 +1,123 @@
<template>
<div class="Header " >
<div class="Header-container" :style="[HeaderStyleOption]">
<HeaderIcon :HeaderIcon="HeaderStyleOption.HeaderIcon"></HeaderIcon>
<HeaderNav :HeaderNav="HeaderStyleOption.HeaderNav" :navList="navList"></HeaderNav>
<HeaderSearch :HeaderSearch="HeaderStyleOption.HeaderSearch" :appNav="HeaderStyleOption.appNav" :navList="navList"
@showSearchBox="showSearchBox"></HeaderSearch>
</div>
<div class="search-box ">
<input type="text" class="search-box-input " @blur="showSearchHideBox([])" @input="searchEvent">
<div class="search-hide-box ">
<div class="search-hide-items" v-for="item in searchRes">
<nuxtLink :to="item.href">
{{ item.txt }}
</nuxtLink>
</div>
</div>
</div>
</div>
<div class="phone-box">
</div>
</template>
<script setup>
import HeaderIcon from "./HeaderIcon.vue";
import HeaderNav from "./HeaderNav.vue";
import HeaderSearch from "./HeaderSearch.vue";
const route = useRouter()
/**样式配置*/
const HeaderStyleOption = reactive({
/**导航样式*/
HeaderNav: {
'padding-left': '25vw'
},
/**icon样式*/
HeaderIcon: {
},
/**搜索样式*/
HeaderSearch: {
position: ' absolute',
right: '20px',
},
/**手机菜单栏样式*/
appNav: {
top: ' 0',
height: '100%',
width: '100%'
}
})
let info_article_type_id = ref(0)
// '/product'
// '/product/child'
// 'child'
let navList = [
{
name: 'Home',
children: [],
href: '/',
alias: 'index'
},
{
name: 'Gitee',
children: [],
href: 'https://gitee.com/zhi-lan_0/aerowen-toolbox',
alias: 'Gitee'
},
{
name: 'GitHub',
children: [],
href: 'https://github.com/Abbh1/AerwenTool',
alias: 'GitHub'
},
]
// [
// {
// txt:'123',
// href:''
// }
// ]
let searchRes = ref(null)
const showSearchBox = function () {
document.getElementsByClassName('search-box')[0].classList.toggle('search-show')
document.getElementsByClassName('search-box-input')[0].classList.toggle('search-input-show')
}
let timer = null
const searchEvent = function (e) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
let searchVal = e.target.value
// get('',searchVal).then((res)=>{
// showSearchHideBox(res)
// })
// showSearchHideBox(res)
}, 1000)
}
const showSearchHideBox = function (data) {
searchRes.value = data
if (data && data.length !== 0) {
document.getElementsByClassName('search-box-input')[0].classList.add('search-have')
} else {
document.getElementsByClassName('search-box-input')[0].classList.remove('search-have')
}
}
</script>
<style lang="scss" scoped src="~/assets/css/Header/index.scss"></style>
<style lang="scss" scoped src="~/assets/css/Header/media.scss"></style>

View File

@ -0,0 +1,66 @@
<template>
<div class="ImgDetail-main" ref="ImgDetail-main" @click="closeImgDetail($event)" style="display: none">
<div class="ImgDetail-container" >
<div class="ImgDetail-box">
<div class="close-btn" @click="closeImgDetail($event)">X</div>
<div class="left-box">
<img src="/img/leftImgDetailIcon.png" title="图片" alt="暂无图片"
@click="leftEvent">
</div>
<div class="right-box">
<img src="/img/rightImgDetailIcon.png" title="图片" alt="暂无图片"
@click="rightEvent">
</div>
<div class="img-box">
<template v-for="(item,idx) in props.imgList">
<img v-show="idx === imgIdx" :src="item" alt="">
</template>
</div>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
imgList:Array,
imgIdx:Number
})
const emits = defineEmits()
const imgIdx = ref(props.imgIdx)
const closeImgDetail = function (e){
document.getElementsByClassName('ImgDetail-main')[0].style.display='none'
}
const leftEvent = function (){
if(!imgIdx.value <= 0){
imgIdx.value -=1
emits('left')
}
}
const rightEvent = function (){
if(imgIdx.value < props.imgList.length-1){
imgIdx.value += 1
emits('right')
}
}
watch(props,nv=>{
imgIdx.value = nv.imgIdx
})
defineExpose({
showImgDetail(){
document.getElementsByClassName('ImgDetail-main')[0].style.display='block'
}
})
</script>
<style scoped src="~/assets/css/ImgDetail/index.scss"></style>
<style scoped src="~/assets/css/ImgDetail/media.scss"></style>

124
components/Load/index.vue Normal file
View File

@ -0,0 +1,124 @@
<template>
<div class="Load-main">
<div class="Load-container">
<div class="Load-box">
<template v-for="(item,idx) in _loadTxt">
<span class="Load-txt op0" v-html="item" :style="'--delayTime:'+idx*0.5+'s'"></span>
</template>
</div>
</div>
</div>
</template>
<script setup>
/**
*
* Load:
* @author:黄勇文
* @example:
* <Load
* :loadTxt='这是你要传入的动画文本'
* :speed='这是你要传入的文本显示时间'
* :chockTime='这是等待文本隐藏的间隔时间'
* />
* */
const props = defineProps({
loadTxt:{
type:String,
default:'Aerwen 工具箱'
},
speed:{
type:Number,
default:150,
},
chockTime:{
type:Number,
default:2000
}
})
/**配置项**/
/**动画文本**/
let loadTxt = props.loadTxt || 'Aerwen 工具箱'
/**动画速度**/
let speed = props.speed || 150
/**等待文本隐藏时间**/
let chockTime = props.chockTime || 2000
/**格式优化**/
let _loadTxt = (()=>{
let res = [],
_i = 0
for (let i = 0; i < loadTxt.length; i++) {
let item = loadTxt[i]
let _item = item === ' ' ? '&nbsp;' : item
if(_item === '&nbsp;'){
res[_i] += _item
}else{
_i = i
res.push(_item)
}
}
return res
})()
onMounted(()=>{
document.body.style.overflowY='hidden'
/**动画显示执行**/
;(()=>{
;[...document.getElementsByClassName('Load-txt')].map((item,idx)=>{
setTimeout(()=>{
item.classList.remove('op0')
},idx*speed)
})
})();
/**动画隐藏执行**/
let hideAnimation = (async ()=>{
/**阻塞动画**/
await chockAnimation()
let oTxt = [...document.getElementsByClassName('Load-txt')]
let b = 0
await new Promise(r=>{
for (let i = oTxt.length-1; i >= 0; i--) {
b+=1
let item = oTxt[i]
setTimeout((b)=>{
item.classList.add('op0')
if(b===oTxt.length){
r(true)
}
},b*speed,b)
}
})
/**显示页面**/
await new Promise(r=>{
setTimeout(()=>{
r(true)
},1000)
})
;(()=>{
document.getElementsByClassName('Load-box')[0].style.background = 'rgba(255,255,255,0)'
setTimeout(()=>{
document.getElementsByClassName('Load-box')[0].style.display = 'none'
document.body.style.overflowY='auto'
},400)
})()
})();
function chockAnimation(){
return new Promise(r=>{
setTimeout(()=>{
r(true)
},chockTime)
})
}
})
</script>
<style scoped src="~/assets/css/Load/index.scss"></style>
<style scoped src="~/assets/css/Load/media.scss"></style>

247
components/Map/index.vue Normal file
View File

@ -0,0 +1,247 @@
<template>
<!-- <client-only> -->
<div class="map-wrapper">
<div id="mapcontainer"></div>
<div class="search-box">
<el-autocomplete v-if="props.isSearch" v-model="location.address" :fetch-suggestions="handleSearch"
:trigger-on-focus="false" clearable placeholder="输入城市+关键字搜索" @select="handleSelect"
style="width: 300px" />
<el-input v-if="props.isShowInput" v-model="location.longitude" placeholder="选择经度" maxlength="15" readonly
style="width: 150px; margin: 0 10px 0 20px"></el-input>
<el-input v-if="props.isShowInput" v-model="location.latitude" placeholder="选择纬度" maxlength="15" readonly
style="width: 150px"></el-input>
</div>
</div>
<!-- </client-only> -->
</template>
<script setup>
const props = defineProps({
// v-model ()
modelValue: {
type: Object,
default(v) {
return v;
}
},
//
isSearch: {
type: Boolean,
default: true
},
//
isClick: {
type: Boolean,
default: true
},
//
isShowInput: {
type: Boolean,
default: true
},
mapCb: {
type: Function,
default: function () {
}
}
});
const emit = defineEmits(['update:modelValue']);
const map = shallowRef(null);
const location = ref(props.modelValue);
onMounted(async () => {
// if (process.client) {
await initMap();
// }
});
watch(location.value, val => {
// if (process.client) {
if (val.longitude && val.latitude) {
drawMarker();
}
// }
});
const keyword = ref('');
let placeSearch, AMapObj, marker, geocoder;
async function initMap() {
const AMapLoader = await import('@amap/amap-jsapi-loader');
AMapLoader.load({
key: '582deef9a68a17068f3b7e291807045d', // WebKey load
version: '2.0'
}).then(async AMap => {
await props.mapCb()
AMapObj = AMap;
map.value = new AMap.Map('mapcontainer');
//
if (props.isClick) {
map.value.on('click', onMapClick);
}
if (location.value.longitude) {
drawMarker();
}
AMap.plugin(
[
'AMap.ToolBar',
'AMap.Scale',
'AMap.Geolocation',
'AMap.PlaceSearch',
'AMap.Geocoder'
],
() => {
//
const toolbar = new AMap.ToolBar();
//
const scale = new AMap.Scale();
//
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //使:true
timeout: 10000, //105s
position: 'RT', //
buttonOffset: new AMap.Pixel(10, 20), //Pixel(10, 20)
zoomToAccuracy: true //
});
geocoder = new AMap.Geocoder({
city: '全国'
});
map.value.addControl(geolocation);
map.value.addControl(toolbar);
map.value.addControl(scale);
placeSearch = new AMap.PlaceSearch({
map: map.value,
city: '',
pageSize: 30, //
pageIndex: 1, //
citylimit: false, //
autoFitView: true
});
}
);
});
}
//
function handleSearch(queryString, cb) {
placeSearch.search(queryString, (status, result) => {
if (result && typeof result === 'object' && result.poiList) {
const list = result.poiList.pois;
list.forEach(item => {
item.value = item.name;
item.label = item.name;
});
cb(list);
} else {
cb([]);
}
});
}
//
function onMapClick(e) {
const { lng, lat } = e.lnglat;
//
geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.info === 'OK') {
const { addressComponent, formattedAddress } = result.regeocode;
let { city, province, district } = addressComponent;
if (!city) {
//
city = province;
}
// location.value = {
// longitude: lng,
// latitude: lat,
// address: formattedAddress,
// zone: [province, city, district],
// };
location.value.longitude = lng;
location.value.latitude = lat;
location.value.address = formattedAddress;
location.value.zone = [province, city, district];
}
});
}
//
function handleSelect(item) {
// const { pname, cityname, adname, address, name } = item;
const { lng, lat } = item.location;
//
geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.info === 'OK') {
const { addressComponent, formattedAddress } = result.regeocode;
let { city, province, district } = addressComponent;
if (!city) {
//
city = province;
}
// location.value = {
// longitude: lng,
// latitude: lat,
// address: formattedAddress,
// zone: [province, city, district],
// };
location.value.longitude = lng;
location.value.latitude = lat;
location.value.address = formattedAddress;
location.value.zone = [province, city, district];
}
});
// location.value = {
// longitude: lng,
// latitude: lat,
// address,
// zone: [pname, cityname, adname],
// name
// };
// location.value.longitude = lng;
// location.value.latitude = lat;
// location.value.address = address;
// location.value.name = name;
// location.value.zone = [pname, cityname, adname];
map.value.setZoomAndCenter(16, [lng, lat]);
}
// marker
function drawMarker(val) {
const { longitude, latitude } = location.value || val;
if (marker) {
marker.setMap(null);
}
marker = new AMapObj.Marker({
position: new AMapObj.LngLat(longitude, latitude),
anchor: 'bottom-center'
});
map.value.add(marker);
map.value.setZoomAndCenter(16, [longitude, latitude]);
}
</script>
<style lang="scss" scoped>
.map-wrapper {
position: relative;
width: 100%;
height: 400px;
display: flex;
#mapcontainer {
width: 100%;
height: 100%;
}
.search-box {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
display: flex;
flex-wrap: wrap;
align-items: center;
}
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<div :class="{ hidden: hidden }" class="pagination-container">
<el-pagination large background v-model:current-page="currentPage" v-model:page-size="pageSize" :layout="layout"
:page-sizes="pageSizes" :pager-count="pagerCount" :total="total" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</template>
<script>
// import { scrollTo } from "@/utils/scroll-to";
import { computed } from 'vue'
export default {
name: 'pagingation',
emits: ['update:page', 'update:limit', 'pagination'],
props: {
total: {
required: true,
type: Number,
},
page: {
type: Number,
default: 1,
},
limit: {
type: Number,
default: 10,
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50, 100]
},
},
// 5
pagerCount: {
type: Number,
default: 7,
},
layout: {
type: String,
default: 'total, prev, pager, next, jumper',
},
background: {
type: Boolean,
default: true,
},
autoScroll: {
type: Boolean,
default: true,
},
hidden: {
type: Boolean,
default: false,
},
},
setup(props, { ctx, emit }) {
const currentPage = computed({
get() {
return props.page
},
set(val) {
emit('update:page', val)
},
})
const pageSize = computed({
get() {
return props.limit
},
set(val) {
emit('update:limit', val)
},
})
function handleSizeChange(val) {
emit('pagination', { page: currentPage.value, limit: val })
if (props.autoScroll) {
// scrollTo(0, 800);
}
}
function handleCurrentChange(val) {
emit('pagination', { page: val, limit: pageSize.value })
if (props.autoScroll) {
// scrollTo(0, 800);
}
}
onMounted(() => {
createMediaList({
480(m){
if(m.matches){
document.getElementsByClassName('el-pagination__total ')[0].style.display = 'none'
}else{
document.getElementsByClassName('el-pagination__total ')[0].style.display = 'block'
}
}
})
})
return {
currentPage,
pageSize,
handleSizeChange,
handleCurrentChange,
}
},
}
</script>
<style scoped>
.pagination-container {
/* background: #fff; */
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<div class="Poster-main op0" data-animation="animate__animated animate__fadeIn animate__slow">
<div class="Poster-container" :style="posterStyle">
<img class="Poster-img" :src="posterInfo.imgSrc" alt="">
<div class="Poster-content-box">
<div class="Poster-title"> {{ posterInfo.title }} </div>
<div class="Poster-text">{{ posterInfo.text }}</div>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
type: Number
})
let posterInfo = ref({
// imgSrc: '',
// title: '',
// text: ''
}),
posterStyle = {
height: '40vw'
}
//
useFetch('/api/poster/getPoster', { params: { poster_location: props.type } }).then(res => {
posterInfo.value = JSON.parse(res.data.value).data
setTimeout(() => {
htmlAddAnimations()
});
})
</script>
<style scoped src="~/assets/css/poster/index.scss"></style>
<style scoped src="~/assets/css/poster/media.scss"></style>

81
components/Tab/index.vue Normal file
View File

@ -0,0 +1,81 @@
<template>
<div class="Tab-main">
<div class="Tab-container">
<div class="Tab-box" @click="switchIdx($event)">
<template v-for="(item,idx) in props.tabList" >
<div class="Tab-items" >
<nuxt-link :data-idx = 'idx' :class="props.active.idx === idx ? '_Tab-item active':'_Tab-item'" :to="item?.nuxtLink" @click="changChildren(!!item.children,$event)">{{item.name}}</nuxt-link>
<div class="Tab-child-box dNone" v-if="item?.children">
<template v-for="(_item,_idx) in item.children">
<nuxt-link :to="_item?.nuxtLink" class="Tab-child-items" @click="switchCIdx(_idx,$evnet)">{{_item.name}}</nuxt-link>
</template>
</div>
</div>
</template>
</div>
</div>
</div>
</template>
<script setup>
/**
*
* @type {Readonly<ExtractPropTypes<{tabList: ArrayConstructor, active: ObjectConstructor}>>}
* @description 接收两个参数第一个是tabList第二个是active
* @example
* tabList[
* {
name: '招生新闻', //
target: news // a,
},
//
* ]
* activereactive({idx:0}) //reactiveidx
这个idx为默认先展示第几个
* @return 这个组件没有返回值如果你选中了一个选项它会更新这个active你可以用watch监听这个active
*/
const props = defineProps({
tabList:Array,
active:Object
})
let idx = 0
const switchIdx = function (e){
let tag = e.target,
cl = tag.classList
if(cl.value.indexOf('_Tab-item')!==-1){
tag.parentElement.parentElement.children[idx].children[0].classList.remove('active')
idx = Number(tag.dataset.idx)
tag.parentElement.parentElement.children[idx].children[0].classList.add('active')
props.active.idx = idx
props.active.name = tag.innerText;
if('target' in props.active){
props.active.target = props.tabList[idx].target
}
props.active.nuxtLink = props.tabList[idx].nuxtLink
}
}
const changChildren = function (has,e){
if(has){
let tag = e.target,
cl = tag.classList
if(cl.value.indexOf('_Tab-item')!==-1){
tag.nextElementSibling.classList.toggle('dNone')
}
}else {
[...document.getElementsByClassName('Tab-child-box')].map(item=>{
item.classList.add('dNone')
})
}
}
const switchCIdx = function (_idx,e){
props.active.cIdx = _idx
}
</script>
<style scoped src="~/assets/css/Tab/index.scss"></style>
<style scoped src="~/assets/css/Tab/media.scss"></style>

0
layout/index.vue Normal file
View File

8
middleware/auth.ts Normal file
View File

@ -0,0 +1,8 @@
// export default defineNuxtRouteMiddleware((to) => {
// const path = to['_route'].path
// const router = useRouter()
// if(path === '/'){
// console.log('要跳转到load页')
// location.href = '/load'
// }
// })

39
nuxt.config.ts Normal file
View File

@ -0,0 +1,39 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
// import process from 'process/browser';
export default defineNuxtConfig({
ssr: true,
nitro: {
devProxy: {
"/api-v": {
target: "http://192.168.1.105/Aerwen/houde_web/houde_web_api/public/api.php/", // 文豪
// target: "http://192.168.1.18/ARW/houde_web/houde_web_api/public/api.php/", // 君豪
// target: "http://houde_web.back.aerwen.net/api", // 这里是线上接口地址
changeOrigin: true,
prependPath: true,
},
"/uploads": {
// target: "http://192.168.1.105/Aerwen/houde_web/houde_web_api/public/uploads", // 文豪
// target: "http://192.168.1.18/ARW/houde_web/houde_web_api/public/uploads", // 君豪
target: "https://houde.api.aerwen.net/uploads", // 这里是线上接口地址
changeOrigin: true,
prependPath: true,
},
},
},
plugins: [
// '~/middleware/auth.ts'
],
css: [
"bootstrap/dist/css/bootstrap.min.css",
// "swiper/css/swiper.css",
"~/assets/css/root/media.scss",
"~/assets/css/root/root.scss",
"~/assets/css/root/animation.scss",
"swiper/css",
"animate.css"
],//追加
})

11994
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@ -0,0 +1,33 @@
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev --port 3003",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"@nuxtjs/style-resources": "^1.2.1",
"node-sass": "^8.0.0",
"nuxt": "^3.2.2",
"sass-loader": "^13.2.0",
"unplugin-auto-import": "^0.10.3",
"unplugin-icons": "^0.13.2",
"unplugin-vue-components": "^0.22.8"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"animate.css": "^4.1.1",
"bootstrap": "^5.3.0-alpha1",
"element-plus": "^2.2.32",
"hyw-load": "^1.0.1",
"jquery": "^3.6.4",
"nuxt-build-optimisations": "^1.0.7",
"path": "^0.12.7",
"sass": "^1.58.3",
"swiper": "^8.4.7",
"v3-lazyload-hyw": "^1.5.7",
"vue-awesome-swiper": "^5.0.1"
}
}

225
pages/index.vue Normal file
View File

@ -0,0 +1,225 @@
<template>
<!-- <Load></Load> -->
<ImgDetail ref='ImgDetailRef' :imgList="imgList" :imgIdx="imgIdx"></ImgDetail>
<Head>
<Title>Aerwen工具箱 - 提供专业的研发效能工具和解决方案 | Aerwen官网</Title>
<Meta name="keywords" content="Aerwen工具箱研发效能平台研发工具解决方案自动化智能化" />
<Meta name="description"
content="欢迎访问Aerwen工具箱官网我们致力于为研发团队提供一站式的研发效能平台。通过我们的工具和解决方案您可以提高开发效率、优化团队协作并实现高质量的软件交付。" />
<Meta name="baidu-site-verification" content="" />
</Head>
<Header></Header>
<main class="home-main-box">
<section>
<div class="home-box container">
<!-- 顶部内容 -->
<div class="top-content animate__animated animate__fadeIn">
<!-- 标题 -->
<div class="home-top-title-box">
<h1 class="home-top-title">智能化开发助手Aerwen工具箱</h1>
<h3 class="home-sub-title">做项目轻轻松松的</h3>
</div>
<!-- 下载按钮盒子 -->
<div class="home-download-box">
<a class="home-download-button" target="_blank"
href="http://tool.aerwen.net/prod-api/cdn/tool/AerwenTool.msi">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="windows"
class="svg-inline--fa fa-windows svg-content" role="img" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512">
<path fill="currentColor"
d="M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z">
</path>
</svg>
Download for Windows
</a>
<div class="mt-5">
<a class="home-download-button" target="_blank"
href="https://space.bilibili.com/270021386/channel/seriesdetail?sid=3334327">
使用教程
</a>
</div>
</div>
<!-- 顶部展示图片 -->
<div class="top-show-box">
<img @click="handleImg(0)" :src=openImg1 alt="">
</div>
</div>
<!-- 中间内容 -->
<div class="middle-box">
<!-- 一键打开盒子 -->
<div class="middle-content-big-box">
<!-- 标题 -->
<div class="middle-content-title-box op0" data-animation="animate__animated animate__fadeInUp ">
<h2 class="middle-content-title">一键打开</h2>
<h3 class="middle-content-sub-title">一个按钮打开多个项目文件高效便捷让工作更轻松提升生产力体验全新的工作方式</h3>
</div>
<!-- 内容 -->
<div class="middle-img-box op0" data-animation="animate__animated animate__fadeInLeft">
<img @click="handleImg(1)" :src=openImg alt="">
</div>
</div>
<!-- 一键建表盒子 -->
<div class="middle-content-big-box">
<!-- 标题 -->
<div class="middle-content-title-box op0" data-animation="animate__animated animate__fadeInUp">
<h2 class="middle-content-title">一键建表</h2>
<h3 class="middle-content-sub-title">可视化操作快速创建和执行数据库表格轻松一键翻译字段助力高效数据库管理</h3>
</div>
<!-- 内容 -->
<div class="middle-img-box op0" data-animation="animate__animated animate__fadeInRight">
<div class="create-table-navicat-img-box">
<img src="https://navicat.com/images/02.Product_00_AllProducts_Premium16.svg" alt="">
</div>
<img @click="handleImg(2)" :src=createTableImg alt="">
</div>
</div>
<!-- 资源中心 -->
<div class="middle-content-big-box">
<!-- 标题 -->
<div class="middle-content-title-box op0" data-animation="animate__animated animate__fadeInUp">
<h2 class="middle-content-title">资源中心</h2>
<h3 class="middle-content-sub-title">聚合常用资源快速导航节省开发时间一站式资源中心助你高效开发</h3>
</div>
<!-- 内容 -->
<div class="middle-img-box op0" data-animation="animate__animated animate__fadeInLeft">
<img @click="handleImg(3)" :src=resourcesImg alt="">
</div>
</div>
<!-- 数据库转思维导图 -->
<div class="middle-content-big-box">
<!-- 标题 -->
<div class="middle-content-title-box op0" data-animation="animate__animated animate__fadeInUp">
<h2 class="middle-content-title">数据库转思维导图</h2>
<h3 class="middle-content-sub-title">数据库表与字段一键转换为Ximd思维导图格式助力数据结构梳理轻松可视化提升工作效率</h3>
</div>
<!-- 内容 -->
<div class="middle-img-box op0" data-animation="animate__animated animate__fadeInRight">
<img @click="handleImg(4)" :src=dataBaseImg alt="">
</div>
</div>
</div>
<!-- 底部内容 -->
<div class="bottom-box">
<!-- gitee源码盒子 -->
<div class="gitee-box op0" data-animation="animate__animated animate__lightSpeedInLeft">
<div class="gitee-img-box">
<img src="https://gitee.com/static/images/logo.svg?t=158106664" alt="">
</div>
<div class="gitee-content-box">
<div class="gitee-content-title">Gitee 源码地址</div>
<div class="gitee-content-link">
<a class="home-download-button" target="_blank" href="https://gitee.com/zhi-lan_0/aerowen-toolbox">
下载源码
</a>
</div>
</div>
</div>
<div class="gitee-box op0" data-animation="animate__animated animate__lightSpeedInRight">
<div class="gitee-content-box">
<div class="gitee-content-title">GitHub 源码地址</div>
<div class="gitee-content-link">
<a class="home-download-button" target="_blank" href="https://github.com/Abbh1/AerwenTool">
下载源码
</a>
</div>
</div>
<div class="gitee-img-box">
<img src="/img/home/icons8-github.gif" alt="">
</div>
</div>
</div>
</div>
</section>
</main>
<!-- <Final></Final> -->
</template>
<script setup>
/** 基础变量 **/
let imgList = ref([])
let imgIdx = ref(0)
let ImgDetailRef = ref(null)
/**预对接的数据**/
let openImg1 = ref("/img/home/open/open1.png")
let openImg = ref("/img/home/open/open2.png")
let createTableImg = ref("/img/home/createTable/createTable1.png")
let resourcesImg = ref("/img/home/resources/resources1.png")
let dataBaseImg = ref("/img/home/mind/mind1.png")
/**js常量的定义**/
/**js操控的逻辑变量**/
/**方法函数**/
function handleImg(v) {
ImgDetailRef.value.showImgDetail()
imgIdx.value = v
}
/**onMounted**/
onMounted(() => {
imgList.value.push(openImg1.value)
imgList.value.push(openImg.value)
imgList.value.push(createTableImg.value)
imgList.value.push(resourcesImg.value)
imgList.value.push(dataBaseImg.value)
htmlAddAnimations({ tagDom: 'home-main-box' })
})
/**export**/
defineExpose({
middleware: 'auth'
})
</script>
<style scoped src="~/assets/css/index/index.scss"></style>
<style scoped src="~/assets/css/index/media.scss"></style>

33
pages/test.vue Normal file
View File

@ -0,0 +1,33 @@
<template>
<Head>
<!-- <Title>test</Title> -->
<Title>{{ tdk.tdk_title }}</Title>
<Meta name="keywords" :content=tdk.tdk_keyword />
<Meta name="description" :content=tdk.tdk_description />
</Head>
<h1>{{ contactInfo }}</h1>
<h2>{{ tdk }}</h2>
</template>
<script setup>
let contactInfo = ref({})
const headers = useRequestHeaders(['cookie'])
let tdk = ref({})
onMounted(async () => {
//
// let data = useFetch('/api/contactUs/getContactInfo',{headers})
// let contactInfoData = await useFetch('/api/contactUs/getContactInfo', { headers })
// contactInfo.value = JSON.parse(contactInfoData.data.value)
})
useFetch('/api/tdk/getTdk', { params: { tdk_type: "index" } }).then(res => {
tdk.value = JSON.parse(res.data.value).data
})
</script>

16
plugins/element-plus.ts Normal file
View File

@ -0,0 +1,16 @@
// plugins\element-plus.ts
import { defineNuxtPlugin } from '#app'
import '~/style/element/index.scss'
import { ID_INJECTION_KEY } from 'element-plus';
// 引入中文包
import locale from 'element-plus/lib/locale/lang/zh-cn'
import ElementPlus from 'element-plus'
export default defineNuxtPlugin(nuxtApp => {
// Doing something with nuxtApp
nuxtApp.vueApp.provide(ID_INJECTION_KEY, {
prefix: Math.floor(Math.random() * 10000),
current: 0,
})
nuxtApp.vueApp.use(ElementPlus, { locale })
})

View File

@ -0,0 +1,11 @@
import createLazyLoad from 'v3-lazyload-hyw'
import { defineNuxtPlugin } from '#app'
const LazyOption = {
error:'http://localhost:3003/img/error.png',
loading:'http://localhost:3003/img/loading.gif',
payload:1
}
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.directive('lazy',createLazyLoad(LazyOption))
})

5
plugins/vue-swiper.js Normal file
View File

@ -0,0 +1,5 @@
import VueAwesomeSwiper from "vue-awesome-swiper";
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.use(VueAwesomeSwiper)
})

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
public/img/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/img/icon/qqIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

BIN
public/img/icon/wbIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/img/icon/wxIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

BIN
public/img/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

9
public/site.txt Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://aitool.aerwen.net/</loc>
<lastmod>2023-05-10</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
</urlset>

9
public/site.xml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://aitool.aerwen.net/</loc>
<lastmod>2023-05-10</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
</urlset>

View File

@ -0,0 +1,21 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Banner.Banner/getBannerList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,21 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Flow.Flow/AddFlowRecord", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,24 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
/**
* 获取首页数据
*/
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Home.Home/getHome", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取招生简介列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.Classes/getClassesList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,21 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取班型介绍详情列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.Classes/getClassesInfo", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取招生简介列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.EnrolIntro/getEnrolIntroInfo", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取招生问答列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.EnrolAq/getEnrolAqList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,21 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取招生简介列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.EnrolIntro/getEnrolIntroList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取报名流程列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.EnrolAq/addEnrolAq", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取入学流程列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.EnterSchoolProcess/getEnterSchoolProcessList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取报名方式列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.SignUpIntro/getSignUpIntro", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

View File

@ -0,0 +1,22 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
// 获取报名流程列表
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Enrol.SignUpProcess/getSignUpProcessList", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

21
server/api/tdk/getTdk.js Normal file
View File

@ -0,0 +1,21 @@
import {
readRawBody,
getQuery,
getMethod
} from 'h3'
export default defineEventHandler(async (event) => {
// 基础url
const baseURL = process.env.NUXT_PROXY_WEB_API
const method = getMethod(event).toUpperCase()
let body
if (method !== 'GET') body = await readRawBody(event)
const res = await $fetch("https://houde.api.aerwen.net/api.php/Tdk.Tdk/getTdkInfo", {
method,
baseURL: event.context.baseUrl,
headers: event.context.headers,
params: getQuery(event),
body
})
return res
})

14
server/middleware/auth.js Normal file
View File

@ -0,0 +1,14 @@
// /api/middleware/auth.js
import { getHeaders } from 'h3'
export default defineEventHandler(async (event) => {
const reqHeaders = getHeaders(event)
const ssrHeader = new Headers()
const { app } = useRuntimeConfig()
ssrHeader.set('cookie', reqHeaders.cookie)
ssrHeader.set('x-xsrf-token', app['XSRF_HEADER'])
ssrHeader.set('app-id', app['APP_ID'])
// ssrHeader.set('client-id', await getFingerPrint())
event.context.headers = ssrHeader
event.context.baseUrl = app['BASE_URL']
})

0
store/pinia.vue Normal file
View File

16
style/element/index.scss Normal file
View File

@ -0,0 +1,16 @@
/* element-puls 主题色 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': #a30000,
),
),
);
// 如果你想导入所有样式:
@use "element-plus/theme-chalk/src/base.scss" as *;
@use "element-plus/theme-chalk/src/message.scss" as *;
@use "element-plus/theme-chalk/src/empty.scss" as *;
@use "element-plus/theme-chalk/src/input.scss" as *;
@use "element-plus/theme-chalk/src/button.scss" as *;
@use "element-plus/theme-chalk/src/pagination.scss" as *;

4
tsconfig.json Normal file
View File

@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json",
}

168
utils/Tool.js Normal file
View File

@ -0,0 +1,168 @@
/***
*
* js媒体查询
* @param opt
* @return {{}}
* @example:
createMediaList({
480(ctx){
console.log('is 480',ctx)
},
880(ctx){
console.log('is 880',ctx)
},
1220(ctx){
console.log('is 1220',ctx)
},
1440(ctx){
console.log('is 1440',ctx)
},
})
*
*/
export function createMediaList(opt) {
for (let optKey in opt) {
let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
if (mediaCtx ?.matches) {
opt[optKey](mediaCtx)
}
mediaCtx.addListener(opt[optKey])
}
}
/**
*
* 对象转换成css样式变量
* @param obj
* @param prefix
* @return {{}}
*/
export function conversionStyleVal(obj, prefix) {
let res = {}
for (let key in obj) {
if (obj[key] instanceof Object) {
!prefix ? res[key] = conversionStyleVal(obj[key], key) :
Object.assign(res, conversionStyleVal(obj[key], key))
} else {
prefix ? res['--' + prefix + key] = obj[key] :
res['--' + key] = obj[key]
}
}
return res
}
/**
* 滑动到指定位置触发动画
* 需要放到onMounted使用
* @param {*} tagDom (需要触发的class盒子可读取子级一般填最外层盒子)
* author: hyw
*
* 用法
* <div data-animation="animate__animated animate__fadeInLeft" class="box op0">
* htmlAddAnimations('box')
*
* 参数说明
* data-animation: 填写需要添加的动画效果class名 https://animate.style/https://blog.csdn.net/a1056244734/article/details/113884374
* op0 /可视区域/ 外在class加上此class名
*/
export function htmlAddAnimations(opt) {
let oTagDomList = opt?.tagDom ? [...document.getElementsByClassName(opt.tagDom)[0].querySelectorAll('*')] : [...document.body.querySelectorAll('*')],
domAnimationInfoPool = []
oTagDomList.map((domItem, idx) => {
let animationName = domItem.getAttribute('data-animation')
if (animationName) {
domAnimationInfoPool.push({
dom: domItem,
animationName
})
}
})
let windowScrollEvent = function (e) {
for (let i = domAnimationInfoPool.length - 1; i >= 0; i--) {
let infoItem = domAnimationInfoPool[i]
if (infoItem.dom.getBoundingClientRect().top +
infoItem.dom.getBoundingClientRect().height <
window.innerHeight * (opt?.preload || 1.5)) {
infoItem.dom.classList.remove('op0')
infoItem.animationName.split(' ').map(item => {
if (item) {
infoItem.dom.classList.add(item)
}
})
}
}
}
window.addEventListener('scroll', windowScrollEvent, false)
windowScrollEvent()
}
/**
*
* @param opt
* opt:{
* 触发的分辨率要减少的字体
* }
* 需要放到onMounted使用
* @example
* 使用前要在对应的容器加上类名font-size-box
* fontSizeReactive({
* 880:1,
* 480:2
* })
* 这里要注意的是减少的字体是会叠加减少的例如
* 我初始字体是15px我的配置项为
* {
* 8801
* 4802
* }一般来说按照这个配置项的话我字体在屏幕小于880px的时候会变成14px在小于480的时候会变成13px
* 但实际的话是在小于880的时候会变成14px小于480的时候会变成12px也就是会把880也算上
*/
export function fontSizeReactive(opt = {
880: 1,
480: 1,
}) {
let oBox = document.getElementsByClassName('font-size-box')[0]
let tag = oBox ? [...oBox.querySelectorAll('*')] : [...document.querySelectorAll('*')]
tag.map(item => {
let fontSize = getComputedStyle(item, null)['fontSize'].replace('px', '')
item.style.setProperty('font-size', fontSize + 'px')
})
let fnTpl = ''
for (let key in opt) {
fnTpl += `
${key}(ctx) {
if (ctx.matches) {
tag.map(item => {
item.style.fontSize = item.style.fontSize.replace('px', '') - ${opt[key]} + 'px'
})
} else {
tag.map(item => {
item.style.fontSize = Number(item.style.fontSize.replace('px', '')) + ${opt[key]} + 'px'
})
}
},`
}
(new Function('fn,tag', `
fn({
${fnTpl}
})
`))(function (opt) {
for (let optKey in opt) {
let mediaCtx = window !== undefined ? window.matchMedia(`(max-width: ${optKey}px)`) : global.matchMedia(`(max-width: ${optKey}px)`)
if (mediaCtx ?.matches) {
opt[optKey](mediaCtx)
}
mediaCtx.addListener(opt[optKey])
}
}, tag)
}

10
utils/api.ts Normal file
View File

@ -0,0 +1,10 @@
import Http from './request'
export const get = (address,params?) => {
return Http.get(address, params)
}
export const post = (address,params?) => {
return Http.post(address, params)
}

62
utils/request.ts Normal file
View File

@ -0,0 +1,62 @@
import { _AsyncData } from 'nuxt3/dist/app/composables/asyncData'
//import baseUrl from './baseUrl'
import { ElMessage } from 'element-plus'
let baseUrl = '/api-v'
// 指定后端返回的基本数据类型
export interface ResponseConfig {
code: number,
status: number,
data: any,
msg: string
}
export interface ValueConfig {
value: any,
}
const fetch = (url: string, options?: any): Promise<any> => {
const reqUrl = baseUrl + url
return new Promise((resolve, reject) => {
useFetch(reqUrl, { ...options }).then(({ data, error }: _AsyncData) => {
if (error.value) {
reject(error.value)
return
}
const value = data.value
if (!value) {
// 这里处理错误回调
// reject(value)
// $router.replace('/reject/' + value.status)
}else if(value.code == 1){
ElMessage({
message: value.msg,
type: 'error',
})
} else {
resolve(ref(value))
}
}).catch((err: any) => {
reject(err)
})
})
}
export default new class Http {
get(url: string, params?: any): Promise<any> {
return fetch(url, { method: 'get', params })
}
post(url: string, params?: any): Promise<any> {
return fetch(url, { method: 'post', params })
}
put(url: string, body?: any): Promise<any> {
return fetch(url, { method: 'put', body })
}
delete(url: string, body?: any): Promise<any> {
return fetch(url, { method: 'delete', body })
}
}