Files
guofu-admin/src/views/cms/mp-weixin/user/components/simulator.vue
2024-05-05 16:29:16 +08:00

550 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="phone-layout" v-if="form">
<div class="phone-header-black ele-fluid">
<div class="title ele-fluid">
<div class="title-bar">
<span class="back"></span>
<span>{{ form.pageName || '个人中心' }}</span>
<a class="share" @click="onShare"></a>
</div>
</div>
</div>
<!-- 会员信息卡片 -->
<template v-if="form.showUserCard">
<a-popover>
<template #content> 点击更换背景 </template>
<div
class="user-card"
:style="{
backgroundImage: 'url(' + param.mp_user_top + ')'
}"
@click="
openUserCard({
name: 'mp_user_top',
value: param.mp_user_top,
comments: '小程序我的顶部背景图片',
sortNumber: 100
})
"
>
<div class="user-avatar">
<a-avatar :src="param.site_logo" :size="60" />
<div class="user-info">
<div class="nickname">昵称</div>
<div class="phone">手机号码</div>
</div>
</div>
</div>
</a-popover>
<UserCardEdit
v-model:visible="showUserCardEdit"
:data="current"
@done="reload"
/>
</template>
<!-- 订单卡片 -->
<template v-if="form.showOrderCard">
<div class="order-card ele-cell">
<div
v-for="(item, index) in order"
:key="index"
class="ele-cell-content ele-text-center btn-center"
@click="openMpMenuEdit(item)"
>
<a-image :src="item.icon" :width="30" :preview="false" />
<span>{{ item.title }}</span>
</div>
</div>
</template>
<template v-if="form.showToolsCard">
<div class="tools-card">
<div
v-for="(item, index) in server"
:key="index"
class="ele-cell"
@click="openMpMenuEdit(item)"
>
<a-avatar :src="item.icon" :size="24" />
<div
class="title ele-cell-content"
:style="{ color: item.color || '#333333' }"
>{{ item.title }}</div
>
<RightOutlined class="ele-text-secondary" />
</div>
</div>
<MpMenuEdit
v-model:visible="showMpMenuEdit"
:data="current"
@done="reload"
/>
</template>
<template v-if="form.showMenuCard">
<div class="phone-body" style="overflow-y: auto; overflow-x: hidden">
<!-- 幻灯片轮播 -->
<template v-if="form.showCarousel">
<a-carousel arrows autoplay :dots="true">
<template v-if="adImageList">
<template v-for="(img, index) in adImageList" :key="index">
<div class="ad-item">
<a-image
:preview="false"
:src="img.url"
width="100%"
height="200px"
/>
</div>
</template>
</template>
</a-carousel>
</template>
<!-- 导航菜单 -->
<template v-if="form.showMenuCard">
<div class="menu-card ele-cell">
<div
v-for="(item, index) in scrollList"
:key="index"
class="ele-cell-content ele-text-center btn-center"
@click="openMpMenuEdit(item)"
>
<a-image :src="item.icon" :width="30" :preview="false" />
<span>{{ item.title }}</span>
</div>
</div>
<MpMenuEdit
v-model:visible="showMpMenuEdit"
:data="current"
@done="reload"
/>
</template>
<!-- 商户列表 -->
<template v-if="form.showShopCard">
<div class="merchant-card-title">场地预定</div>
<div
class="merchant-card ele-cell"
v-for="(item, index) in shopList"
:key="index"
>
<a-image :src="item.image" :width="96" :preview="false" />
<div class="merchant-info ele-cell-content">
<div class="merchant-name">{{ item.merchantName }}</div>
<div class="merchant-desc ele-cell-desc">
{{ item.comments }}
</div>
</div>
<!-- <div class="">-->
<!-- <a-button>我要去</a-button>-->
<!-- </div>-->
</div>
</template>
<!-- 培训课程 -->
<template v-if="form.showTtrainCard">
<div class="merchant-card-title">培训课程</div>
<div
class="merchant-card ele-cell"
v-for="(item, index) in shopList"
:key="index"
@click="openMpMenuEdit(item)"
>
<a-image :src="item.image" :width="96" :preview="false" />
<div class="merchant-info ele-cell-content">
<div class="merchant-name">{{ item.merchantName }}</div>
<div class="merchant-desc ele-cell-desc">
{{ item.comments }}
</div>
</div>
</div>
</template>
</div>
</template>
<a-card
class="buy-bar"
:bordered="false"
:body-style="{ padding: '12px 16px' }"
>
<div class="ele-cell">
<a
class="home-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/home`)"
>
<HomeOutlined class="icon" />
<span>首页</span>
</a>
<a
class="shop-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/shop`)"
>
<ShopOutlined class="icon" />
<span>商城</span>
</a>
<a
class="order-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/order`)"
>
<ProfileOutlined class="icon" />
<span>订单</span>
</a>
<a
class="user-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/user`)"
>
<UserOutlined class="icon ele-text-danger" />
<span class="ele-text-danger">我的</span>
</a>
</div>
</a-card>
</div>
</template>
<script lang="ts" setup>
import {
ProfileOutlined,
ShopOutlined,
HomeOutlined,
UserOutlined, RightOutlined
} from "@ant-design/icons-vue";
import { ref, unref, watch } from 'vue';
import { MpWeixinParam, WebsiteField } from '@/api/cms/website/field/model';
import { listWebsiteField } from '@/api/system/website/field';
import { MpMenu } from '@/api/cms/mp-menu/model';
import { listMpMenu } from '@/api/cms/mp-menu';
import { listAd } from '@/api/cms/ad';
import { listMerchant } from '@/api/shop/merchant';
import { Merchant } from '@/api/shop/merchant/model';
import { openUrl } from '@/utils/common';
import { useRouter } from 'vue-router';
const { currentRoute } = useRouter();
const { query } = unref(currentRoute);
import MpMenuEdit from '@/views/cms/mp-weixin/menu/components/mpMenuEdit.vue';
import UserCardEdit from "@/views/cms/field/components/website-field-edit.vue";
const prpos = withDefaults(
defineProps<{
value?: string;
placeholder?: string;
form?: any | null;
type?: number;
list?: any[] | null;
refresh?: boolean;
}>(),
{
placeholder: undefined
}
);
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
const param = ref<MpWeixinParam>({});
const showUserCardEdit = ref(false);
const showMpMenuEdit = ref(false);
// 当前编辑数据
const current = ref<WebsiteField | null>(null);
// 幻灯片广告
const adImageList = ref<any[]>();
// 首页导航图标
const scrollList = ref<any[]>();
// 订单图标
const order = ref<any[]>();
// 服务图标
const server = ref<any[]>();
// 商户列表
const shopList = ref<Merchant[]>();
const config = ref({
selector: '#content', //容器可使用css选择器
branding: false,
language: 'zh_CN', //调用放在langs文件夹内的语言包
toolbar: false, //隐藏工具栏
menubar: false, //隐藏菜单栏
inline: true, //开启内联模式
plugins: [] //选择需加载的插件
//选中时出现的快捷工具,与插件有依赖关系
// quickbars_selection_toolbar: 'bold italic forecolor | link blockquote quickimage',
// init_instance_callback: function (editor) {
// editor.setContent('这里是你的内容字符串');
// }
});
/* 打开编辑弹窗 */
const openUserCard = (row?: WebsiteField) => {
current.value = row ?? null;
showUserCardEdit.value = true;
};
/* 打开编辑弹窗 */
const openMpMenuEdit = (row?: MpMenu) => {
current.value = row ?? null;
showMpMenuEdit.value = true;
};
const onShare = () => {};
const reload = () => {
listWebsiteField({}).then((list) => {
list.map((d) => {
const key = String(d.name);
param.value[key] = d.value;
});
});
listMpMenu({}).then((list) => {
server.value = list.filter((d) => d.type == 0);
order.value = list.filter((d) => d.type == 1);
scrollList.value = list.filter((d) => d.type == 2);
});
listAd({ adType: '幻灯片' }).then((res) => {
const carouselImages = res[0].images;
if (carouselImages) {
adImageList.value = JSON.parse(carouselImages);
}
});
listMerchant({}).then((list) => {
shopList.value = list;
});
emit('done');
};
reload();
watch(
() => prpos.refresh,
(refresh) => {
if (refresh) {
reload();
}
},
{ immediate: true }
);
</script>
<style lang="less" scoped>
.phone-layout {
position: fixed;
right: 16px;
width: 390px;
height: 844px;
background: url('@/assets/img/app-ui.png');
background-repeat: no-repeat;
background-position: top;
background-size: 100%;
//position: relative;
padding: 0 16px;
.phone-header-black {
height: 99px;
border-radius: 20px 20px 0 0;
background-size: 100%;
.title {
height: 99px;
font-size: 16px;
display: flex;
justify-content: center;
align-items: end;
padding-bottom: 13px;
.title-bar {
width: 100%;
display: flex;
justify-content: space-between;
.back {
display: block;
width: 50px;
margin-left: 3px;
background-color: #ffffff;
}
.share {
display: block;
width: 50px;
cursor: pointer;
}
}
}
}
.phone-body-bg {
padding: 0 16px;
height: 680px;
border-radius: 0 0 44px 44px;
overflow: hidden;
}
.phone-body {
width: 356px;
margin-left: 17px;
height: 630px;
padding: 0;
position: absolute;
top: 98px;
left: 0;
z-index: 999;
.comments {
padding: 20px;
word-break: break-all;
}
.form-data {
padding: 10px 20px;
.submit-btn {
padding: 30px 0;
}
}
}
.goods {
.price {
font-size: 18px;
}
.ele-cell-title {
font-weight: 600;
font-size: 16px;
}
.goods-attr {
}
}
.goods-divider {
height: 6px;
}
.buy-bar {
position: fixed;
width: 356px;
bottom: 70px;
//top: 881px;
background-color: #ffffff;
border-radius: 0 0 44px 44px;
border-top: 1px solid var(--grey-8);
.ele-cell-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.shop-btn,
.kefu-btn,
.star-btn {
display: flex;
flex-direction: column;
font-size: 13px;
padding: 0 9px;
cursor: pointer;
white-space: nowrap;
}
.icon {
font-size: 19px;
}
.buy-btn {
display: flex;
.add-cart {
border-radius: 100px 0 0 100px;
border: none;
background-color: var(--orange-5);
color: #ffffff;
height: 40px;
width: 95px;
}
.buy-now {
border-radius: 0 100px 100px 0;
border: none;
background-color: var(--red-6);
color: #ffffff;
height: 40px;
width: 95px;
}
}
}
}
:deep(.slick-slide) {
overflow: hidden;
}
:deep(.slick-arrow.custom-slick-arrow) {
font-size: 38px;
}
:deep(.slick-arrow.custom-slick-arrow) {
color: #fff;
background-color: rgba(31, 45, 61, 0.11);
transition: ease all 0.3s;
opacity: 0.3;
z-index: 1;
}
:deep(.slick-arrow.custom-slick-arrow:before) {
display: none;
}
:deep(.slick-arrow.custom-slick-arrow:hover) {
color: #fff;
opacity: 0.5;
}
:deep(.slick-slide h3) {
color: #fff;
}
.user-card {
height: 170px;
margin: 0 1px;
background-color: var(--grey-10);
background-repeat: no-repeat;
background-size: cover;
display: flex;
.user-avatar {
margin-left: 16px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.user-info {
margin-left: 10px;
.nickname {
color: var(--grey-3);
font-size: 18px;
font-weight: 500;
}
.phone {
color: var(--grey-5);
}
}
}
}
.order-card {
width: 340px;
height: 80px;
margin: 0 1px;
background: #ffffff;
border-radius: 5px;
border-color: slategrey;
position: absolute;
top: 230px;
left: 24px;
.btn-center {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
.tools-card {
width: 340px;
margin: 0 1px;
padding: 6px 16px;
background: #ffffff;
border-radius: 5px;
border-color: slategrey;
position: absolute;
top: 324px;
left: 24px;
.ele-cell {
padding: 4px 0;
border-bottom: 1px solid var(--grey-9);
cursor: pointer;
}
.btn-center {
display: flex;
align-items: center;
justify-content: center;
}
}
</style>