全栈小学生 5b0dfeee91 up
2025-09-13 10:24:40 +08:00

378 lines
14 KiB
Vue

<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-page-title">{{ pageName }}</span>
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">{{ t('addDiyPage') }}</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef">
<el-form-item :label="t('title')" prop="title">
<el-input v-model.trim="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('forAddon')" prop="addon_name">
<el-select v-model="diyPageTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')" @change="handleSelectAddonChange">
<el-option :label="t('all')" value="" />
<el-option v-for="(item, key) in apps" :label="item.title" :value="key" :key="key"/>
</el-select>
</el-form-item>
<el-form-item :label="t('typeName')" prop="type">
<el-select v-model="diyPageTableData.searchParam.type" :placeholder="t('pageTypePlaceholder')">
<el-option :label="t('all')" value="" />
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadDiyPageList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormDiyPageRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<el-table :data="diyPageTableData.data" size="large" v-loading="diyPageTableData.loading">
<template #empty>
<span>{{ !diyPageTableData.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="page_title" :label="t('title')" min-width="120" />
<el-table-column prop="addon_name" :label="t('forAddon')" min-width="80" />
<el-table-column prop="type_name" :label="t('typeName')" min-width="80" />
<el-table-column :label="t('status')" min-width="80">
<template #default="{ row }">
<span v-if="row.type == 'DIY_PAGE'">-</span>
<template v-else>
<span v-if="row.is_default == 1" class="text-primary">{{ t('isUse') }}</span>
<span v-else>{{ t('unused') }}</span>
</template>
</template>
</el-table-column>
<el-table-column prop="update_time" :label="t('updateTime')" min-width="120" />
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="160">
<template #default="{ row }">
<el-button type="primary" link @click="toPreview(row)">{{ t('preview') }}</el-button>
<el-button v-if="row.is_default == 0" type="primary" link @click="setUse(row.id)">{{ t('use') }}</el-button>
<el-button v-if="row.type == 'DIY_PAGE'" type="primary" link @click="openShare(row)">{{ t('shareSet') }}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button v-if="row.is_default == 0 || row.type == 'DIY_PAGE'" type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
<el-button type="primary" link @click="copyEvent(row.id)">{{ t('copy') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="diyPageTableData.page" v-model:page-size="diyPageTableData.limit"
layout="total, sizes, prev, pager, next, jumper" :total="diyPageTableData.total"
@size-change="loadDiyPageList()" @current-change="loadDiyPageList" />
</div>
</el-card>
<!--添加页面-->
<el-dialog v-model="dialogVisible" :title="t('addPageTips')" width="350px">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
<el-form-item :label="t('title')" prop="title">
<el-input v-model.trim="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" />
</el-form-item>
<el-form-item :label="t('typeName')" prop="type">
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')" class="!w-full">
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="addEvent(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
<!-- 分享设置-->
<el-dialog v-model="shareDialogVisible" :title="t('shareSet')" width="30%">
<el-tabs v-model="tabShareType">
<el-tab-pane :label="t('wechat')" name="wechat"></el-tab-pane>
<el-tab-pane :label="t('weapp')" name="weapp"></el-tab-pane>
</el-tabs>
<el-form :model="shareFormData[tabShareType]" label-width="90px" ref="shareFormRef" :rules="shareFormRules">
<el-form-item :label="t('sharePage')">
<span>{{ sharePage }}</span>
</el-form-item>
<el-form-item :label="t('shareTitle')" prop="title">
<el-input v-model.trim="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit />
</el-form-item>
<el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'">
<el-input v-model.trim="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit />
</el-form-item>
<el-form-item :label="t('shareImageUrl')" prop="url">
<upload-image v-model="shareFormData[tabShareType].url" :limit="1" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="shareDialogVisible = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="shareEvent(shareFormRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { getApps, getDiyPageList, deleteDiyPage, getDiyTemplate, editDiyPageShare, setUseDiyPage, copyDiy } from '@/app/api/diy'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
const route = useRoute()
const router = useRouter()
const pageName = route.meta.title
const pageType: any = reactive({}) // 页面类型
// 添加自定义页面
const formData = reactive({
title: '',
type: ''
})
// 表单验证规则
const formRules = computed(() => {
return {
title: [
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' }
],
type: [
{ required: true, message: t('pageTypePlaceholder'), trigger: 'blur' }
]
}
})
const formRef = ref<FormInstance>()
const dialogVisible = ref(false)
const addEvent = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(async (valid) => {
if (valid) {
const query = { type: formData.type, title: formData.title }
const url = router.resolve({
path: '/decorate/edit',
query
})
window.open(url.href)
dialogVisible.value = false
formData.title = ''
formData.type = ''
}
})
}
// 获取自定义页面类型
const loadDiyTemplate = (addon = '') => {
getDiyTemplate({ mode: '', addon }).then(res => {
for (const key in pageType) {
delete pageType[key]
}
for (const key in res.data) {
pageType[key] = res.data[key]
}
})
}
loadDiyTemplate()
const apps: any = reactive({}) // 应用插件列表
getApps({}).then(res => {
if (res.data) {
for (const key in res.data) {
apps[key] = res.data[key]
}
}
})
// 根据所属插件,查询页面类型
const handleSelectAddonChange = (value: any) => {
diyPageTableData.searchParam.type = ''
loadDiyTemplate(value)
}
const diyPageTableData: any = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
title: '',
type: '',
mode: '',
addon_name: ''
}
})
const searchFormDiyPageRef = ref<FormInstance>()
// 获取自定义页面列表
const loadDiyPageList = (page: number = 1) => {
diyPageTableData.loading = true
diyPageTableData.page = page
getDiyPageList({
page: diyPageTableData.page,
limit: diyPageTableData.limit,
...diyPageTableData.searchParam
}).then(res => {
diyPageTableData.loading = false
diyPageTableData.data = res.data.data
diyPageTableData.total = res.data.total
setTablePageStorage(diyPageTableData.page, diyPageTableData.limit, diyPageTableData.searchParam)
}).catch(() => {
diyPageTableData.loading = false
})
}
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
// 编辑自定义页面
const editEvent = (data: any) => {
const url = router.resolve({
path: '/decorate/edit',
query: { id: data.id }
})
window.open(url.href)
}
// 设为使用
const setUse = (id: any) => {
setUseDiyPage({ id }).then(() => {
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
})
}
const repeat = ref(false)
// 复制页面
const copyEvent = (id: any) => {
ElMessageBox.confirm(t('diyPageCopyTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
if (repeat.value) return
repeat.value = true
copyDiy({ id }).then((res: any) => {
if (res.code == 1) {
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
}
repeat.value = false
}).catch(err => {
repeat.value = false
})
})
}
// 删除自定义页面
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('diyPageDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteDiyPage(id).then(() => {
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
}).catch(() => {
})
})
}
// 跳转去预览
const toPreview = (data: any) => {
const url = router.resolve({
path: '/preview/wap',
query: {
page: data.type_page + '?id=' + data.id
}
})
window.open(url.href)
}
const tabShareType = ref('wechat')
const sharePage = ref('')
const shareFormId = ref(0)
const shareFormData = reactive({
wechat: {
title: '',
desc: '',
url: ''
},
weapp: {
title: '',
url: ''
}
})
const shareDialogVisible = ref(false)
const shareFormRules = computed(() => {
return {}
})
const shareFormRef = ref<FormInstance>()
const openShare = async (row: any) => {
shareFormId.value = row.id
sharePage.value = row.title
const share = row.share
? JSON.parse(row.share)
: {
wechat: { title: '', desc: '', url: '' },
weapp: { title: '', url: '' }
}
if (share) {
shareFormData.wechat = share.wechat
shareFormData.weapp = share.weapp
}
shareDialogVisible.value = true
}
const shareEvent = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(async (valid) => {
if (valid) {
editDiyPageShare({
id: shareFormId.value,
share: JSON.stringify(shareFormData)
}).then(() => {
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
shareDialogVisible.value = false
}).catch(() => {
})
}
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadDiyPageList()
}
</script>
<style lang="scss" scoped></style>