小程序初始提交
This commit is contained in:
327
cool-unix/pages/dailyreport/list.uvue
Normal file
327
cool-unix/pages/dailyreport/list.uvue
Normal file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<cl-page title="我的日报">
|
||||
<!-- 筛选栏 -->
|
||||
<view class="px-4 py-3 bg-white border-b">
|
||||
<view class="flex gap-2">
|
||||
<cl-button
|
||||
:type="filterType === 'all' ? 'primary' : 'default'"
|
||||
size="small"
|
||||
@tap="changeFilter('all')"
|
||||
>
|
||||
全部
|
||||
</cl-button>
|
||||
<cl-button
|
||||
:type="filterType === 'draft' ? 'primary' : 'default'"
|
||||
size="small"
|
||||
@tap="changeFilter('draft')"
|
||||
>
|
||||
草稿
|
||||
</cl-button>
|
||||
<cl-button
|
||||
:type="filterType === 'submitted' ? 'primary' : 'default'"
|
||||
size="small"
|
||||
@tap="changeFilter('submitted')"
|
||||
>
|
||||
已提交
|
||||
</cl-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 日报列表 -->
|
||||
<scroll-view scroll-y class="flex-1">
|
||||
<!-- 加载中 -->
|
||||
<view v-if="loading && list.length === 0" class="flex items-center justify-center py-20">
|
||||
<text class="text-gray-400">加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 列表内容 -->
|
||||
<view v-else-if="list.length > 0">
|
||||
<view
|
||||
v-for="(item, index) in list"
|
||||
:key="item.id || index"
|
||||
class="mx-4 my-2 p-4 bg-white rounded-lg shadow-sm"
|
||||
@tap="toDetail(item)"
|
||||
>
|
||||
<!-- 头部:日期和状态 -->
|
||||
<view class="flex justify-between items-center mb-3">
|
||||
<view class="flex items-center gap-2">
|
||||
<text class="text-lg font-bold">{{ formatDate(item.reportDate) }}</text>
|
||||
<text class="text-xs text-gray-500">
|
||||
{{ formatWeekday(item.reportDate) }}
|
||||
</text>
|
||||
</view>
|
||||
<view
|
||||
:class="[
|
||||
'px-2 py-1 rounded text-xs',
|
||||
item.status === 1 ? 'bg-green-100 text-green-700' : 'bg-yellow-100 text-yellow-700'
|
||||
]"
|
||||
>
|
||||
{{ item.status === 1 ? "已提交" : "草稿" }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 内容摘要 -->
|
||||
<view class="mb-3">
|
||||
<text class="text-sm text-gray-700">
|
||||
{{ getContentPreview(item.userEditedContent) }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 底部信息 -->
|
||||
<view class="flex justify-between items-center text-xs text-gray-500">
|
||||
<view class="flex items-center gap-2">
|
||||
<text>{{ item.inputType === 1 ? "🎤 语音输入" : "⌨️ 文字输入" }}</text>
|
||||
</view>
|
||||
<text v-if="item.submitTime">
|
||||
提交于 {{ formatTime(item.submitTime) }}
|
||||
</text>
|
||||
<text v-else-if="item.createTime">
|
||||
创建于 {{ formatTime(item.createTime) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view v-if="loading" class="flex items-center justify-center py-4">
|
||||
<text class="text-gray-400 text-sm">加载中...</text>
|
||||
</view>
|
||||
<view v-else-if="finished" class="flex items-center justify-center py-4">
|
||||
<text class="text-gray-400 text-sm">没有更多了</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-else class="flex flex-col items-center justify-center py-20">
|
||||
<text class="text-6xl mb-4">📝</text>
|
||||
<text class="text-gray-400 text-base">暂无日报</text>
|
||||
<view
|
||||
class="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
|
||||
@tap="toSubmit"
|
||||
>
|
||||
<text>去提交日报</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 悬浮提交按钮 -->
|
||||
<view class="fixed bottom-20 right-4">
|
||||
<cl-button
|
||||
type="primary"
|
||||
size="large"
|
||||
round
|
||||
@tap="toSubmit"
|
||||
>
|
||||
<text class="text-2xl">✏️</text>
|
||||
</cl-button>
|
||||
</view>
|
||||
</cl-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { request, router, useStore } from "@/cool";
|
||||
import { useUi } from "@/uni_modules/cool-ui";
|
||||
|
||||
const ui = useUi();
|
||||
const { user } = useStore();
|
||||
|
||||
// 列表相关
|
||||
const list = ref<any[]>([]);
|
||||
const loading = ref(false);
|
||||
const finished = ref(false);
|
||||
const page = ref(1);
|
||||
const pageSize = ref(20);
|
||||
|
||||
// 筛选类型
|
||||
const filterType = ref<"all" | "draft" | "submitted">("all");
|
||||
|
||||
// 用户ID(从登录状态获取)
|
||||
const userId = ref(0);
|
||||
|
||||
// 初始化
|
||||
onMounted(async () => {
|
||||
console.log("【日报列表】页面加载, user.info:", user.info.value);
|
||||
|
||||
// 先尝试获取最新用户信息
|
||||
if (user.token) {
|
||||
try {
|
||||
await user.get();
|
||||
} catch (e) {
|
||||
console.error("【日报列表】获取用户信息失败:", e);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("【日报列表】获取用户信息后, user.info:", user.info.value);
|
||||
|
||||
if (user.info.value && user.info.value.id) {
|
||||
userId.value = user.info.value.id;
|
||||
console.log("【日报列表】设置userId:", userId.value);
|
||||
loadReports();
|
||||
} else {
|
||||
console.error("【日报列表】用户未登录或用户信息为空");
|
||||
ui.showToast({
|
||||
message: "请先登录",
|
||||
type: "error"
|
||||
});
|
||||
setTimeout(() => {
|
||||
router.to("/pages/user/login");
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
// 加载日报列表
|
||||
async function loadReports() {
|
||||
if (loading.value || finished.value) return;
|
||||
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
console.log("【日报列表】开始加载, userId:", userId.value);
|
||||
|
||||
if (!userId.value || userId.value === 0) {
|
||||
console.error("【日报列表】userId无效:", userId.value);
|
||||
throw new Error("用户ID无效,请重新登录");
|
||||
}
|
||||
|
||||
const params: any = {
|
||||
userId: userId.value,
|
||||
page: page.value,
|
||||
size: pageSize.value
|
||||
};
|
||||
|
||||
// 添加状态筛选
|
||||
if (filterType.value === "draft") {
|
||||
params.status = 0;
|
||||
} else if (filterType.value === "submitted") {
|
||||
params.status = 1;
|
||||
}
|
||||
|
||||
console.log("【日报列表】请求参数:", params);
|
||||
|
||||
const res = await request({
|
||||
url: "/app/dailyreport/report/myReports",
|
||||
method: "GET",
|
||||
params
|
||||
});
|
||||
|
||||
console.log("【日报列表】响应数据:", res);
|
||||
console.log("【日报列表】响应类型:", typeof res);
|
||||
console.log("【日报列表】是否为数组:", Array.isArray(res));
|
||||
console.log("【日报列表】数据长度:", res ? res.length : 0);
|
||||
|
||||
if (res && res.length > 0) {
|
||||
console.log("【日报列表】开始填充列表数据");
|
||||
if (page.value === 1) {
|
||||
list.value = res;
|
||||
} else {
|
||||
list.value.push(...res);
|
||||
}
|
||||
page.value++;
|
||||
|
||||
console.log("【日报列表】列表已更新, 当前list长度:", list.value.length);
|
||||
console.log("【日报列表】列表第一项数据:", list.value[0]);
|
||||
|
||||
// 如果返回数据少于每页大小,说明已经到底了
|
||||
if (res.length < pageSize.value) {
|
||||
finished.value = true;
|
||||
}
|
||||
} else {
|
||||
console.log("【日报列表】无数据或数据为空");
|
||||
// 即使没有数据,也不应该标记为finished,可能只是筛选条件没有匹配的数据
|
||||
if (page.value === 1) {
|
||||
list.value = [];
|
||||
}
|
||||
finished.value = true;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("加载日报列表失败:", error);
|
||||
ui.showToast({
|
||||
message: "加载失败: " + (error.message || "未知错误"),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 下拉刷新
|
||||
function onRefresh() {
|
||||
console.log("【日报列表】下拉刷新");
|
||||
page.value = 1;
|
||||
finished.value = false;
|
||||
list.value = [];
|
||||
loadReports();
|
||||
}
|
||||
|
||||
// 切换筛选条件
|
||||
function changeFilter(type: "all" | "draft" | "submitted") {
|
||||
console.log("【日报列表】切换筛选:", type);
|
||||
filterType.value = type;
|
||||
page.value = 1;
|
||||
finished.value = false;
|
||||
list.value = [];
|
||||
loadReports();
|
||||
}
|
||||
|
||||
// 跳转到详情
|
||||
function toDetail(item: any) {
|
||||
const date = item.reportDate ? encodeURIComponent(item.reportDate) : '';
|
||||
router.to(`/pages/dailyreport/detail?id=${item.id}&date=${date}`);
|
||||
}
|
||||
|
||||
// 跳转到提交页面
|
||||
function toSubmit() {
|
||||
router.to("/pages/dailyreport/submit");
|
||||
}
|
||||
|
||||
// 格式化日期
|
||||
function formatDate(dateStr: string) {
|
||||
if (!dateStr) return "";
|
||||
const date = new Date(dateStr);
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${month}月${day}日`;
|
||||
}
|
||||
|
||||
// 格式化星期
|
||||
function formatWeekday(dateStr: string) {
|
||||
if (!dateStr) return "";
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
|
||||
return weekdays[date.getDay()];
|
||||
}
|
||||
|
||||
// 格式化时间
|
||||
function formatTime(timeStr: string) {
|
||||
if (!timeStr) return "";
|
||||
const date = new Date(timeStr);
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
const hours = String(date.getHours()).padStart(2, "0");
|
||||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
||||
return `${month}-${day} ${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
// 获取内容摘要
|
||||
function getContentPreview(content: string) {
|
||||
if (!content) return "(无内容)";
|
||||
// 移除 Markdown 标记
|
||||
const plain = content.replace(/[#*`\[\]()]/g, "").trim();
|
||||
// 限制长度
|
||||
return plain.length > 100 ? plain.substring(0, 100) + "..." : plain;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user