add notify editor/view
This commit is contained in:
@@ -78,6 +78,7 @@ const formattedValue = computed(() => formatNumber(String(props.value ?? "").tri
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tui-contact-number {
|
||||
width: fit-content;
|
||||
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
|
||||
+12
-2
@@ -16,6 +16,8 @@ import TiptapEditor from "./tiptap-editor";
|
||||
import TiptapView from "./tiptap-view";
|
||||
import ArticleEditor from "./article-editor";
|
||||
import ArticleView from "./article-view";
|
||||
import NotifyEditor from "./notify-editor";
|
||||
import NotifyView from "./notify-view";
|
||||
|
||||
export default [
|
||||
Icon,
|
||||
@@ -34,7 +36,9 @@ export default [
|
||||
TiptapEditor,
|
||||
TiptapView,
|
||||
ArticleEditor,
|
||||
ArticleView
|
||||
ArticleView,
|
||||
NotifyEditor,
|
||||
NotifyView
|
||||
];
|
||||
|
||||
export {
|
||||
@@ -54,7 +58,9 @@ export {
|
||||
TiptapEditor,
|
||||
TiptapView,
|
||||
ArticleEditor,
|
||||
ArticleView
|
||||
ArticleView,
|
||||
NotifyEditor,
|
||||
NotifyView
|
||||
};
|
||||
|
||||
export type {
|
||||
@@ -71,3 +77,7 @@ export type {
|
||||
export type {
|
||||
ArticleEditorExpose
|
||||
} from "./article-editor";
|
||||
|
||||
export type {
|
||||
NotifyEditorExpose
|
||||
} from "./notify-editor";
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import view from "./index.vue";
|
||||
import Toolkit from "../../utils/Toolkit";
|
||||
import type { NotifyDetail } from "../../types";
|
||||
|
||||
export type NotifyEditorExpose = {
|
||||
submit: () => Promise<NotifyDetail>;
|
||||
getPendingMediaCount: () => number;
|
||||
};
|
||||
|
||||
export const NotifyEditor = Toolkit.withInstall(view);
|
||||
export default NotifyEditor;
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<article-editor
|
||||
ref="articleEditorRef"
|
||||
:model-value="articleValue"
|
||||
:placeholder="placeholder"
|
||||
:upload-image="uploadImage"
|
||||
:upload-video="uploadVideo"
|
||||
:resolve-attachment-url="resolveAttachmentUrl"
|
||||
:resolve-temp-url="resolveTempUrl"
|
||||
@change="onArticleChange"
|
||||
@update:model-value="onArticleCommit"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Article, ArticleContentType, Attachment, NotifyDetail } from "../../types";
|
||||
import type { ArticleEditorExpose } from "../article-editor";
|
||||
import { ArticleEditor } from "../article-editor";
|
||||
import type { UploadResult } from "../tiptap-editor";
|
||||
import { normalizeNotifyContentType } from "../notify/shared";
|
||||
|
||||
defineOptions({
|
||||
name: "NotifyEditor"
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue?: NotifyDetail;
|
||||
placeholder?: string;
|
||||
uploadImage?: (file: File) => Promise<UploadResult>;
|
||||
uploadVideo?: (file: File) => Promise<UploadResult>;
|
||||
resolveAttachmentUrl?: (attachmentId: string, attachment?: Attachment) => string | Promise<string>;
|
||||
resolveTempUrl?: (tempFileId: string) => string | Promise<string>;
|
||||
}>(), {
|
||||
modelValue: () => ({}),
|
||||
placeholder: "请输入通知内容"
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
change: [value: NotifyDetail];
|
||||
"update:modelValue": [value: NotifyDetail];
|
||||
}>();
|
||||
|
||||
const articleEditorRef = ref<ArticleEditorExpose>();
|
||||
|
||||
const articleValue = computed<Article>(() => ({
|
||||
contentType: normalizeNotifyContentType(props.modelValue?.contentType) as ArticleContentType,
|
||||
content: props.modelValue?.content || "",
|
||||
attachmentList: props.modelValue?.attachmentList
|
||||
}));
|
||||
|
||||
function buildNotifyValue(value: Article): NotifyDetail {
|
||||
return {
|
||||
...(props.modelValue || {}),
|
||||
contentType: normalizeNotifyContentType(value.contentType),
|
||||
content: value.content || "",
|
||||
attachmentList: value.attachmentList || []
|
||||
};
|
||||
}
|
||||
|
||||
function onArticleChange(value: Article) {
|
||||
emit("change", buildNotifyValue(value));
|
||||
}
|
||||
|
||||
function onArticleCommit(value: Article) {
|
||||
emit("update:modelValue", buildNotifyValue(value));
|
||||
}
|
||||
|
||||
async function submit() {
|
||||
const value = await articleEditorRef.value?.submit();
|
||||
return buildNotifyValue(value || articleValue.value);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
getPendingMediaCount: () => articleEditorRef.value?.getPendingMediaCount() || 0
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,5 @@
|
||||
import view from "./index.vue";
|
||||
import Toolkit from "../../utils/Toolkit";
|
||||
|
||||
export const NotifyView = Toolkit.withInstall(view);
|
||||
export default NotifyView;
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<article-view
|
||||
:article="articleValue"
|
||||
:empty-text="emptyText"
|
||||
:resolve-attachment-url="resolveAttachmentUrl"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Article, ArticleContentType, Attachment, NotifyDetail } from "../../types";
|
||||
import { ArticleView } from "../article-view";
|
||||
import { normalizeNotifyContentType } from "../notify/shared";
|
||||
|
||||
defineOptions({
|
||||
name: "NotifyView"
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
detail?: NotifyDetail;
|
||||
emptyText?: string;
|
||||
resolveAttachmentUrl?: (attachmentId: string, attachment?: Attachment) => string | Promise<string>;
|
||||
}>(), {
|
||||
detail: () => ({}),
|
||||
emptyText: "暂无通知内容"
|
||||
});
|
||||
|
||||
const articleValue = computed<Article>(() => ({
|
||||
contentType: normalizeNotifyContentType(props.detail?.contentType) as ArticleContentType,
|
||||
content: props.detail?.content || "",
|
||||
attachmentList: props.detail?.attachmentList
|
||||
}));
|
||||
</script>
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { NotifyContentType } from "../../types";
|
||||
|
||||
export const DEFAULT_NOTIFY_CONTENT_TYPE: NotifyContentType = "TIP_TAP";
|
||||
|
||||
/** 规范化通知内容类型,兼容旧通知未返回内容类型的情况 */
|
||||
export function normalizeNotifyContentType(contentType?: string): NotifyContentType {
|
||||
return contentType === "TEXT" ? "TEXT" : DEFAULT_NOTIFY_CONTENT_TYPE;
|
||||
}
|
||||
+9
-1
@@ -1,4 +1,5 @@
|
||||
import type { Model } from "./Model";
|
||||
import type { Attachment } from "./Attachment";
|
||||
import type { User } from "./User";
|
||||
|
||||
/** 通知消息类型 */
|
||||
@@ -7,6 +8,9 @@ export type NotifyMsgType = "INTERNAL" | "SMS" | "MAIL" | "HTTP" | "WECHAT";
|
||||
/** 通知投递状态 */
|
||||
export type NotifyStatus = "WAITING" | "REMINDED" | "TIMEOUT" | "CANCEL" | "FAIL";
|
||||
|
||||
/** 通知内容类型 */
|
||||
export type NotifyContentType = "TEXT" | "TIP_TAP";
|
||||
|
||||
/** 通知 */
|
||||
export type Notify = {
|
||||
/** 业务类型 */
|
||||
@@ -34,7 +38,11 @@ export type NotifyDetail = {
|
||||
/** 标题 */
|
||||
subject?: string;
|
||||
/** 内容 */
|
||||
data?: string;
|
||||
content?: string;
|
||||
/** 内容类型 */
|
||||
contentType?: NotifyContentType;
|
||||
/** 媒体附件列表 */
|
||||
attachmentList?: Attachment[];
|
||||
/** 参数 */
|
||||
args?: string;
|
||||
/** 发送来源 */
|
||||
|
||||
Reference in New Issue
Block a user