Преглед на файлове

上传文件至 'packageGoods/pages'

linwenxin преди 4 месеца
родител
ревизия
fafe8b668d
променени са 4 файла, в които са добавени 1989 реда и са изтрити 0 реда
  1. 1256 0
      packageGoods/pages/order.vue
  2. 248 0
      packageGoods/pages/search.vue
  3. 458 0
      packageGoods/pages/seckill.vue
  4. 27 0
      packageGoods/pages/template.vue

+ 1256 - 0
packageGoods/pages/order.vue

@@ -0,0 +1,1256 @@
+<template>
+	<view class="app-container" :class="isNoticebar ? 'hasNoticebar' : ''">
+		<view class="noticebar" v-if="isNoticebar">
+			<uni-notice-bar v-if="noticeContent" scrollable="true" single="true" showClose="true" :text="noticeContent"
+				background-color="#f6e6e7" color="#de3749" @close="closeNoticebar"></uni-notice-bar>
+		</view>
+
+		<view class="address-container" @tap="chooseAddress">
+			<view class="left">
+				<view class="icon">
+					<image src="../../static/icon/address.png"></image>
+				</view>
+				<view class="nodata" v-if="!hasAddress">选择收货地址</view>
+				<view class="hasdata" v-else>
+					<view class="name">{{ addressInfo.name }}<text>{{ addressInfo.phone }}</text></view>
+					<view class="address ellipsis-2">{{ addressInfo.province }}{{ addressInfo.city
+            }}{{ addressInfo.area }}{{ addressInfo.street
+            }}{{ addressInfo.address }}{{ addressInfo.houseNo }}</view>
+				</view>
+			</view>
+			<image class="right" src="../../static/icon/right.png"></image>
+		</view>
+
+		<view class="card goods-container">
+			<view class="title">商品信息</view>
+			<block v-for="(item, index) in goodsList" :key="index">
+				<view>
+					<view class="item">
+						<image v-if="
+                item.logo && 
+				$compareTime(item.logoStartTime, item.logoEndTime) && item.mergeImage
+              " :src="item.mergeImage"></image>
+						<image v-else :src="item.imgUrl"></image>
+						<view class="right">
+							<view class="name ellipsis-2">{{ item.goodsName }}</view>
+							<view class="des">{{ item.specValue }}</view>
+							<view class="bottom">
+								<view class="price">
+									<view class="price-1">¥{{ item.price | numToFixed }}</view>
+									<view class="price-2">¥{{ item.orgPrice | numToFixed }}</view>
+								</view>
+
+								<u-number-box @tap.stop v-model="item.num" :min="1" :buttonSize="26"
+									iconStyle="font-size: 12px;" :disabled="!hasAddress"
+									@change="changeCount($event, index)">
+								</u-number-box>
+							</view>
+						</view>
+					</view>
+					<view style="box-sizing: border-box; padding: 10rpx 0">
+						<view class="guobutishi" v-if="
+                goodsList.length == 1 &&
+                item.num == 1 &&
+                [
+                  'GDYJKT',
+                  'GDYJBX',
+                  'GDYJXYJ',
+                  'GDYJXYYJ',
+                  'GDYJDZ',
+                  'GDYJRSQ',
+                ].includes(item.umsDiscountCode)
+              ">
+							<view class="guobutishi1">云闪付</view>
+							<view class="guobutishi2">用券新机补贴预估{{ (item.price * 0.2).toFixed(2) }}元</view>
+						</view>
+						<view class="guobutishi" v-if="
+                goodsList.length == 1 &&
+                item.num == 1 &&
+                [
+                  'GDEJKT',
+                  'GDEJBX',
+                  'GDEJXYJ',
+                  'GDEJXYYJ',
+                  'GDEJDZ',
+                  'GDEJRSQ',
+                ].includes(item.umsDiscountCode)
+              ">
+							<view class="guobutishi1">云闪付</view>
+							<view class="guobutishi2">用券新机补贴预估{{ (item.price * 0.15).toFixed(2) }}元</view>
+						</view>
+					</view>
+				</view>
+			</block>
+		</view>
+
+		<view class="card row-container">
+			<view class="item">
+				<view class="title">优惠券</view>
+				<view class="coupon" @tap="chooseCoupon">
+					<text v-if="hasCoupon">{{ couponInfo.couponName }}</text>
+					<text v-else style="color: #666666">未使用优惠券</text>
+					<image src="../../static/icon/right.png"></image>
+				</view>
+			</view>
+			<view class="item">
+				<view class="title">配送方式</view>
+				<view class="right" v-if="freight == 0">快递包邮</view>
+				<view class="right" v-if="freight != 0">快递自费</view>
+			</view>
+			<!-- <view class="item" v-if="isServiceUser">
+        <view class="title">工单派单方式</view>
+        <view class="radio-group">
+          <view class="radio" @tap="dispatchType = 1">
+            <text
+              class="iconfont"
+              :class="
+                dispatchType === 1 ? 'icon-danxuan2 active' : 'icon-danxuan'
+              "
+            ></text>
+            自卖自装
+          </view>
+          <view class="radio" @tap="dispatchType = 2">
+            <text
+              class="iconfont"
+              :class="
+                dispatchType === 2 ? 'icon-danxuan2 active' : 'icon-danxuan'
+              "
+            ></text>
+            当地安装
+          </view>
+        </view>
+      </view> -->
+			<view class="item">
+				<view class="title">买家留言</view>
+				<view class="remark">
+					<textarea auto-height :placeholder="isApplyDialog ? '' : '选填,留言建议50字内'" v-model="remark"></textarea>
+				</view>
+			</view>
+		</view>
+
+		<view class="card row-container">
+			<view class="item">
+				<view class="title">商品金额</view>
+				<view class="orange">¥{{ orderInfo.totalAmount | numToFixed }}</view>
+			</view>
+			<view class="item">
+				<view class="title">运费</view>
+				<view class="orange">¥{{ freight | numToFixed }}</view>
+			</view>
+			<view class="item">
+				<view class="title">优惠</view>
+				<view class="orange">-¥{{
+            (couponInfo.couponValue
+              ? couponInfo.couponValue
+              : orderInfo.exchangeAmount || 0) | numToFixed
+          }}</view>
+			</view>
+			<view class="item" v-if="orderInfo.promotionDiscountRate">
+				<view class="title">折扣优惠</view>
+				<view class="orange">-¥{{ orderInfo.discountAmount | numToFixed }}({{
+            orderInfo.promotionDiscountRate * 10
+          }}折)</view>
+			</view>
+		</view>
+
+		<view class="card row-container">
+			<view class="item">
+				<view class="title">优惠码</view>
+				<view class="input"><input placeholder="请输入优惠码" v-model="exchangeCode" @blur="exchangeCodeBlur()" />
+				</view>
+			</view>
+		</view>
+
+		<view class="card row-container">
+			<view class="item">
+				<view class="title">订单总金额</view>
+				<view class="orange">¥{{ orderInfo.payAmount | numToFixed }}</view>
+			</view>
+			<!-- <view class="item">
+				<view class="title">减免金额申请</view>
+				<view class="orange">-¥0.00</view>
+			</view>
+			<view class="item">
+				<view class="title">应付总金额</view>
+				<view class="orange">¥{{orderInfo.payAmount | numToFixed}}</view>
+			</view> -->
+		</view>
+
+		<view class="bottom-container">
+			<!-- <view class="left">共{{orderInfo.totalNum}}件,合计:<text>¥{{orderInfo.payAmount | numToFixed}}</text></view> -->
+			<view class="btn-group">
+				<view class="button3" @tap="toApply" v-if="isServiceUser && isInnerrUser && !isGiftGoods">申请减免金额</view>
+				<view class="button2" @tap="replaceOrder" v-if="(isServiceUser || isHeadUser) && !isGiftGoods">代客下单
+				</view>
+				<view class="button" @tap="submitOrder">提交订单</view>
+			</view>
+		</view>
+
+		<!-- 代客下单 -->
+		<view class="global-mask" v-show="isCodeDialog"></view>
+		<view class="codeDialog" v-show="isCodeDialog">
+			<view class="close">
+				<image src="@/static/icon/close.png" @tap="isCodeDialog = false"></image>
+			</view>
+			<!-- <view class="code"><image :src="'data:image/jpeg;base64,' + codeUrl" mode="aspectFill"></image></view> -->
+			<view class="code">
+				<image :src="codeUrl" mode="aspectFill"></image>
+			</view>
+			<view class="tips">请让客户扫码下单</view>
+		</view>
+
+		<modal-dialog showTitle="提示" showText="优惠券和优惠码只能使用其中一个" :isShowDialog="isBothDialog"
+			@cancel="chooseDiscountWay(1)" @confirm="chooseDiscountWay(2)" cancelText="使用优惠券"
+			confirmText="使用优惠码"></modal-dialog>
+
+		<modal-dialog showTitle="提示" :showText="errorMsg" :isShowDialog="isErrorDialog" :isShowCancel="false"
+			@confirm="isErrorDialog = false"></modal-dialog>
+
+		<view class="apply-dialog" v-show="isApplyDialog">
+			<view class="dialog">
+				<view class="title">减免金额申请</view>
+				<view class="content">
+					<view class="row">
+						<text>订单金额:¥{{ orderInfo.payAmount | numToFixed }}</text>
+					</view>
+					<view class="row">
+						<text>减免金额:</text><input type="digit" v-model="applyForm.amount" /><text></text>
+					</view>
+					<view class="row">
+						<text>应付金额:¥{{
+                ((orderInfo.payAmount * 100 - applyForm.amount * 100) / 100)
+                  | numToFixed
+              }}</text>
+					</view>
+					<view class="row">
+						<text>申请备注:</text><input type="text" v-model="applyForm.remark" /><text></text>
+					</view>
+				</view>
+				<view class="btn">
+					<view class="left" @tap="cancelApplyForm">取消</view>
+					<view class="right" @tap="confirmApplyForm">提交</view>
+				</view>
+			</view>
+		</view>
+
+		<zhifutanchuan v-if="detail_" :orderInfo="orderInfo" @PAY_TYPE_STR="PAY_TYPE_STR" />
+	</view>
+</template>
+
+<script>
+	import {
+		mapState
+	} from 'vuex';
+	import EventBus from '@/utils/eventbus.js';
+	import modalDialog from '@/components/modalDialog.vue';
+	import zhifutanchuan from '@/components/zhifutanchuan.vue';
+	export default {
+		components: {
+			modalDialog,
+			zhifutanchuan,
+		},
+		data() {
+			return {
+				detail_: null,
+				configInfo: uni.getStorageSync('configInfo'),
+				hasAddress: false, // 是否有收货地址
+				addressInfo: {}, // 收货地址信息
+				hasCoupon: false, // 是否有优惠券
+				couponInfo: {}, // 优惠券信息
+				buyList: [], // 商品列表(从商品详情带入,用于请求订单信息接口)
+				orderInfo: {}, // 订单信息
+				goodsList: [], // 商品列表(从订单信息接口获取,用于渲染)
+				freight: 0, // 运费
+				remark: '', // 买家留言
+				isCodeDialog: false, // 代客下单弹窗
+				codeUrl: '', // 代客下单二维码
+				isSeckill: false, // 是否秒杀订单
+				secKillId: null, // 秒杀id
+				secKillSpecId: null,
+				secToken: null,
+				orderId: null, // 订单id
+				isGiftGoods: false, // 是否福利商品
+				exchangeCode: '', // 优惠码
+				isNoticebar: false, // 是否显示公告栏
+				noticeContent: '', // 公告内容
+				groupbuyId: null, // 团购id
+				isBothDialog: false, // 优惠券和优惠码都选择的提示
+				packageId: null, // 套购id
+
+				isErrorDialog: false,
+				errorMsg: '',
+
+				dispatchType: 1,
+				isApplyDialog: false,
+				applyForm: {
+					amount: '',
+					remark: '',
+				},
+			};
+		},
+		computed: {
+			...mapState(['userInfo', 'isLogin', 'userId']),
+
+			isServiceUser() {
+				// 是否业务员
+				return this.userInfo.type === 'SERVICE';
+			},
+			isHeadUser() {
+				// 是否团长
+				return this.userInfo.promotionGroupLeader;
+			},
+			isInnerrUser() {
+				// 是否内部人员
+				return this.userInfo.innerr;
+			},
+
+			total() {
+				let price = Number(this.orderInfo.totalAmount); // 商品金额
+				let freight = Number(this.freight); // 运费
+				let coupon = this.couponInfo.couponValue ?
+					Number(this.couponInfo.couponValue) :
+					Number(this.orderInfo.exchangeAmount || 0); // 优惠金额
+				let total = price + freight - coupon; // 合计
+				return total < 0 ? 0 : total;
+			},
+		},
+		async onLoad({
+			buyList,
+			secKillId,
+			secKillSpecId,
+			secToken,
+			groupbuyId,
+			packageId,
+		}) {
+			this.getNoticebar();
+
+			this.buyList = JSON.parse(buyList);
+			console.log(this.buyList);
+			this.secKillId = secKillId;
+			this.secKillSpecId = secKillSpecId;
+			this.secToken = secToken;
+			this.groupbuyId = groupbuyId;
+			this.packageId = packageId;
+
+			// 进入页面先获取默认地址
+			await this.getAddress();
+
+			// 获取订单信息
+			this.getOrderInfo();
+
+			// 接收地址信息
+			EventBus.$on('chooseAddress', (result) => {
+				this.hasAddress = true;
+				this.addressInfo = result;
+				this.getOrderInfo();
+			});
+
+			// 接收优惠券信息
+			EventBus.$on('chooseCoupon', (result) => {
+				if (result) {
+					this.hasCoupon = true;
+					this.couponInfo = result;
+				} else {
+					this.hasCoupon = false;
+					this.couponInfo = {};
+				}
+				this.getOrderInfo();
+			});
+		},
+		destroyed() {
+			EventBus.$off(['chooseAddress', 'chooseCoupon']);
+		},
+		methods: {
+			findElem(array, attr, val) {
+				for (var i = 0; i < array.length; i++) {
+					if (array[i][attr] == val) {
+						return i; //返回当前索引值
+					}
+				}
+				return -1;
+			},
+
+			// 获取公告栏
+			getNoticebar() {
+				this.$axios({
+					url: '/shpping/cart/notice',
+					method: 'get',
+					params: {
+						userId: this.userId,
+					},
+				}).then((res) => {
+					this.noticeContent = res.data;
+					this.isNoticebar = res.data ? true : false;
+				});
+			},
+
+			// 关闭通告栏
+			closeNoticebar() {
+				this.isNoticebar = false;
+			},
+
+			// 获取订单信息
+			getOrderInfo(type) {
+				this.$axios({
+						url: '/order/ackdata',
+						type: 'application/json',
+						params: {
+							buyGoods: this.buyList,
+							userAddressId: this.addressInfo.userAddressId,
+							userCouponId: this.hasCoupon ? this.couponInfo.id : '',
+							exchangeCode: this.exchangeCode,
+							promotionGroupId: this.groupbuyId || '',
+							goodsPackageId: this.packageId || '',
+						},
+					})
+					.then((res) => {
+						if (res.code == 1100) {
+							this.errorMsg = res.message;
+							this.isErrorDialog = true;
+							uni.hideLoading();
+							setTimeout(() => {
+								uni.showToast({
+									title: res.message,
+									icon: 'none'
+								});
+							}, 500)
+							return false;
+							// return this.$toast(res.message);
+						} else if (res.code !== 200) {
+							setTimeout(() => {
+								uni.navigateBack({
+									delta: 1,
+								});
+							}, 1000);
+						}
+						this.orderInfo = res.data;
+						this.goodsList = res.data.goods;
+						this.isSeckill = res.data.isSecKill;
+						this.freight = res.data.freight;
+						this.isGiftGoods = this.findElem(res.data.goods, 'isGift', true) >= 0;
+					})
+					.catch((res) => {
+						setTimeout(() => {
+							uni.navigateBack({
+								delta: 1,
+							});
+						}, 1000);
+					});
+			},
+
+			// 获取地址信息
+			async getAddress() {
+				const result = new Promise((resolve, reject) => {
+					this.$axios({
+						url: '/user/address/list',
+						method: 'get',
+						params: {
+							pageNum: 1,
+							pageSize: 100,
+							userId: this.userId,
+						},
+					}).then((res) => {
+						let hasDefault = this.findElem(res.data.records, 'defaultAddr', true);
+						if (hasDefault >= 0) {
+							this.hasAddress = true;
+							this.addressInfo = res.data.records[hasDefault];
+						} else {
+							this.hasAddress = false;
+						}
+						resolve();
+					});
+				});
+				return result;
+			},
+
+			findElem(array, attr, val) {
+				for (var i = 0; i < array.length; i++) {
+					if (array[i][attr] == val) {
+						return i; //返回当前索引值
+					}
+				}
+				return -1;
+			},
+
+			// 去选择优惠券
+			chooseCoupon() {
+				// if(this.isSeckill) {
+				// 	return this.$toast('秒杀商品不可使用优惠券');
+				// }
+				let goodsIds = [];
+				this.goodsList.forEach((item) => {
+					goodsIds.push(item.goodsId);
+				});
+
+				let amount = Number(this.orderInfo.totalAmount) + Number(this.freight);
+
+				uni.navigateTo({
+					url: '/packageGoods/pages/coupon?orderAmount=' +
+						amount +
+						'&goodsIds=' +
+						JSON.stringify(goodsIds),
+				});
+			},
+
+			// 去选择地址
+			chooseAddress() {
+				uni.navigateTo({
+					url: '/pages/mine/address/list?isChoose=' + true,
+				});
+			},
+
+			// 更改数量
+			changeCount(e, index) {
+				this.buyList[index].num = e.value;
+				this.getOrderInfo();
+			},
+
+			// 礼品卡密码失去光标
+			exchangeCodeBlur() {
+				if (this.exchangeCode.length >= 8) {
+					this.getOrderInfo('psw');
+				}
+			},
+
+			// 选择优惠方式
+			chooseDiscountWay(type) {
+				if (type === 1) {
+					this.exchangeCode = '';
+				} else {
+					this.hasCoupon = false;
+					this.couponInfo = {};
+				}
+				this.isBothDialog = false;
+				this.getOrderInfo();
+				this.orderPay();
+			},
+
+			PAY_TYPE_STR(ewPam) {
+				this.orderPay(ewPam);
+			},
+
+			// 提交订单
+			submitOrder() {
+				let that = this;
+				if (!this.hasAddress) {
+					return this.$toast('请先选择收货地址');
+				}
+				if (!this.orderInfo.openId) {
+					return uni.redirectTo({
+						url: '/pages/login/index?isNotOpenid=' + true,
+					});
+				}
+
+				if (this.exchangeCode && this.hasCoupon) {
+					return (this.isBothDialog = true);
+				}
+
+				this.detail_ = true;
+			},
+
+			// 下单支付
+			orderPay(ewPam = {}) {
+				let that = this;
+				this.$axios({
+					url: '/order/buy',
+					type: 'application/json',
+					params: {
+						...ewPam,
+						userId: this.userId,
+						buyGoods: this.buyList,
+						buyerMsg: this.remark,
+						userAddressId: this.addressInfo.userAddressId,
+						userCouponId: this.hasCoupon ? this.couponInfo.id : '',
+						exchangeCode: this.exchangeCode,
+						promotionGroupId: this.groupbuyId || '',
+						goodsPackageId: this.packageId || '',
+						// dispatchType: this.isServiceUser
+						//   ? this.dispatchType === 1
+						//     ? '自卖自装'
+						//     : '当地安装'
+						//   : '',
+					},
+					isLoading: 1,
+				}).then((res) => {
+					that.orderId = res.data.id;
+					if (res.code === 1100) {
+						this.detail_ = false;
+						this.errorMsg = res.message;
+						this.isErrorDialog = true;
+						uni.hideLoading();
+						setTimeout(() => {
+							uni.showToast({
+								title: res.message,
+								icon: 'none'
+							});
+						}, 500)
+						return false;
+					}
+					if (res.data.isPay === false) {
+						this.detail_ = false;
+						this.$successToast('购买成功');
+						this.requestMessage();
+					} else {
+						if (ewPam.payType == '微信支付') {
+							uni.getProvider({
+								service: 'payment',
+								success: (e) => {
+									uni.requestPayment({
+										provider: e.provider[0],
+										orderInfo: res.data,
+										timeStamp: res.data.timeStamp,
+										nonceStr: res.data.nonceStr,
+										package: res.data.payPackage,
+										signType: 'MD5',
+										paySign: res.data.paySign,
+										success: (payRes) => {
+											this.detail_ = false;
+											that.$successToast('购买成功');
+											that.requestMessage();
+											uni.reLaunch({
+												url: '/pages/mine/order/detail?orderId=' +
+													that.orderId,
+											});
+										},
+										fail: (err) => {
+											this.detail_ = false;
+											that.$toast('支付失败');
+											uni.reLaunch({
+												url: '/pages/mine/order/detail?orderId=' +
+													that.orderId,
+											});
+										},
+									});
+								},
+							});
+						} else if (
+							ewPam.payType == '云闪付' &&
+							res?.data?.umsMiniRep?.miniPayRequest?.cqpMpAppId
+						) {
+							uni.navigateToMiniProgram({
+								appId: res.data?.umsMiniRep?.miniPayRequest?.cqpMpAppId,
+								path: res.data?.umsMiniRep?.miniPayRequest?.cqpMpPath,
+								success(res) {
+									uni.onAppShow(({
+										scene
+									}) => {
+										// if (scene == 1038) {
+										// }
+										this.detail_ = false;
+										uni.reLaunch({
+											url: '/pages/mine/order/detail?orderId=' + that
+												.orderId,
+										});
+										uni.offAppShow();
+									});
+								},
+							});
+						}
+					}
+				});
+			},
+
+			// 消息推送
+			requestMessage() {
+				let that = this;
+				uni.showModal({
+					title: '温馨提示',
+					content: '为更好的促进您与买家的交流,需要在您的订单成交时向您发送消息',
+					confirmText: '同意',
+					cancelText: '拒绝',
+					success: function(res) {
+						if (res.confirm) {
+							let tmplIds = [that.configInfo.template];
+							uni.requestSubscribeMessage({
+								tmplIds: tmplIds,
+								success(res) {
+									let status = null;
+									tmplIds.map((item, index) => {
+										if (res[item] == 'accept') {
+											status = 'accept';
+										}
+									});
+									if (status == 'accept') {
+										that.$successToast('订阅成功');
+									} else {
+										that.$toast('订阅取消');
+									}
+									setTimeout(() => {
+										uni.reLaunch({
+											url: '/pages/mine/order/list?tab=DFH' +
+												'&orderId=' +
+												that.orderId,
+										});
+									}, 1000);
+								},
+								fail(res) {
+									console.log(res);
+									that.$toast('订阅失败');
+									setTimeout(() => {
+										uni.reLaunch({
+											url: '/pages/mine/order/list?tab=DFH' +
+												'&orderId=' +
+												that.orderId,
+										});
+									}, 1000);
+								},
+							});
+						} else if (res.cancel) {
+							uni.showModal({
+								title: '温馨提示',
+								content: '拒绝后您将无法获取实时的与卖家(买家)的交易消息',
+								confirmText: '知道了',
+								showCancel: false,
+								success: function(res) {
+									uni.reLaunch({
+										url: '/pages/mine/order/list?tab=DFH' +
+											'&orderId=' +
+											that.orderId,
+									});
+								},
+							});
+						}
+					},
+				});
+			},
+
+			// 代客下单
+			replaceOrder() {
+				if (!this.hasAddress) {
+					return this.$toast('请先选择收货地址');
+				}
+				this.$axios({
+					url: '/order/buy',
+					type: 'application/json',
+					params: {
+						userId: this.userId,
+						buyGoods: this.buyList,
+						buyerMsg: this.remark,
+						userAddressId: this.addressInfo.userAddressId,
+						userCouponId: this.hasCoupon ? this.couponInfo.id : '',
+						exchangeCode: this.exchangeCode,
+						proxyUser: true,
+						// dispatchType: this.isServiceUser
+						//   ? this.dispatchType === 1
+						//     ? '自卖自装'
+						//     : '当地安装'
+						//   : '',
+					},
+					isLoading: 1,
+				}).then((res) => {
+					if (res.code === 1100) {
+						this.errorMsg = res.message;
+						this.isErrorDialog = true;
+						uni.hideLoading();
+						setTimeout(() => {
+							uni.showToast({
+								title: res.message,
+								icon: 'none'
+							});
+						}, 500)
+						return false;
+						// return this.$toast(res.message);
+					}
+					this.codeUrl = res.data.codeUrl.replace(/[\r\n]/g, '');
+					this.isCodeDialog = true;
+				});
+			},
+
+			// 打开申请减免金额表单
+			toApply(id) {
+				this.isApplyDialog = true;
+			},
+
+			// 取消申请减免金额表单
+			cancelApplyForm() {
+				this.applyForm.amount = '';
+				this.isApplyDialog = false;
+			},
+
+			// 提交申请减免金额表单
+			confirmApplyForm() {
+				if (!this.applyForm.amount) {
+					return this.$toast('请填写优惠金额');
+				}
+				if (this.applyForm.amount > this.orderInfo.payAmount) {
+					return this.$toast('优惠金额不能大于订单总金额');
+				}
+				this.$axios({
+					url: '/promotion/apply/apply',
+					method: 'post',
+					type: 'application/json',
+					params: {
+						userId: this.userId,
+						buyGoods: this.buyList,
+						buyerMsg: this.remark,
+						userAddressId: this.addressInfo.userAddressId,
+						userCouponId: this.hasCoupon ? this.couponInfo.id : '',
+						exchangeCode: this.exchangeCode,
+						promotionGroupId: this.groupbuyId || '',
+						goodsPackageId: this.packageId || '',
+
+						applyAmount: this.applyForm.amount,
+						applyRemark: this.applyForm.remark,
+					},
+					isLoading: 1,
+				}).then((res) => {
+					this.cancelApplyForm();
+					this.$successToast('提交成功');
+					setTimeout(() => {
+						uni.redirectTo({
+							url: '/pages/mine/discount/list',
+						});
+					}, 500);
+				});
+			},
+		},
+	};
+</script>
+
+<style lang="scss">
+	.guobutishi {
+		width: 65%;
+		display: inline-block;
+		height: 100%;
+		z-index: 100;
+		display: flex;
+		border: 1px solid #fe781f;
+		box-sizing: border-box;
+		padding: 10rpx;
+		border-radius: 10rpx;
+
+		.guobutishi1 {
+			font-size: 22rpx;
+			border-radius: 10rpx;
+			background: red;
+			box-sizing: border-box;
+			padding: 0 10rpx;
+			color: #e5e5e5;
+			margin-right: 10rpx;
+		}
+
+		.guobutishi2 {
+			font-size: 24rpx;
+			color: #fe781f;
+		}
+	}
+
+	.app-container {
+		background: #f4f2f2;
+		padding: 20rpx 20rpx 160rpx;
+		box-sizing: border-box;
+
+		&.hasNoticebar {
+			padding-top: 84rpx;
+		}
+
+		.noticebar {
+			position: fixed;
+			top: 0;
+			left: 0;
+			width: 100%;
+			z-index: 100;
+		}
+	}
+
+	.card {
+		background: #ffffff;
+		border-radius: 20rpx;
+		margin-top: 20rpx;
+		padding: 0 20rpx;
+	}
+
+	.address-container {
+		background: #ffffff;
+		border-radius: 20rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		height: 150rpx;
+		padding: 0 20rpx;
+
+		.right {
+			width: 16rpx;
+			height: 28rpx;
+			flex-shrink: 0;
+		}
+
+		.left {
+			display: flex;
+			align-items: center;
+			margin-right: 20rpx;
+
+			.icon {
+				width: 52rpx;
+				height: 52rpx;
+				border-radius: 50%;
+				background: linear-gradient(-90deg, #ff4042 0%, #fe781f 100%);
+				display: flex;
+				flex-shrink: 0;
+				justify-content: center;
+				align-items: center;
+				margin-right: 20rpx;
+
+				image {
+					width: 28rpx;
+					height: 36rpx;
+				}
+			}
+
+			.nodata {
+				font-size: 28rpx;
+				color: #999999;
+			}
+
+			.hasdata {
+				.name {
+					font-size: 32rpx;
+					color: #333333;
+
+					text {
+						color: #999999;
+						font-size: 28rpx;
+						margin-left: 16rpx;
+					}
+				}
+
+				.address {
+					font-size: 28rpx;
+					color: #666666;
+					line-height: 34rpx;
+					margin-top: 10rpx;
+				}
+			}
+		}
+	}
+
+	.goods-container {
+		.title {
+			font-size: 32rpx;
+			color: #333333;
+			line-height: 32rpx;
+			padding-top: 20rpx;
+		}
+
+		.item {
+			padding: 20rpx 0;
+			display: flex;
+			align-items: center;
+			background: #ffffff;
+			border-bottom: 1px solid #eaeaea;
+
+			&:last-child {
+				border: none;
+			}
+
+			image {
+				width: 180rpx;
+				height: 180rpx;
+				display: block;
+				margin-right: 20rpx;
+				flex-shrink: 0;
+			}
+
+			.right {
+				width: 470rpx;
+				height: 190rpx;
+				display: flex;
+				justify-content: space-between;
+				flex-direction: column;
+
+				.name {
+					font-size: 28rpx;
+					color: #333333;
+					line-height: 36rpx;
+					height: 72rpx;
+				}
+
+				.des {
+					font-size: 24rpx;
+					color: #999999;
+					line-height: 36rpx;
+				}
+
+				.bottom {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+
+					.price {
+						display: flex;
+						flex-direction: column;
+					}
+
+					.price-1 {
+						font-size: 32rpx;
+						color: #ff3f42;
+						line-height: 36rpx;
+					}
+
+					.price-2 {
+						font-size: 26rpx;
+						color: #666666;
+						line-height: 30rpx;
+						text-decoration: line-through;
+					}
+				}
+			}
+		}
+	}
+
+	.row-container {
+		.item {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			min-height: 88rpx;
+			border-bottom: 1px solid #eaeaea;
+
+			&:last-child {
+				border: none;
+			}
+
+			.title {
+				font-size: 28rpx;
+				color: #333333;
+			}
+
+			.coupon {
+				display: flex;
+				align-items: center;
+
+				image {
+					width: 16rpx;
+					height: 28rpx;
+					margin-left: 15rpx;
+				}
+			}
+
+			.input {
+				width: 500rpx;
+
+				input {
+					width: 500rpx;
+					height: 88rpx;
+					text-align: right;
+				}
+			}
+
+			.radio-group {
+				display: flex;
+				height: 48rpx;
+				align-items: center;
+
+				.radio {
+					display: flex;
+					align-items: center;
+					margin-left: 30rpx;
+
+					.iconfont {
+						font-size: 36rpx;
+						color: #999999;
+						margin-right: 10rpx;
+
+						&.active {
+							color: #ff3f42;
+						}
+					}
+				}
+			}
+
+			.remark {
+				width: 500rpx;
+
+				textarea {
+					width: 500rpx;
+					padding: 20rpx 0;
+				}
+			}
+
+			.orange {
+				font-size: 28rpx;
+				color: #fe781f;
+			}
+		}
+	}
+
+	.bottom-container {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		z-index: 99;
+		width: 100%;
+		box-sizing: border-box;
+		background: #ffffff;
+		padding: 0 20rpx;
+		display: flex;
+		justify-content: flex-end;
+		align-items: center;
+		height: 100rpx;
+
+		.left {
+			font-size: 28rpx;
+			color: #333333;
+
+			text {
+				color: #ff3f42;
+			}
+		}
+
+		.btn-group {
+			display: flex;
+		}
+
+		.button {
+			width: 190rpx;
+			height: 80rpx;
+			border-radius: 80rpx;
+			background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
+			font-size: 28rpx;
+			color: #ffffff;
+			text-align: center;
+			line-height: 80rpx;
+		}
+
+		.button2 {
+			width: 190rpx;
+			height: 80rpx;
+			border-radius: 80rpx;
+			font-size: 28rpx;
+			color: #ff3f42;
+			text-align: center;
+			line-height: 80rpx;
+			margin-right: 10rpx;
+			border: 1px solid #ff3f42;
+			box-sizing: border-box;
+		}
+
+		.button3 {
+			width: 220rpx;
+			height: 80rpx;
+			border-radius: 80rpx;
+			font-size: 28rpx;
+			color: #ffffff;
+			text-align: center;
+			line-height: 80rpx;
+			margin-right: 10rpx;
+			border: 1px solid #ff3f42;
+			background: #ff3f42;
+			box-sizing: border-box;
+		}
+	}
+
+	.codeDialog {
+		position: fixed;
+		top: 40%;
+		left: 150rpx;
+		z-index: 999;
+		width: 400rpx;
+		background: #ffffff;
+		border-radius: 10rpx;
+		box-sizing: border-box;
+		padding: 20rpx 20rpx 40rpx;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+
+		.close {
+			width: 100%;
+			display: flex;
+			justify-content: flex-end;
+
+			image {
+				width: 32rpx;
+				height: 32rpx;
+				display: block;
+			}
+		}
+
+		.code {
+			margin-top: 10rpx;
+
+			image {
+				width: 280rpx;
+				height: 280rpx;
+				display: block;
+			}
+		}
+
+		.tips {
+			font-size: 28rpx;
+			color: #666666;
+			margin-top: 20rpx;
+		}
+	}
+
+	.apply-dialog {
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 9999;
+		width: 100%;
+		height: 100%;
+		background: rgba(0, 0, 0, 0.3);
+		display: flex;
+		align-items: center;
+		justify-content: center;
+
+		.dialog {
+			width: 600rpx;
+			background: #ffffff;
+			border-radius: 20rpx;
+			overflow: hidden;
+
+			.title {
+				font-size: 36rpx;
+				font-weight: 500;
+				text-align: center;
+				line-height: 100rpx;
+				padding-bottom: 10rpx;
+			}
+
+			.content {
+				padding: 0 40rpx 30rpx;
+
+				.row {
+					height: 50rpx;
+					display: flex;
+					align-items: center;
+					margin-bottom: 10rpx;
+					font-size: 28rpx;
+					color: #333333;
+
+					input {
+						flex: 1;
+						height: 50rpx;
+						border: 1px solid #e5e5e5;
+						margin-right: 16rpx;
+						padding: 0 12rpx;
+						font-size: 28rpx;
+					}
+				}
+			}
+
+			.btn {
+				border-top: 1px solid #eaeaea;
+				display: flex;
+
+				&>view {
+					flex: 1;
+					text-align: center;
+					line-height: 100rpx;
+					font-size: 32rpx;
+
+					&.left {
+						color: #666666;
+					}
+
+					&.right {
+						color: #ffffff;
+						background: #ff3f42;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 248 - 0
packageGoods/pages/search.vue

@@ -0,0 +1,248 @@
+<template>
+	<view class="app-container">
+		<view class="search-container">
+			<view class="search">
+				<image src="/static/icon/search.png" class=""></image>
+				<input type="text" confirm-type="search" placeholder="搜索商品名称或型号" v-model="keyword" @confirm="searchSubmit">
+			</view>
+		</view>
+		
+		<view class="list-container">
+			<block v-for="(item, index) in goodsList" :key='index'>
+				<view class="item" @tap="toGoodsDetail(item.goodsId)">
+					<view class="image">
+					  <image :src="item.imgUrl" mode="aspectFill" class="img"></image>
+					  <image
+					    :src="item.logo"
+					    mode="aspectFill"
+					    class="water"
+					    v-if="item.isShowWater"
+					  ></image>
+					</view>
+					<view class="content">
+						<view class="title ellipsis-2">{{item.goodsName}}</view>
+						<view class="bottom">
+							<view class="price">
+								<view class="price-1">¥{{item.goodsPrice | numToFixed}}</view>
+								<view class="price-2">¥{{item.orgGoodsPrice | numToFixed}}</view>
+							</view>
+							<view class="btn"><image src="@/static/icon/cart.png" mode="aspectFill"></image></view>
+						</view>
+					</view>
+				</view>
+			</block>
+		</view>
+		<no-data v-if="!goodsList.length" :showText="'暂无商品'"></no-data>
+		<loading-text v-if="goodsList.length"  :loading="loading" :noMore="noMore" ></loading-text>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				keyword: '',
+				goodsList: [],
+				pageNum: 1,
+				pageSize: 8,
+				noMore: false,
+				loading: false,
+			}
+		},
+		
+		onLoad({keyword}) {
+			this.keyword = keyword;
+			this.getGoodsList();
+		},
+		
+		// 下拉刷新
+		onPullDownRefresh() {
+			this.pageNum = 1;
+			this.getGoodsList();
+		},
+		
+		// 上拉加载
+		onReachBottom() {
+			this.getGoodsList(1);
+		},
+		
+		methods: {
+			// 获取商品列表
+			getGoodsList(loadMore) {
+				if(this.noMore && loadMore)return;
+				this.noMore = false
+				if(!loadMore){
+					this.pageNum = 1;
+				}else{
+					this.loading = true;
+				}
+				this.$axios({
+					url: '/goods/list/sort/page',
+					method: 'get',
+					params: {
+						pageNum: this.pageNum,
+						pageSize: this.pageSize,
+						keyword: this.keyword,
+					},
+					isLoading: !loadMore
+				}).then(res => {
+					res.data.records.forEach((item) => {
+					  if (item.logo && item.logoStartTime) {
+					    item.isShowWater = this.$compareTime(
+					      item.logoStartTime,
+					      item.logoEndTime
+					    );
+					  } else {
+					    item.isShowWater = false;
+					  }
+					});
+					let _list = res.data.records;
+					let pageTotal = res.data.pages;
+					if(this.pageNum >= pageTotal){
+						this.noMore = true;
+					}
+					if (_list.length) {
+						this.pageNum += 1
+					}
+					if (loadMore) {
+						this.goodsList = this.goodsList.concat(_list);
+						this.loading = false;
+					} else {
+						this.goodsList = _list;
+					}
+					
+					uni.stopPullDownRefresh();
+				})
+			},
+			
+			searchSubmit() {
+				this.getGoodsList();
+			},
+			
+			toGoodsDetail(id) {
+				uni.navigateTo({
+					url:'/packageGoods/pages/detail?id=' + id
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.app-container {
+		background: #F4F2F2;
+		box-sizing: border-box;
+		padding-top: 90rpx;
+	}
+	.search-container {
+		background: #FFFFFF;
+		padding: 12rpx 20rpx;
+		border-bottom: 1px solid #F4F2F2;
+		position: fixed;
+		top: 0;
+		left: 0;
+		width: 100%;
+		box-sizing: border-box;
+		.search {
+			height: 64rpx;
+			display: flex;
+			align-items: center;
+			background: #F0F0F0;
+			border-radius: 64rpx;
+			padding: 0 20rpx;
+			image {
+				width: 28rpx;
+				height: 28rpx;
+			}
+			input {
+				width: 100%;
+				padding-left: 15rpx;
+			}
+		}
+	}
+	.list-container {
+		display: flex;
+		flex-wrap: wrap;
+		padding: 20rpx;
+		.item {
+			width: 348rpx;
+			background: #FFFFFF;
+			margin-right: 14rpx;
+			margin-bottom: 20rpx;
+			border-radius: 20rpx;
+			overflow: hidden;
+			&:nth-child(2n) {
+				margin-right: 0;
+			}
+			// image {
+			// 	width: 348rpx;
+			// 	height: 348rpx;
+			// }
+			.image {
+			  width: 348rpx;
+			  height: 348rpx;
+			  flex-shrink: 0;
+			  position: relative;
+			  .img {
+			    width: 348rpx;
+			    height: 348rpx;
+			    display: block;
+			  }
+			  .water {
+			    width: 348rpx;
+			    height: 348rpx;
+			    display: block;
+			    position: absolute;
+			    left: 0;
+			    top: 0;
+			    z-index: 1;
+			  }
+			}
+			.content {
+				padding: 15rpx 20rpx;
+				.title {
+					font-size: 30rpx;
+					color: #333333;
+					line-height: 36rpx;
+					font-weight: 600;
+					height: 72rpx;
+				}
+				.bottom {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					margin-top: 10rpx;
+					.price {
+						display: flex;
+						flex-direction: column;
+					}
+					.price-1 {
+						font-size: 32rpx;
+						color: #FF3F42;
+						line-height: 36rpx;
+					}
+					.price-2 {
+						font-size: 26rpx;
+						color: #666666;
+						line-height: 30rpx;
+						text-decoration: line-through;
+					}
+					.btn {
+						width: 60rpx;
+						height: 60rpx;
+						background: #FE781F;
+						border-radius: 50%;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						image {
+							width: 41rpx;
+							height: 36rpx;
+							display: block;
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 458 - 0
packageGoods/pages/seckill.vue

@@ -0,0 +1,458 @@
+<template>
+	<view class="app-container">
+		<view class="bg-container">
+			<image src="@/static/home/top_bg.png" mode="widthFix"></image>
+		</view>
+		<view class="top-container">
+			<image src="@/static/home/top_bg2.png" mode="widthFix" class="front-bg" v-if="StatusBar <= 20"></image>
+			<image src="@/static/home/top_bg3.png" mode="widthFix" class="front-bg" v-if="StatusBar > 20"></image>
+			
+			<view class="content" :style="'height:' + (StatusBar > 20 ? getpx(350) : getpx(300)) + 'px'">
+				<view class="title" :style="cuStyle">
+					<view class="left" @tap="toBack">
+						<image src="@/static/icon/back.png"></image>
+					</view>
+					<view class="tit">限时秒杀</view>
+					<view class="right"></view>
+				</view>
+				<view class="time-list">
+					<block v-for="(item, index) in seckillTimeList" :key='index'>
+						<view class="item" :class="seckillTimeCurrent == index ? 'current':''" @tap="changeSeckillTime(index)">
+							<view class="time">{{item.startHour}}:00</view>
+							<view class="tag" v-if="item.type == 'yjs'">已结束</view>
+							<view class="tag" v-if="item.type == 'jxz'">{{countdownTime}}</view>
+							<view class="tag" v-if="item.type == 'wks'">即将开始</view>
+						</view>
+					</block>
+				</view>
+			</view>
+		</view>
+		<view class="list-container">
+			<scroll-view class="scroll-view" scroll-y :refresher-triggered="refresherTriggered" @scrolltolower="scrolltolower" @refresherrefresh="refresherrefresh" refresher-enabled  :class="StatusBar > 20 ? 'higher':''">
+				<block v-for="(item, index) in goodsList" :key='index'>
+					<div class="item" @tap="toSeckillGoodsDetail(item.goodsId)">
+						<image :src="item.imgUrl" mode="aspectFill"></image>
+						<view class="right">
+							<view class="title ellipsis-2">{{item.goodsName}}</view>
+							<view class="des ellipsis-2">{{item.describeText ? item.describeText : ''}}</view>
+							<view class="stock-sales">
+								<view class="stock">
+									<text>剩余{{item.secStockNum}}件</text>
+									<view class="progress-box">
+										<!-- 库存 / 总数 * 100 = 剩余百分比 -->
+										<progress :percent="item.secStockNum / item.limitBuy * 100" activeColor="#FF3F42" active stroke-width="6" />
+									</view>
+								</view>
+								<view class="sales">销量:{{item.salesVolume}}</view>
+							</view>
+							<view class="bottom">
+								<view class="price">
+									<view class="price-1">¥{{item.price | numToFixed}}</view>
+									<view class="price-2">¥{{item.goodsPrice | numToFixed}}</view>
+								</view>
+								<view class="btn" v-if="seckillTimeList[seckillTimeCurrent].type == 'jxz'">马上抢</view>
+								<view class="btn2" v-else>马上抢</view>
+							</view>
+						</view>
+					</div>
+				</block>
+				<no-data v-if="!goodsList.length" :showText="'暂无商品'"></no-data>
+				<loading-text v-if="goodsList.length"  :loading="loading" :noMore="noMore" ></loading-text>
+			</scroll-view>
+		</view>
+		
+		<!-- <drag-button :isDock="true" :customBar="false" ref="dragButton"></drag-button> -->
+	</view>
+</template>
+
+<script>
+	import {mapState} from 'vuex';
+	// import dragButton from '@/components/drag-button.vue';
+	
+	export default {
+		// components:{
+		// 	dragButton
+		// },
+		data() {
+			return {
+				scrollTop: 0, // 滚动高度(用于控制自定义导航)
+				seckillTimeList: [], // 秒杀时间段列表
+				seckillTimeCurrent: 0, // 秒杀时间段选择
+				goodsList: [], // 秒杀商品列表
+				pageNum: 1,
+				pageSize: 8,
+				noMore: false,
+				loading: false,
+				countdownTime: '', // 倒计时
+				endDatetime: '', // 倒计时结束时间
+				nowDate: null, // 当前时间
+				dateInterval: null, // 时间定时器
+				refresherTriggered: false,
+				StatusBar: this.StatusBar
+			}
+		},
+		computed:{
+			cuStyle(){
+				return `height:${this.CustomBar-this.StatusBar}px; padding-top:${this.StatusBar}px;`
+			},
+			...mapState(['userInfo', 'isLogin', 'userId']),
+			isLoaded() {
+				uni.hideLoading();
+				return this.isLoaded_banner && this.isLoaded_coupon && this.isLoaded_seckill && this.isLoaded_tab && this.isLoaded_myManager;
+			}
+		},
+		watch: {
+			nowDate() {
+				let hh = this.nowDate.getHours(),
+					mm = this.nowDate.getMinutes(),
+					ss = this.nowDate.getSeconds();
+				let hs = [10, 12, 15, 18, 20];
+				if(mm == 0 && ss == 0 && hs.indexOf(hh) >= 0) {
+					setTimeout(() => {
+						this.getSeckillTimeList();
+					}, 1000)
+				}
+			}
+		},
+		onShow() {
+			// this.$refs.dragButton.init();
+		},
+		onLoad() {
+			this.getSeckillTimeList();
+		},
+		methods: {
+			toBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			
+			getpx(val) {
+				return uni.upx2px(val);
+			},
+			
+			// 下拉刷新
+			refresherrefresh() {
+				this.refresherTriggered = true;
+				this.pageNum = 1;
+				this.getSeckillGoodsList();
+			},
+			
+			// 上拉加载
+			scrolltolower() {
+				this.getSeckillGoodsList(true);
+			},
+			
+			findElem(array, attr, val) {
+			    for (var i = 0; i < array.length; i++) {
+			        if (array[i][attr] == val) {
+			            return i; //返回当前索引值
+			        }
+			    }
+			    return -1;
+			},
+			
+			// 计算倒计时
+			countTime() {
+				let endDatetime = this.endDatetime.replace(/\-/g, '/');
+				// console.log(endDatetime)
+			    var nowtime = new Date(),  //获取当前时间
+			        endtime = new Date(endDatetime);  //定义结束时间
+			    var lefttime = endtime.getTime() - nowtime.getTime(),  //距离结束时间的毫秒数
+			        hh = Math.floor(lefttime/(1000*60*60)),  //计算小时数
+			        mm = Math.floor(lefttime/(1000*60)%60),  //计算分钟数
+			        ss = Math.floor(lefttime/1000%60);  //计算秒数
+				// console.log(new Date(endDatetime))
+				function checkTime(i){
+					if (i<10) {
+						i = "0"+i;
+					}
+					return i;
+				}
+				setTimeout(() => {
+					this.countTime();
+				}, 1000);
+				this.countdownTime = checkTime(hh) + ":" + checkTime(mm) + ":" + checkTime(ss);
+				// console.log(this.countdownTime)
+			},
+			
+			// 获取秒杀时间列表
+			getSeckillTimeList() {
+				this.$axios({
+					url: '/goods/sec/time',
+					method: 'get',
+					params: {}
+				}).then(res => {
+					if(res.data.length < 1) {return false;}
+					this.seckillTimeList = res.data;
+					this.seckillTimeCurrent = this.findElem(this.seckillTimeList, 'type', 'jxz');
+					if(this.seckillTimeCurrent == -1) {
+						this.seckillTimeCurrent = 0;
+						this.getSeckillGoodsList();
+					}else {
+						this.endDatetime = this.seckillTimeList[this.seckillTimeCurrent].endDatetime;
+						this.countTime();
+						this.getSeckillGoodsList();
+					}
+				}).finally(res => {
+					this.isLoaded_seckill = true;
+				})
+			},
+			
+			// 切换秒杀时间
+			changeSeckillTime(index) {
+				this.seckillTimeCurrent = index;
+				this.getSeckillGoodsList();
+			},
+			
+			// 获取秒杀商品列表
+			getSeckillGoodsList(loadMore) {
+				if(this.noMore && loadMore)return;
+				this.noMore = false;
+				if(!loadMore){
+					this.pageNum = 1;
+				}else{
+					this.loading = true;
+				}
+				let secKillId = this.seckillTimeList[this.seckillTimeCurrent].secKillId;
+				this.$axios({
+					url: '/goods/sec/goods/list',
+					method: 'get',
+					params: {
+						pageNum: this.pageNum,
+						pageSize: this.pageSize,
+						secKillId: secKillId,
+					}
+				}).then(res => {
+					let _list = res.data.records;
+					let pageTotal = res.data.pages;
+					if(this.pageNum >= pageTotal){
+						this.noMore = true;
+					}
+					if (_list.length) {
+						this.pageNum += 1
+					}
+					if (loadMore) {
+						this.goodsList = this.goodsList.concat(_list);
+						this.loading = false;
+					} else {
+						this.goodsList = _list;
+					}
+				}).finally(res => {
+					this.refresherTriggered = false;
+				})
+			},
+			
+			// 进入秒杀商品详情
+			toSeckillGoodsDetail(id) {
+				if(!id) {
+					return false;
+				}
+				if(this.seckillTimeList[this.seckillTimeCurrent].type == 'wks') {
+					return this.$toast('活动未开始');
+				}
+				uni.navigateTo({
+					url: '/packageGoods/pages/detail?id=' + id
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.app-container {
+		background: #F4F2F2;
+		box-sizing: border-box;
+	}
+	.bg-container {
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 0;
+		image {
+			width: 750rpx;
+		}
+	}
+	.top-container {
+		position: relative;
+		.front-bg {
+			display: block;
+			width: 750rpx;
+			position: absolute;
+			top: 0;
+			z-index: 0;
+		}
+		.content {
+			width: 750rpx;
+			padding: 0 20rpx;
+			position: relative;
+			box-sizing: border-box;
+			z-index: 1;
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+		}
+		.title {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			color: #FFFFFF;
+			font-size: 36rpx;
+			.left {
+				width: 50rpx;
+				height: 50rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+			image {
+				width: 32rpx;
+				height: 32rpx;
+				display: block;
+			}
+			.right {
+				width: 50rpx;
+				height: 50rpx;
+			}
+		}
+		.time-list {
+			flex: 1;
+			display: flex;
+			overflow-x: scroll;
+			align-items: center;
+			.item {
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				flex-shrink: 0;
+				width: 140rpx;
+				margin-right: 48rpx;
+				.time {
+					font-size: 32rpx;
+					color: #FFFFFF;
+				}
+				.tag {
+					width: 140rpx;
+					height: 44rpx;
+					border-radius: 44rpx;
+					border: 1px solid #FFFFFF;
+					font-size: 24rpx;
+					color: #FFFFFF;
+					box-sizing: border-box;
+					margin-top: 12rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+				&.current {
+					.tag {
+						background: #FFFFFF;
+						color: #FF3F42;
+					}
+				}
+			}
+		}
+	}
+	.list-container {
+		padding: 0 20rpx;
+		.scroll-view {
+			height: calc(100vh - 300rpx);
+			&.higher {
+				height: calc(100vh - 350rpx);
+			}
+		}
+		.item {
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			display: flex;
+			padding: 20rpx;
+			margin-bottom: 20rpx;
+			image {
+				display: block;
+				width: 180rpx;
+				height: 180rpx;
+				flex-shrink: 0;
+			}
+			.right {
+				width: 490rpx;
+				box-sizing: border-box;
+				padding-left: 20rpx;
+				.title {
+					font-size: 30rpx;
+					color: #333333;
+					line-height: 36rpx;
+					font-weight: 600;
+				}
+				.des {
+					font-size: 24rpx;
+					line-height: 30rpx;
+					color: #999999;
+					margin-top: 6rpx;
+				}
+				.stock-sales {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					margin-top: 10rpx;
+					font-size: 24rpx;
+					color: #666666;
+					.stock {
+						display: flex;
+						align-items: center;
+						text {
+							font-size: 24rpx;
+							color: #666666;
+						}
+						.progress-box {
+							width: 140rpx;
+							border-radius: 6px;
+							overflow: hidden;
+							margin-left: 10rpx;
+						}
+					}
+				}
+				.bottom {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					margin-top: 10rpx;
+					.price {
+						display: flex;
+						flex-direction: column;
+					}
+					.price-1 {
+						font-size: 32rpx;
+						color: #FF3F42;
+						line-height: 36rpx;
+					}
+					.price-2 {
+						font-size: 26rpx;
+						color: #666666;
+						line-height: 30rpx;
+						text-decoration: line-through;
+					}
+					.btn {
+						width: 110rpx;
+						height: 44rpx;
+						background: #FF3F42;
+						border-radius: 5rpx;
+						font-size: 28rpx;
+						color: #FFFFFF;
+						text-align: center;
+						line-height: 44rpx;
+					}
+					.btn2 {
+						width: 110rpx;
+						height: 44rpx;
+						background: #AAAAAA;
+						border-radius: 5rpx;
+						font-size: 28rpx;
+						color: #FFFFFF;
+						text-align: center;
+						line-height: 44rpx;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 27 - 0
packageGoods/pages/template.vue

@@ -0,0 +1,27 @@
+<template>
+	<view class="app-container">
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.app-container {
+		background: #F4F2F2;
+		padding: 0 30rpx;
+		padding-top: 20rpx;
+		box-sizing: border-box;
+	}
+</style>