初始版本
This commit is contained in:
43
business_uniapp/src/components/widgets/banner/banner.vue
Normal file
43
business_uniapp/src/components/widgets/banner/banner.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<view
|
||||
class="banner translate-y-0"
|
||||
:class="{ 'px-[20rpx]': !isLargeScreen }"
|
||||
v-if="content.data.length && content.enabled"
|
||||
>
|
||||
<LSwiper
|
||||
:content="content"
|
||||
:height="isLargeScreen ? '1100' : '321'"
|
||||
:circular="true"
|
||||
:effect3d="false"
|
||||
:border-radius="isLargeScreen ? '0' : '14'"
|
||||
interval="7000"
|
||||
bgColor="transparent"
|
||||
@change="handleChange"
|
||||
></LSwiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LSwiper from '@/components/l-swiper/l-swiper.vue'
|
||||
import {useAppStore} from "@/stores/app";
|
||||
|
||||
const emit = defineEmits(['change'])
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isLargeScreen: {
|
||||
type: Boolean
|
||||
}
|
||||
})
|
||||
const {getImageUrl} = useAppStore();
|
||||
|
||||
const handleChange = (index: number) => {
|
||||
emit('change', getImageUrl(props['content'].data[index].bg))
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<view class="bg-white p-[30rpx] flex text-[#101010] font-medium text-lg">
|
||||
联系我们
|
||||
</view>
|
||||
<view
|
||||
class="customer-service bg-white flex flex-col justify-center items-center mx-[36rpx] mt-[30rpx] rounded-[20rpx] px-[20rpx] pb-[100rpx]"
|
||||
>
|
||||
<view
|
||||
class="w-full border-solid border-0 border-b border-[#f5f5f5] p-[30rpx] text-center text-[#101010] text-base font-medium">
|
||||
{{ content.title }}
|
||||
</view>
|
||||
|
||||
<view class="mt-[60rpx]">
|
||||
<!-- 这样渲染是为了能在小程序中长按识别二维码 -->
|
||||
<u-parse :html="richTxt"></u-parse>
|
||||
<!-- <u-image width="200" height="200" border-radius="10rpx" :src="getImageUrl(content.qrcode)"/>-->
|
||||
</view>
|
||||
<view v-if="content.remark" class="text-sm mt-[40rpx] font-medium">{{ content.remark }}</view>
|
||||
<view v-if="content.mobile" class="text-sm mt-[24rpx] flex flex-wrap">
|
||||
<!-- #ifdef H5 -->
|
||||
<a class="ml-[10rpx] phone text-primary underline" :href="'tel:' + content.mobile">
|
||||
{{ content.mobile }}
|
||||
</a>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 -->
|
||||
<view class="ml-[10rpx] phone text-primary underline" @click="handleCall">
|
||||
{{ content.mobile }}
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view v-if="content.time" class="text-muted text-sm mt-[30rpx]">
|
||||
服务时间:{{ content.time }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {useAppStore} from '@/stores/app'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const {getImageUrl} = useAppStore()
|
||||
|
||||
const richTxt = computed(() => {
|
||||
const src = getImageUrl(props.content.qrcode)
|
||||
return `<img src="${src}" style="width: 100px;height: 100px; border-radius: 8px" />`
|
||||
})
|
||||
|
||||
const handleCall = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: String(props.content.mobile)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<view
|
||||
class="banner h-[200rpx] mx-[20rpx] mt-[20rpx] translate-y-0"
|
||||
v-if="showList.length && content.enabled"
|
||||
>
|
||||
<swiper
|
||||
class="swiper h-full"
|
||||
:indicator-dots="showList.length > 1"
|
||||
indicator-active-color="#4173ff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item
|
||||
v-for="(item, index) in showList"
|
||||
:key="index"
|
||||
@click="handleClick(item.link)"
|
||||
>
|
||||
<u-image
|
||||
mode="widthFix"
|
||||
width="100%"
|
||||
height="100%"
|
||||
:src="getImageUrl(item.image)"
|
||||
:border-radius="14"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { navigateTo } from '@/utils/util'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const handleClick = (link: any) => {
|
||||
navigateTo(link)
|
||||
}
|
||||
const { getImageUrl } = useAppStore()
|
||||
|
||||
const showList = computed(() => {
|
||||
return props.content.data?.filter((item: any) => item.is_show == '1') || []
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
75
business_uniapp/src/components/widgets/nav/nav.vue
Normal file
75
business_uniapp/src/components/widgets/nav/nav.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="relative mx-[20rpx] mt-[20rpx]">
|
||||
<swiper
|
||||
class="py-[20rpx] bg-white rounded-lg"
|
||||
:style="{
|
||||
height: navList[0].length > content.per_line ? '288rpx' : '132rpx'
|
||||
}"
|
||||
:autoplay="false"
|
||||
:indicator-dots="false"
|
||||
@change="swiperChange"
|
||||
>
|
||||
<swiper-item v-for="(sItem, sIndex) in navList" :key="sIndex">
|
||||
<view class="nav" v-if="navList.length && content.enabled">
|
||||
<view
|
||||
class="grid grid-rows-auto gap-y-3 w-full"
|
||||
:style="{ 'grid-template-columns': `repeat(${content.per_line}, 1fr)` }"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in sItem"
|
||||
:key="index"
|
||||
class="flex flex-col items-center"
|
||||
@click="handleClick(item.link)"
|
||||
>
|
||||
<u-image width="82" height="82" :src="getImageUrl(item.image)" alt=""/>
|
||||
<view class="mt-[14rpx] text-xs">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, watch, computed} from 'vue'
|
||||
import {useAppStore} from '@/stores/app'
|
||||
import {navigateTo, sliceArray} from '@/utils/util'
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const {getImageUrl} = useAppStore()
|
||||
const swiperCurrent = ref<number>(0)
|
||||
const navList = ref<Record<string, any>>([])
|
||||
|
||||
const pagesNum = computed<number>(() => {
|
||||
return props.content.per_line * props.content.show_line
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.content.data,
|
||||
(val) => {
|
||||
const num = props.content.style === 1 ? val.length : pagesNum.value
|
||||
navList.value = sliceArray(val, num)
|
||||
console.log(navList.value)
|
||||
},
|
||||
{deep: true, immediate: true}
|
||||
)
|
||||
|
||||
const handleClick = (link: any) => {
|
||||
navigateTo(link)
|
||||
}
|
||||
|
||||
const swiperChange = (e: any) => {
|
||||
swiperCurrent.value = e.detail.current
|
||||
}
|
||||
</script>
|
||||
93
business_uniapp/src/components/widgets/search/search.vue
Normal file
93
business_uniapp/src/components/widgets/search/search.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<!-- #ifndef H5 -->
|
||||
<u-sticky h5-nav-height="0" bg-color="transparent">
|
||||
<u-navbar
|
||||
:class="{ 'fixed top-0 z-10': isLargeScreen }"
|
||||
:is-back="false"
|
||||
:is-fixed="true"
|
||||
:title="metaData.title"
|
||||
:custom-title="metaData.title_type == 2"
|
||||
:border-bottom="false"
|
||||
:title-bold="true"
|
||||
:background="{ background: 'rgba(256,256, 256, 0)' }"
|
||||
:title-color="percent > 0.5 ? '#000' : metaData.text_color == 1 ? '#fff' : '#000'"
|
||||
>
|
||||
<template #default>
|
||||
<view class="px-[24px] py-[30px] flex items-center">
|
||||
<u-image src="" height="50" width="50" border-radius="999"></u-image>
|
||||
<text class="ml-1 text-white">肩颈管家·精油按摩(雅乐店)</text>
|
||||
</view>
|
||||
<!-- <navigator
|
||||
url="/pages/search/search"
|
||||
class="mini-search"
|
||||
hover-class="none"
|
||||
:style="{ opacity: isLargeScreen ? 1 : percent }"
|
||||
>
|
||||
<u-icon name="search"></u-icon>
|
||||
</navigator> -->
|
||||
</template>
|
||||
<!-- <template #title>
|
||||
<image class="!h-[54rpx]" :src="metaData.title_img" mode="widthFix"></image>
|
||||
</template> -->
|
||||
</u-navbar>
|
||||
</u-sticky>
|
||||
<!-- #endif -->
|
||||
<!-- <navigator
|
||||
v-if="!isLargeScreen"
|
||||
url="/pages/search/search"
|
||||
class="px-[24rpx] mt-[24rpx] mb-[30rpx]"
|
||||
:style="{ opacity: 1 - percent }"
|
||||
hover-class="none"
|
||||
>
|
||||
<u-search
|
||||
placeholder="请输入关键词搜索"
|
||||
:height="72"
|
||||
:disabled="true"
|
||||
:show-action="false"
|
||||
bgColor="#ffffff"
|
||||
></u-search>
|
||||
</navigator> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
pageMeta: {
|
||||
type: Object,
|
||||
default: () => []
|
||||
},
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isLargeScreen: {
|
||||
type: Boolean
|
||||
},
|
||||
percent: {
|
||||
type: Number
|
||||
}
|
||||
})
|
||||
|
||||
const metaData: any = computed(() => {
|
||||
return props.pageMeta[0].content
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mini-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-left: 20rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<view
|
||||
class="banner h-[200rpx] mx-[20rpx] mt-[20rpx] translate-y-0"
|
||||
v-if="content.data.length && content.enabled"
|
||||
>
|
||||
<swiper
|
||||
class="swiper h-full"
|
||||
:indicator-dots="content.data.length > 1"
|
||||
indicator-active-color="#4173ff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item
|
||||
v-for="(item, index) in content.data"
|
||||
:key="index"
|
||||
@click="handleClick(item.limk)"
|
||||
>
|
||||
<u-image
|
||||
mode="aspectFit"
|
||||
width="100%"
|
||||
height="100%"
|
||||
:src="getImageUrl(item.image)"
|
||||
:border-radius="14"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { navigateTo } from '@/utils/util'
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const handleClick = (link: any) => {
|
||||
navigateTo(link)
|
||||
}
|
||||
const { getImageUrl } = useAppStore()
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
170
business_uniapp/src/components/widgets/user-info/user-info.vue
Normal file
170
business_uniapp/src/components/widgets/user-info/user-info.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<view class="user-info" v-if="content.enabled">
|
||||
<view class="flex items-center justify-between px-[30rpx] pb-[30rpx] pt-[20rpx]">
|
||||
<view
|
||||
v-if="isLogin"
|
||||
class="flex items-center w-full"
|
||||
@click="router.navigate('/pages/user_set/user_set')"
|
||||
>
|
||||
<u-avatar :src="userInfo.logo" :size="108"></u-avatar>
|
||||
<view class="ml-[28rpx] text-black">
|
||||
<view class="text-xl text-main font-medium">{{ userInfo.name }}</view>
|
||||
<view
|
||||
v-if="content.user_info == 2"
|
||||
class="text-base mt-1 text-content"
|
||||
@click.stop="copy(userInfo.mobile)"
|
||||
>
|
||||
手机号:{{ userInfo.mobile || '-' }}
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="text-base mt-1 text-content"
|
||||
@click.stop="copy(userInfo.sn)"
|
||||
>
|
||||
工号: {{ userInfo.sn || '-' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<navigator
|
||||
v-else
|
||||
class="flex items-center text-black"
|
||||
hover-class="none"
|
||||
url="/pages/login/login"
|
||||
>
|
||||
<u-avatar src="/static/images/user/default_avatar.png" :size="108"></u-avatar>
|
||||
<view class="ml-[28rpx] text-black">
|
||||
<view class="text-xl text-main font-bold">立即登录/注册</view>
|
||||
<view class="text-base text-content mt-1">
|
||||
登录后查看更多
|
||||
</view>
|
||||
</view>
|
||||
</navigator>
|
||||
<navigator v-if="isLogin" hover-class="none" url="/pages/user_set/user_set">
|
||||
<u-icon name="arrow-right" color="#999" :size="28"></u-icon>
|
||||
</navigator>
|
||||
<navigator v-else hover-class="none" url="/pages/login/login">
|
||||
<u-icon name="arrow-right" color="#999" :size="28"></u-icon>
|
||||
</navigator>
|
||||
</view>
|
||||
|
||||
<view class="bg-white mt-4 rounded-xl p-[10px]">
|
||||
<view class="flex justify-around py-2">
|
||||
<view
|
||||
class="text-center"
|
||||
v-if="content.content?.includes('value1')"
|
||||
@click="router.navigateTo('/packages/pages/my_master/my_master')"
|
||||
>
|
||||
<view class="text-[20px] font-bold">
|
||||
{{ userInfo?.coach_count || 0 }}</view>
|
||||
<view class="text-muted">我的技师</view>
|
||||
</view>
|
||||
<view
|
||||
class="text-center"
|
||||
v-if="content.content?.includes('value2')"
|
||||
@click="router.navigateTo('/packages/pages/platform_project/platform_project')"
|
||||
>
|
||||
<view class="text-[20px] font-bold">
|
||||
{{ userInfo?.goods_count || 0 }}
|
||||
</view>
|
||||
<view class="text-muted">平台项目</view>
|
||||
</view>
|
||||
<view
|
||||
class="text-center"
|
||||
v-if="content.content?.includes('value3')"
|
||||
@click="router.navigateTo('/packages/pages/my_project/my_project')"
|
||||
>
|
||||
<view class="text-[20px] font-bold">{{ userInfo?.shop_goods_count || 0 }}</view>
|
||||
<view class="text-muted">店铺项目</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex gap-x-[10px] mt-2">
|
||||
<view
|
||||
class="comment flex flex-1 text-[#4A65A3]"
|
||||
@click="router.navigateTo('/packages/pages/bond/bond')"
|
||||
>
|
||||
<view class="w-full">
|
||||
<view class="text-xl font-medium">
|
||||
{{ userInfo?.deposit || 0 }}
|
||||
</view>
|
||||
<view class="mt-1 flex items-center">
|
||||
<view class="text-xs mr-[4rpx]">
|
||||
我的保证金
|
||||
</view>
|
||||
<u-icon name="arrow-right" color="#4A65A3" :size="20">
|
||||
</u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="wallet flex flex-1 text-[#2DA9BC]"
|
||||
@click="router.navigateTo('/packages/pages/balance/balance')"
|
||||
>
|
||||
<view class="w-full">
|
||||
<view class="text-xl font-medium">
|
||||
{{ userInfo?.money || 0 }}
|
||||
</view>
|
||||
<view class="mt-1 flex items-center">
|
||||
<view class="text-xs mr-[4rpx]">
|
||||
我的账户余额
|
||||
</view>
|
||||
<u-icon name="arrow-right" color="#2DA9BC" :size="20">
|
||||
</u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useCopy } from '@/hooks/useCopy'
|
||||
import { useRouter } from 'uniapp-router-next'
|
||||
|
||||
const { copy } = useCopy()
|
||||
const router = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
userInfo: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isLogin: {
|
||||
type: Boolean
|
||||
}
|
||||
})
|
||||
const navigateTo = (url: string) => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-info {
|
||||
padding: 24px 12px 0 12px;
|
||||
|
||||
.comment {
|
||||
background-color: #e0ebfd;
|
||||
background-image: url('@/static/images/user/bg_wdbzj.png');
|
||||
background-size: 100% auto;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.wallet {
|
||||
background-color: #c7effb;
|
||||
background-image: url('@/static/images/user/bg_wdzhye.png');
|
||||
background-size: 100% auto;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div
|
||||
class="user-service bg-white mx-[30rpx] mt-[30rpx] rounded-lg p-[30rpx]"
|
||||
v-if="content.enabled"
|
||||
>
|
||||
<div
|
||||
v-if="content.title"
|
||||
class="title text-content text-base"
|
||||
>
|
||||
<div>{{ content.title }}</div>
|
||||
</div>
|
||||
<!-- 横排 -->
|
||||
<div v-if="content.style == 1" class="grid grid-cols-4 gap-x-6">
|
||||
<div
|
||||
v-for="(item, index) in content.data"
|
||||
:key="index"
|
||||
class="flex flex-col items-center pt-[40rpx]"
|
||||
@click="handleClick(item.link)"
|
||||
v-show="Number(item.is_show)"
|
||||
>
|
||||
<u-image width="68" height="68" :src="getImageUrl(item.image)" alt="" />
|
||||
<div class="mt-2 text-xs">{{ 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 h-[100rpx] px-[24rpx]"
|
||||
@click="handleClick(item.link)"
|
||||
v-show="Number(item.is_show)"
|
||||
>
|
||||
<u-image width="52" height="52" :src="getImageUrl(item.image)" alt="" />
|
||||
<div class="ml-[20rpx] flex-1">{{ item.name }}</div>
|
||||
<div class="text-muted">
|
||||
<u-icon name="arrow-right" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { navigateTo } from '@/utils/util'
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const { getImageUrl } = useAppStore()
|
||||
const handleClick = (link: any) => {
|
||||
navigateTo(link)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
Reference in New Issue
Block a user