mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2025-12-11 09:32: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 {
|
||||
Attachment: typeof import('./src/components/upload-attachment/attachment.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']
|
||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||
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']
|
||||
SpreadPopup: typeof import('./src/components/spread-popup/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']
|
||||
UploadImage: typeof import('./src/components/upload-image/index.vue')['default']
|
||||
UploadVideo: typeof import('./src/components/upload-video/index.vue')['default']
|
||||
|
||||
@ -157,7 +157,7 @@ UE.I18N['zh-cn'] = {
|
||||
'elementPathTip': "元素路径",
|
||||
'wordCountTip': "字数统计",
|
||||
'wordCountMsg': '{#count} / {#leave}',
|
||||
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值,服务器可能拒绝保存!</span>',
|
||||
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值!</span>',
|
||||
'ok': "确认",
|
||||
'cancel': "取消",
|
||||
'closeDialog': "关闭对话框",
|
||||
|
||||
@ -13,6 +13,7 @@ import useAppStore from '@/stores/modules/app'
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import { setThemeColor } from '@/utils/common'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { getSiteAllowChange} from '@/app/api/site'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
@ -24,7 +25,14 @@ systemStore.getWebsiteInfo()
|
||||
systemStore.getWebsiteLayout()
|
||||
|
||||
const toggleDark = useToggle(useDark())
|
||||
|
||||
const getSiteAllowChangeFn = ()=>{
|
||||
getSiteAllowChange().then(({data})=>{
|
||||
let isAllowChange = data.is_allow ? true : false
|
||||
localStorage.setItem('isAllowChange',isAllowChange.toString())
|
||||
})
|
||||
|
||||
}
|
||||
getSiteAllowChangeFn()
|
||||
watch(route, () => {
|
||||
useAppStore().$patch(state => {
|
||||
state.route = route
|
||||
@ -39,3 +47,9 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<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')
|
||||
}
|
||||
|
||||
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 })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自定义页面选择列表
|
||||
*/
|
||||
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>) {
|
||||
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 }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取核销详情
|
||||
* @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="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">
|
||||
<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>
|
||||
<div class="image-slot">
|
||||
<img class="w-[40px] h-[40px]" src="@/app/assets/images/index/app_default.png" />
|
||||
@ -65,7 +65,13 @@ getMarketingList()
|
||||
|
||||
const toLink = (item: any) => {
|
||||
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 {
|
||||
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-item :label="t('selectStyle')" class="flex">
|
||||
<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 />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
@ -57,7 +57,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showBlockStyle">{{ diyStore.editComponent.blockStyle.title }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showBlockStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<el-form label-width="100px" class="px-[10px]" @submit.prevent>
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<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 />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { img } from '@/utils/common'
|
||||
@ -330,6 +330,10 @@ const handleHeight = (isCalcHeight: boolean = false) => {
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => diyStore.editComponent.list, () => {
|
||||
handleHeight(true)
|
||||
}, { deep: true })
|
||||
|
||||
defineExpose({})
|
||||
</script>
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
|
||||
@ -510,12 +510,12 @@ const spreadPopupRef = ref(null)
|
||||
|
||||
const spreadEvent = (data: any) => {
|
||||
const pagePath = '/app/pages/index/diy_form'
|
||||
const columnName = 'form_id'
|
||||
const columnValue = data.form_id
|
||||
const paramsArr = [
|
||||
{ name: 'form_id', value: data.form_id },
|
||||
];
|
||||
const title = '表单推广'
|
||||
const folder = 'diy_form'
|
||||
|
||||
spreadPopupRef.value?.show(pagePath, columnName, columnValue, title, folder)
|
||||
spreadPopupRef.value?.show(pagePath, paramsArr, title, folder);
|
||||
}
|
||||
|
||||
// 表单提交成功页弹出框
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<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="relative" v-if="formData">
|
||||
<div class="flex mb-[20px] justify-between text-[15px]">
|
||||
@ -152,8 +152,4 @@ defineExpose({
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -3,11 +3,16 @@
|
||||
<!-- <div class="flex justify-between items-center">
|
||||
<layoutHeader></layoutHeader>
|
||||
</div> -->
|
||||
<div class="flex justify-between items-center py-[24px] pl-[62px] pr-[64px] home-head">
|
||||
<div class="flex items-center" v-if="webConfig">
|
||||
<img class="w-[32x] h-[32px] rounded-full" v-if="webConfig.icon" :src="img(webConfig.icon)" alt="">
|
||||
<img class="w-[32x] h-[32px] rounded-full" v-else src="@/app/assets/images/icon-addon.png" alt="">
|
||||
<span class="ml-[10px] text-[16px] font-bold">{{webConfig.site_name}}</span>
|
||||
<div class="flex justify-between items-center py-[24px] pr-[64px] home-head">
|
||||
<div class="flex items-center w-[219px] justify-center" v-if="webConfig">
|
||||
<div class="max-w-[82px] h-[40px] overflow-hidden">
|
||||
<el-image class="h-[40px]" :src="img(webConfig.icon)" fit="contain">
|
||||
<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 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">
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<div class="flex h-[156px]">
|
||||
<div class="w-full h-full ">
|
||||
<el-carousel :interval="3000" height="156px" class="rounded-[6px]">
|
||||
<el-carousel-item >
|
||||
<!-- <el-carousel-item >
|
||||
<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">
|
||||
</div>
|
||||
@ -21,7 +21,14 @@
|
||||
<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">
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
@ -248,7 +255,7 @@
|
||||
import { ref, watch ,onMounted} from 'vue'
|
||||
import { t } from '@/lang'
|
||||
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 { getFrameworkNewVersion } from '@/app/api/module'
|
||||
import { getWebCopyright } from '@/app/api/sys'
|
||||
@ -302,12 +309,20 @@ const appList = ref<any>([])
|
||||
const getAppIndexFn = () => {
|
||||
loading.value = true
|
||||
getAppIndex().then((res) => {
|
||||
appList.value = res.data.data
|
||||
console.log(res)
|
||||
appList.value = res.data
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
getAppIndexFn()
|
||||
|
||||
const bannerlistr = ref<any>([])
|
||||
const getAdvListFn = () => {
|
||||
getAdvList().then((res) => {
|
||||
console.log(res.data)
|
||||
bannerlistr.value = res.data
|
||||
})
|
||||
}
|
||||
getAdvListFn()
|
||||
const getInfoFn = () => {
|
||||
if (copyright.value.copyright_desc) {
|
||||
dialogVisible.value = true
|
||||
@ -442,6 +457,9 @@ const toTypeLink = (url: any,type: any) => {
|
||||
const toApplication = () => {
|
||||
window.open('https://www.niucloud.com/app')
|
||||
}
|
||||
const toApplicationurl = (item: any) => {
|
||||
window.open(item.url)
|
||||
}
|
||||
const toApplicationDetail = (item: any) => {
|
||||
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">
|
||||
<template #error>
|
||||
<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>
|
||||
</template>
|
||||
</el-image>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<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">
|
||||
<el-tabs v-model="activeName" class="pb-[10px]" @tab-change="handleClick">
|
||||
<el-tab-pane label="核销信息" name="verifyInfo" />
|
||||
@ -28,7 +28,7 @@
|
||||
<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]">
|
||||
{{ verifyData.member ? verifyData.member.nickname : '--' }}
|
||||
{{ (verifyData.is_admin == 1 ? '后台核销' : verifyData.member?.nickname) || '--' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
@ -156,8 +156,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -39,15 +39,17 @@
|
||||
<template #empty>
|
||||
<span>{{ !recordTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<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">
|
||||
<el-table-column :label="t('verifyTime')" min-width="180" align="left" :show-overflow-tooltip="true">
|
||||
<template #default="{ row }">
|
||||
{{ row.create_time || '' }}
|
||||
</template>
|
||||
</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 :label="t('operation')" align="right" fixed="right" width="100">
|
||||
<template #default="{ row }">
|
||||
@ -89,7 +91,7 @@ const recordTable = reactive({
|
||||
data: [],
|
||||
searchParam: {
|
||||
code: '',
|
||||
type: '',
|
||||
type: route.query.type || '',
|
||||
verifier_member_id: '',
|
||||
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>
|
||||
<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="bg-page py-[20px] pr-[30px] relative flex">
|
||||
<div class="member-info w-[250px]">
|
||||
@ -375,17 +375,20 @@ const getMemberInfoFn = async (bool=false) => {
|
||||
Object.keys(data).forEach((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) {
|
||||
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||
return item.label_id
|
||||
})
|
||||
|
||||
|
||||
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||
return item.label_name
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
loading.value = false
|
||||
} else {
|
||||
loading.value = false
|
||||
}
|
||||
@ -406,8 +409,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
||||
if (prop.value.weight) {
|
||||
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;'
|
||||
}
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
|
||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
||||
if (prop.value.weight) {
|
||||
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;'
|
||||
}
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
|
||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
||||
if (prop.value.weight) {
|
||||
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;'
|
||||
}
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
|
||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
||||
if (prop.value.weight) {
|
||||
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;`;
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
|
||||
@ -6,7 +6,13 @@
|
||||
<span class="text-page-title">{{ pageName }}</span>
|
||||
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">{{ t('添加海报') }}</el-button>
|
||||
</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-form :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
|
||||
<el-form-item :label="t('posterName')" prop="name">
|
||||
@ -103,7 +109,7 @@ import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
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'
|
||||
|
||||
const router = useRouter()
|
||||
@ -281,6 +287,16 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
||||
formEl.resetFields()
|
||||
loadPosterPageList()
|
||||
}
|
||||
const isImagick = ref(false)
|
||||
// 判断是否安装imagemagick扩展
|
||||
const checkImagickFn = () => {
|
||||
checkImagick().then((res:any) => {
|
||||
console.log(res)
|
||||
isImagick.value = res.data
|
||||
|
||||
})
|
||||
}
|
||||
checkImagickFn()
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
<el-form-item :label="t('createTime')">
|
||||
<div class="input-width"> {{ formData.create_time }} </div>
|
||||
</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>
|
||||
|
||||
<template #footer>
|
||||
@ -55,7 +59,9 @@ const initialFormData = {
|
||||
name: '',
|
||||
nickname: '',
|
||||
mobile: '',
|
||||
sms_type_name: ''
|
||||
sms_type_name: '',
|
||||
status:'',
|
||||
result:''
|
||||
}
|
||||
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">
|
||||
<template #error>
|
||||
<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>
|
||||
</template>
|
||||
</el-image>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3>
|
||||
|
||||
<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-[110px] text-center">{{ t('onState') }}</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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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"/>
|
||||
</template>
|
||||
@ -210,6 +209,6 @@ const cancelFn = () => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-item-border {
|
||||
@apply border-b border-[var(--el-border-color)];
|
||||
@apply border-b border-[var(--el-border-color-lighter)];
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -77,8 +77,80 @@
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
|
||||
<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__inner-wrapper">
|
||||
@ -169,7 +241,7 @@
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
||||
@size-change="loadSiteList()" @current-change="loadSiteList" />
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
</el-card>
|
||||
<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 } })
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 编辑站点详情
|
||||
* @param data
|
||||
@ -687,8 +757,8 @@ const confirmInit = () => {
|
||||
:deep(.setting-card .el-card__body){
|
||||
padding: 0 !important;
|
||||
}
|
||||
:deep(.el-scrollbar__view){
|
||||
margin-bottom: 53px !important;
|
||||
}
|
||||
// :deep(.el-scrollbar__view){
|
||||
// margin-bottom: 53px !important;
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
||||
@ -67,16 +67,53 @@
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { img, setTablePageStorage } from '@/utils/common'
|
||||
import { t } from '@/lang'
|
||||
import { getGenerateTableList, deleteGenerateTable, generateCreate, generatePreview, generatorCheckFile, getAddonDevelop } from '@/app/api/tools'
|
||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
@ -251,6 +288,27 @@ const listToTree = (arr:any) => {
|
||||
}
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -26,13 +26,13 @@
|
||||
<div class="flex justify-between">
|
||||
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
|
||||
<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 v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<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="1" />
|
||||
<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 channel = ref('h5')
|
||||
|
||||
// H5相关变量
|
||||
const wapUrl = ref('')
|
||||
const wapDomain = ref('')
|
||||
const wapImage = ref('')
|
||||
const wapPreview = ref('')
|
||||
const pageName = ref('')
|
||||
|
||||
// 小程序相关变量
|
||||
const weappData = reactive({
|
||||
path: ''
|
||||
})
|
||||
|
||||
// 基础配置获取
|
||||
getUrl().then((res: any) => {
|
||||
wapUrl.value = res.data.wap_url
|
||||
|
||||
@ -66,42 +70,53 @@ getUrl().then((res: any) => {
|
||||
if (import.meta.env.MODE == 'production') return
|
||||
|
||||
wapDomain.value = res.data.wap_domain
|
||||
|
||||
// env文件配置过wap域名
|
||||
if (wapDomain.value) {
|
||||
wapUrl.value = wapDomain.value + '/wap'
|
||||
}
|
||||
|
||||
const wapDomainStorage = storage.get('wap_domain')
|
||||
if (wapDomainStorage) {
|
||||
wapUrl.value = wapDomainStorage
|
||||
}
|
||||
})
|
||||
|
||||
// **生成H5二维码**
|
||||
// 生成H5二维码(支持多参数)
|
||||
const generateH5QRCode = () => {
|
||||
wapPreview.value = `${ wapUrl.value }${ pageName.value }`
|
||||
QRCode.toDataURL(wapPreview.value, { errorCorrectionLevel: 'L', margin: 0, width: 120 }).then(url => {
|
||||
// 处理参数为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
|
||||
})
|
||||
}
|
||||
|
||||
// **获取小程序二维码**
|
||||
// 获取小程序二维码(支持多参数)
|
||||
const fetchWeAppQRCode = () => {
|
||||
// 去掉 page 参数前面的 '/'
|
||||
if (pagePath.value.startsWith('/')) {
|
||||
pagePath.value = pagePath.value.slice(1);
|
||||
// 处理页面路径(去掉前缀的 '/')
|
||||
let page = pagePath.value
|
||||
if (page.startsWith('/')) {
|
||||
page = page.slice(1)
|
||||
}
|
||||
|
||||
// 调用接口获取小程序二维码
|
||||
getQrcode({
|
||||
page: pagePath.value, // 传递页面路径
|
||||
folder: folder.value, // 传递模块目录
|
||||
params: [
|
||||
{
|
||||
column_name: columnName.value,
|
||||
column_value: columnValue.value
|
||||
}
|
||||
]
|
||||
page: page,
|
||||
folder: folder.value,
|
||||
// 转换参数格式为接口要求的 { column_name, column_value }
|
||||
params: params.value.map(item => ({
|
||||
column_name: item.name,
|
||||
column_value: item.value
|
||||
}))
|
||||
}).then((res: any) => {
|
||||
if (res.data) {
|
||||
weappData.path = res.data.weapp_path
|
||||
@ -109,24 +124,30 @@ const fetchWeAppQRCode = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 定义变量存储传入的数据
|
||||
const pagePath = ref("")
|
||||
const columnName = ref("")
|
||||
const columnValue = ref("")
|
||||
const titleName = ref("")
|
||||
const folder: any = ref("")
|
||||
// 核心参数存储
|
||||
const pagePath = ref("") // 页面路径(如 "/addon/pintuan/pages/goods/detail")
|
||||
const params = ref<Array<{name: string; value: string | number}>>([]) // 多参数数组
|
||||
const titleName = 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
|
||||
columnName.value = column
|
||||
columnValue.value = value
|
||||
params.value = paramsArr
|
||||
titleName.value = title
|
||||
folder.value = dir
|
||||
pageName.value = `${ pagePath.value }?${ columnName.value }=${ columnValue.value }`
|
||||
|
||||
|
||||
// 生成二维码
|
||||
generateH5QRCode()
|
||||
fetchWeAppQRCode()
|
||||
|
||||
// 显示弹窗
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
@ -156,3 +177,4 @@ defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<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">
|
||||
@ -82,7 +82,7 @@
|
||||
<div class="flex items-center">
|
||||
<el-tooltip placement="top">
|
||||
<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-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,
|
||||
page: 1,
|
||||
total: 0,
|
||||
limit: prop.scene == 'select' ? 10 : 20,
|
||||
limit: prop.scene == 'select' ? 18 : 20,
|
||||
data: []
|
||||
})
|
||||
|
||||
if (prop.scene == 'select') {
|
||||
attachment.limit = 10
|
||||
attachment.limit = 18
|
||||
if (prop.type == 'icon') {
|
||||
attachment.limit = 20
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<span @click="openDialog" class="cursor-pointer">
|
||||
<slot></slot>
|
||||
</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" />
|
||||
|
||||
|
||||
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">
|
||||
<el-image style="width: 40px; height: 40px" :src="img(logoUrl)" fit="contain">
|
||||
<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>
|
||||
</el-image>
|
||||
</div>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<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">
|
||||
<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>
|
||||
</el-image>
|
||||
</div>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<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">
|
||||
<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>
|
||||
</el-image>
|
||||
</div>
|
||||
|
||||
@ -15,7 +15,8 @@
|
||||
<!-- 面包屑导航 -->
|
||||
<div class="flex items-center h-full pl-[10px]">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<el-container class="w-100 h-screen">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<img class="max-w-[40px]" src="@/app/assets/images/icon-addon-one.png" alt="" object-fit="contain">
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
@ -38,8 +38,8 @@
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
|
||||
<el-scrollbar v-if="twoMenuData.length" class="two-menu w-[140px]">
|
||||
<div class="w-[140px] h-[64px] flex items-center justify-center text-[16px] border-b-[1px] border-solid border-[var(--el-border-color-lighter)]">
|
||||
<el-scrollbar v-if="twoMenuData.length" class="two-menu w-[132px]">
|
||||
<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 }}
|
||||
</div>
|
||||
|
||||
@ -161,6 +161,18 @@ onMounted(async () => {
|
||||
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(() => {
|
||||
// if (!appList.value || loading.value) return; // 确保数据加载完毕
|
||||
const addonKeys = appList.value?.addon?.list?.map(item => item.key) ?? []
|
||||
@ -199,10 +211,10 @@ watchEffect(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
secondMenuShowWayFn()
|
||||
})
|
||||
|
||||
// watch(route, () => {
|
||||
// console.log(route.matched);
|
||||
|
||||
// if (route.meta.attr != '') {
|
||||
// oneMenuActive.value = route.matched[2].name
|
||||
@ -230,18 +242,6 @@ watchEffect(() => {
|
||||
// }
|
||||
// }
|
||||
// }, { 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>
|
||||
|
||||
<style lang="scss">
|
||||
@ -259,8 +259,8 @@ watch(twoMenuData.value, () => {
|
||||
border-radius: 2px;
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
background-color: transparent;
|
||||
color: #ffffff;
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
@ -287,14 +287,14 @@ watch(twoMenuData.value, () => {
|
||||
.two-menu {
|
||||
|
||||
.aside-menu:not(.el-menu--collapse) {
|
||||
width: 140px;
|
||||
width: 132px;
|
||||
padding-top: 16px;
|
||||
border: 0;
|
||||
|
||||
.el-menu-item {
|
||||
height: 36px;
|
||||
margin: 0 8px 4px;
|
||||
padding: 0 8px !important;
|
||||
margin: 0 12px 4px;
|
||||
padding: 0 !important;
|
||||
border-radius: 2px;
|
||||
|
||||
span {
|
||||
@ -318,7 +318,7 @@ watch(twoMenuData.value, () => {
|
||||
.el-sub-menu__title {
|
||||
height: 36px;
|
||||
margin: 0 8px 4px;
|
||||
padding-left: 8px;
|
||||
padding-left: 0;
|
||||
border-radius: 2px;
|
||||
|
||||
span {
|
||||
@ -339,6 +339,9 @@ watch(twoMenuData.value, () => {
|
||||
|
||||
.el-menu-item {
|
||||
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">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@ -238,7 +239,7 @@ const refreshRouter = () => {
|
||||
|
||||
// 面包屑导航
|
||||
const breadcrumb = computed(() => {
|
||||
console.log(route.matched)
|
||||
// console.log(route.matched)
|
||||
const matched = route.matched.filter(item => { return item.meta.title })
|
||||
if (matched[0] && matched[0].path == '/') matched.splice(0, 1)
|
||||
return matched
|
||||
|
||||
@ -67,7 +67,7 @@ const usePosterStore = defineStore('poster', {
|
||||
height: 60,
|
||||
minWidth: 120,
|
||||
minHeight: 44,
|
||||
fontFamily: 'static/font/SourceHanSansCN-Regular.ttf',
|
||||
fontFamily: 'static/font/PingFang-Medium.ttf',
|
||||
fontSize: 40,
|
||||
weight: false,
|
||||
lineHeight: 10,
|
||||
|
||||
@ -19,12 +19,12 @@ html, body {
|
||||
// 海报价格字体
|
||||
@font-face {
|
||||
font-family: 'poster_price_font';
|
||||
src: url('./font/price.ttf') format('truetype');
|
||||
src: url('./font/OPLUSSANS3-REGULAR.ttf') format('truetype');
|
||||
}
|
||||
// 海报价格字体
|
||||
@font-face {
|
||||
font-family: 'poster_default_font';
|
||||
src: url('./font/SourceHanSansCN-Regular.ttf') format('truetype');
|
||||
src: url('./font/PingFang-Medium.ttf') format('truetype');
|
||||
}
|
||||
|
||||
// 以下最新,请勿改动 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 data
|
||||
* @param config
|
||||
@ -94,7 +94,7 @@ class Request {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
* 发送put请求
|
||||
* @param url
|
||||
* @param data
|
||||
* @param config
|
||||
@ -105,7 +105,7 @@ class Request {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
* 发送delete请求
|
||||
* @param url
|
||||
* @param config
|
||||
* @returns
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user