diff --git a/package.json b/package.json
index dce5244d..1a836c5a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "yudao-ui-admin-vue3",
- "version": "1.7.1-snapshot.1961",
+ "version": "1.7.2-snapshot",
"description": "基于vue3、vite4、element-plus、typesScript",
"author": "xingyu",
"private": false,
diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts
index d3b18d9c..55e933ed 100644
--- a/src/router/modules/remaining.ts
+++ b/src/router/modules/remaining.ts
@@ -272,7 +272,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
{
path: '/manager/task-assign-rule',
component: () => import('@/views/bpm/taskAssignRule/index.vue'),
- name: 'BpmTaskAssignRule',
+ name: 'BpmTaskAssignRuleList',
meta: {
noCache: true,
hidden: true,
diff --git a/src/utils/routerHelper.ts b/src/utils/routerHelper.ts
index af6a9c3c..a6825653 100644
--- a/src/utils/routerHelper.ts
+++ b/src/utils/routerHelper.ts
@@ -1,10 +1,22 @@
+import type { RouteLocationNormalized, Router, RouteRecordNormalized } from 'vue-router'
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
-import type { Router, RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'
import { isUrl } from '@/utils/is'
-import { omit, cloneDeep } from 'lodash-es'
+import { cloneDeep, omit } from 'lodash-es'
const modules = import.meta.glob('../views/**/*.{vue,tsx}')
-
+/**
+ * 注册一个异步组件
+ * @param componentPath 例:/bpm/oa/leave/detail
+ */
+export const registerComponent = (componentPath: string) => {
+ for (const item in modules) {
+ if (item.includes(componentPath)) {
+ // 使用异步组件的方式来动态加载组件
+ // @ts-ignore
+ return defineAsyncComponent(modules[item])
+ }
+ }
+}
/* Layout */
export const Layout = () => import('@/layout/Layout.vue')
diff --git a/src/views/bpm/form/editor/index.vue b/src/views/bpm/form/editor/index.vue
index c56a7747..f11c1228 100644
--- a/src/views/bpm/form/editor/index.vue
+++ b/src/views/bpm/form/editor/index.vue
@@ -44,10 +44,13 @@ import { CommonStatusEnum } from '@/utils/constants'
import * as FormApi from '@/api/bpm/form'
import FcDesigner from '@form-create/designer'
import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate'
+import { useTagsViewStore } from '@/store/modules/tagsView'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息
-const { query } = useRoute() // 路由
+const { push, currentRoute } = useRouter() // 路由
+const { query } = useRoute() // 路由信息
+const { delView } = useTagsViewStore() // 视图操作
const designer = ref() // 表单设计器
const dialogVisible = ref(false) // 弹窗是否展示
@@ -88,10 +91,16 @@ const submitForm = async () => {
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
+ close()
} finally {
formLoading.value = false
}
}
+/** 关闭按钮 */
+const close = () => {
+ delView(unref(currentRoute))
+ push('/bpm/manager/form')
+}
/** 初始化 **/
onMounted(async () => {
diff --git a/src/views/bpm/form/index.vue b/src/views/bpm/form/index.vue
index 915bd0bd..48bb3698 100644
--- a/src/views/bpm/form/index.vue
+++ b/src/views/bpm/form/index.vue
@@ -2,26 +2,33 @@
- 搜索
- 重置
-
- 新增
+
+
+ 搜索
+
+
+
+ 重置
+
+
+
+ 新增
@@ -30,38 +37,38 @@
-
-
-
+
+
+
-
+
-
+
编辑
-
+
详情
删除
@@ -70,27 +77,28 @@
-
@@ -231,12 +231,8 @@ const sendMsg = async () => {
list.value = [...list.value, ...[data]]
scrollToBottom()
- //ts检查的時候会判断这个组件可能是空的,所以需要进行断言。
- //避免 tab 的数据未清理
- const deleteObj = replySelectRef.value?.deleteObj
- if (deleteObj) {
- deleteObj()
- }
+ // 发送后清空数据
+ replySelectRef.value?.clear()
}
const loadingMore = () => {
@@ -333,6 +329,7 @@ const scrollToBottom = () => {
.send-but {
float: right;
- margin-top: 8px !important;
+ margin-top: 8px;
+ margin-bottom: 8px;
}
diff --git a/src/views/mp/components/wx-reply/components/TabImage.vue b/src/views/mp/components/wx-reply/components/TabImage.vue
new file mode 100644
index 00000000..eecc24cb
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabImage.vue
@@ -0,0 +1,171 @@
+
+
+
+ 图片
+
+
+
+
![]()
+
{{ objData.name }}
+
+
+
+
+
+
+
+
+
+
+
+ 素材库选择
+
+
+
+
+
+
+
+
+ 上传图片
+
+
+ 支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/TabMusic.vue b/src/views/mp/components/wx-reply/components/TabMusic.vue
new file mode 100644
index 00000000..2c3b04e5
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabMusic.vue
@@ -0,0 +1,119 @@
+
+
+
+ 音乐
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 本地上传
+
+ 素材库选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/TabNews.vue b/src/views/mp/components/wx-reply/components/TabNews.vue
new file mode 100644
index 00000000..bb9272e7
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabNews.vue
@@ -0,0 +1,78 @@
+
+
+
+ 图文
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ newsType === NewsType.Published ? '选择已发布图文' : '选择草稿箱图文' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/TabText.vue b/src/views/mp/components/wx-reply/components/TabText.vue
new file mode 100644
index 00000000..bd7b0187
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabText.vue
@@ -0,0 +1,27 @@
+
+
+
+ 文本
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/TabVideo.vue b/src/views/mp/components/wx-reply/components/TabVideo.vue
new file mode 100644
index 00000000..c924bc2a
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabVideo.vue
@@ -0,0 +1,132 @@
+
+
+
+ 视频
+
+
+
+
+
+
+
+
+
+
+
+
+ 素材库选择
+
+
+
+
+
+
+
+
+ 新建视频
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/TabVoice.vue b/src/views/mp/components/wx-reply/components/TabVoice.vue
new file mode 100644
index 00000000..6d40a052
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/TabVoice.vue
@@ -0,0 +1,160 @@
+
+
+
+ 语音
+
+
+
{{ objData.name }}
+
+
+
+
+
+
+
+
+
+
+
+ 素材库选择
+
+
+
+
+
+
+
+
+ 点击上传
+
+
+ 格式支持 mp3/wma/wav/amr,文件大小不超过 2M,播放长度不超过 60s
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/components/wx-reply/components/types.ts b/src/views/mp/components/wx-reply/components/types.ts
new file mode 100644
index 00000000..d5273334
--- /dev/null
+++ b/src/views/mp/components/wx-reply/components/types.ts
@@ -0,0 +1,25 @@
+type ReplyType = '' | 'news' | 'image' | 'voice' | 'video' | 'music' | 'text'
+
+interface ObjData {
+ accountId: number
+ type: ReplyType
+ name: string | null
+ content: string | null
+ mediaId: string | null
+ url: string | null
+ title: string | null
+ description: string | null
+ thumbMediaId: string | null
+ thumbMediaUrl: string | null
+ musicUrl: string | null
+ hqMusicUrl: string | null
+ introduction: string | null
+ articles: any[]
+}
+
+enum NewsType {
+ Published = '1',
+ Draft = '2'
+}
+
+export { ObjData, NewsType }
diff --git a/src/views/mp/components/wx-reply/main.vue b/src/views/mp/components/wx-reply/main.vue
index 4768eb31..b00e4345 100644
--- a/src/views/mp/components/wx-reply/main.vue
+++ b/src/views/mp/components/wx-reply/main.vue
@@ -8,607 +8,64 @@
④ 支持发送【视频】消息时,支持新建视频
-->
-
+
-
-
- 文本
-
-
-
+
-
-
- 图片
-
-
-
-
![]()
-
{{ objDataRef.name }}
-
-
-
-
-
-
-
-
-
-
-
- 素材库选择
-
-
-
-
-
-
-
-
- 上传图片
-
-
- 支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
-
-
-
-
-
-
+
-
-
- 语音
-
-
-
{{ objDataRef.name }}
-
-
-
-
-
-
-
-
-
-
-
- 素材库选择
-
-
-
-
-
-
-
-
- 点击上传
-
-
- 格式支持 mp3/wma/wav/amr,文件大小不超过 2M,播放长度不超过 60s
-
-
-
-
-
-
+
-
-
- 视频
-
-
-
-
-
-
-
-
-
-
-
-
- 素材库选择
-
-
-
-
-
-
-
-
- 新建视频
-
-
-
-
-
-
+
-
-
- 图文
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ newsType === '1' ? '选择已发布图文' : '选择草稿箱图文' }}
-
-
-
-
-
-
-
-
-
-
+
-
-
- 音乐
-
-
-
-
-
-
-
-
-
-
-
-
-
- 本地上传
-
- 素材库选择
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
diff --git a/src/views/mp/draft/components/DraftTable.vue b/src/views/mp/draft/components/DraftTable.vue
new file mode 100644
index 00000000..63cee31f
--- /dev/null
+++ b/src/views/mp/draft/components/DraftTable.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/draft/components/NewsForm.vue b/src/views/mp/draft/components/NewsForm.vue
new file mode 100644
index 00000000..a2b88a5b
--- /dev/null
+++ b/src/views/mp/draft/components/NewsForm.vue
@@ -0,0 +1,302 @@
+
+
+
+
+
+
+
+
![]()
+
{{ news.title }}
+
+
+ moveDownNews(index)">
+
+
+ removeNews(index)"
+ >
+
+
+
+
+
+
+
{{ news.title }}
+
+
![]()
+
+
+
+ moveDownNews(index)"
+ >
+
+
+ moveUpNews(index)"
+ >
+
+
+ removeNews(index)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 摘要:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/draft/components/index.ts b/src/views/mp/draft/components/index.ts
new file mode 100644
index 00000000..51e843d3
--- /dev/null
+++ b/src/views/mp/draft/components/index.ts
@@ -0,0 +1,7 @@
+import type { Article, NewsItem, NewsItemList } from './types'
+import { createEmptyNewsItem } from './types'
+import DraftTable from './DraftTable.vue'
+import NewsForm from './NewsForm.vue'
+
+export { DraftTable, NewsForm, createEmptyNewsItem }
+export type { Article, NewsItem, NewsItemList }
diff --git a/src/views/mp/draft/components/types.ts b/src/views/mp/draft/components/types.ts
new file mode 100644
index 00000000..a8cf00c3
--- /dev/null
+++ b/src/views/mp/draft/components/types.ts
@@ -0,0 +1,40 @@
+interface NewsItem {
+ title: string
+ thumbMediaId: string
+ author: string
+ digest: string
+ showCoverPic: string
+ content: string
+ contentSourceUrl: string
+ needOpenComment: string
+ onlyFansCanComment: string
+ thumbUrl: string
+}
+
+interface NewsItemList {
+ newsItem: NewsItem[]
+}
+
+interface Article {
+ mediaId: string
+ content: NewsItemList
+ updateTime: number
+}
+
+const createEmptyNewsItem = (): NewsItem => {
+ return {
+ title: '',
+ thumbMediaId: '',
+ author: '',
+ digest: '',
+ showCoverPic: '',
+ content: '',
+ contentSourceUrl: '',
+ needOpenComment: '',
+ onlyFansCanComment: '',
+ thumbUrl: ''
+ }
+}
+
+export type { Article, NewsItem, NewsItemList }
+export { createEmptyNewsItem }
diff --git a/src/views/mp/draft/index.vue b/src/views/mp/draft/index.vue
index cf0bb10d..7de992cd 100644
--- a/src/views/mp/draft/index.vue
+++ b/src/views/mp/draft/index.vue
@@ -14,7 +14,13 @@
-
+
新增
@@ -23,40 +29,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
![]()
-
{{ news.title }}
-
-
- 下移
- 删除
-
-
-
-
-
-
{{ news.title }}
-
-
![]()
-
-
-
- 下移
-
- 上移
- 删除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 封面:
-
-
-
-
-
-
- 本地上传
-
- 素材库选择
-
- 支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
-
-
-
-
-
-
-
-
-
- 摘要:
-
-
-
-
-
-
-
-
-
-
-
- 取 消
- 提 交
-
-
-
+
+
+
+
+
+ 取 消
+ 提 交
+
+
+
diff --git a/src/views/mp/hooks/useUpload.ts b/src/views/mp/hooks/useUpload.ts
new file mode 100644
index 00000000..b2d32d71
--- /dev/null
+++ b/src/views/mp/hooks/useUpload.ts
@@ -0,0 +1,50 @@
+import type { UploadRawFile } from 'element-plus'
+
+const message = useMessage() // 消息
+
+enum MaterialType {
+ Image = 'image',
+ Voice = 'voice',
+ Video = 'video'
+}
+
+const useBeforeUpload = (type: MaterialType, maxSizeMB: number) => {
+ const fn = (rawFile: UploadRawFile): boolean => {
+ let allowTypes: string[] = []
+ let name = ''
+
+ switch (type) {
+ case MaterialType.Image:
+ allowTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/jpg']
+ maxSizeMB = 2
+ name = '图片'
+ break
+ case MaterialType.Voice:
+ allowTypes = ['audio/mp3', 'audio/mpeg', 'audio/wma', 'audio/wav', 'audio/amr']
+ maxSizeMB = 2
+ name = '语音'
+ break
+ case MaterialType.Video:
+ allowTypes = ['video/mp4']
+ maxSizeMB = 10
+ name = '视频'
+ break
+ }
+ // 格式不正确
+ if (!allowTypes.includes(rawFile.type)) {
+ message.error(`上传${name}格式不对!`)
+ return false
+ }
+ // 大小不正确
+ if (rawFile.size / 1024 / 1024 > maxSizeMB) {
+ message.error(`上传${name}大小不能超过${maxSizeMB}M!`)
+ return false
+ }
+
+ return true
+ }
+
+ return fn
+}
+
+export { MaterialType, useBeforeUpload }
diff --git a/src/views/mp/material/components/UploadFile.vue b/src/views/mp/material/components/UploadFile.vue
index 3ab62224..be7e323b 100644
--- a/src/views/mp/material/components/UploadFile.vue
+++ b/src/views/mp/material/components/UploadFile.vue
@@ -6,12 +6,13 @@
:limit="1"
:file-list="fileList"
:data="uploadData"
- :on-progress="() => (uploading = true)"
- :before-upload="beforeUpload"
- :on-success="handleUploadSuccess"
+ :on-progress="(isUploading = true)"
+ :on-error="onUploadError"
+ :before-upload="onBeforeUpload"
+ :on-success="onUploadSuccess"
>
-
- {{ uploading ? '正在上传' : '点击上传' }}
+
+ {{ isUploading ? '正在上传' : '点击上传' }}
@@ -33,7 +34,7 @@ import {
const message = useMessage()
-const props = defineProps<{ type: boolean }>()
+const props = defineProps<{ type: MaterialType }>()
const fileList = ref([])
const emit = defineEmits<{
@@ -45,11 +46,13 @@ const uploadData: UploadData = reactive({
title: '',
introduction: ''
})
-const uploading = ref(false)
+const isUploading = ref(false)
-const beforeUpload = props.type == MaterialType.Image ? beforeImageUpload : beforeVoiceUpload
+/** 上传前检查 */
+const onBeforeUpload = props.type === MaterialType.Image ? beforeImageUpload : beforeVoiceUpload
-const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
+/** 上传成功处理 */
+const onUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
if (res.code !== 0) {
message.alertError('上传出错:' + res.msg)
return false
@@ -61,7 +64,16 @@ const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
uploadData.introduction = ''
message.notifySuccess('上传成功')
- uploading.value = false
+ isUploading.value = false
emit('uploaded')
}
+
+/** 上传失败处理 */
+const onUploadError = (err: Error) => message.error('上传失败: ' + err.message)
+
+
diff --git a/src/views/mp/material/components/UploadVideo.vue b/src/views/mp/material/components/UploadVideo.vue
index 816711d1..8e374767 100644
--- a/src/views/mp/material/components/UploadVideo.vue
+++ b/src/views/mp/material/components/UploadVideo.vue
@@ -8,8 +8,9 @@
:file-list="fileList"
:data="uploadData"
:before-upload="beforeVideoUpload"
- :on-progress="() => (uploading = true)"
- :on-success="handleUploadSuccess"
+ :on-progress="(isUploading = true)"
+ :on-error="onUploadError"
+ :on-success="onUploadSuccess"
ref="uploadVideoRef"
:auto-upload="false"
class="mb-5"
@@ -22,7 +23,7 @@
>
-
+
取 消
- 提 交
@@ -75,7 +76,7 @@ const emit = defineEmits<{
(e: 'uploaded', v: void)
}>()
-const showDialog = computed({
+const showDialog = computed({
get() {
return props.modelValue
},
@@ -84,7 +85,7 @@ const showDialog = computed({
}
})
-const uploading = ref(false)
+const isUploading = ref(false)
const fileList = ref([])
@@ -106,8 +107,9 @@ const submitVideo = () => {
})
}
-const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
- uploading.value = false
+/** 上传成功处理 */
+const onUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
+ isUploading.value = false
if (res.code !== 0) {
message.error('上传出错:' + res.msg)
return false
@@ -122,4 +124,7 @@ const handleUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
message.notifySuccess('上传成功')
emit('uploaded')
}
+
+/** 上传失败处理 */
+const onUploadError = (err: Error) => message.error(`上传失败: ${err.message}`)
diff --git a/src/views/mp/material/components/upload.ts b/src/views/mp/material/components/upload.ts
index 239665a2..dc52a9eb 100644
--- a/src/views/mp/material/components/upload.ts
+++ b/src/views/mp/material/components/upload.ts
@@ -1,15 +1,9 @@
import type { UploadProps, UploadRawFile } from 'element-plus'
import { getAccessToken } from '@/utils/auth'
-const message = useMessage() // 消息
-const HEADERS = { Authorization: 'Bearer ' + getAccessToken() } // 请求头
-// const UPLOAD_URL = 'http://127.0.0.1:8000/upload/' // 上传地址
-const UPLOAD_URL = import.meta.env.VITE_BASE_URL + '/admin-api/mp/material/upload-permanent' // 上传地址
+import { MaterialType, useBeforeUpload } from '@/views/mp/hooks/useUpload'
-enum MaterialType {
- Image = 'image',
- Voice = 'voice',
- Video = 'video'
-}
+const HEADERS = { Authorization: 'Bearer ' + getAccessToken() } // 请求头
+const UPLOAD_URL = import.meta.env.VITE_BASE_URL + '/admin-api/mp/material/upload-permanent' // 上传地址
interface UploadData {
type: MaterialType
@@ -17,48 +11,14 @@ interface UploadData {
introduction: string
}
-const beforeUpload = (rawFile: UploadRawFile, materialType: MaterialType): boolean => {
- let allowTypes: string[] = []
- let maxSizeMB = 0
- let name = ''
- switch (materialType) {
- case MaterialType.Image:
- allowTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/jpg']
- maxSizeMB = 2
- name = '图片'
- break
- case MaterialType.Voice:
- allowTypes = ['audio/mp3', 'audio/mpeg', 'audio/wma', 'audio/wav', 'audio/amr']
- maxSizeMB = 2
- name = '图片'
- break
- case MaterialType.Video:
- allowTypes = ['video/mp4']
- maxSizeMB = 10
- name = '视频'
- break
- }
- // 格式不正确
- if (!allowTypes.includes(rawFile.type)) {
- message.error(`上传${name}格式不对!`)
- return false
- }
- // 大小不正确
- if (rawFile.size / 1024 / 1024 > maxSizeMB) {
- message.error(`上传${name}大小不能超过${maxSizeMB}M!`)
- return false
- }
- return true
-}
-
const beforeImageUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) =>
- beforeUpload(rawFile, MaterialType.Image)
+ useBeforeUpload(MaterialType.Image, 2)(rawFile)
const beforeVoiceUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) =>
- beforeUpload(rawFile, MaterialType.Voice)
+ useBeforeUpload(MaterialType.Voice, 2)(rawFile)
const beforeVideoUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) =>
- beforeUpload(rawFile, MaterialType.Video)
+ useBeforeUpload(MaterialType.Video, 10)(rawFile)
export {
HEADERS,
diff --git a/src/views/mp/menu/components/MenuEditor.vue b/src/views/mp/menu/components/MenuEditor.vue
new file mode 100644
index 00000000..0bd27f19
--- /dev/null
+++ b/src/views/mp/menu/components/MenuEditor.vue
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+ 删除当前菜单
+
+
+
+ 菜单名称:
+
+
+
+
+
+
+ 跳转链接:
+
+
+
+
+ 小程序的 appid :
+
+
+
+ 小程序的页面路径:
+
+
+
+ 小程序的备用网页:
+
+
+
tips:需要和公众号进行关联才可以把小程序绑定带微信菜单上哟!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 素材库选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/menu/components/MenuPreviewer.vue b/src/views/mp/menu/components/MenuPreviewer.vue
new file mode 100644
index 00000000..aca1c2ae
--- /dev/null
+++ b/src/views/mp/menu/components/MenuPreviewer.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mp/menu/menuOptions.ts b/src/views/mp/menu/components/menuOptions.ts
similarity index 100%
rename from src/views/mp/menu/menuOptions.ts
rename to src/views/mp/menu/components/menuOptions.ts
diff --git a/src/views/mp/menu/components/types.ts b/src/views/mp/menu/components/types.ts
new file mode 100644
index 00000000..b9f76597
--- /dev/null
+++ b/src/views/mp/menu/components/types.ts
@@ -0,0 +1,73 @@
+export interface Replay {
+ title: string
+ description: string
+ picUrl: string
+ url: string
+}
+
+export type MenuType =
+ | ''
+ | 'click'
+ | 'view'
+ | 'scancode_waitmsg'
+ | 'scancode_push'
+ | 'pic_sysphoto'
+ | 'pic_photo_or_album'
+ | 'pic_weixin'
+ | 'location_select'
+ | 'article_view_limited'
+
+interface _RawMenu {
+ // db
+ id: number
+ parentId: number
+ accountId: number
+ appId: string
+ createTime: number
+
+ // mp-native
+ name: string
+ menuKey: string
+ type: MenuType
+ url: string
+ miniProgramAppId: string
+ miniProgramPagePath: string
+ articleId: string
+ replyMessageType: string
+ replyContent: string
+ replyMediaId: string
+ replyMediaUrl: string
+ replyThumbMediaId: string
+ replyThumbMediaUrl: string
+ replyTitle: string
+ replyDescription: string
+ replyArticles: Replay
+ replyMusicUrl: string
+ replyHqMusicUrl: string
+}
+
+export type RawMenu = Partial<_RawMenu>
+
+interface _Reply {
+ type: string
+ accountId: number
+ content: string
+ mediaId: string
+ url: string
+ thumbMediaId: string
+ thumbMediaUrl: string
+ title: string
+ description: string
+ articles: null | Replay[]
+ musicUrl: string
+ hqMusicUrl: string
+}
+
+export type Reply = Partial<_Reply>
+
+interface _Menu extends RawMenu {
+ children: _Menu[]
+ reply: Reply
+}
+
+export type Menu = Partial<_Menu>
diff --git a/src/views/mp/menu/index.vue b/src/views/mp/menu/index.vue
index 3d428f06..c053a47c 100644
--- a/src/views/mp/menu/index.vue
+++ b/src/views/mp/menu/index.vue
@@ -9,7 +9,6 @@
-
@@ -17,169 +16,33 @@
-
-
-
-
-
- 删除当前菜单
-
-
-
- 菜单名称:
-
-
-
-
-
-
- 跳转链接:
-
-
-
-
- 小程序的 appid :
-
-
-
- 小程序的页面路径:
-
-
-
- 小程序的备用网页:
-
-
-
tips:需要和公众号进行关联才可以把小程序绑定带微信菜单上哟!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 素材库选择
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -188,37 +51,55 @@
+
@@ -513,9 +294,9 @@ const deleteMaterial = () => {
}
.clearfix::after {
- content: '';
display: table;
clear: both;
+ content: '';
}
div {
@@ -523,116 +304,50 @@ div {
}
.weixin-hd {
- color: #fff;
- text-align: center;
position: relative;
bottom: 426px;
- left: 0px;
+ left: 0;
width: 300px;
height: 64px;
+ color: #fff;
+ text-align: center;
background: transparent url('./assets/menu_head.png') no-repeat 0 0;
background-position: 0 0;
background-size: 100%;
}
.weixin-title {
- color: #fff;
- font-size: 14px;
- width: 100%;
- text-align: center;
position: absolute;
top: 33px;
- left: 0px;
+ left: 0;
+ width: 100%;
+ font-size: 14px;
+ color: #fff;
+ text-align: center;
}
.weixin-menu {
- background: transparent url('./assets/menu_foot.png') no-repeat 0 0;
padding-left: 43px;
font-size: 12px;
-}
-
-.menu_option {
- width: 40% !important;
+ background: transparent url('./assets/menu_foot.png') no-repeat 0 0;
}
.public-account-management {
- min-width: 1200px;
width: 1200px;
+ // min-width: 1200px;
margin: 0 auto;
.left {
- float: left;
+ position: relative;
display: inline-block;
+ float: left;
width: 350px;
height: 715px;
+ padding: 518px 25px 88px;
background: url('./assets/iphone_backImg.png') no-repeat;
background-size: 100% auto;
- padding: 518px 25px 88px;
- position: relative;
box-sizing: border-box;
- /*第一级菜单*/
- .menu_main {
- .menu_bottom {
- position: relative;
- float: left;
- display: inline-block;
- box-sizing: border-box;
- width: 85.5px;
- text-align: center;
- border: 1px solid #ebedee;
- background-color: #fff;
- cursor: pointer;
-
- &.menu_addicon {
- height: 46px;
- line-height: 46px;
- }
-
- .menu_item {
- height: 44px;
- line-height: 44px;
- // text-align: center;
- box-sizing: border-box;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
-
- &.active {
- border: 1px solid #2bb673;
- }
- }
-
- .menu_subItem {
- height: 44px;
- line-height: 44px;
- text-align: center;
- box-sizing: border-box;
-
- &.active {
- border: 1px solid #2bb673;
- }
- }
- }
-
- i {
- color: #2bb673;
- }
-
- /*第二级菜单*/
- .submenu {
- position: absolute;
- width: 85.5px;
- bottom: 45px;
-
- .subtitle {
- background-color: #fff;
- box-sizing: border-box;
- }
- }
- }
-
.save_div {
margin-top: 15px;
text-align: center;
@@ -644,85 +359,29 @@ div {
}
}
- /*右边菜单内容*/
+ /* 右边菜单内容 */
.right {
float: left;
width: 63%;
- background-color: #e8e7e7;
padding: 20px;
margin-left: 20px;
- -webkit-box-sizing: border-box;
+ background-color: #e8e7e7;
+ box-sizing: border-box;
box-sizing: border-box;
-
- .configure_page {
- .delete_btn {
- text-align: right;
- margin-bottom: 15px;
- }
-
- .menu_content {
- margin-top: 20px;
- }
-
- .configur_content {
- margin-top: 20px;
- background-color: #fff;
- padding: 20px 10px;
- border-radius: 5px;
- }
-
- .blue {
- color: #29b6f6;
- margin-top: 10px;
- }
-
- .applet {
- margin-bottom: 20px;
-
- span {
- width: 20%;
- }
- }
-
- .input_width {
- width: 40%;
- }
-
- .material {
- .input_width {
- width: 30%;
- }
-
- .el-textarea {
- width: 80%;
- }
- }
- }
- }
-
- .el-input {
- width: 70%;
- margin-right: 2%;
}
}
diff --git a/src/views/system/notify/template/index.vue b/src/views/system/notify/template/index.vue
index 6d1938ad..12392b8a 100644
--- a/src/views/system/notify/template/index.vue
+++ b/src/views/system/notify/template/index.vue
@@ -212,7 +212,7 @@ const handleDelete = async (id: number) => {
// 删除的二次确认
await message.delConfirm()
// 发起删除
- await NotifyTemplateApi.deleteNotifyTemplateApi(id)
+ await NotifyTemplateApi.deleteNotifyTemplate(id)
message.success('删除成功')
// 刷新列表
await getList()
diff --git a/src/views/system/role/RoleAssignMenuForm.vue b/src/views/system/role/RoleAssignMenuForm.vue
index 9b7d5a15..cfd30842 100644
--- a/src/views/system/role/RoleAssignMenuForm.vue
+++ b/src/views/system/role/RoleAssignMenuForm.vue
@@ -91,6 +91,7 @@ const open = async (row: RoleApi.RoleVO) => {
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
if (!formRef) return
@@ -109,6 +110,8 @@ const submitForm = async () => {
await PermissionApi.assignRoleMenu(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
+ // 发送操作成功的事件
+ emit('success')
} finally {
formLoading.value = false
}
diff --git a/src/views/system/role/RoleDataPermissionForm.vue b/src/views/system/role/RoleDataPermissionForm.vue
index 87a33e6c..279ba973 100644
--- a/src/views/system/role/RoleDataPermissionForm.vue
+++ b/src/views/system/role/RoleDataPermissionForm.vue
@@ -107,6 +107,7 @@ const open = async (row: RoleApi.RoleVO) => {
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
formLoading.value = true
try {
@@ -121,6 +122,8 @@ const submitForm = async () => {
await PermissionApi.assignRoleDataScope(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
+ // 发送操作成功的事件
+ emit('success')
} finally {
formLoading.value = false
}
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index 4df19ef8..e7b8158b 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -156,9 +156,9 @@
-
+
-
+