This commit is contained in:
parent
5c0105e786
commit
95e1c837ed
|
|
@ -0,0 +1,6 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
//首页数据
|
||||||
|
export function getIndex() {
|
||||||
|
return request.get({ url: '/index' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view v-for="(item, index) in pages" :key="index">
|
||||||
|
<template v-if="item.name == 'search'">
|
||||||
|
<w-search :content="item.content" :styles="item.styles" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.name == 'banner'">
|
||||||
|
<w-banner :content="item.content" :styles="item.styles" />
|
||||||
|
</template>
|
||||||
|
<template v-if="item.name == 'nav'">
|
||||||
|
<w-nav :content="item.content" :styles="item.styles" />
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType } from 'vue'
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
pages: {
|
||||||
|
type: Array as PropType<any[]>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-form label-width="70px">
|
|
||||||
<el-form-item label="是否启用">
|
|
||||||
<el-radio-group v-model="content.enabled">
|
|
||||||
<el-radio :label="1">开启</el-radio>
|
|
||||||
<el-radio :label="0">停用</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="图片设置">
|
|
||||||
<div class="flex-1">
|
|
||||||
<div class="form-tips">最多添加5张,建议图片尺寸:750px*400px</div>
|
|
||||||
<del-wrap
|
|
||||||
v-for="(item, index) in content.data"
|
|
||||||
:key="index"
|
|
||||||
@close="handleDelete(index)"
|
|
||||||
class="max-w-[400px]"
|
|
||||||
>
|
|
||||||
<div class="bg-fill-light flex items-center w-full p-4 mt-4">
|
|
||||||
<material-picker v-model="item.image" upload-class="bg-body" />
|
|
||||||
<div class="ml-3 flex-1">
|
|
||||||
<el-form-item label="图片名称">
|
|
||||||
<el-input v-model="item.name" placeholder="请输入名称" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="mt-[18px]" label="图片链接">
|
|
||||||
<link-picker v-model="item.link" />
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</del-wrap>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="content.data?.length < limit">
|
|
||||||
<el-button type="primary" @click="handleAdd">添加图片</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import feedback from '@/utils/feedback'
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
const limit = 5
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
if (props.content.data?.length < limit) {
|
|
||||||
props.content.data.push({
|
|
||||||
image: '',
|
|
||||||
name: '',
|
|
||||||
link: {}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
feedback.msgError(`最多添加${limit}张图片`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleDelete = (index: number) => {
|
|
||||||
if (props.content.data?.length <= 1) {
|
|
||||||
return feedback.msgError('最少保留一张图片')
|
|
||||||
}
|
|
||||||
props.content.data.splice(index, 1)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="banner">
|
|
||||||
<div class="banner-image">
|
|
||||||
<image-contain width="100%" height="200px" :src="getImage" fit="contain" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const getImage = computed(() => {
|
|
||||||
const { data } = props.content
|
|
||||||
if (Array.isArray(data)) {
|
|
||||||
return data[0] ? data[0].image : ''
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '首页轮播图',
|
|
||||||
name: 'banner',
|
|
||||||
content: {
|
|
||||||
enabled: 1,
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
image: '',
|
|
||||||
name: '',
|
|
||||||
link: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-form label-width="90px">
|
|
||||||
<el-form-item label="客服标题">
|
|
||||||
<el-input class="w-[400px]" v-model="content.title" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="服务时间">
|
|
||||||
<el-input class="w-[400px]" v-model="content.time" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="联系电话">
|
|
||||||
<el-input class="w-[400px]" v-model="content.mobile" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="客服二维码">
|
|
||||||
<div>
|
|
||||||
<material-picker v-model="content.qrcode" />
|
|
||||||
<div class="form-tips">建议图片尺寸:200*200像素;图片格式:jpg、png、jpeg</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="customer-service">
|
|
||||||
<image-contain width="140px" height="140px" :src="content.qrcode" alt="" />
|
|
||||||
<div class="text-[15px] mt-[7px] font-medium">{{ content.title }}</div>
|
|
||||||
<div class="text-[#666] mt-[20px]">服务时间:{{ content.time }}</div>
|
|
||||||
<div class="text-[#666] mt-[7px]">客服电话:{{ content.mobile }}</div>
|
|
||||||
<div
|
|
||||||
class="text-white text-[16px] rounded-[42px] bg-[#4173FF] w-full h-[42px] flex justify-center items-center mt-[50px]"
|
|
||||||
>
|
|
||||||
保存二维码图片
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.customer-service {
|
|
||||||
margin: 10px 18px;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 50px 55px 80px;
|
|
||||||
background: #fff;
|
|
||||||
@apply flex flex-col justify-center items-center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '客服设置',
|
|
||||||
name: 'customer-service',
|
|
||||||
content: {
|
|
||||||
title: '添加客服二维码',
|
|
||||||
time: '',
|
|
||||||
mobile: '',
|
|
||||||
qrcode: ''
|
|
||||||
},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
const widgets: Record<string, any> = import.meta.glob('./**/index.ts', { eager: true })
|
|
||||||
interface Widget {
|
|
||||||
attr: any
|
|
||||||
content: any
|
|
||||||
options: any
|
|
||||||
}
|
|
||||||
console.log(widgets)
|
|
||||||
const exportWidgets: Record<string, Widget> = {}
|
|
||||||
Object.keys(widgets).forEach((key) => {
|
|
||||||
const widgetName = key.replace(/^\.\/([\w-]+).*/gi, '$1')
|
|
||||||
exportWidgets[widgetName] = widgets[key]?.default
|
|
||||||
})
|
|
||||||
|
|
||||||
export default exportWidgets
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-form label-width="70px">
|
|
||||||
<el-form-item label="排版样式">
|
|
||||||
<el-radio-group v-model="content.style">
|
|
||||||
<el-radio :label="1">横排</el-radio>
|
|
||||||
<el-radio :label="2">竖排</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="标题名称">
|
|
||||||
<el-input class="w-[400px]" v-model="content.title" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="菜单设置">
|
|
||||||
<div class="flex-1">
|
|
||||||
<AddNav v-model="content.data" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
import AddNav from '../../add-nav.vue'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="my-service">
|
|
||||||
<div v-if="content.title" class="title px-[15px] py-[10px]">
|
|
||||||
<div>{{ content.title }}</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="content.style == 1" class="flex flex-wrap pt-[20px] pb-[10px]">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in content.data"
|
|
||||||
:key="index"
|
|
||||||
class="flex flex-col items-center w-1/4 mb-[15px]"
|
|
||||||
>
|
|
||||||
<image-contain width="26px" height="26px" :src="item.image" alt="" />
|
|
||||||
<div class="mt-[7px]">{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="content.style == 2">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in content.data"
|
|
||||||
:key="index"
|
|
||||||
class="flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"
|
|
||||||
>
|
|
||||||
<image-contain width="24px" height="24px" :src="item.image" alt="" />
|
|
||||||
<div class="ml-[10px] flex-1">{{ item.name }}</div>
|
|
||||||
<div>
|
|
||||||
<icon name="el-icon-ArrowRight" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.my-service {
|
|
||||||
margin: 10px 10px 0;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 7px;
|
|
||||||
.title {
|
|
||||||
border-bottom: 1px solid #e5e5e5;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '我的服务',
|
|
||||||
name: 'my-service',
|
|
||||||
content: {
|
|
||||||
style: 1,
|
|
||||||
title: '我的服务',
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
image: '',
|
|
||||||
name: '',
|
|
||||||
link: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-form label-width="70px">
|
|
||||||
<el-form-item label="是否启用">
|
|
||||||
<el-radio-group v-model="content.enabled">
|
|
||||||
<el-radio :label="1">开启</el-radio>
|
|
||||||
<el-radio :label="0">停用</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="菜单设置">
|
|
||||||
<div class="flex-1">
|
|
||||||
<div class="form-tips mb-4">最多可添加10个,建议图片尺寸:100px*100px</div>
|
|
||||||
<AddNav v-model="content.data" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
import AddNav from '../../add-nav.vue'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="nav pt-[15px] pb-[8px]">
|
|
||||||
<div class="flex flex-wrap">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in content.data"
|
|
||||||
:key="index"
|
|
||||||
class="flex flex-col items-center w-1/5 mb-[15px]"
|
|
||||||
>
|
|
||||||
<image-contain width="41px" height="41px" :src="item.image" alt="" />
|
|
||||||
<div class="mt-[7px]">{{ item.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.nav {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '导航菜单',
|
|
||||||
name: 'nav',
|
|
||||||
content: {
|
|
||||||
enabled: 1,
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
image: '',
|
|
||||||
name: '导航',
|
|
||||||
link: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<template>
|
|
||||||
<div></div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="search">
|
|
||||||
<div class="search-con flex items-center px-[15px]">
|
|
||||||
<icon name="el-icon-Search" :size="17" />
|
|
||||||
<span class="ml-[5px]">请输入关键词搜索</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup></script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.search {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 7px 12px;
|
|
||||||
.search-con {
|
|
||||||
height: 100%;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 36px;
|
|
||||||
background: #f4f4f4;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '搜索',
|
|
||||||
name: 'search',
|
|
||||||
disabled: 1,
|
|
||||||
content: {},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-form label-width="70px">
|
|
||||||
<el-form-item label="是否启用">
|
|
||||||
<el-radio-group v-model="content.enabled">
|
|
||||||
<el-radio :label="1">开启</el-radio>
|
|
||||||
<el-radio :label="0">停用</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="图片设置">
|
|
||||||
<div class="flex-1">
|
|
||||||
<div class="form-tips">最多添加5张,建议图片尺寸:750px*200px</div>
|
|
||||||
<del-wrap
|
|
||||||
v-for="(item, index) in content.data"
|
|
||||||
:key="index"
|
|
||||||
@close="handleDelete(index)"
|
|
||||||
class="max-w-[400px]"
|
|
||||||
>
|
|
||||||
<div class="bg-fill-light flex items-center w-full p-4 mt-4">
|
|
||||||
<material-picker v-model="item.image" upload-class="bg-body" />
|
|
||||||
<div class="ml-3 flex-1">
|
|
||||||
<el-form-item label="图片名称">
|
|
||||||
<el-input v-model="item.name" placeholder="请输入名称" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="mt-[18px]" label="图片链接">
|
|
||||||
<link-picker v-model="item.link" />
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</del-wrap>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="content.data?.length < limit">
|
|
||||||
<el-button type="primary" @click="handleAdd">添加图片</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import feedback from '@/utils/feedback'
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
const limit = 5
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
if (props.content.data?.length < limit) {
|
|
||||||
props.content.data.push({
|
|
||||||
image: '',
|
|
||||||
name: '',
|
|
||||||
link: {}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
feedback.msgError(`最多添加${limit}张图片`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleDelete = (index: number) => {
|
|
||||||
if (props.content.data?.length <= 1) {
|
|
||||||
return feedback.msgError('最少保留一张图片')
|
|
||||||
}
|
|
||||||
props.content.data.splice(index, 1)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="banner mx-[10px] mt-[10px]">
|
|
||||||
<div class="banner-image">
|
|
||||||
<image-contain width="100%" height="100px" :src="getImage" fit="contain" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const getImage = computed(() => {
|
|
||||||
const { data } = props.content
|
|
||||||
if (Array.isArray(data)) {
|
|
||||||
return data[0] ? data[0].image : ''
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '个人中心广告图',
|
|
||||||
name: 'user-banner',
|
|
||||||
content: {
|
|
||||||
enabled: 1,
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
image: '',
|
|
||||||
name: '',
|
|
||||||
link: {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<template>
|
|
||||||
<div></div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import type options from './options'
|
|
||||||
type OptionsType = ReturnType<typeof options>
|
|
||||||
const props = defineProps({
|
|
||||||
content: {
|
|
||||||
type: Object as PropType<OptionsType['content']>,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
type: Object as PropType<OptionsType['styles']>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="user-info flex items-center px-[25px]">
|
|
||||||
<img src="./images/default_avatar.png" class="w-[60px] h-[60px]" alt="" />
|
|
||||||
<div class="text-white text-[18px] ml-[10px]">未登录</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup></script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.user-info {
|
|
||||||
background: url(./images/my_topbg.png);
|
|
||||||
height: 115px;
|
|
||||||
background-position: bottom;
|
|
||||||
background-size: 100% auto;
|
|
||||||
.search-con {
|
|
||||||
height: 100%;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 36px;
|
|
||||||
background: #f4f4f4;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 139 KiB |
|
|
@ -1,8 +0,0 @@
|
||||||
import attr from './attr.vue'
|
|
||||||
import content from './content.vue'
|
|
||||||
import options from './options'
|
|
||||||
export default {
|
|
||||||
attr,
|
|
||||||
content,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export default () => ({
|
|
||||||
title: '用户信息',
|
|
||||||
name: 'user-info',
|
|
||||||
disabled: 1,
|
|
||||||
content: {},
|
|
||||||
styles: {}
|
|
||||||
})
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
<view class="banner h-[400rpx] bg-white">
|
||||||
|
<swiper
|
||||||
|
class="swiper h-full"
|
||||||
|
indicator-dots
|
||||||
|
indicator-active-color="#4173ff"
|
||||||
|
:autoplay="true"
|
||||||
|
>
|
||||||
|
<swiper-item v-for="(item, index) in content.data" :key="index">
|
||||||
|
<u-image mode="aspectFit" width="100%" height="100%" :src="item.image" />
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
content: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
<view class="nav pt-[30rpx] pb-[16rpx] bg-white">
|
||||||
|
<view class="nav-item flex flex-wrap">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in content.data"
|
||||||
|
:key="index"
|
||||||
|
class="flex flex-col items-center w-1/5 mb-[30rpx]"
|
||||||
|
>
|
||||||
|
<u-image width="41px" height="41px" :src="item.image" alt="" />
|
||||||
|
<view class="mt-[14rpx]">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
content: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<view class="search px-[24rpx] py-[14rpx] bg-white">
|
||||||
|
<u-search placeholder="请输入关键子" disabled :show-action="false"></u-search>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
|
@ -59,7 +59,8 @@
|
||||||
},
|
},
|
||||||
"easycom": {
|
"easycom": {
|
||||||
"custom": {
|
"custom": {
|
||||||
"^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)": "z-paging/components/z-paging$1/z-paging$1.vue"
|
"^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)": "z-paging/components/z-paging$1/z-paging$1.vue",
|
||||||
|
"^w-(.*)": "@/components/widgets/$1/$1.vue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="index">
|
||||||
<navigator url="/pages/login/login" hover-class="navigator-hover">
|
<decoration :pages="state.pages" />
|
||||||
<button type="default">跳转到新页面</button>
|
<view class="article"> </view>
|
||||||
</navigator>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import { getIndex } from '@/api/shop'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
const state = reactive({
|
||||||
|
pages: []
|
||||||
|
})
|
||||||
|
const getData = async () => {
|
||||||
|
const data = await getIndex()
|
||||||
|
state.pages = JSON.parse(data.pages)
|
||||||
|
console.log(state.pages)
|
||||||
|
}
|
||||||
|
getData()
|
||||||
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="login min-h-full flex flex-col items-center px-[40rpx] pt-[80rpx] box-border">
|
<view
|
||||||
|
class="bg-white login min-h-full flex flex-col items-center px-[40rpx] pt-[80rpx] box-border"
|
||||||
|
>
|
||||||
<view>
|
<view>
|
||||||
<u-image src="" mode="widthFix" height="160" width="160" />
|
<u-image src="" mode="widthFix" height="160" width="160" />
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -138,7 +140,7 @@ const sendSms = async () => {
|
||||||
uCodeRef.value?.start()
|
uCodeRef.value?.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const accountLogin = async (scene: LoginTypeEnum) => {
|
const accountLogin = async (scene: LoginTypeEnum, code?: string) => {
|
||||||
if (!isCheckAgreement.value) return uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》')
|
if (!isCheckAgreement.value) return uni.$u.toast('请勾选已阅读并同意《服务协议》和《隐私协议》')
|
||||||
if (scene == LoginTypeEnum.ACCOUNT) {
|
if (scene == LoginTypeEnum.ACCOUNT) {
|
||||||
if (!formData.username) return uni.$u.toast('请输入账号/手机号码')
|
if (!formData.username) return uni.$u.toast('请输入账号/手机号码')
|
||||||
|
|
@ -148,8 +150,12 @@ const accountLogin = async (scene: LoginTypeEnum) => {
|
||||||
if (!formData.mobile) return uni.$u.toast('请输入手机号码')
|
if (!formData.mobile) return uni.$u.toast('请输入手机号码')
|
||||||
if (!formData.code) return uni.$u.toast('请输入验证码')
|
if (!formData.code) return uni.$u.toast('请输入验证码')
|
||||||
}
|
}
|
||||||
|
const params = {
|
||||||
await login({ ...formData, scene })
|
...formData,
|
||||||
|
scene
|
||||||
|
}
|
||||||
|
if (code) params.code = code
|
||||||
|
await login(params)
|
||||||
uni.$u.toast('登录成功')
|
uni.$u.toast('登录成功')
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +164,8 @@ const wxLogin = async () => {
|
||||||
const data: any = await uni.login({
|
const data: any = await uni.login({
|
||||||
provider: 'weixin'
|
provider: 'weixin'
|
||||||
})
|
})
|
||||||
accountLogin(LoginTypeEnum.MNP)
|
console.log(data)
|
||||||
|
accountLogin(LoginTypeEnum.MNP, data.code)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
// .input-placeholder {
|
page {
|
||||||
// color: $u-info !important;
|
background-color: $u-bg-color;
|
||||||
// }
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue