Compare commits

...

2 Commits

9 changed files with 413 additions and 14 deletions

View File

@ -16,10 +16,10 @@ export default {
updateTime: '更新时间',
required: '必填项不能为空',
app: {
title: 'Maku Admin',
title: '在线书城',
description:
'基于Vue3、TypeScript、Element Plus、Vue Router、Pinia、Axios、i18n、Vite等开发的后台管理使用门槛极低采用MIT开源协议完全免费开源且终生免费可免费用于商业项目等场景',
logoText: 'Maku Admin',
logoText: '在线书城后台',
miniLogoText: 'MAKU',
username: '用户名',
password: '密码',

View File

@ -2,15 +2,6 @@
<div class="navbar-right">
<Lang />
<ComponentSize />
<a href="https://maku.net" target="_blank">
<ma-icon icon="icon-earth"></ma-icon>
</a>
<a href="https://github.com/makunet/maku-admin" target="_blank">
<ma-icon icon="icon-github-fill"></ma-icon>
</a>
<a href="https://gitee.com/makunet/maku-admin" target="_blank">
<ma-icon icon="icon-gitee-fill-round"></ma-icon>
</a>
<Search />
<Fullscreen />
<User />

View File

@ -21,6 +21,10 @@ const constantRoutes: RouteRecordRaw[] = [
]
},
{
path: '/',
redirect: '/book/index'
},
{
path: '/iframe/:query?',
component: () => import('../layout/components/Router/Iframe.vue')
},
@ -31,13 +35,40 @@ const constantRoutes: RouteRecordRaw[] = [
{
path: '/404',
component: () => import('../views/404.vue')
},
{
path: '/book/index',
component: () => import('../views/book/index.vue'),
redirect: '/book/home',
children: [
{
path: '/book/home',
component: () => import('../views/book/component/home.vue')
},
{
path: '/book/collection',
component: () => import('../views/book/component/collection.vue')
},
{
path: '/book/trolley',
component: () => import('../views/book/component/trolley.vue')
},
{
path: '/book/my',
component: () => import('../views/book/component/my.vue')
}
]
},
{
path: '/book/login',
component: () => import('../views/book/login.vue')
}
]
const asyncRoutes: RouteRecordRaw = {
path: '/',
component: () => import('../layout/index.vue'),
redirect: '/dashboard/index',
redirect: '/book/index',
children: [
{
path: '/profile',
@ -55,7 +86,7 @@ const asyncRoutes: RouteRecordRaw = {
export const dashboardMenu = [
{
id: 100,
name: 'Dashboard',
name: '控制台',
url: null,
openStyle: 0,
icon: 'icon-appstore',
@ -166,7 +197,7 @@ export const router = createRouter({
})
// 白名单列表
const whiteList = ['/login']
const whiteList = ['/login', '/book/index', '/book/login', '/book/home', '/book/collection', '/book/trolley', '/book/my']
// 路由跳转前
router.beforeEach(async (to, from, next) => {
@ -204,6 +235,9 @@ router.beforeEach(async (to, from, next) => {
asyncRoutes.children?.push(...keepAliveRoutes)
router.addRoute(asyncRoutes)
// // 添加商城首页菜单
// router.addRoute(bookIndexRouter)
// 错误路由
router.addRoute(errorRoute)

View File

@ -0,0 +1,5 @@
<script setup lang="ts"></script>
<template></template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,149 @@
<script setup lang="ts"></script>
<template>
<div class="search-suggest-combobox">
<div class="input-search">
<input placeholder="马嘉祺" />
<button>搜索</button>
</div>
</div>
<div class="screen-outer">
<div class="tb-pick-content-item">
<div class="img-wrapper"></div>
<div class="info-wrapper">进口安佳淡奶油1L动物奶油新西兰家用生日蛋糕裱花蛋挞液专用烘焙</div>
<div class="price-wrapper">
<span class="price-unit">¥</span>
<span class="price-value">30</span>
</div>
</div>
<div class="tb-pick-content-item"></div>
<div class="tb-pick-content-item"></div>
<div class="tb-pick-content-item"></div>
<div class="tb-pick-content-item"></div>
<div class="tb-pick-content-item"></div>
</div>
</template>
<style scoped lang="scss">
.search-suggest-combobox {
width: 100%;
height: 38px;
margin-top: 40px;
display: flex;
justify-content: center;
.input-search {
width: 1004px;
height: 38px;
border-radius: 8px;
border: 2px solid rgb(255, 80, 0);
align-items: center;
display: flex;
justify-content: space-between;
background: white;
input {
border: none;
background: none;
height: 38px;
margin-left: 30px;
width: 800px;
}
button {
width: 72px;
height: 34px;
border: none;
background: #ff6200;
color: #fff;
font-size: 16px;
font-weight: 700;
border-radius: 4px;
margin-right: 5px;
}
}
}
.screen-outer {
background: #fff;
width: 1552px;
margin: 30px auto;
border-radius: 18px;
padding-top: 16px;
padding-bottom: 24px;
min-height: 300px;
display: flex; /* 添加此行启用Flex布局 */
flex-wrap: wrap; /* 允许Flex子项目换行 */
box-sizing: border-box; /* 确保padding计算在总宽内 */
}
.tb-pick-content-item {
border-radius: 12px;
border: 1px solid transparent;
box-sizing: border-box;
cursor: pointer;
margin: 16px 0 16px 16px; /* 调整上边距以适应新的换行布局 */
position: relative;
transition: all 0.5s;
width: 240px;
height: 358px;
padding: 5px;
.info-wrapper {
height: 48px;
margin-top: 8px;
overflow: hidden;
width: 96%;
color: #11192d;
display: inline-block;
font-size: 16px;
font-weight: 500;
line-height: 24px;
margin-left: 8px;
margin-right: 8px;
max-height: 48px;
word-break: break-all;
}
}
.tb-pick-content-item:hover {
border: 1px solid #ff6200;
}
.img-wrapper {
background-image: url('https://img.alicdn.com/bao/uploaded/i1/3937219703/O1CN01FZXnRo2LY1zwkI3j0_!!3937219703-0-C2M.jpg');
background-position: 50%;
background-repeat: no-repeat;
background-size: cover;
background-color: #f3f6f8;
border-radius: 8px;
height: 230px;
overflow: hidden;
position: relative;
width: 230px;
}
.price-wrapper {
align-items: flex-end;
display: flex;
flex-direction: row;
height: 24px;
margin-left: 8px;
margin-top: 8px;
.price-unit {
font-size: 14px;
line-height: 14px;
margin-bottom: 1px;
margin-right: 2px;
color: #ff5500;
}
.price-value {
font-size: 24px;
font-weight: 700;
line-height: 24px;
color: #ff5500;
}
}
</style>

View File

@ -0,0 +1,5 @@
<script setup lang="ts"></script>
<template></template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,5 @@
<script setup lang="ts"></script>
<template></template>
<style scoped lang="scss"></style>

93
src/views/book/index.vue Normal file
View File

@ -0,0 +1,93 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { ref } from 'vue'
const router = useRouter()
//
const changeValue = ref('/book/index')
const changeRouters = () => {
debugger
if (changeValue.value == '/book/my') {
changeValue.value = '/book/index'
} else if (changeValue.value == '/book/index') {
changeValue.value = '/book/my'
}
router.push(changeValue.value)
}
</script>
<template>
<div class="bg-color">
<div class="nav-link">
<div class="site-nav-bd">
<ul>
<li @click="router.push('/book/login?returnUrl=/book/index&status=0')">请登录</li>
<li @click="router.push('/book/login?returnUrl=/book/index&status=1')">免费注册</li>
</ul>
<ul>
<li @click="changeRouters">{{ changeValue == '/book/my' ? '商城首页' : '我的淘宝' }}</li>
<li @click="router.push('/book/trolley')">
<el-icon>
<ShoppingCart />
</el-icon>
购物车
</li>
<li @click="router.push('/book/collection')">
<el-icon>
<Collection />
</el-icon>
收藏夹
</li>
</ul>
</div>
</div>
<router-view></router-view>
</div>
</template>
<style scoped lang="scss">
.nav-link {
background-color: #f5f5f5;
border-bottom: 1px solid #eee;
width: 100%;
height: 35px;
top: 0;
left: 0;
z-index: 10000;
.site-nav-bd {
margin: 0 auto;
width: 1190px;
height: 35px;
background: #f5f5f5;
display: flex;
justify-content: space-between;
ul {
display: flex;
}
ul li {
list-style-type: none;
height: 35px;
margin-right: 15px;
display: flex;
align-items: center;
}
li:hover {
color: #ff4400;
cursor: pointer;
}
}
}
.bg-color {
position: fixed;
width: 100%;
height: 100%;
background-color: #f5f8fa;
overflow-y: scroll;
}
</style>

117
src/views/book/login.vue Normal file
View File

@ -0,0 +1,117 @@
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import { onMounted, ref } from 'vue'
const route = useRoute()
const router = useRouter()
const handleLogin = () => {
if (active.value == '0') {
console.log('登录')
if (route.query.returnUrl) {
router.push(route.query.returnUrl as string)
}
} else if (active.value == '1') {
active.value = '0'
}
}
onMounted(() => {
if (route.query.status) {
active.value = route.query.status as string
}
})
const active = ref('0')
</script>
<template>
<div class="bg-color">
<div class="login-main">
<div class="login-c">
<form id="login-form">
<div class="login-choice">
<div :class="{ active: active == '0' }" @click="active = '0'">用户登录</div>
<div :class="{ active: active == '1' }" @click="active = '1'">用户注册</div>
</div>
<input class="fm-text" placeholder="用户名" />
<input class="fm-text" placeholder="密码" type="password" />
<input v-if="active == '1'" class="fm-text" placeholder="确认密码" type="password" />
<button @click.prevent="handleLogin">{{ active == '0' ? '登录' : '注册' }}</button>
</form>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.bg-color {
position: fixed;
width: 100%;
height: 100%;
background-color: #f5f8fa;
overflow-y: scroll;
.login-main {
display: flex;
width: 100%;
margin-top: 200px;
justify-content: center;
.login-c {
width: 735px;
height: 514px;
border-radius: 18px;
background: white;
padding: 30px;
}
}
}
#login-form {
display: flex;
flex-direction: column;
width: 100%;
font-size: 25px;
.login-choice {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 50px;
font-weight: 900;
div {
width: 120px;
cursor: pointer;
}
}
button {
width: 100%;
height: 48px;
background: #ff6200;
font-size: 16px;
color: #fff;
border-radius: 8px;
border: none;
font-weight: 900;
}
.fm-text {
padding-left: 20px;
height: 48px;
border-radius: 8px;
opacity: 1;
border: none;
background: #f3f6f8;
font-size: 16px;
font-weight: 500;
line-height: 18px;
letter-spacing: 0;
margin-bottom: 50px;
}
}
.active {
color: #ff5500;
font-weight: 900;
}
</style>