Merge branch 'develop' of gitee.com:youlaiorg/vue-uniapp-template into develop
This commit is contained in:
201
src/api/system/notice.ts
Normal file
201
src/api/system/notice.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
const NOTICE_BASE_URL = "/api/v1/notices";
|
||||
|
||||
const NoticeAPI = {
|
||||
/** 获取通知公告分页数据 */
|
||||
getPage(queryParams?: NoticePageQuery) {
|
||||
return request<PageResult<NoticePageVO[]>>({
|
||||
url: `${NOTICE_BASE_URL}/page`,
|
||||
method: "GET",
|
||||
data: queryParams,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取通知公告表单数据
|
||||
*
|
||||
* @param id NoticeID
|
||||
* @returns Notice表单数据
|
||||
*/
|
||||
getFormData(id: number) {
|
||||
return request<NoticeForm>({
|
||||
url: `${NOTICE_BASE_URL}/${id}/form`,
|
||||
method: "GET",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加通知公告
|
||||
*
|
||||
* @param data Notice表单数据
|
||||
* @returns
|
||||
*/
|
||||
add(data: NoticeForm) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}`,
|
||||
method: "POST",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新通知公告
|
||||
*
|
||||
* @param id NoticeID
|
||||
* @param data Notice表单数据
|
||||
*/
|
||||
update(id: number, data: NoticeForm) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}/${id}`,
|
||||
method: "PUT",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量删除通知公告,多个以英文逗号(,)分割
|
||||
*
|
||||
* @param ids 通知公告ID字符串,多个以英文逗号(,)分割
|
||||
*/
|
||||
deleteByIds(ids: string) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}/${ids}`,
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布通知
|
||||
*
|
||||
* @param id 被发布的通知公告id
|
||||
* @returns
|
||||
*/
|
||||
publish(id: number) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}/${id}/publish`,
|
||||
method: "PUT",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 撤回通知
|
||||
*
|
||||
* @param id 撤回的通知id
|
||||
* @returns
|
||||
*/
|
||||
revoke(id: number) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}/${id}/revoke`,
|
||||
method: "PUT",
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 查看通知
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
getDetail(id: string) {
|
||||
return request<NoticeDetailVO>({
|
||||
url: `${NOTICE_BASE_URL}/${id}/detail`,
|
||||
method: "GET",
|
||||
});
|
||||
},
|
||||
|
||||
/* 全部已读 */
|
||||
readAll() {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}/read-all`,
|
||||
method: "PUT",
|
||||
});
|
||||
},
|
||||
|
||||
/** 获取我的通知分页列表 */
|
||||
getMyNoticePage(queryParams?: NoticePageQuery) {
|
||||
return request<PageResult<NoticePageVO[]>>({
|
||||
url: `${NOTICE_BASE_URL}/my-page`,
|
||||
method: "GET",
|
||||
data: queryParams,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default NoticeAPI;
|
||||
|
||||
/** 通知公告分页查询参数 */
|
||||
export interface NoticePageQuery extends PageQuery {
|
||||
/** 标题 */
|
||||
title?: string;
|
||||
/** 发布状态(0:未发布,1:已发布,-1:已撤回) */
|
||||
publishStatus?: number;
|
||||
|
||||
isRead?: number;
|
||||
}
|
||||
|
||||
/** 通知公告表单对象 */
|
||||
export interface NoticeForm {
|
||||
id?: number;
|
||||
/** 通知标题 */
|
||||
title?: string;
|
||||
/** 通知内容 */
|
||||
content?: string;
|
||||
/** 通知类型 */
|
||||
type?: number;
|
||||
/** 优先级(L:低,M:中,H:高) */
|
||||
level?: string;
|
||||
/** 目标类型(1-全体 2-指定) */
|
||||
targetType?: number;
|
||||
/** 目标ID合集,以,分割 */
|
||||
targetUserIds?: string;
|
||||
}
|
||||
|
||||
/** 通知公告分页对象 */
|
||||
export interface NoticePageVO {
|
||||
id: string;
|
||||
/** 通知标题 */
|
||||
title?: string;
|
||||
/** 通知内容 */
|
||||
content?: string;
|
||||
/** 通知类型 */
|
||||
type?: number;
|
||||
/** 发布人 */
|
||||
publisherName?: string;
|
||||
/** 优先级(0-低 1-中 2-高) */
|
||||
priority?: number;
|
||||
/** 目标类型(0-全体 1-指定) */
|
||||
targetType?: number;
|
||||
/** 发布状态(0-未发布 1已发布 2已撤回) */
|
||||
publishStatus?: number;
|
||||
/** 发布时间 */
|
||||
publishTime?: Date;
|
||||
/** 撤回时间 */
|
||||
revokeTime?: Date;
|
||||
/** 优先级(L-低 M-中 H-高) */
|
||||
level?: string | number;
|
||||
}
|
||||
|
||||
export interface NoticeDetailVO {
|
||||
/** 通知ID */
|
||||
id?: string;
|
||||
|
||||
/** 通知标题 */
|
||||
title?: string;
|
||||
|
||||
/** 通知内容 */
|
||||
content?: string;
|
||||
|
||||
/** 通知类型 */
|
||||
type?: number;
|
||||
|
||||
/** 发布人 */
|
||||
publisherName?: string;
|
||||
|
||||
/** 优先级(L-低 M-中 H-高) */
|
||||
level?: string;
|
||||
|
||||
/** 发布时间 */
|
||||
publishTime?: Date;
|
||||
|
||||
/** 发布状态 */
|
||||
publishStatus?: number;
|
||||
}
|
||||
@@ -50,7 +50,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/work/config/config",
|
||||
"path": "pages/work/config/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "系统配置"
|
||||
}
|
||||
@@ -60,6 +60,18 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "配置详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/work/notice/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "通知公告"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/work/notice/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "通知详情"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
277
src/pages/work/config/index.vue
Normal file
277
src/pages/work/config/index.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<view class="work">
|
||||
<!-- 筛选 -->
|
||||
<wd-drop-menu
|
||||
close-on-click-modal
|
||||
class="mb-20rpx"
|
||||
style="margin-right: 20rpx; margin-left: 20rpx"
|
||||
>
|
||||
<wd-drop-menu-item
|
||||
ref="dropMenu"
|
||||
title="筛选"
|
||||
icon="filter"
|
||||
icon-size="18px"
|
||||
@opened="handleOpened"
|
||||
>
|
||||
<view>
|
||||
<wd-input
|
||||
v-model="queryParams.keywords"
|
||||
label="关键字"
|
||||
type="text"
|
||||
placeholder="请输入关键字"
|
||||
/>
|
||||
<view class="flex flex-row items-center mb-20rpx">
|
||||
<wd-button class="mt-20rpx mb-20rpx" size="medium" @click="search()">查询</wd-button>
|
||||
<wd-button size="medium" type="info" @click="reset">重置</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-drop-menu-item>
|
||||
</wd-drop-menu>
|
||||
|
||||
<!-- 列表 -->
|
||||
<scroll-view scroll-y class="list-container">
|
||||
<view
|
||||
v-for="(item, index) in pageData"
|
||||
:key="index"
|
||||
class="card"
|
||||
style="margin: 20rpx; border-bottom: 1px solid #ccc"
|
||||
@click="itemClicked(item)"
|
||||
>
|
||||
<view class="card-content" style="padding: 20rpx; margin: 20rpx">
|
||||
<view class="item">
|
||||
<view class="title">配置名称:{{ item.configName }}</view>
|
||||
<view class="content">
|
||||
<!-- <view class="row">-->
|
||||
<!-- <view class="label">配置名称:</view>-->
|
||||
<!-- <view class="value">{{ item.configName }}</view>-->
|
||||
<!-- </view>-->
|
||||
<view class="row">
|
||||
<view class="label">配置键:</view>
|
||||
<view class="value">{{ item.configKey }}</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="label">配置值:</view>
|
||||
<view class="value">{{ item.configValue }}</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="label">备注:</view>
|
||||
<view class="value">{{ item.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-loadmore :state="state" @reload="handleQuery" />
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view
|
||||
class="footer-buttons"
|
||||
style="
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 20rpx;
|
||||
background-color: #fff;
|
||||
"
|
||||
>
|
||||
<wd-button size="medium" type="primary" @click="add">添加</wd-button>
|
||||
<wd-button size="medium" type="success" @click="refreshCache">刷新缓存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ConfigAPI, { ConfigPageVO, ConfigForm, ConfigPageQuery } from "@/api/system/config";
|
||||
import { DropMenuItemExpose } from "wot-design-uni/components/wd-drop-menu-item/types";
|
||||
import { LoadMoreState } from "wot-design-uni/components/wd-loadmore/types";
|
||||
|
||||
const state = ref<LoadMoreState>("loading"); // 加载状态 loading, finished:, error
|
||||
const loading = ref(false);
|
||||
const total = ref(0);
|
||||
const queryParams = reactive<ConfigPageQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
keywords: "",
|
||||
});
|
||||
// 系统配置表格数据
|
||||
const pageData = ref<ConfigPageVO[]>([]);
|
||||
/**
|
||||
* 搜索栏
|
||||
*/
|
||||
const dropMenu = ref<DropMenuItemExpose>();
|
||||
|
||||
function search() {
|
||||
pageData.value = [];
|
||||
dropMenu.value?.close();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置搜索条件
|
||||
*/
|
||||
function reset() {
|
||||
queryParams.pageNum = 1;
|
||||
queryParams.keywords = "";
|
||||
// queryParams.createTime = ["", ""];
|
||||
// timeStampArray.value = [];
|
||||
pageData.value = [];
|
||||
dropMenu.value?.close();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理下拉菜单打开事件
|
||||
*/
|
||||
function handleOpened() {
|
||||
// 在这里可以添加处理下拉菜单打开时的逻辑
|
||||
console.log("下拉菜单已打开");
|
||||
}
|
||||
|
||||
/**
|
||||
* 触底事件
|
||||
*/
|
||||
onReachBottom(() => {
|
||||
queryParams.pageNum++;
|
||||
handleQuery();
|
||||
});
|
||||
|
||||
function handleQuery() {
|
||||
state.value = "loading";
|
||||
ConfigAPI.getPage(queryParams)
|
||||
.then((data) => {
|
||||
pageData.value = data.list;
|
||||
total.value = data.total;
|
||||
// // 计算当前已加载的条数
|
||||
// const loadedCount = queryParams.pageNum * queryParams.pageSize;
|
||||
//
|
||||
// // 判断是否需要加载下一页
|
||||
// if (loadedCount < total.value) {
|
||||
// queryParams.pageNum++;
|
||||
// // 调用 handleQuery 继续加载下一页
|
||||
// handleQuery();
|
||||
// }
|
||||
})
|
||||
.finally(() => {
|
||||
state.value = "finished";
|
||||
});
|
||||
}
|
||||
|
||||
function add() {
|
||||
// 跳转到指定页面
|
||||
uni.navigateTo({
|
||||
url: "/pages/work/config/item",
|
||||
});
|
||||
}
|
||||
|
||||
function refreshCache() {
|
||||
ConfigAPI.refreshCache().then(() => {
|
||||
uni.showToast({
|
||||
title: "刷新缓存成功",
|
||||
icon: "success",
|
||||
duration: 1000, // 显示时间,单位为毫秒,设置为 0 则不会自动消失
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function itemClicked(item: ConfigPageVO) {
|
||||
console.log(item);
|
||||
|
||||
// 直接传递整个 item 对象
|
||||
uni.navigateTo({
|
||||
url: "/pages/work/system/config/item?item=" + encodeURIComponent(JSON.stringify(item)),
|
||||
});
|
||||
}
|
||||
|
||||
// 新增 onShow 方法
|
||||
onShow(() => {
|
||||
handleQuery(); // 重新加载数据
|
||||
});
|
||||
|
||||
onLoad(() => {
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/* stylelint-disable selector-type-no-unknown */
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
/* stylelint-enable selector-type-no-unknown */
|
||||
|
||||
.work {
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
::v-deep .wd-drop-menu__item {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 50rpx;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
height: calc(100vh - 350rpx); /* 调整高度以避免被底部按钮挡住 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
//margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 10rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
padding: 10rpx;
|
||||
margin: 10rpx;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.row-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0rpx; /* 调整 label 和 value 之间的间距 */
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%; /* 调整宽度以适应两列布局 */
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1; /* 让 label 占据剩余空间的一部分 */
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 3; /* 让 value 占据剩余空间的大部分 */
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
@@ -51,12 +51,13 @@ const gridList = reactive([
|
||||
{
|
||||
icon: "/static/icons/config.png",
|
||||
title: "系统配置",
|
||||
url: "/pages/work/config",
|
||||
url: "/pages/work/config/index",
|
||||
prem: "sys:config:query",
|
||||
},
|
||||
{
|
||||
icon: "/static/icons/notice.png",
|
||||
title: "通知公告",
|
||||
url: "/pages/work/notice/index",
|
||||
prem: "sys:notice:query",
|
||||
},
|
||||
],
|
||||
|
||||
148
src/pages/work/notice/detail.vue
Normal file
148
src/pages/work/notice/detail.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="notice-detail">
|
||||
<wd-cell-group>
|
||||
<div class="notice-header">
|
||||
<h2 class="notice-title">
|
||||
<wd-icon name="prompt" size="20px" class="title-icon" />
|
||||
{{ noticeDetail.title }}
|
||||
</h2>
|
||||
<div class="notice-meta">
|
||||
<div class="meta-row">
|
||||
<span>发布人:{{ noticeDetail.publisherName }}</span>
|
||||
<wd-divider direction="vertical" />
|
||||
<span>发布时间:{{ formatDate(noticeDetail.publishTime ?? "") }}</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="priority-wrapper">
|
||||
优先级:
|
||||
<wd-tag :type="getLevelType(noticeDetail.level) as TagType">
|
||||
{{ getLevelText(noticeDetail.level) }}
|
||||
</wd-tag>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<wd-divider />
|
||||
<div class="notice-content" v-html="noticeDetail.content" />
|
||||
</wd-cell-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import type { NoticeDetailVO } from "@/api/system/notice";
|
||||
import NoticeAPI from "@/api/system/notice";
|
||||
import { TagType } from "wot-design-uni/components/wd-tag/types";
|
||||
|
||||
const route = useRoute();
|
||||
const noticeDetail = ref<NoticeDetailVO>({});
|
||||
|
||||
const getLevelColor = (level?: string) => {
|
||||
const colorMap: Record<string, string> = {
|
||||
L: "blue",
|
||||
M: "orange",
|
||||
H: "red",
|
||||
};
|
||||
return colorMap[level || "L"];
|
||||
};
|
||||
|
||||
const getLevelText = (level?: string) => {
|
||||
const textMap: Record<string, string> = {
|
||||
L: "低",
|
||||
M: "中",
|
||||
H: "高",
|
||||
};
|
||||
return textMap[level || "L"];
|
||||
};
|
||||
const getLevelType = (level?: string) => {
|
||||
const typeMap: Record<string, string> = {
|
||||
L: "primary",
|
||||
M: "warning",
|
||||
H: "danger",
|
||||
};
|
||||
return typeMap[level || "L"];
|
||||
};
|
||||
|
||||
const getNoticeDetail = async () => {
|
||||
try {
|
||||
const res = await NoticeAPI.getDetail(route.query.id as string);
|
||||
console.log(res);
|
||||
noticeDetail.value = res;
|
||||
} catch (error) {
|
||||
console.error("获取通知详情失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (date: string | Date): string => {
|
||||
return date ? date.toString().split(" ")[0] : "-";
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getNoticeDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.notice-detail {
|
||||
padding: 12px;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.notice-header {
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.notice-title {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title-icon {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.notice-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.priority-wrapper {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notice-content {
|
||||
padding: 16px;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
:deep(.wd-divider) {
|
||||
margin: 0 8px;
|
||||
}
|
||||
</style>
|
||||
306
src/pages/work/notice/index.vue
Normal file
306
src/pages/work/notice/index.vue
Normal file
@@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<view class="notice-container">
|
||||
<!-- 添加搜索栏 -->
|
||||
<wd-drop-menu close-on-click-modal class="mb-20rpx">
|
||||
<wd-drop-menu-item ref="dropMenu" title="筛选" icon="filter" icon-size="18px">
|
||||
<view>
|
||||
<wd-input
|
||||
v-model="queryParams.title"
|
||||
label="关键字"
|
||||
type="text"
|
||||
placeholder="请输入关键字"
|
||||
/>
|
||||
|
||||
<view class="flex flex-row items-center mb-20rpx">
|
||||
<wd-button class="mt-20rpx mb-20rpx" size="medium" @click="handleSearch()">
|
||||
查询
|
||||
</wd-button>
|
||||
<wd-button size="medium" type="info" @click="reset">重置</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-drop-menu-item>
|
||||
</wd-drop-menu>
|
||||
|
||||
<!-- 列表内容 -->
|
||||
<view v-for="(item, index) in dataList" :key="index" class="mb-20rpx">
|
||||
<wd-card>
|
||||
<template #title>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="flex-1 text-truncate">{{ item.title }}</view>
|
||||
<wd-tag :type="getStatusType(item.publishStatus)" size="small">
|
||||
{{ getStatusText(item.publishStatus) }}
|
||||
</wd-tag>
|
||||
</view>
|
||||
</template>
|
||||
<wd-row class="mb-20rpx">
|
||||
<wd-col :span="12">
|
||||
<wd-col :span="12">
|
||||
<view>通告目标类型:</view>
|
||||
</wd-col>
|
||||
<wd-col :span="12">
|
||||
<view>{{ item.targetType === 1 ? "指定" : "全体" }}</view>
|
||||
</wd-col>
|
||||
</wd-col>
|
||||
<wd-col v-if="item.publishStatus === 1" :span="12">
|
||||
<wd-col :span="8">
|
||||
<view>发布时间:</view>
|
||||
</wd-col>
|
||||
<wd-col :span="16">
|
||||
<view>{{ formatDate(item.publishTime) }}</view>
|
||||
</wd-col>
|
||||
</wd-col>
|
||||
<wd-col v-else :span="12">
|
||||
<wd-col :span="8">
|
||||
<view>撤回时间:</view>
|
||||
</wd-col>
|
||||
<wd-col :span="16">
|
||||
<view>{{ formatDate(item.revokeTime) }}</view>
|
||||
</wd-col>
|
||||
</wd-col>
|
||||
</wd-row>
|
||||
<wd-row class="mb-20rpx">
|
||||
<wd-col :span="12">
|
||||
<wd-col :span="8">
|
||||
<view>发布人:</view>
|
||||
</wd-col>
|
||||
<wd-col :span="16">
|
||||
<view>{{ item.publisherName || "-" }}</view>
|
||||
</wd-col>
|
||||
</wd-col>
|
||||
<wd-col :span="12">
|
||||
<wd-col :span="8">
|
||||
<view>紧急程度:</view>
|
||||
</wd-col>
|
||||
<wd-col :span="16">
|
||||
<view>{{ getLevelType(item.level) || "-" }}</view>
|
||||
</wd-col>
|
||||
</wd-col>
|
||||
</wd-row>
|
||||
|
||||
<template #footer>
|
||||
<view class="flex justify-end gap-20rpx">
|
||||
<wd-button size="small" plain @click="handleView(item)">查看详情</wd-button>
|
||||
<wd-button size="small" type="primary" @click="handleAction(item)">更多操作</wd-button>
|
||||
</view>
|
||||
</template>
|
||||
</wd-card>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<wd-loadmore custom-class="loadmore" :state="loadState" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { LoadMoreState } from "wot-design-uni/components/wd-loadmore/types";
|
||||
import { DropMenuItemExpose } from "wot-design-uni/components/wd-drop-menu-item/types";
|
||||
import NoticeAPI, { NoticePageQuery, NoticePageVO } from "@/api/system/notice";
|
||||
const loadState = ref<LoadMoreState>("finished");
|
||||
const dataList = ref<NoticePageVO[]>([]);
|
||||
const total = ref(0);
|
||||
// 添加新的响应式数据
|
||||
const statusOptions = [
|
||||
{ value: "", label: "全部状态" },
|
||||
{ value: 0, label: "未发布" },
|
||||
{ value: 1, label: "已发布" },
|
||||
{ value: -1, label: "已撤回" },
|
||||
];
|
||||
|
||||
// 修改查询参数
|
||||
const queryParams = ref<NoticePageQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
title: "",
|
||||
publishStatus: undefined,
|
||||
});
|
||||
|
||||
// 添加搜索处理函数
|
||||
const dropMenu = ref<DropMenuItemExpose>();
|
||||
const handleSearch = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
loadMore();
|
||||
dropMenu.value?.close();
|
||||
};
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
queryParams.value = { pageNum: 1, pageSize: 10 };
|
||||
dropMenu.value?.close();
|
||||
loadMore();
|
||||
};
|
||||
|
||||
// 获取状态样式
|
||||
const getStatusType = (
|
||||
status: number | undefined
|
||||
): "default" | "primary" | "danger" | "warning" | "success" => {
|
||||
if (!status) return "default";
|
||||
const statusMap: Record<number, "default" | "primary" | "danger" | "warning" | "success"> = {
|
||||
0: "primary",
|
||||
1: "success",
|
||||
[-1]: "warning",
|
||||
};
|
||||
return statusMap[status] || "default";
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: number | undefined): string => {
|
||||
if (status !== 0 && !status) return "-";
|
||||
const statusMap: Record<number, string> = {
|
||||
0: "未发布",
|
||||
1: "已发布",
|
||||
[-1]: "已撤回",
|
||||
};
|
||||
return statusMap[status] || "未知";
|
||||
};
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (date: Date | undefined): string => {
|
||||
return date ? date.toString() : "-";
|
||||
};
|
||||
|
||||
const getLevelType = (level: string | number | undefined): string => {
|
||||
if (!level) return "-";
|
||||
const levelMap: Record<string, string> = {
|
||||
L: "低",
|
||||
M: "中",
|
||||
H: "高",
|
||||
};
|
||||
return levelMap[level] || "未知";
|
||||
};
|
||||
|
||||
// 加载更多
|
||||
const loadMore = async () => {
|
||||
if (loadState.value === "loading") return;
|
||||
|
||||
loadState.value = "loading";
|
||||
try {
|
||||
const { list, total: totalCount } = await NoticeAPI.getPage(queryParams.value);
|
||||
|
||||
if (queryParams.value.pageNum === 1) {
|
||||
dataList.value = list;
|
||||
} else {
|
||||
dataList.value = [...dataList.value, ...list];
|
||||
}
|
||||
|
||||
total.value = totalCount;
|
||||
queryParams.value.pageNum++;
|
||||
|
||||
loadState.value = dataList.value.length >= total.value ? "finished" : "loading";
|
||||
} catch (error) {
|
||||
loadState.value = "error";
|
||||
uni.showToast({ title: "加载失败", icon: "none" });
|
||||
}
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleView = (notice: NoticePageVO) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/work/notice/detail?id=${notice.id}`,
|
||||
});
|
||||
};
|
||||
|
||||
// 操作按钮
|
||||
const handleAction = (notice: NoticePageVO) => {
|
||||
const actions = notice.publishStatus !== 1 ? ["删除", "发布"] : ["撤回"];
|
||||
uni.showActionSheet({
|
||||
itemList: actions,
|
||||
success: ({ tapIndex }) => {
|
||||
switch (actions[tapIndex]) {
|
||||
case "编辑":
|
||||
handleEdit(notice);
|
||||
break;
|
||||
case "删除":
|
||||
handleDelete(notice);
|
||||
break;
|
||||
case "发布":
|
||||
handlePublish(notice);
|
||||
break;
|
||||
case "撤回":
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "确定要撤回该通知吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await NoticeAPI.revoke(Number(notice.id));
|
||||
uni.showToast({
|
||||
title: "撤回成功",
|
||||
icon: "success",
|
||||
});
|
||||
// 刷新列表
|
||||
queryParams.value.pageNum = 1;
|
||||
loadMore();
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "撤回失败",
|
||||
icon: "error",
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (notice: NoticePageVO) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/work/notice/edit?id=${notice.id}`,
|
||||
});
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDelete = (notice: NoticePageVO) => {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "确定要删除该通知吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await NoticeAPI.deleteByIds(notice.id);
|
||||
uni.showToast({ title: "删除成功", icon: "success" });
|
||||
// 重新加载第一页
|
||||
queryParams.value.pageNum = 1;
|
||||
loadMore();
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "删除失败", icon: "none" });
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 发布
|
||||
const handlePublish = (notice: NoticePageVO) => {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "确定要发布该通知吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await NoticeAPI.publish(Number(notice.id));
|
||||
uni.showToast({ title: "发布成功", icon: "success" });
|
||||
// 重新加载第一页
|
||||
queryParams.value.pageNum = 1;
|
||||
loadMore();
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "发布失败", icon: "none" });
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onReachBottom(() => {
|
||||
if (loadState.value === "loading" || loadState.value === "finished") return;
|
||||
loadMore();
|
||||
});
|
||||
|
||||
onLoad(() => {
|
||||
loadMore();
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user