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

522 lines
13 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.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">
<template
v-for="(item, index) in navigation1"
:key="index"
>
<div
v-if="index < 4"
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>
</template>
<template
v-for="(item, index) in navigation2"
:key="index"
>
<div
v-if="index < 4"
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>
</template>
</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 ele-text-danger" />
<span class="ele-text-danger">首页</span>
</a>
<a
class="shop-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/shop`)"
>
<ShopOutlined class="icon" />
商城
</a>
<a
class="order-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/order`)"
>
<ProfileOutlined class="icon" />
订单
</a>
<a
class="user-btn ele-cell-content ele-text-secondary"
@click="openUrl(`/mp-weixin/user`)"
>
<UserOutlined class="icon" />
我的
</a>
</div>
</a-card>
</div>
</template>
<script lang="ts" setup>
import {
ProfileOutlined,
ShopOutlined,
HomeOutlined,
UserOutlined
} 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';
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 navigation1 = ref<any[]>();
// 第二排
const navigation2 = 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);
navigation1.value = list.filter((d) => d.type == 2 && d.rows == 0);
navigation2.value = list.filter((d) => d.type == 2 && d.rows == 1);
});
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: 26px;
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;
}
.home-btn,
.shop-btn,
.order-btn,
.user-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);
}
}
}
}
.menu-card {
width: 340px;
margin: 6px auto;
background: #ffffff;
border-radius: 5px;
border-color: slategrey;
.btn-center {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
.merchant-card-title {
width: 340px;
margin: 6px auto;
font-size: 20px;
font-weight: 500;
margin-top: 16px;
}
.merchant-card {
width: 340px;
max-height: 80px;
margin: 6px auto;
margin-bottom: 16px;
padding: 8px;
background: #ffffff;
border-radius: 5px;
border-color: slategrey;
.merchant-name {
font-weight: 500;
font-size: 15px;
}
.merchant-desc {
width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.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);
}
.btn-center {
display: flex;
align-items: center;
justify-content: center;
}
}
</style>