|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <view class="notice_header">
|
|
|
|
|
|
|
+ <view class="notice_header" :style="{ paddingTop: statusBarHeight + 'rpx' }">
|
|
|
<!-- 顶部栏 -->
|
|
<!-- 顶部栏 -->
|
|
|
<view class="header_top">
|
|
<view class="header_top">
|
|
|
<view class="header_left">
|
|
<view class="header_left">
|
|
@@ -12,16 +12,14 @@
|
|
|
</view>
|
|
</view>
|
|
|
<text v-else-if="showSave" class="save_btn" @click="handleSave">保存</text>
|
|
<text v-else-if="showSave" class="save_btn" @click="handleSave">保存</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 过滤栏 -->
|
|
|
|
|
- <view v-if="showFilter" class="filter_bar">
|
|
|
|
|
- <!-- 通知类型筛选 -->
|
|
|
|
|
|
|
+ <!-- 通知模式过滤栏 -->
|
|
|
|
|
+ <view v-if="showFilter && mode === 'notice'" class="filter_bar">
|
|
|
<picker mode="selector" :range="typeOptions" :value="typeIndex" @change="handleTypeChange">
|
|
<picker mode="selector" :range="typeOptions" :value="typeIndex" @change="handleTypeChange">
|
|
|
<view class="filter_item">
|
|
<view class="filter_item">
|
|
|
<text class="filter_text">{{ typeOptions[typeIndex] }}</text>
|
|
<text class="filter_text">{{ typeOptions[typeIndex] }}</text>
|
|
|
<uni-icons type="down" size="16" color="#999999"></uni-icons>
|
|
<uni-icons type="down" size="16" color="#999999"></uni-icons>
|
|
|
</view>
|
|
</view>
|
|
|
</picker>
|
|
</picker>
|
|
|
- <!-- 时间筛选 -->
|
|
|
|
|
<picker mode="selector" :range="timeOptions" :value="timeIndex" @change="handleTimeChange">
|
|
<picker mode="selector" :range="timeOptions" :value="timeIndex" @change="handleTimeChange">
|
|
|
<view class="filter_item">
|
|
<view class="filter_item">
|
|
|
<text class="filter_text">{{ timeOptions[timeIndex] }}</text>
|
|
<text class="filter_text">{{ timeOptions[timeIndex] }}</text>
|
|
@@ -29,10 +27,40 @@
|
|
|
</view>
|
|
</view>
|
|
|
</picker>
|
|
</picker>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 标签栏 -->
|
|
|
|
|
- <view v-if="showTabs" class="tabs_bar">
|
|
|
|
|
|
|
+ <!-- 通知模式标签栏 -->
|
|
|
|
|
+ <view v-if="showTabs && mode === 'notice'" class="tabs_bar">
|
|
|
<text v-for="(tab, idx) in tabs" :key="idx" class="tab_item" :class="{ active: activeTabIndex === idx }" @click="handleTabChange(idx)">{{ tab }}</text>
|
|
<text v-for="(tab, idx) in tabs" :key="idx" class="tab_item" :class="{ active: activeTabIndex === idx }" @click="handleTabChange(idx)">{{ tab }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 任务总览模式过滤栏 -->
|
|
|
|
|
+ <view v-if="showFilter && mode === 'taskOverview'" class="filter_bar task_overview_filter">
|
|
|
|
|
+ <picker mode="selector" class="picker_wide" :range="academicYearOptions" :value="academicYearIndex" @change="handleAcademicYearChange">
|
|
|
|
|
+ <view class="filter_item">
|
|
|
|
|
+ <text class="filter_text">{{ academicYearOptions[academicYearIndex] }}</text>
|
|
|
|
|
+ <uni-icons type="down" size="16" color="#999999"></uni-icons>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </picker>
|
|
|
|
|
+ <picker mode="selector" class="picker_narrow" :range="categoryOptions" :value="categoryIndex" @change="handleCategoryChange">
|
|
|
|
|
+ <view class="filter_item">
|
|
|
|
|
+ <text class="filter_text">{{ categoryOptions[categoryIndex] }}</text>
|
|
|
|
|
+ <uni-icons type="down" size="16" color="#999999"></uni-icons>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </picker>
|
|
|
|
|
+ <picker mode="selector" class="picker_narrow" :range="materialTypeOptions" :value="materialTypeIndex" @change="handleMaterialTypeChange">
|
|
|
|
|
+ <view class="filter_item">
|
|
|
|
|
+ <text class="filter_text">{{ materialTypeOptions[materialTypeIndex] }}</text>
|
|
|
|
|
+ <uni-icons type="down" size="16" color="#999999"></uni-icons>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </picker>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 任务总览模式标签栏 -->
|
|
|
|
|
+ <view v-if="(showTabs || showCreateBtn) && mode === 'taskOverview'" class="tabs_bar task_overview_tabs">
|
|
|
|
|
+ <text v-for="(tab, idx) in tabs" :key="idx" class="tab_item" :class="{ active: activeTabIndex === idx }" @click="handleTabChange(idx)">{{ tab }}</text>
|
|
|
|
|
+ <view v-if="showCreateBtn" class="create_btn" @click="handleCreate">
|
|
|
|
|
+ <image src="/static/image/workspace/add.png" class="add_icon" mode="aspectFit"></image>
|
|
|
|
|
+ <text class="create_text">新建</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -40,6 +68,9 @@
|
|
|
import { ref, onMounted, computed } from 'vue';
|
|
import { ref, onMounted, computed } from 'vue';
|
|
|
import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
|
|
import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
|
|
|
import overviewApi from '@/reqApi/overview.js';
|
|
import overviewApi from '@/reqApi/overview.js';
|
|
|
|
|
+import { useSafeArea } from '@/common/safeArea';
|
|
|
|
|
+
|
|
|
|
|
+const { statusBarHeight, initSafeArea } = useSafeArea();
|
|
|
|
|
|
|
|
const typeIndex = ref(0);
|
|
const typeIndex = ref(0);
|
|
|
const timeIndex = ref(0);
|
|
const timeIndex = ref(0);
|
|
@@ -47,11 +78,20 @@ const typeData = ref([{ id: '0', name: '全部类型' }]);
|
|
|
const typeOptions = ref(['全部类型']);
|
|
const typeOptions = ref(['全部类型']);
|
|
|
const searchWord = ref('');
|
|
const searchWord = ref('');
|
|
|
|
|
|
|
|
|
|
+const academicYearIndex = ref(0);
|
|
|
|
|
+const categoryIndex = ref(0);
|
|
|
|
|
+const materialTypeIndex = ref(0);
|
|
|
|
|
+
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
title: {
|
|
title: {
|
|
|
type: String,
|
|
type: String,
|
|
|
default: ''
|
|
default: ''
|
|
|
},
|
|
},
|
|
|
|
|
+ mode: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: 'notice',
|
|
|
|
|
+ validator: (value) => ['notice', 'taskOverview'].includes(value)
|
|
|
|
|
+ },
|
|
|
showSearch: {
|
|
showSearch: {
|
|
|
type: Boolean,
|
|
type: Boolean,
|
|
|
default: false
|
|
default: false
|
|
@@ -68,10 +108,26 @@ const props = defineProps({
|
|
|
type: Array,
|
|
type: Array,
|
|
|
default: () => ['全部时间', '最近3天', '最近7天', '最近1月', '最近3月']
|
|
default: () => ['全部时间', '最近3天', '最近7天', '最近1月', '最近3月']
|
|
|
},
|
|
},
|
|
|
|
|
+ academicYearOptions: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => ['2025-2026学年', '2024-2025学年', '2023-2024学年']
|
|
|
|
|
+ },
|
|
|
|
|
+ categoryOptions: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => ['全部分类', '日常教学', '考试测评', '教研活动']
|
|
|
|
|
+ },
|
|
|
|
|
+ materialTypeOptions: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => ['全部类目', '教案', '课件', '试卷', '作业']
|
|
|
|
|
+ },
|
|
|
showTabs: {
|
|
showTabs: {
|
|
|
type: Boolean,
|
|
type: Boolean,
|
|
|
default: false
|
|
default: false
|
|
|
},
|
|
},
|
|
|
|
|
+ showCreateBtn: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
tabs: {
|
|
tabs: {
|
|
|
type: Array,
|
|
type: Array,
|
|
|
default: () => ['全部', '待发布', '已发布', '已关闭']
|
|
default: () => ['全部', '待发布', '已发布', '已关闭']
|
|
@@ -95,7 +151,10 @@ const activeTabIndex = computed(() => {
|
|
|
return statusMap.indexOf(props.activeTab);
|
|
return statusMap.indexOf(props.activeTab);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const emit = defineEmits(['save', 'tabChange', 'typeChange', 'timeChange', 'searchChange']);
|
|
|
|
|
|
|
+const emit = defineEmits([
|
|
|
|
|
+ 'save', 'tabChange', 'typeChange', 'timeChange', 'searchChange',
|
|
|
|
|
+ 'academicYearChange', 'categoryChange', 'materialTypeChange', 'create'
|
|
|
|
|
+]);
|
|
|
|
|
|
|
|
const fetchNoticeTypeList = async () => {
|
|
const fetchNoticeTypeList = async () => {
|
|
|
try {
|
|
try {
|
|
@@ -114,7 +173,10 @@ const fetchNoticeTypeList = async () => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
- fetchNoticeTypeList();
|
|
|
|
|
|
|
+ initSafeArea();
|
|
|
|
|
+ if (props.mode === 'notice') {
|
|
|
|
|
+ fetchNoticeTypeList();
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const handleTabChange = (idx) => {
|
|
const handleTabChange = (idx) => {
|
|
@@ -137,8 +199,23 @@ const handleTimeChange = (e) => {
|
|
|
emit('timeChange', timeIndex.value);
|
|
emit('timeChange', timeIndex.value);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const handleAcademicYearChange = (e) => {
|
|
|
|
|
+ academicYearIndex.value = e.detail.value;
|
|
|
|
|
+ emit('academicYearChange', academicYearIndex.value);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleCategoryChange = (e) => {
|
|
|
|
|
+ categoryIndex.value = e.detail.value;
|
|
|
|
|
+ emit('categoryChange', categoryIndex.value);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleMaterialTypeChange = (e) => {
|
|
|
|
|
+ materialTypeIndex.value = e.detail.value;
|
|
|
|
|
+ emit('materialTypeChange', materialTypeIndex.value);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
|
- uni.switchTab({
|
|
|
|
|
|
|
+ uni.redirectTo({
|
|
|
url: '/pages/workspace/index'
|
|
url: '/pages/workspace/index'
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
@@ -150,6 +227,10 @@ const handleSave = () => {
|
|
|
const handleSearchInput = () => {
|
|
const handleSearchInput = () => {
|
|
|
emit('searchChange', searchWord.value);
|
|
emit('searchChange', searchWord.value);
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+const handleCreate = () => {
|
|
|
|
|
+ emit('create');
|
|
|
|
|
+};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -162,8 +243,6 @@ const handleSearchInput = () => {
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
background-color: #FFFFFF;
|
|
background-color: #FFFFFF;
|
|
|
z-index: 999;
|
|
z-index: 999;
|
|
|
- padding-top: env(safe-area-inset-top);
|
|
|
|
|
- // border-bottom: 2rpx solid #EBEEF5;
|
|
|
|
|
|
|
|
|
|
.header_top {
|
|
.header_top {
|
|
|
display: flex;
|
|
display: flex;
|
|
@@ -232,7 +311,6 @@ const handleSearchInput = () => {
|
|
|
background-color: #FFFFFF;
|
|
background-color: #FFFFFF;
|
|
|
border-radius: 8rpx;
|
|
border-radius: 8rpx;
|
|
|
min-width: 240rpx;
|
|
min-width: 240rpx;
|
|
|
- // height: 72rpx;
|
|
|
|
|
border: 2rpx solid #DCDFE6;
|
|
border: 2rpx solid #DCDFE6;
|
|
|
|
|
|
|
|
.filter_text {
|
|
.filter_text {
|
|
@@ -243,10 +321,36 @@ const handleSearchInput = () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .task_overview_filter {
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .picker_wide {
|
|
|
|
|
+ flex: 1.2;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .picker_narrow {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .filter_item {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ padding: 16rpx 12rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ .filter_text {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.tabs_bar {
|
|
.tabs_bar {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
height: 56rpx;
|
|
height: 56rpx;
|
|
|
- padding:4rpx 24rpx 24rpx 24rpx;
|
|
|
|
|
|
|
+ padding: 4rpx 24rpx 12rpx 24rpx;
|
|
|
|
|
+
|
|
|
.tab_item {
|
|
.tab_item {
|
|
|
font-size: 32rpx;
|
|
font-size: 32rpx;
|
|
|
color: #999999;
|
|
color: #999999;
|
|
@@ -264,13 +368,48 @@ const handleSearchInput = () => {
|
|
|
bottom: 0rpx;
|
|
bottom: 0rpx;
|
|
|
left: 50%;
|
|
left: 50%;
|
|
|
transform: translateX(-50%);
|
|
transform: translateX(-50%);
|
|
|
- width: 48rpx;
|
|
|
|
|
|
|
+ width: 100%;
|
|
|
height: 4rpx;
|
|
height: 4rpx;
|
|
|
background-color: #2E64FA;
|
|
background-color: #2E64FA;
|
|
|
- // border-radius: 2rpx;
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .task_overview_tabs {
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 72rpx;
|
|
|
|
|
+ .tab_item {
|
|
|
|
|
+ margin-right: 48rpx;
|
|
|
|
|
+ &.active {
|
|
|
|
|
+
|
|
|
|
|
+ &::after {
|
|
|
|
|
+ bottom: -8rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .create_btn {
|
|
|
|
|
+ margin-left: auto;
|
|
|
|
|
+ background-color: #2E64FA;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ width: 148rpx;
|
|
|
|
|
+ height: 72rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ gap: 8rpx;
|
|
|
|
|
+ .add_icon {
|
|
|
|
|
+ width: 32rpx;
|
|
|
|
|
+ height: 32rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .create_text {
|
|
|
|
|
+ color: #FFFFFF;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|