vome-core 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/config/plugin-dev.js +1 -1
- package/dist/admin/crud/components/vm-richtext.vue +186 -236
- package/dist/admin/crud/config.js +1 -1
- package/dist/admin/crud/confirm.js +1 -1
- package/dist/admin/crud/dict.js +1 -1
- package/dist/admin/crud/key.js +1 -1
- package/dist/admin/crud/mitt.js +1 -1
- package/dist/admin/crud/plugins.js +1 -1
- package/dist/admin/crud/span.js +1 -1
- package/dist/admin/crud/style.js +1 -1
- package/dist/admin/crud/validate.js +1 -1
- package/dist/admin/directives/perm.js +1 -1
- package/dist/admin/hooks/useUpload.js +1 -1
- package/dist/admin/lib/browser.js +1 -1
- package/dist/admin/lib/cn.js +1 -1
- package/dist/admin/lib/dialog-float.js +1 -1
- package/dist/admin/lib/export-excel.js +1 -1
- package/dist/admin/lib/import-excel.js +1 -1
- package/dist/admin/lib/json.js +1 -1
- package/dist/admin/lib/menu.js +1 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.js +1 -1
- package/dist/admin/lib/video-frame.js +1 -1
- package/dist/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/excel.js +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/locale-json.js +1 -1
- package/dist/shared/tree.js +1 -1
- package/package.json +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
function _0x55aa(_0x5efc8d,_0x4f89c7){_0x5efc8d=_0x5efc8d-0xff;const _0x3bfc59=_0x3bfc();let _0x55aa59=_0x3bfc59[_0x5efc8d];if(_0x55aa['RjQbtO']===undefined){var _0xe1461b=function(_0x506f0c){const _0xcb60e9='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4a8998='',_0x20ce27='';for(let _0x8afedc=0x0,_0x3e9e4e,_0x5a012d,_0x42a114=0x0;_0x5a012d=_0x506f0c['charAt'](_0x42a114++);~_0x5a012d&&(_0x3e9e4e=_0x8afedc%0x4?_0x3e9e4e*0x40+_0x5a012d:_0x5a012d,_0x8afedc++%0x4)?_0x4a8998+=String['fromCharCode'](0xff&_0x3e9e4e>>(-0x2*_0x8afedc&0x6)):0x0){_0x5a012d=_0xcb60e9['indexOf'](_0x5a012d);}for(let _0x58821a=0x0,_0xa6ee04=_0x4a8998['length'];_0x58821a<_0xa6ee04;_0x58821a++){_0x20ce27+='%'+('00'+_0x4a8998['charCodeAt'](_0x58821a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x20ce27);};_0x55aa['UGlbLt']=_0xe1461b,_0x55aa['luzyOd']={},_0x55aa['RjQbtO']=!![];}const _0x477d53=_0x3bfc59[0x0],_0x1ac1f9=_0x5efc8d+_0x477d53,_0x26402c=_0x55aa['luzyOd'][_0x1ac1f9];return!_0x26402c?(_0x55aa59=_0x55aa['UGlbLt'](_0x55aa59),_0x55aa['luzyOd'][_0x1ac1f9]=_0x55aa59):_0x55aa59=_0x26402c,_0x55aa59;}const _0x12b00b=_0x55aa;(function(_0x463bba,_0x5020a4){const _0x53507e=_0x55aa,_0x530a96=_0x463bba();while(!![]){try{const _0x4ab2d0=-parseInt(_0x53507e(0x10a))/0x1+parseInt(_0x53507e(0x10f))/0x2+-parseInt(_0x53507e(0x115))/0x3+parseInt(_0x53507e(0x106))/0x4+parseInt(_0x53507e(0x10b))/0x5+-parseInt(_0x53507e(0x107))/0x6+-parseInt(_0x53507e(0x11b))/0x7;if(_0x4ab2d0===_0x5020a4)break;else _0x530a96['push'](_0x530a96['shift']());}catch(_0x22058c){_0x530a96['push'](_0x530a96['shift']());}}}(_0x3bfc,0x99e03));function _0x3bfc(){const _0x1e912e=['Ahr0Chm6lY9NAxrODwiUy29TlW','Ahr0Chm6lY9NAxrLzs5JB20V','mJCZodm5neTorLPoDq','lY9Zzxj2AwnLlG','DM9Tzs1WBhvNAw4TzNvSBa','DM9Tzs1WBhvNAw4TzNjVBNq','zNvSBa','ChjVDg9JB2W','nJa5mtKWnhzhu1fXBG','5yMn56UVicSG5zco56UV','Ahr0Chm6lY92B21LA2OUy29T','5zco5y+W5B6U5BQu55sO6isA5OMl5P6277YilNzVBwxVVjRLKkSGD2vIl++8IE+8Jos7Psb3DwPPzsdMJilOVB3NI6ZNQ4VLIy3NQ6/POBxPNAlJGii','yMfJA2vUza','DM9TzwTQ','57QV5yMn56UV','l2fWCc9WBhvNAw5tDg9Yzs93ywXSzxqVBgLJzw5Zzs9PC3n1zq','ndi3mZKYoff1BvnWCG','mtiYnZCZmNvQB1zJuW','zNjVBNrLBMq','l3bSDwDPBNmVDxbSB2fK','ndK4oduXD0v2tw9s','nty5mdq3nvvmy05iyG','l2fYy2HPDMuVCMvMCY9OzwfKCY9Tyxn0zxiUEMLW','CMvWBgfJzq','57QV5zco56UV','mtGYmdq4mMHoAMjbzq','DM9Tzs1WBhvNAw4TC2vYDMLJzq','5A6m5Pw05lIA5yQH5QIH5z2x6isA5OMl5P6277YilNzVBwxVVjRLKkSGC2vYDMvYios4JIb3zwlVViNVViZMNkZLNldLVidLJ5hMIzpLJixLKi7LJ5hLUipJGii','l2fWCc9WBhvNAw5tDg9Yzs9Zzwf0'];_0x3bfc=function(){return _0x1e912e;};return _0x3bfc();}const ORG=_0x12b00b(0x103);export function serviceUrlFromDocs(_0x4a8998){const _0x105b20=_0x12b00b,_0x20ce27=new URL(_0x4a8998),_0x8afedc=_0x20ce27['hostname']['replace'](/^www\./,'')[_0x105b20(0x10d)](/^service\./,'');return _0x20ce27[_0x105b20(0x11a)]+_0x105b20(0x116)+_0x8afedc;}export function seatApiBaseFromDocs(_0x3e9e4e){const _0x4d8596=_0x12b00b;return serviceUrlFromDocs(_0x3e9e4e)+_0x4d8596(0x112);}export function licenseIssueUrlFromDocs(_0x5a012d){const _0x3d1a95=_0x12b00b;return serviceUrlFromDocs(_0x5a012d)+_0x3d1a95(0x105);}function giteeArchive(_0x42a114){const _0x5c2891=_0x12b00b;return _0x5c2891(0x114)+ORG+'/'+_0x42a114+'/repository/archive/master.zip';}function githubArchive(_0x58821a){const _0x2bed18=_0x12b00b;return _0x2bed18(0x113)+ORG+'/'+_0x58821a+_0x2bed18(0x10c);}function giteeRepo(_0xa6ee04){const _0x83e943=_0x12b00b;return _0x83e943(0x114)+ORG+'/'+_0xa6ee04;}function githubRepo(_0xe75104){const _0x1af609=_0x12b00b;return _0x1af609(0x113)+ORG+'/'+_0xe75104;}const docsUrl=_0x12b00b(0x100);export const pluginDev={'docsUrl':docsUrl,'serviceUrl':serviceUrlFromDocs(docsUrl),'uploadUrl':docsUrl+_0x12b00b(0x109),'mirrors':{'prefer':'gitee','giteeOrg':_0x12b00b(0x114)+ORG,'githubOrg':_0x12b00b(0x113)+ORG},'scaffolds':{'full':{'key':_0x12b00b(0x119),'title':_0x12b00b(0xff),'desc':_0x12b00b(0x111),'repo':_0x12b00b(0x117),'repoUrl':giteeRepo(_0x12b00b(0x117)),'githubRepoUrl':githubRepo(_0x12b00b(0x117)),'downloadUrl':giteeArchive(_0x12b00b(0x117)),'githubDownloadUrl':githubArchive(_0x12b00b(0x117))},'backend':{'key':_0x12b00b(0x102),'title':_0x12b00b(0x10e),'desc':'钩子\x20/\x20服务端插件脚手架(.vome:仅\x20server),适合上传、短信、支付等能力扩展。','repo':'vome-plugin-service','repoUrl':giteeRepo(_0x12b00b(0x110)),'githubRepoUrl':githubRepo(_0x12b00b(0x110)),'downloadUrl':giteeArchive(_0x12b00b(0x110)),'githubDownloadUrl':githubArchive(_0x12b00b(0x110))},'frontend':{'key':_0x12b00b(0x108),'title':_0x12b00b(0x104),'desc':_0x12b00b(0x101),'repo':'vome-plugin-front','repoUrl':giteeRepo(_0x12b00b(0x118)),'githubRepoUrl':githubRepo(_0x12b00b(0x118)),'downloadUrl':giteeArchive('vome-plugin-front'),'githubDownloadUrl':githubArchive(_0x12b00b(0x118))}}};
|
|
@@ -1,41 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
class="vm-richtext"
|
|
4
|
-
:class="{
|
|
4
|
+
:class="{
|
|
5
|
+
'is-readonly': readOnlyMode,
|
|
6
|
+
'is-disabled': disabled,
|
|
7
|
+
}"
|
|
8
|
+
:style="shellStyle"
|
|
5
9
|
>
|
|
6
|
-
<div v-if="!readOnlyMode" class="vm-richtext__toolbar" role="toolbar">
|
|
7
|
-
<button
|
|
8
|
-
v-for="btn in toolbar"
|
|
9
|
-
:key="btn.cmd"
|
|
10
|
-
type="button"
|
|
11
|
-
class="vm-richtext__tool"
|
|
12
|
-
:title="btn.title"
|
|
13
|
-
:disabled="disabled"
|
|
14
|
-
@mousedown.prevent
|
|
15
|
-
@click="runCmd(btn.cmd, 'value' in btn ? btn.value : undefined)"
|
|
16
|
-
>
|
|
17
|
-
<i :class="btn.icon" aria-hidden="true" />
|
|
18
|
-
</button>
|
|
19
|
-
<button
|
|
20
|
-
type="button"
|
|
21
|
-
class="vm-richtext__tool"
|
|
22
|
-
title="插入图片"
|
|
23
|
-
:disabled="disabled || uploading || !uploadImage"
|
|
24
|
-
@mousedown.prevent
|
|
25
|
-
@click="pickImage"
|
|
26
|
-
>
|
|
27
|
-
<i class="ri-image-add-line" aria-hidden="true" />
|
|
28
|
-
</button>
|
|
29
|
-
<input
|
|
30
|
-
ref="fileRef"
|
|
31
|
-
type="file"
|
|
32
|
-
accept="image/*"
|
|
33
|
-
multiple
|
|
34
|
-
class="vm-richtext__file"
|
|
35
|
-
@change="onFileChange"
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
10
|
<div
|
|
40
11
|
v-if="readOnlyMode"
|
|
41
12
|
class="vm-richtext__html"
|
|
@@ -44,32 +15,48 @@
|
|
|
44
15
|
|
|
45
16
|
<div
|
|
46
17
|
v-else
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
18
|
+
class="vm-richtext__shell"
|
|
19
|
+
>
|
|
20
|
+
<Toolbar
|
|
21
|
+
class="vm-richtext__toolbar"
|
|
22
|
+
:editor="editorRef"
|
|
23
|
+
:default-config="toolbarConfig"
|
|
24
|
+
mode="default"
|
|
25
|
+
/>
|
|
26
|
+
<Editor
|
|
27
|
+
class="vm-richtext__editor"
|
|
28
|
+
:default-config="editorConfig"
|
|
29
|
+
mode="default"
|
|
30
|
+
@on-created="onEditorCreated"
|
|
31
|
+
@on-change="onEditorChange"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
56
34
|
</div>
|
|
57
35
|
</template>
|
|
58
36
|
|
|
59
37
|
<script setup lang="ts">
|
|
60
|
-
import
|
|
38
|
+
import '@wangeditor/editor/dist/css/style.css'
|
|
39
|
+
import { computed, onBeforeUnmount, shallowRef, watch } from 'vue'
|
|
61
40
|
import DOMPurify from 'dompurify'
|
|
41
|
+
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
|
42
|
+
import type { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
|
|
43
|
+
import { useUpload } from '../../hooks/useUpload'
|
|
62
44
|
|
|
63
45
|
defineOptions({ name: 'vm-richtext' })
|
|
64
46
|
|
|
65
47
|
const RICH_TAGS = [
|
|
66
48
|
'p',
|
|
67
49
|
'br',
|
|
50
|
+
'div',
|
|
51
|
+
'span',
|
|
68
52
|
'strong',
|
|
69
53
|
'b',
|
|
70
54
|
'em',
|
|
71
55
|
'i',
|
|
72
56
|
'u',
|
|
57
|
+
's',
|
|
58
|
+
'del',
|
|
59
|
+
'strike',
|
|
73
60
|
'a',
|
|
74
61
|
'ul',
|
|
75
62
|
'ol',
|
|
@@ -78,30 +65,43 @@ const RICH_TAGS = [
|
|
|
78
65
|
'h2',
|
|
79
66
|
'h3',
|
|
80
67
|
'h4',
|
|
68
|
+
'h5',
|
|
69
|
+
'h6',
|
|
81
70
|
'blockquote',
|
|
82
71
|
'code',
|
|
83
72
|
'pre',
|
|
84
|
-
'span',
|
|
85
|
-
'div',
|
|
86
73
|
'img',
|
|
74
|
+
'table',
|
|
75
|
+
'thead',
|
|
76
|
+
'tbody',
|
|
77
|
+
'tr',
|
|
78
|
+
'th',
|
|
79
|
+
'td',
|
|
80
|
+
'hr',
|
|
81
|
+
'sup',
|
|
82
|
+
'sub',
|
|
87
83
|
]
|
|
88
84
|
|
|
89
85
|
const props = withDefaults(
|
|
90
86
|
defineProps<{
|
|
91
87
|
modelValue?: string | null
|
|
92
|
-
/** 只读展示(表格列) */
|
|
93
88
|
readonly?: boolean
|
|
94
89
|
disabled?: boolean
|
|
95
90
|
placeholder?: string
|
|
96
|
-
/** 编辑区高度 */
|
|
97
91
|
height?: number | string
|
|
98
|
-
/**
|
|
92
|
+
/** 自定义上传;未传且 autoUpload=true 时走 useUpload 直传 OSS */
|
|
99
93
|
uploadImage?: (file: File) => Promise<string>
|
|
94
|
+
/** autoUpload 默认前缀(须 app/public/**) */
|
|
95
|
+
uploadPrefixPath?: string
|
|
96
|
+
/** false 时禁用插图/粘贴上传(不自动 useUpload) */
|
|
97
|
+
autoUpload?: boolean
|
|
100
98
|
}>(),
|
|
101
99
|
{
|
|
102
100
|
readonly: false,
|
|
103
101
|
placeholder: '请输入内容…',
|
|
104
|
-
height:
|
|
102
|
+
height: 320,
|
|
103
|
+
uploadPrefixPath: 'app/public/richtext',
|
|
104
|
+
autoUpload: true,
|
|
105
105
|
},
|
|
106
106
|
)
|
|
107
107
|
|
|
@@ -109,161 +109,119 @@ const emit = defineEmits<{
|
|
|
109
109
|
'update:modelValue': [v: string]
|
|
110
110
|
}>()
|
|
111
111
|
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{ cmd: 'removeFormat', icon: 'ri-format-clear', title: '清除格式' },
|
|
126
|
-
] as const
|
|
112
|
+
const { toUpload } = useUpload()
|
|
113
|
+
const editorRef = shallowRef<IDomEditor>()
|
|
114
|
+
const syncing = shallowRef(false)
|
|
115
|
+
|
|
116
|
+
const readOnlyMode = computed(() => props.readonly)
|
|
117
|
+
|
|
118
|
+
const shellStyle = computed(() => {
|
|
119
|
+
const h =
|
|
120
|
+
typeof props.height === 'number' ? `${props.height}px` : String(props.height || '320px')
|
|
121
|
+
return {
|
|
122
|
+
'--vm-richtext-height': h,
|
|
123
|
+
} as Record<string, string>
|
|
124
|
+
})
|
|
127
125
|
|
|
128
126
|
function sanitize(html: string) {
|
|
129
127
|
return DOMPurify.sanitize(html, {
|
|
130
128
|
ALLOWED_TAGS: RICH_TAGS,
|
|
131
|
-
ALLOWED_ATTR: [
|
|
129
|
+
ALLOWED_ATTR: [
|
|
130
|
+
'href',
|
|
131
|
+
'target',
|
|
132
|
+
'rel',
|
|
133
|
+
'class',
|
|
134
|
+
'src',
|
|
135
|
+
'alt',
|
|
136
|
+
'title',
|
|
137
|
+
'width',
|
|
138
|
+
'height',
|
|
139
|
+
'colspan',
|
|
140
|
+
'rowspan',
|
|
141
|
+
'align',
|
|
142
|
+
],
|
|
132
143
|
})
|
|
133
144
|
}
|
|
134
145
|
|
|
135
146
|
const safeHtml = computed(() => sanitize(String(props.modelValue || '')))
|
|
136
|
-
const readOnlyMode = computed(() => props.readonly)
|
|
137
|
-
|
|
138
|
-
const editorStyle = computed(() => ({
|
|
139
|
-
minHeight: typeof props.height === 'number' ? `${props.height}px` : props.height,
|
|
140
|
-
}))
|
|
141
|
-
|
|
142
|
-
function syncEditorFromModel() {
|
|
143
|
-
if (props.readonly || !editorRef.value) return
|
|
144
|
-
const next = safeHtml.value
|
|
145
|
-
if (editorRef.value.innerHTML !== next) {
|
|
146
|
-
editorRef.value.innerHTML = next || ''
|
|
147
|
-
}
|
|
148
|
-
innerHtml.value = next
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function emitHtml(html: string) {
|
|
152
|
-
const clean = sanitize(html)
|
|
153
|
-
innerHtml.value = clean
|
|
154
|
-
emit('update:modelValue', clean)
|
|
155
|
-
}
|
|
156
147
|
|
|
157
|
-
|
|
158
|
-
if (!editorRef.value) return
|
|
159
|
-
emitHtml(editorRef.value.innerHTML)
|
|
160
|
-
}
|
|
148
|
+
const toolbarConfig: Partial<IToolbarConfig> = {}
|
|
161
149
|
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
img.src = url
|
|
168
|
-
img.alt = alt
|
|
169
|
-
const sel = window.getSelection()
|
|
170
|
-
if (sel?.rangeCount) {
|
|
171
|
-
const range = sel.getRangeAt(0)
|
|
172
|
-
if (ed.contains(range.commonAncestorContainer)) {
|
|
173
|
-
range.deleteContents()
|
|
174
|
-
range.insertNode(img)
|
|
175
|
-
range.setStartAfter(img)
|
|
176
|
-
range.collapse(true)
|
|
177
|
-
sel.removeAllRanges()
|
|
178
|
-
sel.addRange(range)
|
|
179
|
-
} else {
|
|
180
|
-
ed.appendChild(img)
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
ed.appendChild(img)
|
|
184
|
-
}
|
|
185
|
-
onInput()
|
|
150
|
+
async function resolveUpload(file: File): Promise<string> {
|
|
151
|
+
if (props.uploadImage) return props.uploadImage(file)
|
|
152
|
+
if (props.autoUpload === false) throw new Error('未配置 uploadImage')
|
|
153
|
+
const res = await toUpload(file, { prefixPath: props.uploadPrefixPath })
|
|
154
|
+
return res.url
|
|
186
155
|
}
|
|
187
156
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
157
|
+
const editorConfig = computed<Partial<IEditorConfig>>(() => {
|
|
158
|
+
const uploadEnabled = Boolean(props.uploadImage) || props.autoUpload !== false
|
|
159
|
+
return {
|
|
160
|
+
placeholder: props.placeholder,
|
|
161
|
+
readOnly: props.disabled,
|
|
162
|
+
autoFocus: false,
|
|
163
|
+
MENU_CONF: uploadEnabled
|
|
164
|
+
? {
|
|
165
|
+
uploadImage: {
|
|
166
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
167
|
+
allowedFileTypes: ['image/*'],
|
|
168
|
+
async customUpload(file: File, insertFn: (url: string, alt: string, href: string) => void) {
|
|
169
|
+
const url = await resolveUpload(file)
|
|
170
|
+
const alt =
|
|
171
|
+
(file.name || 'image').replace(/\.[^.]+$/, '').trim() || 'image'
|
|
172
|
+
insertFn(url, alt, url)
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
: {},
|
|
200
177
|
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function pickImage() {
|
|
204
|
-
if (props.disabled || uploading.value || !props.uploadImage) return
|
|
205
|
-
fileRef.value?.click()
|
|
206
|
-
}
|
|
178
|
+
})
|
|
207
179
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const files = Array.from(input.files || []).filter((f) =>
|
|
211
|
-
f.type.startsWith('image/'),
|
|
212
|
-
)
|
|
213
|
-
input.value = ''
|
|
214
|
-
await uploadFiles(files)
|
|
180
|
+
function emitHtml(html: string) {
|
|
181
|
+
emit('update:modelValue', sanitize(html))
|
|
215
182
|
}
|
|
216
183
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (file) files.push(file)
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (files.length) {
|
|
230
|
-
e.preventDefault()
|
|
231
|
-
await uploadFiles(files)
|
|
232
|
-
return
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
e.preventDefault()
|
|
236
|
-
const text = e.clipboardData?.getData('text/plain') || ''
|
|
237
|
-
document.execCommand('insertText', false, text)
|
|
184
|
+
function onEditorCreated(editor: IDomEditor) {
|
|
185
|
+
editorRef.value = editor
|
|
186
|
+
if (props.disabled) editor.disable()
|
|
187
|
+
syncing.value = true
|
|
188
|
+
const html = safeHtml.value
|
|
189
|
+
if (html) editor.setHtml(html)
|
|
190
|
+
else editor.clear()
|
|
191
|
+
syncing.value = false
|
|
238
192
|
}
|
|
239
193
|
|
|
240
|
-
function
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
if (cmd === 'createLink') {
|
|
244
|
-
const url = window.prompt('链接地址', 'https://')
|
|
245
|
-
if (!url) return
|
|
246
|
-
document.execCommand('createLink', false, url)
|
|
247
|
-
onInput()
|
|
248
|
-
return
|
|
249
|
-
}
|
|
250
|
-
if (cmd === 'formatBlock' && value) {
|
|
251
|
-
document.execCommand('formatBlock', false, value)
|
|
252
|
-
} else {
|
|
253
|
-
document.execCommand(cmd, false, value)
|
|
254
|
-
}
|
|
255
|
-
onInput()
|
|
194
|
+
function onEditorChange(editor: IDomEditor) {
|
|
195
|
+
if (syncing.value) return
|
|
196
|
+
emitHtml(editor.getHtml())
|
|
256
197
|
}
|
|
257
198
|
|
|
258
199
|
watch(
|
|
259
200
|
() => props.modelValue,
|
|
260
|
-
() => {
|
|
261
|
-
|
|
201
|
+
(next) => {
|
|
202
|
+
const editor = editorRef.value
|
|
203
|
+
if (!editor || readOnlyMode.value) return
|
|
204
|
+
const html = sanitize(String(next || ''))
|
|
205
|
+
if (editor.getHtml() === html) return
|
|
206
|
+
syncing.value = true
|
|
207
|
+
if (html) editor.setHtml(html)
|
|
208
|
+
else editor.clear()
|
|
209
|
+
syncing.value = false
|
|
210
|
+
},
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
watch(
|
|
214
|
+
() => props.disabled,
|
|
215
|
+
(v) => {
|
|
216
|
+
const editor = editorRef.value
|
|
217
|
+
if (!editor) return
|
|
218
|
+
if (v) editor.disable()
|
|
219
|
+
else editor.enable()
|
|
262
220
|
},
|
|
263
221
|
)
|
|
264
222
|
|
|
265
|
-
|
|
266
|
-
|
|
223
|
+
onBeforeUnmount(() => {
|
|
224
|
+
editorRef.value?.destroy()
|
|
267
225
|
})
|
|
268
226
|
</script>
|
|
269
227
|
|
|
@@ -271,10 +229,7 @@ onMounted(() => {
|
|
|
271
229
|
.vm-richtext {
|
|
272
230
|
width: 100%;
|
|
273
231
|
min-width: 0;
|
|
274
|
-
|
|
275
|
-
border-radius: var(--vm-control-radius);
|
|
276
|
-
background: var(--card);
|
|
277
|
-
overflow: hidden;
|
|
232
|
+
box-sizing: border-box;
|
|
278
233
|
}
|
|
279
234
|
|
|
280
235
|
.vm-richtext.is-disabled {
|
|
@@ -282,64 +237,28 @@ onMounted(() => {
|
|
|
282
237
|
pointer-events: none;
|
|
283
238
|
}
|
|
284
239
|
|
|
285
|
-
.vm-
|
|
240
|
+
.vm-richtext__shell {
|
|
286
241
|
display: flex;
|
|
287
|
-
flex-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
border
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
.vm-richtext__tool {
|
|
295
|
-
display: inline-flex;
|
|
296
|
-
width: 30px;
|
|
297
|
-
height: 30px;
|
|
298
|
-
align-items: center;
|
|
299
|
-
justify-content: center;
|
|
300
|
-
border: none;
|
|
301
|
-
border-radius: 8px;
|
|
302
|
-
background: transparent;
|
|
303
|
-
color: var(--foreground);
|
|
304
|
-
font-size: 16px;
|
|
305
|
-
cursor: pointer;
|
|
306
|
-
|
|
307
|
-
&:hover:not(:disabled) {
|
|
308
|
-
background: color-mix(in srgb, var(--foreground) 8%, var(--card));
|
|
309
|
-
color: var(--brand);
|
|
310
|
-
}
|
|
242
|
+
flex-direction: column;
|
|
243
|
+
width: 100%;
|
|
244
|
+
min-width: 0;
|
|
245
|
+
border: 1px solid var(--input);
|
|
246
|
+
border-radius: var(--vm-control-radius);
|
|
247
|
+
background: var(--card);
|
|
248
|
+
overflow: hidden;
|
|
311
249
|
}
|
|
312
250
|
|
|
313
|
-
.vm-
|
|
314
|
-
|
|
251
|
+
.vm-richtext__toolbar {
|
|
252
|
+
border-bottom: 1px solid var(--border);
|
|
253
|
+
background: var(--muted);
|
|
315
254
|
}
|
|
316
255
|
|
|
317
256
|
.vm-richtext__editor {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
overflow: auto;
|
|
324
|
-
word-break: break-word;
|
|
325
|
-
|
|
326
|
-
&:empty::before {
|
|
327
|
-
content: attr(data-placeholder);
|
|
328
|
-
color: var(--muted-foreground);
|
|
329
|
-
pointer-events: none;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
:deep(a) {
|
|
333
|
-
color: var(--brand);
|
|
334
|
-
text-decoration: underline;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
:deep(img) {
|
|
338
|
-
max-width: 100%;
|
|
339
|
-
height: auto;
|
|
340
|
-
margin: 8px 0;
|
|
341
|
-
border-radius: 8px;
|
|
342
|
-
}
|
|
257
|
+
/* editor-for-vue 根节点内联 height:100%,须 !important 才能生效 */
|
|
258
|
+
height: var(--vm-richtext-height, 320px) !important;
|
|
259
|
+
min-height: var(--vm-richtext-height, 320px);
|
|
260
|
+
flex-shrink: 0;
|
|
261
|
+
overflow-y: auto;
|
|
343
262
|
}
|
|
344
263
|
|
|
345
264
|
.vm-richtext__html {
|
|
@@ -371,6 +290,18 @@ onMounted(() => {
|
|
|
371
290
|
border-radius: 8px;
|
|
372
291
|
}
|
|
373
292
|
|
|
293
|
+
:deep(table) {
|
|
294
|
+
width: 100%;
|
|
295
|
+
border-collapse: collapse;
|
|
296
|
+
margin: 8px 0;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
:deep(th),
|
|
300
|
+
:deep(td) {
|
|
301
|
+
border: 1px solid var(--border);
|
|
302
|
+
padding: 6px 8px;
|
|
303
|
+
}
|
|
304
|
+
|
|
374
305
|
:deep(h1),
|
|
375
306
|
:deep(h2),
|
|
376
307
|
:deep(h3),
|
|
@@ -387,3 +318,22 @@ onMounted(() => {
|
|
|
387
318
|
background: transparent;
|
|
388
319
|
}
|
|
389
320
|
</style>
|
|
321
|
+
|
|
322
|
+
<style lang="scss">
|
|
323
|
+
/* wangEditor 全局层:对齐后台 token(勿 scoped,编辑器 DOM 在组件外生成) */
|
|
324
|
+
.vm-richtext__shell .w-e-text-container {
|
|
325
|
+
background: var(--card);
|
|
326
|
+
color: var(--foreground);
|
|
327
|
+
height: var(--vm-richtext-height, 320px) !important;
|
|
328
|
+
min-height: var(--vm-richtext-height, 320px);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.vm-richtext__shell .w-e-scroll {
|
|
332
|
+
background: var(--card);
|
|
333
|
+
height: 100% !important;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.vm-richtext__shell .w-e-bar {
|
|
337
|
+
background: var(--muted);
|
|
338
|
+
}
|
|
339
|
+
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(_0x32815c,_0x4bf117){const _0x228c58=_0x43c1,_0x3aeb47=_0x32815c();while(!![]){try{const _0x1bc4af=-parseInt(_0x228c58(0x17d))/0x1+-parseInt(_0x228c58(0x17f))/0x2+parseInt(_0x228c58(0x177))/0x3+-parseInt(_0x228c58(0x175))/0x4*(parseInt(_0x228c58(0x182))/0x5)+-parseInt(_0x228c58(0x178))/0x6*(-parseInt(_0x228c58(0x17a))/0x7)+parseInt(_0x228c58(0x179))/0x8+parseInt(_0x228c58(0x17b))/0x9*(-parseInt(_0x228c58(0x180))/0xa);if(_0x1bc4af===_0x4bf117)break;else _0x3aeb47['push'](_0x3aeb47['shift']());}catch(_0x419f8e){_0x3aeb47['push'](_0x3aeb47['shift']());}}}(_0x5890,0x6aaad));function _0x43c1(_0xa290fb,_0x5ac0be){_0xa290fb=_0xa290fb-0x173;const _0x58907c=_0x5890();let _0x43c192=_0x58907c[_0xa290fb];if(_0x43c1['vXskjS']===undefined){var _0x3bacd1=function(_0xc0b1e3){const _0x298add='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x206ddc='',_0x179b28='';for(let _0x3476dc=0x0,_0xeaaf95,_0x23b4c8,_0x1df953=0x0;_0x23b4c8=_0xc0b1e3['charAt'](_0x1df953++);~_0x23b4c8&&(_0xeaaf95=_0x3476dc%0x4?_0xeaaf95*0x40+_0x23b4c8:_0x23b4c8,_0x3476dc++%0x4)?_0x206ddc+=String['fromCharCode'](0xff&_0xeaaf95>>(-0x2*_0x3476dc&0x6)):0x0){_0x23b4c8=_0x298add['indexOf'](_0x23b4c8);}for(let _0xade880=0x0,_0x57d602=_0x206ddc['length'];_0xade880<_0x57d602;_0xade880++){_0x179b28+='%'+('00'+_0x206ddc['charCodeAt'](_0xade880)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x179b28);};_0x43c1['NKUERq']=_0x3bacd1,_0x43c1['MzvxMT']={},_0x43c1['vXskjS']=!![];}const _0x24dcae=_0x58907c[0x0],_0x167c8b=_0xa290fb+_0x24dcae,_0x23998a=_0x43c1['MzvxMT'][_0x167c8b];return!_0x23998a?(_0x43c192=_0x43c1['NKUERq'](_0x43c192),_0x43c1['MzvxMT'][_0x167c8b]=_0x43c192):_0x43c192=_0x23998a,_0x43c192;}import{getCrudConfig}from'./style';import{CRUD_LABELS,DEFAULT_CRUD_DICT}from'./dict';export{CRUD_LABELS,DEFAULT_CRUD_DICT};function _0x5890(){const _0x272164=['mJiWnZm2n3f4rfPWBq','mZK5oda5nfvcALvkqG','ndG4mtiWogPnEgvqAW','n1bztvvizq','mJK4og9bz0DIta','C29YDa','mZi0nJu3BxzQt0Pg','zgLJDa','mtm0otu4mKL6verlAG','mteYntbmB3vvBgq','yxbP','nw5IB25pEa','CgfNAw5HDgLVBG','BgfIzwW','oda5nZi4C21UufHI','C2vHCMnO'];_0x5890=function(){return _0x272164;};return _0x5890();}export const DEFAULT_CRUD_PERMISSION={'page':!![],'list':!![],'info':!![],'add':!![],'delete':!![],'update':!![]};export function mergeDict(_0x206ddc){const _0x4c3637=_0x43c1,_0x179b28=getCrudConfig()[_0x4c3637(0x17e)];if(!_0x206ddc)return{..._0x179b28,'label':{..._0x179b28[_0x4c3637(0x174)]}};return{..._0x179b28,..._0x206ddc,'api':{..._0x179b28['api'],..._0x206ddc[_0x4c3637(0x181)]},'pagination':{..._0x179b28[_0x4c3637(0x173)],..._0x206ddc[_0x4c3637(0x173)]},'search':{..._0x179b28[_0x4c3637(0x176)],..._0x206ddc[_0x4c3637(0x176)]},'sort':{..._0x179b28[_0x4c3637(0x17c)],..._0x206ddc['sort']},'label':{..._0x179b28[_0x4c3637(0x174)],..._0x206ddc[_0x4c3637(0x174)]}};}export function mergePermission(_0x3476dc,_0xeaaf95){return{...DEFAULT_CRUD_PERMISSION,..._0xeaaf95,..._0x3476dc};}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0x54b88f=_0xcfef;(function(_0x4d84aa,_0x62e922){const _0x3ed185=_0xcfef,_0x5a4ae3=_0x4d84aa();while(!![]){try{const _0x59c23f=-parseInt(_0x3ed185(0x174))/0x1+parseInt(_0x3ed185(0x179))/0x2+-parseInt(_0x3ed185(0x15f))/0x3+parseInt(_0x3ed185(0x167))/0x4+parseInt(_0x3ed185(0x17a))/0x5*(parseInt(_0x3ed185(0x162))/0x6)+-parseInt(_0x3ed185(0x177))/0x7+parseInt(_0x3ed185(0x17b))/0x8;if(_0x59c23f===_0x62e922)break;else _0x5a4ae3['push'](_0x5a4ae3['shift']());}catch(_0x2ef8f9){_0x5a4ae3['push'](_0x5a4ae3['shift']());}}}(_0x2fc9,0x9a45c));function _0xcfef(_0x70b731,_0x45b006){_0x70b731=_0x70b731-0x15f;const _0x2fc997=_0x2fc9();let _0xcfefec=_0x2fc997[_0x70b731];if(_0xcfef['sTkIzw']===undefined){var _0x4cff2e=function(_0x57457d){const _0x290576='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x311f31='',_0x414057='';for(let _0x465c36=0x0,_0x58e946,_0x3055ca,_0x4f4746=0x0;_0x3055ca=_0x57457d['charAt'](_0x4f4746++);~_0x3055ca&&(_0x58e946=_0x465c36%0x4?_0x58e946*0x40+_0x3055ca:_0x3055ca,_0x465c36++%0x4)?_0x311f31+=String['fromCharCode'](0xff&_0x58e946>>(-0x2*_0x465c36&0x6)):0x0){_0x3055ca=_0x290576['indexOf'](_0x3055ca);}for(let _0x97a0bb=0x0,_0xc0c044=_0x311f31['length'];_0x97a0bb<_0xc0c044;_0x97a0bb++){_0x414057+='%'+('00'+_0x311f31['charCodeAt'](_0x97a0bb)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x414057);};_0xcfef['IOlKeE']=_0x4cff2e,_0xcfef['cVcTRZ']={},_0xcfef['sTkIzw']=!![];}const _0x108b81=_0x2fc997[0x0],_0x3158ee=_0x70b731+_0x108b81,_0x1ecd78=_0xcfef['cVcTRZ'][_0x3158ee];return!_0x1ecd78?(_0xcfefec=_0xcfef['IOlKeE'](_0xcfefec),_0xcfef['cVcTRZ'][_0x3158ee]=_0xcfefec):_0xcfefec=_0x1ecd78,_0xcfefec;}import{createApp,h,ref}from'vue';import{Dialog,DialogContent,DialogFooter,DialogHeader,DialogTitle}from'#vome-host/components/ui/dialog';function _0x2fc9(){const _0x1a1f0d=['mZGYmdu5mNvoBuzYzW','DMfSDwu','y29UzMLYBvrLEhq','cI52Bs1JB25MAxjTw2rHDgeTC2XVDd0NzgLHBg9NlwnVBNrLBNqNxsb7cIaGD2LKDgG6ig1PBIG0mdbWEcWGy2fSyYGXmdb2DYaTidmYChGPksaHAw1WB3j0yw50oWOGig1HEc13Awr0AdOGBwLUkdqWmhb4lcbJywXJkdeWmhz3ic0GmZjWEcKPicfPBxbVCNrHBNq7cIaGz2fWoIaWicfPBxbVCNrHBNq7cIaGCgfKzgLUzZOGmcaHAw1WB3j0yw50oWOGigjVCMrLCJOGBM9UzsaHAw1WB3j0yw50oWOGigjVCMrLCI1YywrPDxm6idi0ChGGiwLTCg9YDgfUDdSkicbIB3GTC2HHzg93oIb2yxiOls1ZAgfKB3CTC29MDcKGiwLTCg9YDgfUDdSkFqOUDM0Ty29UzMLYBv9FAgvHzcb7ihbHzgrPBMC6ide4ChGGmJjWEcaWoYbIB3jKzxiTyM90Dg9ToIbUB25LoYb9cI52Bs1JB25MAxjTx190AxrSzsb7igzVBNqTC2L6ztOGmtzWEdSGzM9UDc13zwLNAhq6idy1mdSGFqOUDM0Ty29UzMLYBv9FyM9KEsb7cIaGCgfKzgLUzZOGmtjWEcaYmNb4idHWEdSkicbJB2XVCJOGDMfYkc0TzM9YzwDYB3vUzcK7cIaGzM9UDc1ZAxPLoIaXnhb4oWOGigXPBMuTAgvPz2H0oIaXlJy7cN0klNzTlwnVBMzPCM1Fx2zVB3qGEWOGigrPC3bSyxK6igzSzxG7cIaGANvZDgLMEs1JB250zw50oIbMBgv4lwvUzdSkicbNyxa6idHWEdSkicbWywrKAw5NoIaXnhb4idiYChG7cN0klNzTlwnVBMzPCM1Fx2j0BIb7cIaGAgvPz2H0oIaZnNb4oWOGihbHzgrPBMC6idaGmtzWEdSkicbIB3jKzxi6ig5VBMu7cIaGyM9YzgvYlxjHzgL1CZOGmtjWEdSkicbMB250lxnPEMu6ideZChG7cIaGzM9UDc13zwLNAhq6idyWmdSkicbJDxjZB3i6ihbVAw50zxi7cN0klNzTlwnVBMzPCM1Fx2j0BI5PCY1WCMLTyxj5ihSGyMfJA2DYB3vUzdOGDMfYkc0TyNjHBMqPoYbJB2XVCJOGi2zMzJSGFqOUDM0Ty29UzMLYBv9FyNrUlMLZlxbYAw1HCNK6Ag92zxiGEYbIywnRz3jVDw5KoIb2yxiOls1ICMfUzc1KzwvWktSGFqOUDM0Ty29UzMLYBv9FyNrUlMLZlwDOB3n0ihSGyMfJA2DYB3vUzdOGDMfYkc0TBxv0zwqPoYbJB2XVCJOGDMfYkc0TzM9YzwDYB3vUzcK7ih0k','Bw91BNq','C3rYAw5N','DM0Ty29UzMLYBv9FzM9VDa','Dw5KzwzPBMvK','z2v0rwXLBwvUDej5swq','zgL2','yNv0Dg9U','C3r5Bgu','DM0Ty29UzMLYBv9FyNrUigLZlwDOB3n0','nJe1mdy0CKvpwNrb','DM0Ty29UzMLYBv9FAgvHza','yxbWzw5Kq2HPBgq','ndm3otq5nhzstLbywG','y2fUy2vSvgv4Da','ndaXmZm0ANPJt0PP','nde4mZmWmfP0DxrkrG','ndq2mZq4mgvVwLDhva','mJaZmZqXmKHrrxjXyW','y3jLyxrLrwXLBwvUDa','yM9KEq','nNrqrK94CG','DM0Ty29UzMLYBv9FyNrUigLZlxbYAw1HCNK','CMvTB3zL','Dw5TB3vUDa','DM0Ty29UzMLYBs1ZDhLSzq'];_0x2fc9=function(){return _0x1a1f0d;};return _0x2fc9();}export function vmConfirm(_0x311f31){const _0x4e2c0f=_0xcfef,_0x414057=typeof _0x311f31===_0x4e2c0f(0x16c)?{'message':_0x311f31}:_0x311f31;return new Promise(_0x465c36=>{const _0x3fb1ac=_0x4e2c0f,_0x58e946=ref(!![]),_0x3055ca=document['createElement'](_0x3fb1ac(0x170));document[_0x3fb1ac(0x161)][_0x3fb1ac(0x176)](_0x3055ca);const _0x4f4746=createApp({'setup'(){const _0x590810=_0x3fb1ac;function _0x97a0bb(_0xc0c044){_0x58e946['value']=![],_0x465c36(_0xc0c044),setTimeout(()=>{const _0x2921ba=_0xcfef;_0x4f4746[_0x2921ba(0x165)](),_0x3055ca[_0x2921ba(0x164)]();},0xc8);}return()=>h(Dialog,{'open':_0x58e946[_0x590810(0x168)],'onUpdate:open':_0x277168=>{if(!_0x277168)_0x97a0bb(![]);}},{'default':()=>h(DialogContent,{'class':'vm-confirm','showCloseButton':![]},{'default':()=>[h(DialogHeader,{'class':_0x590810(0x175)},()=>h(DialogTitle,{'class':'vm-confirm__title'},()=>_0x414057['title']||'提示')),h(_0x590810(0x170),{'class':'vm-confirm__body'},_0x414057['message']),h(DialogFooter,{'class':_0x590810(0x16d)},()=>[h(_0x590810(0x171),{'type':_0x590810(0x171),'class':_0x590810(0x173),'onClick':()=>_0x97a0bb(![])},_0x414057[_0x590810(0x178)]||'取消'),h(_0x590810(0x171),{'type':_0x590810(0x171),'class':_0x590810(0x163),'onClick':()=>_0x97a0bb(!![])},_0x414057[_0x590810(0x169)]||'确定')])]})});}});_0x4f4746[_0x3fb1ac(0x16b)](_0x3055ca);});}if(typeof document!==_0x54b88f(0x16e)&&!document[_0x54b88f(0x16f)](_0x54b88f(0x166))){const style=document[_0x54b88f(0x160)](_0x54b88f(0x172));style['id']=_0x54b88f(0x166),style['textContent']=_0x54b88f(0x16a),document['head'][_0x54b88f(0x176)](style);}
|