mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2025-12-13 10:02:48 +00:00
up
This commit is contained in:
parent
1edbfb2a1f
commit
fd7f31e40a
2
admin/components.d.ts
vendored
2
admin/components.d.ts
vendored
@ -9,6 +9,7 @@ declare module '@vue/runtime-core' {
|
|||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
Attachment: typeof import('./src/components/upload-attachment/attachment.vue')['default']
|
Attachment: typeof import('./src/components/upload-attachment/attachment.vue')['default']
|
||||||
DiyLink: typeof import('./src/components/diy-link/index.vue')['default']
|
DiyLink: typeof import('./src/components/diy-link/index.vue')['default']
|
||||||
|
DiyPage: typeof import('./src/components/diy-page/index.vue')['default']
|
||||||
Editor: typeof import('./src/components/editor/index.vue')['default']
|
Editor: typeof import('./src/components/editor/index.vue')['default']
|
||||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||||
ElAside: typeof import('element-plus/es')['ElAside']
|
ElAside: typeof import('element-plus/es')['ElAside']
|
||||||
@ -91,6 +92,7 @@ declare module '@vue/runtime-core' {
|
|||||||
SelectIcon: typeof import('./src/components/select-icon/index.vue')['default']
|
SelectIcon: typeof import('./src/components/select-icon/index.vue')['default']
|
||||||
SpreadPopup: typeof import('./src/components/spread-popup/index.vue')['default']
|
SpreadPopup: typeof import('./src/components/spread-popup/index.vue')['default']
|
||||||
UploadAttachment: typeof import('./src/components/upload-attachment/index.vue')['default']
|
UploadAttachment: typeof import('./src/components/upload-attachment/index.vue')['default']
|
||||||
|
UploadAudio: typeof import('./src/components/upload-audio/index.vue')['default']
|
||||||
UploadFile: typeof import('./src/components/upload-file/index.vue')['default']
|
UploadFile: typeof import('./src/components/upload-file/index.vue')['default']
|
||||||
UploadImage: typeof import('./src/components/upload-image/index.vue')['default']
|
UploadImage: typeof import('./src/components/upload-image/index.vue')['default']
|
||||||
UploadVideo: typeof import('./src/components/upload-video/index.vue')['default']
|
UploadVideo: typeof import('./src/components/upload-video/index.vue')['default']
|
||||||
|
|||||||
@ -157,7 +157,7 @@ UE.I18N['zh-cn'] = {
|
|||||||
'elementPathTip': "元素路径",
|
'elementPathTip': "元素路径",
|
||||||
'wordCountTip': "字数统计",
|
'wordCountTip': "字数统计",
|
||||||
'wordCountMsg': '{#count} / {#leave}',
|
'wordCountMsg': '{#count} / {#leave}',
|
||||||
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值,服务器可能拒绝保存!</span>',
|
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值!</span>',
|
||||||
'ok': "确认",
|
'ok': "确认",
|
||||||
'cancel': "取消",
|
'cancel': "取消",
|
||||||
'closeDialog': "关闭对话框",
|
'closeDialog': "关闭对话框",
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import useAppStore from '@/stores/modules/app'
|
|||||||
import { useDark, useToggle } from '@vueuse/core'
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
import { setThemeColor } from '@/utils/common'
|
import { setThemeColor } from '@/utils/common'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { getSiteAllowChange} from '@/app/api/site'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
@ -24,7 +25,14 @@ systemStore.getWebsiteInfo()
|
|||||||
systemStore.getWebsiteLayout()
|
systemStore.getWebsiteLayout()
|
||||||
|
|
||||||
const toggleDark = useToggle(useDark())
|
const toggleDark = useToggle(useDark())
|
||||||
|
const getSiteAllowChangeFn = ()=>{
|
||||||
|
getSiteAllowChange().then(({data})=>{
|
||||||
|
let isAllowChange = data.is_allow ? true : false
|
||||||
|
localStorage.setItem('isAllowChange',isAllowChange.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
getSiteAllowChangeFn()
|
||||||
watch(route, () => {
|
watch(route, () => {
|
||||||
useAppStore().$patch(state => {
|
useAppStore().$patch(state => {
|
||||||
state.route = route
|
state.route = route
|
||||||
@ -39,3 +47,9 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
<style>
|
||||||
|
.el-page-header__header .el-page-header__left .el-page-header__content{
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -103,3 +103,6 @@ export function getAppIndex() {
|
|||||||
return request.get('app/index')
|
return request.get('app/index')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAdvList() {
|
||||||
|
return request.get('index/adv_list')
|
||||||
|
}
|
||||||
|
|||||||
@ -199,6 +199,12 @@ export function copyDiy(params: Record<string, any>) {
|
|||||||
return request.post(`diy/copy`, params, { showSuccessMessage: true })
|
return request.post(`diy/copy`, params, { showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义页面选择列表
|
||||||
|
*/
|
||||||
|
export function getPageLink(params: Record<string, any>) {
|
||||||
|
return request.get(`diy/page_link`, { params })
|
||||||
|
}
|
||||||
/***************************************************** 主题风格 ****************************************************/
|
/***************************************************** 主题风格 ****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -113,3 +113,7 @@ export function getPreviewPoster(params: Record<string, any>) {
|
|||||||
export function getPosterGenerate(params: Record<string, any>) {
|
export function getPosterGenerate(params: Record<string, any>) {
|
||||||
return request.get(`sys/poster/generate`, { params, showErrorMessage: false })
|
return request.get(`sys/poster/generate`, { params, showErrorMessage: false })
|
||||||
}
|
}
|
||||||
|
// 判断是否安装imagemagick扩展
|
||||||
|
export function checkImagick() {
|
||||||
|
return request.get(`sys/check_imagick`, { showErrorMessage: false })
|
||||||
|
}
|
||||||
@ -21,6 +21,23 @@ export function getVerifyDetail(verifyCode: string) {
|
|||||||
return request.get(`verify/verify/${ verifyCode }`)
|
return request.get(`verify/verify/${ verifyCode }`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取核销详情
|
||||||
|
* @param verifyCode
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getVerifyDetailInfo(verifyCode: string) {
|
||||||
|
return request.get(`verify/detail/${ verifyCode }`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 核销
|
||||||
|
* @param verifyCode
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function verify(verifyCode: string, params: Record<string, any>) {
|
||||||
|
return request.post(`verify/verify/${ verifyCode }`,params,{ showSuccessMessage: true})
|
||||||
|
}
|
||||||
/***************************************************** 核销员 ****************************************************/
|
/***************************************************** 核销员 ****************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
BIN
admin/src/app/assets/images/goods_default.png
Normal file
BIN
admin/src/app/assets/images/goods_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
admin/src/app/assets/images/icon-addon-one.png
Normal file
BIN
admin/src/app/assets/images/icon-addon-one.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
admin/src/app/assets/images/write.png
Normal file
BIN
admin/src/app/assets/images/write.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 B |
@ -13,7 +13,7 @@
|
|||||||
<div class="flex flex-wrap plug-list pb-10 plug-large">
|
<div class="flex flex-wrap plug-list pb-10 plug-large">
|
||||||
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
||||||
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
||||||
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(childItem.icon)" fit="contain">
|
<el-image class="w-[40px] h-[40px] mr-[10px] rounded-[6px] overflow-hidden" :src="img(childItem.icon)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<img class="w-[40px] h-[40px]" src="@/app/assets/images/index/app_default.png" />
|
<img class="w-[40px] h-[40px]" src="@/app/assets/images/index/app_default.png" />
|
||||||
@ -65,7 +65,13 @@ getMarketingList()
|
|||||||
|
|
||||||
const toLink = (item: any) => {
|
const toLink = (item: any) => {
|
||||||
if (item.url) {
|
if (item.url) {
|
||||||
router.push(item.url)
|
// 判断如果携带is_target=true就通过新窗口打开
|
||||||
|
if (item.url.indexOf('is_target=true') != -1) {
|
||||||
|
const url = router.resolve(item.url)
|
||||||
|
window.open(url.href)
|
||||||
|
} else {
|
||||||
|
router.push(item.url)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
addonIndexRoute[item.key] && router.push({ name: addonIndexRoute[item.key] })
|
addonIndexRoute[item.key] && router.push({ name: addonIndexRoute[item.key] })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<el-form label-width="80px" class="px-[10px]" @submit.prevent>
|
<el-form label-width="80px" class="px-[10px]" @submit.prevent>
|
||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer" @click="showTitleStyle">{{ diyStore.editComponent.titleStyle.title }}</span>
|
<span class="text-primary flex-1 cursor-pointer" @click="showTitleStyle">{{ diyStore.editComponent.titleStyle.title }}</span>
|
||||||
<el-icon>
|
<el-icon @click="showTitleStyle" class="cursor-pointer">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -57,7 +57,7 @@
|
|||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer"
|
<span class="text-primary flex-1 cursor-pointer"
|
||||||
@click="showBlockStyle">{{ diyStore.editComponent.blockStyle.title }}</span>
|
@click="showBlockStyle">{{ diyStore.editComponent.blockStyle.title }}</span>
|
||||||
<el-icon>
|
<el-icon @click="showBlockStyle" class="cursor-pointer">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
<el-form label-width="100px" class="px-[10px]" @submit.prevent>
|
<el-form label-width="100px" class="px-[10px]" @submit.prevent>
|
||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer" @click="showSearchStyle">{{ diyStore.editComponent.search.styleName }}</span>
|
<span class="text-primary flex-1 cursor-pointer" @click="showSearchStyle">{{ diyStore.editComponent.search.styleName }}</span>
|
||||||
<el-icon>
|
<el-icon @click="showSearchStyle" class="cursor-pointer">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer"
|
<span class="text-primary flex-1 cursor-pointer"
|
||||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||||
<el-icon>
|
<el-icon @click="showStyle" class="cursor-pointer">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@ -74,7 +74,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
@ -330,6 +330,10 @@ const handleHeight = (isCalcHeight: boolean = false) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(() => diyStore.editComponent.list, () => {
|
||||||
|
handleHeight(true)
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer"
|
<span class="text-primary flex-1 cursor-pointer"
|
||||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||||
<el-icon>
|
<el-icon @click="showStyle" class="cursor-pointer">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@ -510,12 +510,12 @@ const spreadPopupRef = ref(null)
|
|||||||
|
|
||||||
const spreadEvent = (data: any) => {
|
const spreadEvent = (data: any) => {
|
||||||
const pagePath = '/app/pages/index/diy_form'
|
const pagePath = '/app/pages/index/diy_form'
|
||||||
const columnName = 'form_id'
|
const paramsArr = [
|
||||||
const columnValue = data.form_id
|
{ name: 'form_id', value: data.form_id },
|
||||||
|
];
|
||||||
const title = '表单推广'
|
const title = '表单推广'
|
||||||
const folder = 'diy_form'
|
const folder = 'diy_form'
|
||||||
|
spreadPopupRef.value?.show(pagePath, paramsArr, title, folder);
|
||||||
spreadPopupRef.value?.show(pagePath, columnName, columnValue, title, folder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单提交成功页弹出框
|
// 表单提交成功页弹出框
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="showDialog" title="退款详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
<el-drawer v-model="showDialog" title="退款详情" direction="rtl" :before-close="handleClose" size="1300px">
|
||||||
<div class="main-container" v-loading="loading">
|
<div class="main-container" v-loading="loading">
|
||||||
<div class="relative" v-if="formData">
|
<div class="relative" v-if="formData">
|
||||||
<div class="flex mb-[20px] justify-between text-[15px]">
|
<div class="flex mb-[20px] justify-between text-[15px]">
|
||||||
@ -152,8 +152,4 @@ defineExpose({
|
|||||||
setFormData
|
setFormData
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped></style>
|
||||||
.member-detail-drawer{
|
|
||||||
width: 1300px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -3,11 +3,16 @@
|
|||||||
<!-- <div class="flex justify-between items-center">
|
<!-- <div class="flex justify-between items-center">
|
||||||
<layoutHeader></layoutHeader>
|
<layoutHeader></layoutHeader>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="flex justify-between items-center py-[24px] pl-[62px] pr-[64px] home-head">
|
<div class="flex justify-between items-center py-[24px] pr-[64px] home-head">
|
||||||
<div class="flex items-center" v-if="webConfig">
|
<div class="flex items-center w-[219px] justify-center" v-if="webConfig">
|
||||||
<img class="w-[32x] h-[32px] rounded-full" v-if="webConfig.icon" :src="img(webConfig.icon)" alt="">
|
<div class="max-w-[82px] h-[40px] overflow-hidden">
|
||||||
<img class="w-[32x] h-[32px] rounded-full" v-else src="@/app/assets/images/icon-addon.png" alt="">
|
<el-image class="h-[40px]" :src="img(webConfig.icon)" fit="contain">
|
||||||
<span class="ml-[10px] text-[16px] font-bold">{{webConfig.site_name}}</span>
|
<template #error>
|
||||||
|
<div class="flex justify-center items-center w-full h-full"><img class="max-w-[70px]" src="@/app/assets/images/logo.default.png" alt="" object-fit="contain"></div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
<span class="ml-[10px] max-w-[120px] text-[16px] font-bold truncate">{{webConfig.site_name}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div v-if="userStore.userInfo.is_super_admin" class="border-primary border-[1px] h-[30px] px-[15px] flex items-center rounded-[6px] mr-[10px] cursor-pointer" @click="toHome">
|
<div v-if="userStore.userInfo.is_super_admin" class="border-primary border-[1px] h-[30px] px-[15px] flex items-center rounded-[6px] mr-[10px] cursor-pointer" @click="toHome">
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<div class="flex h-[156px]">
|
<div class="flex h-[156px]">
|
||||||
<div class="w-full h-full ">
|
<div class="w-full h-full ">
|
||||||
<el-carousel :interval="3000" height="156px" class="rounded-[6px]">
|
<el-carousel :interval="3000" height="156px" class="rounded-[6px]">
|
||||||
<el-carousel-item >
|
<!-- <el-carousel-item >
|
||||||
<div class="h-full index-carousel" @click="toApplication">
|
<div class="h-full index-carousel" @click="toApplication">
|
||||||
<img :src="img('static/resource/images/banner_1.png')" alt="" class="w-full h-full cursor-pointer">
|
<img :src="img('static/resource/images/banner_1.png')" alt="" class="w-full h-full cursor-pointer">
|
||||||
</div>
|
</div>
|
||||||
@ -21,7 +21,14 @@
|
|||||||
<div class="h-full index-carousel" @click="toApplication">
|
<div class="h-full index-carousel" @click="toApplication">
|
||||||
<img :src="img('static/resource/images/banner_2.png')" alt="" class="w-full h-full cursor-pointer">
|
<img :src="img('static/resource/images/banner_2.png')" alt="" class="w-full h-full cursor-pointer">
|
||||||
</div>
|
</div>
|
||||||
|
</el-carousel-item> -->
|
||||||
|
|
||||||
|
<el-carousel-item v-for="(item, index) in bannerlistr" :key="index">
|
||||||
|
<div class="h-full index-carousel" @click="toApplicationurl(item)">
|
||||||
|
<img :src="item.image" alt="" class="w-full h-full cursor-pointer">
|
||||||
|
</div>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
|
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -248,7 +255,7 @@
|
|||||||
import { ref, watch ,onMounted} from 'vue'
|
import { ref, watch ,onMounted} from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getStatInfo } from '@/app/api/stat'
|
import { getStatInfo } from '@/app/api/stat'
|
||||||
import { getAppIndex } from '@/app/api/addon'
|
import { getAppIndex ,getAdvList} from '@/app/api/addon'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { getFrameworkNewVersion } from '@/app/api/module'
|
import { getFrameworkNewVersion } from '@/app/api/module'
|
||||||
import { getWebCopyright } from '@/app/api/sys'
|
import { getWebCopyright } from '@/app/api/sys'
|
||||||
@ -302,12 +309,20 @@ const appList = ref<any>([])
|
|||||||
const getAppIndexFn = () => {
|
const getAppIndexFn = () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
getAppIndex().then((res) => {
|
getAppIndex().then((res) => {
|
||||||
appList.value = res.data.data
|
console.log(res)
|
||||||
|
appList.value = res.data
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getAppIndexFn()
|
getAppIndexFn()
|
||||||
|
const bannerlistr = ref<any>([])
|
||||||
|
const getAdvListFn = () => {
|
||||||
|
getAdvList().then((res) => {
|
||||||
|
console.log(res.data)
|
||||||
|
bannerlistr.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getAdvListFn()
|
||||||
const getInfoFn = () => {
|
const getInfoFn = () => {
|
||||||
if (copyright.value.copyright_desc) {
|
if (copyright.value.copyright_desc) {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
@ -442,6 +457,9 @@ const toTypeLink = (url: any,type: any) => {
|
|||||||
const toApplication = () => {
|
const toApplication = () => {
|
||||||
window.open('https://www.niucloud.com/app')
|
window.open('https://www.niucloud.com/app')
|
||||||
}
|
}
|
||||||
|
const toApplicationurl = (item: any) => {
|
||||||
|
window.open(item.url)
|
||||||
|
}
|
||||||
const toApplicationDetail = (item: any) => {
|
const toApplicationDetail = (item: any) => {
|
||||||
window.open(`https://www.niucloud.com/app/detail?id=${item.app_id}`)
|
window.open(`https://www.niucloud.com/app/detail?id=${item.app_id}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@
|
|||||||
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
|
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex items-center w-full h-full">
|
<div class="flex items-center w-full h-full">
|
||||||
<img class="max-w-full max-h-full" src="@/app/assets/images/icon-addon.png" alt="" />
|
<img class="max-w-full max-h-full" src="@/app/assets/images/icon-addon-one.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="showDialog" title="核销记录详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
<el-drawer v-model="showDialog" title="核销记录详情" direction="rtl" :before-close="handleClose" size="1300px">
|
||||||
<div class="main-container" v-loading="loading">
|
<div class="main-container" v-loading="loading">
|
||||||
<el-tabs v-model="activeName" class="pb-[10px]" @tab-change="handleClick">
|
<el-tabs v-model="activeName" class="pb-[10px]" @tab-change="handleClick">
|
||||||
<el-tab-pane label="核销信息" name="verifyInfo" />
|
<el-tab-pane label="核销信息" name="verifyInfo" />
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<div class="flex items-center mt-[15px]">
|
<div class="flex items-center mt-[15px]">
|
||||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销人员') }}</span>
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销人员') }}</span>
|
||||||
<span class="text-[14px] text-[#666666]">
|
<span class="text-[14px] text-[#666666]">
|
||||||
{{ verifyData.member ? verifyData.member.nickname : '--' }}
|
{{ (verifyData.is_admin == 1 ? '后台核销' : verifyData.member?.nickname) || '--' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -156,8 +156,4 @@ defineExpose({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped></style>
|
||||||
.member-detail-drawer{
|
|
||||||
width: 1300px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -39,15 +39,17 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !recordTable.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !recordTable.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<el-table-column :label="t('verifyTime')" min-width="180" align="left" :show-overflow-tooltip="true">
|
||||||
<el-table-column prop="code" :show-overflow-tooltip="true" :label="t('verifyCode')" align="left" min-width="150" />
|
|
||||||
<el-table-column prop="type_name" :label="t('verifyType')" align="left" min-width="150" />
|
|
||||||
<el-table-column :label="t('verifyTime')" min-width="180" align="center" :show-overflow-tooltip="true">
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.create_time || '' }}
|
{{ row.create_time || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="member.nickname" :label="t('verifyer')" min-width="180" align="center">
|
<el-table-column prop="type_name" :label="t('verifyType')" align="left" min-width="150" />
|
||||||
|
<el-table-column prop="code" :show-overflow-tooltip="true" :label="t('verifyCode')" align="left" min-width="150" />
|
||||||
|
<el-table-column :label="t('verifyer')" min-width="180" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.is_admin == 1 ? '后台核销' : row.member?.nickname }}
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@ -89,7 +91,7 @@ const recordTable = reactive({
|
|||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
code: '',
|
code: '',
|
||||||
type: '',
|
type: route.query.type || '',
|
||||||
verifier_member_id: '',
|
verifier_member_id: '',
|
||||||
create_time: []
|
create_time: []
|
||||||
}
|
}
|
||||||
|
|||||||
130
admin/src/app/views/marketing/verify_index.vue
Normal file
130
admin/src/app/views/marketing/verify_index.vue
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main-container min-h-[300px]">
|
||||||
|
<div class="">
|
||||||
|
<el-card class="box-card mt-[10px]!border-none table-search-wrap" shadow="never">
|
||||||
|
<div class="flex p-[10px] items-end">
|
||||||
|
<div class="flex items-center w-[500px] h-[45px] border-[2px] border-primary rounded-l-lg">
|
||||||
|
<span class="h-[15px] ml-[10px] pr-[10px] border-r-[1px] border-[#DEE1E7] leading-[1]">
|
||||||
|
<img class="w-[15px]" src="@/app/assets/images/write.png" />
|
||||||
|
</span>
|
||||||
|
<input class="w-[400px] h-[40px] outline-none pl-[10px] text-[18px] bg-transparent"
|
||||||
|
v-model="verifycode" />
|
||||||
|
</div>
|
||||||
|
<div class="bg-primary h-[45px] flex items-center px-[20px] rounded-[10px] ml-[10px] text-[#fff] cursor-pointer"
|
||||||
|
@click="handelVerify">
|
||||||
|
<span>{{ t("核销") }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="bg-primary h-[45px] flex items-center px-[20px] rounded-[10px] ml-[10px] text-[#fff] cursor-pointer"
|
||||||
|
@click="router.push('/marketing/verify')">
|
||||||
|
<span>{{ t("核销记录") }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<el-dialog v-model="showDialog" :title="t('核销')" width="500px" :destroy-on-close="true">
|
||||||
|
<div>
|
||||||
|
<h3 class="panel-title !text-sm">{{ t('核销信息') }}</h3>
|
||||||
|
<div class="flex items-center mt-[15px]">
|
||||||
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销码') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{verifycode}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-[15px]">
|
||||||
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销类型') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ verifyInfo.type_name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-[15px]" v-for="(item,index) in verifyInfo.fixed" :key="index">
|
||||||
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ item.title }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ item.value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="box-card mt-[15px] !border-none" shadow="never" v-for="(item,index) in verifyContentData.diy" :key="index">
|
||||||
|
<h3 class="panel-title !text-sm">{{ item.title }}</h3>
|
||||||
|
|
||||||
|
<div class="flex items-center mt-[15px]" v-for="(subItem,subIndex) in item.list" :key="subIndex">
|
||||||
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ subItem.title }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ subItem.value }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-[15px]">
|
||||||
|
<h3 class="panel-title !text-sm">{{ t('商品信息') }}</h3>
|
||||||
|
<el-table :data="verifyGoodsList" size="large">
|
||||||
|
<el-table-column :label="t('商品名称')" align="left" width="300">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex">
|
||||||
|
<div class="flex items-center shrink-0">
|
||||||
|
<el-image v-if="row.cover" class="w-[50px] h-[50px] mr-[10rpx]" :src="img(row.cover)" fit="contain">
|
||||||
|
<template #error>
|
||||||
|
<div class="image-slot">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10rpx]" src="@/app/assets/images/goods_default.png" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<img v-else class="w-[50px] h-[50px] mr-[10rpx]" src="@/app/assets/images/goods_default.png" fit="contain" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<p class="multi-hidden text-[14px]">{{ row.name }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="num" :label="t('数量')" min-width="50" align="right" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="verifyCode">{{ t("confirm") }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang='ts' setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { t } from '@/lang'
|
||||||
|
import {img} from '@/utils/common'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { getVerifyDetailInfo ,verify} from '@/app/api/verify'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const loading = ref(false)
|
||||||
|
const verifycode = ref('')
|
||||||
|
const verifyInfo = ref<any>([])
|
||||||
|
const verifyContentData: any = ref({})
|
||||||
|
const verifyGoodsList: any = ref([])
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const handelVerify = () => {
|
||||||
|
if (verifycode.value == '') return
|
||||||
|
getVerifyDetailInfo(verifycode.value).then((res) => {
|
||||||
|
showDialog.value = true
|
||||||
|
verifyInfo.value = res.data
|
||||||
|
verifyContentData.value = res.data.value.content || {}
|
||||||
|
verifyGoodsList.value = res.data.value.list || []
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSubmit = ref(false)
|
||||||
|
const verifyCode = () => {
|
||||||
|
if (verifycode.value == '') return
|
||||||
|
if (isSubmit.value) return
|
||||||
|
isSubmit.value = true
|
||||||
|
verify(verifycode.value).then(() => {
|
||||||
|
showDialog.value = false
|
||||||
|
isSubmit.value = false
|
||||||
|
}).catch(() => {
|
||||||
|
isSubmit.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="member-detail-drawer" size="1300px">
|
||||||
<div class="main-container" v-loading="loading">
|
<div class="main-container" v-loading="loading">
|
||||||
<div class="bg-page py-[20px] pr-[30px] relative flex">
|
<div class="bg-page py-[20px] pr-[30px] relative flex">
|
||||||
<div class="member-info w-[250px]">
|
<div class="member-info w-[250px]">
|
||||||
@ -375,17 +375,20 @@ const getMemberInfoFn = async (bool=false) => {
|
|||||||
Object.keys(data).forEach((item) => {
|
Object.keys(data).forEach((item) => {
|
||||||
formData[item] = data[item]
|
formData[item] = data[item]
|
||||||
})
|
})
|
||||||
|
if(!data.member_label_array){
|
||||||
|
formData.member_label_array =[]
|
||||||
|
formData.member_label_name=''
|
||||||
|
}
|
||||||
if (formData?.member_label_array && Object.keys(formData.member_label_array)?.length) {
|
if (formData?.member_label_array && Object.keys(formData.member_label_array)?.length) {
|
||||||
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||||
return item.label_id
|
return item.label_id
|
||||||
})
|
})
|
||||||
|
|
||||||
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||||
return item.label_name
|
return item.label_name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
} else {
|
} else {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -406,8 +409,4 @@ defineExpose({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped></style>
|
||||||
.member-detail-drawer{
|
|
||||||
width: 1300px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
|||||||
if (prop.value.weight) {
|
if (prop.value.weight) {
|
||||||
style += 'font-weight: bold;'
|
style += 'font-weight: bold;'
|
||||||
}
|
}
|
||||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||||
style += 'font-family: poster_default_font;'
|
style += 'font-family: poster_default_font;'
|
||||||
}
|
}
|
||||||
const box: any = document.getElementById(prop.value.id)
|
const box: any = document.getElementById(prop.value.id)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
|||||||
if (prop.value.weight) {
|
if (prop.value.weight) {
|
||||||
style += 'font-weight: bold;'
|
style += 'font-weight: bold;'
|
||||||
}
|
}
|
||||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||||
style += 'font-family: poster_default_font;'
|
style += 'font-family: poster_default_font;'
|
||||||
}
|
}
|
||||||
const box: any = document.getElementById(prop.value.id)
|
const box: any = document.getElementById(prop.value.id)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
|||||||
if (prop.value.weight) {
|
if (prop.value.weight) {
|
||||||
style += 'font-weight: bold;'
|
style += 'font-weight: bold;'
|
||||||
}
|
}
|
||||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||||
style += 'font-family: poster_default_font;'
|
style += 'font-family: poster_default_font;'
|
||||||
}
|
}
|
||||||
const box: any = document.getElementById(prop.value.id)
|
const box: any = document.getElementById(prop.value.id)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
|||||||
if (prop.value.weight) {
|
if (prop.value.weight) {
|
||||||
style += `font-weight: bold;`;
|
style += `font-weight: bold;`;
|
||||||
}
|
}
|
||||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||||
style += `font-family: poster_default_font;`;
|
style += `font-family: poster_default_font;`;
|
||||||
}
|
}
|
||||||
let box: any = document.getElementById(prop.value.id)
|
let box: any = document.getElementById(prop.value.id)
|
||||||
|
|||||||
@ -6,7 +6,13 @@
|
|||||||
<span class="text-page-title">{{ pageName }}</span>
|
<span class="text-page-title">{{ pageName }}</span>
|
||||||
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">{{ t('添加海报') }}</el-button>
|
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">{{ t('添加海报') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-[20px]" v-if="!isImagick">
|
||||||
|
<el-alert type="warning" show-icon :closable="false">
|
||||||
|
<template #title>
|
||||||
|
<span class="!text-[14px]">检测到PHP未安装ImageMagick扩展,需安装后才能使用海报功能</span>
|
||||||
|
</template>
|
||||||
|
</el-alert>
|
||||||
|
</div>
|
||||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
|
<el-form :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
|
||||||
<el-form-item :label="t('posterName')" prop="name">
|
<el-form-item :label="t('posterName')" prop="name">
|
||||||
@ -103,7 +109,7 @@ import { reactive, ref, computed } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { getPosterPageList, getPosterType, modifyPosterStatus, modifyPosterDefault, deletePoster, getPreviewPoster } from '@/app/api/poster'
|
import { getPosterPageList, getPosterType, modifyPosterStatus, modifyPosterDefault, deletePoster, getPreviewPoster ,checkImagick} from '@/app/api/poster'
|
||||||
import { img, setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
import { img, setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -281,6 +287,16 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
|||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
loadPosterPageList()
|
loadPosterPageList()
|
||||||
}
|
}
|
||||||
|
const isImagick = ref(false)
|
||||||
|
// 判断是否安装imagemagick扩展
|
||||||
|
const checkImagickFn = () => {
|
||||||
|
checkImagick().then((res:any) => {
|
||||||
|
console.log(res)
|
||||||
|
isImagick.value = res.data
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
checkImagickFn()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,11 @@
|
|||||||
<el-form-item :label="t('createTime')">
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.create_time }} </div>
|
<div class="input-width"> {{ formData.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('发送结果')">
|
||||||
|
<div class="input-width" v-if="formData.status == 'sending'"> 发送失败 </div>
|
||||||
|
<div class="input-width" v-if="formData.status == 'success'"> 发送成功 </div>
|
||||||
|
<div class="input-width" v-if="formData.status == 'fail'"> {{ formData.result }} </div>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -55,7 +59,9 @@ const initialFormData = {
|
|||||||
name: '',
|
name: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
sms_type_name: ''
|
sms_type_name: '',
|
||||||
|
status:'',
|
||||||
|
result:''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<el-image class="w-[40px] h-[40px] rounded-md overflow-hidden" :src="row.icon" fit="contain">
|
<el-image class="w-[40px] h-[40px] rounded-md overflow-hidden" :src="row.icon" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex items-center w-full h-full">
|
<div class="flex items-center w-full h-full">
|
||||||
<img class="w-full h-full" src="@/app/assets/images/icon-addon.png" alt="">
|
<img class="w-full h-full" src="@/app/assets/images/icon-addon-one.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3>
|
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between p-[10px] table-item-border bg">
|
<div class="flex items-center justify-between px-[10px] table-item-border bg h-[50px]">
|
||||||
<span class="text-base w-[230px]">{{ t('payType') }}</span>
|
<span class="text-base w-[230px]">{{ t('payType') }}</span>
|
||||||
<span class="text-base w-[110px] text-center">{{ t('onState') }}</span>
|
<span class="text-base w-[110px] text-center">{{ t('onState') }}</span>
|
||||||
<span class="text-base w-[80px] text-center" v-if="isEdit">{{ t('templateName') }}</span>
|
<span class="text-base w-[80px] text-center" v-if="isEdit">{{ t('templateName') }}</span>
|
||||||
@ -52,7 +52,6 @@
|
|||||||
<el-button type="primary" :loading="loading" @click="saveFn(formRef)">{{ t('save') }}</el-button>
|
<el-button type="primary" :loading="loading" @click="saveFn(formRef)">{{ t('save') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-for="(item, index) in payTypeList">
|
<template v-for="(item, index) in payTypeList">
|
||||||
<component :is="item.setting_component" :ref="(el) => setPayTypeRefs(el, item.key)" v-if="item.setting_component" @complete="setConfigInfo"/>
|
<component :is="item.setting_component" :ref="(el) => setPayTypeRefs(el, item.key)" v-if="item.setting_component" @complete="setConfigInfo"/>
|
||||||
</template>
|
</template>
|
||||||
@ -210,6 +209,6 @@ const cancelFn = () => {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.table-item-border {
|
.table-item-border {
|
||||||
@apply border-b border-[var(--el-border-color)];
|
@apply border-b border-[var(--el-border-color-lighter)];
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -77,8 +77,80 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<div class="mt-[20px]">
|
<div class="mt-[20px]">
|
||||||
|
<el-table :data="siteTableData.data" size="large" v-loading="siteTableData.loading">
|
||||||
|
<template #empty>
|
||||||
|
<span>{{ !siteTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
|
</template>
|
||||||
|
<el-table-column prop="site_id" :label="t('siteId')" width="100" :show-overflow-tooltip="true" />
|
||||||
|
|
||||||
|
<el-table-column :label="t('siteInfo')" width="300" align="left">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-if="row.logo" :src="img(row.logo)" alt="">
|
||||||
|
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-else src="@/app/assets/images/site_default.png" alt="">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span>{{ row.site_name || '' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="t('manager')" width="150" align="left">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span>{{ row.admin.username || '' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="group_name" :label="t('groupId')" width="150" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column prop="site_domain" :label="t('siteDomain')" width="250" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column prop="create_time" :label="t('createTime')" width="200" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column prop="expire_time" :label="t('expireTime')" width="200" :show-overflow-tooltip="true">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.expire_time == 0">永久</div>
|
||||||
|
<div v-else>{{ row.expire_time }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="t('status')" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ row.status_name }}</el-tag>
|
||||||
|
<el-tag class="ml-2" type="error" v-else-if="row.status == 3">
|
||||||
|
{{ row.status_name }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag class="ml-2" type="error" v-else>
|
||||||
|
{{ row.status_name }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="t('operation')" min-width="250" align="right" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="operation-buttons">
|
||||||
|
<div class="button-row">
|
||||||
|
<el-button type="primary" link @click="toSiteLink(row.site_id)">{{ t('toSite') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="openClose(row.status, row.site_id)" v-if="row.status == 1 || row.status == 3">{{ row.status == 1 ? t('closeTxt') : t('openTxt') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="button-row">
|
||||||
|
<el-button type="primary" link @click="initSiteEvent(row)">{{ t('站点初始化') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="mt-[16px] flex justify-end">
|
||||||
|
<el-pagination v-model:current-page="siteTableData.page" v-model:page-size="siteTableData.limit"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
||||||
|
@size-change="loadSiteList()" @current-change="loadSiteList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="mt-[20px]">
|
||||||
<div class="el-table--fit el-table--default el-table overflow-x-auto w-full" style="width: 100%;" v-loading="siteTableData.loading">
|
<div class="el-table--fit el-table--default el-table overflow-x-auto w-full" style="width: 100%;" v-loading="siteTableData.loading">
|
||||||
|
|
||||||
<div class="el-table__inner-wrapper">
|
<div class="el-table__inner-wrapper">
|
||||||
@ -169,7 +241,7 @@
|
|||||||
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
||||||
@size-change="loadSiteList()" @current-change="loadSiteList" />
|
@size-change="loadSiteList()" @current-change="loadSiteList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<edit-site ref="addSiteDialog" @complete="loadSiteList()" />
|
<edit-site ref="addSiteDialog" @complete="loadSiteList()" />
|
||||||
@ -404,8 +476,6 @@ const infoEvent = (data: any) => {
|
|||||||
router.push({ path: '/admin/site/info', query: { id: data.site_id } })
|
router.push({ path: '/admin/site/info', query: { id: data.site_id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑站点详情
|
* 编辑站点详情
|
||||||
* @param data
|
* @param data
|
||||||
@ -687,8 +757,8 @@ const confirmInit = () => {
|
|||||||
:deep(.setting-card .el-card__body){
|
:deep(.setting-card .el-card__body){
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
:deep(.el-scrollbar__view){
|
// :deep(.el-scrollbar__view){
|
||||||
margin-bottom: 53px !important;
|
// margin-bottom: 53px !important;
|
||||||
}
|
// }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -67,16 +67,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" class="dialog-visible" width="70%" title="代码预览">
|
||||||
|
<div class="flex h-[50vh]" v-loading="codeLoading">
|
||||||
|
<el-scrollbar class="h-[100%] w-[270px]">
|
||||||
|
<div class="w-[600px]">
|
||||||
|
<el-tree v-if="treeData.length && treeKey != ''" :data="treeData" :props="{ label: 'name', value: 'key' }"
|
||||||
|
node-key="key" :current-node-key="treeKey" :expand-on-click-node="false" highlight-current
|
||||||
|
default-expand-all ref="treeRef" @node-click="nodeClick">
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<el-icon v-if="data.children">
|
||||||
|
<Folder v-if="!node.expanded" />
|
||||||
|
<FolderOpened v-else />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon v-else>
|
||||||
|
<Document />
|
||||||
|
</el-icon>
|
||||||
|
<span class="pl-[5px]">{{ data.name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
<div class="ml-[20px] relative" style="width: calc(100% - 285px);">
|
||||||
|
<el-scrollbar class="h-[100%] w-[100%]">
|
||||||
|
<highlightjs autodetect class="h-[100%]" :code="code" />
|
||||||
|
</el-scrollbar>
|
||||||
|
<div class="absolute top-0 right-[15px] z-5 cursor-pointer hover:text-primary" @click="copyCode">
|
||||||
|
<el-tooltip content="点击复制" placement="top" >
|
||||||
|
<icon name="iconfont icondingdanzhongxinPC-3"/>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { img, setTablePageStorage } from '@/utils/common'
|
import { img, setTablePageStorage } from '@/utils/common'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getGenerateTableList, deleteGenerateTable, generateCreate, generatePreview, generatorCheckFile, getAddonDevelop } from '@/app/api/tools'
|
import { getGenerateTableList, deleteGenerateTable, generateCreate, generatePreview, generatorCheckFile, getAddonDevelop } from '@/app/api/tools'
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -251,6 +288,27 @@ const listToTree = (arr:any) => {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { copy, isSupported, copied } = useClipboard()
|
||||||
|
const copyCode = () => {
|
||||||
|
if (!isSupported.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('notSupportCopy'),
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
copy(code.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(copied, () => {
|
||||||
|
if (copied.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('copySuccess'),
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -26,13 +26,13 @@
|
|||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('title')" prop="key">
|
<el-form-item :label="t('title')" prop="key">
|
||||||
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable :remote-method="loadCronList(1)">
|
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable>
|
||||||
<el-option label="全部" value="all" />
|
<el-option label="全部" value="all" />
|
||||||
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
|
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('status')" prop="status">
|
<el-form-item :label="t('status')" prop="status">
|
||||||
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" filterable remote clearable :remote-method="loadCronList(1)">
|
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" clearable>
|
||||||
<el-option label="全部" value="all" />
|
<el-option label="全部" value="all" />
|
||||||
<el-option label="启用" value="1" />
|
<el-option label="启用" value="1" />
|
||||||
<el-option label="关闭" value="0" />
|
<el-option label="关闭" value="0" />
|
||||||
|
|||||||
202
admin/src/components/diy-page/index.vue
Normal file
202
admin/src/components/diy-page/index.vue
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div @click="show">
|
||||||
|
<slot>
|
||||||
|
<el-input v-model="selectData.title" :placeholder="t('请选择跳转页面')" readonly class="link-input">
|
||||||
|
<template #suffix>
|
||||||
|
<div @click.stop="clear">
|
||||||
|
<el-icon v-if="selectData.name">
|
||||||
|
<Close />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon v-else>
|
||||||
|
<ArrowRight />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<el-dialog v-model="showDialog" :title="t('页面选择')" width="850px" :destroy-on-close="true" :close-on-click-modal="false">
|
||||||
|
|
||||||
|
<el-table :data="tableData.data" size="large" v-loading="tableData.loading" ref="timeListTableRef" max-height="400">
|
||||||
|
<template #empty>
|
||||||
|
<span>{{ !tableData.loading ? t('emptyData') : '' }}</span>
|
||||||
|
</template>
|
||||||
|
<el-table-column min-width="7%">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-checkbox v-model="row.checked" @change="handleCheckChange($event,row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="page_title" :label="t('页面名称')" min-width="25%" />
|
||||||
|
<el-table-column prop="type_name" :label="t('页面类型')" min-width="25%" />
|
||||||
|
<el-table-column prop="url" :label="t('页面路径')" min-width="25%" />
|
||||||
|
</el-table>
|
||||||
|
<div class="mt-[16px] flex">
|
||||||
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.limit"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper" :total="tableData.total"
|
||||||
|
@size-change="loadList()" @current-change="loadList" />
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { t } from '@/lang'
|
||||||
|
import { ref, reactive, nextTick,computed } from 'vue'
|
||||||
|
import { FormInstance, ElMessage } from "element-plus";
|
||||||
|
import { getPageLink } from '@/app/api/diy'
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
id: 0,
|
||||||
|
name: '',
|
||||||
|
parent: '',
|
||||||
|
title: '',
|
||||||
|
url: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ignore: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
selectData.value = {
|
||||||
|
id: 0,
|
||||||
|
name: '',
|
||||||
|
parent: '',
|
||||||
|
title: '',
|
||||||
|
url: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'confirm', 'success'])
|
||||||
|
|
||||||
|
const selectData: any = computed({
|
||||||
|
get() {
|
||||||
|
return prop.modelValue
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
|
const tableData = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
total: 0,
|
||||||
|
loading: true,
|
||||||
|
data: [],
|
||||||
|
searchParam: {
|
||||||
|
name: '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const timeListTableRef = ref()
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const show = () => {
|
||||||
|
showDialog.value = true
|
||||||
|
loadList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取商品列表
|
||||||
|
*/
|
||||||
|
const loadList = (page: number = 1) => {
|
||||||
|
tableData.loading = true
|
||||||
|
tableData.page = page
|
||||||
|
getPageLink({
|
||||||
|
page: tableData.page,
|
||||||
|
limit: tableData.limit,
|
||||||
|
...tableData.searchParam
|
||||||
|
}).then(res => {
|
||||||
|
tableData.loading = false
|
||||||
|
tableData.data = res.data.data
|
||||||
|
tableData.data.forEach((item: any) => {
|
||||||
|
item.checked = item.id == selectData.value.id
|
||||||
|
|
||||||
|
})
|
||||||
|
tableData.total = res.data.total
|
||||||
|
setTimesSelected();
|
||||||
|
}).catch(() => {
|
||||||
|
tableData.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadList()
|
||||||
|
const handleCheckChange = (isSelect: any, row: any) => {
|
||||||
|
if (isSelect) {
|
||||||
|
selectData.value.id = row.id
|
||||||
|
} else {
|
||||||
|
selectData.value.id = 0 // 未选中,移除当前
|
||||||
|
}
|
||||||
|
setTimesSelected()
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 表格设置选中状态
|
||||||
|
const setTimesSelected = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
for (let i = 0; i < tableData.data.length; i++) {
|
||||||
|
tableData.data[i].checked = false
|
||||||
|
if (selectData.value.id == tableData.data[i].id) {
|
||||||
|
tableData.data[i].checked = true
|
||||||
|
Object.assign(selectData.value, tableData.data[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
formEl.resetFields()
|
||||||
|
|
||||||
|
loadList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
if (selectData.value.id == 0) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: `${ t('请选择页面') }`
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectData.value ={
|
||||||
|
id:selectData.value.id,
|
||||||
|
name:selectData.value.name,
|
||||||
|
parent:selectData.value.parent,
|
||||||
|
title:selectData.value.title,
|
||||||
|
url:selectData.value.url
|
||||||
|
}
|
||||||
|
showDialog.value = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
showDialog,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.form-item-wrap {
|
||||||
|
margin-right: 10px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
|
||||||
|
&.last-child {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -50,15 +50,19 @@ import { img } from '@/utils/common'
|
|||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const channel = ref('h5')
|
const channel = ref('h5')
|
||||||
|
|
||||||
|
// H5相关变量
|
||||||
const wapUrl = ref('')
|
const wapUrl = ref('')
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
const wapImage = ref('')
|
const wapImage = ref('')
|
||||||
const wapPreview = ref('')
|
const wapPreview = ref('')
|
||||||
const pageName = ref('')
|
|
||||||
|
// 小程序相关变量
|
||||||
const weappData = reactive({
|
const weappData = reactive({
|
||||||
path: ''
|
path: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 基础配置获取
|
||||||
getUrl().then((res: any) => {
|
getUrl().then((res: any) => {
|
||||||
wapUrl.value = res.data.wap_url
|
wapUrl.value = res.data.wap_url
|
||||||
|
|
||||||
@ -66,42 +70,53 @@ getUrl().then((res: any) => {
|
|||||||
if (import.meta.env.MODE == 'production') return
|
if (import.meta.env.MODE == 'production') return
|
||||||
|
|
||||||
wapDomain.value = res.data.wap_domain
|
wapDomain.value = res.data.wap_domain
|
||||||
|
|
||||||
// env文件配置过wap域名
|
// env文件配置过wap域名
|
||||||
if (wapDomain.value) {
|
if (wapDomain.value) {
|
||||||
wapUrl.value = wapDomain.value + '/wap'
|
wapUrl.value = wapDomain.value + '/wap'
|
||||||
}
|
}
|
||||||
|
|
||||||
const wapDomainStorage = storage.get('wap_domain')
|
const wapDomainStorage = storage.get('wap_domain')
|
||||||
if (wapDomainStorage) {
|
if (wapDomainStorage) {
|
||||||
wapUrl.value = wapDomainStorage
|
wapUrl.value = wapDomainStorage
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// **生成H5二维码**
|
// 生成H5二维码(支持多参数)
|
||||||
const generateH5QRCode = () => {
|
const generateH5QRCode = () => {
|
||||||
wapPreview.value = `${ wapUrl.value }${ pageName.value }`
|
// 处理参数为URL格式
|
||||||
QRCode.toDataURL(wapPreview.value, { errorCorrectionLevel: 'L', margin: 0, width: 120 }).then(url => {
|
const queryStr = params.value
|
||||||
|
.map(item => `${encodeURIComponent(item.name)}=${encodeURIComponent(item.value)}`)
|
||||||
|
.join('&')
|
||||||
|
|
||||||
|
// 拼接完整H5链接
|
||||||
|
wapPreview.value = `${wapUrl.value}${pagePath.value}${queryStr ? '?' + queryStr : ''}`
|
||||||
|
|
||||||
|
// 生成二维码
|
||||||
|
QRCode.toDataURL(wapPreview.value, {
|
||||||
|
errorCorrectionLevel: 'L',
|
||||||
|
margin: 0,
|
||||||
|
width: 120
|
||||||
|
}).then(url => {
|
||||||
wapImage.value = url
|
wapImage.value = url
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// **获取小程序二维码**
|
// 获取小程序二维码(支持多参数)
|
||||||
const fetchWeAppQRCode = () => {
|
const fetchWeAppQRCode = () => {
|
||||||
// 去掉 page 参数前面的 '/'
|
// 处理页面路径(去掉前缀的 '/')
|
||||||
if (pagePath.value.startsWith('/')) {
|
let page = pagePath.value
|
||||||
pagePath.value = pagePath.value.slice(1);
|
if (page.startsWith('/')) {
|
||||||
|
page = page.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 调用接口获取小程序二维码
|
||||||
getQrcode({
|
getQrcode({
|
||||||
page: pagePath.value, // 传递页面路径
|
page: page,
|
||||||
folder: folder.value, // 传递模块目录
|
folder: folder.value,
|
||||||
params: [
|
// 转换参数格式为接口要求的 { column_name, column_value }
|
||||||
{
|
params: params.value.map(item => ({
|
||||||
column_name: columnName.value,
|
column_name: item.name,
|
||||||
column_value: columnValue.value
|
column_value: item.value
|
||||||
}
|
}))
|
||||||
]
|
|
||||||
}).then((res: any) => {
|
}).then((res: any) => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
weappData.path = res.data.weapp_path
|
weappData.path = res.data.weapp_path
|
||||||
@ -109,24 +124,30 @@ const fetchWeAppQRCode = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义变量存储传入的数据
|
// 核心参数存储
|
||||||
const pagePath = ref("")
|
const pagePath = ref("") // 页面路径(如 "/addon/pintuan/pages/goods/detail")
|
||||||
const columnName = ref("")
|
const params = ref<Array<{name: string; value: string | number}>>([]) // 多参数数组
|
||||||
const columnValue = ref("")
|
const titleName = ref("") // 弹窗标题
|
||||||
const titleName = ref("")
|
const folder: any = ref("") // 模块目录
|
||||||
const folder: any = ref("")
|
|
||||||
|
|
||||||
// **显示对话框**
|
// 显示弹窗(对外暴露的方法)
|
||||||
const show = (page: string, column: string, value: string, title: string, dir: string) => {
|
const show = (
|
||||||
|
page: string,
|
||||||
|
paramsArr: Array<{name: string; value: string | number}>,
|
||||||
|
title: string,
|
||||||
|
dir: string
|
||||||
|
) => {
|
||||||
|
// 重置参数
|
||||||
pagePath.value = page
|
pagePath.value = page
|
||||||
columnName.value = column
|
params.value = paramsArr
|
||||||
columnValue.value = value
|
|
||||||
titleName.value = title
|
titleName.value = title
|
||||||
folder.value = dir
|
folder.value = dir
|
||||||
pageName.value = `${ pagePath.value }?${ columnName.value }=${ columnValue.value }`
|
|
||||||
|
// 生成二维码
|
||||||
generateH5QRCode()
|
generateH5QRCode()
|
||||||
fetchWeAppQRCode()
|
fetchWeAppQRCode()
|
||||||
|
|
||||||
|
// 显示弹窗
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,3 +177,4 @@ defineExpose({
|
|||||||
show
|
show
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex border-t border-b main-wrap border-color w-full attachment-wrap" :class="scene == 'select' ? 'h-[40vh]' : 'h-full'">
|
<div class="flex border-t border-b main-wrap border-color w-full attachment-wrap" :class="scene == 'select' ? 'h-[546px]' : 'h-full'">
|
||||||
|
|
||||||
<!-- 分组 -->
|
<!-- 分组 -->
|
||||||
<div class="group-wrap w-[180px] p-[15px] h-full border-r border-color flex flex-col">
|
<div class="group-wrap w-[180px] p-[15px] h-full border-r border-color flex flex-col">
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>{{ item.real_name }}</template>
|
<template #content>{{ item.real_name }}</template>
|
||||||
<div class="truncate my-[10px] cursor-pointer text-base flex-1 text-center">{{ item.real_name }}</div>
|
<div class="truncate my-[10px] cursor-pointer text-base flex-1 text-center h-[20px] leading-[20px]">{{ item.real_name }}</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<!-- 图片操作 -->
|
<!-- 图片操作 -->
|
||||||
<el-dropdown :hide-on-click="false" v-if="scene == 'attachment'" class="attachment-action hidden ">
|
<el-dropdown :hide-on-click="false" v-if="scene == 'attachment'" class="attachment-action hidden ">
|
||||||
@ -232,12 +232,12 @@ const attachment: Record<string, any> = reactive({
|
|||||||
loading: true,
|
loading: true,
|
||||||
page: 1,
|
page: 1,
|
||||||
total: 0,
|
total: 0,
|
||||||
limit: prop.scene == 'select' ? 10 : 20,
|
limit: prop.scene == 'select' ? 18 : 20,
|
||||||
data: []
|
data: []
|
||||||
})
|
})
|
||||||
|
|
||||||
if (prop.scene == 'select') {
|
if (prop.scene == 'select') {
|
||||||
attachment.limit = 10
|
attachment.limit = 18
|
||||||
if (prop.type == 'icon') {
|
if (prop.type == 'icon') {
|
||||||
attachment.limit = 20
|
attachment.limit = 20
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<span @click="openDialog" class="cursor-pointer">
|
<span @click="openDialog" class="cursor-pointer">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</span>
|
</span>
|
||||||
<el-dialog v-model="showDialog" :title="t('upload.select' + type)" width="60%" class="attachment-dialog" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="t('upload.select' + type)" width="920px" class="attachment-dialog" :destroy-on-close="true">
|
||||||
|
|
||||||
<attachment :limit="limit" :type="type" ref="attachmentRef" />
|
<attachment :limit="limit" :type="type" ref="attachmentRef" />
|
||||||
|
|
||||||
|
|||||||
74
admin/src/components/upload-audio/index.vue
Normal file
74
admin/src/components/upload-audio/index.vue
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<el-upload v-bind="upload" class="upload-file">
|
||||||
|
<slot>
|
||||||
|
<el-button type="primary">{{ t('上传音频') }}</el-button>
|
||||||
|
</slot>
|
||||||
|
</el-upload>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { t } from '@/lang'
|
||||||
|
import { getToken } from '@/utils/common'
|
||||||
|
import { UploadFile, ElMessage } from 'element-plus'
|
||||||
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
type: String,
|
||||||
|
default: 'sys/audio'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const value = computed({
|
||||||
|
get () {
|
||||||
|
return prop.modelValue
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const upload: Record<string, any> = {
|
||||||
|
action: `${import.meta.env.VITE_APP_BASE_URL}/${prop.api}`,
|
||||||
|
showFileList: false,
|
||||||
|
headers: {},
|
||||||
|
accept: 'audio/*,.mp3,.wav,.ogg,.m4a,.flac,.aac,.wma',
|
||||||
|
beforeUpload: (file: File) => {
|
||||||
|
const audioTypes = ['audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a', 'audio/flac', 'audio/aac', 'audio/wma', 'audio/mpeg']
|
||||||
|
const audioExtensions = ['.mp3', '.wav', '.ogg', '.m4a', '.flac', '.aac', '.wma']
|
||||||
|
|
||||||
|
const isAudio = audioTypes.includes(file.type) || audioExtensions.some(ext => file.name.toLowerCase().endsWith(ext))
|
||||||
|
|
||||||
|
if (!isAudio) {
|
||||||
|
ElMessage({ message: t('请上传音频文件'), type: 'error' })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
onSuccess: (response: any, uploadFile: UploadFile) => {
|
||||||
|
if (response.code != undefined && response.code != 1) {
|
||||||
|
ElMessage({ message: response.msg, type: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
value.value = response.data.url
|
||||||
|
ElMessage({ message: t('upload.success'), type: 'success' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
upload.headers[import.meta.env.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken()
|
||||||
|
upload.headers[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = storage.get('siteId') || 0
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.upload-file .el-upload {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -6,7 +6,7 @@
|
|||||||
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
||||||
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon.png" alt="" object-fit="contain"></div>
|
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon-one.png" alt="" object-fit="contain"></div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
||||||
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon.png" alt="" object-fit="contain"></div>
|
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon-one.png" alt="" object-fit="contain"></div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
||||||
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon.png" alt="" object-fit="contain"></div>
|
<div class="flex justify-center items-center w-full h-[40px]"><img class="max-w-[40px]" src="@/app/assets/images/icon-addon-one.png" alt="" object-fit="contain"></div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -15,7 +15,8 @@
|
|||||||
<!-- 面包屑导航 -->
|
<!-- 面包屑导航 -->
|
||||||
<div class="flex items-center h-full pl-[10px]">
|
<div class="flex items-center h-full pl-[10px]">
|
||||||
<el-breadcrumb separator="/">
|
<el-breadcrumb separator="/">
|
||||||
<el-breadcrumb-item v-for="(route, index) in breadcrumb" :to="route.path" class="inter" :key="index">{{route.meta.title }}</el-breadcrumb-item>
|
<!-- :to="route.path" class="inter" 这种修改方式导致部分跳转不对,需要重新调整菜单才可以 -->
|
||||||
|
<el-breadcrumb-item v-for="(route, index) in breadcrumb" :key="index">{{route.meta.title }}</el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="w-100 h-screen">
|
<el-container class="w-100 h-screen">
|
||||||
<el-main class="flex p-0">
|
<el-main class="flex p-0">
|
||||||
<div class="one-menu w-[124px] h-screen px-[8px] bg-[#282c34]">
|
<div class="one-menu w-[124px] h-screen px-[8px] bg-[#1c2233]">
|
||||||
<el-header class="logo-wrap">
|
<el-header class="logo-wrap">
|
||||||
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
<div class="logo flex items-center m-auto h-[64px]" v-if="!systemStore.menuIsCollapse">
|
||||||
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="flex justify-center items-center w-full h-[40px]">
|
<div class="flex justify-center items-center w-full h-[40px]">
|
||||||
<img class="max-w-[40px]" src="@/app/assets/images/icon-addon.png" alt="" object-fit="contain">
|
<img class="max-w-[40px]" src="@/app/assets/images/icon-addon-one.png" alt="" object-fit="contain">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@ -38,8 +38,8 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-scrollbar v-if="twoMenuData.length" class="two-menu w-[140px]">
|
<el-scrollbar v-if="twoMenuData.length" class="two-menu w-[132px]">
|
||||||
<div class="w-[140px] h-[64px] flex items-center justify-center text-[16px] border-b-[1px] border-solid border-[var(--el-border-color-lighter)]">
|
<div class="w-[132px] h-[64px] flex items-center justify-center text-[16px] border-b-[1px] border-solid border-[var(--el-border-color-lighter)]">
|
||||||
{{ route.matched[1].meta.title }}
|
{{ route.matched[1].meta.title }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -161,6 +161,18 @@ onMounted(async () => {
|
|||||||
await getMarketingList()
|
await getMarketingList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 让二级菜单默认展开
|
||||||
|
const menuOption = ref([])
|
||||||
|
const secondMenuShowWayFn = () => {
|
||||||
|
menuOption.value = []
|
||||||
|
if (oneMenuActive.value !== 'active' && oneMenuActive.value !== 'addon' && twoMenuData.value && Object.values(twoMenuData.value).length) {
|
||||||
|
const data = cloneDeep(twoMenuData.value)
|
||||||
|
for (const key in data) {
|
||||||
|
menuOption.value.push(data[key].name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
// if (!appList.value || loading.value) return; // 确保数据加载完毕
|
// if (!appList.value || loading.value) return; // 确保数据加载完毕
|
||||||
const addonKeys = appList.value?.addon?.list?.map(item => item.key) ?? []
|
const addonKeys = appList.value?.addon?.list?.map(item => item.key) ?? []
|
||||||
@ -199,10 +211,10 @@ watchEffect(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
secondMenuShowWayFn()
|
||||||
})
|
})
|
||||||
|
|
||||||
// watch(route, () => {
|
// watch(route, () => {
|
||||||
// console.log(route.matched);
|
|
||||||
|
|
||||||
// if (route.meta.attr != '') {
|
// if (route.meta.attr != '') {
|
||||||
// oneMenuActive.value = route.matched[2].name
|
// oneMenuActive.value = route.matched[2].name
|
||||||
@ -230,18 +242,6 @@ watchEffect(() => {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }, { immediate: true })
|
// }, { immediate: true })
|
||||||
|
|
||||||
// 让二级菜单默认展开
|
|
||||||
const menuOption = ref([])
|
|
||||||
watch(twoMenuData.value, () => {
|
|
||||||
menuOption.value = []
|
|
||||||
if (twoMenuData.value && Object.values(twoMenuData.value).length) {
|
|
||||||
const data = cloneDeep(twoMenuData.value)
|
|
||||||
for (const key in data) {
|
|
||||||
menuOption.value.push(data[key].name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, { immediate: true })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -259,8 +259,8 @@ watch(twoMenuData.value, () => {
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--el-color-primary);
|
color: #ffffff;
|
||||||
background-color: transparent;
|
background-color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
@ -287,14 +287,14 @@ watch(twoMenuData.value, () => {
|
|||||||
.two-menu {
|
.two-menu {
|
||||||
|
|
||||||
.aside-menu:not(.el-menu--collapse) {
|
.aside-menu:not(.el-menu--collapse) {
|
||||||
width: 140px;
|
width: 132px;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|
||||||
.el-menu-item {
|
.el-menu-item {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
margin: 0 8px 4px;
|
margin: 0 12px 4px;
|
||||||
padding: 0 8px !important;
|
padding: 0 !important;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@ -318,7 +318,7 @@ watch(twoMenuData.value, () => {
|
|||||||
.el-sub-menu__title {
|
.el-sub-menu__title {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
margin: 0 8px 4px;
|
margin: 0 8px 4px;
|
||||||
padding-left: 8px;
|
padding-left: 0;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@ -339,6 +339,9 @@ watch(twoMenuData.value, () => {
|
|||||||
|
|
||||||
.el-menu-item {
|
.el-menu-item {
|
||||||
padding-left: 20px !important;
|
padding-left: 20px !important;
|
||||||
|
span{
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,8 @@
|
|||||||
<!-- 面包屑导航 -->
|
<!-- 面包屑导航 -->
|
||||||
<div class="flex items-center h-full pl-[10px] hidden-xs-only">
|
<div class="flex items-center h-full pl-[10px] hidden-xs-only">
|
||||||
<el-breadcrumb separator="/">
|
<el-breadcrumb separator="/">
|
||||||
<el-breadcrumb-item v-for="(route, index) in breadcrumb" :key="index" :to="route.path" class="inter">{{route.meta.title }}</el-breadcrumb-item>
|
<!-- :to="route.path" class="inter" 这种修改方式导致部分跳转不对,需要重新调整菜单才可以 -->
|
||||||
|
<el-breadcrumb-item v-for="(route, index) in breadcrumb" :key="index">{{route.meta.title }}</el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -238,7 +239,7 @@ const refreshRouter = () => {
|
|||||||
|
|
||||||
// 面包屑导航
|
// 面包屑导航
|
||||||
const breadcrumb = computed(() => {
|
const breadcrumb = computed(() => {
|
||||||
console.log(route.matched)
|
// console.log(route.matched)
|
||||||
const matched = route.matched.filter(item => { return item.meta.title })
|
const matched = route.matched.filter(item => { return item.meta.title })
|
||||||
if (matched[0] && matched[0].path == '/') matched.splice(0, 1)
|
if (matched[0] && matched[0].path == '/') matched.splice(0, 1)
|
||||||
return matched
|
return matched
|
||||||
|
|||||||
@ -67,7 +67,7 @@ const usePosterStore = defineStore('poster', {
|
|||||||
height: 60,
|
height: 60,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
minHeight: 44,
|
minHeight: 44,
|
||||||
fontFamily: 'static/font/SourceHanSansCN-Regular.ttf',
|
fontFamily: 'static/font/PingFang-Medium.ttf',
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
weight: false,
|
weight: false,
|
||||||
lineHeight: 10,
|
lineHeight: 10,
|
||||||
|
|||||||
@ -19,12 +19,12 @@ html, body {
|
|||||||
// 海报价格字体
|
// 海报价格字体
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'poster_price_font';
|
font-family: 'poster_price_font';
|
||||||
src: url('./font/price.ttf') format('truetype');
|
src: url('./font/OPLUSSANS3-REGULAR.ttf') format('truetype');
|
||||||
}
|
}
|
||||||
// 海报价格字体
|
// 海报价格字体
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'poster_default_font';
|
font-family: 'poster_default_font';
|
||||||
src: url('./font/SourceHanSansCN-Regular.ttf') format('truetype');
|
src: url('./font/PingFang-Medium.ttf') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 以下最新,请勿改动 2024.5.25
|
// 以下最新,请勿改动 2024.5.25
|
||||||
|
|||||||
BIN
admin/src/styles/font/OPLUSSANS3-REGULAR.TTF
Normal file
BIN
admin/src/styles/font/OPLUSSANS3-REGULAR.TTF
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -83,7 +83,7 @@ class Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送get请求
|
* 发送post请求
|
||||||
* @param url
|
* @param url
|
||||||
* @param data
|
* @param data
|
||||||
* @param config
|
* @param config
|
||||||
@ -94,7 +94,7 @@ class Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送get请求
|
* 发送put请求
|
||||||
* @param url
|
* @param url
|
||||||
* @param data
|
* @param data
|
||||||
* @param config
|
* @param config
|
||||||
@ -105,7 +105,7 @@ class Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送get请求
|
* 发送delete请求
|
||||||
* @param url
|
* @param url
|
||||||
* @param config
|
* @param config
|
||||||
* @returns
|
* @returns
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user