This commit is contained in:
2025-12-07 18:58:41 +08:00
parent 221ecbf05a
commit e388613fc8
26 changed files with 3368 additions and 722 deletions

View File

@@ -0,0 +1,266 @@
<template>
<BasicModal
v-bind="$attrs"
@register="register"
title="详细信息"
@ok="handleSubmit()"
:showFooter="true"
width="60%"
@cancel="handleCancel"
>
<div class="detail-container">
<div class="detail-title">{{ NoticeList?.title || '无标题' }}</div>
<div class="detail-info">
<span class="info-item">时间{{ NoticeList?.createTime || '-' }}</span>
<span class="info-item">类型{{ getTypeText(NoticeList?.type) }}</span>
</div>
<!-- 优化后的内容展示区域 -->
<div class="detail-content">
<pre class="db-content">{{ NoticeList?.description || '无内容' }}</pre>
</div>
<div v-if="NoticeList?.type === '3'" class="todo-opinion">
<div class="opinion-card card">
<div class="card-header">
<span class="label block-label">待办意见</span>
<span class="required-mark">*</span>
</div>
<div class="card-body">
<textarea
v-model="TodoValue"
type="textarea"
:rows="4"
placeholder="请输入处理意见"
class="opinion-input"
/>
</div>
</div>
</div>
</div>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
import { bizListItemSflow, BizListItem } from '@jeesite/biz/api/biz/listItem';
export default defineComponent({
components: { BasicModal },
emits: ['modalClose'],
setup(props, { emit }) {
const TodoValue = ref();
const NoticeList = ref();
const { createMessage } = useMessage();
// 模态框注册
const [register, { closeModal }] = useModalInner(async (data: any) => {
if (!data) return;
NoticeList.value = Array.isArray(data) ? data[0] : data;
});
const getTypeText = (type: string) => {
switch (type) {
case '1': return '通知';
case '2': return '消息';
case '3': return '待办';
default: return '未知';
}
};
async function handleSubmit() {
if (NoticeList.value?.type === '3' && !TodoValue.value?.trim()) {
createMessage.warning('请输入处理意见');
return;
}
const params = {
id: NoticeList.value?.id ?? '',
extra: TodoValue.value ?? {},
readFlag: true,
};
try {
const res = await bizListItemSflow(params);
createMessage.success(res.message || '提交成功');
closeModal();
handleCancel();
} catch (error: any) {
console.error('提交失败:', error);
createMessage.error('提交失败,请重试');
}
}
const handleCancel = () => {
emit('modalClose');
};
return {
register,
closeModal,
NoticeList,
getTypeText,
TodoValue,
handleSubmit,
handleCancel,
};
},
});
</script>
<style scoped>
/* 全局盒模型重置 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* 主容器样式 - 淡蓝色系优化 */
.detail-container {
background-color: #f0f8ff; /* 统一淡蓝色背景 */
padding: 20px;
border-radius: 8px;
min-height: 200px;
font-size: 14px;
color: #333;
}
/* 标题样式 - 优化分隔线和间距 */
.detail-title {
font-size: 18px;
font-weight: 600;
text-align: center;
margin-bottom: 16px;
color: #1f2937;
padding-bottom: 12px;
border-bottom: 1px solid #d1e7ff; /* 淡蓝色分隔线 */
}
/* 时间和类型行样式 - 紧凑化+优化背景 */
.detail-info {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
color: #4b5563;
font-size: 13px;
gap: 15px;
}
.info-item {
background-color: #ffffff; /* 白色背景更清爽 */
padding: 6px 12px;
border-radius: 6px;
border: 1px solid #d1e7ff; /* 淡蓝色边框 */
box-shadow: 0 1px 2px rgba(0,0,0,0.03);
white-space: nowrap;
}
/* 内容展示区域 - 优化样式和滚动 */
.detail-content {
font-size: 13px;
line-height: 1.6;
color: #374151;
margin-bottom: 20px;
padding: 14px;
background-color: #ffffff;
border-radius: 8px;
border: 1px solid #d1e7ff;
max-height: 200px;
overflow-y: auto;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
/* 数据库格式展示样式 - 优化字体和间距 */
.db-content {
margin: 0;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
white-space: pre-wrap; /* 保留换行和空格 */
word-break: break-all; /* 防止长文本溢出 */
color: #333;
}
/* 待办意见容器 */
.todo-opinion {
width: 100%;
}
/* 通用卡片样式 - 统一风格 */
.card {
border: 1px solid #d1e7ff;
border-radius: 8px;
overflow: hidden;
background: #ffffff;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
transition: box-shadow 0.2s;
}
.card:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
/* 卡片头部 */
.card-header {
padding: 10px 16px;
border-bottom: 1px solid #e8f4ff;
background: #f8fbff;
display: flex;
align-items: center;
}
.block-label {
font-size: 14px;
font-weight: 600;
color: #1f2937;
}
.required-mark {
color: #f53f3f;
font-size: 14px;
margin-left: 4px;
}
/* 卡片内容区 */
.card-body {
padding: 14px;
}
/* 待办意见输入框 - 优化样式 */
.opinion-input {
width: 100%;
padding: 10px 12px;
border: 1px solid #d1e7ff;
border-radius: 6px;
font-size: 13px;
line-height: 1.5;
resize: vertical;
transition: all 0.2s;
background-color: #ffffff;
}
.opinion-input:focus {
outline: none;
border-color: #4096ff;
box-shadow: 0 0 0 2px rgba(64, 150, 255, 0.1);
}
/* 滚动条优化 */
.detail-content::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.detail-content::-webkit-scrollbar-track {
background: #f8fbff;
border-radius: 3px;
}
.detail-content::-webkit-scrollbar-thumb {
background: #d1e7ff;
border-radius: 3px;
}
.detail-content::-webkit-scrollbar-thumb:hover {
background: #4096ff;
}
</style>

View File

@@ -12,30 +12,32 @@
{{ item.name }}
<span v-if="item.list.length !== 0">({{ item.list.length }})</span>
</template>
<!-- 绑定title-click事件的通知列表中标题是可点击-->
<NoticeList :list="item.list" v-if="item.key === '3'" @title-click="onNoticeClick" />
<NoticeList :list="item.list" v-else />
<NoticeList :list="item.list" v-if="item.list.length > 0" @click="openModal(true, item.list)" />
</TabPane>
</template>
</Tabs>
</template>
</Popover>
</div>
<Modal @register="register" @modalClose="getDataList()" />
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, ref } from 'vue';
import { Popover, Tabs, Badge } from 'ant-design-vue';
import { BellOutlined } from '@ant-design/icons-vue';
import NoticeList from './NoticeList.vue';
import { useModal } from '@jeesite/core/components/Modal';
import { useDesign } from '@jeesite/core/hooks/web/useDesign';
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
import { tabListDataAll, bizListItemSflow, TabItem, BizListItem } from '@jeesite/biz/api/biz/listItem';
import Modal from './NoticeInfo.vue';
export default defineComponent({
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList },
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList, Modal },
setup() {
const [register, { openModal }] = useModal();
const { prefixCls } = useDesign('header-notify');
const { createMessage } = useMessage();
const listData = ref<TabItem[]>([]);
const getDataList = async () => {
@@ -47,19 +49,13 @@
}
}
const count = computed(() => {
const count = computed(() => {
let count = 0;
for (let i = 0; i < listData.value.length; i++) {
count += listData.value[i].list.length;
}
return count;
});
async function onNoticeClick(record: BizListItem) {
const res = await bizListItemSflow(record);
createMessage.success(res.message);
getDataList()
}
onMounted(() => {
getDataList()
@@ -69,8 +65,10 @@
prefixCls,
listData,
count,
onNoticeClick,
register,
openModal,
numberStyle: {},
getDataList,
};
},
});