添加项目文件。

This commit is contained in:
JianWeie
2021-12-20 21:27:32 +08:00
parent 747486f5cb
commit 82d825b7a5
3514 changed files with 887941 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="CoreShop\.hbuilderx\**" />
<Compile Remove="CoreShop\uni_modules\**" />
<Compile Remove="CoreShop\unpackage\**" />
<EmbeddedResource Remove="CoreShop\.hbuilderx\**" />
<EmbeddedResource Remove="CoreShop\uni_modules\**" />
<EmbeddedResource Remove="CoreShop\unpackage\**" />
<None Remove="CoreShop\.hbuilderx\**" />
<None Remove="CoreShop\uni_modules\**" />
<None Remove="CoreShop\unpackage\**" />
</ItemGroup>
</Project>

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,189 @@
<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 version = plus.runtime.version;
//检测当前平台,如果是安卓则启动安卓更新
uni.getSystemInfo({
success: res => {
this.updateHandler(res.platform, version);
}
})
},
// 更新操作
updateHandler(platform, version) {
let data = {
platform: platform,
version: version
}
let _this = this;
this.$u.api.getAppVersion(data).then(res => {
if (res.status && res.data[0].version) {
const info = res.data[0];
if (info.version !== '' && info.version > version) {
uni.showModal({
//提醒用户更新
title: '更新提示',
content: info.note,
success: res => {
if (res.confirm) {
plus.runtime.openURL(info.download_url)
}
}
})
}
}
});
}
// #endif
}
}
</script>
<style lang="scss">
/* 注意要写在第一行同时给style标签加入lang="scss"属性 */
@import "@/uni_modules/uview-ui/index.scss";
/*公共css */
@import '@/static/style/coreCommon.scss';
@import '@/static/style/corePage.scss';
// 非nvue的样式
/* #ifndef APP-NVUE */
@import "@/static/style/style.vue.scss";
/* #endif */
// nvue的特有样式
/* #ifdef APP-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,274 @@
/**
* 全局混入型
*/
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' })
}
},
/**
* 订单接口信息
*/
// 查看订单详情
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 });
},
// 前往用户协议
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 });
},
/**
* 工具函数
*/
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,580 @@
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 goodsDetail = (params, config = {}) => http.post('/Api/Good/GetDetial', params, { custom: { methodName: 'goods.getdetial', needToken: false } });
//获取随机推荐商品
let getGoodsRecommendList = (params, config = {}) => http.post('/Api/Good/GetGoodsRecommendList', params, { custom: { methodName: 'goods.getGoodsRecommendList', needToken: false } });
// 获取商品详情
let goodsDetailByToken = (params, config = {}) => http.post('/Api/Good/GetDetialByToken', params, { custom: { methodName: 'goods.getDetialByToken', needToken: true } });
// 获取商品参数信息
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 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 } });
// 获取收货地址详情
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 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 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/App/CheckVersion', params, { custom: { methodName: 'app-api-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,
addCart,
removeCart,
cartList,
setCartNum,
getCartNum,
getCartCoupon,
userShip,
userDefaultShip,
saveUserShip,
saveUserShipWx,
getAreaId,
shipDetail,
editShip,
removeShip,
setDefShip,
createOrder,
cancelOrder,
delOrder,
orderDetail,
confirmOrder,
orderShip,
orderList,
getOrderStatusSum,
afterSalesList,
afterSalesInfo,
addAfterSales,
sendShip,
addGoodsBrowsing,
delGoodsBrowsing,
delGoodsBrowsing,
goodsBrowsing,
goodsCollection,
goodsCollectionList,
paymentList,
paymentInfo,
pay,
orderEvaluate,
isSign,
sign,
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,93 @@
import { apiBaseUrl } from '@/common/setting/constVarsHelper.js';
import * as db from '@/common/utils/dbHelper.js' //引入common
// 这里的Vue为Vue对象(非创建出来的实例)vm为main.js中“Vue.use(httpInterceptor, app)”这一句的第二个参数,
// 为一个Vue的实例也即每个页面的"this"
// 如果需要了解这个install方法是什么请移步https://uviewui.com/components/vueUse.html
const install = (Vue, vm) => {
// 此为自定义配置参数,具体参数见上方说明
Vue.prototype.$u.http.setConfig({
baseUrl: apiBaseUrl, // 请求的本域名
method: 'POST',
dataType: 'json',// 设置为json返回后会对数据进行一次JSON.parse()
showLoading: true, // 是否显示请求中的loading
loadingText: '请求中...', // 请求loading中的文字提示
loadingTime: 800, // 在此时间内请求还没回来的话就显示加载中动画单位ms
originalData: false, // 是否在拦截器中返回服务端的原始数据
loadingMask: true, // 展示loading的时候是否给一个透明的蒙层防止触摸穿透
// 配置请求头信息
header: {
'Content-type': 'application/json'
},
});
// 请求拦截部分,如配置,每次请求前都会执行
Vue.prototype.$u.http.interceptor.request = (config) => {
if (config.header.needToken) {
// 获取用户token
const userToken = db.get("userToken");
if (!userToken) {
console.log("开启弹窗");
Vue.prototype.$store.commit('showLoginTip', true);
return false;
} else {
config.header.Authorization = 'Bearer ' + userToken;
}
}
//额外需求
if (config.header.method == 'user.share') {
const userToken = db.get("userToken");
config.header.Authorization = 'Bearer ' + userToken;
}
return config;
}
// 响应拦截,如配置,每次请求结束都会执行本方法
Vue.prototype.$u.http.interceptor.response = (result) => {
let pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!result.status && page) {
//console.log(page.route);
// 登录信息过期或者未登录
if (result.data === 14007 || result.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);
Vue.prototype.$store.commit('hasLogin', false);
// #endif
}
}
return result;
// res为服务端返回值可能有coderesult等字段
// 这里对res.result进行返回将会在this.$u.post(url).then(res => {})的then回调中的res的到
// 如果配置了originalData为true请留意这里的返回值
}
}
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/json'
};
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,38 @@
/**
* 全局配置文件
* @version 1.0.0
*/
//接口请求地址如果需要不部署接口端的情况下测试uni-app可以直接替换为官方测试接口https://api.demo.coreshop.cn
export const apiBaseUrl = 'https://api.demo.coreshop.cn';
//项目静态资源请求地址如果使用官方的静态文件地址可以直接替换为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 = {
//支付单类型
order: 1, //订单
recharge: 2, //充值
formPay: 3, //表单订单
formOrder: 4, //表单付款码
serviceOrder: 5, //服务订单
};
// #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,26 @@
<template>
<view class="coreshop-copyright">
<view class="coreshop-font-xs" v-if="shopName">
© {{shopName}} 品牌运营
</view>
<view class="coreshop-font-xs" v-if="shopBeiAn">
<view v-if="shopBeiAn">备案号{{shopBeiAn}}</view>
</view>
<view class="coreshop-font-xs">
Powered by CoreShop
</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,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,476 @@
<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 v-model="agreement" @change="checkboxChange" size="30" active-color="#19be6b"></u-checkbox>
<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" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">确定授权</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,
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.value;
},
// 隐藏登录弹窗
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);
_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) {
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,157 @@
<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="showSliderInfo2" :data-type="coreshopdata.parameters.list[0].linkType" :data-val="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
},
showSliderInfo(type, val) {
console.log(type);
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
// #ifdef MP-WEIXIN
showSliderInfo2: function (e) {
let type = e.currentTarget.dataset.type;
let val = e.currentTarget.dataset.val;
console.log(type);
console.log(val)
console.log(type);
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
}
// #endif
},
}
</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; width: calc(100% - 100px);
.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,95 @@
<template>
<view>
<!--提示框组件-->
<u-toast ref="uToast" />
<view class="coreshop-coupon coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10" v-if="count">
<view class="coreshop-coupon-card-view coreshop-margin-bottom-10 coreshop-margin-top-10" :class="item.maxRecevieNums > 0 && item.getNumber >= item.maxRecevieNums ?'coreshop-lower-shelf':''" v-for="(item, key) in coreshopdata.parameters.list" :key="key">
<view class="img-lower-box" v-if="item.maxRecevieNums > 0 && item.getNumber >= item.maxRecevieNums ">已领完</view>
<view class="card-price-view">
<view class="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>
</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: {
// 用户领取优惠券
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)
}
})
},
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,151 @@
<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%" radius="10" @click="goGoodsDetail(item.id)"></u--image>
<view class="good_title u-line-2">
{{item.name}}
</view>
<view class="good-price">
{{item.price}} <span class="u-font-xs coreshop-text-through u-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 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">
<view class="good_box">
<u--image src="/static/images/common/empty.png" mode="widthFix" width="100%" radius="10" @click="goGoodsDetail(item.id)"></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" @click="goGoodsDetail(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="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>
<image class="order-none-img" src="/static/images/order.png" mode=""></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
current: 0,
nameList: [],
newData: {}
};
},
name: "coreshopgoodTabBar",
props: {
coreshopdata: {
// type: Array,
required: true,
}
},
mounted() {
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);
}
},
computed: {
},
methods: {
change(index) {
var _this = this;
this.current = 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,193 @@
<template>
<view class="goodsBox coreshop-margin-left-10 coreshop-margin-right-10 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 ">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" v-if="coreshopdata.parameters.title != ''" @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%" radius="10" @click="goGoodsDetail(item.id)"></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 && !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 != ''" @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" mode="widthFix" width="100%" radius="10" @click="goGoodsDetail(item.id)"></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 class="order-none" v-else>
<image class="order-none-img" src="/static/images/order.png" mode=""></image>
</view>
</view>
<!-- 横向滚动 -->
<block v-if="coreshopdata.parameters.column == '2' && coreshopdata.parameters.display == 'slide' || coreshopdata.parameters.column == '3' && 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 ">
<coreshop-section font-size="15" :title="coreshopdata.parameters.title" v-if="coreshopdata.parameters.title != ''" @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">
<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?'120px':coreshopdata.parameters.column==2?'176px':''" radius="10" @click="goGoodsDetail(item.id)">
</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>
</swiper-item>
</swiper>
<view class="indicator-dots">
<view class="indicator-dots-item" v-for="no of pageCount" :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,
};
},
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: {
pageCount() {
var count = this.coreshopdata.parameters.list.length / this.coreshopdata.parameters.column;
if (this.coreshopdata.parameters.column * count < this.coreshopdata.parameters.list.length) {
count = count + 1;
}
return count;
},
count() {
return (this.coreshopdata.parameters.list.length > 0)
}
},
methods: {
change(e) {
this.current = e.detail.current;
}
},
}
</script>
<style scoped lang="scss">
.goodsBox { border-radius: 8px; color: #333333 !important; padding: 0 5px;
.good_box { border-radius: 8px; margin: 3px; background-color: #ffffff; padding: 5px; position: relative;
.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,92 @@
<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"></u-image>
</view>
<view class="img-list-item-r">
<view class="coreshop-font-14 u-line-1">{{item.name}}</view>
<view class="description u-line-2 coreshop-margin-10">{{item.goods.name}}</view>
<view class="item-c">
<view class="red-price coreshop-justify-between">
{{item.goods.product.price}}
<span class="coreshop-font-xs coreshop-text-through coreshop-margin-left-15">{{item.goods.product.mktprice}}</span>
</view>
<view class="coreshop-flex-direction-row coreshop-justify-between">
<view>
<view class="red-price coreshop-font-30 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>
</view>
<u-icon name="shopping-cart" color="#2979ff" size="20" 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,144 @@
<template>
<!-- 单图 -->
<view class="coreshop-imgsingle coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-10 coreshop-bg-white" v-if="coreshopdata.parameters.list && coreshopdata.parameters.list.length > 0">
<view class="" v-for="item in coreshopdata.parameters.list" :key="item.id">
<!-- #ifdef MP-WEIXIN -->
<view @click="showSliderInfo2" :data-type="item.linkType" :data-val="item.linkValue">
<image class="ad-img" :src="item.image" mode="widthFix"></image>
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<image class="ad-img" :src="item.image" mode="widthFix" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
<!-- #endif -->
<view class="imgup-btn" v-if="item.buttonText != ''" @click="showSliderInfo(item.linkType, item.linkValue)">
<button class="coreshop-btn" :style="{background:item.buttonColor,color:item.textColor}">{{item.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: {
showSliderInfo(type, val) {
console.log(type);
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
// #ifdef MP-WEIXIN
showSliderInfo2: function (e) {
let type = e.currentTarget.dataset.type;
let val = e.currentTarget.dataset.val;
console.log(type);
console.log(val)
console.log(type);
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
}
// #endif
},
}
</script>
<style lang="scss" scoped>
.coreshop-imgsingle { overflow: hidden; position: relative;
.ad-img { width: 100%; float: left; position: relative; z-index: 667; }
.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,99 @@
<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" keyName="image" @click="taped"></u-swiper>
</view>
</template>
<script>
export default {
name: "coreshopimgSlide",
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
swiperItems: [],
};
},
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);
}
},
watch: {},
methods: {
taped: function (e) {
this.showSliderInfo(this.swiperItems[e].linkType, this.swiperItems[e].linkValue);
},
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9BFB4><EFBFBD><EFBFBD>
showSliderInfo(type, val) {
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// <20><>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD>
this.goGoodsDetail(val)
} else if (type == 3) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// <20><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//<2F><><EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD>
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// <20>û<EFBFBD><C3BB><EFBFBD>ȡ<EFBFBD>Ż<EFBFBD>ȯ
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
}
}
</script>

View File

@@ -0,0 +1,99 @@
<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: {
showSliderInfo(type, val) {
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view class="coreshop-padding-top-10 coreshop-padding-bottom-10 coreshop-margin-left-10 coreshop-margin-right-10 coreshop-margin-bottom-10 coreshop-margin-top-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: {
showSliderInfo(type, val) {
if (!val) {
return;
}
if (this.$u.test.url(val)) {
// #ifdef H5
window.location.href = 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 (type == navLinkType.urlLink) {
this.$u.route(val);
} 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);
}
return;
}
// #endif
}
},
}
}
</script>

View File

@@ -0,0 +1,49 @@
<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" mode="link"></u-notice-bar>
</view>
</template>
<script>
export default {
name: "coreshopnotice",
components: {
},
props: {
coreshopdata: {
// type: Object,
required: true,
}
},
data() {
return {
model: {
text: "",
url: "",
},
}
},
created() {
var data = this.coreshopdata.parameters.list;
if (data.length > 0) {
this.model.text = data[0].title;
this.model.url = '/pages/article/details/details?id=' + data[0].id + '&idType=2';
};
//for (var i = 0; i < data.length; i++) {
// let moder = {
// title: data[i].title,
// url: '/pages/article/details/details?id=' + data[i].id + '&idType=2',
// opentype: "navigate"
// }
// this.model.text.push(data[i].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,127 @@
<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="goPinTuanList()"></coreshop-section>
</view>
<view class="coreshop-margin-left-15 coreshop-margin-right-15 coreshop-bg-white coreshop-padding-10" v-if="goodsList && count">
<view class="goods-box swiper-box coreshop-flex coreshop-align-center">
<swiper class="carousel" circular @change="swiperChange" :autoplay="true" duration="2000">
<swiper-item v-for="(goods, index) in goodsList" :key="index" class="carousel-item">
<view class="coreshop-flex-direction-row coreshop-flex coreshop-align-center">
<view class="goods-item" v-for="item in goods" :key="item.id" @tap="goPinTuanDetail(item.goodsId,item.id)">
<view class="min-goods">
<view class="img-box">
<view class="tag">{{item.peopleNumber}}人团</view>
<image class="img" :src="item.goodsImage" mode="widthFix"></image>
</view>
<view class="price-box">
<view class="coreshop-flex coreshop-flex-direction coreshop-align-center">
<text class="seckill-current">{{item.pinTuanPrice}}</text>
<text class="original">{{item.pinTuanPrice + item.discountAmount}}</text>
</view>
</view>
<view class="title"><slot name="titleText"></slot></view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<view class="swiper-dots" v-if="goodsList.length > 1">
<text :class="swiperCurrent === index ? 'dot-active' : 'dot'" v-for="(dot, index) in goodsList.length" :key="index"></text>
</view>
</view>
</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">
.swiper-box,
.carousel { width: 350px; height: 240upx; position: relative; border-radius: 10px; }
.swiper-box .carousel-item,
.carousel .carousel-item { width: 100%; height: 100%; }
.swiper-box .swiper-image,
.carousel .swiper-image { width: 100%; height: 100%; }
.swiper-dots { display: flex; position: absolute; left: 50%; transform: translateX(-50%); bottom: 0px; z-index: 66;
.dot { width: 22.5px; height: 1.5px; background: #eee; border-radius: 50%; margin-right: 5px; }
.dot-active { width: 22.5px; height: 1.5px; background: #a8700d; border-radius: 50%; margin-right: 5px; }
}
.group-goods { background: #fff; border-radius: 10px; overflow: hidden;
.title-box { padding-bottom: 10px;
.title { font-size: 16px; font-weight: bold; }
.group-people {
.time-box { font-size: 13px; color: #edbf62;
.count-text-box { width: 15px; height: 17px; background: #edbf62; text-align: center; line-height: 17px; font-size: 12px; border-radius: 3px; color: rgba(255, 255, 255, 0.9); margin: 0 4px; }
}
.head-box {
.head-img { width: 20px; height: 20px; border-radius: 50%; background: #ccc; }
}
.tip { font-size: 14px; padding-left: 15px; color: #666; }
.cuIcon-right { font-size: 15px; line-height: 14px; color: #666; }
}
}
}
.goods-item { margin-right: 11px;
&:nth-child(4n) { margin-right: 0; }
}
.min-goods { width: 75px; background: #fff;
.img-box { width: 76px; height: 76px; overflow: hidden; position: relative;
.tag { position: absolute; left: 0; bottom: 0px; z-index: 2; line-height: 17.5px; background: linear-gradient(132deg, #f3dfb1, #f3dfb1, #ecbe60); border-radius: 0px 9px 9px 0px; padding: 0 5px; font-size: 12px; font-family: PingFang SC; font-weight: bold; color: #784f06; }
.img { width: 100%; background-color: #ccc; }
}
.price-box { width: 100%; margin-top: 5px;
.seckill-current { font-size: 15px; font-weight: 500; color: #e1212b; }
.original { font-size: 10px; font-weight: 400; text-decoration: line-through; color: #999999; margin-left: 7px; }
}
.title { font-size: 13px; }
}
</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">
<view class="red-price">{{item.money}}</view>
<view class="coreshop-flex-direction-row coreshop-justify-between">
<view>
<view class="coreshop-font-30 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="goods-salesvolume red-price" v-if="item.status == 1">已结束</view>
<view class="goods-salesvolume red-price" v-if="item.status == 2">售罄</view>
</view>
<u-icon name="shopping-cart" color="#2979ff" size="20" 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,133 @@
<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 class="coreshop-tabbar coreshop-margin-bottom-10 tabbar-fixed" v-show="tabbarFixed">
<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' });
},
showSliderInfo(type, val) {
console.log(val)
if (!val) {
return;
}
console.log("11")
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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 {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// console.log("11")
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
},
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,182 @@
<template>
<view>
<u-toast ref="uToast" />
<view v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)" v-if="!(type == 2 && item.code == 'balancepay')">
<view class="u-reset-button coreshop-list menu-avatar padding-xl radius shadow shadow-lg bg-blue margin-top">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius">
<u--image width="34px" height="34px" :src="item.icon" :lazy-load="false" :fade="false" duration="0"></u--image>
</view>
<view class="content">
<view class="coreshop-text-grey">{{ item.name }}</view>
<view class="coreshop-text-gray coreshop-font-sm flex coreshop-text-left">
<view class="u-line-1">
{{ item.memo }}
</view>
</view>
</view>
<view class="action">
<u-tag text="选择此支付方式" mode="dark" type="error" shape="circle" />
</view>
</view>
</view>
</view>
<view class="payment-pop" v-show="popShow">
<view class="payment-pop-c">
<image src="/static/images/payments/wait-pay.png" style="width: 30px;height: 30px;"></image>
<view class="text">支付中请稍后...</view>
</view>
<view class="payment-pop-b">
<button class="coreshop-btn coreshop-btn-c" @click="popHide">支付失败</button>
<button class="coreshop-btn coreshop-btn-o" @click="popHide">支付成功</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 如果是商品订单此参数必须
orderId: {
type: String,
default() {
return '';
}
},
// 如果是充值订单此参数必须
recharge: {
type: Number,
default() {
return 0;
}
},
// 用户id
uid: {
type: Number,
default() {
return 0;
}
},
// 订单类型
type: {
type: Number,
default() {
return 1;
}
}
},
data() {
return {
payments: [],
popShow: false
}
},
mounted() {
this.getPayments();
},
methods: {
// 获取可用支付方式列表
getPayments() {
this.$u.api.paymentList().then(res => {
if (res.status) {
this.payments = this.formatPayments(res.data);
}
})
},
// 支付方式处理
formatPayments(payments) {
payments = payments.filter(item => item.code !== 'wechatpay');
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
if (this.type === 2) {
payments = payments.filter(item => item.code !== 'balancepay' || item.isOnline === false)
}
// 设置logo图片
payments.forEach(item => {
this.$set(item, 'icon', '/static/images/payments/' + item.code + '.png')
});
return payments;
},
// 用户点击支付方式处理
toPayHandler(code) {
this.popShow = true;
let data = {
payment_code: code,
payment_type: this.type
}
data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
// 判断订单支付类型
if (this.type == 2 && this.recharge) {
data['params'] = {
money: this.recharge,
trade_type: 'JSAPI'
}
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
trade_type: 'JSAPI',
}
} else {
data['params'] = {
trade_type: 'JSAPI'
}
}
let _this = this;
switch (code) {
case 'alipay':
this.$u.api.pay(data).then(res => {
if (res.status) {
uni.requestPayment({
provider: 'alipay',
tradeNO: res.data.trade_no,
success: function (e) {
if (e.errMsg === 'requestPayment:ok') {
_this.$refs.uToast.show({
message: res.msg, type: 'success', complete: function () {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
}
})
}
},
fail: function (res) {
console.log(res);
}
});
} else {
this.$u.toast(res.msg);
this.popHide();
}
})
break
case 'balancepay':
//用户余额支付
this.$u.api.pay(data).then(res => {
if (res.status) {
this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
} else {
this.$u.toast(res.msg);
this.popHide();
}
})
break;
case 'offline':
//线下支付
this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => { }, false, '取消', '确定')
break;
}
},
// 支付中显示隐藏
popHide() {
this.popShow = false
}
}
}
</script>
<style lang="scss">
.coreshop-avatar { background: #fff; }
</style>

View File

@@ -0,0 +1,237 @@
<template>
<view>
<u-toast ref="uToast" />
<view v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)" v-if="!(type == 2 && item.code == 'balancepay')">
<view class="u-reset-button coreshop-list menu-avatar padding-xl radius shadow shadow-lg bg-blue margin-top">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius">
<u--image width="34px" height="34px" :src="item.icon" :lazy-load="false" :fade="false" duration="0"></u--image>
</view>
<view class="content">
<view class="coreshop-text-grey">{{ item.name }}</view>
<view class="coreshop-text-gray coreshop-font-sm flex coreshop-text-left">
<view class="u-line-1">
{{ item.memo }}
</view>
</view>
</view>
<view class="action">
<u-tag text="选择此支付方式" mode="dark" type="error" shape="circle" />
</view>
</view>
</view>
</view>
<view class="payment-pop" v-show="popShow">
<view class="payment-pop-c">
<image src="/static/images/payments/wait-pay.png" style="width: 30px;height: 30px;"></image>
<view class="text">支付中请稍后...</view>
</view>
<view class="payment-pop-b">
<button class="coreshop-btn coreshop-btn-c" @click="popHide">支付失败</button>
<button class="coreshop-btn coreshop-btn-o" @click="popHide">支付成功</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 如果是商品订单此参数必须
orderId: {
type: String,
default() {
return ''
}
},
// 如果是充值订单此参数必须
recharge: {
type: Number,
default() {
return 0
}
},
// 用户id
uid: {
type: Number,
default() {
return 0
}
},
// 订单类型
type: {
type: Number,
default() {
return 1
}
}
},
data() {
return {
payments: [],
popShow: false
}
},
mounted() {
this.getPayments()
},
methods: {
// 获取可用支付方式列表
getPayments() {
this.$u.api.paymentList().then(res => {
if (res.status) {
this.payments = this.formatPayments(res.data)
}
})
},
// 支付方式处理
formatPayments(payments) {
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
if (this.type === 2) {
payments = payments.filter(item => item.code !== 'balancepay' || item.isOnline === false)
}
// 设置logo图片
payments.forEach(item => {
this.$set(item, 'icon', '/static/images/payments/' + item.code + '.png')
})
return payments
},
// 用户点击支付方式处理
toPayHandler(code) {
this.popShow = true;
let _this = this
let data = {
payment_code: code,
payment_type: _this.type
}
data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
trade_type: 'APP',
}
}
switch (code) {
case 'alipay':
/**
* 支付宝支付需要模拟GET提交数据
*/
if (_this.type == 1 && _this.orderId) {
data['params'] = {
trade_type: 'APP'
}
} else if (_this.type == 2 && _this.recharge) {
data['params'] = {
trade_type: 'APP',
money: _this.recharge
}
}
_this.$u.api.pay(data).then(res => {
if (res.status) {
uni.requestPayment({
provider: "alipay",
orderInfo: res.data.data,
success: function (data) {
_this.$refs.uToast.show({
message: '支付成功', type: 'success', complete: function () {
_this.redirectHandler(res.data.paymentId)
}
})
}
});
} else {
_this.$comon.errorToShow(res.msg)
_this.popHide();
}
})
break
case 'wechatpay':
// 微信 H5支付
if (_this.type == 1 && _this.orderId) {
data['params'] = {
trade_type: 'APP'
}
} else if (_this.type == 2 && _this.recharge) {
data['params'] = {
trade_type: 'APP',
money: _this.recharge
}
}
// 微信app支付
_this.$u.api.pay(data).then(res => {
if (res.status) {
//console.log(JSON.stringify(res));
// 调用微信支付
uni.requestPayment({
provider: "wxpay",
orderInfo: {
appid: res.data.appid,
noncestr: res.data.noncestr,
package: res.data.package,
partnerid: res.data.partnerid,
prepayid: res.data.prepayid,
timestamp: res.data.timestamp,
sign: res.data.sign,
},
success: function (data) {
_this.$refs.uToast.show({
message: '支付成功', type: 'success', complete: function () {
_this.redirectHandler(res.data.paymentId)
}
})
},
fail: function (res) {
console.log(res);
}
});
} else {
_this.$u.toast(res.msg)
_this.popHide();
}
})
break
case 'balancepay':
/**
* 用户余额支付
*
*/
_this.$u.api.pay(data).then(res => {
if (res.status) {
_this.redirectHandler(res.data.paymentId)
} else {
_this.$u.toast(res.msg)
_this.popHide();
}
})
break
case 'offline':
/**
* 线下支付
*/
_this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => { }, false, '取消', '确定')
break
}
},
// 支付成功后跳转操作
redirectHandler(paymentId) {
this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + paymentId });
},
// 支付中显示隐藏
popHide() {
this.popShow = false
}
}
}
</script>
<style lang="scss">
.coreshop-avatar { background: #fff; }
</style>

View File

@@ -0,0 +1,334 @@
<template>
<view>
<u-toast ref="uToast" />
<view v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)" v-if="!(type == 2 && item.code == 'balancepay')">
<view class="u-reset-button coreshop-list menu-avatar padding-xl radius shadow shadow-lg bg-blue margin-top">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius">
<u--image width="34px" height="34px" :src="item.icon" :lazy-load="false" :fade="false" duration="0"></u--image>
</view>
<view class="content">
<view class="coreshop-text-grey">{{ item.name }}</view>
<view class="coreshop-text-gray coreshop-font-sm flex coreshop-text-left">
<view class="u-line-1">
{{ item.memo }}
</view>
</view>
</view>
<view class="action">
<u-tag text="选择此支付方式" mode="dark" type="error" shape="circle" />
</view>
</view>
</view>
</view>
<view class="payment-pop" v-show="popShow">
<view class="payment-pop-c">
<image src="/static/images/payments/wait-pay.png" style="width: 30px;height: 30px;"></image>
<view class="text">支付中请稍后...</view>
</view>
<view class="payment-pop-b">
<button class="coreshop-btn coreshop-btn-c" @click="popHide">支付失败</button>
<button class="coreshop-btn coreshop-btn-o" @click="popHide">支付成功</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 如果是商品订单此参数必须
orderId: {
type: String,
default() {
return ''
}
},
// 如果是充值订单此参数必须
recharge: {
type: Number,
default() {
return 0
}
},
// 用户id
uid: {
type: Number,
default() {
return 0
}
},
// 订单类型
type: {
type: Number,
default() {
return 1
}
}
},
data() {
return {
payments: [],
openid: '',
popShow: false
}
},
mounted() {
this.getPayments()
},
methods: {
// 获取可用支付方式列表
getPayments() {
this.$u.api.paymentList().then(res => {
if (res.status) {
this.payments = this.formatPayments(res.data)
}
})
},
// 支付方式处理
formatPayments(payments) {
// h5支付并且是在微信浏览器内 过滤支付宝支付
if (this.$common.isWeiXinBrowser()) {
payments = payments.filter(item => item.code !== 'alipay')
}
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
if (this.type === 2) {
payments = payments.filter(
item => item.code !== 'balancepay' || item.is_online === 1
)
}
// 设置logo图片
payments.forEach(item => {
this.$set(item, 'icon', '/static/images/payments/' + item.code + '.png')
})
return payments
},
checkWXJSBridge(data) {
let that = this
let interval = setInterval(() => {
if (typeof window.WeixinJSBridge != 'undefined') {
clearTimeout(interval)
that.onBridgeReady(data)
}
}, 200)
},
onBridgeReady(data) {
var _this = this
window.WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
appId: data.appid, // 公众号名称,由商户传入
timeStamp: data.timeStamp, // 时间戳自1970年以来的秒数
nonceStr: data.nonceStr, // 随机串
package: data.package,
signType: data.signType, // 微信签名方式:
paySign: data.paySign // 微信签名
},
function (res) {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
_this.$common.successToShow('支付成功')
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
_this.$u.toast('取消支付')
} else {
_this.$u.toast('支付失败')
}
setTimeout(() => {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + data.paymentId });
}, 1000)
}
)
},
// 用户点击支付方式处理
toPayHandler(code) {
this.popShow = true;
let data = {
payment_code: code,
payment_type: this.type
}
data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
switch (code) {
case 'alipay':
/**
* 支付宝支付需要模拟GET提交数据
*/
if (this.type == 1 && this.orderId) {
data['params'] = {
trade_type: 'WAP',
return_url: baseUrl +
'wap/pages/payment/result/result'
}
} else if (this.type == 2 && this.recharge) {
data['params'] = {
money: this.recharge,
return_url: baseUrl + 'wap/pages/payment/result/result'
}
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
}
}
this.$u.api.pay(data).then(res => {
if (res.status) {
const url = res.data.url
const data = res.data.data
// 模拟GET提交
let tempForm = document.createElement('form')
tempForm.id = 'aliPay'
tempForm.methods = 'post'
tempForm.action = url
tempForm.target = '_self'
let input = []
for (let k in data) {
input[k] = document.createElement('input')
input[k].type = 'hidden'
input[k].name = k
input[k].value = data[k]
tempForm.appendChild(input[k])
}
tempForm.addEventListener('submit', function () { }, false)
document.body.appendChild(tempForm)
tempForm.dispatchEvent(new Event('submit'))
tempForm.submit()
document.body.removeChild(tempForm)
}
})
break
case 'wechatpay':
/**
* 微信支付有两种
* 判断是否在微信浏览器
* 微信jsapi支付
*/
let isWeiXin = this.$common.isWeiXinBrowser()
if (isWeiXin) {
var transitUrl =
baseUrl +
'wap/pages/payment/waiting/waiting?orderId=' +
this.orderId +
'&type=' +
this.type;
if (this.type == 1 && this.orderId) {
// 微信jsapi支付
// if (this.openid) {
// data['params'] = {
// trade_type: 'JSAPI_OFFICIAL',
// openid: this.openid
// }
// } else {
// data['params'] = {
// trade_type: 'JSAPI_OFFICIAL',
// url: window.location.href
// }
// }
data['params'] = {
trade_type: 'JSAPI_OFFICIAL',
url: transitUrl
}
} else if (this.type == 2 && this.recharge) {
data['params'] = {
trade_type: 'JSAPI_OFFICIAL',
money: this.recharge,
url: transitUrl + '&uid=' + this.uid + '&money=' + this.recharge
}
// if (this.openid) {
// data['params'] = {
// money: this.recharge,
// openid: this.openid
// }
// } else {
// data['params'] = {
// money: this.recharge,
// url: window.location.href
// }
// }
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
}
}
this.$u.api.pay(data).then(res => {
if (!res.status && res.data == '10066') {
window.location.href = res.msg
return;
}
const data = res.data
this.checkWXJSBridge(data)
})
} else {
// 微信 H5支付
if (this.type == 1 && this.orderId) {
data['params'] = {
trade_type: 'MWEB',
return_url: baseUrl +
'wap/pages/payment/result/result'
}
} else if (this.type == 2 && this.recharge) {
data['params'] = {
trade_type: 'MWEB',
money: this.recharge,
return_url: baseUrl + 'wap/pages/payment/result/result'
}
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
}
}
// 微信h5支付
this.$u.api.pay(data).then(res => {
if (res.status) {
location.href = res.data.mweb_url
} else {
this.$u.toast(res.msg)
this.popHide();
}
})
}
break
case 'balancepay':
/**
* 用户余额支付
*
*/
if ((this.type == 5 || this.type == 6) && this.recharge) {
data['params'] = {
}
}
this.$u.api.pay(data).then(res => {
if (res.status) {
this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
} else {
this.$u.toast(res.msg)
this.popHide();
}
})
break
case 'offline':
/**
* 线下支付
*/
this.$common.modelShow(
'线下支付说明',
'请联系客服进行线下支付',
() => { },
false,
'取消',
'确定'
)
break
}
},
// 支付中显示隐藏
popHide() {
this.popShow = false
}
}
}
</script>
<style lang="scss">
.coreshop-avatar { background: #fff; }
</style>

View File

@@ -0,0 +1,232 @@
<template>
<view>
<u-toast ref="uToast" />
<form v-for="item in payments" :key="item.code" @submit="toPayHandler" report-submit="true" v-if="!(type == 2 && item.code == 'balancepay')">
<input name="code" :value="item.code" class="hide">
<button class="u-reset-button coreshop-list menu-avatar padding-xl radius shadow shadow-lg bg-blue margin-top" form-type="submit">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius">
<u--image width="34px" height="34px" :src="item.icon" :lazy-load="false" :fade="false" duration="0"></u--image>
</view>
<view class="content">
<view class="coreshop-text-grey">{{ item.name }}</view>
<view class="coreshop-text-gray coreshop-font-sm flex coreshop-text-left">
<view class="u-line-1">
{{ item.memo }}
</view>
</view>
</view>
<view class="action">
<u-tag text="选择此支付方式" mode="dark" type="error" shape="circle" />
</view>
</view>
</button>
</form>
<view class="payment-pop" v-show="popShow">
<view class="payment-pop-c">
<image src="/static/images/payments/wait-pay.png"></image>
<view class="text">支付中请稍后...</view>
</view>
<view class="payment-pop-b">
<button class="coreshop-btn coreshop-btn-c" @click="popHide">支付失败</button>
<button class="coreshop-btn coreshop-btn-o" @click="popHide">支付成功</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 如果是商品订单此参数必须
orderId: {
type: String,
default() {
return ''
}
},
// 如果是充值订单此参数必须
recharge: {
type: Number,
default() {
return 0
}
},
// 用户id
uid: {
type: Number,
default() {
return 0
}
},
// 订单类型
type: {
type: Number,
default() {
return 1
}
}
},
data() {
return {
payments: [],
popShow: false
}
},
mounted() {
this.getPayments()
},
methods: {
// 获取可用支付方式列表
getPayments() {
this.$u.api.paymentList().then(res => {
if (res.status) {
this.payments = this.formatPayments(res.data)
}
})
},
// 支付方式处理
formatPayments(payments) {
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
if (this.type === 2) {
payments = payments.filter(item => item.code !== 'balancepay' || item.isOnline === false)
}
// 设置logo图片
payments.forEach(item => {
this.$set(item, 'icon', '/static/images/payments/' + item.code + '.png')
})
return payments
},
// 用户点击支付方式处理
toPayHandler(e) {
this.popShow = true;
let code = e.target.value.code;
let data = {
payment_code: code,
payment_type: this.type,
params: {
trade_type: 'TT'
}
}
data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
// 判断订单支付类型
if (this.type == 2 && this.recharge) {
data['params']['money'] = this.recharge;
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
}
let _this = this
switch (code) {
case 'wechatpay':
this.$u.api.pay(data).then(res => {
if (res.status) {
uni.pay({
provider: 'wxpay',
orderInfo: res.data.tt_order_info,
service: 1,
getOrderStatus: function (es) {
},
success: function (e) {
if (e.code == 0) {
_this.$refs.uToast.show({
message: '支付成功', type: 'success', complete: function () {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
}
})
} else if (e.code == 1) {
_this.$u.toast('支付超时');
_this.popHide();
} else if (e.code == 2) {
_this.$u.toast('支付失败');
_this.popHide();
} else if (e.code == 3) {
_this.$u.toast('支付关闭');
_this.popHide();
} else if (e.code == 9) {
_this.$u.toast('支付异常,请联系客服处理。');
_this.popHide();
}
},
fail: function (res) {
console.log(res);
}
});
} else {
this.$u.toast(res.msg);
}
})
break
case 'alipay':
this.$u.api.pay(data).then(res => {
if (res.status) {
uni.pay({
provider: 'alipay',
orderInfo: res.data.tt_order_info,
service: 1,
getOrderStatus: function (es) {
},
success: function (e) {
if (e.code == 0) {
_this.$refs.uToast.show({
message: '支付成功', type: 'success', complete: function () {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
}
})
} else if (e.code == 1) {
_this.$u.toast('支付超时');
} else if (e.code == 2) {
_this.$u.toast('支付失败');
} else if (e.code == 3) {
_this.$u.toast('支付关闭');
} else if (e.code == 9) {
_this.$u.toast('支付异常,请联系客服处理。');
}
}
});
} else {
this.$u.toast(res.msg);
_this.popHide();
}
})
break
case 'balancepay':
/**
* 用户余额支付
*
*/
this.$u.api.pay(data).then(res => {
if (res.status) {
this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
} else {
this.$u.toast(res.msg);
_this.popHide();
}
})
break
case 'offline':
/**
* 线下支付
*/
this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => { }, false, '取消', '确定')
break
}
},
// 支付中显示隐藏
popHide() {
this.popShow = false
}
}
}
</script>
<style lang="scss">
.coreshop-avatar { background: #fff; }
</style>

View File

@@ -0,0 +1,216 @@
<template>
<view>
<u-toast ref="uToast" />
<form v-for="item in payments" :key="item.code" @submit="toPayHandler" v-if="!(type == 2 && item.code == 'balancepay')">
<input name="code" :value="item.code" class="hide">
<button class="u-reset-button coreshop-list menu-avatar padding-xl radius shadow shadow-lg bg-blue margin-top" form-type="submit">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius">
<u--image width="34px" height="34px" :src="item.icon" :lazy-load="false" :fade="false" duration="0"></u--image>
</view>
<view class="content">
<view class="coreshop-text-grey">{{ item.name }}</view>
<view class="coreshop-text-gray coreshop-font-sm flex coreshop-text-left">
<view class="u-line-1">
{{ item.memo }}
</view>
</view>
</view>
<view class="action">
<u-tag text="选择此支付方式" mode="dark" type="error" shape="circle" />
</view>
</view>
</button>
</form>
<view class="payment-pop" v-show="popShow">
<view class="payment-pop-c">
<image src="/static/images/payments/wait-pay.png"></image>
<view class="text">支付中请稍后...</view>
</view>
<view class="payment-pop-b">
<button class="coreshop-btn coreshop-btn-c" @click="popHide">支付失败</button>
<button class="coreshop-btn coreshop-btn-o" @click="popHide">支付成功</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 如果是商品订单此参数必须
orderId: {
type: String,
default() {
return ''
}
},
// 如果是充值订单此参数必须
recharge: {
type: Number,
default() {
return 0
}
},
// 用户id
uid: {
type: Number,
default() {
return 0
}
},
// 订单类型
type: {
type: Number,
default() {
return 1
}
}
},
data() {
return {
payments: [],
popShow: false
}
},
mounted() {
this.getPayments()
},
methods: {
// 获取可用支付方式列表
getPayments() {
this.$u.api.paymentList().then(res => {
if (res.status) {
this.payments = this.formatPayments(res.data)
}
})
},
// 支付方式处理
formatPayments(payments) {
// 过滤支付宝支付
payments = payments.filter(item => item.code !== 'alipay')
// 如果是充值订单,服务订单 过滤余额支付 过滤非线上支付方式
if (this.type === 2 || this.type === 5) {
payments = payments.filter(item => item.code !== 'balancepay' || item.isOnline === false)
}
// 设置logo图片
payments.forEach(item => {
this.$set(item, 'icon', '/static/images/payments/' + item.code + '.png')
})
return payments
},
// 用户点击支付方式处理
toPayHandler(e) {
this.popShow = true;
let code = e.target.value.code;
let data = {
payment_code: code,
payment_type: this.type,
params: {}
}
data['ids'] = (this.type == 1 || this.type == 3 || this.type == 4 || this.type == 5) ? this.orderId : this.uid
// 判断订单支付类型
if (this.type == 2 && this.recharge) {
data['params'] = {
money: this.recharge
}
} else if ((this.type == 3 || this.type == 4) && this.recharge) {
data['params'] = {
}
}
let _this = this
switch (code) {
case 'wechatpay':
this.$u.api.pay(data).then(res => {
if (res.status) {
if (res.otherData.checkSceneResult && res.otherData.checkSceneResult.is_matched == 1) {
wx.requestOrderPayment({
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
orderInfo: res.otherData.orderInfo,
success: function (e) {
console.log(e);
if (e.errMsg === 'requestOrderPayment:ok') {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
}
},
fail: function (res) {
if (res.errMsg === 'requestPayment:fail cancel') {
_this.popHide();
_this.$u.toast("您已经取消此方式支付,可继续选择其他方式支付。")
}
console.log(res);
}
});
} else {
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
success: function (e) {
console.log(e);
if (e.errMsg === 'requestPayment:ok') {
_this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
}
},
fail: function (res) {
if (res.errMsg === 'requestPayment:fail cancel') {
_this.popHide();
_this.$u.toast("您已经取消此方式支付,可继续选择其他方式支付。")
}
console.log(res);
}
});
}
} else {
_this.$u.toast(res.msg)
_this.popHide();
}
})
break
case 'balancepay':
/**
* 用户余额支付
*
*/
this.$u.api.pay(data).then(res => {
if (res.status) {
this.$u.route({ type: 'redirectTo', url: '/pages/payment/result/result?id=' + res.data.paymentId });
} else {
this.$u.toast(res.msg)
this.popHide();
}
})
break
case 'offline':
/**
* 线下支付
*/
this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => { }, false, '取消', '确定')
break
}
},
// 支付中显示隐藏
popHide() {
this.popShow = false
}
}
}
</script>
<style lang="scss">
.coreshop-avatar { background: #fff; }
</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,265 @@
<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>
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
}
},
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/ic-wechat.png',
sort: 0
})
data.push({
name: '分享到微信朋友圈',
cate: 'share',
id: 'weixin',
type: 'WXSenceTimeline',
img: '/static/images/circle-of-friends.png',
sort: 1
})
break;
case 'qq':
data.push({
name: '分享到QQ',
cate: 'share',
id: 'qq',
img: '/static/images/qq.png',
sort: 3
})
break;
default:
break;
}
}
data.push({
name: '生成海报',
cate: 'poster',
id: 'poster',
img: '/static/images/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,143 @@
<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
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: 2
},
//拼团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 == 2) {
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 == 3) {
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
}
} else if (this.shareType == 12) {
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()
this.$u.route('/pages/share/sharePoster/sharePoster?poster=' + encodeURIComponent(res.data))
} else {
this.$u.toast(res.msg)
}
});
}
}
}
</script>

View File

@@ -0,0 +1,61 @@
<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
}
},
watch: {
spesData: function (val) {
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,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,26 @@
<!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>
</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,168 @@
{
"name" : "南山田舍",
"appid" : "__UNI__EAACF14",
"description" : "核心商城系统CoreShop是基于uni-app框架开发的商城应用程序",
"versionName" : "1.0",
"versionCode" : 1,
"transformPx" : false,
"app-plus" : {
/* 5+App */
"modules" : {
"Payment" : {},
"VideoPlayer" : {}
},
/* */
"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"
},
"alipay" : {
"scheme" : ""
}
},
"ad" : {},
"maps" : {},
"oauth" : {
"univerify" : {}
}
},
"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" : "wx11d95cdaee6058f6",
"setting" : {
"urlCheck" : true,
"postcss" : true,
"minified" : true,
"es6" : true,
"checkSiteMap" : false
},
"permission" : {
"scope.userLocation" : {
"desc" : "用于获取您附近的门店列表"
}
},
"optimization" : {
"subPackages" : true
}
},
"h5" : {
"title" : "南山田舍",
"domain" : "https://h5.demo.coreshop.cn",
"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,762 @@
{
"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/cart/cart",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "购物车"
}
},
{
"path": "pages/index/member/member",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "会员中心"
}
},
{
"path": "pages/search/search",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "搜索"
}
},
{
"path": "pages/category/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分类"
}
},
{
"path": "pages/category/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商品列表"
}
},
{
"path": "pages/goods/goodDetails/goodDetails",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "商品详情",
"navigationStyle": "custom"
}
},
{
"path": "pages/placeOrder/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "提交订单"
}
},
{
"path": "pages/placeOrder/invoice/invoice",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "发票"
}
},
{
"path": "pages/placeOrder/storeList/storeList",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "门店列表"
}
},
{
"path": "pages/payment/pay/pay",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "支付"
}
},
{
"path": "pages/payment/waiting/waiting",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "等待支付"
}
},
{
"path": "pages/payment/result/result",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "支付结果"
}
},
{
"path": "pages/article/details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "文章详情"
}
},
{
"path": "pages/article/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "文章列表"
}
},
{
"path": "pages/login/loginBySMS/loginBySMS",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "授权登录"
}
},
{
"path": "pages/share/sharePoster/sharePoster",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "分享"
}
},
{
"path": "pages/activity/pinTuan/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "拼团列表"
}
},
{
"path": "pages/activity/pinTuan/pinTuanDetails/pinTuanDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "拼团详情"
}
},
{
"path": "pages/activity/seckill/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "秒杀列表"
}
},
{
"path": "pages/activity/seckill/seckillDetails/seckillDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "秒杀详情"
}
},
{
"path": "pages/activity/groupBuying/list/list",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "团购列表"
}
},
{
"path": "pages/activity/groupBuying/groupBuyingDetails/groupBuyingDetails",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "团购详情"
}
},
{
"path": "pages/form/details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "万能表单"
}
},
{
"path": "pages/share/jump/jump",
"style": {
"navigationBarTextStyle": "black",
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "加载中..."
}
},
{
"path": "pages/storeMap/storeMap",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "门店列表"
}
},
{
"path": "pages/serviceGoods/index/index",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务商品列表"
}
},
{
"path": "pages/serviceGoods/details/details",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "服务商品详情"
}
},
{
"path": "pages/coupon/coupon",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "优惠券列表"
}
},
{
"path": "pages/map/map",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "地图展示"
}
},
{
"path": "pages/goods/goodComments/goodComments",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商品评论"
}
},
{
"path": "pages/reward/reward",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "打赏"
}
},
{
"path": "pages/template",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "模板"
}
},
{
"path": "pages/demo",
"style": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示"
}
}
],
"subpackages": [
{
"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": "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,911 @@
<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="325" :list="goodsInfo.album" 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" :autoStart="true" :millisecond="true" style="color: #fff;"></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="selectTap(0)" 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="grid col-2">
<view class="col-item 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>
<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 :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 :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 :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 :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 :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="100%" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 u-line-2">{{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%" radius="10"></u--image>
<view class="good_title u-line-2">
{{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 class="coreshop-common-view-box select hide" :class="modalType=='select' ?'show':''">
<!--商品信息-->
<view class="coreshop-list menu-avatar">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius lg" :style="[{backgroundImage:'url('+ product.images +')'}] " />
<view class="content">
<view class="coreshop-text-price-view">
<text class="coreshop-text-price coreshop-text-red coreshop-margin-right-10">{{ product.price || ''}}</text>
<text class="coreshop-font-sm coreshop-text-gray coreshop-text-through">{{ product.mktprice || ''}}</text>
<!--<u-tag text="秒杀中" mode="plain" type="error" shape="circle" size="mini" />-->
</view>
<view class="coreshop-text-black coreshop-font-sm flex">
<view class="u-line-2">已选: {{ product.spesDesc || '无'}}</view>
</view>
</view>
</view>
</view>
<!--规格数据-->
<view class="coreshop-select-btn-list-box">
<coreshop-spec :spesData="defaultSpesDesc" ref="spec" @changeSpes="changeSpes"></coreshop-spec>
<view class="select-item">
<view class="coreshop-text-black">数量</view>
<view class="select-btn">
<u-number-box v-model="buyNum" :min="minNums" :max="product.stock"></u-number-box>
</view>
</view>
</view>
</view>
<!--公共按钮-->
<view class="coreshop-padding-15 coreshop-text-center" v-if="modalType=='select'">
<u-button type="error" :custom-style="customStyle" size="normal" @click="clickHandle()" :disabled='submitStatus' :loading='submitStatus' v-if="product.stock>0" shape="circle">确定</u-button>
<u-button type="default" size="normal" v-else>已售罄</u-button>
</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">
<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-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="selectTap()" shape="circle" color="#f37b1d">立即{{ typeName || '' }}</u-button>
</view>
</view>
</view>
<!-- 右边浮动球 -->
<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 {
background: {
backgroundColor: '#f37b1d'
},
goodsId: 0, // 商品id
groupId: 0, // 团购ID
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 规格详情
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
buyNum: 1, // 选定的购买数量
minBuyNum: 1, // 最小可购买数量
type: 2,
cartType: 3,
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;
},
// 规格切换计算规格商品的 可购买数量
minNums() {
var num = this.product.stock > 0 ? this.product.stock : 0;
return num > this.minBuyNum ? this.minBuyNum : num;
},
// 判断商品是否是多规格商品 (为了兼容小程序 只能写在计算属性里面了)
isSpes() {
if (this.product.hasOwnProperty('defaultSpecificationDescription') && this.product.defaultSpecificationDescription != null && Object.keys(this.product.defaultSpecificationDescription).length) {
if (this.product.defaultSpecificationDescription != null && this.product.defaultSpecificationDescription != "" && this.product.defaultSpecificationDescription != undefined) {
return true;
} else {
return false;
}
} else {
return false;
}
},
// 优惠信息重新组装
promotion() {
let arr = [];
if (this.product.promotionList) {
for (let k in this.product.promotionList) {
arr.push(this.product.promotionList[k]);
}
}
return arr;
},
typeName() {
return this.goodsInfo.groupType == 3 ? '团购' : '秒杀';
},
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
},
defaultSpesDesc() {
return this.product.defaultSpecificationDescription;
}
},
methods: {
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
};
// 如果用户已经登录 要传用户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;
let products = res.data.product;
_this.goodsInfo = info;
_this.isfav = _this.goodsInfo.isfav;
_this.type = _this.goodsInfo.groupType;
_this.product = _this.spesClassHandle(products);
_this.buyNum = _this.product.stock >= _this.minBuyNum ? _this.minBuyNum : 0;
// 判断如果登录用户添加商品浏览足迹
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;
}
});
}
},
// 切换商品规格
changeSpes(obj) {
let index = obj.v;
let key = obj.k;
let tmp_defaultSpecificationDescription = JSON.parse(this.product.defaultSpecificationDescription);
if (tmp_defaultSpecificationDescription[index][key].hasOwnProperty('productId') && tmp_defaultSpecificationDescription[index][key].productId) {
let data = {
id: tmp_defaultSpecificationDescription[index][key].productId,
type: 'group', //商品类型
groupId: this.groupId
};
let userToken = this.$db.get('userToken');
if (userToken) {
data['token'] = userToken;
}
this.$u.api.getProductInfo(data).then(res => {
if (res.status == true) {
// 切换规格判断可购买数量
this.buyNum = res.data.stock > this.minBuyNum ? this.minBuyNum : res.data.stock;
this.product = this.spesClassHandle(res.data);
}
});
uni.showLoading({
title: '加载中'
});
setTimeout(function () {
uni.hideLoading();
}, 1000);
}
},
// 多规格样式统一处理
spesClassHandle(products) {
// 判断是否是多规格 (是否有默认规格)
if (products.hasOwnProperty('defaultSpecificationDescription')) {
let spes = products.defaultSpecificationDescription;
for (let key in spes) {
for (let i in spes[key]) {
if (spes[key][i].hasOwnProperty('isDefault') && spes[key][i].isDefault === true) {
this.$set(spes[key][i], 'cla', 'selected');
} else if (spes[key][i].hasOwnProperty('productId') && spes[key][i].productId) {
this.$set(spes[key][i], 'cla', 'not-selected');
} else {
this.$set(spes[key][i], 'cla', 'none');
}
}
}
spes = JSON.stringify(spes)
products.defaultSpecificationDescription = spes;
}
return products;
},
// 购买数量加减操作
bindChange(e) {
this.buyNum = e.val;
},
// 商品收藏/取消
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 => { });
},
// 点击弹出框确定按钮事件处理
clickHandle() {
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
this.submitStatus = true;
this.buyNow();
},
// 立即购买
buyNow() {
if (this.buyNum > 0) {
let data = {
ProductId: this.product.id,
Nums: this.buyNum,
type: this.type,
cartType: this.cartType,
objectId: this.groupId
};
this.$u.api.addCart(data).then(res => {
if (res.status) {
this.hideModal(); // 关闭弹出层
let cartIds = res.data;
this.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds) + '&orderType=' + this.cartType + '&objectId=' + this.groupId);
} else {
this.$u.toast(res.msg);
}
});
}
},
// 购物车页面跳转
redirectCart() {
this.$u.route({
type: 'switchTab',
url: '/pages/index/cart/cart'
});
},
trigger(e) {
this.content[e.index].active = !e.item.active;
this.$u.route({
type: 'switchTab',
url: e.item.url
});
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(imgs) {
// 预览图片
uni.previewImage({
urls: imgs.split()
});
},
//在线客服,只有手机号的,请自己替换为手机号
showChat() {
// #ifdef H5
let _this = this;
window._AIHECONG('ini', {
entId: this.config.entId,
button: false,
appearance: {
panelMobile: {
tone: '#FF7159',
sideMargin: 30,
ratio: 'part',
headHeight: 50
}
}
});
//传递客户信息
window._AIHECONG('customer', {
head: _this.userInfo.avatar,
名称: _this.userInfo.nickname,
手机: _this.userInfo.mobile
});
window._AIHECONG('showChat');
// #endif
// 客服页面
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #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();
},
// 显示modal弹出框
selectTap() {
this.modalTitle = "选择规格";
this.modalType = 'select';
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" scoped>
</style>

View File

@@ -0,0 +1,6 @@
.goods-item { margin-bottom: 1px;
.progress-text { color: #999999; font-size: 10px; margin-left: 12px; }
}
.activity-goods-box {
.goods-right { width: 240px; }
}

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-between">
<view class="img-box">
<view class="tag" v-if="index < 3">TOP{{ index + 1 }}</view>
<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">
<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-10">
<view class="coreshop-flex coreshop-align-center">
<view class="current">{{ item.pinTuanPrice }}</view>
<view class="original">{{ item.price }}</view>
</view>
</view>
<button class="cu-btn buy-btn" @tap="goPinTuanDetail(item.id,item.pinTuanRule.id)">马上拼</button>
</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,13 @@
.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; }
}
.activity-goods-box {
.goods-right { width: 240px; }
}

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,914 @@
<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="325" :list="goodsInfo.album" 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" :autoStart="true" :millisecond="true"></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="selectTap(0)" 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="grid col-2">
<view class="col-item 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>
<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 :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 :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 :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 :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 :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="100%" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 u-line-2">{{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%" radius="10"></u--image>
<view class="good_title u-line-2">
{{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 class="coreshop-common-view-box select hide" :class="modalType=='select' ?'show':''">
<!--商品信息-->
<view class="coreshop-list menu-avatar">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius lg" :style="[{backgroundImage:'url('+ product.images +')'}] " />
<view class="content">
<view class="coreshop-text-price-view">
<text class="coreshop-text-price coreshop-text-red coreshop-margin-right-10">{{ product.price || ''}}</text>
<text class="coreshop-font-sm coreshop-text-gray coreshop-text-through">{{ product.mktprice || ''}}</text>
<!--<u-tag text="秒杀中" mode="plain" type="error" shape="circle" size="mini" />-->
</view>
<view class="coreshop-text-black coreshop-font-sm flex">
<view class="u-line-2">已选: {{ product.spesDesc || '无'}}</view>
</view>
</view>
</view>
</view>
<!--规格数据-->
<view class="coreshop-select-btn-list-box">
<coreshop-spec :spesData="defaultSpesDesc" ref="spec" @changeSpes="changeSpes"></coreshop-spec>
<view class="select-item">
<view class="coreshop-text-black">数量</view>
<view class="select-btn">
<u-number-box v-model="buyNum" :min="minNums" :max="product.stock"></u-number-box>
</view>
</view>
</view>
</view>
<!--公共按钮-->
<view class="coreshop-padding-15 coreshop-text-center" v-if="modalType=='select'">
<u-button type="error" :custom-style="customStyle" size="normal" @click="clickHandle()" :disabled='submitStatus' :loading='submitStatus' v-if="product.stock>0" shape="circle">确定</u-button>
<u-button type="default" size="normal" v-else>已售罄</u-button>
</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">
<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-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="selectTap()" shape="circle" color="#9c26b0">立即{{ typeName || '' }}</u-button>
</view>
</view>
</view>
<!-- 右边浮动球 -->
<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 {
goodsId: 0, // 商品id
groupId: 0, // 团购ID
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 规格详情
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
buyNum: 1, // 选定的购买数量
minBuyNum: 1, // 最小可购买数量
type: 2,
cartType: 4,
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;
},
// 规格切换计算规格商品的 可购买数量
minNums() {
var num = this.product.stock > 0 ? this.product.stock : 0;
return num > this.minBuyNum ? this.minBuyNum : num;
},
// 判断商品是否是多规格商品 (为了兼容小程序 只能写在计算属性里面了)
isSpes() {
if (this.product.hasOwnProperty('defaultSpecificationDescription') && this.product.defaultSpecificationDescription != null && Object.keys(this.product.defaultSpecificationDescription).length) {
if (this.product.defaultSpecificationDescription != null && this.product.defaultSpecificationDescription != "" && this.product.defaultSpecificationDescription != undefined) {
return true;
} else {
return false;
}
} else {
return false;
}
},
// 优惠信息重新组装
promotion() {
let arr = [];
if (this.product.promotionList) {
for (let k in this.product.promotionList) {
arr.push(this.product.promotionList[k]);
}
}
return arr;
},
typeName() {
return this.goodsInfo.groupType == 3 ? '团购' : '秒杀';
},
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
},
defaultSpesDesc() {
return this.product.defaultSpecificationDescription;
}
},
methods: {
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
};
// 如果用户已经登录 要传用户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;
let products = res.data.product;
_this.goodsInfo = info;
_this.isfav = _this.goodsInfo.isfav;
_this.type = _this.goodsInfo.groupType;
_this.product = _this.spesClassHandle(products);
_this.buyNum = _this.product.stock >= _this.minBuyNum ? _this.minBuyNum : 0;
// 判断如果登录用户添加商品浏览足迹
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;
}
});
}
},
// 切换商品规格
changeSpes(obj) {
let index = obj.v;
let key = obj.k;
let tmp_defaultSpecificationDescription = JSON.parse(this.product.defaultSpecificationDescription);
if (tmp_defaultSpecificationDescription[index][key].hasOwnProperty('productId') && tmp_defaultSpecificationDescription[index][key].productId) {
let data = {
id: tmp_defaultSpecificationDescription[index][key].productId,
type: 'group', //商品类型
groupId: this.groupId
};
let userToken = this.$db.get('userToken');
if (userToken) {
data['token'] = userToken;
}
this.$u.api.getProductInfo(data).then(res => {
if (res.status == true) {
// 切换规格判断可购买数量
this.buyNum = res.data.stock > this.minBuyNum ? this.minBuyNum : res.data.stock;
this.product = this.spesClassHandle(res.data);
}
});
uni.showLoading({
title: '加载中'
});
setTimeout(function () {
uni.hideLoading();
}, 1000);
}
},
// 多规格样式统一处理
spesClassHandle(products) {
// 判断是否是多规格 (是否有默认规格)
if (products.hasOwnProperty('defaultSpecificationDescription')) {
let spes = products.defaultSpecificationDescription;
for (let key in spes) {
for (let i in spes[key]) {
if (spes[key][i].hasOwnProperty('isDefault') && spes[key][i].isDefault === true) {
this.$set(spes[key][i], 'cla', 'selected');
} else if (spes[key][i].hasOwnProperty('productId') && spes[key][i].productId) {
this.$set(spes[key][i], 'cla', 'not-selected');
} else {
this.$set(spes[key][i], 'cla', 'none');
}
}
}
spes = JSON.stringify(spes)
products.defaultSpecificationDescription = spes;
}
return products;
},
// 购买数量加减操作
bindChange(e) {
this.buyNum = e.val;
},
// 商品收藏/取消
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 => { });
},
// 点击弹出框确定按钮事件处理
clickHandle() {
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
this.submitStatus = true;
this.buyNow();
},
// 立即购买
buyNow() {
if (this.buyNum > 0) {
let data = {
ProductId: this.product.id,
Nums: this.buyNum,
type: this.type,
cartType: this.cartType,
objectId: this.groupId
};
this.$u.api.addCart(data).then(res => {
if (res.status) {
this.hideModal(); // 关闭弹出层
let cartIds = res.data;
this.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds) + '&orderType=' + this.cartType + '&objectId=' + this.groupId);
} else {
this.$u.toast(res.msg);
}
});
}
},
// 购物车页面跳转
redirectCart() {
this.$u.route({
type: 'switchTab',
url: '/pages/index/cart/cart'
});
},
trigger(e) {
this.content[e.index].active = !e.item.active;
this.$u.route({
type: 'switchTab',
url: e.item.url
});
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(imgs) {
// 预览图片
uni.previewImage({
urls: imgs.split()
});
},
//在线客服,只有手机号的,请自己替换为手机号
showChat() {
// #ifdef H5
let _this = this;
window._AIHECONG('ini', {
entId: this.config.entId,
button: false,
appearance: {
panelMobile: {
tone: '#FF7159',
sideMargin: 30,
ratio: 'part',
headHeight: 50
}
}
});
//传递客户信息
window._AIHECONG('customer', {
head: _this.userInfo.avatar,
名称: _this.userInfo.nickname,
手机: _this.userInfo.mobile
});
window._AIHECONG('showChat');
// #endif
// 客服页面
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #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();
},
// 显示modal弹出框
selectTap() {
this.modalTitle = "选择规格";
this.modalType = 'select';
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">
.buyBtn { height: 37px; width: 90%; }
</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,120 @@
<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);
} else {
this.cid = 1;
}
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,184 @@
<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">
<u-row gutter="16">
<u-col span="12" v-for="(item,index) in tabbar" :key="index" @click="goClass(item.id)">
<u--image width="100%" height="125px" :src="item.imageUrl"></u--image>
<view class="coreshop-text-center coreshop-padding-top-30 coreshop-padding-bottom-30">
{{item.name}}
</view>
</u-col>
</u-row>
</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"></u--image>
<view class="coreshop-text-center coreshop-padding-top-30 coreshop-padding-bottom-30 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">
<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" @click="goClass(item1.id)"></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: [],
advert: {},
isChild: false,
searchKey: ''
}
},
computed: {
CateStyle() {
return this.$store.state.config.cateStyle ? this.$store.state.config.cateStyle : 3;
}
},
onShow() {
this.categories();
this.getBanner();
},
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
});
},
getBanner() {
this.$u.api.advert(
{
codes: 'tpl1_class_banner1'
}).then(res => {
this.advert = res.data;
}
);
},
// 广告点击查看详情
showSliderInfo(type, val) {
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val);
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1');
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val);
}
},
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 */ }
.good_box { border-radius: 8px; margin: 5px; background-color: #ffffff; padding: 5px; position: relative; width: calc(100% - 6px); }
.good_image { width: 100%; border-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,661 @@
<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">
<u-grid :col="2" :border="false" align="left">
<u-grid-item bg-color="transparent" :custom-style="{padding: '1px'}" v-for="item in goodsList" :key="item.id" @click="goGoodsDetail(item.id)">
<view class="good_box">
<u--image :src="item.image" :index="item.id" width="100%" mode="widthFix" radius="10" @click="goGoodsDetail(item.id)"></u--image>
<view class="good_title u-line-2">
{{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>
<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>
<!-- 列表图片 -->
<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) {
//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();
}
},
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,136 @@
<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)
}
})
},
// 用户领取优惠券
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' })
} 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,899 @@
<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">
<view>
<view class='sw'>
<swiper>
<swiper-item v-for="(item,itemIndex) in slideImg" :key="itemIndex">
<image :src="item" class="slide-image" mode='widthFix' />
</swiper-item>
</swiper>
</view>
</view>
</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" 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">
<label class="coreshop-margin-right-40" v-for="(radioItem, itemIndex) in item.radioValue" :key="itemIndex">
<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>
</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.$db.get('userToken')) {
// this.hasLogin = true
// this.$u.api.userInfo().then(res => {
// if (res.status) {
// }
// })
//} else {
// this.hasLogin = false
//}
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,973 @@
<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="325" :list="goodsInfo.album" indicator indicatorMode="line" circular @click="clickImg"></u-swiper>
</view>
<!--限时秒杀-->
<view class="coreshop-limited-seckill-box coreshop-bg-red">
<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 class="coreshop-text-through">原价{{ product.mktprice || '0.00'}}</view>
<view>{{ goodsInfo.buyCount || '0' }} 人已购买</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>
{{ product.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="selectTap(0)" 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="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 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="100%" radius="10"></u--image>
<view class="u-line-2 coreshop-font-sm coreshop-text-black coreshop-margin-top-10 coreshop-margin-bottom-10 u-line-2">{{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-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="grid col-2">
<view class="col-item 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>
<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 :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 :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 :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 :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 :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-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%" radius="10"></u--image>
<view class="good_title u-line-2">
{{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">
<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-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="selectTap(1)">
<text class="coreshop-font-12">加购物车</text>
</u-button>
<u-button type="success" size="normal" shape="circle" @click="selectTap(2)">
<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 class="coreshop-common-view-box select hide" :class="modalType=='select' ?'show':''">
<!--商品信息-->
<view class="coreshop-list menu-avatar">
<view class="coreshop-list-item">
<view class="coreshop-avatar radius lg" :style="[{backgroundImage:'url('+ product.images +')'}] " />
<view class="content">
<view class="coreshop-text-price-view">
<text class="coreshop-text-price coreshop-text-red coreshop-margin-right-10">{{ product.price || ''}}</text>
<text class="coreshop-font-sm coreshop-text-gray coreshop-text-through">{{ product.mktprice || ''}}</text>
<!--<text class="cu-tag bg-gradual-red radius sm">
<text class="cuIcon-hotfill"/>
<text>秒杀中</text>
</text>-->
</view>
<view class="coreshop-text-black coreshop-font-sm flex">
<view class="u-line-2">已选: {{ product.spesDesc || product.name}} 库存{{product.stock > 0 ? product.stock :0 }}</view>
</view>
</view>
</view>
</view>
<!--规格数据-->
<view class="coreshop-select-btn-list-box">
<coreshop-spec :spesData="defaultSpesDesc" ref="spec" @changeSpes="changeSpes"></coreshop-spec>
<view class="coreshop-text-black coreshop-padding-top-10 coreshop-padding-bottom-10">数量</view>
<view class="select-btn">
<u-number-box v-model="buyNum" :min="minNums" :max="product.stock"></u-number-box>
</view>
</view>
</view>
<!--公共按钮-->
<view class="coreshop-padding-15 coreshop-text-center" v-if="modalType=='select'">
<u-button type="error" size="default" @click="clickHandle()" :disabled='submitStatus' :loading='submitStatus' v-if="product.stock > 0" shape="circle">确定</u-button>
<u-button type="default" size="normal" v-else>已售罄</u-button>
</view>
</view>
</view>
</u-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 {
background: {
backgroundColor: '#e54d42'
},
bannerCur: 0,
current: 0, // init tab位
goodsId: 0, // 商品id
goodsInfo: {}, // 商品详情
cartNums: 0, // 购物车数量
product: {}, // 货品详情
shopRecommendData: [], // 本店推荐数据
otherRecommendData: [], // 其他数据
goodsParams: [], // 商品参数信息
goodsComments: [], // 商品评论信息
buyNum: 1, // 选定的购买数量
minBuyNum: 1, // 最小可购买数量
type: 2, // 1加入购物车 2购买
cartType: 1,
isfav: false, // 商品是否收藏
submitStatus: false,
bottomModal: false,
modalTitle: '',
modalType: 'promotion',
selectType: '',
shareUrl: '/pages/share/jump/jump',
shareBox: false,
serviceDescription: {
commonQuestion: [],
delivery: [],
service: [],
}
}
},
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() {
this.submitStatus = false;
},
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);
}
},
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;
},
// 规格切换计算规格商品的 可购买数量
minNums() {
var num = this.product.stock > 0 ? this.product.stock : 0;
return num > this.minBuyNum ? this.minBuyNum : num;
},
// 判断商品是否是多规格商品 (为了兼容小程序 只能写在计算属性里面了)
isSpes() {
if (this.product.hasOwnProperty('defaultSpecificationDescription') && Object.keys(this.product.defaultSpecificationDescription).length) {
return true;
} else {
return false;
}
},
// 优惠信息重新组装
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
},
defaultSpesDesc() {
return this.product.defaultSpecificationDescription;
}
},
methods: {
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)
}
// 如果用户已经登录 要传用户token
let userToken = this.$db.get("userToken");
if (userToken) {
this.$u.api.goodsDetailByToken(data).then(res => {
if (res.status == true) {
let info = res.data;
let products = res.data.product;
_this.goodsInfo = info;
_this.isfav = res.data.isFav;
_this.product = _this.spesClassHandle(products);
_this.buyNum = _this.product.stock >= _this.minBuyNum ? _this.minBuyNum : 0;
// 判断如果登录用户添加商品浏览足迹
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) {
let info = res.data;
let products = res.data.product;
_this.goodsInfo = info;
_this.isfav = res.data.isFav;
_this.product = _this.spesClassHandle(products);
_this.buyNum = _this.product.stock >= _this.minBuyNum ? _this.minBuyNum : 0;
// 判断如果登录用户添加商品浏览足迹
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;
}
})
}
},
// 切换商品规格
changeSpes(obj) {
let index = obj.v;
let key = obj.k;
let userToken = this.$db.get('userToken');
let tmp_defaultSpecificationDescription = JSON.parse(this.product.defaultSpecificationDescription);
if (tmp_defaultSpecificationDescription[index][key].hasOwnProperty('productId') && tmp_defaultSpecificationDescription[index][key].productId) {
this.$refs.spec.changeSpecData();
this.$u.api.getProductInfo({ id: tmp_defaultSpecificationDescription[index][key].productId, token: userToken }).then(res => {
if (res.status == true) {
// 切换规格判断可购买数量
this.buyNum = res.data.stock >= this.minBuyNum ? this.minBuyNum : res.data.stock;
this.product = this.spesClassHandle(res.data);
}
});
uni.showLoading({
title: '加载中'
});
setTimeout(function () {
uni.hideLoading();
}, 1000);
}
},
// 多规格样式统一处理
spesClassHandle(products) {
// 判断是否是多规格 (是否有默认规格)
if (products.hasOwnProperty('defaultSpecificationDescription')) {
let spes = products.defaultSpecificationDescription;
for (let key in spes) {
for (let i in spes[key]) {
if (spes[key][i].hasOwnProperty('isDefault') && spes[key][i].isDefault === true) {
this.$set(spes[key][i], 'cla', 'selected');
} else if (spes[key][i].hasOwnProperty('productId') && spes[key][i].productId) {
this.$set(spes[key][i], 'cla', 'not-selected');
} else {
this.$set(spes[key][i], 'cla', 'none');
}
}
}
spes = JSON.stringify(spes)
products.defaultSpecificationDescription = spes;
}
return products;
},
// 购买数量加减操作
//bindChange(val) {
// this.buyNum = val.value;
// console.log(val);
// console.log(this.buyNum);
//},
// 商品收藏/取消
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);
}
})
},
// tab点击切换
onClickItem(index) {
if (this.current !== index) {
this.current = index;
}
},
// 获取商品参数信息
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 => { });
},
// 加入购物车
addToCart() {
if (this.buyNum > 0) {
let data = {
productId: this.product.id,
nums: this.buyNum
}
this.$u.api.addCart(data).then(res => {
this.submitStatus = false;
if (res.status) {
this.hideModal(); // 关闭弹出层
this.getCartNums(); // 获取购物车数量
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false });
} else {
this.$u.toast(res.msg);
}
});
}
},
// 立即购买
buyNow() {
if (this.buyNum > 0) {
let data = {
productId: this.product.id,
nums: this.buyNum,
type: this.type, // 区分加入购物车和购买
cartType: this.cartType // 区分加入购物车和购买
}
this.$u.api.addCart(data).then(res => {
this.submitStatus = false;
if (res.status) {
this.hideModal();
let cartIds = res.data;
this.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds));
} else {
this.$u.toast(res.msg);
}
});
}
},
// 购物车页面跳转
redirectCart() {
this.$u.route({
type: 'switchTab',
url: '/pages/index/cart/cart'
});
},
// 点击弹出框确定按钮事件处理
clickHandle() {
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
this.submitStatus = true;
this.type === 1 ? this.addToCart() : this.buyNow();
},
trigger(e) {
this.content[e.index].active = !e.item.active;
this.$u.route({
type: 'switchTab',
url: e.item.url
})
},
// 跳转到h5分享页面
goShare() {
this.shareBox = true;
},
closeShare() {
this.shareBox = false;
},
// 图片点击放大
clickImg(imgs) {
// 预览图片
uni.previewImage({
urls: imgs.split()
});
},
//在线客服,只有手机号的,请自己替换为手机号
showChat() {
let _this = this;
// #ifdef H5
window._AIHECONG('ini', {
entId: this.config.entId,
button: false,
appearance: {
panelMobile: {
tone: '#FF7159',
sideMargin: 30,
ratio: 'part',
headHeight: 50
}
}
})
//传递客户信息
window._AIHECONG('customer', {
head: _this.userInfo.avatar,
'名称': _this.userInfo.nickname,
'手机': _this.userInfo.mobile
})
window._AIHECONG('showChat')
// #endif
// 客服页面
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #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();
},
selectTap(type) {
this.selectType = type;
this.type = type;
this.modalTitle = "选择规格";
this.modalType = 'select';
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">
</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: 25px; 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,343 @@
<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" @click="goGoodsDetail(item.products.goodsId)">
<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">
<text class="cart-shoppingcard-goods-price">{{item.products.price}}</text>
<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>
<u-icon name="trash" size="14" @click="removeGoods" :index="index" label="删除" labelSize="12"></u-icon>
</view>
</view>
</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-row coreshop-justify-between coreshop-align-center">
<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: ['全选']
}
},
//页面加载
onShow() {
let userToken = this.$db.get('userToken');
if (userToken) {
this.getCartData(); //获取购物车数据
// 初始化时候计算总价如果使用api 获取购物车项目在 api 请求完成后执行此函数
//this.countTotoal();
}
},
computed: {
// 从vuex中获取店铺名称
shopName() {
return this.$store.state.config.shopName;
},
GoodsStocksWarn() {
return this.$store.state.config.goodsStocksWarn;
}
},
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;
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.totalprice = _that.$common.formatMoney(total, 2, '');
},
toNumberChange: function (e) {
this.$u.throttle(this.numberChange(e), 500)
},
numberChange(e) {
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;
} else {
_this.$u.toast(res.msg);
}
});
//重新计算总价
this.countTotoal();
},
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,331 @@
<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
let _this = this;
window._AIHECONG('ini', {
entId: this.$store.state.config.entId,
button: false,
appearance: {
panelMobile: {
tone: '#FF7159',
sideMargin: 30,
ratio: 'part',
headHeight: 50
}
}
});
//传递客户信息
window._AIHECONG('customer', {
head: _this.userInfo.avatarImage,
名称: _this.userInfo.nickName,
手机: _this.userInfo.mobile
});
window._AIHECONG('showChat');
// #endif
// 客服页面
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #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);
},
// 广告点击查看详情
showSliderInfo(type, val) {
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
},
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>

View File

@@ -0,0 +1,323 @@
<template>
<!-- 页面主体 -->
<view>
<!--提示框组件-->
<u-toast ref="uToast" />
<!--无网络组件-->
<u-no-network></u-no-network>
<!--头部组件-->
<u-navbar leftIcon="search" :title="appTitle" safeAreaInsetTop fixed placeholder @leftClick="goSearch"></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="45"></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="45"></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) {
this.initData();
},
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
let _this = this;
window._AIHECONG('ini', {
entId: this.$store.state.config.entId,
button: false,
appearance: {
panelMobile: {
tone: '#FF7159',
sideMargin: 30,
ratio: 'part',
headHeight: 50
}
}
});
//传递客户信息
window._AIHECONG('customer', {
head: _this.userInfo.avatarImage,
名称: _this.userInfo.nickName,
手机: _this.userInfo.mobile
});
window._AIHECONG('showChat');
// #endif
// 客服页面
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #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);
},
// 广告点击查看详情
showSliderInfo(type, val) {
if (!val) {
return;
}
if (type == 1) {
if (val.indexOf('http') != -1) {
// #ifdef H5
window.location.href = 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') > -1) {
var id = val.replace('/pages/coupon/coupon?id=', "");
this.receiveCoupon(id)
} else {
this.$u.route(val);
return;
}
// #endif
}
} else if (type == 2) {
// 商品详情
this.goGoodsDetail(val)
} else if (type == 3) {
// 文章详情
this.$u.route('/pages/article/details/details?id=' + val + '&idType=1')
} else if (type == 4) {
// 文章列表
this.$u.route('/pages/article/list/list?cid=' + val)
} else if (type == 5) {
//智能表单
this.$u.route('/pages/form/details/details?id=' + val)
}
},
// 用户领取优惠券
receiveCoupon(couponId) {
let data = {
promotion_id: couponId
}
this.$u.api.getCoupon(data).then(res => {
if (res.status) {
this.$refs.uToast.show({ message: res.msg, type: 'success', back: false })
} else {
this.$u.toast(res.msg)
}
})
},
},
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>

View File

@@ -0,0 +1,59 @@
.memberBox {
.headBox { padding-top: 0; padding-bottom: 50px; background-image: url('/static/images/common/bg.png'); background-size: cover; background-position: center;
.user-info-box { padding-top: 20px;
.login-user-view { position: relative; text-align: center;
.login-user-avatar-view { position: relative; margin-bottom: 10px; align-items: center; justify-content: center; display: flex; }
}
}
.user-info-tip-box { position: relative; margin: 10px 14px; border-radius: 10px; padding: 10px 14px;
.u-line-1 { padding-right: 22px; }
.icon { position: absolute; right: 14px; top: 12px; }
}
}
}
.coreshop-view-content { padding: 0 10px 10px 10px; margin-top: -32px;
.coreshop-user-info-order-box { border-radius: 10px;
.coreshop-list {
&.grid {
&.no-border { padding: 0;
& > .coreshop-list-item { padding-bottom: 5px; }
}
}
}
.transactionNumber { font-size: 20px; margin-bottom: 2px; color: $core-main-color; }
}
.coreshop-list {
&.grid {
& > .coreshop-list-item {
text { color: inherit; }
}
}
}
.coreshop-user-info-money-box { border-radius: 10px;
.money-col {
.money-item { position: relative;
.money-item-view { border: 1px solid #f3f2f3; border-radius: 10px; position: relative; padding: 5px;
.money-avatar { position: absolute; left: 5px; }
.money-content { position: relative; margin-left: 55px; margin-bottom: 14px; top: 6px; }
}
}
}
}
.coreshop-user-info-tools-box { border-radius: 10px;
.tools-view { position: relative;
.tools-title { padding-right: 41px; }
.tools-right { position: absolute; right: 5px; bottom: 12px; }
}
}
}
.text-border-x { margin-right: 23px; position: relative;
&:after { position: absolute; background: #dddddd; top: 5px; width: 1px; right: -6.5px; height: 8px; content: " "; }
}
.account-face { height: 60px; width: 60px; flex: 0 0 60px; background-color: transparent; border-radius: 500px; display: -webkit-inline-box; display: -webkit-inline-flex; display: inline-flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center; font-size: 14px; color: #606266; -webkit-border-radius: 10px; border-radius: 10px; position: relative; }
.yqhy { background-image: url(/static/images/my/1.png); }
.yqhy2 { background-image: url(/static/images/my/2.png); }
.grid-text { font-size: 14px; margin-top: 10px; margin-bottom: 10px; color: $core-type-info; }

View File

@@ -0,0 +1,632 @@
<template>
<view class="memberBox">
<u-toast ref="uToast" /><u-no-network></u-no-network>
<u-navbar leftIcon="search" title="会员中心" safeAreaInsetTop fixed placeholder @leftClick="goSearch"></u-navbar>
<view class="headBox coreshop-bg-red">
<!--标题栏-->
<!--小程序端不显示-->
<!--用户信息-->
<view class="user-info-box">
<!--未登陆-->
<view class="login-user-view" v-if="!hasLogin">
<!-- #ifdef H5 || APP-PLUS -->
<view class="login-user-avatar-view">
<u-avatar :src="$store.state.config.shopLogo" size="60"></u-avatar>
</view>
<u-button type="default" size="mini" @click="toLogin()">立即登录</u-button>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="login-user-avatar-view">
<view class="account-face grace-box-shadow">
<open-data type="userAvatarUrl"></open-data>
</view>
</view>
<u-button type="default" size="mini" @click="goLogin()">立即登录</u-button>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<view class="login-user-avatar-view">
<u-avatar :src="userInfo.avatarImage" size="large"></u-avatar>
</view>
<u-button type="default" size="mini" @click="goLogin()">立即登录</u-button>
<!-- #endif -->
</view>
<!--已登陆-->
<view v-else>
<view class="coreshop-flex user-box coreshop-padding-left-15 coreshop-padding-right-10 coreshop-padding-bottom-30 coreshop-flex-direction-row">
<view class="coreshop-margin-right-10">
<u-avatar :src="userInfo.avatarImage" size="48"></u-avatar>
</view>
<view class="coreshop-flex-1 coreshop-padding-top-10 coreshop-padding-bottom-5 coreshop-padding-right-10">
<view class="coreshop-font-17 coreshop-padding-bottom-10 coreshop-flex-direction-row">
<text class="coreshop-margin-right-10">{{ userInfo.nickName }}</text>
<text class="coreshop-font-12">{{ userInfo.gradeName }}</text>
</view>
<view class="coreshop-font-12 coreshop-flex-direction-row">
<text class="text-border-x">积分 {{ userInfo.point }}</text>
<text>余额 {{ userInfo.balance }}</text>
</view>
</view>
<!-- #ifndef MP-WEIXIN -->
<view class="coreshop-margin-left-10 coreshop-padding-10">
<u-icon name="scan" color="#fff" size="16"></u-icon>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-10" @tap="navigateToHandle('/pages/member/setting/userInfo/index')">
<u-icon name="arrow-right" color="#fff" size="16"></u-icon>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="coreshop-margin-left-10 coreshop-padding-10" @click="syncWeChatInfo()">
<u-icon name="reload" color="#fff" size="16"></u-icon>
</view>
<view class="coreshop-margin-left-10 coreshop-padding-10" @tap="navigateToHandle('/pages/member/setting/userInfo/index')">
<u-icon name="arrow-right" color="#fff" size="16"></u-icon>
</view>
<!-- #endif -->
</view>
</view>
</view>
<!--用户数据-->
<view class="user-info-num-box">
<u-row customStyle="margin-bottom: 10px">
<u-col span="3" @tap="navigateToHandle('/pages/member/history/index')" textAlign="center">
<view class="coreshop-font-18" v-if="!hasLogin">-</view>
<view class="coreshop-font-18" v-else>{{ userInfo.footPrintCount }}</view>
<text class="coreshop-font-11">足迹</text>
</u-col>
<u-col span="3" @tap="navigateToHandle('/pages/member/coupon/index')" textAlign="center">
<view class="coreshop-font-18" v-if="!hasLogin">-</view>
<view class="coreshop-font-18" v-else>{{ userInfo.userCouponCount }}</view>
<text class="coreshop-font-11">优惠券</text>
</u-col>
<u-col span="3" @tap="navigateToHandle('/pages/member/collection/index')" textAlign="center">
<view class="coreshop-font-18" v-if="!hasLogin">-</view>
<view class="coreshop-font-18" v-else>{{ userInfo.collectionCount }}</view>
<text class="coreshop-font-11">收藏</text>
</u-col>
<u-col span="3" @tap="navigateToHandle('/pages/member/afterSales/list/list')" textAlign="center">
<view class="coreshop-font-18" v-if="!hasLogin">-</view>
<view class="coreshop-font-18" v-else>{{afterSaleNums || 0}}</view>
<text class="coreshop-font-11">售后</text>
</u-col>
</u-row>
</view>
</view>
<view class="coreshop-view-content">
<!--用户数据-->
<view class="coreshop-padding-10 coreshop-bg-white coreshop-user-info-order-box">
<view class="coreshop-text-black coreshop-font-lg coreshop-text-bold coreshop-padding-10">我的交易</view>
<u-grid :col="5" :border="false">
<u-grid-item v-for="(item, index) in orderItems" :key="index" @click="orderNavigateHandle('/pages/member/order/index/index', index)">
<view class="transactionNumber" v-if="hasLogin">{{ item.nums }}</view>
<u-icon :name="item.icon" :size="25" v-else></u-icon>
<view class="grid-text">{{ item.name }}</view>
</u-grid-item>
</u-grid>
</view>
<!--天天有钱-->
<view class="coreshop-padding-10 coreshop-bg-white coreshop-margin-top-15 coreshop-user-info-money-box" v-if="other.invite.showItem">
<view class="coreshop-text-black coreshop-font-lg coreshop-text-bold coreshop-padding-10">天天有钱</view>
<view class="money-col">
<u-row gutter="16">
<u-col span="6">
<view class="money-item">
<view class="money-item-view coreshop-flex-direction-row" @click="navigateToHandle('/pages/member/invite/index')">
<view class="money-avatar coreshop-avatar lg yqhy" />
<view class="money-content">
<view class="coreshop-text-black u-line-1">边逛边赚钱</view>
<view class="coreshop-text-gray coreshop-font-sm u-line-1">最高提现20元</view>
</view>
</view>
</view>
</u-col>
<u-col span="6">
<view class="money-item">
<view class="money-item-view coreshop-flex-direction-row" @click="navigateToHandle('/pages/member/invite/index')">
<view class="money-avatar coreshop-avatar lg yqhy2" />
<view class="money-content">
<view class="coreshop-text-black u-line-1">邀请好友</view>
<view class="coreshop-text-gray coreshop-font-sm u-line-1">最高分红50000</view>
</view>
</view>
</view>
</u-col>
</u-row>
</view>
</view>
<!--我的服务-->
<view class="coreshop-padding-top-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-30 coreshop-bg-white coreshop-margin-top-15 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 @click="navigateToHandle('/pages/member/merchant/index/index')" v-if="isClerk">
<u-icon name="calendar" :size="25" color="#666" label="商家管理" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<u-grid-item @tap="goDistributionPanel" v-if="isDistribution">
<u-icon name="wifi" :size="25" color="#666" label="分销中心" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<u-grid-item @tap="goAgentPanel" v-if="isAgent">
<u-icon name="list" :size="25" color="#666" label="代理中心" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<u-grid-item v-for="(item,i) in utilityMenus" :key="i" v-if="(item.showItem && i != 'invoice') || (item.showItem && i == 'invoice' && InvoiceSwitch == 1)" @click="navigateToHandle(item.router)">
<u-icon :name="item.icon" :size="25" color="#666" :label="item.name" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
</u-grid>
</view>
</view>
<!--增值业务-->
<view class="coreshop-padding-top-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-30 coreshop-bg-white coreshop-margin-top-15 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" :label="item.name" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
</u-grid>
</view>
</view>
<!--其他-->
<view class="coreshop-padding-top-10 coreshop-padding-left-10 coreshop-padding-right-10 coreshop-padding-bottom-30 coreshop-bg-white coreshop-margin-top-15 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 @click="goArticleList()">
<u-icon name="question-circle" :size="25" color="#666" label="帮助中心" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<u-grid-item v-for="(item,i) in other" :key="i" v-if="item.showItem" @click="navigateToHandle(item.router)">
<u-icon :name="item.icon" :size="25" color="#666" :label="item.name" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<!-- #ifdef H5 || APP-PLUS || APP-PLUS-NVUE -->
<u-grid-item @click="showChat">
<u-icon name="server-man" :size="25" color="#666" label="联系客服" labelPos="bottom" labelSize="13" space="25" top="15"></u-icon>
</u-grid-item>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<!-- todo:: 微信客服 -->
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<!-- todo:: 头条客服 -->
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<!-- todo:: 支付宝客服 -->
<!-- #endif -->
</u-grid>
</view>
</view>
</view>
<!-- 登录提示 -->
<coreshop-login-modal></coreshop-login-modal>
</view>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex';
export default {
data() {
return {
afterSaleNums: 0, //售后数量
isClerk: false,//显示商家管理
isDistribution: false,//显示分销中心
isAgent: false,//显示代理中心
config: '',//配置信息
orderItems: [
{
name: '全部',
icon: 'order',
nums: 0
}, {
name: '待付款',
icon: 'order',
nums: 0
},
{
name: '待发货',
icon: 'order',
nums: 0
},
{
name: '待收货',
icon: 'order',
nums: 0
},
{
name: '待评价',
icon: 'order',
nums: 0
}
],
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
},
},
other: {
invite: {
name: '邀请好友',
icon: 'man-add',
router: '/pages/member/invite/index',
showItem: false
},
search: {
name: '商品检索',
icon: 'search',
router: '/pages/search/search',
showItem: true
},
setting: {
name: '系统设置',
icon: 'setting',
router: '/pages/member/setting/index/index',
showItem: true
}
},
list: 2,
suTipStatus: false,
opacity: 0,
}
},
onShow() {
this.initData()
},
computed: {
...mapState({
hasLogin: state => state.hasLogin,
userInfo: state => state.userInfo,
}),
shopMobile() {
return this.$store.state.config.shopMobile || 0;
},
InvoiceSwitch() {
return this.$store.state.config.invoiceSwitch || 2;
},
StoreSwitch() {
return this.$store.state.config.storeSwitch || 0;
},
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);
}
}
},
methods: {
goAgentPanel() {
var _this = this;
uni.showLoading({
title: '跳转中...'
});
_this.$u.api.getAgentInfo().then(res => {
if (res.status) {
_this.condition = res.data;
if (_this.condition.verifyStatus == 1 || (!_this.condition.needApply && _this.conditionStatus)) {
_this.$u.route('/pages/member/agent/panel/panel');
} else if (_this.condition.verifyStatus > 1) {
_this.$u.route('/pages/member/agent/applyState/applyState');
} else {
_this.$u.route('/pages/member/agent/index/index');
}
} else {
//报错了
_this.$u.toast(res.msg);
}
});
uni.hideLoading();
},
goDistributionPanel() {
var _this = this;
uni.showLoading({
title: '跳转中...'
});
_this.$u.api.getDistributionInfo().then(res => {
if (res.status) {
_this.condition = res.data;
if (_this.condition.hasOwnProperty('verifyStatus')) {
if (_this.condition.verifyStatus == 1 || (!_this.condition.needApply && _this.conditionStatus)) {
_this.$u.route({ url: '/pages/member/distribution/panel/panel' });
} else if (_this.condition.verifyStatus > 1) {
_this.$u.route({ url: '/pages/member/distribution/applyState/applyState' });
} else {
_this.$u.route({ url: '/pages/member/distribution/index/index' });
}
}
} else {
//报错了
_this.$u.toast(res.msg);
}
});
uni.hideLoading();
},
goLogin() {
this.$store.commit('showLoginTip', true);
//getApp().globalData.showLoginTip = true;
},
toLogin() {
this.$u.route({ url: '/pages/login/loginBySMS/loginBySMS' });
},
initData() {
var _this = this
//判断是开启分销还是原始推广
this.config = this.$store.state.config;
if (this.config.openDistribution == 2) {
//屏蔽分销按钮
_this.isDistribution = false
} else if (this.config.openDistribution == 1) {
_this.isDistribution = true
}
if (this.config.isOpenAgent == 1 && this.config.isShowAgentPortal == 1) {
_this.isAgent = true
} else if (this.config.openDistribution == 1) {
//屏蔽代理中心入库
_this.isAgent = false
}
if (this.config.showInviter == 1) {
//不显示-邀请好友
_this.other.invite.showItem = true;
} else if (this.config.showInviter == 2) {
//显示-邀请好友
_this.other.invite.showItem = false;
}
if (this.config.showStoresSwitch == 1) {
//不显示-门店展示列表
_this.vas.storeMap.showItem = true;
} else if (this.config.showStoresSwitch == 2) {
//显示-门店展示列表
_this.vas.storeMap.showItem = false;
}
this.getUserInfo();
},
getUserInfo() {
var _this = this
if (this.$db.get('userToken')) {
this.hasLogin = true
this.$u.api.userInfo().then(res => {
if (res.status) {
_this.userInfo = res.data
// #ifdef MP-WEIXIN
// #endif
// 获取订单不同状态的数量
let data = {
ids: '0,1,2,3,4',
isAfterSale: true
}
_this.$u.api.getOrderStatusSum(data).then(res => {
if (res.status) {
_this.orderItems.forEach((item, key) => {
item.nums = res.data[key]
})
_this.afterSaleNums = res.data['isAfterSale'];
}
})
//判断是否是店员
_this.$u.api.isStoreUser().then(res => {
this.isClerk = res.data
})
}
})
} else {
this.hasLogin = false
}
},
navigateToHandle(pageUrl) {
uni.showLoading({
title: '跳转中...'
});
if (!this.hasLogin) {
console.log('未登录');
//getApp().globalData.showLoginTip = true;
this.$store.commit('showLoginTip', true);
uni.hideLoading();
return false;
}
uni.hideLoading();
this.$u.route(pageUrl)
},
orderNavigateHandle(url, tab = 0) {
if (!this.hasLogin) {
this.$store.commit('showLoginTip', true);
return false;
}
this.$store.commit('orderTab', tab)
this.$u.route(url + '?swiperCurrentIndexId=' + tab);
},
//在线客服,只有手机号的,请自己替换为手机号
showChat() {
// #ifdef H5
// #endif
// #ifdef APP-PLUS || APP-PLUS-NVUE
this.$u.route('/pages/member/customerService/index');
// #endif
// 头条系客服
// #ifdef MP-TOUTIAO
if (this.shopMobile != 0) {
let _this = this;
tt.makePhoneCall({
phoneNumber: this.shopMobile.toString(),
success(res) { },
fail(res) { }
});
} else {
_this.$u.toast('暂无设置客服电话');
}
// #endif
},
//同步微信昵称数据
syncWeChatInfo() {
let _this = this
wx.getUserProfile({
desc: "获取你的昵称、头像、地区及性别",
success: e => {
console.log(e)
if (e.errMsg == 'getUserProfile:ok') {
_this.$u.api.syncWeChatInfo(e.userInfo).then(res => {
console.log(res);
if (res.status) {
_this.$refs.uToast.show({ message: '同步成功', type: 'success', });
if (res.data) {
_this.hasLogin = true
//_this.$store.commit('userInfo', res.data);
}
} else {
_this.$u.toast('登录失败,请重试')
}
})
}
},
fail: res => {
//拒绝授权
this.$refs.uToast.show({ message: '您拒绝了请求', type: 'error' })
return;
}
})
},
},
watch: {
hasLogin() {
this.getUserInfo();
}
},
//分享
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
}
},
}
</script>
<style lang="scss" scoped>
@import 'member.scss';
</style>

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