### 0.6.0 专业版(大版本升级,破坏性升级,请酌情处理):

【新增】弃用现在sku前端,启用全新sku组件,更加灵活,体验更好。
【新增】新增通过商品序列获取sku全新列表功能。
【新增】仓储层底层增加二级缓存功能,后面将逐步完善底层缓存中心模块。
【新增】0元购,积分兑换模式下,也去计算用户是否科技升级。
【新增】数据及业务仓储增加二级缓存功能。curd可自主控制是否缓存和清除。
【新增】订单导出excel数据增加商品名称+货品sku组合展示的方式。
【新增】自定义交易组件增加【获取商家信息】【更新商家信息】两个接口处理。
【新增】增加公告列表及公告详情页面,首页组件公告点击跳转列表展示。
【新增】个人中心增加【公告中心】入口。
【新增】后台余额变动增加说明录入。

【调整】将前端能进行分包的文件夹都进行分包,减少主包占用,方便进行二开。
【调整】因ckeditor5存在图片不可设置宽度,上传不支持mp4,排版不畅等情况,降级使用ckeditor4版本。
【修复】修复0.5.5版本售后积分返还机制积分模式判断异常的问题。
【修复】修复使用积分全额抵扣,或其他优惠政策导致的0元购,未进行短信提醒及小票打印机未打印的问题。
【修复】修复更换ckeditor4编辑器后接龙添加编辑调用失败的问题。
【修复】修复积分全额抵扣,金额0元购的情况下,进行售后执行完毕,订单未完结的情况。
【优化】去除分销申请面板按钮无用并失效报错的customStyle属性。
【优化】优化部分方法中使用手写字符串的遗留问题,统一采用enum方式。
【优化】优化前端及接口部分命名错误的问题。错将skill误写成seckill。
【优化】去除uniapp端多个客服代码。
【优化】商品详情底部完善购物车数量显示的问题。
【优化】优化团购列表,拼团列表,秒杀页面页面样式布局差异问题。
【优化】调整支付结果界面样式效果,仿微信支付结果界面。更加清晰明朗。
【优化】优化售后提交页面json计算,开放当用户下单后但未发货情况下,可以申请直接售后的操作需求。
【优化】后台商家手机号码支持设置多个,使用小写逗号分隔,方便多个商家管理员接收下单提醒。
【优化】后台售后单审核,调整售后商品为必选项。
This commit is contained in:
大灰灰
2022-09-14 00:53:04 +08:00
parent 6ce893cb38
commit 7b68f352d7
3118 changed files with 161226 additions and 10176 deletions

View File

@@ -0,0 +1,20 @@
{ // launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"app-plus" :
{
"launchtype" : "local"
},
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

View File

@@ -0,0 +1,191 @@
<script>
import Vue from 'vue'
export default {
//使用方法
//getApp().globalData.showLoginTip = false
//console.log(getApp().globalData.text)
globalData: {
showLoginTip: false,
},
onLaunch() {
// #ifdef MP-WEIXIN
this.autoUpdate();
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.checkVersion()
// #endif
// 获取店铺配置信息 全局只请求一次
this.$u.api.shopConfigV2().then(res => {
this.$store.commit('config', res.data)
// #ifdef H5
//百度统计
if (res.data.statistics) {
var script = document.createElement("script");
script.innerHTML = res.data.statistics;
document.getElementsByTagName("body")[0].appendChild(script);
}
// #endif
})
//获取三级联动城市信息
this.$u.api.getAreaList().then(res => {
if (res.status) {
this.$db.set('areaList', res.data)
}
});
},
onShow: function (obj) {
// #ifdef MP-WEIXIN
this.$store.commit('scene', obj.scene)
console.log(obj);
// #endif
//console.log('App Show')
},
onHide: function () {
//console.log('App Hide')
},
methods: {
// #ifdef MP-WEIXIN
//微信小程序检测更新措施方式更新功能后要等待24小时内才刷新的问题。
autoUpdate() {
var self = this
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
//console.log("进入小程序自动更新检测");
const updateManager = wx.getUpdateManager()
//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function (res) {
//console.log("进入小程序检测是否需要自动更新");
//console.log(res);
// 请求完新版本信息的回调
if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({
title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?',
success: function (res) {
if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager)
} else if (res.cancel) {
//用户点击取消按钮,需要强制更新,二次弹窗
wx.showModal({
title: '温馨提示~',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
showCancel: false,
confirmText: "确定更新",
success: function (res) {
if (res.confirm) {
//下载新版本,并重新应用
self.downLoadAndUpdate(updateManager)
}
}
})
}
}
})
}
})
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
},
downLoadAndUpdate(updateManager) {
var self = this
wx.showLoading();
//静默下载更新小程序新版本
updateManager.onUpdateReady(function () {
wx.hideLoading()
//新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
})
updateManager.onUpdateFailed(function () {
// 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
},
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
// app更新检测
checkVersion() {
// 获取应用版本号
let _this = this;
let version = plus.runtime.version;
console.log('版本号:' + version);
//检测当前平台,如果是安卓则启动安卓更新
uni.getSystemInfo({
success: res => {
console.log('当前平台:' + res.platform);
if (res.platform =='android') {
_this.updateHandler(version);
}
}
})
},
// 更新操作
updateHandler(version) {
let _this = this;
this.$u.api.getAppVersion().then(res => {
console.log(res);
if (res.status && res.data) {
if (res.data.version !== '' && res.data.version > version) {
uni.showModal({
//提醒用户更新
title: '更新提示',
content: res.data.note,
success: function (resOpen) {
if (resOpen.confirm) {
plus.runtime.openURL(res.data.android)
console.log('用户点击确定');
} else if (resOpen.cancel) {
console.log('用户点击取消');
}
}
})
}
}
});
}
// #endif
}
}
</script>
<style lang="scss">
/* 注意要写在第一行同时给style标签加入lang="scss"属性 */
@import "@/uni_modules/uview-ui/index.scss";
/*公共css */
@import '@/static/style/coreCommon.scss';
@import "@/static/style/tags";
// vue App的样式
/* #ifdef APP-PLUS */
@import "@/static/style/style.vue.scss";
/* #endif */
// nvue的特有样式
// #ifdef APP-PLUS-NVUE
@import "@/static/style/style.nvue.scss";
/* #endif */
// 小程序特有的样式
/* #ifdef MP */
@import "@/static/style/style.mp.scss";
/* #endif */
// H5特有的样式
/* #ifdef H5 */
@import "@/static/style/style.h5.scss";
/* #endif */
</style>

View File

@@ -0,0 +1,361 @@
import { navLinkType } from '@/common/setting/constVarsHelper.js';
/**
* 全局混入型
*/
module.exports = {
beforeCreate() {
},
data() {
return {
/**
* 页面加载
*/
pageLoading: true
}
},
methods: {
/**
* //常用链接操作
*/
//返回首页
goHome() {
uni.switchTab({ url: '/pages/index/default/default' });
},
//返回上一页
goNavigateBack() {
uni.navigateBack();
},
//路由跳转
goRoute(url) {
// 无参数
this.$u.route(url);
},
goRoute(url, params) {
// 带参数,传递的对象形式的参数,如{name: 'lisa', age: 18}
this.$u.route(url, params);
},
//查看所在坐标地图位置
goShopMap() {
var reshipCoordinate = this.$store.state.config.reshipCoordinate;
if (reshipCoordinate && reshipCoordinate.indexOf(",") != -1) {
var arr = reshipCoordinate.split(',')
this.$u.route('/pages/map/map', { id: 1, latitude: arr[0], longitude: arr[1], });
}
},
//查看所在坐标地图位置
goMapDetails(id, latitude, longitude) {
this.$u.route('/pages/map/map', { id: id, latitude: latitude, longitude: longitude, });
},
goUserCenter() {
this.$u.route({ url: '/pages/index/member/member', type: 'switchTab' });
},
goSearch() {
this.$u.route({ url: '/pages/search/search', });
},
// 返回上一页
toBackBtn() {
var pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack({
delta: 1
});
} else {
this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' });
}
},
//返回操作处理
toOnBackPress(options) {
if (options.from === 'navigateBack') {
return false
}
let loginPages = ['/pages/index/cart/cart', '/pages/index/member/member']
let backPage = this.$store.state.redirectPage
if (loginPages.indexOf(backPage) > -1) {
this.$store.commit({
type: 'redirect',
page: ''
})
this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' })
return true
}
},
//登录成功统一跳转处理
toLoginSuccessHandleBack() {
let redirect = this.$store.state.redirectPage
this.$store.commit({
type: 'redirect',
page: ''
})
let switchTabs = ['/pages/index/default/default', '/pages/index/member/member']
if (switchTabs.indexOf(redirect) > -1) {
this.$u.route({ type: 'switchTab', url: redirect })
} else if (redirect) {
this.$u.route({ type: 'switchTab', url: redirect })
} else {
this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' })
}
},
// 购物车页面跳转
redirectCart() {
this.$u.route({
type: 'switchTab',
url: '/pages/index/cart/cart'
});
},
/**
* 订单接口信息
*/
// 查看订单详情
goOrderDetail(orderId) {
this.$u.route('/pages/member/order/detail/detail', { orderId: orderId });
},
// 取消订单
// 去支付
goToPay(orderId) {
this.$u.route('/pages/payment/pay/pay', { orderId: orderId, type: 1 });
},
// 确认收货
// 去评价
toEvaluate(orderId) {
this.$u.route('/pages/member/order/evaluate/evaluate', { orderId: orderId });
},
// 申请售后
// 查看物流信息
goShowExpress(code, no, address = '', mobile = '') {
let params = encodeURIComponent(
'code=' + code + '&no=' + no + '&add=' + address + '&mobile=' + mobile
)
this.$u.route('/pages/member/order/expressDelivery/expressDelivery', { params: params });
},
/**
* 商品接口信息
*/
// 查看商品详情
goGoodsDetail(goodsId) {
this.$u.route('/pages/goods/goodDetails/goodDetails', { id: goodsId });
},
// 查看商品评论详情
goGoodComments(goodsId) {
this.$u.route('/pages/goods/goodComments/goodComments', { id: goodsId });
},
// 跳转商品列表页
goGoodsList(obj = {}) {
let url = '/pages/category/list/list'
if (Object.keys(obj).length) {
url = url + this.$u.queryParams(obj)
}
this.$u.route(url)
},
// 秒杀详情
goSeckillDetail(id, groupId) {
this.$u.route('/pages/activity/seckill/seckillDetails/seckillDetails', { id: id, groupId: groupId, });
},
// 团购详情
goGroupBuyingDetail(id, groupId) {
this.$u.route('/pages/activity/groupBuying/groupBuyingDetails/groupBuyingDetails', { id: id, groupId: groupId, });
},
//拼团详情页
goPinTuanDetail(id, pinTuanId, teamId) {
if (teamId) {
this.$u.route('/pages/activity/pinTuan/pinTuanDetails/pinTuanDetails', { id: id, pinTuanId: pinTuanId, teamId: teamId, });
} else {
this.$u.route('/pages/activity/pinTuan/pinTuanDetails/pinTuanDetails', { id: id, pinTuanId: pinTuanId });
}
},
// 查看秒杀列表
goSeckillList() {
this.$u.route('/pages/activity/seckill/list/list')
},
// 查看拼团列表
goPinTuanList() {
this.$u.route('/pages/activity/pinTuan/list/list')
},
/**
* 文章接口
*/
// 查看文章总列表
goArticleList() {
this.$u.route('/pages/article/list/list')
},
// 查看文章详情
goArticleDetail(id) {
this.$u.route('/pages/article/details/details', { idType: 1, id: id });
},
/**
* 公告接口
*/
// 查看公告列表
goNoticeList() {
this.$u.route('/pages/notice/list/list')
},
// 查看公告详情
goNoticeDetail(id) {
this.$u.route('/pages/notice/details/details', { id: id });
},
// 前往用户协议
goUserAgreementPage() {
var id = this.$store.state.config.userAgreementId;
this.$u.route('/pages/article/details/details', { idType: 1, id: id });
},
// 前往隐私协议
goUserPrivacyPolicy() {
var id = this.$store.state.config.privacyPolicyId;
this.$u.route('/pages/article/details/details', { idType: 1, id: id });
},
// 关于我们
goAboutUs() {
let id = this.$store.state.config.aboutArticleId;
this.$u.route('/pages/article/details/details', { idType: 1, id: id });
},
/**
* 接龙接口信息
*/
// 查看服务详情
goSolitaireDetail(id) {
this.$u.route('/pages/activity/solitaire/solitaireDetails/solitaireDetails', { id: id });
},
// 查看服务列表
goSolitaireList() {
this.$u.route('/pages/activity/solitaire/list/list')
},
//服务接口信息
// 查看服务详情
goServicesDetail(serviceId) {
this.$u.route('/pages/serviceGoods/details/details', { id: serviceId });
},
// 查看服务列表
goServicesList() {
this.$u.route('/pages/serviceGoods/index/index')
},
// 查看个人详情
goServicesUserDetail(serviceId) {
this.$u.route('/pages/member/serviceOrder/details/details', { id: serviceId });
},
/**
* 广告相关
*/
// 广告点击查看详情
showSliderInfo(type, val) {
if (!val) {
return;
}
if (type == navLinkType.urlLink) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = val
// #endif
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
this.$u.route('/pages/webview/webview', { src: val });
// #endif
} else {
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
if (val == '/pages/index/default/default' || val == '/pages/category/index/index' || val == '/pages/index/cart/cart' || val == '/pages/index/member/member') {
this.$u.route({ type: 'switchTab', url: val });
return;
} else if (val.indexOf('/pages/coupon/coupon?id=') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == navLinkType.shop) {
// 商品详情
this.$u.route('/pages/goods/goodDetails/goodDetails', { id: val });
} else if (type == navLinkType.article) {
// 文章详情
this.$u.route('/pages/article/details/details', { idType: 1, id: val });
} else if (type == navLinkType.articleCategory) {
// 文章列表
this.$u.route('/pages/article/list/list')
} else if (type == navLinkType.intelligentForms) {
//自定义表单
this.$u.route('/pages/form/details/details', { id: val });
} else {
this.$u.route(val);
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let _this = this;
let coreshopdata = {
id: couponId
}
this.$u.api.getCoupon(coreshopdata).then(res => {
if (res.status) {
_this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
_this.$u.toast(res.msg)
}
})
},
/**
* 工具函数
*/
doCopyData(data) {
var _this = this;
uni.setClipboardData({
data: data,
success: function () {
_this.$u.toast('复制成功')
}
});
},
doPhoneCall() {
var phome = this.$store.state.config.shopMobile || 0;
if (phome != 0) {
uni.makePhoneCall({
phoneNumber: phome
});
}
},
goBack() {
//处理兼容,如果没有上一级界面则返回首页
const pages = getCurrentPages();
if (pages.length === 2) {
uni.navigateBack({
delta: 1
});
} else if (pages.length === 1) {
uni.switchTab({
url: '/pages/index/default/default',
})
} else {
uni.navigateBack({
delta: 1
});
}
},
}
}

View File

@@ -0,0 +1,608 @@
const http = uni.$u.http
// 此处第二个参数vm就是我们在页面使用的this你可以通过vm获取vuex等操作更多内容详见uView对拦截器的介绍部分
// https://uviewui.com/js/http.html#%E4%BD%95%E8%B0%93%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%EF%BC%9F
const install = (Vue, vm) => {
// 获取店铺配置
//let shopConfig = (params, config = {}) => http.post('/Api/Common/GetConfig', params, { custom: { methodName: 'common.shopConfig', needToken: false } });
let shopConfigV2 = (params, config = {}) => http.post('/Api/Common/GetConfigV2', params, { custom: { methodName: 'common.shopConfigV2', needToken: false } });
//获取商城关键词说明
let getServiceDescription = (params, config = {}) => http.post('/Api/Common/GetServiceDescription', params, { custom: { methodName: 'common.getServiceDescription', needToken: false } });
// 用户信息
let userInfo = (params, config = {}) => http.post('/Api/User/GetUserInfo', params, { custom: { methodName: 'user.info', needToken: true } });
// 上传头像
let changeAvatar = (params, config = {}) => http.post('/Api/User/ChangeAvatar', params, { custom: { methodName: 'user.changeavatar', needToken: true } });
// 编辑用户信息
let editInfo = (params, config = {}) => http.post('/Api/User/EditInfo', params, { custom: { methodName: 'user.editinfo', needToken: true } });
// 发送短信验证码
let sms = (params, config = {}) => http.post('/Api/User/SendSms', params, { custom: { methodName: 'user.sms', needToken: false } });
// 短信验证码登录
let smsLogin = (params, config = {}) => http.post('/Api/User/SmsLogin', params, { custom: { methodName: 'user.smslogin', needToken: false } });
// 退出登录
let logout = (params, config = {}) => http.post('/Api/User/LogOut', params, { custom: { methodName: 'user.logout', needToken: true } });
// 获取首页幻灯片
let slider = (params, config = {}) => http.post('/Api/Advert/GetAdvertList', params, { custom: { methodName: 'advert.getAdvertList', needToken: false } });
// 获取广告
let advert = (params, config = {}) => http.post('/Api/Advert/GetPositionList', params, { custom: { methodName: 'advert.getcarousellists', needToken: false } });
// 获取公告列表
let notice = (params, config = {}) => http.post('/Api/Notice/NoticeList', params, { custom: { methodName: 'notice.noticeList', needToken: false } });
// 获取公告详情
let noticeInfo = (params, config = {}) => http.post('/Api/Notice/NoticeInfo', params, { custom: { methodName: 'notice.noticeInfo', needToken: false } });
// 获取文章详情
let articleInfo = (params, config = {}) => http.post('/Api/Article/GetArticleDetail', params, { custom: { methodName: 'articles.getArticleDetail', needToken: false } });
// 获取文章列表
let articleList = (params, config = {}) => http.post('/Api/Article/GetArticleList', params, { custom: { methodName: 'articles.getArticleList', needToken: false } });
// 获取商品分类
let categories = (params, config = {}) => http.post('/Api/Good/GetAllCategories', params, { custom: { methodName: 'categories.getallcat', needToken: false } });
// 获取商品列表
let goodsList = (params, config = {}) => http.post('/Api/Good/GetGoodsPageList', params, { custom: { methodName: 'goods.goodsList', needToken: false } });
//获取随机推荐商品
let getGoodsRecommendList = (params, config = {}) => http.post('/Api/Good/GetGoodsRecommendList', params, { custom: { methodName: 'goods.getGoodsRecommendList', needToken: false } });
// 获取商品参数信息
let goodsParams = (params, config = {}) => http.post('/Api/Good/GetGoodsParams', params, { custom: { methodName: 'goods.getgoodsparams', needToken: false } });
// 获取设置默认货品
let getProductInfo = (params, config = {}) => http.post('/Api/Good/GetProductInfo', params, { custom: { methodName: 'goods.getproductinfo', needToken: false } });
// 获取商品评论信息
let goodsComment = (params, config = {}) => http.post('/Api/Good/GetGoodsComment', params, { custom: { methodName: 'goods.getgoodscomment', needToken: false } });
// 获取商品详情
let goodsDetail = (params, config = {}) => http.post('/Api/Good/GetDetial', params, { custom: { methodName: 'goods.getdetial', needToken: false } });
// 获取商品详情
let goodsDetailByToken = (params, config = {}) => http.post('/Api/Good/GetDetialByToken', params, { custom: { methodName: 'goods.getDetialByToken', needToken: true } });
// 获取商品详情
let goodsSku = (params, config = {}) => http.post('/Api/Good/GetSku', params, { custom: { methodName: 'goods.getdetial', needToken: false } });
// 获取商品详情
let goodsSkuByToken = (params, config = {}) => http.post('/Api/Good/GetSkuByToken', params, { custom: { methodName: 'goods.getDetialByToken', needToken: true } });
// 添加购物车
let addCart = (params, config = {}) => http.post('/Api/Cart/AddCart', params, { custom: { methodName: 'cart.add', needToken: true } });
// 移除购物车
let removeCart = (params, config = {}) => http.post('/Api/Cart/DoDelete', params, { custom: { methodName: 'cart.del', needToken: true } });
// 获取购物车列表
let cartList = (params, config = {}) => http.post('/Api/Cart/GetList', params, { custom: { methodName: 'cart.getlist', needToken: true } });
// 设置购物车商品数量
let setCartNum = (params, config = {}) => http.post('/Api/Cart/SetCartNum', params, { custom: { methodName: 'cart.setnums', needToken: true } });
// 获取购物车数量
let getCartNum = (params, config = {}) => http.post('/Api/User/GetCartNumber', params, { custom: { methodName: 'cart.getnumber', needToken: true } });
// 根据购物车已有数据获取能够使用的优惠券
let getCartCoupon = (params, config = {}) => http.post('/Api/Cart/GetCartAvailableCoupon', params, { custom: { methodName: 'cart.getCartCoupon', needToken: true } });
// 获取用户的收货地址列表
let userShip = (params, config = {}) => http.post('/Api/User/GetUserShip', params, { custom: { methodName: 'user.getusership', needToken: true } });
// 获取用户默认收货地址
let userDefaultShip = (params, config = {}) => http.post('/Api/User/GetUserDefaultShip', params, { custom: { methodName: 'user.getuserdefaultship', needToken: true } });
// 存储用户收货地址
let saveUserShip = (params, config = {}) => http.post('/Api/User/SaveUserShip', params, { custom: { methodName: 'user.vuesaveusership', needToken: true } });
// 微信存储收货地址
let saveUserShipWx = (params, config = {}) => http.post('/Api/User/SaveUserShip', params, { custom: { methodName: 'user.saveusership', needToken: true } });
//获取区域ID
let getAreaId = (params, config = {}) => http.post('/Api/User/GetAreaId', params, { custom: { methodName: 'user.getareaid', needToken: false } });
//根据区/县名称获取城市id信息
let getAreaIdByName = (params, config = {}) => http.post('/Api/User/GetAreaIdByName', params, { custom: { methodName: 'user.getareaid', needToken: false } });
// 获取收货地址详情
let shipDetail = (params, config = {}) => http.post('/Api/User/GetShipDetail', params, { custom: { methodName: 'user.getshipdetail', needToken: true } });
// 收货地址编辑
let editShip = (params, config = {}) => http.post('/Api/User/SaveUserShip', params, { custom: { methodName: 'user.editship', needToken: true } });
// 收货地址删除
let removeShip = (params, config = {}) => http.post('/Api/User/RemoveShip', params, { custom: { methodName: 'user.removeship', needToken: true } });
// 设置默认收货地址
let setDefShip = (params, config = {}) => http.post('/Api/User/SetDefShip', params, { custom: { methodName: 'user.setdefship', needToken: true } });
// 生成订单
let createOrder = (params, config = {}) => http.post('/Api/Order/CreateOrder', params, { custom: { methodName: 'order.create', needToken: true } });
// 取消订单
let cancelOrder = (params, config = {}) => http.post('/Api/Order/CancelOrder', params, { custom: { methodName: 'order.cancel', needToken: true } });
// 删除订单
let delOrder = (params, config = {}) => http.post('/Api/Order/DeleteOrder', params, { custom: { methodName: 'order.del', needToken: true } });
// 获取订单详情
let orderDetail = (params, config = {}) => http.post('/Api/Order/OrderDetails', params, { custom: { methodName: 'order.details', needToken: true } });
// 确认收货
let confirmOrder = (params, config = {}) => http.post('/Api/Order/OrderConfirm', params, { custom: { methodName: 'order.confirm', needToken: true } });
// 获取配送方式
let orderShip = (params, config = {}) => http.post('/Api/Order/GetShip', params, { custom: { methodName: 'order.getship', needToken: true } });
// 获取全部订单列表
let orderList = (params, config = {}) => http.post('/Api/Order/GetOrderList', params, { custom: { methodName: 'order.getorderlist', needToken: true } });
// 获取订单不同状态的数量
let getOrderStatusSum = (params, config = {}) => http.post('/Api/Order/GetOrderStatusNum', params, { custom: { methodName: 'order.getorderstatusnum', needToken: true } });
// 获取不同类型营销下单支持的配送方式
let getOrderDistributionModel = (params, config = {}) => http.post('/Api/Order/GetOrderDistributionModel', params, { custom: { methodName: 'order.getOrderdistributionmodel', needToken: true } });
// 售后单列表
let afterSalesList = (params, config = {}) => http.post('/Api/Order/AftersalesList', params, { custom: { methodName: 'order.aftersaleslist', needToken: true } });
// 售后单详情
let afterSalesInfo = (params, config = {}) => http.post('/Api/Order/Aftersalesinfo', params, { custom: { methodName: 'order.aftersalesinfo', needToken: true } });
// 添加售后单
let addAfterSales = (params, config = {}) => http.post('/Api/Order/AddAftersales', params, { custom: { methodName: 'order.addaftersales', needToken: true } });
// 用户发送退货包裹
let sendShip = (params, config = {}) => http.post('/Api/Order/SendReship', params, { custom: { methodName: 'order.sendreship', needToken: true } });
// 添加商品浏览足迹
let addGoodsBrowsing = (params, config = {}) => http.post('/Api/User/AddGoodsBrowsing', params, { custom: { methodName: 'user.addgoodsbrowsing', needToken: true } });
// 删除商品浏览足迹
let delGoodsBrowsing = (params, config = {}) => http.post('/Api/User/DelGoodsBrowsing', params, { custom: { methodName: 'user.delgoodsbrowsing', needToken: true } });
// 获取商品浏览足迹
let goodsBrowsing = (params, config = {}) => http.post('/Api/User/Goodsbrowsing', params, { custom: { methodName: 'user.goodsbrowsing', needToken: true } });
// 商品收藏 关注/取消
let goodsCollection = (params, config = {}) => http.post('/Api/User/GoodsCollectionCreateOrDelete', params, { custom: { methodName: 'user.goodscollection', needToken: true } });
// 获取商品收藏关注列表
let goodsCollectionList = (params, config = {}) => http.post('/Api/User/GoodscollectionList', params, { custom: { methodName: 'user.goodscollectionlist', needToken: true } });
// 获取店铺支付方式列表
let paymentList = (params, config = {}) => http.post('/Api/Payments/GetList', params, { custom: { methodName: 'payments.getlist', needToken: false } });
// 获取支付单详情
let paymentInfo = (params, config = {}) => http.post('/Api/Payments/GetInfo', params, { custom: { methodName: 'payments.getinfo', needToken: true } });
// 支付接口
let pay = (params, config = {}) => http.post('/Api/User/Pay', params, { custom: { methodName: 'user.pay', needToken: true } });
// 订单评价接口
let orderEvaluate = (params, config = {}) => http.post('/Api/User/OrderEvaluate', params, { custom: { methodName: 'user.orderevaluate', needToken: true } });
// 判断是否签到(作废)
//let isSign = (params, config = {}) => http.post('/Api/User/IsSign', params, { custom: { methodName: 'user.issign', needToken: true } });
// 签到接口(作废)
//let sign = (params, config = {}) => http.post('/Api/User/Sign', params, { custom: { methodName: 'user.sign', needToken: true } });
// 签到接口
let userCheckIn = (params, config = {}) => http.post('/Api/CheckIn/DoUserCheckIn', params, { custom: { methodName: 'user.doUserCheckIn', needToken: true } });
//获取用户按月签到数据
let getUserCheckByMonth = (params, config = {}) => http.post('/Api/CheckIn/GetUserCheckByMonth', params, { custom: { methodName: 'user.getUserCheckByMonth', needToken: true } });
//获取用户总签到次数
let getUserCheckCount = (params, config = {}) => http.post('/Api/CheckIn/GetUserCheckCount', params, { custom: { methodName: 'user.getUserCheckCount', needToken: true } });
// 积分记录
let pointLog = (params, config = {}) => http.post('/Api/User/UserPointLog', params, { custom: { methodName: 'user.userpointlog', needToken: true } });
// 物流信息接口
let logistics = (params, config = {}) => http.post('/Api/Order/LogisticsByApi', params, { custom: { methodName: 'order.logisticbyapi', needToken: true } });
// 优惠券列表
let couponList = (params, config = {}) => http.post('/Api/Coupon/CouponList', params, { custom: { methodName: 'coupon.couponlist', needToken: false } });
// 优惠券详情
let couponDetail = (params, config = {}) => http.post('/Api/Coupon/CouponDetail', params, { custom: { methodName: 'coupon.coupondetail', needToken: false } });
// 用户领取优惠券
let getCoupon = (params, config = {}) => http.post('/Api/Coupon/GetCoupon', params, { custom: { methodName: 'coupon.getcoupon', needToken: true } });
// 用户已领取的优惠券列表
let userCoupon = (params, config = {}) => http.post('/Api/Coupon/UserCoupon', params, { custom: { methodName: 'coupon.usercoupon', needToken: true } });
// 获取我的银行卡列表
let getBankCardList = (params, config = {}) => http.post('/Api/User/GetMyBankcardsList', params, { custom: { methodName: 'user.getbankcardlist', needToken: true } });
// 获取默认的银行卡
let getDefaultBankCard = (params, config = {}) => http.post('/Api/User/GetDefaultBankCard', params, { custom: { methodName: 'user.getdefaultbankcard', needToken: true } });
// 添加银行卡
let addBankCard = (params, config = {}) => http.post('/Api/User/AddBankCards', params, { custom: { methodName: 'user.addbankcard', needToken: true } });
// 删除银行卡
let removeBankCard = (params, config = {}) => http.post('/Api/User/Removebankcard', params, { custom: { methodName: 'user.removebankcard', needToken: true } });
// 设置默认银行卡
let setDefaultBankCard = (params, config = {}) => http.post('/Api/User/SetDefaultBankCard', params, { custom: { methodName: 'user.setdefaultbankcard', needToken: true } });
// 获取银行卡信息
let getBankCardInfo = (params, config = {}) => http.post('/Api/User/GetBankCardInfo', params, { custom: { methodName: 'user.getbankcardinfo', needToken: true } });
// 获取银行卡组织信息
let getBankCardOrganization = (params, config = {}) => http.post('/Api/User/GetBankCardsOrganization', params, { custom: { methodName: 'user.getbankcardorganization', needToken: true } });
// 用户修改密码
let editPwd = (params, config = {}) => http.post('/Api/User/EditPwd', params, { custom: { methodName: 'user.editpwd', needToken: true } });
// 用户找回密码
let forgotPwd = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'user.forgotpwd', needToken: true } });
// 获取用户余额明细
let getBalanceList = (params, config = {}) => http.post('/Api/User/UserBalance', params, { custom: { methodName: 'user.balancelist', needToken: true } });
// 用户推荐列表
let recommendUserList = (params, config = {}) => http.post('/Api/User/Recommend', params, { custom: { methodName: 'user.recommend', needToken: true } });
// 邀请码
let shareCode = (params, config = {}) => http.post('/Api/User/ShareCode', params, { custom: { methodName: 'user.sharecode', needToken: true } });
// 用户提现
let userToCash = (params, config = {}) => http.post('/Api/User/Cash', params, { custom: { methodName: 'user.cash', needToken: true } });
// 用户提现列表
let cashList = (params, config = {}) => http.post('/Api/User/CashList', params, { custom: { methodName: 'user.cashlist', needToken: true } });
// 判断用户下单可以使用多少积分
let usablePoint = (params, config = {}) => http.post('/Api/User/GetUserPoint', params, { custom: { methodName: 'user.getuserpoint', needToken: true } });
// 门店列表
let storeList = (params, config = {}) => http.post('/Api/Store/GetStoreList', params, { custom: { methodName: 'store.getstorelist', needToken: false } });
//根据用户序列获取门店数据
let getStoreByUserId = (params, config = {}) => http.post('/Api/Store/GetStoreByUserId', params, { custom: { methodName: 'store.getStoreByUserId', needToken: true } });
//根据序列获取门店数据
let getStoreById = (params, config = {}) => http.post('/Api/Store/GetStoreById', params, { custom: { methodName: 'store.getStoreByUserId', needToken: false } });
//获取门店订单列表
let getOrderPageByMerchant = (params, config = {}) => http.post('/Api/Store/GetOrderPageByMerchant', params, { custom: { methodName: 'store.getOrderPageByMerchant', needToken: true } });
//获取门店订单列表
let getOrderPageByMerchantSearch = (params, config = {}) => http.post('/Api/Store/GetOrderPageByMerchantSearch', params, { custom: { methodName: 'store.getOrderPageByMerchantSearch', needToken: true } });
// 判断是否开启门店自提
let switchStore = (params, config = {}) => http.post('/Api/Store/GetStoreSwitch', params, { custom: { methodName: 'store.getstoreswitch', needToken: false } });
// 获取默认的门店
let defaultStore = (params, config = {}) => http.post('/Api/Store/GetDefaultStore', params, { custom: { methodName: 'store.getdefaultstore', needToken: false } });
// 判断是否开启积分
let isPoint = (params, config = {}) => http.post('/Api/User/isPoint', params, { custom: { methodName: 'user.ispoint', needToken: false } });
// 用户输入code领取优惠券
let couponKey = (params, config = {}) => http.post('/Api/Coupon/GetCouponKey', params, { custom: { methodName: 'coupon.getcouponkey', needToken: true } });
// 判断是否是店员
let isStoreUser = (params, config = {}) => http.post('/Api/Store/IsClerk', params, { custom: { methodName: 'store.isclerk', needToken: true } });
// 获取店铺提货单列表
let storeLadingList = (params, config = {}) => http.post('/Api/Store/StoreLadingList', params, { custom: { methodName: 'store.storeladinglist', needToken: true } });
// 获取提货单详情
let ladingInfo = (params, config = {}) => http.post('/Api/Store/LadingInfo', params, { custom: { methodName: 'store.ladinginfo', needToken: true } });
// 店铺提单核销操作
let ladingExec = (params, config = {}) => http.post('/Api/Store/Lading', params, { custom: { methodName: 'store.lading', needToken: true } });
// 提货单删除
let ladingDel = (params, config = {}) => http.post('/Api/Store/LadingDelete', params, { custom: { methodName: 'store.ladingdel', needToken: true } });
// 获取活动列表
let activityList = (params, config = {}) => http.post('/Api/Group/GetList', params, { custom: { methodName: 'group.getlist', needToken: false } });
// 获取活动详情
let activityDetail = (params, config = {}) => http.post('/Api/Group/GetGoodsDetial', params, { custom: { methodName: 'group.getgoodsdetial', needToken: false } });
//小程序解析code
let onLogin = (params, config = {}) => http.post('/Api/User/OnLogin', params, { custom: { methodName: 'user.wxappOnlogin', needToken: false } });
//小程序登录第二步(核验数据并获取用户详细资料)
let loginByDecodeEncryptedData = (params, config = {}) => http.post('/Api/User/DecodeEncryptedData', params, { custom: { methodName: 'user.wxapploginByDecodeEncryptedData', needToken: false } });
//小程序同步用户数据
let syncWeChatInfo = (params, config = {}) => http.post('/Api/User/SyncWeChatInfo', params, { custom: { methodName: 'user.SyncWeChatInfo', needToken: true } });
//小程序手机授权(拉取手机号码)
let loginByGetPhoneNumber = (params, config = {}) => http.post('/Api/User/DecryptPhoneNumber', params, { custom: { methodName: 'user.wxapploginByGetPhoneNumber', needToken: false } });
//取下级地址列表
let getAreaList = (params, config = {}) => http.post('/Api/Common/GetAreas', params, { custom: { methodName: 'user.getarealist', needToken: false } });
//取搜索页推荐关键字
let getRecommendKeys = (params, config = {}) => http.post('/Api/Common/GetRecommendKeys', params, { custom: { methodName: 'common.getrecommendkeys', needToken: false } });
// 获取我的邀请信息
let myInvite = (params, config = {}) => http.post('/Api/User/MyInvite', params, { custom: { methodName: 'user.myinvite', needToken: true } });
// 设置我的上级邀请人
let setMyInvite = (params, config = {}) => http.post('/Api/User/SetMyInvite', params, { custom: { methodName: 'user.SetMyInvite', needToken: true } });
// 获取我的上级邀请人
let getMyInvite = (params, config = {}) => http.post('/Api/User/GetMyInvite', params, { custom: { methodName: 'user.GetMyInvite', needToken: true } });
//获取我的下级发展用户数量
let getMyChildSum = (params, config = {}) => http.post('/Api/User/GetMyChildSum', params, { custom: { methodName: 'user.GetMyChildSum', needToken: true } });
// 获取秒杀团购
let getGroup = (params, config = {}) => http.post('/Api/Group/GetList', params, { custom: { methodName: 'group.getlist', needToken: false } });
// 获取秒杀团购详情
let groupInfo = (params, config = {}) => http.post('/Api/Group/GetGoodsDetial', params, { custom: { methodName: 'group.getgoodsdetial', needToken: false } });
// 自定义页面
let getPageConfig = (params, config = {}) => http.post('/Api/Page/GetPageConfig', params, { custom: { methodName: 'pages.getpageconfig', needToken: false } });
// 获取分销商进度状态
let getDistributionInfo = (params, config = {}) => http.post('/Api/Distribution/Info', params, { custom: { methodName: 'distribution_center-api-info', needToken: true } });
// 申请分销商
let applyDistribution = (params, config = {}) => http.post('/Api/Distribution/ApplyDistribution', params, { custom: { methodName: 'distribution_center-api-applydistribution', needToken: true } });
// 店铺设置
let setDistributionStore = (params, config = {}) => http.post('/Api/Distribution/SetStore', params, { custom: { methodName: 'distribution_center-api-setstore', needToken: true } });
//获取店铺信息
let getDistributionStoreInfo = (params, config = {}) => http.post('/Api/Distribution/GetStoreInfo', params, { custom: { methodName: 'distribution_center-api-getstoreinfo', needToken: false } });
//我的分销订单
let getDistributionOrder = (params, config = {}) => http.post('/Api/Distribution/MyOrder', params, { custom: { methodName: 'distribution_center-api-myorder', needToken: true } });
//分销团队统计
let getDistributionTeamSum = (params, config = {}) => http.post('/Api/Distribution/GetTeamSum', params, { custom: { methodName: 'distribution.getTeamSum', needToken: true } });
//分销订单统计
let getDistributionOrderSum = (params, config = {}) => http.post('/Api/Distribution/GetOrderSum', params, { custom: { methodName: 'distribution.getOrderSum', needToken: true } });
//获取分销商排行
let getDistributionRanking = (params, config = {}) => http.post('/Api/Distribution/getDistributionRanking', params, { custom: { methodName: 'distribution.getDistributionRanking', needToken: true } });
// 获取代理商进度状态
let getAgentInfo = (params, config = {}) => http.post('/Api/Agent/Info', params, { custom: { methodName: 'agent_center-api-info', needToken: true } });
// 申请代理商
let applyAgent = (params, config = {}) => http.post('/Api/Agent/ApplyAgent', params, { custom: { methodName: 'agent_center-api-applyAgent', needToken: true } });
// 店铺设置
let setAgentStore = (params, config = {}) => http.post('/Api/Agent/SetStore', params, { custom: { methodName: 'agent_center-api-setstore', needToken: true } });
//获取店铺信息
let getAgentStoreInfo = (params, config = {}) => http.post('/Api/Agent/GetStoreInfo', params, { custom: { methodName: 'agent_center-api-getstoreinfo', needToken: false } });
//我的代理订单
let getAgentOrder = (params, config = {}) => http.post('/Api/Agent/MyOrder', params, { custom: { methodName: 'agent_center-api-myorder', needToken: true } });
//代理团队统计
let getAgentTeamSum = (params, config = {}) => http.post('/Api/Agent/GetTeamSum', params, { custom: { methodName: 'agent.getTeamSum', needToken: true } });
//代理订单统计
let getAgentOrderSum = (params, config = {}) => http.post('/Api/Agent/GetOrderSum', params, { custom: { methodName: 'agent.getOrderSum', needToken: true } });
//获取代理池商品数据
let getAgentGoodsPageList = (params, config = {}) => http.post('/Api/Agent/GetGoodsPageList', params, { custom: { methodName: 'agent.getGoodsPageList', needToken: false } });
//获取代理商排行
let getAgentRanking = (params, config = {}) => http.post('/Api/Agent/GetAgentRanking', params, { custom: { methodName: 'agent.getAgentRanking', needToken: true } });
// 拼团列表
let pinTuanList = (params, config = {}) => http.post('/Api/PinTuan/GetList', params, { custom: { methodName: 'pinTuan.list', needToken: false } });
// 拼团商品详情
let pinTuanGoodsInfo = (params, config = {}) => http.post('/Api/PinTuan/GetGoodsInfo', params, { custom: { methodName: 'pinTuan.goodsinfo', needToken: false } });
// 拼团货品详情
let pinTuanProductInfo = (params, config = {}) => http.post('/Api/PinTuan/GetProductInfo', params, { custom: { methodName: 'pinTuan.productinfo', needToken: false } });
//获取我的发票列表
let myInvoiceList = (params, config = {}) => http.post('/Api/User/UserInvoiceList', params, { custom: { methodName: 'user.myinvoicelist', needToken: true } });
//获取支付信息
let paymentsCheckpay = (params, config = {}) => http.post('/Api/Payments/CheckPay', params, { custom: { methodName: 'payments.checkpay', needToken: true } });
//忘记密码
let userForgetpwd = (params, config = {}) => http.post('/Api/User/ForgetPwd', params, { custom: { methodName: 'user.forgetpwd', needToken: false } });
// 根据订单id取拼团信息用在订单详情页
let getOrderPinTuanTeamInfo = (params, config = {}) => http.post('/Api/PinTuan/GetPinTuanTeam', params, { custom: { methodName: 'pinTuan.pinTuanteam', needToken: true } });
//发票模糊查询
let getTaxInfo = (params, config = {}) => http.post('/Api/Order/GetTaxCode', params, { custom: { methodName: 'order.gettaxcode', needToken: true } });
// 获取店铺设置
let getSetting = (params, config = {}) => http.post('/Api/User/GetSetting', params, { custom: { methodName: 'user.getsetting', needToken: false } });
// 获取商户配置信息
let getSellerSetting = (params, config = {}) => http.post('/Api/User/GetSellerSetting', params, { custom: { methodName: 'user.getsellersetting', needToken: false } });
// 获取小程序二维码
let getInviteQRCode = (params, config = {}) => http.post('/Api/Store/GetInviteQrCode', params, { custom: { methodName: 'store.getinviteqrcode', needToken: false } });
// 生成海报
let createPoster = (params, config = {}) => http.post('/Api/User/GetPoster', params, { custom: { methodName: 'user.getposter', needToken: false } });
//============================================================//万能表单
let getFormDetial = (params, config = {}) => http.post('/Api/Form/GetFormDetial', params, { custom: { methodName: 'form.getformdetial', needToken: false } });
//============================================================//提交表单
let addSubmitForm = (params, config = {}) => http.post('/Api/Form/AddSubmit', params, { custom: { methodName: 'form.addsubmit', needToken: false } });
//================================================================////抽奖规则
let lotteryConfig = (params, config = {}) => http.post('/Api/Lottery/GetLotteryConfig', params, { custom: { methodName: 'lottery-api-getLotteryConfig', needToken: true } });
//================================================================////抽奖操作
let lottery = (params, config = {}) => http.post('/Api/Lottery/Lottery', params, { custom: { methodName: 'lottery-api-lottery', needToken: true } });
//================================================================////获取我的抽奖记录
let myLottery = (params, config = {}) => http.post('/Api/Lottery/LotteryLog', params, { custom: { methodName: 'lottery-api-lotteryLog', needToken: true } });
//================================================================////生成分享URL
let createShareUrl = (params, config = {}) => http.post('/Api/User/ShareUrl', params, { custom: { methodName: 'user.shareurl', needToken: false } });
//================================================================////微信图文消息
let messageDetail = (params, config = {}) => http.post('/Api/Articles/GetWeChatMessage', params, { custom: { methodName: 'articles.getweixinmessage', needToken: false } });
//================================================================////获取APP版本
let getAppVersion = (params, config = {}) => http.post('/Api/Common/GetAppVersions', params, { custom: { methodName: 'Common.checkVersion', needToken: false } });
//============================================================//公众号授权获取openid第三方登录
let getOpenId = (params, config = {}) => http.post('/Api/User/OfficialLogin', params, { custom: { methodName: 'user.officiallogin', needToken: false } });
//============================================================// 获取授权登录方式(获取第三方登录列表)
let getTrustLogin = (params, config = {}) => http.post('/Api/User/GetTrustLogin', params, { custom: { methodName: 'user.gettrustlogin', needToken: false } });
//============================================================// APP信任登录(app第三方登录方式)
let appTrustLogin = (params, config = {}) => http.post('/Api/User/UniAppLogin', params, { custom: { methodName: 'user.uniapplogin', needToken: false } });
//================================================================//// 绑定授权登录
let trustBind = (params, config = {}) => http.post('/Api/User/TrustBind', params, { custom: { methodName: 'user.trustbind', needToken: false } });
//================================================================//支付宝小程序解析code第三方支付宝登录方式
let alilogin1 = (params, config = {}) => http.post('/Api/User/AlipayAppLogin1', params, { custom: { methodName: 'user.alipayapplogin1', needToken: false } });
//================================================================////头条小程序登录
let ttlogin = (params, config = {}) => http.post('/Api/User/TtLogin', params, { custom: { methodName: 'user.ttlogin', needToken: false } });
//获取订阅模板
let getSubscriptionTmplIds = (params, config = {}) => http.post('/Api/WeChatAppletsMessage/Tmpl', params, { custom: { methodName: 'wechat_applets_message-api-tmpl', needToken: true } });
//订阅状态修改
let setSubscriptionStatus = (params, config = {}) => http.post('/Api/WeChatAppletsMessage/SetTip', params, { custom: { methodName: 'wechat_applets_message-api-settip', needToken: true } });
//用户关闭订阅提醒
let subscriptionCloseTip = (params, config = {}) => http.post('/Api/WeChatAppletsMessage/CloseTip', params, { custom: { methodName: 'wechat_applets_message-api-closetip', needToken: true } });
//判断用户是否需要显示订阅提醒
let subscriptionIsTip = (params, config = {}) => http.post('/Api/WeChatAppletsMessage/IsTip', params, { custom: { methodName: 'wechat_applets_message-api-istip', needToken: true } });
//统一分享
let share = (params, config = {}) => http.post('/Api/User/Share', params, { custom: { methodName: 'user.share', needToken: false } });
//统一分享解码
let deshare = (params, config = {}) => http.post('/Api/User/deshare', params, { custom: { methodName: 'user.deshare', needToken: false } });
//获取服务列表
let getServicelist = (params, config = {}) => http.post('/Api/Service/GetPageList', params, { custom: { methodName: 'service.getpagelist', needToken: false } });
//获取服务详情
let getServiceDetail = (params, config = {}) => http.post('/Api/Service/GetDetails', params, { custom: { methodName: 'service.getdetail', needToken: false } });
//生成服务购买订单
let addServiceOrder = (params, config = {}) => http.post('/Api/Service/AddServiceOrder', params, { custom: { methodName: 'service.addServiceOrder', needToken: true } });
//获取个人服务订单列表
let getUserServicesPageList = (params, config = {}) => http.post('/Api/User/GetServicesPageList', params, { custom: { methodName: 'user.getServicesPageList', needToken: true } });
//获取服务卡下用户券列表
let getServicesTickets = (params, config = {}) => http.post('/Api/User/GetServicesTickets', params, { custom: { methodName: 'user.getServicesTickets', needToken: true } });
//门店核销的服务券列表
let getverificationPageList = (params, config = {}) => http.post('/Api/Service/VerificationPageList', params, { custom: { methodName: 'service.verificationPageList', needToken: true } });
//删除核销券
let serviceLogDelete = (params, config = {}) => http.post('/Api/Service/LogDelete', params, { custom: { methodName: 'service.logDelete', needToken: true } });
// 获取服务券详情准备核销
let getServiceVerificationTicketInfo = (params, config = {}) => http.post('/Api/Service/GetTicketInfo', params, { custom: { methodName: 'service.getTicketInfo', needToken: true } });
//核销服务券
let serviceVerificationTicket = (params, config = {}) => http.post('/Api/Service/VerificationTicket', params, { custom: { methodName: 'service.verificationTicket', needToken: true } });
//获取接龙列表
let getSolitairePageList = (params, config = {}) => http.post('/Api/Solitaire/GetList', params, { custom: { methodName: 'solitaire.getList', needToken: false } });
let getSolitaireDetail = (params, config = {}) => http.post('/Api/Solitaire/GetDetail', params, { custom: { methodName: 'solitaire.getDetail', needToken: false } });
// 用户注册废弃改为自动获取app数据及使用短信验证码登录建议直接使用smsLogin接口
//let reg = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'user.reg', needToken: true } });
// 用户登录(废弃,改为短信验证码登录)
//let login = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'user.login', needToken: true } });
// 获取用户信息(废弃)
// let trustLogin = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'user.trustcallback', needToken: true } });
// 订单售后状态(废弃方法建议直接用order.details接口)
// let afterSalesStatus = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'order.aftersalesstatus', needToken: true } });
// 我的积分(弃用)
//let myPoint = (params, config = {}) => http.post('/Api/Common/InterFaceTest', params, { custom: { methodName: 'user.mypoint', needToken: true } });
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = {
shopConfigV2,
getServiceDescription,
userInfo,
changeAvatar,
editInfo,
sms,
smsLogin,
logout,
slider,
advert,
notice,
noticeInfo,
articleInfo,
articleList,
categories,
goodsList,
goodsDetail,
getGoodsRecommendList,
goodsDetailByToken,
goodsParams,
getProductInfo,
goodsComment,
goodsSku,
goodsSkuByToken,
addCart,
removeCart,
cartList,
setCartNum,
getCartNum,
getCartCoupon,
userShip,
userDefaultShip,
saveUserShip,
saveUserShipWx,
getAreaId,
getAreaIdByName,
shipDetail,
editShip,
removeShip,
setDefShip,
createOrder,
cancelOrder,
delOrder,
orderDetail,
confirmOrder,
orderShip,
orderList,
getOrderStatusSum,
getOrderDistributionModel,
afterSalesList,
afterSalesInfo,
addAfterSales,
sendShip,
addGoodsBrowsing,
delGoodsBrowsing,
delGoodsBrowsing,
goodsBrowsing,
goodsCollection,
goodsCollectionList,
paymentList,
paymentInfo,
pay,
orderEvaluate,
//isSign,
//sign,
userCheckIn,
getUserCheckByMonth,
getUserCheckCount,
pointLog,
logistics,
couponList,
couponDetail,
getCoupon,
userCoupon,
getBankCardList,
getDefaultBankCard,
addBankCard,
removeBankCard,
setDefaultBankCard,
getBankCardInfo,
getBankCardOrganization,
editPwd,
forgotPwd,
getBalanceList,
recommendUserList,
shareCode,
userToCash,
cashList,
usablePoint,
storeList,
getStoreByUserId,
getStoreById,
getOrderPageByMerchant,
getOrderPageByMerchantSearch,
switchStore,
defaultStore,
isPoint,
couponKey,
isStoreUser,
storeLadingList,
ladingInfo,
ladingExec,
ladingDel,
activityList,
activityDetail,
onLogin,
loginByDecodeEncryptedData,
syncWeChatInfo,
loginByGetPhoneNumber,
getAreaList,
getRecommendKeys,
myInvite,
setMyInvite,
getMyInvite,
getMyChildSum,
getGroup,
groupInfo,
getPageConfig,
getDistributionInfo,
applyDistribution,
setDistributionStore,
getDistributionStoreInfo,
getDistributionOrder,
getDistributionTeamSum,
getDistributionOrderSum,
getDistributionRanking,
getAgentInfo,
applyAgent,
setAgentStore,
getAgentStoreInfo,
getAgentOrder,
getAgentTeamSum,
getAgentOrderSum,
getAgentGoodsPageList,
getAgentRanking,
pinTuanList,
pinTuanGoodsInfo,
pinTuanProductInfo,
myInvoiceList,
paymentsCheckpay,
userForgetpwd,
getOrderPinTuanTeamInfo,
getTaxInfo,
getSetting,
getSellerSetting,
getInviteQRCode,
createPoster,
getFormDetial,
addSubmitForm,
lotteryConfig,
lottery,
myLottery,
createShareUrl,
messageDetail,
getAppVersion,
getOpenId,
getTrustLogin,
appTrustLogin,
trustBind,
ttlogin,
alilogin1,
getSubscriptionTmplIds,
setSubscriptionStatus,
subscriptionCloseTip,
subscriptionIsTip,
share,
deshare,
getServicelist,
getServiceDetail,
addServiceOrder,
getUserServicesPageList,
getServicesTickets,
getverificationPageList,
serviceLogDelete,
getServiceVerificationTicketInfo,
serviceVerificationTicket,
getSolitairePageList,
getSolitaireDetail
};
}
export default {
install
}

View File

@@ -0,0 +1,119 @@
import { apiBaseUrl } from '@/common/setting/constVarsHelper.js';
import * as db from '@/common/utils/dbHelper.js' //引入common
// 此vm参数为页面的实例可以通过它引用vuex中的变量
module.exports = (vm) => {
// 初始化请求配置
uni.$u.http.setConfig((defaultConfig) => {
/* defaultConfig 为默认全局配置 */
defaultConfig.baseURL = apiBaseUrl; /* 根域名 */
//defaultConfig.header = {
// 'Content-type': 'application/json1'
//};
defaultConfig.method = 'POST';
defaultConfig.dataType = 'json';
// #ifndef MP-ALIPAY
defaultConfig.responseType = 'text';
// #endif
// 注如果局部custom与全局custom有同名属性则后面的属性会覆盖前面的属性相当于Object.assign(全局,局部)
//defaultConfig.custom = {}; // 全局自定义参数默认值
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
defaultConfig.timeout = 60000;
// #endif
// #ifdef APP-PLUS
defaultConfig.sslVerify = true;
// #endif
// #ifdef H5
// 跨域请求时是否携带凭证cookies仅H5支持HBuilderX 2.6.15+
defaultConfig.withCredentials = false;
// #endif
// #ifdef APP-PLUS
defaultConfig.firstIpv4 = false; // DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
// #endif
// 局部优先级高于全局返回当前请求的task,options。请勿在此处修改options。非必填
// getTask: (task, options) => {
// 相当于设置了请求超时时间500ms
// setTimeout(() => {
// task.abort()
// }, 500)
// },
// 全局自定义验证器。参数为statusCode 且必存在,不用判断空情况。
defaultConfig.validateStatus = (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
return statusCode >= 200 && statusCode < 300
}
return defaultConfig
})
// 请求拦截
uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
// 初始化请求拦截器时会执行此方法此时data为undefined赋予默认{}
config.data = config.data || {}
if (config?.custom?.needToken) {
// 获取用户token
const userToken = db.get("userToken");
if (!userToken) {
console.log("开启弹窗");
vm.$store.commit('showLoginTip', true);
console.log("弹窗已经开启");
return false;
} else {
config.header.Authorization = 'Bearer ' + userToken;
}
}
//额外需求
if (config.custom.methodName == 'user.share') {
const userToken = db.get("userToken");
config.header.Authorization = 'Bearer ' + userToken;
}
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
// 响应拦截
uni.$u.http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
const data = response.data
let pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!data.status && page) {
//console.log(page.route);
// 登录信息过期或者未登录
if (data.data === 14007 || data.data === 14006) {
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE
if (page.route.indexOf('pages/login/loginBySMS/loginBySMS') < 0) {
db.del("userToken");
uni.showToast({
title: result.msg,
icon: 'none',
duration: 1000,
complete: function () {
setTimeout(function () {
uni.hideToast();
uni.navigateTo({
url: '/pages/login/loginBySMS/loginBySMS'
});
},
1000);
}
});
}
// #endif
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO
db.del("userToken");
console.log("开启登录弹窗");
//Vue.prototype.$store.commit('showLoginTip', true);
vm.$store.commit('hasLogin', false);
// #endif
}
}
return data === undefined ? {} : data
}, (response) => {
// 对响应错误做点什么 statusCode !== 200
return Promise.reject(response)
})
}

View File

@@ -0,0 +1,92 @@
/**
* 全局配置文件
* @version 1.0.0
*/
//接口请求地址如果需要不部署接口端的情况下测试uni-app可以直接替换为官方测试接口https://api.demo.coreshop.cn
//export const apiBaseUrl = 'https://api.pro.coreshop.cn';
export const apiBaseUrl = 'http://localhost:2015';
//项目静态资源请求地址如果使用官方的静态文件地址可以直接替换为https://files.cdn.coreshop.cn
export const apiFilesUrl = 'https://files.cdn.coreshop.cn';
export const h5Url = apiBaseUrl + "/wap/"; //H5端网站地址,
// #ifdef H5
export const baseUrl = process.env.NODE_ENV === 'development' ? window.location.origin + '/' : apiBaseUrl
// #endif
//支付单类型
export const paymentType = {
//普通订单
common: 1,
//拼团订单
pinTuan: 2,
//团购订单
group: 3,
//秒杀订单
seckill: 4,
//砍价
bargain: 6,
//赠品
giveaway: 7,
//接龙
solitaire: 8,
//交易组件
transactionComponent: 10,
//充值
recharge: 201,
//服务订单
serviceOrder: 501,
//表单付款码
formPay: 301,
//表单订单
formOrder: 302,
};
//分享链接及海报类型
export const shareType = {
// 首页
index: 1,
// 2商品详情页
goods: 2,
// 3拼团详情页
pinTuan: 3,
// 4店铺邀请
inv: 4,
// 5文章页面
article: 5,
// 6参团页面
addPinTuan: 6,
// 7自定义页面
page: 7,
// 8智能表单
form: 8,
// 9团购
group: 9,
// 10秒杀
seckill: 10,
// 11代理
agent: 11,
// 12接龙
solitaire: 12,
};
// #ifdef MP-TOUTIAO
export const ttPlatform = 'toutiao'; //toutiao=今日头条小程序, douyin=抖音小程序, pipixia=皮皮虾小程序, huoshan=火山小视频小程序
// #endif
//nav页面导航类型
export const navLinkType = {
urlLink: 1, //"URL链接"
shop: 2,// "商品"
article: 3,// "文章"
articleCategory: 4,// "文章分类",
intelligentForms: 5// "智能表单"
};

View File

@@ -0,0 +1,25 @@
/**
* 很多无法css实现的换肤效果通过此模块实现
* 使用方法,在代码中直接使用 this.$coreTheme.mainNabBar.background
* @version 1.0.0
*/
//通用头部背景样式
export const mainNabBar = {
background: {
//颜色
backgroundColor: '#e54d42',
// 导航栏背景图
// background: 'url(https://cdn.uviewui.com/uview/swiper/1.jpg) no-repeat',
// 还可以设置背景图size属性
// backgroundSize: 'cover',
// 渐变色
//backgroundImage: 'linear-gradient(45deg, rgb(28, 187, 180), rgb(141, 198, 63))'
},
//通用头部文字颜色
titleColor: "#fff",
//通用头部文字颜色
backIconColor: "#fff",
};

View File

@@ -0,0 +1,75 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
config: {
shopLogo: "/static/images/logo/logo.png"
}, // 店铺配置信息 //添加一个前端项目中的图片地址
orderTab: 0, // 选中的订单tab页
scene: 0, // 选中的订单tab页
redirectPage: '',
uuid: '',//当前客户端
searchStyle: '',
sessionAuthId: '', //微信缓存授权信息
searchFixed: false,//搜索框样式
showLoginTip: false,//显示登录框
hasLogin: false,//存储用户当前是否登录,作为切换特效使用
userShip: {}, //地区信息
userInfo: {}, //用户信息存储
invoice: {}, //发票信息
},
mutations: {
config(state, payload) {
state.config = payload
},
orderTab(state, tab) {
state.orderTab = tab
},
scene(state, tab) {
state.scene = tab
},
redirect(state, payload) {
state.redirectPage = payload.page
},
searchStyle(state, style) {
state.searchStyle = style
},
sessionAuthId(state, payload) {
state.sessionAuthId = payload
},
searchFixed(state, payload) {
state.searchFixed = payload
},
showLoginTip(state, payload) {
state.showLoginTip = payload
},
hasLogin(state, payload) {
state.hasLogin = payload
},
userShip(state, userShip) {
state.userShip = userShip
},
userInfo(state, userInfo) {
state.userInfo = userInfo
},
invoice(state, invoice) {
state.invoice = invoice
}
},
actions: {
},
getters: {
shopConfig: state => state.config,
scene: state => state.scene,
userInfo: state => state.userInfo,
uuid: state => state.uuid,
hasLogin: state => state.hasLogin,
sessionAuthId: state => state.sessionAuthId,
}
})
export default store

View File

@@ -0,0 +1,153 @@
// 提示框
function modelShow(
title = '提示',
content = '确认执行此操作吗?',
callback = () => { },
showCancel = true,
cancelText = '取消',
confirmText = '确定'
) {
uni.showModal({
title: title,
content: content,
showCancel: showCancel,
cancelText: cancelText,
confirmText: confirmText,
cancelText: cancelText,
success: function (res) {
if (res.confirm) {
// 用户点击确定操作
setTimeout(() => {
callback()
}, 500)
} else if (res.cancel) {
// 用户取消操作
}
}
})
};
//时间差转倒计时数据
function timeToDateObj(micro_second) {
var time = {}
// 总秒数
var second = Math.floor(micro_second)
// 天数
time.day = Math.floor(second / 3600 / 24)
// 小时
time.hour = Math.floor((second / 3600) % 24)
// 分钟
time.minute = Math.floor((second / 60) % 60)
// 秒
time.second = Math.floor(second % 60)
return time
};
//货币格式化
function formatMoney(number, places, symbol, thousand, decimal) {
// console.log(number)
// console.log(places)
number = number || 0
places = !isNaN((places = Math.abs(places))) ? places : 2
symbol = symbol !== undefined ? symbol : '¥'
thousand = thousand || ','
decimal = decimal || '.'
var negative = number < 0 ? '-' : '',
i = parseInt((number = Math.abs(+number || 0).toFixed(places)), 10) + '',
j = (j = i.length) > 3 ? j % 3 : 0
return (
symbol +
negative +
(j ? i.substr(0, j) + thousand : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) +
(places ?
decimal +
Math.abs(number - i)
.toFixed(places)
.slice(2) :
'')
)
}
/**
* 获取url参数
*
* @param {*} name
* @param {*} [url=window.location.serach]
* @returns
*/
function getQueryString(name, url) {
var url = url || window.location.href
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
var r = url.substr(1).match(reg)
if (r != null) {
return r[2]
}
return null
}
/**
*
* 判断是否在微信浏览器 true是
*/
function isWeiXinBrowser() {
// #ifdef H5
// window.navigator.userAgent属性包含了浏览器类型、版本、操作系统类型、浏览器引擎类型等信息这个属性可以用来判断浏览器类型
let ua = window.navigator.userAgent.toLowerCase()
// 通过正则表达式匹配ua中是否含有MicroMessenger字符串
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true
} else {
return false
}
// #endif
return false
}
/**
* 金额相加
* @param {Object} value1
* @param {Object} value2
*/
function moneySum(value1, value2) {
return (parseFloat(value1) + parseFloat(value2)).toFixed(2);
}
/**
* 金额相减
* @param {Object} value1
* @param {Object} value2
*/
function moneySub(value1, value2) {
let res = (parseFloat(value1) - parseFloat(value2)).toFixed(2);
return res > 0 ? res : 0;
}
//设置手机通知栏字体颜色
function setBarColor(black = false) {
if (black) {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#FAFAFA'
});
} else {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#FAFAFA'
});
}
}
export {
formatMoney,
modelShow,
isWeiXinBrowser,
getQueryString,
timeToDateObj,
moneySum,
moneySub,
setBarColor
}

View File

@@ -0,0 +1,71 @@
//取值
function get(key, sync = true) {
try {
if (sync) {
return uni.getStorageSync(key);
} else {
let data = '';
uni.getStorage({
key: key,
success: function (res) {
data = res.data;
}
});
return data;
}
} catch (e) {
return false;
}
}
//赋值
function set(key, value, sync = true) {
try {
if (sync) {
return uni.setStorageSync(key, value);
} else {
uni.setStorage({
key: key,
data: value
});
}
} catch (e) {
}
}
//移除
function del(key, sync = true) {
try {
if (sync) {
return uni.removeStorageSync(key);
} else {
uni.removeStorage({
key: key
});
}
} catch (e) {
return false;
}
}
//清空
function clear(sync = true) {
try {
if (sync) {
return uni.clearStorageSync();
} else {
uni.clearStorage();
}
} catch (e) {
return false;
}
}
export {
get,
set,
del,
clear
}

View File

@@ -0,0 +1,169 @@
import { apiBaseUrl } from '@/common/setting/constVarsHelper.js';
import * as db from './dbHelper.js' //引入common
const showError = error => {
let errorMsg = '';
switch (error.status) {
case 400:
errorMsg = '请求参数错误';
break;
case 401:
errorMsg = '未授权,请登录';
break;
case 403:
errorMsg = '跨域拒绝访问';
break;
case 404:
errorMsg = `请求地址出错: ${error.config.url}`;
break;
case 408:
errorMsg = '请求超时';
break;
case 500:
errorMsg = '服务器内部错误';
break;
case 501:
errorMsg = '服务未实现';
break;
case 502:
errorMsg = '网关错误';
break;
case 503:
errorMsg = '服务不可用';
break;
case 504:
errorMsg = '网关超时';
break;
case 505:
errorMsg = 'HTTP版本不受支持';
break;
default:
errorMsg = error.msg;
break;
}
uni.showToast({
title: errorMsg,
icon: 'none',
duration: 1000,
complete: function () {
setTimeout(function () {
uni.hideToast();
},
1000);
}
});
};
// 文件上传
export const uploadFiles = (data, callback) => {
// 获取用户token
let userToken = db.get("userToken");
if (!userToken) {
this.$store.commit('showLoginTip', true);
return false;
};
uni.chooseImage({
success: (chooseImageRes) => {
uni.showLoading({
title: '上传中...'
});
const tempFilePaths = chooseImageRes.tempFilePaths;
const uploadTask = uni.uploadFile({
url: apiBaseUrl + '/Api/Common/UploadImages',
filePath: tempFilePaths[0],
fileType: 'image',
name: 'file',
header: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + userToken
},
formData: {
'method': 'images.upload',
'upfile': tempFilePaths[0]
},
success: (uploadFileRes) => {
//console.log("交互成功");
//console.log(uploadFileRes);
callback(JSON.parse(uploadFileRes.data));
},
fail: (error) => {
console.log("交互失败");
console.log(error);
if (error && error.response) {
showError(error.response);
}
},
complete: () => {
setTimeout(function () {
uni.hideLoading();
},
250);
}
});
//uploadTask.onProgressUpdate((res) => {
// console.log('上传进度' + res.progress);
// console.log('已经上传的数据长度' + res.totalBytesSent);
// console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
// // 测试条件,取消上传任务。
// if (res.progress > 50) {
// uploadTask.abort();
// }
//});
}
});
};
// 上传图片
export const uploadImage = (num, callback) => {
// 获取用户token
let userToken = db.get("userToken");
if (!userToken) {
this.$store.commit('showLoginTip', true);
return false;
};
uni.chooseImage({
count: num,
success: (res) => {
uni.showLoading({
title: '上传中...'
});
let tempFilePaths = res.tempFilePaths;
for (var i = 0; i < tempFilePaths.length; i++) {
uni.uploadFile({
url: apiBaseUrl + '/Api/Common/UploadImages',
filePath: tempFilePaths[i],
fileType: 'image',
name: 'file',
header: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + userToken
},
formData: {
'method': 'images.upload',
'upfile': tempFilePaths[i]
},
success: (uploadFileRes) => {
callback(JSON.parse(uploadFileRes.data));
},
fail: (error) => {
if (error && error.response) {
showError(error.response);
}
},
complete: () => {
setTimeout(function () {
uni.hideLoading();
},
250);
},
});
}
}
});
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
<template>
<view>
<!--提示框组件-->
<u-toast ref="uToast" />
<view v-for="item in advert">
<u--image :showLoading="true" :src="item.imageUrl" mode="widthFix" width="100%" height="auto" @click="showSliderInfo(item.type, item.val)"></u--image>
</view>
</view>
</template>
<script>
export default {
props: {
codes: {
type: String,
required: true,
default: 'tpl1_class_banner1'
}
},
data() {
return {
advert: [],
}
},
created() {
//console.log(this.codes);
this.getData();
},
methods: {
getData() {
this.$u.api.advert({
codes: this.codes
}).then(res => {
this.advert = res.data;
});
},
},
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,27 @@
<template>
<view class="coreshop-copyright">
<view class="coreshop-font-xs">
<!--© {{shopName}} 品牌运营-->
© 小小助农 品牌运营
</view>
<!--<view class="coreshop-font-xs" v-if="shopBeiAn">
<view>备案号{{shopBeiAn}}</view>
</view>-->
<view class="coreshop-font-xs">
软件技术支持怀化南山田舍科技有限公司
</view>
</view>
</template>
<script>
export default {
data() {
return {
shopBeiAn: this.$store.state.config.shopBeiAn || '',
shopName: this.$store.state.config.shopName || ''
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,31 @@
.fab-box { position: fixed; display: flex; justify-content: center; align-items: center; z-index: 2;
&.top { width: 30px; height: 30px; right: 15px; bottom: 90px; border: 1px #5989b9 solid; background: #6699cc; border-radius: 5px; color: #fff; transition: all 0.3; opacity: 0; }
&.active { opacity: 1; }
&.fab { z-index: 10;
&.leftBottom { left: 15px; bottom: 90px; }
&.leftTop { left: 15px; top: 40px; top: calc(40px + var(--window-top)); }
&.rightBottom { right: 15px; bottom: 90px; }
&.rightTop { right: 15px; top: 40px; top: calc(40px + var(--window-top)); }
}
}
.fab-circle { display: flex; justify-content: center; align-items: center; position: absolute; width: 45px; height: 45px; background: #3c3e49; border-radius: 50%; box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.2); z-index: 11;
&.left { left: 0; }
&.right { right: 0; }
&.top { top: 0; }
&.bottom { bottom: 0; }
.icon-jia { color: #ffffff; font-size: 25px; transition: all 0.3s; width: 22px; height: 22px;
&.active { transform: rotate(90deg); }
}
}
.fab-content { background: #6699cc; box-sizing: border-box; display: flex; border-radius: 50px; overflow: hidden; box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.1); transition: all 0.2s; width: 55px;
&.left { justify-content: flex-start; }
&.right { justify-content: flex-end; }
&.flexDirection { flex-direction: column; justify-content: flex-end; }
&.flexDirectionStart { flex-direction: column; justify-content: flex-start; }
&.flexDirectionEnd { flex-direction: column; justify-content: flex-end; }
.fab-item { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 45px; height: 45px; font-size: 12px; color: #fff; opacity: 0; transition: opacity 0.2s;
&.active { opacity: 1; }
.content-image { width: 30px; height: 30px; margin-bottom: 5px; }
&.first { width: 55px; }
}
}

View File

@@ -0,0 +1,199 @@
<template>
<view>
<view class="fab-box fab" :class="{ leftBottom: leftBottom, rightBottom: rightBottom, leftTop: leftTop, rightTop: rightTop }">
<view class="fab-circle"
:class="{
left: horizontal === 'left' && direction === 'horizontal',
top: vertical === 'top' && direction === 'vertical',
bottom: vertical === 'bottom' && direction === 'vertical',
right: horizontal === 'right' && direction === 'horizontal'
}"
:style="{ 'background-color': styles.buttonColor }"
@click="open">
<image class="icon icon-jia" src="/static/images/common/menu.png" mode="" :class="{ active: showContent }"></image>
<!-- <text class="icon icon-jia" :class="{ active: showContent }"></text> -->
</view>
<view class="fab-content"
:class="{
left: horizontal === 'left',
right: horizontal === 'right',
flexDirection: direction === 'vertical',
flexDirectionStart: flexDirectionStart,
flexDirectionEnd: flexDirectionEnd
}"
:style="{ width: boxWidth, height: boxHeight, background: styles.backgroundColor }">
<view v-if="flexDirectionStart || horizontalLeft" class="fab-item first"></view>
<view class="fab-item"
v-for="(item, index) in content"
:key="index"
:class="{ active: showContent }"
:style="{
color: item.active ? styles.selectedColor : styles.color
}"
@click="taps(index, item)">
<image class="content-image icon"
:src="item.active ? item.selectedIconPath : item.iconPath"
mode=""></image>
<text class="text">{{ item.text }}</text>
</view>
<view v-if="flexDirectionEnd || horizontalRight" class="fab-item first"></view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
pattern: {
type: Object,
default: () => {
return {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#FF7159'
};
}
},
horizontal: {
type: String,
default: 'left'
},
vertical: {
type: String,
default: 'bottom'
},
direction: {
type: String,
default: 'horizontal'
},
content: {
type: Array,
default: () => {
return [{
iconPath: '/static/images/common/tab-ic-hom-selected.png',
selectedIconPath: '/static/images/common/tab-ic-hom-unselected.png',
// text: '首页',
active: false,
url: '/pages/index/default/default'
},
{
iconPath: '/static/images/common/tab-ic-me-selected.png',
selectedIconPath: '/static/images/common/tab-ic-me-unselected.png',
// text: '个人中心',
active: false,
url: '/pages/index/member/member'
}];
}
}
},
data() {
return {
fabShow: false,
flug: true,
showContent: false,
styles: {
color: '#3c3e49',
selectedColor: '#007AFF',
backgroundColor: '#fff',
buttonColor: '#3c3e49'
}
};
},
created() {
if (this.top === 0) {
this.fabShow = true;
}
// 初始化样式
this.styles = Object.assign({}, this.styles, this.pattern);
},
methods: {
open() {
this.showContent = !this.showContent;
},
/**
* 按钮点击事件
*/
taps(index, item) {
//this.$emit('trigger', {
// index,
// item
//});
this.$u.route({
type: 'switchTab',
url: item.url
});
},
/**
* 获取 位置信息
*/
getPosition(types, paramA, paramB) {
if (types === 0) {
return this.horizontal === paramA && this.vertical === paramB;
} else if (types === 1) {
return this.direction === paramA && this.vertical === paramB;
} else if (types === 2) {
return this.direction === paramA && this.horizontal === paramB;
} else {
return this.showContent && this.direction === paramA
? this.contentWidth
: this.contentWidthMin;
}
}
},
watch: {
pattern(newValue, oldValue) {
// console.log(JSON.stringify(newValue));
this.styles = Object.assign({}, this.styles, newValue);
}
},
computed: {
contentWidth(e) {
return uni.upx2px((this.content.length + 1) * 90 + 20) + 'px';
},
contentWidthMin() {
return uni.upx2px(90) + 'px';
},
// 动态计算宽度
boxWidth() {
return this.getPosition(3, 'horizontal');
},
// 动态计算高度
boxHeight() {
return this.getPosition(3, 'vertical');
},
// 计算左下位置
leftBottom() {
return this.getPosition(0, 'left', 'bottom');
},
// 计算右下位置
rightBottom() {
return this.getPosition(0, 'right', 'bottom');
},
// 计算左上位置
leftTop() {
return this.getPosition(0, 'left', 'top');
},
rightTop() {
return this.getPosition(0, 'right', 'top');
},
flexDirectionStart() {
return this.getPosition(1, 'vertical', 'top');
},
flexDirectionEnd() {
return this.getPosition(1, 'vertical', 'bottom');
},
horizontalLeft() {
return this.getPosition(2, 'horizontal', 'left');
},
horizontalRight() {
return this.getPosition(2, 'horizontal', 'right');
}
}
};
</script>
<style scoped lang="scss">
@import "coreshop-fab.scss";
</style>

View File

@@ -0,0 +1,130 @@
<template>
<!-- 首页标题栏轮播图整合插件 -->
<view class="banner-swiper-wrap">
<!-- 标题栏 -->
<view class="u-navbar u-navbar-fixed" :style="[navbarStyle]">
<view class="u-status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
<view class="u-navbar-inner" :style="[navbarInnerStyle]">
<view class="u-back-wrap">
<view class="u-icon-wrap u-back-text u-line-1 coreshop-text-white coreshop-font-20">
<u--image :showLoading="true" src="/static/images/logo/logo2.png" width="223px" height="50px"></u--image>
</view>
</view>
<view hover-class="hover-search" class="search-box coreshop-flex u-row-center u-col-center coreshop-margin-right-10" @tap="goSearch">
<u-icon name="search" color="#fff" size="24"></u-icon>
</view>
</view>
</view>
</view>
</template>
<script>
// 获取系统状态栏的高度
let systemInfo = uni.getSystemInfoSync();
let menuButtonInfo = {};
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
/**
* home-head-轮播卡片,主要为了处理数据
* @property {Array} list 轮播图数据,
* @property {String} mode 指示器模式
*/
export default {
components: {},
data() {
return {
navBgImage: '',
changeNavBackground: false,
swiperCur: 0,
statusBarHeight: systemInfo.statusBarHeight
};
},
props: {
coreshopdata: {
// type: Object,
required: true,
},
isScorll: {
type: Boolean,
default: false
}
},
watch: {
isScorll(newValue, oldValue) {
this.changeNavBackground = newValue;
this.navBgImage = this.coreshopdata.parameters.list[this.swiperCur].image;
}
},
computed: {
// 导航栏内部盒子的样式
navbarInnerStyle() {
let style = {};
style.height = this.navbarHeight + 'px';
// #ifdef MP
let rightButtonWidth = systemInfo.windowWidth - menuButtonInfo.left;
style.marginRight = rightButtonWidth + 'px';
// #endif
return style;
},
// 整个导航栏的样式
navbarStyle() {
let style = {};
style.zIndex = this.$u.zIndex.navbar;
style.background = this.changeNavBackground ? `url(${this.navBgImage}) no-repeat top / 100% auto` : 'none';
Object.assign(style, this.background);
return style;
},
navbarHeight() {
// #ifdef APP-PLUS || H5
return 44;
// #endif
// #ifdef MP
return systemInfo.platform == 'ios' ? 44 : 48;
// #endif
}
},
created() {
this.navBgImage = this.coreshopdata.parameters.list[0].image;
},
methods: {
onSwiper(e) {
var item = this.coreshopdata.parameters.list[e];
if (item) {
this.showSliderInfo(item.linkType, item.linkValue);
}
},
onChange(e) {
this.swiperCur = e.detail.current;
}
}
};
</script>
<style lang="scss" scoped>
@mixin vue-flex($direction: row) { /* #ifndef APP-NVUE */ display: flex; flex-direction: $direction; /* #endif */ }
// 轮播
.banner-swiper-wrap { height: 260px; position: relative; z-index: 100;
.search-box { width: 25px; height: 25px; background: rgba(#000, 0.18); border-radius: 100%; justify-content: center; }
.hover-search { background: rgba(#fff, 0.18); }
}
.u-navbar { width: 100%; }
.u-navbar-fixed { position: fixed; left: 0; right: 0; top: 0; z-index: 991; }
.u-status-bar { width: 100%; }
.u-navbar-inner {
@include vue-flex;
justify-content: space-between;
position: relative;
align-items: center;
}
.u-back-wrap {
@include vue-flex;
align-items: center;
flex: 1;
flex-grow: 0;
padding: 0px 7px 7px 5px;
}
</style>

View File

@@ -0,0 +1,38 @@
.modal-box { width: 305px; border-radius: 10px; background: #fff; position: relative; left: 50%; transform: translateX(-50%); padding: 15px; z-index: 11111; }
.modal-box-head-bg { width: 100%; height: 105px; }
.modal-box-detail { width: 100%; text-align: center; }
.modal-box-detail-title1 { color: #46351b; font-size: 18px; font-weight: bold; }
.modal-box-detail-title2 { font-size: 14px; color: #999; padding-top: 10px; }
.modal-box-detail-title3 { color: #46351b; font-size: 18px; font-weight: bold; text-align: left; line-height: 18px; padding: 15px 0 15px 15px; }
.modal-box-detail-desc { font-size: 12px; line-height: 20px; color: #333; background: #f7f8fa; text-align: left; padding: 10px; }
.modal-box-detail-user-avatar { width: 80px; height: 80px; overflow: hidden; margin: 0 auto; margin-bottom: 20px; }
.modal-box-detail-user-name { font-size: 18px; font-family: PingFang SC; font-weight: bold; color: #845708; margin-bottom: 10px; }
.shopDesc { padding: 15px 0px 0px 0px; text-align: left; }
.shopDesc-shopName { margin-left: 10px; line-height: 20px; }
.shopDesc-get { margin-left: 10px; line-height: 20px; }
.agreement-checked-view { position: relative; padding: 10px 0px 10px 15px; display: flex; align-items: center; margin: 5px 0; font-size: 12px; }
.getCaptcha { background-color: rgb(253, 243, 208); color: $u-tips-color; border: none; font-size: 15px; padding: 6px 0;
&::after { border: none; }
}
.wrap-content { width: 300px; margin: 40px auto 0; }
.wrap { font-size: 14px; }
.hint { padding: 10px 20px; font-size: 11px; color: $u-tips-color; }
.wrapkey { padding: 40px 35px; }
.box { margin: 15px 0; font-size: 15px; color: #555; }
.key-input { padding: 15px 0;
text { display: none; }
.error { display: block; color: red; font-size: 15px; margin: 10px 0; }
}
.key-input .tips { font-size: 15px; color: #333; margin-top: 10px; margin-bottom: 30px; }
.captcha { color: $u-type-warning; font-size: 15px; margin-top: 20px;
.noCaptcha { display: block; }
.regain { display: block; }
}

View File

@@ -0,0 +1,498 @@
<template>
<view>
<u-toast ref="uToast" />
<!-- #ifndef MP-WEIXIN -->
<u-popup class="coreshop-bottom-popup-box" :show="showLogin" @close="hideModal" mode="bottom" :closeable="true">
<view class="radius coreshop-bg-white wrap">
<view v-if="!showCodeBox">
<view class="wrap-content">
<view class="coreshop-font-25 coreshop-font-weight-bold coreshop-margin-bottom-50">欢迎登录{{shopName}}</view>
<input class="coreshop-solid coreshop-margin-bottom-10 coreshop-padding-bottom-5" type="number" v-model="mobile" placeholder="请输入手机号" />
<view class="coreshop-margin-bottom-30 coreshop-margin-top-5 ">未注册的手机号验证后自动创建平台账号</view>
<button @tap="submit" :style="[inputStyle]" class="getCaptcha">获取短信验证码</button>
<view class="coreshop-flex coreshop-justify-between coreshop-margin-top-25">
<view class="password">一键登录</view>
<view class="issue">遇到问题</view>
</view>
</view>
<view class=" coreshop-padding-bottom-30 coreshop-padding-top-30">
<view class="hint">
登录即代表你同意
<text @click="goUserAgreementPage()">用户协议</text>
<text @click="goUserPrivacyPolicy()">隐私政策</text>
并授权使用您的{{shopName}}账号信息如昵称头像收获地址以便您统一管理
</view>
</view>
</view>
<view class="wrapkey" v-if="showCodeBox">
<view class="key-input">
<view class="coreshop-font-25 coreshop-font-weight-bold coreshop-margin-bottom-50">输入验证码</view>
<view class="coreshop-margin-bottom-30 coreshop-margin-top-5">验证码已发送至 +{{mobile}}</view>
<u-code-input :focus="true" v-model="codevalue" @change="change" @finish="finish" mode="box" :maxlength="maxlength"></u-code-input>
<text :class="{ error: error }">{{errorMsg}}</text>
<view class="captcha">
<text :class="{ noCaptcha: verification }" @tap="noCaptcha">收不到验证码点这里</text>
<text :class="{ regain: !verification }">{{ timer }}秒后重新获取验证码</text>
</view>
</view>
</view>
</view>
</u-popup>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<u-popup class="coreshop-bottom-popup-box" :show="showLogin" @close="hideModal" mode="center">
<view class="radius coreshop-bg-white">
<view class="modal-box">
<view class="modal-box-detail-detail">
<view class="shopDesc">
<view class="coreshop-avatar sm round margin-left">
<u--image width="24px" height="24px" :src="shopLogo"></u--image>
</view>
<text class="shopName">
{{shopName||'登录授权'}}
</text>
<text class="get">
申请
</text>
</view>
<view class="modal-box-detail-title3">获取以下权限为您提供服务</view>
<view class="modal-box-detail-desc">
1获取你的手机号提供更好的账户安全物流订单状态提醒等服务在接下来微信授权手机号的弹窗中选择允许<br />
2使用我们的相关服务需要将您的手机号授权给我们
</view>
<!--服务协议-->
<view class="coreshop-margin-top-15 coreshop-margin-bottom-30 agreement-checked-view">
<u-checkbox-group>
<u-checkbox v-model="agreement" :checked="agreement" @change="checkboxChange" size="20" active-color="#19be6b"></u-checkbox>
</u-checkbox-group>
<view class="coreshop-text-black-view">
<text class="coreshop-text-black">同意</text>
<text class="text-blue" @tap="goUserAgreementPage">服务协议</text>
<text class="coreshop-text-black"></text>
<text class="text-blue" @tap="goUserPrivacyPolicy">隐私协议</text>
</view>
</view>
</view>
<view class="coreshop-flex coreshop-justify-between coreshop-padding-left-15 coreshop-padding-right-15">
<view class="coreshop-padding-5">
<u-button @click="closeAuth">暂不授权</u-button>
</view>
<view class="coreshop-padding-5">
<u-button type="success" :disabled="isDisabled" v-if="isDisabled">确定授权</u-button>
<u-button type="success" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" v-else>确定授权</u-button>
</view>
</view>
</view>
</view>
</u-popup>
<!-- #endif -->
</view>
</template>
<script>
/**
* 登录提示页
* @property {Boolean} value=showLoginTip - 由v-model控制显示隐藏。
* @property {Boolean} forceOauth - 小程序端特制的全屏登录提示。
*/
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
name: 'coreshopLoginModal',
components: {},
data() {
return {
agreement: true,
isDisabled: false,
maxMobile: 11,
mobile: '', // 用户手机号
code: '', // 短信验证码
verification: true, // 通过v-show控制显示获取还是倒计时
timer: 60, // 定义初始时间为60s
btnb: 'coreshop-btn coreshop-btn-square coreshop-btn-c coreshop-btn-all', //按钮背景
type: '', // 有值是第三方登录账号绑定
showCodeBox: false,
maxlength: 6,
codevalue: '',
error: false,
errorMsg: '验证码错误,请重新输入',
};
},
props: {
value: {},
modalType: {
type: String,
default: ''
}
},
computed: {
...mapState({
showLoginTip: state => state.showLoginTip,
sessionAuthId: state => state.sessionAuthId,
hasLogin: state => state.hasLogin,
}),
shopLogo() {
return this.$store.state.config.shopLogo
},
shopName() {
return this.$store.state.config.shopName;
},
showLogin: {
get() {
return this.showLoginTip;
},
set(val) {
this.$store.commit('showLoginTip', val);
}
},
sessionAuthIdTool: {
get() {
return this.sessionAuthId;
},
set(val) {
this.$store.commit('sessionAuthId', val);
}
},
inputStyle() {
let style = {};
if (this.mobile) {
style.color = "#fff";
style.backgroundColor = this.$u.color['warning'];
}
return style;
},
// 验证手机号
rightMobile() {
let res = {};
if (!this.mobile) {
res.status = false;
res.msg = '请输入手机号';
} else if (!this.$u.test.mobile(this.mobile)) {
res.status = false;
res.msg = '手机号格式不正确';
} else {
res.status = true;
}
return res;
},
// 动态计算发送验证码按钮样式
sendCodeBtn() {
let btn = 'coreshop-btn coreshop-btn-g';
if (this.mobile.length === this.maxMobile && this.rightMobile.status) {
return btn + ' coreshop-btn-b';
} else {
return btn;
}
},
// 动态更改登录按钮bg
regButtonClass() {
return this.mobile && this.mobile.length === this.maxMobile && this.code ? this.btnb + ' coreshop-btn-b' : this.btnb;
}
},
mounted() {
const _this = this
// #ifdef MP-WEIXIN
var userInfo = this.$store.state.userInfo;
//var token = this.$db.get('userToken');
if (Object.keys(userInfo).length != 0) {
//console.log("获取到store.state用户数据");
} else {
_this.doToken();
}
// #endif
},
//watch: {
// 'hasLogin': {
// handler(newVal) {
// //console.log(newVal);
// if (newVal == false) {
// //console.log("watch监听");
// this.doToken();
// }
// },
// deep: true,
// immediate: true,
// }
//},
onShow() {
let _this = this;
_this.timer = parseInt(_this.$db.get('timer'));
if (_this.timer != null && _this.timer > 0) {
_this.countDown();
_this.verification = false;
}
},
methods: {
submit() {
if (this.$u.test.mobile(this.mobile)) {
this.sendCode();
} else {
this.$u.toast('请输入合法的手机号码!');
}
},
// 收不到验证码选择时的选择
noCaptcha() {
var _this = this;
uni.showActionSheet({
itemList: ['重新获取验证码'],
success: function (res) {
_this.sendCode();
},
fail: function (res) {
this.$u.toast('重发失败!');
}
});
},
// change事件侦听
change(value) {
console.log('change', value);
},
// 输入完验证码最后一位执行
finish(value) {
this.code = value;
if (this.sessionAuthIdTool) {
this.toBind();
} else {
this.login();
}
},
// 发送短信验证码
sendCode() {
if (!this.rightMobile.status) {
this.$u.toast(this.rightMobile.msg);
} else {
uni.showToast({ title: '发送中...', icon: 'loading' })
setTimeout(() => {
uni.hideToast();
this.$u.api.sms({ mobile: this.mobile, code: 'login' }).then(res => {
if (res.status) {
this.showCodeBox = true;
this.timer = 60;
this.verification = false;
this.$refs.uToast.show({ message: res.msg, type: 'success' });
this.countDown(); // 执行验证码计时
} else {
this.$u.toast(res.msg);
}
});
}, 1000);
}
},
// 验证码倒计时
countDown() {
let auth_timer = setInterval(() => {
// 定时器设置每秒递减
this.timer--; // 递减时间
uni.setStorage({
key: 'timer',
data: this.timer,
success: function () { }
});
if (this.timer <= 0) {
this.verification = true; // 60s时间结束还原v-show状态并清除定时器
clearInterval(auth_timer);
}
}, 1000);
},
// 登录
login() {
var _this = this;
if (!_this.rightMobile.status) {
_this.$u.toast(_this.rightMobile.msg);
} else {
// 短信验证码登录
if (!_this.code) {
_this.$u.toast('请输入短信验证码!');
} else {
let data = {
mobile: _this.mobile,
code: _this.code
};
let invicode = _this.$db.get('invitecode');
if (invicode) {
data.invitecode = invicode;
}
_this.$u.api.smsLogin(data).then(res => {
if (res.status) {
this.$db.set('userToken', res.data.token);
_this.redirectHandler(res.msg);
} else {
_this.$u.toast(res.msg);
_this.error = true;
_this.errorMsg = res.msg;
}
});
}
}
},
// 重定向跳转 或者返回上一个页面
redirectHandler(msg) {
let _this = this;
this.$refs.uToast.show({
message: msg, type: 'success', complete: function () {
_this.$db.set('timer', 0);
_this.$db.del('invitecode');
_this.showLogin = false;
_this.toLoginSuccessHandleBack();
}
})
},
doToken() {
const _this = this
//console.log("重新获取用户数据");
_this.getCode(function (code) {
var data = {
code: code
}
_this.$u.api.onLogin(data).then(res => {
if (res.status) {
if (res.data.auth) {
_this.$db.set('userToken', res.data.auth.token)
_this.$store.commit('hasLogin', true);
}
if (res.data.user) {
_this.$store.commit('userInfo', res.data.user);
}
_this.sessionAuthIdTool = res.otherData;
//console.log("成功后获取sessionAuthIdTool" + _this.sessionAuthIdTool);
} else {
_this.sessionAuthIdTool = res.otherData;
//console.log("失败后获取sessionAuthIdTool" + _this.sessionAuthIdTool);
}
})
})
},
// 勾选版权协议
checkboxChange(e) {
this.agreement = e;
if (e == true) {
this.isDisabled = false;
} else {
this.isDisabled = true;
}
console.log(this.agreement);
},
// 隐藏登录弹窗
hideModal() {
this.showLogin = false;
},
// 去登录
toAccountLogin() {
this.showLogin = false;
this.$u.route('/pages/login/loginByAccount/loginByAccount');
},
// 小程序,取消登录
closeAuth() {
this.showLogin = false;
this.$u.toast('您已取消授权')
},
getCode: function (callback) {
let _this = this
uni.login({
// #ifdef MP-ALIPAY
scopes: 'auth_user',
// #endif
success: function (res) {
//console.log(res);
if (res.code) {
return callback(res.code)
} else {
//login成功但是没有取到code
_this.$refs.uToast.show({ message: '未取得code请重试', type: 'error', })
}
},
fail: function (res) {
//console.log(res);
var scene = this.$store.state.scene;
//判断是否为 朋友圈内打开“单页模式",单页模式下,数据交互无法执行。所以不进行提醒
if (scene != 1154) {
_this.$refs.uToast.show({ message: '用户授权失败wx.login请重试', type: 'error', })
}
}
})
},
toLogin: function (data) {
let _this = this
_this.$u.api.loginByDecodeEncryptedData(data).then(res => {
if (res.status) {
//判断是否返回了token如果没有就说明没有绑定账号跳转到绑定页面
if (res.data.token) {
//登陆成功设置token并返回上一页
_this.$db.set('userToken', res.data.token)
_this.$store.commit('hasLogin', true);
_this.$refs.uToast.show({ message: '登录成功', type: 'success', })
return false
} else {
// #ifdef MP-WEIXIN
_this.sessionAuthIdTool = res.data.sessionAuthId;
// #endif
// #ifndef MP-WEIXIN
_this.$u.route({ type: 'navigateTo', url: '/pages/login/loginBySMS/loginBySMS?sessionAuthId=' + res.data.sessionAuthId });
// #endif
}
} else {
_this.$refs.uToast.show({ message: '登录失败,请重试', type: 'error', })
}
})
},
async getPhoneNumber(e) {
if (this.agreement == false) {
this.$refs.uToast.show({ message: '请先勾选并同意服务', type: 'error', })
return false;
} else {
let _this = this;
if (e.mp.detail.errMsg == 'getPhoneNumber:ok') {
var data = {
sessionAuthId: _this.sessionAuthIdTool,
iv: e.mp.detail.iv,
encryptedData: e.mp.detail.encryptedData,
}
//有推荐码的话,带上
var invitecode = _this.$db.get('invitecode')
if (invitecode) {
data.invitecode = invitecode
}
_this.toGetPhoneNumber(data);
} else {
_this.$u.toast('如未授权,您可尝试使用手机号+短信验证码登录');
}
_this.showLogin = false;
}
},
//实际的去登陆
toGetPhoneNumber: function (data) {
let _this = this
_this.$u.api.loginByGetPhoneNumber(data).then(res => {
//console.log(res);
if (res.status) {
//判断是否返回了token如果没有就说明没有绑定账号跳转到绑定页面
if (res.data.token) {
//console.log("登陆成功设置token并返回上一页");
//登陆成功设置token并返回上一页
_this.$db.set('userToken', res.data.token)
_this.$store.commit('hasLogin', true);
_this.showLogin = false;
_this.$refs.uToast.show({ message: '登录成功', type: 'success', })
return false
}
} else if (res.status == false && res.code == 500) {
//console.log("sessionId不正确重载");
_this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' });
} else {
_this.$u.toast('登录失败,请重试')
}
})
},
}
};
</script>
<style lang="scss" scoped>
@import "coreshop-login-modal.scss";
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view class="coreshop-modal-box" :class="show?'show':''">
<view class="dialog">
<image class="img" :src="src" lazy-load mode="widthFix" @tap="imgEvent"></image>
<text class="cuIcon-roundclose close" @tap="closeEvent"></text>
</view>
</view>
</template>
<script>
export default {
name: 'coreshop-modal-img',
props: {
src: {
type: String,
default: ""
},
show: {
type: Boolean,
default: false
}
},
methods: {
imgEvent() {
this.$emit('imgTap');
},
closeEvent() {
this.$emit('closeTap');
}
}
}
</script>
<style lang="scss" scoped>
.coreshop-modal-box { position: fixed; opacity: 0; top: inherit; left: inherit; right: inherit; bottom: inherit; z-index: 99999999; text-align: center; background: rgba(0, 0, 0, 0.6); transition: all 0.3s; pointer-events: none;
&::before { content: "\200B"; display: inline-block; height: 100%; vertical-align: middle; }
.dialog { position: relative; display: inline-block; vertical-align: middle; width: 310px;
.img { width: 100%; border-radius: 3%; }
.close { color: #dadada; top: 10px; position: relative; font-size: 26px; }
}
}
.coreshop-modal-box.show { top: 0; left: 0; right: 0; bottom: 0; opacity: 1; pointer-events: auto; }
</style>

View File

@@ -0,0 +1,326 @@
<template>
<view class="coreshop-header-slot-wrap coreshop-justify-center" :style="[navbarStyle]">
<view class="coreshop-slot-btns coreshop-flex coreshop-flex-nowrap coreshop-self-start" :style="{
background: backgroundColor,
borderColor :leftIconColor
}">
<u-icon name="home-fill" :color="leftIconColor" :size="leftIconSize" @tap="isGoBack" v-if="showHomeIcon && showLeftOneBtn"></u-icon>
<u-icon name="arrow-left-double" :color="leftIconColor" :size="leftIconSize" @tap="isGoBack" v-if="!showHomeIcon && showLeftOneBtn"></u-icon>
<view class="coreshop-slot-cut-off" :style="{
borderLeftColor: leftIconColor,
}" v-if="showLeftOneBtn"></view>
<u-icon name="list-dot" color="#fff" :color="leftIconColor" size="18" @click="doShowPopup"></u-icon>
</view>
<view class="coreshop-text-white coreshop-font-32 coreshop-header-title">
<view class="u-title u-line-1"
:style="{
color: titleColor,
fontSize: titleSize + 'px',
fontWeight: titleBold ? 'bold' : 'normal'
}">
{{ title }}
</view>
</view>
<view v-show="isShowPopup" class="coreshop-mark">
<u-overlay :show="isShowPopup" @click="maskClick"></u-overlay>
<view class="poptip">
<view class="poptip-arrow poptip-arrow-top"><em></em><i></i></view>
<!--增值业务-->
<view class="coreshop-padding-5 coreshop-bg-white coreshop-margin-top-10 coreshop-user-info-tools-box">
<view class="coreshop-padding-10 tools-view">
<view class="coreshop-text-black coreshop-text-bold coreshop-font-lg tools-title">增值业务</view>
</view>
<view class="coreshop-tools-list-box">
<u-grid :col="4" :border="false">
<u-grid-item v-for="(item,i) in vas" :key="i" v-if="item.showItem" @click="goRoute(item.router)">
<u-icon :name="item.icon" :size="25" color="#666"></u-icon>
<view class="grid-text">{{ item.name }}</view>
</u-grid-item>
</u-grid>
</view>
</view>
<!--我的服务-->
<view class="coreshop-padding-5 coreshop-bg-white coreshop-margin-top-10 coreshop-user-info-tools-box">
<view class="coreshop-padding-10 tools-view">
<view class="coreshop-text-black coreshop-text-bold coreshop-font-lg tools-title">我的服务</view>
</view>
<view class="coreshop-tools-list-box">
<u-grid :col="4" :border="false">
<u-grid-item v-for="(item,i) in utilityMenus" :key="i" @click="navigateToHandle(item.router)">
<u-icon :name="item.icon" :size="25" color="#666"></u-icon>
<view class="grid-text">{{ item.name }}</view>
</u-grid-item>
</u-grid>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
name: "coreshop-navbar-slot",
props: {
// 左侧按钮组背景颜色
backgroundColor: {
type: String,
default: '#fff'
},
// 左侧按钮组边框颜色
borderColor: {
type: String,
default: '#fff'
},
// 是否显示第一个按钮
showLeftOneBtn: {
type: Boolean,
default: true
},
// 返回箭头的颜色
leftIconColor: {
type: String,
default: '#fff'
},
// 左边返回的图标
leftIconName: {
type: String,
default: 'nav-back'
},
// 左边返回图标的大小px
leftIconSize: {
type: [String, Number],
default: '22'
},
// 导航栏标题
title: {
type: String,
default: ''
},
// 标题的宽度如果需要自定义右侧内容且右侧内容很多时可能需要减少这个宽度单位px
titleWidth: {
type: [String, Number],
default: '125'
},
// 标题的颜色
titleColor: {
type: String,
default: '#606266'
},
// 标题字体是否加粗
titleBold: {
type: Boolean,
default: false
},
// 标题的字体大小
titleSize: {
type: [String, Number],
default: 16
},
// 对象形式,因为用户可能定义一个纯色,或者线性渐变的颜色
background: {
type: Object,
default() {
return {
}
}
}
},
data() {
return {
isShowPopup: false,
showHomeIcon: false,
utilityMenus: {
myCoupon: {
name: '我的优惠券',
icon: 'coupon',
router: '/pages/member/coupon/index',
showItem: true
},
myBalance: {
name: '我的余额',
icon: 'rmb-circle',
router: '/pages/member/balance/index/index',
showItem: true
},
myInvoice: {
name: '我的发票',
icon: 'calendar',
router: '/pages/member/invoice/index',
showItem: true
},
myServices: {
name: '我的服务卡',
icon: 'bell',
router: '/pages/member/serviceOrder/index/index',
showItem: true
},
myIntegral: {
name: '我的积分',
icon: 'integral',
router: '/pages/member/integral/index',
showItem: true
},
myAddress: {
name: '地址管理',
icon: 'map',
router: '/pages/member/address/list/list',
showItem: true
},
myCollection: {
name: '我的收藏',
icon: 'bookmark',
router: '/pages/member/collection/index',
showItem: true
},
myHistory: {
name: '我的足迹',
icon: 'bag',
router: '/pages/member/history/index',
showItem: true
},
},
vas: {
storeMap: {
name: '门店列表',
icon: 'home',
router: '/pages/storeMap/storeMap',
showItem: false
},
servicePackage: {
name: '服务商品',
icon: 'list-dot',
router: '/pages/serviceGoods/index/index',
showItem: true
},
coupons: {
name: '优惠券',
icon: 'red-packet',
router: '/pages/coupon/coupon',
showItem: true
},
pinTuan: {
name: '拼团',
icon: 'grid',
router: '/pages/activity/pinTuan/list/list',
showItem: true
},
seckill: {
name: '秒杀',
icon: 'clock',
router: '/pages/activity/seckill/list/list',
showItem: true
},
groupBuying: {
name: '团购',
icon: 'trash',
router: '/pages/activity/groupBuying/list/list',
showItem: true
},
solitaire: {
name: '接龙',
icon: 'bag',
router: '/pages/activity/solitaire/list/list',
showItem: true
},
},
};
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
},
// 整个导航栏的样式
navbarStyle() {
let style = {};
// 合并用户传递的背景色对象
Object.assign(style, this.background);
return style;
},
},
mounted() {
let pages = getCurrentPages();
var page = pages[pages.length - 2];
console.log(page);
if (!page) {
this.showHomeIcon = true;
}
console.log(this.showHomeIcon);
},
methods: {
navigateToHandle(pageUrl) {
this.isShowPopup = false;
uni.showLoading({
title: '跳转中...'
});
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
uni.hideLoading();
return false;
}
uni.hideLoading();
this.$u.route(pageUrl)
},
isGoBack() {
this.isShowPopup = false;
if (this.showHomeIcon) {
uni.switchTab({
url: '/pages/index/default/default'
});
} else {
uni.navigateBack();
}
},
doShowPopup() {
this.isShowPopup = true;
},
// 遮罩被点击
maskClick() {
this.isShowPopup = false;
},
}
};
</script>
<style scoped lang="scss">
.coreshop-mark { position: fixed; top: 90px; left: 0; right: 0; z-index: 10074; width: 100%;
.poptip { position: absolute; top: 0px; left: 0px; line-height: 16px; color: #db7c22; font-size: 12px; background: #fff; border: solid 1px #ffbb76; border-radius: 10px; box-shadow: 0 0 3px #ddd; margin: 0 10px; width: calc(100% - 20px); padding: 10px; z-index: 10072; }
.poptip-arrow { position: absolute; overflow: hidden; font-style: normal; font-family: simsun; font-size: 12px; text-shadow: 0 0 2px #ccc;
em { color: #ffbb76; }
i { color: #fffcef; text-shadow: none; }
}
.poptip-arrow em, .poptip-arrow i { position: absolute; left: 0; top: 0; font-style: normal; }
.poptip-arrow-top { height: 12px; width: 22px; left: 66px; margin-left: -12px; }
.poptip-arrow-bottom { height: 6px; width: 12px; left: 12px; margin-left: -6px; }
.poptip-arrow-left, .poptip-arrow-right { height: 12px; width: 6px; top: 12px; margin-top: -6px; }
.poptip-arrow-top { top: -8px;
em { top: -1px; }
i { top: 0px; }
}
.poptip-arrow-bottom { bottom: -6px;
em { top: -8px; }
i { top: -9px; }
}
.poptip-arrow-left { left: -6px;
em { left: 1px; }
i { left: 2px; }
}
.poptip-arrow-right { right: -6px;
em { left: -6px; }
i { left: -7px; }
}
}
</style>

View File

@@ -0,0 +1,62 @@
<template>
<!-- 单图 -->
<view class="coreshop-adpop" v-if="coreshopdata.parameters.list && coreshopdata.parameters.list.length > 0">
<view class="adpop" v-if="closeAd">
<view class="adpop-center">
<view class="adpop-img">
<!-- #ifdef MP-WEIXIN -->
<view @click="showSliderInfo(coreshopdata.parameters.list[0].linkType, coreshopdata.parameters.list[0].linkValue)">
<image class="ad-img" :src="coreshopdata.parameters.list[0].image" mode="widthFix"></image>
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<image class="ad-img" :src="coreshopdata.parameters.list[0].image" mode="widthFix" @click="showSliderInfo(coreshopdata.parameters.list[0].linkType, coreshopdata.parameters.list[0].linkValue)"></image>
<!-- #endif -->
</view>
<image class="close-btn" src="/static/images/close-pink.png" mode="" @click="closePop"></image>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshopadpop",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
closeAd: true
}
},
computed: {
count() {
// console.log(coreshopdata)
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
closePop() {
this.closeAd = false
},
},
}
</script>
<style scoped lang="scss">
.coreshop-adpop {
.adpop { position: fixed; background: rgba(0,0,0,.5); width: 100%; height: 100vh; z-index: 999; top: 0; left: 0;
.adpop-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 70%; text-align: center;
.adpop-img { width: 100%; max-height: 500px; margin-bottom: 25px;
.ad-img { width: 100%; max-height: 500px; }
}
.close-btn { width: 40px; height: 40px; }
}
}
}
</style>

View File

@@ -0,0 +1,54 @@
<template>
<view class='coreshop-index-article coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white' v-if="coreshopdata.parameters.list && count">
<view class='coreshop-cell-item' v-for="item in coreshopdata.parameters.list" :key="item.id" @click="articleDetail(item.id)">
<view class="coreshop-cell-item-bd">
<view class="article-title ">
{{ item.title }}
</view>
<view class="article-des u-line-2">
{{ item.brief }}
</view>
</view>
<view class="cell-title-img">
<image :src="item.coverImage" mode="aspectFill" class="coverImage"></image>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshoparticle",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
// 查看文章详情
articleDetail(articleId) {
this.$u.route('/pages/article/details/details?id=' + articleId + '&idType=1')
}
}
}
</script>
<style scoped lang="scss">
.coreshop-index-article { border-radius: 8px; padding: 0px 10px; background: #FFFFFF !important; color: #333333 !important; overflow: hidden;
.coreshop-cell-item { padding: 5px 0px 5px 0; float: left; width: 100%; border-bottom: 1px solid #f3f3f3;
.coreshop-cell-item-bd { float: left; width: calc(100% - 100px);
.article-title { font-size: 14px; color: #333; width: 100%; overflow: hidden; float: left; margin-bottom: 5px; }
.article-des { font-size: 14px; color: #999; overflow: hidden; float: left; line-height: 20px; }
}
.cell-title-img { width: 80px; height: 80px; float: right;
.coverImage { width: 80px; height: 80px; }
}
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<view class='coreshop-index-article coreshop-cell-group coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white' v-if="coreshopdata.parameters.list && count">
<view class='coreshop-cell-item' v-for="item in coreshopdata.parameters.list" :key="item.id" @click="articleDetail(item.id)">
<view class="coreshop-cell-item-bd">
<view class="article-title">
{{ item.title }}
</view>
<view class="article-des u-line-2">
{{ item.brief }}
</view>
</view>
<view class="cell-title-img">
<image :src="item.coverImage" mode="aspectFill" class="coverImage"></image>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshoparticleclassify",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
computed: {
count() {
if (!this.coreshopdata.parameters.list) {
return false;
}
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
// 查看文章详情
articleDetail(articleId) {
this.$u.route('/pages/article/details/details?id=' + articleId + '&idType=1')
}
}
}
</script>
<style lang="scss" scoped>
.coreshop-index-article { border-radius: 8px; padding: 0px 10px; background: #FFFFFF !important; color: #333333 !important; overflow: hidden;
.coreshop-cell-item { padding: 5px 0px 5px 0; float: left; width: 100%; border-bottom: 1px solid #f3f3f3;
.coreshop-cell-item-bd { float: left; display: flex; flex-direction: column;
.article-title { font-size: 14px; color: #333; width: 100%; overflow: hidden; float: left; margin-bottom: 5px; }
.article-des { font-size: 12px; color: #999; overflow: hidden; float: left; line-height: 20px; }
}
.cell-title-img { width: 80px; height: 80px; float: right;
.coverImage { width: 80px; height: 80px; }
}
}
}
</style>

View File

@@ -0,0 +1,23 @@
<template>
<view class="coreshop-padding-10 coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white">
<u-gap :height="coreshopdata.parameters.height * 2" :bg-color="coreshopdata.parameters.backgroundColor"></u-gap>
</view>
</template>
<script>
export default {
name: "coreshopblank",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,30 @@
<template>
<view class="u-content">
<u-parse :content="content" :selectable="true"></u-parse>
</view>
</template>
<script>
//视频和文本解析组件
export default {
name: 'coreshopContent',
props: {
content: {
required: true,
}
},
created() { },
methods: {
preview(src, e) {
// do something
},
navigate(href, e) {
// do something
}
}
}
</script>
<style lang="scss" scoped>
.u-content { color: $u-content-color; font-size: 13px; line-height: 1.8; }
.u-content p { color: $u-tips-color; }
</style>

View File

@@ -0,0 +1,147 @@
<template>
<!-- 首页优惠券卡片 -->
<view class="coupon-box coreshop-margin-bottom-5 coreshop-padding-10" v-if="count">
<!--提示框组件-->
<u-toast ref="uToast" />
<view class="head-box coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-margin-bottom-10">
<view class="head-title u-ellipsis-1">领券专区</view>
<!--<view class="head-more coreshop-flex coreshop-align-center coreshop-flex-direction-row u-col-center" @tap="$Router.push('/pages/app/coupon/list')">
<text class="more-text coreshop-margin-right-10">查看更多</text>
<text class="iconfont icon-youjiantou-tianchong more-icon"></text>
</view>-->
<u-icon name="arrow-right-double" size="12" label="查看更多" labelSize="12" labelPos="left" @tap="$u.route('/pages/coupon/coupon')"></u-icon>
</view>
<scroll-view class="groupon-scroll" enable-flex scroll-anchoring scroll-x scroll-with-animation>
<view class="groupon-card-wrap coreshop-flex coreshop-align-center">
<view v-for="(item, index) in coreshopdata.parameters.list" :key="item.id">
<!-- mini -->
<!--<view class="coupon-card u-flex u-row-between u-m-r-16" v-if="couponType === 2" :style="{ background: `linear-gradient(to right, ${bgColor1}, ${bgColor2})` }">
<view class="card-left u-flex-col u-row-center u-p-l-30">
<view class="price coreshop-margin-bottom-10" :style="{ color: priceColor }">{{ item.amount }}</view>
<view class="notice" :style="{ color: color }">{{ item.enough }}元可用</view>
<view class="notice coreshop-margin-bottom-10" :style="{ color: color }">仅剩{{ item.stock }}</view>
</view>
<view class="card-right u-p-y-20 u-p-r-10 u-flex-col u-row-center u-col-center">
<button class="u-reset-button get-btn coreshop-margin-bottom-10" :style="{ color: color }" @tap="getCoupon(item.id, index)">
{{ item.status_code === 'cannot_get' ? '不可领取' : '领券购买' }}
</button>
</view>
</view>-->
<!-- big -->
<view class="coreshop-padding-right-5">
<view class="coupon-wrap " :style="{ background: `linear-gradient(to right, ${bgColor1}, ${bgColor2})` }">
<view class="coupon-item coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between">
<view class="coupon-left coreshop-flex coreshop-flex-direction ">
<view class="sum-box">
<text class="unit" style="color: #6b3f12"></text>
<!--<text class="sum " style="color: #6b3f12">{{ item.name }}</text>-->
<text class="sub" style="color: #6b3f12">{{ item.name }}</text>
</view>
<view class="notice " style="color: #9d6d25">
<text v-for="(itemCondition, index) in item.conditions" :key="index">{{itemCondition}}</text>
</view>
<view class="notice" style="color: #9d6d25">
有效期{{$u.timeFormat(item.startTime, 'yyyy-mm-dd')}} {{$u.timeFormat(item.endTime, 'yyyy-mm-dd')}}
</view>
</view>
<view class="coupon-right coreshop-flex coreshop-flex-direction">
<button class="get-btn" :style="{ color: bgColor1 }" @tap.stop="receiveCoupon(item.id)">立即领取</button>
<view class="surplus-num" style="color: #9d6d25">
<text v-for="(itemResult, index) in item.results" :key="index">{{itemResult}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name: "coreshopcoupon",
components: {
},
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
computed: {
count() {
if (!this.coreshopdata) {
return false;
}
if (!this.coreshopdata.parameters) {
return false;
}
if (!this.coreshopdata.parameters.list) {
return false;
}
return (this.coreshopdata.parameters.list.length > 0)
}
},
data() {
return {
coupons: [
{
color: '#9F6DFA', ltBg: "#FFFFFF", height: '90px',
unit: "¥", number: 5, txt: "满50元可用", title: "全场通用券", desc: "有效期至 2018-05-20",
btn: "领取", drawed: "已抢2100张"
}
]
}
},
created() {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
// 失效
.gray-wrap { filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1) !important; -webkit-filter: grayscale(100%) !important; -moz-filter: grayscale(100%) !important; -ms-filter: grayscale(100%) !important; -o-filter: grayscale(100%) !important; filter: grayscale(100%) !important; filter: gray !important; }
.groupon-scroll { height: 85px; width: 375px;
.groupon-card-wrap { height: 85px; width: 375px; }
}
.coupon-box { background-color: #fff;
.head-box {
.head-title { width: 150px; font-size: 16px; font-weight: bold; color: #333333; }
.head-more {
.more-text { font-size: 11px; font-weight: 500; color: #333333; }
.more-icon { color: #333333; font-size: 12px; }
}
}
.coupon-card { width: 171.5px; height: 85px; background: linear-gradient(90deg, #f8dca5, #efc480); border-radius: 5px; mask: url($apiFilesUrl+'/static/images/coupon/coupon_mini_bg.png'); -webkit-mask-box-image: url($apiFilesUrl+'/static/images/coupon/coupon_mini_bg.png'); mask-size: 100% 100%;
.card-left { height: 100%; width: 130px;
.price { color: #4f3a1e; font-size: 15px; font-weight: bold;
&::before { content: '¥'; font-size: 10px; }
}
.notice { font-size: 11px; font-weight: 500; color: #a8700d; }
}
.card-right { height: 100%; width: 30px;
.get-btn { font-size: 12px; font-weight: 500; text-align: right; color: #a8700d; writing-mode: vertical-lr; /*从左向右 从右向左是 writing-mode: vertical-rl;*/ writing-mode: tb-lr; /*IE浏览器的从左向右 从右向左是 writing-mode: tb-rl*/ }
}
}
}
// 未领取,已领取
.coupon-wrap { mask: url($apiFilesUrl+'/static/images/coupon/coupon_bg1.png'); -webkit-mask-box-image: url($apiFilesUrl+'/static/images/coupon/coupon_bg1.png'); mask-size: 100% 100%; position: relative; border-radius: 5px; width: 355px; height: 85px; background: linear-gradient(to right, $u-type-warning-disabled, $u-type-warning);
.coupon-item { width: 100%; height: 168rpx; border-radius: 5px;
.coupon-left { height: 100%; justify-content: center; padding-left: 20px;
.unit { font-size: 12px; color: #fff; }
.sum { font-size: 22.5px; font-weight: bold; color: #fff; line-height: 22.5px; padding-right: 5px; }
.sub { font-size: 18px; font-weight: bold; color: #fff; line-height: 18px; padding-right: 5px; }
.notice { font-size: 11px; color: rgba(#fff, 0.7); margin-top: 3px; }
}
.coupon-right { height: 100%; width: 110px; justify-content: center; align-items: center;
.get-btn { width: 72px; height: 27px; background: #ffffff; border-radius: 13px; padding: 0; font-size: 12px; font-weight: 500; color: $u-type-warning; }
.surplus-num { font-size: 11px; font-weight: 500; color: #fff; margin-top: 7px; }
}
}
}
</style>

View File

@@ -0,0 +1,159 @@
<template>
<view>
<u-tabs :list="nameList" :current="current" @change="change"></u-tabs>
<view v-for="(child,indexP) in newData.parameters.list" :key="indexP">
<view class="goodsBox" v-show="child.isShow==true">
<!-- 列表平铺两列三列 -->
<view v-if="child.column == '2' || child.column == '3' " v-bind:class="'column'+child.column">
<view class="" v-if="child.list">
<u-grid :col="child.column" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0rpx'}" v-for="(item, index) in child.list" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image :src="item.image" mode="widthFix" width="100%" :height="child.column==2?'164px':'104px'" radius="10"></u--image>
<view class="good_title u-line-2">
{{item.name}}
</view>
<view class="good-price coreshop-display-block">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-5 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<view v-else-if="!count && !child.listAjax">
<u-grid col="3" border="false" align="center">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0rpx'}" v-for="item in 3" :key="item" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image src="/static/images/common/empty.png" mode="widthFix" width="100%" radius="10"></u--image>
<view class="good_title u-line-2">
</view>
<view class="good-price">
0
</view>
<view class="good-tag-recommend">
推荐
</view>
<view class="good-tag-hot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
</view>
<!-- 列表平铺单列 -->
<view v-if="child.column == '1'">
<view v-if="child.list">
<u-grid :col="1" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0rpx'}" v-for="item in child.list" :key="item.id" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u-row gutter="5" justify="space-between">
<u-col span="4">
<u--image :src="item.image" mode="widthFix" width="100%" radius="10"></u--image>
<view class="good-tag-recommend2" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</u-col>
<u-col span="8">
<view class="good_title-xl u-line-3 u-padding-10">
{{item.name}}
</view>
<view class="good-price u-padding-10">
{{item.price}} <span class="u-font-xs coreshop-text-through u-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
</u-col>
</u-row>
</view>
</u-grid-item>
</u-grid>
</view>
<view class="order-none" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/order.png'" icon-size="150" text="暂无" mode="list"></u-empty>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
current: 0,
nameList: [],
newData: {}
};
},
name: "coreshopgoodTabBar",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
mounted() {
var _this = this;
this.newData = this.coreshopdata;
for (var i = 0; i < this.newData.parameters.list.length; i++) {
let item = {
name: this.newData.parameters.list[i].title
}
this.nameList.push(item);
if (_this.current == i) {
_this.newData.parameters.list[i].isShow = true;
} else {
_this.newData.parameters.list[i].isShow = false;
}
}
},
computed: {
},
methods: {
change(item) {
var _this = this;
this.current = item.index;
for (var i = 0; i < _this.newData.parameters.list.length; i++) {
if (_this.current == i) {
_this.newData.parameters.list[i].isShow = true;
} else {
_this.newData.parameters.list[i].isShow = false;
}
}
}
},
}
</script>
<style scoped lang="scss">
.goodsBox { border-radius: 16rpx; color: #333333 !important; margin: 5px 5px;
.good_box { border-radius: 8px; margin: 3px; background-color: #ffffff; padding: 5px; position: relative; width: calc(100% - 6px);
.good_title { font-size: 13px; margin-top: 5px; color: $u-main-color; }
.good_title-xl { font-size: 14px; margin-top: 5px; color: $u-main-color; }
.good-tag-hot { display: flex; margin-top: 5px; position: absolute; top: 7.5px; left: 7.5px; background-color: $u-type-error; color: #FFFFFF; display: flex; align-items: center; padding: 4rpx 14rpx; border-radius: 25px; font-size: 10px; line-height: 1; }
.good-tag-recommend { display: flex; margin-top: 5px; position: absolute; top: 7.5px; right: 7.5px; background-color: $u-type-primary; color: #FFFFFF; margin-left: 10px; border-radius: 25px; line-height: 1; padding: 4rpx 14rpx; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-tag-recommend2 { display: flex; margin-top: 5px; position: absolute; bottom: 7.5px; left: 7.5px; background-color: $u-type-primary; color: #FFFFFF; border-radius: 25px; line-height: 1; padding: 4rpx 14rpx; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-price { font-size: 30rpx; color: $u-type-error; margin-top: 5px; }
}
.indicator-dots { margin-top: 10px; margin-bottom: 10px; display: flex; justify-content: center; align-items: center;
.indicator-dots-item { background-color: $u-tips-color; height: 6px; width: 6px; border-radius: 10px; margin: 0 3px; }
.indicator-dots-active { background-color: $u-type-primary; }
}
}
</style>

View File

@@ -0,0 +1,249 @@
<template>
<view class="goodsBox coreshop-margin-bottom-10 coreshop-padding-top-5 coreshop-bg-white">
<!-- 列表平铺两列三列 -->
<view v-if="coreshopdata.parameters.column == '2' && coreshopdata.parameters.display == 'list' || coreshopdata.parameters.column == '3' && coreshopdata.parameters.display == 'list'" v-bind:class="'column'+coreshopdata.parameters.column">
<view class="coreshop-margin-left-5 coreshop-margin-right-5 coreshop-margin-top-10 coreshop-margin-bottom-10 " v-if="coreshopdata.parameters.lookTitle == 'true'">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" v-if="coreshopdata.parameters.title != '' && coreshopdata.parameters.lookTitle == 'true'" @click="coreshopdata.parameters.lookMore == 'true' ? goGoodsList({catId: coreshopdata.parameters.classifyId,brandId:coreshopdata.parameters.brandId}) :''" :arrow="coreshopdata.parameters.lookMore == 'true'" :sub-title="coreshopdata.parameters.lookMore == 'true'?'更多':''"></coreshop-section>
</view>
<view class="" v-if="count">
<u-grid :col="coreshopdata.parameters.column" :border="false" align="left">
<u-grid-item :custom-style="{padding: '0px'}" v-for="(item, index) in coreshopdata.parameters.list" :key="index">
<view class="good_box" @tap="goGoodsDetail(item.id)">
<u--image :src="item.image" mode="widthFix" width="100%" :height="coreshopdata.parameters.column==2?'164px':'104px'" radius="10"></u--image>
<view class="good_title u-line-2">
{{item.name}}
</view>
<view class="good-price coreshop-display-block">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-5 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
<view>
{{ pointShowName}}兑换价:
</view>
<view class="coreshop-text-red">
{{pointDiscountedProportion * item.pointsDeduction }}{{ pointShowName}}+{{ item.price - item.pointsDeduction}}
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && item.points > 0">
<view>
购买赠送:
</view>
<view class="coreshop-text-red">
{{item.points}}{{ pointShowName}}
</view>
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<view v-else-if="!count && !coreshopdata.parameters.listAjax">
<u-grid col="3" border="false" align="left">
<u-grid-item :custom-style="{padding: '0px'}" v-for="item in 3" :key="item">
<view class="good_box">
<view class="good_title u-line-2">
</view>
<view class="good-price">
0
</view>
<view class="good-tag-recommend">
推荐
</view>
<view class="good-tag-hot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
</view>
<!-- 列表平铺单列 -->
<view v-if="coreshopdata.parameters.column == '1' && coreshopdata.parameters.display == 'list'">
<view class="coreshop-margin-left-5 coreshop-margin-right-5 coreshop-margin-top-10 coreshop-margin-bottom-10 ">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" v-if="coreshopdata.parameters.title != '' && coreshopdata.parameters.lookTitle == 'true'" @click="coreshopdata.parameters.lookMore == 'true' ? goGoodsList({catId: coreshopdata.parameters.classifyId,brandId:coreshopdata.parameters.brandId}) :''" :arrow="coreshopdata.parameters.lookMore == 'true'" :sub-title="coreshopdata.parameters.lookMore == 'true'?'更多':''"></coreshop-section>
</view>
<view v-if="count">
<u-grid :col="1" :border="false" align="left">
<u-grid-item :custom-style="{padding: '0px'}" v-for="item in coreshopdata.parameters.list" :key="item.id">
<view class="good_box" @click="goGoodsDetail(item.id)">
<u--image :src="item.image" width="100%" radius="10"></u--image>
<view class="good_title u-line-2">
{{item.name}}
</view>
<view class="good-price coreshop-display-block">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-5 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
<view>
{{ pointShowName}}兑换价:
</view>
<view class="coreshop-text-red">
{{pointDiscountedProportion * item.pointsDeduction }}{{ pointShowName}}+{{ item.price - item.pointsDeduction}}
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && item.points > 0">
<view>
购买赠送:
</view>
<view class="coreshop-text-red">
{{item.points}}{{ pointShowName}}
</view>
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<view class="order-none" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/order.png'" icon-size="150" text="暂无" mode="list"></u-empty>
</view>
</view>
<!-- 横向滚动 -->
<block v-if="coreshopdata.parameters.display == 'slide'"
v-bind:class="'slide'+coreshopdata.parameters.column">
<view class="coreshop-margin-left-15 coreshop-margin-right-15 coreshop-margin-top-15 coreshop-margin-bottom-15" v-if="coreshopdata.parameters.lookTitle == 'true'">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" v-if="coreshopdata.parameters.title != '' && coreshopdata.parameters.lookTitle == 'true'" @click="coreshopdata.parameters.lookMore == 'true' ? goGoodsList({catId: coreshopdata.parameters.classifyId,brandId:coreshopdata.parameters.brandId}) :''" :arrow="coreshopdata.parameters.lookMore == 'true'" :sub-title="coreshopdata.parameters.lookMore == 'true'?'更多':''"></coreshop-section>
</view>
<block v-if="count">
<swiper :class="coreshopdata.parameters.column==3?'swiper3':coreshopdata.parameters.column==2?'swiper2':''" @change="change">
<swiper-item v-for="no of pageCount" :key="no">
<u-grid :col="coreshopdata.parameters.column" :border="false" align="left" :data-id="no">
<u-grid-item v-for="(item, index) in coreshopdata.parameters.list" v-if="index >=coreshopdata.parameters.column*no && index <coreshopdata.parameters.column*(no+1)" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u-image :src="item.image" :index="item.id" mode="widthFit" width="100%" :height="coreshopdata.parameters.column==3?'104px':coreshopdata.parameters.column==2?'164px':'104px'" radius="10">
</u-image>
<view class="good_title u-line-2">
{{item.name}}
</view>
<view class="good-price coreshop-display-block">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-5 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
<view>
{{ pointShowName}}兑换价:
</view>
<view class="coreshop-text-red">
{{pointDiscountedProportion * item.pointsDeduction }}{{ pointShowName}}+{{ item.price - item.pointsDeduction}}
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && item.points > 0">
<view>
购买赠送:
</view>
<view class="coreshop-text-red">
{{item.points}}{{ pointShowName}}
</view>
</view>
</view>
</u-grid-item>
</u-grid>
</swiper-item>
</swiper>
<view class="indicator-dots">
<view class="indicator-dots-item" v-for="no of pageCount" :key="no" :class="[current == no ? 'indicator-dots-active' : '']">
</view>
</view>
</block>
<view v-else="">
<scroll-view class='swiper-list' scroll-x="true"></scroll-view>
</view>
</block>
</view>
</template>
<script>
export default {
data() {
return {
current: 0,
pageCount: [],
count: false
};
},
filters: {
substr(val) {
if (val.length == 0 || val == undefined) {
return false;
} else if (val.length > 13) {
return val.substring(0, 13) + "...";
} else {
return val;
}
}
},
name: "coreshopgoods",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
computed: {
pointSwitch() { return this.$store.state.config.pointSwitch },
pointShowExchangePrice() { return this.$store.state.config.pointShowExchangePrice },
pointDiscountedProportion() { return this.$store.state.config.pointDiscountedProportion },
pointExchangeModel() { return this.$store.state.config.pointExchangeModel },
pointShowName() { return this.$store.state.config.pointShowName },
pointGetModel() { return this.$store.state.config.pointGetModel },
pointShowPoint() { return this.$store.state.config.pointShowPoint },
},
methods: {
change(e) {
this.current = e.detail.current;
}
},
created() {
this.count = this.coreshopdata.parameters.list.length > 0;
var page = Number(this.coreshopdata.parameters.list.length / this.coreshopdata.parameters.column).toFixed(0);
if (this.coreshopdata.parameters.column * page < this.coreshopdata.parameters.list.length) {
page = Number(page) + 1;
}
for (var i = 0; i < page; i++) {
this.pageCount.push(i);
}
}
}
</script>
<style scoped lang="scss">
.goodsBox { color: #333333 !important; padding: 0 5px; overflow: hidden;
.good_box { border-radius: 8px; margin: 3px; background-color: #ffffff; padding: 5px; position: relative; width: 100%;
.good_title { font-size: 13px; margin-top: 5px; color: $u-main-color; }
.good_title-xl { font-size: 14px; margin-top: 5px; color: $u-main-color; }
.good-tag-hot { display: flex; margin-top: 5px; position: absolute; top: 7.5px; left: 7.5px; background-color: $u-type-error; color: #FFFFFF; display: flex; align-items: center; padding: 2px 7px; border-radius: 25px; font-size: 10px; line-height: 1; }
.good-tag-recommend { display: flex; margin-top: 5px; position: absolute; top: 7.5px; right: 7.5px; background-color: $u-type-primary; color: #FFFFFF; margin-left: 10px; border-radius: 25px; line-height: 1; padding: 2px 7px; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-tag-recommend2 { display: flex; margin-top: 5px; position: absolute; bottom: 7.5px; left: 7.5px; background-color: $u-type-primary; color: #FFFFFF; border-radius: 25px; line-height: 1; padding: 2px 7px; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-price { font-size: 15px; color: $u-type-error; margin-top: 5px; }
}
.indicator-dots { margin-top: 10px; margin-bottom: 10px; display: flex; justify-content: center; align-items: center; flex-direction: row;
.indicator-dots-item { background-color: $u-tips-color; height: 6px; width: 6px; border-radius: 10px; margin: 0 3px; }
.indicator-dots-active { background-color: $u-type-primary; }
}
}
.swiper3 { height: 200px; }
.swiper2 { height: 270px; }
.image2 { height: 150px; }
.image3 { height: 150px; }
</style>

View File

@@ -0,0 +1,90 @@
<template>
<!-- 团购秒杀 -->
<view v-if="count">
<view class="coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-top-10 coreshop-margin-bottom-10">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" @click="goSeckillList()"></coreshop-section>
</view>
<view class="coreshop-margin-left-15 coreshop-margin-right-15" v-if="coreshopdata.parameters.list && count">
<view class="img-list-item" v-if="item.id !== 'undefined' && item.id" v-for="(item, key) in coreshopdata.parameters.list" :key="key" @click="goSeckillDetail(item.goods.id, item.goods.groupId)">
<view class="img-list-item-l">
<u-image :src="item.goods.image" :index="item.id" :showLoading="true" width="100%" height="96px"></u-image>
</view>
<view class="img-list-item-r">
<view class="coreshop-font-18 u-line-1">{{item.name}}</view>
<view class="u-line-2 coreshop-margin-top-5 coreshop-margin-bottom-5">{{item.goods.name}}</view>
<view class="item-c coreshop-flex coreshop-justify-between">
<view class="red-price coreshop-justify-between">
{{item.goods.product.price}}
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-5">{{item.goods.product.mktprice}}</span>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between">
<view class="red-price coreshop-font-15 coreshop-flex-direction-row" v-if="(item.startStatus == 1) && item.lastTime">
<u-count-down :time="item.lastTime" format="HH:mm:ss"></u-count-down>
</view>
<view class="coreshop-font-12 red-price" v-if="item.startStatus == 3">已结束</view>
<view class="coreshop-font-12 red-price" v-if="item.startStatus == 2">即将开始</view>
<u-icon name="shopping-cart" color="#2979ff" size="25" class="btnCart"></u-icon>
</view>
</view>
</view>
</view>
<view class="img-list-item" v-if="!item.id" v-for="(item, key) in coreshopdata.parameters.list" :key="key">
<image class="img-list-item-l" :src="item.image== '/images/empty-banner.png'? '/static/images/common/empty-banner.png':item.image" mode='aspectFill'></image>
<view class="img-list-item-r">
<view class="goods-name list-goods-name">{{item.name}}</view>
<view class="item-c">
<view class=" red-price">{{item.price}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshopgrouppurchase",
props: {
coreshopdata: {
// type: Array,
required: false,
}
},
computed: {
count() {
if (!this.coreshopdata) {
return false;
}
if (!this.coreshopdata.parameters) {
return false;
}
if (!this.coreshopdata.parameters.list) {
return false;
}
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
end(index) {
let _that = this;
_that.list.splice(index, 1)
}
},
}
</script>
<style lang="scss" scoped>
.img-list-item { border-radius: 8px; margin: 2.5px 2.5px 10px 2.5px; background-color: #ffffff; padding: 5px; position: relative; overflow: hidden; flex-direction: row;
.img-list-item-l { width: 100px; height: 100px; display: inline-block; float: left; }
.img-list-item-r { width: calc(100% - 120px); display: inline-block; margin-left: 7.5px; float: left; position: relative;
.description { font-size: 12px; color: #929292; }
.item-c { width: 100%; margin-top: 0;
.red-price { color: #FF7159 !important; }
.btnCart { float: right; }
}
}
}
.u-count-down__text { font-size: 12px; }
</style>

View File

@@ -0,0 +1,47 @@
<template>
<!-- 单图 -->
<view class="coreshop-imgsingle coreshop-bg-white" v-if="coreshopdata.parameters.list && coreshopdata.parameters.list.length > 0">
<view class="" v-for="child in coreshopdata.parameters.list">
<view @click="taped(child)">
<image class="ad-img" :src="child.image" mode="widthFix"></image>
</view>
<view class="imgup-btn" v-if="child.buttonText != ''" @click="showSliderInfo(child.linkType, child.linkValue)">
<button class="coreshop-btn" :style="{background:child.buttonColor,color:child.textColor}">{{child.buttonText}}</button>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshopimgsingle",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
computed: {
count() {
// console.log(coreshopdata)
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
taped(item) {
this.showSliderInfo(item.linkType, item.linkValue);
},
},
}
</script>
<style lang="scss" scoped>
.coreshop-imgsingle { overflow: hidden; position: relative;
.ad-img { width: 100%; float: left; }
.ad-img:last-child { margin-bottom: 0; }
.imgup-btn { position: absolute; z-index: 668; bottom: 40px; left: 20px;
.coreshop-btn { line-height: 2; font-size: 14px; padding: 0 25px; border-radius: 25px; }
}
}
</style>

View File

@@ -0,0 +1,52 @@
<template>
<view class="coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white">
<u-swiper :list="swiperItems" :height="swiperHeight" :interval="swiperDuration" keyName="image" @click="taped"></u-swiper>
</view>
</template>
<script>
export default {
name: "coreshopimgSlide",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
swiperItems: [],
swiperHeight: 130,
swiperDuration: 2500,
};
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
components: {},
created() {
var data = this.coreshopdata.parameters.list;
for (var i = 0; i < data.length; i++) {
let moder = {
image: data[i].image == '/images/empty-banner.png' ? '/static/images/common/empty-banner.png' : data[i].image,
opentype: 'click',
url: '',
title: data[i].linkType,
linkType: data[i].linkType,
linkValue: data[i].linkValue,
}
this.swiperItems.push(moder);
}
this.swiperHeight = this.coreshopdata.parameters.height;
this.swiperDuration = this.coreshopdata.parameters.duration;
},
watch: {},
methods: {
taped: function (e) {
this.showSliderInfo(this.swiperItems[e].linkType, this.swiperItems[e].linkValue);
},
}
}
</script>

View File

@@ -0,0 +1,48 @@
<template>
<view class="coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10">
<u-grid :border="false" align="left" :col="coreshopdata.parameters.style" v-if="coreshopdata.parameters.style == '2' ||coreshopdata.parameters.style == '3' ||coreshopdata.parameters.style == '4'">
<u-grid-item bg-color="transparent" v-for="(item, index) in coreshopdata.parameters.list" :key="index" :custom-style="{padding:coreshopdata.parameters.margin+'px'}">
<image :src="item.image" mode="widthFix" @click="showSliderInfo(item.linkType, item.linkValue)" style="width:100%;"></image>
</u-grid-item>
</u-grid>
<u-grid :border="false" align="left" :col="2" v-if="coreshopdata.parameters.style == '0'">
<u-grid-item bg-color="transparent" :custom-style="{padding:coreshopdata.parameters.margin+'px'}">
<image :src="coreshopdata.parameters.list[0].image" mode="widthFix" v-if="coreshopdata.parameters.list[0]" @click="showSliderInfo(coreshopdata.parameters.list[0].linkType, coreshopdata.parameters.list[0].linkValue)" class="coreshop-percent-100"></image>
</u-grid-item>
<u-grid-item bg-color="transparent" :custom-style="{padding:coreshopdata.parameters.margin+'px'}">
<image :src="coreshopdata.parameters.list[1].image" mode="widthFix" v-if="coreshopdata.parameters.list[1]" @click="showSliderInfo(coreshopdata.parameters.list[1].linkType, coreshopdata.parameters.list[1].linkValue)" class="coreshop-percent-100"></image>
<u-grid :border="false" align="left" :col="2">
<u-grid-item bg-color="transparent" :custom-style="{padding:coreshopdata.parameters.margin+'px'}">
<image :src="coreshopdata.parameters.list[2].image" mode="widthFix" v-if="coreshopdata.parameters.list[2]" @click="showSliderInfo(coreshopdata.parameters.list[2].linkType, coreshopdata.parameters.list[2].linkValue)" class="coreshop-percent-100"></image>
</u-grid-item>
<u-grid-item bg-color="transparent" :custom-style="{padding:coreshopdata.parameters.margin+'px'}">
<image :src="coreshopdata.parameters.list[3].image" mode="widthFix" v-if="coreshopdata.parameters.list[3]" @click="showSliderInfo(coreshopdata.parameters.list[3].linkType, coreshopdata.parameters.list[3].linkValue)" class="coreshop-percent-100"></image>
</u-grid-item>
</u-grid>
</u-grid-item>
</u-grid>
</view>
</template>
<script>
export default {
name: "coreshopimgwindow",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
padding: '3'
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,44 @@
<template>
<view class=" coreshop-margin-bottom-5 coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-bg-white">
<u-grid :col="limit" :border="false">
<u-grid-item v-for="(item, index) in ListData" :key="index" @click="showSliderInfo(item.linkType, item.linkValue)">
<view class="coreshop-padding-bottom-10 coreshop-padding-top-10">
<u-icon :name="item.image" width="40" height="40" :label="item.text" :labelSize="13" labelPos="bottom" :top="25" space="10"></u-icon>
</view>
</u-grid-item>
</u-grid>
</view>
</template>
<script>
import { navLinkType } from '@/common/setting/constVarsHelper.js';
export default {
name: "coreshopnavbar",
components: {},
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
ListData: [],
limit: 0,
multiple: 0,
count: 0,
scrollPage: 1,
scrollDot: 0,
}
},
mounted() {
},
created() {
this.ListData = this.coreshopdata.parameters.list;
this.limit = this.coreshopdata.parameters.limit;
},
methods: {
}
}
</script>

View File

@@ -0,0 +1,38 @@
<template>
<view class="coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white" v-if="count > 0">
<u-notice-bar :text="model.text" @click="goNoticeList()"></u-notice-bar>
</view>
</template>
<script>
export default {
name: "coreshopnotice",
components: {
},
props: {
coreshopdata: {
required: true,
}
},
data() {
return {
model: {
text: "",
},
}
},
created() {
var data = this.coreshopdata.parameters.list;
if (data.length > 0) {
this.model.text = data[0].title;
};
},
methods: {
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
}
}
</script>

View File

@@ -0,0 +1,106 @@
<template>
<view>
<block v-for="(item,index) in coreshopdata" :key="index">
<!--搜索修复-->
<coreshopsearch :coreshopdata="item" v-if="item.widgetCode=='search' "></coreshopsearch>
<!--切换-->
<coreshoptabbar :coreshopdata="item" v-if="item.widgetCode=='tabBar' "></coreshoptabbar>
<!--公告修复-->
<coreshopnotice :coreshopdata="item" v-if="item.widgetCode=='notice' "></coreshopnotice>
<!--图片轮播修复-->
<coreshopimgSlide :coreshopdata="item" v-if="item.widgetCode=='imgSlide' "></coreshopimgSlide>
<!--优惠券修复-->
<coreshopcoupon :coreshopdata="item" v-if="item.widgetCode=='coupon' "></coreshopcoupon>
<!--空格修复-->
<coreshopblank :coreshopdata="item" v-if="item.widgetCode=='blank' "></coreshopblank>
<!--多行文本输入区修复-->
<coreshoptextarea :coreshopdata="item" v-if="item.widgetCode=='textarea' "></coreshoptextarea>
<!--视频修复-->
<coreshopvideo :coreshopdata="item" v-if="item.widgetCode=='video' "></coreshopvideo>
<!--图片集修复-->
<coreshopimgWindow :coreshopdata="item" v-if="item.widgetCode=='imgWindow' "></coreshopimgWindow>
<!--图片--修复-->
<coreshopimgSingle :coreshopdata="item" v-if="item.widgetCode=='imgSingle' "></coreshopimgSingle>
<!--商品修复-->
<coreshopgoods :coreshopdata="item" v-if="item.widgetCode=='goods' "></coreshopgoods>
<!--商品选项卡修复-->
<coreshopgoodTabBar :coreshopdata="item" v-if="item.widgetCode=='goodTabBar' "></coreshopgoodTabBar>
<!--文章修复-->
<coreshoparticle :coreshopdata="item" v-if="item.widgetCode=='article' "></coreshoparticle>
<!--文章分类修复-->
<coreshoparticleClassify :coreshopdata="item" v-if="item.widgetCode=='articleClassify' "></coreshoparticleClassify>
<!--宫格自定义导航修复-->
<coreshopnavBar :coreshopdata="item" v-if="item.widgetCode=='navBar' "></coreshopnavBar>
<!--团购修复-->
<coreshopgroupPurchase :coreshopdata="item" v-if="item.widgetCode=='groupPurchase' "></coreshopgroupPurchase>
<!--浏览记录修复-->
<coreshoprecord :coreshopdata="item" v-if="item.widgetCode=='record' "></coreshoprecord>
<!--拼团修复-->
<coreshoppinTuan :coreshopdata="item" v-if="item.widgetCode=='pinTuan' "></coreshoppinTuan>
<!--服务修复-->
<coreshopservice :coreshopdata="item" v-if="item.widgetCode=='service' "></coreshopservice>
<!--弹窗广告-->
<coreshopadpop :coreshopdata="item" v-if="item.widgetCode=='adpop' "></coreshopadpop>
<!--文本内容修复-->
<coreshopContent :coreshopdata="item" v-if="item.widgetCode=='content' "></coreshopContent>
</block>
</view>
</template>
<script>
import coreshopimgSlide from '@/components/coreshop-page/coreshop-imgSlide.vue'
import coreshopsearch from '@/components/coreshop-page/coreshop-search.vue'
import coreshopnotice from '@/components/coreshop-page/coreshop-notice.vue'
import coreshopcoupon from '@/components/coreshop-page/coreshop-coupon.vue'
import coreshopblank from '@/components/coreshop-page/coreshop-blank.vue'
import coreshoptextarea from '@/components/coreshop-page/coreshop-textarea.vue'
import coreshopvideo from '@/components/coreshop-page/coreshop-video.vue'
import coreshopimgWindow from '@/components/coreshop-page/coreshop-imgWindow.vue'
import coreshopimgSingle from '@/components/coreshop-page/coreshop-imgSingle.vue'
import coreshopgoods from '@/components/coreshop-page/coreshop-goods.vue'
import coreshopgoodTabBar from '@/components/coreshop-page/coreshop-goodTabBar.vue'
import coreshoparticle from '@/components/coreshop-page/coreshop-article.vue'
import coreshoparticleClassify from '@/components/coreshop-page/coreshop-articleClassify.vue'
import coreshopnavBar from '@/components/coreshop-page/coreshop-navBar.vue'
import coreshopgroupPurchase from '@/components/coreshop-page/coreshop-groupPurchase.vue'
import coreshoprecord from '@/components/coreshop-page/coreshop-record.vue'
import coreshoppinTuan from '@/components/coreshop-page/coreshop-pinTuan.vue'
import coreshopservice from '@/components/coreshop-page/coreshop-service.vue'
import coreshoptabbar from '@/components/coreshop-page/coreshop-tabbar.vue'
import coreshopadpop from '@/components/coreshop-page/coreshop-adpop.vue'
import coreshopContent from '@/components/coreshop-page/coreshop-content.vue'
export default {
name: 'coreshop-page',
components: {
coreshopimgSlide,
coreshopsearch,
coreshopnotice,
coreshopcoupon,
coreshopblank,
coreshoptextarea,
coreshopvideo,
coreshopimgWindow,
coreshopimgSingle,
coreshopgoods,
coreshopgoodTabBar,
coreshoparticle,
coreshoparticleClassify,
coreshopnavBar,
coreshopgroupPurchase,
coreshoprecord,
coreshoppinTuan,
coreshopservice,
coreshoptabbar,
coreshopadpop,
coreshopContent
},
props: {
coreshopdata: {
default: function () {
return []
}
}
}
}
</script>

View File

@@ -0,0 +1,140 @@
<template>
<!-- 活动商品 -->
<view class="activity-wrap coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-10 coreshop-margin-bottom-5 groupon-card" v-if="count">
<!-- 标题栏 -->
<view class="title-box coreshop-flex coreshop-justify-between coreshop-padding-top-10 coreshop-padding-bottom-10 groupon-title">
<view class="coreshop-flex coreshop-flex-direction coreshop-align-center">
<view class="title-text coreshop-margin-right-10 u-line-1">每日拼团</view>
</view>
<u-icon name="arrow-right-double" size="12" label="查看更多" labelSize="12" labelPos="left" @tap="goPinTuanList()"></u-icon>
</view>
<!-- 活动商品 -->
<scroll-view class="scroll-box" scroll-x scroll-anchoring>
<view class="goods-box coreshop-flex">
<view class="min-goods coreshop-margin-right-6" v-for="mgoods in coreshopdata.parameters.list" :key="mgoods.id" @tap="goPinTuanDetail(mgoods.goodsId,mgoods.id)">
<view class="img-box">
<image class="img" :src="mgoods.goodsImage" mode=""></image>
</view>
<view class="mgoods-card-bottom coreshop-padding-10">
<view class="goods-title coreshop-margin-bottom-5 u-line-1">{{ mgoods.name }}</view>
<view class="price coreshop-margin-bottom-5">{{mgoods.pinTuanPrice}}</view>
<view class="original-price">{{ mgoods.pinTuanPrice + mgoods.discountAmount }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name: "coreshoppinTuan",
props: {
coreshopdata: {
required: false,
}
},
data() {
return {
goodsList: [],
swiperCurrent: 0
};
},
created() {
let that = this;
if (that.coreshopdata.parameters.list.length > 0) {
let arr = that.sortData(that.coreshopdata.parameters.list, 4);
that.goodsList = arr;
}
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
swiperChange(e) {
this.swiperCurrent = e.detail.current;
},
// 数据分层
sortData(oArr, length) {
let arr = [];
let minArr = [];
oArr.forEach(c => {
if (minArr.length === length) {
minArr = [];
}
if (minArr.length === 0) {
arr.push(minArr);
}
minArr.push(c);
});
return arr;
}
},
}
</script>
<style lang="scss" scoped>
.groupon-card { background: linear-gradient(#faecca 20%, #ffffff 30%, #ffffff 100%); }
.groupon-title { background: url($apiFilesUrl+'/static/images/pinTuan/groupon_title_bg.png') no-repeat; background-position: center top; background-size: 100% auto; }
.activity-wrap { background-color: #fff; min-height: 300rpx;
.title-box {
.title-text { font-size: 32rpx; font-weight: bold; color: #333333; }
.more-box {
.more-text { font-size: 22rpx; font-weight: 500; color: #333333; }
.more-icon { font-size: 24rpx; color: #333333; }
}
}
.scroll-box,
.goods-box { height: 380rpx; width: 100%; }
}
// 小商品卡片
.min-goods { width: 220rpx; height: 380rpx; background: #fffaef; box-shadow: 0px 7rpx 8rpx 1rpx rgba(162, 117, 27, 0.24); border-radius: 10rpx;
.img-box { width: 220rpx; height: 220rpx; overflow: hidden; position: relative; border-radius: 10rpx 10rpx 0 0;
.img { width: 220rpx; height: 220rpx; background-color: #ccc; }
}
.mgoods-card-bottom { height: 160rpx; background: url($apiFilesUrl+'/static/images/pinTuan/groupon_goods_bg.png') no-repeat; background-position: bottom center; background-size: 100% 100%; }
.goods-title { font-size: 26rpx; font-weight: 500; color: #000000; width: 180rpx; line-height: 26rpx; }
.price { font-size: 30rpx; font-weight: 500; color: #ff0000;
&::before { content: '¥'; font-size: 24rpx; }
}
.original-price { font-size: 20rpx; font-weight: 500; text-decoration: line-through; color: #c4c4c4; }
.groupon-num-box {
.avatar-box { direction: rtl; unicode-bidi: bidi-override; height: 30rpx;
.avatar-img { width: 30rpx; height: 30rpx; border-radius: 50%; background-color: #f5f5f5; }
}
.groupon-num-text { font-size: 18rpx; font-weight: 500; color: #e9b461; }
}
}
// 大商品卡片
.big-goods { width: 710rpx; min-height: 260rpx; background: #ffffff; box-shadow: 0px 7rpx 8rpx 1rpx #fffaef; border-radius: 20rpx;
.goods-img { width: 220rpx; height: 220rpx; border-radius: 6rpx; }
.card-right { width: 430rpx; height: 100%; }
.goods-title { font-size: 26rpx; font-weight: 600; width: 400rpx; color: #000000; vertical-align: middle;
.title-tag { transform: scale(0.9); }
}
.subtitle-text { font-size: 22rpx; width: 400rpx; font-weight: 500; color: #666666; }
.buy-btn { width: 120rpx; line-height: 50rpx; background: linear-gradient(90deg, #ff6600 0%, #fe832a 100%); border-radius: 25rpx; font-size: 24rpx; font-weight: 500; color: #ffffff; }
.sell-box { background: rgba(#f9efd6, 0.3); border-radius: 16rpx; line-height: 32rpx;
.sell-num { font-size: 20rpx; font-weight: 400; color: #ff6904; }
.hot-icon { font-size: 26rpx; color: #ff6904; margin-right: 8rpx; }
}
.group-num { font-size: 20rpx; font-weight: 500; color: rgba(153, 153, 153, 1); margin-left: 20rpx; }
.price { color: #ff0000; font-weight: 600;
&::before { content: '¥'; font-size: 20rpx; }
}
.origin-price { color: #c4c4c4; font-size: 24rpx; text-decoration: line-through;
&::before { content: '¥'; font-size: 20rpx; }
}
}
</style>

View File

@@ -0,0 +1,124 @@
<template>
<view class="adbrathing" v-show="adbshow" v-bind:class="['adbrathing'+coreshopdata.parameters.style.align,!hideanimation?'pc':hideanimation?'hc':'']" :style="{top:coreshopdata.parameters.style.top+'%'}">
<view class="adbrathing-c coreshop-flex-direction-row">
<view class="adbrathing-l">
<image class="user-head-img" :src="log.avatar" mode="aspectFill"></image>
<view class="user-name">
{{log.nickname}}
</view>
</view>
<view class="adbrathing-r">
{{log.createTime}}{{log.desc}}
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshoprecord",
props: {
coreshopdata: {
// type: Object,
required: true,
},
//记录显示的位置类型
ltype: {
type: String,
required: false,
default: 'home',
},
//记录显示的位置的值
lvalue: {
type: String,
required: false,
default: '0',
}
},
data() {
return {
adbshow: false,
hideanimation: true,
log: {
avatar: '/static/images/common/user_black.png',
nickname: '',
desc: '',
ctime: '',
},
times: {},//定时器
};
},
methods: {
//隐藏
hideLog() {
var _this = this;
_this.times = setInterval(function () {
_this.adbshow = !_this.adbshow;
_this.hideanimation = !_this.hideanimation;
clearInterval(_this.times);
_this.times = setInterval(function () {
_this.getRecod();
}, 5000);
}, 3000)
},
//获取日志
getRecod() {
var _this = this;
if (_this.times != {}) {
clearInterval(_this.times);
}
var data = {
type: _this.ltype,
value: _this.lvalue,
};
uni.request({
url: this.$globalConstVars.apiBaseUrl + '/Api/Page/GetRecod',
data: data,
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
method: 'POST',
success: (response) => {
var res = response.data;
if (res.status == true) {
if (res.data) {
_this.log = res.data;
_this.adbshow = true;
_this.hideanimation = false;
_this.hideLog();
}
}
}
});
}
},
mounted() {
this.getRecod();
}
}
</script>
<style lang="scss" scoped>
.adbrathing { position: fixed; height: 35px; background-color: rgba(0,0,0,.5); border-radius: 5px; padding: 5px; z-index: 666;
.adbrathing-c { width: 100%; height: 100%; overflow: hidden; color: #fff; font-size: 12px;
.adbrathing-l { display: inline-block; height: 100%; float: left; overflow: hidden;
.user-head-img { width: 25px; height: 25px; border-radius: 50%; float: left; }
.user-name { float: left; display: inline-block; height: 100%; line-height: 25px; margin: 0 2px 0 5px; max-width: 60px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
.adbrathing-r { float: left; height: 100%; display: inline-block; line-height: 25px; }
}
}
.pc { animation: showcenter .55s; }
.hc { animation: hidecenter .55s; }
@keyframes showcenter {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes hidecenter {
0% { opacity: 1; }
100% { opacity: 0; }
}
</style>

View File

@@ -0,0 +1,59 @@
<template>
<!-- 搜索组件宽度自适应于外层 -->
<view class="coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-10 coreshop-padding-top-10 coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white" v-bind:class="coreshopdata.parameters.style">
<u-toast ref="uToast"></u-toast>
<u-search :placeholder="coreshopdata.parameters.keywords" v-model="keyword" shape="square" :show-action="true" action-text="搜索" @custom="goSearch" @search="goSearch"></u-search>
</view>
</template>
<script>
export default {
name: "coreshopsearch",
props: {
coreshopdata: {
required: true,
}
},
data() {
return {
keyword: '',
searchTop: 0,
scrollTop: 0,
searchFixed: this.$store.state.searchFixed || false,
};
},
created() {
//#ifdef H5
this.$nextTick(() => {
this.searchTop = this.$refs.searchBar.$el.offsetTop;
})
// #endif
this.searchStyle()
},
mounted() {
// #ifdef H5
window.addEventListener('scroll', this.handleScroll)
// #endif
},
methods: {
searchStyle() {
this.$store.commit('searchStyle', this.coreshopdata.parameters.style)
// console.log(this.data.parameters.style)
},
change(value) {
// 搜索框内容变化时会触发此事件value值为输入框的内容
//console.log(value);
},
goSearch() {
if (this.keyword != '') {
this.$u.route('/pages/category/list/list?key=' + this.keyword);
} else {
this.$refs.uToast.show({ message: '请输入查询关键字', type: 'warning', })
}
},
handleScroll() {
this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
this.scrollTop >= this.searchTop ? this.searchFixed = true : this.searchFixed = false;
},
},
}
</script>

View File

@@ -0,0 +1,72 @@
<template>
<view>
<view class="coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-top-10 coreshop-margin-bottom-10">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" @click="goServicesList()" sub-title="查看更多"></coreshop-section>
</view>
<view class="coreshop-margin-left-15 coreshop-margin-right-15" v-if="coreshopdata.parameters.list && count">
<view class="img-list-item coreshop-flex-direction-row" v-if="item.id !== 'undefined' && item.id" v-for="(item, key) in coreshopdata.parameters.list" :key="key" @click="goServicesDetail(item.id)">
<view class="img-list-item-l">
<u--image :src="item.thumbnail" :index="item.id" width="100px" height="100px"></u--image>
</view>
<view class="img-list-item-r">
<view class="coreshop-font-14 coreshop-text-bold u-line-1">{{item.title}}</view>
<view class="coreshop-font-12 u-line-2 coreshop-margin-top-10 coreshop-margin-bottom-10">{{item.description}}</view>
<view class="item-c coreshop-flex coreshop-justify-between">
<view class="red-price coreshop-justify-between">
{{item.money}}
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between">
<view class="red-price coreshop-font-15 coreshop-flex-direction-row" v-if="item.status == 0 && item.lastTime > 0">
<u-count-down :time="item.lastTime" format="HH:mm:ss"></u-count-down>
</view>
<view class="coreshop-font-12 red-price" v-if="item.status == 3">已结束</view>
<view class="coreshop-font-12 red-price" v-if="item.status == 2">即将开始</view>
<u-icon name="shopping-cart" color="#2979ff" size="25" class="btnCart"></u-icon>
</view>
</view>
</view>
</view>
<view class="img-list-item" v-if="!item.id" v-for="(item, key) in coreshopdata.parameters.list" :key="key">
<image class="img-list-item-l" :src="item.image== '/images/empty-banner.png'? '/static/images/common/empty-banner.png':item.image" mode='aspectFill'></image>
<view class="img-list-item-r">
<view class="goods-name list-goods-name">{{item.name}}</view>
<view class="item-c">
<view class=" red-price">{{item.price}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "coreshopservice",
props: {
coreshopdata: {
// type: Array,
required: false,
}
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
},
}
</script>
<style lang="scss" scoped>
.img-list-item { border-radius: 8px; margin: 2.5px 2.5px 10px 2.5px; background-color: #ffffff; padding: 5px; position: relative; overflow: hidden;
.img-list-item-l { width: 100px; height: 100px; display: inline-block; float: left; }
.img-list-item-r { width: calc(100% - 120px); display: inline-block; margin-left: 7.5px; float: left; position: relative;
.item-c { width: 100%; margin-top: 0;
.red-price { color: #FF7159 !important; }
.btnCart { float: right; }
}
}
}
</style>

View File

@@ -0,0 +1,82 @@
<template>
<view class="">
<view class="coreshop-tabbar coreshop-margin-bottom-10" ref="tabBar">
<scroll-view scroll-x='true' class="tabbar-list">
<view class="tabbar-item" v-for="(item, index) in coreshopdata.parameters.list" :key="index" @click="showSliderInfo(item.linkType, item.linkValue)">
{{item.text}}
<view class="active-tabbar"></view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name: "coreshopTabbar",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
searchTop: 0,
scrollTop: 0,
tabbarFixed: false
};
},
created() {
//#ifdef H5
this.$nextTick(() => {
this.searchTop = this.$refs.tabBar.$el.offsetTop - 52;
})
// #endif
this.searchStyle()
},
mounted() {
// #ifdef H5
window.addEventListener('scroll', this.handleScroll)
// #endif
},
methods: {
searchStyle() {
this.$store.commit('searchStyle', this.coreshopdata.parameters.style)
// console.log(this.data.parameters.style)
},
handleScroll() {
this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
this.scrollTop >= this.searchTop ? this.tabbarFixed = true : this.tabbarFixed = false;
},
goClassify() {
this.$u.route({ type: 'switchTab', url: '/pages/category/index/index' });
},
},
onPageScroll() {
var _this = this;
// #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
const query = uni.createSelectorQuery().in(this)
query.select('.search').boundingClientRect(function (res) {
if (res.top < 0) {
_this.tabbarFixed = true;
} else {
_this.tabbarFixed = false;
}
}).exec()
// #endif
}
}
</script>
<style lang="scss" scoped>
.tabbar-list { padding: 5px 0; background-color: #fff; white-space: nowrap; width: 100%;
.tabbar-item { display: inline-block; padding: 5px 10px;
.active-tabbar { display: none; }
}
}
.tabbar-item:first-of-type { color: #FF7159;
.active-tabbar { display: block; width: 100%; height: 2px; margin: 5px auto 0; background-color: #FF7159; }
}
.tabbar-fixed { position: fixed; top: 52px; transition: all .5s; z-index: 999; background-color: #fff; width: 100%; }
</style>

View File

@@ -0,0 +1,39 @@
<template>
<view class="textarea coreshop-margin-left-10 coreshop-margin-right-10 coreshop-padding-10">
<coreshopContent :content="coreshopdata.parameters.value" v-if="coreshopdata.parameters.value"></coreshopContent>
</view>
</template>
<script>
import coreshopContent from '@/components/coreshop-page/coreshop-content.vue'//视频和文本解析组件
export default {
components: {
coreshopContent
},
name: "coreshoptextarea",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
created() {
},
onLoad() {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.textarea { background-color: #fff;
p {
img { width: 100% !important; background-color: #000; }
}
div { background-color: #000; }
}
.clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
</style>

View File

@@ -0,0 +1,42 @@
<template>
<view class="video coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10">
<video class="videoCT" id="myVideo" :src="coreshopdata.parameters.list[0].url" :autoplay="autoplay" :poster="coreshopdata.parameters.list[0].image"></video>
</view>
</template>
<script>
export default {
name: "coreshopvideo",
props: {
coreshopdata: {
type: Object,
required: true,
}
},
data() {
return {
autoplay: false
}
},
created() {
if (this.coreshopdata.parameters.autoplay == 'true' || this.coreshopdata.parameters.autoplay == true) {
this.autoplay = true;
}
},
onReady: function (res) {
// #ifndef MP-ALIPAY
this.videoContext = uni.createVideoContext('myVideo')
// #endif
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.video { border-radius: 8px;
.videoCT { width: 100%; min-height: 100px; }
}
</style>

View File

@@ -0,0 +1,134 @@
<template>
<view class="coreshop-section">
<view class="coreshop-section__title" :style="{
fontWeight: bold ? 'bold' : 'normal',
color: color,
fontSize: fontSize + 'px',
paddingLeft: showLine ? (fontSize * 0.7) + 'px' : 0
}" :class="{
'coreshop-section--line': showLine
}">
<view class="coreshop-section__title__icon-wrap coreshop-flex" :style="[lineStyle]" v-if="showLine">
<u-icon top="0" name="column-line" :size="fontSize * 1.25" bold :color="lineColor ? lineColor : color"></u-icon>
</view>
<text class="coreshop-flex coreshop-section__title__text">{{title}}</text>
</view>
<view class="coreshop-section__right-info" v-if="right || $slots.right" :style="{
color: subColor
}" @tap="rightClick">
<slot name="right" v-if="$slots.right" />
<block v-else>
{{subTitle}}
<view class="coreshop-section__right-info__icon-arrow u-flex" v-if="arrow">
<u-icon name="arrow-right" size="14" :color="subColor"></u-icon>
</view>
</block>
</view>
</view>
</template>
<script>
/**
* section 查看更多
* @description 该组件一般用于分类信息有很多,但是限于篇幅只能列出一部分,让用户通过"查看更多"获得更多信息的场景,实际效果见演示。
* @tutorial https://www.uviewui.com/components/section.html
* @property {String} title 左边主标题
* @property {String} sub-title 右边副标题(默认更多)
* @property {Boolean} right 是否显示右边的内容默认true
* @property {Boolean} showLine 是否显示左边的竖条默认true
* @property {Boolean} arrow 是否显示右边箭头默认true
* @property {String Number} font-size 主标题的字体大小默认28
* @property {Boolean} bold 主标题是否加粗默认true
* @property {String} color 主标题颜色(默认#303133
* @event {Function} click 组件右侧的内容被点击时触发,用于跳转"更多"
* @example <coreshop-section title="今日热门" :right="false"></coreshop-section>
*/
export default {
name: "coreshop-section",
props: {
// 标题信息
title: {
type: String,
default: ''
},
// 右边副标题内容
subTitle: {
type: String,
default: '更多'
},
// 是否显示右边的内容
right: {
type: Boolean,
default: true
},
fontSize: {
type: [Number, String],
default: 28
},
// 主标题是否加粗
bold: {
type: Boolean,
default: true
},
// 主标题的颜色
color: {
type: String,
default: '#303133'
},
// 右边副标题的颜色
subColor: {
type: String,
default: '#909399'
},
// 是否显示左边的竖条
showLine: {
type: Boolean,
default: true
},
// 左边竖线的颜色
lineColor: {
type: String,
default: ''
},
// 是否显示右边箭头
arrow: {
type: Boolean,
default: true
},
},
computed: {
// 左边竖条的样式
lineStyle() {
// 由于安卓和iOS的需要稍微调整绝对定位的top值才能让左边的竖线和右边的文字垂直居中
return {
// 由于竖线为字体图标,具有比实际线宽更宽的宽度,所以也需要根据字体打下动态调整
left: -(Number(this.fontSize) * 0.9) / 2 + 'px',
top: -(Number(this.fontSize) * (this.$u.os() == 'ios' ? 0.14 : 0.15)) / 2 + 'px',
}
}
},
methods: {
rightClick() {
this.$emit('click');
}
}
}
</script>
<style lang="scss" scoped>
.coreshop-section { /* #ifndef APP-NVUE */ display: flex; flex-direction: row; /* #endif */ justify-content: space-between; align-items: center; width: 100%;
&__title { position: relative; font-size: 14px; padding-left: 10px; /* #ifndef APP-NVUE */ display: flex; flex-direction: row; /* #endif */ align-items: center;
&__icon-wrap { position: absolute; }
&__text { line-height: 1; }
}
&__right-info { color: $u-tips-color; font-size: 13px; /* #ifndef APP-NVUE */ display: flex; flex-direction: row; /* #endif */ align-items: center;
&__icon-arrow { margin-left: 3px; }
}
}
</style>

View File

@@ -0,0 +1,360 @@
<template>
<view class="u-select">
<u-popup :maskCloseAble="maskCloseAble" mode="bottom" :show="value" :safeAreaInsetBottom="safeAreaInsetBottom" @close="close" :zIndex="uZIndex">
<view class="u-select">
<view class="u-select__header" @touchmove.stop.prevent="">
<view class="u-select__header__cancel u-select__header__btn"
:style="{ color: cancelColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@tap="getResult('cancel')">
{{cancelText}}
</view>
<view class="u-select__header__title">
{{title}}
</view>
<view class="u-select__header__confirm u-select__header__btn"
:style="{ color: moving ? cancelColor : confirmColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@touchmove.stop=""
@tap.stop="getResult('confirm')">
{{confirmText}}
</view>
</view>
<view class="u-select__body">
<picker-view @change="columnChange" class="u-select__body__picker-view" :value="defaultSelector" @pickstart="pickstart" @pickend="pickend">
<picker-view-column v-for="(item, index) in columnData" :key="index">
<view class="u-select__body__picker-view__item" v-for="(item1, index1) in item" :key="index1">
<view class="u-line-1">{{ item1[labelName] }}</view>
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
/**
* select 列选择器
* @description 此选择器用于单列,多列,多列联动的选择场景。(从1.3.0版本起不建议使用Picker组件的单列和多列模式Select组件是专门为列选择而构造的组件更简单易用。)
* @tutorial http://uviewui.com/components/select.html
* @property {String} mode 模式选择,"single-column"-单列模式,"mutil-column"-多列模式,"mutil-column-auto"-多列联动模式
* @property {Array} list 列数据,数组形式,见官网说明
* @property {Boolean} v-model 布尔值变量,用于控制选择器的弹出与收起
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {String} cancel-color 取消按钮的颜色(默认#606266
* @property {String} confirm-color 确认按钮的颜色(默认#2979ff)
* @property {String} confirm-text 确认按钮的文字
* @property {String} cancel-text 取消按钮的文字
* @property {String} default-value 提供的默认选中的下标,见官网说明
* @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
* @property {String Number} z-index 弹出时的z-index值(默认10075)
* @property {String} value-name 自定义list数据的value属性名 1.3.6
* @property {String} label-name 自定义list数据的label属性名 1.3.6
* @property {String} child-name 自定义list数据的children属性名只对多列联动模式有效 1.3.7
* @event {Function} confirm 点击确定按钮,返回当前选择的值
* @example <u-select v-model="show" :list="list"></u-select>
*/
export default {
props: {
// 列数据
list: {
type: Array,
default() {
return [];
}
},
// 是否显示边框
border: {
type: Boolean,
default: true
},
// 通过双向绑定控制组件的弹出与收起
value: {
type: Boolean,
default: false
},
// "取消"按钮的颜色
cancelColor: {
type: String,
default: '#606266'
},
// "确定"按钮的颜色
confirmColor: {
type: String,
default: '#2979ff'
},
// 弹出的z-index值
zIndex: {
type: [String, Number],
default: 0
},
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// 是否允许通过点击遮罩关闭Picker
maskCloseAble: {
type: Boolean,
default: true
},
// 提供的默认选中的下标
defaultValue: {
type: Array,
default() {
return [0];
}
},
// 模式选择single-column-单列mutil-column-多列mutil-column-auto-多列联动
mode: {
type: String,
default: 'single-column'
},
// 自定义value属性名
valueName: {
type: String,
default: 'value'
},
// 自定义label属性名
labelName: {
type: String,
default: 'label'
},
// 自定义多列联动模式的children属性名
childName: {
type: String,
default: 'children'
},
// 顶部标题
title: {
type: String,
default: ''
},
// 取消按钮的文字
cancelText: {
type: String,
default: '取消'
},
// 确认按钮的文字
confirmText: {
type: String,
default: '确认'
}
},
data() {
return {
// 用于列改变时,保存当前的索引,下一次变化时比较得出是哪一列发生了变化
defaultSelector: [0],
// picker-view的数据
columnData: [],
// 每次队列发生变化时,保存选择的结果
selectValue: [],
// 上一次列变化时的index
lastSelectIndex: [],
// 列数
columnNum: 0,
// 列是否还在滑动中,微信小程序如果在滑动中就点确定,结果可能不准确
moving: false
};
},
watch: {
// 在select弹起的时候重新初始化所有数据
value: {
immediate: true,
handler(val) {
if (val) setTimeout(() => this.init(), 10);
}
},
},
computed: {
uZIndex() {
// 如果用户有传递z-index值优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
},
methods: {
// 标识滑动开始,只有微信小程序才有这样的事件
pickstart() {
// #ifdef MP-WEIXIN
this.moving = true;
// #endif
},
// 标识滑动结束
pickend() {
// #ifdef MP-WEIXIN
this.moving = false;
// #endif
},
init() {
this.setColumnNum();
this.setDefaultSelector();
this.setColumnData();
this.setSelectValue();
},
// 获取默认选中列下标
setDefaultSelector() {
// 如果没有传入默认选中的值生成长度为columnNum用0填充的数组
this.defaultSelector = this.defaultValue.length == this.columnNum ? this.defaultValue : Array(this.columnNum).fill(0);
this.lastSelectIndex = this.$u.deepClone(this.defaultSelector);
},
// 计算列数
setColumnNum() {
// 单列的列数为1
if (this.mode == 'single-column') this.columnNum = 1;
// 多列时this.list数组长度就是列数
else if (this.mode == 'mutil-column') this.columnNum = this.list.length;
// 多列联动时通过历遍this.list的第一个元素得出有多少列
else if (this.mode == 'mutil-column-auto') {
let num = 1;
let column = this.list;
// 只要有元素并且第一个元素有children属性继续历遍
while (column[0][this.childName]) {
column = column[0] ? column[0][this.childName] : {};
num++;
}
this.columnNum = num;
}
},
// 获取需要展示在picker中的列数据
setColumnData() {
let data = [];
this.selectValue = [];
if (this.mode == 'mutil-column-auto') {
// 获得所有数据中的第一个元素
let column = this.list[this.defaultSelector.length ? this.defaultSelector[0] : 0];
// 通过循环所有的列数,再根据设定列的数组,得出当前需要渲染的整个列数组
for (let i = 0; i < this.columnNum; i++) {
// 第一列默认为整个list数组
if (i == 0) {
data[i] = this.list;
column = column[this.childName];
} else {
// 大于第一列时,判断是否有默认选中的,如果没有就用该列的第一项
data[i] = column;
column = column[this.defaultSelector[i]][this.childName];
}
}
} else if (this.mode == 'single-column') {
data[0] = this.list;
} else {
data = this.list;
}
this.columnData = data;
},
// 获取默认选中的值如果没有设置defaultValue就默认选中每列的第一个
setSelectValue() {
let tmp = null;
for (let i = 0; i < this.columnNum; i++) {
tmp = this.columnData[i][this.defaultSelector[i]];
let data = {
value: tmp ? tmp[this.valueName] : null,
label: tmp ? tmp[this.labelName] : null
};
// 判断是否存在额外的参数,如果存在,就返回
if (tmp && tmp.extra) data.extra = tmp.extra;
this.selectValue.push(data)
}
},
// 列选项
columnChange(e) {
let index = null;
let columnIndex = e.detail.value;
// 由于后面是需要push进数组的所以需要先清空数组
this.selectValue = [];
if (this.mode == 'mutil-column-auto') {
// 对比前后两个数组,寻找变更的是哪一列,如果某一个元素不同,即可判定该列发生了变化
this.lastSelectIndex.map((val, idx) => {
if (val != columnIndex[idx]) index = idx;
});
this.defaultSelector = columnIndex;
for (let i = index + 1; i < this.columnNum; i++) {
// 当前变化列的下一列的数据需要获取上一列的数据同时需要指定是上一列的第几个的children再往后的
// 默认是队列的第一个为默认选项
this.columnData[i] = this.columnData[i - 1][i - 1 == index ? columnIndex[index] : 0][this.childName];
// 改变的列之后的所有列,默认选中第一个
this.defaultSelector[i] = 0;
}
// 在历遍的过程中可能由于上一步修改this.columnData导致产生连锁反应程序触发columnChange会有多次调用
// 只有在最后一次数据稳定后的结果是正确的此前的历遍中可能会产生undefined故需要判断
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
// 判断是否有需要额外携带的参数
if (data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
})
// 保存这一次的结果,用于下次列发生变化时作比较
this.lastSelectIndex = columnIndex;
} else if (this.mode == 'single-column') {
let data = this.columnData[0][columnIndex[0]];
// 初始默认选中值
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
// 判断是否有需要额外携带的参数
if (data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
} else if (this.mode == 'mutil-column') {
// 初始默认选中值
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
// 初始默认选中值
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
// 判断是否有需要额外携带的参数
if (data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
})
}
},
close() {
this.$emit('input', false);
},
// 点击确定或者取消
getResult(event = null) {
// #ifdef MP-WEIXIN
if (this.moving) return;
// #endif
if (event) this.$emit(event, this.selectValue);
this.close();
},
selectHandler() {
this.$emit('click');
}
}
};
</script>
<style scoped lang="scss">
.u-select {
&__action { position: relative; line-height: $u-form-item-height; height: $u-form-item-height;
&__icon { position: absolute; right: 20rpx; top: 50%; transition: transform .4s; transform: translateY(-50%); z-index: 1;
&--reverse { transform: rotate(-180deg) translateY(50%); }
}
}
&__hader {
&__title { color: $u-content-color; }
}
&--border { border-radius: 6rpx; border-radius: 4px; border: 1px solid $u-form-item-border-color; }
&__header { display: flex; align-items: center; justify-content: space-between; height: 80rpx; padding: 0 40rpx; }
&__body { width: 100%; height: 500rpx; overflow: hidden; background-color: #fff;
&__picker-view { height: 100%; box-sizing: border-box;
&__item { display: flex; align-items: center; justify-content: center; font-size: 32rpx; color: $u-main-color; padding: 0 8rpx; }
}
}
}
</style>

View File

@@ -0,0 +1,130 @@
<template>
<view class="coreshop-share-Box">
<u-toast ref="uToast" />
<view class="coreshop-share-pop">
<view class="coreshop-share-item">
<button class="coreshop-btn" open-type="share">
<u-icon label="分享给好友" labelPos="bottom" size="40" name="/static/images/common/share-friend.png"></u-icon>
</button>
</view>
<view class="coreshop-share-item">
<button class="coreshop-btn" @click="$u.throttle(createPoster, 500)">
<u-icon label="生成海报" labelPos="bottom" size="40" name="/static/images/common/share-poster.png"></u-icon>
</button>
</view>
</view>
<view class="coreshop-bottomBox">
<button class="coreshop-btn coreshop-btn-w coreshop-btn-square" @click="close()">关闭</button>
</view>
</view>
</template>
<script>
export default {
props: {
// 商品id
goodsId: {
type: Number,
default: 0
},
// 分享的图片
shareImg: {
type: String,
default: ''
},
// 分享标题
shareTitle: {
type: String,
default: ''
},
// 分享内容
shareContent: {
type: String,
default: ''
},
// 分享链接
shareHref: {
type: String,
default: ''
},
//分享类型
shareType: {
type: Number,
default: 1
},
//拼团id
groupId: {
type: Number,
default: 0
},
//拼团的团队id
teamId: {
type: Number,
default: 0
}
},
data() {
return {
providerList: [] // 分享通道 包含生成海报
}
},
mounted() {
},
methods: {
// 关闭弹出层
close() {
this.$emit('close')
},
// 生成海报
createPoster() {
let data = {};
if (this.shareType == 1) {
//商品
data = {
page: 2, //商品
url: '/pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 3,//海报
client: 6
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == 3) {
//拼团
data = {
page: 3, //商品
url: '/pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 3,//海报
client: 6
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
this.$u.api.share(data).then(res => {
if (res.status) {
this.close()
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
} else {
this.$u.toast(res.msg)
}
});
},
// 分享操作
async share(e) {
}
}
}
</script>

View File

@@ -0,0 +1,264 @@
<template>
<view class="coreshop-share-Box">
<u-toast ref="uToast" />
<view class="coreshop-share-pop">
<view class="coreshop-share-item"
v-for="(item, index) in providerList"
:key="index"
@click="clickHandler(item)">
<image :src="item.img" mode=""></image>
<view class="">{{ item.name }}</view>
</view>
</view>
<view class="coreshop-bottomBox">
<button class="coreshop-btn coreshop-btn-w coreshop-btn-square" @click="close()">关闭</button>
</view>
</view>
</template>
<script>
export default {
props: {
// 商品id
goodsId: {
type: Number,
default: 0
},
// 分享的图片
shareImg: {
type: String,
default: ''
},
// 分享标题
shareTitle: {
type: String,
default: ''
},
// 分享内容
shareContent: {
type: String,
default: ''
},
// 分享链接
shareHref: {
type: String,
default: ''
},
//分享类型
shareType: {
type: Number,
default: 1
},
//拼团id
groupId: {
type: Number,
default: 0
},
//拼团的团队id
teamId: {
type: Number,
default: 0
}
},
data() {
return {
providerList: [] // 分享通道 包含生成海报
}
},
mounted() {
/**
*
* H5+ 获取分享通道
*
*/
uni.getProvider({
service: 'share',
success: (e) => {
let data = []
for (let i = 0; i < e.provider.length; i++) {
switch (e.provider[i]) {
case 'weixin':
data.push({
name: '分享到微信好友',
cate: 'share',
id: 'weixin',
img: '/static/images/common/share-wechat.png',
sort: 0
})
data.push({
name: '分享到微信朋友圈',
cate: 'share',
id: 'weixin',
type: 'WXSenceTimeline',
img: '/static/images/common/share--wechat-friends.png',
sort: 1
})
break;
case 'qq':
data.push({
name: '分享到QQ',
cate: 'share',
id: 'qq',
img: '/static/images/common/share-qq.png',
sort: 3
})
break;
default:
break;
}
}
data.push({
name: '生成海报',
cate: 'poster',
id: 'poster',
img: '/static/images/common/share-poster.png',
sort: 5
})
this.providerList = data.sort((x, y) => {
return x.sort - y.sort
});
},
fail: (e) => {
// console.log('获取分享通道失败', e)
}
});
},
methods: {
// 关闭弹出层
close() {
this.$emit('close')
},
// 点击操作
clickHandler(e) {
if (e.cate === 'poster') {
this.createPoster()
} else {
// 去分享
this.share(e)
}
},
// 生成海报
createPoster() {
let data = {};
if (this.shareType == 1) {
//商品
data = {
page: 2, //商品
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == 3) {
//拼团
data = {
page: 3, //商品
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
this.$u.api.share(data).then(res => {
if (res.status) {
this.close()
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
} else {
this.$u.toast(res.msg)
}
});
},
// 分享操作
async share(e) {
let shareOPtions = {
provider: e.id,
scene: e.type && e.type === 'WXSenceTimeline' ? 'WXSenceTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面“WXSenceTimeline”分享到朋友圈“WXSceneFavorite”分享到微信收藏
type: this.shareType,
success: (e) => {
uni.showModal({
content: '分享成功',
showCancel: false
})
},
fail: (e) => {
uni.showModal({
content: e.errMsg,
showCancel: false
})
},
complete: function () {
// console.log('分享操作结束!')
}
}
shareOPtions.summary = this.shareContent ? this.shareContent : ''
shareOPtions.imageUrl = this.shareImg ? this.shareImg : ''
shareOPtions.title = this.shareTitle ? this.shareTitle : ''
shareOPtions.href = this.shareHref ? this.shareHref : ''
if (shareOPtions.type === 0 && plus.os.name === 'iOS') {//如果是图文分享且是ios平台则压缩图片
shareOPtions.imageUrl = await this.compress()
}
if (shareOPtions.type === 1 && shareOPtions.provider === 'qq') {//如果是分享文字到qq则必须加上href和title
shareOPtions.href = this.shareHref
shareOPtions.title = this.shareTitle
}
uni.share(shareOPtions);
},
// 压缩图片 图文分享要求分享图片大小不能超过20Kb
compress() {
// console.log('开始压缩');
let img = this.shareImg;
return new Promise((res) => {
var localPath = plus.io.convertAbsoluteFileSystem(img.replace('file://', ''));
// console.log('after' + localPath);
// 压缩size
plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
entry.file((file) => {// 可通过entry对象操作图片
// console.log('getFile:' + JSON.stringify(file));
if (file.size > 20480) {// 压缩后size 大于20Kb
plus.zip.compressImage({
src: img,
dst: img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG'),
width: '10%',
height: '10%',
quality: 1,
overwrite: true
}, (event) => {
// console.log('success zip****' + event.size);
let newImg = img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG');
res(newImg);
}, function (error) {
uni.showModal({
content: '分享图片太大,需要请重新选择图片!',
showCancel: false
})
});
}
});
}, (e) => {
// console.log('Resolve file URL failed: ' + e.message);
uni.showModal({
content: '分享图片太大,需要请重新选择图片!',
showCancel: false
})
});
})
}
}
}
</script>

View File

@@ -0,0 +1,185 @@
<template>
<view class="coreshop-share-Box">
<u-toast ref="uToast" />
<view class="coreshop-share-pop">
<view class="coreshop-share-item" @click="copyUrl()" v-show="!ifwx">
<button class="coreshop-btn">
<u-icon label="复制链接" labelPos="bottom" size="40" name="/static/images/common/share-friend.png"></u-icon>
</button>
</view>
<view class="coreshop-share-item" @click="$u.throttle(createPoster, 500)">
<button class="coreshop-btn">
<u-icon label="生成海报" labelPos="bottom" size="40" name="/static/images/common/share-poster.png"></u-icon>
</button>
</view>
</view>
<view class="coreshop-bottomBox">
<button class="coreshop-btn coreshop-btn-w coreshop-btn-square" @click="close()">关闭</button>
</view>
</view>
</template>
<script>
import { h5Url } from '@/common/setting/constVarsHelper.js'
export default {
props: {
// 商品id
goodsId: {
type: Number,
default: 0
},
// 分享的图片
shareImg: {
type: String,
default: ''
},
// 分享标题
shareTitle: {
type: String,
default: ''
},
// 分享内容
shareContent: {
type: String,
default: ''
},
// 分享链接
shareHref: {
type: String,
default: ''
},
//分享类型
shareType: {
type: Number,
default: 1
},
//拼团id
groupId: {
type: Number,
default: 0
},
//拼团的团队id
teamId: {
type: Number,
default: 0
},
ifwx: {
type: Boolean
}
},
mounted() {
/**
*
* H5端分享两种 (微信浏览器内引导用户去分享, 其他浏览器)
*
*/
},
methods: {
// 关闭弹出层
close() {
this.$emit('close')
},
// 生成海报
createPoster() {
let data = {};
if (this.shareType == 1) {
//商品
data = {
page: 2, //商品
url: h5Url + 'pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 3,//海报
client: 1
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == 3) {
//拼团
data = {
page: 3, //商品
url: h5Url + 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 3,//海报
client: 1
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
this.$u.api.share(data).then(res => {
if (res.status) {
this.close()
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
} else {
this.$u.toast(res.msg)
}
});
},
copyUrl() {
let data = {};
if (this.shareType == 1) {
data = {
page: 2, //商品
url: h5Url + 'pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 1,//URL
client: 1
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == 3) {
data = {
page: 3, //拼团
url: h5Url + 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 1,//URL
client: 1
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
let _this = this;
_this.$u.api.share(data).then(res => {
if (res.status) {
uni.setClipboardData({
data: res.data,
success: function (data) {
_this.$refs.uToast.show({ message: '复制成功', type: 'success' })
},
fail: function (err) {
_this.$u.toast('复制分享URL失败');
}
})
} else {
_this.$u.toast('复制分享URL失败');
}
});
},
// 分享操作
share() {
// h5分享 判断是否是微信浏览器 引导用户完成分享操作
// 其他浏览器的分享
}
}
}
</script>

View File

@@ -0,0 +1,124 @@
<template>
<view class="coreshop-share-Box">
<u-toast ref="uToast" />
<view class="coreshop-share-pop">
<view class="coreshop-share-item">
<button class="coreshop-btn" @click="$u.throttle(createPoster, 500)">
<u-icon label="生成海报" labelPos="bottom" size="40" name="/static/images/common/share-poster.png"></u-icon>
</button>
</view>
</view>
<view class="coreshop-bottomBox">
<button class="coreshop-btn coreshop-btn-w coreshop-btn-square" @click="close()">关闭</button>
</view>
</view>
</template>
<script>
// #ifdef MP-TOUTIAO
import { ttPlatform } from '@/common/setting/constVarsHelper.js'
// #endif
export default {
props: {
// 商品id
goodsId: {
type: Number,
default: 0
},
// 分享的图片
shareImg: {
type: String,
default: ''
},
// 分享标题
shareTitle: {
type: String,
default: ''
},
// 分享内容
shareContent: {
type: String,
default: ''
},
// 分享链接
shareHref: {
type: String,
default: ''
},
//分享类型
shareType: {
type: Number,
default: 1
},
//拼团id
groupId: {
type: Number,
default: 0
},
//拼团的团队id
teamId: {
type: Number,
default: 0
}
},
data() {
return {
providerList: [] // 分享通道 包含生成海报
}
},
mounted() {
},
methods: {
// 关闭弹出层
close() {
this.$emit('close')
},
// 生成海报
createPoster() {
let data = {};
if (this.shareType == 1) {
//商品
data = {
page: 2, //商品
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 3,//海报
client: 4
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == 3) {
//拼团
data = {
page: 3, //商品
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 3,//海报
client: 4
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
this.$u.api.share(data).then(res => {
if (res.status) {
this.close()
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
} else {
this.$u.toast(res.msg)
}
});
}
}
}
</script>

View File

@@ -0,0 +1,203 @@
<template>
<view class="coreshop-share-Box">
<u-toast ref="uToast" />
<view class="coreshop-share-pop">
<view class="coreshop-share-item">
<button class="coreshop-btn" open-type="share">
<u-icon label="分享微信好友" labelPos="bottom" size="40" name="/static/images/common/share-friend.png"></u-icon>
</button>
</view>
<view class="coreshop-share-item">
<button class="coreshop-btn" @click="$u.throttle(createPoster, 500)">
<u-icon label="生成海报" labelPos="bottom" size="40" name="/static/images/common/share-poster.png"></u-icon>
</button>
</view>
</view>
<view class="coreshop-share-bottomBox">
<button class="coreshop-btn coreshop-btn-w coreshop-btn-square" @click="close()">关闭</button>
</view>
</view>
</template>
<script>
export default {
props: {
// 通用传参id
objectId: {
type: Number,
default: 0
},
// 商品id
goodsId: {
type: Number,
default: 0
},
// 分享的图片
shareImg: {
type: String,
default: ''
},
// 分享标题
shareTitle: {
type: String,
default: ''
},
// 分享内容
shareContent: {
type: String,
default: ''
},
// 分享链接
shareHref: {
type: String,
default: ''
},
//分享类型
shareType: {
type: Number,
default: 1
},
//拼团id
groupId: {
type: Number,
default: 0
},
//拼团的团队id
teamId: {
type: Number,
default: 0
}
},
data() {
return {
providerList: [] // 分享通道 包含生成海报
}
},
mounted() {
// console.log("类型:" + this.shareType);
},
methods: {
// 关闭弹出层
close() {
this.$emit('close')
},
// 生成海报
createPoster() {
let data = {};
if (this.shareType == this.$globalConstVars.shareType.index) {
data = {
page: this.shareType, //商品
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId
},
type: 3,//海报
client: 2 //终端
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
} else if (this.shareType == this.$globalConstVars.shareType.pinTuan) {
data = {
page: this.shareType, //拼团
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
teamId: this.teamId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
console.log(data);
}
else if (this.shareType == this.$globalConstVars.shareType.group || this.shareType == this.$globalConstVars.shareType.seckill) {
data = {
page: this.shareType, //拼团
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
console.log(data);
}
else if (this.shareType == this.$globalConstVars.shareType.goods) {
data = {
page: this.shareType, //拼团
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
console.log(data);
}
else if (this.shareType == this.$globalConstVars.shareType.addPinTuan) {
data = {
page: this.shareType, //拼团
url: 'pages/share/jump/jump',
params: {
goodsId: this.goodsId,
groupId: this.groupId,
teamId: this.teamId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
console.log(data);
} else if (this.shareType == this.$globalConstVars.shareType.solitaire) {
data = {
page: this.shareType,
url: 'pages/share/jump/jump',
params: {
id: this.objectId
},
type: 3,//海报
client: 2
}
let userToken = this.$db.get('userToken')
if (userToken) {
data.token = userToken
}
}
this.$u.api.share(data).then(res => {
if (res.status) {
this.close()
if (this.shareType == this.$globalConstVars.shareType.goods) {
//data.posterUrl = encodeURIComponent(res.data);
data.params.posterUrl = res.data;
data.params.shareType = this.shareType;
this.$u.route('/pages/share/shareNewPoster/shareNewPoster' + uni.$u.queryParams(data.params))
} else {
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
}
} else {
this.$u.toast(res.msg)
}
});
}
}
}
</script>

View File

@@ -0,0 +1,67 @@
<template>
<view class="coreshop-padding-bottom-10">
<view class="select-item" v-for="(item, index) in specList" :key="index">
<view class="coreshop-text-black coreshop-margin-10 coreshop-solid-bottom coreshop-padding-bottom-10">{{ index }}</view>
<view class="select-btn">
<button class="sku-btn coreshop-margin-5 coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between" :class="spes.cla" v-for="(spes, key) in item" :key="key" @click="specChangeSpes(index, key)">
<u-avatar :src="spes.image" size="25" class="coreshop-margin-right-10 coreshop-margin-top-10" style="margin-left: -10px;"></u-avatar>
{{ spes.name }}
</button>
</view>
</view>
</view>
</template>
<script>
export default {
name: "spec",
data() {
return {
specList: {}
}
},
props: {
// 默认picker选中项索引
spesData: {
required: true
}
},
created() {
// #ifdef H5 || APP-PLUS
this.specList = JSON.parse(this.spesData);
// #endif
},
watch: {
spesData: function (val) {
console.log('watch');
let d = JSON.parse(val);
this.specList = d;
}
},
methods: {
specChangeSpes(v, k) {
let newData = {
v: v,
k: k
}
this.$emit("changeSpes", newData);
},
changeSpecData() {
this.specList = {};
}
}
}
</script>
<style scoped lang="scss">
.selected { border: 1px solid #ff0000; background-color: #fff5f6; color: #ff0000; }
.not-selected { border: 1px solid #ccc; }
.none { border: 1px dashed #ccc; color: #888; display: none; }
.select-item { padding: 10px 0; border-bottom: 1px solid #f3f3f3;
.select-btn { position: relative; margin-top: 8px; width: 100%; overflow: auto;
.sku-btn { font-size: 12px; border-radius: 5px; float: left; padding: 0 5px;
.u-avatar { top: 5px; }
}
.sku-btn.light { border: 0.5px dashed; }
.sku-btn[disabled] { color: #aaaaaa; }
}
}
</style>

View File

@@ -0,0 +1,97 @@
<template>
<view class="fy-dropdown-floor">
<scroll-view :scroll-y="true" style="height: 220px;">
<view class="fy-dropdown-floor_item" v-for="(item, index) in options" :key="index">
<text class="fy-dropdown-floor_title">{{ item.title }}</text>
<view class="fy-dropdown-floor_ul">
<text :class="['fy-dropdown-floor_li', selected[item.key] == cell.value ? 'fy-dropdown-floor_li__active' : '']" v-for="(cell, cellIndex) in item.list" :key="cellIndex" @click.stop.prevent="handlerCellClick(item.key, cell.value)">{{ cell.text }}</text>
</view>
</view>
</scroll-view>
<view class="fy-dropdown-button-list">
<button class="fy-dropdown-button-item" @click.stop.prevent="handlerCancel"><text class="fy-dropdown-button-text" :style="{color: cancelColor}">取消</text></button>
<text class="fy-dropdown-button-border-left"></text>
<button class="fy-dropdown-button-item" @click.stop.prevent="handlerConfirm"><text class="fy-dropdown-button-text" :style="{color: confirmColor}">确定</text></button>
</view>
</view>
</template>
<script>
export default {
props: {
// 选项数据如果传入了默认slot此参数无效
options: {
type: Array, default () { return [] }
},
cancelColor: {
type: String, default: '#333333'
},
confirmColor: {
type: String, default: '#4cd964'
},
},
data() {
return {
selected: {}, // 存储选中的值
}
},
watch: {
options: {
immediate: true, deep: true,
handler: function(list) {
for (var i = 0, len = list.length; i < len; i++) {
if (list[i]['key']) {
this.$set(this.selected, list[i]['key'], list[i]['default']);
}
}
}
}
},
methods: {
handlerCellClick(key, data) {
this.$set(this.selected, key, data);
},
handlerCancel() {
this.$emit('success', { cancel: true, type: 'column', })
},
handlerConfirm() {
try {
this.$emit('success', { confirm: true, type: 'column', data: JSON.parse(JSON.stringify(this.selected)) })
} catch(err) {
this.$emit('success', { confirm: true, type: 'column', data: JSON.parse(JSON.stringify(this.selected)) })
}
}
},
}
</script>
<style lang="scss" scoped>
// 定义混入指令用于在非nvue环境下的flex定义因为nvue没有display属性会报错
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
// @include vue-flex;
.fy-dropdown-floor{background-color: #ffffff;border-top: 1px solid #f2f2f2;}
.fy-dropdown-floor_item{margin-top: 42rpx;}
.fy-dropdown-floor_title{font-size: 30rpx;color: #333333;padding-bottom: 6rpx;margin-left: 40rpx;font-weight: bold;}
.fy-dropdown-floor_ul{@include vue-flex;align-items: center;flex-wrap: wrap;padding: 0 40rpx 0 20rpx;}
.fy-dropdown-floor_li{border: 1px solid #EFEFEF;height: 52rpx;line-height: 49rpx;text-align: center;padding: 0 28rpx;border-radius: 26rpx;background-color: #EFEFEF;color: #999999;
font-size: 26rpx;margin-left: 20rpx;margin-top: 20rpx;
}
.fy-dropdown-floor_li__active{border-color: #00BCD4;color: #00BCD4;background-color: #ffffff;}
.fy-dropdown-button-list{@include vue-flex;align-items: center;border-top: 1px solid #f6f6f6;}
.fy-dropdown-button-item{@include vue-flex;align-items: center;justify-content: center;flex: 1;height: 100rpx;background-color: #ffffff;border-radius: 0;border-width: 0rpx;
/* #ifndef APP-NVUE */
&::after{border: none;}
/* #endif */
}
.fy-dropdown-button-text{font-size: 30rpx;}
.fy-dropdown-button-border-left{width: 1px;height: 100rpx;background-color: #f2f2f2;transform: scaleX(0.7);}
</style>

View File

@@ -0,0 +1,11 @@
// 定义混入指令用于在非nvue环境下的flex定义因为nvue没有display属性会报错
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
.fy_dropdown-item_scroll{@include vue-flex(column);border-top: 1px solid #f2f2f2;}
.fy_dropdown-item_scroll_cell{@include vue-flex(row);padding: 0 30rpx;justify-content: space-between;align-items: center;border-bottom: 1px solid #f6f6f6;background-color: #FFFFFF;}
.fy_cell_title{font-size: 30rpx;text-align: left;color: #909399;}

View File

@@ -0,0 +1,188 @@
<template>
<view :class="['fy-dropdown-item', 'fy_dropdown-item']" @touchmove.stop.prevent="() => {}" :style="{'background-color': backgroundColor, 'height': activeItemHeight+'rpx'}" v-if="active">
<template v-if="!custom">
<template v-if="type == 'column'">
<Fy-dropdown-column :options="options" @success="onCateSuccess" />
</template>
<template v-else>
<scroll-view :scroll-y="true" class="fy_dropdown-item_scroll" :style="getScrollStyle">
<view v-for="(item, index) in options" :key="index" @click.stop.prevent="cellClick(item.value)" class="fy_dropdown-item_scroll_cell"
:style="{'height': `${itemHeight}rpx`, 'line-height': `${itemHeight}rpx`}"
>
<text class="fy_cell_title" :style="{ color: value == item.value ? activeColor : inactiveColor }">{{ item.label }}</text>
<uni-icons v-if="value == item.value" type="checkmarkempty" size="22" :color="activeColor" />
</view>
</scroll-view>
</template>
</template>
<slot v-else></slot>
</view>
</template>
<script>
import FyDropdownColumn from './fy-dropdown-column.vue';
/**
* dropdown-item 下拉菜单
* @description 该组件一般用于向下展开菜单,同时可切换多个选项卡的场景
* @property {String | Number} v-model 双向绑定选项卡选择值
* @property {Array[Object]} options 选项数据如果传入了默认slot此参数无效
* @property {Boolean} disabled 是否禁用此选项卡默认false
* @property {String | Number} duration 选项卡展开和收起的过渡时间单位ms默认300
* @property {String | Number} height 弹窗下拉内容的高度(内容超出将会滚动)默认auto
* @example <fy-dropdown-item></fy-dropdown-item>
*/
export default {
name: 'fy-dropdown-item',
components: { FyDropdownColumn },
props: {
// 当前选中项的value值
dropdownKey: {
type: String, default: ''
},
// 当前选中项的value值
value: {
type: [Number, String, Array, Object], default: ''
},
// 选项数据如果传入了默认slot此参数无效
options: {
type: Array, default () { return [] }
},
// 是否禁用此菜单项
disabled: {
type: Boolean, default: false
},
backgroundColor: {
type: String, default: 'transparent'
},
maxHeight: {
type: Number, default: 800
},
itemHeight: {
type: Number, default: 90
},
type: {
type: String, default: ''
},
custom: {
type: Boolean, default: false
}
},
data() {
return {
initComponent: false,
activeItemHeight: 300,
active: false, // 当前项是否处于展开状态
// #ifndef MP
parent: null,
// #endif
activeColor: '#00bcd4', // 激活时左边文字和右边对勾图标的颜色
inactiveColor: '#606266', // 未激活时左边文字和右边对勾图标的颜色
}
},
computed: {
getScrollHeight() {
let height = this.options.length * this.itemHeight;
if (height === 0) {
return 300;
} else if(height > this.maxHeight) {
return this.maxHeight;
} else {
return height;
}
},
getScrollStyle() {
return { 'height': `${this.getScrollHeight}rpx` }
}
},
created() {
this.activeItemHeight = 300;
// #ifdef MP
this.parent = null;
// #endif
},
mounted() {
this.init();
},
methods: {
// 获取父组件的参数因为支付宝小程序不支持provide/inject的写法
// this.$parent在非H5中可以准确获取到父组件但是在H5中需要多次this.$parent.$parent.xxx
// 这里默认值等于undefined有它的含义因为最顶层元素(组件)的$parent就是undefined意味着不传name
// 值(默认为undefined),就是查找最顶层的$parent
getParent(name = undefined) {
try {
let parent = this.$parent;
// 通过while历遍这里主要是为了H5需要多层解析的问题
while (parent) {
// 父组件
if (parent.$options && parent.$options.name !== name) {
// 如果组件的name不相等继续上一级寻找
parent = parent.$parent;
} else {
return parent;
}
}
return false;
} catch(err) {
console.log(err);
return false;
}
},
// 将当前px转换为rpx
getScaleToRpx(px) {
try {
const screenWidth = uni.getSystemInfoSync().screenWidth;
const unit = 750 / screenWidth;
return px * unit;
} catch(err) {
return px;
}
},
init() {
try {
let parent = this.getParent.call(this, 'fy-dropdown');
if (!parent) return;
this.parent = parent;
this.active = parent.currentKey == this.dropdownKey;
if (this.initComponent === false) {
parent.childList.push(this); // 供父组件依次更新子组件显示内容
}
if (this.active === false) {
this.initComponent = true;
return;
}
if (this.type === 'cate' || this.type === 'address') {
this.activeItemHeight = this.getScaleToRpx(320) + 100;
} else if(this.type === 'column') {
this.activeItemHeight = this.getScaleToRpx(220) + 100;
} else {
this.activeItemHeight = this.getScrollHeight;
}
this.initComponent = true;
} catch(err) {
console.log(err)
}
},
// cell被点击
cellClick(value) {
// 修改通过v-model绑定的值
this.$emit('input', value);
// 通知父组件(fy-dropdown)收起菜单
this.parent.close();
// 发出事件抛出当前勾选项的value
this.$emit('change', value);
},
onCateSuccess(data) {
this.parent.close();
this.$emit('change', data);
}
}
}
</script>
<style lang="scss">
@import './fy-dropdown-item.scss';
</style>

View File

@@ -0,0 +1,17 @@
// 定义混入指令用于在非nvue环境下的flex定义因为nvue没有display属性会报错
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
.fy_dropdown {width: 750rpx;position: relative;}
.fy_flex{@include vue-flex(row);align-items: center;}
.fy_dropdown__menu{@include vue-flex(row);position: relative;align-items: center;justify-content: space-between;}
.fy_border-bottom{border-bottom: 1px solid #f2f2f2;}
.fy_dropdown__menu_mian{@include vue-flex(row);align-items: center;justify-content: space-between;flex: 1;background-color: #ffffff}
.fy_dropdown__menu__center{@include vue-flex(row);align-items: center;justify-content: space-between;flex: 1;}
.fy_dropdown__menu__item {@include vue-flex(row);justify-content: center;align-items: center;flex: 1;}
.fy_dropdown__menu__item__text{font-size: 28rpx;color: #606266;}
.fy_dropdown__menu__item__arrow{@include vue-flex(row);margin-left: 5rpx;margin-top: 3rpx;transition-property: transform;transition-duration: 0.3s; transform: scale(0.8);align-items: center;}

View File

@@ -0,0 +1,233 @@
<template>
<view class="fy_dropdown" @click.stop.prevent="() => {}">
<view :class="['fy_dropdown__menu', borderBottom ? 'fy_border-bottom' : '']" id="fy_dropdown__menu" :style="{ 'height': `${height}rpx`, 'background-color': backgroundColor }">
<view class="fy_dropdown__menu_mian">
<view class="fy_dropdown__menu__left" :style="{ height: `${height}rpx` }">
<slot name="left"></slot>
</view>
<view class="fy_dropdown__menu__center">
<view class="fy_dropdown__menu__item" :style="{ height: `${height}rpx` }" v-for="(item, index) in menuList" :key="index" @click="handlerMenuClick(index, item.dropdownKey)">
<view class="fy_flex">
<text class="fy_dropdown__menu__item__text" v-if="item.title"
:style="{ color: item.disabled ? '#c0c4cc' : (index === current || highlightIndex == index) ? activeColor : inactiveColor, fontSize: `${titleSize}rpx` }"
>{{item.title}}</text>
<view class="fy_dropdown__menu__item__arrow" :style="{'transform': index === current ? 'scale(0.8) rotate(180deg)' : 'scale(1) rotate(0deg)'}">
<uni-icons :type="menuIcon" :size="menuIconSize" :color="index === current || highlightIndex == index ? activeColor : '#c0c4cc'" />
</view>
</view>
</view>
</view>
<view class="fy_dropdown__menu__right" :style="{ height: `${height}rpx` }">
<slot name="right"></slot>
</view>
</view>
</view>
<uni-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="active" @click="handlerMaskClick" />
<uni-transition :mode-class="['fade']" :styles="transClass" :duration="duration" :show="active">
<view class="fy_dropdown__content__popup">
<slot></slot>
</view>
</uni-transition>
</view>
</template>
<script>
/**
* dropdown 下拉菜单
* @description 该组件一般用于向下展开菜单,同时可切换多个选项卡的场景
* @property {String} active-color 标题和选项卡选中的颜色(默认#00bcd4
* @property {String} inactive-color 标题和选项卡未选中的颜色(默认#606266
* @property {Boolean} close-on-click-mask 点击遮罩是否关闭菜单默认true
* @property {Boolean} close-on-click-self 点击当前激活项标题是否关闭菜单默认true
* @property {String | Number} duration 选项卡展开和收起的过渡时间单位ms默认300
* @property {String | Number} height 标题菜单的高度单位任意默认90
* @property {String | Number} border-radius 菜单展开内容下方的圆角值单位任意默认0
* @property {Boolean} border-bottom 标题菜单是否显示下边框默认false
* @property {String | Number} title-size 标题的字体大小单位任意数值默认为rpx单位默认28
* @event {Function} open 下拉菜单被打开时触发
* @event {Function} close 下拉菜单被关闭时触发
* @example <fy-dropdown></fy-dropdown>
*/
export default {
name: 'fy-dropdown',
props: {
// 菜单标题和选项的激活态颜色
activeColor: {
type: String, default: '#00bcd4'
},
// 菜单标题和选项的未激活态颜色
inactiveColor: {
type: String, default: '#606266'
},
// 点击遮罩是否关闭菜单
closeOnClickMask: {
type: Boolean, default: true
},
// 点击当前激活项标题是否关闭菜单
closeOnClickSelf: {
type: Boolean, default: true
},
// 过渡时间
duration: {
type: [Number, String], default: 300
},
// 标题菜单的高度单位任意数值默认为rpx单位
height: {
type: [Number, String], default: 90
},
// 是否显示下边框
borderBottom: {
type: Boolean, default: false
},
// 标题的字体大小
titleSize: {
type: [Number, String], default: 28
},
// 菜单右侧的icon图标
menuIcon: {
type: String, default: 'arrowdown'
},
// 菜单右侧图标的大小
menuIconSize: {
type: [Number, String], default: 11
},
// 背景色
backgroundColor: {
type: String, default: 'transparent'
},
// 显示的菜单
menuList: {
type: Array, default() { return [] }
},
// h5的导航栏高度
H5NavBarHeight: {
type: Number, default: 44
},
},
data() {
return {
titleHeight: 40,
active: false, // 下拉菜单的状态
// 当前是第几个菜单处于激活状态小程序中此处不能写成false或者""否则后续将current赋值为0
// 无能的TX没有使用===而是使用==判断,导致程序认为前后二者没有变化,从而不会触发视图更新
current: 99999,
currentKey: '',
// 让某个菜单保持高亮的状态
highlightIndex: 99999,
contentHeight: 0, // 内容高度
maskClass: { // 遮罩层样式
'position': 'fixed', 'bottom': 0, 'top': 0, 'left': 0, 'right': 0, 'backgroundColor': 'rgba(0, 0, 0, 0.6)', 'z-index': 999999
},
transClass: { // 内容弹框样式
'position': 'fixed', 'left': 0, 'right': 0, 'top': 0, 'z-index': 999999
},
// #ifndef MP
childList: [],
// #endif
timers: null
}
},
created() {
// #ifdef MP
// 供子组件调用不能在data中声明变量否则在微信小程序会造成循环引用而报错
this.childList = [];
// #endif
},
mounted() {
this.$nextTick(()=>{
this.titleHeight = uni.upx2px(this.height);
})
},
methods: {
// 点击菜单
handlerMenuClick(index, dropdownKey) {
// 判断是否被禁用
if (this.menuList[index].disabled) return;
// 如果点击时的索引和当前激活项索引相同,意味着点击了激活项,需要收起下拉菜单
if (index == this.current && this.closeOnClickSelf) {
return this.close();
}
clearTimeout(this.timers);
this.timers = setTimeout(() => {
this.open(index, dropdownKey);
clearTimeout(this.timers);
}, 0);
},
// 打开下拉菜单
open(index, dropdownKey) {
// 重置高亮索引,否则会造成多个菜单同时高亮
this.highlightIndex = 9999;
// 展开时,设置下拉内容的样式
// 标记展开状态以及当前展开项的索引
this.active = true;
this.current = index;
this.currentKey = dropdownKey;
this.getContentHeight();
this.childList.forEach(item=>item.init())
this.$emit('open', this.current);
},
// 设置下拉菜单处于收起状态
close() {
this.$emit('close', this.current);
// 设置为收起状态同时current归位设置为空字符串
this.active = false;
this.current = 99999;
this.currentKey = '';
// #ifndef MP
this.childList = [];
// #endif
},
// 点击遮罩
handlerMaskClick() {
// 如果不允许点击遮罩,直接返回
if (!this.closeOnClickMask) return;
this.close();
},
// 外部手动设置某个菜单高亮
highlight(index = undefined) {
this.highlightIndex = index !== undefined ? index : 99999;
},
// 获取下拉菜单内容的高度
getContentHeight() {
// #ifdef APP-NVUE
uni.createSelectorQuery().in(this).select('#fy_dropdown__menu').boundingClientRect().exec(rect => {
const data = rect[0];
const top = data.top + this.titleHeight + 'px';
this.maskClass.top = top;
this.transClass.top = top;
});
// #endif
// #ifdef H5
uni.createSelectorQuery().in(this).select('#fy_dropdown__menu').boundingClientRect().exec(rect => {
const data = rect[0];
const top = data.top + this.titleHeight + this.H5NavBarHeight + 'px';
this.maskClass.top = top;
this.transClass.top = top;
});
// #endif
// #ifndef APP-NVUE || H5
uni.createSelectorQuery().in(this).select('.fy_dropdown__menu').boundingClientRect(rect => {
const top = rect.top + this.titleHeight + 'px';
this.maskClass.top = top;
this.transClass.top = top;
}).exec()
// #endif
}
}
}
</script>
<style lang="scss">
@import './fy-dropdown.scss';
</style>

View File

@@ -0,0 +1,52 @@
<template>
<view class="coreshop-bg-white">
<u-swiper :list="swiperItems" :height="swiperHeight" :interval="swiperDuration" keyName="image" @click="taped" circular radius="0"></u-swiper>
</view>
</template>
<script>
export default {
name: "coreshopimgSlide",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
swiperItems: [],
swiperHeight: 130,
swiperDuration: 2500,
};
},
computed: {
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
components: {},
created() {
var data = this.coreshopdata.parameters.list;
for (var i = 0; i < data.length; i++) {
let moder = {
image: data[i].image == '/images/empty-banner.png' ? '/static/images/common/empty-banner.png' : data[i].image,
opentype: 'click',
url: '',
title: data[i].linkType,
linkType: data[i].linkType,
linkValue: data[i].linkValue,
}
this.swiperItems.push(moder);
}
this.swiperHeight = this.coreshopdata.parameters.height;
this.swiperDuration = this.coreshopdata.parameters.duration;
},
watch: {},
methods: {
taped: function (e) {
this.showSliderInfo(this.swiperItems[e].linkType, this.swiperItems[e].linkValue);
},
}
}
</script>

View File

@@ -0,0 +1,110 @@
<template>
<view>
<block v-for="(item,index) in coreshopdata" :key="index">
<!--搜索修复-->
<coreshopsearch :coreshopdata="item" v-if="item.widgetCode=='search' "></coreshopsearch>
<!--切换-->
<coreshoptabbar :coreshopdata="item" v-if="item.widgetCode=='tabBar' "></coreshoptabbar>
<!--公告修复-->
<coreshopnotice :coreshopdata="item" v-if="item.widgetCode=='notice' "></coreshopnotice>
<!--图片轮播修复-->
<coreshopimgSlide :coreshopdata="item" v-if="item.widgetCode=='imgSlide' "></coreshopimgSlide>
<!--优惠券修复-->
<coreshopcoupon :coreshopdata="item" v-if="item.widgetCode=='coupon' "></coreshopcoupon>
<!--空格修复-->
<coreshopblank :coreshopdata="item" v-if="item.widgetCode=='blank' "></coreshopblank>
<!--多行文本输入区修复-->
<coreshoptextarea :coreshopdata="item" v-if="item.widgetCode=='textarea' "></coreshoptextarea>
<!--视频修复-->
<coreshopvideo :coreshopdata="item" v-if="item.widgetCode=='video' "></coreshopvideo>
<!--图片集修复-->
<coreshopimgWindow :coreshopdata="item" v-if="item.widgetCode=='imgWindow' "></coreshopimgWindow>
<!--图片--修复-->
<coreshopimgSingle :coreshopdata="item" v-if="item.widgetCode=='imgSingle' "></coreshopimgSingle>
<!--商品修复-->
<coreshopgoods :coreshopdata="item" v-if="item.widgetCode=='goods' "></coreshopgoods>
<!--商品选项卡修复-->
<coreshopgoodTabBar :coreshopdata="item" v-if="item.widgetCode=='goodTabBar' "></coreshopgoodTabBar>
<!--文章修复-->
<coreshoparticle :coreshopdata="item" v-if="item.widgetCode=='article' "></coreshoparticle>
<!--文章分类修复-->
<coreshoparticleClassify :coreshopdata="item" v-if="item.widgetCode=='articleClassify' "></coreshoparticleClassify>
<!--宫格自定义导航修复-->
<coreshopnavBar :coreshopdata="item" v-if="item.widgetCode=='navBar' "></coreshopnavBar>
<!--团购修复-->
<coreshopgroupPurchase :coreshopdata="item" v-if="item.widgetCode=='groupPurchase' "></coreshopgroupPurchase>
<!--浏览记录修复-->
<coreshoprecord :coreshopdata="item" v-if="item.widgetCode=='record' "></coreshoprecord>
<!--拼团修复-->
<coreshoppinTuan :coreshopdata="item" v-if="item.widgetCode=='pinTuan' "></coreshoppinTuan>
<!--服务修复-->
<coreshopservice :coreshopdata="item" v-if="item.widgetCode=='service' "></coreshopservice>
<!--弹窗广告-->
<coreshopadpop :coreshopdata="item" v-if="item.widgetCode=='adpop' "></coreshopadpop>
<!--文本内容修复-->
<coreshopContent :coreshopdata="item" v-if="item.widgetCode=='content' "></coreshopContent>
</block>
</view>
</template>
<script>
import coreshopimgSlide from '@/components/nsts-page/coreshop-imgSlide.vue'
import coreshopsearch from '@/components/coreshop-page/coreshop-search.vue'
import coreshopnotice from '@/components/coreshop-page/coreshop-notice.vue'
import coreshopcoupon from '@/components/coreshop-page/coreshop-coupon.vue'
import coreshopblank from '@/components/coreshop-page/coreshop-blank.vue'
import coreshoptextarea from '@/components/coreshop-page/coreshop-textarea.vue'
import coreshopvideo from '@/components/coreshop-page/coreshop-video.vue'
import coreshopimgWindow from '@/components/coreshop-page/coreshop-imgWindow.vue'
import coreshopimgSingle from '@/components/coreshop-page/coreshop-imgSingle.vue'
import coreshopgoods from '@/components/coreshop-page/coreshop-goods.vue'
import coreshopgoodTabBar from '@/components/coreshop-page/coreshop-goodTabBar.vue'
import coreshoparticle from '@/components/coreshop-page/coreshop-article.vue'
import coreshoparticleClassify from '@/components/coreshop-page/coreshop-articleClassify.vue'
import coreshopnavBar from '@/components/coreshop-page/coreshop-navBar.vue'
import coreshopgroupPurchase from '@/components/coreshop-page/coreshop-groupPurchase.vue'
import coreshoprecord from '@/components/coreshop-page/coreshop-record.vue'
import coreshoppinTuan from '@/components/coreshop-page/coreshop-pinTuan.vue'
import coreshopservice from '@/components/coreshop-page/coreshop-service.vue'
import coreshoptabbar from '@/components/coreshop-page/coreshop-tabbar.vue'
import coreshopadpop from '@/components/coreshop-page/coreshop-adpop.vue'
import coreshopContent from '@/components/coreshop-page/coreshop-content.vue'
export default {
name: 'nsts-page',
components: {
coreshopimgSlide,
coreshopsearch,
coreshopnotice,
coreshopcoupon,
coreshopblank,
coreshoptextarea,
coreshopvideo,
coreshopimgWindow,
coreshopimgSingle,
coreshopgoods,
coreshopgoodTabBar,
coreshoparticle,
coreshoparticleClassify,
coreshopnavBar,
coreshopgroupPurchase,
coreshoprecord,
coreshoppinTuan,
coreshopservice,
coreshoptabbar,
coreshopadpop,
coreshopContent
},
props: {
coreshopdata: {
default: function () {
return []
}
},
isScorll: {
type: Boolean,
default: true
}
}
}
</script>

View File

@@ -0,0 +1,132 @@
export default {
"pulldown": "\ue588",
"refreshempty": "\ue461",
"back": "\ue471",
"forward": "\ue470",
"more": "\ue507",
"more-filled": "\ue537",
"scan": "\ue612",
"qq": "\ue264",
"weibo": "\ue260",
"weixin": "\ue261",
"pengyouquan": "\ue262",
"loop": "\ue565",
"refresh": "\ue407",
"refresh-filled": "\ue437",
"arrowthindown": "\ue585",
"arrowthinleft": "\ue586",
"arrowthinright": "\ue587",
"arrowthinup": "\ue584",
"undo-filled": "\ue7d6",
"undo": "\ue406",
"redo": "\ue405",
"redo-filled": "\ue7d9",
"bars": "\ue563",
"chatboxes": "\ue203",
"camera": "\ue301",
"chatboxes-filled": "\ue233",
"camera-filled": "\ue7ef",
"cart-filled": "\ue7f4",
"cart": "\ue7f5",
"checkbox-filled": "\ue442",
"checkbox": "\ue7fa",
"arrowleft": "\ue582",
"arrowdown": "\ue581",
"arrowright": "\ue583",
"smallcircle-filled": "\ue801",
"arrowup": "\ue580",
"circle": "\ue411",
"eye-filled": "\ue568",
"eye-slash-filled": "\ue822",
"eye-slash": "\ue823",
"eye": "\ue824",
"flag-filled": "\ue825",
"flag": "\ue508",
"gear-filled": "\ue532",
"reload": "\ue462",
"gear": "\ue502",
"hand-thumbsdown-filled": "\ue83b",
"hand-thumbsdown": "\ue83c",
"hand-thumbsup-filled": "\ue83d",
"heart-filled": "\ue83e",
"hand-thumbsup": "\ue83f",
"heart": "\ue840",
"home": "\ue500",
"info": "\ue504",
"home-filled": "\ue530",
"info-filled": "\ue534",
"circle-filled": "\ue441",
"chat-filled": "\ue847",
"chat": "\ue263",
"mail-open-filled": "\ue84d",
"email-filled": "\ue231",
"mail-open": "\ue84e",
"email": "\ue201",
"checkmarkempty": "\ue472",
"list": "\ue562",
"locked-filled": "\ue856",
"locked": "\ue506",
"map-filled": "\ue85c",
"map-pin": "\ue85e",
"map-pin-ellipse": "\ue864",
"map": "\ue364",
"minus-filled": "\ue440",
"mic-filled": "\ue332",
"minus": "\ue410",
"micoff": "\ue360",
"mic": "\ue302",
"clear": "\ue434",
"smallcircle": "\ue868",
"close": "\ue404",
"closeempty": "\ue460",
"paperclip": "\ue567",
"paperplane": "\ue503",
"paperplane-filled": "\ue86e",
"person-filled": "\ue131",
"contact-filled": "\ue130",
"person": "\ue101",
"contact": "\ue100",
"images-filled": "\ue87a",
"phone": "\ue200",
"images": "\ue87b",
"image": "\ue363",
"image-filled": "\ue877",
"location-filled": "\ue333",
"location": "\ue303",
"plus-filled": "\ue439",
"plus": "\ue409",
"plusempty": "\ue468",
"help-filled": "\ue535",
"help": "\ue505",
"navigate-filled": "\ue884",
"navigate": "\ue501",
"mic-slash-filled": "\ue892",
"search": "\ue466",
"settings": "\ue560",
"sound": "\ue590",
"sound-filled": "\ue8a1",
"spinner-cycle": "\ue465",
"download-filled": "\ue8a4",
"personadd-filled": "\ue132",
"videocam-filled": "\ue8af",
"personadd": "\ue102",
"upload": "\ue402",
"upload-filled": "\ue8b1",
"starhalf": "\ue463",
"star-filled": "\ue438",
"star": "\ue408",
"trash": "\ue401",
"phone-filled": "\ue230",
"compose": "\ue400",
"videocam": "\ue300",
"trash-filled": "\ue8dc",
"download": "\ue403",
"chatbubble-filled": "\ue232",
"chatbubble": "\ue202",
"cloud-download": "\ue8e4",
"cloud-upload-filled": "\ue8e5",
"cloud-upload": "\ue8e6",
"cloud-download-filled": "\ue8e9",
"headphones":"\ue8bf",
"shop":"\ue609"
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,128 @@
// const defaultOption = {
// duration: 300,
// timingFunction: 'linear',
// delay: 0,
// transformOrigin: '50% 50% 0'
// }
// #ifdef APP-NVUE
const nvueAnimation = uni.requireNativePlugin('animation')
// #endif
class MPAnimation {
constructor(options, _this) {
this.options = options
this.animation = uni.createAnimation(options)
this.currentStepAnimates = {}
this.next = 0
this.$ = _this
}
_nvuePushAnimates(type, args) {
let aniObj = this.currentStepAnimates[this.next]
let styles = {}
if (!aniObj) {
styles = {
styles: {},
config: {}
}
} else {
styles = aniObj
}
if (animateTypes1.includes(type)) {
if (!styles.styles.transform) {
styles.styles.transform = ''
}
let unit = ''
if(type === 'rotate'){
unit = 'deg'
}
styles.styles.transform += `${type}(${args+unit}) `
} else {
styles.styles[type] = `${args}`
}
this.currentStepAnimates[this.next] = styles
}
_animateRun(styles = {}, config = {}) {
let ref = this.$.$refs['ani'].ref
if (!ref) return
return new Promise((resolve, reject) => {
nvueAnimation.transition(ref, {
styles,
...config
}, res => {
resolve()
})
})
}
_nvueNextAnimate(animates, step = 0, fn) {
let obj = animates[step]
if (obj) {
let {
styles,
config
} = obj
this._animateRun(styles, config).then(() => {
step += 1
this._nvueNextAnimate(animates, step, fn)
})
} else {
this.currentStepAnimates = {}
typeof fn === 'function' && fn()
this.isEnd = true
}
}
step(config = {}) {
// #ifndef APP-NVUE
this.animation.step(config)
// #endif
// #ifdef APP-NVUE
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
this.next++
// #endif
return this
}
run(fn) {
// #ifndef APP-NVUE
this.$.animationData = this.animation.export()
this.$.timer = setTimeout(() => {
typeof fn === 'function' && fn()
}, this.$.durationTime)
// #endif
// #ifdef APP-NVUE
this.isEnd = false
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
if(!ref) return
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
this.next = 0
// #endif
}
}
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
'translateZ'
]
const animateTypes2 = ['opacity', 'backgroundColor']
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
MPAnimation.prototype[type] = function(...args) {
// #ifndef APP-NVUE
this.animation[type](...args)
// #endif
// #ifdef APP-NVUE
this._nvuePushAnimates(type, args)
// #endif
return this
}
})
export function createAnimation(option, _this) {
if(!_this) return
clearTimeout(_this.timer)
return new MPAnimation(option, _this)
}

View File

@@ -0,0 +1,276 @@
<template>
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
</template>
<script>
import { createAnimation } from './createAnimation'
/**
* Transition 过渡动画
* @description 简单过渡动画组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
* @value fade 渐隐渐出过渡
* @value slide-top 由上至下过渡
* @value slide-right 由右至左过渡
* @value slide-bottom 由下至上过渡
* @value slide-left 由左至右过渡
* @value zoom-in 由小到大过渡
* @value zoom-out 由大到小过渡
* @property {Number} duration 过渡动画持续时间
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
*/
export default {
name: 'uniTransition',
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: [Array, String],
default() {
return 'fade'
}
},
duration: {
type: Number,
default: 300
},
styles: {
type: Object,
default() {
return {}
}
},
customClass:{
type: String,
default: ''
}
},
data() {
return {
isShow: false,
transform: '',
opacity: 1,
animationData: {},
durationTime: 300,
config: {}
}
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
// 避免上来就执行 close,导致动画错乱
if (this.isShow) {
this.close()
}
}
},
immediate: true
}
},
computed: {
// 生成样式数据
stylesObject() {
let styles = {
...this.styles,
'transition-duration': this.duration / 1000 + 's'
}
let transform = ''
for (let i in styles) {
let line = this.toLine(i)
transform += line + ':' + styles[i] + ';'
}
return transform
},
// 初始化动画条件
transformStyles() {
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
}
},
created() {
// 动画默认配置
this.config = {
duration: this.duration,
timingFunction: 'ease',
transformOrigin: '50% 50%',
delay: 0
}
this.durationTime = this.duration
},
methods: {
/**
* ref 触发 初始化动画
*/
init(obj = {}) {
if (obj.duration) {
this.durationTime = obj.duration
}
this.animation = createAnimation(Object.assign(this.config, obj))
},
/**
* 点击组件触发回调
*/
onClick() {
this.$emit('click', {
detail: this.isShow
})
},
/**
* ref 触发 动画分组
* @param {Object} obj
*/
step(obj, config = {}) {
if (!this.animation) return
for (let i in obj) {
try {
if(typeof obj[i] === 'object'){
this.animation[i](...obj[i])
}else{
this.animation[i](obj[i])
}
} catch (e) {
// console.error(`方法 ${i} 不存在`)
}
}
this.animation.step(config)
return this
},
/**
* ref 触发 执行动画
*/
run(fn) {
if (!this.animation) return
this.animation.run(fn)
},
// 开始过度动画
open() {
clearTimeout(this.timer)
this.transform = ''
this.isShow = true
let { opacity, transform } = this.styleInit(false)
if (typeof opacity !== 'undefined') {
this.opacity = opacity
}
this.transform = transform
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
this.$nextTick(() => {
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
this.timer = setTimeout(() => {
this.animation = createAnimation(this.config, this)
this.tranfromInit(false).step()
this.animation.run()
this.$emit('change', {
detail: this.isShow
})
}, 20)
})
},
// 关闭过度动画
close(type) {
if (!this.animation) return
this.tranfromInit(true)
.step()
.run(() => {
this.isShow = false
this.animationData = null
this.animation = null
let { opacity, transform } = this.styleInit(false)
this.opacity = opacity || 1
this.transform = transform
this.$emit('change', {
detail: this.isShow
})
})
},
// 处理动画开始前的默认样式
styleInit(type) {
let styles = {
transform: ''
}
let buildStyle = (type, mode) => {
if (mode === 'fade') {
styles.opacity = this.animationType(type)[mode]
} else {
styles.transform += this.animationType(type)[mode] + ' '
}
}
if (typeof this.modeClass === 'string') {
buildStyle(type, this.modeClass)
} else {
this.modeClass.forEach(mode => {
buildStyle(type, mode)
})
}
return styles
},
// 处理内置组合动画
tranfromInit(type) {
let buildTranfrom = (type, mode) => {
let aniNum = null
if (mode === 'fade') {
aniNum = type ? 0 : 1
} else {
aniNum = type ? '-100%' : '0'
if (mode === 'zoom-in') {
aniNum = type ? 0.8 : 1
}
if (mode === 'zoom-out') {
aniNum = type ? 1.2 : 1
}
if (mode === 'slide-right') {
aniNum = type ? '100%' : '0'
}
if (mode === 'slide-bottom') {
aniNum = type ? '100%' : '0'
}
}
this.animation[this.animationMode()[mode]](aniNum)
}
if (typeof this.modeClass === 'string') {
buildTranfrom(type, this.modeClass)
} else {
this.modeClass.forEach(mode => {
buildTranfrom(type, mode)
})
}
return this.animation
},
animationType(type) {
return {
fade: type ? 1 : 0,
'slide-top': `translateY(${type ? '0' : '-100%'})`,
'slide-right': `translateX(${type ? '0' : '100%'})`,
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
'slide-left': `translateX(${type ? '0' : '-100%'})`,
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
}
},
// 内置动画类型与实际动画对应字典
animationMode() {
return {
fade: 'opacity',
'slide-top': 'translateY',
'slide-right': 'translateX',
'slide-bottom': 'translateY',
'slide-left': 'translateX',
'zoom-in': 'scale',
'zoom-out': 'scale'
}
},
// 驼峰转中横线
toLine(name) {
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
}
}
}
</script>
<style></style>

View File

@@ -0,0 +1,456 @@
<!-- 步进器 -->
<template>
<view class="vk-data-input-number-box">
<view
class="u-icon-minus"
:class="{ 'u-icon-disabled': disabled || inputVal <= min }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color,
fontSize: size + 'rpx',
minHeight: '1.4em'
}"
@touchstart.prevent="btnTouchStart('minus')"
@touchend.stop.prevent="clearTimer"
>
<view :style="'font-size:' + (Number(size) + 10) + 'rpx'" class="num-btn"></view>
</view>
<input
v-model="inputVal"
:disabled="disabledInput || disabled"
:cursor-spacing="getCursorSpacing"
:class="{ 'u-input-disabled': disabled }"
class="u-number-input"
type="number"
:style="{
color: color,
fontSize: size + 'rpx',
background: bgColor,
height: inputHeight + 'rpx',
width: inputWidth + 'rpx'
}"
@blur="onBlur"
/>
<view
class="u-icon-plus"
:class="{ 'u-icon-disabled': disabled || inputVal >= max }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color,
fontSize: size + 'rpx',
minHeight: '1.4em'
}"
@touchstart.prevent="btnTouchStart('plus')"
@touchend.stop.prevent="clearTimer"
>
<view :style="'font-size:' + (Number(size) + 10) + 'rpx'" class="num-btn"></view>
</view>
</view>
</template>
<script>
/**
* numberBox 步进器此为uview组件改造
* @description 该组件一般用于商城购物选择物品数量的场景。注意该输入框只能输入大于或等于0的整数不支持小数输入
* @tutorial https://www.uviewui.com/components/numberBox.html
* @property {Number} value 输入框初始值默认1
* @property {String} bg-color 输入框和按钮的背景颜色(默认#F2F3F5
* @property {Number} min 用户可输入的最小值默认0
* @property {Number} max 用户可输入的最大值默认99999
* @property {Number} step 步长每次加或减的值默认1
* @property {Number} stepFirst 步进值,首次增加或最后减的值(默认step值和一致
* @property {Boolean} disabled 是否禁用操作禁用后无法加减或手动修改输入框的值默认false
* @property {Boolean} disabled-input 是否禁止输入框手动输入值默认false
* @property {Boolean} positive-integer 是否只能输入正整数默认true
* @property {String | Number} size 输入框文字和按钮字体大小单位rpx默认26
* @property {String} color 输入框文字和加减按钮图标的颜色(默认#323233
* @property {String | Number} input-width 输入框宽度单位rpx默认80
* @property {String | Number} input-height 输入框和按钮的高度单位rpx默认50
* @property {String | Number} index 事件回调时用以区分当前发生变化的是哪个输入框
* @property {Boolean} long-press 是否开启长按连续递增或递减(默认true)
* @property {String | Number} press-time 开启长按触发后每触发一次需要多久单位ms(默认250)
* @property {String | Number} cursor-spacing 指定光标于键盘的距离避免键盘遮挡输入框单位rpx默认200
* @event {Function} change 输入框内容发生变化时触发,对象形式
* @event {Function} blur 输入框失去焦点时触发,对象形式
* @event {Function} minus 点击减少按钮时触发(按钮可点击情况下),对象形式
* @event {Function} plus 点击增加按钮时触发(按钮可点击情况下),对象形式
* @example <vk-data-input-number-box :min="1" :max="100"></vk-data-input-number-box>
*/
export default {
name: 'vk-data-input-number-box',
emits: ['update:modelValue', 'input', 'change', 'blur', 'plus', 'minus'],
props: {
// 预显示的数字
value: {
type: Number,
default: 1
},
modelValue: {
type: Number,
default: 1
},
// 背景颜色
bgColor: {
type: String,
default: '#F2F3F5'
},
// 最小值
min: {
type: Number,
default: 0
},
// 最大值
max: {
type: Number,
default: 99999
},
// 步进值,每次加或减的值
step: {
type: Number,
default: 1
},
// 步进值,首次增加或最后减的值
stepFirst: {
type: Number,
default: 0
},
// 是否只能输入 step 的倍数
stepStrictly: {
type: Boolean,
default: false
},
// 是否禁用加减操作
disabled: {
type: Boolean,
default: false
},
// input的字体大小单位rpx
size: {
type: [Number, String],
default: 26
},
// 加减图标的颜色
color: {
type: String,
default: '#323233'
},
// input宽度单位rpx
inputWidth: {
type: [Number, String],
default: 80
},
// input高度单位rpx
inputHeight: {
type: [Number, String],
default: 50
},
// index索引用于列表中使用让用户知道是哪个numberbox发生了变化一般使用for循环出来的index值即可
index: {
type: [Number, String],
default: ''
},
// 是否禁用输入框与disabled作用于输入框时为OR的关系即想要禁用输入框又可以加减的话
// 设置disabled为falsedisabledInput为true即可
disabledInput: {
type: Boolean,
default: false
},
// 输入框于键盘之间的距离
cursorSpacing: {
type: [Number, String],
default: 100
},
// 是否开启长按连续递增或递减
longPress: {
type: Boolean,
default: true
},
// 开启长按触发后,每触发一次需要多久
pressTime: {
type: [Number, String],
default: 250
},
// 是否只能输入大于或等于0的整数(正整数)
positiveInteger: {
type: Boolean,
default: true
}
},
watch: {
valueCom(v1, v2) {
// 只有value的改变是来自外部的时候才去同步inputVal的值否则会造成循环错误
if (!this.changeFromInner) {
this.inputVal = v1;
// 因为inputVal变化后会触发this.handleChange()在其中changeFromInner会再次被设置为true
// 造成外面修改值也导致被认为是内部修改的混乱这里进行this.$nextTick延时保证在运行周期的最后处
// 将changeFromInner设置为false
this.$nextTick(function() {
this.changeFromInner = false;
});
}
},
inputVal(v1, v2) {
// 为了让用户能够删除所有输入值,重新输入内容,删除所有值后,内容为空字符串
if (v1 == '') return;
let value = 0;
// 首先判断是否数值并且在min和max之间如果不是使用原来值
let tmp = this.isNumber(v1);
if (tmp && v1 >= this.min && v1 <= this.max) value = v1;
else value = v2;
// 判断是否只能输入大于等于0的整数
if (this.positiveInteger) {
// 小于0或者带有小数点
if (v1 < 0 || String(v1).indexOf('.') !== -1) {
value = v2;
// 双向绑定input的值必须要使用$nextTick修改显示的值
this.$nextTick(() => {
this.inputVal = v2;
});
}
}
// 发出change事件
this.handleChange(value, 'change');
},
min(v1) {
if (v1 !== undefined && v1 != '' && this.valueCom < v1) {
this.$emit('input', v1);
this.$emit('update:modelValue', v1);
}
},
max(v1) {
if (v1 !== undefined && v1 != '' && this.valueCom > v1) {
this.$emit('input', v1);
this.$emit('update:modelValue', v1);
}
}
},
data() {
return {
inputVal: 1, // 输入框中的值不能直接使用props中的value因为应该改变props的状态
timer: null, // 用作长按的定时器
changeFromInner: false, // 值发生变化,是来自内部还是外部
innerChangeTimer: null // 内部定时器
};
},
created() {
this.inputVal = Number(this.valueCom);
},
computed: {
valueCom() {
// #ifndef VUE3
return this.value;
// #endif
// #ifdef VUE3
return this.modelValue;
// #endif
},
getCursorSpacing() {
// 先将值转为px单位再转为数值
return Number(uni.upx2px(this.cursorSpacing));
}
},
methods: {
// 点击退格键
btnTouchStart(callback) {
// 先执行一遍方法否则会造成松开手时就执行了clearTimer导致无法实现功能
this[callback]();
// 如果没开启长按功能,直接返回
if (!this.longPress) return;
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
// 执行加或减函数
this[callback]();
}, this.pressTime);
},
clearTimer() {
this.$nextTick(() => {
clearInterval(this.timer);
this.timer = null;
});
},
minus() {
this.computeVal('minus');
},
plus() {
this.computeVal('plus');
},
// 为了保证小数相加减出现精度溢出的问题
calcPlus(num1, num2) {
let baseNum, baseNum1, baseNum2;
try {
baseNum1 = num1.toString().split('.')[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split('.')[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2; //精度
return ((num1 * baseNum + num2 * baseNum) / baseNum).toFixed(precision);
},
// 为了保证小数相加减出现精度溢出的问题
calcMinus(num1, num2) {
let baseNum, baseNum1, baseNum2;
try {
baseNum1 = num1.toString().split('.')[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split('.')[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2;
return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
},
computeVal(type) {
uni.hideKeyboard();
if (this.disabled) return;
let value = 0;
// 新增stepFirst开始
// 减
if (type === 'minus') {
if (this.stepFirst > 0 && this.inputVal == this.stepFirst) {
value = this.min;
} else {
value = this.calcMinus(this.inputVal, this.step);
}
} else if (type === 'plus') {
if (this.stepFirst > 0 && this.inputVal < this.stepFirst) {
value = this.stepFirst;
} else {
value = this.calcPlus(this.inputVal, this.step);
}
}
if (this.stepStrictly) {
let strictly = value % this.step;
if (strictly > 0) {
value -= strictly;
}
}
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min;
}
// 新增stepFirst结束
this.inputVal = value;
this.handleChange(value, type);
},
// 处理用户手动输入的情况
onBlur(event) {
let val = 0;
let value = event.detail.value;
// 如果为非0-9数字组成或者其第一位数值为0直接让其等于min值
// 这里不直接判断是否正整数是因为用户传递的props min值可能为0
if (!/(^\d+$)/.test(value) || value[0] == 0) val = this.min;
val = +value;
// 新增stepFirst开始
if (this.stepFirst > 0 && this.inputVal < this.stepFirst && this.inputVal > 0) {
val = this.stepFirst;
}
// 新增stepFirst结束
if (this.stepStrictly) {
let strictly = val % this.step;
if (strictly > 0) {
val -= strictly;
}
}
if (val > this.max) {
val = this.max;
} else if (val < this.min) {
val = this.min;
}
this.$nextTick(() => {
this.inputVal = val;
});
this.handleChange(val, 'blur');
},
handleChange(value, type) {
if (this.disabled) return;
// 清除定时器,避免造成混乱
if (this.innerChangeTimer) {
clearTimeout(this.innerChangeTimer);
this.innerChangeTimer = null;
}
// 发出input事件修改通过v-model绑定的值达到双向绑定的效果
this.changeFromInner = true;
// 一定时间内清除changeFromInner标记否则内部值改变后
// 外部通过程序修改value值将会无效
this.innerChangeTimer = setTimeout(() => {
this.changeFromInner = false;
}, 150);
this.$emit('input', Number(value));
this.$emit('update:modelValue', Number(value));
this.$emit(type, {
// 转为Number类型
value: Number(value),
index: this.index
});
},
/**
* 验证十进制数字
*/
isNumber(value) {
return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
}
}
};
</script>
<style lang="scss" scoped>
.vk-data-input-number-box {
display: inline-flex;
align-items: center;
}
.u-number-input {
position: relative;
text-align: center;
padding: 0;
margin: 0 6rpx;
display: flex;
align-items: center;
justify-content: center;
}
.u-icon-plus,
.u-icon-minus {
width: 60rpx;
display: flex;
justify-content: center;
align-items: center;
}
.u-icon-plus {
border-radius: 0 8rpx 8rpx 0;
}
.u-icon-minus {
border-radius: 8rpx 0 0 8rpx;
}
.u-icon-disabled {
color: #c8c9cc !important;
background: #f7f8fa !important;
}
.u-input-disabled {
color: #c8c9cc !important;
background-color: #f2f3f5 !important;
}
.num-btn {
font-weight: 550;
position: relative;
top: -4rpx;
}
</style>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<!-- Open Graph data -->
<!-- <meta property="og:title" content="Title Here" /> -->
<!-- <meta property="og:url" content="http://www.example.com/" /> -->
<!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
<!-- <meta property="og:description" content="Description Here" /> -->
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -0,0 +1,64 @@
import Vue from 'vue'
import App from './App'
//上传方法
import * as Upload from '@/common/utils/uploadHelper.js'
//常用方法库
import * as Common from '@/common/utils/commonHelper.js'
//本地存储封装
import * as Db from '@/common/utils/dbHelper.js'
//全局常量配置
import * as GlobalConstVars from '@/common/setting/constVarsHelper.js'
//全局常量配置
import * as CoreTheme from '@/common/setting/coreThemeHelper.js'
import store from '@/common/store'
//引入全局uView
import uView from '@/uni_modules/uview-ui'
Vue.use(uView)
// #ifdef MP
// 引入uView对小程序分享的mixin封装
let mpShare = require('@/uni_modules/uview-ui/libs/mixin/mpShare.js');
Vue.mixin(mpShare)
// #endif
//全局引用常量配置文件,用于template内代码使用
Vue.mixin({
data() {
return {
$globalConstVars: GlobalConstVars
}
}
})
//引入全局自定义mixin主要用于在template内代码使用方法
import mixinsHelper from "@/common/mixins/mixinsHelper.js"
Vue.mixin(mixinsHelper)
Vue.config.productionTip = false
Vue.prototype.$upload = Upload;
Vue.prototype.$common = Common;
Vue.prototype.$db = Db;
Vue.prototype.$globalConstVars = GlobalConstVars;
Vue.prototype.$coreTheme = CoreTheme;
Vue.prototype.$store = store;
App.mpType = 'app'
const app = new Vue({
...App
})
// 引入请求封装
require('@/common/request/request')(app)
// http接口API集中管理引入部分
import httpApi from '@/common/request/http.api.js'
Vue.use(httpApi, app)
app.$mount()

View File

@@ -0,0 +1,178 @@
{
"name" : "小小助农",
"appid" : "__UNI__EAACF14",
"description" : "核心商城系统CoreShop是基于uni-app框架开发的商城应用程序",
"versionName" : "1.0",
"versionCode" : 1,
"transformPx" : false,
"app-plus" : {
/* 5+App */
"modules" : {
"Payment" : {},
"VideoPlayer" : {},
"Maps" : {}
},
/* */
"distribute" : {
/* */
"android" : {
/* android */
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
},
"ios" : {},
/* ios */
"sdkConfigs" : {
"payment" : {
"weixin" : {
"appid" : "wx11d95cdaee6058f6"
}
},
"ad" : {},
"maps" : {
"amap" : {
"appkey_ios" : "91b94ecb48605c4e048aa1971459eca7",
"appkey_android" : "91b94ecb48605c4e048aa1971459eca7"
}
},
"oauth" : {
"univerify" : {}
},
"share" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
},
"splashscreen" : {
"waiting" : true
}
},
/* SDK */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx6fc139d4de0b470f",
"setting" : {
"urlCheck" : true,
"postcss" : true,
"minified" : true,
"es6" : true,
"checkSiteMap" : false
},
"plugins" : {
"chooseLocation" : {
"version" : "1.0.9",
"provider" : "wx76a9a06e5b4e693e"
}
},
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序定位"
}
},
"optimization" : {
"subPackages" : true
}
},
"h5" : {
"title" : "南山田舍",
"domain" : "https://h5.coreshop.coreshop.net",
"router" : {
"base" : "./",
"mode" : "hash"
},
"template" : "index.html",
"devServer" : {
"port" : 80,
"disableHostCheck" : true,
"https" : true
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "AEIBZ-H5TRI-A6VGA-5KRNA-QKKK6-JGB33"
}
}
},
"optimization" : {
"treeShaking" : {
"enable" : false
}
}
},
"mp-toutiao" : {
"setting" : {
"es6" : true,
"postcss" : true,
"minified" : true
},
"appid" : ""
},
"mp-qq" : {
"setting" : {
"es6" : true,
"postcss" : true,
"minified" : true
},
"optimization" : {
"subPackages" : true
}
},
"mp-alipay" : {},
"mp-baidu" : {}
}

View File

@@ -0,0 +1,3 @@
{
"lockfileVersion": 1
}

View File

@@ -0,0 +1,922 @@
{
"usingShopPlugin": true,
"easycom": {
"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
},
"pages": [
{
"path": "pages/index/default/default",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "首页",
// #ifdef H5
"titleNView": false,
// #endif
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/custom/custom",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "页面",
// #ifdef H5
"titleNView": false,
// #endif
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/designDefault/designDefault",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "设计页面",
// #ifdef H5
"titleNView": false,
// #endif
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/cart/cart",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "购物车"
}
},
{
"path": "pages/index/member/member",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "会员中心"
}
},
{
"path": "pages/category/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分类"
}
},
{
"path": "pages/category/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商品列表"
}
},
{
"path": "pages/template",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "模板"
}
},
{
"path": "pages/demo",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示"
}
}
],
"subpackages": [
{
"root": "pages/article",
"name": "article",
"pages": [
{
"path": "details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "文章详情"
}
},
{
"path": "list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "文章列表"
}
}
]
},
{
"root": "pages/notice",
"name": "notice",
"pages": [
{
"path": "details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "公告详情"
}
},
{
"path": "list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "公告列表"
}
}
]
},
{
"root": "pages/webview",
"name": "webview",
"pages": [
{
"path": "webview",
"style": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "网页详情"
}
}
]
},
{
"root": "pages/map",
"name": "map",
"pages": [
{
"path": "map",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "地图展示"
}
}
]
},
{
"root": "pages/form",
"name": "form",
"pages": [
{
"path": "details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "万能表单"
}
}
]
},
{
"root": "pages/coupon",
"name": "coupon",
"pages": [
{
"path": "coupon",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "优惠券列表"
}
}
]
},
{
"root": "pages/goods",
"name": "goods",
"pages": [
{
"path": "goodDetails/goodDetails",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "商品详情",
"navigationStyle": "custom"
}
},
{
"path": "goodComments/goodComments",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商品评论"
}
}
]
},
{
"root": "pages/login",
"name": "login",
"pages": [
{
"path": "loginBySMS/loginBySMS",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "授权登录"
}
}
]
},
{
"root": "pages/payment",
"name": "payment",
"pages": [
{
"path": "pay/pay",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "支付"
}
},
{
"path": "waiting/waiting",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "等待支付"
}
},
{
"path": "result/result",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "支付结果"
}
}
]
},
{
"root": "pages/placeOrder",
"name": "placeOrder",
"pages": [
{
"path": "index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提交订单"
}
},
{
"path": "invoice/invoice",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "发票"
}
},
{
"path": "storeList/storeList",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "门店列表"
}
}
]
},
{
"root": "pages/reward",
"name": "reward",
"pages": [
{
"path": "reward",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "打赏"
}
}
]
},
{
"root": "pages/storeMap",
"name": "storeMap",
"pages": [
{
"path": "storeMap",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "门店列表"
}
}
]
},
{
"root": "pages/search",
"name": "search",
"pages": [
{
"path": "search",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "搜索"
}
}
]
},
{
"root": "pages/serviceGoods",
"name": "serviceGoods",
"pages": [
{
"path": "index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务商品列表"
}
},
{
"path": "details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务商品详情"
}
}
]
},
{
"root": "pages/share",
"name": "share",
"pages": [
{
"path": "sharePoster/sharePoster",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分享"
}
},
{
"path": "shareNewPoster/shareNewPoster",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "新版分享"
}
},
{
"path": "jump/jump",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "加载中..."
}
}
]
},
{
"root": "pages/activity",
"name": "activity",
"pages": [
{
"path": "pinTuan/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "拼团列表"
}
},
{
"path": "pinTuan/pinTuanDetails/pinTuanDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "拼团详情"
}
},
{
"path": "seckill/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "秒杀列表"
}
},
{
"path": "seckill/seckillDetails/seckillDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "秒杀详情"
}
},
{
"path": "groupBuying/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "团购列表"
}
},
{
"path": "groupBuying/groupBuyingDetails/groupBuyingDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "团购详情"
}
},
{
"path": "solitaire/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "接龙"
}
},
{
"path": "solitaire/solitaireDetails/solitaireDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "接龙详情"
}
},
{
"path": "checkIn/checkIn/checkIn",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "日历签到"
}
}
]
},
{
"root": "pages/member",
"name": "member",
"pages": [
{
"path": "coupon/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的优惠券"
}
},
{
"path": "balance/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的余额"
}
},
{
"path": "balance/recharge/recharge",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "储值"
}
},
{
"path": "balance/withdrawCash/withdrawCash",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提现"
}
},
{
"path": "balance/details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "余额明细"
}
},
{
"path": "balance/cashlist/cashlist",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提现记录"
}
},
{
"path": "balance/bankcard/bankcard",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的银行卡"
}
},
{
"path": "balance/addBankCard/addBankCard",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "添加银行卡"
}
},
{
"path": "collection/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的收藏"
}
},
{
"path": "history/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的足迹"
}
},
{
"path": "address/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "地址管理"
}
},
{
"path": "address/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "修改地址"
}
},
{
"path": "address/map/map",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "选取街道"
}
},
{
"path": "setting/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "设置"
}
},
{
"path": "setting/userInfo/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "个人信息"
}
},
{
"path": "setting/userInfo/password",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "修改密码"
}
},
{
"path": "integral/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的积分"
}
},
{
"path": "invite/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "邀请好友"
}
},
{
"path": "invite/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "邀请列表"
}
},
{
"path": "invoice/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的发票"
}
},
{
"path": "order/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "订单列表"
}
},
{
"path": "order/detail/detail",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "订单详情"
}
},
{
"path": "order/invitationGroup/invitationGroup",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "邀请拼单"
}
},
{
"path": "afterSales/submit/submit",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "申请售后"
}
},
{
"path": "afterSales/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "售后列表"
}
},
{
"path": "afterSales/detail/detail",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "售后详情"
}
},
{
"path": "order/evaluate/evaluate",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "订单评价"
}
},
{
"path": "order/expressDelivery/expressDelivery",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "物流信息"
}
},
{
"path": "distribution/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分销中心"
}
},
{
"path": "distribution/apply/apply",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "申请成为分销"
}
},
{
"path": "distribution/applyState/applyState",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "审核状态"
}
},
{
"path": "distribution/panel/panel",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分销中心"
}
},
{
"path": "distribution/agreement/agreement",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分销协议"
}
},
{
"path": "distribution/order/order",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "推广订单"
}
},
{
"path": "distribution/myStore/myStore",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的店铺"
}
},
{
"path": "distribution/storeSetting/storeSetting",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "店铺设置"
}
},
{
"path": "distribution/team/team",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的团队"
}
},
{
"path": "distribution/commissionDetails/commissionDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "佣金明细"
}
},
{
"path": "distribution/rankings/rankings",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分销排行"
}
},
{
"path": "distribution/shareLog/shareLog",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分享记录"
}
},
{
"path": "agent/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "代理中心"
}
},
{
"path": "agent/apply/apply",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "申请成为代理"
}
},
{
"path": "agent/applyState/applyState",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "审核状态"
}
},
{
"path": "agent/panel/panel",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "代理中心"
}
},
{
"path": "agent/agreement/agreement",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "代理协议"
}
},
{
"path": "agent/order/order",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "推广订单"
}
},
{
"path": "agent/myStore/myStore",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的店铺"
}
},
{
"path": "agent/storeSetting/storeSetting",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "店铺设置"
}
},
{
"path": "agent/team/team",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的团队"
}
},
{
"path": "agent/commissionDetails/commissionDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "佣金明细"
}
},
{
"path": "agent/rankings/rankings",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "代理排行"
}
},
{
"path": "agent/shareLog/shareLog",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分享记录"
}
},
{
"path": "setting/subscription/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "消息订阅"
}
},
{
"path": "serviceOrder/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的服务卡"
}
},
{
"path": "serviceOrder/details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务卡详情"
}
},
{
"path": "merchant/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商家管理"
}
},
{
"path": "merchant/search/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "订单查询"
}
},
{
"path": "merchant/detail/detail",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "订单预览"
}
},
{
"path": "merchant/storeList/storeList",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "门店选择"
}
},
{
"path": "merchant/serviceVerification/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "核验服务券"
}
},
{
"path": "merchant/serviceVerification/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务券列表"
}
},
{
"path": "merchant/takeDelivery/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提货单核销"
}
},
{
"path": "merchant/takeDelivery/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提货单列表"
}
}
]
}
],
"preloadRule": { //加载规则 当渲染pages/index/default/default时加载子包
"pages/index/default/default": {
"network": "all",
"packages": [ "member" ]
}
},
"globalStyle": {
"navigationStyle": "custom",
"mp-alipay": {
"allowsBounceVertical": "NO",
"transparentTitle": "always"
}
},
"tabBar": {
"color": "#999",
"selectedColor": "#333",
"backgroundColor": "#fff",
"list": [
{
"pagePath": "pages/index/default/default",
"text": "首页",
"iconPath": "static/images/indexMenus/index01.png",
"selectedIconPath": "static/images/indexMenus/index01_1.png"
},
{
"pagePath": "pages/category/index/index",
"text": "分类",
"iconPath": "static/images/indexMenus/index02.png",
"selectedIconPath": "static/images/indexMenus/index02_1.png"
},
{
"pagePath": "pages/index/cart/cart",
"text": "购物车",
"iconPath": "static/images/indexMenus/index03.png",
"selectedIconPath": "static/images/indexMenus/index03_1.png"
},
{
"pagePath": "pages/index/member/member",
//"pagePath": "pages/login/loginByAccount/loginByAccount",
"text": "我的",
"iconPath": "static/images/indexMenus/index04.png",
"selectedIconPath": "static/images/indexMenus/index04_1.png"
}
]
}
}

View File

@@ -0,0 +1,32 @@
.bar { display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin: 30rpx 20rpx; padding: 10rpx;
.barbtn { height: 30px; line-height: 30px; font-size: 12px; }
}
.week { display: flex; flex-direction: row; justify-content: space-between; padding: 20rpx; padding-left: 40rpx; padding-right: 40rpx; margin: 20rpx; border-radius: 10px; background-color: #fff; }
.myDateTable { margin: 2.5vw; padding: 2vw; border-radius: 10px; background: linear-gradient(#74AADA, #94db98);
.dateCell { width: 11vw; margin: 1vw; display: inline-block; text-align: center; font-size: 16px;
.cell { display: flex; border-radius: 50%; height: 11vw; justify-content: center; align-items: center; }
}
}
.greenColor { color: #01b90b; font-weight: bold; }
.bgWhite { background-color: #fff; }
.bgGray { background-color: rgba(255, 255, 255, 0.42); }
.bgBlue { font-size: 14px; background-color: #4b95e6; }
.redColor { color: #ff0000; }
.TipArea { word-break: break-all; word-wrap: break-word; font-size: 14px; padding: 10px; }
.impTip { display: inline-block; color: #ff0000; }
.count { margin: 20rpx; padding: 30rpx; display: flex; text-align: center; border-radius: 10px; flex-direction: column; justify-content: center; align-items: center;
.daynumber { display: flex; flex-direction: row; justify-content: center;
.day { margin-top: 50rpx; }
.number { color: #fff; font-size: 60rpx; background-color: #94db98; width: 100rpx; height: 100rpx; border-radius: 50%; display: flex; flex-direction: column; justify-content: center; margin: 20rpx; }
}
.monthSum { color: red; font-size: 40rpx; }
}
.count text { margin: 10rpx; }

View File

@@ -0,0 +1,307 @@
<template>
<!-- 打卡日历页面 -->
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="日历签到" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="bar">
<!-- 上一个月 -->
<view class="previous" @click="handleCalendar(0)">
<button class="barbtn" v-if="langType=='ch'">上一月</button>
<button class="barbtn" v-else>Last</button>
</view>
<!-- 显示年月 -->
<view class="date">{{cur_year || "--"}} {{cur_month || "--"}} </view>
<!-- 下一个月 -->
<view class="next" @click="handleCalendar(1)">
<button class="barbtn" v-if="langType=='ch'">下一月</button>
<button class="barbtn" v-else>Next</button>
</view>
</view>
<!-- 显示星期 -->
<view class="week" v-if="langType=='ch'">
<view v-for="(item,index) in weeks_ch" :key="index">{{item}}</view>
</view>
<view class="week" v-else>
<view v-for="(item,index) in weeks_en" :key="index">{{item}}</view>
</view>
<view class="myDateTable">
<view v-for="(item,j) in days" :key="j" class='dateCell'>
<view v-if="item.date==undefined||item.date == null" class='cell'>
<text :decode="true">&nbsp;&nbsp;</text>
</view>
<view v-else>
<!-- 已签到日期 -->
<view v-if="item.isSign == true" class='cell greenColor bgWhite '>
<text>{{item.date}}</text>
</view>
<!-- 漏签 -->
<view @click="clickSignUp(item.date,0)" class="cell redColor bgGray"
v-else-if="cur_year<toYear||(cur_year==toYear&&cur_month<toMonth)||(cur_year==toYear&&cur_month==toMonth&&item.date<today)">
<!-- 小程序不兼容这个 v-else-if="(new Date(cur_year+'-'+cur_month+'-'+item.date))<(new Date())"> -->
<text>{{item.date}}</text>
</view>
<!-- 今日未签到-->
<view @click="clickSignUp(item.date,1)" class="cell coreshop-text-white bgBlue" v-else-if="item.date==today&&cur_month==toMonth&&cur_year==toYear">
<text>签到</text>
</view>
<!-- 当前日期之后 -->
<view class="coreshop-text-white cell" v-else>
<text>{{item.date}}</text>
</view>
</view>
</view>
</view>
<!--<view class="TipArea ">
坚持签到<view class="impTip">可获得积分和余额</view>
</view>-->
<view class='count'>
<text>截至目前已坚持打卡</text>
<view class='daynumber'>
<text class='number'>{{sumCount}}</text>
<text class='day'></text>
</view>
<view>本月累积打卡<text class="monthSum">{{dataSource.length}}</text></view>
<text>请再接再厉继续努力!</text>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
days: [],
SignUp: [],
cur_year: 0, //当前选的年
cur_month: 0, //当前选的月
today: parseInt(new Date().getDate()), //本日
toMonth: parseInt(new Date().getMonth() + 1), //本月
toYear: parseInt(new Date().getFullYear()), //本年
weeks_ch: ['日', '一', '二', '三', '四', '五', '六'],
weeks_en: ['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'],
dataSource: [], //已签到的数据源
langType: 'ch',//只是示例一个翻译而已,要想所有都翻译自己可以再加加
sumCount: 0,
signData: []
};
},
onLoad() {
var checkInIsOpen = this.$store.state.config.checkInIsOpen;
if (checkInIsOpen == 2) {
console.log('签到功能未开启');
this.$refs.uToast.show({
message: "签到功能未开启", type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
} else {
this.getUserCheckByMonth(this.cur_year, this.cur_month);
this.getUserCheckCount();
}
},
created() {
this.cur_year = new Date().getFullYear();
this.cur_month = new Date().getMonth() + 1;
this.SignUp = this.dataSource;
this.calculateEmptyGrids(this.cur_year, this.cur_month);
this.calculateDays(this.cur_year, this.cur_month);
this.onJudgeSign();
},
watch: {
dataSource: 'onResChange',
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
},
methods: {
getUserCheckCount() {
this.$u.api.getUserCheckCount().then(res => {
console.log(res);
if (res.status) {
this.sumCount = res.data;
} else {
this.$refs.uToast.show({ message: res.msg, type: 'error', back: false })
}
});
},
getUserCheckByMonth(cur_year, cur_month) {
this.$refs.uToast.show({
loading: false, type: 'loading',
title: '正在加载',
message: "正在加载",
duration: 1000
})
this.$u.api.getUserCheckByMonth({
year: cur_year,
month: cur_month,
}).then(res => {
console.log(res);
if (res.status) {
this.dataSource = res.data;
} else {
this.$refs.uToast.show({ message: res.msg, type: 'error', back: false })
}
});
},
goLogin() {
this.$store.commit('showLoginTip', true);
},
// 获取当月共多少天
getThisMonthDays(year, month) {
return new Date(year, month, 0).getDate()
},
// 获取当月第一天星期几
getFirstDayOfWeek(year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
},
// 计算当月1号前空了几个格子把它填充在days数组的前面
calculateEmptyGrids(year, month) {
//计算每个月时要清零
this.days = [];
const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
if (firstDayOfWeek > 0) {
for (let i = 0; i < firstDayOfWeek; i++) {
var obj = {
date: null,
isSign: false
}
this.days.push(obj);
}
}
},
// 绘制当月天数占的格子并把它放到days数组中
calculateDays(year, month) {
const thisMonthDays = this.getThisMonthDays(year, month);
// this.columnsLen=Math.ceil(thisMonthDays/7);
// console.log(this.columnsLen);
for (let i = 1; i <= thisMonthDays; i++) {
var obj = {
date: i,
isSign: false
}
this.days.push(obj);
}
//console.log(this.days);
},
onResChange(newD, oldD) {
this.SignUp = newD;
this.onJudgeSign();
},
//匹配判断当月与当月哪些日子签到打卡
onJudgeSign() {
var signs = this.SignUp;
var daysArr = this.days;
for (var i = 0; i < signs.length; i++) {
var current = new Date(signs[i].replace(/-/g, "/"));
var year = current.getFullYear();
var month = current.getMonth() + 1;
var day = current.getDate();
day = parseInt(day);
for (var j = 0; j < daysArr.length; j++) {
//年月日相同则打卡成功
if (year == this.cur_year && month == this.cur_month && daysArr[j].date == day) { //&& signs[i].isSign == "今日已打卡"
// console.log(daysArr[j].date, day);
daysArr[j].isSign = true;
}
}
}
this.days = daysArr;
},
// 切换控制年月,上一个月,下一个月
handleCalendar(type) {
const cur_year = parseInt(this.cur_year);
const cur_month = parseInt(this.cur_month);
var newMonth;
var newYear = cur_year;
if (type === 0) { //上个月
newMonth = cur_month - 1;
if (newMonth < 1) {
newYear = cur_year - 1;
newMonth = 12;
}
} else {
newMonth = cur_month + 1;
if (newMonth > 12) {
newYear = cur_year + 1;
newMonth = 1;
}
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.cur_year = newYear;
this.cur_month = newMonth;
this.SignUp = []; //先清空
this.getUserCheckByMonth(this.cur_year, this.cur_month);
//this.$emit('dateChange', this.cur_year + "-" + this.cur_month); //传给调用模板页面去拿新数据
},
clickSignUp(date, type) { //type=0补签type=1当日签到
var _this = this;
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
} else {
//如果不需要补签功能直接在这阻止不执行后面的代码就行。
if (type == 0) {
return false;
}
var postDate = this.cur_year + "-" + this.cur_month + "-" + date;
this.$u.api.userCheckIn({
date: postDate,
}).then(res => {
console.log(res);
if (res.status) {
uni.showToast({
title: "签到成功",
icon: 'success',
duration: 2000
});
//this.SignUp.push(this.cur_year + "-" + this.cur_month + "-" + date);
_this.dataSource.push(this.cur_year + "-" + this.cur_month + "-" + date);
console.log(_this.dataSource);
//_this.SignUp = _this.dataSource;
if (res.data) {
_this.sumCount = res.data.cumulativeCheckInCount;
}
_this.onJudgeSign();
} else {
this.$refs.uToast.show({ message: res.msg, type: 'error', back: false })
}
});
this.$forceUpdate();
}
}
}
}
</script>
<style scoped lang="scss">
@import "checkIn.scss";
</style>

View File

@@ -0,0 +1,786 @@
<template>
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="团购详情" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<!--幻灯片-->
<view class="coreshop-full-screen-banner-swiper-box">
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<!--限时秒杀-->
<view class="coreshop-limited-seckill-box coreshop-bg-orange">
<text class="coreshop-text-price coreshop-font-20">{{ product.price || '0.00' }}</text>
<view class="coreshop-font-xs coreshop-cost-price-num price-4">
<view>已售{{ goodsInfo.buyCount || '0' }}/剩余{{ product.stock || '0' }}</view>
<view>累计销售{{ goodsInfo.buyCount || '0' }}</view>
</view>
<view class="coreshop-text-right coreshop-time-right">
<view>距结束仅剩</view>
<u-count-down :time="goodsInfo.groupTimestamp*1000" :autoStart="true" :millisecond="true" format="DD天HH时mm秒ss"></u-count-down>
</view>
</view>
<!--标题-->
<view class="coreshop-bg-white coreshop-common-view-box coreshop-good-title-view-box">
<view class="title-view coreshop-text-black coreshop-font-lg coreshop-text-bold">
<view class="brand-tag" v-if="goodsInfo.brand"><u-tag :text="goodsInfo.brand.name" type="error" size="mini" /></view>
{{ goodsInfo.name || '' }}
</view>
<view class="coreshop-bg-red-light radius coreshop-margin-top-10 coreshop-title-tip-box">
<text class="coreshop-font-sm">{{ goodsInfo.brief || '' }}</text>
</view>
</view>
<!--服务-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">服务</text>
</view>
<view class="coreshop-basis-8">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<u-icon name="checkmark-circle" size="12" labelSize="12" color="#e54d42" :label="item.title" v-for="(item, index) in serviceDescription.service" :key="index" class="coreshop-margin-right-10"></u-icon>
</view>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--发货/规格-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="serviceDescription.delivery.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">发货</text>
</view>
<view class="coreshop-coreshop-basis-9" v-for="(item, index) in serviceDescription.delivery" :key="index">
<text class="coreshop-font-sm">{{item.description}}</text>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" v-if="serviceDescription.delivery.length>0" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10" @tap="openSkuPopup">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">规格</text>
</view>
<view class="coreshop-basis-8">
<text class="coreshop-font-sm">{{ product.spesDesc || ''}}</text>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--评论-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-10" v-if="goodsComments.length">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10 coreshop-flex-direction-row">
<view class="coreshop-basis-2">
<text class="coreshop-text-black coreshop-font-md">评价{{goodsComments.length}}</text>
</view>
<view class="coreshop-basis-7"></view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right" @tap="goGoodComments(goodsInfo.id)"></u-icon>
</view>
</view>
</view>
<view v-for="(item, index) in goodsComments" :key="index">
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-10 coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<view class="coreshop-avatar sm round" :style="[{backgroundImage:'url('+ item.avatarImage +')'}]" />
</view>
<view class="coreshop-basis-9 coreshop-font-sm">
<view>{{ (item.nickName && item.nickName != '')?item.nickName:item.mobile }}</view>
<view class="coreshop-margin-top-10">{{ item.contentBody || ''}}</view>
<view class="coreshop-text-gray coreshop-margin-top-5">
<u-rate v-model="item.score" :count="5" size="13"></u-rate>
</view>
<view class="coreshop-margin-top-10" v-if="item.imagesArr">
<u-album :urls="item.imagesArr" rowCount="4"></u-album>
</view>
<view class="coreshop-text-gray coreshop-margin-top-5 coreshop-font-12">{{ item.createTime || ''}} {{ item.addon || ''}}</view>
</view>
</view>
</view>
</view>
<!--内容区-->
<view class="coreshop-margin-top-10 coreshop-bg-white">
<view class="coreshop-font-md coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row">
<u-icon name="more-circle" color="#e54d42" label="商品详情" labelSize="15px" label-pos="right"></u-icon>
</view>
<!--参数-->
<view class="coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row" v-for="(item, index) in goodsParams" :key="index">
<text class="coreshop-text-gray">{{ item.name || ''}}</text>
<text class="coreshop-text-black">{{ item.value || ''}}</text>
</view>
<view class="coreshop-padding-10">
<u-parse :content="goodsInfo.intro" :selectable="true" v-if="goodsInfo.intro"></u-parse>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="详情为空" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 分享弹窗 -->
<view class="coreshop-padding-0">
<u-popup mode="bottom" :show="shareBox" ref="share">
<!-- #ifdef H5 -->
<coreshop-share-h5 :shareType='$globalConstVars.shareType.group' :groupId="groupId" :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-h5>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<coreshop-share-wx :shareType='$globalConstVars.shareType.group' :groupId="groupId" :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-wx>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<coreshop-share-alipay :shareType='$globalConstVars.shareType.group' :groupId="groupId" :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-alipay>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<coreshop-share-tt :shareType='$globalConstVars.shareType.group' :groupId="groupId" :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-tt>
<!-- #endif -->
<!-- #ifdef APP-PLUS || APP-PLUS-NVUE -->
<coreshop-share-app :shareType='$globalConstVars.shareType.group' :groupId="groupId" :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-app>
<!-- #endif -->
</u-popup>
<div id="qrCode" ref="qrCodeDiv"></div>
</view>
<!--常见问题-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-margin-bottom-30 coreshop-common-view-box">
<view class="coreshop-font-md coreshop-padding-bottom-20 coreshop-flex-direction-row">
<u-icon name="question-circle" color="#e54d42" label="常见说明" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-flex coreshop-flex-wrap coreshop-margin-bottom-10 coreshop-flex-direction-row" v-for="(item, index) in serviceDescription.commonQuestion" :key="index">
<view class="coreshop-basis-2">
{{item.title}}
</view>
<view class="coreshop-basis-8">
<view class="coreshop-font-12">{{item.description}}</view>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-text-center coreshop-text-blue coreshop-padding-top-10" @tap="goArticleList()">查看更多问题</view>
</view>
<!--商家及推荐-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box coreshop-goods-shop-info-view-box">
<view class="coreshop-shop-view">
<view class="coreshop-position-absolute">
<u-avatar :src="shopLogo"></u-avatar>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-left-40 coreshop-padding-right-40">
<view class="coreshop-margin-bottom-5">{{shopName}}</view>
<view class="coreshop-font-sm u-line-1">{{shareTitle}}</view>
</view>
<u-button type="error" size="mini" :plain="true" @click="doPhoneCall">联系商家</u-button>
</view>
<view class="coreshop-solid-bottom coreshop-padding-top-5 coreshop-padding-bottom-5" />
<view class="live-tag-view coreshop-margin-top-10 coreshop-margin-bottom-10">
<view class="text-view">
<view class="location-tag"><u-tag text="已定位" mode="plain" size="mini" type="warning" /></view>
<text class="coreshop-margin-left-10 u-line-1">可直接获取商家地理位置信息</text>
</view>
<view class="coreshop-font-sm coreshop-text-red go-map-box" @tap="goShopMap">
<text class="coreshop-margin-right-10">去地图</text>
<u-icon name="arrow-right"></u-icon>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-good-shop-recommend-list-box">
<view class="coreshop-font-sm coreshop-padding-top-10 ">本店推荐</view>
<!--滑动列表-->
<view class="recommend-scroll-box">
<scroll-view class="recommend-scroll" scroll-x>
<block v-for="(items,indexs) in shopRecommendData" :key="indexs">
<view :id="['scroll' + (indexs + 1 )]" class="recommend-scroll-item" @tap="goGoodsDetail(items.id)">
<u--image :src="items.image" mode="widthFix" width="91px" height="91px" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-min-height-34">{{items.name}}</view>
<view class="coreshop-text-red coreshop-text-price coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-font-md coreshop-flex-direction-row">
{{items.price}}
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
<!--为您推荐-->
<view class="coreshop-recommended-title-view">
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
<view class="coreshop-flex-4 coreshop-text-right">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
<view class="coreshop-flex-4 coreshop-text-center">
<text class="coreshop-text-black coreshop-font-lg">为您推荐</text>
</view>
<view class="coreshop-flex-4 coreshop-text-left">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
</view>
</view>
<!--推荐列表-->
<view class="coreshop-goods-group" v-if="otherRecommendData.length>0">
<u-grid col="2" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0px'}" v-for="(item, index) in otherRecommendData" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image :src="item.image" mode="widthFix" width="100%" height="174px" radius="10"></u--image>
<view class="good_title u-line-2 coreshop-min-height-34">
{{item.name}}
</view>
<view class="good-price">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<u-popup class="coreshop-bottom-popup-box" :show="bottomModal" mode="bottom" height="70%" @close="hideModal" :closeable="true">
<view class="radius coreshop-bg-white">
<!--标题-->
<view class="coreshop-text-black coreshop-text-center coreshop-margin-top-15 coreshop-margin-bottom-15 coreshop-font-lg coreshop-title-bar">
<text>{{modalTitle}}</text>
</view>
<!--内容区域-->
<view class="coreshop-modal-content">
<!--服务区域-->
<view class="coreshop-common-view-box service" v-if="modalType=='service'">
<view v-for="(item, index) in serviceDescription.service" :key="index">
<view class="coreshop-font-md coreshop-padding-bottom-10 coreshop-padding-top-10 coreshop-flex-direction-row">
<u-icon name="checkmark-circle" color="#e54d42" :label="item.title" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-font-sm coreshop-text-gray coreshop-padding-bottom-5 coreshop-padding-top-5">
{{item.description}}
</view>
</view>
</view>
<!--促销区域-->
<view class="coreshop-common-view-box promotion" v-if="modalType=='promotion'">
<view class="text-view" v-for="(item, index) in promotion" :key="index">
<text class="cu-tag line-orange radius sm">{{item.name}}</text>
<text class="coreshop-margin-left-10 u-line-5 coreshop-text-black">{{item.name}}</text>
</view>
</view>
</view>
</view>
</u-popup>
<!--占位底部距离-->
<view class="coreshop-tabbar-height" />
<!--底部操作-->
<view class="coreshop-good-footer-fixed">
<view class="tabbar">
<view class="coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<!-- 客服按钮 -->
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
<view class="action" @click="showChat()">
<button class="noButtonStyle">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="action">
<button open-type="contact" bindcontact="showChat" class="noButtonStyle" :send-message-title="goodsInfo.name" :send-message-path="'/pages/goods/goodDetails/goodDetails?id='+goodsInfo.id" :send-message-img="goodsInfo.image" show-message-card="true">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<view class="action" @click="collection">
<button class="noButtonStyle">
<u-icon name="star-fill" :size="20" label="已收藏" :labelSize="12" labelPos="bottom" v-if="isfav"></u-icon>
<u-icon name="star" :size="20" label="加收藏" :labelSize="12" labelPos="bottom" v-else></u-icon>
</button>
</view>
<view class="action" @click="redirectCart">
<button class="noButtonStyle">
<u-badge type="warning" :value="cartNums" showZero="false" absolute="true" :offset="[1, 4]"></u-badge>
<u-icon name="shopping-cart" :size="20" label="购物车" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
</view>
<view class="btn-group coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<u-button type="error" size="normal" @click="openSkuPopup" shape="circle" color="#f37b1d">立即团购</u-button>
</view>
</view>
</view>
<vk-data-goods-sku-popup ref="skuPopup"
v-model="skuKey"
border-radius="20"
:amount-type="0"
:localdata="goodsSkuInfo"
mode="3"
@add-cart="addCart"
@buy-now="buyNow"></vk-data-goods-sku-popup>
<!-- 右边浮动球 -->
<coreshop-fab horizontal="right" vertical="bottom" direction="vertical"></coreshop-fab>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
// 是否打开SKU弹窗
skuKey: false,
// 后端返回的商品信息
goodsSkuInfo: {},
goodsId: 0, // 商品id
groupId: 0, // 团购ID
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 规格详情
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
type: 2,
cartType: this.$globalConstVars.paymentType.group,
isfav: false, // 商品是否收藏
//拼团列表滑动数据
swiperSet: {
indicatorDots: false,
autoplay: false,
interval: 2000,
duration: 500,
groupHeight: '',
},
bottomModal: false,
modalTitle: '',
modalType: 'promotion',
selectType: '',
shareUrl: '/pages/share/jump/jump',
shareBox: false,
serviceDescription: {
commonQuestion: [],
delivery: [],
service: [],
}
};
},
onLoad(e) {
this.goodsId = e.id;
this.groupId = e.groupId;
if (this.goodsId && this.groupId) {
this.getServiceDescription();
this.getGoodsInfo();
this.getGoodsParams();
this.getGoodsComments();
} else {
this.$refs.uToast.show({
message: '获取失败', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
}
// 获取购物车数量
this.getCartNums();
//获取推荐数据
this.getGoodsRecommendList();
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
},
shopName() {
return this.$store.state.config.shopName;
},
shareTitle() {
return this.$store.state.config.shareTitle;
},
shopLogo() {
return this.$store.state.config.shopLogo;
},
// 获取店铺联系人手机号
shopMobile() {
return this.$store.state.config.shopMobile || 0;
},
// 优惠信息重新组装
promotion() {
let arr = [];
if (this.product.promotionList) {
for (let k in this.product.promotionList) {
arr.push(this.product.promotionList[k]);
}
}
return arr;
},
shareHref() {
let pages = getCurrentPages();
let page = pages[pages.length - 1];
// #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId + '&groupId=' + this.groupId;
// #endif
// #ifdef MP-ALIPAY
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId + '&groupId=' + this.groupId;
// #endif
}
},
methods: {
// 打开sku弹出
openSkuPopup() {
this.skuKey = true;
},
closeSkuPopup() {
this.skuKey = false;
},
// 立即购买
buyNow(selectShop) {
var that = this;
uni.showLoading({
title: '加载中'
});
if (!this.hasLogin) {
uni.hideLoading();
this.$store.commit('showLoginTip', true);
return false;
}
if (selectShop.buy_num > 0) {
let data = {
ProductId: selectShop._id,
Nums: selectShop.buy_num,
type: this.type,
cartType: this.cartType,
objectId: this.groupId
};
this.$u.api.addCart(data).then(res => {
if (res.status) {
let cartIds = res.data;
this.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds) + '&orderType=' + this.cartType + '&objectId=' + this.groupId);
uni.hideLoading();
} else {
this.$u.toast(res.msg);
uni.hideLoading();
}
});
}
that.closeSkuPopup();
},
getServiceDescription() {
let _this = this;
this.$u.api.getServiceDescription().then(res => {
console.log(res);
if (res.status == true) {
_this.serviceDescription.commonQuestion = res.data.commonQuestion;
_this.serviceDescription.delivery = res.data.delivery;
_this.serviceDescription.service = res.data.service;
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
})
},
getGoodsInfo() {
let data = {
id: this.goodsId,
groupId: this.groupId,
type: "group",
needSku: true,
};
// 如果用户已经登录 要传用户token
let userToken = this.$db.get('userToken');
if (userToken) {
data.token = userToken;
}
let _this = this;
this.$u.api.groupInfo(data).then(res => {
if (res.status) {
if (res.data.length < 1) {
_this.$refs.uToast.show({
message: '该商品不存在,请返回重新选择商品。', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
} else if (res.data.isMarketable == false) {
_this.$refs.uToast.show({
message: '该商品已下架,请返回重新选择商品。', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
} else {
let info = res.data;
_this.product = res.data.product;
_this.goodsInfo = info;
this.goodsSkuInfo = res.data.skuList;
if (_this.goodsInfo.album) {
var albums = [];
for (var i = 0; i < _this.goodsInfo.album.length; i++) {
let album = {
url: _this.goodsInfo.album[i],
type: 'image'
}
albums.push(album);
}
_this.goodsInfo.album = albums;
if (_this.goodsInfo.video) {
let videoObj = {
url: _this.goodsInfo.video,
poster: _this.goodsInfo.image,
type: 'video'
}
_this.goodsInfo.album.unshift(videoObj);
_this.autoplay = false;
}
}
_this.isfav = _this.goodsInfo.isfav;
_this.type = _this.goodsInfo.groupType;
// 判断如果登录用户添加商品浏览足迹
if (userToken) {
_this.goodsBrowsing();
}
}
}
});
},
// 获取推荐商品信息
getGoodsRecommendList() {
let _this = this;
let recommenddata = {
id: 10,
data: true
}
_this.$u.api.getGoodsRecommendList(recommenddata).then(res => {
if (res.status) {
_this.shopRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
let data = {
id: 10
}
_this.$u.api.getGoodsRecommendList(data).then(res => {
if (res.status) {
_this.otherRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
},
// 获取购物车数量
getCartNums() {
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
// 获取购物车数量
this.$u.api.getCartNum().then(res => {
if (res.status) {
this.cartNums = res.data;
}
});
}
},
// 商品收藏/取消
collection() {
let data = {
id: this.goodsInfo.id
};
this.$u.api.goodsCollection(data).then(res => {
if (res.status) {
this.isfav = !this.isfav;
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false });
} else {
this.$u.toast(res.msg);
}
});
},
// 获取商品参数信息
getGoodsParams() {
this.$u.api.goodsParams(
{
id: this.goodsId
}).then(res => {
if (res.status == true) {
this.goodsParams = res.data;
}
}
);
},
// 获取商品评论信息
getGoodsComments() {
let data = {
page: 1,
limit: 5,
id: this.goodsId,
}
this.$u.api.goodsComment(data).then(res => {
if (res.status == true) {
let _list = res.data.list;
// 如果评论没有图片 在这块作处理否则控制台报错
_list.forEach(item => {
if (!item.hasOwnProperty('images')) {
this.$set(item, 'images', [])
}
});
this.goodsComments = [...this.goodsComments, ..._list];
} else {
this.$u.toast(res.msg);
}
})
},
// 添加商品浏览足迹
goodsBrowsing() {
let data = {
id: this.goodsInfo.id
};
this.$u.api.addGoodsBrowsing(data).then(res => { });
},
// 点击弹出框确定按钮事件处理
clickHandle() {
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
this.submitStatus = true;
this.buyNow();
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(index) {
if (this.goodsInfo.album[index].type == 'image') {
uni.previewImage({
urls: [this.goodsInfo.album[index].url],
});
}
},
//在线客服
showChat() {
// #ifdef H5
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 9,
params: {
goodsId: this.goodsId,
groupId: this.groupId
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
},
serviceTap() {
this.modalTitle = "说明";
this.modalType = 'service';
this.showModal();
},
promotionTap() {
this.modalTitle = "促销优惠";
this.modalType = 'promotion';
this.showModal();
},
showModal() {
this.bottomModal = true;
},
hideModal(e) {
this.bottomModal = false;
this.modalTitle = "";
this.modalType = '';
},
},
watch: {
goodsId: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
};
</script>
<style lang="scss">
image { display: block; }
</style>

View File

@@ -0,0 +1,3 @@
.goods-item { margin-bottom: 1px;
.progress-text { color: #999999; font-size: 10px; margin-left: 12px; }
}

View File

@@ -0,0 +1,151 @@
<template>
<view class="pageBox">
<u-navbar title="团购" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="goods-item" v-for="item in goodsList" :key="item.id" v-if="goodsList.length>0">
<view class="activity-goods-box coreshop-flex coreshop-justify-between">
<view class="img-box">
<slot name="tag"></slot>
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
<view class="goods-right coreshop-flex coreshop-justify-between coreshop-flex-direction">
<view class="title u-line-2">{{ item.name }}</view>
<view class="tip u-line-1">{{ item.brief }}</view>
<view class="slod-end">
<view class="coreshop-flex coreshop-align-center">
<u-line-progress :percentage="getPercent(item.buyPromotionCount, item.stock)"></u-line-progress>
<view class="progress-text">已抢{{ getProgress(item.buyPromotionCount, item.stock) }}</view>
</view>
</view>
<view class="coreshop-flex coreshop-justify-between coreshop-margin-top-10">
<view class="coreshop-flex coreshop-align-center">
<view class="current">{{ item.price }}</view>
<view class="original">{{ item.mktprice }}</view>
</view>
<view class="coreshop-width-fit-content">
<u-button type="error" size="mini" v-if="tabCurrent=='ing'" @click="goGroupBuyingDetail(item.id, item.groupId)">{{ btnType[tabCurrent].name }}</u-button>
<u-button type="error" size="mini" v-else>{{ btnType[tabCurrent].name }}</u-button>
</view>
</view>
</view>
</view>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="暂无团购信息" mode="list"></u-empty>
</view>
<!-- 加载更多 -->
<u-loadmore :status="loadStatus" :icon-type="iconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
loadStatus: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
},
loading: false,
page: 1,
limit: 10,
lastPage: 1,
status: 1,
tabCurrent: 'ing',
goodsList: [],
btnType: {
ing: {
name: '立即抢购',
},
nostart: {
name: '尚未开始',
},
ended: {
name: '已结束',
},
},
};
},
onLoad() {
this.loading = true;
this.getGoodsList();
},
onReachBottom() {
if (this.loadStatus === 'loadmore') {
this.getGoodsList()
}
},
methods: {
// 百分比
getProgress(sales, stock) {
let unit = '';
if (stock + sales > 0) {
let num = (sales / (sales + stock)) * 100;
unit = num.toFixed(2) + '%';
} else {
unit = '0%';
}
return unit;
},
// 进度数
getPercent(sales, stock) {
let unit = 0;
if (stock + sales > 0) {
let num = (sales / (sales + stock)) * 100;
} else {
unit = 30;
}
return unit;
},
// 秒杀列表
getGoodsList() {
let _this = this;
let data = {
page: this.page,
limit: this.limit,
type: 3, //团购
status: this.status
}
this.loadStatus = 'loading';
this.$u.api.getGroup(data).then(res => {
if (res.status) {
if (res.data) {
let _goodsList = res.data.goods;
_this.goodsList = [..._this.goodsList, ..._goodsList]
}
_this.lastPage = res.data.totalPages;
if (_this.page < res.data.totalPages) {
_this.page++
_this.loadStatus = 'loadmore'
} else {
_this.loadStatus = 'nomore'
}
} else {
_this.$u.toast(res.msg)
}
});
}
}
}
</script>
<style lang="scss" scoped>
@import "list.scss";
</style>

View File

@@ -0,0 +1,5 @@
.group-wrap { background: url('/static/images/pinTuan/pinTuanListBg.png') no-repeat; background-size: 100% 186px; }
.group-head { padding: 0 12.5px; height: 50px; line-height: 50px;
.group-head__title { font-size: 16px; font-family: PingFang SC; font-weight: 500; color: rgba(255, 255, 255, 1); }
.group-head__notice { font-size: 13px; font-family: PingFang SC; font-weight: 500; color: rgba(255, 255, 255, 1); }
}

View File

@@ -0,0 +1,110 @@
<template>
<view>
<u-navbar title="拼团" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="content">
<!-- 列表图片 -->
<scroll-view class="scroll-box" scroll-y>
<view class="group-wrap coreshop-bg-red">
<view class="group-head coreshop-flex coreshop-justify-between">
<text class="group-head__title">爆款推荐</text>
<text class="group-head__notice">省钱省心限时拼</text>
</view>
<view class="group-box">
<view class="goods-item" v-for="(item, index) in goodsList" :key="item.id" v-if="goodsList.length>0">
<view class="activity-goods-box coreshop-flex coreshop-justify-start">
<view class="img-box">
<view class="tag" v-if="index < 3">TOP{{ index + 1 }}</view>
<u--image :src="item.image" mode="widthFix" width="100%" height="104px" radius="10"></u--image>
</view>
<view class="goods-right coreshop-flex coreshop-flex-direction">
<view class="title u-line-2">{{ item.name }}</view>
<view class="tip u-line-1">{{ item.brief }}</view>
<view class="slod-end">
<view class="coreshop-flex coreshop-align-center">
<view class="sell-box">
<text class="cuIcon-hotfill"></text>
<text class="sell-num">已拼{{ item.buyPinTuanCount }}</text>
</view>
<text class="group-num">{{ item.pinTuanRule.peopleNumber || 0 }}人团</text>
</view>
</view>
<view class="coreshop-flex coreshop-justify-between coreshop-margin-top-2">
<view class="coreshop-flex coreshop-align-center">
<view class="current">{{ item.pinTuanPrice }}</view>
<view class="original">{{ item.price }}</view>
</view>
<button class="cu-btn buy-btn" @tap="goPinTuanDetail(item.id,item.pinTuanRule.id)">马上拼</button>
</view>
</view>
</view>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/history.png'" icon-size="150" text="暂无提现明细" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 空白 -->
</scroll-view>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
goodsList: [],
status: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
}
};
},
//加载执行
onShow: function () {
this.getGoods();
},
methods: {
//取得列表数据
getGoods: function () {
var _this = this;
let data = {};
_this.$u.api.pinTuanList(data).then(res => {
if (res.status) {
_this.goodsList = res.data;
if (_this.goodsList) {
_this.goodsList.forEach(item => {
if (item.pinTuanPrice <= 0) {
item.pinTuanPrice = '0.00';
} else {
item.pinTuanPrice = this.$common.moneySub(item.price, item.pinTuanRule.discountAmount);
}
});
}
}
});
}
}
};
</script>
<style lang="scss">
@import "list.scss";
</style>

View File

@@ -0,0 +1,36 @@

.groupHeight { height: 61px !important; }
.group-swiper-c { height: 121px; }
.group-swiper-c .swiper-item .coreshop-cell-item { height: 50%; }
.group-swiper-c .swiper-item .coreshop-cell-item .user-head-img { width: 40px; height: 40px; border-radius: 50%; }
.group-swiper-c .swiper-item .coreshop-cell-item .coreshop-cell-hd-title { max-width: 100px; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.group-swiper-c .swiper-item .coreshop-cell-item .coreshop-cell-item-bd { min-width: 75px; text-align: center; display: block; }
.group-swiper-c .swiper-item .coreshop-cell-item .coreshop-cell-item-bd .coreshop-cell-bd-view { margin-bottom: 0; }
.group-swiper-c .swiper-item .coreshop-cell-item .coreshop-cell-item-bd .coreshop-cell-bd-text { float: none; }
.group-swiper-c .commodity-day > text { background: none !important; padding: 0; }
.group-swiper-c .swiper-item .coreshop-cell-item .coreshop-cell-item-ft .btn { font-size: 13px; color: #fff; background-color: #ff7159; text-align: center; }
.ig-top { text-align: center; background-color: #fff; padding: 10px 13px; width: 100%; height: 125px; background: #FFFFFF; }
.ig-top-t,
.ig-top-m { margin-bottom: 10px; }
.ig-top-t > view { display: inline-block; padding: 0 5px; color: #999; }
.user-head-img-c { position: relative; width: 40px; height: 40px; border-radius: 50%; margin-right: 10px; box-sizing: border-box; display: inline-block; border: 1px solid #f3f3f3; }
.user-head-img-tip { position: absolute; top: -3px; left: -5px; display: inline-block; background-color: #FF7159; color: #fff; font-size: 11px; z-index: 98; padding: 0 5px; border-radius: 5px; transform: scale(.8); }
.user-head-img-c .user-head-img { width: 100%; height: 100%; border-radius: 50%; }
.user-head-img-c:first-child { border: 1px solid #FF7159; }
.uhihn { width: 40px; height: 40px; border-radius: 50%; display: inline-block; border: 1px dashed #e1e1e1; text-align: center; color: #d1d1d1; font-size: 20px; box-sizing: border-box; position: relative; }
.uhihn > text { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.igtb-top { font-size: 16px; color: #333; margin-bottom: 8px; }
.igtb-mid { margin-bottom: 8px; }
.igtb-mid .coreshop-btn { width: 100%; background-color: #FF7159; color: #fff; }
.igtb-bot { font-size: 12px; color: #666; }
.coreshop-cell-ft-text { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-notice .coreshop-cell-ft-text { color: #999; margin-left: 10px; font-size: 13px; }
.coreshop-lower-shelf { }
.coreshop-lower-shelf .coreshop-cell-item-hd { opacity: 0.4; }
.coreshop-lower-shelf .coreshop-cell-item-bd { opacity: 0.4; }
.coreshop-lower-shelf .coreshop-cell-item-ft { opacity: 0.4; }
.coreshop-lower-shelf .coreshop-lower-box { position: absolute; height: calc(100% - 20px); width: calc(100% - 10px); background-color: rgba(0, 0, 0, 0.6); text-align: center; font-size: 14px; color: #dedede; -webkit-transition: left .15s; transition: left .15s; z-index: 999; -webkit-transition: all .15s; transition: all .15s; line-height: 40px; }

View File

@@ -0,0 +1,10 @@
.tab-box {
.tab-item { flex: 1; line-height: 42px; text-align: center; background: #636363; color: #fff; font-size: 14px; font-family: PingFang SC; font-weight: 500; color: #ffffff; position: relative; border-right: 0.5px solid #fff;
.tab-triangle { position: absolute; z-index: 2; bottom: -7px; left: 50%; transform: translateX(-50%); width: 14px; height: 14px; background: #e54d42; transform: rotate(45deg); transform-origin: center; }
}
.tab-active { background: #e54d42; }
}
.goods-item { margin-bottom: 1px;
.progress-text { color: #999999; font-size: 10px; margin-left: 12px; }
}

View File

@@ -0,0 +1,200 @@
<template>
<view class="pageBox">
<u-navbar title="限时秒杀" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="tab-box coreshop-flex coreshop-align-center">
<view class="tab-item" @tap="onTab(tab.id,tab.status)" :class="{ 'tab-active': tabCurrent === tab.id }" v-for="tab in tabList" :key="tab.id">
<text class="tab-title">{{ tab.title }}</text>
<text v-show="tabCurrent === tab.id" class="tab-triangle"></text>
</view>
</view>
<view class="content-box">
<scroll-view scroll-y="true" enable-back-to-top @scrolltolower="loadMore" class="scroll-box">
<view class="goods-item" v-for="item in goodsList" :key="item.id" v-if="goodsList.length>0">
<view class="activity-goods-box coreshop-flex coreshop-justify-between">
<view class="img-box">
<slot name="tag"></slot>
<image class="img" :src="item.image" mode="aspectFill"></image>
</view>
<view class="goods-right coreshop-flex coreshop-justify-between coreshop-flex-direction">
<view class="title u-line-2">{{ item.name }}</view>
<view class="tip u-line-1">{{ item.brief }}</view>
<view class="slod-end">
<view class="coreshop-flex coreshop-align-center">
<u-line-progress :percentage="getPercent(item.buyPromotionCount, item.stock)"></u-line-progress>
<view class="progress-text">已抢{{ getProgress(item.buyPromotionCount, item.stock) }}</view>
</view>
</view>
<view class="coreshop-flex coreshop-justify-between coreshop-margin-top-10">
<view class="coreshop-flex coreshop-align-center">
<view class="current">{{ item.price }}</view>
<view class="original">{{ item.mktprice }}</view>
</view>
<view class="coreshop-width-fit-content">
<u-button type="error" class="buy-btn" size="mini" v-if="tabCurrent=='ing'" @click="goSeckillDetail(item.id, item.groupId)">{{ btnType[tabCurrent].name }}</u-button>
<u-button type="error" class="buy-btn" size="mini" v-else>{{ btnType[tabCurrent].name }}</u-button>
</view>
</view>
</view>
</view>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="暂无秒杀信息" mode="list"></u-empty>
</view>
<!-- 加载更多 -->
<u-loadmore :status="loadStatus" :icon-type="iconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
</scroll-view>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
loadStatus: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
},
loading: false,
page: 1,
limit: 10,
lastPage: 1,
status: 1,
tabCurrent: 'ing',
goodsList: [],
btnType: {
ing: {
name: '立即抢购',
color: 'btn-ing'
},
nostart: {
name: '尚未开始',
color: 'btn-nostart'
},
ended: {
name: '已结束',
color: 'btn-end',
},
},
tabList: [
{
id: 'ing',
title: '进行中',
status: 1
},
{
id: 'nostart',
title: '即将开始',
status: 0
},
{
id: 'ended',
title: '已结束',
status: 2
},
]
};
},
onLoad() {
setTimeout(() => {
this.loading = true;
}, 500);
this.getGoodsList();
},
//onReachBottom() {
// if (this.loadStatus === 'loadmore') {
// this.getGoodsList()
// }
//},
methods: {
onTab(id, status) {
this.tabCurrent = id;
this.status = status;
this.goodsList = [];
this.page = 1;
this.loadStatus = 'loading';
this.$u.debounce(this.getGoodsList, 500);
},
// 百分比
getProgress(sales, stock) {
let unit = '';
if (stock + sales > 0) {
let num = (sales / (sales + stock)) * 100;
unit = num.toFixed(2) + '%';
} else {
unit = '0%';
}
return unit;
},
// 进度数
getPercent(sales, stock) {
let unit = 0;
if (stock + sales > 0) {
let num = (sales / (sales + stock)) * 100;
} else {
unit = 30;
}
return unit;
},
// 加载更多
loadMore() {
if (this.page < this.lastPage) {
this.page += 1;
this.getGoodsList();
}
},
// 秒杀列表
getGoodsList() {
let _this = this;
let data = {
page: this.page,
limit: this.limit,
type: 4, //秒杀
status: this.status
}
this.loadStatus = 'loading';
this.$u.api.getGroup(data).then(res => {
if (res.status) {
if (res.data) {
let _goodsList = res.data.goods;
_this.goodsList = [..._this.goodsList, ..._goodsList]
}
_this.lastPage = res.data.totalPages;
if (_this.page < res.data.totalPages) {
_this.page++
_this.loadStatus = 'loadmore'
} else {
_this.loadStatus = 'nomore'
}
} else {
_this.$u.toast(res.msg)
}
});
}
}
}
</script>
<style lang="scss" scoped>
@import "list.scss";
</style>

View File

@@ -0,0 +1,784 @@
<template>
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="秒杀详情" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="share-fill" size="22" @click="goShare"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<!--幻灯片-->
<view class="coreshop-full-screen-banner-swiper-box">
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<!--限时秒杀-->
<view class="coreshop-limited-seckill-box coreshop-bg-mauve">
<text class="coreshop-text-price coreshop-font-20">{{ product.price || '0.00' }}</text>
<view class="coreshop-font-xs coreshop-cost-price-num price-4">
<view>已售{{ goodsInfo.buyCount || '0' }}/剩余{{ product.stock || '0' }}</view>
<view>累计销售{{ goodsInfo.buyCount || '0' }}</view>
</view>
<view class="coreshop-text-right coreshop-time-right">
<view>距结束仅剩</view>
<u-count-down :time="goodsInfo.groupTimestamp*1000" :autoStart="true" :millisecond="true" format="DD天HH时mm秒ss"></u-count-down>
</view>
</view>
<!--标题-->
<view class="coreshop-bg-white coreshop-common-view-box coreshop-good-title-view-box">
<view class="title-view coreshop-text-black coreshop-font-lg coreshop-text-bold">
<view class="brand-tag" v-if="goodsInfo.brand"><u-tag :text="goodsInfo.brand.name" type="error" size="mini" /></view>
{{ goodsInfo.name || '' }}
</view>
<view class="coreshop-bg-red-light radius coreshop-margin-top-10 coreshop-title-tip-box">
<text class="coreshop-font-sm">{{ goodsInfo.brief || '' }}</text>
</view>
</view>
<!--服务-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">服务</text>
</view>
<view class="coreshop-basis-8">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<u-icon name="checkmark-circle" size="12" labelSize="12" color="#e54d42" :label="item.title" v-for="(item, index) in serviceDescription.service" :key="index" class="coreshop-margin-right-10"></u-icon>
</view>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--发货/规格-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="serviceDescription.delivery.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">发货</text>
</view>
<view class="coreshop-coreshop-basis-9" v-for="(item, index) in serviceDescription.delivery" :key="index">
<text class="coreshop-font-sm">{{item.description}}</text>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" v-if="serviceDescription.delivery.length>0" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10" @tap="openSkuPopup()" v-if="isSpes">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">规格</text>
</view>
<view class="coreshop-basis-8">
<text class="coreshop-font-sm">{{ product.spesDesc || ''}}</text>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--评论-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-10" v-if="goodsComments.length">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10 coreshop-flex-direction-row">
<view class="coreshop-basis-2">
<text class="coreshop-text-black coreshop-font-md">评价{{goodsComments.length}}</text>
</view>
<view class="coreshop-basis-7"></view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right" @tap="goGoodComments(goodsInfo.id)"></u-icon>
</view>
</view>
</view>
<view v-for="(item, index) in goodsComments" :key="index">
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-10 coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<view class="coreshop-avatar sm round" :style="[{backgroundImage:'url('+ item.avatarImage +')'}]" />
</view>
<view class="coreshop-basis-9 coreshop-font-sm">
<view>{{ (item.nickName && item.nickName != '')?item.nickName:item.mobile }}</view>
<view class="coreshop-margin-top-10">{{ item.contentBody || ''}}</view>
<view class="coreshop-text-gray coreshop-margin-top-5">
<u-rate v-model="item.score" :count="5" size="13"></u-rate>
</view>
<view class="coreshop-margin-top-10" v-if="item.imagesArr">
<u-album :urls="item.imagesArr" rowCount="4"></u-album>
</view>
<view class="coreshop-text-gray coreshop-margin-top-5 coreshop-font-12">{{ item.createTime || ''}} {{ item.addon || ''}}</view>
</view>
</view>
</view>
</view>
<!--内容区-->
<view class="coreshop-margin-top-10 coreshop-bg-white">
<view class="coreshop-font-md coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row">
<u-icon name="more-circle" color="#e54d42" label="商品详情" labelSize="15px" label-pos="right"></u-icon>
</view>
<!--参数-->
<view class="coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row" v-for="(item, index) in goodsParams" :key="index">
<text class="coreshop-text-gray">{{ item.name || ''}}</text>
<text class="coreshop-text-black">{{ item.value || ''}}</text>
</view>
<view class="coreshop-padding-10">
<u-parse :content="goodsInfo.intro" :selectable="true" v-if="goodsInfo.intro"></u-parse>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="详情为空" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 分享弹窗 -->
<view class="coreshop-padding-0">
<u-popup mode="bottom" :show="shareBox" ref="share">
<!-- #ifdef H5 -->
<coreshop-share-h5 :shareType='$globalConstVars.shareType.seckill' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-h5>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<coreshop-share-wx :shareType='$globalConstVars.shareType.seckill' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-wx>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<coreshop-share-alipay :shareType='$globalConstVars.shareType.seckill' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-alipay>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<coreshop-share-tt :shareType='$globalConstVars.shareType.seckill' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-tt>
<!-- #endif -->
<!-- #ifdef APP-PLUS || APP-PLUS-NVUE -->
<coreshop-share-app :shareType='$globalConstVars.shareType.seckill' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-app>
<!-- #endif -->
</u-popup>
<div id="qrCode" ref="qrCodeDiv"></div>
</view>
<!--常见问题-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-margin-bottom-30 coreshop-common-view-box">
<view class="coreshop-font-md coreshop-padding-bottom-20 coreshop-flex-direction-row">
<u-icon name="question-circle" color="#e54d42" label="常见说明" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-flex coreshop-flex-wrap coreshop-margin-bottom-10 coreshop-flex-direction-row" v-for="(item, index) in serviceDescription.commonQuestion" :key="index">
<view class="coreshop-basis-2">
{{item.title}}
</view>
<view class="coreshop-basis-8">
<view class="coreshop-font-12">{{item.description}}</view>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-text-center coreshop-text-blue coreshop-padding-top-10" @tap="goArticleList()">查看更多问题</view>
</view>
<!--商家及推荐-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box coreshop-goods-shop-info-view-box">
<view class="coreshop-shop-view">
<view class="coreshop-position-absolute">
<u-avatar :src="shopLogo"></u-avatar>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-left-40 coreshop-padding-right-40">
<view class="coreshop-margin-bottom-5">{{shopName}}</view>
<view class="coreshop-font-sm u-line-1">{{shareTitle}}</view>
</view>
<u-button type="error" size="mini" :plain="true" @click="doPhoneCall">联系商家</u-button>
</view>
<view class="coreshop-solid-bottom coreshop-padding-top-5 coreshop-padding-bottom-5" />
<view class="live-tag-view coreshop-margin-top-10 coreshop-margin-bottom-10">
<view class="text-view">
<view class="location-tag"><u-tag text="已定位" mode="plain" size="mini" type="warning" /></view>
<text class="coreshop-margin-left-10 u-line-1">可直接获取商家地理位置信息</text>
</view>
<view class="coreshop-font-sm coreshop-text-red go-map-box" @tap="goShopMap">
<text class="coreshop-margin-right-10">去地图</text>
<u-icon name="arrow-right"></u-icon>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-good-shop-recommend-list-box">
<view class="coreshop-font-sm coreshop-padding-top-10 ">本店推荐</view>
<!--滑动列表-->
<view class="recommend-scroll-box">
<scroll-view class="recommend-scroll" scroll-x>
<block v-for="(items,indexs) in shopRecommendData" :key="indexs">
<view :id="['scroll' + (indexs + 1 )]" class="recommend-scroll-item" @tap="goGoodsDetail(items.id)">
<u--image :src="items.image" mode="widthFix" width="91px" height="91px" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-min-height-34">{{items.name}}</view>
<view class="coreshop-text-red coreshop-text-price coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-font-md coreshop-flex-direction-row">
{{items.price}}
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
<!--为您推荐-->
<view class="coreshop-recommended-title-view">
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
<view class="coreshop-flex-4 coreshop-text-right">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
<view class="coreshop-flex-4 coreshop-text-center">
<text class="coreshop-text-black coreshop-font-lg">为您推荐</text>
</view>
<view class="coreshop-flex-4 coreshop-text-left">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
</view>
</view>
<!--推荐列表-->
<view class="coreshop-goods-group" v-if="otherRecommendData.length>0">
<u-grid col="2" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0px'}" v-for="(item, index) in otherRecommendData" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image :src="item.image" mode="widthFix" width="100%" height="174px" radius="10"></u--image>
<view class="good_title u-line-2 coreshop-min-height-34">
{{item.name}}
</view>
<view class="good-price">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<u-popup class="coreshop-bottom-popup-box" :show="bottomModal" mode="bottom" height="70%" @close="hideModal" :closeable="true">
<view class="radius coreshop-bg-white">
<!--标题-->
<view class="coreshop-text-black coreshop-text-center coreshop-margin-top-15 coreshop-margin-bottom-15 coreshop-font-lg coreshop-title-bar">
<text>{{modalTitle}}</text>
</view>
<!--内容区域-->
<view class="coreshop-modal-content">
<!--服务区域-->
<view class="coreshop-common-view-box service" v-if="modalType=='service'">
<view v-for="(item, index) in serviceDescription.service" :key="index">
<view class="coreshop-font-md coreshop-padding-bottom-10 coreshop-padding-top-10 coreshop-flex-direction-row">
<u-icon name="checkmark-circle" color="#e54d42" :label="item.title" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-font-sm coreshop-text-gray coreshop-padding-bottom-5 coreshop-padding-top-5">
{{item.description}}
</view>
</view>
</view>
<!--促销区域-->
<view class="coreshop-common-view-box promotion" v-if="modalType=='promotion'">
<view class="text-view" v-for="(item, index) in promotion" :key="index">
<text class="cu-tag line-orange radius sm">{{item.name}}</text>
<text class="coreshop-margin-left-10 u-line-5 coreshop-text-black">{{item.name}}</text>
</view>
</view>
</view>
</view>
</u-popup>
<!--占位底部距离-->
<view class="coreshop-tabbar-height" />
<!--底部操作-->
<view class="coreshop-good-footer-fixed">
<view class="tabbar">
<view class="coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<!-- 客服按钮 -->
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
<view class="action" @click="showChat()">
<button class="noButtonStyle">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="action">
<button open-type="contact" bindcontact="showChat" class="noButtonStyle" :send-message-title="goodsInfo.name" :send-message-path="'/pages/goods/goodDetails/goodDetails?id='+goodsInfo.id" :send-message-img="goodsInfo.image" show-message-card="true">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<view class="action" @click="collection">
<button class="noButtonStyle">
<u-icon name="star-fill" :size="20" label="已收藏" :labelSize="12" labelPos="bottom" v-if="isfav"></u-icon>
<u-icon name="star" :size="20" label="加收藏" :labelSize="12" labelPos="bottom" v-else></u-icon>
</button>
</view>
<view class="action" @click="redirectCart">
<button class="noButtonStyle">
<u-badge type="warning" :value="cartNums" showZero="false" absolute="true" :offset="[1, 4]"></u-badge>
<u-icon name="shopping-cart" :size="20" label="购物车" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
</view>
<view class="btn-group coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<u-button type="error" size="normal" @click="openSkuPopup()" shape="circle" color="#9c26b0">立即秒杀</u-button>
</view>
</view>
</view>
<vk-data-goods-sku-popup ref="skuPopup"
v-model="skuKey"
border-radius="20"
:amount-type="0"
:localdata="goodsSkuInfo"
mode="3"
@add-cart="addCart"
@buy-now="buyNow"></vk-data-goods-sku-popup>
<!-- 右边浮动球 -->
<coreshop-fab horizontal="right" vertical="bottom" direction="vertical"></coreshop-fab>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
// 是否打开SKU弹窗
skuKey: false,
// 后端返回的商品信息
goodsSkuInfo: {},
goodsId: 0, // 商品id
groupId: 0, // 团购ID
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 规格详情
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
type: 2,
cartType: this.$globalConstVars.paymentType.seckill,
isfav: false, // 商品是否收藏
//拼团列表滑动数据
swiperSet: {
indicatorDots: false,
autoplay: false,
interval: 2000,
duration: 500,
groupHeight: '',
},
bottomModal: false,
modalTitle: '',
modalType: 'promotion',
selectType: '',
shareUrl: '/pages/share/jump/jump',
shareBox: false,
shareType: 10,
serviceDescription: {
commonQuestion: [],
delivery: [],
service: [],
}
};
},
onLoad(e) {
this.goodsId = e.id;
this.groupId = e.groupId;
if (this.goodsId && this.groupId) {
this.getServiceDescription();
this.getGoodsInfo();
this.getGoodsParams();
this.getGoodsComments();
} else {
this.$refs.uToast.show({
message: '获取失败', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
}
// 获取购物车数量
this.getCartNums();
//获取推荐数据
this.getGoodsRecommendList();
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
},
shopName() {
return this.$store.state.config.shopName;
},
shareTitle() {
return this.$store.state.config.shareTitle;
},
shopLogo() {
return this.$store.state.config.shopLogo;
},
// 获取店铺联系人手机号
shopMobile() {
return this.$store.state.config.shopMobile || 0;
},
// 优惠信息重新组装
promotion() {
let arr = [];
if (this.product.promotionList) {
for (let k in this.product.promotionList) {
arr.push(this.product.promotionList[k]);
}
}
return arr;
},
shareHref() {
let pages = getCurrentPages();
let page = pages[pages.length - 1];
// #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId + '&groupId=' + this.groupId;
// #endif
// #ifdef MP-ALIPAY
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId + '&groupId=' + this.groupId;
// #endif
},
},
methods: {
// 打开sku弹出
openSkuPopup() {
this.skuKey = true;
},
closeSkuPopup() {
this.skuKey = false;
},
// 立即购买
buyNow(selectShop) {
var that = this;
uni.showLoading({
title: '加载中'
});
if (!this.hasLogin) {
uni.hideLoading();
this.$store.commit('showLoginTip', true);
return false;
}
if (selectShop.buy_num > 0) {
let data = {
ProductId: selectShop._id,
Nums: selectShop.buy_num,
type: this.type,
cartType: this.cartType,
objectId: this.groupId
};
this.$u.api.addCart(data).then(res => {
if (res.status) {
let cartIds = res.data;
this.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds) + '&orderType=' + this.cartType + '&objectId=' + this.groupId);
uni.hideLoading();
} else {
this.$u.toast(res.msg);
uni.hideLoading();
}
});
}
that.closeSkuPopup();
},
getServiceDescription() {
let _this = this;
this.$u.api.getServiceDescription().then(res => {
console.log(res);
if (res.status == true) {
_this.serviceDescription.commonQuestion = res.data.commonQuestion;
_this.serviceDescription.delivery = res.data.delivery;
_this.serviceDescription.service = res.data.service;
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
})
},
getGoodsInfo() {
let data = {
id: this.goodsId,
groupId: this.groupId,
type: "seckill",
needSku: true
};
// 如果用户已经登录 要传用户token
let userToken = this.$db.get('userToken');
if (userToken) {
data['token'] = userToken;
}
let _this = this;
this.$u.api.groupInfo(data).then(res => {
if (res.status) {
if (res.data.length < 1) {
_this.$refs.uToast.show({
message: '该商品不存在,请返回重新选择商品。', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
uni.hideLoading();
} else if (res.data.isMarketable == false) {
_this.$refs.uToast.show({
message: '该商品已下架,请返回重新选择商品。', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
} else {
let info = res.data;
this.product = res.data.product;
_this.goodsInfo = info;
this.goodsSkuInfo = res.data.skuList;
if (_this.goodsInfo.album) {
var albums = [];
for (var i = 0; i < _this.goodsInfo.album.length; i++) {
let album = {
url: _this.goodsInfo.album[i],
type: 'image'
}
albums.push(album);
}
_this.goodsInfo.album = albums;
if (_this.goodsInfo.video) {
let videoObj = {
url: _this.goodsInfo.video,
poster: _this.goodsInfo.image,
type: 'video'
}
_this.goodsInfo.album.unshift(videoObj);
_this.autoplay = false;
}
}
_this.isfav = _this.goodsInfo.isfav;
_this.type = _this.goodsInfo.groupType;
// 判断如果登录用户添加商品浏览足迹
if (userToken) {
_this.goodsBrowsing();
}
}
}
});
},
// 获取推荐商品信息
getGoodsRecommendList() {
let _this = this;
let recommenddata = {
id: 10,
data: true
}
_this.$u.api.getGoodsRecommendList(recommenddata).then(res => {
if (res.status) {
_this.shopRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
let data = {
id: 10
}
_this.$u.api.getGoodsRecommendList(data).then(res => {
if (res.status) {
_this.otherRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
},
// 获取购物车数量
getCartNums() {
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
// 获取购物车数量
this.$u.api.getCartNum().then(res => {
if (res.status) {
this.cartNums = res.data;
}
});
}
},
// 商品收藏/取消
collection() {
let data = {
id: this.goodsInfo.id
};
this.$u.api.goodsCollection(data).then(res => {
if (res.status) {
this.isfav = !this.isfav;
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false });
} else {
this.$u.toast(res.msg);
}
});
},
// 获取商品参数信息
getGoodsParams() {
this.$u.api.goodsParams(
{
id: this.goodsId
}).then(res => {
if (res.status == true) {
this.goodsParams = res.data;
}
}
);
},
// 获取商品评论信息
getGoodsComments() {
let data = {
page: 1,
limit: 5,
id: this.goodsId,
}
this.$u.api.goodsComment(data).then(res => {
if (res.status == true) {
let _list = res.data.list;
// 如果评论没有图片 在这块作处理否则控制台报错
_list.forEach(item => {
if (!item.hasOwnProperty('images')) {
this.$set(item, 'images', [])
}
});
this.goodsComments = [...this.goodsComments, ..._list];
} else {
console.log("错误2");
this.$u.toast(res.msg);
}
})
},
// 添加商品浏览足迹
goodsBrowsing() {
let data = {
id: this.goodsInfo.id
};
this.$u.api.addGoodsBrowsing(data).then(res => { });
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(index) {
if (this.goodsInfo.album[index].type == 'image') {
uni.previewImage({
urls: [this.goodsInfo.album[index].url],
});
}
},
//在线客服
showChat() {
// #ifdef H5
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: this.shareType,
params: {
goodsId: this.goodsId,
groupId: this.groupId
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data.token = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
},
serviceTap() {
this.modalTitle = "说明";
this.modalType = 'service';
this.showModal();
},
promotionTap() {
this.modalTitle = "促销优惠";
this.modalType = 'promotion';
this.showModal();
},
hideModal(e) {
this.bottomModal = false;
this.modalTitle = "";
this.modalType = '';
},
},
watch: {
goodsId: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
};
</script>
<style lang="scss">
.buyBtn { height: 37px; width: 90%; }
image { display: block; }
</style>

View File

@@ -0,0 +1,128 @@
<template>
<view>
<u-navbar title="接龙" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="solitaire-details-bg"></view>
<view class="solitaire-details-placeholder-body" />
<!--商家及推荐-->
<view class="coreshop-margin-20 coreshop-goods-shop-info-view-box">
<view class="coreshop-shop-view">
<view class="coreshop-position-absolute">
<u-avatar :src="shopLogo" shape="square"></u-avatar>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-left-40 coreshop-padding-right-40">
<view class="coreshop-margin-bottom-5 coreshop-text-white">{{shopName || ' '}}</view>
<view class="coreshop-font-sm u-line-1 coreshop-text-white">{{shareTitle || ' '}}</view>
</view>
<u-button type="default" size="mini" :plain="true" @click="doPhoneCall" icon="phone" text="联系商家" color="#272d47"></u-button>
</view>
</view>
<view class="page-box coreshop-margin-top-20" v-if="listData.length > 0">
<view class="orderList" v-for="(item, itemIndex) in listData" :key="itemIndex">
<view class="top" @click="goSolitaireDetail(item.id)">
<view class="store u-line-2">{{item.title}}</view>
</view>
<view class="item">
<view class="left">
<u--image :showLoading="true" :src="item.thumbnail && item.thumbnail!='null' ? item.thumbnail : '/static/images/common/empty-banner.png'" width="80px" height="80px" mode="aspectFill"></u--image>
</view>
<view class="content">
<view class="type u-line-4">{{item.description}}</view>
<view class="delivery-time">截止时间{{ $u.timeFormat(item.endTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
</view>
</view>
<view class="bottom coreshop-margin-top-10">
<view class="more">正在接龙中</view>
<view class="coreshop-flex">
<view class='logistics coreshop-btn' @click="goSolitaireDetail(item.id)">查看详情</view>
</view>
</view>
</view>
<u-loadmore :status="loadStatus"></u-loadmore>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/order.png'" icon-size="150" text="暂无接龙信息" mode="list"></u-empty>
<navigator class="coreshop-btn" url="/pages/category/index/index" open-type="switchTab">随便逛逛</navigator>
</view>
</view>
</template>
<script>
export default {
data() {
return {
page: 1,
limit: 10,
listData: [],
loadStatus: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
},
}
},
onLoad() {
this.getList();
},
computed: {
shopName() {
return this.$store.state.config.shopName;
},
shareTitle() {
return this.$store.state.config.shareTitle;
},
shopLogo() {
return this.$store.state.config.shopLogo;
},
},
onReachBottom() {
if (this.loadStatus === 'loadmore') {
this.getList();
}
},
methods: {
//获取列表
getList() {
this.loadStatus = 'loading'
let data = {
page: this.page,
limit: this.limit,
}
this.$u.api.getSolitairePageList(data).then(res => {
if (res.status) {
let newList = this.listData.concat(res.data);
this.listData = newList;
if (res.data.count > this.listData.length) {
this.page++
this.loadStatus = 'loadmore'
} else {
this.loadStatus = 'nomore'
}
} else {
this.$u.toast(res.msg);
}
});
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,390 @@
<template>
<view>
<u-navbar title="群接龙" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="solitaire-details-bg"></view>
<view class="solitaire-details-placeholder-body" />
<!--商家及推荐-->
<view class="coreshop-margin-20 coreshop-goods-shop-info-view-box">
<view class="coreshop-shop-view">
<view class="coreshop-position-absolute">
<u-avatar :src="shopLogo" shape="square"></u-avatar>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-left-40 coreshop-padding-right-40">
<view class="coreshop-margin-bottom-5 coreshop-text-white">{{shopName || ' '}}</view>
<view class="coreshop-font-sm u-line-1 coreshop-text-white">{{shareTitle || ' '}}</view>
</view>
<u-button type="default" size="mini" :plain="true" @click="doPhoneCall" icon="phone" text="联系商家" color="#272d47"></u-button>
</view>
</view>
<view class="coreshop-bg-white solitaire-details-body">
<view class="coreshop-flex coreshop-flex-nowrap coreshop-justify-between">
<view class="coreshop-padding-top-15 coreshop-margin-bottom-10 coreshop-text-black u-line-2 coreshop-font-15">
{{model.title || ' '}}
</view>
<view class="solitaire-details-shareBox" @click="goShare()">
<u-icon name="share" color="#fff" size="22"></u-icon>
</view>
</view>
<view class="coreshop-font-11 coreshop-text-gray coreshop-margin-bottom-10 ">
{{$u.timeFormat(model.createTime, 'mm月dd日')}}发布截至{{$u.timeFormat(model.endTime, 'mm月dd日 hh:MM:ss')}}
</view>
<view class="coreshop-padding-10 coreshop-content">
<u-parse :content="model.contentBody" :selectable="true" v-if="model.contentBody"></u-parse>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="详情为空" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 购物车主结构 -->
<view class="solitaire-details-product-item" v-for="(item, index) in items" :key="index">
<view class="coreshop-flex">
<u-avatar :src="item.productObj.images ? item.productObj.images+'?x-oss-process=image/resize,m_lfit,h_320,w_240' : item.goodObj.image+'?x-oss-process=image/resize,m_lfit,h_320,w_240'" :size="60" shape="square"></u-avatar>
<view class="coreshop-margin-left-10">
<view class="coreshop-font-13 u-line-2">{{item.goodObj.name}} </view>
<view class="coreshop-font-12 coreshop-text-yellow coreshop-margin-top-10 u-line-1">{{ item.productObj.spesDesc }}</view>
<view class="coreshop-flex coreshop-justify-between coreshop-margin-top-10">
<view>
<text class="coreshop-font-16 coreshop-text-red coreshop-text-price">
{{item.price}}
</text>
<text class="coreshop-text-through coreshop-font-11 coreshop-margin-left-10 coreshop-text-grey">原价{{ item.productObj.mktprice || '0.00'}}</text>
</view>
<view class="cart-shoppingcard-goods-number">
<u-number-box buttonSize="24" integer :name="index" :value="item.nums" @change="toNumberChange" :step="1" :min="0" :max="item.oneCanBuy"></u-number-box>
</view>
</view>
<view class="cart-space-between">
<text class="cart-shoppingcard-remove cart-icons icon-msg" v-if="item.stockNo">库存不足</text>
<text class="cart-shoppingcard-remove cart-icons icon-msg" v-else-if="item.stockTension">库存紧张</text>
<text class="cart-shoppingcard-remove cart-icons" v-else=""></text>
</view>
</view>
</view>
</view>
<!--内容区-->
<view class="coreshop-margin-10 coreshop-padding-top-10 coreshop-bg-white">
<view class="coreshop-font-md coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row">
<u-icon name="more-circle" color="#e54d42" label="接龙清单" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-padding-top-10">
<!--接龙记录-->
<view class="coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-top-10 coreshop-padding-bottom-10" v-if="records.length>0">
<view class="coreshop-flex coreshop-flex-nowrap coreshop-justify-between coreshop-margin-bottom-10" v-for="(item, index) in records" :key="index">
<view class="coreshop-flex coreshop-flex-nowrap coreshop-justify-between coreshop-align-center">
<text class="coreshop-text-black coreshop-margin-right-10 coreshop-font-12">{{ records.length-index}}</text>
<u-avatar :src="item.avatarImage" :size="30"></u-avatar>
<text class="coreshop-text-black coreshop-font-12 u-line-1">{{ item.nickName}}</text>
<view class="coreshop-margin-left-10 coreshop-width-max-content">
<text class="coreshop-text-gray coreshop-font-10">{{$u.timeFormat(item.create, 'mm月dd日')}}</text>
</view>
</view>
<view class="coreshop-text-right coreshop-flex-direction-column">
<text class="coreshop-text-black coreshop-font-11 u-line-2">{{ item.productSku}}</text>
<text class="coreshop-text-gray coreshop-margin-left-10 coreshop-font-10">x{{ item.nums}}</text>
</view>
</view>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox coreshop-margin-0" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="就你购买后展示效果了^_^" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 分享弹窗 -->
<view class="coreshop-padding-10">
<u-popup mode="bottom" :show="shareBox" ref="share">
<!-- #ifdef H5 -->
<coreshop-share-h5 :objectId="model.id" :shareType="12" @close="closeShare()"></coreshop-share-h5>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<coreshop-share-wx :objectId="model.id" :shareType="12" @close="closeShare()"></coreshop-share-wx>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<coreshop-share-alipay :objectId="model.id" :shareType="12" @close="closeShare()"></coreshop-share-alipay>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<coreshop-share-tt :objectId="model.id" :shareType="12" @close="closeShare()"></coreshop-share-tt>
<!-- #endif -->
<!-- #ifdef APP-PLUS || APP-PLUS-NVUE -->
<coreshop-share-app :objectId="model.id" :shareType="12" @close="closeShare()"></coreshop-share-app>
<!-- #endif -->
</u-popup>
<div id="qrCode" ref="qrCodeDiv"></div>
</view>
<view class="coreshop-foot-hight-view" />
<!--按钮-->
<view class="coreshop-bg-white coreshop-footer-fixed coreshop-foot-padding-bottom">
<view class="coreshop-flex coreshop-padding-10 coreshop-justify-between coreshop-align-center coreshop-percent-100">
<view>
<text>合计 :</text>
<text class="coreshop-font-26 coreshop-text-red">¥{{totalprice}}</text>
</view>
<view class="coreshop-width-fit-content">
<u-button type="error" size="normal" @click="doSubmit" :disabled='submitStatus' :loading='submitStatus'>立即结算</u-button>
</view>
</view>
</view>
<!-- 右边浮动球 -->
<!--<coreshop-fab horizontal="right" vertical="bottom" direction="vertical"></coreshop-fab>-->
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
id: 0,
model: {},
items: [],
records: [],
background: {
background: '#272d47'
},
customButtonStyle: {
background: 'none',
color: '#fff'
},
totalprice: '0.00',
cart: [],
type: 2,
cartType: this.$globalConstVars.paymentType.solitaire,
shareBox: false,
submitStatus: false,
shareUrl: '/pages/share/jump/jump',
}
},
onLoad(e) {
this.id = e.id;
},
onShow() {
this.getDetial();
this.submitStatus = false;
},
computed: {
shopName() {
return this.$store.state.config.shopName;
},
shareTitle() {
return this.$store.state.config.shareTitle;
},
shopLogo() {
return this.$store.state.config.shopLogo;
},
},
methods: {
//获取列表
getDetial() {
let data = {
id: this.id
}
this.$u.api.getSolitaireDetail(data).then(res => {
if (res.status) {
this.model = res.data.model;
this.items = res.data.items;
this.records = res.data.record;
} else {
this.$u.toast(res.msg);
}
});
},
//获取商品总额
getGoodsTotalMoney() {
var goodsTotalMoney = 0
this.cart.forEach(function (item, index, input) {
goodsTotalMoney += item.price * item.nums
})
this.totalprice = this.$common.formatMoney(goodsTotalMoney, 2, '')
},
toNumberChange: function (e) {
console.log(e);
this.$u.throttle(this.numberChange(e), 500)
},
numberChange: function (e) {
var _this = this;
var item = this.items[e.name];
var nums = e.value;
if (nums > 0) {
let data = {
ProductId: item.productId,
Nums: nums,
type: this.type,
cartType: this.cartType,
objectId: this.id
};
_this.$u.api.addCart(data).then(res => {
if (res.status) {
if (_this.cart.length < 1) {
_this.cart.push({
key: e.name,
id: res.data,
productId: item.productId,
goodsId: item.goodId,
nums: e.value,
price: item.price
})
} else {
var isIn = false
for (var i = 0; i < _this.cart.length; i++) {
if (_this.cart[i].key == e.name && _this.cart[i].productId == item.productId) {
_this.cart[i] = {
key: e.name,
id: res.data,
productId: item.productId,
goodsId: item.goodId,
nums: e.value,
price: item.price
}
isIn = true
}
}
if (!isIn) {
_this.cart.push({
key: e.name,
id: res.data,
productId: item.productId,
goodsId: item.goodId,
nums: e.value,
price: item.price
})
}
}
_this.getGoodsTotalMoney();
} else {
_this.$u.toast(res.msg);
}
});
} else {
var deleteIndex = -1;
var deleteId = 0;
for (var i = 0; i < _this.cart.length; i++) {
if (_this.cart[i].key == e.name && _this.cart[i].productId == item.productId) {
//移除数据库
deleteIndex = i;
deleteId = _this.cart[i].id;
}
}
if (deleteIndex >= 0 && deleteId > 0) {
let data = {
id: deleteId
};
_this.$u.api.removeCart(data).then(res => {
if (res.status) {
_this.cart.splice(deleteIndex, 1);
_this.getGoodsTotalMoney();
}
});
}
}
},
doSubmit() {
if (this.cart.length < 1) {
this.$u.toast('请先选择商品')
return true
}
if (parseFloat(this.totalprice) < parseFloat(this.model.startBuyPrice)) {
this.$u.toast('最小购买价格为' + this.model.startBuyPrice + '元,请增加购买产品')
return true
}
let userToken = this.$db.get('userToken');
let obj = {
cart: this.cart,
id: this.id,
token: userToken
}
this.submitStatus = true;
let newData = '';
for (var i = 0; i < this.cart.length; i++) {
if (this.cart[i].nums > 0) {
newData += ',' + this.cart[i].id;
}
}
if (newData.substr(0, 1) == ',') {
newData = newData.substr(1);
}
if (newData.length > 0) {
this.$u.route('/pages/placeOrder/index/index?orderType=' + this.cartType + '&objectId=' + this.id + '&cartIds=' + JSON.stringify(newData));
return true;
} else {
//没有选择不跳转
}
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 12,
params: {
id: this.model.id,
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
},
},
watch: {
model: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.model.title,
imageUrl: this.model.thumbnail,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.model.title,
imageUrl: this.model.thumbnail,
path: this.shareUrl
}
},
}
</script>
<style lang="scss">
image { display: block; }
</style>

View File

@@ -0,0 +1,10 @@

.article-title { font-size: 16px; color: #333; margin: 10px 0px; position: relative; text-align: center; }
.article-time { margin-top: 5px; font-size: 11px; text-align: center; }
.u-content { margin-top: 10px; color: $u-content-color; font-size: 14px; line-height: 1.8; }
.u-content p { color: $u-tips-color; }
.interlayer {
video { width: 100%; }
}

View File

@@ -0,0 +1,164 @@
<template>
<!-- 页面主体 -->
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar :title="title" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="coreshop-bg-white coreshop-padding-10 coreshop-margin-10">
<u--image width="100%" height="150px" v-if="info.coverImage" :src="info.coverImage && info.coverImage!='null' ? info.coverImage+'?x-oss-process=image/resize,m_lfit,h_320,w_240' : '/static/images/common/empty-banner.png'"></u--image>
<view class="article-title">
{{ info.title }}
</view>
<view class="article-time" v-if="info.createTime">{{ info.createTime }}</view>
<u-line dashed></u-line>
<view class="u-content">
<u-parse :content="contentBody" :selectable="true"></u-parse>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
idType: 1, //1文章 2公告 3微信图文消息
id: 0,
info: {},
contentBody: '',
shareUrl: '/pages/share/jump/jump',
title: ''
};
},
onLoad(e) {
this.idType = e.idType;
this.id = e.id;
if (!this.idType && !this.id) {
this.$refs.uToast.show({ message: '获取失败', type: 'error', isTab: true, url: '/pages/index/default/default' });
} else if (this.idType == 1) {
this.title = "文章详情";
this.articleDetail();
} else if (this.idType == 2) {
this.title = "公告详情";
this.noticeDetail();
} else if (this.idType == 3) {
this.title = "图文消息";
this.messageDetail();
}
},
computed: {
shopName() {
return this.$store.state.config.shopName;
},
shopLogo() {
return this.$store.state.config.shopLogo;
}
},
methods: {
articleDetail() {
let data = {
id: this.id
};
this.$u.api.articleInfo(data).then(res => {
if (res.status) {
this.info = res.data;
this.contentBody = res.data.contentBody;
this.title = this.info.title;
} else {
this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
});
},
noticeDetail() {
let data = {
id: this.id
};
this.$u.api.noticeInfo(data).then(res => {
if (res.status) {
this.info = res.data;
this.contentBody = res.data.contentBody;
this.title = this.info.title;
} else {
this.$u.toast(res.msg);
}
});
},
//微信图文消息
messageDetail() {
let data = {
id: this.id
};
this.$u.api.messageDetail(data).then(res => {
if (res.status) {
this.info = res.data;
this.contentBody = res.data.contentBody;
this.title = this.info.title;
} else {
this.$u.toast(res.msg);
}
});
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 5,
params: {
articleId: this.id,
articleType: this.idType
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
}
},
watch: {
id: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.info.title,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.info.title,
path: this.shareUrl
}
},
};
</script>
<style lang="scss" scoped>
@import "details.scss";
</style>

View File

@@ -0,0 +1,117 @@
<template>
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="帮助中心" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<u-tabs :list="articleType" sticky :current="current" @change="change" lineWidth="30"></u-tabs>
<view class="coreshop-bg-white coreshop-margin-10">
<view class="coreshop-flex coreshop-solid-bottom coreshop-justify-between coreshop-flex-nowrap coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10" v-for="item in list" :key="item.id" @click="goArticleDetail(item.id)">
<view class="coreshop-flex coreshop-flex-nowrap">
<u--image width="25px" height="25px" :src="item.coverImage" mode="aspectFill" :showLoading="true"></u--image>
<view class="u-line-2 coreshop-padding-left-5 coreshop-font-14">{{item.title}}</view>
</view>
<view class="coreshop-text-gray coreshop-text-right coreshop-justify-end">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
<view>
<u-loadmore :status="status" :icon-type="iconType" :load-text="loadText" margin-top="0" margin-bottom="20" class="coreshop-padding-top-10" />
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
cid: 0, // 文章分类id
page: 1,
limit: 10,
list: [],
status: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
},
articleType: [],
typeName: '',
current: 0
};
},
onLoad(options) {
if (options.cid) {
this.cid = Number(options.cid);
}
this.articleList();
if (options.current) {
this.current = options.current;
}
},
onReachBottom() {
if (this.status === 'loadmore') {
this.articleList();
}
},
methods: {
articleList() {
let data = {
page: this.page,
limit: this.limit,
id: this.cid
};
this.status = 'loading';
this.$u.api.articleList(data).then(res => {
if (res.status) {
this.articleType = res.data.articleType;
for (var i = 0; i < this.articleType.length; i++) {
if (this.cid === this.articleType[i].id) {
this.current = i;
}
}
this.typeName = res.data.typeName;
const _list = res.data.list;
this.list = [...this.list, ..._list];
if (res.data.count > this.list.length) {
this.status = 'loadmore';
this.page++;
} else {
// 数据已加载完毕
this.status = 'nomore';
}
} else {
// 接口请求出错了
this.$u.toast(res.msg);
}
});
},
change(item) {
this.current = item.index;
this.cid = item.id;
this.list = [];
this.page = 1;
this.limit = 10;
this.loadStatus = 'more';
this.articleList();
}
}
};
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,19 @@

.u-wrap { height: calc(100vh); /* #ifdef H5 */ height: calc(100vh - var(--window-top)); /* #endif */ }
.u-menu-wrap { flex: 1; display: flex; overflow: hidden;
.u-tab-view { width: 100px; height: 100%; background: #f6f6f6;
.u-tab-item { height: 55px; background: #f6f6f6; box-sizing: border-box; display: flex; align-items: center; justify-content: center; font-size: 13px; color: #444; font-weight: 400; line-height: 1; }
.u-tab-item-active { position: relative; color: #000; font-weight: 600; background: #fff; }
.u-tab-item-active::before { content: ""; position: absolute; border-left: 4px solid #e02e24; height: 16px; left: 0; top: 20px; }
}
.right-box { background-color: rgb(250, 250, 250); width: calc(100% - 100px);
.class-item { margin-bottom: 15px; background-color: #fff; padding: 8px; border-radius: 4px;
.item-title { font-size: 12px; color: $u-main-color; font-weight: bold; }
.item-container { display: flex; flex-wrap: wrap;
.thumb-box { width: 33.333333%; display: flex; align-items: center; justify-content: center; flex-direction: column; margin-top: 10px;
.item-menu-name { font-weight: normal; font-size: 12px; color: $u-main-color; margin-top: 7.5px; }
}
}
}
}
}

View File

@@ -0,0 +1,140 @@
<template>
<view class="u-wrap">
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar safeAreaInsetTop fixed placeholder>
<view slot="left">
<u-search :show-action="true" shape="round" v-model="searchKey" actionText="搜索" placeholder="请输入搜索内容" @custom="goSearch" @search="goSearch"></u-search>
</view>
<u-icon name="scan" color="#fff" size="16" slot="right"></u-icon>
</u-navbar>
<view class="coreshop-padding-10" v-if="CateStyle==1">
<view v-for="(item,index) in tabbar" :key="index" @click="goClass(item.id)">
<u--image width="100%" height="195px" :src="item.imageUrl" :showLoading="false"></u--image>
<view class="coreshop-text-center coreshop-padding-top-10 coreshop-padding-bottom-10">
{{item.name}}
</view>
</view>
</view>
<view class="coreshop-padding-10" v-if="CateStyle==2">
<u-row gutter="16">
<u-col span="4" v-for="(item,index) in tabbar" :key="index" @click="goClass(item.id)">
<u--image width="100%" height="80px" :src="item.imageUrl" :showLoading="false"></u--image>
<view class="coreshop-text-center coreshop-padding-top-15 coreshop-padding-bottom-15 coreshop-font-sm">
{{item.name}}
</view>
</u-col>
</u-row>
</view>
<view class="u-menu-wrap coreshop-flex-direction-row" v-if="CateStyle==3">
<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
<view v-for="(item,index) in tabbar" :key="index" class="u-tab-item" :class="[current==index ? 'u-tab-item-active' : '']"
:data-current="index" @tap.stop="swichMenu(index)">
<text class="u-line-1">{{item.name}}</text>
</view>
</scroll-view>
<block v-for="(item,index) in tabbar" :key="index">
<scroll-view scroll-y class="right-box" v-if="current==index">
<view class="coreshop-padding-10">
<coreshop-advert codes="TplIndexBanner1"></coreshop-advert>
<view class="class-item">
<view class="item-title">
<text>{{item.name}}</text>
</view>
<view class="item-container coreshop-flex-direction-row">
<view class="thumb-box" v-for="(item1, index1) in item.child" :key="index1" @click="goClass(item1.id)">
<u--image width="60px" height="60px" :src="item1.imageUrl" :showLoading="false"></u--image>
<view class="item-menu-name">{{item1.name}}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</block>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
tabbar: [],
scrollTop: 0, //tab标题的滚动条位置
current: 0, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度,
beans: [],
isChild: false,
searchKey: ''
}
},
computed: {
CateStyle() {
return this.$store.state.config.cateStyle ? this.$store.state.config.cateStyle : 3;
}
},
onShow() {
this.categories();
},
methods: {
categories() {
this.$u.api.categories().then(res => {
if (res.status) {
this.tabbar = res.data;
}
});
},
getImg() {
return Math.floor(Math.random() * 35);
},
// 点击左边的栏目切换
async swichMenu(index) {
if (index == this.current) return;
this.current = index;
// 如果为0意味着尚未初始化
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
await this.getElRect('menu-scroll-view', 'menuHeight');
await this.getElRect('u-tab-item', 'menuItemHeight');
}
// 将菜单菜单活动item垂直居中
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query.select('.' + elClass).fields({ size: true }, res => {
// 如果节点尚未生成res值为null循环调用执行
if (!res) {
setTimeout(() => {
this.getElRect(elClass);
}, 10);
return;
}
this[dataVal] = res.height;
}).exec();
})
},
goClass(catId) {
uni.navigateTo({
url: '/pages/category/list/list?id=' + catId
});
},
goSearch() {
if (this.searchKey != '') {
this.$u.route('/pages/category/list/list?key=' + this.searchKey);
} else {
this.$refs.uToast.show({ message: '请输入查询关键字', type: 'warning', })
}
}
}
}
</script>
<style lang="scss" scoped>
@import "index.scss";
</style>

View File

@@ -0,0 +1,34 @@
.topBox { position: sticky; z-index: 1; width: 100%; /* #ifdef APP-PLUS */ top: calc(var(--status-bar-height) + 35px); /* #endif */ /* #ifdef H5 */ top: calc(var(--status-bar-height) + 55px); /* #endif */ /* #ifdef MP */ top: calc(var(--status-bar-height) + 62.5px); /* #endif */ }
.goodsBox { display: flex; flex-flow: row wrap; align-content: flex-start; margin-top: 10px; }
.good_box { border-radius: 8px; margin: 0 5px 8px 5px; background-color: #ffffff; position: relative; box-sizing: border-box; break-inside: avoid; overflow: auto; width: calc(50% - 10px); }
.good_image { width: 100%; border-top-left-radius: 4px; border-top-right-radius: 4px; }
.good_title { font-size: 13px; margin-top: 5px; color: $core-main-color; }
.good_title-xl { font-size: 14px; margin-top: 5px; color: $core-main-color; }
.good-tag-hot { display: flex; margin-top: 5px; position: absolute; top: 7.5px; left: 7.5px; background-color: $core-type-error; color: #FFFFFF; display: flex; align-items: center; padding: 2px 7px; border-radius: 25px; font-size: 10px; line-height: 1; }
.good-tag-recommend { display: flex; margin-top: 5px; position: absolute; top: 7.5px; right: 7.5px; background-color: $core-type-primary; color: #FFFFFF; margin-left: 10px; border-radius: 25px; line-height: 1; padding: 2px 7px; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-tag-recommend2 { display: flex; margin-top: 5px; position: absolute; bottom: 17.5px; left: 7.5px; background-color: $core-type-primary; color: #FFFFFF; border-radius: 25px; line-height: 1; padding: 2px 7px; display: flex; align-items: center; border-radius: 25px; font-size: 10px; }
.good-price { font-size: 15px; color: $core-type-error; margin-top: 5px; }
.good-des { font-size: 11px; color: $core-tips-color; margin-top: 5px; }
.contentBody { position: relative; }
.btnCart { position: absolute; bottom: 2.5px; right: 5px; }
.fliter-item-title { padding: 10px 13px 10px 0; width: 362px; margin-left: 13px; border-bottom: 1px solid #f3f3f3; position: relative; background-color: #fff; color: #333; display: flex; min-height: 45px; align-items: center; justify-content: space-between; }
.fliter-item-title-hd { display: flex; /* vertical-align: middle; */ align-items: center; font-size: 14px; position: relative; }
.fliter-item-title-hd-title { /* float: left; */ display: inline-block; position: relative; /* #ifdef MP-ALIPAY */ top: 2px; /* #endif */ }
.fliter-c { }
.fliter-item { }
.fliter-item .fliter-item-title { border-bottom: none; }
.fliter-i-c { padding: 0 13px; overflow: hidden; }
.fic-item { display: inline-block; float: left; width: 80px; margin-right: 7px; height: 35px; background-color: #f1f1f1; text-align: center; font-size: 12px; margin-bottom: 7px; color: #333; padding: 0 5px; }
.fic-item-active { background-color: #ff7159; color: #fff; }
.fic-item-text { position: relative; top: 50%; transform: translateY(-50%); }
.fic-item:nth-child(4n) { margin-right: 0; }
.fic-item-line { float: left; margin: 17px 9px 0 0; width: 25px; height: 1px; border-bottom: 1px solid #ccc; }
.fic-item-input { position: relative; top: 50%; transform: translateY(-50%); }
.coreshop-bottomBtnsBox { text-align: center; position: absolute; bottom: 0px; width: 100%; padding: 10px;
view { margin: 0 5px; width: calc(50% - 10px); }
}

View File

@@ -0,0 +1,687 @@
<template>
<view class="">
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar :title="title" safeAreaInsetTop fixed placeholder @leftClick="goNavigateBack"></u-navbar>
<!-- 条件筛选 -->
<view class="coreshop-justify-center coreshop-bg-white">
<fy-dropdown :menuList="menuList" ref="uDropdown">
<fy-dropdown-item v-model="comprehensiveDataValue" dropdownKey="synthesis" title="综合" :options="comprehensiveData" @change="comprehensive"></fy-dropdown-item>
<fy-dropdown-item v-model="priceSortDataValue" dropdownKey="price" title="价格" :options="priceSortData" @change="priceSort"></fy-dropdown-item>
<fy-dropdown-item v-model="salesVolumeDataValue" dropdownKey="sales" title="销量" :options="salesVolumeData" @change="salesVolume"></fy-dropdown-item>
<fy-dropdown-item v-model="current" title="显示" :options="currentData"></fy-dropdown-item>
<fy-dropdown-item title="其他" dropdownKey="other" :custom="true">
<view class="slot-content coreshop-bg-white">
<view class="fliter-c coreshop-padding-10">
<view class="fliter-item">
<view class="fliter-item-title">
<view class="fliter-item-title-hd"><view class="fliter-item-title-hd-title">价格区间</view></view>
</view>
<view class="fliter-i-c coreshop-flex-direction-row">
<view class="fic-item"><input class="fic-item-input" type="number" v-model="sPrice" /></view>
<view class="fic-item-line"></view>
<view class="fic-item"><input class="fic-item-input" type="number" v-model="ePrice" /></view>
</view>
</view>
<view class="fliter-item" v-if="catList.length > 0">
<view class="fliter-item-title">
<view class="fliter-item-title-hd"><view class="fliter-item-title-hd-title">分类</view></view>
</view>
<view class="fliter-i-c coreshop-flex-direction-row">
<view v-for="item in catList" :key="item.goodsCatId" v-if="item.goodsCatId && item.name" @click="selectKey('catList', item.goodsCatId)">
<view class="fic-item" v-if="!item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
<view class="fic-item fic-item-active" v-else-if="item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
</view>
</view>
</view>
<view class="fliter-item" v-if="brandList.length > 0">
<view class="fliter-item-title">
<view class="fliter-item-title-hd"><view class="fliter-item-title-hd-title">品牌</view></view>
</view>
<view class="fliter-i-c coreshop-flex-direction-row">
<view v-for="item in brandList" :key="item.id" v-if="item.id && item.name" @click="selectKey('brandList', item.id)">
<view class="fic-item" v-if="!item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
<view class="fic-item fic-item-active" v-if="item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
</view>
</view>
</view>
<view class="fliter-item" v-if="labelList.length > 0">
<view class="fliter-item-title">
<view class="fliter-item-title-hd"><view class="fliter-item-title-hd-title">标签</view></view>
</view>
<view class="fliter-i-c coreshop-flex-direction-row">
<view v-for="item in labelList" :key="item.id" v-if="item.id && item.name" @click="selectKey('labelList', item.id)">
<view class="fic-item" v-if="!item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
<view class="fic-item fic-item-active" v-else-if="item.isSelect">
<view class="fic-item-text two-line">{{ item.name }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="coreshop-category-bottomBox">
<view>
<u-button size="medium" @click="filterNo()">取消</u-button>
</view>
<view>
<u-button size="medium" type="primary" @click="filterOk()">确定</u-button>
</view>
</view>
</view>
</fy-dropdown-item>
</fy-dropdown>
</view>
<!-- 商品列表 -->
<scroll-view scroll-y="true" :scroll-into-view="toView" class="scroll-Y" @scrolltolower="lower" enable-back-to-top="true" lower-threshold="45">
<!-- 表格图片 -->
<view v-if="current === 0">
<view v-if="goodsList.length > 0" class="goodsBox">
<view class="good_box" v-for="item in goodsList" :key="item.id" @click="goGoodsDetail(item.id)">
<u--image :src="item.image" :index="item.id" width="100%" height="167px" mode="widthFix"></u--image>
<view class="coreshop-padding-5">
<view class="good_title u-line-2 coreshop-min-height-34">
{{item.name}}
</view>
<view class="good-price">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.pointsDeduction > 0">
<view>
{{ pointShowName}}兑换价:
</view>
<view class="coreshop-text-red">
{{pointDiscountedProportion * item.pointsDeduction }}{{ pointShowName}}+{{ item.price - item.pointsDeduction}}
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-11 coreshop-margin-top-5" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && item.points > 0">
<view>
购买赠送:
</view>
<view class="coreshop-text-red">
{{item.points}}{{ pointShowName}}
</view>
</view>
</view>
</view>
<view class="coreshop-btn-all">
<u-loadmore :status="loadStatus" :icon-type="loadIconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
</view>
</view>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="当前列表为空" mode="list"></u-empty>
</view>
</view>
<!-- 列表图片 -->
<view v-if="current === 1">
<view v-if="goodsList.length > 0">
<view class="img-list-item" v-for="(item, index) in goodsList" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u-row gutter="5" justify="space-between">
<u-col span="4">
<!-- 警告微信小程序中需要hx2.8.11版本才支持在template中结合其他组件比如下方的lazy-load组件 -->
<u--image :src="item.image" :index="item.id"></u--image>
<view class="good-tag-recommend2" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</u-col>
<u-col span="8">
<view class="contentBody">
<view class="good_title-xl u-line-2 coreshop-padding-left-10 coreshop-padding-right-10">
{{item.name}}
</view>
<view class="good-price coreshop-padding-10">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-des coreshop-padding-10" v-if="item.commentsCount > 0">
{{ item.commentsCount }}条评论
</view>
<view class="good-des coreshop-padding-10" v-else-if="item.commentsCount <= 0">
暂无评论
</view>
<u-icon name="shopping-cart" color="#2979ff" size="40" class="btnCart"></u-icon>
</view>
</u-col>
</u-row>
</view>
</view>
<u-loadmore :status="loadStatus" :icon-type="loadIconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
</view>
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="当前列表为空" mode="list"></u-empty>
</view>
</view>
</scroll-view>
<u-back-top :scroll-top="scrollTop" :duration="300"></u-back-top>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
title: '列表',
current: 0,
id: '',
showView: false,
goodsList: [],
minPrice: '',
maxPrice: '',
scrollTop: 0,
loadStatus: 'loadmore',
loadIconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
},
toView: '',
searchData: {
where: {},
limit: 10,
page: 1,
order: {
key: 'sort',
sort: 'asc'
}
},
searchKey: '请输入关键字搜索', //关键词
alllist: true,
allgrid: false,
screents: true,
screentc: false,
sPrice: '',
ePrice: '',
brandList: [],
catList: [],
labelList: [],
menuList: [{ title: '综合', dropdownKey: 'synthesis' }, { title: '价格', dropdownKey: 'price' }, { title: '销量', dropdownKey: 'sales' }, { title: '其他', dropdownKey: 'other' }],
comprehensiveDataValue: 'asc',
priceSortDataValue: '',
salesVolumeDataValue: 1,
comprehensiveData: [{
label: '顺序',
value: 'asc',
},
{
label: '倒序',
value: 'desc',
}],
salesVolumeData: [{
label: '从小到大',
value: 'asc',
},
{
label: '从大到小',
value: 'desc',
}],
priceSortData: [{
label: '从小到大',
value: 'asc',
},
{
label: '从大到小',
value: 'desc',
}],
currentData: [{
label: '表格',
value: 0,
},
{
label: '列表',
value: 1,
}],
};
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
//加载执行
onLoad: function (options) {
uni.showTabBar();
//console.log(options);
var where = {};
if (options.id) {
where.catId = options.id;
}
if (options.key) {
where = {
searchName: options.key
};
this.searchKey = options.key;
}
if (options.type) {
if (options.type == 'hot') {
where = {
hot: true
};
}
if (options.type == 'recommend') {
where = {
recommend: true
};
}
}
if (options.catId) {
where.catId = options.catId;
}
if (options.brandId) {
where.brandId = options.brandId;
}
if (options.hot) {
where.hot = options.hot;
}
if (options.recommend) {
where.recommend = options.recommend;
}
if (options.labelId) {
where.labelId = options.labelId;
}
this.searchData.where = where;
//this.setSearchData({
// where: where
//});
this.setSearchData(this.searchData, true);
this.getGoods();
},
onReachBottom() {
if (this.loadStatus != 'nomore') {
this.getGoods();
}
},
computed: {
pointSwitch() { return this.$store.state.config.pointSwitch },
pointShowExchangePrice() { return this.$store.state.config.pointShowExchangePrice },
pointDiscountedProportion() { return this.$store.state.config.pointDiscountedProportion },
pointExchangeModel() { return this.$store.state.config.pointExchangeModel },
pointShowName() { return this.$store.state.config.pointShowName },
pointGetModel() { return this.$store.state.config.pointGetModel },
pointShowPoint() { return this.$store.state.config.pointShowPoint },
},
methods: {
listGrid() {
if (this.current == 0) {
this.current = 1;
} else {
this.current = 0;
}
},
//设置查询条件
setSearchData: function (searchData, clear = false) {
// 深度克隆
this.searchData = this.$u.deepClone(searchData);
if (clear) {
this.goodsList = [];
}
},
onChangeShowState: function () {
var _this = this;
_this.showView = !_this.showView;
},
//点击综合排序
comprehensive: function (value) {
//console.log('点击综合排序:' + value);
if (value) {
this.searchData.order = {
key: 'sort',
sort: value
};
this.searchData.page = 1; //从第一页重新显示
this.setSearchData(this.searchData, true);
this.getGoods();
}
},
//销量
salesVolume: function (value) {
this.priceSortDataValue = '';
this.searchData.order = {
key: 'buyCount',
sort: value
};
this.searchData.page = 1; //从第一页重新显示
this.setSearchData(this.searchData, true);
this.getGoods();
},
//价格排序
priceSort: function (value) {
this.salesVolumeDataValue = '';
this.searchData.order = {
key: 'price',
sort: value
};
this.searchData.page = 1; //从第一页重新显示
this.setSearchData(this.searchData, true);
this.getGoods();
},
//设置查询价格区间
// orderPrice: function(e) {
// var reg = /^[0-9]+(.[0-9]{2})?$/;
// if (!reg.test(e.detail.value)) {
// this.$u.toast('请输入正确金额');
// this.maxPrice = '';
// } else {
// this.maxPrice = e.detail.value;
// }
// },
//查询价格区间
// searchPrice: function(event) {
// if (
// this.minPrice > 0 &&
// this.maxPrice > 0 &&
// this.minPrice > this.maxPrice
// ) {
// app.common.errorToShow('价格区间有误');
// return false;
// }
//
// this.setSearchData(
// {
// page: 1,
// where: {
// priceFrom: this.minPrice,
// priceTo: this.maxPrice
// }
// },
// true
// );
// this.getGoods();
// },
//取得商品数据
getGoods: function () {
var _this = this;
_this.$u.api.goodsList(_this.conditions()).then(res => {
if (res.status) {
if (res.data.className != '') {
_this.title = res.data.className;
} else {
if (res.data.where && res.data.where.searchName && res.data.where.searchName != '') {
_this.title = "商品搜索";
}
}
_this.goodsList = _this.goodsList.concat(res.data.list);
if (res.data.brands) {
for (let i = 0; i < res.data.brands.length; i++) {
res.data.brands[i].isSelect = false;
}
_this.brandList = res.data.brands;
}
if (res.data.filter) {
if (filter.goodsCat) {
for (let i = 0; i < filter.goodsCat.length; i++) {
filter.goodsCat[i].isSelect = false;
}
_this.catList = filter.goodsCat;
}
if (filter.labelIds) {
for (let i = 0; i < filter.labelIds.length; i++) {
filter.labelIds[i].isSelect = false;
}
_this.labelList = filter.labelIds;
}
}
//console.log(_this.searchData);
if (res.data.totalPages > _this.searchData.page) {
_this.loadStatus = 'loadmore';
_this.searchData.page++;
} else {
// 数据已加载完毕
_this.loadStatus = 'nomore';
}
}
});
},
//上拉加载
lower: function () {
var _this = this;
_this.toView = 'loading';
if (!_this.loadingComplete) {
_this.setSearchData({
page: _this.searchData.page + 1
});
_this.getGoods();
}
},
listgrid: function () {
let _this = this;
if (_this.alllist) {
_this.allgrid = true;
_this.listgrid = true;
_this.alllist = false;
} else {
_this.allgrid = false;
_this.listgrid = false;
_this.alllist = true;
}
},
// 统一返回筛选条件 查询条件 分页
conditions() {
let data = this.searchData;
var newData = this.$u.deepClone(data);
if (data.where) {
newData.where = JSON.stringify(data.where);
}
//把排序换成字符串
if (data.order) {
var sort = data.order.key + ' ' + data.order.sort;
if (data.order.key != 'sort') {
sort = sort + ',sort asc'; //如果不是综合排序,增加上第二个排序优先级排序
}
newData.order = sort;
} else {
newData.order = 'sort asc';
}
return newData;
},
//老搜索
search() {
this.setSearchData(
{
page: 1,
where: {
searchName: this.keyword
}
},
true
);
this.getGoods();
},
//去搜索
goSearch() {
let pages = getCurrentPages();
let prevPage = pages[pages.length - 2];
// #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE || MP-TOUTIAO
if (prevPage && prevPage.route) {
let search_flag = prevPage.route;
if (search_flag == 'pages/search/search') {
uni.navigateBack({
delta: 1
});
} else {
this.$u.route('/pages/search/search');
}
} else {
this.$u.route('/pages/search/search');
}
// #endif
// #ifdef MP-ALIPAY
if (prevPage && prevPage.__proto__.route) {
let search_flag = prevPage.__proto__.route;
if (search_flag == 'pages/search/search') {
uni.navigateBack({
delta: 1
});
} else {
this.$u.route('/pages/search/search');
}
} else {
this.$u.route('/pages/search/search');
}
// #endif
},
//取消筛选
filterNo() {
this.ePrice = '';
this.sPrice = '';
for (let i = 0; i < this.catList.length; i++) {
this.catList[i].isSelect = false;
}
for (let i = 0; i < this.brandList.length; i++) {
this.brandList[i].isSelect = false;
}
for (let i = 0; i < this.labelList.length; i++) {
this.labelList[i].isSelect = false;
}
this.filterOk();
//this.toclose();
},
//确认筛选
filterOk() {
let data = this.searchData;
//获取分类
// data.where.catId = '';
for (let i = 0; i < this.catList.length; i++) {
if (this.catList[i].isSelect) {
data.where.catId = this.catList[i].goodsCatId;
}
}
//获取多个品牌
let brandIds = '';
for (let i = 0; i < this.brandList.length; i++) {
if (this.brandList[i].isSelect) {
brandIds += this.brandList[i].id + ',';
}
}
if (brandIds) {
brandIds = brandIds.substr(0, brandIds.length - 1);
}
data.where.brandId = brandIds;
//获取标签
data.where.labelId = '';
for (let i = 0; i < this.labelList.length; i++) {
if (this.labelList[i].isSelect) {
data.where.labelId = this.labelList[i].id;
}
}
//价格区间
data.where.priceFrom = '';
data.where.priceTo = '';
if (
this.sPrice * 1 < 0 ||
(this.ePrice != '' && this.ePrice <= 0) ||
this.ePrice * 1 < 0 ||
(this.sPrice * 1 > this.ePrice * 1 && this.sPrice != '' && this.ePrice != '')
) {
this.$u.toast('价格区间有误');
return false;
} else {
data.where.priceFrom = this.sPrice;
data.where.priceTo = this.ePrice;
}
this.searchData.page = 1; //从第一页重新显示
this.setSearchData(data, true);
this.getGoods();
this.closeDropdown();
},
//选择
selectKey(type, id) {
//分类一次只能选择一个
if (type == 'catList') {
for (let i = 0; i < this.catList.length; i++) {
if (this.catList[i].goodsCatId == id) {
this.catList[i].isSelect = this.catList[i].isSelect ? false : true;
} else {
this.catList[i].isSelect = false;
}
}
}
if (type == 'brandList') {
for (let i = 0; i < this.brandList.length; i++) {
if (this.brandList[i].id == id) {
this.brandList[i].isSelect = this.brandList[i].isSelect ? false : true;
} else {
this.brandList[i].isSelect = false;
}
}
}
if (type == 'labelList') {
for (let i = 0; i < this.labelList.length; i++) {
if (this.labelList[i].id == id) {
this.labelList[i].isSelect = this.labelList[i].isSelect ? false : true;
} else {
this.labelList[i].isSelect = false;
}
}
}
console.log(this.brandList);
},
closeDropdown() {
this.$refs.uDropdown.close();
}
},
// #ifdef MP-ALIPAY
onChangeShowState_show: function () {
var that = this;
that.setData({
showView: (that.showView = true)
});
},
onChangeShowState_hid: function () {
var that = this;
that.setData({
showView: (that.showView = false)
});
}
// #endif
};
</script>
<style scoped lang="scss">
@import "list.scss";
</style>

View File

@@ -0,0 +1,122 @@
<template>
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="优惠券" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="coreshop-coupon coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10">
<view v-if="list.length">
<view v-for="(item, key) in list" :key="key">
<view class="coreshop-coupon-card-view" :class="item.maxRecevieNums > 0 && item.getNumber >= item.maxRecevieNums ?'coreshop-lower-shelf':''">
<view class="img-lower-box" v-if="item.maxRecevieNums > 0 && item.getNumber >= item.maxRecevieNums ">已领完</view>
<view class="card-price-view">
<view class="coreshop-text-red price-left-view">
<image class="icon" src="/static/images/coupon/coupon-element.png" mode=""></image>
</view>
<view class="name-content-view">
<view class="u-line-1 coreshop-text-red"> {{item.name}}</view>
<view class="coreshop-font-xs">
优惠方式<text v-for="(itemResult, index) in item.results" :key="index">{{itemResult}}</text>
</view>
<view class="coreshop-font-xs">领取时间{{$u.timeFormat(item.startTime, 'yyyy-mm-dd')}} - {{$u.timeFormat(item.endTime, 'yyyy-mm-dd')}}</view>
</view>
<view class="btn-right-view">
<u-button type="success" shape="circle" size="mini" @click="receiveCoupon(item.id)">立即领取</u-button>
</view>
</view>
<view class="card-num-view coreshop-flex coreshop-flex-direction-row coreshop-justify-between">
<view class="coreshop-font-xs coreshop-flex-direction-row coreshop-basis-9 u-line-1">
<text v-for="(itemCondition, index) in item.conditions" :key="index">{{itemCondition}}</text>
</view>
<view class="coreshop-width-fit-content">
<u-icon name="arrow-down-fill" class="coreshop-float-right" size="14"></u-icon>
</view>
</view>
</view>
</view>
<u-loadmore :status="status" :icon-type="iconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
</view>
<view class="services-none" v-else>
<view class="page-box">
<view>
<view class="coreshop-emptybox">
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/coupon.png'" icon-size="150" mode="order" text="暂无优惠券可领取"></u-empty>
<navigator class="coreshop-btn" url="/pages/category/index/index" open-type="switchTab">随便逛逛</navigator>
</view>
</view>
</view>
</view>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
computed: {
},
data() {
return {
page: 1,
limit: 10,
list: [],
status: 'loadmore',
iconType: 'flower',
loadText: {
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '实在没有了'
}
};
},
onLoad() {
this.getCouponlist()
},
onShow() {
},
onReachBottom() {
if (this.status === 'loadmore') {
this.getCouponlist()
}
},
methods: {
getCouponlist() {
let _this = this;
let data = {
page: this.page,
limit: this.limit
}
this.status = 'loading'
this.$u.api.couponList(data).then(res => {
if (res.status) {
if (res.data) {
let _list = res.data
this.list = [...this.list, ..._list]
}
if (res.code >= _this.list.length) {
_this.page++
_this.status = 'loadmore'
} else {
_this.status = 'nomore'
}
} else {
_this.$u.toast(res.msg)
}
})
},
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view>
<u-navbar :title="title" safeAreaInsetTop fixed placeholder @leftClick="goNavigateBack"></u-navbar>
<u-tag text="标签"></u-tag>
<u-tag text="标签" type="warning"></u-tag>
<u-tag text="标签" type="success"></u-tag>
<u-tag text="标签" type="error"></u-tag>
<u-button type="primary" text="确定"></u-button>
<u-button type="primary" :plain="true" text="镂空"></u-button>
<u-button type="primary" :plain="true" :hairline="true" text="细边"></u-button>
<u-button type="primary" :disabled="disabled" text="禁用"></u-button>
<u-button type="primary" loading="true" loadingText="加载中"></u-button>
<u-button type="primary" icon="map" text="图标按钮"></u-button>
<u-button type="primary" shape="circle" text="按钮形状"></u-button>
<u-button text="渐变色按钮" color="linear-gradient(to right, rgb(66, 83, 216), rgb(213, 51, 186))"></u-button>
<u-button type="primary" size="small" text="大小尺寸"></u-button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,72 @@
.swiper, .video { height: 281.5px; }
.banner, .swiper, .video { width: 100%; background-color: #fff; }
.banner image, .swiper swiper, .swiper swiper image, .video video { width: 100%; height: 100%; }
.plaintext { padding: 10px 15px; font-size: 15px; color: #333; background-color: #fff; }
/*商品界面*/
.goods-box-item { overflow: hidden; padding: 10px 10px 10px 10px; border-bottom: 0.5px solid #eeeeee;
.goods-img { width: 75px; height: 75px; display: inline-block; float: left; }
.goods-right { width: 260px; display: inline-block; float: left; margin-left: 10px;
.goods-name { font-size: 15px; color: #333; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.goods-mid { font-size: 12px; color: #999; }
.goods-buttom { overflow: hidden; position: relative; height: 30px;
.choose-specs { width: 68px; height: 24px; line-height: 23px; border-radius: 25px; margin: 0 auto; text-align: center; display: inline-block; overflow: hidden; box-sizing: border-box; float: right; font-size: 12px; border: 1px solid #ccc; position: relative; top: 6px; }
.order-num { display: block; min-width: 8px; height: 14px; line-height: 14px; background-color: #ff3b44; color: #fff; font-size: 8px; border-radius: 25px; position: absolute; right: 0px; top: 0px; padding: 0 3px; text-align: center; }
}
.goods-price { font-size: 14px; color: #eb0000; display: inline-block; }
}
}
.goods-box-item:nth-last-child(2) { border: none; }
.goods-bottom { border-top: 1px solid #eeeeee; overflow: hidden; padding: 10px 15px; background-color: #fff; }
.selected { border: 1px solid #ff0000; background-color: #fff5f6; color: #ff0000; }
.not-selected { border: 1px solid #ccc; }
.none { border: 1px dashed #ccc; color: #888; display: none; }
.select-item { padding: 10px 0; border-bottom: 1px solid #f3f3f3;
.select-btn { position: relative; margin-top: 8px; width: 100%; overflow: auto;
.sku-btn { font-size: 12px; border-radius: 5px; float: left; padding: 0 5px;
.u-avatar { top: 5px; }
}
.sku-btn.light { border: 0.5px dashed; }
.sku-btn[disabled] { color: #aaaaaa; }
}
}
/*表单结构*/
.form-input-box-item { padding: 10px; border-bottom: 1px solid #eeeeee;
.input-box-item-left { display: flex; font-size: 14px; color: #333; width: 100%; padding: 5px 0; flex-wrap: wrap; flex-direction: row; justify-content: space-between; }
.input-box-item-right { width: 100%; display: inline-block; color: #666; font-size: 14px; padding: 3px 0;
.ib-item-input { color: #666; font-size: 14px; }
.ib-item-mid { padding-top: 2px; margin: 0; display: flex;
picker { height: 20px; }
.weui-select { border: none; height: 100%; line-height: 24px; min-height: 20px; }
.icon-img { width: 16px; height: 16px; }
.icon-img-right { width: 16px; height: 16px; right: 0; }
}
.checkout-list { overflow: hidden;
.checkout-item { display: inline-block; float: left; margin-right: 20px;
.checkout-item-c { margin-right: 5px; border-radius: 3px; color: #888; }
}
}
}
.ib-item-textarea { width: 100%; height: 100px; box-sizing: border-box; border: 1px solid #e2e2e2; background-color: #f7f7f7; border-radius: 3px; padding: 10px 15px; }
}
/*上传界面*/
.upload-img-list { overflow: hidden;
.upload-img-hd { position: relative; width: 75px; height: 75px; border: 1px solid #e2e2e2; background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; float: left; margin-left: 15px;
input { position: absolute; width: 100%; height: 100%; opacity: 0; }
image { width: 24px; height: 24px; position: relative; top: 50%; left: 50%; transform: translate(-50%, -50%); }
}
.upload-img-bd { float: left; overflow: hidden;
.upload-img { width: 75px; height: 75px; position: relative; float: left; margin-right: 15px;
.upload-camera { width: 100%; height: 100%; }
.del-img { width: 18px !important; height: 18px !important; position: absolute; right: 0; top: 0; z-index: 99; }
}
.upload-img:last-child { margin-right: 0; }
}
}
/*底部按钮*/
.bottom-btn { width: 100%; height: 35px; line-height: 35px; margin: 0 auto; background-color: #333; color: #fff; font-size: 14px; border-radius: 0; }

View File

@@ -0,0 +1,883 @@
<template>
<view v-show="showPage">
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar :title="form.name" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<form @submit="formSubmit" bindreset="formReset">
<view v-if="form.headType==1">
<view class="banner">
<image :src='slideImg[0]' mode='widthFix'></image>
</view>
</view>
<!-- 轮播图 -->
<view v-else-if="form.headType == 2">
<u-swiper height="calc(350rpx * 6 / 6)" radius="0" :list="slideImg" :autoplay="autoplay" indicator indicatorMode="line" circular></u-swiper>
</view>
<view v-else-if="form.headType==3">
<view class='video'>
<video :src='form.headTypeVideo' :poster="form.headTypeValue"></video>
</view>
</view>
<!-- 纯文字 -->
<view v-if="form.description !=''">
<view class='plaintext'>
<text>{{form.description}}</text>
</view>
</view>
<view class="coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-padding-10 coreshop-bg-white">
<view v-for="(item,index) in form.items" :key="index">
<view class='goods-box-item' v-if="item.type=='goods'">
<view class='coreshop-flex coreshop-justify-between coreshop-padding-bottom-10'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<image class='goods-img' :src='item.good.image' mode='aspectFit'></image>
<view class='goods-right'>
<view class='goods-name'>{{item.good.name}}</view>
<view class='goods-mid'>
<text>已售{{item.good.buyCount}}</text>
</view>
<view class='goods-buttom'>
<view class="goods-price">{{item.good.price}}</view>
<view class='choose-specs' @click="specifications($event,item)" data-type='1' :data-goods="item.good.id" :data-id="item.id" data-statu="openspecs">
选规格
</view>
<text class='order-num' v-if="item.cartCount> 0">{{item.cartCount || 0}}</text>
</view>
</view>
</view>
<!-- 文本框 -->
<view class='form-input-box-item' v-if="item.type=='text'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<input class='ib-item-input' type="text" :name="'objName'+item.id" :data-id="item.id" v-model="item.defaultValue" :placeholder="'请输入'+item.name"></input>
</view>
</view>
<!-- 日期 -->
<view class='form-input-box-item' v-if="item.type=='date'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid">
<picker mode="date" :name="'objName'+item.id" :value="item.defaultValue" @change="bindDateChange($event,item)" :data-id='item.id'>
<view>{{item.defaultValue}}</view>
</picker>
<image class='icon-img-right' :src="$globalConstVars.apiFilesUrl+'/static/images/common/ic-unfold.png'"></image>
</view>
</view>
</view>
<!-- 时间 -->
<view class='form-input-box-item' v-if="item.type=='time'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid">
<picker class="weui-btn" :name="'objName'+item.id" mode="time" :value="item.defaultValue" @change="bindTimeChange($event,item)" :data-id='item.id'>
<view>{{item.defaultValue}}</view>
</picker>
<image class='icon-img-right' :src="$globalConstVars.apiFilesUrl+'/static/images/common/ic-unfold.png'"></image>
</view>
</view>
</view>
<!-- 范围选择 -->
<!-- 多选 -->
<view class='form-input-box-item' v-if="item.type=='checbox'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class='checkout-list'>
<checkbox-group @change="checkboxChange($event,item)" :data-value="item.id" :name="'objName'+item.id">
<label class="checkout-item coreshop-padding-bottom-10" v-for="(checkboxItem,itemIndex) in item.checkboxValue" :key="itemIndex">
<view class="checkout-item-c">
<checkbox class="" :value="checkboxItem.value" :checked="checkboxItem.checked" /> {{checkboxItem.value}}
</view>
</label>
</checkbox-group>
</view>
</view>
</view>
<!-- radio时处理 -->
<view class='form-input-box-item' v-if="item.type=='radio'">
<view class='input-box-item-left'>
<text>{{item.name}}:</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<radio-group class="uni-list" @change="radioChange($event,item)" :data-value="item.id" :name="'objName'+item.id">
<view class="coreshop-padding-bottom-10" v-for="(radioItem, itemIndex) in item.radioValue" :key="itemIndex">
<label class="coreshop-margin-right-40 coreshop-btn-all" >
<view class="coreshop-display-inline-block">
<radio class="a-radio" :id="radioItem" :value="radioItem" checked=true v-if="radioItem==item.defaultValue"></radio>
<radio class="a-radio" :id="radioItem" :value="radioItem" v-if="radioItem!=item.defaultValue"></radio>
</view>
<view class="coreshop-display-inline-block">
<label class="label-2-text" :for="radioItem">
<text>{{radioItem}}</text>
</label>
</view>
</label>
</view>
</radio-group>
</view>
</view>
<!-- 省市区选择 -->
<view class='form-input-box-item' v-if="item.type=='area'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid">
<input class="ib-item-input" :value="pickerValue" @focus="showThreePicker" :name="'objName'+item.id" style="width: 100%;" />
<coreshop-select v-model="show" mode="mutil-column-auto" :list="pickerList" :default-value="pickerIndex" @confirm="onConfirm"></coreshop-select>
</view>
</view>
</view>
<!-- 金额 -->
<view class='form-input-box-item' v-if="item.type=='money'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid">
<input class='ib-item-input' type="digit" :name="'objName'+item.id" v-model="item.defaultValue"
:placeholder="'请输入'+item.name"></input>
</view>
</view>
</view>
<!-- 密码 -->
<view class='form-input-box-item' v-if="item.type=='password'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid">
<input class='ib-item-input' type='password' :name="'objName'+item.id" v-model="item.defaultValue"
:placeholder="'请输入'+item.name"></input>
</view>
</view>
</view>
<!-- 图片 -->
<view class='form-input-box-item' v-if="item.type=='image'">
<view class='input-box-item-left'>
<text>{{item.name}}限制3张</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必传" size="mini"></u-button></view>
</view>
<view class='coreshop-margin-top-15'>
<view class='upload-img-list'>
<view class='upload-img-bd'>
<view class='upload-img' v-for="(picItem, i) in item.pics" :key="i">
<image @click='picDel(item,index,i)' :data-index="i" class='del-img' :src="$globalConstVars.apiFilesUrl+'/static/images/common/del.png'"></image>
<image class='upload-camera' :src="picItem" mode='aspectFit'></image>
<input type='text' hidden='hidden' :name="'objName'+item.id" v-model="item.pics" />
</view>
</view>
<view class='upload-img-hd'>
<image class='upload-camera' :src="$globalConstVars.apiFilesUrl+'/static/images/common/camera.png'" @click="picChoose($event,item,index)"
:data-id="item.id"></image>
</view>
</view>
</view>
</view>
<!-- 文本域 -->
<view class='form-input-box-item' v-if="item.type=='textarea'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='coreshop-margin-top-15'>
<textarea :name="'objName'+item.id" class='ib-item-textarea' :placeholder="'请输入'+item.name"></textarea>
</view>
</view>
<!-- 定位 -->
<view class='form-input-box-item' v-if="item.type=='coordinate'">
<view class='input-box-item-left'>
<text>{{item.name}}</text>
<view class="coreshop-width-fit-content" v-if="item.required"><u-button type="error" :plain="true" text="必选" size="mini"></u-button></view>
</view>
<view class='input-box-item-right'>
<view class="ib-item-mid coreshop-justify-start">
<image class='icon-img' :src="$globalConstVars.apiFilesUrl+'/static/images/common/ic-location.png'"></image>
<input class='ib-item-input coreshop-margin-right-40' :name="'objName'+item.id" :value="item.defaultValue"
disabled='disabled' placeholder="点击获取位置信息" @click="chooseLocation($event,item,index)" :data-id='item.id' />
</view>
</view>
</view>
</view>
</view>
<view class='goods-bottom' v-if="form.type==1">
<text class='coreshop-float-right coreshop-font-14 coreshop-text-black'>
合计
<text class='coreshop-text-red coreshop-font-30'>{{goodsTotalMoney}}</text>
</text>
</view>
<view class="coreshop-tabbar-height"></view>
<!-- 底部按钮 -->
<view class='coreshop-bg-white coreshop-footer-fixed coreshop-foot-padding-bottom'>
<view class="coreshop-padding-10">
<!--<u-button type="primary" :text="buttonName" :customStyle='{backgroundColor:form.buttonColor}' formType="submit" :disabled='submitStatus' :loading='submitStatus'></u-button>-->
<button :customStyle='{backgroundColor:form.buttonColor}' class="bottom-btn" data-statu="open" form-type="submit" :disabled='submitStatus' :loading='submitStatus'>
{{buttonName}}
</button>
</view>
</view>
</form>
<!--弹出框-->
<u-popup class="coreshop-bottom-popup-box" :show="bottomModal" mode="bottom" height="70%" @close="closeModal" :closeable="true">
<!-- 多规格商品弹出 -->
<block v-if="showSpecs">
<view class="coreshop-bg-white">
<!--标题-->
<view class="coreshop-text-black coreshop-text-center coreshop-margin-top-15 coreshop-margin-bottom-15 coreshop-font-lg coreshop-title-bar">
<text>选择商品</text>
</view>
<!--内容区域-->
<view class="coreshop-modal-content">
<!--选择规格-->
<view class="coreshop-common-view-box select">
<!--商品信息-->
<view class="coreshop-list menu-avatar">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius lg" :style="[{backgroundImage:'url('+ goodsInfoImage +')'}] " />
<view class="content">
<view class="coreshop-text-price-view">
<text class="coreshop-margin-right-10">{{goodsInfoName}}</text>
<text class="coreshop-font-sm coreshop-text-gray">{{goodsInfoPrint}}</text>
</view>
</view>
</view>
</view>
<!--规格数据-->
<view class="coreshop-select-btn-list-box">
<view class="coreshop-padding-bottom-10">
<view class="select-item" v-for="(value,key) in goodsSpesDesc" :key="key">
<text class='coreshop-text-black coreshop-margin-10 coreshop-solid-bottom coreshop-padding-bottom-10'>{{key}}</text>
<view class='select-btn'>
<button class="sku-btn coreshop-margin-5 coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between" :class='i.isDefault ? "selected" : "not-selected"' v-for="(i,itemIndex) in value" :key="itemIndex" :data-key="i.productId" :data-id="i.name" @click="selectSku">
<u-avatar :src="i.image" size="25" class="coreshop-margin-right-10 coreshop-margin-top-10" style="margin-left: -10px;"></u-avatar>
{{ i.name }}
</button>
</view>
</view>
</view>
<!-- 库存 -->
<view class="coreshop-text-black coreshop-padding-top-10 coreshop-padding-bottom-10">数量</view>
<view class="select-btn">
<u-number-box v-model="goodsNums" :min="0" :max="goodsInfoNumber" @change="valChange"></u-number-box>
</view>
</view>
</view>
<!--公共按钮-->
<view class="coreshop-padding-15 coreshop-text-center">
<u-button type="error" :plain="true" size="normal" @click='goodsAddCart' v-if="status">确定</u-button>
<u-button type="default" size="normal" v-else>已售罄</u-button>
</view>
</view>
</view>
</block>
</u-popup>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
formBoxId: '',
form: {
headType: 1,
},
showPage: true,
slideImg: [], //幻灯片广告数据
region: ['湖南省', '怀化市', '鹤城区'],
areaId: 431202,
pickerValue: '',
show: false,
pickerList: this.$db.get("areaList"),
province: this.$db.get("areaList"),
pickerIndex: [0, 0, 0], // picker索引值
provinceKey: -1,//省份id
cityKey: -1,//市id
areaKey: -1,//区域id
pics: [], //图片
goodsNums: 0,
cart: [],
currentKey: 0, //当前下单的商品的Key
currentGoodsId: 0, //当前选中的商品ID
goodsTotalMoney: '0.00', //商品总额
originForm: [], //原始表单
paymentType: '', //支付类型
paymentType: '', //表单付款码||表单订单
/** 商品信息*/
goodsSpesDesc: '',
productId: '',
status: '',
goodsInfoName: '',
goodsInfoImage: '',
goodsInfoPrint: '',
goodsInfoNumber: '',
selectGoodsId: '',
selectId: '',
showSpecs: false,
submitStatus: false, //按钮状态
shareUrl: '/pages/share/jump/jump',
bottomModal: false,
buttonName: '',
}
},
onLoad(options) {
var id = options.id
if (!id) {
this.$u.toast('路径错误')
return false
}
this.formBoxId = id
this.$db.set('formBoxId', id)
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
}
},
onShow() {
this.getFormDetail()
},
methods: {
//倒查城市信息
getFullPath(id, data) {
for (var i = 0; i < data.length; i++) {
if (id == data[i].value) {
if (!data[i].children) {
this.areaKey = i;
return true;
} else if (data[i].hasOwnProperty("children")) {
if (data[i].children[0] && !data[i].children[0].children) {
this.cityKey = i;
return true;
} else {
this.provinceKey = i;
return true;
}
}
} else {
if (data[i].hasOwnProperty("children")) {
if (data[i].children[0] !== undefined) {
if (data[i].children[0].hasOwnProperty("children")) {
this.provinceKey = i;
} else {
this.cityKey = i;
}
}
if (typeof data[i].children != 'undefined') {
var res = this.getFullPath(id, data[i].children);
if (res) {
return true;
}
}
}
}
}
},
init() {
console.log(this.areaId);
this.getFullPath(this.areaId, this.province);
this.pickerIndex = [this.provinceKey, this.cityKey, this.areaKey];
console.log(this.pickerIndex);
},
// 省市区联动初始化
showThreePicker() {
this.pickerValue = this.region[0] + ' ' + this.region[1] + ' ' + this.region[2];
this.init();
this.show = true;
},
onConfirm(e) {
console.log(e);
var that = this
let provinceName = e[0].label;
let cityName = e[1].label;
let countyName = e[2].label;
this.pickerValue = e[0].label + " " + e[1].label + " " + e[2].label
let data = {
provinceName: provinceName,
cityName: cityName,
countyName: countyName
}
let regionName = [provinceName, cityName, countyName];
this.region = regionName;
this.$u.api.getAreaId(data).then(res => {
if (res.status) {
that.areaId = res.data;
that.init();
} else {
uni.showModal({
title: '提示',
content: '地区选择出现问题,请重新选择地区',
showCancel: false
});
}
});
console.log(this.areaId);
},
getFormDetail() {
var _this = this;
var data = {
id: this.formBoxId,
token: this.$db.get('userToken')
}
var that = this
this.$u.api.getFormDetial(data).then(res => {
if (res.status) {
this.form = res.data
this.originForm = res.data
this.buttonName = res.data.buttonName
if (res.data.images) {
this.slideImg = res.data.images.split(',');
}
if (res.data.type == '1' || res.data.type == '2') {
if (res.data.type == '1') {
//订单
that.paymentType = this.$globalConstVars.paymentType.formPay
} else if (res.data.type == '2') {
//付款码
that.paymentType = this.$globalConstVars.paymentType.formOrder
}
}
} else {
this.showPage = false;
if (res.data.isExpires) {
uni.showModal({
title: '提示',
content: '表单已过期,请扫描新的二维码',
showCancel: false,
success: function (res) {
if (res.confirm) {
_this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' })
}
}
})
} else if (res.data.needLogin) {
console.log("要登录权限了");
this.$u.route({ type: 'switchTab', url: '/pages/index/default/default' })
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
}
}
})
},
// 选择日期
bindDateChange(e, item) {
item.defaultValue = e.target.value
},
// 选择时间
bindTimeChange(e, item) {
item.defaultValue = e.target.value
},
// 单选
radioChange(e, item) {
item.defaultValue = e.detail.value
},
// 多选
checkboxChange(e, item) {
var values = e.detail.value
for (var i = 0; i < item.checkboxValue.length; ++i) {
const checkboxItem = item.checkboxValue[i]
if (values.includes(checkboxItem.value)) {
this.$set(checkboxItem, 'checked', true)
} else {
this.$set(checkboxItem, 'checked', false)
}
}
},
/* 输入框事件 */
valChange(e) {
this.num = e.value;
},
//选择位置
chooseLocation(e, item, index) {
var pages = getCurrentPages()
var items = pages[0].$vm.form.items;
var that = this;
uni.chooseLocation({
success(e) {
item.defaultValue = e.latitude + ',' + e.longitude
items[index] = item;
setTimeout(() => {
that.form.items = items;
}, 500)
},
fail(e) {
uni.getSetting({
success(res) {
if (!res.authSetting['scope.userLocation']) {
uni.openSetting()
}
}
})
}
})
},
picChoose(e, item, index) {
var that = this
//var pages = getCurrentPages()
//if (pages.length > 1) {
// var items = pages[1].$vm.form.items;
//} else {
// var items = pages[0].$vm.form.items;
//}
var items = this.form.items;
if (!item.pics) {
item.pics = []
}
if (item.pics.length >= 3) {
that.$refs.uToast.show({ message: "最多允许上传3张图片", type: 'error' })
return false;
}
this.$upload.uploadImage(1, res => {
if (res.status) {
item.pics.push(res.data.src);
// #ifdef H5
that.$set(that.form.items, index, item)
// #endif
// #ifndef H5
items[index] = item;
setTimeout(() => {
that.form.items = items;
}, 500)
// #endif
that.$refs.uToast.show({ message: res.msg, type: 'success' })
} else {
that.$refs.uToast.show({ message: res.msg, type: 'error' })
}
})
console.log(item.pics);
},
//删除图片
picDel(item, index, i) {
item.pics.splice(i, 1)
this.$set(this.form.items, index, item)
},
//表单提交
formSubmit(e) {
var that = this
var data = e.detail.value
var keys = Object.keys(data);
var postData = [];
keys.forEach(function (value, index) {
var name = value;
var id = name.replace('objName', '');
let obj = {
key: Number(id),
value: data[name].toString()
};
postData.push(obj);
})
//订单时需要合并购物车信息
console.log(this.cart);
if (this.form.type == 1) {
if (this.cart.length < 1) {
this.$u.toast('请先选择商品')
return true
}
var tempArray = []
this.cart.map((mapItem) => {
if (tempArray.length == 0) {
let pushData = { key: mapItem.key, value: [] }
pushData.value.push(mapItem);
tempArray.push(pushData)
} else {
//判断是否存在同名key的数据进行累加
let res = tempArray.some((item) => {
if (item.key == mapItem.key) {
item.value.push(mapItem)
return true
}
})
if (!res) {
let pushData = { key: mapItem.key, value: [] }
pushData.value.push(mapItem);
tempArray.push(pushData)
}
}
})
tempArray.forEach(function (item, index) {
item.value = JSON.stringify(item.value);
postData.push(item);
})
}
console.log(data);
console.log(postData);
let userToken = this.$db.get('userToken')
let obj = {
data: postData,
id: this.form.id,
token: userToken
}
this.submitStatus = true;
this.$u.api.addSubmitForm(obj).then(res => {
this.submitStatus = false;
if (res.status) {
//表单类型判断是否需要支付,支付金额多少
if (that.form.type == '1' || that.form.type == '2') {
that.$refs.uToast.show({ message: res.msg, type: 'success' });
//跳转首页
setTimeout(function () {
//出来支付按钮
that.$u.route({
type: 'redirectTo', url: '/pages/payment/pay/pay?formId=' + res.data.formSubmitId + '&type=' + that.paymentType +
'&recharge=' + res.data.money
});
}, 1000)
} else {
that.formReset()
that.$refs.uToast.show({ message: res.msg, type: 'success' })
//跳转首页
setTimeout(function () {
wx.switchTab({
url: '/pages/index/default/default'
})
}, 1500)
}
} else {
this.$u.toast(res.msg);
}
});
},
//表单清空
formReset(e) {
this.$db.set('formBoxId', '')
this.cart = [] //初始化,刷新当前页面
this.form = this.originForm
},
closeModal() {
this.bottomModal = false;
this.showSpecs = false
},
//选择规格弹出
specifications(e, item) {
this.bottomModal = true;
this.showSpecs = true
this.selectId = e.target.dataset.id
this.selectGoodsId = e.target.dataset.goods
this.currentKey = e.target.dataset.id //当前选中的key
this.currentGoodsId = e.target.dataset.goods //当前选中的商品ID
this.getGoodsInfo(item)
},
//获取商品详情
getGoodsInfo(item) {
let goods = item.good
this.goodsSpesDesc = this.$u.deepClone(goods.product.defaultSpecificationDescription);
this.productId = goods.product.id
this.goodsInfoName = goods.product.name
this.goodsInfoImage = goods.product.images
this.goodsInfoPrint = goods.product.price
this.goodsInfoNumber = goods.product.stock
this.goodsNums = this.getNumsByKey(this.currentKey, goods.product.id)
this.status = goods.product.stock < 1 ? false : true
},
/*获取key的数量 */
getNumsByKey(key, productId) {
var that = this
if (that.cart.length < 1) {
return 0
} else {
for (var i = 0; i < that.cart.length; i++) {
if (that.cart[i].key == key && that.cart[i].productId == productId) {
return that.cart[i].nums
}
}
return 0
}
},
//加入购物车
goodsAddCart: function () {
var productId = this.productId
var currentKey = this.currentKey
console.log(productId);
console.log(currentKey);
if (this.cart.length < 1) {
this.cart.push({
key: currentKey,
productId: productId,
goodsId: this.selectGoodsId,
nums: this.goodsNums,
price: this.goodsInfoPrint
})
} else {
var isIn = false
for (var i = 0; i < this.cart.length; i++) {
if (this.cart[i].key == currentKey && this.cart[i].productId == productId) {
this.cart[i] = {
key: currentKey,
productId: productId,
goodsId: this.selectGoodsId,
nums: this.goodsNums,
price: this.goodsInfoPrint
}
isIn = true
}
}
if (!isIn) {
this.cart.push({
key: currentKey,
productId: productId,
goodsId: this.selectGoodsId,
nums: this.goodsNums,
price: this.goodsInfoPrint
})
}
}
this.closeModal();
this.getCartNums()
},
getCartNums() {
var items = this.form.items
var itemKey = ''
for (var i = 0, len = items.length; i < len; ++i) {
if (items[i].id == this.currentKey) {
itemKey = i
}
}
var that = this
if (this.form.items[itemKey].good.id == this.currentGoodsId) {
if (this.form.items[itemKey].cartCount > 0) {
var cartCount = 0
var currentKey = this.currentKey
this.cart.forEach(function (item, index, input) {
if (item.key == currentKey) {
cartCount += item.nums
}
that.form.items[itemKey].cartCount = cartCount
})
} else {
this.form.items[itemKey].cartCount = this.goodsNums
}
} else {
this.form.items[itemKey].cartCount = this.goodsNums
}
this.getGoodsTotalMoney()
},
//获取商品总额
getGoodsTotalMoney() {
var that = this
var goodsTotalMoney = 0
this.cart.forEach(function (item, index, input) {
goodsTotalMoney += item.price * item.nums
})
this.goodsTotalMoney = this.$common.formatMoney(goodsTotalMoney, 2, '')
},
getSpes: function (product) {
if (!product.defaultSpecificationDescription) {
return []
}
return product.defaultSpecificationDescription
},
//获取规格信息
selectSku(e) {
var id = e.target.dataset.key
this.$u.api.getProductInfo({
id
}).then(res => {
if (res.status) {
this.goodsSpesDesc = this.$u.deepClone(res.data.defaultSpecificationDescription);
this.productId = res.data.id
this.goodsInfoName = res.data.name
this.goodsInfoImage = res.data.images
this.goodsInfoPrint = res.data.price
this.goodsInfoNumber = res.data.stock
this.goodsNums = this.getNumsByKey(this.currentKey, res.data.id)
this.status = res.data.stock < 1 ? false : true
}
})
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 8,
params: {
id: this.formBoxId
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
}
},
watch: {
formBoxId: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.form.name,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.form.name,
path: this.shareUrl
}
},
}
</script>
<style lang="scss" scoped>
@import 'details.scss';
</style>

View File

@@ -0,0 +1,111 @@
<template>
<view>
<u-toast ref="uToast" />
<u-no-network></u-no-network>
<u-navbar title="评论列表" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<view class="coreshop-padding-10">
<!--评论-->
<view class="coreshop-bg-white">
<view v-for="(item, index) in goodsComments" :key="index">
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" v-if="index > 0" />
<view class="coreshop-common-view-box">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm">
<view class="coreshop-basis-1">
<view class="coreshop-avatar sm round" :style="[{backgroundImage:'url('+ item.avatarImage +')'}]" />
</view>
<view class="coreshop-basis-9 coreshop-font-sm">
<view>{{ (item.nickName && item.nickName != '')?item.nickName:item.mobile }}</view>
<view class="coreshop-margin-top-10">{{ item.contentBody || ''}}</view>
<view class="coreshop-text-gray coreshop-margin-top-10">
<u-rate v-model="item.score" :count="5" size="15"></u-rate>
</view>
<view class="coreshop-margin-top-10">
<u-album :urls="item.imagesArr" rowCount="4"></u-album>
</view>
<view class="coreshop-text-gray coreshop-margin-top-10 coreshop-font-12">{{ item.createTime || ''}} {{ item.addon || ''}}</view>
</view>
</view>
</view>
</view>
</view>
<u-loadmore :status="loadStatus" class="coreshop-margin-top-10" :icon-type="iconType" :load-text="loadText" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
goodsId: 0,
goodsComments: [],
page: 1,
limit: 10,
page: 1,
pageSize: 20,
loadStatus: 'loadmore',
loadIconType: 'flower',
loadText: {
loadmore: '点击或上拉加载更多',
loading: '正在加载中',
nomore: '没有更多了'
},
}
},
onLoad(options) {
this.goodsId = options.id;
this.getGoodsComments();
},
onReachBottom() {
if (this.loadStatus != 'nomore') {
this.getGoodsComments();
}
},
methods: {
// 获取商品评论信息
getGoodsComments() {
var _that = this;
let data = {
page: _that.page,
limit: _that.limit,
id: _that.goodsId,
}
this.loadStatus = 'loading';
this.$u.api.goodsComment(data).then(res => {
if (res.status == true) {
let _list = res.data.list;
// 如果评论没有图片 在这块作处理否则控制台报错
_list.forEach(item => {
if (!item.hasOwnProperty('images')) {
_that.$set(item, 'images', [])
}
_that.goodsComments.push(item);
});
// 根据count数量判断是否还有数据
if (res.data.totalPages > _that.page) {
_that.loadStatus = 'loadmore';
_that.page++;
} else {
// 数据已加载完毕
this.loadStatus = 'nomore';
}
} else {
_that.$refs.uToast.show({ message: res.msg, type: 'error' });
}
})
},
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,975 @@
<template>
<view>
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar title="商品详情" safeAreaInsetTop fixed placeholder>
<view class="coreshop-navbar-left-slot" slot="left">
<u-icon name="arrow-left" size="19" @click="goNavigateBack"></u-icon>
<u-line direction="column" :hairline="false" margin="0 8px"></u-line>
<u-icon name="home" size="22" @click="goHome"></u-icon>
</view>
<view slot="right">
</view>
</u-navbar>
<!--幻灯片-->
<u-swiper height="calc(750rpx * 6 / 6)" radius="0" :list="goodsInfo.album" :autoplay="autoplay" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
<view class="coreshop-margin-left-16 coreshop-margin-right-16 coreshop-margin-top-12 coreshop-padding-16 coreshop-border-radius-18 coreshop-bg-white">
<view class="coreshop-flex coreshop-justify-between coreshop-align-center">
<view class="coreshop-text-red coreshop-font-weight-bold">
<text class="coreshop-font-16">¥</text>
<text class="coreshop-font-24">{{ product.price || '0.00' }}</text>
</view>
<view class="coreshop-flex-sub coreshop-text-left coreshop-margin-left-12 coreshop-margin-top-6">
<text class="coreshop-font-16 coreshop-text-gray coreshop-text-through">{{ priceSection }}</text>
</view>
<view class="coreshop-flex coreshop-align-center">
<u-icon name="star-fill" :size="20" label="收藏" :labelSize="14" labelPos="right" @click="collection" v-if="isfav"></u-icon>
<u-icon name="star" :size="20" label="收藏" :labelSize="14" labelPos="right" @click="collection" v-else></u-icon>
</view>
</view>
<view class="coreshop-margin-top-12 coreshop-multiple-line-clamp">
<text class="coreshop-font-16 coreshop-font-weight-bold">{{ goodsInfo.name || '' }}</text>
</view>
<view class="coreshop-margin-top-8 coreshop-single-line-clamp">
<text class="coreshop-font-14 coreshop-text-gray">{{ goodsInfo.brief || '' }}</text>
</view>
<view class="coreshop-flex coreshop-margin-top-8">
<u-tag :text="goodsInfo.brand.name" v-if="goodsInfo.brand"></u-tag>
<view class="tag-64 cp832" wx:if="{{$root.m1}}">
<text class="font-color-orange">832产品</text>
</view>
<view class="tag-64 shitang" wx:if="{{$root.m2}}">
<text class="font-color-blue">食堂专供</text>
</view>
</view>
<view class="coreshop-margin-top-16 coreshop-padding-top-16 coreshop-solid-top coreshop-flex coreshop-justify-between coreshop-align-center coreshop-text-gray">
<view class="coreshop-font-12">
<text>运费</text>
<text class="font-color-orange">包邮</text>
</view>
<view class="coreshop-font-12">
<text>销量</text>
<text>{{ goodsInfo.buyCount || '0' }}</text>
</view>
<view class="coreshop-font-12">
<text>库存</text>
<text>{{product.stock}}</text>
</view>
</view>
</view>
<!--限时秒杀-->
<!--<view class="coreshop-limited-seckill-box coreshop-bg-red coreshop-flex coreshop-justify-start">-->
<!--<text class="coreshop-text-price coreshop-font-20">{{ product.price || '0.00' }}</text>-->
<!--<text class="coreshop-text-price coreshop-font-20">{{ priceSection }}</text>
<view class="coreshop-font-xs price-4 coreshop-margin-left-20">
<view v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && product.pointsDeduction > 0">
<view class="coreshop-padding-bottom-5 coreshop-font-14">
兑换价{{pointDiscountedProportion * product.pointsDeduction }}{{ pointShowName}}+{{ product.price - product.pointsDeduction}}
</view>
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
<view class="coreshop-text-through coreshop-padding-bottom-5">原价{{ product.mktprice || '0.00'}}</view>
<view class="coreshop-margin-left-10">{{ goodsInfo.buyCount || '0' }} 人已购买</view>
<view class="coreshop-margin-left-10" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">购买赠送:{{product.points}}{{ pointShowName}}</view>
</view>
</view>
<view v-else>
<view class="coreshop-text-through coreshop-padding-bottom-5">原价{{ product.mktprice || '0.00'}}</view>
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
<view>{{ goodsInfo.buyCount || '0' }} 人已购买</view>
<view class="coreshop-margin-left-10" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && product.points > 0">购买赠送:{{product.points}}{{ pointShowName}}</view>
</view>
</view>
</view>
<view class="coreshop-text-right coreshop-share-right">
<u-icon name="share" @click="goShare()" label="分享" size="20" labelSize="11" color="#fff" labelColor="#fff" labelPos="bottom"></u-icon>
</view>
</view>-->
<!--标题-->
<!--<view class="coreshop-bg-white coreshop-common-view-box coreshop-good-title-view-box">
<view class="title-view coreshop-text-black coreshop-font-lg coreshop-text-bold">
<view class="brand-tag" v-if="goodsInfo.brand"><u-tag :text="goodsInfo.brand.name" type="error" size="mini" /></view>
{{ goodsInfo.name || '' }}
</view>
<view class="coreshop-bg-red-light radius coreshop-margin-top-10 coreshop-title-tip-box">
<text class="coreshop-font-sm">{{ goodsInfo.brief || '' }}</text>
</view>
</view>-->
<!--促销-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="promotion.length > 0" @tap="promotionTap">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">促销</text>
</view>
<view class="coreshop-basis-8">
<view v-for="(item, index) in promotion" :key="index" :class="index> 1 ? 'coreshop-margin-top-10':''">
<text class="cu-tag line-orange sm radius">{{item.name}}</text>
</view>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--服务-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" @tap="serviceTap" v-if="serviceDescription.service.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">服务</text>
</view>
<view class="coreshop-basis-8">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<u-icon name="checkmark-circle" size="12" labelSize="12" color="#e54d42" :label="item.title" v-for="(item, index) in serviceDescription.service" :key="index" class="coreshop-margin-right-10"></u-icon>
</view>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--发货/规格-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box" v-if="serviceDescription.delivery.length>0">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">发货</text>
</view>
<view class="coreshop-coreshop-basis-9" v-for="(item, index) in serviceDescription.delivery" :key="index">
<text class="coreshop-font-sm">{{item.description}}</text>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" v-if="serviceDescription.delivery.length>0" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10" @tap="openSkuPopup">
<view class="coreshop-basis-1">
<text class="coreshop-text-gray">规格</text>
</view>
<view class="coreshop-basis-8">
<text class="coreshop-font-sm">{{ product.spesDesc || ''}}</text>
</view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right-double"></u-icon>
</view>
</view>
</view>
</view>
<!--评论-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-10" v-if="goodsComments.length">
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-top-10 coreshop-flex-direction-row">
<view class="coreshop-basis-2">
<text class="coreshop-text-black coreshop-font-md">评价{{goodsComments.length}}</text>
</view>
<view class="coreshop-basis-7"></view>
<view class="coreshop-basis-1">
<view class="coreshop-float-right">
<u-icon name="arrow-right" @tap="goGoodComments(goodsInfo.id)"></u-icon>
</view>
</view>
</view>
<view v-for="(item, index) in goodsComments" :key="index">
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-flex coreshop-flex-wrap coreshop-font-sm coreshop-padding-10 coreshop-flex-direction-row">
<view class="coreshop-basis-1">
<view class="coreshop-avatar sm round" :style="[{backgroundImage:'url('+ item.avatarImage +')'}]" />
</view>
<view class="coreshop-basis-9 coreshop-font-sm">
<view>{{ (item.nickName && item.nickName != '')?item.nickName:item.mobile }}</view>
<view class="coreshop-margin-top-10">{{ item.contentBody || ''}}</view>
<view class="coreshop-text-gray coreshop-margin-top-5">
<u-rate v-model="item.score" :count="5" size="15"></u-rate>
</view>
<view class="coreshop-margin-top-10" v-if="item.imagesArr">
<u-album :urls="item.imagesArr" rowCount="4"></u-album>
</view>
<view class="coreshop-text-gray coreshop-margin-top-5 coreshop-font-12">{{ item.createTime || ''}} {{ item.addon || ''}}</view>
</view>
</view>
</view>
</view>
<!--内容区-->
<view class="coreshop-margin-top-10 coreshop-bg-white">
<view class="coreshop-font-md coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row">
<u-icon name="more-circle" color="#e54d42" label="商品详情" labelSize="15px" label-pos="right"></u-icon>
</view>
<!--参数-->
<view class="coreshop-padding-bottom-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-flex-direction-row" v-for="(item, index) in goodsParams" :key="index">
<text class="coreshop-text-gray">{{ item.name || ''}}</text>
<text class="coreshop-text-black">{{ item.value || ''}}</text>
</view>
<view class="coreshop-padding-10">
<u-parse :content="goodsInfo.intro" :selectable="true" v-if="goodsInfo.intro"></u-parse>
<!-- 无数据时默认显示 -->
<view class="coreshop-emptybox" v-else>
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/data.png'" icon-size="150" text="详情为空" mode="list"></u-empty>
</view>
</view>
</view>
<!-- 分享弹窗 -->
<view class="coreshop-padding-0">
<u-popup mode="bottom" :show="shareBox" ref="share">
<!-- #ifdef H5 -->
<coreshop-share-h5 :shareType='$globalConstVars.shareType.goods' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-h5>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<coreshop-share-wx :shareType='$globalConstVars.shareType.goods' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-wx>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<coreshop-share-alipay :shareType='$globalConstVars.shareType.goods' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-alipay>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<coreshop-share-tt :shareType='$globalConstVars.shareType.goods' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-tt>
<!-- #endif -->
<!-- #ifdef APP-PLUS || APP-PLUS-NVUE -->
<coreshop-share-app :shareType='$globalConstVars.shareType.goods' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></coreshop-share-app>
<!-- #endif -->
</u-popup>
<div id="qrCode" ref="qrCodeDiv"></div>
</view>
<!--常见问题-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-margin-bottom-30 coreshop-common-view-box">
<view class="coreshop-font-md coreshop-padding-bottom-20 coreshop-flex-direction-row">
<u-icon name="question-circle" color="#e54d42" label="常见说明" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-flex coreshop-flex-wrap coreshop-margin-bottom-10 coreshop-flex-direction-row" v-for="(item, index) in serviceDescription.commonQuestion" :key="index">
<view class="coreshop-basis-2">
{{item.title}}
</view>
<view class="coreshop-basis-8">
<view class="coreshop-font-12">{{item.description}}</view>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-text-center coreshop-text-blue coreshop-padding-top-10" @tap="goArticleList()">查看更多问题</view>
</view>
<!--商家及推荐-->
<view class="coreshop-margin-top-10 coreshop-bg-white coreshop-common-view-box coreshop-goods-shop-info-view-box">
<view class="coreshop-shop-view">
<view class="coreshop-position-absolute">
<u-avatar :src="shopLogo"></u-avatar>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-left-40 coreshop-padding-right-40">
<view class="coreshop-margin-bottom-5">{{shopName}}</view>
<view class="coreshop-font-sm u-line-1">{{shareTitle}}</view>
</view>
<u-button type="error" size="mini" :plain="true" @click="doPhoneCall">联系商家</u-button>
</view>
<view class="coreshop-solid-bottom coreshop-padding-top-5 coreshop-padding-bottom-5" />
<view class="live-tag-view coreshop-margin-top-10 coreshop-margin-bottom-10">
<view class="text-view">
<view class="location-tag"><u-tag text="已定位" mode="plain" size="mini" type="warning" /></view>
<text class="coreshop-margin-left-10 u-line-1">可直接获取商家地理位置信息</text>
</view>
<view class="coreshop-font-sm coreshop-text-red go-map-box" @tap="goShopMap">
<text class="coreshop-margin-right-10">去地图</text>
<u-icon name="arrow-right"></u-icon>
</view>
</view>
<view class="coreshop-solid-bottom coreshop-margin-top-10 coreshop-margin-bottom-10" />
<view class="coreshop-good-shop-recommend-list-box">
<view class="coreshop-font-sm coreshop-padding-top-10 ">本店推荐</view>
<!--滑动列表-->
<view class="recommend-scroll-box">
<scroll-view class="recommend-scroll" scroll-x>
<block v-for="(items,indexs) in shopRecommendData" :key="indexs">
<view :id="['scroll' + (indexs + 1 )]" class="recommend-scroll-item" @tap="goGoodsDetail(items.id)">
<u--image :src="items.image" mode="widthFix" width="91px" height="91px" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-min-height-34">{{items.name}}</view>
<view class="coreshop-text-red coreshop-text-price coreshop-margin-top-10 coreshop-margin-bottom-10 coreshop-font-md coreshop-flex-direction-row">
{{items.price}}
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
<!--为您推荐-->
<view class="coreshop-recommended-title-view">
<view class="coreshop-flex coreshop-flex-wrap coreshop-flex-direction-row">
<view class="coreshop-flex-4 coreshop-text-right">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
<view class="coreshop-flex-4 coreshop-text-center">
<text class="coreshop-text-black coreshop-font-lg">为您推荐</text>
</view>
<view class="coreshop-flex-4 coreshop-text-left">
<image class="img-anc" src="/static/images/common/anc.png" mode="widthFix" />
</view>
</view>
</view>
<!--推荐列表-->
<view class="coreshop-goods-group" v-if="otherRecommendData.length>0">
<u-grid col="2" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '0px'}" v-for="(item, index) in otherRecommendData" :key="index" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image :src="item.image" mode="widthFix" width="100%" height="174px" radius="10"></u--image>
<view class="good_title u-line-2 coreshop-min-height-34">
{{item.name}}
</view>
<view class="good-price">
{{item.price}} <span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15 coreshop-text-gray">{{item.mktprice}}</span>
</view>
<view class="good-tag-recommend" v-if="item.isRecommend">
推荐
</view>
<view class="good-tag-hot" v-if="item.isHot">
热门
</view>
</view>
</u-grid-item>
</u-grid>
</view>
<!--占位底部距离-->
<view class="coreshop-tabbar-height" />
<!--底部操作-->
<view class="coreshop-good-footer-fixed">
<view class="tabbar">
<view class="coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<!-- 客服按钮 -->
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
<view class="action" @click="showChat()">
<button class="noButtonStyle">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="action">
<button open-type="contact" bindcontact="showChat" class="noButtonStyle" :send-message-title="goodsInfo.name" :send-message-path="'/pages/goods/goodDetails/goodDetails?id='+goodsInfo.id" :send-message-img="goodsInfo.image" show-message-card="true">
<u-icon name="server-fill" :size="20" label="找客服" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
<!-- #endif -->
<view class="action" @click="collection">
<button class="noButtonStyle">
<u-icon name="star-fill" :size="20" label="已收藏" :labelSize="12" labelPos="bottom" v-if="isfav"></u-icon>
<u-icon name="star" :size="20" label="加收藏" :labelSize="12" labelPos="bottom" v-else></u-icon>
</button>
</view>
<view class="action" @click="redirectCart">
<button class="noButtonStyle">
<u-badge type="warning" :value="cartNums" showZero="false" absolute="true" :offset="[1, 4]"></u-badge>
<u-icon name="shopping-cart" :size="20" label="购物车" :labelSize="12" labelPos="bottom"></u-icon>
</button>
</view>
</view>
<view class="btn-group coreshop-flex coreshop-align-center coreshop-flex-direction-row coreshop-justify-between coreshop-basis-5">
<u-button type="primary" size="normal" shape="circle" @click="openSkuPopup">
<text class="coreshop-font-12">加购物车</text>
</u-button>
<u-button type="success" size="normal" shape="circle" @click="openSkuPopup">
<text class="coreshop-font-12">立即购买</text>
</u-button>
</view>
</view>
</view>
<!--弹出框-->
<u-popup class="coreshop-bottom-popup-box" :show="bottomModal" mode="bottom" @close="hideModal" :closeable="true" safeAreaInsetTop>
<view class="radius coreshop-bg-white">
<!--标题-->
<view class="coreshop-text-black coreshop-text-center coreshop-margin-top-15 coreshop-margin-bottom-15 coreshop-font-lg coreshop-title-bar">
<text>{{modalTitle}}</text>
</view>
<!--内容区域-->
<view class="coreshop-modal-content">
<!--服务区域-->
<view class="coreshop-common-view-box service" v-if="modalType=='service'">
<view v-for="(item, index) in serviceDescription.service" :key="index">
<view class="coreshop-font-md coreshop-padding-bottom-10 coreshop-padding-top-10 coreshop-flex-direction-row">
<u-icon name="checkmark-circle" color="#e54d42" :label="item.title" labelSize="15px" label-pos="right"></u-icon>
</view>
<view class="coreshop-font-sm coreshop-text-gray coreshop-padding-bottom-5 coreshop-padding-top-5">
{{item.description}}
</view>
</view>
</view>
<!--促销区域-->
<view class="coreshop-common-view-box promotion" v-if="modalType=='promotion'">
<view class="text-view" v-for="(item, index) in promotion" :key="index">
<text class="cu-tag line-orange radius sm">{{item.name}}</text>
<text class="coreshop-margin-left-10 u-line-5 coreshop-text-black">{{item.name}}</text>
</view>
</view>
</view>
</view>
</u-popup>
<vk-data-goods-sku-popup ref="skuPopup"
v-model="skuKey"
border-radius="20"
:amount-type="0"
:localdata="goodsSkuInfo"
:mode="skuMode"
@open="onOpenSkuPopup"
@close="onCloseSkuPopup"
@add-cart="addCart"
@buy-now="buyNow"></vk-data-goods-sku-popup>
<!-- 右边浮动球 -->
<coreshop-fab horizontal="right" vertical="bottom" direction="vertical"></coreshop-fab>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
// 是否打开SKU弹窗
skuKey: false,
// SKU弹窗模式
skuMode: 1,
// 后端返回的商品信息
goodsSkuInfo: {},
goodsId: 0, // 商品id
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 货品详情
priceSection: '',
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
type: 2, // 1加入购物车 2购买
cartType: this.$globalConstVars.paymentType.common,
isfav: false, // 商品是否收藏
bottomModal: false,
modalTitle: '',
modalType: 'promotion',
selectType: '',
shareUrl: '/pages/share/jump/jump',
shareBox: false,
serviceDescription: {
commonQuestion: [],
delivery: [],
service: [],
},
autoplay: true,
}
},
onLoad(options) {
//获取商品ID
if (options.id != '') {
this.goodsId = options.id;
}
if (this.goodsId) {
this.getServiceDescription();
this.getGoodsDetail();
this.getGoodsParams();
this.getGoodsComments();
} else {
this.$refs.uToast.show({
message: '获取失败', type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
});
}
// 获取购物车数量
this.getCartNums();
//获取推荐商品数据
this.getGoodsRecommendList();
var _this = this
if (this.$db.get('userToken')) {
this.$u.api.userInfo().then(res => {
if (res.status) {
_this.userInfo = res.data
_this.hasLogin = true;
// #ifdef MP-WEIXIN
//微信小程序打开客服时,传递用户信息
var kefupara = {}
kefupara.nickName = res.data.nickname
kefupara.tel = res.data.mobile
_this.kefupara = JSON.stringify(kefupara)
// #endif
}
})
};
},
onShow() {
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
},
userInfo: {
get() {
return this.$store.state.userInfo;
},
set(val) {
this.$store.commit('userInfo', val);
}
},
pointSwitch() { return this.$store.state.config.pointSwitch },
pointShowExchangePrice() { return this.$store.state.config.pointShowExchangePrice },
pointDiscountedProportion() { return this.$store.state.config.pointDiscountedProportion },
pointExchangeModel() { return this.$store.state.config.pointExchangeModel },
pointShowName() { return this.$store.state.config.pointShowName },
pointGetModel() { return this.$store.state.config.pointGetModel },
pointShowPoint() { return this.$store.state.config.pointShowPoint },
shopName() {
return this.$store.state.config.shopName;
},
shareTitle() {
return this.$store.state.config.shareTitle;
},
shopLogo() {
return this.$store.state.config.shopLogo;
},
// 获取店铺联系人手机号
shopMobile() {
return this.$store.state.config.shopMobile || 0;
},
// 优惠信息重新组装
promotion() {
let arr = [];
if (this.product.promotionList) {
for (let k in this.product.promotionList) {
arr.push(this.product.promotionList[k]);
}
}
return arr;
},
shareHref() {
let pages = getCurrentPages()
let page = pages[pages.length - 1]
// #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId;
// #endif
// #ifdef MP-ALIPAY
return this.$globalConstVars.apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId;
// #endif
},
},
methods: {
// 打开sku弹出
openSkuPopup() {
this.skuKey = true;
},
closeSkuPopup() {
this.skuKey = false;
},
// sku组件监听
onOpenSkuPopup() {
//console.log("监听 - 打开sku组件");
},
onCloseSkuPopup() {
//console.log("监听 - 关闭sku组件");
},
// 加入购物车按钮
addCart(selectShop) {
//console.log("监听 - 加入购物车");
//console.log(selectShop);
var that = this;
uni.showLoading({
title: '加载中'
});
if (!this.hasLogin) {
uni.hideLoading();
this.$store.commit('showLoginTip', true);
return false;
}
if (selectShop.buy_num > 0) {
let data = {
productId: selectShop._id,
nums: selectShop.buy_num,
type: 1,
}
this.$u.api.addCart(data).then(res => {
if (res.status) {
uni.hideLoading();
that.getCartNums(); // 获取购物车数量
that.$refs.uToast.show({ message: res.msg, type: 'success' });
} else {
that.$u.toast(res.msg);
uni.hideLoading();
}
});
}
that.closeSkuPopup();
},
// 立即购买
buyNow(selectShop) {
//console.log("监听 - 立即购买");
//console.log(selectShop);
var that = this;
uni.showLoading({
title: '加载中'
});
if (!this.hasLogin) {
uni.hideLoading();
this.$store.commit('showLoginTip', true);
return false;
}
if (selectShop.buy_num > 0) {
let data = {
productId: selectShop._id,
nums: selectShop.buy_num,
type: 2,
cartType: this.cartType
}
this.$u.api.addCart(data).then(res => {
if (res.status) {
let cartIds = res.data;
that.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds));
uni.hideLoading();
} else {
this.$u.toast(res.msg);
uni.hideLoading();
}
});
}
that.closeSkuPopup();
},
//获取服务项
getServiceDescription() {
let _this = this;
this.$u.api.getServiceDescription().then(res => {
if (res.status == true) {
_this.serviceDescription.commonQuestion = res.data.commonQuestion;
_this.serviceDescription.delivery = res.data.delivery;
_this.serviceDescription.service = res.data.service;
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
})
},
// 获取商品详情
getGoodsDetail() {
let _this = this;
let data = {
id: parseInt(this.goodsId),
data: true
}
// 如果用户已经登录 要传用户token
let userToken = this.$db.get("userToken");
if (userToken) {
this.$u.api.goodsDetailByToken(data).then(res => {
if (res.status == true) {
let info = res.data;
_this.product = res.data.product;
_this.goodsInfo = info;
_this.goodsSkuInfo = res.data.skuList;
//价格区间
if (res.data.minPrice != res.data.maxPrice) {
_this.priceSection = res.data.minPrice + '~' + res.data.maxPrice;
} else {
_this.priceSection = res.data.product.price;
}
if (_this.goodsInfo.album) {
var albums = [];
for (var i = 0; i < _this.goodsInfo.album.length; i++) {
let album = {
url: _this.goodsInfo.album[i],
type: 'image'
}
albums.push(album);
}
_this.goodsInfo.album = albums;
if (_this.goodsInfo.video) {
let videoObj = {
url: _this.goodsInfo.video,
poster: _this.goodsInfo.image,
type: 'video'
}
_this.goodsInfo.album.unshift(videoObj);
_this.autoplay = false;
}
}
_this.isfav = res.data.isFav;
// 判断如果登录用户添加商品浏览足迹
if (userToken) {
_this.goodsBrowsing();
}
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
})
} else {
this.$u.api.goodsDetail(data).then(res => {
if (res.status == true) {
_this.goodsInfo = res.data;
_this.product = res.data.product;
_this.goodsSkuInfo = res.data.skuList;
//价格区间
if (res.data.minPrice != res.data.maxPrice) {
_this.priceSection = res.data.minPrice + '~' + res.data.maxPrice;
} else {
_this.priceSection = res.data.product.price;
}
if (_this.goodsInfo.album) {
var albums = [];
for (var i = 0; i < _this.goodsInfo.album.length; i++) {
let album = {
url: _this.goodsInfo.album[i],
type: 'image'
}
albums.push(album);
}
_this.goodsInfo.album = albums;
if (_this.goodsInfo.video) {
let videoObj = {
url: _this.goodsInfo.video,
poster: _this.goodsInfo.image,
type: 'video'
}
_this.goodsInfo.album.unshift(videoObj);
_this.autoplay = false;
}
}
_this.isfav = res.data.isFav;
// 判断如果登录用户添加商品浏览足迹
if (userToken) {
_this.goodsBrowsing();
}
} else {
_this.$refs.uToast.show({
message: res.msg, type: 'error', complete: function () {
uni.navigateBack({
delta: 1
});
}
})
}
})
}
},
// 获取推荐商品信息
getGoodsRecommendList() {
let _this = this;
let recommenddata = {
id: 10,
data: true
}
_this.$u.api.getGoodsRecommendList(recommenddata).then(res => {
if (res.status) {
_this.shopRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
let data = {
id: 10
}
_this.$u.api.getGoodsRecommendList(data).then(res => {
if (res.status) {
_this.otherRecommendData = _this.$u.randomArray(res.data);
} else {
_this.$u.toast(res.msg)
}
});
},
// 获取购物车数量
getCartNums() {
let userToken = this.$db.get("userToken");
if (userToken && userToken != '') {
// 获取购物车数量
this.$u.api.getCartNum().then(res => {
if (res.status) {
this.cartNums = res.data;
}
})
}
},
// 商品收藏/取消
collection() {
let data = {
id: this.goodsInfo.id
}
this.$u.api.goodsCollection(data).then(res => {
if (res.status) {
this.isfav = !this.isfav;
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false });
} else {
this.$u.toast(res.msg);
}
})
},
// 获取商品参数信息
getGoodsParams() {
this.$u.api.goodsParams({
id: this.goodsId
}).then(res => {
if (res.status == true) {
this.goodsParams = res.data;
}
})
},
// 获取商品评论信息
getGoodsComments() {
let data = {
page: 1,
limit: 5,
id: this.goodsId,
}
this.$u.api.goodsComment(data).then(res => {
if (res.status == true) {
let _list = res.data.list;
// 如果评论没有图片 在这块作处理否则控制台报错
_list.forEach(item => {
if (!item.hasOwnProperty('images')) {
this.$set(item, 'images', [])
}
});
this.goodsComments = [...this.goodsComments, ..._list];
} else {
console.log("错误2");
this.$u.toast(res.msg);
}
})
},
// 添加商品浏览足迹
goodsBrowsing() {
let data = {
id: this.goodsInfo.id
}
this.$u.api.addGoodsBrowsing(data).then(res => { });
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(index) {
if (this.goodsInfo.album[index].type == 'image') {
uni.previewImage({
urls: [this.goodsInfo.album[index].url],
});
}
},
//在线客服
showChat() {
// #ifdef H5
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 2,
params: {
goodsId: this.goodsInfo.id,
}
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
},
serviceTap() {
this.modalTitle = "说明";
this.modalType = 'service';
this.showModal();
},
promotionTap() {
this.modalTitle = "促销优惠";
this.modalType = 'promotion';
this.showModal();
},
showModal() {
this.bottomModal = true;
console.log("打开弹窗");
},
hideModal(e) {
this.bottomModal = false;
this.modalTitle = "";
this.modalType = '';
},
},
watch: {
goodsInfo: {
handler() {
this.getShareUrl();
},
deep: true
}
},
//分享
onShareAppMessage(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.goodsInfo.name,
imageUrl: this.goodsInfo.image,
path: this.shareUrl
}
},
}
</script>
<style lang="scss">
image { display: block; }
</style>

View File

@@ -0,0 +1,24 @@
.wrap { display: flex; flex-direction: column; height: calc(100vh - var(--window-top)); width: 100%; }
.cart-shoppingcard { background: #FFFFFF; border-radius: 4px; margin: 0 10px; margin-top: 10px; border-radius: 8px; padding: 10px 10px; background: #FFFFFF !important;
.cart-shopp-name { width: calc(100% - 60px); }
.cart-shoppingcard-goods { display: flex; flex-wrap: nowrap;
.cart-shoppingcard-goods-checkbtn { width: 30px; flex-shrink: 0; }
.cart-shoppingcard-goods-image { width: 60px; height: 60px; border-radius: 5px; margin-right: 10px; flex-shrink: 0; }
.cart-shoppingcard-goods-body { width: 100%;
.cart-shoppingcard-goods-title { line-height: 1.4em; }
.cart-shoppingcard-goods-price { color: #e54d42; font-size: 16px; display: flex; flex-wrap: nowrap; justify-content: space-between; }
.cart-shoppingcard-goods-number { padding: 2px 0; }
.cart-shoppingcard-remove { display: block; text-align: right; line-height: 25px; color: #CCCCCC; font-size: 12px; }
}
}
}
.cart-shoppingcard:last-child { margin-bottom: 75px }
.cart-shoppingcard-checkbtn { /*width: 100px;*/ margin-left: 15px; flex-shrink: 0; }
.cart-shoppingcard-checkout { width: 90px; height: 50px; line-height: 50px; font-size: 14px; text-align: center; flex-shrink: 0; }
.cart-bg-gray { background: #A5A7B2 !important; color: #FFFFFF !important; }
.cart-badge { border-radius: 19px; height: 19px; line-height: 19px; padding: 0 6.5px; font-size: 11px; }
.cart-footer { background-color: #FFFFFF; width: 100%; position: fixed; left: 0; bottom: 0; z-index: 99; }

View File

@@ -0,0 +1,398 @@
<template>
<view class="wrap">
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar leftIcon="search" title="购物车" safeAreaInsetTop fixed placeholder @leftClick="goSearch"></u-navbar>
<!-- 购物车主结构 -->
<view v-if="shoppingCard.list && shoppingCard.list.length > 0">
<u-checkbox-group placement="column" v-model="cartIds" @change="itemChange">
<view class="cart-shoppingcard" v-for="(item, index) in shoppingCard.list" :key="index">
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-align-center">
<view class="cart-shopp-name">
<text class="coreshop-font-15 coreshop-text-bold">{{item.products.name}}</text>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between">
<u-button :plain="true" size="mini" @click="goGoodsDetail(item.products.goodsId)">浏览</u-button>
</view>
</view>
<view style="height: 12.5px;"></view>
<view class="cart-shoppingcard-goods">
<view class="cart-shoppingcard-goods-checkbtn">
<u-checkbox active-color="red" :name="item.id"></u-checkbox>
</view>
<image class="cart-shoppingcard-goods-image" :src="item.products.images && item.products.images!='null' ? item.products.images+'?x-oss-process=image/resize,m_lfit,h_320,w_240' : '/static/images/common/empty-banner.png'" mode="widthFix"></image>
<view class="cart-shoppingcard-goods-body">
<view class="cart-shoppingcard-goods-title" v-if="item.products.spesDesc">{{ item.products.spesDesc }}</view>
<view class="cart-shoppingcard-goods-title" v-if="item.products.promotionList">
<text class="cart-badge cart-bg-gray" v-for="(v, k) in item.products.promotionList" :key="k" :class="v.type !== 2 ? 'bg-gray' : ''"> {{ v.name }}</text>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-margin-top-10">
<view class="coreshop-flex coreshop-flex-direction-row coreshop-align-center">
<text class="cart-shoppingcard-goods-price">{{item.products.price}}</text>
<text class="coreshop-font-10 coreshop-margin-left-5" v-if="pointSwitch==1 && pointGetModel==2 && pointShowPoint==1 && item.products.points > 0">
( {{item.products.points}}{{ pointShowName}})
</text>
</view>
<view class="cart-shoppingcard-goods-number">
<u-number-box buttonSize="24" integer :name="index" :value="item.nums" ref="index" @change="toNumberChange" :step="1" :min="1" :max="item.products.stock"></u-number-box>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-margin-top-10">
<text class="cart-shoppingcard-remove coreshop-text-green" v-if="item.stockNo">库存不足</text>
<text class="cart-shoppingcard-remove coreshop-text-green" v-else-if="item.stockTension">库存紧张</text>
<text class="cart-shoppingcard-remove " v-else=""></text>
</view>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-margin-top-10">
<view class="coreshop-flex coreshop-flex-direction-row coreshop-font-13" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && item.products.pointsDeduction > 0">
<view>
{{ pointShowName}}兑换价:
</view>
<view class="coreshop-text-red">
{{pointDiscountedProportion * item.products.pointsDeduction }}{{ pointShowName}}+{{ item.products.price - item.products.pointsDeduction}}元
</view>
</view>
<view v-else></view>
<u-icon name="trash" size="14" @click="removeGoods" :index="index" label="删除" labelSize="12"></u-icon>
</view>
</view>
</u-checkbox-group>
</view>
<!-- 购物车为空 -->
<view v-else>
<view class="coreshop-emptybox">
<u-empty :icon="$globalConstVars.apiFilesUrl+'/static/images/empty/cart.png'" icon-size="150" text="您的购物车空空如也" mode="list"></u-empty>
<navigator class="coreshop-btn" url="/pages/category/index/index" open-type="switchTab">随便逛逛</navigator>
</view>
</view>
<view class="coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-align-center cart-footer" v-if="shoppingCard.list && shoppingCard.list.length >= 1">
<view class="cart-shoppingcard-checkbtn coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-align-center">
<u-checkbox-group v-model="selectAll" @change="itemChangeAll">
<u-checkbox name="全选" label="全选" active-color="red"></u-checkbox>
</u-checkbox-group>
</view>
<view class="cart-shoppingcard-count coreshop-flex coreshop-flex-direction-column coreshop-justify-between coreshop-align-left coreshop-margin-right-5" v-if="pointSwitch==1 && pointExchangeModel==2 && pointShowExchangePrice==1 && pointShowMoney>0">
<view>
<text class="cart-text">合计 :</text>
<text class="coreshop-font-18 coreshop-text-red">¥{{totalprice}}</text>
</view>
<view>
<text class="coreshop-font-12">{{ pointShowName}}兑换价:</text>
<text class="coreshop-font-12 coreshop-text-red">{{pointShowText}}</text>
</view>
</view>
<view class="cart-shoppingcard-count coreshop-flex coreshop-flex-direction-row coreshop-justify-between coreshop-align-center coreshop-margin-right-5" v-else>
<text class="cart-text">合计 :</text>
<text class="coreshop-font-18 coreshop-text-red">¥{{totalprice}}</text>
</view>
<view class="cart-shoppingcard-checkout coreshop-bg-red" @tap="checkout">立即结算</view>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
export default {
data() {
return {
// 总价
totalprice: '0.00',
// 选择文本
// 购物车数据 可以来自 api 请求或本地数据
shoppingCard: {},
cartIds: [], //选中ids
goSettlement: false, //去结算按钮
selectAll: ['全选'],
pointShowText: "",
pointShowMoney: 0,
}
},
//页面加载
onShow() {
let userToken = this.$db.get('userToken');
if (userToken) {
this.cartIds = [];
this.getCartData(); //获取购物车数据
// 初始化时候计算总价如果使用api 获取购物车项目在 api 请求完成后执行此函数
//this.countTotoal();
}
},
computed: {
// 从vuex中获取店铺名称
shopName() {
return this.$store.state.config.shopName;
},
GoodsStocksWarn() {
return this.$store.state.config.goodsStocksWarn;
},
pointSwitch() { return this.$store.state.config.pointSwitch },
pointShowExchangePrice() { return this.$store.state.config.pointShowExchangePrice },
pointDiscountedProportion() { return this.$store.state.config.pointDiscountedProportion },
pointExchangeModel() { return this.$store.state.config.pointExchangeModel },
pointShowName() { return this.$store.state.config.pointShowName },
pointGetModel() { return this.$store.state.config.pointGetModel },
pointShowPoint() { return this.$store.state.config.pointShowPoint },
},
methods: {
//数组转字符串
arrayToStr: function (array) {
return array.toString();
},
//获取购物车数据
getCartData: function () {
let _this = this;
let cartIds = _this.arrayToStr(_this.cartIds);
let data = {
ids: cartIds,
display: 'all'
};
this.$u.api.cartList(data).then(res => {
if (res.status) {
_this.shoppingCard = res.data;
_this.showHandle(_this.shoppingCard); //数量设置
//console.log(_this.shoppingCard);
}
});
},
//渲染前配置数据
showHandle: function (data, flag = true) {
let _this = this;
let goSettlement = false;
for (let i in data.list) {
//不可能购买0件
if (data.list[i].nums < 1) {
data.list[i].nums = 1;
}
//不能买大于库存的数量(库存不足)
let stockNo = false;
let maxStock = data.list[i].products.stock;
if (data.list[i].nums > data.list[i].products.stock) {
stockNo = true;
maxStock = data.list[i].nums;
}
data.list[i].maxStock = maxStock;
data.list[i].stockNo = stockNo;
//库存紧张
let stockTension = false;
if (_this.GoodsStocksWarn >= data.list[i].products.stock) {
stockTension = true;
}
data.list[i].stockTension = stockTension;
//设置样式
data.list[i].minStatus = 'normal';
data.list[i].maxStatus = 'normal';
if (data.list[i].nums == 1) {
data.list[i].minStatus = 'disabled';
}
if (data.list[i].nums == data.list[i].products.stock) {
data.list[i].maxStatus = 'disabled';
}
//设置规格参数
data.list[i].spes = [];
if (data.list[i].products.spesDesc != null) {
let spesArray = data.list[i].products.spesDesc.split(',');
for (let key in spesArray) {
let spesOne = spesArray[key].split(':');
data.list[i].spes.push(spesOne[1]);
}
}
//添加左滑效果
data.list[i].isTouchMove = false;
//是否可以去支付
if (data.list[i].isSelect) {
goSettlement = true;
}
//id转换为字符串
data.list[i].id = _this.arrayToStr(data.list[i].id);
//选中状态
if (flag) {
data.list[i].isSelect = true;
if (data.list[i].isSelect) {
if (_this.cartIds.indexOf(data.list[i].id) < 0) {
_this.cartIds.push(data.list[i].id);
}
}
}
}
data.goodsPromotionMoney = _this.$common.formatMoney(data.goodsPromotionMoney, 2, '');
data.orderPromotionMoney = _this.$common.formatMoney(data.orderPromotionMoney, 2, '');
data.amount = _this.$common.formatMoney(data.amount, 2, '');
let isLoad = false;
if (data.list.length < 1) {
isLoad = true;
}
let n = 0;
for (let i in data.promotionList) {
n++;
}
_this.goSettlement = goSettlement;
_this.isLoad = isLoad;
_this.cartNums = n;
if (flag) {
_this.shoppingCard = data;
} else {
_this.getCartData();
}
_this.countTotoal();
},
//计算总计函数
countTotoal: function () {
let _that = this;
var total = 0;
var pointsMoneySum = 0;
var pointsSum = 0;
for (let i in _that.shoppingCard.list) {
if (_that.shoppingCard.list[i].isSelect) {
total += Number(_that.shoppingCard.list[i].products.price) * Number(_that.shoppingCard.list[i].nums);
_that.pointShowMoney += Number(_that.shoppingCard.list[i].products.pointsDeduction) * Number(_that.shoppingCard.list[i].nums);
pointsSum += _that.pointDiscountedProportion * Number(_that.shoppingCard.list[i].products.pointsDeduction) * Number(_that.shoppingCard.list[i].nums);
pointsMoneySum += Number(_that.shoppingCard.list[i].products.price - _that.shoppingCard.list[i].products.pointsDeduction) * Number(_that.shoppingCard.list[i].nums);
}
}
_that.pointShowText = pointsSum + _that.pointShowName + '+' + _that.$common.formatMoney(pointsMoneySum, 2, '');
_that.totalprice = _that.$common.formatMoney(total, 2, '');
},
toNumberChange: function (e) {
this.$u.throttle(this.numberChange(e), 500)
},
numberChange(e) {
uni.showLoading({
title: '加载中',
mask: true
});
let _this = this;
let data = {
id: this.shoppingCard.list[e.name].productId,
nums: e.value
};
_this.$u.api.setCartNum(data).then(res => {
if (res.status) {
_this.shoppingCard.list[e.name].nums = e.value;
//重新计算总价
this.countTotoal();
setTimeout(function () {
uni.hideLoading();
}, 300);
} else {
_this.$u.toast(res.msg);
setTimeout(function () {
uni.hideLoading();
}, 300);
}
});
},
removeGoods: function (index) {
let _this = this;
var index = index;
uni.showModal({
title: '确认提醒',
content: '您确定要移除此商品吗?',
success: (e) => {
if (e.confirm) {
//移除数据库
let data = {
id: _this.shoppingCard.list[index].id
};
_this.$u.api.removeCart(data).then(res => {
if (res.status) {
//清除已经勾选的商品和购物车数据
var idIndex = _this.cartIds.indexOf(_this.shoppingCard.list[index].id);
if (idIndex > -1) {
_this.cartIds.splice(index, 1);
}
_this.shoppingCard.list.splice(index, 1);
//计算总价
_this.countTotoal();
_this.$refs.uToast.show({ message: res.msg, type: 'success', back: false });
}
});
}
}
})
},
checkout: function () {
let _this = this;
let cartData = _this.shoppingCard.list;
let newData = '';
for (let key in cartData) {
if (cartData[key].isSelect == true) {
newData += ',' + cartData[key].id;
_this.goSettlement = true;
}
}
if (newData.substr(0, 1) == ',') {
newData = newData.substr(1);
}
if (newData.length > 0) {
_this.$u.route('/pages/placeOrder/index/index?orderType=1&cartIds=' + JSON.stringify(newData));
return true;
} else {
//没有选择不跳转
_this.$refs.uToast.show({ message: "请选择要下单的商品", type: 'error', back: false });
}
},
// 商品选中
itemChange: function (e) {
var _this = this;
_this.cartIds = e;
var list = _this.shoppingCard.list;
for (var i = 0; i < list.length; i++) {
var bl = _this.cartIds.indexOf(list[i].id) != -1;
if (bl) {
list[i].isSelect = true;
} else {
list[i].isSelect = false;
}
}
_this.shoppingCard.list = list;
if (_this.cartIds.length == _this.shoppingCard.list.length) {
this.selectAll = ['全选'];
} else {
this.selectAll = [];
}
this.countTotoal();
},
itemChangeAll: function (e) {
let _this = this;
if (e.length > 0) {
var ids = [];
for (var i = 0; i < _this.shoppingCard.list.length; i++) {
_this.shoppingCard.list[i].isSelect = true;
ids.push(_this.shoppingCard.list[i].id);
}
_this.cartIds = ids;
} else {
for (var i = 0; i < _this.shoppingCard.list.length; i++) {
_this.shoppingCard.list[i].isSelect = false;
}
_this.cartIds = [];
}
this.countTotoal();
},
}
}
</script>
<style lang="scss" scoped>
@import "cart.scss";
</style>

View File

@@ -0,0 +1,240 @@
<template>
<!-- 页面主体 -->
<view>
<!--提示框组件-->
<u-toast ref="uToast" />
<!--无网络组件-->
<u-no-network></u-no-network>
<!--头部组件-->
<u-navbar :is-back="false" :title="appTitle" :background="background" :title-color="titleColor" :custom-back="about" safeAreaInsetTop fixed placeholder @leftClick="goNavigateBack"></u-navbar>
<!--首页模块化组合组件-->
<coreshop-page :coreshopdata="pageData"></coreshop-page>
<!--版权组件-->
<coreshop-copyright v-if="copy"></coreshop-copyright>
<!--客服组件-->
<!-- #ifdef H5 || APP-PLUS-NVUE || APP-PLUS -->
<view class="floatingButton" @click="showChat()">
<u-icon name="server-man" color="#e54d42" size="60"></u-icon>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<button class="floatingButton" hover-class="none" open-type="contact" bindcontact="showChat" :session-from="kefupara">
<u-icon name="server-man" color="#e54d42" size="60"></u-icon>
</button>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<contact-button class="floatingButton icon" icon="/static/images/common/seller-content.png" size="40px*40px" tnt-inst-id="" scene="" hover-class="none" />
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<!-- 头条客服 -->
<!-- #endif -->
<!--返回顶部组件-->
<u-back-top :scroll-top="scrollTop" :duration="500"></u-back-top>
<!--弹出框-->
<!--<coreshop-modal-img :show="modalShow" :src="$globalConstVars.apiFilesUrl+'/static/images/empty/reward.png'" @imgTap="imgTap" @closeTap="closeTap" />-->
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
background: this.$coreTheme.mainNabBar.background,
titleColor: this.$coreTheme.mainNabBar.titleColor,
swiperItems: [],
currentIndex: 0,
opacity: 0,
scrollTop: 0,
imageUrl: '/static/images/ShareImage.png', //店铺分享图片
pageData: [],
pageCode: 'mobile_home', //页面布局编码
//userInfo: {}, // 用户信息
kefupara: '', //客服传递资料
copy: false,
shareUrl: '/pages/share/jump/jump',
modalShow: true,
};
},
updated() {
this.copy = true;
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
hasLogin: {
get() {
return this.$store.state.hasLogin;
},
set(val) {
this.$store.commit('hasLogin', val);
}
},
userInfo: {
get() {
return this.$store.state.userInfo;
},
set(val) {
this.$store.commit('userInfo', val);
}
},
appTitle() {
return this.$store.state.config.shopName;
},
// 获取店铺联系人手机号
shopMobile() {
return this.$store.state.config.shopMobile || 0;
}
},
onLoad(e) {
//增加页面编码,可自定义编码
if (e.pageCode) {
this.pageCode = e.pageCode;
}
this.initData();
console.log("数据:" + this.$globalConstVars.apiFilesUrl);
},
methods: {
about() {
},
imgTap() {
this.modalShow = false;
uni.navigateTo({
url: "/pages/reward/reward"
});
},
closeTap() {
this.modalShow = false;
},
goSearch() {
uni.navigateTo({
url: '/pages/search/search'
});
},
// 首页初始化获取数据
initData() {
uni.showLoading({
title: '加载中'
});
//获取首页配置
this.$u.api.getPageConfig({ code: this.pageCode }).then(res => {
if (res.status == true) {
this.pageData = res.data.items;
if (res.data.items.length > 0) {
for (var i = 0; i < res.data.items.length; i++) {
if (res.data.items[i].widgetCode == 'topImgSlide') {
var data = res.data.items[i].parameters.list;
for (var i = 0; i < data.length; i++) {
let moder = {
image: data[i].image == '/images/empty-banner.png' ? '/static/images/common/empty-banner.png' : data[i].image,
bg: data[i].bg == '/images/empty-banner.png' ? '/static/images/common/empty-banner.png' : data[i].bg,
opentype: 'click',
url: '',
title: data[i].linkType,
linkType: data[i].linkType,
linkValue: data[i].linkValue,
}
this.swiperItems.push(moder);
}
}
}
}
}
setTimeout(function () {
uni.hideLoading();
}, 1000);
});
var _this = this;
if (this.$db.get('userToken')) {
this.$u.api.userInfo().then(res => {
if (res.status) {
_this.userInfo = res.data;
_this.hasLogin = true;
// #ifdef MP-WEIXIN
//微信小程序打开客服时,传递用户信息
var kefupara = {};
kefupara.nickName = res.data.nickName;
kefupara.tel = res.data.mobile;
_this.kefupara = JSON.stringify(kefupara);
//console.log(_this.kefupara);
// #endif
}
});
}
this.getShareUrl();
},
swiperChange(e) {
this.currentIndex = e;
},
//在线客服
showChat() {
// #ifdef H5
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
},
//获取分享URL
getShareUrl() {
let data = {
client: 2,
url: "/pages/share/jump/jump",
type: 1,
page: 1,
};
let userToken = this.$db.get('userToken');
if (userToken && userToken != '') {
data['token'] = userToken;
}
this.$u.api.share(data).then(res => {
this.shareUrl = res.data
});
},
taped: function (e) {
this.showSliderInfo(this.swiperItems[e].linkType, this.swiperItems[e].linkValue);
},
},
onPullDownRefresh() {
this.swiperItems = [];
this.initData();
uni.stopPullDownRefresh();
},
//分享
onShareAppMessage(res) {
return {
title: this.$store.state.config.shareTitle,
imageUrl: this.$store.state.config.shareImage,
path: this.shareUrl
}
},
onShareTimeline(res) {
return {
title: this.$store.state.config.shareTitle,
imageUrl: this.$store.state.config.shareImage,
path: this.shareUrl
}
},
onPageScroll: function (e) {
this.scrollTop = e.scrollTop;
if (e.scrollTop <= 100) {
this.opacity = e.scrollTop / 100;
} else if (this.scrollTop > 100) {
this.opacity = 1;
}
},
};
</script>
<style lang="scss">
</style>

Some files were not shown because too many files have changed in this diff Show More