前端联调接口
This commit is contained in:
20
Yi.Vue3.x.Vant/src/api/articleApi.ts
Normal file
20
Yi.Vue3.x.Vant/src/api/articleApi.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import myaxios from '@/utils/myaxios.ts'
|
||||
import { ArticleEntity } from '@/type/interface/ArticleEntity'
|
||||
|
||||
export default {
|
||||
add(data: ArticleEntity) {
|
||||
console.log(data)
|
||||
return myaxios({
|
||||
url: `/article/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data:ArticleEntity) {
|
||||
return myaxios({
|
||||
url: '/article/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
}
|
||||
12
Yi.Vue3.x.Vant/src/api/fileApi.ts
Normal file
12
Yi.Vue3.x.Vant/src/api/fileApi.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import myaxios from '@/utils/myaxios.ts'
|
||||
|
||||
export default{
|
||||
upload(type:string,data:any){
|
||||
return myaxios({
|
||||
url: `/upload/${type}`,
|
||||
headers:{"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"},
|
||||
method: 'POST',
|
||||
data:data
|
||||
});
|
||||
}
|
||||
}
|
||||
37
Yi.Vue3.x.Vant/src/components/AppCreateTime.vue
Normal file
37
Yi.Vue3.x.Vant/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>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
<router-view />
|
||||
<div style="min-height: 100rem;"></div>
|
||||
<div style=""></div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
8
Yi.Vue3.x.Vant/src/type/interface/ArticleEntity.ts
Normal file
8
Yi.Vue3.x.Vant/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'
|
||||
93
Yi.Vue3.x.Vant/src/utils/myaxios.ts
Normal file
93
Yi.Vue3.x.Vant/src/utils/myaxios.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import axios from 'axios'
|
||||
// import store from '../store/index'
|
||||
// import vm from '../main'
|
||||
import JsonBig from 'json-bigint'
|
||||
// import VuetifyDialogPlugin from 'vuetify-dialog/nuxt/index';
|
||||
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) {
|
||||
|
||||
// config.headers.Authorization = 'Bearer ' + store.state.user.token;
|
||||
// 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 == undefined && resp.message == undefined) {
|
||||
// vm.$dialog.notify.error("错误代码:无,原因:与服务器失去连接", {
|
||||
// position: "top-right",
|
||||
// timeout: 5000,
|
||||
// });
|
||||
} else if (resp.code == 401) {
|
||||
// const res = await vm.$dialog.error({
|
||||
// text: `错误代码:${resp.code},原因:${resp.message}<br>是否重新进行登录?`,
|
||||
// title: '错误',
|
||||
// actions: {
|
||||
// 'false': '取消',
|
||||
// 'true': '跳转'
|
||||
// }
|
||||
// });
|
||||
// if (res) {
|
||||
// vm.$router.push({ path: "/login" });
|
||||
// }
|
||||
|
||||
} else if (resp.code !== 200) {
|
||||
// vm.$dialog.notify.error(`错误代码:${resp.code},原因:${resp.message}`, {
|
||||
// position: "top-right",
|
||||
// timeout: 5000,
|
||||
// });
|
||||
}
|
||||
|
||||
// store.dispatch("closeLoad");
|
||||
return resp;
|
||||
}, async function(error) {
|
||||
// const resp = error.response.data
|
||||
// if (resp.code == undefined && resp.message == undefined) {
|
||||
// vm.$dialog.notify.error("错误代码:无,原因:与服务器失去连接", {
|
||||
// position: "top-right",
|
||||
// timeout: 5000,
|
||||
// });
|
||||
// } else if (resp.code == 401) {
|
||||
// const res = await vm.$dialog.error({
|
||||
// text: `错误代码:${resp.code},原因:${resp.message}<br>是否重新进行登录?`,
|
||||
// title: '错误',
|
||||
// actions: {
|
||||
// 'false': '取消',
|
||||
// 'true': '跳转'
|
||||
// }
|
||||
// });
|
||||
// if (res) {
|
||||
// vm.$store.dispatch("Logout").then((resp) => {
|
||||
// vm.$router.push({ path: "/login" });
|
||||
// });
|
||||
// }
|
||||
|
||||
// } else if (resp.code !== 200) {
|
||||
// vm.$dialog.notify.error(`错误代码:${resp.code},原因:${resp.message}`, {
|
||||
// position: "top-right",
|
||||
// timeout: 5000,
|
||||
// });
|
||||
// }
|
||||
|
||||
// store.dispatch("closeLoad");
|
||||
return Promise.reject(error);
|
||||
});
|
||||
export default myaxios
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
|
||||
<van-list
|
||||
class="list"
|
||||
v-model:loading="loading"
|
||||
@@ -7,7 +7,8 @@
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad"
|
||||
>
|
||||
<van-row v-for="item in list" class="row">
|
||||
|
||||
<van-row v-for="(item,index) in articleList" :key="index" class="row">
|
||||
<van-col span="4" class="leftCol">
|
||||
<van-image
|
||||
round
|
||||
@@ -20,7 +21,7 @@
|
||||
<van-col span="14" class="centerTitle">
|
||||
<span class="justtitle"> 大白</span>
|
||||
<br />
|
||||
<span class="subtitle">一小时前</span>
|
||||
<app-createTime :time="item.createTime"/>
|
||||
</van-col>
|
||||
|
||||
<van-col span="6" class="down">
|
||||
@@ -28,21 +29,19 @@
|
||||
</van-col>
|
||||
|
||||
<van-col class="rowBody" span="24"
|
||||
>这是第:{{
|
||||
item
|
||||
}}个,不要害怕重新开始,因为这一次你不是从头开始,而是从经验开始</van-col
|
||||
>{{item.content}}</van-col
|
||||
>
|
||||
|
||||
<van-col
|
||||
span="8"
|
||||
v-for="item of 9"
|
||||
:key="item"
|
||||
v-for="(image,imageIndex) in item.images"
|
||||
:key="imageIndex"
|
||||
class="imageCol"
|
||||
@click="imageShow = true"
|
||||
@click="openImage(item.images)"
|
||||
><van-image
|
||||
width="100%"
|
||||
height="7rem"
|
||||
src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:src="url+image"
|
||||
radius="5"
|
||||
/>
|
||||
</van-col>
|
||||
@@ -56,7 +55,7 @@
|
||||
</van-col>
|
||||
</van-row>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
|
||||
|
||||
<!-- 功能页面 -->
|
||||
<van-action-sheet
|
||||
@@ -69,27 +68,40 @@
|
||||
<!-- 图片预览 -->
|
||||
<van-image-preview
|
||||
v-model:show="imageShow"
|
||||
:images="images"
|
||||
:images="imagesPreview"
|
||||
@change="onChange"
|
||||
:closeable=true
|
||||
>
|
||||
<template v-slot:index>第{{ index }}页</template>
|
||||
<template v-slot:index>第{{ index+1 }}页</template>
|
||||
</van-image-preview>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { ref ,onMounted,reactive, toRefs} from "vue";
|
||||
import { ImagePreview, Toast } from "vant";
|
||||
|
||||
import AppCreateTime from '@/components/AppCreateTime.vue'
|
||||
import articleApi from "@/api/articleApi.ts";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity.ts";
|
||||
const VanImagePreview = ImagePreview.Component;
|
||||
const url=`${import.meta.env.VITE_APP_BASE_API}/file/image/`
|
||||
const data=reactive({
|
||||
|
||||
queryParams:{
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// dictName: undefined,
|
||||
// dictType: undefined,
|
||||
isDeleted: false
|
||||
}
|
||||
});
|
||||
const {queryParams} =toRefs(data);
|
||||
|
||||
const articleList=ref<ArticleEntity[]>([]);
|
||||
const totol=ref<Number>(0);
|
||||
const imageShow = ref(false);
|
||||
const index = ref(0);
|
||||
const images = [
|
||||
"https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg",
|
||||
"https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg",
|
||||
];
|
||||
let imagesPreview =ref<string[]>([]);
|
||||
|
||||
const onChange = (newIndex: any) => {
|
||||
index.value = newIndex;
|
||||
};
|
||||
@@ -105,24 +117,40 @@ const actions = [
|
||||
{ name: "将TA拉黑" },
|
||||
{ name: "举报"}
|
||||
];
|
||||
const onLoad = () => {
|
||||
setTimeout(() => {
|
||||
if (refreshing.value) {
|
||||
list.value = [];
|
||||
refreshing.value = false;
|
||||
}
|
||||
// const onLoad = () => {
|
||||
|
||||
// if (refreshing.value) {
|
||||
// articleList.value = [];
|
||||
// refreshing.value = false;
|
||||
// queryParams.value.pageNum=0;
|
||||
// }
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
list.value.push(list.value.length + 1);
|
||||
}
|
||||
loading.value = false;
|
||||
// queryParams.value.pageNum+=1;
|
||||
// getList();
|
||||
|
||||
if (list.value.length >= 40) {
|
||||
finished.value = true;
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
// loading.value = false;
|
||||
|
||||
// if (articleList.value.length >= 40) {
|
||||
// finished.value = true;
|
||||
// }
|
||||
|
||||
// };
|
||||
const onLoad = async() => {
|
||||
// 异步更新数据
|
||||
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
|
||||
setTimeout(async() => {
|
||||
console.log("执行")
|
||||
// await getList();
|
||||
// queryParams.value.pageNum+=1
|
||||
// 加载状态结束
|
||||
loading.value = false;
|
||||
|
||||
// 数据全部加载完成
|
||||
if (list.value.length >= 4000) {
|
||||
finished.value = true;
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
const onRefresh = () => {
|
||||
// 清空列表数据
|
||||
finished.value = false;
|
||||
@@ -130,8 +158,23 @@ const onRefresh = () => {
|
||||
// 重新加载数据
|
||||
// 将 loading 设置为 true,表示处于加载状态
|
||||
loading.value = true;
|
||||
onLoad();
|
||||
// onLoad();
|
||||
};
|
||||
const openImage=(imagesUrl :string[])=>{
|
||||
imagesPreview.value=imagesUrl.map(i=>url+i);
|
||||
imageShow.value=true;
|
||||
}
|
||||
onMounted(()=>{
|
||||
articleList.value=[];
|
||||
getList();
|
||||
})
|
||||
|
||||
const getList=()=>{
|
||||
articleApi.pageList(queryParams.value).then((response:any)=>{
|
||||
articleList.value.push(...response.data.data as ArticleEntity[]);
|
||||
totol.value=response.data.totol;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.list {
|
||||
|
||||
@@ -3,7 +3,14 @@
|
||||
|
||||
<van-row class="test ">
|
||||
<van-col span="24">
|
||||
这里是广场页面
|
||||
<van-list
|
||||
v-model:loading="loading"
|
||||
:finished="finished"
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad"
|
||||
>
|
||||
<van-cell v-for="item in list" :key="item" :title="item" />
|
||||
</van-list>
|
||||
</van-col>
|
||||
|
||||
</van-row>
|
||||
@@ -11,4 +18,31 @@
|
||||
<van-col span="24"></van-col>
|
||||
</template>
|
||||
<style scoped>
|
||||
</style>
|
||||
</style>
|
||||
<script lang="ts" setup>
|
||||
import {ref} from 'vue'
|
||||
|
||||
const list = ref([]);
|
||||
const loading = ref(false);
|
||||
const finished = ref(false);
|
||||
|
||||
const onLoad = () => {
|
||||
console.log("执行")
|
||||
// 异步更新数据
|
||||
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
|
||||
setTimeout(() => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
list.value.push(list.value.length + 1);
|
||||
}
|
||||
|
||||
// 加载状态结束
|
||||
loading.value = false;
|
||||
|
||||
// 数据全部加载完成
|
||||
if (list.value.length >= 1000) {
|
||||
finished.value = true;
|
||||
}
|
||||
}, 1);
|
||||
};
|
||||
|
||||
</script>
|
||||
@@ -1,95 +1,126 @@
|
||||
<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">发布</van-col>
|
||||
</van-row>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
|
||||
<van-cell-group>
|
||||
<van-field rows="5" autosize type="textarea" v-model="value" label-width="0" :show-word-limit="true"
|
||||
maxlength="500" placeholder="每一天,都是为了下一天" />
|
||||
</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>选择更多人看到</span>
|
||||
<van-icon name="arrow" size="1.2rem" />
|
||||
</van-col>
|
||||
<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">发布</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="每一天,都是为了下一天"
|
||||
/>
|
||||
</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>选择更多人看到</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 v-model="fileList" multiple />
|
||||
</van-col>
|
||||
</van-row>
|
||||
<van-divider />
|
||||
<van-row>
|
||||
<van-col class="img-col" span="24">
|
||||
<van-uploader :after-read="afterRead" v-model="fileList" multiple />
|
||||
</van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
|
||||
</transition>
|
||||
|
||||
|
||||
</transition>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref,onMounted } from 'vue'
|
||||
const value = ref<string>("")
|
||||
const fileList = ref([
|
||||
]);
|
||||
const visible=ref<boolean>(false)
|
||||
import { ref, onMounted, reactive, toRefs } from "vue";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity.ts";
|
||||
import fileApi from "@/api/fileApi.ts";
|
||||
import articleApi from "@/api/articleApi.ts";
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter();
|
||||
const form = reactive<ArticleEntity>({
|
||||
title: "",
|
||||
content: "",
|
||||
images: [],
|
||||
isDeleted: false,
|
||||
});
|
||||
|
||||
const { images, content } = toRefs(form);
|
||||
const fileList = ref([]);
|
||||
const visible = ref<boolean>(false);
|
||||
onMounted(() => {
|
||||
visible.value=true;
|
||||
})
|
||||
visible.value = true;
|
||||
});
|
||||
const afterRead = (file: any) => {
|
||||
file.status = "uploading";
|
||||
file.message = "上传中...";
|
||||
var formData = new FormData();
|
||||
formData.append("file", file.file);
|
||||
fileApi.upload("image", formData)
|
||||
.then((response: any) => {
|
||||
images.value.push(response.data);
|
||||
file.status = "done";
|
||||
file.message = "成功";
|
||||
})
|
||||
};
|
||||
|
||||
const send = () => {
|
||||
articleApi.add(form).then((response:any)=>{
|
||||
router.push({ path: '/recommend'});
|
||||
})
|
||||
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.head-row {
|
||||
background-color: #F8F8F8;
|
||||
background-color: #f8f8f8;
|
||||
|
||||
padding: 2rem 1rem 1.5rem 1rem;
|
||||
padding: 2rem 1rem 1.5rem 1rem;
|
||||
}
|
||||
|
||||
.head-row span {
|
||||
font-size: large;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.van-field-5-label {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.body-row {
|
||||
margin-top: 1rem;
|
||||
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);
|
||||
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;
|
||||
margin: 0 1.2rem 0 1.2rem;
|
||||
}
|
||||
|
||||
.img-col {
|
||||
text-align: left;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user