20 Commits
dev ... master

Author SHA1 Message Date
ad433c4093 Merge remote-tracking branch 'origin/master' 2025-10-26 16:07:24 +08:00
da0f6bd183 feat & bugfix:优化部门模块的代码、提示等 2025-10-26 16:07:18 +08:00
b35276bdb3 fix: mp lint 2025-10-23 09:40:02 +08:00
9e75e98a3f fix: wangEditor 2025-10-15 11:30:40 +08:00
4e870d6980 chore: 使用wangeditor-next 替换wangeditor 2025-10-15 11:29:20 +08:00
d4c8ddbd85 fix:【mall 商城】自提订单的 pickUpStoreId 参数不正确 2025-10-13 20:52:58 +08:00
6b28dba11b (〃'▽'〃) v2025.10 发布:新增工作流的工单打印、优化物联网的场景联动、完善 vben5 的 antd、vben 版本的功能 2025-10-12 15:29:18 +08:00
6caed15c1a !827 fix: 修复 Editor 切换 readonly 时只读状态无效的 bug
Merge pull request !827 from 局外人/fix/editor
2025-10-12 06:57:52 +00:00
5bc3c9090b fix: 修复 Editor 切换 readonly 时只读状态无效的 bug 2025-10-10 18:20:50 +08:00
2e1ef8aee4 fix:修复引入plugin-mention插件后Editor组件报错 2025-10-10 17:00:55 +08:00
9bc289cb2a fix:更新按钮文本为“添加销售产品”并修复支付信息展示逻辑 2025-10-06 20:45:35 +08:00
bdb42bb927 fix:【修复】产品跳转到设备列表时,productId 未传递的问题,对应 https://t.zsxq.com/jvXyq 2025-10-02 11:25:34 +08:00
62a9a99146 fix:【pay 支付】微信支付 publicKeyContent 调整为非必填,兼容 https://t.zsxq.com/ODR5V、https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/ICUE53 2025-10-02 10:24:22 +08:00
13386def62 fix:前端的密码长度限制统一,https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/ICVDAT 2025-10-02 09:41:54 +08:00
a126f42c35 fix:【bpm 工作流】已办任务的审批状态过滤不正确 2025-10-02 09:36:06 +08:00
eda7d63e4f Merge branch 'dev' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 2025-10-01 15:56:31 +08:00
d076d75c38 !813 update src/store/modules/tagsView.ts.
Merge pull request !813 from 口口口/N/A
2025-09-21 02:48:31 +00:00
3137c6cee4 !818 雪花 ID 溢出问题 update src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue.
Merge pull request !818 from 山野羡民/N/A
2025-09-21 02:47:33 +00:00
722d6405a1 雪花 ID 溢出问题 update src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue.
Signed-off-by: 山野羡民 <liyujiang_tk@yeah.net>
2025-09-05 03:58:12 +00:00
bd506fab0d update src/store/modules/tagsView.ts.
当存在多个相同名称的标签时,删除缓存应该排除是否存在相同的名称。

Signed-off-by: 口口口 <17975121@qq.com>
2025-08-20 03:32:41 +00:00
46 changed files with 1442 additions and 1374 deletions

View File

@ -25,8 +25,8 @@ const include = [
'echarts/components',
'echarts/renderers',
'echarts-wordcloud',
'@wangeditor/editor',
'@wangeditor/editor-for-vue',
'@wangeditor-next/editor',
'@wangeditor-next/editor-for-vue',
'@microsoft/fetch-event-source',
'markdown-it',
'markmap-view',

View File

@ -1,6 +1,6 @@
{
"name": "yudao-ui-admin-vue3",
"version": "2025.09-snapshot",
"version": "2025.10-snapshot",
"description": "基于vue3、vite4、element-plus、typesScript",
"author": "xingyu",
"private": false,
@ -32,9 +32,9 @@
"@microsoft/fetch-event-source": "^2.0.1",
"@videojs-player/vue": "^1.0.0",
"@vueuse/core": "^10.9.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.10",
"@wangeditor/plugin-mention": "^1.0.0",
"@wangeditor-next/editor": "^5.6.46",
"@wangeditor-next/editor-for-vue": "^5.1.14",
"@wangeditor-next/plugin-mention": "^1.0.16",
"@zxcvbn-ts/core": "^3.0.4",
"animate.css": "^4.1.1",
"axios": "1.9.0",

2534
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import Editor from './src/Editor.vue'
import { IDomEditor } from '@wangeditor/editor'
import { IDomEditor } from '@wangeditor-next/editor'
export interface EditorExpose {
getEditorRef: () => Promise<IDomEditor>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { PropType } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor/editor'
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue'
import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor-next/editor'
import { propTypes } from '@/utils/propTypes'
import { isNumber } from '@/utils/is'
import { ElMessage } from 'element-plus'
@ -20,7 +20,7 @@ const currentLocale = computed(() => localeStore.getCurrentLocale)
i18nChangeLanguage(unref(currentLocale).lang)
const props = defineProps({
editorId: propTypes.string.def('wangeEditor-1'),
editorId: propTypes.string.def('wangEditor-1'),
height: propTypes.oneOfType([Number, String]).def('500px'),
editorConfig: {
type: Object as PropType<Partial<IEditorConfig>>,
@ -58,6 +58,16 @@ watch(
emit('update:modelValue', val)
}
)
watch(
() => props.readonly,
(val) => {
if (val) {
editorRef.value?.disable()
} else {
editorRef.value?.enable()
}
}
)
const handleCreated = (editor: IDomEditor) => {
editorRef.value = editor
@ -90,6 +100,12 @@ const editorConfig = computed((): IEditorConfig => {
},
autoFocus: false,
scroll: true,
EXTEND_CONF: {
mentionConfig: {
showModal: () => {},
hideModal: () => {}
}
},
MENU_CONF: {
['uploadImage']: {
server: getUploadUrl(),
@ -243,4 +259,4 @@ defineExpose({
</div>
</template>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style src="@wangeditor-next/editor/dist/css/style.css"></style>

View File

@ -1,5 +1,3 @@
import { Rule } from '@form-create/element-ui' //左侧拖拽按钮
// 左侧拖拽按钮
export interface MenuItem {
label: string
@ -14,24 +12,6 @@ export interface Menu {
list: MenuItem[]
}
export interface MenuList extends Array<Menu> {}
// 拖拽组件的规则
export interface DragRule {
icon: string
name: string
label: string
children?: string
inside?: true
drag?: true | String
dragBtn?: false
mask?: false
rule(): Rule
props(v: any, v1: any): Rule[]
}
// 通用下拉组件 Props 类型
export interface ApiSelectProps {
name: string // 组件名称
@ -46,6 +26,6 @@ export interface SelectRuleOption {
label: string // label 名称
name: string // 组件名称
icon: string // 组件图标
props?: any[], // 组件规则
props?: any[] // 组件规则
event?: any[] // 事件配置
}

View File

@ -93,6 +93,11 @@ export const useTagsViewStore = defineStore('tagsView', {
delCachedView() {
const route = router.currentRoute.value
const index = findIndex<string>(this.getCachedViews, (v) => v === route.name)
for (const v of this.visitedViews) {
if (v.name === route.name) {
return
}
}
if (index > -1) {
this.cachedViews.delete(this.getCachedViews[index])
}

View File

@ -44,11 +44,11 @@ const equalToPassword = (_rule, value, callback) => {
const rules = reactive<FormRules>({
oldPassword: [
{ required: true, message: t('profile.password.oldPwdMsg'), trigger: 'blur' },
{ min: 6, max: 20, message: t('profile.password.pwdRules'), trigger: 'blur' }
{ min: 4, max: 16, message: t('profile.password.pwdRules'), trigger: 'blur' }
],
newPassword: [
{ required: true, message: t('profile.password.newPwdMsg'), trigger: 'blur' },
{ min: 6, max: 20, message: t('profile.password.pwdRules'), trigger: 'blur' }
{ min: 4, max: 16, message: t('profile.password.pwdRules'), trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: t('profile.password.cfPwdMsg'), trigger: 'blur' },

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IDomEditor } from '@wangeditor/editor'
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue'
import { IDomEditor } from '@wangeditor-next/editor'
import MentionModal from './MentionModal.vue'
const emit = defineEmits(['confirm'])
@ -43,7 +43,7 @@ const handleConfirm = () => {
// Editor 相关
const editorRef = shallowRef<IDomEditor>()
const editorId = ref('wangeEditor-1')
const editorId = ref('wangEditor-1')
const toolbarConfig = {
excludeKeys: ['group-video'],
insertKeys: {
@ -86,7 +86,7 @@ onBeforeUnmount(() => {
/>
</div>
<!-- TODO @unocss 简化 style -->
<div style="border: 1px solid #ccc; margin: 10px">
<div style=" margin: 10px;border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
@ -106,11 +106,11 @@ onBeforeUnmount(() => {
@insert-mention="insertMention"
/>
</div>
<div style="margin-right: 10px; float: right">
<div style=" float: right;margin-right: 10px">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</div>
</el-dialog>
</template>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style src="@wangeditor-next/editor/dist/css/style.css"></style>

View File

@ -1,6 +1,6 @@
import { Boot } from '@wangeditor/editor'
import { Boot } from '@wangeditor-next/editor'
import processRecordModule from './module'
import mentionModule from '@wangeditor/plugin-mention'
import mentionModule from '@wangeditor-next/plugin-mention'
// 注册:要在创建编辑器之前注册,且只能注册一次,不可重复注册
export const setupWangEditorPlugin = () => {

View File

@ -1,4 +1,4 @@
import { SlateElement } from '@wangeditor/editor'
import { SlateElement } from '@wangeditor-next/editor'
function processRecordToHtml(_elem: SlateElement, _childrenHtml: string): string {
return `<span data-w-e-type="process-record" data-w-e-is-void data-w-e-is-inline>流程记录</span>`

View File

@ -1,4 +1,4 @@
import { IModuleConf } from '@wangeditor/editor'
import { IModuleConf } from '@wangeditor-next/editor'
import withProcessRecord from './plugin'
import renderElemConf from './render-elem'
import elemToHtmlConf from './elem-to-html'

View File

@ -1,4 +1,4 @@
import { IButtonMenu, IDomEditor } from '@wangeditor/editor'
import { IButtonMenu, IDomEditor } from '@wangeditor-next/editor'
class ProcessRecordMenu implements IButtonMenu {
readonly tag: string

View File

@ -1,16 +1,28 @@
import { DOMElement } from './utils/dom'
import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor/editor'
import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor-next/editor'
/**
* 解析 HTML 字符串,生成“附件”元素
* @param domElem HTML 对应的 DOM Element
* @param children 子节点
* @param editor editor 实例
* @returns “附件”元素,如上文的 myResume
*/
function parseHtml(
_elem: DOMElement,
_domElem: DOMElement,
_children: SlateDescendant[],
_editor: IDomEditor
): SlateElement {
return {
// TODO @lesan这里有个红色告警可以去掉哇
// TS 语法
// 生成“流程记录”元素(按照此前约定的数据结构)
const processRecord = {
type: 'process-record',
children: [{ text: '' }]
children: [{ text: '' }], // void node 必须有 children ,其中有一个空字符串,重要!!!
}
return processRecord
}
const parseHtmlConf = {

View File

@ -1,4 +1,4 @@
import { DomEditor, IDomEditor } from '@wangeditor/editor'
import { DomEditor, IDomEditor } from '@wangeditor-next/editor'
function withProcessRecord<T extends IDomEditor>(editor: T) {
const { isInline, isVoid } = editor

View File

@ -1,5 +1,5 @@
import { h, VNode } from 'snabbdom'
import { DomEditor, IDomEditor, SlateElement } from '@wangeditor/editor'
import { DomEditor, IDomEditor, SlateElement } from '@wangeditor-next/editor'
function renderProcessRecord(
elem: SlateElement,

View File

@ -242,7 +242,6 @@ const handleProcessDetail = (row) => {
})
}
// fix: 列表不刷新的问题。
watch(
() => router.currentRoute.value,
() => {

View File

@ -52,13 +52,13 @@
<el-form-item label="" prop="status" :style="{ position: 'absolute', right: '130px' }">
<el-select
v-model="queryParams.status"
placeholder="请选择流程状态"
placeholder="请选择审批状态"
clearable
class="!w-155px"
@change="handleQuery"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS)"
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"

View File

@ -132,7 +132,7 @@
</el-table>
</el-form>
<el-row justify="center" class="mt-3" v-if="!disabled">
<el-button @click="handleAdd" round>+ 添加采购产品</el-button>
<el-button @click="handleAdd" round>+ 添加销售产品</el-button>
</el-row>
</template>
<script setup lang="ts">

View File

@ -384,6 +384,7 @@ defineOptions({ name: 'IoTDevice' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const route = useRoute()
const loading = ref(true) // 列表加载中
const list = ref<DeviceVO[]>([]) // 列表的数据
@ -392,7 +393,7 @@ const queryParams = reactive({
pageNo: 1,
pageSize: 10,
deviceName: undefined,
productId: undefined,
productId: undefined as number | undefined,
deviceType: undefined,
nickname: undefined,
status: undefined,
@ -513,7 +514,12 @@ const handleImport = () => {
/** 初始化 **/
onMounted(async () => {
getList()
// 处理 productId 参数
const { productId } = route.query
if (productId) {
queryParams.productId = Number(productId)
}
await getList()
// 获取产品列表
products.value = await ProductApi.getSimpleProductList()

View File

@ -72,7 +72,7 @@ const copyToClipboard = async (text: string) => {
/** 路由跳转到设备管理 */
const { push } = useRouter()
const goToDeviceList = (productId: number) => {
push({ name: 'IoTDevice', params: { productId } })
push({ name: 'IoTDevice', query: { productId } })
}
/** 修改操作 */

View File

@ -69,7 +69,6 @@ const getOrderData = async () => {
/** 查询商品数据 */
const getProductData = async () => {
// TODO: @芋艿:这个接口的返回值,是不是用命名字段更好些?
const productCount = await ProductSpuApi.getTabsCount()
data.productForSale.value = productCount['0']
data.productInWarehouse.value = productCount['1']

View File

@ -196,7 +196,7 @@ const getOrderCountTrendComparison = async (
}
eChartOptions.xAxis!['data'] = dates
eChartOptions.series = series
// legend在4个切换到2个的时候,还是显示成4个,需要手动配置一下
// legend 在 4 个切换到 2 个的时候,还是显示成 4 个,需要手动配置一下
eChartOptions.legend['data'] = series.map((item) => item.name)
loading.value = false
}

View File

@ -166,11 +166,15 @@ const handleEditorReset = () => storePageIndex()
//#region 无感刷新
// 记录标识
const DIY_PAGE_INDEX_KEY = 'diy_page_index'
// 1. 记录
const storePageIndex = () =>
sessionStorage.setItem(DIY_PAGE_INDEX_KEY, `${selectedTemplateItem.value}`)
function storePageIndex() {
debugger
return sessionStorage.setItem(DIY_PAGE_INDEX_KEY, `${selectedTemplateItem.value}`)
}
// 2. 恢复
const recoverPageIndex = () => {
debugger
// 恢复重置前的页面,默认是第一个页面
const pageIndex = toNumber(sessionStorage.getItem(DIY_PAGE_INDEX_KEY)) || 0
// 移除标记

View File

@ -68,7 +68,6 @@
min-width="100"
prop="marketPrice"
/>
<el-table-column label="原价" min-width="100" prop="marketPrice" />
<el-table-column align="center" label="活动状态" min-width="100" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />

View File

@ -20,7 +20,7 @@ const crudSchemas = reactive<CrudSchema[]>([
}
},
{
label: '积分商城活动商品',
label: '活动商品',
field: 'spuId',
isTable: true,
isSearch: false,

View File

@ -89,9 +89,7 @@ const initGiveCouponList = async () => {
if (isEmpty(rewardRule.value) || isEmpty(rewardRule.value.giveCouponTemplateCounts)) {
return
}
const tempLateIds = Object.keys(rewardRule.value.giveCouponTemplateCounts!).map((item) =>
parseInt(item)
)
const tempLateIds = Object.keys(rewardRule.value.giveCouponTemplateCounts!)
const data = await CouponTemplateApi.getCouponTemplateList(tempLateIds)
if (!data) {
return

View File

@ -29,7 +29,6 @@ const terminalChartOptions = reactive<EChartsOption>({
orient: 'vertical',
left: 'right'
},
roseType: 'area',
series: [
{
name: '会员终端',

View File

@ -22,9 +22,9 @@
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item label="自提门店" prop="pickUpStoreId">
<el-form-item label="自提门店" prop="pickUpStoreIds">
<el-select
v-model="queryParams.pickUpStoreId"
v-model="queryParams.pickUpStoreIds"
class="!w-280px"
placeholder="全部"
@change="handleQuery"
@ -251,7 +251,7 @@ const INIT_QUERY_PARAMS = {
// 配送方式
deliveryType: DeliveryTypeEnum.PICK_UP.type,
// 自提门店
pickUpStoreId: -1
pickUpStoreIds: -1
} // 初始表单参数
const queryParams = ref({ ...INIT_QUERY_PARAMS }) // 表单搜索
@ -264,7 +264,7 @@ const isUse = ref(true) // 是否可核销
// 订单聚合搜索 select 类型配置(动态搜索)
const dynamicSearchList = ref([
{ value: 'no', label: '订单号' },
{ value: 'userId', label: '用户UID' },
{ value: 'userId', label: '用户 UID' },
{ value: 'userNickname', label: '用户昵称' },
{ value: 'userMobile', label: '用户电话' }
])
@ -309,7 +309,7 @@ const resetQuery = () => {
queryFormRef.value?.resetFields()
queryParams.value = { ...INIT_QUERY_PARAMS }
if (pickUpStoreList.value.length > 0) {
queryParams.value.pickUpStoreId = pickUpStoreList.value[0].id
queryParams.value.pickUpStoreIds = pickUpStoreList.value[0].id
}
handleQuery()
}
@ -418,7 +418,7 @@ onMounted(async () => {
}
// 查询
queryParams.value.pickUpStoreId = pickUpStoreList.value[0].id
queryParams.value.pickUpStoreIds = pickUpStoreList.value[0].id
isUse.value = false
await getList()
})

View File

@ -121,7 +121,7 @@ const loadMore = () => {
const getPage = async (page: any, params: any = null) => {
loading.value = true
let dataTemp = await getMessagePage(
const dataTemp = await getMessagePage(
Object.assign(
{
pageNo: page.pageNo,

View File

@ -13,7 +13,7 @@
<div class="news-main">
<div class="news-content">
<el-image
:src="article.picUrl||article.thumbUrl"
:src="article.picUrl || article.thumbUrl"
class="material-img"
style="width: 100%; height: 120px"
/>
@ -29,7 +29,7 @@
<div class="news-content-item">
<div class="news-content-item-title">{{ article.title }}</div>
<div class="news-content-item-img">
<img :src="article.picUrl||article.thumbUrl" class="material-img" height="100%"/>
<img :src="article.picUrl || article.thumbUrl" class="material-img" height="100%" />
</div>
</div>
</div>

View File

@ -106,7 +106,7 @@ watch(
if (temp) {
reply.value = temp
} else {
let newData = createEmptyReply(reply)
const newData = createEmptyReply(reply)
newData.type = newTab
reply.value = newData
}

View File

@ -1,6 +1,6 @@
<template>
<div class="waterfall" v-loading="props.loading">
<template v-for="item in props.list" :key="item.articleId">
<template v-for="(item, index) in props.list" :key="index">
<div class="waterfall-item" v-if="item.content && item.content.newsItem">
<WxNews :articles="item.content.newsItem" />
<!-- 操作按钮 -->

View File

@ -186,7 +186,9 @@ const removeNews = async (index: number) => {
if (activeNewsIndex.value === index) {
activeNewsIndex.value = 0
}
} catch {}
} catch {
// empty
}
}
// 添加一个图文

View File

@ -1,4 +1,4 @@
import { IEditorConfig } from '@wangeditor/editor'
import { IEditorConfig } from '@wangeditor-next/editor'
import { getAccessToken, getTenantId } from '@/utils/auth'
const message = useMessage()

View File

@ -110,7 +110,9 @@ const onBeforeDialogClose = async (onDone: () => {}) => {
try {
await message.confirm('修改内容可能还未保存,确定关闭吗?')
onDone()
} catch {}
} catch {
//
}
}
// ======================== 列表查询 ========================
@ -179,7 +181,9 @@ const onPublish = async (item: Article) => {
await MpFreePublishApi.submitFreePublish(accountId.value, mediaId)
message.notifySuccess('发布成功')
await getList()
} catch {}
} catch {
//
}
}
/** 删除按钮操作 */
@ -190,7 +194,9 @@ const onDelete = async (item: Article) => {
await MpDraftApi.deleteDraft(accountId.value, mediaId)
message.notifySuccess('删除成功')
await getList()
} catch {}
} catch {
//
}
}
</script>

View File

@ -97,7 +97,9 @@ const handleDelete = async (item: any) => {
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
} catch {
//
}
}
</script>
<style lang="scss" scoped>

View File

@ -101,7 +101,7 @@ const uploadVideoRef = ref<UploadInstance | null>(null)
const submitVideo = () => {
uploadFormRef.value?.validate((valid) => {
if (!valid) {
return false
return
}
uploadVideoRef.value?.submit()
})

View File

@ -131,7 +131,7 @@ const onParentDragEnd = ({ oldIndex, newIndex }) => {
}
// 使用一个辅助数组来模拟菜单移动,然后找到展开的二级菜单的新下标`newParent`
let positions = new Array<boolean>(menuList.value.length).fill(false)
const positions = new Array<boolean>(menuList.value.length).fill(false)
positions[props.parentIndex] = true
const [out] = positions.splice(oldIndex, 1) // 移出菜单保存到变量out
positions.splice(newIndex, 0, out) // 把out变量插入被移出的菜单

View File

@ -217,7 +217,9 @@ const onDeleteMenu = async () => {
activeMenu.value = {}
showRightPanel.value = false
activeIndex.value = MENU_NOT_SELECTED
} catch {}
} catch {
//
}
}
// ======================== 菜单编辑 ========================
@ -267,7 +269,7 @@ const menuListToBackend = () => {
// 将前端的 menu转换成后端接收的 menu
// TODO: @芋艿需要根据后台API删除不需要的字段
const menuToBackend = (menu: any) => {
let result = {
const result = {
...menu,
children: undefined, // 不处理子节点
reply: undefined // 稍后复制

View File

@ -99,7 +99,7 @@ const userSummaryOption = reactive({
series: [
{
name: '新增用户',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -108,7 +108,7 @@ const userSummaryOption = reactive({
},
{
name: '取消关注的用户',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -122,7 +122,7 @@ const userCumulateOption = reactive({
data: ['累计用户量']
},
xAxis: {
type: 'category',
type: 'category' as const,
data: [] as any[]
},
yAxis: {
@ -132,7 +132,7 @@ const userCumulateOption = reactive({
{
name: '累计用户量',
data: [] as any[], // 累计用户量的数据
type: 'line',
type: 'line' as const,
smooth: true,
label: {
show: true
@ -156,7 +156,7 @@ const upstreamMessageOption = reactive({
series: [
{
name: '用户发送人数',
type: 'line',
type: 'line' as const,
smooth: true,
label: {
show: true
@ -165,7 +165,7 @@ const upstreamMessageOption = reactive({
},
{
name: '用户发送条数',
type: 'line',
type: 'line' as const,
smooth: true,
label: {
show: true
@ -188,7 +188,7 @@ const interfaceSummaryOption = reactive({
series: [
{
name: '被动回复用户消息的次数',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -197,7 +197,7 @@ const interfaceSummaryOption = reactive({
},
{
name: '失败次数',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -205,7 +205,7 @@ const interfaceSummaryOption = reactive({
},
{
name: '最大耗时',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -213,7 +213,7 @@ const interfaceSummaryOption = reactive({
},
{
name: '总耗时',
type: 'bar',
type: 'bar' as const,
label: {
show: true
},
@ -282,7 +282,9 @@ const initUserSummaryChart = async () => {
userSummaryOption.series[1].data[index] = item.cancelUser
})
})
} catch {}
} catch {
//
}
}
/** 累计用户数据 */
@ -300,7 +302,9 @@ const initUserCumulateChart = async () => {
data.forEach((item, index) => {
userCumulateOption.series[0].data[index] = item.cumulateUser
})
} catch {}
} catch {
//
}
}
/** 消息概况数据 */
@ -320,7 +324,9 @@ const initUpstreamMessageChart = async () => {
upstreamMessageOption.series[0].data[index] = item.messageUser
upstreamMessageOption.series[1].data[index] = item.messageCount
})
} catch {}
} catch {
//
}
}
/** 接口分析数据 */
@ -344,6 +350,8 @@ const interfaceSummaryChart = async () => {
interfaceSummaryOption.series[2].data[index] = item.maxTimeCost
interfaceSummaryOption.series[3].data[index] = item.totalTimeCost
})
} catch {}
} catch {
//
}
}
</script>

View File

@ -139,7 +139,9 @@ const handleDelete = async (id: number) => {
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
} catch {
//
}
}
/** 同步操作 */
@ -149,6 +151,8 @@ const handleSync = async () => {
await MpTagApi.syncTag(queryParams.accountId as number)
message.success('同步标签成功')
await getList()
} catch {}
} catch {
//
}
}
</script>

View File

@ -54,7 +54,7 @@
<el-table-column label="用户标识" align="center" prop="openid" width="260" />
<el-table-column label="用户头像" min-width="80px" prop="headImageUrl">
<template #default="scope">
<el-avatar :src="scope.row.headImageUrl"/>
<el-avatar :src="scope.row.headImageUrl" />
</template>
</el-table-column>
<el-table-column label="昵称" align="center" prop="nickname" />
@ -176,7 +176,9 @@ const handleSync = async () => {
await MpUserApi.syncUser(queryParams.accountId)
message.success('开始从微信公众号同步粉丝信息,同步需要一段时间,建议稍后再查询')
await getList()
} catch {}
} catch {
//
}
}
/** 初始化 */

View File

@ -147,7 +147,11 @@
前往微信商户平台查看证书序列号
</a>
</el-form-item>
<el-form-item label="public_key.pem 证书" label-width="180px" prop="config.publicKeyContent">
<el-form-item
label="public_key.pem 证书"
label-width="180px"
prop="config.publicKeyContent"
>
<el-input
v-model="formData.config.publicKeyContent"
:autosize="{ minRows: 2, maxRows: 4 }"
@ -174,17 +178,10 @@
</el-upload>
</el-form-item>
<el-form-item label="公钥 ID" label-width="180px" prop="config.publicKeyId">
<el-input
v-model="formData.config.publicKeyId"
clearable
placeholder="请输入公钥 ID"
/>
<el-input v-model="formData.config.publicKeyId" clearable placeholder="请输入公钥 ID" />
</el-form-item>
<el-form-item label-width="180px">
<a
href="https://pay.weixin.qq.com/doc/v3/merchant/4012153196"
target="_blank"
>
<a href="https://pay.weixin.qq.com/doc/v3/merchant/4012153196" target="_blank">
微信支付公钥产品简介及使用说明
</a>
</el-form-item>
@ -246,7 +243,6 @@ const formRules = {
{ required: true, message: '请上传 apiclient_key.pem 证书', trigger: 'blur' }
],
'config.certSerialNo': [{ required: true, message: '请输入证书序列号', trigger: 'blur' }],
'config.publicKeyContent': [{ required: true, message: '请上传 public_key.pem 证书', trigger: 'blur' }],
'config.publicKeyId': [{ required: true, message: '请输入公钥 ID', trigger: 'blur' }],
'config.apiV3Key': [{ required: true, message: '请上传 api V3 密钥值', trigger: 'blur' }]
}

View File

@ -238,7 +238,6 @@ const getDetail = async () => {
return
}
const data = await PayOrderApi.getOrder(id.value, true)
payOrder.value = data
// 1.2 无法查询到支付信息
if (!data) {
message.error('支付订单不存在,请检查!')
@ -255,6 +254,8 @@ const getDetail = async () => {
goReturnUrl('close')
return
}
// 2. 正常展示支付信息
payOrder.value = data
}
/** 提交支付 */

View File

@ -1,4 +1,4 @@
import { SlateDescendant } from '@wangeditor/editor'
import { SlateDescendant } from '@wangeditor-next/editor'
declare module 'slate' {
interface CustomTypes {