论坛调整
This commit is contained in:
parent
743f8aeae7
commit
05e789ebb4
@ -5,3 +5,8 @@ import { get, post } from "@/utils/request";
|
|||||||
export const findNjJsListApi = async (params: any) => {
|
export const findNjJsListApi = async (params: any) => {
|
||||||
return await get("/api/bj/findNjJsList", params);
|
return await get("/api/bj/findNjJsList", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 根据教师ID列表查询教师信息
|
||||||
|
export const findByIdsApi = async (params: any) => {
|
||||||
|
return await get("/api/js/findByIds", params);
|
||||||
|
};
|
||||||
201
src/api/forum/index.ts
Normal file
201
src/api/forum/index.ts
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
import { get, post } from "@/utils/request";
|
||||||
|
|
||||||
|
// ==================== 社区相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询社区列表
|
||||||
|
*/
|
||||||
|
export function communityFindPageApi(params: any) {
|
||||||
|
return get('/api/forumCommunity/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询社区详情
|
||||||
|
*/
|
||||||
|
export function communityFindByIdApi(params: any) {
|
||||||
|
return get('/api/forumCommunity/findById', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增/修改社区
|
||||||
|
*/
|
||||||
|
export function communitySaveApi(params: any) {
|
||||||
|
return post('/api/forumCommunity/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除社区
|
||||||
|
*/
|
||||||
|
export function communityDeleteApi(params: any) {
|
||||||
|
return post('/api/forumCommunity/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 社区成员相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加入社区
|
||||||
|
*/
|
||||||
|
export function communityMemberJoinApi(params: any) {
|
||||||
|
return post('/api/forumCommunityMember/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出社区
|
||||||
|
*/
|
||||||
|
export function communityMemberQuitApi(params: any) {
|
||||||
|
return post('/api/forumCommunityMember/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取社区成员列表
|
||||||
|
*/
|
||||||
|
export function communityMemberFindPageApi(params: any) {
|
||||||
|
return get('/api/forumCommunityMember/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取我加入的社区
|
||||||
|
*/
|
||||||
|
export function getMyCommunityListApi(params: any) {
|
||||||
|
return get('/api/forumCommunityMember/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 帖子相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询帖子列表
|
||||||
|
*/
|
||||||
|
export function postFindPageApi(params: any) {
|
||||||
|
return get('/api/forumPost/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询帖子详情
|
||||||
|
*/
|
||||||
|
export function postFindByIdApi(params: any) {
|
||||||
|
return get('/api/forumPost/findById', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增/修改帖子
|
||||||
|
*/
|
||||||
|
export function postSaveApi(params: any) {
|
||||||
|
return post('/api/forumPost/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除帖子
|
||||||
|
*/
|
||||||
|
export function postDeleteApi(params: any) {
|
||||||
|
return post('/api/forumPost/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 评论相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询评论列表
|
||||||
|
*/
|
||||||
|
export function commentFindPageApi(params: any) {
|
||||||
|
return get('/api/forumComment/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询评论详情
|
||||||
|
*/
|
||||||
|
export function commentFindByIdApi(params: any) {
|
||||||
|
return get('/api/forumComment/findById', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增/修改评论
|
||||||
|
*/
|
||||||
|
export function commentSaveApi(params: any) {
|
||||||
|
return post('/api/forumComment/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除评论
|
||||||
|
*/
|
||||||
|
export function commentDeleteApi(params: any) {
|
||||||
|
return post('/api/forumComment/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 点赞相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点赞/取消点赞
|
||||||
|
*/
|
||||||
|
export function likeSaveApi(params: any) {
|
||||||
|
return post('/api/forumLike/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除点赞
|
||||||
|
*/
|
||||||
|
export function likeDeleteApi(params: any) {
|
||||||
|
return post('/api/forumLike/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询是否已点赞
|
||||||
|
*/
|
||||||
|
export function likeFindByIdApi(params: any) {
|
||||||
|
return get('/api/forumLike/findById', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 收藏相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏/取消收藏
|
||||||
|
*/
|
||||||
|
export function collectSaveApi(params: any) {
|
||||||
|
return post('/api/forumCollect/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除收藏
|
||||||
|
*/
|
||||||
|
export function collectDeleteApi(params: any) {
|
||||||
|
return post('/api/forumCollect/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我的收藏
|
||||||
|
*/
|
||||||
|
export function collectFindPageApi(params: any) {
|
||||||
|
return get('/api/forumCollect/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 消息相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询消息列表
|
||||||
|
*/
|
||||||
|
export function messageFindPageApi(params: any) {
|
||||||
|
return get('/api/forumMessage/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记消息已读
|
||||||
|
*/
|
||||||
|
export function messageReadApi(params: any) {
|
||||||
|
return post('/api/forumMessage/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取未读消息数量
|
||||||
|
*/
|
||||||
|
export function messageUnreadCountApi(params: any) {
|
||||||
|
return get('/api/forumMessage/unreadCount', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 文件上传相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*/
|
||||||
|
export function fileUploadApi(params: any) {
|
||||||
|
return post('/api/upload/uploadFile', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -339,6 +339,51 @@
|
|||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "学校论坛",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "论坛详情",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/create",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "创建论坛",
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "修改论坛",
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/postDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "帖子详情",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/lt/publish",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "发布帖子",
|
||||||
|
"backgroundColor": "#f5f7fa"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/routine/ShiTangXunCha/index",
|
"path": "pages/view/routine/ShiTangXunCha/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@ -294,7 +294,7 @@ const sections = reactive<Section[]>([
|
|||||||
text: "交流讨论",
|
text: "交流讨论",
|
||||||
show: true,
|
show: true,
|
||||||
permissionKey: "ysyc-jltl",
|
permissionKey: "ysyc-jltl",
|
||||||
path: "/pages/view/rw/index",
|
path: "/pages/view/routine/lt/index",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "gnyy7",
|
id: "gnyy7",
|
||||||
|
|||||||
1037
src/pages/view/routine/lt/create.vue
Normal file
1037
src/pages/view/routine/lt/create.vue
Normal file
File diff suppressed because it is too large
Load Diff
1052
src/pages/view/routine/lt/detail.vue
Normal file
1052
src/pages/view/routine/lt/detail.vue
Normal file
File diff suppressed because it is too large
Load Diff
1028
src/pages/view/routine/lt/edit.vue
Normal file
1028
src/pages/view/routine/lt/edit.vue
Normal file
File diff suppressed because it is too large
Load Diff
703
src/pages/view/routine/lt/index.vue
Normal file
703
src/pages/view/routine/lt/index.vue
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
<template>
|
||||||
|
<view class="forum-community-page">
|
||||||
|
<!-- 顶部搜索和筛选区域 -->
|
||||||
|
<view class="top-section">
|
||||||
|
<view class="search-card">
|
||||||
|
<!-- 搜索框 -->
|
||||||
|
<view class="search-item">
|
||||||
|
<view class="search-container">
|
||||||
|
<BasicSearch
|
||||||
|
placeholder="搜索交流群名称"
|
||||||
|
@search="handleSearch"
|
||||||
|
class="search-input"
|
||||||
|
v-model="searchKeyword"
|
||||||
|
/>
|
||||||
|
<u-button
|
||||||
|
text="查询"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
class="search-button"
|
||||||
|
@click="handleSearch(searchKeyword)"
|
||||||
|
:custom-style="{ flexShrink: 0, width: 'auto', minWidth: '120rpx' }"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- Tab筛选 -->
|
||||||
|
<scroll-view scroll-x class="filter-tabs-scroll">
|
||||||
|
<view class="filter-tabs">
|
||||||
|
<view
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.value"
|
||||||
|
class="filter-tab"
|
||||||
|
:class="{ active: activeTab === tab.value }"
|
||||||
|
@click="switchTab(tab.value)"
|
||||||
|
>
|
||||||
|
{{ tab.label }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 中间内容区域 -->
|
||||||
|
<view class="middle-section">
|
||||||
|
<scroll-view
|
||||||
|
scroll-y
|
||||||
|
class="list-scroll-view"
|
||||||
|
@scrolltolower="loadMore"
|
||||||
|
lower-threshold="100"
|
||||||
|
>
|
||||||
|
<view v-if="isLoading && dataList.length === 0" class="loading-indicator">
|
||||||
|
<text class="loading-icon">⏳</text>
|
||||||
|
<text class="loading-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else-if="dataList.length > 0">
|
||||||
|
<view
|
||||||
|
v-for="item in dataList"
|
||||||
|
:key="item.id"
|
||||||
|
class="community-item"
|
||||||
|
:class="{ 'no-image': !item.fileUrl }"
|
||||||
|
@click="goDetail(item)"
|
||||||
|
>
|
||||||
|
<!-- 社区封面 -->
|
||||||
|
<image
|
||||||
|
v-if="item.fileUrl"
|
||||||
|
:src="item.fileUrl"
|
||||||
|
class="community-cover"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 社区信息 -->
|
||||||
|
<view class="community-info" :class="{ 'full-width': !item.fileUrl }">
|
||||||
|
<view class="info-header">
|
||||||
|
<text class="community-name">{{ item.communityName }}</text>
|
||||||
|
<u-tag
|
||||||
|
v-if="item.communityType == 2"
|
||||||
|
text="私密"
|
||||||
|
type="warning"
|
||||||
|
size="mini"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<text class="community-desc">{{ item.communityDesc || '暂无描述' }}</text>
|
||||||
|
|
||||||
|
<view class="community-meta">
|
||||||
|
<view class="meta-item">
|
||||||
|
<u-icon name="account" size="14" color="#999" />
|
||||||
|
<text>{{ item.memberCount || 0 }} 成员</text>
|
||||||
|
</view>
|
||||||
|
<view class="meta-item">
|
||||||
|
<u-icon name="edit-pen" size="14" color="#999" />
|
||||||
|
<text>{{ item.postCount || 0 }} 帖子</text>
|
||||||
|
</view>
|
||||||
|
<view class="meta-item">
|
||||||
|
<u-icon name="calendar" size="14" color="#999" />
|
||||||
|
<text>{{ item.createdUserName || '未知' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 分类标签和修改按钮 -->
|
||||||
|
<view class="category-and-edit">
|
||||||
|
<view class="category-tag" v-if="item.category">
|
||||||
|
<u-tag
|
||||||
|
:text="getCategoryText(item.category)"
|
||||||
|
plain
|
||||||
|
size="mini"
|
||||||
|
type="info"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="edit-icon" @click.stop="goEdit(item)">
|
||||||
|
<u-icon name="edit-pen" size="20" color="#007aff" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<view class="action-btn">
|
||||||
|
<u-icon name="arrow-right" size="18" color="#999" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<view v-else class="empty-state">
|
||||||
|
<text class="empty-icon">📚</text>
|
||||||
|
<text class="empty-text">暂无数据</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载更多 -->
|
||||||
|
<view v-if="isLoading && dataList.length > 0" class="loading-more">
|
||||||
|
<text class="loading-more-icon">⏳</text>
|
||||||
|
<text class="loading-more-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 没有更多数据 -->
|
||||||
|
<view v-if="!hasMore && dataList.length > 0" class="no-more">
|
||||||
|
<text class="no-more-icon">✓</text>
|
||||||
|
<text class="no-more-text">已加载全部社区</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部创建按钮 -->
|
||||||
|
<view class="bottom-section">
|
||||||
|
<u-button
|
||||||
|
type="primary"
|
||||||
|
text="创建交流群"
|
||||||
|
@click="goCreate"
|
||||||
|
block
|
||||||
|
shape="circle"
|
||||||
|
:custom-style="{ height: '88rpx', fontSize: '32rpx' }"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted, onUnmounted } from 'vue';
|
||||||
|
import { communityFindPageApi } from '@/api/forum';
|
||||||
|
import { useDicStore } from '@/store/modules/dic';
|
||||||
|
import BasicSearch from '@/components/BasicSearch/Search.vue';
|
||||||
|
|
||||||
|
const { findByPid } = useDicStore();
|
||||||
|
|
||||||
|
// 搜索关键词
|
||||||
|
const searchKeyword = ref('');
|
||||||
|
|
||||||
|
// Tab选项 - 动态加载
|
||||||
|
const tabs = ref([
|
||||||
|
{ label: '全部', value: 'all', dictionaryCode: 'all' }
|
||||||
|
]);
|
||||||
|
const activeTab = ref('all');
|
||||||
|
|
||||||
|
// 数据列表
|
||||||
|
const dataList = ref([]);
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const hasMore = ref(true);
|
||||||
|
const currentPage = ref(1);
|
||||||
|
const pageSize = ref(20);
|
||||||
|
|
||||||
|
// 加载Tab分类数据
|
||||||
|
const loadTabData = async () => {
|
||||||
|
try {
|
||||||
|
const res = await findByPid({ pid: 2146632765 });
|
||||||
|
console.log('Tab分类API返回数据:', res);
|
||||||
|
|
||||||
|
// 检查数据结构,实际数据在 res.result 中
|
||||||
|
let data = [];
|
||||||
|
if (res && res.result && Array.isArray(res.result) && res.result.length > 0) {
|
||||||
|
data = res.result;
|
||||||
|
} else if (res && Array.isArray(res) && res.length > 0) {
|
||||||
|
data = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.length > 0) {
|
||||||
|
// 构建Tab选项,只包含"全部"和字典数据中的分类
|
||||||
|
const tabOptions = [
|
||||||
|
{ label: '全部', value: 'all', dictionaryCode: 'all' }
|
||||||
|
];
|
||||||
|
|
||||||
|
// 添加字典数据中的分类
|
||||||
|
data.forEach(item => {
|
||||||
|
if (item.dictionaryValue && item.dictionaryCode) {
|
||||||
|
tabOptions.push({
|
||||||
|
label: item.dictionaryValue,
|
||||||
|
value: item.dictionaryCode,
|
||||||
|
dictionaryCode: item.dictionaryCode
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tabs.value = tabOptions;
|
||||||
|
console.log('加载Tab数据成功:', tabs.value);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载Tab数据失败:', error);
|
||||||
|
// 使用默认Tab选项
|
||||||
|
tabs.value = [
|
||||||
|
{ label: '全部', value: 'all', dictionaryCode: 'all' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
const queryData = async (isLoadMore = false) => {
|
||||||
|
if (isLoading.value) return;
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
|
const params: any = {
|
||||||
|
page: isLoadMore ? currentPage.value + 1 : 1,
|
||||||
|
rows: pageSize.value,
|
||||||
|
communityName: searchKeyword.value,
|
||||||
|
status: 'A'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据Tab筛选
|
||||||
|
if (activeTab.value !== 'all' && activeTab.value !== 'my') {
|
||||||
|
params.communityType = parseInt(activeTab.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('queryData中的searchKeyword.value:', searchKeyword.value);
|
||||||
|
console.log('请求参数:', params);
|
||||||
|
|
||||||
|
const res = await communityFindPageApi(params);
|
||||||
|
|
||||||
|
console.log('API返回数据:', res);
|
||||||
|
|
||||||
|
// 根据实际返回的数据结构调整
|
||||||
|
let list = [];
|
||||||
|
if (res?.rows && Array.isArray(res.rows)) {
|
||||||
|
// 数据结构: { total: 1, page: 1, records: 1, rows: [...] }
|
||||||
|
list = res.rows;
|
||||||
|
} else if (res?.records && Array.isArray(res.records)) {
|
||||||
|
// 数据结构: { records: [...], total: 1 }
|
||||||
|
list = res.records;
|
||||||
|
} else if (res?.data) {
|
||||||
|
// 数据结构: { data: { records: [...] } }
|
||||||
|
if (Array.isArray(res.data)) {
|
||||||
|
list = res.data;
|
||||||
|
} else if (res.data.rows && Array.isArray(res.data.rows)) {
|
||||||
|
list = res.data.rows;
|
||||||
|
} else if (res.data.records && Array.isArray(res.data.records)) {
|
||||||
|
list = res.data.records;
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(res)) {
|
||||||
|
// 直接是数组
|
||||||
|
list = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('解析后的列表数据:', list);
|
||||||
|
|
||||||
|
if (isLoadMore) {
|
||||||
|
dataList.value.push(...list);
|
||||||
|
currentPage.value++;
|
||||||
|
} else {
|
||||||
|
dataList.value = list;
|
||||||
|
currentPage.value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasMore.value = list.length === pageSize.value;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('查询社区列表失败:', error);
|
||||||
|
uni.showToast({
|
||||||
|
title: '查询失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换Tab
|
||||||
|
const switchTab = (value: string) => {
|
||||||
|
activeTab.value = value;
|
||||||
|
queryData(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 搜索处理
|
||||||
|
const handleSearch = (event: any) => {
|
||||||
|
console.log('搜索事件对象:', event);
|
||||||
|
|
||||||
|
let keyword = '';
|
||||||
|
|
||||||
|
// 判断事件对象的类型
|
||||||
|
if (typeof event === 'string') {
|
||||||
|
// 如果直接是字符串
|
||||||
|
keyword = event;
|
||||||
|
} else if (event && typeof event === 'object') {
|
||||||
|
// 如果是事件对象,尝试多种方式获取值
|
||||||
|
keyword = event.detail?.value ||
|
||||||
|
event.target?.value ||
|
||||||
|
event.value ||
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保更新 searchKeyword
|
||||||
|
searchKeyword.value = keyword;
|
||||||
|
console.log('搜索关键词:', searchKeyword.value);
|
||||||
|
|
||||||
|
// 延迟执行查询,确保 searchKeyword 已更新
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('延迟查询时的searchKeyword:', searchKeyword.value);
|
||||||
|
queryData(false);
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载更多
|
||||||
|
const loadMore = () => {
|
||||||
|
if (!isLoading.value && hasMore.value) {
|
||||||
|
queryData(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取分类文本
|
||||||
|
const getCategoryText = (category: string) => {
|
||||||
|
const categoryMap: Record<string, string> = {
|
||||||
|
'study': '学习交流',
|
||||||
|
'club': '社团活动',
|
||||||
|
'lost': '失物招领',
|
||||||
|
'news': '校园动态'
|
||||||
|
};
|
||||||
|
return categoryMap[category] || category || '未分类';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 跳转详情
|
||||||
|
const goDetail = (item: any) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/view/routine/lt/detail?id=${item.id}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑社区
|
||||||
|
const goEdit = (item: any) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/view/routine/lt/edit?id=${item.id}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建社区
|
||||||
|
const goCreate = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/view/routine/lt/create'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// 先加载Tab数据,再查询列表数据
|
||||||
|
await loadTabData();
|
||||||
|
queryData(false);
|
||||||
|
|
||||||
|
// 监听创建成功后的刷新事件
|
||||||
|
uni.$on('refreshCommunityList', () => {
|
||||||
|
console.log('收到刷新事件,重新加载数据');
|
||||||
|
queryData(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面卸载时移除事件监听
|
||||||
|
onUnmounted(() => {
|
||||||
|
uni.$off('refreshCommunityList');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.forum-community-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
background: #f5f7fa;
|
||||||
|
|
||||||
|
.top-section {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
.search-card {
|
||||||
|
.search-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-button {
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
width: auto !important;
|
||||||
|
min-width: 120rpx !important;
|
||||||
|
height: 80rpx !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-tabs-scroll {
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.filter-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 0 4rpx; // 防止第一个和最后一个Tab贴边
|
||||||
|
min-width: 100%;
|
||||||
|
|
||||||
|
.filter-tab {
|
||||||
|
flex-shrink: 0; // 防止Tab被压缩
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
text-align: center;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
transition: all 0.3s;
|
||||||
|
padding: 0 24rpx; // 给Tab添加内边距
|
||||||
|
white-space: nowrap; // 防止文字换行
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-section {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-scroll-view {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 0; // 关键:触发flex布局中的滚动
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
.loading-indicator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 60rpx 20rpx;
|
||||||
|
|
||||||
|
.loading-icon {
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-item {
|
||||||
|
display: flex;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有图片时的样式
|
||||||
|
&.no-image {
|
||||||
|
.community-info {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-cover {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-info {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
// 没有图片时占满宽度
|
||||||
|
&.full-width {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
|
||||||
|
.community-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-desc {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-meta {
|
||||||
|
display: flex;
|
||||||
|
gap: 32rpx;
|
||||||
|
|
||||||
|
.meta-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-and-edit {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tag {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(0, 122, 255, 0.1);
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: rgba(0, 122, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 12rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空状态
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80rpx 20rpx;
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
font-size: 64rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #4a5568;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-hint {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #a0aec0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载更多状态
|
||||||
|
.loading-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
padding: 40rpx;
|
||||||
|
|
||||||
|
.loading-more-icon {
|
||||||
|
font-size: 36rpx;
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-more-text {
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无更多数据状态
|
||||||
|
.no-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
padding: 48rpx 40rpx;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
background: linear-gradient(135deg, #f7f9fc 0%, #e8f0fe 100%);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
margin-left: 32rpx;
|
||||||
|
margin-right: 32rpx;
|
||||||
|
|
||||||
|
.no-more-icon {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
color: #718096;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-section {
|
||||||
|
flex-shrink: 0;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||||
|
z-index: 100;
|
||||||
|
border-top: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
1106
src/pages/view/routine/lt/postDetail.vue
Normal file
1106
src/pages/view/routine/lt/postDetail.vue
Normal file
File diff suppressed because it is too large
Load Diff
259
src/pages/view/routine/lt/publish.vue
Normal file
259
src/pages/view/routine/lt/publish.vue
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
<template>
|
||||||
|
<view class="publish-post-page">
|
||||||
|
<view class="form-container">
|
||||||
|
<!-- 标题输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="item-label">标题 <text class="required">*</text></view>
|
||||||
|
<u--input
|
||||||
|
v-model="form.title"
|
||||||
|
placeholder="请输入标题(最多50字)"
|
||||||
|
:maxlength="50"
|
||||||
|
:showWordLimit="true"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 内容输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="item-label">内容</view>
|
||||||
|
<u--textarea
|
||||||
|
v-model="form.content"
|
||||||
|
placeholder="分享你的想法..."
|
||||||
|
:maxlength="2000"
|
||||||
|
:count="true"
|
||||||
|
:auto-height="true"
|
||||||
|
:height="300"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 图片视频文档上传 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="item-label">图片视频文档</view>
|
||||||
|
<view class="upload-section">
|
||||||
|
<ImageVideoUpload
|
||||||
|
v-model:image-list="imageList"
|
||||||
|
v-model:video-list="videoList"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:max-image-count="5"
|
||||||
|
:max-video-count="3"
|
||||||
|
:max-file-count="5"
|
||||||
|
:enable-file="true"
|
||||||
|
:allowed-file-types="['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt']"
|
||||||
|
:compress-config="compressConfig"
|
||||||
|
:upload-api="attachmentUpload"
|
||||||
|
@image-upload-success="onImageUploadSuccess"
|
||||||
|
@video-upload-success="onVideoUploadSuccess"
|
||||||
|
@file-upload-success="onFileUploadSuccess"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-buttons">
|
||||||
|
<u-button
|
||||||
|
text="发布"
|
||||||
|
type="primary"
|
||||||
|
@click="publishPost"
|
||||||
|
:loading="submitting"
|
||||||
|
block
|
||||||
|
shape="circle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { postSaveApi } from '@/api/forum';
|
||||||
|
import { attachmentUpload } from '@/api/system/upload';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
import { ImageVideoUpload, type ImageItem, type VideoItem, type FileItem, COMPRESS_PRESETS } from '@/components/ImageVideoUpload';
|
||||||
|
|
||||||
|
// 获取用户store
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
// 社区ID(从详情页跳转过来)
|
||||||
|
const communityId = ref('');
|
||||||
|
|
||||||
|
// 获取当前教师ID
|
||||||
|
const getCurrentTeacherId = () => {
|
||||||
|
const jsData = userStore.getJs;
|
||||||
|
return jsData?.id || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = ref({
|
||||||
|
communityId: '',
|
||||||
|
title: '',
|
||||||
|
content: '',
|
||||||
|
fileUrl: '',
|
||||||
|
fileName: '',
|
||||||
|
fileFormat: '',
|
||||||
|
userId: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
// 压缩配置
|
||||||
|
const compressConfig = ref(COMPRESS_PRESETS.medium);
|
||||||
|
|
||||||
|
// 图片列表
|
||||||
|
const imageList = ref<ImageItem[]>([]);
|
||||||
|
|
||||||
|
// 视频列表
|
||||||
|
const videoList = ref<VideoItem[]>([]);
|
||||||
|
|
||||||
|
// 文件列表
|
||||||
|
const fileList = ref<FileItem[]>([]);
|
||||||
|
|
||||||
|
// 提交状态
|
||||||
|
const submitting = ref(false);
|
||||||
|
|
||||||
|
// 页面加载
|
||||||
|
onLoad((options: any) => {
|
||||||
|
if (options.communityId) {
|
||||||
|
communityId.value = options.communityId;
|
||||||
|
form.value.communityId = options.communityId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 上传成功回调
|
||||||
|
const onImageUploadSuccess = (image: ImageItem, index: number) => {
|
||||||
|
console.log('图片上传成功:', image, index);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onVideoUploadSuccess = (video: VideoItem, index: number) => {
|
||||||
|
console.log('视频上传成功:', video, index);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFileUploadSuccess = (file: FileItem, index: number) => {
|
||||||
|
console.log('文档上传成功:', file, index);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发布帖子
|
||||||
|
const publishPost = async () => {
|
||||||
|
// 表单验证
|
||||||
|
if (!form.value.title) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入标题',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting.value = true;
|
||||||
|
try {
|
||||||
|
// 获取当前用户ID
|
||||||
|
const currentUserId = getCurrentTeacherId();
|
||||||
|
if (!currentUserId) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '无法获取用户信息',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
submitting.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置用户ID
|
||||||
|
form.value.userId = currentUserId;
|
||||||
|
|
||||||
|
// 处理图片、视频和文档
|
||||||
|
const imageUrls = imageList.value
|
||||||
|
.filter(img => img.url)
|
||||||
|
.map(img => img.url)
|
||||||
|
.filter((url): url is string => !!url);
|
||||||
|
|
||||||
|
const videoUrls = videoList.value
|
||||||
|
.filter(video => video.url)
|
||||||
|
.map(video => video.url)
|
||||||
|
.filter((url): url is string => !!url);
|
||||||
|
|
||||||
|
const fileUrls = fileList.value
|
||||||
|
.filter(file => file.url)
|
||||||
|
.map(file => file.url)
|
||||||
|
.filter((url): url is string => !!url);
|
||||||
|
|
||||||
|
// 合并所有URL
|
||||||
|
const allUrls = [...imageUrls, ...videoUrls, ...fileUrls];
|
||||||
|
|
||||||
|
form.value.fileUrl = JSON.stringify(allUrls);
|
||||||
|
form.value.fileName = JSON.stringify(allUrls.map(url => {
|
||||||
|
return url.split('/').pop() || '';
|
||||||
|
}));
|
||||||
|
form.value.fileFormat = JSON.stringify(allUrls.map(url => {
|
||||||
|
return url.split('.').pop() || 'jpg';
|
||||||
|
}));
|
||||||
|
|
||||||
|
await postSaveApi(form.value);
|
||||||
|
|
||||||
|
uni.showToast({
|
||||||
|
title: '发布成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack({
|
||||||
|
success: () => {
|
||||||
|
// 发送刷新事件给detail页面
|
||||||
|
uni.$emit('refreshPostList');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
|
} catch (error: any) {
|
||||||
|
uni.showToast({
|
||||||
|
title: error.message || '发布失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
submitting.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.publish-post-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f5f7fa;
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
padding-bottom: 180rpx;
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 32rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
|
.required {
|
||||||
|
color: #f56c6c;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-section {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-buttons {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@ -17,46 +17,26 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 查询组件 -->
|
<!-- 统计和学期选择 -->
|
||||||
<view class="query-component">
|
<view class="stats-bar">
|
||||||
<view class="search-card">
|
<view class="stats-left">
|
||||||
<view class="search-item">
|
<text class="stats-icon">📖</text>
|
||||||
<uni-search-bar
|
<text class="stats-text">所有课程</text>
|
||||||
v-model="searchForm.kcmc"
|
<text class="stats-count">{{ courseList.length }}门</text>
|
||||||
placeholder="搜索课程名称、教师..."
|
</view>
|
||||||
bgColor="#ffffff"
|
<view class="stats-right">
|
||||||
radius="100"
|
<uni-data-select
|
||||||
cancelButton="none"
|
v-model="searchForm.xqId"
|
||||||
@confirm="handleSearch"
|
:localdata="xqList"
|
||||||
@input="handleSearchInput"
|
placeholder="选择学期"
|
||||||
></uni-search-bar>
|
@change="handleXqChange"
|
||||||
</view>
|
class="xq-select"
|
||||||
<view class="search-actions">
|
></uni-data-select>
|
||||||
<u-button
|
|
||||||
text="查询"
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="handleSearch"
|
|
||||||
class="search-btn"
|
|
||||||
/>
|
|
||||||
<u-button
|
|
||||||
text="重置"
|
|
||||||
type="info"
|
|
||||||
size="small"
|
|
||||||
@click="handleReset"
|
|
||||||
class="reset-btn"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 列表组件 -->
|
<!-- 列表组件 -->
|
||||||
<view class="list-component">
|
<view class="list-component">
|
||||||
<view class="list-header">
|
|
||||||
<text class="list-title-icon">📖</text>
|
|
||||||
<text class="list-title">所有课程</text>
|
|
||||||
<text class="list-subtitle">共 {{ courseList.length }} 门课程</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<scroll-view
|
<scroll-view
|
||||||
scroll-y
|
scroll-y
|
||||||
@ -133,7 +113,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, onMounted } from "vue";
|
import { ref, reactive, onMounted } from "vue";
|
||||||
import { onShow } from "@dcloudio/uni-app";
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
import { kcjbFindPageApi, kcjbBannerApi, kcjbRegisterApi } from "@/api/base/kcjbApi";
|
import { kcjbFindPageApi, kcjbBannerApi, kcjbRegisterApi, getXqList } from "@/api/base/kcjbApi";
|
||||||
import { useUserStore } from "@/store/modules/user";
|
import { useUserStore } from "@/store/modules/user";
|
||||||
|
|
||||||
const { getJs, getUser } = useUserStore();
|
const { getJs, getUser } = useUserStore();
|
||||||
@ -153,9 +133,12 @@ interface CourseItem {
|
|||||||
|
|
||||||
// 搜索表单
|
// 搜索表单
|
||||||
const searchForm = reactive({
|
const searchForm = reactive({
|
||||||
kcmc: '' // 课程名称
|
xqId: '' // 学期ID
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 学期列表
|
||||||
|
const xqList = ref<Array<{ value: string; text: string }>>([]);
|
||||||
|
|
||||||
// 数据列表
|
// 数据列表
|
||||||
const courseList = ref<CourseItem[]>([]);
|
const courseList = ref<CourseItem[]>([]);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
@ -163,20 +146,37 @@ const hasMore = ref(true);
|
|||||||
const currentPage = ref(1);
|
const currentPage = ref(1);
|
||||||
const pageSize = ref(10);
|
const pageSize = ref(10);
|
||||||
|
|
||||||
// 处理搜索输入
|
// 获取学期列表
|
||||||
const handleSearchInput = (value: string) => {
|
const loadXqList = async () => {
|
||||||
searchForm.kcmc = value;
|
try {
|
||||||
|
const response: any = await getXqList();
|
||||||
|
console.log('学期列表原始数据:', response);
|
||||||
|
// 转换数据格式为 uni-data-select 需要的格式
|
||||||
|
const data = Array.isArray(response) ? response : (response?.result || response?.data || response?.rows || []);
|
||||||
|
console.log('提取的学期数据:', data);
|
||||||
|
xqList.value = data.map((item: any) => ({
|
||||||
|
value: item.id,
|
||||||
|
text: item.xqmc || item.name
|
||||||
|
}));
|
||||||
|
console.log('转换后的下拉选项:', xqList.value);
|
||||||
|
|
||||||
|
// 默认选择第一条作为当前学期
|
||||||
|
if (xqList.value.length > 0) {
|
||||||
|
searchForm.xqId = xqList.value[0].value;
|
||||||
|
console.log('默认选择学期:', searchForm.xqId);
|
||||||
|
// 自动触发查询
|
||||||
|
getCourseList(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取学期列表失败:', error);
|
||||||
|
xqList.value = [];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理搜索
|
// 处理学期选择变化
|
||||||
const handleSearch = () => {
|
const handleXqChange = (value: string) => {
|
||||||
console.log('搜索课程名称:', searchForm.kcmc);
|
console.log('选择的学期ID:', value);
|
||||||
getCourseList(false);
|
// 选择学期后自动查询
|
||||||
};
|
|
||||||
|
|
||||||
// 重置搜索
|
|
||||||
const handleReset = () => {
|
|
||||||
searchForm.kcmc = '';
|
|
||||||
getCourseList(false);
|
getCourseList(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ const getCourseList = async (isLoadMore = false) => {
|
|||||||
const params: any = {
|
const params: any = {
|
||||||
page: isLoadMore ? currentPage.value + 1 : 1,
|
page: isLoadMore ? currentPage.value + 1 : 1,
|
||||||
rows: pageSize.value,
|
rows: pageSize.value,
|
||||||
kcmc: searchForm.kcmc
|
xqId: searchForm.xqId
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果不是 admin 用户,则传递当前教师ID进行过滤
|
// 如果不是 admin 用户,则传递当前教师ID进行过滤
|
||||||
@ -298,12 +298,15 @@ const loadMore = () => {
|
|||||||
|
|
||||||
// 页面显示时刷新数据
|
// 页面显示时刷新数据
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
getCourseList(false);
|
// 如果已有学期选择,则查询课程列表
|
||||||
|
if (searchForm.xqId) {
|
||||||
|
getCourseList(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 页面加载时也调用一次
|
// 页面加载时也调用一次
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getCourseList(false);
|
loadXqList(); // 加载学期列表,会自动选择第一条并查询
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -384,33 +387,46 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询组件样式
|
// 统计和学期选择样式
|
||||||
.query-component {
|
.stats-bar {
|
||||||
padding: 16px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 14px 16px;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-bottom: 1px solid #e8ecf1;
|
border-bottom: 1px solid #e9ecef;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
}
|
gap: 12px;
|
||||||
|
|
||||||
.search-card {
|
.stats-left {
|
||||||
.search-item {
|
display: flex;
|
||||||
margin-bottom: 12px;
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
:deep(.uni-searchbar) {
|
.stats-icon {
|
||||||
border: 1px solid #e8ecf1;
|
font-size: 20px;
|
||||||
border-radius: 20px;
|
}
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
||||||
|
.stats-text {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-count {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #4e73df;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-actions {
|
.stats-right {
|
||||||
display: flex;
|
flex: 1;
|
||||||
gap: 10px;
|
max-width: 200px;
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
.search-btn, .reset-btn {
|
.xq-select {
|
||||||
min-width: 70px;
|
width: 100%;
|
||||||
border-radius: 20px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,37 +438,11 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.list-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 16px 16px 12px 16px;
|
|
||||||
background-color: transparent;
|
|
||||||
|
|
||||||
.list-title-icon {
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 1;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #2c3e50;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-subtitle {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #7f8c9a;
|
|
||||||
margin-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-scroll-view {
|
.list-scroll-view {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 0 16px 16px 16px;
|
padding: 12px 16px 16px 16px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
height: 0; // 关键:触发flex布局中的滚动
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,16 +709,29 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 深度选择器用于第三方组件样式调整
|
// 深度选择器用于第三方组件样式调整
|
||||||
:deep(.uni-searchbar__box) {
|
:deep(.stats-right .uni-data-select) {
|
||||||
border-radius: 20px !important;
|
width: 100%;
|
||||||
background-color: #ffffff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.uni-searchbar__text-placeholder) {
|
.uni-select {
|
||||||
color: #a0aec0 !important;
|
background-color: #f8f9fa;
|
||||||
}
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
height: 36px;
|
||||||
|
min-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.uni-searchbar__box-icon-search) {
|
.uni-select__input-text {
|
||||||
color: #4e73df !important;
|
color: #212529;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select__input-placeholder {
|
||||||
|
color: #adb5bd;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select__selector {
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -364,6 +364,7 @@ onMounted(() => {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
height: 0; // 关键:触发flex布局中的滚动
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
src/static/base/view/fire-black.png
Normal file
BIN
src/static/base/view/fire-black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
BIN
src/static/base/view/fire-white.png
Normal file
BIN
src/static/base/view/fire-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
BIN
src/static/base/view/fire.png
Normal file
BIN
src/static/base/view/fire.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
Loading…
x
Reference in New Issue
Block a user