-
17.gitignore
-
11.hbuilderx/launch.json
-
91App.vue
-
28README.md
-
153api/activity.js
-
73api/admin.js
-
17api/live.js
-
150api/order.js
-
108api/public.js
-
183api/store.js
-
444api/user.js
-
2assets/css/base.css
-
1assets/css/base.css.map
-
180assets/css/base.less
-
2assets/css/reset.css
-
1assets/css/reset.css.map
-
43assets/css/reset.less
-
9377assets/css/style.less
-
661assets/iconfont/iconfont.css
-
77components/AddressWindow.vue
-
210components/Adv.vue
-
289components/CitySelect.vue
-
121components/CountDown.vue
-
122components/CouponListWindow.vue
-
75components/CouponPop.vue
-
88components/CouponWindow.vue
-
24components/DataFormat.vue
-
24components/DataFormatT.vue
-
65components/Footer.vue
-
49components/GoodList.vue
-
59components/Home.vue
-
21components/Loading.vue
-
74components/Mask.vue
-
155components/Menu.vue
-
47components/OrderGoods.vue
-
202components/Payment.vue
-
133components/PriceChange.vue
-
71components/ProductConSwiper.vue
-
141components/ProductWindow.vue
-
212components/PromotionGood.vue
-
82components/Recommend.vue
-
40components/ShareInfo.vue
-
43components/ShareRedPackets.vue
-
324components/ShopLiveCard.vue
-
243components/StorePoster.vue
-
155components/SwitchWindow.vue
-
52components/UserEvaluation.vue
-
127components/WriteOff.vue
-
184components/colorui/animation.css
-
70components/colorui/components/cu-custom.vue
-
1226components/colorui/icon.css
-
4040components/colorui/main.css
-
40components/sh-activity-goods.vue
-
217components/sh-adv.vue
-
197components/sh-groupon.vue
-
203components/t-goods-item/t-goods-item.vue
-
495components/tui-button/tui-button.vue
-
103components/tui-divider/tui-divider.vue
-
354components/tui-tag/tui-tag.vue
-
132components/uni-icons/icons.js
-
67components/uni-icons/uni-icons.vue
-
395components/uni-notice-bar/uni-notice-bar.vue
-
22components/uni-popup/message.js
-
25components/uni-popup/popup.js
-
243components/uni-popup/uni-popup-dialog.vue
-
116components/uni-popup/uni-popup-message.vue
-
165components/uni-popup/uni-popup-share.vue
-
294components/uni-popup/uni-popup.vue
-
279components/uni-transition/uni-transition.vue
-
10config/index.js
-
BINicons/1024x1024.png
-
BINicons/120x120.png
-
BINicons/144x144.png
-
BINicons/152x152.png
-
BINicons/167x167.png
-
BINicons/180x180.png
-
BINicons/192x192.png
-
BINicons/20x20.png
-
BINicons/29x29.png
-
BINicons/40x40.png
-
BINicons/58x58.png
-
BINicons/60x60.png
-
BINicons/72x72.png
-
BINicons/76x76.png
-
BINicons/80x80.png
-
BINicons/87x87.png
-
BINicons/96x96.png
-
51libs/chat.js
-
227libs/order.js
-
397libs/wechat.js
-
122main.js
-
188manifest.json
-
27mixins/SendVerifyCode.js
-
25package.json
-
476pages.json
-
103pages/Loading/index.vue
-
55pages/NotDefined/index.vue
-
131pages/activity/BargainRecord/index.vue
-
629pages/activity/DargainDetails/index.vue
-
84pages/activity/GoodsBargain/index.vue
@ -0,0 +1,17 @@ |
|||
.DS_Store |
|||
node_modules/ |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
|
|||
package-lock.json |
|||
# Editor directories and files |
|||
.idea |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.keystore |
|||
unpackage/ |
|||
assets/css/style.css |
|||
assets/css/style.css.map |
@ -0,0 +1,11 @@ |
|||
{ // 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": [{ |
|||
"type": "uniCloud", |
|||
"default": { |
|||
"launchtype": "remote" |
|||
} |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,91 @@ |
|||
<script> |
|||
import Vue from 'vue' |
|||
// #ifdef H5 |
|||
var VConsole = require('@/utils/vconsole.min.js') |
|||
// #endif |
|||
export default { |
|||
onLaunch: function () { |
|||
const updateManager = uni.getUpdateManager() |
|||
updateManager.onCheckForUpdate(function (res) { |
|||
// 请求完新版本信息的回调 |
|||
console.log(res.hasUpdate) |
|||
}) |
|||
// 下载新版本 |
|||
updateManager.onUpdateReady(function () { |
|||
uni.showModal({ |
|||
title: '更新提示', |
|||
content: '新版本已经准备好,是否重启应用?', |
|||
success(res) { |
|||
if (res.confirm) { |
|||
// 重启应用 |
|||
updateManager.applyUpdate() |
|||
} |
|||
}, |
|||
}) |
|||
}) |
|||
// 新版本下载失败 |
|||
updateManager.onUpdateFailed(function (res) { |
|||
// 新的版本下载失败 |
|||
uni.showModal({ |
|||
title: '已经有新版本了哟~', |
|||
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~', |
|||
}) |
|||
}) |
|||
}, |
|||
onShow: function () { |
|||
console.log('App Show') |
|||
}, |
|||
onHide: function () { |
|||
console.log('App Hide') |
|||
}, |
|||
mounted() { |
|||
// #ifdef H5 |
|||
var vConsole = new VConsole() |
|||
console.log('开启调试') |
|||
// #endif |
|||
this.setAppInfo() |
|||
}, |
|||
methods: { |
|||
// 获取系统栏高度 |
|||
async setAppInfo() { |
|||
let that = this |
|||
return new Promise((resolve, reject) => { |
|||
uni.getSystemInfo({ |
|||
success: function (e) { |
|||
Vue.prototype.StatusBar = e.statusBarHeight |
|||
// #ifdef H5 |
|||
Vue.prototype.CustomBar = e.statusBarHeight + 45 |
|||
// #endif |
|||
|
|||
// #ifdef APP-PLUS |
|||
if (e.platform == 'android') { |
|||
Vue.prototype.CustomBar = e.statusBarHeight + 50 |
|||
} else { |
|||
Vue.prototype.CustomBar = e.statusBarHeight + 45 |
|||
} |
|||
// #endif |
|||
|
|||
// #ifdef MP-WEIXIN |
|||
let custom = wx.getMenuButtonBoundingClientRect() |
|||
Vue.prototype.Custom = custom |
|||
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight |
|||
// #endif |
|||
}, |
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 自动登录 |
|||
async autoLogin(data) {}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less"> |
|||
/*每个页面公共css */ |
|||
@import 'animate.css'; |
|||
@import './assets/iconfont/iconfont.css'; |
|||
@import './assets/css/base.less'; |
|||
@import './assets/css/reset.less'; |
|||
@import './assets/css/style.less'; |
|||
</style> |
@ -0,0 +1,28 @@ |
|||
# 使用说明 |
|||
|
|||
## Hbuilderx |
|||
|
|||
- 已支持HBuilderX最新版 |
|||
|
|||
## 小程序安装步骤 |
|||
- 先从私服上clone下来项目 |
|||
- 下载uni的开发者工具 https://www.dcloud.io/hbuilderx.html |
|||
- 登录微信开发者工具打开 菜单 > 设置 > 安全设置 勾选服务端口为开启 |
|||
- 当前项目下执行 npm install |
|||
- 命令行进入项目所在的目录,点击 hbuilderx > 菜单 > 运行 > 运行到小程序模拟器 > 微信开发者工具 |
|||
- uni会自动打开微信开发者工具并且打开uni的项目 |
|||
|
|||
## 注意事项 |
|||
- uniapp v3.1版本已经兼容h5,另外yshop有自己的H5,uniappv3.1以下版本未对H5端进行处理,如果需要请自行兼容。 |
|||
- manifest.json 中可以配置uni项目的一些信息 |
|||
- 打开manifest.json可配置小程序的 appid |
|||
- 由于需要兼容app,公共样式由 main.js 迁移到了 App.vue,公共样式请在App.vue中进行编辑 |
|||
- 由于需要兼容app,尺寸单位由之前的rem改为rpx,由于修改样式工作量太大并且容易出错,已将.css更改为.less并在其中以之前rem的单位*100,获得新的rpx单位 |
|||
- 如需修改样式问题,请编辑.less的文件,请勿编辑.css的文件 |
|||
|
|||
|
|||
|
|||
## 声明 |
|||
- app测试版已上,请通过 `https://www.pgyer.com/yRYf` 安装测试。 |
|||
- 运行app项目ios需要安装xcode,安卓需要装安卓的sdk以及安卓模拟器,建议安卓安装genymotion https://www.genymotion.com/ 登录时可选择私人使用,勾选后无需付费 |
|||
|
@ -0,0 +1,153 @@ |
|||
import request from "@/utils/request"; |
|||
|
|||
/** |
|||
* 拼团列表 |
|||
*/ |
|||
export function getCombinationList(data) { |
|||
return request.get("/combination/list", data, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 拼团产品详情 |
|||
* @param {*} id |
|||
*/ |
|||
export function getCombinationDetail(id) { |
|||
return request.get("/combination/detail/" + id, {}, { login: true }); |
|||
} |
|||
|
|||
/** |
|||
* 拼团 开团 |
|||
* @param {*} id |
|||
*/ |
|||
export function getCombinationPink(id) { |
|||
return request.get("/combination/pink/" + id); |
|||
} |
|||
|
|||
/** |
|||
* 拼团 取消开团 |
|||
*/ |
|||
export function getCombinationRemove(data) { |
|||
return request.post("/combination/remove", data); |
|||
} |
|||
|
|||
/** |
|||
* 拼团海报 |
|||
* @param {*} id |
|||
*/ |
|||
export function getCombinationPoster(data) { |
|||
return request.post("/combination/poster", data); |
|||
} |
|||
|
|||
/** |
|||
* 秒杀列表配置 |
|||
*/ |
|||
export function getSeckillConfig() { |
|||
return request.get("/seckill/index", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 秒杀列表 |
|||
*/ |
|||
export function getSeckillList(time, data) { |
|||
return request.get("/seckill/list/" + time, data, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 秒杀产品详情 |
|||
*/ |
|||
export function getSeckillDetail(id) { |
|||
return request.get("/seckill/detail/" + id, {}, { login: true }); |
|||
} |
|||
|
|||
/** |
|||
* 砍价列表 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainList(data) { |
|||
return request.get("/bargain/list", data, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 砍价产品详情 |
|||
*/ |
|||
export function getBargainDetail(id) { |
|||
return request.get("/bargain/detail/" + id); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 观看/分享/参与次数 |
|||
*/ |
|||
export function getBargainShare(data) { |
|||
return request.post("/bargain/share", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价开启 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainStart(data) { |
|||
return request.post("/bargain/start", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 帮助好友砍价 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainHelp(data) { |
|||
return request.post("/bargain/help", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 砍掉金额 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainHelpPrice(data) { |
|||
return request.post("/bargain/help/price", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 砍价帮总人数、剩余金额、进度条、已经砍掉的价格 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainHelpCount(data) { |
|||
return request.post("/bargain/help/count", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 开启砍价用户信息 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainStartUser(data) { |
|||
return request.post("/bargain/start/user", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价 砍价帮 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainHelpList(data) { |
|||
return request.post("/bargain/help/list", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价海报 |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainPoster(data) { |
|||
return request.post("/bargain/poster", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价列表(已参与) |
|||
* @param {*} data |
|||
*/ |
|||
export function getBargainUserList(data) { |
|||
return request.get("/bargain/user/list", data); |
|||
} |
|||
|
|||
/** |
|||
* 砍价取消 |
|||
*/ |
|||
export function getBargainUserCancel(data) { |
|||
return request.post("/bargain/user/cancel", data); |
|||
} |
@ -0,0 +1,73 @@ |
|||
import request from "@/utils/request"; |
|||
|
|||
/** |
|||
* 统计数据 |
|||
*/ |
|||
export function getStatisticsInfo() { |
|||
return request.get("/admin/order/statistics", {}, { login: true }); |
|||
} |
|||
/** |
|||
* 订单月统计 |
|||
*/ |
|||
export function getStatisticsMonth(where) { |
|||
return request.get("/admin/order/data", where, { login: true }); |
|||
} |
|||
/** |
|||
* 订单月统计 |
|||
*/ |
|||
export function getAdminOrderList(where) { |
|||
return request.get("/admin/order/list", where, { login: true }); |
|||
} |
|||
/** |
|||
* 订单改价 |
|||
*/ |
|||
export function setAdminOrderPrice(data) { |
|||
return request.post("/admin/order/price", data, { login: true }); |
|||
} |
|||
/** |
|||
* 订单备注 |
|||
*/ |
|||
export function setAdminOrderRemark(data) { |
|||
return request.post("/admin/order/remark", data, { login: true }); |
|||
} |
|||
/** |
|||
* 订单详情 |
|||
*/ |
|||
export function getAdminOrderDetail(orderId) { |
|||
return request.get("/admin/order/detail/" + orderId, {}, { login: true }); |
|||
} |
|||
/** |
|||
* 订单发货信息获取 |
|||
*/ |
|||
export function getAdminOrderDelivery(orderId) { |
|||
return request.get( |
|||
"/admin/order/detail/" + orderId, |
|||
{}, |
|||
{ login: true } |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* 订单发货保存 |
|||
*/ |
|||
export function setAdminOrderDelivery(data) { |
|||
return request.post("/admin/order/delivery/keep", data, { login: true }); |
|||
} |
|||
/** |
|||
* 订单统计图 |
|||
*/ |
|||
export function getStatisticsTime(data) { |
|||
return request.get("/admin/order/time", data, { login: true }); |
|||
} |
|||
/** |
|||
* 线下付款订单确认付款 |
|||
*/ |
|||
export function setOfflinePay(data) { |
|||
return request.post("/admin/order/offline", data, { login: true }); |
|||
} |
|||
/** |
|||
* 订单确认退款 |
|||
*/ |
|||
export function setOrderRefund(data) { |
|||
return request.post("/admin/order/refund", data, { login: true }); |
|||
} |
@ -0,0 +1,17 @@ |
|||
|
|||
|
|||
import request from "@/utils/request"; |
|||
|
|||
/** |
|||
* 查询所有直播间 |
|||
*/ |
|||
export function yxWechatLive(data) { |
|||
return request.get("/yxWechatLive", data, { login: true }); |
|||
} |
|||
|
|||
/** |
|||
* 获取直播回放 |
|||
*/ |
|||
export function getLiveReplay(id, data) { |
|||
return request.get("/yxWechatLive/getLiveReplay/" + id, data, { login: false }); |
|||
} |
@ -0,0 +1,150 @@ |
|||
/* |
|||
* 订单确认 |
|||
* */ |
|||
import request from "@/utils/request"; |
|||
|
|||
/** |
|||
* 通过购物车 id 获取订单信息 |
|||
* @param cartId |
|||
* @returns {*} |
|||
*/ |
|||
export function postOrderConfirm(cartId) { |
|||
return request.post("/order/confirm", { |
|||
cartId |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 计算订单金额 |
|||
* @param key |
|||
* @param data |
|||
* @returns {*} |
|||
*/ |
|||
export function postOrderComputed(key, data) { |
|||
return request.post("/order/computed/" + key, data); |
|||
} |
|||
|
|||
/** |
|||
* 获取指定金额可用优惠券 |
|||
* @param price |
|||
* @returns {*} |
|||
*/ |
|||
export function getOrderCoupon(cartId) { |
|||
return request.get("/coupons/order/" + cartId); |
|||
} |
|||
|
|||
/** |
|||
* 生成订单 |
|||
* @param key |
|||
* @param data |
|||
* @returns {*} |
|||
*/ |
|||
export function createOrder(key, data) { |
|||
return request.post("/order/create/" + key, data || {}); |
|||
} |
|||
|
|||
/** |
|||
* 订单统计数据 |
|||
* @returns {*} |
|||
*/ |
|||
export function getOrderData() { |
|||
return request.get("/order/data"); |
|||
} |
|||
|
|||
/** |
|||
* 订单列表 |
|||
* @returns {*} |
|||
*/ |
|||
export function getOrderList(data) { |
|||
return request.get("/order/list", data); |
|||
} |
|||
|
|||
/** |
|||
* 取消订单 |
|||
* @returns {*} |
|||
*/ |
|||
export function cancelOrder(id) { |
|||
return request.post("/order/cancel", { |
|||
id |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 订单详情 |
|||
* @returns {*} |
|||
*/ |
|||
export function orderDetail(id) { |
|||
return request.get("/order/detail/" + id); |
|||
} |
|||
|
|||
/** |
|||
* 退款理由 |
|||
* @returns {*} |
|||
*/ |
|||
export function getRefundReason() { |
|||
return request.get("/order/refund/reason"); |
|||
} |
|||
|
|||
/** |
|||
* 提交退款 |
|||
* @returns {*} |
|||
*/ |
|||
export function postOrderRefund(data) { |
|||
return request.post("/order/refund/verify", data); |
|||
} |
|||
|
|||
/** |
|||
* 确认收货 |
|||
* @returns {*} |
|||
*/ |
|||
export function takeOrder(uni) { |
|||
return request.post("/order/take", { |
|||
uni |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 删除订单 |
|||
* @returns {*} |
|||
*/ |
|||
export function delOrder(uni) { |
|||
return request.post("/order/del", { |
|||
uni |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 订单查询物流信息 |
|||
* @returns {*} |
|||
*/ |
|||
export function express(params) { |
|||
return request.post("order/express", params); |
|||
} |
|||
|
|||
/** |
|||
* 订单查询物流信息 |
|||
* @returns {*} |
|||
*/ |
|||
export function payOrder(uni, paytype, from) { |
|||
return request.post("order/pay", { |
|||
uni, |
|||
paytype, |
|||
from |
|||
}); |
|||
} |
|||
/** |
|||
* 订单核销 |
|||
* @returns {*} |
|||
*/ |
|||
|
|||
export function orderVerific(verifyCode, isConfirm) { |
|||
return request.post("order/order_verific", { verifyCode, isConfirm }); |
|||
} |
|||
/** |
|||
* 获取订阅消息ID |
|||
* @param price |
|||
* @returns {*} |
|||
*/ |
|||
export function getSubscribeTemplate() { |
|||
return request.get("/order/getSubscribeTemplate"); |
|||
} |
@ -0,0 +1,108 @@ |
|||
import request from "@/utils/request"; |
|||
|
|||
/** |
|||
* 首页 |
|||
* @returns {*} |
|||
*/ |
|||
export function getHomeData() { |
|||
return request.get("index", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 首页 |
|||
* @returns {*} |
|||
*/ |
|||
export function getCanvas() { |
|||
return request.get("/getCanvas?terminal=3", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 文章 轮播列表 |
|||
* @returns {*} |
|||
*/ |
|||
export function getArticleBanner() { |
|||
return request.get("/article/banner/list", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 文章分类列表 |
|||
* @returns {*} |
|||
*/ |
|||
export function getArticleCategory() { |
|||
return request.get("/article/category/list", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 文章 热门列表 |
|||
* @returns {*} |
|||
*/ |
|||
export function getArticleHotList() { |
|||
return request.get("/article/hot/list", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 文章列表 |
|||
* @returns {*} |
|||
*/ |
|||
export function getArticleList(q) { |
|||
return request.get("/article/list/", q, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 分享 |
|||
* @returns {*} |
|||
*/ |
|||
export function getShare() { |
|||
return request.get("/share", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 文章详情 |
|||
* @returns {*} |
|||
*/ |
|||
export function getArticleDetails(id) { |
|||
return request.get("/article/details/" + id, {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 获取微信sdk配置 |
|||
* @returns {*} |
|||
*/ |
|||
export function getWechatConfig() { |
|||
return request.get( |
|||
"/wechat/config", |
|||
{ url: location.href }, |
|||
{ login: false } |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* 获取微信sdk配置 |
|||
* @returns {*} |
|||
*/ |
|||
export function wechatAuth(code, spread, login_type) { |
|||
return request.get( |
|||
"/wechat/auth", |
|||
{ code, spread, login_type }, |
|||
{ login: false } |
|||
); |
|||
} |
|||
/** |
|||
* 获取快递公司 |
|||
* @returns {*} |
|||
*/ |
|||
export function getLogistics() { |
|||
return request.get("/logistics", {}, { login: false }); |
|||
} |
|||
|
|||
/** |
|||
* 获取图片base64 |
|||
* @retins {*} |
|||
* */ |
|||
export function imageBase64(image, code) { |
|||
return request.post( |
|||
"/image_base64", |
|||
{ image: image, code: code }, |
|||
{ login: false } |
|||
); |
|||
} |
@ -0,0 +1,183 @@ |
|||
import request from "@/utils/request"; |
|||
|
|||
/* |
|||
* 商品分类 |
|||
* */ |
|||
export function getCategory() { |
|||
return request.get("/category", {}, { |
|||
login: false |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 商品详情 |
|||
* */ |
|||
export function getProductDetail(id, data) { |
|||
return request.get("/product/detail/" + id, data, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 商品分销二维码 |
|||
* */ |
|||
export function getProductCode(id) { |
|||
return request.get("/product/code/" + id, {}, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 商品列表 |
|||
* */ |
|||
export function getProducts(q) { |
|||
return request.get("/products", q, { |
|||
login: false |
|||
}); |
|||
} |
|||
/* |
|||
* 积分商品列表 |
|||
* */ |
|||
export function getProductsIntegral(q) { |
|||
return request.get("/products/integral", q, { |
|||
login: false |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 购物车数量 |
|||
* */ |
|||
export function getCartNum() { |
|||
return request.get("/cart/count"); |
|||
} |
|||
|
|||
/* |
|||
* 添加收藏 |
|||
* */ |
|||
export function toCollect(id, category) { |
|||
return request.get("/collect/add/" + id + "/" + category); |
|||
} |
|||
|
|||
/* |
|||
* 为你推荐 |
|||
* */ |
|||
export function getHostProducts(page, limit) { |
|||
return request.get( |
|||
"/product/hot", { |
|||
page: page, |
|||
limit: limit |
|||
}, { |
|||
login: false |
|||
} |
|||
); |
|||
} |
|||
|
|||
/* |
|||
* 精品、热门、首发列表 |
|||
* */ |
|||
export function getGroomList(type) { |
|||
return request.get("/groom/list/" + type, {}, { |
|||
login: true |
|||
}); |
|||
} |
|||
/* |
|||
* 获取商品海报 |
|||
* */ |
|||
export function getProductPoster(id, data) { |
|||
return request.get("/product/poster/" + id, data, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 购物车 添加 |
|||
* */ |
|||
export function postCartAdd(data) { |
|||
return request.post("/cart/add", data); |
|||
} |
|||
|
|||
/* |
|||
* 购物车列表 |
|||
* */ |
|||
export function getCartList() { |
|||
return request.get("/cart/list"); |
|||
} |
|||
|
|||
/* |
|||
* 购物车 删除 |
|||
* */ |
|||
export function postCartDel(ids) { |
|||
return request.post("/cart/del", { |
|||
ids |
|||
}); |
|||
} |
|||
|
|||
/* |
|||
* 购物车 获取数量 |
|||
* */ |
|||
export function getCartCount(data) { |
|||
return request.get("/cart/count", data); |
|||
} |
|||
|
|||
/* |
|||
* 购物车 修改商品数量 |
|||
* */ |
|||
export function changeCartNum(id, number) { |
|||
return request.post("/cart/num", { |
|||
id, |
|||
number |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 搜索推荐关键字 |
|||
*/ |
|||
export function getSearchKeyword() { |
|||
return request.get("/search/keyword", {}, { |
|||
login: false |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 产品评论列表 |
|||
*/ |
|||
export function getReplyList(id, q) { |
|||
return request.get("/reply/list/" + id, q, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 产品评价数量和好评度 |
|||
*/ |
|||
export function getReplyConfig(id) { |
|||
return request.get("/reply/config/" + id, {}, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 评价页面获取单个产品详情 |
|||
*/ |
|||
export function postOrderProduct(unique) { |
|||
return request.post("/order/product", { |
|||
unique |
|||
}, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 提交评价页面; |
|||
*/ |
|||
export function postOrderComment(data) { |
|||
return request.post("/order/comment", data, { |
|||
login: true |
|||
}); |
|||
} |
|||
|
|||
export function storeListApi(data) { |
|||
return request.get("store_list", data, { |
|||
login: false |
|||
}); |
|||
} |
@ -0,0 +1,444 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
/** |
|||
* 省市区 |
|||
*/ |
|||
export function getCity(data) { |
|||
return request.get('/city_list', data, { |
|||
// return request.get("/citys", data, {
|
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
export function district(data) { |
|||
// return request.get("/city_list", data, {
|
|||
return request.get('/citys', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户登录 |
|||
* @param data object 用户账号密码 |
|||
*/ |
|||
export function login(data) { |
|||
return request.post('/login', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户手机号登录 |
|||
* @param data object 用户手机号 也只能 |
|||
*/ |
|||
export function loginMobile(data) { |
|||
return request.post('/login/mobile', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户发送验证码 |
|||
* @param data object 用户手机号 |
|||
*/ |
|||
export function registerVerify(data) { |
|||
return request.post('/register/verify', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户手机号注册 |
|||
* @param data object 用户手机号 验证码 密码 |
|||
*/ |
|||
export function register(data) { |
|||
return request.post('/register', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户手机号修改密码 |
|||
* @param data object 用户手机号 验证码 密码 |
|||
*/ |
|||
export function registerReset(data) { |
|||
return request.post('/register/reset', data, { |
|||
login: true, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 领取优惠券列表 |
|||
* */ |
|||
export function getCoupon(q) { |
|||
return request.get('/coupons', q, { |
|||
login: true, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 点击领取优惠券 |
|||
* */ |
|||
export function getCouponReceive(id) { |
|||
return request.post( |
|||
'/coupon/receive', |
|||
{ |
|||
couponId: id, |
|||
}, |
|||
{ |
|||
login: true, |
|||
} |
|||
) |
|||
} |
|||
|
|||
/* |
|||
* 批量领取优惠券 |
|||
* */ |
|||
export function couponReceiveBatch(couponId) { |
|||
return request.post('/coupon/receive/batch', { |
|||
couponId, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 我的优惠券 |
|||
* */ |
|||
export function getCouponsUser(type) { |
|||
return request.get('/coupons/user/' + type) |
|||
} |
|||
|
|||
/* |
|||
* 个人中心 |
|||
* */ |
|||
export function getUser() { |
|||
return request.get('/user') |
|||
} |
|||
|
|||
/* |
|||
* 用户信息 |
|||
* */ |
|||
export function getUserInfo() { |
|||
return request.get('/userinfo', { |
|||
login: true, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 小程序登陆 |
|||
* */ |
|||
export function wxappAuth(data) { |
|||
return request.post('/wxapp/auth', data, { |
|||
login: false, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 个人中心(功能列表) |
|||
* */ |
|||
export function getMenuUser() { |
|||
return request.get('/menu/user') |
|||
} |
|||
|
|||
/* |
|||
* 地址列表 |
|||
* */ |
|||
export function getAddressList(data) { |
|||
return request.get('/address/list', data || {}) |
|||
} |
|||
|
|||
/* |
|||
* 删除地址 |
|||
* */ |
|||
export function getAddressRemove(id) { |
|||
return request.post('/address/del', { |
|||
id: id, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 设置默认地址 |
|||
* */ |
|||
export function getAddressDefaultSet(id) { |
|||
return request.post('/address/default/set', { |
|||
id: id, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 获取默认地址 |
|||
* */ |
|||
export function getAddressDefault() { |
|||
return request.get('/address/default') |
|||
} |
|||
|
|||
/* |
|||
* 获取单个地址 |
|||
* */ |
|||
export function getAddress(id) { |
|||
return request.get('/address/detail/' + id) |
|||
} |
|||
|
|||
/* |
|||
* 修改 添加地址 |
|||
* */ |
|||
export function postAddress(data) { |
|||
return request.post('/address/edit', data) |
|||
} |
|||
|
|||
/* |
|||
* 获取收藏产品 |
|||
* */ |
|||
export function getCollectUser(page, limit, type) { |
|||
return request.get('/collect/user', { |
|||
page: page, |
|||
limit: limit, |
|||
type, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 删除收藏产品 |
|||
* */ |
|||
export function getCollectDel(id, category) { |
|||
return request.post('/collect/del', { |
|||
id: id, |
|||
category: category, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 批量收藏产品 |
|||
* */ |
|||
export function postCollectAll(data) { |
|||
return request.post('/collect/all', data) |
|||
} |
|||
|
|||
/* |
|||
* 添加收藏产品 |
|||
* */ |
|||
export function getCollectAdd(id, category) { |
|||
return request.post('collect/add', { |
|||
id: id, |
|||
category: category, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 签到配置 |
|||
* */ |
|||
export function getSignConfig() { |
|||
return request.get('/sign/config') |
|||
} |
|||
|
|||
/* |
|||
* 签到里的签到列表 |
|||
* */ |
|||
export function getSignList(page, limit) { |
|||
return request.get('/sign/list', { |
|||
page: page, |
|||
limit: limit, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 签到列表 |
|||
* */ |
|||
export function getSignMonth(page, limit) { |
|||
return request.get('/sign/month', { |
|||
page: page, |
|||
limit: limit, |
|||
}) |
|||
} |
|||
|
|||
/* |
|||
* 签到用户信息 |
|||
* */ |
|||
export function postSignUser(sign) { |
|||
return request.post('/sign/user', sign) |
|||
} |
|||
|
|||
/* |
|||
* 签到 |
|||
* */ |
|||
export function postSignIntegral(sign) { |
|||
return request.post('/sign/integral', sign) |
|||
} |
|||
|
|||
/* |
|||
* 推广数据 |
|||
* */ |
|||
export function getSpreadInfo() { |
|||
return request.get('/commission') |
|||
} |
|||
|
|||
/* |
|||
* 推广人列表 |
|||
* */ |
|||
export function getSpreadUser(screen) { |
|||
return request.post('/spread/people', screen) |
|||
} |
|||
|
|||
/* |
|||
* 推广人订单 |
|||
* */ |
|||
export function getSpreadOrder(where) { |
|||
return request.post('/spread/order', where) |
|||
} |
|||
|
|||
/* |
|||
* 资金明细(types|0=全部,1=消费,2=充值,3=返佣,4=提现) |
|||
* */ |
|||
export function getCommissionInfo(q, types) { |
|||
return request.get('/spread/commission/' + types, q) |
|||
} |
|||
|
|||
/* |
|||
* 积分记录 |
|||
* */ |
|||
export function getIntegralList(q) { |
|||
return request.get('/integral/list', q) |
|||
} |
|||
|
|||
/* |
|||
* 提现银行 |
|||
* */ |
|||
export function getBank() { |
|||
return request.get('/extract/bank') |
|||
} |
|||
|
|||
/* |
|||
* 提现申请 |
|||
* */ |
|||
export function postCashInfo(cash) { |
|||
return request.post('/extract/cash', cash) |
|||
} |
|||
|
|||
/* |
|||
* 会员中心 |
|||
* */ |
|||
export function getVipInfo() { |
|||
return request.get('/user/level/grade') |
|||
} |
|||
|
|||
/* |
|||
* 会员等级任务 |
|||
* */ |
|||
export function getVipTask(id) { |
|||
return request.get('/user/level/task/' + id) |
|||
} |
|||
|
|||
/* |
|||
* 资金统计 |
|||
* */ |
|||
export function getBalance() { |
|||
return request.get('/user/balance') |
|||
} |
|||
|
|||
/* |
|||
* 活动状态 |
|||
* */ |
|||
export function getActivityStatus() { |
|||
return request.get( |
|||
'/user/activity', |
|||
{}, |
|||
{ |
|||
login: false, |
|||
} |
|||
) |
|||
} |
|||
|
|||
/* |
|||
* 活动状态 |
|||
* */ |
|||
export function getSpreadImg(data) { |
|||
return request.get('/spread/banner', data) |
|||
} |
|||
|
|||
/* |
|||
* 用户修改信息 |
|||
* */ |
|||
export function postUserEdit(data) { |
|||
return request.post('/user/edit', data) |
|||
} |
|||
|
|||
/* |
|||
* 用户修改信息 |
|||
* */ |
|||
export function getChatRecord(to_uid, data) { |
|||
return request.get('user/service/record/' + to_uid, data) |
|||
} |
|||
|
|||
/* |
|||
* 用户修改信息 |
|||
* */ |
|||
export function serviceList() { |
|||
return request.get('user/service/list') |
|||
} |
|||
|
|||
/* |
|||
* 公众号充值 |
|||
* */ |
|||
export function rechargeWechat(data) { |
|||
return request.post('/recharge/wechat', data) |
|||
} |
|||
|
|||
/* |
|||
* 退出登录 |
|||
* */ |
|||
export function getLogout() { |
|||
return request.post('/auth/logout') |
|||
} |
|||
|
|||
/* |
|||
* 小程序绑定手机号 |
|||
* */ |
|||
export function bindingPhone(data) { |
|||
return request.post('/binding', data) |
|||
} |
|||
|
|||
/* |
|||
* 绑定手机号 |
|||
* */ |
|||
export function wxappBindingPhone(data) { |
|||
return request.post('wxapp/binding', data) |
|||
} |
|||
|
|||
/** |
|||
* 小程序上传用户头像 |
|||
*/ |
|||
export function wxappGetUserInfo (data) { |
|||
// return request.post('/wxapp/loginAuth', data)
|
|||
return request.get('/wechat/auth', data) |
|||
} |
|||
|
|||
/* |
|||
* h5切换公众号登陆 |
|||
* */ |
|||
export function switchH5Login() { |
|||
return request.post('switch_h5', { |
|||
from: 'wechat', |
|||
}) |
|||
} |
|||
/* |
|||
* 获取推广人排行 |
|||
* */ |
|||
export function getRankList(q) { |
|||
return request.get('rank', q) |
|||
} |
|||
/* |
|||
* 获取佣金排名 |
|||
* */ |
|||
export function getBrokerageRank(q) { |
|||
return request.get('brokerage_rank', q) |
|||
} |
|||
|
|||
/** |
|||
* 检测会员等级 |
|||
*/ |
|||
export function setDetection() { |
|||
return request.get('user/level/detection') |
|||
} |
|||
|
|||
export function getRechargeApi() { |
|||
return request.get('recharge/index') |
|||
} |
@ -0,0 +1,2 @@ |
|||
@charset "UTF-8";.font-color-red{color:#eb3729 !important}.bg-color-red{background-color:#eb3729 !important}.icon-color{color:#eb3729}.cart-color{color:#eb3729 !important;border:1px solid #eb3729 !important}.padding20{padding:20rpx}.pad20{padding:0 20rpx}.padding30{padding:30rpx}.pad30{padding:0 30rpx}.acea-row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.acea-row.row-middle{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.acea-row.row-top{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.acea-row.row-bottom{-webkit-box-align:end;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.acea-row.row-center{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.acea-row.row-right{-webkit-box-pack:end;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.acea-row.row-left{-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start}.acea-row.row-between{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.acea-row.row-around{-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.acea-row.row-column-around{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.acea-row.row-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.acea-row.row-column-between{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.acea-row.row-center-wrapper{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.acea-row.row-between-wrapper{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.slider-banner{position:relative;width:100%;overflow:hidden}.slider-banner .swiper-container{height:100%}.slider-banner image{display:block;width:100%;height:100%}.start{width:122rpx;height:30rpx;background-image:url("https://wx.yixiang.co/static/images/start.png");background-repeat:no-repeat;-webkit-background-size:122rpx auto;background-size:122rpx auto}.start.star5{background-position:0 3rpx}.start.star4{background-position:0 -30rpx}.start.star3{background-position:0 -70rpx}.start.star2{background-position:0 -105rpx}.start.star1{background-position:0 -140rpx}.start.star0{background-position:0 -175rpx}.checkbox-wrapper{position:relative}.checkbox-wrapper input{display:none}.checkbox-wrapper .icon{position:absolute;left:0;top:50%;display:inline-block;width:18px;height:18px;border:1px solid #cccccc;-webkit-border-radius:50%;border-radius:50%;-webkit-transform:translate(0, -50%);-ms-transform:translate(0, -50%);transform:translate(0, -50%)}.checkbox-wrapper input:checked+.icon{background-color:#e93323;border-color:#e93323;background-image:url("https://wx.yixiang.co/static/images/enter.png");-webkit-background-size:21rpx 15rpx;background-size:21rpx 15rpx;background-repeat:no-repeat;background-position:center center}.Loads{height:80rpx;font-size:25rpx;color:#000}.Loads .iconfont{font-size:30rpx;margin-right:10rpx;height:32rpx;line-height:32rpx}@-webkit-keyframes load{from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load{from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.loadingpic{-webkit-animation:load 3s linear 1s infinite;animation:load 3s linear 1s infinite}.loading{-webkit-animation:load linear 1s infinite;animation:load linear 1s infinite} |
|||
/*# sourceMappingURL=./base.css.map */ |
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["base.less"],"names":[],"mappings":"AAAA,iBAIA,gBACE,wBAAA,CAEF,cACE,mCAAA,CAEF,YACE,aAAA,CAEF,YACE,yBACA,mCAAA,CAGF,WACE,aAAA,CAGF,OACE,eAAA,CAGF,WACE,aAAA,CAGF,OACE,eAAA,CAGF,UACE,oBACA,AADA,qBACA,AADA,oBACA,AADA,aACA,uBAAA,mBAAA,cAAA,CAGF,qBACE,yBAAA,2BAAA,sBAAA,kBAAA,CAEF,kBACE,wBAAA,+BAAA,qBAAA,sBAAA,CAEF,qBACE,sBAAA,6BAAA,mBAAA,oBAAA,CAEF,qBACE,wBAAA,+BAAA,qBAAA,sBAAA,CAEF,oBACE,qBAAA,iCAAA,kBAAA,wBAAA,CAEF,mBACE,uBAAA,mCAAA,oBAAA,0BAAA,CAEF,sBACE,yBAAA,sCAAA,sBAAA,6BAAA,CAEF,qBACE,qCAAA,yBAAA,4BAAA,CAEF,4BACE,4BACA,AADA,6BACA,AADA,8BACA,AADA,0BACA,AADA,sBACA,qCAAA,yBAAA,4BAAA,CAEF,qBACE,4BAAA,6BAAA,8BAAA,0BAAA,qBAAA,CAEF,6BACE,4BACA,AADA,6BACA,AADA,8BACA,AADA,0BACA,AADA,sBACA,yBAAA,sCAAA,sBAAA,6BAAA,CAGF,6BACE,yBACA,AADA,2BACA,AADA,sBACA,AADA,mBACA,wBAAA,+BAAA,qBAAA,sBAAA,CAGF,8BACE,yBACA,AADA,2BACA,AADA,sBACA,AADA,mBACA,yBAAA,sCAAA,sBAAA,6BAAA,CAIF,eACE,kBACA,WAEA,eAAA,CAKF,iCACE,WAAA,CAEF,qBACE,cACA,WACA,WAAA,CAEF,OACE,aACA,aACA,sEACA,4BACA,oCAAA,2BAAA,CAEF,aACE,0BAAA,CAEF,aACE,4BAAA,CAEF,aACE,4BAAA,CAEF,aACE,6BAAA,CAEF,aACE,6BAAA,CAEF,aACE,6BAAA,CAGF,kBACE,iBAAA,CAEF,wBACE,YAAA,CAEF,wBACE,kBACA,OACA,QACA,qBACA,WACA,YACA,yBACA,0BACA,AADA,kBACA,qCAAW,AAAX,iCAAW,AAAX,4BAAW,CAEb,sCACE,yBACA,qBACA,sEACA,oCACA,AADA,4BACA,4BACA,iCAAA,CAEF,OACE,aACA,gBACA,UAAA,CAEF,iBACE,gBACA,mBACA,aACA,iBAAA,CAGF,wBACE,KACE,+BAAW,AAAX,sBAAW,CAEb,GACE,iCAAW,AAAX,wBAAW,CAAA,CAGf,AARA,gBACE,KACE,+BAAW,AAAX,sBAAW,CAEb,GACE,iCAAW,AAAX,wBAAW,CAAA,CAGf,YACE,6CAAA,oCAAA,CAEF,SACE,0CAAA,iCAAA,CAAA","file":"to.css","sourcesContent":[null]} |
@ -0,0 +1,180 @@ |
|||
@charset "UTF-8"; |
|||
/** |
|||
*相关初始化 |
|||
*/ |
|||
.font-color-red { |
|||
color: #eb3729 !important; |
|||
} |
|||
.bg-color-red { |
|||
background-color: #eb3729 !important; |
|||
} |
|||
.icon-color { |
|||
color: #eb3729; |
|||
} |
|||
.cart-color { |
|||
color: #eb3729 !important; |
|||
border: 1px solid #eb3729 !important; |
|||
} |
|||
/* padding20 */ |
|||
.padding20 { |
|||
padding: 0.2*100rpx; |
|||
} |
|||
/* pad20 */ |
|||
.pad20 { |
|||
padding: 0 0.2*100rpx; |
|||
} |
|||
/* padding30 */ |
|||
.padding30 { |
|||
padding: 0.3*100rpx; |
|||
} |
|||
/*pad30 */ |
|||
.pad30 { |
|||
padding: 0 0.3*100rpx; |
|||
} |
|||
/* layout */ |
|||
.acea-row { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
/* 辅助类 */ |
|||
} |
|||
.acea-row.row-middle { |
|||
align-items: center; |
|||
} |
|||
.acea-row.row-top { |
|||
align-items: flex-start; |
|||
} |
|||
.acea-row.row-bottom { |
|||
align-items: flex-end; |
|||
} |
|||
.acea-row.row-center { |
|||
justify-content: center; |
|||
} |
|||
.acea-row.row-right { |
|||
justify-content: flex-end; |
|||
} |
|||
.acea-row.row-left { |
|||
justify-content: flex-start; |
|||
} |
|||
.acea-row.row-between { |
|||
justify-content: space-between; |
|||
} |
|||
.acea-row.row-around { |
|||
justify-content: space-around; |
|||
} |
|||
.acea-row.row-column-around { |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
} |
|||
.acea-row.row-column { |
|||
flex-direction: column; |
|||
} |
|||
.acea-row.row-column-between { |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
} |
|||
/* 上下左右垂直居中 */ |
|||
.acea-row.row-center-wrapper { |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
/* 上下两边居中对齐 */ |
|||
.acea-row.row-between-wrapper { |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
/* 轮播图 */ |
|||
.slider-banner { |
|||
position: relative; |
|||
width: 100%; |
|||
/* height:750rpx; */ |
|||
overflow: hidden; |
|||
} |
|||
.slider-banner{ |
|||
|
|||
} |
|||
.slider-banner .swiper-container { |
|||
height: 100%; |
|||
} |
|||
.slider-banner image{ |
|||
display: block; |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
.start { |
|||
width: 1.22*100rpx; |
|||
height: 0.3*100rpx; |
|||
background-image: url("https://wx.yixiang.co/static/images/start.png"); |
|||
background-repeat: no-repeat; |
|||
background-size: 1.22*100rpx auto; |
|||
} |
|||
.start.star5 { |
|||
background-position: 0 0.03*100rpx; |
|||
} |
|||
.start.star4 { |
|||
background-position: 0 -0.3*100rpx; |
|||
} |
|||
.start.star3 { |
|||
background-position: 0 -0.7*100rpx; |
|||
} |
|||
.start.star2 { |
|||
background-position: 0 -1.05*100rpx; |
|||
} |
|||
.start.star1 { |
|||
background-position: 0 -1.4*100rpx; |
|||
} |
|||
.start.star0 { |
|||
background-position: 0 -1.75*100rpx; |
|||
} |
|||
/* 单选框和多选框 */ |
|||
.checkbox-wrapper { |
|||
position: relative; |
|||
} |
|||
.checkbox-wrapper input { |
|||
display: none; |
|||
} |
|||
.checkbox-wrapper .icon { |
|||
position: absolute; |
|||
left: 0; |
|||
top: 50%; |
|||
display: inline-block; |
|||
width: 18px; |
|||
height: 18px; |
|||
border: 1px solid #cccccc; |
|||
border-radius: 50%; |
|||
transform: translate(0, -50%); |
|||
} |
|||
.checkbox-wrapper input:checked + .icon { |
|||
background-color: #e93323; |
|||
border-color: #e93323; |
|||
background-image: url("https://wx.yixiang.co/static/images/enter.png"); |
|||
background-size: 0.21*100rpx 0.15*100rpx; |
|||
background-repeat: no-repeat; |
|||
background-position: center center; |
|||
} |
|||
.Loads { |
|||
height: 0.8*100rpx; |
|||
font-size: 0.25*100rpx; |
|||
color: #000; |
|||
} |
|||
.Loads .iconfont { |
|||
font-size: 0.3*100rpx; |
|||
margin-right: 0.1*100rpx; |
|||
height: 0.32*100rpx; |
|||
line-height: 0.32*100rpx; |
|||
} |
|||
/*加载动画*/ |
|||
@keyframes load { |
|||
from { |
|||
transform: rotate(0deg); |
|||
} |
|||
to { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
.loadingpic { |
|||
animation: load 3s linear 1s infinite; |
|||
} |
|||
.loading { |
|||
animation: load linear 1s infinite; |
|||
} |
@ -0,0 +1,2 @@ |
|||
input{line-height:normal;-webkit-box-sizing:border-box;box-sizing:border-box}@font-face{font-family:'GuildfordProBook 5';src:url('https://wx.yixiang.co/static/iconfont/GuildfordProBook5.otf')}[v-cloak]{display:none}.iconfont{font-size:36rpx}@media (-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5){.border-1px::after{-webkit-transform:scaleY(.7);-ms-transform:scaleY(.7);transform:scaleY(.7)}.border-1px::before{-webkit-transform:scaleY(.7);-ms-transform:scaleY(.7);transform:scaleY(.7)}}@media (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){.border-1px::after{-webkit-transform:scaleY(.5);-ms-transform:scaleY(.5);transform:scaleY(.5)}.border-1px::before{-webkit-transform:scaleY(.5);-ms-transform:scaleY(.5);transform:scaleY(.5)}}@media (-webkit-min-device-pixel-ratio:3),(min-device-pixel-ratio:3){.border-1px::after{-webkit-transform:scaleY(.33);-ms-transform:scaleY(.33);transform:scaleY(.33)}.border-1px::before{-webkit-transform:scaleY(.33);-ms-transform:scaleY(.33);transform:scaleY(.33)}}.line1{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;width:100%}.line2{word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:55;background-color:rgba(0,0,0,0.5)} |
|||
/*# sourceMappingURL=./reset.css.map */ |
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["reset.less"],"names":[],"mappings":"AAAA,MAAM,mBAAqB,8BAAA,qBAAA,CAC3B,WACE,iCACA,sEAAS,CAEX,UACE,YAAA,CAEF,UACE,eAAA,CAGF,yEACE,mBACE,6BAAW,AAAX,yBAAW,AAAX,oBAAW,CAEb,oBACE,6BAAW,AAAX,yBAAW,AAAX,oBAAW,CAAA,CAGf,qEACE,mBACE,6BAAW,AAAX,yBAAW,AAAX,oBAAW,CAEb,oBACE,6BAAW,AAAX,yBAAW,AAAX,oBAAW,CAAA,CAGf,qEACE,mBACE,8BAAW,AAAX,0BAAW,AAAX,qBAAW,CAEb,oBACE,8BAAW,AAAX,0BAAW,AAAX,qBAAW,CAAA,CAGf,OAAO,gBAAgB,0BAAuB,AAAvB,uBAAuB,mBAAmB,UAAA,CACjE,OAAO,qBAAqB,oBAAoB,qBAAqB,4BAA4B,eAAA,CACjG,MAAM,eAAe,MAAM,OAAO,QAAQ,SAAS,WAAW,gCAAA,CAAA","file":"to.css","sourcesContent":[null]} |
@ -0,0 +1,43 @@ |
|||
input{line-height: normal; box-sizing:border-box;} |
|||
@font-face { |
|||
font-family: 'GuildfordProBook 5'; |
|||
src: url('https://wx.yixiang.co/static/iconfont/GuildfordProBook5.otf'); |
|||
} |
|||
[v-cloak] { |
|||
display: none; |
|||
} |
|||
.iconfont{ |
|||
font-size: .36*100rpx; |
|||
} |
|||
/* 一像素边框 */ |
|||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) { |
|||
.border-1px::after { |
|||
transform: scaleY(0.7); |
|||
} |
|||
.border-1px::before { |
|||
transform: scaleY(0.7); |
|||
} |
|||
} |
|||
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) { |
|||
.border-1px::after { |
|||
transform: scaleY(0.5); |
|||
} |
|||
.border-1px::before { |
|||
transform: scaleY(0.5); |
|||
} |
|||
} |
|||
@media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) { |
|||
.border-1px::after { |
|||
transform: scaleY(0.33); |
|||
} |
|||
.border-1px::before { |
|||
transform: scaleY(0.33); |
|||
} |
|||
} |
|||
.line1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 100%;} |
|||
.line2{word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;} |
|||
.mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:55;background-color:rgba(0,0,0,0.5);} |
|||
|
|||
|
|||
|
|||
|
9377
assets/css/style.less
File diff suppressed because it is too large
View File
661
assets/iconfont/iconfont.css
File diff suppressed because it is too large
View File
@ -0,0 +1,77 @@ |
|||
<template> |
|||
<view> |
|||
<view class="address-window" :class="value === true ? 'on' : ''"> |
|||
<view class="title"> |
|||
选择地址 |
|||
<text class="iconfont icon-guanbi" @click="closeAddress"></text> |
|||
</view> |
|||
<view class="list" v-if="addressList.length"> |
|||
<view |
|||
class="item acea-row row-between-wrapper" |
|||
:class="item.id === checked ? 'font-color-red' : ''" |
|||
v-for="(item, addressIndex) in addressList" |
|||
@click="tapAddress(addressIndex)" |
|||
:key="addressIndex" |
|||
> |
|||
<text class="iconfont icon-ditu" :class="item.id === checked ? 'font-color-red' : ''"></text> |
|||
<view class="addressTxt"> |
|||
<view class="name" :class="item.id === checked ? 'font-color-red' : ''"> |
|||
{{ item.realName }} |
|||
<text class="phone">{{ item.phone }}</text> |
|||
</view> |
|||
<view class="line1"> |
|||
{{ item.province }}{{ item.city }}{{ item.district |
|||
}}{{ item.detail }} |
|||
</view> |
|||
</view> |
|||
<text class="iconfont icon-complete" :class="item.id === checked ? 'font-color-red' : ''"></text> |
|||
</view> |
|||
</view> |
|||
<view class="pictrue" v-if="addressList.length < 1"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/noAddress.png`" class="image" /> |
|||
</view> |
|||
<view class="addressBnt bg-color-red" @click="goAddressPages">新加地址</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent :hidden="value === false" @click="closeAddress"></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { getAddressList } from "@/api/user"; |
|||
|
|||
export default { |
|||
name: "AddressWindow", |
|||
props: { |
|||
value: Boolean, |
|||
checked: Number |
|||
}, |
|||
data: function() { |
|||
return { |
|||
addressList: [], |
|||
current: 0, |
|||
cartId: 0, |
|||
pinkId: 0, |
|||
couponId: 0 |
|||
}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
getAddressList: function() { |
|||
let that = this; |
|||
getAddressList().then(res => { |
|||
that.addressList = res.data; |
|||
}); |
|||
}, |
|||
closeAddress() { |
|||
this.$emit("input", false); |
|||
}, |
|||
goAddressPages: function() { |
|||
this.$yrouter.push({ path: "/pages/user/address/AddAddress/index" }); |
|||
this.$emit("redirect"); |
|||
}, |
|||
tapAddress: function(index) { |
|||
this.$emit("checked", this.addressList[index]); |
|||
this.$emit("input", false); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,210 @@ |
|||
<template> |
|||
<view class="adv-box mx20 mb10"> |
|||
<!-- 模板1--> |
|||
<view class="x-f" v-if="detail.style == 1"> |
|||
<image style="width: 710rpx; height: 220rpx" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
</view> |
|||
<!-- 模板2--> |
|||
<view class="type1 x-f" v-if="detail.style == 2"> |
|||
<image class="type1-img" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type1-img" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<!-- 模板3--> |
|||
<view class="type2 x-bc" v-if="detail.style == 3"> |
|||
<image class="type2-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<view class="y-f type2-box"> |
|||
<image class="type2-img2" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill" style="border-bottom: 1rpx solid #f6f6f6"></image> |
|||
<image class="type2-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
<!-- 模板4--> |
|||
<view class="type3 x-bc" v-if="detail.style == 4"> |
|||
<view class="type3-box y-f"> |
|||
<image class="type3-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type3-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<image class="type3-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
<!-- 模板5--> |
|||
<view class="type4 y-f" v-if="detail.style == 5"> |
|||
<view class="type4-box x-f"> |
|||
<image class="type4-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type4-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<image class="type4-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
<!-- 模板6--> |
|||
<view class="type5 y-f" v-if="detail.style == 6"> |
|||
<image class="type5-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<view class="type5-box x-bc"> |
|||
<image class="type5-img2" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill" style="border-bottom: 1rpx solid #f6f6f6"></image> |
|||
<image class="type5-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
<!-- 模板7--> |
|||
<view class="type6 y-f" v-if="detail.style == 7"> |
|||
<view class="x-f type6-box1"> |
|||
<image class="type6-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type6-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<view class="x-f type6-box2"> |
|||
<image class="type6-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
<image class="type6-img2" @tap="jump(detail.list[3])" :src="detail.list[3].image" mode="aspectFill"></image> |
|||
<image class="type6-img2" @tap="jump(detail.list[4])" :src="detail.list[4].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: {}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
detail: Object, |
|||
}, |
|||
computed: {}, |
|||
created() {}, |
|||
methods: { |
|||
// 路由跳转 |
|||
jump(item) { |
|||
console.log(item) |
|||
if (item) { |
|||
this.$yrouter.push(path) |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.adv-box { |
|||
background-color: #fff; |
|||
border-radius: 20rpx; |
|||
overflow: hidden; |
|||
.type1 { |
|||
.type1-img { |
|||
flex: 1; |
|||
height: 220rpx; |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type2 { |
|||
.type2-img1 { |
|||
width: (710rpx/2); |
|||
height: 340rpx; |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
|
|||
.type2-box { |
|||
flex: 1; |
|||
height: 340rpx; |
|||
width: (710rpx/2); |
|||
|
|||
.type2-img2 { |
|||
height: (340rpx/2); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type3 { |
|||
.type3-box { |
|||
width: (710rpx/2); |
|||
border-right: 1rpx solid #f6f6f6; |
|||
.type3-img1 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type3-img2 { |
|||
flex: 1; |
|||
height: 340rpx; |
|||
width: (710rpx/2); |
|||
} |
|||
} |
|||
|
|||
.type4 { |
|||
.type4-box { |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
.type4-img1 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type4-img2 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
width: 710rpx; |
|||
} |
|||
} |
|||
|
|||
.type5 { |
|||
.type5-img1 { |
|||
width: 710rpx; |
|||
height: (340rpx/2); |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
} |
|||
|
|||
.type5-box { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
width: 710rpx; |
|||
|
|||
.type5-img2 { |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type6 { |
|||
.type6-box1 { |
|||
.type6-img1 { |
|||
width: (710rpx/2); |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type6-box2 { |
|||
border-top: 1rpx solid #f6f6f6; |
|||
|
|||
.type6-img2 { |
|||
width: (710rpx/3); |
|||
height: (340rpx/2); |
|||
border-right: 1rpx solid #f6f6f6; |
|||
|
|||
&:last-child { |
|||
border-right: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
image { |
|||
// background-color: #ccc; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,289 @@ |
|||
<template> |
|||
<view> |
|||
<text class="uni-input" @tap="open">{{value}}</text> |
|||
<uni-popup ref="popup" type="bottom"> |
|||
<view class="cityselect"> |
|||
<view class="cityselect-header"> |
|||
<view class="cityselect-title"> |
|||
<text>请选择地址</text> |
|||
</view> |
|||
<view class="cityselect-nav"> |
|||
<view class="item" v-if="provinceActive" @tap="changeNav(0)"> |
|||
<text>{{provinceActive.n}}</text> |
|||
</view> |
|||
<view class="item" v-if="cityActive" @tap="changeNav(1)"> |
|||
<text>{{cityActive.n}}</text> |
|||
</view> |
|||
<view class="item" v-if="districtActive" @tap="changeNav(2)"> |
|||
<text>{{districtActive.n}}</text> |
|||
</view> |
|||
<view class="item active" v-else> |
|||
<text>请选择</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="cityselect-content"> |
|||
<swiper class="swiper" disable-touch="true" touchable="false" :current="current"> |
|||
<swiper-item> |
|||
<scroll-view scroll-y class="cityScroll"> |
|||
<view> |
|||
<view |
|||
class="cityselect-item" |
|||
v-for="(item,index) in province" |
|||
:key="index" |
|||
@tap="selectProvince(index)" |
|||
> |
|||
<view class="cityselect-item-box"> |
|||
<text>{{item.n}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</swiper-item> |
|||
<swiper-item> |
|||
<scroll-view scroll-y class="cityScroll"> |
|||
<view> |
|||
<view |
|||
class="cityselect-item" |
|||
v-for="(item,index) in city" |
|||
:key="index" |
|||
@tap="selectCity(index)" |
|||
> |
|||
<view class="cityselect-item-box"> |
|||
<text>{{item.n}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</swiper-item> |
|||
<swiper-item> |
|||
<scroll-view scroll-y class="cityScroll"> |
|||
<view> |
|||
<view |
|||
class="cityselect-item" |
|||
v-for="(item,index) in district" |
|||
:key="index" |
|||
@tap="selectDistrict(index)" |
|||
> |
|||
<view class="cityselect-item-box"> |
|||
<text>{{item.n}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</swiper-item> |
|||
</swiper> |
|||
</view> |
|||
</view> |
|||
</uni-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script type="text/babel"> |
|||
import uniPopup from "./uni-popup/uni-popup.vue"; |
|||
import uniPopupMessage from "./uni-popup/uni-popup-message.vue"; |
|||
import uniPopupDialog from "./uni-popup/uni-popup-dialog.vue"; |
|||
|
|||
export default { |
|||
name: "CitySelect", |
|||
components: { |
|||
uniPopup, |
|||
uniPopupMessage, |
|||
uniPopupDialog |
|||
}, |
|||
props: ["callback", "items", "defaultValue"], |
|||
data() { |
|||
return { |
|||
value: "请选择", |
|||
show: this.value, |
|||
province: [], |
|||
provinceActive: null, |
|||
city: [], |
|||
cityActive: null, |
|||
district: [], |
|||
districtActive: null, |
|||
current: 0 |
|||
}; |
|||
}, |
|||
watch: { |
|||
items(nextItem) { |
|||
this.province = nextItem; |
|||
}, |
|||
defaultValue(next){ |
|||
this.value=next |
|||
} |
|||
}, |
|||
mounted() { |
|||
console.log(this); |
|||
if (this.value) { |
|||
this.value = this.value; |
|||
} |
|||
this.province = this.items; |
|||
}, |
|||
methods: { |
|||
open() { |
|||
this.province = this.items; |
|||
this.provinceActive = null; |
|||
this.cityActive = null; |
|||
this.districtActive = null; |
|||
this.city = []; |
|||
this.district = []; |
|||
this.current = 0; |
|||
this.$refs.popup.open(); |
|||
}, |
|||
changeNav(index) { |
|||
if (index == 0) { |
|||
this.provinceActive = null; |
|||
} |
|||
if (index == 1) { |
|||
this.cityActive = null; |
|||
} |
|||
if (index == 2) { |
|||
this.districtActive = null; |
|||
} |
|||
this.current = index; |
|||
}, |
|||
selectProvince(index) { |
|||
this.provinceActive = this.province[index]; |
|||
this.city = this.province[index].c; |
|||
this.current = 1; |
|||
}, |
|||
selectCity(index) { |
|||
this.cityActive = this.city[index]; |
|||
this.district = this.city[index].c; |
|||
this.current = 2; |
|||
}, |
|||
selectDistrict(index) { |
|||
this.districtActive = this.district[index]; |
|||
this.value = `${this.provinceActive.n} ${this.cityActive.n} ${this.districtActive.n}`; |
|||
// this.callback({ |
|||
// province: { |
|||
// id: this.provinceActive.v, |
|||
// name: this.provinceActive.n |
|||
// }, |
|||
// city: { |
|||
// id: this.cityActive.v, |
|||
// name: this.cityActive.n |
|||
// }, |
|||
// district: { |
|||
// id: this.districtActive.v, |
|||
// name: this.districtActive.n |
|||
// } |
|||
// }); |
|||
this.$emit("callback", { |
|||
province: { |
|||
id: this.provinceActive.v, |
|||
name: this.provinceActive.n |
|||
}, |
|||
city: { |
|||
id: this.cityActive.v, |
|||
name: this.cityActive.n |
|||
}, |
|||
district: { |
|||
id: this.districtActive.v, |
|||
name: this.districtActive.n |
|||
} |
|||
}); |
|||
this.$refs.popup.close(); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="less"> |
|||
.cityselect { |
|||
width: 100%; |
|||
height: 75%; |
|||
background-color: #fff; |
|||
z-index: 1502; |
|||
position: relative; |
|||
padding-bottom: 0; |
|||
padding-bottom: constant(safe-area-inset-bottom); |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
.cityScroll { |
|||
height: 100%; |
|||
} |
|||
.swiper { |
|||
height: 800rpx; |
|||
} |
|||
} |
|||
.cityselect-header { |
|||
width: 100%; |
|||
z-index: 1; |
|||
} |
|||
.cityselect-title { |
|||
width: 100%; |
|||
font-size: 30rpx; |
|||
text-align: center; |
|||
height: 95rpx; |
|||
line-height: 95rpx; |
|||
position: relative; |
|||
&:cityselect-title:after { |
|||
height: 1px; |
|||
position: absolute; |
|||
z-index: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
content: ""; |
|||
width: 100%; |
|||
background-image: linear-gradient(0deg, #ececec 50%, transparent 0); |
|||
} |
|||
} |
|||
.cityselect-nav { |
|||
width: 100%; |
|||
padding-left: 20rpx; |
|||
overflow: hidden; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
.item { |
|||
font-size: 26rpx; |
|||
color: #222; |
|||
display: block; |
|||
height: 80rpx; |
|||
line-height: 92rpx; |
|||
padding: 0 16rpx; |
|||
position: relative; |
|||
margin-right: 30rpx; |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
max-width: 40%; |
|||
&.active { |
|||
color: #f23030 !important; |
|||
border-bottom: 1rpx solid #f23030; |
|||
} |
|||
} |
|||
} |
|||
.cityselect-content { |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
.cityselect-item { |
|||
.cityselect-item-box { |
|||
display: block; |
|||
padding: 0 40rpx; |
|||
position: relative; |
|||
overflow: hidden; |
|||
display: -webkit-box; |
|||
-webkit-line-clamp: 2; |
|||
-webkit-box-orient: vertical; |
|||
word-break: break-all; |
|||
text-overflow: ellipsis; |
|||
line-height: 64rpx; |
|||
max-height: 65rpx; |
|||
font-size: 26rpx; |
|||
color: #333; |
|||
&:after { |
|||
content: ""; |
|||
height: 1rpx; |
|||
position: absolute; |
|||
z-index: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
background-image: linear-gradient(0deg, #ececec 50%, transparent 0); |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,121 @@ |
|||
<template> |
|||
<view class="time"> |
|||
{{ tipText }} |
|||
<text class="styleAll" v-if="isDay === true">{{ day }}</text> |
|||
<text class="timeTxt">{{ dayText }}</text> |
|||
<text class="styleAll">{{ hour }}</text> |
|||
<text class="timeTxt">{{ hourText }}</text> |
|||
<text class="styleAll">{{ minute }}</text> |
|||
<text class="timeTxt">{{ minuteText }}</text> |
|||
<text class="styleAll">{{ second }}</text> |
|||
<text class="timeTxt">{{ secondText }}</text> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'CountDown', |
|||
props: { |
|||
//距离开始提示文字 |
|||
tipText: { |
|||
type: String, |
|||
default: '倒计时', |
|||
}, |
|||
dayText: { |
|||
type: String, |
|||
default: '天', |
|||
}, |
|||
hourText: { |
|||
type: String, |
|||
default: '时', |
|||
}, |
|||
minuteText: { |
|||
type: String, |
|||
default: '分', |
|||
}, |
|||
secondText: { |
|||
type: String, |
|||
default: '秒', |
|||
}, |
|||
datatime: {}, |
|||
isDay: { |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
timeInterval: null, |
|||
time: this.datatime, |
|||
day: '00', |
|||
hour: '00', |
|||
minute: '00', |
|||
second: '00', |
|||
} |
|||
}, |
|||
created() { |
|||
this.show_time() |
|||
}, |
|||
watch: { |
|||
datatime(val) { |
|||
clearInterval(this.timeInterval) |
|||
this.time = val |
|||
this.show_time() |
|||
}, |
|||
}, |
|||
mounted() { |
|||
}, |
|||
methods: { |
|||
show_time() { |
|||
console.log(this.datatime) |
|||
if (this.time.toString().length == 13) { |
|||
// 毫秒级 |
|||
console.log('毫秒') |
|||
this.time = this.time / 1000 |
|||
} else if (this.time.toString().length == 10) { |
|||
console.log('秒') |
|||
// 秒级 |
|||
} else { |
|||
// 时间 |
|||
console.log('时间') |
|||
this.time = Date.parse(this.time) / 1000 |
|||
} |
|||
this.runTime() |
|||
this.timeInterval = setInterval(this.runTime, 1000) |
|||
}, |
|||
runTime() { |
|||
//时间函数 |
|||
let intDiff = this.time - Date.parse(new Date()) / 1000 //获取数据中的时间戳的时间差 |
|||
let day = 0, |
|||
hour = 0, |
|||
minute = 0, |
|||
second = 0 |
|||
if (intDiff > 0) { |
|||
//转换时间 |
|||
if (this.isDay === true) { |
|||
day = Math.floor(intDiff / (60 * 60 * 24)) |
|||
} else { |
|||
day = 0 |
|||
} |
|||
hour = Math.floor(intDiff / (60 * 60)) - day * 24 |
|||
minute = Math.floor(intDiff / 60) - day * 24 * 60 - hour * 60 |
|||
second = Math.floor(intDiff) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60 |
|||
if (hour <= 9) hour = '0' + hour |
|||
if (minute <= 9) minute = '0' + minute |
|||
if (second <= 9) second = '0' + second |
|||
this.day = day |
|||
this.hour = hour |
|||
this.minute = minute |
|||
this.second = second |
|||
} else { |
|||
this.day = '00' |
|||
this.hour = '00' |
|||
this.minute = '00' |
|||
this.second = '00' |
|||
} |
|||
} |
|||
}, |
|||
destroyed() { |
|||
clearTimeout(this.timeInterval) |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,122 @@ |
|||
<template> |
|||
<view> |
|||
<view class="coupon-list-window" :class="value === true ? 'on' : ''"> |
|||
<view class="title"> |
|||
优惠券 |
|||
<text class="iconfont icon-guanbi" @click="close"></text> |
|||
</view> |
|||
<view v-if="couponList.length > 0"> |
|||
<view class="coupon-list"> |
|||
<div |
|||
class="item acea-row row-center-wrapper" |
|||
v-for="coupon in couponList" |
|||
:key="coupon.id" |
|||
@click="click(coupon)" |
|||
> |
|||
<div class="money"> |
|||
<div> |
|||
¥<span class="num">{{ coupon.couponPrice }}</span> |
|||
</div> |
|||
<div class="pic-num">满{{ coupon.useMinPrice }}元可用</div> |
|||
</div> |
|||
<div class="text"> |
|||
<div class="condition line1">{{ coupon.couponTitle }}</div> |
|||
<div class="data acea-row row-between-wrapper"> |
|||
<div v-if="coupon.endTime === 0">不限时</div> |
|||
<div v-else>截止:{{ coupon.endTime }}</div> |
|||
<div |
|||
class="iconfont icon-xuanzhong1 font-color-red" |
|||
v-if="checked === coupon.id" |
|||
></div> |
|||
<div class="iconfont icon-weixuanzhong" v-else></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</view> |
|||
<view class="couponNo bg-color-red" @click="couponNo">不使用优惠券</view> |
|||
</view> |
|||
<view v-if="!couponList.length && loaded"> |
|||
<view class="pictrue"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/noCoupon.png`" class="image" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent :hidden="value === false" @click="close"></view> |
|||
</view> |
|||
</template> |
|||
<style scoped lang="less"> |
|||
.coupon-list-window .iconfont { |
|||
font-size: 40rpx; |
|||
} |
|||
.couponNo { |
|||
font-size: 30rpx; |
|||
font-weight: bold; |
|||
color: #fff; |
|||
width: 690rpx; |
|||
height: 86rpx; |
|||
border-radius: 43rpx; |
|||
text-align: center; |
|||
line-height: 86rpx; |
|||
margin: 60rpx auto; |
|||
} |
|||
</style> |
|||
<script> |
|||
import { getOrderCoupon } from "@/api/order"; |
|||
import DataFormatT from "@/components/DataFormatT"; |
|||
|
|||
export default { |
|||
name: "CouponListWindow", |
|||
components: { |
|||
DataFormatT |
|||
}, |
|||
props: { |
|||
value: Boolean, |
|||
checked: Number, |
|||
price: { |
|||
type: [Number, String], |
|||
default: undefined |
|||
}, |
|||
cartid: { |
|||
type: String, |
|||
default: "" |
|||
} |
|||
}, |
|||
data: function() { |
|||
return { |
|||
couponList: [], |
|||
loaded: false |
|||
}; |
|||
}, |
|||
watch: { |
|||
price(n) { |
|||
if (n === undefined || n == null) return; |
|||
this.getCoupon(); |
|||
}, |
|||
cartid(n) { |
|||
if (n === undefined || n == null) return; |
|||
this.getCoupon(); |
|||
} |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
close: function() { |
|||
this.$emit("input", false); |
|||
this.$emit("close"); |
|||
}, |
|||
getCoupon() { |
|||
getOrderCoupon(this.cartid).then(res => { |
|||
this.couponList = res.data; |
|||
this.loaded = true; |
|||
}); |
|||
}, |
|||
click(coupon) { |
|||
this.$emit("checked", coupon); |
|||
this.$emit("input", false); |
|||
}, |
|||
couponNo: function() { |
|||
this.$emit("checked", null); |
|||
this.$emit("input", false); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,75 @@ |
|||
<template> |
|||
<view> |
|||
<view class="coupon-list-window" :class="coupon.coupon === true ? 'on' : ''"> |
|||
<view class="title"> |
|||
优惠券 |
|||
<text class="iconfont icon-guanbi" @click="close"></text> |
|||
</view> |
|||
<view class="coupon-list" v-if="coupon.list.length > 0"> |
|||
<view |
|||
class="item acea-row row-center-wrapper" |
|||
v-for="(item, couponpopIndex) in coupon.list" |
|||
:key="couponpopIndex" |
|||
@click="getCouponUser(couponpopIndex, item.id)" |
|||
> |
|||
<view class="money"> |
|||
¥ |
|||
<text class="num">{{ item.couponPrice }}</text> |
|||
</view> |
|||
<view class="text"> |
|||
<view class="condition line1">购物满{{ item.useMinPrice }}元可用</view> |
|||
<view class="data acea-row row-between-wrapper"> |
|||
<view v-if="item.end_time === 0">不限时</view> |
|||
<view v-else>{{ item.startTime }}-{{ item.endTime }}</view> |
|||
<view |
|||
class="bnt acea-row row-center-wrapper" |
|||
:class="!item.isUse ? 'bg-color-red' : 'gray'" |
|||
>{{ !item.isUse ? "立即领取" : "已领取" }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!--无优惠券--> |
|||
<view class="pictrue" v-else> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/noCoupon.png`" class="image" /> |
|||
</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent :hidden="coupon.coupon === false" @click="close"></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { getCouponReceive } from "@/api/user"; |
|||
export default { |
|||
name: "CouponPop", |
|||
props: { |
|||
coupon: { |
|||
type: Object, |
|||
default: () => {} |
|||
} |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
close: function() { |
|||
this.$emit("changeFun", { action: "changecoupon", value: false }); //$emit():注册事件; |
|||
}, |
|||
getCouponUser: function(index, id) { |
|||
let that = this, |
|||
list = that.coupon.list; |
|||
if (list[index].is_use === true) return; |
|||
getCouponReceive(id).then(function() { |
|||
uni.showToast({ |
|||
title: "已领取", |
|||
icon: "none", |
|||
duration: 2000 |
|||
}); |
|||
that.$set(list[index], "is_use", true); |
|||
that.$emit("changefun", { action: "currentcoupon", value: index }); |
|||
that.$emit("changeFun", { action: "changecoupon", value: false }); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,88 @@ |
|||
<template> |
|||
<view v-if="couponList.length > 0"> |
|||
<view class="coupon-window" :class="value ? 'on' : ''"> |
|||
<view class="couponWinList"> |
|||
<view class="item acea-row row-between-wrapper" v-for="(item, couponwindiwIndex) in couponList" :key="couponwindiwIndex"> |
|||
<view class="money font-color-red"> |
|||
¥<text class="num">{{ item.coupon_price }}</text> |
|||
</view> |
|||
<view class="text"> |
|||
<view class="name"> |
|||
购物买{{ item.use_min_price }}减{{ item.coupon_price }} |
|||
</view> |
|||
<view v-if="item.end_time"> |
|||
{{ item.start_time }}-{{ item.end_time }} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view style="height:120rpx"></view> |
|||
</view> |
|||
<view class="lid"> |
|||
<view class="bnt font-color-red" @click="checked">立即领取</view> |
|||
<view class="iconfont icon-guanbi3" @click="close"></view> |
|||
</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent :hidden="!value"></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { |
|||
mapGetters |
|||
} from "vuex"; |
|||
import {handleLoginFailure} from "@/utils"; |
|||
import { |
|||
couponReceiveBatch |
|||
} from "@/api/user"; |
|||
|
|||
export default { |
|||
name: "CouponWindow", |
|||
props: { |
|||
couponList: { |
|||
type: Array, |
|||
default: () => [] |
|||
} |
|||
}, |
|||
computed: mapGetters(["isLogin"]), |
|||
data: function() { |
|||
return { |
|||
value: true |
|||
}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
checked() { |
|||
const isLogin = this.isLogin; |
|||
if (!isLogin) return handleLoginFailure(); |
|||
|
|||
const ids = this.couponList.reduce((initial, coupon) => { |
|||
initial.push(coupon.id); |
|||
return initial; |
|||
}, []); |
|||
couponReceiveBatch(ids) |
|||
.then(() => { |
|||
this.$emit("success"); |
|||
uni.showToast({ |
|||
title: '领取成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
}) |
|||
.catch(() => { |
|||
uni.showToast({ |
|||
title: '已领取', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
}); |
|||
if (isLogin) { |
|||
this.value = false; |
|||
this.$emit("checked"); |
|||
} |
|||
}, |
|||
close: function() { |
|||
this.value = false; |
|||
this.$emit("close"); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<text>{{time}}</text> |
|||
</template> |
|||
<script> |
|||
import { dataFormat } from "@/utils"; |
|||
|
|||
export default { |
|||
name: "DataFormat", |
|||
props: ["date"], |
|||
data: function() { |
|||
return { |
|||
time: "" |
|||
}; |
|||
}, |
|||
mounted() { |
|||
this.time = dataFormat(this.date); |
|||
}, |
|||
watch: { |
|||
"$props.date"(props) { |
|||
this.time = dataFormat(this.date); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<text>{{time}}</text> |
|||
</template> |
|||
<script> |
|||
import { dateFormatT } from "@/utils"; |
|||
|
|||
export default { |
|||
name: "DataFormatT", |
|||
props: ["date"], |
|||
data: function() { |
|||
return { |
|||
time: "" |
|||
}; |
|||
}, |
|||
mounted() { |
|||
this.time = dateFormatT(this.date); |
|||
}, |
|||
watch: { |
|||
"$props.date"(props) { |
|||
this.time = dateFormatT(this.date); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,65 @@ |
|||
<template> |
|||
<view> |
|||
<view class="footer-bg"></view> |
|||
<view id="footer" :class="[isIpx ? 'iphonex-footer' : '', 'acea-row row-middle'] "> |
|||
<view |
|||
class="item" |
|||
:class="{ on: footerIndex == tabtarIndex }" |
|||
v-for="(item, footerIndex) in footerList" |
|||
:key="footerIndex" |
|||
> |
|||
<view |
|||
class="iconfont" |
|||
:class="item.icon1 + ' ' + (footerIndex == tabtarIndex ? item.icon2 : '')" |
|||
></view> |
|||
<view>{{ item.name }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { mapState, mapMutations, mapActions } from "vuex"; |
|||
export default { |
|||
name: "Footer", |
|||
props: {}, |
|||
data: function() { |
|||
return { |
|||
footerList: [ |
|||
{ |
|||
name: "首页", |
|||
icon1: "icon-shouye-xianxing", |
|||
icon2: "icon-shouye", |
|||
url: "/pages/home/index" |
|||
}, |
|||
{ |
|||
name: "分类", |
|||
icon1: "icon-yingyongchengxu-xianxing", |
|||
icon2: "icon-yingyongchengxu", |
|||
url: "/pages/shop/GoodsClass/index" |
|||
}, |
|||
{ |
|||
name: "购物车", |
|||
icon1: "icon-caigou-xianxing", |
|||
icon2: "icon-caigou", |
|||
url: "/pages/shop/ShoppingCart/index" |
|||
}, |
|||
{ |
|||
name: "我的", |
|||
icon1: "icon-yonghu-xianxing", |
|||
icon2: "icon-yonghu", |
|||
url: "/pages/user/User/index" |
|||
} |
|||
], |
|||
isIpx: false |
|||
}; |
|||
}, |
|||
computed: { |
|||
...mapState(["tabtarIndex"]) |
|||
}, |
|||
methods: { |
|||
}, |
|||
mounted() { |
|||
|
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,49 @@ |
|||
<template> |
|||
<view class="goodList"> |
|||
<view @click="routerGo(item)" class="item acea-row row-between-wrapper" v-for="(item, goodlistIndex) in goodList" :key="goodlistIndex"> |
|||
<view class="pictrue"> |
|||
<image :src="item.image" class="image" /> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/one.png`" class="numPic" v-if="isSort === true && index === 0" /> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/two.png`" class="numPic" v-if="isSort === true && index === 1" /> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/three.png`" class="numPic" v-if="isSort === true && index === 2" /> |
|||
</view> |
|||
<view class="underline"> |
|||
<view class="text"> |
|||
<view class="line1">{{ item.storeName }}</view> |
|||
<view class="money font-color-red"> |
|||
¥ |
|||
<text class="num">{{ item.price }}</text> |
|||
</view> |
|||
<view class="vip-money acea-row row-middle"> |
|||
<view class="vip">¥{{ item.otPrice || 0 }}</view> |
|||
<text class="num">已售{{ item.sales }}{{ item.unitName }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- <view class="iconfont icon-gouwuche cart-color acea-row row-center-wrapper"></view> --> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "GoodList", |
|||
props: { |
|||
goodList: { |
|||
type: Array, |
|||
default: () => [] |
|||
}, |
|||
isSort: { |
|||
type: Boolean, |
|||
default: true |
|||
} |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
methods:{ |
|||
routerGo(item) { |
|||
this.$yrouter.push({ path: '/pages/shop/GoodsCon/index', query: { id: item.id } }); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,59 @@ |
|||
<template> |
|||
<view class="home" :style="{ top: top + 'px' }" style="position:fixed;" id="right-nav" @touchmove="touchmove($event)"> |
|||
<view class="homeCon bg-color-red1" :class="homeActive === true ? 'on' : ''"> |
|||
<view @click="homeGo()" class="iconfont icon-shouye-xianxing " style="color: green;"></view> |
|||
<view @click="shoppingCartGo()" class="iconfont icon-caigou-xianxing" style="color: green;"></view> |
|||
<!--<view @click="userGo()" class="iconfont icon-yonghu1"></view>--> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { mapGetters } from 'vuex'; |
|||
export default { |
|||
name: 'Home', |
|||
props: {}, |
|||
data: function() { |
|||
return { |
|||
top: '', |
|||
homeActive: true |
|||
}; |
|||
}, |
|||
computed: mapGetters(['homeActive']), |
|||
methods: { |
|||
userGo() { |
|||
this.$yrouter.push('/pages/user/User/index'); |
|||
}, |
|||
homeGo() { |
|||
this.$yrouter.switchTab('/pages/home/index'); |
|||
}, |
|||
shoppingCartGo() { |
|||
this.$yrouter.switchTab('/pages/shop/ShoppingCart/index'); |
|||
}, |
|||
touchmove(event) { |
|||
// event.preventDefault(); |
|||
// let top = |
|||
// event.touches[0].pageY - |
|||
// (document.documentElement.scrollTop || document.body.scrollTop) - |
|||
// this.$el.clientHeight; |
|||
|
|||
// if (top > 390) top = 390; |
|||
// else if (top < 55) top = 55; |
|||
this.top = 55; |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style scoped lang="less"> |
|||
.mystyl { |
|||
display: inline-block; |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
margin-top:12rpx; |
|||
box-sizing: border-box; |
|||
border: 1px solid #e1e1e1; |
|||
border-radius: 50%; |
|||
background-size: 124rpx auto; |
|||
background-repeat: no-repeat; |
|||
background-color: rgba(255, 255, 255, 0.9); |
|||
} |
|||
</style> |
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<view class="Loads acea-row row-center-wrapper" v-if="loading || !loaded" style="margin-top: 20rpx;"> |
|||
<template v-if="loading"> |
|||
<view class="iconfont icon-jiazai loading acea-row row-center-wrapper"></view> |
|||
正在加载中 |
|||
</template> |
|||
<template v-if="!loading"> |
|||
上拉加载更多 |
|||
</template> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "Loading", |
|||
props: { |
|||
loaded: Boolean, |
|||
loading: Boolean |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,74 @@ |
|||
<template> |
|||
<div |
|||
:class="show?'yd-mask g-fix-ios-overflow-scrolling-bug':'yd-mask' " |
|||
ref="scrollView" |
|||
:style="styles" |
|||
> |
|||
<slot></slot> |
|||
</div> |
|||
</template> |
|||
|
|||
<script type="text/babel"> |
|||
export default { |
|||
name: "yd-mask", |
|||
data() { |
|||
return { |
|||
show: this.value |
|||
}; |
|||
}, |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
bgcolor: { |
|||
type: String, |
|||
default: "#000" |
|||
}, |
|||
zindex: { |
|||
default: 1500 |
|||
}, |
|||
opacity: { |
|||
default: 0.5 |
|||
}, |
|||
animated: { |
|||
type: Boolean, |
|||
default: true |
|||
} |
|||
}, |
|||
computed: { |
|||
styles() { |
|||
const style = { |
|||
"z-index": this.zindex, |
|||
"background-color": this.bgcolor |
|||
}; |
|||
if (this.show) { |
|||
style["opacity"] = this.opacity; |
|||
style["pointer-events"] = "auto"; |
|||
} |
|||
return style; |
|||
} |
|||
}, |
|||
mounted() {} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="less"> |
|||
@css-prefix: yd; |
|||
|
|||
.@{css-prefix} { |
|||
&-mask { |
|||
position: fixed; |
|||
bottom: 0; |
|||
right: 0; |
|||
left: 0; |
|||
top: 0; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
pointer-events: none; |
|||
transition: opacity 0.2s ease-in; |
|||
opacity: 0; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,155 @@ |
|||
<template> |
|||
<!-- 产品分类导航 --> |
|||
<view class="menu-category-box mb10" v-if="carousel" :style="list.length <= menu ? `height:200rpx` : `height:360rpx`"> |
|||
<swiper |
|||
class="menu-swiper-box" |
|||
:style="list.length <= menu ? `height:160rpx` : `height:320rpx`" |
|||
@change="onSwiper" |
|||
circular |
|||
:autoplay="false" |
|||
:interval="3000" |
|||
:duration="1000" |
|||
> |
|||
<swiper-item class="menu-swiper-item" v-for="(itemList, index) in carousel" :key="index" :style="list.length <= menu ? `height:200rpx` : `height:340rpx`"> |
|||
<view class="menu-tab-box"> |
|||
<view class="tab-list y-f" :style="{ width: 690 / menu + 'rpx' }" v-for="item in itemList" :key="item.name" @tap="routerTo(item)"> |
|||
<image class="tab-img Shop-selector-circular" :style="{ width: imgW + 'rpx', height: imgW + 'rpx' }" :src="item.pic"></image> |
|||
<text class="Shop-selector-rect">{{ item.name }}</text> |
|||
</view> |
|||
</view> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="menu-category-dots" v-if="carousel.length > 1"> |
|||
<text :class="categoryCurrent === index ? 'category-dot-active' : 'category-dot'" v-for="(dot, index) in carousel.length" :key="index"></text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: {}, |
|||
data() { |
|||
return { |
|||
categoryCurrent: 0 //分类轮播下标 |
|||
}; |
|||
}, |
|||
props: { |
|||
list: { |
|||
type: Array, |
|||
default: [] |
|||
}, |
|||
menu: { |
|||
default: 4 |
|||
}, |
|||
imgW: { |
|||
type: Number, |
|||
default: 88 |
|||
} |
|||
}, |
|||
computed: { |
|||
carousel() { |
|||
if (this.list) { |
|||
let list = this.sortData(this.list, this.menu * 2); |
|||
return list; |
|||
} |
|||
} |
|||
}, |
|||
created() {}, |
|||
methods: { |
|||
// 数据分层 |
|||
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; |
|||
}, |
|||
// 轮播 |
|||
onSwiper(e) { |
|||
this.categoryCurrent = e.detail.current; |
|||
}, |
|||
// 路由跳转 |
|||
routerTo(item) { |
|||
this.$yrouter.push(item.uniapp_url); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
// 产品分类 |
|||
.y-f { |
|||
display: -webkit-box; |
|||
display: -webkit-flex; |
|||
display: flex; |
|||
-webkit-box-orient: vertical; |
|||
-webkit-box-direction: normal; |
|||
-webkit-flex-direction: column; |
|||
flex-direction: column; |
|||
-webkit-box-align: center; |
|||
-webkit-align-items: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.menu-category-box { |
|||
padding: 30rpx 30rpx 0 30rpx; |
|||
background: #fff; |
|||
box-sizing: border-box; |
|||
} |
|||
.menu-category-box, |
|||
.menu-swiper-box { |
|||
position: relative; |
|||
background: #fff; |
|||
.menu-swiper-item { |
|||
background: #fff; |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
.menu-tab-box { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.tab-list { |
|||
font-size: 22rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(51, 51, 51, 1); |
|||
padding-bottom: 30rpx; |
|||
|
|||
.tab-img { |
|||
border-radius: 25rpx; |
|||
margin-bottom: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.menu-category-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 20rpx; |
|||
|
|||
.category-dot { |
|||
width: 40rpx; |
|||
height: 3rpx; |
|||
background: #eeeeee; |
|||
margin-right: 10rpx; |
|||
} |
|||
|
|||
.category-dot-active { |
|||
width: 40rpx; |
|||
height: 3rpx; |
|||
background: #a8700d; |
|||
margin-right: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,47 @@ |
|||
<template> |
|||
<view class="orderGoods"> |
|||
<view class="total">共{{ cartInfo.length }}件商品</view> |
|||
<view class="goodWrapper"> |
|||
<view class="item acea-row row-between-wrapper" v-for="cart in cartInfo" :key="cart.id"> |
|||
<view class="pictrue"> |
|||
<image :src="cart.productInfo.image" class="image" /> |
|||
</view> |
|||
<view class="text"> |
|||
<view class="acea-row row-between-wrapper"> |
|||
<view class="name line1">{{ cart.productInfo.storeName }}</view> |
|||
<view class="num">x {{ cart.cartNum }}</view> |
|||
</view> |
|||
<view class="attr line1" v-if="cart.productInfo.attrInfo">{{ cart.productInfo.attrInfo.sku }}</view> |
|||
<view class="money font-color-red" v-if="isIntegral">{{ cart.costPrice }}积分</view> |
|||
<view class="money font-color-red" v-else>¥{{ cart.truePrice }}</view> |
|||
<view class="evaluate" v-if="evaluate == 3 && cart.isReply == 0" @click="routerGo(cart)">评价</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'OrderGoods', |
|||
props: { |
|||
evaluate: Number, |
|||
cartInfo: { |
|||
type: Array, |
|||
default: () => [], |
|||
}, |
|||
isIntegral: Boolean, |
|||
}, |
|||
data: function() { |
|||
return {} |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
routerGo(cart) { |
|||
this.$yrouter.push({ |
|||
path: '/pages/shop/GoodsEvaluate/index', |
|||
query: { id: cart.unique }, |
|||
}) |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
@ -0,0 +1,202 @@ |
|||
<template> |
|||
<view> |
|||
<view class="payment" :class="value === true ? 'on' : ''"> |
|||
<view class="title acea-row row-center-wrapper"> |
|||
选择付款方式<text class="iconfont icon-guanbi" @click="close"></text> |
|||
</view> |
|||
<view |
|||
class="item acea-row row-between-wrapper" |
|||
v-if="types.indexOf('weixin') !== -1" |
|||
@click="checked('weixin')" |
|||
> |
|||
<view class="left acea-row row-between-wrapper"> |
|||
<view class="iconfont icon-weixinzhifu"></view> |
|||
<view class="text"> |
|||
<view class="name">微信支付</view> |
|||
<view class="info">使用微信快捷支付</view> |
|||
</view> |
|||
</view> |
|||
<view class="iconfont icon-xiangyou"></view> |
|||
</view> |
|||
<!-- <view |
|||
class="item acea-row row-between-wrapper" |
|||
v-if="types.indexOf('alipay') !== -1" |
|||
@click="checked('alipay')" |
|||
> |
|||
<view class="left acea-row row-between-wrapper"> |
|||
<view class="iconfont icon-zhifubao"></view> |
|||
<view class="text"> |
|||
<view class="name">支付宝支付</view> |
|||
<view class="info">使用线上支付宝支付</view> |
|||
</view> |
|||
</view> |
|||
<view class="iconfont icon-xiangyou"></view> |
|||
</view> --> |
|||
<view |
|||
class="item acea-row row-between-wrapper" |
|||
v-if="types.indexOf('yue') !== -1" |
|||
@click="checked('yue')" |
|||
> |
|||
<view class="left acea-row row-between-wrapper"> |
|||
<view class="iconfont icon-yuezhifu"></view> |
|||
<view class="text"> |
|||
<view class="name">余额支付</view> |
|||
<view class="info"> |
|||
当前可用余额:<text class="money">{{ balance }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="iconfont icon-xiangyou"></view> |
|||
</view> |
|||
<!-- <view |
|||
class="item acea-row row-between-wrapper" |
|||
v-if="types.indexOf('offline') !== -1" |
|||
@click="checked('offline')" |
|||
> |
|||
<view class="left acea-row row-between-wrapper"> |
|||
<view class="iconfont icon-yuezhifu1"></view> |
|||
<view class="text"> |
|||
<view class="name">线下支付</view> |
|||
<view class="info">选择线下付款方式</view> |
|||
</view> |
|||
</view> |
|||
<view class="iconfont icon-xiangyou"></view> |
|||
</view> --> |
|||
</view> |
|||
<view class="mask" v-show="value" @click="close"></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "Payment", |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
balance: { |
|||
type: [Number, String], |
|||
default: 0 |
|||
}, |
|||
types: { |
|||
type: Array, |
|||
default: () => ["weixin", "alipay", "yue", "offline"] |
|||
} |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
checked: function(type) { |
|||
this.$emit("checked", type); |
|||
this.close(); |
|||
}, |
|||
close: function() { |
|||
this.$emit("input", false); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style scoped lang="less" lang="less"> |
|||
.payment { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
border-radius: 0.16*100rpx 0.16*100rpx 0 0; |
|||
background-color: #fff; |
|||
padding-bottom: 0.6*100rpx; |
|||
z-index: 99; |
|||
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9); |
|||
-webkit-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9); |
|||
-moz-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9); |
|||
-o-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9); |
|||
transform: translate3d(0, 100%, 0); |
|||
-webkit-transform: translate3d(0, 100%, 0); |
|||
-ms-transform: translate3d(0, 100%, 0); |
|||
-moz-transform: translate3d(0, 100%, 0); |
|||
-o-transform: translate3d(0, 100%, 0); |
|||
} |
|||
|
|||
.payment.on { |
|||
transform: translate3d(0, 0, 0); |
|||
-webkit-transform: translate3d(0, 0, 0); |
|||
-ms-transform: translate3d(0, 0, 0); |
|||
-moz-transform: translate3d(0, 0, 0); |
|||
-o-transform: translate3d(0, 0, 0); |
|||
} |
|||
|
|||
.payment .title { |
|||
text-align: center; |
|||
height: 1.23*100rpx; |
|||
font-size: 0.32*100rpx; |
|||
color: #282828; |
|||
font-weight: bold; |
|||
padding-right: 0.3*100rpx; |
|||
margin-left: 0.3*100rpx; |
|||
position: relative; |
|||
border-bottom: 0.01*100rpx solid #eee; |
|||
} |
|||
|
|||
.payment .title .iconfont { |
|||
position: absolute; |
|||
right: 0.3*100rpx; |
|||
top: 50%; |
|||
transform: translateY(-50%); |
|||
font-size: 0.43*100rpx; |
|||
color: #8a8a8a; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.payment .item { |
|||
border-bottom: 0.01*100rpx solid #eee; |
|||
height: 1.3*100rpx; |
|||
margin-left: 0.3*100rpx; |
|||
padding-right: 0.3*100rpx; |
|||
} |
|||
|
|||
.payment .item .left { |
|||
width: 6.1*100rpx; |
|||
} |
|||
|
|||
.payment .item .left .text { |
|||
width: 5.4*100rpx; |
|||
} |
|||
|
|||
.payment .item .left .text .name { |
|||
font-size: 0.32*100rpx; |
|||
color: #282828; |
|||
} |
|||
|
|||
.payment .item .left .text .info { |
|||
font-size: 0.24*100rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
.payment .item .left .text .info .money { |
|||
color: #ff9900; |
|||
} |
|||
|
|||
.payment .item .left .iconfont { |
|||
font-size: 0.45*100rpx; |
|||
color: #09bb07; |
|||
} |
|||
|
|||
.payment .item .left .iconfont.icon-zhifubao { |
|||
color: #00aaea; |
|||
} |
|||
|
|||
.payment .item .left .iconfont.icon-yuezhifu { |
|||
color: #ff9900; |
|||
} |
|||
|
|||
.payment .item .left .iconfont.icon-yuezhifu1 { |
|||
color: #eb6623; |
|||
} |
|||
|
|||
.payment .item .iconfont { |
|||
font-size: 0.3*100rpx; |
|||
color: #999; |
|||
} |
|||
</style> |
@ -0,0 +1,133 @@ |
|||
<template> |
|||
<view> |
|||
<view class="priceChange" :class="change === true ? 'on' : ''"> |
|||
<view class="priceTitle"> |
|||
<text v-if="status==0"> |
|||
<text v-if="orderInfo.refundStatus == 1">立即退款</text> |
|||
<text v-if="orderInfo.refundStatus != 1">一键改价</text> |
|||
</text> |
|||
<text v-if="status!=0">订单备注</text> |
|||
<text class="iconfont icon-guanbi" @click="close"></text> |
|||
</view> |
|||
<view class="listChange" v-if="status == 0"> |
|||
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refundStatus === 0"> |
|||
<view>商品总价(¥)</view> |
|||
<view class="money"> |
|||
{{ orderInfo.totalPrice }} |
|||
<text class="iconfont icon-suozi"></text> |
|||
</view> |
|||
</view> |
|||
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refundStatus === 0"> |
|||
<view>原始邮费(¥)</view> |
|||
<view class="money"> |
|||
{{ orderInfo.payPostage }} |
|||
<text class="iconfont icon-suozi"></text> |
|||
</view> |
|||
</view> |
|||
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refundStatus === 0"> |
|||
<view>实际支付(¥)</view> |
|||
<view class="money"> |
|||
<input |
|||
type="text" |
|||
v-model="price" |
|||
:class="focus === true ? 'on' : ''" |
|||
@focus="priceChange" |
|||
/> |
|||
</view> |
|||
</view> |
|||
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refundStatus === 1"> |
|||
<view>实际支付(¥)</view> |
|||
<view class="money"> |
|||
{{ orderInfo.payPrice }} |
|||
<text class="iconfont icon-suozi"></text> |
|||
</view> |
|||
</view> |
|||
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refundStatus === 1"> |
|||
<view>退款金额(¥)</view> |
|||
<view class="money"> |
|||
<input |
|||
type="text" |
|||
v-model="refund_price" |
|||
:class="focus === true ? 'on' : ''" |
|||
@focus="priceChange" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="listChange" v-else> |
|||
<textarea |
|||
:placeholder="'请填写备注信息...'" |
|||
v-model="remark" |
|||
></textarea> |
|||
</view> |
|||
<view class="modify" @click="save">{{ orderInfo.refundStatus === 0 ? "立即修改" : "确认退款" }}</view> |
|||
<view class="modify1" @click="refuse" v-if="orderInfo.refundStatus === 1">拒绝退款</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent v-show="change === true"></view> |
|||
</view> |
|||
</template> |
|||
<style scoped lang="less" > |
|||
.priceChange .listChange textarea { |
|||
border: 1px solid #eee; |
|||
width: 100%; |
|||
height: 200rpx; |
|||
margin-top: 50rpx; |
|||
border-radius: 10rpx; |
|||
color: #333; |
|||
padding: 20rpx; |
|||
} |
|||
</style> |
|||
<script> |
|||
export default { |
|||
name: "PriceChange", |
|||
components: {}, |
|||
props: { |
|||
change: Boolean, |
|||
orderInfo: Object, |
|||
status: String |
|||
}, |
|||
data: function() { |
|||
return { |
|||
focus: false, |
|||
price: 0, |
|||
refund_price: 0, |
|||
remark: "" |
|||
}; |
|||
}, |
|||
watch: { |
|||
orderInfo: function() { |
|||
this.price = this.orderInfo.payPrice; |
|||
this.refund_price = this.orderInfo.payPrice; |
|||
this.remark = ""; |
|||
} |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
priceChange: function() { |
|||
this.focus = true; |
|||
}, |
|||
close: function() { |
|||
this.price = this.orderInfo.payPrice; |
|||
this.$emit("closechange", false); |
|||
}, |
|||
save: function() { |
|||
let that = this; |
|||
that.$emit("savePrice", { |
|||
price: that.price, |
|||
refund_price: that.refund_price, |
|||
type: 1, |
|||
remark: that.remark |
|||
}); |
|||
}, |
|||
refuse: function() { |
|||
let that = this; |
|||
that.$emit("savePrice", { |
|||
price: that.price, |
|||
refund_price: that.refund_price, |
|||
type: 2, |
|||
remark: that.remark |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,71 @@ |
|||
<template> |
|||
<view class="slider-banner product-bg"> |
|||
<swiper |
|||
class="swiper-wrapper" |
|||
@change="handleChange" |
|||
v-if="imgUrls.length > 0" |
|||
> |
|||
<block v-for="(item, imgUrlsIndex) in imgUrls" :key="imgUrlsIndex"> |
|||
<swiper-item> |
|||
<image :src="item" @tap="previewImage(imgUrlsIndex)" class="slide-image" /> |
|||
</swiper-item> |
|||
</block> |
|||
</swiper> |
|||
<!-- <swiper class="swiper-wrapper" :options="ProductConSwiper" v-if="imgUrls.length > 0"> |
|||
<swiperSlide class="swiper-slide" v-for="item in imgUrls" :key="item" ref="goodSwiper"> |
|||
<image :src="item" class="slide-image" /> |
|||
</swiperSlide> |
|||
</swiper>--> |
|||
<view class="pages">{{ currents || 1 }}/{{ imgUrls.length || 1 }}</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
// import { swiper, swiperSlide } from "vue-awesome-swiper"; |
|||
|
|||
export default { |
|||
name: "ProductConSwiper", |
|||
components: { |
|||
// swiper, |
|||
// swiperSlide |
|||
}, |
|||
props: { |
|||
imgUrls: { |
|||
type: Array, |
|||
default: () => [], |
|||
}, |
|||
}, |
|||
data: function () { |
|||
let that = this; |
|||
return { |
|||
currents: 1, |
|||
ProductConSwiper: { |
|||
autoplay: { |
|||
disableOnInteraction: false, |
|||
delay: 2000, |
|||
}, |
|||
loop: true, |
|||
speed: 1000, |
|||
observer: true, |
|||
observeParents: true, |
|||
on: { |
|||
slideChangeTransitionStart: function () { |
|||
that.currents = this.realIndex + 1; |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
}, |
|||
mounted: function () {}, |
|||
methods: { |
|||
handleChange(event) { |
|||
this.currents = event.mp.detail.current + 1; |
|||
}, |
|||
previewImage(current) { |
|||
uni.previewImage({ |
|||
current, |
|||
urls: this.imgUrls, |
|||
}); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,141 @@ |
|||
<template> |
|||
<view> |
|||
<view class="product-window" :class="attr.cartAttr === true ? 'on' : ''"> |
|||
<view class="textpic acea-row row-between-wrapper"> |
|||
<view class="pictrue"> |
|||
<image @tap="previewImage" :src="attr.productSelect.image" class="image" /> |
|||
</view> |
|||
<view class="text"> |
|||
<view class="line1">{{ attr.productSelect.store_name }}</view> |
|||
<view class="money font-color-red" v-if="!isIntegral"> |
|||
¥ |
|||
<text class="num">{{ attr.productSelect.price }}</text> |
|||
<text class="stock">库存: {{ attr.productSelect.stock }}</text> |
|||
</view> |
|||
<view class="money font-color-red" v-if="isIntegral"> |
|||
<text class="num">{{ attr.productSelect.integral }}积分</text> |
|||
<text class="stock">库存: {{ attr.productSelect.stock }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="iconfont icon-guanbi" @click="closeAttr"></view> |
|||
</view> |
|||
<view class="productWinList"> |
|||
<view |
|||
class="item" |
|||
v-for="(item, indexw) in attr.productAttr" |
|||
:key="indexw" |
|||
> |
|||
<view class="title">{{ item.attrName }}</view> |
|||
<view class="listn acea-row row-middle"> |
|||
<view |
|||
class="itemn" |
|||
:class="item.index == indexn ? 'on' : ''" |
|||
v-for="(itemn, indexn) in item.attrValue" |
|||
@click="tapAttr(indexw, indexn)" |
|||
:key="indexn" |
|||
>{{ itemn.attr }}</view |
|||
> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="cart"> |
|||
<view class="title">数量</view> |
|||
<view class="carnum acea-row row-left"> |
|||
<view |
|||
class="item reduce" |
|||
:class="cartNum <= 1 ? 'on' : ''" |
|||
@click="CartNumDes" |
|||
>-</view |
|||
> |
|||
<view class="item num">{{ cartNum }}</view> |
|||
<view |
|||
class="item plus" |
|||
:class="cartNum >= attr.productSelect.stock ? 'on' : ''" |
|||
@click="CartNumAdd" |
|||
>+</view |
|||
> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view |
|||
class="mask" |
|||
@touchmove.prevent |
|||
:hidden="attr.cartAttr === false" |
|||
@click="closeAttr" |
|||
></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "ProductWindow", |
|||
props: { |
|||
isIntegral:Boolean, |
|||
attr: { |
|||
type: Object, |
|||
default: () => {}, |
|||
}, |
|||
cartNum: { |
|||
type: Number, |
|||
default: () => 1, |
|||
}, |
|||
}, |
|||
data: function () { |
|||
return {}; |
|||
}, |
|||
mounted: function () { |
|||
console.log(this.attr) |
|||
console.log(this); |
|||
}, |
|||
watch: { |
|||
attr(nextAttr) { |
|||
}, |
|||
}, |
|||
methods: { |
|||
closeAttr: function () { |
|||
this.$emit("changeFun", { action: "changeattr", value: false }); |
|||
}, |
|||
CartNumDes: function () { |
|||
this.$emit("changeFun", { action: "ChangeCartNum", value: false }); |
|||
}, |
|||
CartNumAdd: function () { |
|||
this.$emit("changeFun", { action: "ChangeCartNum", value: 1 }); |
|||
}, |
|||
tapAttr: function (indexw, indexn) { |
|||
// 修改商品规格不生效的原因: |
|||
// H5端下面写法,attr更新,但是除H5外其他端不支持, |
|||
// 尽量避免下面的骚写法,不要在子组件内更新props |
|||
// 这里修改是为了能获取到被选中的属性 |
|||
this.attr.productAttr[indexw].index = indexn; |
|||
let that = this; |
|||
let value = that.getCheckedValue().sort().join(","); |
|||
that.$emit("changeFun", { |
|||
action: "ChangeAttr", |
|||
value: { |
|||
value, |
|||
indexw, |
|||
indexn, |
|||
}, |
|||
}); |
|||
}, |
|||
//获取被选中属性; |
|||
getCheckedValue: function () { |
|||
let productAttr = this.attr.productAttr; |
|||
let value = []; |
|||
for (let i = 0; i < productAttr.length; i++) { |
|||
for (let j = 0; j < productAttr[i].attrValueArr.length; j++) { |
|||
if (productAttr[i].index === j) { |
|||
value.push(productAttr[i].attrValueArr[j]); |
|||
} |
|||
} |
|||
} |
|||
return value; |
|||
}, |
|||
previewImage() { |
|||
uni.previewImage({ |
|||
current: 0, |
|||
urls: [this.attr.productSelect.image], |
|||
}); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,212 @@ |
|||
<template> |
|||
<view> |
|||
<view class="sh-title-card mb10"> |
|||
<view class="title-box"> |
|||
<image class="title-bg" :src="`${$VUE_APP_RESOURCES_URL}/images/title1.png`" mode="aspectFill" /> |
|||
<view class="title-text">为你推荐</view> |
|||
<!-- <view class="title-text" :style="{ color: detail.color }">为你推荐</view> --> |
|||
</view> |
|||
</view> |
|||
<view class="hot-goods mx20 mb10" v-if="benefit.length"> |
|||
<view class="goods-list x-f"> |
|||
<view class="goods-item" v-for="(item, promotionGoodIndex) in benefit" :key="promotionGoodIndex"> |
|||
<view class="goods-box" @tap="routerGo(item)"> |
|||
<view class="img-box"> |
|||
<!-- <image class="tag-img" :src="item.image" mode=""></image> --> |
|||
<image class="img" :src="item.image" lazy-load mode="aspectFill"></image> |
|||
</view> |
|||
<view class="tip one-t">{{ item.storeName }}</view> |
|||
<view class="title more-t">{{ item.storeName }}</view> |
|||
<view class="price-box"> |
|||
<view class="flex x-bc align-end"> |
|||
<view class="current">{{ item.price }} </view> |
|||
<view class="sales miso-font">仅剩:{{ item.stock }}{{ item.unitName }}</view> |
|||
</view> |
|||
<view class="x-f tag-box"> |
|||
<!-- <view class="discount">新人礼</view> |
|||
<view class="discount">满100减60</view> --> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'PromotionGood', |
|||
props: ['benefit'], |
|||
data: function() { |
|||
return {} |
|||
}, |
|||
methods: { |
|||
routerGo(item) { |
|||
this.$yrouter.push({ |
|||
path: '/pages/shop/GoodsCon/index', |
|||
query: { |
|||
id: item.id, |
|||
}, |
|||
}) |
|||
}, |
|||
}, |
|||
mounted() {}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.sh-title-card { |
|||
width: 750rpx; |
|||
} |
|||
|
|||
.title-box { |
|||
width: 710rpx; |
|||
height: 88rpx; |
|||
margin: 0 auto; |
|||
position: relative; |
|||
border-radius: 30rpx; |
|||
|
|||
.title-bg { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.title-text { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.goods-box { |
|||
width: 345rpx; |
|||
background: #fff; |
|||
padding-bottom: 20rpx; |
|||
border-radius: 20rpx; |
|||
overflow: hidden; |
|||
|
|||
.img-box { |
|||
width: 345rpx; |
|||
height: 345rpx; |
|||
overflow: hidden; |
|||
position: relative; |
|||
|
|||
.tag-img { |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
z-index: 2; |
|||
width: 80rpx; |
|||
height: 40rpx; |
|||
} |
|||
|
|||
.img { |
|||
width: 345rpx; |
|||
height: 345rpx; |
|||
background-color: #ccc; |
|||
} |
|||
} |
|||
|
|||
.tip { |
|||
width: 346rpx; |
|||
line-height: 56rpx; |
|||
background: rgba(246, 242, 234, 1); |
|||
font-size: 22rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 400; |
|||
color: rgba(168, 112, 13, 1); |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
.title { |
|||
font-size: 24rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
line-height: 36rpx; |
|||
height: 72rpx; |
|||
margin: 20rpx 20rpx 10rpx; |
|||
} |
|||
|
|||
.price-box { |
|||
padding: 10rpx 20rpx 0; |
|||
width: 344rpx; |
|||
box-sizing: border-box; |
|||
|
|||
.sales { |
|||
font-size: 20rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 400; |
|||
color: rgba(153, 153, 153, 1); |
|||
line-height: 20rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.current { |
|||
font-size: 30rpx; |
|||
font-weight: 500; |
|||
color: rgba(225, 33, 43, 1); |
|||
line-height: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
|
|||
&:before { |
|||
content: '¥'; |
|||
font-size: 26rpx; |
|||
} |
|||
} |
|||
|
|||
.original { |
|||
font-size: 22rpx; |
|||
font-weight: 400; |
|||
text-decoration: line-through; |
|||
color: rgba(153, 153, 153, 1); |
|||
margin-left: 14rpx; |
|||
line-height: 22rpx; |
|||
margin-bottom: 10rpx; |
|||
|
|||
&:before { |
|||
content: '¥'; |
|||
font-size: 20rpx; |
|||
} |
|||
} |
|||
|
|||
.tag-box { |
|||
.discount { |
|||
line-height: 28rpx; |
|||
border: 1rpx solid rgba(225, 33, 43, 1); |
|||
border-radius: 8rpx; |
|||
font-size: 18rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(225, 33, 43, 1); |
|||
padding: 0 8rpx; |
|||
margin-right: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 为你推荐 |
|||
.hot-goods { |
|||
// background: linear-gradient(#fff 200rpx, #f6f6f6 500rpx, #f6f6f6); |
|||
// border-radius: 20rpx; |
|||
|
|||
.goods-list { |
|||
flex-wrap: wrap; |
|||
width: 710rpx; |
|||
|
|||
.goods-item { |
|||
margin-right: 20rpx; |
|||
margin-bottom: 20rpx; |
|||
width: 345rpx; |
|||
box-shadow: 0px 0px 10rpx 4rpx rgba(199, 199, 199, 0.22); |
|||
border-radius: 20rpx; |
|||
|
|||
&:nth-child(2n) { |
|||
margin-right: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,82 @@ |
|||
<template> |
|||
<view class="recommend" ref="container"> |
|||
<view class="title acea-row row-center-wrapper"> |
|||
<text class="iconfont icon-zhuangshixian"></text> |
|||
<text class="name">为你推荐</text> |
|||
<text class="iconfont icon-zhuangshixian lefticon"></text> |
|||
</view> |
|||
<view class="recommendList acea-row row-between-wrapper"> |
|||
<view @click="routerGo(item)" class="item" v-for="(item, recommendIndex) in hostProduct" |
|||
:key="recommendIndex"> |
|||
<view class="pictrue"> |
|||
<image :src="item.image" class="image" /> |
|||
</view> |
|||
<view class="name line1">{{ item.storeName }}</view> |
|||
<view class="money font-color-red"> |
|||
¥ |
|||
<text class="num">{{ item.price }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<Loading :loaded="loadend" :loading="loading"></Loading> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { |
|||
getHostProducts |
|||
} from '@/api/store'; |
|||
import Loading from '@/components/Loading'; |
|||
export default { |
|||
name: 'Recommend', |
|||
props: { |
|||
recommendLoading: Boolean |
|||
}, |
|||
components: { |
|||
Loading |
|||
}, |
|||
watch: { |
|||
recommendLoading(nextLoading) { |
|||
if (nextLoading) { |
|||
this.hostProducts() |
|||
} |
|||
} |
|||
}, |
|||
data: function () { |
|||
return { |
|||
hostProduct: [], |
|||
page: 1, |
|||
limit: 20, |
|||
loadTitle: '', |
|||
loading: false, |
|||
loadend: false |
|||
}; |
|||
}, |
|||
mounted: function () { |
|||
this.hostProducts(); |
|||
}, |
|||
methods: { |
|||
routerGo(item) { |
|||
this.$yrouter.push({ |
|||
path: '/pages/shop/GoodsCon/index', |
|||
query: { |
|||
id: item.id |
|||
} |
|||
}); |
|||
}, |
|||
hostProducts: function () { |
|||
let that = this; |
|||
if (that.loading) return; //阻止下次请求(false可以进行请求); |
|||
if (that.loadend) return; //阻止结束当前请求(false可以进行请求); |
|||
that.loading = true; |
|||
getHostProducts(that.page, that.limit).then(res => { |
|||
that.loading = false; |
|||
//apply();js将一个数组插入另一个数组; |
|||
that.hostProduct.push.apply(that.hostProduct, res.data); |
|||
that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成; |
|||
that.page = that.page + 1; |
|||
this.$emit('changeRecommendLoading', false) |
|||
}); |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,40 @@ |
|||
<template> |
|||
<view v-if="shareInfoStatus" class="poster-first"> |
|||
<view class="mask-share"> |
|||
<!-- <image :src="`${$VUE_APP_RESOURCES_URL}/images/share-info.png`" @click="shareInfoClose" /> --> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<style scoped lang="less"> |
|||
.poster-first { |
|||
overscroll-behavior: contain; |
|||
} |
|||
.mask-share { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 999; |
|||
} |
|||
.mask-share image{ |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
<script> |
|||
export default { |
|||
name: "ShareInfo", |
|||
props: { |
|||
shareInfoStatus: Boolean |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
shareInfoClose: function() { |
|||
this.$emit("setShareInfoStatus"); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,43 @@ |
|||
<template> |
|||
<view class="sharing-packets" :class="state === true ? 'on' : ''"> |
|||
<view |
|||
class="iconfont icon-guanbi acea-row row-center-wrapper" |
|||
@click="closeShare" |
|||
></view> |
|||
<view class="line"></view> |
|||
<view class="sharing-con" @click="goShare"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/red-packets.png`" class="image" /> |
|||
<view class="text font-color-red"> |
|||
<view>会员分享返</view> |
|||
<view class="money"><text class="label">¥</text>{{ priceName }}</view> |
|||
<view class="tip">下单即返佣金</view> |
|||
<view class="shareBut">立即分享</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "ShareRedPackets", |
|||
props: { |
|||
priceName: { |
|||
type: [String, Number], |
|||
default: "" |
|||
} |
|||
}, |
|||
data: function() { |
|||
return { |
|||
state: false |
|||
}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
goShare: function() { |
|||
this.$emit("changeFun", { action: "shareCode", value: false }); |
|||
}, |
|||
closeShare: function() { |
|||
this.state = true; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,324 @@ |
|||
<template> |
|||
<view class="sp-live-card" :style="{ width: wh + 'rpx' }"> |
|||
<view class="live-content" @tap="goRoom" :style="{ width: wh + 'rpx' }"> |
|||
<image class="item-cover" :src="detail.shareImge" mode="aspectFill"></image> |
|||
<view class="item-status"> |
|||
<image class="status-img" :src="liveStatus[detail.liveStatus].img" mode=""></image> |
|||
<text class="status-text">{{ liveStatus[detail.liveStatus].title }}</text> |
|||
</view> |
|||
<view class="item-title" :style="{ width: wh + 'rpx' }">{{ detail.name }}</view> |
|||
</view> |
|||
<view class="live-bottom" :style="{ width: wh + 'rpx' }"> |
|||
<view class="live-info"> |
|||
<view class="info-box"> |
|||
<view class="info-name">{{ detail.anchorName }}</view> |
|||
</view> |
|||
</view> |
|||
<slot name="liveGoods"> |
|||
<view class="live-goods" v-if="detail.product.length"> |
|||
<view class="live-goods__item" v-for="(goods, index) in detail.product" :key="goods.goodsId" |
|||
v-if="index < 3"> |
|||
<image class="live-goods__img" :src="goods.coverImgeUrl" mode=""></image> |
|||
<view class="live-goods__price" v-if="index < 2">¥{{ goods.price }}</view> |
|||
<view class="live-goods__mark" v-else> |
|||
<text>{{ detail.product.length }}+</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
dataFormatL |
|||
} from "@/utils"; |
|||
let HAS_LIVE = false |
|||
// #ifdef MP-WEIXIN |
|||
HAS_LIVE = true |
|||
let livePlayer = null; |
|||
if (HAS_LIVE) { |
|||
livePlayer = requirePlugin('live-player-plugin'); |
|||
} |
|||
// #endif |
|||
let timer = null; |
|||
export default { |
|||
name: 'shopLiveCard', |
|||
components: {}, |
|||
data() { |
|||
return { |
|||
liveStatus: { |
|||
'101': { |
|||
img: 'https://wx.yixiang.co/static/images/live.png', |
|||
title: '直播中' |
|||
}, |
|||
'102': { |
|||
img: 'https://wx.yixiang.co/static/images/prevue.png', |
|||
title: '未开始' |
|||
}, |
|||
'103': { |
|||
img: 'https://wx.yixiang.co/static/images/playback.png', |
|||
title: '已结束' |
|||
}, |
|||
'104': { |
|||
img: 'https://wx.yixiang.co/static/images/104.png', |
|||
title: '禁播' |
|||
}, |
|||
'105': { |
|||
img: 'https://wx.yixiang.co/static/images/105.png', |
|||
title: '暂停中' |
|||
}, |
|||
'106': { |
|||
img: 'https://wx.yixiang.co/static/images/106.png', |
|||
title: '异常' |
|||
}, |
|||
'107': { |
|||
img: 'https://wx.yixiang.co/static/images/past.png', |
|||
title: '已过期' |
|||
} |
|||
} |
|||
}; |
|||
}, |
|||
props: { |
|||
detail: { |
|||
type: Object, |
|||
default: null |
|||
}, |
|||
wh: { |
|||
type: Number, |
|||
default: 345 |
|||
} |
|||
}, |
|||
|
|||
computed: {}, |
|||
created() { |
|||
this.getLiveStatus(); |
|||
}, |
|||
mounted() { |
|||
let that = this; |
|||
timer = setInterval(() => { |
|||
that.getLiveStatus(); |
|||
}, 60000); |
|||
}, |
|||
beforeDestroy() { |
|||
timer = null; |
|||
}, |
|||
methods: { |
|||
goRoom() { |
|||
let that = this; |
|||
wx.navigateTo({ |
|||
url: `plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id=${that.detail.roomId}` |
|||
}); |
|||
}, |
|||
dateFormat(fmt, date) { |
|||
let ret; |
|||
const opt = { |
|||
"Y+": date.getFullYear().toString(), // 年 |
|||
"m+": (date.getMonth() + 1).toString(), // 月 |
|||
"d+": date.getDate().toString(), // 日 |
|||
"H+": date.getHours().toString(), // 时 |
|||
"M+": date.getMinutes().toString(), // 分 |
|||
"S+": date.getSeconds().toString() // 秒 |
|||
// 有其他格式化字符需求可以继续添加,必须转化成字符串 |
|||
}; |
|||
for (let k in opt) { |
|||
ret = new RegExp("(" + k + ")").exec(fmt); |
|||
if (ret) { |
|||
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) |
|||
}; |
|||
}; |
|||
return fmt; |
|||
}, |
|||
// 轮询liveStatus |
|||
getLiveStatus() { |
|||
if (HAS_LIVE) { |
|||
let that = this; |
|||
let date = ''; |
|||
if (that.detail.liveStatus == 102) { |
|||
date = this.dateFormat('mm-dd HH:MM', new Date(that.detail.startTime * 1000)).replace('-','/'); |
|||
that.liveStatus['102'].title = '预告 ' + date; |
|||
} |
|||
// livePlayer |
|||
// .getLiveStatus({ |
|||
// room_id: that.detail.roomId |
|||
// }) |
|||
// .then(res => { |
|||
// // 101: 直播中, 102: 未开始, 103: 已结束, 104: 禁播, 105: 暂停中, 106: 异常,107:已过期 |
|||
// that.detail.liveStatus = res.liveStatus; |
|||
// }) |
|||
// .catch(err => { |
|||
// console.log('get live status', err); |
|||
// }); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.sp-live-card { |
|||
width: 344rpx; |
|||
box-shadow: 0px 0px 10rpx 4rpx rgba(199, 199, 199, 0.22); |
|||
border-radius: 20rpx; |
|||
height: 100%; |
|||
overflow: auto; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.live-content { |
|||
position: relative; |
|||
width: 344rpx; |
|||
height: 344rpx; |
|||
overflow: hidden; |
|||
|
|||
.item-cover { |
|||
background-color: #eee; |
|||
width: 100%; |
|||
height: 100%; |
|||
border-radius: 20rpx 20rpx 0 0; |
|||
} |
|||
|
|||
.item-status { |
|||
position: absolute; |
|||
top: 20rpx; |
|||
left: 10rpx; |
|||
height: 40rpx; |
|||
background: rgba(0, 0, 0, 0.4); |
|||
border-radius: 20rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
|
|||
.status-img { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
} |
|||
|
|||
.status-text { |
|||
font-size: 22rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(255, 255, 255, 1); |
|||
padding: 0 10rpx; |
|||
} |
|||
} |
|||
|
|||
.item-title { |
|||
width: 345rpx; |
|||
position: absolute; |
|||
bottom: 0; |
|||
line-height: 60rpx; |
|||
padding: 0 20rpx; |
|||
font-size: 26rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(255, 255, 255, 1); |
|||
background: linear-gradient(transparent, rgba(#000, 0.5)); |
|||
padding-right: 60rpx; |
|||
} |
|||
|
|||
.like-img { |
|||
position: absolute; |
|||
bottom: 20rpx; |
|||
right: 10rpx; |
|||
width: 60rpx; |
|||
height: 130rpx; |
|||
} |
|||
} |
|||
|
|||
.live-bottom { |
|||
background-color: #fff; |
|||
padding: 20rpx; |
|||
width: 345rpx; |
|||
|
|||
.live-info { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
width: 100%; |
|||
|
|||
.info-box { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.info-avatar { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
border-radius: 50%; |
|||
margin-right: 10rpx; |
|||
background: #eee; |
|||
} |
|||
|
|||
.info-name { |
|||
width: 150rpx; |
|||
font-size: 24rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(51, 51, 51, 1); |
|||
} |
|||
|
|||
.views { |
|||
font-size: 20rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 400; |
|||
color: rgba(153, 153, 153, 1); |
|||
} |
|||
} |
|||
|
|||
.live-goods { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-top: 20rpx; |
|||
|
|||
&__item { |
|||
position: relative; |
|||
width: 96rpx; |
|||
height: 96rpx; |
|||
border: 1rpx solid rgba(238, 238, 238, 1); |
|||
border-radius: 10rpx; |
|||
overflow: hidden; |
|||
margin-right: 8rpx; |
|||
|
|||
&:nth-child(3n) { |
|||
margin-right: 0; |
|||
} |
|||
} |
|||
|
|||
&__img { |
|||
background: #eee; |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
&__price { |
|||
position: absolute; |
|||
bottom: 0; |
|||
line-height: 40rpx; |
|||
width: 100%; |
|||
background: linear-gradient(transparent, rgba(#000, 0.5)); |
|||
font-size: 20rpx; |
|||
color: #fff; |
|||
} |
|||
|
|||
&__mark { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
top: 0; |
|||
left: 0; |
|||
margin: auto; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
|
|||
background: rgba(#000, 0.3); |
|||
font-size: 24rpx; |
|||
font-family: PingFang SC; |
|||
font-weight: 500; |
|||
color: rgba(255, 255, 255, 1); |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,243 @@ |
|||
<template> |
|||
<view v-if="posterImageStatus" class="poster-first"> |
|||
<div class="posterCanvasWarp"> |
|||
<canvas class="posterCanvas" canvas-id="myCanvas"></canvas> |
|||
</div> |
|||
<!-- <view class="poster-pop" v-show="!canvasStatus"> |
|||
<image |
|||
:src="`${$VUE_APP_RESOURCES_URL}/images/poster-close.png`" |
|||
class="close" |
|||
@click="posterImageClose" |
|||
/> |
|||
<view class="canvas" ref="poster"> |
|||
<image class="image" :src="posterData.image" alt="商品图片" /> |
|||
<view class="text black"> |
|||
<text v-text="posterData.title"></text> |
|||
</view> |
|||
<view class="text rad"> |
|||
<text v-text="'¥' + posterData.price"></text> |
|||
</view> |
|||
<view class="code"> |
|||
<view class="code-img"> |
|||
<image :src="posterData.code" show-menu-by-longpress mode="widthFix" alt="二维码" /> |
|||
</view> |
|||
<view class="code-text"> |
|||
<text>长按识别二维码 立即购买</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="save-poster" @click="savePosterPath">生成图片</view> |
|||
</view>--> |
|||
<view class="poster-pop" v-show="canvasStatus"> |
|||
<img :src="`${$VUE_APP_RESOURCES_URL}/images/poster-close.png`" class="close" @click="posterImageClose" mode="widthFix" /> |
|||
<image :src="posterImage" alt="tp" class="poster-image" show-menu-by-longpress mode="widthFix" /> |
|||
<view class="save-poster" @click="saveImg">保存海报</view> |
|||
</view> |
|||
<view class="mask"></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
// import html2canvas from "html2canvas"; |
|||
import { PosterCanvas } from '@/utils' |
|||
import { getProductPoster } from '@/api/store' |
|||
|
|||
export default { |
|||
name: 'StorePoster', |
|||
props: { |
|||
posterImageStatus: Boolean, |
|||
posterData: Object, |
|||
goodId: String, |
|||
}, |
|||
data: function() { |
|||
return { |
|||
canvasStatus: false, |
|||
posterImage: '', |
|||
} |
|||
}, |
|||
watch: { |
|||
posterImageStatus: function() { |
|||
var that = this |
|||
if (that.posterImageStatus === true) { |
|||
that.$nextTick(function() { |
|||
that.savePosterPath() |
|||
}) |
|||
} |
|||
}, |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
posterImageClose: function() { |
|||
this.posterImageStatus = false |
|||
this.canvasStatus = false |
|||
this.$emit('setPosterImageStatus') |
|||
}, |
|||
saveImg: function() { |
|||
this.downloadFile(this.posterImage) |
|||
}, |
|||
downloadFile(url) { |
|||
uni.downloadFile({ |
|||
url, |
|||
fail: function(res) { |
|||
console.log(res) |
|||
|
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '保存失败', |
|||
}) |
|||
}, |
|||
success: function(res) { |
|||
console.log(res) |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '保存成功', |
|||
}) |
|||
}, |
|||
}) |
|||
}, |
|||
savePosterPath: function() { |
|||
const that = this |
|||
|
|||
uni.showLoading({ |
|||
title: '海报生成中', |
|||
mask: true, |
|||
}) |
|||
getProductPoster(this.goodId, { |
|||
from: this.$deviceType == 'weixin' || this.$deviceType == 'weixinh5' ? 'uniappH5' : this.$deviceType, |
|||
}) |
|||
.then(res => { |
|||
this.canvasStatus = true |
|||
this.posterImage = res.data |
|||
}) |
|||
.finally(() => { |
|||
uni.hideLoading() |
|||
}) |
|||
// return; |
|||
// //清空图片重新生成 |
|||
// that.posterImage = ""; |
|||
// uni.showLoading({ title: "海报生成中", mask: true }); |
|||
// console.log(this); |
|||
// var prodId = that.$yrouter.currentRoute.query.id; |
|||
// uni.downloadFile({ |
|||
// url: |
|||
// this.$VUE_APP_API_URL + |
|||
// "/shareImg/" + |
|||
// prodId + |
|||
// "?shareImgName=" + |
|||
// this.posterData.code, |
|||
// fail: function(res) {}, |
|||
// success: function(res) { |
|||
// that.canvasStatus = true; |
|||
// that.posterImage = res.tempFilePath; |
|||
// uni.hideLoading(); |
|||
// } |
|||
// }); |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="less" lang="less"> |
|||
.poster-first { |
|||
overscroll-behavior: contain; |
|||
} |
|||
|
|||
.poster-pop { |
|||
width: 4.5 * 100rpx; |
|||
height: 8 * 100rpx; |
|||
position: fixed; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
z-index: 99; |
|||
top: 50%; |
|||
margin-top: -4.6 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .canvas { |
|||
background-color: #ffffff; |
|||
height: 8 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .poster-image { |
|||
width: 100%; |
|||
height: auto; |
|||
} |
|||
|
|||
.poster-pop .canvas .image { |
|||
width: 4.5 * 100rpx; |
|||
height: 4.5 * 100rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.poster-pop .canvas .text { |
|||
text-align: center; |
|||
color: #000000; |
|||
margin-top: 0.32 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .canvas .text.black { |
|||
height: 0.68 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .canvas .text.rad { |
|||
color: #ff0000; |
|||
} |
|||
|
|||
.poster-pop .canvas .code { |
|||
height: 1.4 * 100rpx; |
|||
display: flex; |
|||
} |
|||
|
|||
.poster-pop .canvas .code .code-img { |
|||
width: 33%; |
|||
padding: 0.06 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .canvas .code .code-img image { |
|||
width: 100%; |
|||
} |
|||
|
|||
.poster-pop .canvas .code .code-text { |
|||
width: 60%; |
|||
font-size: 0.12 * 100rpx; |
|||
line-height: 1.64 * 100rpx; |
|||
} |
|||
|
|||
.poster-pop .close { |
|||
width: 0.46 * 100rpx; |
|||
height: 0.75 * 100rpx; |
|||
position: fixed; |
|||
right: 0; |
|||
top: -0.73 * 100rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.poster-pop .save-poster { |
|||
background-color: #df2d0a; |
|||
font-size: 0.22 * 100rpx; |
|||
color: #fff; |
|||
text-align: center; |
|||
height: 0.76 * 100rpx; |
|||
line-height: 0.76 * 100rpx; |
|||
width: 100%; |
|||
margin-top: -0.1 * 100rpx; |
|||
border-radius: 0 0 10rpx 10rpx; |
|||
} |
|||
|
|||
.poster-pop .keep { |
|||
color: #fff; |
|||
text-align: center; |
|||
font-size: 0.25 * 100rpx; |
|||
margin-top: 0.1 * 100rpx; |
|||
} |
|||
|
|||
.mask { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.6); |
|||
z-index: 9; |
|||
} |
|||
</style> |
@ -0,0 +1,155 @@ |
|||
<template> |
|||
<view> |
|||
<view class="switchWindow" :class="switchActive === true ? 'on' : ''"> |
|||
<view class="pictrue"> |
|||
|
|||
</view> |
|||
<!-- 是否选择切换到小程序账户? --> |
|||
<view class="info"> |
|||
<text>是否选择切换到</text> |
|||
<text class="font-color" v-if="login_type === 'h5'">微信账号</text> |
|||
<text class="font-color" v-else>手机用户</text> |
|||
<text>?</text> |
|||
</view> |
|||
<view class="switchBnt" @click="switchH5"> |
|||
<text>切换</text> |
|||
</view> |
|||
<view class="switchBnt cancelBnt" @click="switchClose"> |
|||
<text>取消</text> |
|||
</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent v-show="switchActive === true" @click="switchClose"></view> |
|||
</view> |
|||
</template> |
|||
<style lang="less"> |
|||
.switchWindow { |
|||
width: 5.6*100rpx; |
|||
border-radius: 0.2*100rpx; |
|||
-webkit-border-radius: 0.2*100rpx; |
|||
background-color: #fff; |
|||
position: fixed; |
|||
top: 50%; |
|||
left: 50%; |
|||
margin-left: -2.8*100rpx; |
|||
margin-top: -3*100rpx; |
|||
z-index: 99; |
|||
padding: 0.5*100rpx 0.3*100rpx 0.4*100rpx 0.3*100rpx; |
|||
text-align: center; |
|||
box-sizing: border-box; |
|||
-webkit-box-sizing: border-box; |
|||
transition: all 0.3s ease-in-out 0s; |
|||
-webkit-transition: all 0.3s ease-in-out 0s; |
|||
-moz-transition: all 0.3s ease-in-out 0s; |
|||
-o-transition: all 0.3s ease-in-out 0s; |
|||
opacity: 0; |
|||
transform: scale(0); |
|||
} |
|||
|
|||
.switchWindow.on { |
|||
opacity: 1; |
|||
transform: scale(1); |
|||
-webkit-transform: scale(1); |
|||
-ms-transform: scale(1); |
|||
-moz-transform: scale(1); |
|||
-o-transform: scale(1); |
|||
} |
|||
|
|||
.switchWindow .pictrue { |
|||
width: 2.36*100rpx; |
|||
height: 2.36*100rpx; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.switchWindow .pictrue image { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: block; |
|||
} |
|||
|
|||
.switchWindow .info { |
|||
font-size: 0.32*100rpx; |
|||
color: #282828; |
|||
margin-top: 0.44*100rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.switchWindow .switchBnt { |
|||
font-size: 0.32*100rpx; |
|||
color: #fff; |
|||
width: 3.6*100rpx; |
|||
height: 0.82*100rpx; |
|||
border-radius: 0.41*100rpx; |
|||
-webkit-border-radius: 0.41*100rpx; |
|||
margin: 0.57*100rpx auto 0 auto; |
|||
line-height: 0.82*100rpx; |
|||
background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
} |
|||
|
|||
.switchWindow .switchBnt.cancelBnt { |
|||
background-color: #fff; |
|||
color: #999; |
|||
background-image: none; |
|||
margin-top: 0.1*100rpx; |
|||
} |
|||
</style> |
|||
<script> |
|||
import { switchH5Login } from "@/api/user"; |
|||
import cookie from "@/utils/store/cookie"; |
|||
import store from "@//store"; |
|||
import dayjs from "dayjs"; |
|||
|
|||
export default { |
|||
name: "SwitchWindow", |
|||
props: { |
|||
switchActive: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
login_type: { |
|||
type: String, |
|||
default: "" |
|||
} |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
switchClose: function() { |
|||
this.$emit("changeswitch", false); //$emit():注册事件; |
|||
}, |
|||
switchH5() { |
|||
let that = this; |
|||
uni.showLoading({ |
|||
title: "正在切换中" |
|||
}); |
|||
if (that.login_type === "h5") { |
|||
cookie.set("loginType", "wechat", 60); |
|||
uni.hideLoading(); |
|||
this.$store.commit("logout"); |
|||
this.$emit("changeswitch", false); |
|||
location.reload(); |
|||
} else { |
|||
switchH5Login() |
|||
.then(({ data }) => { |
|||
uni.hideLoading(); |
|||
const expires_time = dayjs(data.expires_time); |
|||
store.commit("login", data.token, expires_time); |
|||
this.$emit("changeswitch", false); |
|||
location.reload(); |
|||
}) |
|||
.catch(err => { |
|||
uni.hideLoading(); |
|||
uni.showToast({ |
|||
title: err.msg || err.response.data.msg|| err.response.data.message, |
|||
icon: "none", |
|||
duration: 2000 |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,52 @@ |
|||
<template> |
|||
<view class="evaluateWtapper" v-if="reply&&reply.length>0"> |
|||
<view v-for="(item, evaluateWtapperIndex) in reply" :key="evaluateWtapperIndex"> |
|||
<view class="evaluateItem" v-if="item"> |
|||
<view class="pic-text acea-row row-middle"> |
|||
<view class="pictrue"> |
|||
<image :src="item.avatar" class="image" /> |
|||
</view> |
|||
<view class="acea-row row-middle"> |
|||
<view class="name line1">{{ item.nickname }}</view> |
|||
<view class="start" :class="'star' + item.star"></view> |
|||
</view> |
|||
</view> |
|||
<view class="time">{{ item.createTime }} {{ item.sku||'' }}</view> |
|||
<view class="evaluate-infor">{{ item.comment }}</view> |
|||
<view class="imgList acea-row"> |
|||
<view class="pictrue" v-for="(itemn, eq) in item.picturesArr" :key="eq"> |
|||
<image :src="itemn" class="image" /> |
|||
</view> |
|||
</view> |
|||
<view class="reply" v-if="item.merchantReplyContent"> |
|||
<span class="font-color-red">yshop店员</span> |
|||
:{{item.merchantReplyContent}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { |
|||
dataFormat |
|||
} from "@/utils"; |
|||
|
|||
export default { |
|||
name: "UserEvaluation", |
|||
props: { |
|||
reply: { |
|||
type: Array, |
|||
default: () => [] |
|||
} |
|||
}, |
|||
data: function () { |
|||
return {}; |
|||
}, |
|||
mounted: function () { |
|||
console.log(this) |
|||
}, |
|||
methods: { |
|||
dataFormat |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,127 @@ |
|||
<template> |
|||
<view v-show="iShidden === false"> |
|||
<view class="WriteOff"> |
|||
<view class="num acea-row row-center-wrapper"> |
|||
{{ orderInfo.orderId }} |
|||
</view> |
|||
<view class="tip">确定要核销此订单吗?</view> |
|||
<view class="sure" @click="confirm">确定核销</view> |
|||
<view class="sure cancel" @click="cancel">取消</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent></view> |
|||
</view> |
|||
</template> |
|||
<style scoped lang="less"> |
|||
.WriteOff { |
|||
width: 5.6*100rpx; |
|||
height: 5*100rpx; |
|||
background-color: #fff; |
|||
border-radius: 0.2*100rpx; |
|||
position: fixed; |
|||
top: 50%; |
|||
left: 50%; |
|||
margin-top: -4*100rpx; |
|||
margin-left: -2.8*100rpx; |
|||
padding-top: 0.55*100rpx; |
|||
z-index: 99999; |
|||
} |
|||
.WriteOff .pictrue { |
|||
width: 3.4*100rpx; |
|||
height: 3.4*100rpx; |
|||
margin: 0 auto; |
|||
} |
|||
.WriteOff .pictrue image{ |
|||
width: 100%; |
|||
height: 100%; |
|||
display: block; |
|||
border-radius: 0.1*100rpx; |
|||
} |
|||
.WriteOff .num { |
|||
font-size: 0.3*100rpx; |
|||
color: #666; |
|||
margin: 0.28*100rpx 0 0.3*100rpx 0; |
|||
} |
|||
.WriteOff .num .see { |
|||
font-size: 0.16*100rpx; |
|||
color: #fff; |
|||
border-radius: 0.04*100rpx; |
|||
background-color: #c68937; |
|||
padding-left: 0.05*100rpx; |
|||
margin-left: 0.12*100rpx; |
|||
} |
|||
.WriteOff .num .see .iconfont { |
|||
font-size: 0.15*100rpx; |
|||
} |
|||
.WriteOff .tip { |
|||
font-size: 0.36*100rpx; |
|||
color: #282828; |
|||
text-align: center; |
|||
border-top: 1px dashed #ccc; |
|||
padding-top: 0.4*100rpx; |
|||
position: relative; |
|||
} |
|||
.WriteOff .tip:after { |
|||
content: ""; |
|||
position: absolute; |
|||
width: 0.25*100rpx; |
|||
height: 0.25*100rpx; |
|||
border-radius: 50%; |
|||
background-color: #7f7f7f; |
|||
right: -0.125*100rpx; |
|||
top: -0.125*100rpx; |
|||
} |
|||
.WriteOff .tip:before { |
|||
content: ""; |
|||
position: absolute; |
|||
width: 0.25*100rpx; |
|||
height: 0.25*100rpx; |
|||
border-radius: 50%; |
|||
background-color: #7f7f7f; |
|||
left: -0.125*100rpx; |
|||
top: -0.125*100rpx; |
|||
} |
|||
.WriteOff .sure { |
|||
font-size: 0.32*100rpx; |
|||
color: #fff; |
|||
text-align: center; |
|||
line-height: 0.82*100rpx; |
|||
height: 0.82*100rpx; |
|||
width: 4.6*100rpx; |
|||
border-radius: 0.41*100rpx; |
|||
margin: 0.4*100rpx auto 0 auto; |
|||
background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%); |
|||
} |
|||
.WriteOff .sure.cancel { |
|||
background-image: none; |
|||
color: #999; |
|||
margin-top: 0.1*100rpx; |
|||
} |
|||
</style> |
|||
<script> |
|||
export default { |
|||
name: "WriteOff", |
|||
props: { |
|||
iShidden: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
orderInfo: { |
|||
type: Object |
|||
} |
|||
}, |
|||
data: function() { |
|||
return {}; |
|||
}, |
|||
mounted: function() {}, |
|||
methods: { |
|||
cancel: function() { |
|||
this.$emit("cancel", true); |
|||
}, |
|||
confirm: function() { |
|||
this.$emit("confirm", true); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,184 @@ |
|||
/* |
|||
Animation 微动画 |
|||
基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28 |
|||
*/ |
|||
|
|||
/* css 滤镜 控制黑白底色gif的 */ |
|||
.gif-black{ |
|||
mix-blend-mode: screen; |
|||
} |
|||
.gif-white{ |
|||
mix-blend-mode: multiply; |
|||
} |
|||
|
|||
|
|||
/* Animation css */ |
|||
[class*=animation-] { |
|||
animation-duration: .5s; |
|||
animation-timing-function: ease-out; |
|||
animation-fill-mode: both |
|||
} |
|||
|
|||
.animation-fade { |
|||
animation-name: fade; |
|||
animation-duration: .8s; |
|||
animation-timing-function: linear |
|||
} |
|||
|
|||
.animation-scale-up { |
|||
animation-name: scale-up |
|||
} |
|||
|
|||
.animation-scale-down { |
|||
animation-name: scale-down |
|||
} |
|||
|
|||
.animation-slide-top { |
|||
animation-name: slide-top |
|||
} |
|||
|
|||
.animation-slide-bottom { |
|||
animation-name: slide-bottom |
|||
} |
|||
|
|||
.animation-slide-left { |
|||
animation-name: slide-left |
|||
} |
|||
|
|||
.animation-slide-right { |
|||
animation-name: slide-right |
|||
} |
|||
|
|||
.animation-shake { |
|||
animation-name: shake |
|||
} |
|||
|
|||
.animation-reverse { |
|||
animation-direction: reverse |
|||
} |
|||
|
|||
@keyframes fade { |
|||
0% { |
|||
opacity: 0 |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1 |
|||
} |
|||
} |
|||
|
|||
@keyframes scale-up { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(.2) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: scale(1) |
|||
} |
|||
} |
|||
|
|||
@keyframes scale-down { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(1.8) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: scale(1) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-top { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateY(-100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateY(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-bottom { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateY(100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateY(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes shake { |
|||
|
|||
0%, |
|||
100% { |
|||
transform: translateX(0) |
|||
} |
|||
|
|||
10% { |
|||
transform: translateX(-9px) |
|||
} |
|||
|
|||
20% { |
|||
transform: translateX(8px) |
|||
} |
|||
|
|||
30% { |
|||
transform: translateX(-7px) |
|||
} |
|||
|
|||
40% { |
|||
transform: translateX(6px) |
|||
} |
|||
|
|||
50% { |
|||
transform: translateX(-5px) |
|||
} |
|||
|
|||
60% { |
|||
transform: translateX(4px) |
|||
} |
|||
|
|||
70% { |
|||
transform: translateX(-3px) |
|||
} |
|||
|
|||
80% { |
|||
transform: translateX(2px) |
|||
} |
|||
|
|||
90% { |
|||
transform: translateX(-1px) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-left { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateX(-100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateX(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-right { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateX(100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateX(0) |
|||
} |
|||
} |
@ -0,0 +1,70 @@ |
|||
<template> |
|||
<view class="cu-custom" :style="[{height:CustomBar + 'px'}]"> |
|||
<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]"> |
|||
<view class="action" @tap="BackPage" v-if="isBack"> |
|||
<text class="cuIcon-back"></text> |
|||
<slot name="backText"></slot> |
|||
</view> |
|||
<view class="content" :style="[{top:StatusBar + 'px'}]"> |
|||
<slot name="content"></slot> |
|||
</view> |
|||
<slot name="right"></slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
StatusBar: this.StatusBar, |
|||
CustomBar: this.CustomBar |
|||
}; |
|||
}, |
|||
name: 'cu-custom', |
|||
computed: { |
|||
style() { |
|||
var StatusBar = this.StatusBar; |
|||
var CustomBar = this.CustomBar; |
|||
var bgImage = this.bgImage; |
|||
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;background:${this.bgColor} ;`; |
|||
if (this.bgImage) { |
|||
style = `${style}background-image:url(${bgImage});`; |
|||
} |
|||
return style |
|||
} |
|||
}, |
|||
props: { |
|||
bgColor: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
isBack: { |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
bgImage: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
}, |
|||
methods: { |
|||
BackPage() { |
|||
uni.navigateBack({ |
|||
delta: 1 |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.fixed{ |
|||
position: fixed; |
|||
top:0; |
|||
left:0; |
|||
right:0; |
|||
z-index: 99; |
|||
|
|||
} |
|||
</style> |
1226
components/colorui/icon.css
File diff suppressed because it is too large
View File
4040
components/colorui/main.css
File diff suppressed because it is too large
View File
@ -0,0 +1,40 @@ |
|||
<template> |
|||
<view class="min-goods" @tap="jump('/pages/activity/GroupDetails/index', { id: detail.id })"> |
|||
<view class="img-box"> |
|||
<view class="tag" >{{ detail.people}}人团</view> |
|||
<image class="img" :src="detail.image" mode="widthFix"></image> |
|||
</view> |
|||
<view class="price-box"> |
|||
<view class="y-f"> |
|||
<text class="seckill-current">¥{{ detail.price }}</text> |
|||
<text class="original">销量{{ detail.sales }}{{detail.unitName}}</text> |
|||
</view> |
|||
</view> |
|||
<view class="title"><slot name="titleText"></slot></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: {}, |
|||
data() { |
|||
return {}; |
|||
}, |
|||
props: { |
|||
detail: Object |
|||
}, |
|||
computed: {}, |
|||
methods: { |
|||
// 路由跳转 |
|||
jump(path, query) { |
|||
this.$yrouter.push({ |
|||
path, |
|||
query |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
</style> |
@ -0,0 +1,217 @@ |
|||
<template> |
|||
<view class="adv-box mx20 mb10"> |
|||
<!-- 模板1--> |
|||
<view class="x-f" v-if="detail.style == 1"> |
|||
<image style="width: 710rpx; height: 220rpx" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
</view> |
|||
<!-- 模板2--> |
|||
<view class="type1 x-f" v-if="detail.style == 2"> |
|||
<image class="type1-img" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"> </image> |
|||
<image class="type1-img" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"> </image> |
|||
</view> |
|||
<!-- 模板3--> |
|||
<view class="type2 x-bc" v-if="detail.style == 3"> |
|||
<image class="type2-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"> </image> |
|||
<view class="y-f type2-box"> |
|||
<image class="type2-img2" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill" style="border-bottom: 1rpx solid #f6f6f6"></image> |
|||
<image class="type2-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
<!-- 模板4--> |
|||
<view class="type3 x-bc" v-if="detail.style == 4"> |
|||
<view class="type3-box y-f"> |
|||
<image class="type3-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type3-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<image class="type3-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"> </image> |
|||
</view> |
|||
<!-- 模板5--> |
|||
<view class="type4 y-f" v-if="detail.style == 5"> |
|||
<view class="type4-box x-f"> |
|||
<image class="type4-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type4-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<image class="type4-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"> </image> |
|||
</view> |
|||
<!-- 模板6--> |
|||
<view class="type5 y-f" v-if="detail.style == 6"> |
|||
<image class="type5-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"> </image> |
|||
<view class="type5-box x-bc"> |
|||
<image class="type5-img2" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill" style="border-bottom: 1rpx solid #f6f6f6"></image> |
|||
<image class="type5-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
<!-- 模板7--> |
|||
<view class="type6 y-f" v-if="detail.style == 7"> |
|||
<view class="x-f type6-box1"> |
|||
<image class="type6-img1" @tap="jump(detail.list[0])" :src="detail.list[0].image" mode="aspectFill"></image> |
|||
<image class="type6-img1" @tap="jump(detail.list[1])" :src="detail.list[1].image" mode="aspectFill"></image> |
|||
</view> |
|||
<view class="x-f type6-box2"> |
|||
<image class="type6-img2" @tap="jump(detail.list[2])" :src="detail.list[2].image" mode="aspectFill"></image> |
|||
<image class="type6-img2" @tap="jump(detail.list[3])" :src="detail.list[3].image" mode="aspectFill"></image> |
|||
<image class="type6-img2" @tap="jump(detail.list[4])" :src="detail.list[4].image" mode="aspectFill"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: {}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
detail: Object, |
|||
}, |
|||
computed: {}, |
|||
created() {}, |
|||
mounted() { |
|||
console.log(this) |
|||
}, |
|||
methods: { |
|||
// 路由跳转 |
|||
jump(item) { |
|||
if (item.uniapp_url) { |
|||
this.$yrouter.push(item.uniapp_url) |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.adv-box { |
|||
background-color: #fff; |
|||
border-radius: 20rpx; |
|||
overflow: hidden; |
|||
image { |
|||
width: 100%; |
|||
} |
|||
.type1 { |
|||
.type1-img { |
|||
flex: 1; |
|||
height: 220rpx; |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type2 { |
|||
.type2-img1 { |
|||
width: (710rpx/2); |
|||
height: 340rpx; |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
|
|||
.type2-box { |
|||
flex: 1; |
|||
height: 340rpx; |
|||
width: (710rpx/2); |
|||
|
|||
.type2-img2 { |
|||
height: (340rpx/2); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type3 { |
|||
.type3-box { |
|||
width: (710rpx/2); |
|||
border-right: 1rpx solid #f6f6f6; |
|||
|
|||
.type3-img1 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type3-img2 { |
|||
flex: 1; |
|||
height: 340rpx; |
|||
width: (710rpx/2); |
|||
} |
|||
} |
|||
|
|||
.type4 { |
|||
.type4-box { |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
|
|||
.type4-img1 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type4-img2 { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
width: 710rpx; |
|||
} |
|||
} |
|||
|
|||
.type5 { |
|||
.type5-img1 { |
|||
width: 710rpx; |
|||
height: (340rpx/2); |
|||
border-bottom: 1rpx solid #f6f6f6; |
|||
} |
|||
|
|||
.type5-box { |
|||
flex: 1; |
|||
height: (340rpx/2); |
|||
width: 710rpx; |
|||
|
|||
.type5-img2 { |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type6 { |
|||
.type6-box1 { |
|||
.type6-img1 { |
|||
width: (710rpx/2); |
|||
height: (340rpx/2); |
|||
|
|||
&:first-child { |
|||
border-right: 1rpx solid #f6f6f6; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.type6-box2 { |
|||
border-top: 1rpx solid #f6f6f6; |
|||
|
|||
.type6-img2 { |
|||
width: (710rpx/3); |
|||
height: (340rpx/2); |
|||
border-right: 1rpx solid #f6f6f6; |
|||
|
|||
&:last-child { |
|||
border-right: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
image { |
|||
// background-color: #ccc; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,197 @@ |
|||
<template> |
|||
<!-- 今日必拼 --> |
|||
<view class="group-goods pa20 mx20 mb10"> |
|||
<view class="title-box x-bc" @tap="jump('/pages/activity/GoodsGroup/index')"> |
|||
<text class="title">超值拼团</text> |
|||
<view class="group-people x-f"> |
|||
<text class="tip">更多</text> |
|||
<text class="cuIcon-right"></text> |
|||
</view> |
|||
</view> |
|||
<view class="goods-box swiper-box x-f"> |
|||
<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="goods-list-box x-f"> |
|||
<block v-for="mgoods in goods" :key="mgoods.id"> |
|||
<sh-activity-goods :detail="mgoods" class="goods-item"> |
|||
<!-- <block slot="titleText">立减¥8.5</block> --> |
|||
</sh-activity-goods> |
|||
</block> |
|||
</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> |
|||
</template> |
|||
|
|||
<script> |
|||
import shActivityGoods from './sh-activity-goods.vue'; |
|||
export default { |
|||
name: 'shGroupon', |
|||
components: { |
|||
shActivityGoods |
|||
}, |
|||
data() { |
|||
return { |
|||
goodsList: [], |
|||
swiperCurrent: 0 |
|||
}; |
|||
}, |
|||
props: { |
|||
detail: Array |
|||
}, |
|||
computed: {}, |
|||
created() {}, |
|||
watch: { |
|||
detail(next) { |
|||
this.goodsList = this.sortData(next, 4); |
|||
} |
|||
}, |
|||
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; |
|||
}, |
|||
jump(path, query) { |
|||
this.$yrouter.push({ |
|||
path, |
|||
query, |
|||
}); |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.swiper-box, |
|||
.carousel { |
|||
width: 700rpx; |
|||
height: 240upx; |
|||
position: relative; |
|||
border-radius: 20rpx; |
|||
|
|||
.carousel-item { |
|||
width: 100%; |
|||
height: 100%; |
|||
// padding: 0 28upx; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.swiper-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
// border-radius: 10upx; |
|||
background: #ccc; |
|||
} |
|||
} |
|||
|
|||
.swiper-dots { |
|||
display: flex; |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
bottom: 0rpx; |
|||
z-index: 66; |
|||
|
|||
.dot { |
|||
width: 45rpx; |
|||
height: 3rpx; |
|||
background: #eee; |
|||
border-radius: 50%; |
|||
margin-right: 10rpx; |
|||
} |
|||
|
|||
.dot-active { |
|||
width: 45rpx; |
|||
height: 3rpx; |
|||
background: #a8700d; |
|||
border-radius: 50%; |
|||
margin-right: 10rpx; |
|||
} |
|||
} |
|||
|
|||
// 今日必拼+限时抢购 |
|||
.group-goods { |
|||
background: #fff; |
|||
border-radius: 20rpx; |
|||
overflow: hidden; |
|||
|
|||
.title-box { |
|||
padding-bottom: 20rpx; |
|||
|
|||
.title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.group-people { |
|||
.time-box { |
|||
font-size: 26rpx; |
|||
color: #edbf62; |
|||
|
|||
.count-text-box { |
|||
width: 30rpx; |
|||
height: 34rpx; |
|||
background: #edbf62; |
|||
text-align: center; |
|||
line-height: 34rpx; |
|||
font-size: 24rpx; |
|||
border-radius: 6rpx; |
|||
color: rgba(#fff, 0.9); |
|||
margin: 0 8rpx; |
|||
} |
|||
} |
|||
|
|||
.head-box { |
|||
.head-img { |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
border-radius: 50%; |
|||
background: #ccc; |
|||
} |
|||
} |
|||
|
|||
.tip { |
|||
font-size: 28rpx; |
|||
padding-left: 30rpx; |
|||
color: #666; |
|||
} |
|||
|
|||
.cuIcon-right { |
|||
font-size: 30rpx; |
|||
line-height: 28rpx; |
|||
color: #666; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.goods-box { |
|||
.goods-item { |
|||
margin-right: 22rpx; |
|||
|
|||
&:nth-child(4n) { |
|||
margin-right: 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,203 @@ |
|||
<template> |
|||
<view class="tui-goods__item" :class="{ 'tui-full__item': isList }"> |
|||
<view class="tui-image__box" :class="{ 'tui-full__imgbox': isList }"> |
|||
<image class="tui-goods__img" :class="{ 'tui-full__img': isList }" :src="item.image" mode="widthFix"></image> |
|||
</view> |
|||
<view class="tui-goods__content" :class="{ 'tui-full__content': isList }"> |
|||
<view class="tui-goods__title">{{ item.title || '' }}</view> |
|||
<view class="progress cart-color"> |
|||
<view class="bg-red" :style="{ width: loading ? item.percent + '%' : '' }"></view> |
|||
<view class="piece font-color-red" v-text="'仅剩' + item.stock + '件'"></view> |
|||
</view> |
|||
<view class="tui-tag__box"><tui-tag plain size="24rpx" type="red" padding="8rpx 12rpx">限时价</tui-tag></view> |
|||
<view class="tui-box__bottom"> |
|||
<view class="tui-price__box"> |
|||
<view class="tui-price"> |
|||
<view class="tui-price__small">¥</view> |
|||
<view class="tui-price__large">{{ item.price || '' }}</view> |
|||
<!-- <view class="tui-price__small">.{{ decimalPrice }}</view> --> |
|||
</view> |
|||
<!-- <view class="tui-price__original">¥{{ item.factory || '0.00' }}</view> --> |
|||
</view> |
|||
<view> |
|||
<!-- <tui-button :width="status == 3 ? '146rpx' : '144rpx'" :height="status == 3 ? '60rpx' : '50rpx'" :size="status == 3 ? 26 : 24" :type="status == 1 ? 'gray' : 'danger'" :disabled="status == 1" :plain="status == 3"> |
|||
{{ status | getBtnText(item.subscribe) }} |
|||
</tui-button> --> |
|||
<view class="grab bg-color-red" v-if="timeList[active].status === 1 && item.stock > 0" @click="goDetail">马上抢</view> |
|||
<view class="grab" v-if="timeList[active].status === 1 && item.stock <= 0">已售磬</view> |
|||
<view class="grab bg-color-red" v-if="timeList[active].status === 2">即将开始</view> |
|||
<view class="grab bg-color-red" v-if="timeList[active].status === 0" >已结束</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'tGoodsItem', |
|||
props: { |
|||
item: { |
|||
type: Object, |
|||
default() { |
|||
return {} |
|||
}, |
|||
}, |
|||
//是否为列表展示 |
|||
isList: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
//status:1-已结束,2-正在进行,3-即将开枪 |
|||
status: { |
|||
type: Number, |
|||
default: 2, |
|||
}, |
|||
timeList: { |
|||
type: Array, |
|||
default: [], |
|||
}, |
|||
active: { |
|||
type: Number, |
|||
default: 0, |
|||
}, |
|||
}, |
|||
filters: { |
|||
getBtnText(status, subscribe) { |
|||
status = status || 1 |
|||
let text = ['活动已结束', '立即抢购', '立即预约'][status - 1] |
|||
if (status == 3 && subscribe) { |
|||
text = '取消预约' |
|||
} |
|||
return text |
|||
}, |
|||
}, |
|||
computed: { |
|||
integerPrice: function() { |
|||
let price = this.item.sale || '0.00' |
|||
if (~price.indexOf('.')) { |
|||
return price.split('.')[0] |
|||
} |
|||
return price |
|||
}, |
|||
decimalPrice: function() { |
|||
let price = this.item.sale || '0.00' |
|||
if (~price.indexOf('.')) { |
|||
return price.split('.')[1] |
|||
} |
|||
return '00' |
|||
}, |
|||
}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
methods: { |
|||
goDetail: function() { |
|||
this.$emit('goDetail', this.item) |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.tui-goods__item { |
|||
width: 100%; |
|||
padding: 20rpx 20rpx 36rpx; |
|||
box-sizing: border-box; |
|||
border-radius: 12rpx; |
|||
background-color: #fff; |
|||
margin-bottom: 4%; |
|||
position: relative; |
|||
} |
|||
.tui-full__item { |
|||
display: flex; |
|||
margin-bottom: 20rpx !important; |
|||
padding: 20rpx !important; |
|||
} |
|||
.tui-img__newguest { |
|||
position: absolute; |
|||
width: 96rpx; |
|||
height: 32rpx; |
|||
left: 0; |
|||
top: 8rpx; |
|||
} |
|||
.tui-image__box { |
|||
width: 100%; |
|||
height: 300rpx; |
|||
} |
|||
.tui-full__imgbox { |
|||
width: 240rpx !important; |
|||
height: 240rpx !important; |
|||
margin-right: 20rpx; |
|||
} |
|||
.tui-goods__img { |
|||
max-width: 100%; |
|||
max-height: 300rpx; |
|||
display: block; |
|||
border-radius: 8rpx; |
|||
} |
|||
.tui-full__img { |
|||
max-height: 240rpx !important; |
|||
} |
|||
.tui-goods__content { |
|||
width: 100%; |
|||
padding-top: 16rpx; |
|||
} |
|||
.tui-full__content { |
|||
height: 240rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
padding-top: 0 !important; |
|||
} |
|||
.tui-goods__title { |
|||
font-size: 26rpx; |
|||
font-weight: 400; |
|||
color: #333; |
|||
word-break: break-all; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
display: -webkit-box; |
|||
-webkit-box-orient: vertical; |
|||
-webkit-line-clamp: 2; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
.tui-tag__box { |
|||
display: flex; |
|||
padding-top: 25rpx; |
|||
padding-bottom: 25rpx; |
|||
} |
|||
.tui-box__bottom { |
|||
width: 100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
.tui-price__box { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.tui-price { |
|||
display: flex; |
|||
align-items: flex-end; |
|||
color: #eb0909; |
|||
} |
|||
.tui-price__small { |
|||
font-size: 24rpx; |
|||
line-height: 24rpx; |
|||
} |
|||
.tui-price__large { |
|||
font-size: 34rpx; |
|||
line-height: 32rpx; |
|||
font-weight: 600; |
|||
} |
|||
.tui-price__original { |
|||
font-size: 24rpx; |
|||
line-height: 24rpx; |
|||
text-decoration: line-through; |
|||
color: #999; |
|||
padding-top: 10rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,495 @@ |
|||
<template> |
|||
<button class="tui-btn" :class="[plain ? 'tui-' + type + '-outline' : 'tui-btn-' + (type || 'primary'), getDisabledClass(disabled, type, plain), getShapeClass(shape, plain), getShadowClass(type, shadow, plain), bold ? 'tui-text-bold' : '', link ? 'tui-btn__link' : '']" :hover-class="getHoverClass(disabled, type, plain)" :style="{ width: width, height: height, lineHeight: height, fontSize: size + 'rpx', margin: margin }" :loading="loading" :form-type="formType" :open-type="openType" @getuserinfo="bindgetuserinfo" @getphonenumber="bindgetphonenumber" @contact="bindcontact" @error="binderror" :disabled="disabled" @tap="handleClick"> |
|||
<slot></slot> |
|||
</button> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'tui-button', |
|||
props: { |
|||
//样式类型 primary, white, danger, warning, green,blue, gray,black,brown,gray-primary,gray-danger,gray-warning,gray-green |
|||
type: { |
|||
type: String, |
|||
default: 'primary', |
|||
}, |
|||
//是否加阴影 |
|||
shadow: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
// 宽度 rpx或 % |
|||
width: { |
|||
type: String, |
|||
default: '100%', |
|||
}, |
|||
//高度 rpx |
|||
height: { |
|||
type: String, |
|||
default: '96rpx', |
|||
}, |
|||
//字体大小 rpx |
|||
size: { |
|||
type: Number, |
|||
default: 32, |
|||
}, |
|||
bold: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
margin: { |
|||
type: String, |
|||
default: '0', |
|||
}, |
|||
//形状 circle(圆角), square(默认方形),rightAngle(平角) |
|||
shape: { |
|||
type: String, |
|||
default: 'square', |
|||
}, |
|||
plain: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
//link样式,去掉边框,结合plain一起使用 |
|||
link: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
//禁用后背景是否为灰色 (非空心button生效) |
|||
disabledGray: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
loading: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
formType: { |
|||
type: String, |
|||
default: '', |
|||
}, |
|||
openType: { |
|||
type: String, |
|||
default: '', |
|||
}, |
|||
index: { |
|||
type: [Number, String], |
|||
default: 0, |
|||
}, |
|||
//是否需要阻止重复点击【默认200ms】 |
|||
preventClick: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
time: 0, |
|||
} |
|||
}, |
|||
methods: { |
|||
handleClick() { |
|||
if (this.disabled) return |
|||
if (this.preventClick) { |
|||
if (new Date().getTime() - this.time <= 200) return |
|||
this.time = new Date().getTime() |
|||
setTimeout(() => { |
|||
this.time = 0 |
|||
}, 200) |
|||
} |
|||
this.$emit('click', { |
|||
index: Number(this.index), |
|||
}) |
|||
}, |
|||
bindgetuserinfo({ detail = {} } = {}) { |
|||
this.$emit('getuserinfo', detail) |
|||
}, |
|||
bindcontact({ detail = {} } = {}) { |
|||
this.$emit('contact', detail) |
|||
}, |
|||
bindgetphonenumber({ detail = {} } = {}) { |
|||
this.$emit('getphonenumber', detail) |
|||
}, |
|||
binderror({ detail = {} } = {}) { |
|||
this.$emit('error', detail) |
|||
}, |
|||
getShadowClass: function(type, shadow, plain) { |
|||
let className = '' |
|||
if (shadow && type != 'white' && !plain) { |
|||
className = 'tui-shadow-' + type |
|||
} |
|||
return className |
|||
}, |
|||
getDisabledClass: function(disabled, type, plain) { |
|||
let className = '' |
|||
if (disabled && type != 'white' && type.indexOf('-') == -1) { |
|||
let classVal = this.disabledGray ? 'tui-gray-disabled' : 'tui-dark-disabled' |
|||
className = plain ? 'tui-dark-disabled-outline' : classVal |
|||
} |
|||
return className |
|||
}, |
|||
getShapeClass: function(shape, plain) { |
|||
let className = '' |
|||
if (shape == 'circle') { |
|||
className = plain ? 'tui-outline-fillet' : 'tui-fillet' |
|||
} else if (shape == 'rightAngle') { |
|||
className = plain ? 'tui-outline-rightAngle' : 'tui-rightAngle' |
|||
} |
|||
return className |
|||
}, |
|||
getHoverClass: function(disabled, type, plain) { |
|||
let className = '' |
|||
if (!disabled) { |
|||
className = plain ? 'tui-outline-hover' : 'tui-' + (type || 'primary') + '-hover' |
|||
} |
|||
return className |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.tui-btn-primary { |
|||
background: #5677fc !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-shadow-primary { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(86, 119, 252, 0.2); |
|||
} |
|||
|
|||
.tui-btn-danger { |
|||
background: #eb0909 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-shadow-danger { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.2); |
|||
} |
|||
|
|||
.tui-btn-warning { |
|||
background: #fc872d !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-shadow-warning { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(252, 135, 45, 0.2); |
|||
} |
|||
|
|||
.tui-btn-green { |
|||
background: #07c160 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-shadow-green { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(7, 193, 96, 0.2); |
|||
} |
|||
|
|||
.tui-btn-blue { |
|||
background: #007aff !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-shadow-blue { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(0, 122, 255, 0.2); |
|||
} |
|||
|
|||
.tui-btn-white { |
|||
background: #fff !important; |
|||
color: #333 !important; |
|||
} |
|||
|
|||
.tui-btn-gray { |
|||
background: #bfbfbf !important; |
|||
color: #fff !important; |
|||
} |
|||
|
|||
.tui-btn-black { |
|||
background: #333 !important; |
|||
color: #fff !important; |
|||
} |
|||
.tui-btn-brown { |
|||
background: #ac9157 !important; |
|||
color: #fff !important; |
|||
} |
|||
|
|||
.tui-btn-gray-black { |
|||
background: #f2f2f2 !important; |
|||
color: #333; |
|||
} |
|||
|
|||
.tui-btn-gray-primary { |
|||
background: #f2f2f2 !important; |
|||
color: #5677fc !important; |
|||
} |
|||
|
|||
.tui-gray-primary-hover { |
|||
background: #d9d9d9 !important; |
|||
} |
|||
|
|||
.tui-btn-gray-green { |
|||
background: #f2f2f2 !important; |
|||
color: #07c160 !important; |
|||
} |
|||
|
|||
.tui-gray-green-hover { |
|||
background: #d9d9d9 !important; |
|||
} |
|||
|
|||
.tui-btn-gray-danger { |
|||
background: #f2f2f2 !important; |
|||
color: #eb0909 !important; |
|||
} |
|||
|
|||
.tui-gray-danger-hover { |
|||
background: #d9d9d9 !important; |
|||
} |
|||
|
|||
.tui-btn-gray-warning { |
|||
background: #f2f2f2 !important; |
|||
color: #fc872d !important; |
|||
} |
|||
|
|||
.tui-gray-warning-hover { |
|||
background: #d9d9d9 !important; |
|||
} |
|||
|
|||
.tui-shadow-gray { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(191, 191, 191, 0.2); |
|||
} |
|||
|
|||
.tui-hover-gray { |
|||
background: #f7f7f9 !important; |
|||
} |
|||
|
|||
.tui-black-hover { |
|||
background: #555 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
.tui-brown-hover { |
|||
background: #a37f49 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
/* button start*/ |
|||
|
|||
.tui-btn { |
|||
width: 100%; |
|||
position: relative; |
|||
border: 0 !important; |
|||
border-radius: 6rpx; |
|||
padding-left: 0; |
|||
padding-right: 0; |
|||
overflow: visible; |
|||
} |
|||
|
|||
.tui-btn::after { |
|||
content: ''; |
|||
position: absolute; |
|||
width: 200%; |
|||
height: 200%; |
|||
transform-origin: 0 0; |
|||
transform: scale(0.5, 0.5) translateZ(0); |
|||
box-sizing: border-box; |
|||
left: 0; |
|||
top: 0; |
|||
border-radius: 12rpx; |
|||
border: 0; |
|||
} |
|||
|
|||
.tui-text-bold { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.tui-btn-white::after { |
|||
border: 1px solid #bfbfbf; |
|||
} |
|||
|
|||
.tui-white-hover { |
|||
background: #e5e5e5 !important; |
|||
color: #2e2e2e !important; |
|||
} |
|||
|
|||
.tui-dark-disabled { |
|||
opacity: 0.6 !important; |
|||
color: #fafbfc !important; |
|||
} |
|||
|
|||
.tui-dark-disabled-outline { |
|||
opacity: 0.5 !important; |
|||
} |
|||
|
|||
.tui-gray-disabled { |
|||
background: #f3f3f3 !important; |
|||
color: #919191 !important; |
|||
box-shadow: none; |
|||
} |
|||
|
|||
.tui-outline-hover { |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
.tui-primary-hover { |
|||
background: #4a67d6 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
.tui-primary-outline::after { |
|||
border: 1px solid #5677fc !important; |
|||
} |
|||
|
|||
.tui-primary-outline { |
|||
color: #5677fc !important; |
|||
background: transparent; |
|||
} |
|||
|
|||
.tui-danger-hover { |
|||
background: #c80808 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
.tui-danger-outline { |
|||
color: #eb0909 !important; |
|||
background: transparent; |
|||
} |
|||
|
|||
.tui-danger-outline::after { |
|||
border: 1px solid #eb0909 !important; |
|||
} |
|||
|
|||
.tui-warning-hover { |
|||
background: #d67326 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
.tui-warning-outline { |
|||
color: #fc872d !important; |
|||
background: transparent; |
|||
} |
|||
|
|||
.tui-warning-outline::after { |
|||
border: 1px solid #fc872d !important; |
|||
} |
|||
|
|||
.tui-green-hover { |
|||
background: #06ad56 !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
.tui-green-outline { |
|||
color: #07c160 !important; |
|||
background: transparent; |
|||
} |
|||
|
|||
.tui-green-outline::after { |
|||
border: 1px solid #07c160 !important; |
|||
} |
|||
|
|||
.tui-blue-hover { |
|||
background: #0062cc !important; |
|||
color: #e5e5e5 !important; |
|||
} |
|||
|
|||
.tui-blue-outline { |
|||
color: #007aff !important; |
|||
background: transparent; |
|||
} |
|||
|
|||
.tui-blue-outline::after { |
|||
border: 1px solid #007aff !important; |
|||
} |
|||
|
|||
/* #ifndef APP-NVUE */ |
|||
.tui-btn-gradual { |
|||
background: linear-gradient(90deg, rgb(255, 89, 38), rgb(240, 14, 44)) !important; |
|||
color: #fff !important; |
|||
} |
|||
|
|||
.tui-shadow-gradual { |
|||
box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.15); |
|||
} |
|||
|
|||
/* #endif */ |
|||
|
|||
.tui-gray-hover { |
|||
background: #a3a3a3 !important; |
|||
color: #898989; |
|||
} |
|||
|
|||
/* #ifndef APP-NVUE */ |
|||
.tui-gradual-hover { |
|||
background: linear-gradient(90deg, #d74620, #cd1225) !important; |
|||
color: #fff !important; |
|||
} |
|||
|
|||
/* #endif */ |
|||
|
|||
.tui-gray-outline { |
|||
color: #999 !important; |
|||
background: transparent !important; |
|||
} |
|||
|
|||
.tui-white-outline { |
|||
color: #fff !important; |
|||
background: transparent !important; |
|||
} |
|||
|
|||
.tui-black-outline { |
|||
background: transparent !important; |
|||
color: #333 !important; |
|||
} |
|||
|
|||
.tui-gray-outline::after { |
|||
border: 1px solid #ccc !important; |
|||
} |
|||
|
|||
.tui-white-outline::after { |
|||
border: 1px solid #fff !important; |
|||
} |
|||
|
|||
.tui-black-outline::after { |
|||
border: 1px solid #333 !important; |
|||
} |
|||
|
|||
.tui-brown-outline { |
|||
color: #ac9157 !important; |
|||
background: transparent; |
|||
} |
|||
.tui-brown-outline::after { |
|||
border: 1px solid #ac9157 !important; |
|||
} |
|||
|
|||
/*圆角 */ |
|||
|
|||
.tui-fillet { |
|||
border-radius: 50rpx; |
|||
} |
|||
|
|||
.tui-btn-white.tui-fillet::after { |
|||
border-radius: 98rpx; |
|||
} |
|||
|
|||
.tui-outline-fillet::after { |
|||
border-radius: 98rpx; |
|||
} |
|||
|
|||
/*平角*/ |
|||
.tui-rightAngle { |
|||
border-radius: 0; |
|||
} |
|||
|
|||
.tui-btn-white.tui-rightAngle::after { |
|||
border-radius: 0; |
|||
} |
|||
|
|||
.tui-outline-rightAngle::after { |
|||
border-radius: 0; |
|||
} |
|||
.tui-btn__link::after { |
|||
border: 0 !important; |
|||
} |
|||
</style> |
@ -0,0 +1,103 @@ |
|||
<template> |
|||
<view class="tui-divider" :style="{ height: height + 'rpx' }"> |
|||
<view class="tui-divider-line" :style="{ width: width, background: getBgColor(gradual, gradualColor, dividerColor) }"></view> |
|||
<view |
|||
class="tui-divider-text" |
|||
:style="{ color: color, fontSize: size + 'rpx', lineHeight: size + 'rpx', backgroundColor: backgroundColor, fontWeight: bold ? 'bold' : 'normal' }" |
|||
> |
|||
<slot></slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'tuiDivider', |
|||
props: { |
|||
//divider占据高度 |
|||
height: { |
|||
type: Number, |
|||
default: 100 |
|||
}, |
|||
//divider宽度,可填写具体长度,如400rpx |
|||
width: { |
|||
type: String, |
|||
default: '100%' |
|||
}, |
|||
//divider颜色,如果为渐变线条,此属性失效 |
|||
dividerColor: { |
|||
type: String, |
|||
default: '#e5e5e5' |
|||
}, |
|||
//文字颜色 |
|||
color: { |
|||
type: String, |
|||
default: '#999' |
|||
}, |
|||
//文字大小 rpx |
|||
size: { |
|||
type: Number, |
|||
default: 24 |
|||
}, |
|||
bold: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
//背景颜色,和当前页面背景色保持一致 |
|||
backgroundColor: { |
|||
type: String, |
|||
default: '#fafafa' |
|||
}, |
|||
//是否为渐变线条,为true,divideColor失效 |
|||
gradual: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
//渐变色值,to right ,提供两个色值即可,由浅至深 |
|||
gradualColor: { |
|||
type: Array, |
|||
default: function() { |
|||
return ['#eee', '#ccc']; |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
getBgColor: function(gradual, gradualColor, dividerColor) { |
|||
let bgColor = dividerColor; |
|||
if (gradual) { |
|||
bgColor = 'linear-gradient(to right,' + gradualColor[0] + ',' + gradualColor[1] + ',' + gradualColor[1] + ',' + gradualColor[0] + ')'; |
|||
} |
|||
return bgColor; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.tui-divider { |
|||
width: 100%; |
|||
position: relative; |
|||
text-align: center; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
box-sizing: border-box; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.tui-divider-line { |
|||
position: absolute; |
|||
height: 1rpx; |
|||
top: 50%; |
|||
left: 50%; |
|||
-webkit-transform: scaleY(0.5) translateX(-50%) translateZ(0); |
|||
transform: scaleY(0.5) translateX(-50%) translateZ(0); |
|||
} |
|||
|
|||
.tui-divider-text { |
|||
position: relative; |
|||
text-align: center; |
|||
padding: 0 18rpx; |
|||
z-index: 1; |
|||
} |
|||
</style> |
@ -0,0 +1,354 @@ |
|||
<template> |
|||
<view class="tui-tag" :hover-class="hover ? 'tui-tag-opcity' : ''" :hover-stay-time="150" :class="[originLeft ? 'tui-origin-left' : '', originRight ? 'tui-origin-right' : '', getClassName(shape, plain), getTypeClass(type, plain)]" |
|||
:style="{ transform: `scale(${scaleMultiple})`, padding: padding, margin: margin, fontSize: size, lineHeight: size }" |
|||
@tap="handleClick"> |
|||
<slot></slot> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'tuiTag', |
|||
props: { |
|||
type: { |
|||
type: String, |
|||
default: 'primary' |
|||
}, |
|||
//padding |
|||
padding: { |
|||
type: String, |
|||
default: '16rpx 26rpx' |
|||
}, |
|||
margin: { |
|||
type: String, |
|||
default: '0' |
|||
}, |
|||
//文字大小 rpx |
|||
size: { |
|||
type: String, |
|||
default: '28rpx' |
|||
}, |
|||
// circle, square,circleLeft,circleRight |
|||
shape: { |
|||
type: String, |
|||
default: 'square' |
|||
}, |
|||
//是否空心 |
|||
plain: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
//点击效果 |
|||
hover: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
//缩放倍数 |
|||
scaleMultiple: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
originLeft: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
originRight: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
index: { |
|||
type: Number, |
|||
default: 0 |
|||
} |
|||
}, |
|||
methods: { |
|||
handleClick() { |
|||
this.$emit('click', { |
|||
index: this.index |
|||
}); |
|||
}, |
|||
getTypeClass: function(type, plain) { |
|||
return plain ? 'tui-' + type + '-outline' : 'tui-' + type; |
|||
}, |
|||
getClassName: function(shape, plain) { |
|||
//circle, square,circleLeft,circleRight |
|||
var className = plain ? 'tui-tag-outline ' : ''; |
|||
if (shape != 'square') { |
|||
if (shape == 'circle') { |
|||
className = className + (plain ? 'tui-tag-outline-fillet' : 'tui-tag-fillet'); |
|||
} else if (shape == 'circleLeft') { |
|||
className = className + 'tui-tag-fillet-left'; |
|||
} else if (shape == 'circleRight') { |
|||
className = className + 'tui-tag-fillet-right'; |
|||
} |
|||
} |
|||
return className; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* color start*/ |
|||
|
|||
.tui-primary { |
|||
background-color: #5677fc !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-light-primary { |
|||
background-color: #5c8dff !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-dark-primary { |
|||
background-color: #4a67d6 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-dLight-primary { |
|||
background-color: #4e77d9 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-danger { |
|||
background-color: #ed3f14 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-red { |
|||
background-color: #ff201f !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-warning { |
|||
background-color: #ff7900 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-green { |
|||
background-color: #19be6b !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-high-green { |
|||
background-color: #52dcae !important; |
|||
color: #52dcae; |
|||
} |
|||
|
|||
.tui-black { |
|||
background-color: #000 !important; |
|||
color: #fff; |
|||
} |
|||
|
|||
.tui-white { |
|||
background-color: #fff !important; |
|||
color: #333 !important; |
|||
} |
|||
|
|||
.tui-translucent { |
|||
background-color: rgba(0, 0, 0, 0.7); |
|||
} |
|||
|
|||
.tui-light-black { |
|||
background-color: #333 !important; |
|||
} |
|||
|
|||
.tui-gray { |
|||
background-color: #ededed !important; |
|||
} |
|||
|
|||
.tui-phcolor-gray { |
|||
background-color: #ccc !important; |
|||
} |
|||
|
|||
.tui-divider-gray { |
|||
background-color: #eaeef1 !important; |
|||
} |
|||
|
|||
.tui-btn-gray { |
|||
background-color: #ededed !important; |
|||
color: #999 !important; |
|||
} |
|||
|
|||
.tui-hover-gray { |
|||
background-color: #f7f7f9 !important; |
|||
} |
|||
|
|||
.tui-bg-gray { |
|||
background-color: #fafafa !important; |
|||
} |
|||
|
|||
.tui-light-blue { |
|||
background-color: #ecf6fd; |
|||
color: #4dabeb !important; |
|||
} |
|||
|
|||
.tui-light-brownish { |
|||
background-color: #fcebef; |
|||
color: #8a5966 !important; |
|||
} |
|||
|
|||
.tui-light-orange { |
|||
background-color: #fef5eb; |
|||
color: #faa851 !important; |
|||
} |
|||
|
|||
.tui-light-green { |
|||
background-color: #e8f6e8; |
|||
color: #44cf85 !important; |
|||
} |
|||
|
|||
.tui-primary-outline::after { |
|||
border: 1px solid #5677fc !important; |
|||
} |
|||
|
|||
.tui-primary-outline { |
|||
color: #5677fc !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-danger-outline { |
|||
color: #ed3f14 !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-danger-outline::after { |
|||
border: 1px solid #ed3f14 !important; |
|||
} |
|||
|
|||
.tui-red-outline { |
|||
color: #ff201f !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-red-outline::after { |
|||
border: 1px solid #ff201f !important; |
|||
} |
|||
|
|||
.tui-warning-outline { |
|||
color: #ff7900 !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-warning-outline::after { |
|||
border: 1px solid #ff7900 !important; |
|||
} |
|||
|
|||
.tui-green-outline { |
|||
color: #44cf85 !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-green-outline::after { |
|||
border: 1px solid #44cf85 !important; |
|||
} |
|||
|
|||
.tui-high-green-outline { |
|||
color: #52dcae !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-high-green-outline::after { |
|||
border: 1px solid #52dcae !important; |
|||
} |
|||
|
|||
.tui-gray-outline { |
|||
color: #999 !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-gray-outline::after { |
|||
border: 1px solid #ccc !important; |
|||
} |
|||
|
|||
.tui-black-outline { |
|||
color: #333 !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-black-outline::after { |
|||
border: 1px solid #333 !important; |
|||
} |
|||
|
|||
.tui-white-outline { |
|||
color: #fff !important; |
|||
background-color: none; |
|||
} |
|||
|
|||
.tui-white-outline::after { |
|||
border: 1px solid #fff !important; |
|||
} |
|||
|
|||
/* color end*/ |
|||
|
|||
/* tag start*/ |
|||
|
|||
.tui-tag { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 6rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.tui-tag-outline { |
|||
position: relative; |
|||
background-color: none; |
|||
color: #5677fc; |
|||
} |
|||
|
|||
.tui-tag-outline::after { |
|||
content: ' '; |
|||
position: absolute; |
|||
width: 200%; |
|||
height: 200%; |
|||
transform: scale(0.5) translateZ(0); |
|||
transform-origin: 0 0; |
|||
box-sizing: border-box; |
|||
left: 0; |
|||
top: 0; |
|||
border-radius: 12rpx; |
|||
} |
|||
|
|||
.tui-tag-fillet { |
|||
border-radius: 50rpx; |
|||
} |
|||
|
|||
.tui-white.tui-tag-fillet::after { |
|||
border-radius: 80rpx; |
|||
} |
|||
|
|||
.tui-tag-outline-fillet::after { |
|||
border-radius: 80rpx; |
|||
} |
|||
|
|||
.tui-tag-fillet-left { |
|||
border-radius: 50rpx 0 0 50rpx; |
|||
} |
|||
|
|||
.tui-tag-fillet-right { |
|||
border-radius: 0 50rpx 50rpx 0; |
|||
} |
|||
|
|||
.tui-tag-fillet-left.tui-tag-outline::after { |
|||
border-radius: 100rpx 0 0 100rpx; |
|||
} |
|||
|
|||
.tui-tag-fillet-right.tui-tag-outline::after { |
|||
border-radius: 0 100rpx 100rpx 0; |
|||
} |
|||
|
|||
/* tag end*/ |
|||
.tui-origin-left { |
|||
transform-origin: 0 center; |
|||
} |
|||
|
|||
.tui-origin-right { |
|||
transform-origin: 100% center; |
|||
} |
|||
|
|||
.tui-tag-opcity { |
|||
opacity: 0.5; |
|||
} |
|||
</style> |
@ -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" |
|||
} |
67
components/uni-icons/uni-icons.vue
File diff suppressed because it is too large
View File
@ -0,0 +1,395 @@ |
|||
<template> |
|||
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick"> |
|||
<!-- #ifdef MP-ALIPAY --> |
|||
<view v-if="showClose === true || showClose === 'true'" class="uni-noticebar-close" @click="close"> |
|||
<uni-icons type="closeempty" :color="color" size="12" /> |
|||
</view> |
|||
<view v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon"> |
|||
<uni-icons type="sound" :color="color" size="14" /> |
|||
</view> |
|||
<!-- #endif --> |
|||
<!-- #ifndef MP-ALIPAY --> |
|||
<uni-icons v-if="showClose === true || showClose === 'true'" class="uni-noticebar-close" type="closeempty" :color="color" |
|||
size="12" @click="close" /> |
|||
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound" :color="color" |
|||
size="14" /> |
|||
<!-- #endif --> |
|||
<view ref="textBox" class="uni-noticebar__content-wrapper" :class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}"> |
|||
<view :id="elIdBox" class="uni-noticebar__content" :class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}"> |
|||
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text" :class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || moreText)}" |
|||
:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text> |
|||
</view> |
|||
</view> |
|||
<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more" @click="clickMore"> |
|||
<text v-if="moreText" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text> |
|||
<uni-icons type="arrowright" :color="moreColor" size="14" /> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import uniIcons from '../uni-icons/uni-icons.vue' |
|||
// #ifdef APP-NVUE |
|||
const dom = weex.requireModule('dom'); |
|||
const animation = weex.requireModule('animation'); |
|||
// #endif |
|||
|
|||
/** |
|||
* NoticeBar 自定义导航栏 |
|||
* @description 通告栏组件 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=30 |
|||
* @property {Number} speed 文字滚动的速度,默认100px/秒 |
|||
* @property {String} text 显示文字 |
|||
* @property {String} backgroundColor 背景颜色 |
|||
* @property {String} color 文字颜色 |
|||
* @property {String} moreColor 查看更多文字的颜色 |
|||
* @property {String} moreText 设置“查看更多”的文本 |
|||
* @property {Boolean} single = [true|false] 是否单行 |
|||
* @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行 |
|||
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标 |
|||
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮 |
|||
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行 |
|||
* @event {Function} click 点击 NoticeBar 触发事件 |
|||
* @event {Function} close 关闭 NoticeBar 触发事件 |
|||
* @event {Function} getmore 点击”查看更多“时触发事件 |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'UniNoticeBar', |
|||
components: { |
|||
uniIcons |
|||
}, |
|||
props: { |
|||
text: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
moreText: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
backgroundColor: { |
|||
type: String, |
|||
default: '#fffbe8' |
|||
}, |
|||
speed: { |
|||
// 默认1s滚动100px |
|||
type: Number, |
|||
default: 100 |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#de8c17' |
|||
}, |
|||
moreColor: { |
|||
type: String, |
|||
default: '#999999' |
|||
}, |
|||
single: { |
|||
// 是否单行 |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
scrollable: { |
|||
// 是否滚动,添加后控制单行效果取消 |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
showIcon: { |
|||
// 是否显示左侧icon |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
showGetMore: { |
|||
// 是否显示右侧查看更多 |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
showClose: { |
|||
// 是否显示左侧关闭按钮 |
|||
type: [Boolean, String], |
|||
default: false |
|||
} |
|||
}, |
|||
data() { |
|||
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}` |
|||
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}` |
|||
return { |
|||
textWidth: 0, |
|||
boxWidth: 0, |
|||
wrapWidth: '', |
|||
webviewHide: false, |
|||
// #ifdef APP-NVUE |
|||
stopAnimation: false, |
|||
// #endif |
|||
elId: elId, |
|||
elIdBox: elIdBox, |
|||
show: true, |
|||
animationDuration: 'none', |
|||
animationPlayState: 'paused', |
|||
animationDelay: '0s' |
|||
} |
|||
}, |
|||
mounted() { |
|||
// #ifdef APP-PLUS |
|||
var pages = getCurrentPages(); |
|||
var page = pages[pages.length - 1]; |
|||
var currentWebview = page.$getAppWebview(); |
|||
currentWebview.addEventListener('hide',()=>{ |
|||
this.webviewHide = true |
|||
}) |
|||
currentWebview.addEventListener('show',()=>{ |
|||
this.webviewHide = false |
|||
}) |
|||
// #endif |
|||
this.$nextTick(() => { |
|||
this.initSize() |
|||
}) |
|||
}, |
|||
// #ifdef APP-NVUE |
|||
beforeDestroy() { |
|||
this.stopAnimation = true |
|||
}, |
|||
// #endif |
|||
methods: { |
|||
initSize() { |
|||
if (this.scrollable) { |
|||
// #ifndef APP-NVUE |
|||
let query = [], |
|||
boxWidth = 0, |
|||
textWidth = 0; |
|||
let textQuery = new Promise((resolve, reject) => { |
|||
uni.createSelectorQuery() |
|||
// #ifndef MP-ALIPAY |
|||
.in(this) |
|||
// #endif |
|||
.select(`#${this.elId}`) |
|||
.boundingClientRect() |
|||
.exec(ret => { |
|||
this.textWidth = ret[0].width |
|||
resolve() |
|||
}) |
|||
}) |
|||
let boxQuery = new Promise((resolve, reject) => { |
|||
uni.createSelectorQuery() |
|||
// #ifndef MP-ALIPAY |
|||
.in(this) |
|||
// #endif |
|||
.select(`#${this.elIdBox}`) |
|||
.boundingClientRect() |
|||
.exec(ret => { |
|||
this.boxWidth = ret[0].width |
|||
resolve() |
|||
}) |
|||
}) |
|||
query.push(textQuery) |
|||
query.push(boxQuery) |
|||
Promise.all(query).then(() => { |
|||
this.animationDuration = `${this.textWidth / this.speed}s` |
|||
this.animationDelay = `-${this.boxWidth / this.speed}s` |
|||
setTimeout(() => { |
|||
this.animationPlayState = 'running' |
|||
}, 1000) |
|||
}) |
|||
// #endif |
|||
// #ifdef APP-NVUE |
|||
dom.getComponentRect(this.$refs['animationEle'], (res) => { |
|||
let winWidth = uni.getSystemInfoSync().windowWidth |
|||
this.textWidth = res.size.width |
|||
animation.transition(this.$refs['animationEle'], { |
|||
styles: { |
|||
transform: `translateX(-${winWidth}px)` |
|||
}, |
|||
duration: 0, |
|||
timingFunction: 'linear', |
|||
delay: 0 |
|||
}, () => { |
|||
if (!this.stopAnimation) { |
|||
animation.transition(this.$refs['animationEle'], { |
|||
styles: { |
|||
transform: `translateX(-${this.textWidth}px)` |
|||
}, |
|||
timingFunction: 'linear', |
|||
duration: (this.textWidth - winWidth) / this.speed * 1000, |
|||
delay: 1000 |
|||
}, () => { |
|||
if (!this.stopAnimation) { |
|||
this.loopAnimation() |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
}) |
|||
// #endif |
|||
} |
|||
// #ifdef APP-NVUE |
|||
if (!this.scrollable && (this.single || this.moreText)) { |
|||
dom.getComponentRect(this.$refs['textBox'], (res) => { |
|||
this.wrapWidth = res.size.width |
|||
}) |
|||
} |
|||
// #endif |
|||
}, |
|||
loopAnimation() { |
|||
// #ifdef APP-NVUE |
|||
animation.transition(this.$refs['animationEle'], { |
|||
styles: { |
|||
transform: `translateX(0px)` |
|||
}, |
|||
duration: 0 |
|||
}, () => { |
|||
if (!this.stopAnimation) { |
|||
animation.transition(this.$refs['animationEle'], { |
|||
styles: { |
|||
transform: `translateX(-${this.textWidth}px)` |
|||
}, |
|||
duration: this.textWidth / this.speed * 1000, |
|||
timingFunction: 'linear', |
|||
delay: 0 |
|||
}, () => { |
|||
if (!this.stopAnimation) { |
|||
this.loopAnimation() |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
// #endif |
|||
}, |
|||
clickMore() { |
|||
this.$emit('getmore') |
|||
}, |
|||
close() { |
|||
this.show = false; |
|||
this.$emit('close') |
|||
}, |
|||
onClick() { |
|||
this.$emit('click') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
.uni-noticebar { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
width: 100%; |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
padding: 6px 12px; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.uni-noticebar-close { |
|||
margin-right: 5px; |
|||
} |
|||
|
|||
.uni-noticebar-icon { |
|||
margin-right: 5px; |
|||
} |
|||
|
|||
.uni-noticebar__content-wrapper { |
|||
flex: 1; |
|||
flex-direction: column; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.uni-noticebar__content-wrapper--single { |
|||
/* #ifndef APP-NVUE */ |
|||
line-height: 18px; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-noticebar__content-wrapper--single, |
|||
.uni-noticebar__content-wrapper--scrollable { |
|||
flex-direction: row; |
|||
} |
|||
|
|||
/* #ifndef APP-NVUE */ |
|||
.uni-noticebar__content-wrapper--scrollable { |
|||
position: relative; |
|||
height: 18px; |
|||
} |
|||
/* #endif */ |
|||
|
|||
.uni-noticebar__content--scrollable { |
|||
/* #ifdef APP-NVUE */ |
|||
flex: 0; |
|||
/* #endif */ |
|||
/* #ifndef APP-NVUE */ |
|||
flex: 1; |
|||
display: block; |
|||
overflow: hidden; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-noticebar__content--single { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
flex: none; |
|||
width: 100%; |
|||
justify-content: center; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-noticebar__content-text { |
|||
font-size: 14px; |
|||
line-height: 18px; |
|||
/* #ifndef APP-NVUE */ |
|||
word-break: break-all; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-noticebar__content-text--single { |
|||
/* #ifdef APP-NVUE */ |
|||
lines: 1; |
|||
/* #endif */ |
|||
/* #ifndef APP-NVUE */ |
|||
display: block; |
|||
width: 100%; |
|||
white-space: nowrap; |
|||
/* #endif */ |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
} |
|||
|
|||
.uni-noticebar__content-text--scrollable { |
|||
/* #ifdef APP-NVUE */ |
|||
lines: 1; |
|||
padding-left: 750rpx; |
|||
/* #endif */ |
|||
/* #ifndef APP-NVUE */ |
|||
position: absolute; |
|||
display: block; |
|||
height: 18px; |
|||
line-height: 18px; |
|||
white-space: nowrap; |
|||
padding-left: 100%; |
|||
animation: notice 10s 0s linear infinite both; |
|||
animation-play-state: paused; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-noticebar__more { |
|||
/* #ifndef APP-NVUE */ |
|||
display: inline-flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
flex-wrap: nowrap; |
|||
align-items: center; |
|||
padding-left: 5px; |
|||
} |
|||
|
|||
.uni-noticebar__more-text { |
|||
font-size: 14px; |
|||
} |
|||
|
|||
@keyframes notice { |
|||
100% { |
|||
transform: translate3d(-100%, 0, 0); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,22 @@ |
|||
export default { |
|||
created() { |
|||
if (this.type === 'message') { |
|||
// 不显示遮罩
|
|||
this.maskShow = false |
|||
// 获取子组件对象
|
|||
this.childrenMsg = null |
|||
} |
|||
}, |
|||
methods: { |
|||
customOpen() { |
|||
if (this.childrenMsg) { |
|||
this.childrenMsg.open() |
|||
} |
|||
}, |
|||
customClose() { |
|||
if (this.childrenMsg) { |
|||
this.childrenMsg.close() |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
import message from './message.js'; |
|||
// 定义 type 类型:弹出类型:top/bottom/center
|
|||
const config = { |
|||
// 顶部弹出
|
|||
top:'top', |
|||
// 底部弹出
|
|||
bottom:'bottom', |
|||
// 居中弹出
|
|||
center:'center', |
|||
// 消息提示
|
|||
message:'top', |
|||
// 对话框
|
|||
dialog:'center', |
|||
// 分享
|
|||
share:'bottom', |
|||
} |
|||
|
|||
export default { |
|||
data(){ |
|||
return { |
|||
config:config |
|||
} |
|||
}, |
|||
mixins: [message], |
|||
} |
@ -0,0 +1,243 @@ |
|||
<template> |
|||
<view class="uni-popup-dialog"> |
|||
<view class="uni-dialog-title"> |
|||
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text> |
|||
</view> |
|||
<view class="uni-dialog-content"> |
|||
<text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text> |
|||
<input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus" > |
|||
</view> |
|||
<view class="uni-dialog-button-group"> |
|||
<view class="uni-dialog-button" @click="close"> |
|||
<text class="uni-dialog-button-text">取消</text> |
|||
</view> |
|||
<view class="uni-dialog-button uni-border-left" @click="onOk"> |
|||
<text class="uni-dialog-button-text uni-button-color">确定</text> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* PopUp 弹出层-对话框样式 |
|||
* @description 弹出层-对话框样式 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
|||
* @property {String} value input 模式下的默认值 |
|||
* @property {String} placeholder input 模式下输入提示 |
|||
* @property {String} type = [success|warning|info|error] 主题样式 |
|||
* @value success 成功 |
|||
* @value warning 提示 |
|||
* @value info 消息 |
|||
* @value error 错误 |
|||
* @property {String} mode = [base|input] 模式、 |
|||
* @value base 基础对话框 |
|||
* @value input 可输入对话框 |
|||
* @property {String} content 对话框内容 |
|||
* @property {Boolean} beforeClose 是否拦截取消事件 |
|||
* @event {Function} confirm 点击确认按钮触发 |
|||
* @event {Function} close 点击取消按钮触发 |
|||
*/ |
|||
|
|||
export default { |
|||
name: "uniPopupDialog", |
|||
props: { |
|||
value: { |
|||
type: [String, Number], |
|||
default: '' |
|||
}, |
|||
placeholder: { |
|||
type: [String, Number], |
|||
default: '请输入内容' |
|||
}, |
|||
/** |
|||
* 对话框主题 success/warning/info/error 默认 success |
|||
*/ |
|||
type: { |
|||
type: String, |
|||
default: 'error' |
|||
}, |
|||
/** |
|||
* 对话框模式 base/input |
|||
*/ |
|||
mode: { |
|||
type: String, |
|||
default: 'base' |
|||
}, |
|||
/** |
|||
* 对话框标题 |
|||
*/ |
|||
title: { |
|||
type: String, |
|||
default: '提示' |
|||
}, |
|||
/** |
|||
* 对话框内容 |
|||
*/ |
|||
content: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
/** |
|||
* 拦截取消事件 ,如果拦截取消事件,必须监听close事件,执行 done() |
|||
*/ |
|||
beforeClose: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
dialogType: 'error', |
|||
focus: false, |
|||
val: "" |
|||
} |
|||
}, |
|||
inject: ['popup'], |
|||
watch: { |
|||
type(val) { |
|||
this.dialogType = val |
|||
}, |
|||
mode(val) { |
|||
if (val === 'input') { |
|||
this.dialogType = 'info' |
|||
} |
|||
}, |
|||
value(val) { |
|||
this.val = val |
|||
} |
|||
}, |
|||
created() { |
|||
// 对话框遮罩不可点击 |
|||
this.popup.mkclick = false |
|||
if (this.mode === 'input') { |
|||
this.dialogType = 'info' |
|||
this.val = this.value |
|||
} else { |
|||
this.dialogType = this.type |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.focus = true |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 点击确认按钮 |
|||
*/ |
|||
onOk() { |
|||
this.$emit('confirm', () => { |
|||
this.popup.close() |
|||
if (this.mode === 'input') this.val = this.value |
|||
}, this.mode === 'input' ? this.val : '') |
|||
}, |
|||
/** |
|||
* 点击取消按钮 |
|||
*/ |
|||
close() { |
|||
if (this.beforeClose) { |
|||
this.$emit('close', () => { |
|||
this.popup.close() |
|||
}) |
|||
return |
|||
} |
|||
this.popup.close() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.uni-popup-dialog { |
|||
width: 300px; |
|||
border-radius: 15px; |
|||
background-color: #fff; |
|||
} |
|||
|
|||
.uni-dialog-title { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
padding-top: 15px; |
|||
padding-bottom: 5px; |
|||
} |
|||
|
|||
.uni-dialog-title-text { |
|||
font-size: 16px; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.uni-dialog-content { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
padding: 5px 15px 15px 15px; |
|||
} |
|||
|
|||
.uni-dialog-content-text { |
|||
font-size: 14px; |
|||
color: #6e6e6e; |
|||
} |
|||
|
|||
.uni-dialog-button-group { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
border-top-color: #f5f5f5; |
|||
border-top-style: solid; |
|||
border-top-width: 1px; |
|||
} |
|||
|
|||
.uni-dialog-button { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
|
|||
flex: 1; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 45px; |
|||
} |
|||
|
|||
.uni-border-left { |
|||
border-left-color: #f0f0f0; |
|||
border-left-style: solid; |
|||
border-left-width: 1px; |
|||
} |
|||
|
|||
.uni-dialog-button-text { |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.uni-button-color { |
|||
color: $uni-color-primary; |
|||
} |
|||
|
|||
.uni-dialog-input { |
|||
flex: 1; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.uni-popup__success { |
|||
color: $uni-color-success; |
|||
} |
|||
|
|||
.uni-popup__warn { |
|||
color: $uni-color-warning; |
|||
} |
|||
|
|||
.uni-popup__error { |
|||
color: $uni-color-error; |
|||
} |
|||
|
|||
.uni-popup__info { |
|||
color: #909399; |
|||
} |
|||
</style> |
@ -0,0 +1,116 @@ |
|||
<template> |
|||
<view class="uni-popup-message" :class="'uni-popup__'+[type]"> |
|||
<text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
/** |
|||
* PopUp 弹出层-消息提示 |
|||
* @description 弹出层-消息提示 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
|||
* @property {String} type = [success|warning|info|error] 主题样式 |
|||
* @value success 成功 |
|||
* @value warning 提示 |
|||
* @value info 消息 |
|||
* @value error 错误 |
|||
* @property {String} message 消息提示文字 |
|||
* @property {String} duration 显示时间,设置为 0 则不会自动关闭 |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'UniPopupMessage', |
|||
props: { |
|||
/** |
|||
* 主题 success/warning/info/error 默认 success |
|||
*/ |
|||
type: { |
|||
type: String, |
|||
default: 'success' |
|||
}, |
|||
/** |
|||
* 消息文字 |
|||
*/ |
|||
message: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
/** |
|||
* 显示时间,设置为 0 则不会自动关闭 |
|||
*/ |
|||
duration: { |
|||
type: Number, |
|||
default: 3000 |
|||
} |
|||
}, |
|||
inject: ['popup'], |
|||
data() { |
|||
return {} |
|||
}, |
|||
created() { |
|||
this.popup.childrenMsg = this |
|||
}, |
|||
methods: { |
|||
open() { |
|||
if (this.duration === 0) return |
|||
clearTimeout(this.popuptimer) |
|||
this.popuptimer = setTimeout(() => { |
|||
this.popup.close() |
|||
}, this.duration) |
|||
}, |
|||
close() { |
|||
clearTimeout(this.popuptimer) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.uni-popup-message { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
background-color: #e1f3d8; |
|||
padding: 10px 15px; |
|||
border-color: #eee; |
|||
border-style: solid; |
|||
border-width: 1px; |
|||
} |
|||
.uni-popup-message-text { |
|||
font-size: 14px; |
|||
padding: 0; |
|||
} |
|||
|
|||
.uni-popup__success { |
|||
background-color: #e1f3d8; |
|||
} |
|||
|
|||
.uni-popup__success-text { |
|||
color: #67C23A; |
|||
} |
|||
|
|||
.uni-popup__warn { |
|||
background-color: #faecd8; |
|||
} |
|||
|
|||
.uni-popup__warn-text { |
|||
color: #E6A23C; |
|||
} |
|||
|
|||
.uni-popup__error { |
|||
background-color: #fde2e2; |
|||
} |
|||
|
|||
.uni-popup__error-text { |
|||
color: #F56C6C; |
|||
} |
|||
|
|||
.uni-popup__info { |
|||
background-color: #F2F6FC; |
|||
} |
|||
|
|||
.uni-popup__info-text { |
|||
color: #909399; |
|||
} |
|||
</style> |
@ -0,0 +1,165 @@ |
|||
<template> |
|||
<view class="uni-popup-share"> |
|||
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view> |
|||
<view class="uni-share-content"> |
|||
<view class="uni-share-content-box"> |
|||
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)"> |
|||
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image> |
|||
<text class="uni-share-text">{{item.text}}</text> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
<view class="uni-share-button-box"> |
|||
<button class="uni-share-button" @click="close">取消</button> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'UniPopupShare', |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '分享到' |
|||
} |
|||
}, |
|||
inject: ['popup'], |
|||
data() { |
|||
return { |
|||
bottomData: [{ |
|||
text: '微信', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-2.png', |
|||
name: 'wx' |
|||
}, |
|||
{ |
|||
text: '支付宝', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-8.png', |
|||
name: 'wx' |
|||
}, |
|||
{ |
|||
text: 'QQ', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/gird-3.png', |
|||
name: 'qq' |
|||
}, |
|||
{ |
|||
text: '新浪', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-1.png', |
|||
name: 'sina' |
|||
}, |
|||
{ |
|||
text: '百度', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-7.png', |
|||
name: 'copy' |
|||
}, |
|||
{ |
|||
text: '其他', |
|||
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-5.png', |
|||
name: 'more' |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
created() {}, |
|||
methods: { |
|||
/** |
|||
* 选择内容 |
|||
*/ |
|||
select(item, index) { |
|||
this.$emit('select', { |
|||
item, |
|||
index |
|||
}, () => { |
|||
this.popup.close() |
|||
}) |
|||
}, |
|||
/** |
|||
* 关闭窗口 |
|||
*/ |
|||
close() { |
|||
this.popup.close() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.uni-popup-share { |
|||
background-color: #fff; |
|||
} |
|||
.uni-share-title { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 40px; |
|||
} |
|||
.uni-share-title-text { |
|||
font-size: 14px; |
|||
color: #666; |
|||
} |
|||
.uni-share-content { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
padding-top: 10px; |
|||
} |
|||
|
|||
.uni-share-content-box { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 360px; |
|||
} |
|||
|
|||
.uni-share-content-item { |
|||
width: 90px; |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
padding: 10px 0; |
|||
align-items: center; |
|||
} |
|||
|
|||
.uni-share-content-item:active { |
|||
background-color: #f5f5f5; |
|||
} |
|||
|
|||
.uni-share-image { |
|||
width: 30px; |
|||
height: 30px; |
|||
} |
|||
|
|||
.uni-share-text { |
|||
margin-top: 10px; |
|||
font-size: 14px; |
|||
color: #3B4144; |
|||
} |
|||
|
|||
.uni-share-button-box { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
padding: 10px 15px; |
|||
} |
|||
|
|||
.uni-share-button { |
|||
flex: 1; |
|||
border-radius: 50px; |
|||
color: #666; |
|||
font-size: 16px; |
|||
} |
|||
|
|||
.uni-share-button::after { |
|||
border-radius: 50px; |
|||
} |
|||
</style> |
@ -0,0 +1,294 @@ |
|||
<template> |
|||
<view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear"> |
|||
<uni-transition v-if="maskShow" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" |
|||
@click="onTap" /> |
|||
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap"> |
|||
<view class="uni-popup__wrapper-box" @click.stop="clear"> |
|||
<slot /> |
|||
</view> |
|||
</uni-transition> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import uniTransition from '../uni-transition/uni-transition.vue' |
|||
import popup from './popup.js' |
|||
/** |
|||
* PopUp 弹出层 |
|||
* @description 弹出层组件,为了解决遮罩弹层的问题 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
|||
* @property {String} type = [top|center|bottom] 弹出方式 |
|||
* @value top 顶部弹出 |
|||
* @value center 中间弹出 |
|||
* @value bottom 底部弹出 |
|||
* @value message 消息提示 |
|||
* @value dialog 对话框 |
|||
* @value share 底部分享示例 |
|||
* @property {Boolean} animation = [ture|false] 是否开启动画 |
|||
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗 |
|||
* @event {Function} change 打开关闭弹窗触发,e={show: false} |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'UniPopup', |
|||
components: { |
|||
uniTransition |
|||
}, |
|||
props: { |
|||
// 开启动画 |
|||
animation: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层 |
|||
// message: 消息提示 ; dialog : 对话框 |
|||
type: { |
|||
type: String, |
|||
default: 'center' |
|||
}, |
|||
// maskClick |
|||
maskClick: { |
|||
type: Boolean, |
|||
default: true |
|||
} |
|||
}, |
|||
provide() { |
|||
return { |
|||
popup: this |
|||
} |
|||
}, |
|||
mixins: [popup], |
|||
watch: { |
|||
/** |
|||
* 监听type类型 |
|||
*/ |
|||
type: { |
|||
handler: function(newVal) { |
|||
this[this.config[newVal]]() |
|||
}, |
|||
immediate: true |
|||
}, |
|||
/** |
|||
* 监听遮罩是否可点击 |
|||
* @param {Object} val |
|||
*/ |
|||
maskClick(val) { |
|||
this.mkclick = val |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
duration: 300, |
|||
ani: [], |
|||
showPopup: false, |
|||
showTrans: false, |
|||
maskClass: { |
|||
'position': 'fixed', |
|||
'bottom': 0, |
|||
'top': 0, |
|||
'left': 0, |
|||
'right': 0, |
|||
'backgroundColor': 'rgba(0, 0, 0, 0.4)' |
|||
}, |
|||
transClass: { |
|||
'position': 'fixed', |
|||
'left': 0, |
|||
'right': 0, |
|||
}, |
|||
maskShow: true, |
|||
mkclick: true, |
|||
popupstyle: 'top' |
|||
} |
|||
}, |
|||
created() { |
|||
this.mkclick = this.maskClick |
|||
if (this.animation) { |
|||
this.duration = 300 |
|||
} else { |
|||
this.duration = 0 |
|||
} |
|||
}, |
|||
methods: { |
|||
clear(e) { |
|||
// TODO nvue 取消冒泡 |
|||
e.stopPropagation() |
|||
}, |
|||
open() { |
|||
this.showPopup = true |
|||
this.$nextTick(() => { |
|||
new Promise(resolve => { |
|||
clearTimeout(this.timer) |
|||
this.timer = setTimeout(() => { |
|||
this.showTrans = true |
|||
// fixed by mehaotian 兼容 app 端 |
|||
this.$nextTick(() => { |
|||
resolve(); |
|||
}) |
|||
}, 50); |
|||
}).then(res => { |
|||
// 自定义打开事件 |
|||
clearTimeout(this.msgtimer) |
|||
this.msgtimer = setTimeout(() => { |
|||
this.customOpen && this.customOpen() |
|||
}, 100) |
|||
this.$emit('change', { |
|||
show: true, |
|||
type: this.type |
|||
}) |
|||
}) |
|||
}) |
|||
}, |
|||
close(type) { |
|||
this.showTrans = false |
|||
this.$nextTick(() => { |
|||
this.$emit('change', { |
|||
show: false, |
|||
type: this.type |
|||
}) |
|||
clearTimeout(this.timer) |
|||
// 自定义关闭事件 |
|||
this.customOpen && this.customClose() |
|||
this.timer = setTimeout(() => { |
|||
this.showPopup = false |
|||
}, 300) |
|||
}) |
|||
}, |
|||
onTap() { |
|||
if (!this.mkclick) return |
|||
this.close() |
|||
}, |
|||
/** |
|||
* 顶部弹出样式处理 |
|||
*/ |
|||
top() { |
|||
this.popupstyle = 'top' |
|||
this.ani = ['slide-top'] |
|||
this.transClass = { |
|||
'position': 'fixed', |
|||
'left': 0, |
|||
'right': 0, |
|||
} |
|||
}, |
|||
/** |
|||
* 底部弹出样式处理 |
|||
*/ |
|||
bottom() { |
|||
this.popupstyle = 'bottom' |
|||
this.ani = ['slide-bottom'] |
|||
this.transClass = { |
|||
'position': 'fixed', |
|||
'left': 0, |
|||
'right': 0, |
|||
'bottom': 0 |
|||
} |
|||
}, |
|||
/** |
|||
* 中间弹出样式处理 |
|||
*/ |
|||
center() { |
|||
this.popupstyle = 'center' |
|||
this.ani = ['zoom-out', 'fade'] |
|||
this.transClass = { |
|||
'position': 'fixed', |
|||
/* #ifndef APP-NVUE */ |
|||
'display': 'flex', |
|||
'flexDirection': 'column', |
|||
/* #endif */ |
|||
'bottom': 0, |
|||
'left': 0, |
|||
'right': 0, |
|||
'top': 0, |
|||
'justifyContent': 'center', |
|||
'alignItems': 'center' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.uni-popup { |
|||
position: fixed; |
|||
/* #ifndef APP-NVUE */ |
|||
z-index: 99; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-popup__mask { |
|||
position: absolute; |
|||
top: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
background-color: $uni-bg-color-mask; |
|||
opacity: 0; |
|||
} |
|||
|
|||
.mask-ani { |
|||
transition-property: opacity; |
|||
transition-duration: 0.2s; |
|||
} |
|||
|
|||
.uni-top-mask { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.uni-bottom-mask { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.uni-center-mask { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.uni-popup__wrapper { |
|||
/* #ifndef APP-NVUE */ |
|||
display: block; |
|||
/* #endif */ |
|||
position: absolute; |
|||
} |
|||
|
|||
.top { |
|||
/* #ifdef H5 */ |
|||
top: var(--window-top); |
|||
/* #endif */ |
|||
/* #ifndef H5 */ |
|||
top: 0; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.bottom { |
|||
bottom: 0; |
|||
} |
|||
|
|||
.uni-popup__wrapper-box { |
|||
/* #ifndef APP-NVUE */ |
|||
display: block; |
|||
/* #endif */ |
|||
position: relative; |
|||
/* iphonex 等安全区设置,底部安全区适配 */ |
|||
/* #ifndef APP-NVUE */ |
|||
padding-bottom: constant(safe-area-inset-bottom); |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
/* #endif */ |
|||
} |
|||
|
|||
.content-ani { |
|||
// transition: transform 0.3s; |
|||
transition-property: transform, opacity; |
|||
transition-duration: 0.2s; |
|||
} |
|||
|
|||
|
|||
.uni-top-content { |
|||
transform: translateY(0); |
|||
} |
|||
|
|||
.uni-bottom-content { |
|||
transform: translateY(0); |
|||
} |
|||
|
|||
.uni-center-content { |
|||
transform: scale(1); |
|||
opacity: 1; |
|||
} |
|||
</style> |
@ -0,0 +1,279 @@ |
|||
<template> |
|||
<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject" |
|||
@click="change"> |
|||
<slot></slot> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
// #ifdef APP-NVUE |
|||
const animation = uni.requireNativePlugin('animation'); |
|||
// #endif |
|||
/** |
|||
* Transition 过渡动画 |
|||
* @description 简单过渡动画组件 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=985 |
|||
* @property {Boolean} show = [false|true] 控制组件显示或隐藏 |
|||
* @property {Array} 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, |
|||
default () { |
|||
return [] |
|||
} |
|||
}, |
|||
duration: { |
|||
type: Number, |
|||
default: 300 |
|||
}, |
|||
styles: { |
|||
type: Object, |
|||
default () { |
|||
return {} |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
isShow: false, |
|||
transform: '', |
|||
ani: { in: '', |
|||
active: '' |
|||
} |
|||
}; |
|||
}, |
|||
watch: { |
|||
show: { |
|||
handler(newVal) { |
|||
if (newVal) { |
|||
this.open() |
|||
} else { |
|||
this.close() |
|||
} |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
computed: { |
|||
stylesObject() { |
|||
let styles = { |
|||
...this.styles, |
|||
'transition-duration': this.duration / 1000 + 's' |
|||
} |
|||
let transfrom = '' |
|||
for (let i in styles) { |
|||
let line = this.toLine(i) |
|||
transfrom += line + ':' + styles[i] + ';' |
|||
} |
|||
return transfrom |
|||
} |
|||
}, |
|||
created() { |
|||
// this.timer = null |
|||
// this.nextTick = (time = 50) => new Promise(resolve => { |
|||
// clearTimeout(this.timer) |
|||
// this.timer = setTimeout(resolve, time) |
|||
// return this.timer |
|||
// }); |
|||
}, |
|||
methods: { |
|||
change() { |
|||
this.$emit('click', { |
|||
detail: this.isShow |
|||
}) |
|||
}, |
|||
open() { |
|||
clearTimeout(this.timer) |
|||
this.isShow = true |
|||
this.transform = '' |
|||
this.ani.in = '' |
|||
for (let i in this.getTranfrom(false)) { |
|||
if (i === 'opacity') { |
|||
this.ani.in = 'fade-in' |
|||
} else { |
|||
this.transform += `${this.getTranfrom(false)[i]} ` |
|||
} |
|||
} |
|||
this.$nextTick(() => { |
|||
setTimeout(() => { |
|||
this._animation(true) |
|||
}, 50) |
|||
}) |
|||
|
|||
}, |
|||
close(type) { |
|||
clearTimeout(this.timer) |
|||
this._animation(false) |
|||
}, |
|||
_animation(type) { |
|||
let styles = this.getTranfrom(type) |
|||
// #ifdef APP-NVUE |
|||
if(!this.$refs['ani']) return |
|||
animation.transition(this.$refs['ani'].ref, { |
|||
styles, |
|||
duration: this.duration, //ms |
|||
timingFunction: 'ease', |
|||
needLayout: false, |
|||
delay: 0 //ms |
|||
}, () => { |
|||
if (!type) { |
|||
this.isShow = false |
|||
} |
|||
this.$emit('change', { |
|||
detail: this.isShow |
|||
}) |
|||
}) |
|||
// #endif |
|||
// #ifndef APP-NVUE |
|||
this.transform = '' |
|||
for (let i in styles) { |
|||
if (i === 'opacity') { |
|||
this.ani.in = `fade-${type?'out':'in'}` |
|||
} else { |
|||
this.transform += `${styles[i]} ` |
|||
} |
|||
} |
|||
this.timer = setTimeout(() => { |
|||
if (!type) { |
|||
this.isShow = false |
|||
} |
|||
this.$emit('change', { |
|||
detail: this.isShow |
|||
}) |
|||
|
|||
}, this.duration) |
|||
// #endif |
|||
|
|||
}, |
|||
getTranfrom(type) { |
|||
let styles = { |
|||
transform: '' |
|||
} |
|||
this.modeClass.forEach((mode) => { |
|||
switch (mode) { |
|||
case 'fade': |
|||
styles.opacity = type ? 1 : 0 |
|||
break; |
|||
case 'slide-top': |
|||
styles.transform += `translateY(${type?'0':'-100%'}) ` |
|||
break; |
|||
case 'slide-right': |
|||
styles.transform += `translateX(${type?'0':'100%'}) ` |
|||
break; |
|||
case 'slide-bottom': |
|||
styles.transform += `translateY(${type?'0':'100%'}) ` |
|||
break; |
|||
case 'slide-left': |
|||
styles.transform += `translateX(${type?'0':'-100%'}) ` |
|||
break; |
|||
case 'zoom-in': |
|||
styles.transform += `scale(${type?1:0.8}) ` |
|||
break; |
|||
case 'zoom-out': |
|||
styles.transform += `scale(${type?1:1.2}) ` |
|||
break; |
|||
} |
|||
}) |
|||
return styles |
|||
}, |
|||
_modeClassArr(type) { |
|||
let mode = this.modeClass |
|||
if (typeof(mode) !== "string") { |
|||
let modestr = '' |
|||
mode.forEach((item) => { |
|||
modestr += (item + '-' + type + ',') |
|||
}) |
|||
return modestr.substr(0, modestr.length - 1) |
|||
} else { |
|||
return mode + '-' + type |
|||
} |
|||
}, |
|||
// getEl(el) { |
|||
// console.log(el || el.ref || null); |
|||
// return el || el.ref || null |
|||
// }, |
|||
toLine(name) { |
|||
return name.replace(/([A-Z])/g, "-$1").toLowerCase(); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.uni-transition { |
|||
transition-timing-function: ease; |
|||
transition-duration: 0.3s; |
|||
transition-property: transform, opacity; |
|||
} |
|||
|
|||
.fade-in { |
|||
opacity: 0; |
|||
} |
|||
|
|||
.fade-active { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.slide-top-in { |
|||
/* transition-property: transform, opacity; */ |
|||
transform: translateY(-100%); |
|||
} |
|||
|
|||
.slide-top-active { |
|||
transform: translateY(0); |
|||
/* opacity: 1; */ |
|||
} |
|||
|
|||
.slide-right-in { |
|||
transform: translateX(100%); |
|||
} |
|||
|
|||
.slide-right-active { |
|||
transform: translateX(0); |
|||
} |
|||
|
|||
.slide-bottom-in { |
|||
transform: translateY(100%); |
|||
} |
|||
|
|||
.slide-bottom-active { |
|||
transform: translateY(0); |
|||
} |
|||
|
|||
.slide-left-in { |
|||
transform: translateX(-100%); |
|||
} |
|||
|
|||
.slide-left-active { |
|||
transform: translateX(0); |
|||
opacity: 1; |
|||
} |
|||
|
|||
.zoom-in-in { |
|||
transform: scale(0.8); |
|||
} |
|||
|
|||
.zoom-out-active { |
|||
transform: scale(1); |
|||
} |
|||
|
|||
.zoom-out-in { |
|||
transform: scale(1.2); |
|||
} |
|||
</style> |
@ -0,0 +1,10 @@ |
|||
// export const VUE_APP_API_URL = 'http://natapp.xinxintuan.co/api';
|
|||
// export const VUE_APP_API_URL = 'https://wxapi.yixiang.co/api'
|
|||
export const VUE_APP_API_URL = '/h5api' |
|||
// export const VUE_APP_API_URL = 'http://139.186.134.205:9006/api'
|
|||
// export const VUE_APP_API_URL = 'http://192.168.31.223:8008/api'
|
|||
// export const VUE_APP_API_URL = 'http://natapp.xinxintuan.co/api';
|
|||
// export const VUE_APP_API_URL = 'https://thapi.xinxintuan.co/api'
|
|||
// export const VUE_APP_API_URL = 'https://h5api.xinxintuan.co/api';
|
|||
// export const VUE_APP_API_URL = 'https://h5api.xinxintuan.co/api';
|
|||
export const VUE_APP_RESOURCES_URL = 'https://h5.yixiang.co/static' |
After Width: 1024 | Height: 1024 | Size: 304 KiB |
After Width: 120 | Height: 120 | Size: 4.1 KiB |
After Width: 144 | Height: 144 | Size: 5.1 KiB |
After Width: 152 | Height: 152 | Size: 5.4 KiB |
After Width: 167 | Height: 167 | Size: 5.9 KiB |
After Width: 180 | Height: 180 | Size: 6.6 KiB |
After Width: 192 | Height: 192 | Size: 7.0 KiB |
After Width: 20 | Height: 20 | Size: 470 B |
After Width: 29 | Height: 29 | Size: 778 B |
After Width: 40 | Height: 40 | Size: 1.1 KiB |
After Width: 58 | Height: 58 | Size: 1.7 KiB |
After Width: 60 | Height: 60 | Size: 1.7 KiB |
After Width: 72 | Height: 72 | Size: 2.2 KiB |
After Width: 76 | Height: 76 | Size: 2.3 KiB |
After Width: 80 | Height: 80 | Size: 2.5 KiB |
After Width: 87 | Height: 87 | Size: 2.8 KiB |
After Width: 96 | Height: 96 | Size: 3.2 KiB |
@ -0,0 +1,51 @@ |
|||
import $store from "@//store"; |
|||
import { VUE_APP_WS_URL } from "@/utils"; |
|||
|
|||
const Socket = function() { |
|||
this.ws = new WebSocket(VUE_APP_WS_URL); |
|||
this.ws.onopen = this.onOpen.bind(this); |
|||
this.ws.onerror = this.onError.bind(this); |
|||
this.ws.onmessage = this.onMessage.bind(this); |
|||
this.ws.onclose = this.onClose.bind(this); |
|||
}; |
|||
|
|||
Socket.prototype = { |
|||
vm(vm) { |
|||
this.vm = vm; |
|||
}, |
|||
close() { |
|||
clearInterval(this.timer); |
|||
this.ws.close(); |
|||
}, |
|||
onOpen: function() { |
|||
this.init(); |
|||
this.send({ |
|||
type: "login", |
|||
data: $store.state.token |
|||
}); |
|||
this.vm.$emit("socket_open"); |
|||
}, |
|||
init: function() { |
|||
var that = this; |
|||
this.timer = setInterval(function() { |
|||
that.send({ type: "ping" }); |
|||
}, 10000); |
|||
}, |
|||
send: function(data) { |
|||
return this.ws.send(JSON.stringify(data)); |
|||
}, |
|||
onMessage: function(res) { |
|||
const { type, data = {} } = JSON.parse(res.data); |
|||
this.vm.$emit(type, data); |
|||
}, |
|||
onClose: function() { |
|||
clearInterval(this.timer); |
|||
}, |
|||
onError: function(e) { |
|||
this.vm.$emit("socket_error", e); |
|||
} |
|||
}; |
|||
|
|||
Socket.prototype.constructor = Socket; |
|||
|
|||
export default Socket; |
@ -0,0 +1,227 @@ |
|||
import { |
|||
cancelOrder, |
|||
takeOrder, |
|||
delOrder, |
|||
payOrder, |
|||
getSubscribeTemplate |
|||
} from "@/api/order"; |
|||
import dialog from "@/utils/dialog"; |
|||
import { |
|||
weappPay |
|||
} from "@/libs/wechat"; |
|||
|
|||
import { |
|||
_router |
|||
} from '@/utils' |
|||
|
|||
export function cancelOrderHandle(orderId) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '确认取消该订单?', |
|||
success(res) { |
|||
if (res.confirm) { |
|||
cancelOrder(orderId) |
|||
.then(res => { |
|||
uni.showToast({ |
|||
title: '取消成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
resolve(res); |
|||
}) |
|||
.catch(err => { |
|||
uni.showToast({ |
|||
title: '取消失败', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
reject(err); |
|||
}); |
|||
} else if (res.cancel) {} |
|||
} |
|||
}) |
|||
}); |
|||
} |
|||
|
|||
export function takeOrderHandle(orderId) { |
|||
return new Promise((resolve, reject) => { |
|||
takeOrder(orderId) |
|||
.then(res => { |
|||
uni.showToast({ |
|||
title: '收货成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
resolve(res); |
|||
}) |
|||
.catch(err => { |
|||
uni.showToast({ |
|||
title: '收货失败', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
reject(err); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
export function delOrderHandle(orderId) { |
|||
return new Promise((resolve, reject) => { |
|||
dialog.confirm({ |
|||
mes: "确认删除该订单?", |
|||
opts() { |
|||
delOrder(orderId) |
|||
.then(res => { |
|||
uni.showToast({ |
|||
title: '删除成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
resolve(res); |
|||
}) |
|||
.catch(err => { |
|||
uni.showToast({ |
|||
title: '删除失败', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
reject(err); |
|||
}); |
|||
} |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
// 使用订单号进行支付
|
|||
export async function payOrderHandle(orderId, type, from) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.showLoading({ |
|||
title: "支付中", |
|||
mask: true |
|||
}); |
|||
payOrder(orderId, type, from) |
|||
.then(async res => { |
|||
console.log(res) |
|||
await handleOrderPayResults(res.data, type) |
|||
resolve() |
|||
}) |
|||
.catch(err => { |
|||
reject() |
|||
uni.hideLoading() |
|||
uni.showToast({ |
|||
title: err.msg || err.response.data.msg || err.response.data.message || '订单支付失败', |
|||
icon: "none", |
|||
duration: 2000, |
|||
}); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
// 处理调用支付接口的逻辑
|
|||
// @type create(创建订单)||pay(支付订单)
|
|||
export function handleOrderPayResults(data, type, payType) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.hideLoading() |
|||
switch (data.status) { |
|||
// 订单号已存在
|
|||
case "ORDER_EXIST": |
|||
resolve() |
|||
break; |
|||
// 取消支付
|
|||
case "EXTEND_ORDER": |
|||
uni.showToast({ |
|||
title: data.msg, |
|||
icon: "none", |
|||
duration: 2000, |
|||
}); |
|||
resolve() |
|||
goOrderDetails(data.result.orderId, type) |
|||
break; |
|||
case "PAY_DEFICIENCY": |
|||
break; |
|||
// 支付出错
|
|||
case "PAY_ERROR": |
|||
uni.showToast({ |
|||
title: data.msg, |
|||
icon: "none", |
|||
duration: 2000, |
|||
}); |
|||
reject() |
|||
goOrderDetails(data.result.orderId, type) |
|||
break; |
|||
// 未传递支付环境
|
|||
case "SUCCESS": |
|||
uni.showToast({ |
|||
title: data.msg || data.payMsg, |
|||
icon: "none", |
|||
duration: 2000, |
|||
}); |
|||
resolve() |
|||
goOrderDetails(data.result.orderId, type) |
|||
break; |
|||
// H5支付
|
|||
case "WECHAT_H5_PAY": |
|||
goOrderDetails(data.result.orderId, type) |
|||
console.log(data) |
|||
setTimeout(() => { |
|||
resolve() |
|||
// #ifdef H5
|
|||
// "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx15171343713577e9f3a418b0865ef90000&package=2547890641"
|
|||
// location.href = data.result.jsConfig.mweb_url;
|
|||
// #endif
|
|||
}, 100); |
|||
break; |
|||
// 小程序支付
|
|||
case "WECHAT_PAY": |
|||
weappPay(data.result.jsConfig).finally(() => { |
|||
resolve() |
|||
goOrderDetails(data.result.orderId, type) |
|||
}).then(res => { |
|||
// #ifdef MP-WEIXIN
|
|||
subscribeMessage() |
|||
// #endif
|
|||
}) |
|||
break; |
|||
// APP支付
|
|||
case "WECHAT_APP_PAY": |
|||
weappPay(data.result.jsConfig).finally(() => { |
|||
resolve() |
|||
goOrderDetails(data.result.orderId, type) |
|||
}) |
|||
break; |
|||
} |
|||
}) |
|||
} |
|||
|
|||
export function subscribeMessage() { |
|||
// 调用订阅
|
|||
console.log('调用订阅') |
|||
getSubscribeTemplate() |
|||
.then(res => { |
|||
uni.requestSubscribeMessage({ |
|||
tmplIds: res.data, |
|||
success(res) { |
|||
console.log(res) |
|||
}, |
|||
fail(error) { |
|||
console.log(error) |
|||
} |
|||
}) |
|||
}) |
|||
.catch(err => {}); |
|||
} |
|||
|
|||
|
|||
export function goOrderDetails(id, type) { |
|||
// 创建订单时跳转到详情
|
|||
if (type == 'create') { |
|||
console.log(_router) |
|||
_router.replace({ |
|||
path: "/pages/order/OrderDetails/index", |
|||
query: { |
|||
id |
|||
}, |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,397 @@ |
|||
import { subscribeMessage } from '@/libs/order' |
|||
import { getProvider } from '@/utils' |
|||
import WechatJSSDK from 'wechat-jssdk/dist/client.umd' |
|||
import { getWechatConfig, wechatAuth } from '@/api/public' |
|||
import { parseQuery } from '@/utils' |
|||
import cookie from '@/utils/store/cookie' |
|||
import store from '@/store' |
|||
import dayjs from 'dayjs' |
|||
|
|||
// 支付模块
|
|||
export const weappPay = option => { |
|||
return new Promise((resolve, reject) => { |
|||
if (store.state.$deviceType == 'weixinh5') { |
|||
setTimeout(() => { |
|||
location.href = option.mweb_url |
|||
}, 100) |
|||
resolve() |
|||
return |
|||
} |
|||
if (store.state.$deviceType == 'weixin') { |
|||
pay(option) |
|||
.then(() => { |
|||
uni.showToast({ |
|||
title: '支付成功', |
|||
icon: 'success', |
|||
duration: 5000, |
|||
}) |
|||
resolve() |
|||
}) |
|||
.finally(res => { |
|||
//if(typeof(res) == "undefined") return
|
|||
}) |
|||
.catch(function() { |
|||
uni.showToast({ title: '支付失败', icon: 'none', duration: 5000 }) |
|||
reject() |
|||
}) |
|||
return |
|||
} |
|||
// 吊起微信支付
|
|||
// getProvider('payment').then(provider => {
|
|||
let orderInfo = { |
|||
appid: option.appid, |
|||
noncestr: option.noncestr, |
|||
package: option.package, |
|||
partnerid: option.partnerid, |
|||
prepayid: option.prepayid, |
|||
sign: option.sign, |
|||
timestamp: option.timestamp + '', |
|||
} |
|||
// 调用只接口
|
|||
uni.requestPayment({ |
|||
provider: 'wxpay', |
|||
...option, |
|||
timestamp: orderInfo.timestamp, |
|||
orderInfo, |
|||
success: success => { |
|||
console.log(success) |
|||
uni.showToast({ |
|||
title: '支付成功', |
|||
icon: 'success', |
|||
duration: 5000, |
|||
}) |
|||
let time = setTimeout(() => { |
|||
clearTimeout(time) |
|||
resolve(success) |
|||
}, 3000) |
|||
// #ifdef MP-WEIXIN
|
|||
subscribeMessage() |
|||
// #endif
|
|||
}, |
|||
fail: error => { |
|||
console.log(error) |
|||
if (error.errMsg == 'requestPayment:fail cancel') { |
|||
uni.showToast({ title: '已取消支付', icon: 'none', duration: 5000 }) |
|||
} else { |
|||
uni.showToast({ title: error || error.msg, icon: 'none', duration: 5000 }) |
|||
} |
|||
reject(error) |
|||
}, |
|||
}) |
|||
// })
|
|||
}) |
|||
} |
|||
|
|||
const STATE_KEY = 'wx_authorize_state' |
|||
const WX_AUTH = 'wx_auth' |
|||
const BACK_URL = 'login_back_url' |
|||
const LOGINTYPE = 'loginType' |
|||
let instance |
|||
let wechatObj |
|||
let appId |
|||
let wechatLoading = false |
|||
|
|||
export function wechat() { |
|||
console.log('初始化微信配置') |
|||
wechatLoading = false |
|||
return new Promise((resolve, reject) => { |
|||
if (instance) return resolve(instance) |
|||
getWechatConfig() |
|||
.then(res => { |
|||
console.log(res.data) |
|||
const _wx = WechatJSSDK(res.data) |
|||
console.log(_wx) |
|||
appId = res.data.appId |
|||
wechatObj = _wx |
|||
_wx |
|||
.initialize() |
|||
.then(() => { |
|||
instance = _wx.wx |
|||
instance.initConfig = res.data |
|||
resolve(instance) |
|||
}) |
|||
.catch(error => { |
|||
console.log(error) |
|||
uni.showToast({ |
|||
title: error, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
reject() |
|||
}) |
|||
}) |
|||
.catch(err => { |
|||
console.log(err) |
|||
reject() |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
export function clearAuthStatus() { |
|||
cookie.remove(WX_AUTH) |
|||
cookie.remove(STATE_KEY) |
|||
} |
|||
|
|||
export async function oAuth() { |
|||
console.log('处理微信授权') |
|||
console.log(store) |
|||
console.log(store.state) |
|||
return new Promise((resolve, reject) => { |
|||
// if (cookie.has(WX_AUTH)) {
|
|||
if (cookie.has(WX_AUTH) && store.state.token) { |
|||
reject() |
|||
return |
|||
} |
|||
const { code } = parseQuery() |
|||
if (!code) { |
|||
toAuth() |
|||
return |
|||
} else { |
|||
auth(code) |
|||
} |
|||
resolve() |
|||
}).catch(error => { |
|||
console.log(error) |
|||
}) |
|||
} |
|||
|
|||
export async function auth(code) { |
|||
console.log('获取微信授权') |
|||
return new Promise((resolve, reject) => { |
|||
let loginType = cookie.get(LOGINTYPE) |
|||
let spread = cookie.get('spread') |
|||
console.log('微信授权登录前获取spread', spread) |
|||
wechatAuth(code, spread, loginType) |
|||
.then(({ data }) => { |
|||
console.log(data) |
|||
const expires_time = dayjs(data.expires_time) |
|||
const newTime = Math.round(new Date() / 1000) |
|||
store.commit('login', data.token, expires_time - newTime) |
|||
cookie.set(WX_AUTH, code, expires_time) |
|||
cookie.remove(STATE_KEY) |
|||
loginType && cookie.remove(LOGINTYPE) |
|||
console.log('微信公众号授权登录,获取用户信息') |
|||
store.dispatch('getUser').finally(() => { |
|||
resolve() |
|||
}) |
|||
}) |
|||
.catch(reject) |
|||
}).catch(error => { |
|||
console.log(error) |
|||
}) |
|||
} |
|||
|
|||
export async function toAuth() { |
|||
if (wechatLoading) { |
|||
return |
|||
} |
|||
wechatLoading = true |
|||
wechat().then(wx => { |
|||
location.href = getAuthUrl(appId) |
|||
}) |
|||
} |
|||
|
|||
function getAuthUrl(appId) { |
|||
// const redirect_uri = encodeURIComponent(window.location.href);
|
|||
// const redirect_uri = encodeURIComponent(`${location.origin}/pages/Loading/index`);
|
|||
|
|||
// #ifdef H5
|
|||
// #endif
|
|||
cookie.set('redirect', window.location.href) |
|||
const redirect_uri = encodeURIComponent(`${location.origin}/pages/Loading/index`) |
|||
// const redirect_uri = encodeURIComponent(`${location.origin}/pages/Loading/index?path=${encodeURIComponent(window.location.href)}`);
|
|||
// const redirect_uri = encodeURIComponent(`${window.location.origin}${window.location.pathname}`)
|
|||
// const redirect_uri = encodeURIComponent(`${location.origin}`)
|
|||
cookie.remove(BACK_URL) |
|||
const state = 'STATE' |
|||
// const state = encodeURIComponent(("" + Math.random()).split(".")[1] + "authorizestate");
|
|||
cookie.set(STATE_KEY, state) |
|||
return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect` |
|||
} |
|||
|
|||
function toPromise(fn, config = {}) { |
|||
return new Promise((resolve, reject) => { |
|||
fn({ |
|||
...config, |
|||
success(res) { |
|||
resolve(res) |
|||
}, |
|||
fail(err) { |
|||
reject(err) |
|||
}, |
|||
complete(err) { |
|||
reject(err) |
|||
}, |
|||
cancel(err) { |
|||
reject(err) |
|||
}, |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
export function pay(config) { |
|||
console.log(instance) |
|||
return toPromise(instance.chooseWXPay, config) |
|||
} |
|||
|
|||
export function openAddress() { |
|||
return new Promise((resolve, reject) => { |
|||
wechatEvevt('openAddress', {}) |
|||
.then(res => { |
|||
resolve(res) |
|||
}) |
|||
.catch(res => { |
|||
if (res.is_ready) { |
|||
res.wx.openAddress({ |
|||
fail(res) { |
|||
reject(res) |
|||
}, |
|||
success(res) { |
|||
resolve(res) |
|||
}, |
|||
}) |
|||
} else { |
|||
reject(res) |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
export function openShareAll(config) { |
|||
config || {} |
|||
config.type = config.type == undefined ? 'link' : config.type |
|||
return new Promise(resolve => { |
|||
getWechatConfig().then(res => { |
|||
wechatObj.signSignature({ |
|||
nonceStr: res.data.nonceStr, |
|||
signature: res.data.signature, |
|||
timestamp: res.data.timestamp, |
|||
}) |
|||
instance = wechatObj.getOriginalWx() |
|||
instance.ready(() => { |
|||
instance.updateAppMessageShareData(config) |
|||
instance.updateTimelineShareData(config) |
|||
resolve() |
|||
}) |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
export function openShareAppMessage(config) { |
|||
instance.updateAppMessageShareData(config) |
|||
instance.onMenuShareAppMessage && instance.onMenuShareAppMessage(config) |
|||
} |
|||
|
|||
export function openShareTimeline(config) { |
|||
instance.updateTimelineShareData(config) |
|||
instance.onMenuShareTimeline && instance.onMenuShareTimeline(config) |
|||
} |
|||
|
|||
export function wechatEvevt(name, config) { |
|||
return new Promise((resolve, reject) => { |
|||
let wx |
|||
let configDefault = { |
|||
fail(res) { |
|||
if (wx) return reject({ is_ready: true, wx: wx }) |
|||
getWechatConfig().then(res => { |
|||
wechatObj.signSignature({ |
|||
nonceStr: res.data.nonceStr, |
|||
signature: res.data.signature, |
|||
timestamp: res.data.timestamp, |
|||
}) |
|||
wx = wechatObj.getOriginalWx() |
|||
reject({ is_ready: true, wx: wx }) |
|||
}) |
|||
}, |
|||
success(res) { |
|||
resolve(res) |
|||
}, |
|||
} |
|||
Object.assign(configDefault, config) |
|||
if (typeof instance !== 'undefined') { |
|||
instance.ready(() => { |
|||
if (typeof name === 'object') { |
|||
name.forEach(item => { |
|||
instance[item] && instance[item](configDefault) |
|||
}) |
|||
} else instance[name] && instance[name](configDefault) |
|||
}) |
|||
} else { |
|||
getWechatConfig().then(res => { |
|||
const _wx = WechatJSSDK(res.data) |
|||
_wx.initialize().then(() => { |
|||
instance = _wx.getOriginalWx() |
|||
instance.ready(() => { |
|||
if (typeof name === 'object') { |
|||
name.forEach(item => { |
|||
instance[item] && instance[item](configDefault) |
|||
}) |
|||
} else instance[name] && instance[name](configDefault) |
|||
}) |
|||
}) |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
export function ready() { |
|||
return new Promise(resolve => { |
|||
if (typeof instance !== 'undefined') { |
|||
instance.ready(() => { |
|||
resolve(instance) |
|||
}) |
|||
} else { |
|||
getWechatConfig().then(res => { |
|||
const _wx = WechatJSSDK(res.data) |
|||
_wx.initialize().then(() => { |
|||
instance = _wx.wx |
|||
instance.ready(() => { |
|||
resolve(instance) |
|||
}) |
|||
}) |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
export function wxShowLocation() { |
|||
return new Promise(() => { |
|||
wechatEvevt('getLocation', { type: 'wgs84' }) |
|||
.then(res => { |
|||
let latitude = res.latitude // 纬度
|
|||
let longitude = res.longitude // 经度
|
|||
cookie.set(LATITUDE, latitude) |
|||
cookie.set(LONGITUDE, longitude) |
|||
}) |
|||
.catch(res => { |
|||
if (res.is_ready) { |
|||
res.wx.getLocation({ |
|||
success(res) { |
|||
let latitude = res.latitude // 纬度
|
|||
let longitude = res.longitude // 经度
|
|||
cookie.set(LATITUDE, latitude) |
|||
cookie.set(LONGITUDE, longitude) |
|||
}, |
|||
cancel() { |
|||
cookie.remove(LATITUDE) |
|||
cookie.remove(LONGITUDE) |
|||
uni.showToast({ |
|||
title: '取消获取位置', |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}, |
|||
fail() { |
|||
cookie.remove(LATITUDE) |
|||
cookie.remove(LONGITUDE) |
|||
uni.showToast({ |
|||
title: '授权失败', |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}, |
|||
}) |
|||
} |
|||
}) |
|||
}) |
|||
} |
@ -0,0 +1,122 @@ |
|||
import Vue from 'vue' |
|||
import App from './App' |
|||
|
|||
// import router from "./router";
|
|||
import store from './store' |
|||
import schema from 'async-validator' |
|||
import dialog from './utils/dialog' |
|||
import cookie from '@/utils/store/cookie' |
|||
import cuCustom from '@/components/colorui/components/cu-custom.vue' |
|||
|
|||
import { parseRoute, _router, parseQuery } from '@/utils' |
|||
import { VUE_APP_RESOURCES_URL, VUE_APP_API_URL } from '@/config' |
|||
Vue.component('cu-custom', cuCustom) |
|||
Vue.config.productionTip = false |
|||
Vue.config.devtools = process.env.NODE_ENV !== 'production' |
|||
|
|||
Vue.prototype.$validator = function(rule) { |
|||
return new schema(rule) |
|||
} |
|||
|
|||
Vue.config.productionTip = false |
|||
App.mpType = 'app' |
|||
Vue.prototype.$store = store |
|||
|
|||
const app = new Vue({ |
|||
...App, |
|||
store, |
|||
}) |
|||
|
|||
Object.defineProperty(Vue.prototype, '$yrouter', { |
|||
get() { |
|||
return _router |
|||
}, |
|||
}) |
|||
|
|||
Object.defineProperty(Vue.prototype, '$yroute', { |
|||
get() { |
|||
return this._route |
|||
}, |
|||
}) |
|||
|
|||
Vue.prototype.$VUE_APP_API_URL = VUE_APP_API_URL |
|||
Vue.component('cu-custom', cuCustom) |
|||
|
|||
let deviceType = '' |
|||
// #ifdef APP-PLUS
|
|||
// App平台编译的代码
|
|||
deviceType = 'app' |
|||
Vue.prototype.$platform = uni.getSystemInfoSync().platform |
|||
// #endif
|
|||
|
|||
// #ifdef MP-WEIXIN
|
|||
// 微信小程序编译的代码
|
|||
deviceType = 'routine' |
|||
// #endif
|
|||
|
|||
// !!! ps 不建议在 template 中使用 $deviceType 去判断当前环境,很有可能出现 $deviceType 为 undefined 导致判断出错的问题,可以在 script 模块中正常使用
|
|||
// 建议通过 store 去获取 $deviceType 可以保证 template 中取到的值有效
|
|||
// import { mapState, mapMutations, mapActions } from 'vuex';
|
|||
// computed: {
|
|||
// ...mapState(['$deviceType'])
|
|||
// },
|
|||
|
|||
// #ifdef H5
|
|||
// H5编译的代码
|
|||
|
|||
import { wechat, clearAuthStatus, oAuth, auth, toAuth, pay, openAddress, openShareAll, openShareAppMessage, openShareTimeline, wechatEvevt, ready, wxShowLocation } from '@/libs/wechat' |
|||
|
|||
import { isWeixin } from '@/utils' |
|||
const CACHE_KEY = 'clear_0.0.1' |
|||
|
|||
if (!cookie.has(CACHE_KEY)) { |
|||
cookie.clearAll() |
|||
cookie.set(CACHE_KEY, 1) |
|||
} |
|||
|
|||
var urlSpread = parseQuery()['spread'] |
|||
if (urlSpread) { |
|||
cookie.set('spread', urlSpread) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef H5
|
|||
// H5编译的代码
|
|||
// 判断是否是微信浏览器
|
|||
async function init() { |
|||
if (isWeixin()) { |
|||
deviceType = 'weixin' |
|||
let wechatInit = wechat() |
|||
if (wechatInit) { |
|||
await oAuth() |
|||
} |
|||
} else { |
|||
deviceType = 'weixinh5' |
|||
} |
|||
} |
|||
init() |
|||
// #endif
|
|||
|
|||
Vue.prototype.$deviceType = deviceType |
|||
|
|||
Vue.mixin({ |
|||
onLoad() { |
|||
const { $mp } = this.$root |
|||
this._route = parseRoute($mp) |
|||
}, |
|||
onShow() { |
|||
_router.app = this |
|||
_router.currentRoute = this._route |
|||
}, |
|||
// 这里为了解决 .vue文件中 template 无法获取 VUE.prototype 绑定的变量
|
|||
computed: { |
|||
$VUE_APP_RESOURCES_URL() { |
|||
return VUE_APP_RESOURCES_URL |
|||
}, |
|||
}, |
|||
}) |
|||
|
|||
store.commit('updateDevicetype', deviceType) |
|||
|
|||
app.$mount() |
@ -0,0 +1,188 @@ |
|||
{ |
|||
"name" : "yshopmall", |
|||
"appid" : "__UNI__C7A519E", |
|||
"description" : "", |
|||
"versionName" : "1.0.1", |
|||
"versionCode" : 1, |
|||
"transformPx" : false, |
|||
/* 5+App特有相关 */ |
|||
"app-plus" : { |
|||
"usingComponents" : true, |
|||
"nvueCompiler" : "uni-app", |
|||
"compilerVersion" : 3, |
|||
"splashscreen" : { |
|||
"alwaysShowBeforeRender" : true, |
|||
"waiting" : false, |
|||
"autoclose" : true, |
|||
"delay" : 0 |
|||
}, |
|||
/* 模块配置 */ |
|||
"modules" : { |
|||
"OAuth" : {}, |
|||
"Payment" : {}, |
|||
"Share" : {}, |
|||
"Geolocation" : {} |
|||
}, |
|||
/* 应用发布信息 */ |
|||
"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.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.MODIFY_AUDIO_SETTINGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", |
|||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>", |
|||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>" |
|||
] |
|||
}, |
|||
/* ios打包配置 */ |
|||
"ios" : {}, |
|||
/* SDK配置 */ |
|||
"sdkConfigs" : { |
|||
"oauth" : { |
|||
"weixin" : { |
|||
"appid" : "wx7c84ede33062d1e4", |
|||
"appsecret" : "c47ef66d3311194da44e60387d5c1abd", |
|||
"UniversalLinks" : "https://yixiang.co/app/" |
|||
} |
|||
}, |
|||
"payment" : { |
|||
"weixin" : { |
|||
"appid" : "wx7c84ede33062d1e4", |
|||
"UniversalLinks" : "https://yixiang.co/app/" |
|||
} |
|||
}, |
|||
"share" : { |
|||
"weixin" : { |
|||
"appid" : "wx7c84ede33062d1e4", |
|||
"UniversalLinks" : "https://yixiang.co/app/" |
|||
} |
|||
}, |
|||
"ad" : {}, |
|||
"geolocation" : {} |
|||
}, |
|||
"splashscreen" : { |
|||
"ios" : { |
|||
"iphone" : { |
|||
"portrait-896h@3x" : "splash/1242+2688.png", |
|||
"portrait-896h@2x" : "splash/828+1792.png", |
|||
"iphonex" : "splash/1125+2436.png", |
|||
"retina55" : "splash/1142+2208.png", |
|||
"retina47" : "splash/750+1334.png", |
|||
"retina40" : "splash/640+1136.png", |
|||
"retina35" : "splash/640+960.png" |
|||
} |
|||
}, |
|||
"android" : { |
|||
"hdpi" : "splash/480+762.png", |
|||
"xhdpi" : "splash/720+1242.png", |
|||
"xxhdpi" : "splash/1080+1882.png" |
|||
}, |
|||
"iosStyle" : "common" |
|||
}, |
|||
"icons" : { |
|||
"android" : { |
|||
"hdpi" : "icons/72x72.png", |
|||
"xhdpi" : "icons/96x96.png", |
|||
"xxhdpi" : "icons/144x144.png", |
|||
"xxxhdpi" : "icons/192x192.png" |
|||
}, |
|||
"ios" : { |
|||
"appstore" : "icons/1024x1024.png", |
|||
"ipad" : { |
|||
"app" : "icons/76x76.png", |
|||
"app@2x" : "icons/152x152.png", |
|||
"notification" : "icons/20x20.png", |
|||
"notification@2x" : "icons/40x40.png", |
|||
"proapp@2x" : "icons/167x167.png", |
|||
"settings" : "icons/29x29.png", |
|||
"settings@2x" : "icons/58x58.png", |
|||
"spotlight" : "icons/40x40.png", |
|||
"spotlight@2x" : "icons/80x80.png" |
|||
}, |
|||
"iphone" : { |
|||
"app@2x" : "icons/120x120.png", |
|||
"app@3x" : "icons/180x180.png", |
|||
"notification@2x" : "icons/40x40.png", |
|||
"notification@3x" : "icons/60x60.png", |
|||
"settings@2x" : "icons/58x58.png", |
|||
"settings@3x" : "icons/87x87.png", |
|||
"spotlight@2x" : "icons/80x80.png", |
|||
"spotlight@3x" : "icons/120x120.png" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"quickapp" : {}, |
|||
"mp-weixin" : { |
|||
"appid" : "wx604d2ea4702620d2", |
|||
"setting" : { |
|||
"urlCheck" : true, |
|||
"postcss" : true, |
|||
"minified" : true |
|||
}, |
|||
"usingComponents" : true, |
|||
"permission" : { |
|||
"scope.userLocation" : { |
|||
"desc" : "你的位置信息将用于小程序位置接口的效果展示" |
|||
} |
|||
}, |
|||
"plugins" : { |
|||
// #ifdef MP-WEIXIN |
|||
"live-player-plugin" : { |
|||
"version" : "1.2.8", |
|||
"provider" : "wx2b03c6e691cd7370" |
|||
} |
|||
} |
|||
}, |
|||
// #endif |
|||
"mp-alipay" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-baidu" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-toutiao" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"h5" : { |
|||
"title" : "yshop", |
|||
"devServer" : { |
|||
"disableHostCheck" : true, |
|||
"proxy" : { |
|||
"/h5api" : { |
|||
// 需要被代理的后台地址 |
|||
"target" : "http://itxzz.51vip.biz/", |
|||
"changeOrigin" : true, |
|||
"secure" : false, |
|||
"pathRewrite" : { |
|||
"^/h5api" : "/api" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"router" : { |
|||
"mode" : "history" |
|||
}, |
|||
"sdkConfigs" : { |
|||
"maps" : { |
|||
"qqmap" : { |
|||
"key" : "" |
|||
} |
|||
} |
|||
}, |
|||
"domain" : "h5.yixiang.co" |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
export default { |
|||
data() { |
|||
return { |
|||
disabled: false, |
|||
text: "获取验证码" |
|||
}; |
|||
}, |
|||
methods: { |
|||
sendCode() { |
|||
if (this.disabled) return; |
|||
this.disabled = true; |
|||
let n = 60; |
|||
this.text = "剩余 " + n + "s"; |
|||
const run = setInterval(() => { |
|||
n = n - 1; |
|||
if (n < 0) { |
|||
clearInterval(run); |
|||
} |
|||
this.text = "剩余 " + n + "s"; |
|||
if (this.text < "剩余 " + 0 + "s") { |
|||
this.disabled = false; |
|||
this.text = "重新获取"; |
|||
} |
|||
}, 1000); |
|||
} |
|||
} |
|||
}; |
@ -0,0 +1,25 @@ |
|||
{ |
|||
"name": "yshopmall_uni", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "main.js", |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1" |
|||
}, |
|||
"keywords": [], |
|||
"author": "", |
|||
"license": "ISC", |
|||
"dependencies": { |
|||
"animate.css": "^3.7.2", |
|||
"async-validator": "^3.2.4", |
|||
"dayjs": "^1.8.22", |
|||
"jweixin-module": "^1.6.0", |
|||
"miniapp-color-thief": "^1.0.5", |
|||
"vconsole": "^3.3.4", |
|||
"wechat-jssdk": "^5.0.4" |
|||
}, |
|||
"devDependencies": { |
|||
"@types/html5plus": "^1.0.1", |
|||
"@types/uni-app": "^1.4.3" |
|||
} |
|||
} |
@ -0,0 +1,476 @@ |
|||
{ |
|||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages |
|||
{ |
|||
"path": "pages/Loading/index", |
|||
"style": { |
|||
"navigationBarTitleText": "yshop商城" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/authorization/index", |
|||
"style": { |
|||
"navigationBarTitleText": "微信授权" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/Login/index", |
|||
"style": { |
|||
"navigationBarTitleText": "登录" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/Register/index", |
|||
"style": { |
|||
"navigationBarTitleText": "注册" |
|||
} |
|||
}, |
|||
{ |
|||
// "path": "pages/user/RetrievePassword/index", |
|||
"path": "pages/user/ChangePassword/index", |
|||
"style": { |
|||
"navigationBarTitleText": "重置密码" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/launch/index", |
|||
"style": { |
|||
"navigationBarTitleText": "首页" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/home/index", |
|||
"style": { |
|||
"navigationBarTitleText": "yshop商城", |
|||
"navigationBarTextStyle": "white", |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodSearch/index", |
|||
"style": { |
|||
"navigationBarTitleText": "搜索商品" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsClass/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品分类" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/ShoppingCart/index", |
|||
"style": { |
|||
"navigationBarTitleText": "购物车" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/StoreList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商家列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/NotDefined/index", |
|||
"style": { |
|||
"navigationBarTitleText": "404" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/User/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsCollection/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品收藏" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsFoot/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的足迹" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/news/NewsDetail/index", |
|||
"style": { |
|||
"navigationBarTitleText": "新闻详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/news/NewsList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "新闻列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/EvaluateList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "评价列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsEvaluate/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品评价" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsPromotion/index", |
|||
"style": { |
|||
"navigationBarTitleText": "促销商品" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/HotNewGoods/index", |
|||
"style": { |
|||
"navigationBarTitleText": "热门商品" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/GoodsCon/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/IntegralGoodsCon/index", |
|||
"style": { |
|||
"navigationBarTitleText": "积分商品详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/BindingPhone/index", |
|||
"style": { |
|||
"navigationBarTitleText": "绑定手机号" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/address/AddAddress/index", |
|||
"style": { |
|||
"navigationBarTitleText": "新增收货地址" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/UserAccount/index", |
|||
"style": { |
|||
"navigationBarTitleText": "账户余额" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/address/AddressManagement/index", |
|||
"style": { |
|||
"navigationBarTitleText": "收货地址" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/Poster/index", |
|||
"style": { |
|||
"navigationBarTitleText": "推广名片" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/signIn/Sign/index", |
|||
"style": { |
|||
"navigationBarTitleText": "签到" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/signIn/SignRecord/index", |
|||
"style": { |
|||
"navigationBarTitleText": "签到记录" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/CashAudit/index", |
|||
"style": { |
|||
"navigationBarTitleText": "提现结果" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/PromoterOrder/index", |
|||
"style": { |
|||
"navigationBarTitleText": "分销详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/PromoterList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "分销列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/UserPromotion/index", |
|||
"style": { |
|||
"navigationBarTitleText": "佣金" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/UserBill/index", |
|||
"style": { |
|||
"navigationBarTitleText": "账单记录" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/CashRecord/index", |
|||
"style": { |
|||
"navigationBarTitleText": "提现记录" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/CommissionDetails/index", |
|||
"style": { |
|||
"navigationBarTitleText": "佣金明细" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/signIn/Integral/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的积分" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/UserVip/index", |
|||
"style": { |
|||
"navigationBarTitleText": "用户vip" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/PersonalData/index", |
|||
"style": { |
|||
"navigationBarTitleText": "个人资料" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/coupon/UserCoupon/index", |
|||
"style": { |
|||
"navigationBarTitleText": "优惠券" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/coupon/GetCoupon/index", |
|||
"style": { |
|||
"navigationBarTitleText": "领取优惠券" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/promotion/UserCash/index", |
|||
"style": { |
|||
"navigationBarTitleText": "提现" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/CustomerList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "客服列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/user/Recharge/index", |
|||
"style": { |
|||
"navigationBarTitleText": "充值" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/MyOrder/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的订单" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/Logistics/index", |
|||
"style": { |
|||
"navigationBarTitleText": "查看物流" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/OrderDetails/index", |
|||
"style": { |
|||
"navigationBarTitleText": "订单详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/OrderSubmission/index", |
|||
"style": { |
|||
"navigationBarTitleText": "提交订单" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/PaymentStatus/index", |
|||
"style": { |
|||
"navigationBarTitleText": "支付状态" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/GoodsReturn/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商品退货" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/order/ReturnList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的售后" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/OrderIndex/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商家订单统计" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/AdminOrderList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "订单" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/GoodsDeliver/index", |
|||
"style": { |
|||
"navigationBarTitleText": "发货" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/AdminOrder/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商家订单列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/Statistics/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商家统计数据" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/orderAdmin/OrderCancellation/index", |
|||
"style": { |
|||
"navigationBarTitleText": "商家核销订单" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/Poster/index", |
|||
"style": { |
|||
"navigationBarTitleText": "推广海报" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/DargainDetails/index", |
|||
"style": { |
|||
"navigationBarTitleText": "帮砍价" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/GoodsBargain/index", |
|||
"style": { |
|||
"navigationBarTitleText": "砍价列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/BargainRecord/index", |
|||
"style": { |
|||
"navigationBarTitleText": "砍价记录" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/GoodsGroup/index", |
|||
"style": { |
|||
"navigationBarTitleText": "团购商品列表" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/GroupDetails/index", |
|||
"style": { |
|||
"navigationBarTitleText": "团购商品详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/GroupRule/index", |
|||
"style": { |
|||
"navigationBarTitleText": "团购规则" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/GoodsSeckill/index", |
|||
"style": { |
|||
"navigationBarTitleText": "秒杀" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/activity/SeckillDetails/index", |
|||
"style": { |
|||
"navigationBarTitleText": "秒杀详情" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/map/index", |
|||
"style": { |
|||
"navigationBarTitleText": "地图" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/shop/Live/LiveList/index", |
|||
"style": { |
|||
"navigationBarTitleText": "直播列表" |
|||
} |
|||
} |
|||
], |
|||
"easycom": { |
|||
"autoscan": true, |
|||
"custom": { |
|||
"tui-(.*)": "@/components/tui-$1/tui-$1.vue" |
|||
} |
|||
}, |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "Yshop", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8", |
|||
"navigationStyle": "default" |
|||
}, |
|||
"tabBar": { |
|||
"color": "#282828", |
|||
"selectedColor": "#eb3729", |
|||
"borderStyle": "black", |
|||
"backgroundColor": "#ffffff", |
|||
"height": "50px", |
|||
"fontSize": "10px", |
|||
"iconWidth": "24px", |
|||
"spacing": "3px", |
|||
"list": [ |
|||
{ |
|||
"pagePath": "pages/home/index", |
|||
"iconPath": "static/icon-home.png", |
|||
"selectedIconPath": "static/icon-home-hot.png", |
|||
"text": "首页" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/shop/GoodsClass/index", |
|||
"iconPath": "static/icon-class.png", |
|||
"selectedIconPath": "static/icon-class-hot.png", |
|||
"text": "分类" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/shop/ShoppingCart/index", |
|||
"iconPath": "static/icon-cart.png", |
|||
"selectedIconPath": "static/icon-cart-hot.png", |
|||
"text": "购物车" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/user/User/index", |
|||
"iconPath": "static/icon-user.png", |
|||
"selectedIconPath": "static/icon-user-hot.png", |
|||
"text": "我的" |
|||
} |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,103 @@ |
|||
<template> |
|||
<view class="lottie-bg"> |
|||
<view id="lottie"> |
|||
<image src="@/static/live-logo.gif" rel="preload" mode="widthFix" style="width: 100%" /> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState, mapMutations, mapActions } from 'vuex' |
|||
// 组件 |
|||
// import request from "@//api/request"; |
|||
import { wxappAuth } from '@/api/user' |
|||
import dayjs from 'dayjs' |
|||
import store from '@/store' |
|||
import cookie from '@/utils/store/cookie' |
|||
import { parseQuery, login, handleQrCode, getCurrentPageUrl, handleUrlParam, getCurrentPageUrlWithArgs } from '@/utils' |
|||
|
|||
export default { |
|||
name: 'Loading', |
|||
data() { |
|||
return {} |
|||
}, |
|||
onShow() { |
|||
console.log('getUser') |
|||
var url = handleQrCode() |
|||
if (!url) { |
|||
url = handleUrlParam(getCurrentPageUrlWithArgs()) |
|||
} |
|||
console.log(url) |
|||
console.log('判断是否是分销') |
|||
// 判断是否是分销 |
|||
if (url) { |
|||
let urlSpread = parseInt(url.spread) |
|||
if (urlSpread) { |
|||
cookie.set('spread', urlSpread) |
|||
} |
|||
} |
|||
if (this.$deviceType == 'app' || this.$deviceType == 'weixinh5') { |
|||
this.$yrouter.switchTab({ |
|||
path: '/pages/home/index', |
|||
}) |
|||
return |
|||
} |
|||
if (this.$store.getters.token) { |
|||
// 如果token存在,直接进行进页面 |
|||
console.log('登录状态存在,直接进页面') |
|||
this.toLaunch() |
|||
return |
|||
} |
|||
console.log('进行登录操作') |
|||
login().finally(() => { |
|||
this.$yrouter.switchTab({ |
|||
path: '/pages/home/index', |
|||
}) |
|||
}) |
|||
}, |
|||
methods: { |
|||
...mapActions(['changeAuthorization', 'setUserInfo', 'getUser']), |
|||
toLaunch() { |
|||
console.log('loading home') |
|||
this.changeAuthorization(false) |
|||
let redirect = cookie.get('redirect').replace(/\ /g, '') |
|||
cookie.remove('redirect') |
|||
if (redirect && redirect.indexOf('/pages') != -1) { |
|||
this.$yrouter.replace({ |
|||
path: '/pages' + redirect.split('/pages')[1], |
|||
}) |
|||
} else { |
|||
this.$yrouter.switchTab({ |
|||
path: '/pages/home/index', |
|||
}) |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.lottie-bg { |
|||
position: fixed; |
|||
left: 0; |
|||
top: 0; |
|||
background-color: #fff; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 999; |
|||
display: -webkit-flex; |
|||
display: flex; |
|||
-webkit-align-items: center; |
|||
align-items: center; |
|||
-webkit-justify-content: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
#lottie { |
|||
width: 35%; |
|||
display: block; |
|||
overflow: hidden; |
|||
transform: translate3d(0, 0, 0); |
|||
margin: auto; |
|||
} |
|||
</style> |
@ -0,0 +1,55 @@ |
|||
<template> |
|||
<view class="not-defined"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/404.png`" /> |
|||
<view class="content"> |
|||
<h3 class="title">页面未找到</h3> |
|||
<text>抱歉!您访问的页面不存在,请返回上一级或点击下方按钮返回首页...</text> |
|||
</view> |
|||
<view class="btn" @click="homeGo()"> |
|||
返回首页 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "NotDefined", |
|||
methods: { |
|||
homeGo() { |
|||
this.$yrouter.switchTab('/pages/home/index'); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.not-defined image{ |
|||
width: 100%; |
|||
margin-top: 18%; |
|||
} |
|||
|
|||
.content { |
|||
padding: 0 1*100rpx; |
|||
text-align: center; |
|||
color: #44405e; |
|||
font-size: 15px; |
|||
} |
|||
|
|||
.title { |
|||
margin-bottom: 0.6*100rpx; |
|||
color: #302c48; |
|||
font-size: 20px; |
|||
} |
|||
|
|||
.btn { |
|||
color: #fff; |
|||
background-color: #ef4c4c; |
|||
font-size: 16px; |
|||
padding: 0.16*100rpx; |
|||
border-radius: 25px; |
|||
text-align: center; |
|||
width: 2.4*100rpx; |
|||
margin: 0 auto; |
|||
margin-top: 1*100rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,131 @@ |
|||
<template> |
|||
<view class="bargain-record" ref="container"> |
|||
<view class="item" v-for="(item, bargainrecordIndex) in bargain" :key="bargainrecordIndex"> |
|||
<view class="picTxt acea-row row-between-wrapper"> |
|||
<view class="pictrue"> |
|||
<image :src="item.image" /> |
|||
</view> |
|||
<view class="text acea-row row-column-around"> |
|||
<view class="line1">{{ item.title }}</view> |
|||
<count-down |
|||
:isDay="true" |
|||
:tipText="'倒计时 '" |
|||
:dayText="' 天 '" |
|||
:hourText="' 时 '" |
|||
:minuteText="' 分 '" |
|||
:secondText="' 秒'" |
|||
:datatime="item.datatime" |
|||
></count-down> |
|||
<view class="money font-color-red"> |
|||
已砍至 |
|||
<text class="symbol">¥</text> |
|||
<text class="num">{{ item.residuePrice }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="bottom acea-row row-between-wrapper"> |
|||
<view class="purple" v-if="item.status === 1">活动进行中</view> |
|||
<view class="success" v-else-if="item.status === 3">砍价成功</view> |
|||
<view class="end" v-else>活动已结束</view> |
|||
<view class="acea-row row-middle row-right"> |
|||
<view |
|||
class="bnt cancel" |
|||
v-if="item.status === 1" |
|||
@click="getBargainUserCancel(item.bargainId)" |
|||
>取消活动</view> |
|||
<view |
|||
class="bnt bg-color-red" |
|||
v-if="item.status === 1" |
|||
@click="goDetail(item.bargainId)" |
|||
>继续砍价</view> |
|||
<view class="bnt bg-color-red" v-else @click="goList">重开一个</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<Loading :loaded="status" :loading="loadingList"></Loading> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import CountDown from "@/components/CountDown"; |
|||
import { getBargainUserList, getBargainUserCancel } from "@/api/activity"; |
|||
import Loading from "@/components/Loading"; |
|||
|
|||
export default { |
|||
name: "BargainRecord", |
|||
components: { |
|||
CountDown, |
|||
Loading |
|||
}, |
|||
props: {}, |
|||
data: function() { |
|||
return { |
|||
bargain: [], |
|||
status: false, //砍价列表是否获取完成 false 未完成 true 完成 |
|||
loadingList: false, //当前接口是否请求完成 false 完成 true 未完成 |
|||
page: 1, //页码 |
|||
limit: 20 //数量 |
|||
}; |
|||
}, |
|||
mounted: function() { |
|||
this.getBargainUserList(); |
|||
}, |
|||
onReachBottom() { |
|||
!this.loadingList && this.getBargainUserList(); |
|||
}, |
|||
methods: { |
|||
goDetail: function(id) { |
|||
this.$yrouter.push({ |
|||
path: "/pages/activity/DargainDetails/index", |
|||
query: { id, partake: 0 } |
|||
}); |
|||
}, |
|||
goList: function() { |
|||
this.$yrouter.push({ |
|||
path: "/pages/activity/GoodsBargain/index" |
|||
}); |
|||
}, |
|||
getBargainUserList: function() { |
|||
var that = this; |
|||
if (that.loadingList) return; |
|||
if (that.status) return; |
|||
getBargainUserList({ page: that.page, limit: that.limit }) |
|||
.then(res => { |
|||
that.status = res.data.length < that.limit; |
|||
that.bargain.push.apply(that.bargain, res.data); |
|||
that.page++; |
|||
that.loadingList = false; |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: "none", |
|||
duration: 2000 |
|||
}); |
|||
}); |
|||
}, |
|||
getBargainUserCancel: function(bargainId) { |
|||
var that = this; |
|||
getBargainUserCancel({ bargainId: bargainId }) |
|||
.then(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: "success", |
|||
duration: 2000 |
|||
}); |
|||
that.status = false; |
|||
that.loadingList = false; |
|||
that.page = 1; |
|||
that.bargain = []; |
|||
that.getBargainUserList(); |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: "none", |
|||
duration: 2000 |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,629 @@ |
|||
<template> |
|||
<view class="bargain on"> |
|||
<!-- 在header上加 on 为请求支援 --> |
|||
<!-- 当前登录的用户和url上携带的用户id不一致视为被邀请砍价 --> |
|||
<view class="wrapper bargain-box on user" v-if="bargainUserInfo && bargainUid != userInfo.uid"> |
|||
<!-- <view class="people"> |
|||
{{ bargainShare.lookCount }}人查看 丨 {{ bargainShare.shareCount }}人分享 丨 {{ bargainShare.userCount }}人参与 |
|||
</view> --> |
|||
<!-- 帮助砍价、帮砍成功:--> |
|||
<view class="pictxt acea-row row-center-wrapper"> |
|||
<div class="bargain-header"> |
|||
<view class="pictrue"><image :src="bargainUserInfo.avatar" /></view> |
|||
<view class="text"> |
|||
{{ bargainUserInfo.nickname }} |
|||
<text>邀请您帮忙砍价</text> |
|||
</view> |
|||
</div> |
|||
</view> |
|||
</view> |
|||
<view class="wrapper bargain-box time on"> |
|||
<div class="pictxt"> |
|||
<count-down :isDay="true" :tipText="'倒计时 '" :dayText="' 天 '" :hourText="' 时 '" :minuteText="' 分 '" :secondText="' 秒'" :datatime="goodsDetail.stopTime"></count-down> |
|||
</div> |
|||
</view> |
|||
<view class="wrapper bargain-box bargain-product"> |
|||
<view class="pictxt acea-row row-between-wrapper" @click="openAlone"> |
|||
<view class="pictrue"> |
|||
<image :src="goodsDetail.image" /> |
|||
<view class="bargain_view"> |
|||
查看商品 |
|||
<view class="iconfont icon-jiantou iconfonts"></view> |
|||
</view> |
|||
</view> |
|||
<view class="text acea-row row-column-around"> |
|||
<view class="line2" v-text="goodsDetail.title"></view> |
|||
<view class="money font-color-red"> |
|||
已砍至: ¥ |
|||
<text class="num" v-text="bargainHelpCount.remainingPrice"></text> |
|||
</view> |
|||
<view class="acea-row row-middle"> |
|||
<view class="successNum" v-text="`原价:${goodsDetail.price || 0}`"></view> |
|||
<view class="successNum" v-text="`已有${bargainSumCount || 0}人砍价成功`"></view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 砍价进度条 --> |
|||
<view class="cu-progress acea-row row-middle round margin-top"> |
|||
<view class="acea-row row-middle bg-red" :style="{ width: bargainHelpCount.pricePercent + '%' }"></view> |
|||
</view> |
|||
|
|||
<!-- 砍价进度条下的金额 --> |
|||
<view class="balance acea-row row-between-wrapper"> |
|||
<view v-text="`已砍${bargainHelpCount.alreadyPrice || 0}元`"></view> |
|||
<view v-if="bargainHelpCount.price === 0">砍价成功</view> |
|||
<view v-else v-text="`还剩${bargainHelpCount.price || 0}元`"></view> |
|||
</view> |
|||
|
|||
<!-- 砍价成功:--> |
|||
<!-- |
|||
surplusPrice 砍价剩余金额为0 |
|||
bargainUid 砍价人为发起砍价用户 |
|||
userBargainStatus 砍价状态为 |
|||
--> |
|||
<view class="bargainSuccess" v-if="pay"> |
|||
<span class="iconfont icon-xiaolian"></span> |
|||
恭喜您砍价成功,快去支付吧~ |
|||
</view> |
|||
|
|||
<!-- 参与砍价按钮 同一人--> |
|||
<view v-if="participate" class="bargainBnt" @click="goParticipate">立即发起砍价</view> |
|||
|
|||
<!-- 邀请好友按钮 --> |
|||
<view v-if="inviteFriends" class="bargainBnt" @click="goPoster">邀请好友帮砍价</view> |
|||
|
|||
<!-- 帮砍好友砍按钮 --> |
|||
<view v-if="helpFriendsBargain" class="bargainBnt" @click="getBargainHelp">帮好友砍一刀</view> |
|||
|
|||
<!-- 发起砍价按钮 非同一人--> |
|||
<view v-if="bargain" class="bargainBnt" @click="getBargainStart">我也要砍价</view> |
|||
|
|||
<!-- 支付按钮 --> |
|||
<view class="bargainBnt" @click="goPay" v-if="pay">立即支付</view> |
|||
|
|||
<view class="bargainBnt on" @click="goList">抢更多商品</view> |
|||
<view class="tip"> |
|||
已有 |
|||
<span class="font-color-red" v-text="bargainHelpCount.count"></span> |
|||
位好友成功帮您砍价 |
|||
</view> |
|||
<view class="lock"></view> |
|||
</view> |
|||
<view class="bargainGang bargain-box"> |
|||
<view class="title font-color-red acea-row row-center-wrapper"> |
|||
<view class="pictrue"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
<view class="titleCon">砍价帮</view> |
|||
<view class="pictrue on"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
</view> |
|||
<view class="list"> |
|||
<view class="item acea-row row-between-wrapper" v-for="(item, bargainHelpListIndex) in bargainHelpList" :key="bargainHelpListIndex"> |
|||
<view class="pictxt acea-row row-between-wrapper"> |
|||
<view class="pictrue"><image :src="item.avatar" /></view> |
|||
<view class="text"> |
|||
<view class="name line1" v-text="item.nickname"></view> |
|||
<view class="line1" v-text="item.add_time"></view> |
|||
</view> |
|||
</view> |
|||
<view class="money font-color-red"> |
|||
<text class="iconfont icon-kanjia"></text> |
|||
砍掉{{ item.price }}元 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="load font-color-red" v-if="!helpListStatus" @click="getBargainHelpList">点击加载更多</view> |
|||
<view class="lock"></view> |
|||
</view> |
|||
<view class="goodsDetails bargain-box"> |
|||
<view class="title font-color-red acea-row row-center-wrapper"> |
|||
<view class="pictrue"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
<view class="titleCon">商品详情</view> |
|||
<view class="pictrue on"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
</view> |
|||
<view class="conter" v-html="goodsDetail.description"></view> |
|||
<view class="lock"></view> |
|||
</view> |
|||
<view class="goodsDetails bargain-box"> |
|||
<view class="title font-color-red acea-row row-center-wrapper"> |
|||
<view class="pictrue"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
<view class="titleCon">活动规则</view> |
|||
<view class="pictrue on"><image :src="`${$VUE_APP_RESOURCES_URL}/images/left.png`" /></view> |
|||
</view> |
|||
<view class="conter" v-html="goodsDetail.rule"></view> |
|||
</view> |
|||
<view class="bargainTip" :class="active === true ? 'on' : ''"> |
|||
<view class="cutOff" v-if="bargainUid === userInfo.uid"> |
|||
您已砍掉 |
|||
<text class="font-color-red" v-text="bargainHelpPrice"></text> |
|||
元,听说分享次数越多砍价成功的机会越大哦! |
|||
</view> |
|||
<view class="cutOff on" v-else> |
|||
<view class="help font-color-red" v-text="'成功帮砍' + bargainHelpPrice + '元'"></view> |
|||
,您也可以砍价低价拿哦,快去挑选心仪的商品吧~ |
|||
</view> |
|||
<view class="tipBnt" @click="goPoster" v-if="bargainUid === userInfo.uid">邀请好友帮砍价</view> |
|||
<view class="tipBnt" @click="getBargainStart" v-else>我也要参与</view> |
|||
</view> |
|||
<view class="mask" @touchmove.prevent :hidden="active === false" @click="close"></view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import CountDown from '@/components/CountDown' |
|||
import { getBargainDetail, getBargainShare, getBargainStart, getBargainHelp, getBargainHelpPrice, getBargainHelpList, getBargainHelpCount, getBargainStartUser } from '@/api/activity' |
|||
import { postCartAdd } from '@/api/store' |
|||
import { mapGetters } from 'vuex' |
|||
import {} from '@/libs/wechat' |
|||
import { isWeixin, parseQuery, handleQrCode } from '@/utils/index' |
|||
|
|||
const NAME = 'DargainDetails' |
|||
|
|||
export default { |
|||
name: 'DargainDetails', |
|||
components: { |
|||
CountDown, |
|||
}, |
|||
props: {}, |
|||
data: function () { |
|||
return { |
|||
bargainId: 0, //砍价编号 |
|||
bargainSumCount: 0, //砍价成功人数 |
|||
activeMsg: '', |
|||
active: false, |
|||
bargainHelpPrice: 0, //砍掉金额 |
|||
bargainHelpList: [], |
|||
helpListStatus: false, //砍价列表是否获取完成 false 未完成 true 完成 |
|||
page: 1, //页码 |
|||
limit: 2, //数量 |
|||
pricePercent: 0, //砍价进度条 |
|||
bargainShare: {}, // 砍价分享的消息 |
|||
bargainHelpCount: {}, // 砍价的信息数据 |
|||
goodsDetail: {}, // 商品的详情 |
|||
bargainUserInfo: [], // 开启砍价用户信息 |
|||
bargainUid: 0, // 参与砍价的用户 |
|||
pay: false, // 支付 |
|||
bargain: false, // 发起砍价 |
|||
participate: false, // 参与砍价 |
|||
inviteFriends: false, // 邀请好友 |
|||
helpFriendsBargain: false, // 帮好友砍 |
|||
bargainSuccess: false, // 帮好友砍价成功 |
|||
mainBargainSuccess: false, // 砍价成功 |
|||
} |
|||
}, |
|||
computed: mapGetters(['userInfo', 'isLogin']), |
|||
mounted: function () { |
|||
this.mountedStart() |
|||
}, |
|||
methods: { |
|||
// 开始处理砍价逻辑 |
|||
mountedStart: function () { |
|||
var that = this |
|||
let url = handleQrCode() |
|||
// bargainId 砍价商品id |
|||
// bargainUid 发起砍价人 |
|||
if (url) { |
|||
// 通过二维码进来 |
|||
that.bargainId = url.bargainId |
|||
that.bargainUid = url.partake |
|||
} else { |
|||
// 正常途径进来 |
|||
that.bargainId = that.$yroute.query.id |
|||
that.bargainUid = that.$yroute.query.partake |
|||
} |
|||
if (this.bargainUid == 0 || !this.bargainUid) { |
|||
// url未携带用户uid,填上登录用户uid,跳转 |
|||
that.bargainUid = that.userInfo.uid |
|||
} |
|||
// 获取商品详情 |
|||
that.getBargainDetail() |
|||
// 砍价数据统计 |
|||
that.getBargainShare(0) |
|||
if (that.bargainUid !== that.userInfo.uid) { |
|||
that.getBargainStartUser() |
|||
} |
|||
}, |
|||
// 发起砍价 |
|||
goParticipate() { |
|||
//发起人和当前用户为同一人 |
|||
if (this.bargainUid === this.userInfo.uid) { |
|||
// 变更为当前用户砍价页面 |
|||
this.getBargainStart() |
|||
} else { |
|||
// 发起人与当前用户非同一人,变更为发起人的砍价页面 |
|||
this.getBargainStartUser() |
|||
} |
|||
this.getBargainHelpCount() |
|||
}, |
|||
// 查看商品 |
|||
openAlone: function () { |
|||
this.$yrouter.push({ |
|||
path: '/pages/shop/GoodsCon/index', |
|||
query: { |
|||
id: this.goodsDetail.productId, |
|||
}, |
|||
}) |
|||
}, |
|||
// 砍价完成,去支付 |
|||
goPay: function () { |
|||
var data = {} |
|||
var that = this |
|||
data.productId = that.goodsDetail.productId |
|||
data.cartNum = that.goodsDetail.num |
|||
data.uniqueId = '' |
|||
data.bargainId = that.bargainId |
|||
data.new = 1 |
|||
postCartAdd(data) |
|||
.then(res => { |
|||
that.$yrouter.push({ |
|||
path: '/pages/order/OrderSubmission/index', |
|||
query: { |
|||
id: res.data.cartId, |
|||
}, |
|||
}) |
|||
}) |
|||
.catch(err => { |
|||
uni.showToast({ |
|||
title: err.msg || err.response.data.msg || err.response.data.message, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 生成海报 |
|||
goPoster: function () { |
|||
var that = this |
|||
that.getBargainShare(that.bargainId) |
|||
this.$yrouter.push({ |
|||
path: '/pages/activity/Poster/index', |
|||
query: { |
|||
id: that.bargainId, |
|||
type: 2, |
|||
}, |
|||
}) |
|||
}, |
|||
// 跳转砍价商品列表 |
|||
goList: function () { |
|||
this.$yrouter.push({ |
|||
path: '/pages/activity/GoodsBargain/index', |
|||
}) |
|||
}, |
|||
//砍价分享 |
|||
//bargainId 0 获取 查看人数 分享人数 参与人数 |
|||
//bargainId 砍价产品编号 添加分享次数 获取 查看人数 分享人数 参与人数 |
|||
getBargainShare: function (bargainId) { |
|||
var that = this |
|||
getBargainShare({ |
|||
bargainId: bargainId, |
|||
}).then(res => { |
|||
that.bargainShare = res.data |
|||
}) |
|||
}, |
|||
// 获取产品详情 |
|||
getBargainDetail: function () { |
|||
var that = this |
|||
uni.showLoading({ |
|||
title: '加载中', |
|||
mask: true, |
|||
}) |
|||
getBargainDetail(that.bargainId) |
|||
.then(res => { |
|||
uni.hideLoading() |
|||
that.goodsDetail = res.data.bargain |
|||
console.log(that.goodsDetail) |
|||
that.goodsDetail.description = that.goodsDetail.description.replace(/\<img/gi, '<img style="max-width:100%;height:auto;"') |
|||
that.goodsDetail.rule = that.goodsDetail.rule.replace(/\<img/gi, '<img style="max-width:100%;height:auto;"') |
|||
that.getBargainHelpCount() |
|||
}) |
|||
.catch(res => { |
|||
uni.hideLoading() |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 开启砍价-发起人与当前用户非同一人 |
|||
getBargainStart: function () { |
|||
var that = this |
|||
getBargainStart({ |
|||
bargainId: that.bargainId, |
|||
}) |
|||
.then(() => { |
|||
that.bargainUid = that.userInfo.uid |
|||
that.getBargainHelp() |
|||
that.getBargainHelpCount() |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 参与砍价 |
|||
getBargainHelp: function () { |
|||
var that = this |
|||
if (this.bargainHelpCount.price === 0 && that.bargainUid !== that.userInfo.uid) { |
|||
return uni.showToast({ |
|||
title: '好友已经砍价成功', |
|||
icon: 'success', |
|||
duration: 2000, |
|||
}) |
|||
} |
|||
var data = { |
|||
bargainId: that.bargainId, |
|||
bargainUserUid: that.bargainUid, |
|||
} |
|||
getBargainHelp(data) |
|||
.then(res => { |
|||
that.activeMsg = res.data.status |
|||
if (res.data.status === 'SUCCESSFUL' && that.bargainUid !== that.userInfo.uid) { |
|||
uni.showToast({ |
|||
title: '您已经砍过了', |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
return |
|||
} |
|||
that.helpListStatus = false |
|||
that.page = 1 |
|||
that.bargainHelpList = [] |
|||
that.getBargainHelpPrice() |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
//获取砍掉的金额 |
|||
getBargainHelpPrice: function () { |
|||
var that = this |
|||
getBargainHelpPrice({ |
|||
bargainId: that.bargainId, |
|||
bargainUserUid: that.bargainUid, |
|||
}) |
|||
.then(res => { |
|||
that.bargainHelpPrice = res.data.price |
|||
that.getBargainHelpCount() |
|||
that.getBargainHelpList() |
|||
switch (that.activeMsg) { |
|||
case 'SUCCESSFUL': |
|||
break |
|||
case 'SUCCESS': |
|||
that.active = true |
|||
break |
|||
} |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 砍价帮助列表 |
|||
getBargainHelpList: function () { |
|||
var that = this |
|||
if (that.helpListStatus === true) return |
|||
getBargainHelpList({ |
|||
bargainId: that.bargainId, |
|||
bargainUserUid: that.bargainUid, |
|||
page: that.page, |
|||
limit: that.limit, |
|||
}) |
|||
.then(res => { |
|||
that.helpListStatus = res.data.length < that.limit |
|||
if (that.page == 1) { |
|||
that.bargainHelpList = [] |
|||
} |
|||
that.page++ |
|||
if (res.data) { |
|||
that.bargainHelpList.push.apply(that.bargainHelpList, res.data) |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
if (!err.msg) { |
|||
return |
|||
} |
|||
uni.showToast({ |
|||
title: err.msg || err.response.data.msg || err.response.data.message, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 砍价 砍价帮总人数、剩余金额、进度条、已经砍掉的价格 |
|||
getBargainHelpCount: function () { |
|||
getBargainHelpCount({ |
|||
bargainId: this.bargainId, |
|||
bargainUserUid: this.bargainUid, |
|||
}) |
|||
.then(res => { |
|||
// 剩余砍价金额,显示已砍至¥** 使用 = 商品价格 - 已经砍掉的金额 |
|||
let remainingPrice = (this.goodsDetail.price - res.data.alreadyPrice).toFixed(2) |
|||
this.bargainHelpCount = { |
|||
...res.data, |
|||
remainingPrice, |
|||
} |
|||
this.handleButtonStatus() |
|||
}) |
|||
.catch(err => { |
|||
if (!err.msg) { |
|||
return |
|||
} |
|||
uni.showToast({ |
|||
title: err.msg || err.response.data.msg || err.response.data.message, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 判断是否可以支付 |
|||
handleButtonStatus() { |
|||
// 砍价按钮分为 |
|||
// 1.参与砍价 ==> 发起人与当前用户为同一人 && 未参与 |
|||
if (this.bargainUid === this.userInfo.uid && this.bargainHelpCount.status == 0) { |
|||
this.participate = true |
|||
} else { |
|||
this.participate = false |
|||
} |
|||
|
|||
// 2.邀请好友 ==> 发起人与当前用户同一人 && 已参与未过期 && 剩余金额>0 |
|||
if (this.bargainUid === this.userInfo.uid && this.bargainHelpCount.status == 1 && this.bargainHelpCount.price > 0) { |
|||
this.inviteFriends = true |
|||
} else { |
|||
this.inviteFriends = false |
|||
} |
|||
|
|||
// 3.帮好友砍价 ==> 发起人与当前用户非一人 && 未参与未过期 && 剩余金额>0 && 为砍价 |
|||
if ( |
|||
this.bargainUid != this.userInfo.uid && |
|||
this.bargainHelpCount.status == 1 && |
|||
// this.bargainHelpCount.userBargainStatus && |
|||
this.bargainHelpCount.price > 0 |
|||
) { |
|||
this.helpFriendsBargain = true |
|||
} else { |
|||
this.helpFriendsBargain = false |
|||
} |
|||
|
|||
// 4.支付 ==> 发起人与当前用户同一人 && 已参与未过期 && 剩余金额<=0 |
|||
if (this.bargainUid === this.userInfo.uid && this.bargainHelpCount.status == 1 && this.bargainHelpCount.price <= 0) { |
|||
this.pay = true |
|||
} else { |
|||
this.pay = false |
|||
} |
|||
|
|||
// 5.砍价人发起新的砍价 ==> 发起人与当前用户非一人 && 未参与 |
|||
if (this.bargainUid != this.userInfo.uid) { |
|||
this.bargain = true |
|||
} else { |
|||
this.bargain = false |
|||
} |
|||
|
|||
// 砍价弹窗 |
|||
// 1.发起人砍价成功 ==> 发起人与当前用户同一人 && 已参与未过期 |
|||
// 2.砍价人砍价成功 ==> 发起人与当前用户非一人 && 已参与未过期 |
|||
// 3.已砍价 ==> 已参与 && 砍价状态为 true |
|||
}, |
|||
// 获取开启砍价用户信息 |
|||
// 参与砍价,为同一人发起砍价后 |
|||
getBargainStartUser: function () { |
|||
var that = this |
|||
getBargainStartUser({ |
|||
bargainId: that.bargainId, |
|||
bargainUserUid: that.bargainUid, |
|||
}) |
|||
.then(res => { |
|||
that.bargainUserInfo = res.data |
|||
that.getBargainHelpList() |
|||
}) |
|||
.catch(res => { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none', |
|||
duration: 2000, |
|||
}) |
|||
}) |
|||
}, |
|||
// 关闭弹窗 |
|||
close: function () { |
|||
this.active = false |
|||
}, |
|||
// 设置微信分享 |
|||
onShareAppMessage: function () { |
|||
return { |
|||
title: this.storeInfo.title, |
|||
imageUrl: this.storeInfo.image, |
|||
path: 'pages/activity/DargainDetails/index?id=' + this.storeInfo.id + '&spread=' + uni.getStorageSync('uid'), |
|||
success(res) { |
|||
uni.showToast({ |
|||
title: '分享成功', |
|||
}) |
|||
}, |
|||
fail(res) { |
|||
uni.showToast({ |
|||
title: '分享失败', |
|||
icon: 'none', |
|||
}) |
|||
}, |
|||
} |
|||
}, |
|||
}, |
|||
onShareAppMessage() { |
|||
return { |
|||
path: `/pages/activity/DargainDetails/index/?id=${this.$yroute.query.id}&partake=${this.userInfo.uid}`, |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less"> |
|||
.bargain { |
|||
&.on { |
|||
.bargain-box { |
|||
background: #fff; |
|||
width: auto; |
|||
margin: 0 20rpx; |
|||
border: 0; |
|||
} |
|||
|
|||
.header { |
|||
height: auto; |
|||
text-align: left; |
|||
|
|||
.time { |
|||
text-align: left; |
|||
font-size: 24rpx; |
|||
|
|||
margin: 0; |
|||
padding: 0; |
|||
padding: 20rpx; |
|||
width: auto; |
|||
height: auto; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
page { |
|||
background-color: #f5f5f5 !important; |
|||
} |
|||
|
|||
.bargainBnt_hui { |
|||
font-size: 0.3 * 100rpx; |
|||
font-weight: bold; |
|||
color: #fff; |
|||
width: 6 * 100rpx; |
|||
height: 0.8 * 100rpx; |
|||
border-radius: 0.4 * 100rpx; |
|||
background: #bbb; |
|||
text-align: center; |
|||
line-height: 0.8 * 100rpx; |
|||
margin-top: 0.32 * 100rpx; |
|||
} |
|||
|
|||
.bargain_view { |
|||
left: 0; |
|||
right: 0; |
|||
height: 0.48 * 100rpx; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
opacity: 1; |
|||
border-radius: 0 0 0.06 * 100rpx 0.06 * 100rpx; |
|||
position: absolute; |
|||
bottom: 0; |
|||
font-size: 0.22 * 100rpx; |
|||
color: #fff; |
|||
text-align: center; |
|||
line-height: 0.48 * 100rpx; |
|||
} |
|||
|
|||
.iconfonts { |
|||
font-size: 0.22 * 100rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,84 @@ |
|||
<template> |
|||
<view class="bargain-list"> |
|||
<!-- <view class="header"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/cut-bg.png`" alt=""> |
|||
</view>--> |
|||
<view class="list" v-if="bargainLis.length > 0"> |
|||
<view |
|||
class="item acea-row row-between-wrapper" |
|||
v-for="(item, bargainLisIndex) in bargainLis" |
|||
:key="bargainLisIndex" |
|||
> |
|||
<view class="pictrue"> |
|||
<image :src="item.image" /> |
|||
</view> |
|||
<view class="text acea-row row-column-around"> |
|||
<view class="line1" v-text="item.title"></view> |
|||
<view class="num"> |
|||
<text class="iconfont icon-pintuan"></text> |
|||
{{ item.people }}人正在参与 |
|||
</view> |
|||
<view class="money font-color-red"> |
|||
可砍至: ¥ |
|||
<text class="price">{{item.minPrice}}</text> |
|||
</view> |
|||
</view> |
|||
<view class="cutBnt bg-color-red" @click="goDetail(item.id)"> |
|||
<text class="iconfont icon-kanjia"></text>参与砍价 |
|||
</view> |
|||
</view> |
|||
<view class="load font-color-red" v-if="!status" @click="getBargainList">点击加载更多</view> |
|||
</view> |
|||
<!-- <view class="noCommodity" style="background-color: #fff;" v-if="bargainLis.length === 0"> |
|||
<view class="noPictrue"> |
|||
<image :src="`${$VUE_APP_RESOURCES_URL}/images/noGood.png`" class="image" /> |
|||
</view> |
|||
</view> --> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { getBargainList } from "@/api/activity"; |
|||
export default { |
|||
name: "GoodsBargain", |
|||
components: {}, |
|||
props: {}, |
|||
data: function() { |
|||
return { |
|||
bargainLis: [], //砍价列表 |
|||
status: false, //砍价列表是否获取完成 false 未完成 true 完成 |
|||
loading: false, //当前接口是否请求完成 false 完成 true 未完成 |
|||
page: 1, //页码 |
|||
limit: 20 //数量 |
|||
}; |
|||
}, |
|||
mounted: function() { |
|||
this.getBargainList(); |
|||
}, |
|||
methods: { |
|||
getBargainList: function() { |
|||
var that = this; |
|||
if (that.loading) return; |
|||
if (that.status) return; |
|||
that.loading = true; |
|||
getBargainList({ page: that.page, limit: that.limit }).then(res => { |
|||
that.status = res.data.length < that.limit; |
|||
that.bargainLis.push.apply(that.bargainLis, res.data); |
|||
that.page++; |
|||
that.loading = false; |
|||
}); |
|||
}, |
|||
goDetail: function(id) { |
|||
this.$yrouter.push({ |
|||
path: "/pages/activity/DargainDetails/index", |
|||
query: { id, partake: 0 } |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style > |
|||
page{ |
|||
background-color: rgb(245, 245, 245); |
|||
} |
|||
</style> |