feat: 数据库迁移
This commit is contained in:
16
Yi.App.Vue3/src/App.vue
Normal file
16
Yi.App.Vue3/src/App.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
<template>
|
||||
|
||||
<!-- <HelloWorld msg="123"></HelloWorld> -->
|
||||
<router-view></router-view>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
11
Yi.App.Vue3/src/api/agreeApi.ts
Normal file
11
Yi.App.Vue3/src/api/agreeApi.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
operate(data:any) {
|
||||
return myaxios({
|
||||
url: `/agree/operate`,
|
||||
method: 'get',
|
||||
params: {articleId:data}
|
||||
})
|
||||
},
|
||||
}
|
||||
19
Yi.App.Vue3/src/api/articleApi.ts
Normal file
19
Yi.App.Vue3/src/api/articleApi.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
import { ArticleEntity } from '@/type/interface/ArticleEntity'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/article/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data:any) {
|
||||
return myaxios({
|
||||
url: '/article/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
}
|
||||
17
Yi.App.Vue3/src/api/commentApi.ts
Normal file
17
Yi.App.Vue3/src/api/commentApi.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/comment/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
getListByArticleId(articleId:any) {
|
||||
return myaxios({
|
||||
url: `/comment/GetListByArticleId/${articleId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
}
|
||||
12
Yi.App.Vue3/src/api/fileApi.ts
Normal file
12
Yi.App.Vue3/src/api/fileApi.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default{
|
||||
upload(type:string,data:any){
|
||||
return myaxios({
|
||||
url: `/file/upload/${type}`,
|
||||
headers:{"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"},
|
||||
method: 'POST',
|
||||
data:data
|
||||
});
|
||||
}
|
||||
}
|
||||
59
Yi.App.Vue3/src/api/login.ts
Normal file
59
Yi.App.Vue3/src/api/login.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
// 登录方法
|
||||
export function login(username:string, password:string, code:string, uuid:string) {
|
||||
const data = {
|
||||
username,
|
||||
password,
|
||||
code,
|
||||
uuid
|
||||
}
|
||||
return myaxios({
|
||||
url: '/account/login',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 注册方法
|
||||
export function register(data:any) {
|
||||
return myaxios({
|
||||
url: '/register',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return myaxios({
|
||||
url: '/account/getUserAllInfo',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 退出方法
|
||||
export function logout() {
|
||||
return myaxios({
|
||||
url: '/account/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() {
|
||||
return myaxios({
|
||||
url: '/account/captchaImage',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'get',
|
||||
timeout: 20000
|
||||
})
|
||||
}
|
||||
18
Yi.App.Vue3/src/api/skuApi.ts
Normal file
18
Yi.App.Vue3/src/api/skuApi.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/sku/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data:any) {
|
||||
return myaxios({
|
||||
url: '/sku/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
}
|
||||
25
Yi.App.Vue3/src/api/spuApi.ts
Normal file
25
Yi.App.Vue3/src/api/spuApi.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data: any) {
|
||||
return myaxios({
|
||||
url: `/spu/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data: any) {
|
||||
return myaxios({
|
||||
url: '/spu/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
getById(id: any) {
|
||||
return myaxios({
|
||||
url: `/spu/GetById/${id}`,
|
||||
method: 'get',
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
1
Yi.App.Vue3/src/assets/vue.svg
Normal file
1
Yi.App.Vue3/src/assets/vue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
61
Yi.App.Vue3/src/components/AppCard.vue
Normal file
61
Yi.App.Vue3/src/components/AppCard.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
|
||||
<div class="out-div">
|
||||
<div class="card-div">
|
||||
|
||||
<van-image
|
||||
radius="1rem"
|
||||
width="100%"
|
||||
height="100%"
|
||||
src="https://unpkg.com/@vant/assets/cat.jpeg"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="bottom-div">
|
||||
<div v-for="i of 10" :key="i" class="card-div-inside">
|
||||
<van-image
|
||||
radius="1rem"
|
||||
width="4rem"
|
||||
height="4rem"
|
||||
src="https://unpkg.com/@vant/assets/cat.jpeg"
|
||||
/>
|
||||
<br>
|
||||
¥79.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.out-div {
|
||||
width: 100%;
|
||||
min-height: 10rem;
|
||||
border-radius: 1rem;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.card-div {
|
||||
height: 6rem;
|
||||
width: 100%;
|
||||
}
|
||||
.bottom-div {
|
||||
display: flex;
|
||||
|
||||
/* justify-content: center; */
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-div-inside {
|
||||
flex: none;
|
||||
display: block;
|
||||
margin-top: 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
37
Yi.App.Vue3/src/components/AppCreateTime.vue
Normal file
37
Yi.App.Vue3/src/components/AppCreateTime.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<span class="subtitle">{{ showTime }}</span>
|
||||
</template>
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
|
||||
const props = defineProps<{ time: string }>();
|
||||
const showTime = computed(() => {
|
||||
var dataTime=new Date(Date.parse(props.time));
|
||||
const hour:number= getHour(dataTime,new Date())
|
||||
if(hour<=0)
|
||||
{
|
||||
return "刚刚"
|
||||
}
|
||||
if(hour<=6)
|
||||
{
|
||||
return hour+"小时前"
|
||||
}
|
||||
return props.time;
|
||||
|
||||
});
|
||||
const getHour=(s1:Date, s2:Date)=> {
|
||||
var ms = s2.getTime() - s1.getTime();
|
||||
if (ms < 0) return 0;
|
||||
return Math.floor(ms / 1000 / 60 / 60); //小时
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.subtitle{
|
||||
color: #CBCBCB;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
34
Yi.App.Vue3/src/components/AppGrid.vue
Normal file
34
Yi.App.Vue3/src/components/AppGrid.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<van-row>
|
||||
<van-col span="24">
|
||||
<p > {{data.head}}</p>
|
||||
</van-col>
|
||||
<van-col class="col-body" span="6" v-for="item in data.body"><van-icon :name="item.icon" size="2rem" /> <br>{{item.title}}</van-col>
|
||||
</van-row>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import {AppGridData} from '@/type/class/AppGridData'
|
||||
defineProps<{ data: AppGridData }>()
|
||||
const count = ref(0)
|
||||
</script>
|
||||
<style scoped>
|
||||
.col-body
|
||||
{
|
||||
text-align: center;
|
||||
font-size: small;
|
||||
}
|
||||
.col-body .van-icon
|
||||
{
|
||||
|
||||
color: #FF689B;
|
||||
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
p{
|
||||
font-size: large;
|
||||
font-weight:bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
35
Yi.App.Vue3/src/components/AppUserIcon.vue
Normal file
35
Yi.App.Vue3/src/components/AppUserIcon.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<van-image
|
||||
round
|
||||
:width="width"
|
||||
:height="height"
|
||||
:src="url+(src??'0')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type } from 'os';
|
||||
import { ref } from 'vue'
|
||||
const props= defineProps({
|
||||
src: {type:String,default:'null',required:false},
|
||||
width:{type:String,default:'3rem',required:false},
|
||||
height:{type:String,default:'3rem',required:false}
|
||||
})
|
||||
|
||||
const url = `${import.meta.env.VITE_APP_BASE_API}/file/`;
|
||||
</script>
|
||||
<style scoped>
|
||||
.col-body
|
||||
{
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.col-body .van-icon
|
||||
{
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
p{
|
||||
font-size: large;
|
||||
font-weight:bold;
|
||||
}
|
||||
</style>
|
||||
19
Yi.App.Vue3/src/components/HelloWorld.vue
Normal file
19
Yi.App.Vue3/src/components/HelloWorld.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps<{ msg: string }>()
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
76
Yi.App.Vue3/src/layout/bottom/index.vue
Normal file
76
Yi.App.Vue3/src/layout/bottom/index.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<van-tabbar v-model="active" active-color="#FF689B" inactive-color="#9C9C9C" @change="onChange" z-index="100">
|
||||
<van-tabbar-item v-for="item in tabbar.slice(0,2)" :to="item.to" :icon="item.icon">{{item.title}}</van-tabbar-item>
|
||||
<van-tabbar-item @click="show = true">
|
||||
<template #icon="props">
|
||||
<van-icon class="add" name="add-square" color="#FF689B" size="3rem" />
|
||||
<!-- <img :src="props.active ? icon.active : icon.inactive" /> -->
|
||||
</template>
|
||||
</van-tabbar-item>
|
||||
|
||||
<van-tabbar-item v-for="item in tabbar.slice(3)" :to="item.to" :icon="item.icon">{{item.title}}</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
|
||||
<van-action-sheet v-model:show="show" >
|
||||
|
||||
|
||||
<router-link to="/imageText"> <van-button class="btn1 btn " style="background-color: #5FBC76;" >发图文</van-button></router-link>
|
||||
<van-button class="btn" style="background-color: #FF689B;">(暂未开放)发视频</van-button>
|
||||
<van-button class="btn" style="background-color: #F7A63A;">(暂未开放)发文章</van-button>
|
||||
<van-button class="btn" style="background-color: #6AB5EE;">(暂未开放)发二手</van-button>
|
||||
|
||||
|
||||
|
||||
<van-icon class="icon" name="cross" size="1.5rem" @click="show=false"/>
|
||||
|
||||
|
||||
</van-action-sheet>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
const active = ref(0);
|
||||
const show = ref(false);
|
||||
|
||||
let tabbar=ref([
|
||||
{icon:"wap-home",to:"/",title:"主页"},
|
||||
{icon:"location-o",to:"",title:"发现"},
|
||||
{icon:"",to:"",title:""},
|
||||
{icon:"friends-o",to:"/shopIndex",title:"商城"},
|
||||
// {icon:"friends-o",to:"",title:"商城"},
|
||||
{icon:"setting-o",to:"/my",title:"我的"},
|
||||
])
|
||||
const onChange=(index:number)=>{
|
||||
tabbar.value=[
|
||||
{icon:"wap-home-o",to:"/",title:"主页"},
|
||||
{icon:"location-o",to:"",title:"发现"},
|
||||
{icon:"",to:"",title:""},
|
||||
{icon:"friends-o",to:"/shopIndex",title:"商城"},
|
||||
// {icon:"friends-o",to:"",title:"商城"},
|
||||
{icon:"setting-o",to:"/my",title:"我的"},
|
||||
];
|
||||
tabbar.value[index].icon=tabbar.value[index].icon.replace("-o","")
|
||||
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.btn1
|
||||
{
|
||||
margin-top: 3rem !important;
|
||||
}
|
||||
.btn{
|
||||
border-radius:0.5rem;
|
||||
height: 4rem;
|
||||
width:90%;
|
||||
margin: 0.5rem 1rem 0.5rem 1rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.content {
|
||||
padding: 16px 16px 160px;
|
||||
}
|
||||
.icon{
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.add{
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
</style>
|
||||
9
Yi.App.Vue3/src/layout/head/index.vue
Normal file
9
Yi.App.Vue3/src/layout/head/index.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<van-nav-bar
|
||||
title="标题"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
/>
|
||||
<br>
|
||||
<router-view />
|
||||
</template>
|
||||
13
Yi.App.Vue3/src/layout/index.vue
Normal file
13
Yi.App.Vue3/src/layout/index.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import AppBottom from './bottom/index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
|
||||
<app-bottom/>
|
||||
|
||||
</template>
|
||||
|
||||
12
Yi.App.Vue3/src/layout/main/index.vue
Normal file
12
Yi.App.Vue3/src/layout/main/index.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<app-tab />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import AppTab from '@/layout/tab/index.vue'
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
45
Yi.App.Vue3/src/layout/tab/index.vue
Normal file
45
Yi.App.Vue3/src/layout/tab/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template >
|
||||
<van-sticky :offset-top="0">
|
||||
<van-row class="row" >
|
||||
<van-col span="4" class="icon"><van-icon name="sign" size="1.6rem"/></van-col>
|
||||
<van-col span="16">
|
||||
<van-tabs v-model:active="active" class="tabs" sticky swipeable color="#FF689B">
|
||||
<van-tab v-for="item in tabs" :title="item.title" :to="item.to" class="tab" :style="{fontSize: 0 + 'px'}" ></van-tab>
|
||||
</van-tabs>
|
||||
</van-col>
|
||||
<van-col span="4" class="icon"><van-icon name="search" size="1.6rem" /></van-col>
|
||||
</van-row>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<router-view />
|
||||
<div style=""></div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
const active = ref(1);
|
||||
const tabs=ref([
|
||||
{title:"关注",to:"/follow"},
|
||||
{title:"推荐",to:"/recommend"},
|
||||
{title:"广场",to:"/square"},
|
||||
])
|
||||
</script>
|
||||
<style scoped>
|
||||
.row{
|
||||
background-color: #FFFFFF;
|
||||
min-width: 24rem;
|
||||
}
|
||||
.tab{
|
||||
|
||||
}
|
||||
.icon{
|
||||
padding-top: 0.6rem;
|
||||
}
|
||||
.tabs {
|
||||
width: 100%;
|
||||
}
|
||||
.icon .van-icon
|
||||
{
|
||||
color:#FF689B;
|
||||
}
|
||||
</style>
|
||||
17
Yi.App.Vue3/src/main.ts
Normal file
17
Yi.App.Vue3/src/main.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import 'vant/es/image-preview/style';
|
||||
import 'vant/es/toast/style';
|
||||
import 'vant/es/dialog/style';
|
||||
import 'vant/es/notify/style';
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import './permission'
|
||||
import { Lazyload } from 'vant';
|
||||
import App from './App.vue'
|
||||
|
||||
const app=createApp(App)
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.use(Lazyload);
|
||||
app.mount('#app');
|
||||
52
Yi.App.Vue3/src/permission.ts
Normal file
52
Yi.App.Vue3/src/permission.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import router from './router'
|
||||
// import { ElMessage } from 'element-plus'
|
||||
// import NProgress from 'nprogress'
|
||||
// import 'nprogress/nprogress.css'
|
||||
import { getToken } from '@/utils/auth'
|
||||
// import { isHttp } from '@/utils/validate'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { isRelogin } from '@/utils/myaxios'
|
||||
// import useSettingsStore from '@/store/modules/settings'
|
||||
// import usePermissionStore from '@/store/modules/permission'
|
||||
|
||||
// NProgress.configure({ showSpinner: false });
|
||||
|
||||
const whiteList = ['/login', '/auth-redirect', '/bind', '/register'];
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
// NProgress.start()
|
||||
if (getToken()) {
|
||||
// to.meta.title && useSettingsStore().setTitle(to.meta.title)
|
||||
/* has token*/
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
// NProgress.done()
|
||||
} else {
|
||||
if (useUserStore().roles.length === 0) {
|
||||
isRelogin.show = true
|
||||
useUserStore().getInfo().then((response: any) => {
|
||||
next()
|
||||
});
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
next()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// 没有token
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
// 在免登录白名单,直接进入
|
||||
next()
|
||||
} else {
|
||||
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
// NProgress.done()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
router.afterEach(() => {
|
||||
// NProgress.done()
|
||||
})
|
||||
92
Yi.App.Vue3/src/router/index.ts
Normal file
92
Yi.App.Vue3/src/router/index.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { createWebHistory, createRouter } from 'vue-router';
|
||||
import Layout from '@/layout/index.vue';
|
||||
import HeadLayout from '@/layout/head/index.vue'
|
||||
|
||||
export const constantRoutes = [
|
||||
|
||||
{
|
||||
name:'Layout',
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect:"/recommend",
|
||||
children: [
|
||||
{
|
||||
path: '/shopIndex',
|
||||
component: () => import('@/view/shop/shopIndex.vue'),
|
||||
name: 'ShopIndex',
|
||||
},
|
||||
{
|
||||
path: '/my',
|
||||
component: () => import('@/view/my.vue'),
|
||||
name: 'My',
|
||||
},
|
||||
{
|
||||
path: '/main',
|
||||
component: () => import('@/layout/main/index.vue'),
|
||||
name: 'Main',
|
||||
children:[
|
||||
{
|
||||
path: '/recommend',
|
||||
component: () => import('@/view/main/recommend.vue'),
|
||||
name: 'Recommend',
|
||||
},
|
||||
{
|
||||
path: '/follow',
|
||||
component: () => import('@/view/main/follow.vue'),
|
||||
name: 'Follow',
|
||||
},
|
||||
{
|
||||
path: '/square',
|
||||
component: () => import('@/view/main/square.vue'),
|
||||
name: 'Square',
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/imageText',
|
||||
component: () => import('@/view/send/imageText.vue'),
|
||||
name: 'ImageText',
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/view/login.vue'),
|
||||
name: 'Login',
|
||||
},
|
||||
|
||||
{
|
||||
name:'Shop',
|
||||
path: '/shop',
|
||||
component: HeadLayout,
|
||||
redirect:"/shopIndex",
|
||||
children: [
|
||||
{
|
||||
path: '/shopDetails',
|
||||
component: () => import('@/view/shop/shopDetails.vue'),
|
||||
name: 'ShopDetails',
|
||||
},
|
||||
{
|
||||
path: '/shopSearch',
|
||||
component: () => import('@/view/shop/shopSearch.vue'),
|
||||
name: 'ShopSearch',
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: constantRoutes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
} else {
|
||||
return { top: 0 }
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
4
Yi.App.Vue3/src/store/index.ts
Normal file
4
Yi.App.Vue3/src/store/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { createPinia } from 'pinia'
|
||||
const store = createPinia()
|
||||
|
||||
export default store
|
||||
85
Yi.App.Vue3/src/store/modules/user.ts
Normal file
85
Yi.App.Vue3/src/store/modules/user.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { login, logout, getInfo } from '@/api/login'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
// import defAva from '@/assets/images/profile.jpg'
|
||||
import {defineStore} from 'pinia'
|
||||
const useUserStore = defineStore(
|
||||
'user',
|
||||
{
|
||||
state: () => ({
|
||||
token: getToken(),
|
||||
user:{username:"",nick:"",icon:""},
|
||||
roles: [],
|
||||
permissions: []
|
||||
}),
|
||||
actions: {
|
||||
// 登录
|
||||
login(userInfo:any ) {
|
||||
const username = userInfo.username.trim()
|
||||
const password = userInfo.password
|
||||
const code = userInfo.code
|
||||
const uuid = userInfo.uuid
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
login(username, password, code, uuid).then(res => {
|
||||
if(!res.status)
|
||||
{
|
||||
reject(res)
|
||||
}
|
||||
setToken(res.data.token);
|
||||
this.token = res.data.token;
|
||||
resolve(res);
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
// 获取用户信息
|
||||
getInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo().then(response => {
|
||||
const res=response.data;
|
||||
const user = res.user
|
||||
// const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||
|
||||
if (res.roleCodes && res.roleCodes.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||
this.roles = res.roleCodes
|
||||
this.permissions = res.permissionCodes
|
||||
// this.roles = ["admin"];
|
||||
// this.permissions=["*:*:*"]
|
||||
|
||||
} else {
|
||||
this.roles = ["ROLE_DEFAULT"] as never[]
|
||||
}
|
||||
// this.roles = ["admin"];
|
||||
// this.permissions=["*:*:*"]
|
||||
this.user.username = user.userName;
|
||||
this.user.nick=user.nick
|
||||
this.user.icon = user.icon;
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
// 退出系统
|
||||
logOut() {
|
||||
return new Promise((resolve, reject) => {
|
||||
//this.token
|
||||
logout().then((response) => {
|
||||
this.token = ''
|
||||
this.roles = []
|
||||
this.permissions = []
|
||||
removeToken()
|
||||
resolve(response)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default useUserStore
|
||||
87
Yi.App.Vue3/src/style.css
Normal file
87
Yi.App.Vue3/src/style.css
Normal file
@@ -0,0 +1,87 @@
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0rem;
|
||||
text-align: center;
|
||||
}
|
||||
/* :root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
} */
|
||||
11
Yi.App.Vue3/src/type/class/AppGridData.ts
Normal file
11
Yi.App.Vue3/src/type/class/AppGridData.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export class AppGridData{
|
||||
head!: string;
|
||||
body!: AppGridBody[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
class AppGridBody{
|
||||
icon!: string;
|
||||
title!: string;
|
||||
}
|
||||
8
Yi.App.Vue3/src/type/interface/ArticleEntity.ts
Normal file
8
Yi.App.Vue3/src/type/interface/ArticleEntity.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface ArticleEntity{
|
||||
title: string;
|
||||
content: string;
|
||||
images:string[];
|
||||
isDeleted:boolean;
|
||||
createTime:string;
|
||||
}
|
||||
// import { ArticleEntity } from '@/type/interface/ArticleEntity'
|
||||
13
Yi.App.Vue3/src/utils/auth.ts
Normal file
13
Yi.App.Vue3/src/utils/auth.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
const TokenKey = 'Admin-Token'
|
||||
|
||||
export function getToken() {
|
||||
return localStorage.getItem(TokenKey)
|
||||
}
|
||||
|
||||
export function setToken(token:string) {
|
||||
return localStorage.setItem(TokenKey, token)
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return localStorage.removeItem(TokenKey)
|
||||
}
|
||||
81
Yi.App.Vue3/src/utils/myaxios.ts
Normal file
81
Yi.App.Vue3/src/utils/myaxios.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
import axios from 'axios'
|
||||
// import store from '../store/index'
|
||||
// import vm from '../main'
|
||||
import JsonBig from 'json-bigint'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { useRouter } from "vue-router";
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { Notify } from 'vant';
|
||||
// import VuetifyDialogPlugin from 'vuetify-dialog/nuxt/index';
|
||||
export let isRelogin = { show: false };
|
||||
const myaxios = axios.create({
|
||||
// baseURL:'/'//
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API, // /dev-apis
|
||||
timeout: 50000,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + ""
|
||||
},
|
||||
//雪花id精度问题
|
||||
transformResponse: [ data => {
|
||||
const json = JsonBig({
|
||||
storeAsString: true
|
||||
})
|
||||
return json.parse(data)
|
||||
}],
|
||||
})
|
||||
// 请求拦截器
|
||||
myaxios.interceptors.request.use(function(config:any) {
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||
if (getToken() && !isToken) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// store.dispatch("openLoad");
|
||||
return config;
|
||||
}, function(error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// 响应拦截器
|
||||
myaxios.interceptors.response.use(async function(response) {
|
||||
//成功
|
||||
const resp = response.data
|
||||
if(resp.code==401)
|
||||
{
|
||||
Notify({ type: 'warning', message: '登录过期' });
|
||||
//登出
|
||||
useUserStore().logOut().then(() => {
|
||||
location.href = '/';
|
||||
})
|
||||
isRelogin.show = false;
|
||||
}
|
||||
// store.dispatch("closeLoad");
|
||||
return resp;
|
||||
}, async function(error) {
|
||||
//未授权、失败
|
||||
if(error.response==undefined)
|
||||
{
|
||||
Notify({ type: 'danger', message: `服务器异常:${error.message}` });
|
||||
return Promise.reject(error);;
|
||||
}
|
||||
|
||||
const resp = error.response.data
|
||||
if (resp.code == undefined && resp.message == undefined) {
|
||||
Notify({ type: 'danger', message: '未知错误' });
|
||||
} else if (resp.code == 401) {
|
||||
// if (!isRelogin.show) {
|
||||
Notify({ type: 'warning', message: '登录过期' });
|
||||
//登出
|
||||
useUserStore().logOut().then(() => {
|
||||
location.href = '/';
|
||||
})
|
||||
isRelogin.show = false;
|
||||
// }
|
||||
} else if (resp.code !== 200) {
|
||||
Notify({ type: 'danger', message: `错误代码:${resp.code},原因:${resp.message}` });
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
export default myaxios
|
||||
138
Yi.App.Vue3/src/view/login.vue
Normal file
138
Yi.App.Vue3/src/view/login.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="div-top">
|
||||
<span class="title">意框架</span>
|
||||
<br />
|
||||
<span class="subtitle">有幸相遇、不负未来</span>
|
||||
</div>
|
||||
<div class="div-bottom">
|
||||
<h5>密码登录</h5>
|
||||
<van-field
|
||||
class="van-field-username"
|
||||
v-model="loginForm.username"
|
||||
label="用户"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
<van-field
|
||||
class="van-field-password"
|
||||
v-model="loginForm.password"
|
||||
label="密码"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
/>
|
||||
<van-button type="primary" @click="login">进入意框架</van-button>
|
||||
<p>其他方式登录<van-icon name="arrow" /></p>
|
||||
|
||||
<van-row class="row-bottom" style="margin-top: 6rem">
|
||||
<van-col span="24"><p>第三方登录</p></van-col>
|
||||
<van-col span="2"></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="2"></van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import { Toast } from "vant";
|
||||
|
||||
const router = useRouter();
|
||||
const redirect = ref(undefined);
|
||||
const loginForm = ref({
|
||||
username: "",
|
||||
password: "",
|
||||
rememberMe: false,
|
||||
code: "",
|
||||
uuid: "",
|
||||
});
|
||||
const userStore = useUserStore();
|
||||
const login = () => {
|
||||
// 调用action的登录方法
|
||||
userStore
|
||||
.login(loginForm.value)
|
||||
.then((response: any) => {
|
||||
Toast({
|
||||
message: response.message,
|
||||
position: "bottom",
|
||||
});
|
||||
router.push({ path: redirect.value || "/" });
|
||||
})
|
||||
.catch((response:any) => {
|
||||
loginForm.value.password="";
|
||||
Toast({
|
||||
message: response.message,
|
||||
position: "bottom",
|
||||
});
|
||||
// loading.value = false;
|
||||
// // 重新获取验证码
|
||||
// if (captchaEnabled.value) {
|
||||
// getCode();
|
||||
// }
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background-color: #FF689B;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 60%;
|
||||
}
|
||||
.div-bottom {
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 3rem 3rem 0rem 0rem;
|
||||
padding: 1rem 2rem 2rem 2rem;
|
||||
|
||||
/* min-height: 70%; */
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 1.8rem;
|
||||
font-weight: bolder;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.subtitle {
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
font-weight: lighter;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.van-field-username {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
.van-field-password {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
h5 {
|
||||
text-align: left;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bolder;
|
||||
}
|
||||
.div-bottom .van-button {
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
border-radius: 0.4rem;
|
||||
background-color: #FF689B;
|
||||
border: 0;
|
||||
}
|
||||
.div-bottom p {
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
}
|
||||
.row-bottom {
|
||||
color: #FF689B;
|
||||
}
|
||||
</style>
|
||||
16
Yi.App.Vue3/src/view/main/follow.vue
Normal file
16
Yi.App.Vue3/src/view/main/follow.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template >
|
||||
<van-row >
|
||||
<van-col span="24">
|
||||
<div class="test">这里是关注页面</div>
|
||||
</van-col>
|
||||
|
||||
</van-row>
|
||||
|
||||
|
||||
</template>
|
||||
<style scoped>
|
||||
.test
|
||||
{
|
||||
|
||||
}
|
||||
</style>
|
||||
299
Yi.App.Vue3/src/view/main/recommend.vue
Normal file
299
Yi.App.Vue3/src/view/main/recommend.vue
Normal file
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list
|
||||
class="list"
|
||||
v-model:loading="loading"
|
||||
:finished="finished"
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad"
|
||||
>
|
||||
<van-row v-for="(item, index) in articleList" :key="index" class="row">
|
||||
<van-col span="4" class="leftCol">
|
||||
<AppUserIcon
|
||||
width="3rem"
|
||||
height="3rem"
|
||||
:src="item.user == null ? null : item.user.icon"
|
||||
/>
|
||||
</van-col>
|
||||
|
||||
<van-col span="14" class="centerTitle">
|
||||
<span class="justtitle">{{
|
||||
item.user == null ? "-" : item.user.nick ?? item.user.username
|
||||
}}</span>
|
||||
<br />
|
||||
<app-createTime :time="item.createTime" />
|
||||
</van-col>
|
||||
|
||||
<van-col span="6" class="down">
|
||||
<van-icon name="arrow-down" @click="show = true" />
|
||||
</van-col>
|
||||
|
||||
<van-col class="rowBody" span="24">{{ item.content }}</van-col>
|
||||
|
||||
<van-col
|
||||
span="8"
|
||||
v-for="(image, imageIndex) in item.images"
|
||||
:key="imageIndex"
|
||||
class="imageCol"
|
||||
@click="openImage(item.images, imageIndex)"
|
||||
>
|
||||
<van-image
|
||||
lazy-load
|
||||
fit="cover"
|
||||
width="100%"
|
||||
height="7rem"
|
||||
:src="url + image + '/true'"
|
||||
radius="5"
|
||||
/>
|
||||
<template v-slot:loading>
|
||||
<van-loading type="spinner" size="20" />
|
||||
</template>
|
||||
</van-col>
|
||||
|
||||
<van-col span="24" class="bottomRow">
|
||||
<van-grid direction="horizontal" :column-num="3">
|
||||
<van-grid-item icon="share-o" text="分享" />
|
||||
<van-grid-item
|
||||
icon="comment-o"
|
||||
text="评论"
|
||||
@click="openComment(item.id)"
|
||||
/>
|
||||
<van-grid-item
|
||||
icon="good-job-o"
|
||||
:text="`点赞:${item.agreeNum}`"
|
||||
@click="aggreeHand(item.id)"
|
||||
/>
|
||||
</van-grid>
|
||||
</van-col>
|
||||
</van-row>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
<!-- 功能页面 -->
|
||||
<van-action-sheet
|
||||
v-model:show="show"
|
||||
:actions="actions"
|
||||
cancel-text="取消"
|
||||
close-on-click-action
|
||||
/>
|
||||
|
||||
<!-- 图片预览 -->
|
||||
<van-image-preview
|
||||
v-model:show="imageShow"
|
||||
:images="imagesPreview"
|
||||
:startPosition="startIndex"
|
||||
@change="onChange"
|
||||
:closeable="true"
|
||||
>
|
||||
<template v-slot:index>第{{ index + 1 }}页</template>
|
||||
</van-image-preview>
|
||||
|
||||
<!-- 评论面板 -->
|
||||
<van-action-sheet v-model:show="commentShow" title="共10条评论">
|
||||
<van-row v-for="i in commentList" :key="i" class="commentContent">
|
||||
<van-col span="4">头像</van-col>
|
||||
<van-col span="16">{{ i.content }}</van-col>
|
||||
<van-col span="4">点赞</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-cell-group inset>
|
||||
<van-field v-model="commentData.content" placeholder="请输入评论" >
|
||||
<template #button>
|
||||
<van-button size="small" type="primary" @click="sendComment()">发布</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</van-action-sheet>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, toRefs } from "vue";
|
||||
import { ImagePreview, Toast } from "vant";
|
||||
import AppCreateTime from "@/components/AppCreateTime.vue";
|
||||
import AppUserIcon from "@/components/AppUserIcon.vue";
|
||||
import articleApi from "@/api/articleApi";
|
||||
import agreeApi from "@/api/agreeApi";
|
||||
import commentApi from "@/api/commentApi";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity";
|
||||
const VanImagePreview = ImagePreview.Component;
|
||||
const url = `${import.meta.env.VITE_APP_BASE_API}/file/`;
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// dictName: undefined,
|
||||
// dictType: undefined,
|
||||
isDeleted: false,
|
||||
},
|
||||
});
|
||||
|
||||
const commentData = reactive({
|
||||
content: "",
|
||||
articleId:0
|
||||
});
|
||||
const sendComment=()=>{
|
||||
commentData.articleId=openCommentId.value;
|
||||
commentApi.add(commentData).then(()=>{
|
||||
getCommentList(openCommentId.value);
|
||||
commentData.content="";
|
||||
})
|
||||
}
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
const {content}=toRefs(commentData);
|
||||
const articleList = ref<any[]>([]);
|
||||
const commentList = ref<any[]>([]);
|
||||
const totol = ref<Number>(0);
|
||||
const imageShow = ref(false);
|
||||
const commentShow = ref<any>(false);
|
||||
const index = ref(0);
|
||||
let imagesPreview = ref<string[]>([]);
|
||||
const openCommentId=ref(0);
|
||||
const openComment = (id: any) => {
|
||||
commentShow.value = true;
|
||||
openCommentId.value=id;
|
||||
getCommentList(id);
|
||||
};
|
||||
|
||||
const onChange = (newIndex: any) => {
|
||||
index.value = newIndex;
|
||||
};
|
||||
|
||||
const list = ref<Number[]>([]);
|
||||
const loading = ref(false);
|
||||
const finished = ref(false);
|
||||
const refreshing = ref(false);
|
||||
const startIndex = ref(0);
|
||||
const show = ref(false);
|
||||
const actions = [{ name: "取消关注" }, { name: "将TA拉黑" }, { name: "举报" }];
|
||||
|
||||
const onLoad = async () => {
|
||||
if (refreshing.value) {
|
||||
articleList.value = [];
|
||||
refreshing.value = false;
|
||||
}
|
||||
// 异步更新数据
|
||||
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
|
||||
articleApi.pageList(queryParams.value).then((response: any) => {
|
||||
if (response.data.data.length == 0) {
|
||||
console.log("结束");
|
||||
finished.value = true;
|
||||
} else {
|
||||
console.log("执行");
|
||||
articleList.value.push(...response.data.data);
|
||||
totol.value = response.data.totol;
|
||||
queryParams.value.pageNum += 1;
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
|
||||
console.log(loading.value);
|
||||
});
|
||||
};
|
||||
const onRefresh = () => {
|
||||
finished.value = false;
|
||||
|
||||
// 重新加载数据
|
||||
// 将 loading 设置为 true,表示处于加载状态
|
||||
loading.value = true;
|
||||
queryParams.value.pageNum = 1;
|
||||
onLoad();
|
||||
};
|
||||
const openImage = (imagesUrl: string[], imageIndex: any) => {
|
||||
imagesPreview.value = imagesUrl.map((i) => url + i);
|
||||
startIndex.value = imageIndex;
|
||||
imageShow.value = true;
|
||||
};
|
||||
onMounted(() => {
|
||||
articleList.value = [];
|
||||
// getList();
|
||||
});
|
||||
|
||||
const getCommentList = (id: any) => {
|
||||
commentApi.getListByArticleId(id).then((response: any) => {
|
||||
commentList.value = response.data;
|
||||
});
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
articleApi.pageList(queryParams.value).then((response: any) => {
|
||||
articleList.value.push(...response.data.data);
|
||||
totol.value = response.data.totol;
|
||||
});
|
||||
};
|
||||
const aggreeHand = (articleId: any) => {
|
||||
agreeApi.operate(articleId).then((response: any) => {
|
||||
//更改显示的值
|
||||
if (response.status) {
|
||||
articleList.value.filter((p) => p.id == articleId)[0].agreeNum += 1;
|
||||
} else {
|
||||
articleList.value.filter((p) => p.id == articleId)[0].agreeNum -= 1;
|
||||
}
|
||||
Toast({
|
||||
message: response.message,
|
||||
position: "bottom",
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.list {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.row {
|
||||
background-color: white;
|
||||
padding-top: 1rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.rowBody {
|
||||
text-align: left;
|
||||
background-color: white;
|
||||
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding-top: 1rem;
|
||||
|
||||
min-height: 3rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leftCol {
|
||||
align-content: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.centerTitle {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.imageCol {
|
||||
padding: 0.1rem 0.1rem 0.1rem 0.1rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #cbcbcb;
|
||||
}
|
||||
|
||||
.justtitle {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.bottomRow {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.down {
|
||||
text-align: right;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.commentContent {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
</style>
|
||||
1
Yi.App.Vue3/src/view/main/square.vue
Normal file
1
Yi.App.Vue3/src/view/main/square.vue
Normal file
@@ -0,0 +1 @@
|
||||
<template>这里是广场</template>
|
||||
256
Yi.App.Vue3/src/view/my.vue
Normal file
256
Yi.App.Vue3/src/view/my.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<van-row class="headRow">
|
||||
<van-col span="2"><van-icon name="scan" size="1.5rem" /></van-col>
|
||||
<van-col span="20"></van-col>
|
||||
<van-col span="2"
|
||||
><van-icon name="setting-o" size="1.5rem" @click="show = true"
|
||||
/></van-col>
|
||||
</van-row>
|
||||
|
||||
<van-row class="bodyRow">
|
||||
<van-col span="6" class="leftCol">
|
||||
<AppUserIcon width="4rem" height="4rem" :src="user.icon"></AppUserIcon>
|
||||
</van-col>
|
||||
<van-col span="12" class="title"><span>{{user.nick}}</span></van-col>
|
||||
<van-col span="6" class="subtitle"
|
||||
><span>个人主页<van-icon name="arrow" /></span
|
||||
></van-col>
|
||||
|
||||
<van-col span="6" class="bodyCol"
|
||||
><div><span>6</span><br />关注</div></van-col
|
||||
>
|
||||
<van-col span="6" class="bodyCol"
|
||||
><div><span>3</span><br />粉丝</div></van-col
|
||||
>
|
||||
<van-col span="6" class="bodyCol"
|
||||
><div><span>0</span><br />人气</div></van-col
|
||||
>
|
||||
<van-col span="6" class="bodyCol"
|
||||
><div><span>3</span><br />钱钱</div></van-col
|
||||
>
|
||||
|
||||
<van-col span="24">
|
||||
<van-row class="btnRow">
|
||||
<van-col span="12">
|
||||
<van-button class="btn">
|
||||
<van-icon name="bag" size="1.8rem" /> <span>我的购物</span><van-icon
|
||||
name="arrow"
|
||||
size="1.2rem" /></van-button
|
||||
></van-col>
|
||||
|
||||
<van-col span="12">
|
||||
<van-button class="btn"
|
||||
><van-icon name="send-gift" size="1.8rem" /> <span>我的签到</span><van-icon
|
||||
name="arrow"
|
||||
size="1.2rem" /></van-button
|
||||
></van-col>
|
||||
</van-row>
|
||||
</van-col>
|
||||
|
||||
<AppGrid class="grid" :data="data1"></AppGrid>
|
||||
<AppGrid class="grid" :data="data2"></AppGrid>
|
||||
<AppGrid class="grid" :data="data3"></AppGrid>
|
||||
</van-row>
|
||||
|
||||
<van-popup
|
||||
v-model:show="show"
|
||||
position="right"
|
||||
:style="{ height: '100%', width: '100%', backgroundColor: '#F8F8F8' }"
|
||||
>
|
||||
<van-nav-bar
|
||||
title="设置"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
@click-left="show = false"
|
||||
/>
|
||||
<van-cell-group>
|
||||
<van-cell title="账户与安全" is-link />
|
||||
<van-cell title="黑名单" is-link />
|
||||
<van-cell title="推送设置" is-link />
|
||||
<van-cell title="隐私管理" is-link />
|
||||
<van-cell title="通用设置" is-link />
|
||||
</van-cell-group>
|
||||
<van-cell-group class="group">
|
||||
<van-cell title="家庭入驻" is-link />
|
||||
<van-cell title="社区入驻" is-link />
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group class="group">
|
||||
<van-cell title="清理缓存" is-link />
|
||||
<van-cell title="检测更新" is-link />
|
||||
<van-cell title="关于我们" is-link />
|
||||
<van-cell title="给个好评" is-link />
|
||||
</van-cell-group>
|
||||
|
||||
<van-button type="danger" @click="outLog">退出登录</van-button>
|
||||
</van-popup>
|
||||
<!-- <van-popup v-model:show="show" position="right">
|
||||
<div class="body-div"> 内容</div>
|
||||
</van-popup> -->
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import AppGrid from "@/components/AppGrid.vue";
|
||||
import { AppGridData } from "@/type/class/AppGridData";
|
||||
import { ref } from "vue";
|
||||
import { Dialog } from "vant";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import { storeToRefs } from 'pinia';
|
||||
import AppUserIcon from "@/components/AppUserIcon.vue";
|
||||
const show = ref<boolean>(false);
|
||||
let data1: AppGridData = {
|
||||
head: "个人中心",
|
||||
body: [
|
||||
{
|
||||
title: "我的消息",
|
||||
icon: "comment-o",
|
||||
},
|
||||
{
|
||||
title: "我的聊天",
|
||||
icon: "chat-o",
|
||||
},
|
||||
{
|
||||
title: "我的喜欢",
|
||||
icon: "like-o",
|
||||
},
|
||||
{
|
||||
title: "我的关注",
|
||||
icon: "user-o",
|
||||
},
|
||||
],
|
||||
};
|
||||
let data2: AppGridData = {
|
||||
head: "功能",
|
||||
body: [
|
||||
{
|
||||
title: "排行榜",
|
||||
icon: "medal-o",
|
||||
},
|
||||
{
|
||||
title: "活动报名",
|
||||
icon: "balance-list-o",
|
||||
},
|
||||
{
|
||||
title: "钱钱兑换",
|
||||
icon: "gem-o",
|
||||
},
|
||||
{
|
||||
title: "全网上新",
|
||||
icon: "gift-card-o",
|
||||
},
|
||||
],
|
||||
};
|
||||
let data3: AppGridData = {
|
||||
head: "服务",
|
||||
body: [
|
||||
{
|
||||
title: "客服",
|
||||
icon: "service-o",
|
||||
},
|
||||
{
|
||||
title: "小黑屋",
|
||||
icon: "wap-home-o",
|
||||
},
|
||||
{
|
||||
title: "邀请好友",
|
||||
icon: "friends-o",
|
||||
},
|
||||
],
|
||||
};
|
||||
const userStore=useUserStore();
|
||||
const {user}=storeToRefs(useUserStore());
|
||||
const outLog = () => {
|
||||
Dialog.confirm({
|
||||
title: "提示",
|
||||
message: "确定退出当前用户吗?",
|
||||
})
|
||||
.then(() => {
|
||||
userStore
|
||||
.logOut()
|
||||
.then((response: any) => {
|
||||
location.href = "/";
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.bodyCol
|
||||
{
|
||||
color: #9B9B9B;
|
||||
}
|
||||
.bodyCol span{
|
||||
color: black;
|
||||
font-size:larger;
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn .van-icon{
|
||||
color: #FF689B;
|
||||
}
|
||||
.btn span{
|
||||
font-size:medium;
|
||||
font-weight:600;
|
||||
}
|
||||
.grid {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.headRow {
|
||||
padding: 0.5rem 0.5rem 0.5rem 0.5rem;
|
||||
}
|
||||
.bodyRow {
|
||||
text-align: left;
|
||||
margin-top: 1.5rem;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
line-height: 4rem;
|
||||
}
|
||||
.subtitle {
|
||||
line-height: 4rem;
|
||||
color: #9B9B9B;
|
||||
}
|
||||
.bodyCol {
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #ffffff;
|
||||
border: none;
|
||||
color: black;
|
||||
|
||||
}
|
||||
.btnRow {
|
||||
margin-top: 1.5rem;
|
||||
box-shadow: 0rem 0rem 0.2rem 0.2rem #f3f3f3;
|
||||
}
|
||||
.btnRow .van-button {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.van-icon-send-gift {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.btnRow .van-icon-arrow {
|
||||
margin-left: 0.45rem;
|
||||
}
|
||||
.van-cell {
|
||||
text-align: left;
|
||||
}
|
||||
.group {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.van-popup .van-button {
|
||||
width: 90%;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
</style>
|
||||
185
Yi.App.Vue3/src/view/send/imageText.vue
Normal file
185
Yi.App.Vue3/src/view/send/imageText.vue
Normal file
@@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<transition name="van-slide-right">
|
||||
<div v-show="visible">
|
||||
<van-sticky>
|
||||
<van-row class="head-row">
|
||||
<van-col span="3">
|
||||
<router-link to="/recommend">
|
||||
<van-icon name="arrow-left" size="1.5rem" />
|
||||
</router-link>
|
||||
</van-col>
|
||||
<van-col span="18"><span>发图文</span></van-col>
|
||||
<van-col
|
||||
span="3"
|
||||
@click="send"
|
||||
:style="{ color: isSend ? '#FE70A0' : '#979797' }"
|
||||
>发布</van-col
|
||||
>
|
||||
</van-row>
|
||||
</van-sticky>
|
||||
|
||||
<van-cell-group>
|
||||
<van-field
|
||||
rows="5"
|
||||
autosize
|
||||
type="textarea"
|
||||
v-model="content"
|
||||
label-width="0"
|
||||
:show-word-limit="true"
|
||||
maxlength="500"
|
||||
placeholder="大于5字,每一天,都是为了下一天"
|
||||
/>
|
||||
</van-cell-group>
|
||||
<van-row class="body-row">
|
||||
<van-col span="10">
|
||||
<van-icon name="share-o" size="1.5rem" /><span>发布到去其他</span>
|
||||
</van-col>
|
||||
<van-col span="4"></van-col>
|
||||
<van-col span="10"
|
||||
><span class="right-span">选择更多人看到</span>
|
||||
<van-icon name="arrow" size="1.2rem" />
|
||||
</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-divider />
|
||||
<van-row>
|
||||
<van-col class="img-col" span="24">
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
:after-read="afterRead"
|
||||
v-model="fileList"
|
||||
multiple
|
||||
/>
|
||||
</van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, toRefs, watch } from "vue";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity";
|
||||
import fileApi from "@/api/fileApi";
|
||||
import articleApi from "@/api/articleApi";
|
||||
import { Toast } from "vant";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const form = reactive<any>({
|
||||
title: "",
|
||||
content: "",
|
||||
images: [],
|
||||
isDeleted: false,
|
||||
});
|
||||
|
||||
const isSend = ref(false);
|
||||
const { images, content } = toRefs(form);
|
||||
const fileList = ref([]);
|
||||
const visible = ref<boolean>(false);
|
||||
onMounted(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
const afterRead = (file: any) => {
|
||||
file.status = "uploading";
|
||||
file.message = "上传中...";
|
||||
var formData = new FormData();
|
||||
//一个文件
|
||||
if (file.length == undefined) {
|
||||
formData.append("file", file.file);
|
||||
} else {
|
||||
//多个文件
|
||||
file.forEach((f: any) => {
|
||||
formData.append("file", f.file);
|
||||
f.status = "uploading";
|
||||
f.message = "上传中...";
|
||||
});
|
||||
Toast({
|
||||
message: "全部文件正在上传",
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
|
||||
fileApi.upload("image", formData).then((response: any) => {
|
||||
images.value.push(...response.data);
|
||||
|
||||
if (file.length == undefined) {
|
||||
file.status = "done";
|
||||
file.message = "成功";
|
||||
} else {
|
||||
//多个文件
|
||||
file.forEach((f: any) => {
|
||||
f.status = "done";
|
||||
f.message = "成功";
|
||||
});
|
||||
Toast({
|
||||
message: "全部文件上传成功",
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const send = () => {
|
||||
if (form.content.length < 5) {
|
||||
Toast({
|
||||
message: "请输入至少5个字符",
|
||||
position: "bottom",
|
||||
});
|
||||
} else {
|
||||
articleApi.add(form).then((response: any) => {
|
||||
router.push({ path: "/recommend" });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => form.content,
|
||||
(newValue, oldValue) => {
|
||||
if (newValue.length < 5) {
|
||||
isSend.value = false;
|
||||
} else {
|
||||
isSend.value = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style scoped>
|
||||
.head-row {
|
||||
background-color: #f8f8f8;
|
||||
|
||||
padding: 1.2rem 1rem 0.8rem 1rem;
|
||||
}
|
||||
|
||||
.head-row span {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.van-field-5-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.body-row {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.preview-cover {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.van-uploader {
|
||||
margin: 0 1.2rem 0 1.2rem;
|
||||
}
|
||||
|
||||
.img-col {
|
||||
text-align: left;
|
||||
}
|
||||
.right-span {
|
||||
color: #979797;
|
||||
}
|
||||
</style>
|
||||
44
Yi.App.Vue3/src/view/shop/shopDetails.vue
Normal file
44
Yi.App.Vue3/src/view/shop/shopDetails.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
这里是商品详情页,当所有规格组全部选择完后,就会匹配sku列表,匹配成功才显示价格,即绑定好的sku
|
||||
|
||||
<div >商品名称:{{spuItem.spuName}}</div>
|
||||
<div v-for="spec in spuItem.specsSpuAllInfo" :key="spec">规格组: {{spec.specsGroupName}}
|
||||
<div v-for="name in spec.specsNames" :key="name">规格值: {{name}}</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<div v-for="sku in spuItem.skus" :key="sku"> 价格:{{sku.price}}<br>Sku:{{sku}}
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
<router-link to="/shopIndex">返回商品首页</router-link>
|
||||
|
||||
<van-action-bar>
|
||||
<van-action-bar-icon icon="chat-o" text="客服" dot />
|
||||
<van-action-bar-icon icon="cart-o" text="购物车" badge="5" />
|
||||
<van-action-bar-icon icon="shop-o" text="店铺" badge="12" />
|
||||
<van-action-bar-button type="warning" text="加入购物车" />
|
||||
<van-action-bar-button type="danger" text="立即购买" />
|
||||
</van-action-bar>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {ref,onMounted} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import spuApi from "@/api/spuApi";
|
||||
const router = useRouter();
|
||||
|
||||
const spuItem=ref<any>({});
|
||||
|
||||
onMounted(() => {
|
||||
const spuId=router.currentRoute.value.query.spuId;
|
||||
// 打印
|
||||
spuApi.getById(spuId).then((response:any)=>{
|
||||
spuItem.value=response.data
|
||||
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
</script>>
|
||||
79
Yi.App.Vue3/src/view/shop/shopIndex.vue
Normal file
79
Yi.App.Vue3/src/view/shop/shopIndex.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template >
|
||||
<div class="back">
|
||||
|
||||
<van-row class="top-div"> <van-col span="3"><van-icon name="circle" size="2rem" /></van-col>
|
||||
<van-col span="18"> <router-link to="/shopSearch"><van-cell-group inset>
|
||||
<van-field label="搜索" placeholder="搜索" />
|
||||
</van-cell-group> </router-link></van-col>
|
||||
<van-col span="3"><van-icon name="circle" size="2rem" /></van-col></van-row>
|
||||
|
||||
<div class="head-div">
|
||||
<van-swipe
|
||||
height="100"
|
||||
class="my-swipe"
|
||||
:autoplay="3000"
|
||||
indicator-color="white"
|
||||
>
|
||||
<van-swipe-item>1</van-swipe-item>
|
||||
<van-swipe-item>2</van-swipe-item>
|
||||
<van-swipe-item>3</van-swipe-item>
|
||||
<van-swipe-item>4</van-swipe-item>
|
||||
</van-swipe>
|
||||
</div>
|
||||
|
||||
<van-row class="body-row">
|
||||
<van-col span="24">
|
||||
<van-grid :column-num="4">
|
||||
<van-grid-item
|
||||
v-for="value in 8"
|
||||
:key="value"
|
||||
icon="photo-o"
|
||||
text="文字"
|
||||
/>
|
||||
</van-grid>
|
||||
</van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import AppCard from "@/components/AppCard.vue";
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.my-swipe .van-swipe-item {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
line-height: 150px;
|
||||
text-align: center;
|
||||
background-color: #39a9ed;
|
||||
}
|
||||
.body-row {
|
||||
padding: 1rem;
|
||||
padding-top: 0.2rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.van-swipe {
|
||||
/* margin-top: 10rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem; */
|
||||
}
|
||||
.head-div {
|
||||
padding: 1rem;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.body-row .van-col {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.top-div
|
||||
{
|
||||
padding: 1rem;
|
||||
padding-bottom: 0;
|
||||
|
||||
}
|
||||
.back{
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
</style>
|
||||
39
Yi.App.Vue3/src/view/shop/shopSearch.vue
Normal file
39
Yi.App.Vue3/src/view/shop/shopSearch.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
这里是商品搜索页
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<router-link to="/shopIndex">返回商品首页</router-link>
|
||||
这个是spu:
|
||||
|
||||
<div v-for="item in spuList" :key="item.id">商品名称:{{item.spuName}}
|
||||
<router-link :to="`/shopDetails?spuId=${item.id}`">点击进入该商品详情</router-link>
|
||||
<div v-for="spec in item.specsSpuAllInfo" :key="spec">规格组: {{spec.specsGroupName}}
|
||||
<div v-for="name in spec.specsNames" :key="name">规格值: {{name}}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref,reactive,toRefs} from 'vue'
|
||||
import spuApi from "@/api/spuApi";
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// dictName: undefined,
|
||||
// dictType: undefined,
|
||||
isDeleted: false,
|
||||
},
|
||||
});
|
||||
const spuList = ref<any[]>([]);
|
||||
const { queryParams } = toRefs(data);
|
||||
spuApi.pageList(queryParams.value).then((response:any)=>{
|
||||
spuList.value=response.data.data;
|
||||
})
|
||||
</script>
|
||||
7
Yi.App.Vue3/src/vite-env.d.ts
vendored
Normal file
7
Yi.App.Vue3/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
Reference in New Issue
Block a user