feat: 新增index.html文件并更新多个页面样式和结构

This commit is contained in:
pikachu1995@126.com
2026-07-06 13:53:54 +08:00
parent 5f293d929d
commit b1743cefb0
20 changed files with 821 additions and 288 deletions

View File

@@ -58,7 +58,7 @@ LILISHOP 是基于 Spring Boot / Spring Cloud / Vue / Uniapp 开发的 Java 开
### 1. 项目简介 ### 1. 项目简介
**Lilishop** 是一款功能完善的B2B2C多商户商城系统采用前后端分离架构全端代码开源。 **Lilishop** 是一款功能完善的B2B2C多商户商城系统采用前后端分离架构全端代码开源。
后端基于 **SpringBoot3** 构建,具备高内聚、低耦合的特性,支持分布式部署。 后端基于 **SpringBoot4** 构建,具备高内聚、低耦合的特性,支持分布式部署。
前端覆盖PC、H5、小程序和APP基于 **Vue****uni-app** 开发。 前端覆盖PC、H5、小程序和APP基于 **Vue****uni-app** 开发。
- **官方网站**: <https://pickmall.cn> - **官方网站**: <https://pickmall.cn>

View File

@@ -15,12 +15,13 @@
<script> <script>
import config from "@/config/config"; import config from "@/config/config";
import logoImg from "@/icon.png";
export default { export default {
data() { data() {
return { return {
config, // 设置工具类 config, // 设置工具类
weChat: false, // 是否微信浏览器该项为true时不显示 当前整个页面 weChat: false, // 是否微信浏览器该项为true时不显示 当前整个页面
logo: require("@/icon.png"), //显示的圆形logo logo: logoImg, //显示的圆形logo
}; };
}, },
mounted() { mounted() {

View File

@@ -20,13 +20,14 @@
<script> <script>
// 引入绘制插件 // 引入绘制插件
import DrawPoster from "@/js_sdk/u-draw-poster"; import DrawPoster from "@/js_sdk/u-draw-poster";
import logoImg from "@/pages/passport/static/logo-title.png";
export default { export default {
data: () => ({ data: () => ({
imgUrl: "", //绘制出来的图片路径 imgUrl: "", //绘制出来的图片路径
show: false, //是否展示模态框 show: false, //是否展示模态框
dp: {}, //绘制的dp对象用于存储绘制等一些方法。 dp: {}, //绘制的dp对象用于存储绘制等一些方法。
logo: require("@/pages/passport/static/logo-title.png"), //本地logo地址 logo: logoImg, //本地logo地址
}), }),
props: { props: {

View File

@@ -213,7 +213,8 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: 10rpx 20rpx 284rpx; margin: 10rpx 20rpx 284rpx;
width: 100%; width: calc(100% - 40rpx);
box-sizing: border-box;
&.goods-list--embedded { &.goods-list--embedded {
margin-bottom: 20rpx; margin-bottom: 20rpx;

View File

@@ -18,14 +18,16 @@
import DrawPoster from "@/js_sdk/u-draw-poster"; import DrawPoster from "@/js_sdk/u-draw-poster";
// 生成二维码 // 生成二维码
import uQRCode from '@/components/Sansnn-uQRCode/uqrcode.js'; import uQRCode from '@/components/Sansnn-uQRCode/uqrcode.js';
import logoImg from "@/pages/passport/static/logo-title.png";
import myFaceImg from "@/pages/passport/static/missing-face.png";
export default { export default {
data: () => ({ data: () => ({
imgUrl: "", //绘制出来的图片路径 imgUrl: "", //绘制出来的图片路径
show: false, //是否展示模态框 show: false, //是否展示模态框
dp: {}, //绘制的dp对象用于存储绘制等一些方法。 dp: {}, //绘制的dp对象用于存储绘制等一些方法。
logo: require("@/pages/passport/static/logo-title.png"), // 本地logo地址 logo: logoImg, // 本地logo地址
myFace: require("@/pages/passport/static/missing-face.png"), // 本地默认头像 myFace: myFaceImg, // 本地默认头像
sharingLink: '', // 二维码链接 sharingLink: '', // 二维码链接
}), }),
props: { props: {

View File

@@ -2,10 +2,11 @@
<view class="xt__verify-code"> <view class="xt__verify-code">
<!-- 输入框 --> <!-- 输入框 -->
<input <input
ref="codeInput"
id="xt__input" id="xt__input"
:value="code" :value="code"
class="xt__input" class="xt__input"
:focus="isFocus" :focus="focused"
:password="isPassword" :password="isPassword"
:type="inputType" :type="inputType"
:maxlength="size" :maxlength="size"
@@ -23,7 +24,7 @@
></view> ></view>
<!-- 输入框 - --> <!-- 输入框 - -->
<view id="xt__input-ground" class="xt__input-ground"> <view id="xt__input-ground" class="xt__input-ground" @click="focusInput">
<template v-for="(item, index) in size" :key="index"> <template v-for="(item, index) in size" :key="index">
<view <view
:style="{ borderColor: code.length === index && cursorVisible ? boxActiveColor : boxNormalColor }" :style="{ borderColor: code.length === index && cursorVisible ? boxActiveColor : boxNormalColor }"
@@ -51,7 +52,12 @@
*/ */
export default { export default {
name: 'xt-verify-code', name: 'xt-verify-code',
emits: ['update:modelValue', 'input', 'confirm'],
props: { props: {
modelValue: {
type: String,
default: () => ''
},
value: { value: {
type: String, type: String,
default: () => '' default: () => ''
@@ -89,12 +95,9 @@ export default {
default: () => '#000000' default: () => '#000000'
} }
}, },
model: {
prop: 'value',
event: 'input'
},
data() { data() {
return { return {
focused: false,
cursorVisible: false, cursorVisible: false,
cursorHeight: 35, cursorHeight: 35,
code: '', // 输入的验证码 code: '', // 输入的验证码
@@ -102,12 +105,31 @@ export default {
}; };
}, },
created() { created() {
this.code = this.modelValue || this.value || '';
this.focused = this.isFocus;
this.cursorVisible = this.isFocus; this.cursorVisible = this.isFocus;
}, },
mounted() { mounted() {
this.init(); this.init();
if (this.isFocus) {
this.$nextTick(() => {
this.focusInput();
});
}
}, },
methods: { methods: {
focusInput() {
this.focused = false;
this.$nextTick(() => {
this.focused = true;
// #ifdef H5
const inputEl = this.$refs.codeInput;
if (inputEl && typeof inputEl.focus === 'function') {
inputEl.focus();
}
// #endif
});
},
/** /**
* @description 初始化 * @description 初始化
*/ */
@@ -159,7 +181,9 @@ export default {
// 输入框输入变化的回调 // 输入框输入变化的回调
input(e) { input(e) {
const value = e.detail.value; const value = e.detail.value;
this.code = value;
this.cursorVisible = value.length !== this.size; this.cursorVisible = value.length !== this.size;
this.$emit('update:modelValue', value);
this.$emit('input', value); this.$emit('input', value);
this.inputSuccess(value); this.inputSuccess(value);
}, },
@@ -187,8 +211,11 @@ export default {
} }
}, },
watch: { watch: {
modelValue(val) {
this.code = val || '';
},
value(val) { value(val) {
this.code = val; this.code = val || '';
} }
} }
}; };
@@ -200,11 +227,13 @@ export default {
box-sizing: border-box; box-sizing: border-box;
.xt__input { .xt__input {
height: 100%;
width: 200%;
position: absolute; position: absolute;
left: -100%; top: 0;
z-index: 1; left: 0;
height: 100%;
width: 100%;
opacity: 0;
z-index: 2;
} }
.xt__cursor { .xt__cursor {
position: absolute; position: absolute;
@@ -212,6 +241,8 @@ export default {
transform: translateY(-50%); transform: translateY(-50%);
display: inline-block; display: inline-block;
width: 2px; width: 2px;
z-index: 1;
pointer-events: none;
animation-name: cursor; animation-name: cursor;
animation-duration: 0.8s; animation-duration: 0.8s;
animation-iteration-count: infinite; animation-iteration-count: infinite;
@@ -223,11 +254,14 @@ export default {
align-items: center; align-items: center;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
position: relative;
z-index: 1;
.xt__box { .xt__box {
position: relative; position: relative;
display: inline-block; display: inline-block;
width: 76rpx; width: 76rpx;
height: 112rpx; height: 112rpx;
pointer-events: none;
&-bottom { &-bottom {
border-bottom-width: 2px; border-bottom-width: 2px;
border-bottom-style: solid; border-bottom-style: solid;

View File

@@ -15,7 +15,7 @@ export default {
imWebSrc: "https://im.pickmall.cn", //IM地址 imWebSrc: "https://im.pickmall.cn", //IM地址
baseWsUrl: "wss://im-api.pickmall.cn/lili/webSocket", // IM WS 地址 baseWsUrl: "wss://im-api.pickmall.cn/lili/webSocket", // IM WS 地址
enableGetClipboard: false, //是否启用粘贴板获取 scanAuthNavigation 中的链接,如果匹配则会跳转到对应页面 enableGetClipboard: false, //是否启用粘贴板获取 scanAuthNavigation 中的链接,如果匹配则会跳转到对应页面
enableMiniBarStartUpApp: true, //是否在h5中右侧浮空按钮点击启动app enableMiniBarStartUpApp: false, //是否在h5中右侧浮空按钮点击启动app
/** /**
* 如需更换主题请修改此处以及uni.scss中的全局颜色 * 如需更换主题请修改此处以及uni.scss中的全局颜色
*/ */

17
index.html Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

View File

@@ -14,17 +14,17 @@
</view> </view>
</view> </view>
<u-cell-group class="cell-group"> <u-cell-group class="cell-group" :border="false">
<!-- #ifdef APP-PLUS --> <!-- #ifdef APP-PLUS -->
<u-cell v-if="IosWhether" isLink title="去评分" @click="checkStar"></u-cell> <u-cell v-if="IosWhether" is-link title="去评分" @click="checkStar"></u-cell>
<u-cell isLink title="功能介绍" @click="navigateTo('/pages/mine/set/versionFunctionList')"></u-cell> <u-cell is-link title="功能介绍" @click="navigateTo('/pages/mine/set/versionFunctionList')"></u-cell>
<u-cell isLink title="检查更新" @click="checkUpdate"></u-cell> <u-cell is-link title="检查更新" @click="checkUpdate"></u-cell>
<!-- #endif --> <!-- #endif -->
<u-cell isLink title="证照信息" @click="navigateTo('/pages/mine/help/tips?type=LICENSE_INFORMATION')"></u-cell> <u-cell is-link title="证照信息" @click="navigateTo('/pages/mine/help/tips?type=LICENSE_INFORMATION')"></u-cell>
<u-cell isLink title="服务协议" @click="navigateTo('/pages/mine/help/tips?type=USER_AGREEMENT')"></u-cell> <u-cell is-link title="服务协议" @click="navigateTo('/pages/mine/help/tips?type=USER_AGREEMENT')"></u-cell>
<u-cell isLink title="隐私协议" @click="navigateTo('/pages/mine/help/tips?type=PRIVACY_POLICY')"></u-cell> <u-cell is-link title="隐私协议" @click="navigateTo('/pages/mine/help/tips?type=PRIVACY_POLICY')"></u-cell>
<u-cell isLink title="关于我们" @click="navigateTo('/pages/mine/help/tips?type=ABOUT')"></u-cell> <u-cell is-link title="关于我们" @click="navigateTo('/pages/mine/help/tips?type=ABOUT')"></u-cell>
</u-cell-group> </u-cell-group>
<view class="intro"> <view class="intro">
@@ -131,21 +131,25 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
page { page {
background: #fff !important; background: #f8f8f8 !important;
} }
.edition-intro { .edition-intro {
width: 100%;
min-height: 100vh; min-height: 100vh;
background: #fff; box-sizing: border-box;
background: #f8f8f8;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
} }
.header-block { .header-block {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 80rpx 0 48rpx; padding: 60rpx 0 40rpx;
background: #fff;
} }
.logo { .logo {
@@ -169,10 +173,20 @@ page {
.cell-group { .cell-group {
width: 100%; width: 100%;
margin-top: 20rpx;
background: #fff;
}
:deep(.u-cell-group) {
width: 100%;
} }
:deep(.u-cell) { :deep(.u-cell) {
padding: 0 30rpx; width: 100%;
}
:deep(.u-cell__body) {
padding: 28rpx 30rpx;
} }
:deep(.u-cell__title-text) { :deep(.u-cell__title-text) {
@@ -184,23 +198,35 @@ page {
color: #ccc !important; color: #ccc !important;
} }
:deep(.u-line) {
width: 100% !important;
margin: 0 !important;
}
.intro { .intro {
margin-top: auto; margin-top: auto;
width: 100%; width: 100%;
padding: 48rpx 40rpx 60rpx; padding: 48rpx 40rpx calc(80rpx + env(safe-area-inset-bottom));
text-align: center; text-align: center;
font-size: 24rpx; font-size: 24rpx;
line-height: 1.6; line-height: 1.8;
color: #666; color: #666;
letter-spacing: 1rpx; letter-spacing: 1rpx;
box-sizing: border-box; box-sizing: border-box;
} }
.intro-line { .intro-line {
margin-top: 16rpx; margin-top: 12rpx;
} }
.intro-link { .intro-link {
color: #003a8c; color: #003a8c;
} }
</style> </style>
<style lang="scss">
/* #ifdef H5 */
page {
min-height: 100vh;
}
/* #endif */
</style>

View File

@@ -1,36 +1,55 @@
<template> <template>
<div class="feedBack"> <view class="feedBack">
<div class="feedBack-box"> <view class="feedBack-box">
<h4>猜你想问</h4> <view class="box-title">猜你想问</view>
<div class="feedBack-item" :class="{'active':feedBack.type == item.value }" @click="handleClick(index)" v-for="(item,index) in list" :key="index"> <view
class="feedBack-item"
:class="{ active: feedBack.type == item.value }"
@click="handleClick(index)"
v-for="(item, index) in list"
:key="index"
>
{{ item.text }} {{ item.text }}
</div> </view>
</div> </view>
<div class="feedBack-box"> <view class="feedBack-box">
<h4>问题反馈 <span style="margin-left:10rpx;" v-if="feedBack.type">@{{ list.find(item=>{return item.value == feedBack.type }).text }}</span></h4> <view class="box-title">问题反馈
<u-input class="field-input" height="500" border="none" v-model="feedBack.context" type="textarea" placeholder="请输入反馈信息"> <text class="box-tag" v-if="feedBack.type">@{{ list.find(item => item.value == feedBack.type).text }}</text>
</u-input> </view>
</div> <u-textarea
class="field-textarea"
v-model="feedBack.context"
placeholder="请输入反馈信息"
border="none"
height="240"
maxlength="500"
></u-textarea>
</view>
<!-- 上传凭证 --> <!-- 上传凭证 -->
<div class="feedBack-box"> <view class="feedBack-box">
<view class="opt-view"> <view class="box-title">上传凭证最多2张</view>
<view class="img-title">上传凭证最多2张</view>
<view class="images-view"> <view class="images-view">
<u-upload :file-list="uploadFileList" :auto-upload="false" width="150" @afterRead="onUploadAfterRead" :max-count="2"></u-upload> <u-upload :file-list="uploadFileList" :auto-upload="false" width="150" @afterRead="onUploadAfterRead" :max-count="2"></u-upload>
</view> </view>
</view> </view>
</div>
<div class="feedBack-box"> <view class="feedBack-box">
<h4>手机号</h4> <view class="box-title">手机号</view>
<u-input border="none" v-model="feedBack.mobile" placeholder="请输入您的手机号"> <u-input
</u-input> class="field-input"
</div> v-model="feedBack.mobile"
type="number"
maxlength="11"
border="none"
placeholder="请输入您的手机号"
:custom-style="inputStyle"
></u-input>
</view>
<div class="submit" @click="submit()">提交</div> <view class="submit" @click="submit()">提交</view>
</div> </view>
</template> </template>
@@ -45,7 +64,15 @@ export default {
storage, storage,
config, config,
feedBack: { feedBack: {
type: "FUNCTION", //默认反馈问题为 '功能相关' type: "FUNCTION",
context: "",
mobile: "",
},
inputStyle: {
background: "#fafafa",
borderRadius: "12rpx",
padding: "0 24rpx",
height: "80rpx",
}, },
uploadFileList: [], uploadFileList: [],
list: [ list: [
@@ -116,49 +143,86 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
page {
background: #f8f8f8;
}
.submit { .submit {
text-align: center; text-align: center;
background: $light-color; background: $light-color;
height: 70rpx; height: 88rpx;
line-height: 70rpx; line-height: 88rpx;
color: #fff; color: #fff;
width: 92%; width: 92%;
margin-bottom: 100rpx; margin: 40rpx auto 60rpx;
margin: 0 auto;
border-radius: 100px; border-radius: 100px;
font-size: 30rpx;
} }
.active { .active {
color: $light-color !important; color: $light-color !important;
font-weight: bold; font-weight: bold;
} }
.feedBack { .feedBack {
padding-bottom: 100rpx; width: 100%;
box-sizing: border-box;
padding: 20rpx 24rpx 40rpx;
min-height: 100vh;
background: #f8f8f8;
} }
.feedBack-box { .feedBack-box {
background: #fff; background: #fff;
border-radius: 20rpx; border-radius: 20rpx;
padding: 32rpx; padding: 32rpx;
margin-bottom: 40rpx; margin-bottom: 20rpx;
} }
::v-deep .u-input__textarea {
padding: 12px; .box-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
} }
.feedBack-box:nth-of-type(1) {
border-top-left-radius: 0; .box-tag {
border-top-right-radius: 0; margin-left: 10rpx;
font-size: 26rpx;
font-weight: normal;
color: $light-color;
} }
.feedBack-item { .feedBack-item {
margin: 20rpx 0; margin: 20rpx 0;
font-size: 24rpx; font-size: 28rpx;
color: #666; color: #666;
} }
h4 {
font-size: 30rpx; .field-textarea {
margin-top: 20rpx;
:deep(.u-textarea) {
background: #fafafa !important;
border-radius: 12rpx;
padding: 20rpx;
box-sizing: border-box;
} }
:deep(.u-textarea__field) {
width: 100%;
font-size: 28rpx;
line-height: 1.6;
color: #333;
}
}
.field-input { .field-input {
margin: 20rpx 0; margin-top: 20rpx;
padding: 20rpx 0; width: 100%;
background: #fafafa; }
border-radius: 0.6em;
.images-view {
margin-top: 20rpx;
} }
</style> </style>

View File

@@ -14,21 +14,21 @@
<u-icon color="#ccc" name="arrow-right" size="16"></u-icon> <u-icon color="#ccc" name="arrow-right" size="16"></u-icon>
</view> </view>
<u-cell-group class="cell-group"> <u-cell-group class="cell-group" :border="false">
<!-- #ifdef APP-PLUS --> <!-- #ifdef APP-PLUS -->
<u-cell :isLink="false" title="清除缓存" :value="fileSizeString" @click="clearCache"></u-cell> <u-cell is-link title="清除缓存" :value="fileSizeString" @click="clearCache"></u-cell>
<!-- #endif --> <!-- #endif -->
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
<u-cell <u-cell
:isLink="false" is-link
title="安全中心" title="安全中心"
@click="navigateTo('/pages/mine/set/securityCenter/securityCenter')" @click="navigateTo('/pages/mine/set/securityCenter/securityCenter')"
></u-cell> ></u-cell>
<!-- #endif --> <!-- #endif -->
<u-cell :isLink="false" title="用户注销" v-if="userInfo.id" @click="logoff"></u-cell> <u-cell is-link title="用户注销" v-if="userInfo.id" @click="logoff"></u-cell>
<u-cell :isLink="false" title="意见反馈" @click="navigateTo('/pages/mine/set/feedBack')"></u-cell> <u-cell is-link title="意见反馈" @click="navigateTo('/pages/mine/set/feedBack')"></u-cell>
<u-cell <u-cell
:isLink="false" is-link
:title="`关于${config.name}`" :title="`关于${config.name}`"
@click="navigateTo('/pages/mine/set/editionIntro')" @click="navigateTo('/pages/mine/set/editionIntro')"
></u-cell> ></u-cell>
@@ -148,12 +148,14 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
page { page {
background: #fff !important; background: #f8f8f8 !important;
} }
.set-up { .set-up {
width: 100%;
min-height: 100vh; min-height: 100vh;
background: #fff; box-sizing: border-box;
background: #f8f8f8;
} }
.person { .person {
@@ -161,6 +163,7 @@ page {
align-items: center; align-items: center;
padding: 36rpx 30rpx; padding: 36rpx 30rpx;
background: #fff; background: #fff;
border-bottom: 1rpx solid #ededed;
} }
.user-name { .user-name {
@@ -176,10 +179,20 @@ page {
.cell-group { .cell-group {
width: 100%; width: 100%;
margin-top: 20rpx;
background: #fff;
}
:deep(.u-cell-group) {
width: 100%;
} }
:deep(.u-cell) { :deep(.u-cell) {
padding: 0 30rpx; width: 100%;
}
:deep(.u-cell__body) {
padding: 28rpx 30rpx;
} }
:deep(.u-cell__title-text) { :deep(.u-cell__title-text) {
@@ -191,6 +204,15 @@ page {
color: #ccc !important; color: #ccc !important;
} }
:deep(.u-cell__right-icon-wrap) {
color: #ccc !important;
}
:deep(.u-line) {
width: 100% !important;
margin: 0 !important;
}
.submit { .submit {
height: 90rpx; height: 90rpx;
line-height: 90rpx; line-height: 90rpx;

View File

@@ -136,8 +136,9 @@ page {
.scoll-page, .scoll-page,
.goods-scroll { .goods-scroll {
flex: 1; flex: 1;
height: 0; min-height: 0;
overflow: auto; height: 100%;
box-sizing: border-box;
} }
.search-navbar-wrap { .search-navbar-wrap {
@@ -170,6 +171,30 @@ page {
flex-direction: column; flex-direction: column;
} }
/* #ifdef H5 */
.content--goods {
height: auto;
min-height: 100vh;
overflow: visible;
}
.goods-content--h5 {
flex: none;
min-height: auto;
overflow: visible;
}
.goods-list-wrap {
padding-bottom: 40rpx;
}
.sort-navbar {
position: sticky;
top: 0;
z-index: 9;
}
/* #endif */
.index-nav-arrow:last-child { .index-nav-arrow:last-child {
margin-top: -22rpx; margin-top: -22rpx;
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<view class="content"> <view class="content" :class="{ 'content--goods': isShowSeachGoods }">
<u-navbar <u-navbar
:bg-color="navObj.background" :bg-color="navObj.background"
:auto-back="false" :auto-back="false"
@@ -75,8 +75,8 @@
</div> </div>
</view> </view>
<!-- 搜索 --> <!-- 搜索 -->
<view class="goods-content" v-if="isShowSeachGoods"> <view class="goods-content" :class="{ 'goods-content--h5': isShowSeachGoods }" v-if="isShowSeachGoods">
<view class="navbar"> <view class="navbar sort-navbar">
<view class="nav-item" :class="{ current: filterIndex === 0 }" @click="tabClick(0)">综合排序</view> <view class="nav-item" :class="{ current: filterIndex === 0 }" @click="tabClick(0)">综合排序</view>
<view class="nav-item" :class="{ current: filterIndex === 3 }" @click="tabClick(3, 'buyCount')"> <view class="nav-item" :class="{ current: filterIndex === 3 }" @click="tabClick(3, 'buyCount')">
<text>销量</text> <text>销量</text>
@@ -106,23 +106,36 @@
</view> </view>
<view class="nav-item" @click="sortGoods">筛选</view> <view class="nav-item" @click="sortGoods">筛选</view>
</view> </view>
<!-- #ifdef H5 -->
<view v-if="!empty && isSWitch" class="goods-list-wrap">
<goodsList :res="goodsList" type="oneColumns" :keyword="keyword" :tab-bar-gap="false" />
<uni-load-more :status="loadingType" @clickLoadMore="loadmore"></uni-load-more>
</view>
<view v-if="!empty && !isSWitch && goodsList.length" class="goods-list-wrap">
<goodsList :res="goodsList" :keyword="keyword" :tab-bar-gap="false" />
<uni-load-more :status="loadingType" @clickLoadMore="loadmore"></uni-load-more>
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<!-- 一行一个商品展示 --> <!-- 一行一个商品展示 -->
<scroll-view <scroll-view
v-if="!empty && isSWitch" v-if="!empty && isSWitch"
class="goods-scroll" class="goods-scroll"
:style="goodsScrollStyle"
enableBackToTop="true" enableBackToTop="true"
lower-threshold="250" lower-threshold="250"
@scrolltolower="loadmore()" @scrolltolower="loadmore()"
scroll-with-animation scroll-with-animation
scroll-y scroll-y
> >
<goodsList :res="goodsList" type="oneColumns" :keyword="keyword" /> <goodsList :res="goodsList" type="oneColumns" :keyword="keyword" :tab-bar-gap="false" />
<uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more> <uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more>
</scroll-view> </scroll-view>
<!-- 一行两个商品展示 --> <!-- 一行两个商品展示 -->
<scroll-view <scroll-view
v-if="!empty && !isSWitch && goodsList.length" v-if="!empty && !isSWitch && goodsList.length"
class="goods-scroll" class="goods-scroll"
:style="goodsScrollStyle"
scroll-anchoring scroll-anchoring
enableBackToTop="true" enableBackToTop="true"
@scrolltolower="loadmore()" @scrolltolower="loadmore()"
@@ -130,9 +143,10 @@
scroll-y scroll-y
lower-threshold="250" lower-threshold="250"
> >
<goodsList :res="goodsList" :keyword="keyword" /> <goodsList :res="goodsList" :keyword="keyword" :tab-bar-gap="false" />
<uni-load-more :status="loadingType"></uni-load-more> <uni-load-more :status="loadingType"></uni-load-more>
</scroll-view> </scroll-view>
<!-- #endif -->
<view class="empty" v-if="empty"> <view class="empty" v-if="empty">
<image class="empty-img" src="/static/nodata.png" mode="aspectFit"></image> <image class="empty-img" src="/static/nodata.png" mode="aspectFit"></image>
@@ -296,6 +310,7 @@ export default {
routerVal: '', routerVal: '',
capsuleInsetRight: 0, capsuleInsetRight: 0,
searchNavbarWidth: 0, searchNavbarWidth: 0,
goodsScrollHeight: 0,
}; };
}, },
@@ -310,6 +325,14 @@ export default {
width: '100%', width: '100%',
}; };
}, },
goodsScrollStyle() {
if (this.goodsScrollHeight > 0) {
return {
height: `${this.goodsScrollHeight}px`,
};
}
return {};
},
}, },
onPageScroll(e) { onPageScroll(e) {
@@ -352,6 +375,20 @@ export default {
}, },
onReady() { onReady() {
this.setSearchNavbarWidth(); this.setSearchNavbarWidth();
this.calcGoodsScrollHeight();
},
onShow() {
this.calcGoodsScrollHeight();
},
mounted() {
// #ifdef H5
window.addEventListener('resize', this.calcGoodsScrollHeight);
// #endif
},
beforeUnmount() {
// #ifdef H5
window.removeEventListener('resize', this.calcGoodsScrollHeight);
// #endif
}, },
components: { components: {
mSearch, mSearch,
@@ -374,15 +411,49 @@ export default {
if (val) { if (val) {
this.selectedWay = { brand: [], categoryId: [], prop: [] }; this.selectedWay = { brand: [], categoryId: [], prop: [] };
} }
},
isShowSeachGoods(val) {
if (val) {
this.$nextTick(() => {
this.calcGoodsScrollHeight();
});
}
},
isSWitch() {
this.$nextTick(() => {
this.calcGoodsScrollHeight();
});
} }
}, },
onReachBottom() { onReachBottom() {
this.params.pageNumber++; // #ifdef H5
this.loadData(); if (!this.isShowSeachGoods || this.loadingType !== 'more') {
return;
}
this.loadmore();
// #endif
}, },
methods: { methods: {
calcGoodsScrollHeight() {
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.goods-content').boundingClientRect();
query.select('.goods-content .navbar').boundingClientRect();
query.exec((res) => {
const contentRect = res[0];
const navbarRect = res[1];
if (!contentRect) {
return;
}
const sortBarHeight = navbarRect ? navbarRect.height : uni.upx2px(80);
const { windowHeight } = uni.getWindowInfo();
const height = Math.max(contentRect.height, windowHeight - contentRect.top) - sortBarHeight;
this.goodsScrollHeight = Math.max(height, 0);
});
});
},
setSearchNavbarWidth() { setSearchNavbarWidth() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
try { try {
@@ -529,6 +600,9 @@ export default {
}); });
}, },
loadmore() { loadmore() {
if (this.loadingType !== 'more') {
return;
}
this.params.pageNumber++; this.params.pageNumber++;
this.loadData(); this.loadData();
}, },
@@ -663,6 +737,9 @@ export default {
this.empty = this.goodsList.length === 0; this.empty = this.goodsList.length === 0;
this.initSortGoods(); this.initSortGoods();
this.$nextTick(() => {
this.calcGoodsScrollHeight();
});
if (this.$store.state.isShowToast){ uni.hideLoading() }; if (this.$store.state.isShowToast){ uni.hideLoading() };
}, },
@@ -778,3 +855,12 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import './search.scss'; @import './search.scss';
</style> </style>
<style lang="scss">
/* #ifdef H5 */
page {
height: auto;
min-height: 100vh;
overflow-y: auto;
}
/* #endif */
</style>

View File

@@ -3,8 +3,8 @@
<!-- 订单状态 --> <!-- 订单状态 -->
<div class="info-view order-view"> <div class="info-view order-view">
<div class="order-status" v-if="orderStatusMap[order.orderStatus]"> <div class="order-status" v-if="orderStatusMap[order.orderStatus]">
{{ orderStatusMap[order.orderStatus].title }} <view class="order-status-title">{{ orderStatusMap[order.orderStatus].title }}</view>
<div>{{ orderStatusMap[order.orderStatus].value }}</div> <view class="order-status-desc">{{ orderStatusMap[order.orderStatus].value }}</view>
</div> </div>
</div> </div>
@@ -573,11 +573,14 @@ export default {
color: #fff; color: #fff;
width: 100%; width: 100%;
text-align: center; text-align: center;
font-size: 30rpx;
font-weight: 500;
margin-top: 36rpx; margin-top: 36rpx;
>div { .order-status-title {
font-size: 44rpx;
font-weight: 600;
}
.order-status-desc {
font-size: 22rpx; font-size: 22rpx;
font-weight: normal; font-weight: normal;
margin-top: 8rpx; margin-top: 8rpx;

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div v-if="!wechatLogin"> <div v-if="!wechatLogin" class="login-body">
<u-navbar :auto-back="showBack" :border="false"></u-navbar> <u-navbar :auto-back="showBack" :border="false"></u-navbar>
<div> <div>
<div class="title">{{ loginTitleWay[current].title }}</div> <div class="title">{{ loginTitleWay[current].title }}</div>
@@ -12,16 +12,34 @@
<!-- 手机号 --> <!-- 手机号 -->
<div v-show="!enableUserPwdBox"> <div v-show="!enableUserPwdBox">
<div v-show="current == 0"> <div v-show="current == 0">
<u-input :custom-style="inputStyle" :placeholder-style="placeholderStyle" placeholder="请输入手机号 (11位)" <u-input
class="mobile" focus v-model="mobile" type="number" maxlength="11" /> border="none"
:custom-style="inputStyle"
:placeholder-style="placeholderStyle"
font-size="40rpx"
color="#333"
placeholder="请输入手机号 (11位)"
class="mobile"
focus
v-model="mobile"
type="number"
maxlength="11"
/>
<div :class="!enableFetchCode ? 'disable' : 'fetch'" @click="fetchCode" class="btn"> <div :class="!enableFetchCode ? 'disable' : 'fetch'" @click="fetchCode" class="btn">
获取验证码 获取验证码
</div> </div>
</div> </div>
<!-- 输入验证码 --> <!-- 输入验证码 -->
<div v-show="current == 1" class="box-code"> <div v-if="current == 1" class="box-code">
<verifyCode type="bottom" @confirm="submit" boxActiveColor="#D8D8D8" v-model="code" isFocus <verifyCode
boxNormalColor="#D8D8D8" cursorColor="#D8D8D8" /> type="bottom"
@confirm="submit"
boxActiveColor="#D8D8D8"
v-model="code"
:is-focus="true"
boxNormalColor="#D8D8D8"
cursorColor="#D8D8D8"
/>
<div class="fetch-btn"> <div class="fetch-btn">
<u-code change-text="验证码已发送x" end-text="重新获取验证码" unique-key="page-login" <u-code change-text="验证码已发送x" end-text="重新获取验证码" unique-key="page-login"
@@ -35,18 +53,44 @@
<!-- 帐号密码登录 --> <!-- 帐号密码登录 -->
<div v-show="enableUserPwdBox"> <div v-show="enableUserPwdBox">
<u-input :custom-style="inputStyle" :placeholder-style="placeholderStyle" placeholder="请输入用户名" <u-input
class="mobile" focus v-model="userData.username" /> border="none"
<u-input :custom-style="inputStyle" :placeholder-style="placeholderStyle" placeholder="请输入密码" :custom-style="inputStyle"
class="mobile" focus v-model="userData.password" type="password" /> :placeholder-style="placeholderStyle"
font-size="40rpx"
color="#333"
placeholder="请输入用户名"
class="mobile"
focus
v-model="userData.username"
/>
<u-input
border="none"
:custom-style="inputStyle"
:placeholder-style="placeholderStyle"
font-size="40rpx"
color="#333"
placeholder="请输入密码"
class="mobile"
focus
v-model="userData.password"
type="password"
/>
<div :class="!enableUserBtnColor ? 'disable' : 'fetch'" @click="passwordLogin" class="btn"> <div :class="!enableUserBtnColor ? 'disable' : 'fetch'" @click="passwordLogin" class="btn">
帐号密码登录 帐号密码登录
</div> </div>
</div> </div>
<div class="flex" v-show="current != 1"> <div class="privacy-row" v-show="current != 1">
<u-checkbox usedAlone :icon-size="24" shape="circle" v-model:checked="enablePrivacy" active-color="#FF5E00"></u-checkbox> <u-checkbox
class="privacy-check"
usedAlone
shape="circle"
v-model:checked="enablePrivacy"
:active-color="lightColor"
:icon-size="18"
></u-checkbox>
<div class="tips"> <div class="tips">
未注册的手机号验证后将自动创建用户账号登录即代表您已同意<span @click="navigateToPrivacy('PRIVACY_POLICY')">隐私协议</span> 未注册的手机号验证后将自动创建用户账号登录即代表您已同意<span @click="navigateToPrivacy('PRIVACY_POLICY')">隐私协议</span>
<span @click="navigateToPrivacy('USER_AGREEMENT')"> <span @click="navigateToPrivacy('USER_AGREEMENT')">
@@ -151,9 +195,7 @@
height: "104rpx", height: "104rpx",
"border-bottom": "1rpx solid #D8D8D8", "border-bottom": "1rpx solid #D8D8D8",
"letter-spacing": "1rpx", "letter-spacing": "1rpx",
"font-size": "40rpx", padding: "0",
"line-height": "40rpx",
color: "#333",
}, },
placeholderStyle: "font-size: 32rpx;line-height: 32rpx;color: #999999;", placeholderStyle: "font-size: 32rpx;line-height: 32rpx;color: #999999;",
loginList: [ loginList: [
@@ -311,20 +353,29 @@
async flage(val) { async flage(val) {
if (val) { if (val) {
if (this.$refs.uCode.canGetCode) {
if (this.enableUserPwdBox) { if (this.enableUserPwdBox) {
this.submitUserLogin(); this.submitUserLogin();
return; return;
// 执行登录 }
} else {
// 向后端请求验证码 // 首次发送时 uCode 尚未挂载;重新获取时才检查倒计时
const canSendCode = this.current === 0 || this.$refs.uCode?.canGetCode;
if (!canSendCode) {
this.$u.toast("请倒计时结束后再发送");
return;
}
uni.showLoading({}); uni.showLoading({});
let res = await sendMobile(this.mobile); let res = await sendMobile(this.mobile);
if (this.$store.state.isShowToast){ uni.hideLoading() }; if (this.$store.state.isShowToast) {
// 这里此提示会被this.start()方法中的提示覆盖 uni.hideLoading();
}
if (res.data.success) { if (res.data.success) {
this.code = '';
this.current = 1; this.current = 1;
this.$refs.uCode.start(); this.$nextTick(() => {
this.$refs.uCode?.start();
});
} else { } else {
uni.showToast({ uni.showToast({
title: res.data.message, title: res.data.message,
@@ -332,14 +383,10 @@
icon: "none", icon: "none",
}); });
this.flage = false; this.flage = false;
this.$refs.verification.getCode(); this.$refs.verification?.getCode();
}
} }
} else { } else {
!this.enableUserPwdBox ? this.$u.toast("请倒计时结束后再发送") : ""; this.$refs.verification?.hide();
}
} else {
this.$refs.verification.hide();
} }
}, },
}, },
@@ -751,8 +798,18 @@
} }
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.login-body {
flex: 1;
display: flex;
flex-direction: column;
}
.wrapper { .wrapper {
padding: 0 80rpx; padding: 0 80rpx;
min-height: 100vh;
display: flex;
flex-direction: column;
box-sizing: border-box;
} }
.title { .title {
@@ -813,16 +870,32 @@
} }
.tips { .tips {
font-size: 12px; flex: 1;
line-height: 20px; font-size: 24rpx;
margin-top: 32rpx; line-height: 36rpx;
width: 546rpx; margin-top: 0;
color: #666;
>span { >span {
color: $light-color; color: $light-color;
} }
} }
.privacy-row {
display: flex;
align-items: flex-start;
margin-top: 32rpx;
}
.privacy-check {
flex-shrink: 0;
margin-top: 4rpx;
:deep(.u-checkbox) {
margin: 0;
}
}
.fetch-btn { .fetch-btn {
width: 370rpx; width: 370rpx;
height: 80rpx; height: 80rpx;
@@ -839,8 +912,8 @@
.login-list { .login-list {
display: flex; display: flex;
width: 590rpx; width: 590rpx;
position: absolute; margin-top: auto;
top: 1200rpx; margin-bottom: 80rpx;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
@@ -858,7 +931,8 @@
.user-password-tips { .user-password-tips {
text-align: center; text-align: center;
color: $main-color; color: $light-color;
margin: 20px 0; margin: 40rpx 0;
font-size: 28rpx;
} }
</style> </style>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="box"> <view class="box">
<u-navbar <u-navbar
class="navbar" class="navbar"
:border="false" :border="false"
@@ -30,46 +30,65 @@
:list="tabs" :list="tabs"
></u-tabs> ></u-tabs>
<div class="wrapper"> <view class="wrapper">
<!-- 直播中 全部 直播回放 --> <view
<div class="live-item" :class="{'invalid':item.status == 'END'}" v-for="(item,index) in liveList" :key="index" @click="handleLivePlayer(item)"> class="live-item"
<div class="live-cover-img"> :class="{ invalid: item.status == 'END' }"
<div class="tips"> v-for="(item, index) in liveList"
<div class="live-box"> :key="item.id || item.roomId || index"
<image class="live-gif" src="./static/live.gif"></image> @click="handleLivePlayer(item)"
</div> >
<span>{{item.status == 'END' ? '已结束' : item.status =='NEW' ? '未开始' : '直播中'}}</span> <view class="live-cover-img">
</div> <view class="tips">
<div class="bg"></div> <view class="live-box" v-if="item.status === 'START'">
<u-image width="326" height="354" :src="item.shareImg" /> <image class="live-gif" src="/pages/promotion/static/live.gif" mode="aspectFit"></image>
</div> </view>
<div class="live-goods"> <text>{{ item.status == 'END' ? '已结束' : item.status == 'NEW' ? '未开始' : '直播中' }}</text>
<div class="live-goods-name"> </view>
{{item.name}} <view class="bg"></view>
</div> <u-image
<div class="live-store"> class="cover-image"
<span class="wes">lilishop</span> width="326rpx"
</div> height="354rpx"
<div class="live-goods-list"> mode="aspectFill"
<div class="live-goods-item"> :src="item.shareImg"
<u-image border-radius="20" :src="item.roomGoodsList ? item.roomGoodsList[0] : ''" height="140"></u-image> />
</div> </view>
<div class="live-goods-item"> <view class="live-goods">
<u-image border-radius="20" :src="item.roomGoodsList ? item.roomGoodsList[1] : ''" height="140"></u-image> <view class="live-goods-name">{{ item.name }}</view>
</div> <view class="live-store">
</div> <text class="wes">{{ config.name }}</text>
</div> </view>
</div> <view class="live-goods-list" v-if="item.roomGoodsList && item.roomGoodsList.length">
<u-loadmore v-if="liveList.length > 10" bg-color="#f8f8f8" :status="status" /> <view
</div> class="live-goods-item"
</div> v-for="(goodsImg, goodsIndex) in item.roomGoodsList.slice(0, 2)"
:key="goodsIndex"
>
<u-image
border-radius="20"
:src="goodsImg"
width="100%"
height="140rpx"
mode="aspectFill"
></u-image>
</view>
</view>
</view>
</view>
<u-loadmore v-if="liveList.length > 0" bg-color="#f8f8f8" :status="status" />
<view class="empty-live" v-if="!liveList.length && status === 'noMore'">暂无直播间</view>
</view>
</view>
</template> </template>
<script> <script>
import { getLiveList } from "@/api/promotions.js"; import { getLiveList } from "@/api/promotions.js";
import config from "@/config/config";
export default { export default {
data() { data() {
return { return {
config,
status: "loadmore", status: "loadmore",
activeColor: this.$lightColor, activeColor: this.$lightColor,
current: 0, // 当前tabs索引 current: 0, // 当前tabs索引
@@ -142,6 +161,7 @@ export default {
* 点击标签栏切换 * 点击标签栏切换
*/ */
changeTabs() { changeTabs() {
this.params[this.current].pageNumber = 1;
this.init(); this.init();
}, },
@@ -187,7 +207,7 @@ export default {
// 推荐直播间 // 推荐直播间
if (recommendLives.data.result.records.length) { if (recommendLives.data.result.records.length) {
this.status = "loadmore"; this.status = "loadmore";
this.recommendLives = recommendLives.data.result.records; this.recommendLiveList = recommendLives.data.result.records;
} else { } else {
this.status = "noMore"; this.status = "noMore";
} }
@@ -198,9 +218,9 @@ export default {
* 2.如果没有直播间设置一个默认图片 * 2.如果没有直播间设置一个默认图片
*/ */
if (!this.recommendLives.length) { if (!this.recommendLiveList.length) {
if (this.liveList[0].shareImg) { if (this.liveList[0] && this.liveList[0].shareImg) {
this["swiperImg"] = [ this.swiperImg = [
{ {
image: this.liveList[0].shareImg, image: this.liveList[0].shareImg,
roomId: this.liveList[0].roomId, roomId: this.liveList[0].roomId,
@@ -208,10 +228,8 @@ export default {
]; ];
} }
} else { } else {
this.recommendLives.forEach((item) => { this.recommendLiveList.forEach((item) => {
this["swiperImg"] = [ this.swiperImg = [{ image: item.shareImg, roomId: item.roomId }];
{ image: item.shareImg, roomId: item.roomId },
];
}); });
} }
} }
@@ -239,8 +257,12 @@ export default {
this.liveList.forEach((item) => { this.liveList.forEach((item) => {
if (item.roomGoodsList) { if (item.roomGoodsList && typeof item.roomGoodsList === "string") {
try {
item.roomGoodsList = JSON.parse(item.roomGoodsList); item.roomGoodsList = JSON.parse(item.roomGoodsList);
} catch (e) {
item.roomGoodsList = [];
}
} }
}); });
} }
@@ -277,61 +299,97 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
page {
background: #f8f8f8;
}
.box {
width: 100%;
min-height: 100vh;
background: #f8f8f8;
box-sizing: border-box;
}
.slot-wrap { .slot-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1; flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */ padding-right: 24rpx;
/* padding: 0 30rpx; */
} }
.invalid { .invalid {
filter: grayscale(1); filter: grayscale(1);
} }
.wrapper { .wrapper {
padding: 0 24rpx; padding: 0 24rpx 40rpx;
box-sizing: border-box;
} }
.live-item { .live-item {
display: flex; display: flex;
flex-direction: row;
align-items: stretch;
overflow: hidden; overflow: hidden;
border-radius: 20rpx; border-radius: 20rpx;
flex-wrap: wrap;
background: #fff; background: #fff;
margin: 20rpx 0; margin: 20rpx 0;
} }
.live-cover-img { .live-cover-img {
position: relative; position: relative;
flex-shrink: 0;
width: 326rpx;
height: 354rpx;
overflow: hidden;
border-radius: 20rpx 0 0 20rpx;
} }
.cover-image {
display: block;
width: 100%;
height: 100%;
}
.swiper { .swiper {
margin: 20rpx 0; margin: 20rpx 24rpx;
} }
.live-goods { .live-goods {
position: relative;
flex: 1; flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
padding: 16rpx 24rpx 24rpx; padding: 16rpx 24rpx 24rpx;
box-sizing: border-box;
} }
.live-goods-name { .live-goods-name {
height: 84rpx; min-height: 84rpx;
font-weight: bold; font-weight: bold;
font-size: 30rpx; font-size: 30rpx;
line-height: 1.4;
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
color: #333;
} }
.live-store { .live-store {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 20rpx 0; margin: 12rpx 0 20rpx;
overflow: hidden; overflow: hidden;
width: calc(100% - 50rpx); font-size: 24rpx;
color: #999;
} }
.live-gif { .live-gif {
width: 20rpx; width: 20rpx;
height: 20rpx; height: 20rpx;
} }
.live-box { .live-box {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -340,66 +398,53 @@ export default {
width: 40rpx; width: 40rpx;
margin-right: 10rpx; margin-right: 10rpx;
height: 40rpx; height: 40rpx;
flex-shrink: 0;
background: linear-gradient(90deg, #ff6b35, #ff9f28, #ffcc03); background: linear-gradient(90deg, #ff6b35, #ff9f28, #ffcc03);
} }
.live-goods-list { .live-goods-list {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; gap: 20rpx;
> .live-goods-item { margin-top: auto;
flex: 1;
}
> .live-goods-item:nth-of-type(1) {
padding-right: 38rpx;
}
} }
.live-icon, .live-goods-item {
.zan { flex: 1;
position: absolute; min-width: 0;
width: 80rpx; overflow: hidden;
height: 80rpx; border-radius: 20rpx;
z-index: 9;
} }
.tips { .tips {
display: flex; display: flex;
position: absolute; position: absolute;
z-index: 9; z-index: 9;
align-items: center; align-items: center;
top: 20rpx; top: 20rpx;
right: 0; left: 20rpx;
padding: 4rpx 12rpx 4rpx 0; padding: 4rpx 12rpx 4rpx 4rpx;
font-size: 24rpx; font-size: 24rpx;
border-radius: 100px; border-radius: 100px;
color: #fff; color: #fff;
background: rgba(0, 0, 0, 0.46); background: rgba(0, 0, 0, 0.46);
} }
.live-icon {
right: 0;
top: 104rpx;
}
.zan {
bottom: 0;
right: 0;
width: 100rpx;
height: 100rpx;
}
.bg { .bg {
position: absolute; position: absolute;
bottom: 4rpx; left: 0;
width: 100%; right: 0;
bottom: 0;
height: 100rpx; height: 100rpx;
z-index: 8; z-index: 8;
background-image: -webkit-gradient( pointer-events: none;
linear,
left bottom,
left top,
from(rgba(0, 0, 0, 0.25)),
color-stop(82%, transparent)
);
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.25), transparent 82%); background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.25), transparent 82%);
border-bottom-left-radius: 20rpx; }
.empty-live {
padding: 80rpx 0;
text-align: center;
font-size: 28rpx;
color: #999;
} }
</style> </style>

View File

@@ -107,6 +107,10 @@ export default {
this.pointDetail = res.data.result; this.pointDetail = res.data.result;
} }
}, },
closePopupBuy(val) {
this.maskFlag = val;
},
}, },
}; };
</script> </script>

View File

@@ -2,6 +2,22 @@
<view class="index"> <view class="index">
<user-point /> <user-point />
<view class="index-head"> <view class="index-head">
<!-- #ifdef H5 -->
<view class="list-scroll-content list-scroll-content-h5">
<view class="index-head-navs">
<view
class="index-head-nav"
v-for="(ele, index) in categoryIndexData"
:key="index"
:class="{ 'index-head-nav-active': tabIndex == index }"
@click="setCat(index)"
>
{{ ele.name }}
</view>
</view>
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<scroll-view scroll-x class="list-scroll-content" :scroll-left="currentLeft" scroll-with-animation> <scroll-view scroll-x class="list-scroll-content" :scroll-left="currentLeft" scroll-with-animation>
<view class="index-head-navs"> <view class="index-head-navs">
<view class="index-head-nav" v-for="(ele, index) in categoryIndexData" :key="index" <view class="index-head-nav" v-for="(ele, index) in categoryIndexData" :key="index"
@@ -10,11 +26,48 @@
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<!-- #endif -->
</view> </view>
<!-- #ifdef H5 -->
<view class="tab-content-h5">
<view class="index-items">
<view
class="index-item"
v-for="(item, key) in categoryIndexData[tabIndex].goods"
:key="item.id || key"
@click="toGoods(item)"
>
<view class="index-item-img">
<image
class="index-item-image"
:src="item.thumbnail"
mode="aspectFit"
lazy-load
></image>
</view>
<view class="index-item-info">
<view class="index-item-title">{{ item.goodsName || item.promotionName || '' }}</view>
<view class="index-item-price">
<view class="point">
<text class="point-num">{{ item.points != null ? item.points : 0 }}</text>
<text class="point-unit">积分</text>
</view>
<text class="tipsMkt">¥{{ unitPrice(item.originalPrice) }}</text>
</view>
</view>
</view>
</view>
<uni-load-more
:status="categoryIndexData[tabIndex].loadStatus"
@clickLoadMore="loadMore"
></uni-load-more>
</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<swiper :current="tabIndex" class="swiper-box" @change="ontabchange" duration="300"> <swiper :current="tabIndex" class="swiper-box" @change="ontabchange" duration="300">
<swiper-item v-for="(nav, index) in categoryIndexData" :key="index" class="swiper-item"> <swiper-item v-for="(nav, index) in categoryIndexData" :key="index" class="swiper-item">
<scroll-view class="scroll-v" enableBackToTop="true" scroll-with-animation scroll-y @scrolltolower="loadMore"> <scroll-view class="scroll-v" enableBackToTop="true" scroll-with-animation scroll-y @scrolltolower="loadMore">
<view class="index-items"> <view class="index-items">
<view class="index-item" v-for="(item, key) in nav.goods" :key="item.id || key" @click="toGoods(item)"> <view class="index-item" v-for="(item, key) in nav.goods" :key="item.id || key" @click="toGoods(item)">
@@ -42,6 +95,7 @@
</scroll-view> </scroll-view>
</swiper-item> </swiper-item>
</swiper> </swiper>
<!-- #endif -->
</view> </view>
</template> </template>
@@ -80,11 +134,14 @@ export default {
}, },
onLoad() {}, onLoad() {},
async onPullDownRefresh() { async onPullDownRefresh() {
// #ifndef H5
this.categoryIndexData[this.tabIndex].goods = []; this.categoryIndexData[this.tabIndex].goods = [];
this.categoryIndexData[this.tabIndex].params.pageNumber = 1; this.categoryIndexData[this.tabIndex].params.pageNumber = 1;
this.categoryIndexData[this.tabIndex].loadStatus = "more"; this.categoryIndexData[this.tabIndex].loadStatus = "more";
this.loadGoods(); this.loadGoods();
// #endif
}, },
// #ifndef H5
onPageScroll(e) { onPageScroll(e) {
if (e.scrollTop < -40 && this.flag) { if (e.scrollTop < -40 && this.flag) {
this.flag = false; this.flag = false;
@@ -95,6 +152,7 @@ export default {
this.loadGoods(); this.loadGoods();
} }
}, },
// #endif
watch: { watch: {
tabIndex(val) { tabIndex(val) {
if ( if (
@@ -175,7 +233,9 @@ export default {
}, 3000); }, 3000);
} }
// #ifndef H5
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
// #endif
}, },
setCat(type) { setCat(type) {
this.tabIndex = type; this.tabIndex = type;
@@ -189,12 +249,21 @@ export default {
} }
}, },
loadMore() { loadMore() {
if (this.categoryIndexData[this.tabIndex].loadStatus == "more") { if (this.categoryIndexData[this.tabIndex].loadStatus !== "more") {
return;
}
this.categoryIndexData[this.tabIndex].params.pageNumber++; this.categoryIndexData[this.tabIndex].params.pageNumber++;
this.loadGoods(); this.loadGoods();
},
},
// #ifdef H5
onReachBottom() {
if (this.categoryIndexData[this.tabIndex].loadStatus !== 'more') {
return;
} }
this.loadMore();
}, },
}, // #endif
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -212,15 +281,21 @@ page {
.index { .index {
height: 100vh; height: 100vh;
// #ifdef H5
height: calc(100vh - 44px);
// #endif
width: 100%; width: 100%;
display: flex;
flex-direction: column;
overflow: hidden; overflow: hidden;
// #ifdef H5
height: auto;
min-height: 100vh;
overflow: visible;
// #endif
} }
.index-head { .index-head {
background: #fff; background: #fff;
flex-shrink: 0;
} }
.list-scroll-content { .list-scroll-content {
@@ -259,14 +334,25 @@ page {
} }
} }
.swiper-box {
// #ifdef H5 // #ifdef H5
height: calc(100vh - (100rpx + 300rpx + 44px)); .list-scroll-content-h5 {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
.index-head-navs {
display: inline-flex;
min-width: 100%;
}
}
.tab-content-h5 {
padding-bottom: 40rpx;
}
// #endif // #endif
// #ifndef H5 .swiper-box {
height: calc(100vh - 400rpx); flex: 1;
// #endif min-height: 0;
.scroll-v { .scroll-v {
height: 100%; height: 100%;
@@ -355,3 +441,12 @@ page {
} }
} }
</style> </style>
<style lang="scss">
/* #ifdef H5 */
page {
height: auto;
min-height: 100vh;
overflow-y: auto;
}
/* #endif */
</style>

View File

@@ -35,6 +35,7 @@ export default {
.user-point { .user-point {
padding: 0 20rpx; padding: 0 20rpx;
height: 300rpx; height: 300rpx;
flex-shrink: 0;
background: url("/static/point-bg.png") no-repeat; background: url("/static/point-bg.png") no-repeat;
background-size: 100%; background-size: 100%;
display: flex; display: flex;

View File

@@ -119,24 +119,24 @@
<u-checkbox class="checkout-all" usedAlone shape="circle" :active-color="lightColor" v-model:checked="checkout" <u-checkbox class="checkout-all" usedAlone shape="circle" :active-color="lightColor" v-model:checked="checkout"
:label-size="12" label="全选" @change="checkOut"> :label-size="12" label="全选" @change="checkOut">
</u-checkbox> </u-checkbox>
<span class="price checkout-total"> <view class="checkout-total">
<div class="prices"> <view class="checkout-total-main">
<div class="fullPrice"> <text class="checkout-total-label">总计:</text>
<span class="number" v-if="cartDetail && cartDetail.priceDetailDTO"> <text class="checkout-total-price" v-if="cartDetail && cartDetail.priceDetailDTO">
总计: <text class="checkout-total-currency">¥</text>
<span>¥{{ goodsFormatPrice(cartDetail.priceDetailDTO.flowPrice)[0] }}</span>.<span>{{ goodsFormatPrice(cartDetail.priceDetailDTO.flowPrice)[1] }}</span> <text class="checkout-total-int">{{ goodsFormatPrice(cartDetail.priceDetailDTO.flowPrice)[0] }}</text>
</span> <text class="checkout-total-dec">.{{ goodsFormatPrice(cartDetail.priceDetailDTO.flowPrice)[1] }}</text>
<span class="number" v-else>总计:0.00</span> </text>
</div> <text class="checkout-total-price" v-else>¥0.00</text>
<div </view>
<view
v-if="cartDetail.cartList && cartDetail.cartList.length != 0 && cartDetail.priceDetailDTO && cartDetail.priceDetailDTO.discountPrice != 0" v-if="cartDetail.cartList && cartDetail.cartList.length != 0 && cartDetail.priceDetailDTO && cartDetail.priceDetailDTO.discountPrice != 0"
class="discountPrice"> class="checkout-total-discount"
<span>优惠减:{{(cartDetail.priceDetailDTO.goodsPrice -unitPrice(cartDetail.priceDetailDTO.flowPrice))}} >
</span> <text>优惠减:{{ cartDetail.priceDetailDTO.goodsPrice - unitPrice(cartDetail.priceDetailDTO.flowPrice) }}</text>
<span class="discount-details" @click="discountDetails">优惠明细</span> <text class="discount-details" @click="discountDetails">优惠明细</text>
</div> </view>
</div> </view>
</span>
</view> </view>
<!-- 优惠详情 --> <!-- 优惠详情 -->
<u-popup z-index="3" close mode="bottom" height="50%" closeable v-model:show="discountDetailsFlag" border-radius="20"> <u-popup z-index="3" close mode="bottom" height="50%" closeable v-model:show="discountDetailsFlag" border-radius="20">
@@ -851,7 +851,50 @@ page {
} }
.checkout-total { .checkout-total {
margin-left: 8rpx; flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: center;
}
.checkout-total-main {
display: flex;
align-items: baseline;
line-height: 1.2;
}
.checkout-total-label {
font-size: 28rpx;
color: #333;
flex-shrink: 0;
}
.checkout-total-price {
margin-left: 4rpx;
font-size: 30rpx;
font-weight: bold;
color: $main-color;
line-height: 1.2;
}
.checkout-total-int {
font-size: 38rpx;
font-weight: bold;
}
.checkout-total-dec {
font-size: 24rpx;
font-weight: bold;
}
.checkout-total-discount {
display: flex;
align-items: center;
margin-top: 4rpx;
font-size: 24rpx;
color: #c9c7c7;
line-height: 1.2;
} }
} }
@@ -889,17 +932,6 @@ page {
} }
} }
.prices {
display: flex;
flex-direction: column;
> .discountPrice {
align-items: center;
display: flex;
font-size: 24rpx;
color: rgb(201, 199, 199);
}
}
.discount-details { .discount-details {
margin-left: 10px; margin-left: 10px;
color: #666; color: #666;