Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ad433c4093 | |||
| da0f6bd183 | |||
| b35276bdb3 | |||
| 9e75e98a3f | |||
| 4e870d6980 | |||
| d4c8ddbd85 | |||
| 6b28dba11b | |||
| 6caed15c1a | |||
| 5bc3c9090b | |||
| 2e1ef8aee4 | |||
| 9bc289cb2a | |||
| bdb42bb927 | |||
| 62a9a99146 | |||
| 13386def62 | |||
| a126f42c35 | |||
| eda7d63e4f | |||
| d076d75c38 | |||
| 3137c6cee4 | |||
| 722d6405a1 | |||
| bd506fab0d |
@ -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',
|
||||
|
||||
@ -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
2534
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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[] // 事件配置
|
||||
}
|
||||
|
||||
@ -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])
|
||||
}
|
||||
|
||||
@ -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' },
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 = () => {
|
||||
|
||||
@ -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>`
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IButtonMenu, IDomEditor } from '@wangeditor/editor'
|
||||
import { IButtonMenu, IDomEditor } from '@wangeditor-next/editor'
|
||||
|
||||
class ProcessRecordMenu implements IButtonMenu {
|
||||
readonly tag: string
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -242,7 +242,6 @@ const handleProcessDetail = (row) => {
|
||||
})
|
||||
}
|
||||
|
||||
// fix: 列表不刷新的问题。
|
||||
watch(
|
||||
() => router.currentRoute.value,
|
||||
() => {
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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 } })
|
||||
}
|
||||
|
||||
/** 修改操作 */
|
||||
|
||||
@ -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']
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
// 移除标记
|
||||
|
||||
@ -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" />
|
||||
|
||||
@ -20,7 +20,7 @@ const crudSchemas = reactive<CrudSchema[]>([
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '积分商城活动商品',
|
||||
label: '活动商品',
|
||||
field: 'spuId',
|
||||
isTable: true,
|
||||
isSearch: false,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -29,7 +29,6 @@ const terminalChartOptions = reactive<EChartsOption>({
|
||||
orient: 'vertical',
|
||||
left: 'right'
|
||||
},
|
||||
roseType: 'area',
|
||||
series: [
|
||||
{
|
||||
name: '会员终端',
|
||||
|
||||
@ -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()
|
||||
})
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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" />
|
||||
<!-- 操作按钮 -->
|
||||
|
||||
@ -186,7 +186,9 @@ const removeNews = async (index: number) => {
|
||||
if (activeNewsIndex.value === index) {
|
||||
activeNewsIndex.value = 0
|
||||
}
|
||||
} catch {}
|
||||
} catch {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
|
||||
// 添加一个图文
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IEditorConfig } from '@wangeditor/editor'
|
||||
import { IEditorConfig } from '@wangeditor-next/editor'
|
||||
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -97,7 +97,9 @@ const handleDelete = async (item: any) => {
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -101,7 +101,7 @@ const uploadVideoRef = ref<UploadInstance | null>(null)
|
||||
const submitVideo = () => {
|
||||
uploadFormRef.value?.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
uploadVideoRef.value?.submit()
|
||||
})
|
||||
|
||||
@ -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变量插入被移出的菜单
|
||||
|
||||
@ -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 // 稍后复制
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
|
||||
@ -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' }]
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
/** 提交支付 */
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { SlateDescendant } from '@wangeditor/editor'
|
||||
import { SlateDescendant } from '@wangeditor-next/editor'
|
||||
|
||||
declare module 'slate' {
|
||||
interface CustomTypes {
|
||||
Reference in New Issue
Block a user