main
王文龙 2024-01-26 18:09:24 +08:00
parent fe47426b04
commit e3783d4ddc
19 changed files with 996 additions and 190 deletions

2
.env
View File

@ -2,6 +2,8 @@ VITE_TOKEN_KEY=tokenKey
VITE_URL_PREFIX=/api VITE_URL_PREFIX=/api
VITE_IMG_CND=https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/new-year/
# VITE_BASE_APP_ID='wx0fd5e237dba24ff4' # VITE_BASE_APP_ID='wx0fd5e237dba24ff4'
# VITE_BASE_APP_ID='wxbad2e8a91c62a734' # VITE_BASE_APP_ID='wxbad2e8a91c62a734'

View File

@ -1,8 +0,0 @@
#!/bin/sh
# shellcheck source=./_/husky.sh
. "$(dirname "$0")/_/husky.sh"
PATH="/usr/local/bin:$PATH"
npx --no-install commitlint --edit "$1"

View File

@ -1,7 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
[ -n "$CI" ] && exit 0
# Format and submit code according to lintstagedrc.js configuration
npm run lint:lint-staged

5
.vscode/extensions.json vendored Executable file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"vue.volar"
]
}

147
.vscode/settings.json vendored Executable file
View File

@ -0,0 +1,147 @@
{
"editor.formatOnSave": true,
"typescript.tsdk": "./node_modules/typescript/lib",
"typescript.preferences.autoImportFileExcludePatterns": ["vue-router"],
"npm.packageManager": "pnpm",
"editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.eol": "\n",
"search.exclude": {
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
"**/bower_components": true,
"**/dist": true,
"**/elehukouben": true,
"**/.git": true,
"**/.gitignore": true,
"**/.svn": true,
"**/.DS_Store": true,
"**/.idea": true,
"**/.vscode": false,
"**/yarn.lock": true,
"**/tmp": true,
"out": true,
"dist": true,
"node_modules": true,
"CHANGELOG.md": true,
"examples": true,
"res": true,
"screenshots": true,
"yarn-error.log": true,
"**/.yarn": true
},
"files.exclude": {
"**/.cache": true,
"**/.editorconfig": true,
"**/.eslintcache": true,
"**/bower_components": true,
"**/.idea": true,
"**/tmp": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true
},
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/.vscode/**": true,
"**/node_modules/**": true,
"**/tmp/**": true,
"**/bower_components/**": true,
"**/dist/**": true,
"**/yarn.lock": true
},
"material-icon-theme.folders.color": "#42a5f5",
"material-icon-theme.folders.theme": "specific",
"material-icon-theme.activeIconPack": "vue_vuex",
"path-intellisense.mappings": {
"@/": "${workspaceRoot}/src"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"i18n-ally.localesPaths": ["src/locales/lang"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.enabledParsers": ["ts"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"],
"cSpell.words": [
"antd",
"antv",
"brotli",
"browserslist",
"codemirror",
"commitlint",
"cropperjs",
"echarts",
"ERUDA",
"esnext",
"esno",
"iconify",
"INTLIFY",
"lint-staged",
"lintstagedrc",
"logicflow",
"mkcert",
"mockjs",
"nprogress",
"persistedstate",
"pinia",
"pnpm",
"qrcode",
"sider",
"sortablejs",
"stylelint",
"tailwindcss",
"tdesign",
"tinymce",
"unocss",
"unplugin",
"vben",
"vditor",
"Vite",
"vitejs",
"vueuse",
"windi",
"windicss",
"zxcvbn"
]
}

67
h5-bywh.conf Executable file
View File

@ -0,0 +1,67 @@
server {
listen 80;
listen [::]:80;
server_name bywh.flameby.com;
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name www.swfc.store swfc.store;
ssl_certificate /etc/nginx/ssl/swfc.store/swfc.store.pem;
ssl_certificate_key /etc/nginx/ssl/swfc.store/swfc.store.key;
# 配置SSL参数
ssl_protocols TLSv1.2 TLSv1.3; # 指定支持的SSL/TLS协议版本
ssl_prefer_server_ciphers on; # 使用服务器端加密套件顺序
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; # 指定加密套件
# 配置其他SSL选项
ssl_session_timeout 1d; # SSL会话过期时间
ssl_session_cache shared:SSL:10m; # SSL会话缓存大小
ssl_session_tickets off; # 禁用SSL会话票据
gzip on;
# 定义要压缩的文件类型
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# 定义压缩级别
gzip_comp_level 6;
# 定义压缩缓冲区大小
gzip_buffers 16 8k;
# 定义压缩最小文件大小
gzip_min_length 256;
# 定义压缩的 HTTP 版本
gzip_http_version 1.1;
# 定义压缩的条件
gzip_vary on;
# 定义压缩的处理方式
gzip_proxied any;
# 定义压缩的处理方法
gzip_static on;
root /usr/share/nginx/html/h5-off-line/dist;
index index.html index.htm;
location / {
# try_files $uri $uri/ @router;
try_files $uri $uri/ /index.html;
}
location /api{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20M;
proxy_send_timeout 500;
proxy_read_timeout 480;
rewrite ^/api(.*)$ $1 break;
proxy_pass http://localhost:8088;
}
location /mp/ {
alias /usr/share/nginx/html/mp/;
try_files $uri $uri/ =404;
}
location ~* \.txt$ {
allow all;
}
}

67
h5-msgg.conf Executable file
View File

@ -0,0 +1,67 @@
server {
listen 80;
listen [::]:80;
server_name msgg.flameby.com;
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name www.swfc.store swfc.store;
ssl_certificate /etc/nginx/ssl/swfc.store/swfc.store.pem;
ssl_certificate_key /etc/nginx/ssl/swfc.store/swfc.store.key;
# 配置SSL参数
ssl_protocols TLSv1.2 TLSv1.3; # 指定支持的SSL/TLS协议版本
ssl_prefer_server_ciphers on; # 使用服务器端加密套件顺序
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; # 指定加密套件
# 配置其他SSL选项
ssl_session_timeout 1d; # SSL会话过期时间
ssl_session_cache shared:SSL:10m; # SSL会话缓存大小
ssl_session_tickets off; # 禁用SSL会话票据
gzip on;
# 定义要压缩的文件类型
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# 定义压缩级别
gzip_comp_level 6;
# 定义压缩缓冲区大小
gzip_buffers 16 8k;
# 定义压缩最小文件大小
gzip_min_length 256;
# 定义压缩的 HTTP 版本
gzip_http_version 1.1;
# 定义压缩的条件
gzip_vary on;
# 定义压缩的处理方式
gzip_proxied any;
# 定义压缩的处理方法
gzip_static on;
root /usr/share/nginx/html/h5-off-line/dist;
index index.html index.htm;
location / {
# try_files $uri $uri/ @router;
try_files $uri $uri/ /index.html;
}
location /api{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20M;
proxy_send_timeout 500;
proxy_read_timeout 480;
rewrite ^/api(.*)$ $1 break;
proxy_pass http://localhost:8088;
}
location /mp/ {
alias /usr/share/nginx/html/mp/;
try_files $uri $uri/ =404;
}
location ~* \.txt$ {
allow all;
}
}

33
h5.conf
View File

@ -1,21 +1,24 @@
# server{ server{
# listen 80;
# listen [::]:80;
# server_name www.swfc.store swfc.store;
# # 重定向到 HTTPS
# # return 301 https://swfc.store$request_uri;
# # return 301 https://$host$request_uri;
# # 配置HTTP到HTTPS的重定向可选
# # if ($scheme != "https") {
# # return 301 https://swfc.store;
# # }
# }
server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
server_name www.swfc.store swfc.store; server_name www.swfc.store swfc.store;
# 重定向到 HTTPS
return 301 https://swfc.flameby.com$request_uri;
# return 301 https://$host$request_uri;
# 配置HTTP到HTTPS的重定向可选
# if ($scheme != "https") {
# return 301 https://swfc.store;
# }
# location / {
# rewrite ^ https://swfc.flameby.com$request_uri permanent;
# }
}
server {
# listen 80;
# listen [::]:80;
# server_name www.swfc.store swfc.store;
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;

View File

@ -0,0 +1 @@
q7xJZRWSt4ZVvZYx

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
4865349650456970681

BIN
src/assets/imgs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/imgs/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,7 +1,8 @@
<template> <template>
<div> <div>
<div v-show="!show" class="relative w-screen h-screen bg-cover main min-h-1334px"> <div v-show="!show" class="relative w-screen h-screen bg-cover main min-h-1334px">
<img class="w-240px h-196px ml-50px mt-55px" src="@/assets/imgs/mixtitle@2x.png" alt="" /> <!-- <img class="w-240px h-196px ml-50px mt-55px" src="@/assets/imgs/mixtitle@2x.png" alt="" /> -->
<img class="w-180px h-340px ml-50px mt-55px object-contain" :src="`${VITE_IMG_CND}home/lndj.png`" alt="" />
<!-- <img <!-- <img
class="absolute right-0 w-316px h-675px top-80px" class="absolute right-0 w-316px h-675px top-80px"
src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/build.gif" src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/build.gif"
@ -18,11 +19,12 @@
</div> </div>
</template> </template>
</nut-image> </nut-image>
<img <img class="w-310px absolute top-445px left-[50px] object-contain" :src="`${VITE_IMG_CND}home/2024.png`" alt="" />
<!-- <img
class="w-520px absolute top-245px left-[-30px] object-contain" class="w-520px absolute top-245px left-[-30px] object-contain"
src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/title.gif" src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/title.gif"
alt="" alt=""
/> /> -->
<img class="absolute bottom-0 left-0 w-340px h-764px" src="@/assets/imgs/shiz.png" alt="" /> <img class="absolute bottom-0 left-0 w-340px h-764px" src="@/assets/imgs/shiz.png" alt="" />
<img <img
ref="turnRef" ref="turnRef"
@ -42,29 +44,35 @@
@click="handleClick(1)" @click="handleClick(1)"
class="absolute transition-all ease-in-out duration-800 left-300px bottom-516px animate-fade-in-left1" class="absolute transition-all ease-in-out duration-800 left-300px bottom-516px animate-fade-in-left1"
:class="active === 1 && 'left-350px scale-140 '" :class="active === 1 && 'left-350px scale-140 '"
>季节限定菜单</span >春节年夜饭菜单</span
> >
<!-- >季节限定菜单</span -->
<div <div
@click="handleClick(2)" @click="handleClick(2)"
class="absolute flex items-center transition-all ease-in-out duration-800 left-346px bottom-334px animate-fade-in-left1" class="absolute flex items-center transition-all ease-in-out duration-800 left-346px bottom-334px animate-fade-in-left1"
:class="active === 2 && 'left-400px scale-140 '" :class="active === 2 && 'left-400px scale-140'"
> >
<!-- <div class="flex flex-col text-28px leading-28px"> <!-- <div class="flex flex-col text-22px leading-22px">
<span>Happy</span> <span>Happy</span>
<span>Hour</span> <span>Hour</span>
</div> </div> -->
<span class="ml-14px text-56px">限时特惠酒单</span> --> <span class="">春节营业时间</span>
<div class="flex flex-col text-22px leading-22px"> <!-- <span class="ml-14px">限时特惠酒单</span> -->
<span>Happy</span>
<span>Hour</span>
</div>
<span class="ml-14px">限时特惠酒单</span>
</div> </div>
<span <span
@click="handleClick(3)" @click="handleClick(3)"
class="absolute transition-all ease-in-out duration-800 left-324px bottom-192px animate-fade-in-left1" class="absolute transition-all ease-in-out duration-800 left-324px bottom-192px animate-fade-in-left1"
:class="active === 3 && 'left-374px scale-140'" :class="active === 3 && 'left-374px scale-140'"
>冬季大促福利领取</span >春节活动</span
>
<!-- >冬季大促福利领取</span -->
</div>
<div class="text-38px" v-if="false">
<span
@click="handleClick(0)"
class="absolute transition-all ease-in-out duration-800 left-346px bottom-334px animate-fade-in-left1"
:class="active === 2 && 'left-400px scale-140'"
>推荐餐厅详情</span
> >
</div> </div>
</div> </div>
@ -76,6 +84,7 @@
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
const { VITE_IMG_CND } = import.meta.env;
const turnRef = ref<HTMLImageElement | undefined>(); const turnRef = ref<HTMLImageElement | undefined>();
const active = ref(0); const active = ref(0);
const show = ref(false); const show = ref(false);
@ -103,8 +112,8 @@
watch(show, (val) => { watch(show, (val) => {
if (!val) { if (!val) {
turnRef.value?.classList.remove('turn'); // turnRef.value?.classList.remove('turn');
clearInterval(timer); // clearInterval(timer);
startAnimation(); startAnimation();
sessionStorage.setItem('isFirst', 'false'); sessionStorage.setItem('isFirst', 'false');
} }

View File

@ -7,7 +7,7 @@
<nut-swiper class="swiper" :init-page="state.page" :loop="true" @change="change" :auto-play="5000"> <nut-swiper class="swiper" :init-page="state.page" :loop="true" @change="change" :auto-play="5000">
<nut-swiper-item v-for="item in shopDetail.pictureUrl" :key="item"> <nut-swiper-item v-for="item in shopDetail.pictureUrl" :key="item">
<!-- <img v-if="item" v-lazy="item" alt="" /> --> <!-- <img v-if="item" v-lazy="item" alt="" /> -->
<nut-image v-if="item" :src="item" fit="cover"> <nut-image lazy-load v-if="item" :src="item" fit="cover">
<template #loading> <template #loading>
<div class="bg-black w-full h-full flex justify-center items-center"> <div class="bg-black w-full h-full flex justify-center items-center">
<Loading width="30px" height="30px" name="loading" /> <Loading width="30px" height="30px" name="loading" />
@ -41,6 +41,13 @@
<div class="text-22px leading-5">BUSINESS HOURS</div> <div class="text-22px leading-5">BUSINESS HOURS</div>
</div> </div>
</div> </div>
<div class="flex items-center mt20px">
<img class="w-44px h-44px" src="@/assets/imgs/shop-detail/time.png" alt="" />
<div class="ml-16px">
<div class="text-38px">春节营业时间 - {{ shopDetail.startTime }}</div>
<div class="text-22px leading-5">BUSINESS HOURS</div>
</div>
</div>
<div class="flex items-center mt-20px"> <div class="flex items-center mt-20px">
<img class="w-44px h-44px" src="@/assets/imgs/shop-detail/tele.png" alt="" /> <img class="w-44px h-44px" src="@/assets/imgs/shop-detail/tele.png" alt="" />
<div class="ml-16px"> <div class="ml-16px">
@ -126,34 +133,13 @@
<div <div
class="box-border mx-auto transition-all px-30px py-70px text-32px content w-690px min-h-300px rounded-3xl" class="box-border mx-auto transition-all px-30px py-70px text-32px content w-690px min-h-300px rounded-3xl"
:class="[selLang === 'introChi' && 'rounded-tl-0px', selLang === 'introJap' && 'rounded-tr-0px']" :class="[selLang === 'introChi' && 'rounded-tl-0px', selLang === 'introJap' && 'rounded-tr-0px']"
:style="selLang !== 'introEng' ? { fontFamily: 'Arial, Helvetica, sans-serif' } : '' " :style="selLang !== 'introEng' ? { fontFamily: 'Arial, Helvetica, sans-serif' } : ''"
> >
{{ shopDetail[selLang] }} {{ shopDetail[selLang] }}
</div> </div>
<img class="block mx-auto w-482px h-110px mb-70px mt-130px" src="@/assets/imgs/shop-detail/tscp.png" alt="" /> <img class="block mx-auto w-482px h-110px mb-70px mt-130px" src="@/assets/imgs/shop-detail/tscp.png" alt="" />
<nut-swiper v-if="false" class="swiper-other" :init-page="1" :loop="true"> <div class="w-full pb-80px">
<nut-swiper-item>
<img
src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/ailing/caipin/%E6%89%8B%E6%8B%86%E6%B8%85%E7%82%92%E8%9F%B9%E7%B2%89.JPG"
alt=""
/>
</nut-swiper-item>
<nut-swiper-item>
<img
src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/ailing/caipin/%E5%8D%81%E5%B9%B4%E8%8A%B1%E9%9B%95%E9%86%89%E5%A4%A7%E8%99%BE.JPG"
alt=""
/>
</nut-swiper-item>
<nut-swiper-item>
<img
src="https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/ailing/caipin/%E7%81%AB%E7%84%B0%E7%9B%90%E7%83%A7%E9%B2%8D%E9%B1%BC%E9%B8%A1358.JPG"
alt=""
/>
</nut-swiper-item>
</nut-swiper>
<div class="w-full">
<triple-state-slider <triple-state-slider
v-if="pageShow && shopDetail.vagetableUrl.length" v-if="pageShow && shopDetail.vagetableUrl.length"
:slides="shopDetail.vagetableUrl" :slides="shopDetail.vagetableUrl"
@ -164,6 +150,7 @@
<Loading width="30px" height="30px" name="loading" /> <Loading width="30px" height="30px" name="loading" />
</div> </div>
</div> </div>
<template v-if="false">
<img class="block mx-auto w-482px h-110px mb-60px mt-150px" src="@/assets/imgs/shop-detail/xiandcad.png" alt="" /> <img class="block mx-auto w-482px h-110px mb-60px mt-150px" src="@/assets/imgs/shop-detail/xiandcad.png" alt="" />
<div @click="push('swfc')" class="flex items-center justify-end w-1/2 ml-auto pr-30px text-30px"> <div @click="push('swfc')" class="flex items-center justify-end w-1/2 ml-auto pr-30px text-30px">
<div class="border-b-4px mr-10px" style="border-bottom: 2px solid">更多季节限定菜单</div> <div class="border-b-4px mr-10px" style="border-bottom: 2px solid">更多季节限定菜单</div>
@ -192,8 +179,35 @@
</div> </div>
</template> </template>
</nut-image> </nut-image>
</template>
<!-- <img class="object-contain mt-2 w-750px" :src="shopDetail.hour" /> --> <!-- <img class="object-contain mt-2 w-750px" :src="shopDetail.hour" /> -->
</div> </div>
<div class="bg-[#000] bottom-menu relative" v-if="menuList[id]">
<!-- <nut-image lazy-load class="w-750px" :src="`${VITE_IMG_CND}1727533181588086786/top.png`" fit="contain" /> -->
<nut-swiper ref="swiperRef" class="swiper" :init-page="menu.page" :loop="true" @change="menuChange" :auto-play="5000">
<nut-swiper-item v-for="item in menuList[id]" :key="item">
<nut-image lazy-load :src="`${VITE_IMG_CND + id}/${item}.jpg`" fit="contain">
<template #loading>
<div class="bg-black w-full h-full flex justify-center items-center">
<Loading width="30px" height="30px" name="loading" />
</div>
</template>
</nut-image>
</nut-swiper-item>
<template #page>
<div class="page"> {{ menu.current }}/{{ menuList[id]?.length }} </div>
</template>
</nut-swiper>
<view class="nut-swiper-btns">
<span class="nut-swiper-btns__left" @click="handlePrev">
<Left></Left>
</span>
<span class="nut-swiper-btns__left" @click="handleNext">
<Right></Right>
</span>
</view>
<!-- <nut-image lazy-load class="w-750px" :src="`${VITE_IMG_CND + id}/bt.png`" fit="contain" /> -->
</div>
<nut-image-preview :show="showImgPreview" :images="[imgData]" @close="showImgPreview = false" :show-index="false" /> <nut-image-preview :show="showImgPreview" :images="[imgData]" @close="showImgPreview = false" :show-index="false" />
<div class="bg-black h-4 mt-[-4px]"> </div> <div class="bg-black h-4 mt-[-4px]"> </div>
@ -206,7 +220,7 @@
import { TripleStateSlider } from '@samrahnama/triple-state-slider'; import { TripleStateSlider } from '@samrahnama/triple-state-slider';
import { queryBoxPage, queryShopDetail } from '@/api'; import { queryBoxPage, queryShopDetail } from '@/api';
import { showToast } from '@nutui/nutui'; import { showToast } from '@nutui/nutui';
import { Loading } from '@nutui/icons-vue'; import { Loading, Left, Right } from '@nutui/icons-vue';
nextTick(() => { nextTick(() => {
showToast.loading('', { showToast.loading('', {
@ -226,6 +240,7 @@
pictureUrl: [], pictureUrl: [],
vagetableUrl: [], vagetableUrl: [],
}); });
const { VITE_IMG_CND } = import.meta.env;
const pageShow = ref(false); const pageShow = ref(false);
const showImgPreview = ref(false); const showImgPreview = ref(false);
const lang = [ const lang = [
@ -263,19 +278,42 @@
'Z', 'Z',
]; ];
const bxList = ref<any>([]); const bxList = ref<any>([]);
const swiperRef = ref();
const bxSel = ref(0); const bxSel = ref(0);
const state = reactive({ const state = reactive({
page: 0, page: 0,
current: 1, current: 1,
}); });
const menu = reactive({
page: 0,
current: 1,
});
const imgData = { const imgData = {
src: 'https://picsum.photos/1280/720?random=10', src: 'https://picsum.photos/1280/720?random=10',
}; };
const menuList = {
'1727533181588086786': [1, 2, 3],
'1727970518397460481': [1, 2, 3, 4, 5],
'1727966419073474561': [1, 2],
'1727969634947014658': [1, 2, 3, 4, 5, 6, 7, 8],
'1727961297983479810': [1, 2, 3],
'1727962509772431362': [1, 2],
};
const handlePrev = () => {
swiperRef.value?.prev();
};
const handleNext = () => {
swiperRef.value?.next();
};
const change = (index: number) => { const change = (index: number) => {
state.current = index + 1; state.current = index + 1;
}; };
const menuChange = (index: number) => {
menu.current = index + 1;
};
const handleClickBx = (item: number) => { const handleClickBx = (item: number) => {
bxSel.value = item; bxSel.value = item;
}; };
@ -284,11 +322,11 @@
showImgPreview.value = true; showImgPreview.value = true;
}; };
const handleSelLang = (key: string) => { const handleSelLang = (key: string) => {
if(!shopDetail.value[key]) return if (!shopDetail.value[key]) return;
selLang.value = key; selLang.value = key;
}; };
const id = ref(useRoute().query.id); const id = ref<string>(useRoute().query.id as string);
const getShopDetail = async () => { const getShopDetail = async () => {
const { result } = await queryShopDetail({ id: id.value }); const { result } = await queryShopDetail({ id: id.value });
if (result) { if (result) {
@ -346,6 +384,17 @@
line-height: 450px; line-height: 450px;
height: 450px; height: 450px;
} }
.bottom-menu {
.swiper {
.nut-swiper-inner {
height: auto !important;
}
.nut-swiper-item {
line-height: 1;
height: auto;
}
}
}
.triple-state-slider { .triple-state-slider {
// .previous-slide-wrapper { // .previous-slide-wrapper {
// -webkit-transform: translateX(calc(-100% - 1em)) scaleY(0.9); // -webkit-transform: translateX(calc(-100% - 1em)) scaleY(0.9);
@ -395,4 +444,23 @@
// background: url('@/assets/imgs/shop-detail/tit@2x.png') no-repeat; // background: url('@/assets/imgs/shop-detail/tit@2x.png') no-repeat;
// background-size: cover; // background-size: cover;
// } // }
.nut-swiper-btns {
width: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: flex;
justify-content: space-between;
padding: 0 20px;
box-sizing: border-box;
}
.nut-swiper-btns span {
display: flex;
align-items: center;
justify-content: center;
width: 64px;
height: 80px;
background-color: rgba(0, 0, 0, 0.2);
}
</style> </style>

325
src/views/sale/index copy.vue Executable file
View File

@ -0,0 +1,325 @@
<template>
<div class="relative z-10 w-screen h-screen main pb-4">
<div @click="back" class="absolute z-10 top-30px left-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center">
<img class="w-32px h-29px" src="@/assets/imgs/bgo.png" alt="" />
</div>
<div class="absolute z-0 bgi-light w-220px h-400px top-40px right-30px"> </div>
<div
v-if="false"
@click="handleShareWechat"
class="absolute z-10 top-30px right-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center"
>
<img class="w-32px h-29px" src="@/assets/imgs/sale/fenx@2x.png" alt="" />
</div>
<div class="bgi-top w-80% h-230px w-450px absolute top-124px left-30px z-0"> </div>
<div class="box-border w-full mx-auto bg-cover pt-428px pb-46px px-30px main bg-black">
<div
v-for="item in list"
:key="item.id"
class="relative w-690px p-30px box-border mb-30px rounded-30px border-[#453c32] border-solid border-2"
>
<img class="absolute left-[-8px] top-[-6px] w-98px h-98px text-[#FFF0D7]" :src="item.tagImg" alt="" />
<div class="flex flex-col items-center">
<span class="text-38px">{{ item.title }}</span>
<p class="text-26px mt-10px"
>{{ item.receiveDate }}<span class="ml-20px">{{ item.receiveTime }}</span></p
>
</div>
<div class="mt-50px mb-40px text-28px">
活动规则{{ item.activityRules }}
<p>{{ item.activityDec }}</p>
</div>
<div
class="flex items-center justify-between overflow-hidden rounded-md bg-beijing pr-16px pl-8px h-184px"
:class="(item.nums <= 0 || item.verifState) && 'grayscale'"
>
<img :src="item.giftImage" alt="" class="h-184px mt-[-6px] object-contain" />
<div class="flex items-center justify-between flex-1 pl-2">
<div class="text-36px leading-40px text-[#090909]">
<p class="leading-44px">{{ item.giftName }}</p>
<!-- <p v-if="item.id === 1" class="text-20px leading-36px">{{ item.subRemark }}</p> -->
<p class="text-20px leading-36px">剩余{{ item.nums }}</p>
</div>
<div
v-if="item.nums > 0 && !item.verifState"
@click="handleClick(item)"
class="bg-white hover:bg-light-600 overflow-hidden cursor-pointer text-[#090909] text-26px rounded-26px h-52px w-140px leading-46px text-center"
>
{{ !item.state ? '我要报名' : '去核销' }}
</div>
</div>
<div>
<img v-if="item.nums <= 0 && !item.verifState" src="@/assets/imgs/sale/lingwan.png" alt="" class="w-166px object-contain mr-[-18px]" />
<img v-if="item.verifState" src="@/assets/imgs/sale/hexiao.png" alt="" class="w-166px object-contain mr-[-18px]" />
</div>
</div>
</div>
<div v-if="false" class="relative w-690px p-30px box-border mb-30px rounded-30px border-[#453c32] border-solid border-2">
<img class="absolute left-[-8px] top-[-6px] w-98px h-98px text-[#FFF0D7]" src="@/assets/imgs/sale/huod2@2x.png" alt="" />
<div class="flex flex-col items-center">
<span class="text-38px">私飨岁末会聚丨包厢用餐即享350份精致礼遇!</span>
<p class="text-26px mt-10px"
>2023/12/1-2024/1/1
<span v-if="false" class="ml-20px">11:00-18:00</span>
</p>
</div>
<div class="mt-50px mb-40px text-28px">
活动规则在SWFC指定餐厅晚市每日1700以后预订包厢并到店消费满1,000可凭餐厅盖章的消费小票及支付凭证至2F综合咨询台每日2200领取
Rever足浴SPA礼盒一份礼品共350份每人每天限领一份
<p>礼物发放以线下发放为准先到先得领完为止</p>
</div>
<div class="flex items-center justify-between overflow-hidden rounded-md bg-beijing pr-20px pl-8px h-184px">
<img src="@/assets/imgs/sale/lihe@2x.png" alt="" class="object-contain h-184px" />
<div class="text-36px leading-40px text-[#090909]">
<p class="leading-44px">Rever足浴SPA礼盒</p>
<p class="text-20px leading-36px">剩余222</p>
</div>
<div
@click="handleClick"
class="bg-white hover:bg-light-600 overflow-hidden cursor-pointer text-[#090909] text-26px rounded-26px h-52px w-140px leading-46px text-center"
>
我要报名
</div>
</div>
</div>
<img class="object-contain w-690px mt-80px" src="@/assets/imgs/sale/logohj.png" alt="" />
</div>
</div>
<nut-overlay v-model:visible="show" :overlay-style="overlayStyle" :close-on-click-overlay="false" :z-index="50" lock-scroll>
<div class="flex items-center justify-center w-full h-full">
<div class="relative bg-tbj h-576px w-560px">
<!-- <IconFont class="text-60px w-60px h-60px absolute right-20px top-[-28px] text-light-800" name="close"></IconFont> -->
<div @click.prevent="closeOverlay" class="p-30px absolute right-[-10px] top-[-58px] rounded-1/2">
<img class="object-cover overflow-hidden bg-gray-400 w-58px h-58px rounded-1/2" src="@/assets/imgs/sale/cha@2x.png" alt="" />
<img
v-if="selItem.giftImage && !iptShow"
:src="selItem.giftImage"
alt=""
class="absolute h-214px object-contain bottom-[-440px] left-[-226%]"
:class="selItem.id === 2 && 'left-[-236%]'"
/>
<div
@click.stop
class="absolute right-[56%] top-150px h-190px w-450px pb-10px pt-6px box-border flex flex-col justify-between items-center"
>
<div class="text-36px leading bg-text"> {{ isSuccess ? '核销成功' : '报名成功' }} </div>
<div class="text-60px leading mt-[-4px] bg-text"> {{ selItem.giftName }} </div>
<!-- <div class="text-30px leading bg-text"> {{ isSuccess ? '' : selItem.activityRules }} </div> -->
<div class="text-30px leading bg-text"> 礼品发放以线下库存为准 先到先得 </div>
</div>
<div
v-if="iptShow"
@click.stop
class="absolute box-border right-[80px] top-[380px] h-76px w-415px rounded-10px bg-#FADDC0 overflow-hidden"
>
<nut-input
ref="iptRef"
:formatter="formatter"
format-trigger="onChange"
v-model="checkCode"
:border="false"
max-length="20"
placeholder="请输入核销码"
/>
</div>
<div
v-if="!isSuccess"
@click.prevent="handleIptShow"
class="absolute overflow-hidden text-center text-black top-520px right-150px rounded-32px h-65px w-290px leading-55px text-32px bg-btn"
>
{{ iptShow ? '立即核销' : '去核销' }}
</div>
</div>
</div>
</div>
</nut-overlay>
</template>
<script lang="ts" setup>
import { ref, nextTick, watch } from 'vue';
import { useRouter } from 'vue-router';
import { handleWxRedict, getQueryString } from '@/utils/util';
import shareWechat from '@/utils/wxH5Share';
import { getWxMpRequest, queryCoupon, queryVerification, queryCouponLog } from '@/api';
import { showToast } from '@nutui/nutui';
const { back, replace } = useRouter();
const urlCode = ref(getQueryString('code'));
const token = ref<string>(localStorage.getItem('token') || '');
const show = ref(false);
const iptShow = ref(!!sessionStorage.getItem('selId'));
const isSuccess = ref(false);
const iptRef = ref<HTMLInputElement>();
const checkCode = ref(''); //
const userInfo = ref<any>(localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user') || '') || {} : {}); //
const formatter = (value) => value.replace(/[^a-zA-Z0-9]/g, '');
const selId = ref<string>(sessionStorage.getItem('selId') || ''); // id
const overlayStyle = ref({
// backgroundColor: 'rgba(0, 0, 0, .6)',
});
const selItem = ref<any>({});
const list = ref<any>([]);
list.value = [];
const handleClick = async (item: any) => {
if (!token.value) return (location.href = handleWxRedict());
// state truefalse
if (item.state) {
selId.value = item.id;
selItem.value = item;
show.value = true;
isSuccess.value = false;
iptShow.value = true;
return;
}
const { result, code } = await queryCouponLog({ id: item.id, openId: userInfo.value.openid });
if (code === 200) {
selId.value = result.id;
sessionStorage.setItem('selId', selId.value);
selItem.value = item;
show.value = true;
isSuccess.value = false;
iptShow.value = false; /////
}
};
const closeOverlay = () => {
show.value = false;
};
const handleIptShow = async (e: Event) => {
e.preventDefault();
e.stopPropagation();
if (iptShow.value) {
if (!checkCode.value.trim())
return showToast.text('请输入核销码', {
duration: 1000,
});
try {
const req = { id: selItem.value.id, checkCode: checkCode.value, openId: userInfo.value.openid };
const { code } = await queryVerification(req);
if (code === 200) {
checkCode.value = '';
iptShow.value = false;
isSuccess.value = true;
}
} catch (error) {
showToast.text('核销码不正确!');
}
// show.value = false;
// showToast.success('', {
// duration: 2000,
// });
return;
}
iptShow.value = true;
nextTick(() => {
iptRef.value?.focus();
});
};
const handleShareWechat = () => {
// if (token.value) {
return shareWechat(
'SWFC寻味环球 共飨美馔',
'',
`${window.location.origin}`,
'https://huanqiuzhongxin.oss-cn-shanghai.aliyuncs.com/shipin/logo.png',
);
// window.location.origin
// } else location.href = handleWxRedict();
};
const getCoupon = async () => {
const { result } = await queryCoupon({ openId: userInfo.value?.openid });
if (result) {
list.value = result.records;
}
};
const init = async () => {
if (urlCode.value) {
const { result }: any = await getWxMpRequest({ code: urlCode.value });
if (result?.accessToken) {
token.value = result.accessToken;
localStorage.setItem('token', token.value);
if (result.user) {
localStorage.setItem('user', result.user);
try {
userInfo.value = JSON.parse(result.user);
} catch (e) {}
replace('/sale');
}
} else {
showToast.fail('获取token失败');
localStorage.removeItem('code');
replace('/sale');
}
} else {
const user = localStorage.getItem('user');
if (user) {
userInfo.value = JSON.parse(user);
}
}
getCoupon();
};
init();
handleShareWechat();
watch(show, (val) => {
if (val) {
checkCode.value = '';
} else {
getCoupon()
setTimeout(() => {
selId.value && (iptShow.value = true);
},200)
}
});
</script>
<style lang="scss" scoped>
.bgi-top {
background: url('@/assets/imgs/sale/fulyh.png') no-repeat;
background-size: contain;
}
.bg-beijing {
background: url('@/assets/imgs/sale/qbeij.png') no-repeat;
background-size: contain;
}
.bg-tbj {
background: url('@/assets/imgs/sale/tbj.png') no-repeat;
background-size: contain;
}
.bg-btn {
background: linear-gradient(to left, #eac89a, #ffe3cb);
}
.bg-text {
background: linear-gradient(to left, #e1c691, #fcf4dc, #e0c693);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.nut-input {
box-sizing: border-box;
padding: 10px 8px;
line-height: 54px;
background-color: transparent;
}
:deep {
.input-text {
font-size: 32px;
line-height: 54px;
}
.nut-toast-text {
font-size: 32px;
}
.nut-input-box input {
color: #000;
padding-left: 14px;
}
}
</style>

View File

@ -49,7 +49,12 @@
</div> </div>
</div> </div>
<div> <div>
<img v-if="item.nums <= 0 && !item.verifState" src="@/assets/imgs/sale/lingwan.png" alt="" class="w-166px object-contain mr-[-18px]" /> <img
v-if="item.nums <= 0 && !item.verifState"
src="@/assets/imgs/sale/lingwan.png"
alt=""
class="w-166px object-contain mr-[-18px]"
/>
<img v-if="item.verifState" src="@/assets/imgs/sale/hexiao.png" alt="" class="w-166px object-contain mr-[-18px]" /> <img v-if="item.verifState" src="@/assets/imgs/sale/hexiao.png" alt="" class="w-166px object-contain mr-[-18px]" />
</div> </div>
</div> </div>
@ -160,51 +165,21 @@
// backgroundColor: 'rgba(0, 0, 0, .6)', // backgroundColor: 'rgba(0, 0, 0, .6)',
}); });
const selItem = ref<any>({}); const selItem = ref<any>({});
const list = ref<any>([ const list = ref<any>([]);
{
id: 1,
title: '集赞有礼丨2,500份暖心福利大放送!',
day: '2023/12/1-2023/12/8',
time: '每日11:00-18:00',
content:
'活动规则分享主页至朋友圈集满10个赞即可凭朋友圈集赞页面至2F综合咨询台领取“真不二玫瑰颈贴”一盒。礼品共2,500份每人限领一份。',
remark: '礼物发放以线下发放为准,先到先得领完为止。',
subTit: '真不二玫瑰颈贴',
subRemark: '礼品发放以线下库存为准 先到先得',
count: 0,
unit: '',
img: new URL('@/assets/imgs/sale/huod1@2x.png', import.meta.url).href,
shopImg: new URL('@/assets/imgs/sale/jint@2x.png', import.meta.url).href,
},
{
id: 2,
title: '私飨岁末会聚丨包厢用餐即享350份精致礼遇!',
day: '2023/12/1-2024/1/1',
time: '',
content: `活动规则在SWFC指定餐厅晚市每日1700以后预订包厢并到店消费满1,000元可凭餐厅盖章的消费小票及支付凭证至2F综合咨询台每日2200前领取
Rever足浴SPA礼盒一份礼品共350份每人每天限领一份`,
remark: '礼物发放以线下发放为准,先到先得领完为止。',
subTit: 'Rever足浴SPA礼盒',
subRemark: '礼品发放以线下库存为准 先到先得',
count: 350,
unit: '份',
img: new URL('@/assets/imgs/sale/huod2@2x.png', import.meta.url).href,
shopImg: new URL('@/assets/imgs/sale/lihe@2x.png', import.meta.url).href,
},
]);
list.value = []; list.value = [];
const handleClick = async (item: any) => { const handleClick = async (item: any) => {
if (!token.value) return (location.href = handleWxRedict()); // if (!token.value) return (location.href = handleWxRedict());
// state truefalse // state truefalse
if (item.state) { // if (item.state) {
selId.value = item.id; selId.value = item.id;
selItem.value = item; selItem.value = item;
show.value = true; show.value = true;
isSuccess.value = false; isSuccess.value = false;
iptShow.value = true; iptShow.value = false;
// iptShow.value = true;
return; return;
} // }
const { result, code } = await queryCouponLog({ id: item.id, openId: userInfo.value.openid }); const { result, code } = await queryCouponLog({ id: item.id, openId: userInfo.value.openid });
if (code === 200) { if (code === 200) {
selId.value = result.id; selId.value = result.id;
@ -222,6 +197,9 @@
const handleIptShow = async (e: Event) => { const handleIptShow = async (e: Event) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return showToast.text('请联系工作人员进行核销!', {
duration: 3000,
});
if (iptShow.value) { if (iptShow.value) {
if (!checkCode.value.trim()) if (!checkCode.value.trim())
return showToast.text('请输入核销码', { return showToast.text('请输入核销码', {
@ -304,10 +282,10 @@
if (val) { if (val) {
checkCode.value = ''; checkCode.value = '';
} else { } else {
getCoupon() getCoupon();
setTimeout(() => { setTimeout(() => {
selId.value && (iptShow.value = true); selId.value && (iptShow.value = true);
},200) }, 200);
} }
}); });
</script> </script>

65
src/views/swfc/index-bak.vue Executable file
View File

@ -0,0 +1,65 @@
<template>
<div class="w-screen h-screen main relative">
<div @click="back" class="absolute z-10 top-30px left-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center">
<img class="w-32px h-29px" src="@/assets/imgs/bgo.png" alt="" />
</div>
<div class="bgi-top w-full h-378px absolute top-0 right-0 z-0"> </div>
<div class="w-full pt-378px pb-8px bg-black">
<div
@click="
push({
path: 'recommendShopDetail',
query: {
id: item.id,
},
})
"
class="relative"
v-for="item in data"
:key="item.id"
>
<template v-if="item.season">
<nut-animate v-show="pageShow" class="absolute bottom-350px right-180px" type="twinkle" :loop="true" />
<!-- <img class="w-750px object-contain" :src="item.season" /> -->
<nut-image lazy-load v-if="item.season" class="w-750px" :src="item.season" fit="contain">
<template #loading>
<div class="bg-black w-full h-full flex justify-center items-center rounded-md min-h-800px">
<Loading width="30px" height="30px" name="loading" />
</div>
</template>
</nut-image>
</template>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useRouter } from 'vue-router';
import { querySeason } from '@/api';
import { ref } from 'vue';
import { Loading } from '@nutui/icons-vue';
const { back, push } = useRouter();
const pageShow = ref(false);
const data = ref<any>([]);
const getSeason = async () => {
const { result } = await querySeason();
if (result) {
data.value = result;
}
setTimeout(() => {
pageShow.value = true;
}, 300);
};
getSeason();
</script>
<style lang="scss" scoped>
.bgi-top {
background: url('@/assets/imgs/swfc/cai1.png') no-repeat;
background-size: cover;
}
</style>

View File

@ -3,32 +3,47 @@
<div @click="back" class="absolute z-10 top-30px left-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center"> <div @click="back" class="absolute z-10 top-30px left-30px rounded-1/2 w-62px h-62px bg-[#4A4A4A] flex justify-center items-center">
<img class="w-32px h-29px" src="@/assets/imgs/bgo.png" alt="" /> <img class="w-32px h-29px" src="@/assets/imgs/bgo.png" alt="" />
</div> </div>
<div class="bgi-top w-full h-378px absolute top-0 right-0 z-0"> </div> <!-- <div class="bgi-top w-full h-378px absolute top-0 right-0 z-0"> </div> -->
<div class="w-full pt-378px pb-8px bg-black"> <div class="w-full pt-0px pb-8px bg-black" v-if="pageShow">
<div <!-- @click="
@click="
push({ push({
path: 'recommendShopDetail', path: 'recommendShopDetail',
query: { query: {
id: item.id, id: id,
}, },
}) })
" " -->
class="relative" <div class="relative" v-for="{ id } in shops" :key="id">
v-for="item in data" <nut-swiper
:key="item.id" v-if="menuList[id]"
:ref="(el) => (swiperRef[id] = el)"
@change="menuChange($event, id)"
class="swiper"
:init-page="menuList[id].page"
:loop="true"
:auto-play="5000"
> >
<template v-if="item.season"> <nut-swiper-item v-for="item in menuList[id].list" :key="'item' + id">
<nut-animate v-show="pageShow" class="absolute bottom-350px right-180px" type="twinkle" :loop="true" /> <nut-image :src="`${VITE_IMG_CND + id}/${item}.jpg`" fit="contain" :key="'swiper' + id + item">
<!-- <img class="w-750px object-contain" :src="item.season" /> -->
<nut-image lazy-load v-if="item.season" class="w-750px" :src="item.season" fit="contain">
<template #loading> <template #loading>
<div class="bg-black w-full h-full flex justify-center items-center rounded-md min-h-800px"> <div class="bg-black w-full h-full flex justify-center items-center">
<Loading width="30px" height="30px" name="loading" /> <Loading width="50px" height="50px" name="loading" />
</div> </div>
</template> </template>
</nut-image> </nut-image>
</nut-swiper-item>
<template #page>
<div class="page"> {{ menuList[id].current }}/{{ menuList[id].total }} </div>
</template> </template>
</nut-swiper>
<view class="nut-swiper-btns" v-show="swiperRef[id]">
<span class="nut-swiper-btns__left" @click="handlePrev(id)">
<Left></Left>
</span>
<span class="nut-swiper-btns__left" @click="handleNext(id)">
<Right></Right>
</span>
</view>
</div> </div>
</div> </div>
</div> </div>
@ -36,25 +51,50 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { querySeason } from '@/api'; import { queryShopPage } from '@/api';
import { ref } from 'vue'; import { ref, reactive } from 'vue';
import { Loading } from '@nutui/icons-vue'; import { Loading, Left, Right } from '@nutui/icons-vue';
const { back, push } = useRouter(); const { back, push } = useRouter();
const { VITE_IMG_CND } = import.meta.env;
const shops = ref<any>([]);
const pageShow = ref(false); const pageShow = ref(false);
const data = ref<any>([]); const swiperRef = ref<any>({});
const getSeason = async () => { const menuList = reactive({
const { result } = await querySeason(); '1727533181588086786': { list: [1, 2, 3], page: 0, current: 0, total: 3 },
if (result) { '1727970518397460481': { list: [1, 2, 3, 4, 5], page: 0, current: 0, total: 5 },
data.value = result; '1727966419073474561': { list: [1, 2], page: 0, current: 0, total: 2 },
} '1727969634947014658': { list: [1, 2, 3, 4, 5, 6, 7, 8], page: 0, current: 0, total: 8 },
setTimeout(() => { '1727961297983479810': { list: [1, 2, 3], page: 0, current: 0, total: 3 },
pageShow.value = true; '1727962509772431362': { list: [1, 2], page: 0, current: 0, total: 2 },
}, 300); });
const handlePrev = (id: string) => {
swiperRef.value[id]?.prev();
};
const handleNext = (id: string) => {
swiperRef.value[id]?.next();
};
const menuChange = (index: number, id: string) => {
const { total } = menuList[id];
menuList[id].current = index + 1 > total ? 1 : index + 1;
}; };
getSeason(); const getShopList = async () => {
const { result } = await queryShopPage({
current: 1,
pageSize: 100,
});
if (result) {
shops.value = result?.records || [];
setTimeout(() => {
pageShow.value = true;
}, 150);
}
};
getShopList();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -62,4 +102,47 @@
background: url('@/assets/imgs/swfc/cai1.png') no-repeat; background: url('@/assets/imgs/swfc/cai1.png') no-repeat;
background-size: cover; background-size: cover;
} }
.page {
position: absolute;
bottom: 0;
right: 0;
width: 70px;
height: 38px;
border-radius: 19px 19px 19px 19px;
opacity: 0.5;
background: #000000;
text-align: center;
color: #fff;
font-size: 24px;
}
.nut-swiper-btns {
width: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 1;
display: flex;
justify-content: space-between;
padding: 0 20px;
box-sizing: border-box;
}
.nut-swiper-btns span {
display: flex;
align-items: center;
justify-content: center;
width: 64px;
height: 80px;
background-color: rgba(0, 0, 0, 0.2);
}
:deep {
.swiper {
.nut-swiper-inner {
height: auto !important;
}
.nut-swiper-item {
line-height: 1;
height: auto;
}
}
}
</style> </style>