| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- <template>
- <view class="notice_header">
- <!-- 顶部栏 -->
- <view class="header_top">
- <view class="header_left">
- <uni-icons type="back" size="24" color="#333333" @click="goBack"></uni-icons>
- <text class="header_title">{{ title }}</text>
- </view>
- <view v-if="showSearch" class="search_box">
- <image src="/static/image/overview/search.png" class="search_icon" ></image>
- <input type="text" class="search_input" placeholder="请输入关键字搜索" placeholder-class="search_placeholder" v-model="searchWord" @input="handleSearchInput" />
- </view>
- <text v-else-if="showSave" class="save_btn" @click="handleSave">保存</text>
- </view>
- <!-- 过滤栏 -->
- <view v-if="showFilter" class="filter_bar">
- <!-- 通知类型筛选 -->
- <picker mode="selector" :range="typeOptions" :value="typeIndex" @change="handleTypeChange">
- <view class="filter_item">
- <text class="filter_text">{{ typeOptions[typeIndex] }}</text>
- <uni-icons type="down" size="16" color="#999999"></uni-icons>
- </view>
- </picker>
- <!-- 时间筛选 -->
- <picker mode="selector" :range="timeOptions" :value="timeIndex" @change="handleTimeChange">
- <view class="filter_item">
- <text class="filter_text">{{ timeOptions[timeIndex] }}</text>
- <uni-icons type="down" size="16" color="#999999"></uni-icons>
- </view>
- </picker>
- </view>
- <!-- 标签栏 -->
- <view v-if="showTabs" class="tabs_bar">
- <text v-for="(tab, idx) in tabs" :key="idx" class="tab_item" :class="{ active: activeTabIndex === idx }" @click="handleTabChange(idx)">{{ tab }}</text>
- </view>
- </view>
- </template>
- <script setup>
- import { ref, onMounted, computed } from 'vue';
- import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
- import overviewApi from '@/reqApi/overview.js';
- const typeIndex = ref(0);
- const timeIndex = ref(0);
- const typeData = ref([{ id: '0', name: '全部类型' }]);
- const typeOptions = ref(['全部类型']);
- const searchWord = ref('');
- const props = defineProps({
- title: {
- type: String,
- default: ''
- },
- showSearch: {
- type: Boolean,
- default: false
- },
- showSave: {
- type: Boolean,
- default: false
- },
- showFilter: {
- type: Boolean,
- default: false
- },
- timeOptions: {
- type: Array,
- default: () => ['全部时间', '最近3天', '最近7天', '最近1月', '最近3月']
- },
- showTabs: {
- type: Boolean,
- default: false
- },
- tabs: {
- type: Array,
- default: () => ['全部', '待发布', '已发布', '已关闭']
- },
- activeTab: {
- type: Number,
- default: -1
- },
- tabMode: {
- type: String,
- default: 'status',
- validator: (value) => ['status', 'index'].includes(value)
- }
- });
- const activeTabIndex = computed(() => {
- if (props.tabMode === 'index') {
- return props.activeTab;
- }
- const statusMap = [-1, 0, 1, 2];
- return statusMap.indexOf(props.activeTab);
- });
- const emit = defineEmits(['save', 'tabChange', 'typeChange', 'timeChange', 'searchChange']);
- const fetchNoticeTypeList = async () => {
- try {
- const res = await overviewApi.noticeTypeList();
- if (res.data && Array.isArray(res.data)) {
- const types = res.data.map(item => ({
- id: item.id,
- name: item.name
- }));
- typeData.value = [{ id: '0', name: '全部类型' }, ...types];
- typeOptions.value = ['全部类型', ...types.map(item => item.name)];
- }
- } catch (error) {
- console.error('获取通知类型失败:', error);
- }
- };
- onMounted(() => {
- fetchNoticeTypeList();
- });
- const handleTabChange = (idx) => {
- if (props.tabMode === 'index') {
- emit('tabChange', idx);
- } else {
- const statusMap = [-1, 0, 1, 2];
- emit('tabChange', statusMap[idx]);
- }
- };
- const handleTypeChange = (e) => {
- typeIndex.value = e.detail.value;
- const selectedItem = typeData.value[typeIndex.value];
- emit('typeChange', selectedItem.id);
- };
- const handleTimeChange = (e) => {
- timeIndex.value = e.detail.value;
- emit('timeChange', timeIndex.value);
- };
- const goBack = () => {
- uni.switchTab({
- url: '/pages/workspace/index'
- });
- };
- const handleSave = () => {
- emit('save');
- };
- const handleSearchInput = () => {
- emit('searchChange', searchWord.value);
- };
- </script>
- <style lang="scss" scoped>
- .notice_header {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- display: flex;
- flex-direction: column;
- background-color: #FFFFFF;
- z-index: 999;
- padding-top: env(safe-area-inset-top);
- // border-bottom: 2rpx solid #EBEEF5;
- .header_top {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 24rpx;
- .header_left {
- display: flex;
- align-items: center;
- .header_title {
- font-weight: 600;
- font-size: 44rpx;
- color: #333333;
- margin-left: 24rpx;
- }
- }
- .search_box {
- display: flex;
- align-items: center;
- background-color: #fff;
- border-radius: 8rpx;
- padding: 14rpx 24rpx;
- width: 265rpx;
- border: 2rpx solid #DCDFE6;
- .search_icon {
- width: 32rpx;
- height: 32rpx;
- margin-right: 8rpx;
- }
- .search_input {
- flex: 1;
- font-size: 24rpx;
- color: #333333;
- margin-left: 8rpx;
- }
- .search_placeholder {
- color: #999999;
- }
- }
- .save_btn {
- font-size: 28rpx;
- color: #2E64FA;
- font-weight: 500;
- }
- }
- .filter_bar {
- display: flex;
- gap: 32rpx;
- padding: 20rpx 24rpx;
- background-color: #FFFFFF;
- border-top: 1rpx solid #F0F0F0;
- .filter_item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 20rpx 16rpx;
- background-color: #FFFFFF;
- border-radius: 8rpx;
- min-width: 240rpx;
- // height: 72rpx;
- border: 2rpx solid #DCDFE6;
- .filter_text {
- font-size: 28rpx;
- color: #333333;
- margin-right: 8rpx;
- }
- }
- }
- .tabs_bar {
- display: flex;
- height: 56rpx;
- padding:4rpx 24rpx 24rpx 24rpx;
- .tab_item {
- font-size: 32rpx;
- color: #999999;
- font-weight: 400;
- position: relative;
- margin-right: 48rpx;
- &.active {
- color: #2E64FA;
- font-weight: 500;
- &::after {
- content: '';
- position: absolute;
- bottom: 0rpx;
- left: 50%;
- transform: translateX(-50%);
- width: 48rpx;
- height: 4rpx;
- background-color: #2E64FA;
- // border-radius: 2rpx;
- }
- }
- }
- }
- }
- </style>
|