feat(emergency): 实现急救宣教推送到 IM 会话功能
- 新增 FirstAidPush 组件:分类筛选 + 搜索 + 单条/一键推送 - IM 端切换会话时 postMessage 携带 orderId 通知父页面 - 父页面监听 sessionChanged 联动推送按钮与后端调用 - 推送调后端 push/send 记录状态 + IM postMessage 推卡片 - 资源管理正文改富文本编辑器,修批量操作重复提示 - 重建 iweb 产物
This commit is contained in:
+28
-122
@@ -22,9 +22,10 @@
|
||||
block-node
|
||||
@select="onSelectCategory"
|
||||
>
|
||||
<template #title="{ name, id, status }">
|
||||
<template #title="{ name, id, status, resourceCount }">
|
||||
<div class="tree-node-content">
|
||||
<span class="tree-name">{{ name }}</span>
|
||||
<span v-if="resourceCount != null" class="tree-count">({{ resourceCount }})</span>
|
||||
<a-tag v-if="status === 2" color="red" style="margin-left: 4px">冻结</a-tag>
|
||||
<span class="tree-actions">
|
||||
<a-button type="link" size="small" @click.stop="handleEditCategory({ id, name })">编</a-button>
|
||||
@@ -61,6 +62,7 @@
|
||||
@close.prevent="handleDeleteTag(tag)"
|
||||
>
|
||||
{{ tag.name }}
|
||||
<span v-if="tag.resourceCount != null" class="tag-count">{{ tag.resourceCount }}</span>
|
||||
</a-tag>
|
||||
<a-empty v-if="filteredTags.length === 0 && !tagLoading" description="暂无标签" />
|
||||
</div>
|
||||
@@ -68,7 +70,7 @@
|
||||
</a-card>
|
||||
|
||||
<a-card title="分类权限配置" :bordered="false" class="card-section">
|
||||
<a-alert message="权限矩阵接口后端尚未提供,当前为占位展示" type="info" show-icon style="margin-bottom: 12px" />
|
||||
<!-- <a-alert message="权限矩阵接口后端尚未提供,当前为占位展示" type="info" show-icon style="margin-bottom: 12px" />-->
|
||||
<a-table
|
||||
:columns="permissionColumns"
|
||||
:data-source="permissionList"
|
||||
@@ -89,50 +91,9 @@
|
||||
</a-row>
|
||||
|
||||
<!-- 分类新增/编辑弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="categoryModalVisible"
|
||||
:title="categoryModalTitle"
|
||||
@ok="handleCategorySubmit"
|
||||
:width="480"
|
||||
:confirm-loading="categorySubmitting"
|
||||
>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="分类名称" required>
|
||||
<a-input v-model:value="categoryForm.name" placeholder="请输入分类名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="父级分类">
|
||||
<a-tree-select
|
||||
v-model:value="categoryForm.parentId"
|
||||
:tree-data="categoryTreeSelectData"
|
||||
:field-names="{ label: 'name', value: 'id', children: 'children' }"
|
||||
placeholder="顶级分类(不选)"
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序号">
|
||||
<a-input-number v-model:value="categoryForm.sortNo" :min="0" style="width: 100%" />
|
||||
</a-form-item>
|
||||
<a-form-item label="描述">
|
||||
<a-textarea v-model:value="categoryForm.description" :rows="2" placeholder="可选" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 标签新增弹窗 -->
|
||||
<a-modal v-model:open="tagModalVisible" title="新增标签" @ok="handleTagSubmit" :width="480" :confirm-loading="tagSubmitting">
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="标签名称" required>
|
||||
<a-input v-model:value="tagForm.name" placeholder="请输入标签名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序号">
|
||||
<a-input-number v-model:value="tagForm.sortNo" :min="0" style="width: 100%" />
|
||||
</a-form-item>
|
||||
<a-form-item label="描述">
|
||||
<a-textarea v-model:value="tagForm.description" :rows="2" placeholder="可选" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<CategoryFormModal @register="registerCategoryModal" @success="loadCategoryTree" />
|
||||
<!-- 标签新增/编辑弹窗 -->
|
||||
<TagFormModal @register="registerTagModal" @success="loadTags" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -140,20 +101,22 @@
|
||||
import { ref, reactive, computed, onMounted } from 'vue';
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import {
|
||||
categoryListAllApi,
|
||||
categoryQueryByIdApi,
|
||||
categoryAddApi,
|
||||
categoryEditApi,
|
||||
categoryDeleteApi,
|
||||
tagListAllApi,
|
||||
tagAddApi,
|
||||
tagDeleteApi,
|
||||
buildTree,
|
||||
} from './label.api';
|
||||
import CategoryFormModal from './components/CategoryFormModal.vue';
|
||||
import TagFormModal from './components/TagFormModal.vue';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
const [registerCategoryModal, { openModal: openCategoryModal }] = useModal();
|
||||
const [registerTagModal, { openModal: openTagModal }] = useModal();
|
||||
|
||||
// ============ 分类树 ============
|
||||
const categoryList = ref<any[]>([]);
|
||||
const categoryLoading = ref(false);
|
||||
@@ -188,29 +151,15 @@
|
||||
}
|
||||
|
||||
function handleAddCategory(parentId?: string) {
|
||||
categoryModalTitle.value = '新增分类';
|
||||
categoryForm.id = '';
|
||||
categoryForm.name = '';
|
||||
categoryForm.parentId = parentId || undefined;
|
||||
categoryForm.sortNo = 1;
|
||||
categoryForm.description = '';
|
||||
categoryModalVisible.value = true;
|
||||
openCategoryModal(true, { isUpdate: false, parentId });
|
||||
}
|
||||
|
||||
function handleAddSubCategory(parentId: string) {
|
||||
handleAddCategory(parentId);
|
||||
openCategoryModal(true, { isUpdate: false, parentId });
|
||||
}
|
||||
|
||||
async function handleEditCategory(record: any) {
|
||||
// 拉详情获取完整字段
|
||||
const detail = await categoryQueryByIdApi({ id: record.id }).catch(() => null);
|
||||
categoryModalTitle.value = '编辑分类';
|
||||
categoryForm.id = detail?.id || record.id;
|
||||
categoryForm.name = detail?.name || record.name;
|
||||
categoryForm.parentId = detail?.parentId || undefined;
|
||||
categoryForm.sortNo = detail?.sortNo ?? 1;
|
||||
categoryForm.description = detail?.description || '';
|
||||
categoryModalVisible.value = true;
|
||||
function handleEditCategory(record: any) {
|
||||
openCategoryModal(true, { isUpdate: true, record });
|
||||
}
|
||||
|
||||
function handleDeleteCategory(record: any) {
|
||||
@@ -220,35 +169,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function handleCategorySubmit() {
|
||||
if (!categoryForm.name) {
|
||||
createMessage.warning('请输入分类名称');
|
||||
return;
|
||||
}
|
||||
categorySubmitting.value = true;
|
||||
try {
|
||||
const payload = {
|
||||
id: categoryForm.id || undefined,
|
||||
name: categoryForm.name,
|
||||
parentId: categoryForm.parentId,
|
||||
sortNo: categoryForm.sortNo,
|
||||
description: categoryForm.description,
|
||||
status: 1,
|
||||
};
|
||||
if (categoryForm.id) {
|
||||
await categoryEditApi(payload);
|
||||
createMessage.success('已更新分类');
|
||||
} else {
|
||||
await categoryAddApi(payload);
|
||||
createMessage.success('已新增分类');
|
||||
}
|
||||
categoryModalVisible.value = false;
|
||||
loadCategoryTree();
|
||||
} finally {
|
||||
categorySubmitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 标签 ============
|
||||
const tagList = ref<any[]>([]);
|
||||
const tagLoading = ref(false);
|
||||
@@ -269,10 +189,7 @@
|
||||
}
|
||||
|
||||
function handleAddTag() {
|
||||
tagForm.name = '';
|
||||
tagForm.sortNo = 1;
|
||||
tagForm.description = '';
|
||||
tagModalVisible.value = true;
|
||||
openTagModal(true, { isUpdate: false });
|
||||
}
|
||||
|
||||
function handleDeleteTag(tag: any) {
|
||||
@@ -282,27 +199,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function handleTagSubmit() {
|
||||
if (!tagForm.name) {
|
||||
createMessage.warning('请输入标签名称');
|
||||
return;
|
||||
}
|
||||
tagSubmitting.value = true;
|
||||
try {
|
||||
await tagAddApi({
|
||||
name: tagForm.name,
|
||||
sortNo: tagForm.sortNo,
|
||||
description: tagForm.description,
|
||||
status: 1,
|
||||
});
|
||||
createMessage.success('已新增标签');
|
||||
tagModalVisible.value = false;
|
||||
loadTags();
|
||||
} finally {
|
||||
tagSubmitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 权限矩阵(mock,后端未提供接口) ============
|
||||
const permissionList = ref<any[]>([
|
||||
{ role: '系统管理员', permissions: ['rw', 'rw', 'rw', 'rw', 'rw'] },
|
||||
@@ -400,6 +296,11 @@
|
||||
.tree-name {
|
||||
flex: 1;
|
||||
}
|
||||
.tree-count {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.tree-actions {
|
||||
display: none;
|
||||
margin-left: auto;
|
||||
@@ -419,4 +320,9 @@
|
||||
padding: 4px 14px;
|
||||
cursor: default;
|
||||
}
|
||||
.tag-count {
|
||||
opacity: 0.5;
|
||||
font-size: 11px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user