fix(notice): 通知功能修订12项全量落地——已发送幻影省略号/翻页日期格式化/附件upFile字段/审核状态Tag徽标对齐流程色系/审批中禁用删除/待审核操作列operating-link+查看详情/流程绑定预览选中流程图/一键已读改SvgIcon(read-all.svg)/图片附件icon-tupian/详情标签两端对齐/上传附件换行布局/抄送页接入TablePageAlovaNew(usePagination须返回Method)
build / build (push) Successful in 2m37s
build / build (push) Successful in 2m37s
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M859.977 336.128H608.251V171.489c0-41.159-33.318-74.836-74.039-74.836h-44.421c-40.729 0-74.044 33.677-74.044 74.836v164.639H164.023c-16.289 0-29.616 13.473-29.616 29.936v149.669c0 16.469 13.326 29.942 29.616 29.942h14.803v231.241c0 65.859-14.803 120.493-14.803 120.493 0 16.459 13.324 29.938 29.611 29.938h636.729c16.291 0 29.615-13.481 29.615-29.938 0 0-14.81-56.882-14.81-123.486V545.675h14.81c16.287 0 29.616-13.477 29.616-29.938V366.064c-0.001-16.469-13.323-29.936-29.617-29.936zM682.282 897.403V699.089c0-5.989-5.18-11.225-11.103-11.225h-7.407c-5.917 0-11.103 5.236-11.103 11.225v198.314H534.212V699.089c0-5.989-5.181-11.225-11.116-11.225H515.7c-5.918 0-11.106 5.236-11.106 11.225v198.314H378.731V699.089c0-5.989-5.186-11.225-11.111-11.225h-7.399c-5.918 0-11.106 5.236-11.106 11.225v198.314H193.634s14.812-53.884 14.812-120.487V545.675h607.113v231.241c0 66.606 14.804 120.487 14.804 120.487H682.282z m177.695-396.634c0 8.233-6.66 14.968-14.81 14.968H178.826c-8.145 0-14.807-6.735-14.807-14.968V381.028c0-8.235 6.662-14.964 14.807-14.964H445.36V178.971c0-29.184 22.956-52.382 51.835-52.382h29.61c28.876 0 51.828 23.199 51.828 52.382v187.093h266.535c8.15 0 14.81 6.729 14.81 14.964v119.741z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -115,3 +115,16 @@ h4.subtitle {
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 修复表格幻影省略号(2026-10-10):.ivu-table-cell 基础样式自带 text-overflow:ellipsis,
|
||||||
|
tooltip 列(.ivu-tooltip 行内块包装 + width:100%)与操作列(图标外包 Tooltip)未溢出也常显「...」。
|
||||||
|
恢复组件预期的块级/flex 渲染层级即可;内层 .ivu-table-cell-tooltip-content 的真省略号与
|
||||||
|
悬浮 tooltip 不受影响(已在 dev:mock 实测:短内容无省略号、长标题正常截断+悬浮提示)。 */
|
||||||
|
/* 两条同为 3 类特异性(0,3,0):后者居后胜出 → tooltip 列(.ivu-table-cell-tooltip)最终 flex
|
||||||
|
(组件预期布局),操作列裸 .ivu-tooltip 包装取 block。 */
|
||||||
|
.ivu-table .ivu-table-cell > .ivu-tooltip {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.ivu-table .ivu-table-cell > .ivu-table-cell-tooltip {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|||||||
@@ -92,16 +92,18 @@ export default {
|
|||||||
display: block;
|
display: block;
|
||||||
.upload-row {
|
.upload-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start; /* 提示语与按钮首行对齐(列表换行后不再垂直居中整块) */
|
||||||
}
|
}
|
||||||
:deep(.ivu-upload) {
|
:deep(.ivu-upload) {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
flex-wrap: wrap; /* 允许内部列表换行 */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
/* 文件列表整体另起一行,每项独占一行,不再与按钮挤在一起 */
|
/* 文件列表整体另起一行,每项独占一行,不再与按钮挤在一起 */
|
||||||
:deep(.ivu-upload-list) {
|
:deep(.ivu-upload-list) {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 8px;
|
width: 100%; /* 文件列表整体独占下一行 */
|
||||||
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
:deep(.ivu-upload-list-file) {
|
:deep(.ivu-upload-list-file) {
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
@@ -110,7 +112,7 @@ export default {
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
color: #f90;
|
color: #f90;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1;
|
line-height: 32px; /* 与默认 Button 等高,紧贴按钮右侧 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ export interface NoticeVo {
|
|||||||
smsFlag: number;
|
smsFlag: number;
|
||||||
/** 接收人列表(JSON) */
|
/** 接收人列表(JSON) */
|
||||||
receiveList: string | null;
|
receiveList: string | null;
|
||||||
|
/** 附件ID串("1,2,3";后端 Lombok 序列化名为 upFile,对齐旧 .NET UpFile 语义) */
|
||||||
|
upFile?: string | null;
|
||||||
|
/** @deprecated 旧 .NET 接口的 PascalCase 附件字段,仅作读取兼容 */
|
||||||
|
UpFile?: string | null;
|
||||||
createBy: string | null;
|
createBy: string | null;
|
||||||
createTime: string | null;
|
createTime: string | null;
|
||||||
updateBy: string | null;
|
updateBy: string | null;
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ export default class Utils {
|
|||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
class: `operating-btn iconfont ${iconClass}`,
|
class: `operating-btn iconfont ${iconClass}`,
|
||||||
onClick: callback,
|
onClick: disabled ? null : callback,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Message, Tooltip } from "view-ui-plus";
|
|||||||
import { noticeApi } from "@/api/module/notice";
|
import { noticeApi } from "@/api/module/notice";
|
||||||
import type { NoticeDetailVo, NoticeQuery, NoticeVo, NoticePageResult } from "@/types/notice";
|
import type { NoticeDetailVo, NoticeQuery, NoticeVo, NoticePageResult } from "@/types/notice";
|
||||||
import FilePreviewModal from "@/components/FilePreviewModal.vue";
|
import FilePreviewModal from "@/components/FilePreviewModal.vue";
|
||||||
|
import SvgIcon from "@/components/SvgIcon.vue";
|
||||||
import Utils from "@/utils";
|
import Utils from "@/utils";
|
||||||
|
|
||||||
/* ============ 左侧列表 ============ */
|
/* ============ 左侧列表 ============ */
|
||||||
@@ -111,7 +112,7 @@ function openPreview(item: { name?: string; filename?: string; fileid?: number;
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 附件图标(按扩展名,图标名对齐旧版 matchSuffix → icon-word/excel/ppt/pdf1/txt/tupian1/yasuo/weizhi) */
|
/* 附件图标(按扩展名,图标名对齐旧版 matchSuffix → icon-word/excel/ppt/pdf1/txt/tupian/yasuo/weizhi) */
|
||||||
function getFileIcon(name: string) {
|
function getFileIcon(name: string) {
|
||||||
const suffix = String(name || "").split(".").pop()?.toLowerCase() || "";
|
const suffix = String(name || "").split(".").pop()?.toLowerCase() || "";
|
||||||
if (["doc", "docx", "wps"].includes(suffix)) return "icon-word";
|
if (["doc", "docx", "wps"].includes(suffix)) return "icon-word";
|
||||||
@@ -119,7 +120,8 @@ function getFileIcon(name: string) {
|
|||||||
if (["ppt", "pptx"].includes(suffix)) return "icon-ppt";
|
if (["ppt", "pptx"].includes(suffix)) return "icon-ppt";
|
||||||
if (["pdf"].includes(suffix)) return "icon-pdf1";
|
if (["pdf"].includes(suffix)) return "icon-pdf1";
|
||||||
if (["txt"].includes(suffix)) return "icon-txt";
|
if (["txt"].includes(suffix)) return "icon-txt";
|
||||||
if (["jpg", "jpeg", "png", "gif", "bmp"].includes(suffix)) return "icon-tupian1";
|
// 平台 icons.css 的 icon-tupian 是线性「图片」图标;icon-tupian1 是旧彩色图转单色,看不出是图片
|
||||||
|
if (["jpg", "jpeg", "png", "gif", "bmp"].includes(suffix)) return "icon-tupian";
|
||||||
if (["zip", "rar"].includes(suffix)) return "icon-yasuo";
|
if (["zip", "rar"].includes(suffix)) return "icon-yasuo";
|
||||||
return "icon-weizhi";
|
return "icon-weizhi";
|
||||||
}
|
}
|
||||||
@@ -171,7 +173,7 @@ function shortDate(date: string) {
|
|||||||
<div class="total">
|
<div class="total">
|
||||||
<span>未读<span class="num">{{ page.unreadCount || 0 }}</span>条</span>
|
<span>未读<span class="num">{{ page.unreadCount || 0 }}</span>条</span>
|
||||||
<Tooltip content="一键已读" placement="top" transfer>
|
<Tooltip content="一键已读" placement="top" transfer>
|
||||||
<i class="iconfont icon-saoba clear-icon" @click="allRead"></i>
|
<SvgIcon class="clear-icon" name="read-all" :size="18" color="var(--text-3)" hover-color="var(--brand)" @click="allRead" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
@@ -211,11 +213,11 @@ function shortDate(date: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="title-content">
|
<div class="title-content">
|
||||||
<p>来源:{{ detail.DeptName }}</p>
|
<p><span class="meta-label">来源</span>:{{ detail.DeptName }}</p>
|
||||||
<p>发布人:{{ detail.TeaName }}</p>
|
<p><span class="meta-label">发布人</span>:{{ detail.TeaName }}</p>
|
||||||
<p>发布时间:{{ detail.EditDate }}</p>
|
<p><span class="meta-label">发布时间</span>:{{ detail.EditDate }}</p>
|
||||||
<p>
|
<p>
|
||||||
<span>附件:{{ (detail.ChaoSend || []).length }}个</span>
|
<span class="meta-label">附件</span>:{{ (detail.ChaoSend || []).length }}个
|
||||||
<span class="to-file" v-if="detail.ChaoSend && detail.ChaoSend.length > 0" @click="downAll">全部下载</span>
|
<span class="to-file" v-if="detail.ChaoSend && detail.ChaoSend.length > 0" @click="downAll">全部下载</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -306,12 +308,6 @@ function shortDate(date: string) {
|
|||||||
}
|
}
|
||||||
.clear-icon {
|
.clear-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 18px;
|
|
||||||
color: var(--text-3);
|
|
||||||
transition: color 0.15s;
|
|
||||||
&:hover {
|
|
||||||
color: var(--brand);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.search-box {
|
.search-box {
|
||||||
@@ -443,6 +439,13 @@ function shortDate(date: string) {
|
|||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
/* 标签两端撑开:冒号纵向对齐、值从同一列起(宽度取「发布时间」4 字) */
|
||||||
|
.meta-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 4em;
|
||||||
|
text-align: justify;
|
||||||
|
text-align-last: justify;
|
||||||
|
}
|
||||||
.to-file {
|
.to-file {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
color: var(--brand);
|
color: var(--brand);
|
||||||
|
|||||||
@@ -1,34 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-wrapper yh-fill">
|
<div class="page-wrapper yh-fill">
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<div class="table-region" ref="regionRef">
|
<TablePageAlovaNew ref="listRef" :data-api="fetchPage" :columns="cols">
|
||||||
<Table :columns="cols" :data="rows" :height="tableH || undefined" :loading="loading"
|
<template #title="{ row }">
|
||||||
no-data-text="暂无抄送通知">
|
<a v-if="row.title" class="notice-link" @click="openDetail(row)">{{ row.title }}</a>
|
||||||
<template #title="{ row }">
|
<span v-else class="notice-gone">通知已删除</span>
|
||||||
<a v-if="row.title" class="notice-link" @click="openDetail(row)">{{ row.title }}</a>
|
</template>
|
||||||
<span v-else class="notice-gone">通知已删除</span>
|
<template #status="{ row }">
|
||||||
</template>
|
<Tag v-if="row.auditStatusDesc && row.auditStatusDesc !== '通知已删除'"
|
||||||
<template #status="{ row }">
|
:color="statusColor(row.auditStatus)">{{ row.auditStatusDesc }}</Tag>
|
||||||
<Tag v-if="row.auditStatusDesc && row.auditStatusDesc !== '通知已删除'"
|
<Tag v-else-if="row.noticeStatus === 1" color="green">已发布</Tag>
|
||||||
:color="statusColor(row.auditStatus)">{{ row.auditStatusDesc }}</Tag>
|
<Tag v-else>—</Tag>
|
||||||
<Tag v-else-if="row.noticeStatus === 1" color="green">已发布</Tag>
|
</template>
|
||||||
<Tag v-else>—</Tag>
|
</TablePageAlovaNew>
|
||||||
</template>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
<div class="page-panel" v-if="page.total > page.pageSize">
|
|
||||||
<Page class="page-box fr" :current="page.pageIndex" :page-size="page.pageSize" :total="page.total"
|
|
||||||
show-total @on-change="load" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { Message } from "view-ui-plus";
|
import TablePageAlovaNew from "@/components/TablePageAlovaNew.vue";
|
||||||
import { useElementHeight } from "@/utils/hook/useElementHeight";
|
|
||||||
import ccApi, { type CcItem } from "@/api/module/cc";
|
import ccApi, { type CcItem } from "@/api/module/cc";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,12 +29,9 @@ import ccApi, { type CcItem } from "@/api/module/cc";
|
|||||||
* 编辑视角(type=0)不标读:未发布通知的阅读统计无意义。
|
* 编辑视角(type=0)不标读:未发布通知的阅读统计无意义。
|
||||||
*/
|
*/
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const loading = ref(false);
|
const listRef = ref<InstanceType<typeof TablePageAlovaNew> | null>(null);
|
||||||
const rows = ref<CcItem[]>([]);
|
// usePagination 的 handler 必须返回 Method(组件内部统一 send 并吃全局响应拦截),返回 Promise 会卡在 loading
|
||||||
const page = ref({ total: 0, pageIndex: 1, pageSize: 10 });
|
const fetchPage = (p: { pageIndex: number; pageSize: number }) => ccApi.my(p.pageIndex, p.pageSize);
|
||||||
|
|
||||||
const regionRef = ref<HTMLElement | null>(null);
|
|
||||||
const tableH = useElementHeight(regionRef);
|
|
||||||
|
|
||||||
const cols = [
|
const cols = [
|
||||||
{ title: "通知标题", slot: "title", minWidth: 260, ellipsis: true, tooltip: true },
|
{ title: "通知标题", slot: "title", minWidth: 260, ellipsis: true, tooltip: true },
|
||||||
@@ -69,21 +58,6 @@ function statusColor(auditStatus: number | null) {
|
|||||||
function openDetail(row: CcItem) {
|
function openDetail(row: CcItem) {
|
||||||
router.push({ path: "/list/detail", query: { serid: row.noticeId, type: 0 } });
|
router.push({ path: "/list/detail", query: { serid: row.noticeId, type: 0 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(p = 1) {
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
const res = await ccApi.my(p, page.value.pageSize).send();
|
|
||||||
page.value = res;
|
|
||||||
rows.value = res.content || [];
|
|
||||||
} catch (e: any) {
|
|
||||||
Message.error(e?.message || "抄送列表加载失败");
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => load(1));
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted, watch, h } from "vue";
|
import { ref, computed, onMounted, watch, h, resolveComponent } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { useRequest } from "alova/client";
|
import { useRequest } from "alova/client";
|
||||||
import { Message } from "view-ui-plus";
|
import { Message } from "view-ui-plus";
|
||||||
@@ -33,9 +33,10 @@ const auditStatusOptions = [
|
|||||||
{ value: -1, label: "无需审核" },
|
{ value: -1, label: "无需审核" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function fmtDate(d: Date) {
|
function fmtDate(d: Date | string) {
|
||||||
|
const dt = new Date(d);
|
||||||
const pad = (n: number) => String(n).padStart(2, "0");
|
const pad = (n: number) => String(n).padStart(2, "0");
|
||||||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============ 分页(规范 §3:customPageCount 页长记忆) ============ */
|
/* ============ 分页(规范 §3:customPageCount 页长记忆) ============ */
|
||||||
@@ -55,8 +56,9 @@ async function run() {
|
|||||||
pageSize: pageSize.value,
|
pageSize: pageSize.value,
|
||||||
orderByTime: "1",
|
orderByTime: "1",
|
||||||
};
|
};
|
||||||
if (startDt.value) params.startTime = startDt.value;
|
// DatePicker 选过日期后 v-model 值是 Date 对象,后端 LocalDate 只认 yyyy-MM-dd → 统一格式化
|
||||||
if (endDt.value) params.endTime = endDt.value;
|
if (startDt.value) params.startTime = fmtDate(new Date(startDt.value));
|
||||||
|
if (endDt.value) params.endTime = fmtDate(new Date(endDt.value));
|
||||||
if (auditType.value !== "" && auditType.value !== null) params.auditStatus = Number(auditType.value);
|
if (auditType.value !== "" && auditType.value !== null) params.auditStatus = Number(auditType.value);
|
||||||
if (!isManage.value) {
|
if (!isManage.value) {
|
||||||
params.scope = "user";
|
params.scope = "user";
|
||||||
@@ -144,9 +146,10 @@ function del(row: NoticeVo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 附件下载:逐个触发(间隔 500ms,同旧版) */
|
/* 附件下载:逐个触发(间隔 500ms,同旧版) */
|
||||||
function downloadFiles(row: NoticeVo & { UpFile?: string }) {
|
function downloadFiles(row: NoticeVo) {
|
||||||
if (!row.UpFile) return;
|
const upFile = row.upFile ?? row.UpFile;
|
||||||
row.UpFile.split(",").forEach((id: string, i: number) => {
|
if (!upFile) return;
|
||||||
|
upFile.split(",").forEach((id: string, i: number) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = noticeApi.fileDownUrl(Number(id));
|
window.location.href = noticeApi.fileDownUrl(Number(id));
|
||||||
}, i * 500);
|
}, i * 500);
|
||||||
@@ -172,8 +175,9 @@ const columns = [
|
|||||||
render: (h: any, p: any) => {
|
render: (h: any, p: any) => {
|
||||||
const st = p.row.auditStatus;
|
const st = p.row.auditStatus;
|
||||||
if (st === null || st === undefined) return h("span", { style: "color:var(--text-3);" }, "—");
|
if (st === null || st === undefined) return h("span", { style: "color:var(--text-3);" }, "—");
|
||||||
const colors: Record<number, string> = { 0: "default", 10: "blue", 20: "green", 30: "red", 40: "orange" };
|
// 色系对齐流程侧:待提交灰 / 审批中橙 / 已通过绿 / 已驳回红 / 已撤回灰
|
||||||
return h("Tag", { color: colors[st] || "default" }, () => p.row.auditStatusDesc || "—");
|
const colors: Record<number, string> = { 0: "default", 10: "warning", 20: "success", 30: "error", 40: "default" };
|
||||||
|
return h(resolveComponent("Tag"), { color: colors[st] || "default" }, () => p.row.auditStatusDesc || "—");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: "已读人数", key: "readCount", width: 110, align: "left" },
|
{ title: "已读人数", key: "readCount", width: 110, align: "left" },
|
||||||
@@ -188,7 +192,7 @@ const columns = [
|
|||||||
width: 70,
|
width: 70,
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (h: any, p: any) =>
|
render: (h: any, p: any) =>
|
||||||
p.row.UpFile
|
(p.row.upFile ?? p.row.UpFile)
|
||||||
? Utils.operatingHandle(h, "附件下载", "icon-attachment", () => downloadFiles(p.row))
|
? Utils.operatingHandle(h, "附件下载", "icon-attachment", () => downloadFiles(p.row))
|
||||||
: h("span", { style: "color:var(--text-3);" }, "无"),
|
: h("span", { style: "color:var(--text-3);" }, "无"),
|
||||||
},
|
},
|
||||||
@@ -198,12 +202,12 @@ const columns = [
|
|||||||
align: "center",
|
align: "center",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
render: (h: any, p: any) => {
|
render: (h: any, p: any) => {
|
||||||
// BP-R5-1:审批中(audit=10)禁止删除(后端 403)——不再渲染死按钮,审批通过/驳回/撤回后恢复
|
// BP-R5-1:审批中(audit=10)禁止删除(后端 403)——渲染禁用态而非隐藏,保持操作列对齐
|
||||||
const ops = [Utils.operatingHandle(h, "查看通知", "icon-browse", () => openDetail(p.row))];
|
const delDisabled = p.row.auditStatus === 10;
|
||||||
if (p.row.auditStatus !== 10) {
|
return [
|
||||||
ops.push(Utils.operatingHandle(h, "删除通知", "icon-ashbin", () => del(p.row)));
|
Utils.operatingHandle(h, "查看通知", "icon-browse", () => openDetail(p.row)),
|
||||||
}
|
Utils.operatingHandle(h, "删除通知", "icon-ashbin", () => del(p.row), delDisabled),
|
||||||
return ops;
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -85,13 +85,21 @@ function unbindFlow() {
|
|||||||
* 生产前端静态挂 /flow-center/front*,Caddy 无 /flow-center/ 根路由,window.open 深链必 404) */
|
* 生产前端静态挂 /flow-center/front*,Caddy 无 /flow-center/ 根路由,window.open 深链必 404) */
|
||||||
const flowDiagramVisible = ref(false);
|
const flowDiagramVisible = ref(false);
|
||||||
const flowDiagramEl = ref<HTMLImageElement | null>(null);
|
const flowDiagramEl = ref<HTMLImageElement | null>(null);
|
||||||
|
const flowDiagramGuid = ref(""); // 打开抽屉时定格的流程 GUID(绑定态=boundFlowGuid,预览态=selectedGuid)
|
||||||
const flowDiagramSrc = computed(() =>
|
const flowDiagramSrc = computed(() =>
|
||||||
flowDiagramVisible.value && boundFlowGuid.value
|
flowDiagramVisible.value && flowDiagramGuid.value
|
||||||
? `${config.serviceHost}/api/notice/flow/DiagramDef?flowGuid=${encodeURIComponent(boundFlowGuid.value)}`
|
? `${config.serviceHost}/api/notice/flow/DiagramDef?flowGuid=${encodeURIComponent(flowDiagramGuid.value)}`
|
||||||
: "",
|
: "",
|
||||||
);
|
);
|
||||||
function openFlowDiagram() {
|
function openFlowDiagram() {
|
||||||
if (!boundFlowGuid.value) return;
|
if (!boundFlowGuid.value) return;
|
||||||
|
flowDiagramGuid.value = boundFlowGuid.value;
|
||||||
|
flowDiagramVisible.value = true;
|
||||||
|
}
|
||||||
|
/** 预览下拉当前选中(未必已保存)的流程 */
|
||||||
|
function previewSelectedFlow() {
|
||||||
|
if (!selectedGuid.value) return;
|
||||||
|
flowDiagramGuid.value = selectedGuid.value;
|
||||||
flowDiagramVisible.value = true;
|
flowDiagramVisible.value = true;
|
||||||
}
|
}
|
||||||
function onFlowDiagramError() {
|
function onFlowDiagramError() {
|
||||||
@@ -522,6 +530,7 @@ const groupH = useElementHeight(groupRegionRef);
|
|||||||
<template v-if="flowCanEdit">
|
<template v-if="flowCanEdit">
|
||||||
<Button type="primary" :loading="bindingSaving" @click="saveFlowBinding">保存绑定</Button>
|
<Button type="primary" :loading="bindingSaving" @click="saveFlowBinding">保存绑定</Button>
|
||||||
<Button v-if="boundFlowGuid" @click="unbindFlow">解除绑定</Button>
|
<Button v-if="boundFlowGuid" @click="unbindFlow">解除绑定</Button>
|
||||||
|
<Button v-if="selectedGuid" @click="previewSelectedFlow">查看流程图</Button>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="readonly-hint">仅本校管理员可修改流程绑定</span>
|
<span v-else class="readonly-hint">仅本校管理员可修改流程绑定</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user