diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..676e256 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/atguigu-tuan/.hbuilderx/launch.json b/atguigu-tuan/.hbuilderx/launch.json new file mode 100644 index 0000000..cac109a --- /dev/null +++ b/atguigu-tuan/.hbuilderx/launch.json @@ -0,0 +1,19 @@ +{ + // 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": [ + { + "default": { + "launchtype": "local" + }, + "h5": { + "launchtype": "local" + }, + "mp-weixin": { + "launchtype": "local" + }, + "type": "uniCloud" + } + ] +} diff --git a/atguigu-tuan/App.vue b/atguigu-tuan/App.vue new file mode 100644 index 0000000..c3dc5ef --- /dev/null +++ b/atguigu-tuan/App.vue @@ -0,0 +1,23 @@ + + + diff --git a/atguigu-tuan/common/bmap-wx.min.js b/atguigu-tuan/common/bmap-wx.min.js new file mode 100644 index 0000000..11aeded --- /dev/null +++ b/atguigu-tuan/common/bmap-wx.min.js @@ -0,0 +1 @@ +"use strict"; function _classCallCheck(t, a) { if (!(t instanceof a)) throw new TypeError("Cannot call a class as a function") } var _createClass = function () { function t(t, a) { for (var e = 0; e < a.length; e++) { var i = a[e]; i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(t, i.key, i) } } return function (a, e, i) { return e && t(a.prototype, e), i && t(a, i), a } }(), BMapWX = function () { function t(a) { _classCallCheck(this, t), this.ak = a.ak } return _createClass(t, [{ key: "getWXLocation", value: function (t, a, e, i) { t = t || "gcj02", a = a || function () { }, e = e || function () { }, i = i || function () { }, wx.getLocation({ type: t, success: a, fail: e, complete: i }) } }, { key: "search", value: function (t) { var a = this; t = t || {}; var e = { query: t.query || "生活服务$美食&酒店", scope: t.scope || 1, filter: t.filter || "", coord_type: t.coord_type || 2, page_size: t.page_size || 10, page_num: t.page_num || 0, output: t.output || "json", ak: a.ak, sn: t.sn || "", timestamp: t.timestamp || "", radius: t.radius || 2e3, ret_coordtype: "gcj02ll" }, i = { iconPath: t.iconPath, iconTapPath: t.iconTapPath, width: t.width, height: t.height, alpha: t.alpha || 1, success: t.success || function () { }, fail: t.fail || function () { } }, n = function (t) { e.location = t.latitude + "," + t.longitude, wx.request({ url: "https://api.map.baidu.com/place/v2/search", data: e, header: { "content-type": "application/json" }, method: "GET", success: function (t) { var a = t.data; if (0 === a.status) { var e = a.results, n = {}; n.originalData = a, n.wxMarkerData = []; for (var s = 0; s < e.length; s++)n.wxMarkerData[s] = { id: s, latitude: e[s].location.lat, longitude: e[s].location.lng, title: e[s].name, iconPath: i.iconPath, iconTapPath: i.iconTapPath, address: e[s].address, telephone: e[s].telephone, alpha: i.alpha, width: i.width, height: i.height }; i.success(n) } else i.fail({ errMsg: a.message, statusCode: a.status }) }, fail: function (t) { i.fail(t) } }) }, s = function (t) { i.fail(t) }, o = function (t) { }; if (t.location) { var c = t.location.split(",")[1]; n({ errMsg: "input location", latitude: t.location.split(",")[0], longitude: c }) } else a.getWXLocation("gcj02", n, s, o) } }, { key: "suggestion", value: function (t) { var a = this; t = t || {}; var e = { query: t.query || "", region: t.region || "全国", city_limit: t.city_limit || !1, output: t.output || "json", ak: a.ak, sn: t.sn || "", timestamp: t.timestamp || "", ret_coordtype: "gcj02ll" }, i = { success: t.success || function () { }, fail: t.fail || function () { } }; wx.request({ url: "https://api.map.baidu.com/place/v2/suggestion", data: e, header: { "content-type": "application/json" }, method: "GET", success: function (t) { var a = t.data; 0 === a.status ? i.success(a) : i.fail({ errMsg: a.message, statusCode: a.status }) }, fail: function (t) { i.fail(t) } }) } }, { key: "regeocoding", value: function (t) { var a = this; t = t || {}; var e = { coordtype: t.coordtype || "gcj02ll", ret_coordtype: "gcj02ll", radius: t.radius || 1e3, ak: a.ak, sn: t.sn || "", output: t.output || "json", callback: t.callback || function () { }, extensions_poi: t.extensions_poi || 1, extensions_road: t.extensions_road || !1, extensions_town: t.extensions_town || !1, language: t.language || "zh-CN", language_auto: t.language_auto || 0 }, i = { iconPath: t.iconPath, iconTapPath: t.iconTapPath, width: t.width, height: t.height, alpha: t.alpha || 1, success: t.success || function () { }, fail: t.fail || function () { } }, n = function (t) { e.location = t.latitude + "," + t.longitude, wx.request({ url: "https://api.map.baidu.com/reverse_geocoding/v3", data: e, header: { "content-type": "application/json" }, method: "GET", success: function (a) { var e = a.data; if (0 === e.status) { var n = e.result, s = {}; s.originalData = e, s.wxMarkerData = [], s.wxMarkerData[0] = { id: 0, latitude: t.latitude, longitude: t.longitude, address: n.formatted_address, iconPath: i.iconPath, iconTapPath: i.iconTapPath, desc: n.sematic_description, business: n.business, alpha: i.alpha, width: i.width, height: i.height }, i.success(s) } else i.fail({ errMsg: e.message, statusCode: e.status }) }, fail: function (t) { i.fail(t) } }) }, s = function (t) { i.fail(t) }, o = function (t) { }; if (t.location) { var c = t.location.split(",")[1]; n({ errMsg: "input location", latitude: t.location.split(",")[0], longitude: c }) } else a.getWXLocation("gcj02", n, s, o) } }, { key: "geocoding", value: function (t) { var a = this; t = t || {}; var e = { address: t.address || "", city: t.city || "", ret_coordtype: t.coordtype || "gcj02ll", ak: a.ak, sn: t.sn || "", output: t.output || "json", callback: t.callback || function () { } }, i = { iconPath: t.iconPath, iconTapPath: t.iconTapPath, width: t.width, height: t.height, alpha: t.alpha || 1, success: t.success || function () { }, fail: t.fail || function () { } }; if (t.address) wx.request({ url: "https://api.map.baidu.com/geocoding/v3", data: e, header: { "content-type": "application/json" }, method: "GET", success: function (t) { var a = t.data; if (0 === a.status) { var e = a.result, n = a; n.originalData = a, n.wxMarkerData = [], n.wxMarkerData[0] = { id: 0, latitude: e.location.lat, longitude: e.location.lng, iconPath: i.iconPath, iconTapPath: i.iconTapPath, alpha: i.alpha, width: i.width, height: i.height }, i.success(n) } else i.fail({ errMsg: a.message, statusCode: a.status }) }, fail: function (t) { i.fail(t) } }); else { var n = { errMsg: "input address!" }; i.fail(n) } } }, { key: "weather", value: function (t) { var a = this; t = t || {}; var e = { coord_type: t.coord_type || "gcj02", output: t.output || "json", ak: a.ak, sn: t.sn || "", timestamp: t.timestamp || "" }, i = { success: t.success || function () { }, fail: t.fail || function () { } }, n = function (t) { e.location = t.longitude + "," + t.latitude, wx.request({ url: "https://api.map.baidu.com/telematics/v3/weather", data: e, header: { "content-type": "application/json" }, method: "GET", success: function (t) { var a = t.data; if (0 === a.error && "success" === a.status) { var e = a.results, n = {}; n.originalData = a, n.currentWeather = [], n.currentWeather[0] = { currentCity: e[0].currentCity, pm25: e[0].pm25, date: e[0].weather_data[0].date, temperature: e[0].weather_data[0].temperature, weatherDesc: e[0].weather_data[0].weather, wind: e[0].weather_data[0].wind }, i.success(n) } else i.fail({ errMsg: a.message, statusCode: a.status }) }, fail: function (t) { i.fail(t) } }) }, s = function (t) { i.fail(t) }, o = function (t) { }; if (t.location) { var c = t.location.split(",")[0]; n({ errMsg: "input location", latitude: t.location.split(",")[1], longitude: c }) } else a.getWXLocation("gcj02", n, s, o) } }]), t }(); module.exports.BMapWX = BMapWX; \ No newline at end of file diff --git a/atguigu-tuan/common/const.js b/atguigu-tuan/common/const.js new file mode 100644 index 0000000..49940e8 --- /dev/null +++ b/atguigu-tuan/common/const.js @@ -0,0 +1,2 @@ +export const BAIDU_MAP_AK = 'jU4Ww0DiPzXUZmCshR6XjcH5Y3AG6GCE' +export const BAIDU_MAP_WEB_AK = '1FRohQ2W2TH9XGvEHmuckB6G' \ No newline at end of file diff --git a/atguigu-tuan/common/css/iconfont.css b/atguigu-tuan/common/css/iconfont.css new file mode 100644 index 0000000..dbc2eec --- /dev/null +++ b/atguigu-tuan/common/css/iconfont.css @@ -0,0 +1,123 @@ +@font-face { + font-family: "iconfont"; /* Project id 2738663 */ + src: url('./common/css/iconfont.woff2?t=1629617005518') format('woff2'), + url('./common/css/iconfont.woff?t=1629617005518') format('woff'), + url('./common/css/iconfont.ttf?t=1629617005518') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-pinglun2:before { + content: "\e629"; +} + +.icon-tihuoguanli:before { + content: "\e6a9"; +} + +.icon-daifahuo1:before { + content: "\e612"; +} + +.icon-daifukuan:before { + content: "\e621"; +} + +.icon-tuikuanshouhou:before { + content: "\e6bb"; +} + +.icon-truck-full:before { + content: "\e9d9"; +} + +.icon-daifahuo:before { + content: "\e708"; +} + +.icon-dianpu:before { + content: "\e650"; +} + +.icon-miaosha:before { + content: "\e60e"; +} + +.icon-tubiaolunkuo-:before { + content: "\e605"; +} + +.icon-kefu:before { + content: "\e601"; +} + +.icon-shezhi:before { + content: "\e61c"; +} + +.icon-yonghu:before { + content: "\e616"; +} + +.icon-yaoqing:before { + content: "\e687"; +} + +.icon-ico:before { + content: "\e646"; +} + +.icon-yonghu1:before { + content: "\e615"; +} + +.icon-zhekou-:before { + content: "\e607"; +} + +.icon-tousu:before { + content: "\e638"; +} + +.icon-jiameng:before { + content: "\e624"; +} + +.icon-shanghupiliangruzhu:before { + content: "\e62b"; +} + +.icon-biaoqiankuozhan_tuijian-394:before { + content: "\ebfb"; +} + +.icon-tubiaozhizuomoban:before { + content: "\e647"; +} + +.icon-shuiguo:before { + content: "\f342"; +} + +.icon-cart:before { + content: "\e60c"; +} + +.icon-aui-icon-my:before { + content: "\e61f"; +} + +.icon-categories:before { + content: "\e60f"; +} + +.icon-home:before { + content: "\e61b"; +} + diff --git a/atguigu-tuan/common/css/iconfont.ttf b/atguigu-tuan/common/css/iconfont.ttf new file mode 100644 index 0000000..e43b99e Binary files /dev/null and b/atguigu-tuan/common/css/iconfont.ttf differ diff --git a/atguigu-tuan/common/css/iconfont.woff b/atguigu-tuan/common/css/iconfont.woff new file mode 100644 index 0000000..8759968 Binary files /dev/null and b/atguigu-tuan/common/css/iconfont.woff differ diff --git a/atguigu-tuan/common/css/iconfont.woff2 b/atguigu-tuan/common/css/iconfont.woff2 new file mode 100644 index 0000000..de55df0 Binary files /dev/null and b/atguigu-tuan/common/css/iconfont.woff2 differ diff --git a/atguigu-tuan/common/http.api.js b/atguigu-tuan/common/http.api.js new file mode 100644 index 0000000..965ed62 --- /dev/null +++ b/atguigu-tuan/common/http.api.js @@ -0,0 +1,167 @@ +import {BAIDU_MAP_WEB_AK} from './const.js'; + +const get_baidu_map_address = + `https://api.map.baidu.com/reverse_geocoding/v3/?output=json&ak=${BAIDU_MAP_WEB_AK}&coordtype=wgs84ll&location=` // 通过经纬度获取地址信息 +const get_home_index = 'home/index' // 获取首页数据 +const get_sys_region_find_all_list = '/sys/region/findAllList' // 查询所有提供点的区域 +const get_search_leader = '/search/leader' // 根据经纬度搜索提货点 +const get_select_leader = 'user/leader/auth/selectLeader' // 选择提货点 +const get_categories = '/home/category' // 获取分类 +const get_search_sku = '/search/sku' // 搜索商品 +const get_home_item = '/home/item' // 商品详情 +const get_add_to_cart = '/cart/addToCart' // 加入购物车 +const get_cart_list = '/cart/cartList' // 购物车列表 +const get_check_cart = '/cart/checkCart' // 切换购物车商品的选中状态 +const delete_cart = '/cart/deleteCart' // 删除购物车 +const get_activity_cart_list = '/cart/activityCartList' // 带活动的购物车列表 +const get_check_all_cart = '/cart/checkAllCart' // 对所有购物车商品进行全选/反选 +const post_batch_check_cart = '/cart/batchCheckCart' // 对指定的多个商品进行选择/反选 +const get_find_all_sec_kill_time_list = '/activity/seckill/findAllSeckillTimeList' // 从缓存中查询时间段列表 +const get_find_sec_kill_sku_list = '/activity/seckill/findSeckillSkuList/' // 从缓存中读取秒杀sku +const get_coupon_info = '/activity/auth/getCouponInfo/' // 领取优惠券 +const get_confirm_order = '/order/auth/confirmOrder' // 确认订单 +const post_submit_order = '/order/auth/submitOrder' // 生成订单 +const get_order_info = '/order/auth/getOrderInfoById' // 订单详情 +const get_wx_login = '/user/weixin/wxLogin' // 微信用户登陆 +const post_update_user = '/user/weixin/auth/updateUser' // 更新用户信息 +const get_weixin_payment = '/payment/weixin/createJsapi/' // 获取微信支付信息 +const get_find_user_order = '/order/auth/findUserOrderPage' // 获取用户订单信息 +const get_order_status = '/payment/weixin/queryPayStatus' // 获取订单状态 + +const install = (Vue, vm) => { + const limit = 10; + const page = 1 + + // 获取首页数据 + const getHomeIndex = () => vm.$u.get(get_home_index); + /*--------------------------------------------------------- + 提货点模块 + ---------------------------------------------------------*/ + // 根据经纬度获取地址信息 + const getBaiduMapAddress = (o) => vm.$u.get(get_baidu_map_address + `${o.latitude},${o.longitude}`) + // 查询所有提供点的区域 + const getSysRegionFindAllList = () => vm.$u.get(get_sys_region_find_all_list, { + showLoading: false + }); + // 根据经纬度搜索提货点 + const getSearchLeader = (o) => vm.$u.get(get_search_leader + `/${o.page}/${o.limit}`, { + ...o, + showLoading: false + }) + // 选择提货点 + const getSelectLeader = (o) => vm.$u.get(get_select_leader + `/${o.leaderId}`, { + showLoading: false + }) + /*--------------------------------------------------------- + 商品模块 + ---------------------------------------------------------*/ + // 获取分类 + const getCategories = () => vm.$u.get(get_categories, { + showLoading: false + }); + // 搜索商品 + const getSearchSku = (o) => vm.$u.get(get_search_sku + + `/${o.page || page}/${o.limit || limit}`, { + ...o, + limit: o.limit || limit + }); + // 商品详情 + const getHomeItem = (o) => vm.$u.get(get_home_item + `/${o.skuId}`); + /*--------------------------------------------------------- + 秒杀模块 + ---------------------------------------------------------*/ + // 从缓存中查询时间段列表 + const getFindAllSeckillTimeList = () => vm.$u.get(get_find_all_sec_kill_time_list); + // 从缓存中读取秒杀sku + const getFindSeckillSkuList = (o) => vm.$u.get(get_find_sec_kill_sku_list + `/${o.timeName}`); + /*--------------------------------------------------------- + 购物车模块 + ---------------------------------------------------------*/ + // 加入购物车 + const getAddToCart = (o) => vm.$u.get(get_add_to_cart + `/${o.skuId}/${o.skuNum}`, { + showLoading: false + }); + // 购物车列表 + const getCartList = () => vm.$u.get(get_cart_list); + // 切换购物车商品的选中状态 + const getCheckCart = (o) => vm.$u.get(get_check_cart + `/${o.skuId}/${o.isChecked}`, { + showLoading: false + }); + // 删除购物车 + const deleteCart = (skuId) => vm.$u.delete(delete_cart + `/${skuId}`, { + showLoading: false + }); + // 带活动的购物车列表 + const getActivityCartList = (o) => vm.$u.get(get_activity_cart_list, { + showLoading: o.showLoading ? o.showLoading : false + }); + // 对所有购物车商品进行全选/反选 + const getCheckAllCart = (o) => vm.$u.get(get_check_all_cart + `/${o.isChecked}`, { + showLoading: o.showLoading ? o.showLoading : false + }); + // 对指定的多个商品进行选择/反选 + const postBatchCheckCart = (o) => vm.$u.post(post_batch_check_cart + `/${o.isChecked}`, o.skuIdList); + // 领取优惠券 + const getCouponInfo = (o) => vm.$u.get(get_coupon_info + `/${o.id}`) + // 确认订单 + const getConfirmOrder = () => vm.$u.get(get_confirm_order) + // 生成订单 + const postSubmitOrder = (o) => vm.$u.post(post_submit_order, o) + // 订单详情 + const getOrderInfo = (o) => vm.$u.get(get_order_info + `/${o.orderId}`) + // 获取微信支付信息 + const getWxPayment = (o) => vm.$u.get(get_weixin_payment + `/${o.orderNo}`) + + // 获取订单状态信息 + const getOrderStatus = (o) => vm.$u.get(get_order_status + `/${o.orderNo}`) + + /*--------------------------------------------------------- + 用户登陆 + ---------------------------------------------------------*/ + // 微信用户登陆 + const getWxLogin = (o) => vm.$u.get(get_wx_login + `/${o.code}`, { + showLoading: false + }) + // 更新用户信息 + const postUpdateUser = (o) => vm.$u.post(post_update_user, { + ...o, + showLoading: false + }) + // 获取用户订单信息 + const getFindUserOrder = (o) => vm.$u.get(get_find_user_order + `/${o.page}/${o.limit}`, { + ...o + }) + + vm.$u.api = { + getHomeIndex, + getSysRegionFindAllList, + getSearchLeader, + getSelectLeader, + getCategories, + getSearchSku, + getHomeItem, + getAddToCart, + getCartList, + getCheckCart, + deleteCart, + getActivityCartList, + getCheckAllCart, + postBatchCheckCart, + getBaiduMapAddress, + getFindAllSeckillTimeList, + getFindSeckillSkuList, + getCouponInfo, + getConfirmOrder, + postSubmitOrder, + getOrderInfo, + getWxPayment, + getWxLogin, + postUpdateUser, + getFindUserOrder, + getOrderStatus + }; +} + +export default { + install +} diff --git a/atguigu-tuan/common/http.interceptor.js b/atguigu-tuan/common/http.interceptor.js new file mode 100644 index 0000000..fc1fc02 --- /dev/null +++ b/atguigu-tuan/common/http.interceptor.js @@ -0,0 +1,38 @@ +const install = (Vue, vm) => { + Vue.prototype.$u.http.setConfig({ + //baseUrl: 'https://gmall-prod.atguigu.cn/api', + baseUrl: 'http://ggkt2.vipgz1.91tunnel.com/api', + loadingText: '请求中...', // 请求loading中的文字提示 + loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms + loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透 + }); + + // 请求拦截,配置Token等参数 + Vue.prototype.$u.http.interceptor.request = (config) => { + config.header.token = uni.getStorageSync('token') + + return config; + } + // 响应拦截,判断状态码是否通过 + Vue.prototype.$u.http.interceptor.response = (res) => { + if (res.code == 200) { + return res.data; + } else if (res.code == 208) { + // 未登陆,token过期 + uni.reLaunch({ + url: '/pages/login/login' + }) + return false; + } else { + uni.showToast({ + title: res.message, + icon: 'none' + }) + return false; + } + } +} + +export default { + install +} diff --git a/atguigu-tuan/common/svgIcon.js b/atguigu-tuan/common/svgIcon.js new file mode 100644 index 0000000..c3bf001 --- /dev/null +++ b/atguigu-tuan/common/svgIcon.js @@ -0,0 +1,7 @@ +export const fruit = 'data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODEiIGhlaWdodD0iODEiPjxwYXRoIGQ9Ik01NDMuNjQyIDI2NC4zOTdjNS4xNDUtNi45ODkgOC4yNDMtMTUuNTkgOC4yNDMtMjQuOTYgMC0yMy4yOTYtMTguODY3LTQyLjE2My00Mi4xNjMtNDIuMTYzLTE3LjIzIDAtMzIuMDUyIDEwLjM2OC0zOC41OCAyNS4xOS0xMTYuMjI0LTQwLjc4LTI2MC44MzggMTQuNzQ2LTM0NC45MDggMTQwLjY0Ni05My42MiAxNDAuMTg2LTc3LjkyNyAzMTYuMjEyIDMzLjEyNiA0MDEuMTAxLTUuMjc0IDcuMDQtOC40NDggMTUuNzctOC40NDggMjUuMjQyIDAgMjMuMjk2IDE4Ljg2NyA0Mi4xNjMgNDIuMTYzIDQyLjE2MyAxOS4wNzIgMCAzNS4xNDktMTIuNjcyIDQwLjM3MS0zMC4wMjkgMTE0LjA0OCAzMy4xNTIgMjUxLjgwMi0yMi43ODQgMzMzLjA1Ni0xNDQuNDYgOTAuNjI0LTEzNS43MDYgNzguNzk3LTMwNS4wNzYtMjIuODYtMzkyLjczeiIgZmlsbD0iI0Y5QzA1RCIvPjxwYXRoIGQ9Ik01NTguMzEgMjg5LjUxUzMzMC43MjYgMzAxLjkgMjY1LjQ5OCA1MzMuM2MtNTQuOTEyIDE5NC43OSA1Ni4yMTcgMjY5LjI4NiA1Ni4yMTcgMjY5LjI4Nmw4MS40Ni0xOC4zMDRzLTk1LjU5MS05OS4zMjgtNjQuNzk0LTI1Ny42MzljMTcuMzMxLTU4LjcyNiA1NS4yMTktMTY3Ljg4NSAyMzAuNC0yMTAuNjg4IDMuODkxLTIxLjM3Ni0xMC40Ny0yNi40NDUtMTAuNDctMjYuNDQ1eiIgZmlsbD0iI0VBQTI0MiIvPjxwYXRoIGQ9Ik0zMzguMzU1IDU4NS45MDdhMjY5LjYyIDI2OS42MiAwIDEgMCA1MzkuMjM5IDAgMjY5LjYyIDI2OS42MiAwIDEgMC01MzkuMjM5IDB6IiBmaWxsPSIjRkZFMDhBIi8+PHBhdGggZD0iTTI0NS4yMjIgMzU3Ljc4NmExNS4zMyAxNS4zMyAwIDAgMS0xMS40NDMtNS4wOTVjLTUuNjU3LTYuMzIzLTUuMTQ1LTE2LjAyNSAxLjE3OC0yMS42ODMgMS43OTItMS42MTMgNDQuMTYtMzkuMzczIDg3LjgzMy01NS44ODUgNy45MzYtMi45OTUgMTYuNzk0Ljk5OSAxOS43OSA4LjkzNSAyLjk5NCA3LjkzNi0xIDE2Ljc5My04LjkzNSAxOS43ODgtMzguMjQ3IDE0LjQ2NC03Ny43OTkgNDkuNjY0LTc4LjE4MyA1MC4wMjNhMTUuMTk0IDE1LjE5NCAwIDAgMS0xMC4yNCAzLjkxN3pNMzcwLjM1NSAyNzQuMzU1YTE2LjM4NCAxNi4zODQgMCAxIDAgMzIuNzY4IDAgMTYuMzg0IDE2LjM4NCAwIDEgMC0zMi43NjggMHoiIGZpbGw9IiNGN0Y4RjgiLz48cGF0aCBkPSJNNzA3LjEyMyAzMzUuMTA0YzEyLjg3Ny0yNC4zMiAyMS43ODYtOTAuMDYgMTAuNjc1LTEyMy4zOTItNzUuMzQgMjcuNDk0LTEwNi41OTggNzAuOTYzLTExOS40NSAxMDQuNzggMy4yLS4xMDIgNi40LS4xNzggOS42MjYtLjE3OCAxMDAuMTQ4IDAgMTg3LjU0NiA1NC42MDQgMjM0LjAzNiAxMzUuNjU0IDYzLjUzOS0zOS44MzQgMTEyLjg5Ni0xMTEuODQ2IDEyNC44LTE2MC41MTItMTI0Ljg1Mi0zNi42MDgtMjE0LjQuNjY2LTI1OS42ODcgNDMuNjQ4eiIgZmlsbD0iIzY0RDg4MiIvPjxwYXRoIGQ9Ik05NTEuNzgyIDI5Ny45ODRzLTc0LjUyMSA2NS4zNTctMTQ1LjEgODYuMjcyYzMwLjA1NCA0MC41MjUgNDQuMDA2IDYxLjk3OCA0NC4wMDYgNjEuOTc4czk5Ljc4OS04NS41MDQgMTAxLjA5NC0xNDguMjV6IiBmaWxsPSIjNTJDMTY5Ii8+PHBhdGggZD0iTTc5OC43NzEgNjAxLjI2N0g0MTQuODIyYy04LjQ3MyAwLTE1LjM2LTYuODg2LTE1LjM2LTE1LjM2czYuODg3LTE1LjM2IDE1LjM2LTE1LjM2aDM4My45NWM4LjQ3MyAwIDE1LjM2IDYuODg3IDE1LjM2IDE1LjM2cy02Ljg4NyAxNS4zNi0xNS4zNiAxNS4zNnoiIGZpbGw9IiNFQUEyNDIiLz48cGF0aCBkPSJNNjA2Ljc5NyA3OTMuMjQyYy04LjQ3NCAwLTE1LjM2LTYuODg3LTE1LjM2LTE1LjM2di0zODMuOTVjMC04LjQ3MyA2Ljg4Ni0xNS4zNiAxNS4zNi0xNS4zNnMxNS4zNiA2Ljg4NyAxNS4zNiAxNS4zNnYzODMuOTVjMCA4LjQ3My02Ljg2MSAxNS4zNi0xNS4zNiAxNS4zNnoiIGZpbGw9IiNFQUEyNDIiLz48cGF0aCBkPSJNNDcxLjA2NiA3MzcuMDI0YTE1LjM2IDE1LjM2IDAgMCAxLTEwLjg1NS0yNi4yMTRMNzMxLjcgNDM5LjI5NmExNS4zNiAxNS4zNiAwIDAgMSAyMS43MDkgMGM1Ljk5IDUuOTkgNS45OSAxNS43MTggMCAyMS43MzRMNDgxLjkyIDczMi41MThhMTUuMzM3IDE1LjMzNyAwIDAgMS0xMC44NTQgNC41MDZ6IiBmaWxsPSIjRUFBMjQyIi8+PHBhdGggZD0iTTc0Mi41NTQgNzM3LjAyNGMtMy45NDMgMC03Ljg2LTEuNTEtMTAuODU1LTQuNTA2TDQ2MC4xODYgNDYxLjAzYy01Ljk5LTUuOTktNS45OS0xNS43MTggMC0yMS43MzRhMTUuMzYgMTUuMzYgMCAwIDEgMjEuNzA4IDBMNzUzLjQwOCA3MTAuODFhMTUuMzYgMTUuMzYgMCAwIDEtMTAuODU0IDI2LjIxNHoiIGZpbGw9IiNFQUEyNDIiLz48cGF0aCBkPSJNODM0LjI3OCA4MzkuODM0Yy0xNS4xNTUgMC0yNy40NDMgMTIuMjg4LTI3LjQ0MyAyNy40NDNzMTIuMjg4IDI3LjQ0MyAyNy40NDMgMjcuNDQzIDI3LjQ0NC0xMi4yODggMjcuNDQ0LTI3LjQ0My0xMi4yNjMtMjcuNDQzLTI3LjQ0NC0yNy40NDN6TTQwOS44NTYgODk0Ljc0NmExOS40MDUgMTkuNDA1IDAgMSAwIDM4LjgxIDAgMTkuNDA1IDE5LjQwNSAwIDEgMC0zOC44MSAwek05NzMuMjg2IDI2OS4zMzhjLTEwNS4yNDEtMzAuODQ4LTE4MS42MzItMTEuMzY3LTIyOS4zMjQgMTIuNjk3IDMuMTIzLTI3LjkzIDIuMzgtNTcuNDcyLTQuMzI3LTc3LjYxOWEyMy4wNTggMjMuMDU4IDAgMCAwLTI5Ljc3My0xNC4zNjJjLTY0LjQ4NiAyMy41MjctOTkuODE0IDU4LjQ0NS0xMTkuMTkzIDkwLjA2MWEyNTkuODcyIDI1OS44NzIgMCAwIDAtMTguODE2LTIwLjk5MmMyLjAyMi02LjMyMyAzLjA0Ni0xMi45NTMgMy4wNDYtMTkuNzEyIDAtMzUuOTQyLTI5LjIzNS02NS4yMDMtNjUuMjAzLTY1LjIwM2E2NS4xMjYgNjUuMTI2IDAgMCAwLTQ4LjA1MSAyMS4xNzFjLTU3LjgwNS0xNS43MTgtMTIyLjI5MS0xMS4wODUtMTgzLjYwMyAxMy40OTEtNjcuNDA1IDI3LjAwOC0xMjguMTI4IDc3LjIzNi0xNzAuOTgzIDE0MS40MTVDMTEuMzQxIDQ5My42NyAyMi43ODQgNjczLjk3IDEzMC43MTQgNzcwLjQwNmE2NS4xNiA2NS4xNiAwIDAgMC0yLjg0MiAxOS4wNzJjMCAzNS45NDMgMjkuMjM1IDY1LjIwNCA2NS4yMDMgNjUuMjA0IDIwLjg2NCAwIDQwLjE2Ny0xMC4xOSA1Mi4yNzUtMjYuMzQzIDU3LjAxMiAxMi4wODMgMTE3LjQyOCA0LjcxIDE3My44NzYtMTguOTQ0IDUwLjk5NSA0My4xMzYgMTE2Ljg5IDY5LjE5NyAxODguNzQ4IDY5LjE5NyAxNjEuMzgzIDAgMjkyLjY2LTEzMS4yNzcgMjkyLjY2LTI5Mi42NiAwLTQ1LjI2LTEwLjM0My04OC4xNjYtMjguNzc1LTEyNi40ODkgNjEuNjItNDUuNTE3IDEwNS43OC0xMTUuMzc5IDExNy4zMjUtMTYyLjQ4MyAyLjk0NC0xMS45OC00LjA3LTI0LjE0LTE1Ljg5OC0yNy42MjJ6bS0yNzMuNTYxLTI0Ljk2Yy43MTcgMjAuMTcyLTIuMjI3IDQ0LjA4My02LjU4IDYxLjU0MmEyOTAuMTk0IDI5MC4xOTQgMCAwIDAtNTYuNjc4LTExLjI2NGMxMi44NTEtMTcuMjI5IDMyLjY2Ni0zNS4yMjYgNjMuMjU4LTUwLjI3OHptLTQ1OS44NTMgNTM1LjA5Yy0xMi4xMzQtMy41MDYtMjQuODU4IDMuMzgtMjguNDkzIDE1LjQ4OS0yLjQwNiA4LjAxMy05LjkzMyAxMy42MTktMTguMzA0IDEzLjYxOS0xMC41NDcgMC0xOS4xMjMtOC41NzYtMTkuMTIzLTE5LjEyMyAwLTUuMTk3IDIuMS05LjA4OCAzLjg0LTExLjQxOCA3LjU3OC0xMC4xMTIgNS42MDYtMjQuNDQ4LTQuNDI5LTMyLjEyOC0xMDIuMTE4LTc4LjA1NC0xMTQuNDA2LTI0MC41ODktMjcuOTgtMzY5Ljk5NyA2MC4xNi05MC4wODYgMTU2LjA1Ny0xNDMuNTY0IDI0Ni45MzctMTQzLjU2NCAyNC4zNDYgMCA0OC4zNTggMy44NCA3MS4xOTQgMTEuODUyYTIzLjAwMiAyMy4wMDIgMCAwIDAgMjguNjk3LTEyLjQ0MWMzLjA3Mi02LjkzOCA5LjkzMy0xMS40NDMgMTcuNDg1LTExLjQ0MyAxMC41NDcgMCAxOS4xMjMgOC41NzYgMTkuMTIzIDE5LjEyMyAwIDUuMTItMi4wMjIgOC45Ni0zLjczNyAxMS4yOWEyMy4wMyAyMy4wMyAwIDAgMCAzLjUwNyAzMS4xMDNjNi41MDIgNS42MDcgMTIuNTQ0IDExLjU5NyAxOC4yMjcgMTcuODctMTMyLjA5NiAyOC4yMS0yMzEuNSAxNDUuODE3LTIzMS41IDI4Ni4yMDcgMCA3MS40NSAyNS43NTMgMTM2Ljk4NiA2OC40NTQgMTg3Ljg1My00Ny43MTkgMTYuNDEtOTcuNjEzIDE5LjE3NC0xNDMuODk4IDUuNzA5em0zNjguMTAyIDUzLjAxOGMtNTMuNDc4IDAtMTAzLjAxNC0xNy4xMjYtMTQzLjQ2Mi00Ni4xMyAwIDAtMzEuNjE2LTIyLjE3LTM2LjUwNi0zMi4wNTItNDEuMjkyLTQ0LjEwOS02Ni42MzYtMTAzLjM0Ny02Ni42MzYtMTY4LjM5NyAwLTEyNS4xODQgOTMuNzcyLTIyOC44OSAyMTQuNzU4LTI0NC41MzEgMCAwIDMzLjYxMy02LjQ1MSA1MC41MzQtMS4zMDYgNDUuNDQgMy40ODIgODguNjI4IDE5LjUzMyAxMjQuOTU0IDQ1LjU2OGwuNTYzLjQxYzEuNjEzIDEuMTUyIDMuMiAyLjM1NSA0Ljc4NyAzLjU1OC44Mi42MTUgMS42MzkgMS4yMyAyLjQzMiAxLjg3YTE2NS43NyAxNjUuNzcgMCAwIDEgMi4yMDIgMS43NjZjNTYuNjAyIDQ1LjIxIDkyLjkyOCAxMTQuNzkgOTIuOTI4IDE5Mi42OS4wMjYgMTM1LjkzNy0xMTAuNTkyIDI0Ni41NTQtMjQ2LjU1NCAyNDYuNTU0ek04NDguNTkgNDE5LjMwMmEyOTIuNDAzIDI5Mi40MDMgMCAwIDAtNTkuMjktNjIuOTI0Yy0uNTYzLS40NjEtMS4xNTItLjg5Ni0xLjcxNS0xLjMzMi0xLjE1Mi0uODk2LTIuMzA0LTEuNzY2LTMuNDU2LTIuNjYyLTEuNDM0LTEuMDc1LTIuODkzLTIuMTUtNC4zNTItMy4yMjYtLjQxLS4zMDctLjg0NS0uNjE0LTEuMjU0LS45MjFhMjkyLjU5NyAyOTIuNTk3IDAgMCAwLTI3LjQ5NS0xNy41NjJjMzQuNDgzLTIwLjk5MiA5NS45MjMtNDMuNDk0IDE4Ni4wMzUtMjMuMTY4LTE1LjM4NSAzNi4xOTktNDcuODcyIDgwLjUzOC04OC40NzMgMTExLjc5NXoiIGZpbGw9IiM0NzRFNTQiLz48L3N2Zz4=' + +export const discount = 'data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODEiIGhlaWdodD0iODEiPjxwYXRoIGQ9Ik05MjMuNTI0IDUxNC42NjZMNjIxLjU2MiAxMDMuMTk5YTguNzk1IDguNzk1IDAgMCAwLTcuMDYxLTMuNTg5bC0yNjQuMjI3LS44MzhoLS4wMjdhOC43OSA4Ljc5IDAgMCAwLTguMzk2IDYuMTg1bC00My4xMTMgMTM4LjgxMS0xMTIuNjM5LS4zNThoLS4wMjdhOC43OSA4Ljc5IDAgMCAwLTguMzk2IDYuMTg0bC03OC41MDggMjUyLjc3YTguNzg2IDguNzg2IDAgMCAwIDEuMzA5IDcuODExbDMwMS45NjEgNDExLjQ2NmE4Ljc5NSA4Ljc5NSAwIDAgMCAxMi4yOTcgMS44ODNsMzQyLjczNC0yNTEuOTNhOC43OTQgOC43OTQgMCAwIDAgMS44ODEtMTIuMjg5bC02LjIyMy04LjQ3OSAxNjguNTE4LTEyMy44NzFjMy45MDktMi44NzcgNC43NTEtOC4zNzcgMS44NzktMTIuMjg5em0tNTA3LjUzIDI0NC41OTJhNi44MzIgNi44MzIgMCAwIDEtOS41MjMtMS42ODIgNi44MzcgNi44MzcgMCAwIDEgMS42ODMtOS41MjNsOTAuNjY2LTYzLjQyOCA3LjIwNy01LjA0MyA3LjIwNy01LjA0MS0zOC41MDgtNTIuNDczLTcuMjA3IDUuMDQxLTcuMjA3IDUuMDQzLTkyLjE4NCA2NC40ODhhNi44MTQgNi44MTQgMCAwIDEtMy45MTQgMS4yMzYgNi44MjcgNi44MjcgMCAwIDEtNS42MDktMi45MiA2LjgzNiA2LjgzNiAwIDAgMSAxLjY4NC05LjUyM2w5MS45My02NC4zMTEgNy4yMDctNS4wNDMgNy4yMDctNS4wNDEtMzguNTEtNTIuNDczLTcuMjA2IDUuMDQxLTcuMjA3IDUuMDQxLTkzLjQ0OCA2NS4zNzVhNi44MzMgNi44MzMgMCAwIDEtOS41MjMtMS42ODQgNi44MzYgNi44MzYgMCAwIDEgMS42ODMtOS41MjNsOTMuMTk0LTY1LjE5NyA3LjIwNy01LjA0MSA3LjIwNy01LjA0MS01OS4zNzMtODAuOTA1YTc0Ljc1IDc0Ljc1IDAgMCAxLTYuNDI4IDYuMTA0IDc0LjU0NyA3NC41NDcgMCAwIDEtMy45ODggMy4xNjUgNzcuNDgxIDc3LjQ4MSAwIDAgMS0zLjA0MyAyLjExNmMtMzMuMDM5IDIxLjg0Mi03Ny45MDYgMTQuMDk4LTEwMS41OTItMTguMTc3LTI0LjQyLTMzLjI3NC0xNy4yMTUtODAuMjE0IDE2LjA2MS0xMDQuNjM0YTc0LjYxMiA3NC42MTIgMCAwIDEgMy4xMzctMi4xODIgNzQuNTEyIDc0LjUxMiAwIDAgMSAxMS4wNy02LjAwMiA3My45MTggNzMuOTE4IDAgMCAxIDEwLjM0NC0zLjY1NmwzMC45MTYtOTkuNTQzIDM5LjU4NC0xMjcuNDQ2IDI1My4yOTMuODAyIDI5NC4xNDEgNDAwLjgwOC0xNjEuNDMxIDExOC42Ni0xNjcuMTM4IDEyMi44NTgtNTQuMjU2LTczLjkzNC03LjIwNSA1LjA0MS03LjIwNyA1LjA0MS05MC45MjEgNjMuNjA2eiIgZmlsbD0iI0QzMjA1NSIvPjxwYXRoIGQ9Ik0yODguNzE2IDM4My40NjhhMzYuMjQxIDM2LjI0MSAwIDAgMC03LjE5MSA1LjA2MWMtMTMuNjk2IDEyLjM1OS0xNi4wODYgMzMuMzkzLTQuOTQxIDQ4LjU3OSAxMS4xNDUgMTUuMTg4IDMxLjkyNiAxOS4yMTUgNDcuODI0IDkuODU1YTM2LjIzMiAzNi4yMzIgMCAwIDAgMy4wOTgtMi4wMzkgMzYuNzE3IDM2LjcxNyAwIDAgMCAzLjg4OS0zLjMwNCAzNi4xMzggMzYuMTM4IDAgMCAwIDUuNjczLTcuMTNsLTM5Ljg0Ny01NC4yOTdhMzYuMTU3IDM2LjE1NyAwIDAgMC04LjUwNSAzLjI3NXptMjI1LjY5OS01Mi4yMDRhNzUuMjI3IDc1LjIyNyAwIDAgMCAyLjY3Ni0yLjA3MmMzMC45NjMtMjQuOTI0IDM3LjEzMi03MC4yMDIgMTMuMzgzLTEwMi41NjItMjQuNDE5LTMzLjI3NC03MS4zNTktNDAuNDc5LTEwNC42MzMtMTYuMDYtMTIuMDAxIDguODA3LTIwLjU5IDIwLjU0OS0yNS41NDkgMzMuNTE3LTguNzg5IDIyLjk4OS02LjEyNSA0OS44NDMgOS40ODggNzEuMTE4IDI0LjQyIDMzLjI3NCA3MS4zNTggNDAuNDc5IDEwNC42MzUgMTYuMDU5em0tNzMuNjU2LTM4Ljc5NGMtMTEuMDQ1LTE1LjA1LTguNzg5LTM1LjgzNyA0LjU4Mi00OC4yMzlhMzYuNTc3IDM2LjU3NyAwIDAgMSAzLjIzNC0yLjY4MmMxNi4xOTMtMTEuODg1IDM5LjAzNy04LjM3OCA1MC45MiA3LjgxNiAxMS4yMTEgMTUuMjcyIDguNzIzIDM2LjQ1Ni01LjE4NCA0OC43ODdhMzYuNDMgMzYuNDMgMCAwIDEtMi42MzEgMi4xMzVjLTE2LjE5NSAxMS44ODQtMzkuMDM3IDguMzc4LTUwLjkyMS03LjgxN3oiIGZpbGw9IiNEMzIwNTUiLz48cGF0aCBkPSJNNTU4LjM3NCA2NDMuMDU3bDcuOTU3IDEwLjg4NSAxLjMzMiAxLjgyMmE2Ljg0MyA2Ljg0MyAwIDAgMCA5LjU1NyAxLjQ4NWwxMTcuNTU0LTg1LjkzOEw4MDguNjkgNDg4LjAzYTYuODM3IDYuODM3IDAgMCAwIDEuNDg1LTkuNTU2TDcxMC4wNDggMzQxLjUxMmE2Ljg0NSA2Ljg0NSAwIDAgMC00LjQ3Mi0yLjcyMyA2Ljg1OSA2Ljg1OSAwIDAgMC01LjA4NSAxLjIzNmwtMTE0LjE4OCA4My40NzktMTE3LjI4MSA4NS43NGE2LjgzOSA2LjgzOSAwIDAgMC0yLjM2OSA3LjkxYy4yMTUuNTcyLjUwNCAxLjEyOS44ODMgMS42NDhsNC44NDYgNi42MjUgMzkuNzgzIDU0LjQyIDcuMzU5IDEwLjA2OCAzOC44NSA1My4xNDJ6IiBmaWxsPSIjRTNCOTMzIi8+PC9zdmc+' + +export const invite = 'data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODEiIGhlaWdodD0iODEiPjxwYXRoIGQ9Ik04MDcuMiA0MzcuMVYyMDEuMmMwLTI5LjQtMjMuOC01My4yLTUzLjItNTMuMkgyNzYuNWMtMjkuNCAwLTUzLjIgMjMuOC01My4yIDUzLjJ2MjM1LjljMCA2LjEtNC4zIDExLjUtMTAuMyAxMi43bC0zMC44IDYuNGMtMjEuNyA0LjUtMzcuMiAyMy42LTM3LjIgNDUuOHYyODcuN2MwIDQ0LjIgMzUuOSA4MC4xIDgwLjEgODAuMWg1ODAuNGM0NC4yIDAgODAuMS0zNS45IDgwLjEtODAuMVY1MDJjMC0yMi4yLTE1LjYtNDEuMi0zNy4yLTQ1LjhsLTMwLjgtNi40Yy02LjEtMS4zLTEwLjQtNi41LTEwLjQtMTIuN3oiIGZpbGw9IiNGRjU1NkUiLz48cGF0aCBkPSJNMjc2LjUgMTQ4Yy0yOS40IDAtNTMuMiAyMy44LTUzLjIgNTMuMnYxMy4xYzMxLTI2LjggNjUuNy00OS4zIDEwMy41LTY2LjNoLTUwLjN6bTUzMC43IDk2di00Mi45YzAtMjkuNC0yMy44LTUzLjItNTMuMi01My4yaC04MS4yYzUxIDIzLjEgOTYuNiA1NS45IDEzNC40IDk2LjF6TTE0NS4xIDc2MC4ydjI5LjVjMCA0NC4yIDM1LjkgODAuMSA4MC4xIDgwLjFoMjEuOWMtNDAuMy0zMC4yLTc0LjgtNjcuNC0xMDItMTA5LjZ6bTc0MC41IDI5LjV2LTg2LjljLTI5LjQgNjYuNC03NS40IDEyMy44LTEzMi44IDE2Ni45aDUyLjdjNDQuMiAwIDgwLjEtMzUuOSA4MC4xLTgweiIgZmlsbD0iI0ZGNTU2RSIvPjxwYXRoIGQ9Ik0xNDUuMSA2NDkuMnYxMTFjMjcuMiA0Mi4zIDYxLjggNzkuNSAxMDIgMTA5LjZoMTY4LjJDMjkyLjIgODQ3IDE5MSA3NjIuMyAxNDUuMSA2NDkuMnptNzQwLjUgNTMuNlY1MDJjMC0yMi4yLTE1LjYtNDEuMi0zNy4yLTQ1LjhsLTguMi0xLjdjMyAxOSA0LjcgMzguNCA0LjcgNTguMSAwIDE3Ny45LTEyNy44IDMyNS44LTI5Ni43IDM1N2gyMDQuNmM1Ny4zLTQzIDEwMy4zLTEwMC40IDEzMi44LTE2Ni44em0tNDA0LTU1My4yYzE0Mi43IDAgMjY2LjEgODIuMyAzMjUuNSAyMDIuMVYyNDRjLTM3LjctNDAuMi04My4zLTczLTEzNC4yLTk1LjloLTM0NmMtMzcuOCAxNy03Mi42IDM5LjUtMTAzLjQgNjYuM3Y0My4xYzY1LjctNjYuNiAxNTcuMS0xMDcuOSAyNTguMS0xMDcuOXoiIGZpbGw9IiNGRjVGNzEiLz48cGF0aCBkPSJNODQ0LjcgNTEyLjdjMC0xOS44LTEuNi0zOS4zLTQuNy01OC4xbC0yMi42LTQuN2MtNi0xLjMtMTAuMy02LjYtMTAuMy0xMi43di04NS40Qzc0Ny43IDIzMiA2MjQuMyAxNDkuNyA0ODEuNiAxNDkuN2MtMTAxIDAtMTkyLjQgNDEuMi0yNTguMyAxMDcuOHY0Ny43YzU1LjgtNzEuMSAxNDIuNS0xMTYuOCAyMzkuOS0xMTYuOCAxNjguMyAwIDMwNC42IDEzNi40IDMwNC42IDMwNC42UzYzMS42IDc5Ny41IDQ2My4zIDc5Ny41IDE1OC43IDY2MS4xIDE1OC43IDQ5Mi45YzAtOC40LjQtMTYuNiAxLTI0LjktOSA4LjYtMTQuNiAyMC43LTE0LjYgMzMuOXYxNDcuM0MxOTEgNzYyLjIgMjkyLjMgODQ3IDQxNS4yIDg2OS43aDEzM2MxNjguNy0zMS4yIDI5Ni41LTE3OS4xIDI5Ni41LTM1N3oiIGZpbGw9IiNGRjY5NzQiLz48cGF0aCBkPSJNNDYzLjMgNzk3LjVjMTY4LjMgMCAzMDQuNi0xMzYuNCAzMDQuNi0zMDQuNlM2MzEuNiAxODguMiA0NjMuMyAxODguMmMtOTcuNCAwLTE4NC4xIDQ1LjctMjM5LjkgMTE2Ljh2NjAuNGMzOS45LTgyIDEyNC4xLTEzOC43IDIyMS41LTEzOC43IDEzNiAwIDI0Ni4zIDExMC4yIDI0Ni4zIDI0Ni4zUzU4MC45IDcxOS4zIDQ0NSA3MTkuMyAxOTguOCA2MDkuMSAxOTguOCA0NzNjMC02LjkuMy0xMy43LjktMjAuNGwtMTcuMyAzLjZjLTguNyAxLjgtMTYuNCA2LTIyLjYgMTEuOC0uNyA4LjItMSAxNi41LTEgMjQuOS0uMSAxNjguMiAxMzYuMyAzMDQuNiAzMDQuNSAzMDQuNnoiIGZpbGw9IiNGRjczNzciLz48cGF0aCBkPSJNNDQ1IDcxOS4zYzEzNiAwIDI0Ni4zLTExMC4yIDI0Ni4zLTI0Ni4zUzU4MC45IDIyNi44IDQ0NSAyMjYuOGMtOTcuNCAwLTE4MS43IDU2LjYtMjIxLjUgMTM4Ljd2NzEuNmMwIDYuMS00LjMgMTEuNS0xMC4zIDEyLjdsLTEzLjUgMi44Yy0uNiA2LjctLjkgMTMuNS0uOSAyMC40IDAgMTM2LjEgMTEwLjIgMjQ2LjMgMjQ2LjIgMjQ2LjN6bS0xOC4yLTQ1My44YzEwMy43IDAgMTg3LjggODQuMSAxODcuOCAxODcuOHMtODQuMSAxODcuOC0xODcuOCAxODcuOFMyMzkgNTU3IDIzOSA0NTMuM3M4NC4xLTE4Ny44IDE4Ny44LTE4Ny44eiIgZmlsbD0iI0ZGN0U3QSIvPjxwYXRoIGQ9Ik00MjYuOCA2NDFjMTAzLjcgMCAxODcuOC04NC4xIDE4Ny44LTE4Ny44cy04NC4xLTE4Ny44LTE4Ny44LTE4Ny44UzIzOSAzNDkuNSAyMzkgNDUzLjIgMzIzLjEgNjQxIDQyNi44IDY0MXptLTE4LjQtMzM3YzcxLjQgMCAxMjkuNCA1Ny45IDEyOS40IDEyOS40cy01Ny45IDEyOS41LTEyOS40IDEyOS41UzI3OSA1MDQuOSAyNzkgNDMzLjUgMzM3IDMwNCA0MDguNCAzMDR6IiBmaWxsPSIjRkY4ODdEIi8+PHBhdGggZD0iTTMxNi45IDUyNS4wMjJBMTI5LjQgMTI5LjQgMCAxIDAgNDk5Ljg5NCAzNDIuMDIgMTI5LjQgMTI5LjQgMCAxIDAgMzE2LjkgNTI1LjAyMnoiIGZpbGw9IiNGRjkyODAiLz48cGF0aCBkPSJNODA1LjUgODc4LjhIMjI1LjFjLTQ5LjEgMC04OS4xLTQwLTg5LjEtODkuMVY1MDJjMC0yNi4zIDE4LjctNDkuMyA0NC40LTU0LjZsMzAuOC02LjRjMS44LS40IDMuMS0yIDMuMS0zLjlWMjAxLjJjMC0zNC4zIDI3LjktNjIuMiA2Mi4yLTYyLjJINzU0YzM0LjMgMCA2Mi4yIDI3LjkgNjIuMiA2Mi4ydjIzNS45YzAgMS45IDEuMyAzLjUgMy4zIDMuOWwzMC44IDYuNGMyNS43IDUuNSA0NC40IDI4LjQgNDQuNCA1NC42djI4Ny43Yy0uMSA0OS4xLTQwLjEgODkuMS04OS4yIDg5LjF6TTI3Ni41IDE1N2MtMjQuNCAwLTQ0LjIgMTkuOC00NC4yIDQ0LjJ2MjM1LjljMCAxMC40LTcuNCAxOS41LTE3LjUgMjEuNUwxODQgNDY1Yy0xNy40IDMuNi0zMCAxOS4yLTMwIDM3djI4Ny43YzAgMzkuMiAzMS45IDcxLjEgNzEuMSA3MS4xaDU4MC40YzM5LjIgMCA3MS4xLTMxLjkgNzEuMS03MS4xVjUwMmMwLTE3LjctMTIuNi0zMy4zLTMwLjEtMzdsLTMwLjgtNi40Yy0xMC40LTIuMi0xNy42LTExLTE3LjYtMjEuNVYyMDEuMmMwLTI0LjQtMTkuOC00NC4yLTQ0LjItNDQuMkgyNzYuNXoiIGZpbGw9IiNFRjQ4NjgiLz48cGF0aCBkPSJNNzY0LjUgNTI5LjNMNTQ1LjEgNjM0LjdjLTE4LjkgOS00MC43IDktNTkuNiAwTDI2Ni4xIDUyOS4zYy0xMi4yLTUuOC0yNi40IDMtMjYuNCAxNi42djE5OC44YzAgMjAuMyAxNi40IDM2LjcgMzYuNyAzNi43aDQ3Ny43YzIwLjMgMCAzNi43LTE2LjQgMzYuNy0zNi43VjU0NS45Yy4xLTEzLjYtMTQtMjIuNS0yNi4zLTE2LjZ6bS0yNTcuNi05My41YzIuNSAxLjkgNS4zIDIuNyA4LjQgMi43IDIuOSAwIDUuOC0xIDguNC0yLjcgMi41LTEuOSA2MC44LTQxLjcgODUuMS03OC40IDguNC0xMi42IDE4LjgtMjguNCAxOC44LTUwLjggMC0zNy42LTI5LjEtNjguMy02NC42LTY4LjMtMTkuNyAwLTM1LjQgOS42LTQ3LjQgMjUuNC0xMi4xLTE1LjctMjcuNy0yNS40LTQ3LjQtMjUuNC0zNS43IDAtNjQuOCAzMC42LTY0LjggNjguMyAwIDIyLjUgMTAuNCAzOC4zIDE4LjggNTAuOCAyMy44IDM2LjggODIuMSA3Ni41IDg0LjcgNzguNHoiIGZpbGw9IiNGRkM3QzciLz48cGF0aCBkPSJNMzQwLjEgMTg4LjJoLTljLTM0LjIgMC02MiAyNy44LTYyIDYydjY1LjZjMCA5LjkgOC4xIDE4IDE4IDE4czE4LTguMSAxOC0xOHYtNjUuNmMwLTE0LjQgMTEuNy0yNiAyNi0yNmg5YzkuOSAwIDE4LTguMSAxOC0xOHMtOC4xLTE4LTE4LTE4em0tNTMgMTY5LjdjLTkuOSAwLTE4IDguMS0xOCAxOHYxMmMwIDkuOSA4LjEgMTggMTggMThzMTgtOC4xIDE4LTE4di0xMmMwLTEwLTguMS0xOC0xOC0xOHoiIGZpbGw9IiNGRkYiLz48L3N2Zz4=' + +export const recommend = 'data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iODEiIGhlaWdodD0iODEiPjxwYXRoIGQ9Ik04MjYuMzY4IDI1My42NDVjLTU3LjM0NC01Ny4zNDQtMTQyLjQzOC02OS45NC0yMTIuMDItMzcuODM3LTMzLjc0IDE4NC4xMTUtMjMxLjM3MiAzMDguMjc1LTQ0OS41ODYgMjc5LjE0Mi0zLjIyNi0uNDEtNi4zNS0uOTcyLTkuNTc1LTEuNDg0IDYuNCA5LjI2NyAxMy42NyAxOC4xMjQgMjEuOTY1IDI2LjQxOWw1OC40MiA1OC40MTkgMjU4Ljk2OSAyNTguOTdjMy45OTMgMy45OTMgMTAuNDk2IDMuOTkzIDE0LjQ5IDBMNzY4IDU3OC4zMDRsNTguNDItNTguNDJjNzMuNDcxLTczLjU3NCA3My40NzEtMTkyLjc2Ny0uMDUyLTI2Ni4yNHoiIGZpbGw9IiNmZmUwNDgiLz48cGF0aCBkPSJNNTAxLjc2IDg2MC42NzJjLTguMTkyIDAtMTUuOTIzLTMuMTc0LTIxLjcwOS05LjAxMUwxNjIuNjYyIDUzNC4yNzJjLTgxLjM1Ni04MS4zNTctODEuMzU2LTIxMy44MTEgMC0yOTUuMTY4czIxMy44MTItODEuMzU3IDI5NS4xNjggMGEyMC41MjEgMjAuNTIxIDAgMCAxIDAgMjguOTggMjAuNTIxIDIwLjUyMSAwIDAgMS0yOC45NzkgMGMtNjUuNDMzLTY1LjM4My0xNzEuODI3LTY1LjQzNC0yMzcuMjYgMHMtNjUuNDM0IDE3MS44MjYgMCAyMzcuMjZMNTAxLjc2IDgxNS40NjJsMzEwLjExOC0zMTAuMTE4YzY1LjQzNC02NS40MzQgNjUuNDM0LTE3MS44MjcgMC0yMzcuMjZzLTE3MS44MjctNjUuNDM0LTIzNy4yNiAwTDQ1NC4xNDQgMzg0Ljk3MmEyMC40OCAyMC40OCAwIDAgMS0yOC45OC0uNDYxIDIwLjQ3NSAyMC40NzUgMCAwIDEgLjQ2Mi0yOC45OGwxMjAuMjY4LTExNi42ODRjMzkuMjItMzkuMjIgOTEuNTk3LTYwLjkyOCAxNDcuMzU0LTYwLjkyOHMxMDguMTg2IDIxLjcwOSAxNDcuNjEgNjEuMTMzYzgxLjM1NiA4MS4zNTcgODEuMzU2IDIxMy44MTEgMCAyOTUuMTY4TDUyMy40NjggODUxLjYxYTMwLjE5MyAzMC4xOTMgMCAwIDEtMjEuNzA4IDkuMDYyeiIgZmlsbD0iIzU1NTI0RiIvPjwvc3ZnPg==' diff --git a/atguigu-tuan/components/AddToCart/AddToCart.vue b/atguigu-tuan/components/AddToCart/AddToCart.vue new file mode 100644 index 0000000..b845dd5 --- /dev/null +++ b/atguigu-tuan/components/AddToCart/AddToCart.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/atguigu-tuan/components/CouponInfoList/CouponInfoList.vue b/atguigu-tuan/components/CouponInfoList/CouponInfoList.vue new file mode 100644 index 0000000..a6ffa8c --- /dev/null +++ b/atguigu-tuan/components/CouponInfoList/CouponInfoList.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/atguigu-tuan/components/ListImgItem/ListImgItem.vue b/atguigu-tuan/components/ListImgItem/ListImgItem.vue new file mode 100644 index 0000000..802b046 --- /dev/null +++ b/atguigu-tuan/components/ListImgItem/ListImgItem.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/atguigu-tuan/components/PickUpLocationHeader/PickUpLocationHeader.vue b/atguigu-tuan/components/PickUpLocationHeader/PickUpLocationHeader.vue new file mode 100644 index 0000000..b8b4bf6 --- /dev/null +++ b/atguigu-tuan/components/PickUpLocationHeader/PickUpLocationHeader.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/atguigu-tuan/components/PickUpLocationItem/PickUpLocationItem.vue b/atguigu-tuan/components/PickUpLocationItem/PickUpLocationItem.vue new file mode 100644 index 0000000..bb39595 --- /dev/null +++ b/atguigu-tuan/components/PickUpLocationItem/PickUpLocationItem.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/atguigu-tuan/index.html b/atguigu-tuan/index.html new file mode 100644 index 0000000..566b36c --- /dev/null +++ b/atguigu-tuan/index.html @@ -0,0 +1,15 @@ + + + + + + + + + + +
+ + + diff --git a/atguigu-tuan/main.js b/atguigu-tuan/main.js new file mode 100644 index 0000000..a1ba7de --- /dev/null +++ b/atguigu-tuan/main.js @@ -0,0 +1,26 @@ +import App from './App' +import Vue from 'vue' +import uView from "uview-ui"; +import store from './store' +import dayjs from 'dayjs'; + +Vue.prototype.$dayjs = dayjs; +Vue.use(uView); +Vue.config.productionTip = false +App.mpType = 'app' +const app = new Vue({ + ...App, + store +}) + +// http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用 +import httpInterceptor from '@/common/http.interceptor.js' + +Vue.use(httpInterceptor, app) + +// http接口API集中管理引入部分 +import httpApi from '@/common/http.api.js' + +Vue.use(httpApi, app) + +app.$mount() diff --git a/atguigu-tuan/manifest.json b/atguigu-tuan/manifest.json new file mode 100644 index 0000000..71f216e --- /dev/null +++ b/atguigu-tuan/manifest.json @@ -0,0 +1,80 @@ +{ + "name": "atguigu-tuan", + "appid": "__UNI__3804DB8", + "description": "", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx": false, + /* 5+App特有相关 */ + "app-plus": { + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + /* 模块配置 */ + "modules": {}, + /* 应用发布信息 */ + "distribute": { + /* android打包配置 */ + "android": { + "permissions": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + /* ios打包配置 */ + "ios": {}, + /* SDK配置 */ + "sdkConfigs": {} + } + }, + /* 快应用特有相关 */ + "quickapp": {}, + /* 小程序特有相关 */ + "mp-weixin": { + "appid": "wx2edefe049c6a37b9", + "setting": { + "urlCheck": false, + "es6": true, + "postcss": true, + "minified": true + }, + "usingComponents": true, + "permission": { + "scope.userLocation": { + "desc": "获取地理位置" + } + } + }, + "mp-alipay": { + "usingComponents": true + }, + "mp-baidu": { + "usingComponents": true + }, + "mp-toutiao": { + "usingComponents": true + }, + "uniStatistics": { + "enable": false + }, + "vueVersion": "2" +} diff --git a/atguigu-tuan/package.json b/atguigu-tuan/package.json new file mode 100644 index 0000000..3ec2342 --- /dev/null +++ b/atguigu-tuan/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "dayjs": "^1.10.7", + "uview-ui": "^1.8.4", + "vuex": "^3.6.2" + } +} diff --git a/atguigu-tuan/pages.json b/atguigu-tuan/pages.json new file mode 100644 index 0000000..a3d5be5 --- /dev/null +++ b/atguigu-tuan/pages.json @@ -0,0 +1,164 @@ +{ + "easycom": { + "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" + }, + "pages": [ + //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/index/index", + "style": { + "navigationStyle": "custom", + // 隐藏系统导航栏 + "navigationBarTextStyle": "white", + // 状态栏字体为白色,只能为 white-白色,black-黑色 二选一 + "navigationBarTitleText": "uni-app" + } + }, + { + "path": "pages/categories/categories", + "style": { + "navigationStyle": "custom", + // 隐藏系统导航栏 + "navigationBarTitleText": "分类", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/cart/cart", + "style": { + "navigationStyle": "custom", + // 隐藏系统导航栏 + "navigationBarTitleText": "购物车", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/my/my", + "style": { + "navigationStyle": "custom", + // 隐藏系统导航栏 + "navigationBarTitleText": "我的", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/login/login", + "style": { + "navigationBarTitleText": "登陆页", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/homeItem/homeItem", + "style": { + "navigationStyle": "custom", + // 隐藏系统导航栏 + "navigationBarTitleText": "", + "enablePullDownRefresh": false + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "uni-app", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + }, + "tabBar": { + "color": "#2c2c2c", + "selectedColor": "#d81e06", + "borderStyle": "white", + "backgroundColor": "#ffffff", + "list": [ + { + "pagePath": "pages/index/index", + "iconPath": "static/images/tabbar/home.png", + "selectedIconPath": "static/images/tabbar/home-selected.png", + "text": "首页" + }, + { + "pagePath": "pages/categories/categories", + "iconPath": "static/images/tabbar/categories.png", + "selectedIconPath": "static/images/tabbar/categories-selected.png", + "text": "分类" + }, + { + "pagePath": "pages/cart/cart", + "iconPath": "static/images/tabbar/cart.png", + "selectedIconPath": "static/images/tabbar/cart-selected.png", + "text": "购物车" + }, + { + "pagePath": "pages/my/my", + "iconPath": "static/images/tabbar/my.png", + "selectedIconPath": "static/images/tabbar/my-selected.png", + "text": "我的" + } + ] + }, + "subPackages": [ + { + "root": "pagesLocation", + "pages": [ + { + "path": "myPickUpLocation/myPickUpLocation", + "style": { + "navigationBarTitleText": "我的提货点", + "enablePullDownRefresh": false + } + }, + { + "path": "choosePickUpLocation/choosePickUpLocation", + "style": { + "navigationBarTitleText": "选择其它提货点", + "enablePullDownRefresh": false + } + } + ] + }, + { + "root": "pagesOrder", + "pages": [ + { + "path": "confirmOrder/confirmOrder", + "style": { + "navigationBarTitleText": "确认订单", + "enablePullDownRefresh": false, + "navigationStyle": "custom" + // 隐藏系统导航栏 + } + }, + { + "path": "getOrderInfo/getOrderInfo", + "style": { + "navigationBarTitleText": "确认支付", + "enablePullDownRefresh": false, + "navigationStyle": "custom" + // 隐藏系统导航栏 + } + }, + { + "path": "orderList/orderList", + "style": { + "navigationBarTitleText": "订单列表", + "enablePullDownRefresh": false + } + } + ] + }, + { + "root": "pagesSeckill", + "pages": [ + { + "path": "seckill/seckill", + "style": { + "navigationBarTitleText": "限时秒杀", + "enablePullDownRefresh": false, + "navigationStyle": "custom" + // 隐藏系统导航栏 + } + } + ] + } + ] +} diff --git a/atguigu-tuan/pages/cart/cart.vue b/atguigu-tuan/pages/cart/cart.vue new file mode 100644 index 0000000..8bb9387 --- /dev/null +++ b/atguigu-tuan/pages/cart/cart.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/atguigu-tuan/pages/categories/categories.vue b/atguigu-tuan/pages/categories/categories.vue new file mode 100644 index 0000000..0bc1b7f --- /dev/null +++ b/atguigu-tuan/pages/categories/categories.vue @@ -0,0 +1,295 @@ + + + + + diff --git a/atguigu-tuan/pages/homeItem/homeItem.vue b/atguigu-tuan/pages/homeItem/homeItem.vue new file mode 100644 index 0000000..1cc0b73 --- /dev/null +++ b/atguigu-tuan/pages/homeItem/homeItem.vue @@ -0,0 +1,336 @@ + + + + + diff --git a/atguigu-tuan/pages/index/index.vue b/atguigu-tuan/pages/index/index.vue new file mode 100644 index 0000000..14a2ae8 --- /dev/null +++ b/atguigu-tuan/pages/index/index.vue @@ -0,0 +1,487 @@ + + + + + diff --git a/atguigu-tuan/pages/login/login.vue b/atguigu-tuan/pages/login/login.vue new file mode 100644 index 0000000..63abf98 --- /dev/null +++ b/atguigu-tuan/pages/login/login.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/atguigu-tuan/pages/my/my.vue b/atguigu-tuan/pages/my/my.vue new file mode 100644 index 0000000..a6ad8a6 --- /dev/null +++ b/atguigu-tuan/pages/my/my.vue @@ -0,0 +1,275 @@ + + + + + diff --git a/atguigu-tuan/pagesLocation/choosePickUpLocation/choosePickUpLocation.vue b/atguigu-tuan/pagesLocation/choosePickUpLocation/choosePickUpLocation.vue new file mode 100644 index 0000000..6a1f53b --- /dev/null +++ b/atguigu-tuan/pagesLocation/choosePickUpLocation/choosePickUpLocation.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/atguigu-tuan/pagesLocation/myPickUpLocation/myPickUpLocation.vue b/atguigu-tuan/pagesLocation/myPickUpLocation/myPickUpLocation.vue new file mode 100644 index 0000000..ff9cc17 --- /dev/null +++ b/atguigu-tuan/pagesLocation/myPickUpLocation/myPickUpLocation.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/atguigu-tuan/pagesOrder/confirmOrder/confirmOrder.vue b/atguigu-tuan/pagesOrder/confirmOrder/confirmOrder.vue new file mode 100644 index 0000000..724fd28 --- /dev/null +++ b/atguigu-tuan/pagesOrder/confirmOrder/confirmOrder.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/atguigu-tuan/pagesOrder/getOrderInfo/getOrderInfo.vue b/atguigu-tuan/pagesOrder/getOrderInfo/getOrderInfo.vue new file mode 100644 index 0000000..940e394 --- /dev/null +++ b/atguigu-tuan/pagesOrder/getOrderInfo/getOrderInfo.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/atguigu-tuan/pagesOrder/orderList/orderList.vue b/atguigu-tuan/pagesOrder/orderList/orderList.vue new file mode 100644 index 0000000..19560d4 --- /dev/null +++ b/atguigu-tuan/pagesOrder/orderList/orderList.vue @@ -0,0 +1,341 @@ + + + + + + + diff --git a/atguigu-tuan/pagesSeckill/seckill/seckill.vue b/atguigu-tuan/pagesSeckill/seckill/seckill.vue new file mode 100644 index 0000000..264cda6 --- /dev/null +++ b/atguigu-tuan/pagesSeckill/seckill/seckill.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/atguigu-tuan/static/images/location.png b/atguigu-tuan/static/images/location.png new file mode 100644 index 0000000..8324ae9 Binary files /dev/null and b/atguigu-tuan/static/images/location.png differ diff --git a/atguigu-tuan/static/images/tabbar/cart-selected.png b/atguigu-tuan/static/images/tabbar/cart-selected.png new file mode 100644 index 0000000..cf0e0b9 Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/cart-selected.png differ diff --git a/atguigu-tuan/static/images/tabbar/cart.png b/atguigu-tuan/static/images/tabbar/cart.png new file mode 100644 index 0000000..e5fc17e Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/cart.png differ diff --git a/atguigu-tuan/static/images/tabbar/categories-selected.png b/atguigu-tuan/static/images/tabbar/categories-selected.png new file mode 100644 index 0000000..4d8a3f3 Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/categories-selected.png differ diff --git a/atguigu-tuan/static/images/tabbar/categories.png b/atguigu-tuan/static/images/tabbar/categories.png new file mode 100644 index 0000000..e3e344d Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/categories.png differ diff --git a/atguigu-tuan/static/images/tabbar/home-selected.png b/atguigu-tuan/static/images/tabbar/home-selected.png new file mode 100644 index 0000000..f7c1ea7 Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/home-selected.png differ diff --git a/atguigu-tuan/static/images/tabbar/home.png b/atguigu-tuan/static/images/tabbar/home.png new file mode 100644 index 0000000..e104fef Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/home.png differ diff --git a/atguigu-tuan/static/images/tabbar/my-selected.png b/atguigu-tuan/static/images/tabbar/my-selected.png new file mode 100644 index 0000000..72ae220 Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/my-selected.png differ diff --git a/atguigu-tuan/static/images/tabbar/my.png b/atguigu-tuan/static/images/tabbar/my.png new file mode 100644 index 0000000..11539cc Binary files /dev/null and b/atguigu-tuan/static/images/tabbar/my.png differ diff --git a/atguigu-tuan/static/logo.png b/atguigu-tuan/static/logo.png new file mode 100644 index 0000000..665131f Binary files /dev/null and b/atguigu-tuan/static/logo.png differ diff --git a/atguigu-tuan/store/index.js b/atguigu-tuan/store/index.js new file mode 100644 index 0000000..75a4da5 --- /dev/null +++ b/atguigu-tuan/store/index.js @@ -0,0 +1,19 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import indexModule from './modules/index' +import pickUpLocationModule from './modules/pickUpLocation' +import categoriesModule from './modules/categories' +import cartModule from './modules/cart' +import orderModule from './modules/order' + +Vue.use(Vuex) + +export default new Vuex.Store({ + modules: { + indexModule, + pickUpLocationModule, + categoriesModule, + cartModule, + orderModule + }, +}) diff --git a/atguigu-tuan/store/modules/cart.js b/atguigu-tuan/store/modules/cart.js new file mode 100644 index 0000000..7af2b48 --- /dev/null +++ b/atguigu-tuan/store/modules/cart.js @@ -0,0 +1,246 @@ +import Vue from "vue" + +const state = { + cartList: [], + activityCartList: {} +}; + +const getters = { + // 检查商品是否存在于购物车中 + checkProductExists(state) { + return function (skuId) { + const pos = state.cartList.findIndex(item => item.skuId === skuId) + return pos === -1 ? false : true; + } + }, + // 获取单个商品的购买数量 + getProductSkuNum(state) { + return function (skuId) { + const index = state.cartList.findIndex(item => item.skuId === skuId); + return index !== -1 ? state.cartList[index].skuNum : 0; + } + }, + // 获取购物车商品信息列表 + getCartInfoList(state) { + return state.activityCartList.carInfoVoList + }, + // 是否显示包含多个商品的内容 + showMultiCheckbox(state) { + return function (index) { + return state.activityCartList.carInfoVoList[index].cartInfoList.length > 1 + } + }, + // 确认多个商品项是否为选中 + getMultiCheckCart(state) { + return function (index) { + return state.activityCartList.carInfoVoList[index].cartInfoList.every(item => item.isChecked === 1); + } + }, + // 获取多个商品项的ids + getMultiCheckedIds(state) { + return function (index) { + let ids = [] + state.activityCartList.carInfoVoList[index].cartInfoList.forEach(item => ids.push(item.skuId)); + return ids.toString(); + } + }, + // 判断是否全选 + isAllSelected(state) { + let isAllSelected = true; + state.activityCartList.carInfoVoList && state.activityCartList.carInfoVoList + .forEach(carInfoItem => { + carInfoItem.cartInfoList.forEach(cartInfoItem => { + if (cartInfoItem.isChecked === 0) { + isAllSelected = false; + return false; + } + }) + }) + return isAllSelected; + }, + // 获取购物车价格信息 + getCartPriceInfo(state) { + if (!state.activityCartList.totalAmount) { + return { + couponReduceAmount: 0, + originalTotalAmount: 0, + totalAmount: 0 + } + } + + return { + couponReduceAmount: state.activityCartList.couponReduceAmount, + originalTotalAmount: state.activityCartList.originalTotalAmount, + totalAmount: state.activityCartList.totalAmount + } + }, + // 确认选中购物车的数量 + getSelectedCount(state) { + let count = 0; + state.activityCartList.carInfoVoList && state.activityCartList.carInfoVoList + .forEach(carInfoItem => { + carInfoItem.cartInfoList.forEach(cartInfoItem => { + if (cartInfoItem.isChecked === 1) { + count += cartInfoItem.skuNum; + } + }) + }) + return count; + }, + // 获取购物车优惠券信息列表 + getCartCouponInfoList(state) { + return state.activityCartList.couponInfoList + }, +} + +const mutations = { + // 添加到购物车 + addShopMutation(state, payload) { + state.cartList.push(payload); + }, + // 获取不带活动的购物车列表 + getCartListMutation(state, payload) { + state.cartList = payload; + }, + // 修改购物车数量 + changeSkuNumMutation(state, payload) { + // skuId为商品id + // value为+1或者-1,操作的递增值 + // currentBuyNum为number-box组件当前商品购物车的操作值 + const { + skuId, + value, + currentBuyNum + } = payload + const index = state.cartList.findIndex(item => item.skuId === skuId); + // 如果当前购买数量小于1则删除该商品 + if (currentBuyNum < 1) { + state.cartList.splice(index, 1) + } else { + state.cartList[index].skuNum += value + } + }, + // 删除购物车 + deleteShopMutation(state, payload) { + // 删除cartList中的数据 + const cartListIndex = state.cartList.findIndex(item => item.skuId === payload); + state.cartList.splice(cartListIndex, 1) + }, + // 获取带活动的购物车列表 + getActivityCartListMutation(state, payload) { + state.activityCartList = payload + }, + +} +const actions = { + // 添加到购物车 + async addShopAction({ + commit, + state + }, payload) { + // 给对象添加响应式数据属性 + Vue.set(payload, 'skuNum', 1) + Vue.set(payload, 'skuId', payload.id) + Vue.set(payload, 'isChecked', 1) + await this._vm.$u.api.getAddToCart({ + skuId: payload.id, + skuNum: payload.skuNum, + }) + commit('addShopMutation', payload) + }, + // 获取不带活动的购物车列表 + async getCartListAction({ + commit + }) { + let result = await this._vm.$u.api.getCartList() + commit('getCartListMutation', result) + }, + // 修改购物车数量 + async changeSkuNumAction({ + commit, + dispatch + }, payload) { + const { + skuId, + value, + currentBuyNum, + isCart + } = payload; + // 如果当前购买的数量小于1,则需要将该商品从购物车中删除,否则进行购物车数量的修改 + if (currentBuyNum < 1) { + dispatch('deleteShopAction', payload) + } else { + await this._vm.$u.api.getAddToCart({ + skuId: skuId, + skuNum: value, + }) + commit('changeSkuNumMutation', payload) + } + + // 通过isCart判断是否是在购物车里进行购物车数量的改变, + // 如果是在购物车里进行数量变化,则还需要获取带活动的购物车列表 + if (isCart) dispatch('getActivityCartListAction') + + }, + // 删除购物车 + async deleteShopAction({ + commit, + dispatch + }, payload) { + const { + skuId, + value, + currentBuyNum, + isCart + } = payload; + await this._vm.$u.api.deleteCart(skuId); + + // 删除时如果是在购物车列表操作,则需要重新获取数据 + if (isCart) await dispatch('getActivityCartListAction') + await commit('deleteShopMutation', skuId) + }, + // 获取带活动的购物车列表 + async getActivityCartListAction({ + commit + }, payload) { + let showLoading = false; + if (payload) showLoading = true + + let result = await this._vm.$u.api.getActivityCartList({ + showLoading + }) + commit('getActivityCartListMutation', result) + }, + // 切换购物车商品的选中状态 + async changeCheckCartAction({ + commit, + dispatch + }, payload) { + let result = await this._vm.$u.api.getCheckCart(payload) + dispatch('getActivityCartListAction') + }, + // 对指定的多个商品进行选择/反选 + async changeMultiCheckedCartAction({ + commit, + dispatch + }, payload) { + let result = await this._vm.$u.api.postBatchCheckCart(payload) + dispatch('getActivityCartListAction') + }, + // 对所有购物车商品进行全选/反选 + async changeAllCheckCartAction({ + commit, + dispatch + }, payload) { + let result = await this._vm.$u.api.getCheckAllCart(payload) + dispatch('getActivityCartListAction') + }, +}; + +export default { + namespaced: true, + state, + mutations, + actions, + getters, +}; diff --git a/atguigu-tuan/store/modules/categories.js b/atguigu-tuan/store/modules/categories.js new file mode 100644 index 0000000..ddfb1c5 --- /dev/null +++ b/atguigu-tuan/store/modules/categories.js @@ -0,0 +1,27 @@ +const state = { + categories: [] +}; +const getters = {}; +const mutations = { + updateCategoriesMutation(state, payload) { + state.categories = payload; + } +}; +const actions = { + async getCategoriesAction({ + commit + }) { + return new Promise(async reslove => { + let result = await this._vm.$u.api.getCategories() + commit('updateCategoriesMutation', result) + reslove(); + }) + } +}; +export default { + namespaced: true, + state, + mutations, + actions, + getters, +}; diff --git a/atguigu-tuan/store/modules/index.js b/atguigu-tuan/store/modules/index.js new file mode 100644 index 0000000..87ee1c4 --- /dev/null +++ b/atguigu-tuan/store/modules/index.js @@ -0,0 +1,59 @@ +const state = { + home: {} +}; +const getters = { + // 商品分类 + categoryList(state) { + return state.home.categoryList || []; + }, + // 热销商品 + hotSkuList(state) { + return state.home.hotSkuList || []; + }, + // 新人专享 + newPersonSkuInfoList(state) { + return state.home.newPersonSkuInfoList || []; + }, + // 提货点信息 + leaderAddressVo(state) { + return state.home.leaderAddressVo || {} + }, + // 秒杀时间 + seckillTime(state) { + return state.home.seckillTime || {} + }, + // 秒杀商品 + seckillSkuVoList(state) { + return state.home.seckillSkuVoList || [] + } +}; +const mutations = { + // 获取首页数据 + getHomeIndexMutation(state, payload) { + state.home = payload + } +}; +const actions = { + async getHomeIndexAction({ + commit, + dispatch + }) { + // 直接用this.$u.api在仓库中是无法调用到对应的接口的,因为this对象指向不同 + // 仓库中的this指向的是Store,所以需要通过this._vm来找到对应的Vue实例 + let result = await this._vm.$u.api.getHomeIndex() + await commit('getHomeIndexMutation', result) + // 利用root属性将派发pickUpLocation模块中的action动作 + dispatch('pickUpLocationModule/changeLeaderAddressVoAction', result.leaderAddressVo, { + root: true + }) + + dispatch('cartModule/getCartListAction', {}, {root: true}) + } +}; +export default { + namespaced: true, + state, + mutations, + actions, + getters, +}; diff --git a/atguigu-tuan/store/modules/order.js b/atguigu-tuan/store/modules/order.js new file mode 100644 index 0000000..d6b9212 --- /dev/null +++ b/atguigu-tuan/store/modules/order.js @@ -0,0 +1,90 @@ +import Vue from 'vue' + +const state = { + order: {} +}; + +const getters = { + // 获取订单商品信息列表 + getCartInfoList(state) { + return state.order.carInfoVoList + }, + // 获取提货点信息 + getLeaderAddressVo(state) { + return state.order.leaderAddressVo + }, + // 确认选中购物车的数量 + getSelectedCount(state) { + let count = 0; + state.order.carInfoVoList && state.order.carInfoVoList + .forEach(carInfoItem => { + carInfoItem.cartInfoList.forEach(cartInfoItem => { + if (cartInfoItem.isChecked === 1) { + count += cartInfoItem.skuNum; + } + }) + }) + return count; + }, + // 获取购物车价格信息 + getCartPriceInfo(state) { + if (!state.order.totalAmount) { + return { + couponReduceAmount: 0, + originalTotalAmount: 0, + totalAmount: 0, + activityReduceAmount: 0 + } + } + + return { + couponReduceAmount: state.order.couponReduceAmount, + originalTotalAmount: state.order.originalTotalAmount, + totalAmount: state.order.totalAmount, + activityReduceAmount: state.order.activityReduceAmount + } + }, + // 是否显示包含多个商品的内容 + showMultiCheckbox(state) { + return function (index) { + return state.order.carInfoVoList[index].cartInfoList.length > 1 + } + }, + // 获取订单优惠券信息列表 + getCartCouponInfoList(state) { + const couponInfoList = state.order.couponInfoList || [] + if (couponInfoList) { + couponInfoList.forEach(( + item) => { + Vue.set(item, 'selected', item.isOptimal === 1 && item.isSelect === 1) + + }) + } + return couponInfoList + }, +} + +const mutations = { + // 获取确认订单 + getConfirmOrderMutation(state, payload) { + state.order = payload + } +} + +const actions = { + // 获取确认订单 + async getConfirmOrderAction({ + commit + }) { + let result = await this._vm.$u.api.getConfirmOrder() + commit('getConfirmOrderMutation', result) + } +} + +export default { + namespaced: true, + state, + mutations, + actions, + getters, +}; diff --git a/atguigu-tuan/store/modules/pickUpLocation.js b/atguigu-tuan/store/modules/pickUpLocation.js new file mode 100644 index 0000000..64226da --- /dev/null +++ b/atguigu-tuan/store/modules/pickUpLocation.js @@ -0,0 +1,63 @@ +const state = { + leaderAddressVo: {}, // 当前提货点 + currentPickUpArea: '', // 当前提货点区域 + findAllList: [], // 指定区域的提货点列表 +}; +const getters = { + checkIsCurrent(state, payload) { + return function (id) { + if (state.leaderAddressVo) { + return state.leaderAddressVo.leaderId === id; + } else { + return false + } + } + }, +}; +const mutations = { + getSysRegionFindAllListMutation(state, payload) { + state.findAllList = payload + }, + setCurrentPickUpAreaMutation(state, payload) { + state.currentPickUpArea = payload.regionName + }, + changeCurrentPickUpAreaMutation(state, payload) { + state.currentPickUpArea = payload[0].regionName + }, + changeLeaderAddressVoMutation(state, payload) { + state.leaderAddressVo = payload; + } +}; +const actions = { + async getSysRegionFindAllListAction({ + commit + }) { + let result = await this._vm.$u.api.getSysRegionFindAllList(); + await commit('getSysRegionFindAllListMutation', result) + await commit('changeCurrentPickUpAreaMutation', result) + }, + changeLeaderAddressVoAction({ + commit, + dispatch + }, payload) { + commit('changeLeaderAddressVoMutation', payload) + }, + async selectLeaderAddressVoAction({ + commit, + dispatch + }, payload) { + let result = await this._vm.$u.api.getSelectLeader(payload); + // 从首页设置当前提货点 + dispatch('indexModule/getHomeIndexAction', {}, { + root: true + }) + } +}; + +export default { + namespaced: true, + state, + mutations, + actions, + getters, +}; diff --git a/atguigu-tuan/uni.scss b/atguigu-tuan/uni.scss new file mode 100644 index 0000000..54df989 --- /dev/null +++ b/atguigu-tuan/uni.scss @@ -0,0 +1,78 @@ +/** + * 这里是uni-app内置的常用样式变量 + * + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App + * + */ + +/** + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 + * + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 + */ + +@import 'uview-ui/theme.scss'; + +/* 颜色变量 */ + +/* 行为相关颜色 */ +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color: #333; //基本色 +$uni-text-color-inverse: #fff; //反色 +$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; + +/* 背景颜色 */ +$uni-bg-color: #ffffff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1; //点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色 + +/* 边框颜色 */ +$uni-border-color: #c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm: 12px; +$uni-font-size-base: 14px; +$uni-font-size-lg: 16; + +/* 图片尺寸 */ +$uni-img-size-sm: 20px; +$uni-img-size-base: 26px; +$uni-img-size-lg: 40px; + +/* Border Radius */ +$uni-border-radius-sm: 2px; +$uni-border-radius-base: 3px; +$uni-border-radius-lg: 6px; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 5px; +$uni-spacing-row-base: 10px; +$uni-spacing-row-lg: 15px; + +/* 垂直间距 */ +$uni-spacing-col-sm: 4px; +$uni-spacing-col-base: 8px; +$uni-spacing-col-lg: 12px; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2C405A; // 文章标题颜色 +$uni-font-size-title: 20px; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle: 26px; +$uni-color-paragraph: #3F536E; // 文章段落颜色 +$uni-font-size-paragraph: 15px; diff --git a/atguigu-tuan/yarn.lock b/atguigu-tuan/yarn.lock new file mode 100644 index 0000000..c493869 --- /dev/null +++ b/atguigu-tuan/yarn.lock @@ -0,0 +1,18 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +dayjs@^1.10.7: + version "1.10.7" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468" + integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig== + +uview-ui@^1.8.4: + version "1.8.4" + resolved "https://r.cnpmjs.org/uview-ui/download/uview-ui-1.8.4.tgz#e32bbf2379421d319022e324e1cb7b5387d3bd44" + integrity sha1-4yu/I3lCHTGQIuMk4ct7U4fTvUQ= + +vuex@^3.6.2: + version "3.6.2" + resolved "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71" + integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==