Browse Source

👍 增加地图 增加拼多多

master
Boom 1 year ago
parent
commit
3a33d65d6b
  1. 13
      api/fish.js
  2. 16
      api/store.js
  3. 6
      components/Footer.vue
  4. 38
      components/PromotionGood.vue
  5. 11
      components/Recommend.vue
  6. 2
      manifest.json
  7. 11
      pages.json
  8. 9
      pages/Loading/index.vue
  9. 389
      pages/goods/goodDetail.vue
  10. 173
      pages/goods/goodList.vue
  11. 159
      pages/goods/good_com/good.vue
  12. 207
      pages/goods/good_com/search_bar.vue
  13. 79
      pages/goods/good_com/tabs.vue
  14. 368
      pages/goods/index.vue
  15. 67
      pages/goods/utils/share.js
  16. 18
      pages/goods/utils/uni-share/changelog.md
  17. 204
      pages/goods/utils/uni-share/js_sdk/uni-image-menu.js
  18. 98
      pages/goods/utils/uni-share/js_sdk/uni-share.js
  19. 80
      pages/goods/utils/uni-share/package.json
  20. 95
      pages/goods/utils/uni-share/readme.md
  21. 20
      pages/goods/utils/util.js
  22. 26
      pages/home/components/HotCommodity.vue
  23. 103
      pages/map/index.vue
  24. BIN
      static/business_fish.png
  25. BIN
      static/point.png
  26. BIN
      static/public_fish.png

13
api/fish.js

@ -0,0 +1,13 @@
import request from "@/utils/request";
export function getFishIndex(param) {
return request.post("/fish/index", param, {
login: false
});
}
export function getFishPlaceInfo(id) {
return request.get("/fish/info?id="+id,null,{
login: false
})
}

16
api/store.js

@ -18,6 +18,22 @@ export function getProductDetail(id, data) {
}); });
} }
export function pddLink(goodSign) {
return request.get("/product/pddLink", {
"goodSign": goodSign
}, {
login: true
});
}
export function pddDetail(goodSign) {
return request.get("product/pddDetail", {
"goodSign": goodSign
}, {
login: true
});
}
/* /*
* 商品分销二维码 * 商品分销二维码
* */ * */

6
components/Footer.vue

@ -25,6 +25,12 @@ export default {
data: function() { data: function() {
return { return {
footerList: [ footerList: [
{
name: "地图",
icon1: "icon-shouye-xianxing",
icon2: "icon-shouye",
url: "/pages/map/index"
},
{ {
name: "首页", name: "首页",
icon1: "icon-shouye-xianxing", icon1: "icon-shouye-xianxing",

38
components/PromotionGood.vue

@ -20,7 +20,10 @@
<view class="price-box"> <view class="price-box">
<view class="flex x-bc align-end"> <view class="flex x-bc align-end">
<view class="current">{{ item.price }} </view> <view class="current">{{ item.price }} </view>
<view class="sales miso-font">仅剩{{ item.stock }}{{ item.unitName }}</view> <view class="sales miso-font">
<span v-if="item.salesTip">销量:{{item.salesTip}}</span>
<span v-else>仅剩{{ item.stock }}{{ item.unitName }}</span>
</view>
</view> </view>
<view class="x-f tag-box"> <view class="x-f tag-box">
<!-- <view class="discount">新人礼</view> <!-- <view class="discount">新人礼</view>
@ -34,7 +37,7 @@
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'PromotionGood', name: 'PromotionGood',
props: ['benefit'], props: ['benefit'],
data: function() { data: function() {
@ -42,24 +45,33 @@ export default {
}, },
methods: { methods: {
routerGo(item) { routerGo(item) {
if (item.goodSign) {
this.$yrouter.push({
path: '/pages/goods/goodDetail',
query: {
goodSign: item.goodSign
},
})
} else {
this.$yrouter.push({ this.$yrouter.push({
path: '/pages/shop/GoodsCon/index', path: '/pages/shop/GoodsCon/index',
query: { query: {
id: item.id, id: item.id
}, },
}) })
}
}, },
}, },
mounted() {}, mounted() {},
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.sh-title-card { .sh-title-card {
width: 750rpx; width: 750rpx;
} }
.title-box { .title-box {
width: 710rpx; width: 710rpx;
height: 88rpx; height: 88rpx;
margin: 0 auto; margin: 0 auto;
@ -78,9 +90,9 @@ export default {
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
font-weight: bold; font-weight: bold;
} }
} }
.goods-box { .goods-box {
width: 345rpx; width: 345rpx;
background: #fff; background: #fff;
padding-bottom: 20rpx; padding-bottom: 20rpx;
@ -185,10 +197,10 @@ export default {
} }
} }
} }
} }
// //
.hot-goods { .hot-goods {
// background: linear-gradient(#fff 200rpx, #f6f6f6 500rpx, #f6f6f6); // background: linear-gradient(#fff 200rpx, #f6f6f6 500rpx, #f6f6f6);
// border-radius: 20rpx; // border-radius: 20rpx;
@ -208,5 +220,5 @@ export default {
} }
} }
} }
} }
</style> </style>

11
components/Recommend.vue

@ -56,12 +56,21 @@
}, },
methods: { methods: {
routerGo(item) { routerGo(item) {
if (item.goodSign) {
this.$yrouter.push({
path: '/pages/goods/goodDetail',
query: {
goodSign: item.goodSign
},
})
} else {
this.$yrouter.push({ this.$yrouter.push({
path: '/pages/shop/GoodsCon/index', path: '/pages/shop/GoodsCon/index',
query: { query: {
id: item.id id: item.id
},
})
} }
});
}, },
hostProducts: function () { hostProducts: function () {
let that = this; let that = this;

2
manifest.json

@ -253,7 +253,7 @@
"desc" : "定位最近的门店" "desc" : "定位最近的门店"
} }
}, },
// "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ], "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ],
"plugins" : {} "plugins" : {}
}, },
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN

11
pages.json

@ -141,6 +141,11 @@
"navigationBarTitleText": "商品详情" "navigationBarTitleText": "商品详情"
} }
}, },
{
"path": "pages/goods/goodDetail"
},
{ {
"path": "pages/shop/IntegralGoodsCon/index", "path": "pages/shop/IntegralGoodsCon/index",
"style": { "style": {
@ -467,6 +472,12 @@
"iconWidth": "24px", "iconWidth": "24px",
"spacing": "3px", "spacing": "3px",
"list": [{ "list": [{
"pagePath": "pages/map/index",
"iconPath": "static/icon-home.png",
"selectedIconPath": "static/icon-home-hot.png",
"text": "地图"
},
{
"pagePath": "pages/home/index", "pagePath": "pages/home/index",
"iconPath": "static/icon-home.png", "iconPath": "static/icon-home.png",
"selectedIconPath": "static/icon-home-hot.png", "selectedIconPath": "static/icon-home-hot.png",

9
pages/Loading/index.vue

@ -43,7 +43,8 @@ export default {
} }
if (this.$deviceType == 'app' || this.$deviceType == 'weixinh5') { if (this.$deviceType == 'app' || this.$deviceType == 'weixinh5') {
this.$yrouter.switchTab({ this.$yrouter.switchTab({
path: '/pages/home/index', // path: '/pages/home/index',
path: '/pages/map/index',
}) })
return return
} }
@ -57,7 +58,8 @@ export default {
login().finally(() => { login().finally(() => {
this.changeAuthorization(false) this.changeAuthorization(false)
this.$yrouter.switchTab({ this.$yrouter.switchTab({
path: '/pages/home/index', // path: '/pages/home/index',
path: '/pages/map/index',
}) })
}) })
}, },
@ -79,7 +81,8 @@ export default {
}) })
} else { } else {
this.$yrouter.switchTab({ this.$yrouter.switchTab({
path: '/pages/home/index', // path: '/pages/home/index',
path: '/pages/map/index',
}) })
} }
}, },

389
pages/goods/goodDetail.vue

@ -0,0 +1,389 @@
<template>
<view class="good_detail_page" v-show="data.goodsImageUrl">
<view class="current_goods">
<img class="main_img" :src="data.goodsImageUrl" />
<view class="current_goods_text">
<text class="goods_title">{{data.goodsDesc}}</text>
<view class="price">
<text>{{(data.minGroupPrice - data.couponDiscount) / 100 }}
<text class="yuanjia">团购价{{data.minGroupPrice/100}}
原价{{data.minNormalPrice/100}}</text></text>
</view>
<view class="biaoqian">
<text v-for="(item,index) in data.unifiedTags" :key="index" class="biaoqian_text" v-if="item">{{item}}</text>
</view>
<view class="goods_dp">
<image class="goodsa_dp_img" :src="data.mallImgUrl" mode="aspectFit"></image>
<view class="goodsa_dp_name">
<view>{{data.goodsName}}</view>
<view class="hot">已拼{{data.salesTip}}</view>
</view>
</view>
</view>
<view v-for="(item,index) in data.goodsGalleryUrls" :key="index">
<image class="current_imgs" :src="item" mode="aspectFill"></image>
</view>
</view>
<view type="warn" class="buy_btn">
<view class="topbtn" @click="toTop()">TOP</view>
<view class="price">
<view><text class="juanhou">券后</text>
{{(data.minGroupPrice - data.couponDiscount) / 100 }}</view>
<view class="yuanjia">原价{{data.minNormalPrice/100}} 团购价{{data.minGroupPrice/100}}
{{data.couponDiscount/100}}</view>
<button @click="buy" type="warn" class="btn">领劵购买</button>
</view>
</view>
<!-- #ifdef APP -->
<view class="fenxiang" @click="fenxiang()">分享</view>
<!-- #endif -->
<view class="tuijian_list">
<view class="tuijian_title">为您推荐</view>
<scroll-view style="width: 100%;height: 100%;" scroll-y="true" @scrolltolower="getList()">
<view class="tuijian_item" v-for="(item,index) in list" :key="index">
<good :data="item" :search_id="item.search_id" :pid="pid"></good>
</view>
<uni-load-more :status="moreStatus" color="#FE5353"></uni-load-more>
</scroll-view>
</view>
</view>
</template>
<script>
import good from './good_com/good.vue'
import { pddDetail,pddLink } from '@/api/store'
import fenxiang from './utils/share.js'
export default {
components: {
good
},
data() {
return {
goodSign:"",
hasLogin: true,
data: {},
id: '',
list: [],
page: 1,
moreStatus: '',
search_id: '',
pid: ''
};
},
computed: {
price() {
if (!this.data) {
return;
}
if (this.data.coupon_discount && this.data.min_group_price) {
return (this.data.min_group_price - this.data.coupon_discount) / 100
}
return this.data.min_group_price / 100 || ''
}
},
// #ifdef APP
onBackPress({
from
}) {
if (from == 'backbutton') {
this.$nextTick(function() {
uniShare.hide()
})
return uniShare.isShow;
}
},
// #endif
onReachBottom() {
if (this.moreStatus != 'nomore') {
this.getList()
}
},
mounted() {
this.goodSign = this._route.query.goodSign;
this.getData();
},
methods: {
async buy() {
pddLink(this.goodSign).then(res=>{
uni.navigateToMiniProgram({
appId: res.data.weAppInfo.appId,
path: res.data.weAppInfo.pagePath
})
})
},
doWeb() {
pddApi.promotion_url_generate(this.data.goods_sign, this.pid, this.search_id).then(
res => {
let data = res.data.goods_promotion_url_generate_response
.goods_promotion_url_list[0]
console.log('普通链接:', data)
uni.setStorageSync('webUrl', data.mobile_url)
// #ifndef MP
uni.navigateTo({
url: '/uni_modules/aliea-goods/pages/webview/webview'
})
// #endif
// #ifdef MP
uni.navigateToMiniProgram({
appId: data.we_app_info.app_id,
path: data.we_app_info.page_path
})
// #endif
})
},
getData() {
pddDetail(this.goodSign).then(res=>{
console.log(res);
this.data = res.data;
// this.getList();
uni.setNavigationBarTitle({
title: this.data.goodsDesc
})
this.toTop()
})
},
getList() {
this.moreStatus = 'loading'
pddApi.goodsRecommend(this.data.cat_ids[0], this.id, this.pid, this.list.length).then(res => {
res.data.goods_basic_detail_response.list.forEach((item, index) => {
item.search_id = res.data.goods_basic_detail_response.search_id
this.list.push(item)
})
if (this.list.length == 0) {
this.moreStatus = 'nomore'
} else {
this.moreStatus = 'more'
}
}).catch(err => {
this.moreStatus = 'error'
})
},
toTop() {
uni.pageScrollTo({
duration: 0,
scrollTop: 0
})
},
async fenxiang() {
//#ifdef APP
let url = "/#/uni_modules/aliea-goods/pages/goods/goodDetail?id=" + this.id +
"&search_id=" + this.search_id
if (this.pid) {
url += '&p_id=' + this.pid
}
fenxiang(this.data.mall_name, url, this.data.goods_desc, this.data.goods_thumbnail_url)
//#endif
}
}
}
</script>
<style lang="scss">
.good_detail_page {
width: 100%;
height: auto;
background-color: antiquewhite;
.fenxiang {
position: fixed;
display: flex;
flex-direction: column;
right: 15rpx;
bottom: 270rpx;
width: 60rpx;
line-height: 60rpx;
background-color: #ff5500;
border-radius: 50%;
z-index: 1000;
border: #55aa00 10rpx dashed;
color: #ffffff;
padding: 15rpx;
text-align: center;
font-size: 28rpx;
}
.current_goods {
width: 100%;
background-color: antiquewhite;
display: block;
.main_img {
width: 100%;
}
.current_imgs {
width: 750rpx;
height: 750rpx;
margin: 10rpx 0rpx;
}
.current_goods_text {
// border: #ccc 1px solid;
margin: 30rpx;
padding: 30rpx;
border-radius: 20rpx;
background-color: #fff;
.price {
position: relative;
margin: 20rpx 0;
font-size: 60rpx;
font-weight: 600;
color: red;
.yuanjia {
margin-left: 20rpx;
text-decoration: line-through;
font-size: 28rpx;
color: #868686;
font-weight: normal;
}
}
.biaoqian {
position: relative;
.biaoqian_text {
display: inline-block;
background-color: #ff5500;
padding: 10rpx;
margin: 5rpx;
color: #fff;
border-radius: 15rpx;
line-height: 35rpx;
font-size: 28rpx;
}
}
.goods_title {
margin-bottom: 20rpx;
line-height: 40rpx;
font-weight: bold;
font-size: 30rpx;
}
.goods_dp {
width: 100%;
margin-top: 30rpx;
font-size: 28rpx;
font-weight: bold;
.goodsa_dp_img {
width: 100rpx;
height: 100rpx;
vertical-align: top;
margin-right: 10rpx;
}
.goodsa_dp_name {
display: inline-block;
line-height: 50rpx;
font-size: 26rpx;
.hot {
color: #ff0000;
font-weight: bold;
}
}
}
}
}
.buy_btn {
position: fixed;
background-color: #ff634e;
text-align: center;
z-index: 10;
width: 750rpx;
height: 230rpx;
bottom: 0;
color: #fff;
padding: 30rpx;
.topbtn {
position: absolute;
right: 40rpx;
top: 0rpx;
width: 100rpx;
height: 45rpx;
background-color: #e20000;
font-size: 28rpx;
padding: 0;
line-height: 45rpx;
color: #fff;
}
.price {
color: #fff;
font-size: 45rpx;
.btn {
width: 250rpx;
line-height: 60rpx;
border: #efefef 1px solid;
border-radius: 20rpx;
background-color: #ec0000;
font-size: 38rpx;
}
.juanhou {
color: #fff;
font-size: 26rpx;
}
.yuanjia {
margin-left: 20rpx;
font-size: 26rpx;
color: #e7e7e7;
font-weight: normal;
margin: 10rpx auto;
}
}
}
.tuijian_list {
margin-top: 20rpx;
width: 100%;
height: 100%;
.tuijian_title {
width: 100%;
line-height: 40rpx;
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
font-size: 30rpx;
font-weight: bold;
border-top: #cfcfcf 1px solid;
border-bottom: #cfcfcf 1px solid;
}
.tuijian_item {
display: inline-block;
width: 355rpx;
margin: 10rpx;
}
}
}
</style>

173
pages/goods/goodList.vue

@ -0,0 +1,173 @@
<template>
<view class="content">
<search_bar @toPage="toList"></search_bar>
<view class="paixu">
<view class="select">
<picker mode="selector" :value="sort_type" :range="sort_list" range-key="text" @change="paixu">
<view>{{sort_text}}</view>
</picker>
</view>
</view>
<view class="paixuzw"></view>
<view class="list_item" v-for="(item,index) in list.obj" :key="index">
<good :search_id="search_id" :data="item" :pid="pid"></good>
</view>
<uni-load-more :status="list.moreStatus" color="#FE5353"></uni-load-more>
</view>
</template>
<script>
import good from './good_com/good.vue'
import search_bar from './good_com/search_bar.vue'
import {
checkAuthority
} from './utils/util.js'
const pddApi = uniCloud.importObject('pdd-serve')
export default {
components: {
good,
search_bar
},
onLoad(options) {
this.key_word = options.key_word;
this.pid = options.p_id
uni.setNavigationBarTitle({
title: options.key_word
})
this.search_key();
},
data() {
return {
list: {
obj: [],
page: 1,
pageSize: 20,
moreStatus: 'more'
},
pid: '',
search_id: '',
list_id: '',
sort_text: '排序',
sort_type: 0,
sort_list: [{
id: 0,
text: "综合排序"
}, {
id: 3,
text: "价格由低到高"
}, {
id: 9,
text: "券后价由低到高"
}, {
id: 10,
text: "券后价由高到低"
}, {
id: 6,
text: "销量由高到低"
}, {
id: 8,
text: "优惠券金额由高到低"
}]
};
},
onReachBottom() {
if (this.list.moreStatus != 'noMore') {
this.list.page++
this.loadData()
}
},
methods: {
paixu(e) {
this.list.obj = []
this.list.page = 1
this.list.moreStatus = 'more'
this.sort_type = this.sort_list[e.detail.value].id
this.sort_text = this.sort_list[e.detail.value].text
this.loadData()
},
search_key() {
checkAuthority(this.pid).then(res => {
if (res.mobile_url) {
uni.setStorageSync('webUrl', res.mobile_url)
// #ifndef MP
uni.navigateTo({
url: '/uni_modules/aliea-goods/pages/webview/webview'
})
// #endif
// #ifdef MP
uni.navigateToMiniProgram({
appId: data.we_app_info.app_id,
path: data.we_app_info.page_path
})
// #endif
} else {
this.loadData()
}
})
},
loadData() {
this.list.moreStatus = 'loading'
pddApi.goodsSearch(this.key_word, this.list_id, '', this.pid, this.list.page, this.list.pageSize, this
.sort_type)
.then((
res) => {
let list = res.data.goods_search_response.goods_list
this.search_id = res.data.goods_search_response.search_id
this.list_id = res.data.goods_search_response.list_id
if (list.length == 0) {
this.list.moreStatus = 'noMore'
}
this.list.obj = this.list.obj.concat(list);
})
},
toList(e) {
let url = '/uni_modules/aliea-goods/pages/goods/goodList?key_word=' + e.keyword
if (this.pid) {
url += '&p_id=' + this.pid
}
uni.redirectTo({
url: url
})
}
}
}
</script>
<style lang="scss">
.content {
width: 100%;
background-color: antiquewhite;
.paixu {
position: fixed;
width: 100%;
background-color: rgb(250 235 208);
border-bottom: #dfdfdf 5rpx solid;
z-index: 100;
.select {
display: inline-block;
width: 100%;
line-height: 70rpx;
color: #f80000;
padding-left: 20rpx;
}
}
.paixuzw {
width: 100%;
height: 70rpx;
}
.list_item {
width: 335rpx;
display: inline-block;
margin: 20rpx 15rpx;
}
}
</style>

159
pages/goods/good_com/good.vue

@ -0,0 +1,159 @@
<template>
<view class="goods_page">
<view class="goods_item" @click="detail">
<image mode="aspectFit" class="goods_img" :src="data.goods_thumbnail_url"></image>
<view class="good_group_text">
<text class="goods_title">{{data.goods_name}}</text>
<view class="goods_description">
<view class="juanjia">
<text class="juanjia_title">领劵免拼</text>
<text class="juanjia_price">{{priceFormat(data.min_group_price-data.coupon_discount)}}</text>
</view>
<view class="yuanjia">原价{{priceFormat(data.min_normal_price)}}</view>
<view class="tuanjia">团购{{priceFormat(data.min_group_price)}}</view>
<view class="youhui" v-if="data.has_coupon">{{data.coupon_discount/100}}元卷</view>
<view class="yishou">已售{{data.sales_tip}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
computed: {
},
props: {
data: {
type: Object,
default: () => {
return {}
}
},
search_id: {
type: String,
default: () => {
return ""
}
},
pid: {
type: [String],
default: () => {
return ""
}
}
},
methods: {
detail() {
let url = '/uni_modules/aliea-goods/pages/goods/goodDetail?id=' + this.data.goods_sign +
'&search_id=' + this.search_id
if (this.pid) {
url += '&p_id=' + this.pid
}
uni.navigateTo({
url: url
})
},
priceFormat(price) {
let sj = price / 100
if (sj > 100) {
sj = Math.floor(sj)
}
return sj
}
}
}
</script>
<style lang="scss">
.goods_page {
width: 355rpx;
.goods_item {
width: 355rpx;
border-radius: 15rpx;
background-color: #fff;
padding: 10rpx 0;
.goods_img {
display: block;
width: 335rpx;
height: 335rpx;
border-radius: 15rpx;
margin: 0 auto;
}
.good_group_text {
padding: 0 10rpx;
.goods_title {
display: block;
font-size: 30rpx;
overflow: hidden;
margin: 20rpx 0;
height: 120rpx;
}
.goods_description {
line-height: 38rpx;
font-size: 26rpx;
.yuanjia {
text-decoration: line-through;
color: #999;
width: 50%;
display: inline-block;
}
.tuanjia {
text-decoration: line-through;
width: 50%;
display: inline-block;
text-align: right;
}
.juanjia {
color: red;
font-weight: bold;
position: relative;
.juanjia_title {
font-size: 26rpx;
text-align: justify;
}
.juanjia_price {
font-size: 45rpx;
position: absolute;
right: 10rpx;
top: -10rpx;
}
}
.yishou {
color: #999;
width: 50%;
display: inline-block;
text-align: right;
}
.youhui {
width: 50%;
display: inline-block;
color: #ff5500;
height: 40rpx;
}
}
}
}
}
</style>

207
pages/goods/good_com/search_bar.vue

@ -0,0 +1,207 @@
<template>
<view class="search_page">
<view class="search_bar">
<view v-if="backTag" class="back_icon" @click="back">
<uni-icons color="#ffffff" size="26" type="back"></uni-icons>
</view>
<view class="search_bar_view">
<uni-search-bar @focus="getData" cancelButton="none" v-model="content" @confirm="confirm" />
<!-- <button class="h5_btm" type="default" @click="confirm(content)"></button> -->
</view>
</view>
<view class="searchzw"></view>
<view class="search_result" v-if="lishi">
<view class="search-title">搜索历史
<text v-if="!close" class="edit" @click="edit">编辑</text>
<text v-else class="edit" @click="edit">取消编辑</text>
</view>
<view class="search_text" v-for="(item,index) in searchData" :key="index">
<view v-if="close">{{item}}
<uni-icons @click="clearHis(index)" size="20" class="search_close" type="close">
</uni-icons>
</view>
<view v-else @click="confirms(item)">
{{item}}
</view>
</view>
<view class="guanbi" @click="closeLishi()">关闭</view>
</view>
</view>
</template>
<script>
export default {
name: 'search_bar',
data() {
return {
content: '',
searchData: {},
close: false,
closeText: "编辑",
lishi: false,
};
},
computed: {
backTag() {
return getCurrentPages().length > 1 && uni.getSystemInfoSync().uniPlatform=="app"
}
},
created() {
this.content = this.getSearchData()[0]
},
methods: {
confirm(content) {
this.confirms(content.value)
},
confirms(content) {
this.content = content
if (!this.content) return;
this.clearHis(this.searchData.indexOf(this.content))
this.searchData = this.setSearchData(this.content)
this.closeLishi()
this.$emit("toPage", {
keyword: this.content
})
},
getData() {
this.lishi = true
this.searchData = this.getSearchData()
},
closeLishi() {
this.lishi = false
this.close = false
},
back() {
uni.navigateBack()
},
edit() {
this.close = !this.close
if (this.close) {
this.closeText = "取消编辑"
} else {
this.closeText = "编辑"
}
},
clearHis(index) {
if (index < 0) return
this.searchData.splice(index, 1)
this.setSearchData(this.searchData)
},
setSearchData(content) {
let searchHistory = uni.getStorageSync('searchHistory')
if (typeof searchHistory != "object") {
searchHistory = []
}
if (typeof content == "string") {
if (searchHistory.indexOf(content) == -1) {
searchHistory.unshift(content)
}
} else if (typeof content == "object") {
searchHistory = content
}
uni.setStorageSync('searchHistory', searchHistory)
return searchHistory
},
getSearchData() {
let searchHistory = uni.getStorageSync('searchHistory')
if (typeof searchHistory != "object") {
searchHistory = []
}
return searchHistory
}
}
}
</script>
<style lang="scss">
.search_page {
width: 100%;
position: relative;
.search_bar {
position: fixed;
width: 100%;
padding-top: var(--status-bar-height);
background-color: #ff5500;
height: 115rpx;
line-height: 80rpx;
display: flex;
flex-direction: row;
align-items: center;
z-index: 100;
.back_icon {
width: 70rpx;
text-align: right;
z-index: 100;
}
.search_bar_view {
flex: 1;
position: relative;
}
}
.searchzw {
padding-top: var(--status-bar-height);
width: 100%;
height: 115rpx;
}
//#ifdef APP
//#endif
.search_result {
width: 710rpx;
padding: 20rpx;
line-height: 40rpx;
background-color: #f8f8f8;
border: #efefef 1px solid;
position: absolute;
top: 110rpx+var(--status-bar-height);
z-index: 200;
.search-title {
font-weight: bold;
color: #666;
line-height: 80rpx;
.edit {
position: absolute;
right: 20rpx;
display: inline-block;
text-align: right;
font-weight: normal;
color: #55aaff;
}
}
.search_text {
background-color: #f0f0f0;
padding: 10rpx 20rpx;
display: inline-block;
margin: 10rpx 15rpx;
border-radius: 10rpx;
position: relative;
.search_close {
position: absolute;
right: -15rpx;
top: -10rpx
}
}
.guanbi {
width: 100rpx;
margin: 20rpx auto 0rpx auto;
color: #e3e3e3;
text-align: center;
}
}
}
</style>

79
pages/goods/good_com/tabs.vue

@ -0,0 +1,79 @@
<template>
<view class="content">
<scroll-view class="scroll" :scroll-into-view="'scroll_view_id_'+(tabIndex-1)" scroll-x="true"
show-scrollbar="false">
<div class="scroll_view" :id="'scroll_view_id_'+index" @click="tabClick(index)"
v-for="(item,index) in tabList" :key="index">
<text class="tabText" :style="{
color:tabIndex===index?activeColor:noActiveColor,
fontWeight:tabIndex===index?'bold':'normal',}">{{item.name}}</text>
<view class="active_line"
:style="tabIndex===index?'background-color:'+activeColor:'background-color:#ffffff;'"></view>
</div>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {};
},
props: {
activeColor: {
type: String,
default: '#1596FE'
},
noActiveColor: {
type: String,
default: '#333333'
},
tabList: {
type: Array,
default: ()=>{
return []
}
},
tabIndex: {
type: Number,
default: 0
}
},
methods: {
tabClick(index) {
if (this.tabIndex === index) return;
this.$emit("change", {
detail: {
current: index
}
})
},
}
}
</script>
<style lang="scss" >
.content {
width: 100%;
.scroll {
background-color: #efefef;
white-space: nowrap;
position: relative;
line-height: 70rpx;
.scroll_view {
display: inline-block;
padding: 10rpx 15rpx;
.tabText{
line-height: 50rpx;
font-size: 35rpx;
}
.active_line{
width: 100%;
height: 8rpx;
}
}
}
}
</style>

368
pages/goods/index.vue

@ -0,0 +1,368 @@
<template>
<view class="content_index">
<search_bar @toPage="toList"></search_bar>
<view class="tabs">
<tabs activeColor="#FE5353" :tabList="tabList" :tabIndex="swiperIndex" @change="swiperChange"></tabs>
</view>
<view class="swiper_view" :style="'height:'+screenHeight+'px'">
<swiper :duration="1000" :current="swiperIndex" @change="swiperChange">
<swiper-item>
<view class="goods_list">
<scroll-view style="width: 100%;height: 100%;" scroll-y="true" @scrolltolower="loadData">
<view class="menu_view">
<div class="menu_view_item" @click="menu(item)" v-for="(item,index) in menus"
:key="index">
<img class="menu_view_item_img" :src="item.imgUrl" />
<text class="menu_view_item_text">{{item.name}}</text>
</div>
</view>
<view class="menu_view_title">实时热销榜</view>
<view class="goods_list_item" v-for="(item,index) in recommentList.obj" :key="index">
<good :search_id="search_id" :data="item" :pid="pid"></good>
</view>
<uni-load-more :status="recommentList.moreStatus" color="#FE5353"></uni-load-more>
</scroll-view>
</view>
</swiper-item>
<swiper-item v-for="(ite,inde) in goodList" :key="inde">
<view class="goods_list">
<scroll-view style="width: 100%;height: 100%;" scroll-y="true" @scrolltolower="loadData">
<view class="goods_list_item" v-for="(item,index) in ite.obj" :key="index">
<good :search_id="search_id" :data="item" :pid="pid"></good>
</view>
<uni-load-more :status="ite.obj.moreStatus" color="#FE5353"></uni-load-more>
</scroll-view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</template>
<script>
import good from './good_com/good.vue'
import tabs from './good_com/tabs.vue'
import search_bar from './good_com/search_bar.vue'
import {
checkAuthority
} from './utils/util.js'
const pddApi = uniCloud.importObject('pdd-serve')
export default {
components: {
good,
tabs,
search_bar,
},
data() {
return {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
swiperIndex: 0,
PageScrollTop: 0,
screenHeight: 100,
search_id: '',
goodList: [],
recommentList: {
obj: [],
page: 1,
pageSize: 20,
moreStatus: ''
},
pid: '',
tabList: [{
id: '',
name: '推荐'
}, {
id: 1,
name: '食品'
},
{
id: 743,
name: '男装'
},
{
id: 14,
name: '女装'
},
{
id: 18,
name: '电器'
},
{
id: 1281,
name: '鞋包'
},
{
id: 1282,
name: '内衣'
},
{
id: 16,
name: '美妆'
},
{
id: 13,
name: '水果'
},
{
id: 818,
name: '家纺'
},
{
id: 2478,
name: '文具'
},
{
id: 1451,
name: '运动'
},
{
id: 15,
name: '百货'
},
{
id: 4,
name: '母婴'
},
{
id: 2048,
name: '汽车'
},
{
id: 1917,
name: '家装'
},
{
id: 2974,
name: '家具'
}
],
menus: [{
imgUrl: 'static/ddk/image/miaosha.png',
name: '限时秒杀',
id: 4
},
{
imgUrl: 'static/ddk/image/butie.png',
name: '百亿补贴',
id: 39996
},
{
imgUrl: 'static/ddk/image/lingquan.png',
name: '领券中心',
id: 40000
},
{
imgUrl: 'static/ddk/image/chongzhi.png',
name: '充值中心',
id: 39997
},
]
}
},
onLoad(e) {
this.pid = e.p_id
this.initList();
uni.getSystemInfo({
success: res => {
this.screenHeight = res.screenHeight - uni.upx2px(220) //px rpx
}
});
},
watch: {
swiperIndex(val) {
if (val > 0) {
if (this.goodList[val - 1].obj.length == 0) {
this.goodList[val - 1].page = 1;
}
} else {
if (this.recommentList.obj.length == 0) {
this.recommentList.page = 1;
}
this.recommentList.page = 1;
}
this.loadData()
}
},
methods: {
menu(item) {
checkAuthority(this.pid).then(res => {
if (res.mobile_url) {
uni.setStorageSync('webUrl', res.mobile_url)
// #ifndef MP
uni.navigateTo({
url: '/uni_modules/aliea-goods/pages/webview/webview'
})
// #endif
// #ifdef MP
uni.navigateToMiniProgram({
appId: data.we_app_info.app_id,
path: data.we_app_info.page_path
})
// #endif
} else {
this.doMenu(item)
}
})
},
doMenu(item) {
pddApi.pindao_resource(item.id, this.pid).then(res => {
let data = res.data.resource_url_response
uni.setStorageSync('webUrl', data.single_url_list.mobile_url)
// #ifndef MP
uni.navigateTo({
url: '/uni_modules/aliea-goods/pages/webview/webview'
})
// #endif
// #ifdef MP
uni.navigateToMiniProgram({
appId: data.we_app_info.app_id,
path: data.we_app_info.page_path
})
// #endif
})
},
initList() {
for (let i = 1; i < this.tabList.length; i++) {
this.goodList.push({
obj: [],
page: 1,
pageSize: 20,
moreStatus: ''
})
}
this.loadData()
},
loadData(e) {
if (this.swiperIndex === 0) {
if (this.recommentList.moreStatus === 'loading' ||
this.recommentList.moreStatus === 'refreshing') {
return;
}
pddApi.goodsRecommend('', '', this.pid, this.recommentList.obj.length).then(res => {
let list = []
list = res.data.goods_basic_detail_response.list
this.recommentList.obj.concat(list)
this.search_id = res.data.goods_basic_detail_response.search_id
if (list.length == 0) {
this.this.recommentList.moreStatus = 'noMore'
return
}
this.recommentList.moreStatus = ''
this.recommentList.page++;
this.recommentList.obj = this.recommentList.obj.concat(list);
}).catch((res) => {
this.goodList[this.swiperIndex].moreStatus = 'error'
});
} else {
if (this.goodList[this.swiperIndex - 1].moreStatus === 'loading' ||
this.goodList[this.swiperIndex - 1].moreStatus === 'refreshing') {
return;
}
pddApi.goodsSearch('', '', this.tabList[this.swiperIndex].id, this.pid,
this.goodList[this.swiperIndex - 1].page,
this.goodList[this.swiperIndex - 1].pageSize).then(res => {
let list = []
list = res.data.goods_search_response.goods_list
this.search_id = res.data.goods_search_response.search_id
if (list.length == 0) {
this.goodList[this.swiperIndex - 1].moreStatus = 'noMore'
return
}
this.goodList[this.swiperIndex - 1].moreStatus = ''
this.goodList[this.swiperIndex - 1].page++;
this.goodList[this.swiperIndex - 1].obj = this.goodList[this.swiperIndex - 1].obj.concat(
list);
}).catch((res) => {
this.goodList[this.swiperIndex - 1].moreStatus = 'error'
});
}
},
toList(e) {
let url = '/uni_modules/aliea-goods/pages/goods/goodList?key_word=' + e.keyword
if (this.pid) {
url += '&p_id=' + this.pid
}
uni.navigateTo({
url: url
})
},
swiperChange(e) {
this.swiperIndex = e.detail.current;
}
}
}
</script>
<style lang="scss">
.content_index {
width: 100%;
height: 100%;
.tabs {
width: 100%;
}
.swiper_view {
position: fixed;
background-color: antiquewhite;
width: 100%;
uni-swiper {
width: 100%;
height: 100%;
.goods_list {
height: 100%;
.goods_list_item {
width: 355rpx;
display: inline-block;
margin: 10rpx;
border-radius: 20rpx;
}
.menu_view {
width: 750rpx;
padding: 10rpx;
// margin-top: 10rpx;
border-radius: 20rpx;
.menu_view_item {
background-color: #fff;
display: inline-block;
text-align: center;
width: 162.5rpx;
padding: 20rpx 10rpx;
.menu_view_item_img {
width: 90rpx;
height: 90rpx;
}
.menu_view_item_text {
display: block;
}
}
}
.menu_view_title {
padding: 15rpx;
font-weight: bold;
background-color: #fff;
}
}
}
}
}
</style>

67
pages/goods/utils/share.js

@ -0,0 +1,67 @@
import UniShare from './uni-share/js_sdk/uni-share.js'
const uniShare = new UniShare()
const fenxiang = async (title, url, descript, imgUrl, type = 0) => {
//#ifdef APP
uniShare.show({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: type,
href: url,
title: title,
summary: descript,
imageUrl: imgUrl +
'?x-oss-process=image/resize,m_fill,h_100,w_100' //压缩图片解决,在ios端分享图过大导致的图片失效问题
},
menus: [{
"img": "static/ddk/app-plus/sharemenu/wechatfriend.png",
"text": "微信朋友",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "static/ddk/app-plus/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSceneTimeline"
}
},
{
"img": "static/ddk/app-plus/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "static/ddk/app-plus/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "static/ddk/app-plus/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
}, {
"img": "static/ddk/app-plus/sharemenu/more.png",
"text": "系统分享",
"share": "shareSystem"
}
],
cancelText: "取消",
}, e => { //callback
console.log(e);
})
//#endif
}
export {
fenxiang
}

18
pages/goods/utils/uni-share/changelog.md

@ -0,0 +1,18 @@
## 2.0.2(2021-12-16)
修复在某些情况下报:`Cannot read property 'hide' of undefined`的问题
## 2.0.1(2021-11-29)
修改错误的scene值WXSenceTimeline(分享到朋友圈)更正为WXSceneTimeline
## 2.0.0(2021-10-14)
支持监听返回操作(如:物理返回,全面屏手机侧滑)关闭分享弹窗
## 1.0.6(2021-08-25)
兼容vue3
## 1.0.5(2021-08-05)
优化代码实现,修改原来用`eval()`函数实现的逻辑
## 1.0.4(2021-06-07)
为符合苹果应用市场的审核,只显示存在对应的分享客户端的选项。如:配置包含微信分享,但是用户手机上并没有安装微信,就不显示微信分享。
## 1.0.2(2021-05-06)
修复错误的提示:“打包时未添加oauth模块”
## 1.0.1(2021-04-30)
新增完整示例
## 1.0.0(2021-04-28)
第1版发布

204
pages/goods/utils/uni-share/js_sdk/uni-image-menu.js

@ -0,0 +1,204 @@
var nvMask, nvImageMenu;
class NvImageMenu {
constructor(arg) {
this.isShow = false
}
show({
list,
cancelText
}, callback) {
if (!list) {
list = [{
"img": "/static/sharemenu/wechatfriend.png",
"text": "图标文字"
}]
}
//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
var screenWidth = plus.screen.resolutionWidth
//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
//图标下的按钮文字距离图标5像素,文字大小12像素
//底部取消按钮高度固定为44px
//TODO 未处理横屏和pad,这些情况6个图标应该一排即可
var margin = 20,
iconWidth = 60,
icontextSpace = 5,
textHeight = 12
var left1 = margin / 360 * screenWidth
var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
margin = 15
iconWidth = 40
left1 = margin / 360 * screenWidth
iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
}
var left2 = left1 + iconWidth + iconSpace
var left3 = left1 + (iconWidth + iconSpace) * 2
var left4 = left1 + (iconWidth + iconSpace) * 3
var top1 = left1
var top2 = top1 + iconWidth + icontextSpace + textHeight + left1
const TOP = {
top1,
top2
},
LEFT = {
left1,
left2,
left3,
left4
};
nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
top: '0px',
left: '0px',
height: '100%',
width: '100%',
backgroundColor: 'rgba(0,0,0,0.2)'
});
nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
bottom: '0px',
left: '0px',
height: (iconWidth + textHeight + 2 * margin) * Math.ceil(list.length / 4) + 44 +
'px', //'264px',
width: '100%',
backgroundColor: 'rgb(255,255,255)'
});
nvMask.addEventListener("click", () => { //处理遮罩层点击
// console.log('处理遮罩层点击');
this.hide()
callback({
event: "clickMask"
})
})
let myList = []
list.forEach((item, i) => {
myList.push({
tag: 'img',
src: item.img,
position: {
top: TOP['top' + (parseInt(i / 4) + 1)],
left: LEFT['left' + (1 + i % 4)],
width: iconWidth,
height: iconWidth
}
})
myList.push({
tag: 'font',
text: item.text,
textStyles: {
size: textHeight
},
position: {
top: TOP['top' + (parseInt(i / 4) + 1)] + iconWidth + icontextSpace,
left: LEFT['left' + (1 + i % 4)],
width: iconWidth,
height: textHeight
}
})
})
//绘制底部图标菜单的内容
nvImageMenu.draw([{
tag: 'rect', //菜单顶部的分割灰线
color: '#e7e7e7',
position: {
top: '0px',
height: '1px'
}
},
{
tag: 'font',
text: cancelText, //底部取消按钮的文字
textStyles: {
size: '14px'
},
position: {
bottom: '0px',
height: '44px'
}
},
{
tag: 'rect', //底部取消按钮的顶部边线
color: '#e7e7e7',
position: {
bottom: '45px',
height: '1px'
}
},
...myList
])
nvMask.show()
nvImageMenu.show()
// 开始动画
/*
plus.nativeObj.View.startAnimation({
type: 'slide-in-bottom',
duration: 300
}, nvImageMenu, {}, function() {
console.log('plus.nativeObj.View.startAnimation动画结束');
// 关闭原生动画
plus.nativeObj.View.clearAnimation();
nvImageMenu.show()
});
*/
this.isShow = true
nvImageMenu.addEventListener("click", e => { //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
// console.log("click menu"+JSON.stringify(e));
if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
// callback({event:"clickCancelButton"})
this.hide()
} else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
//屏幕左右边缘5像素及菜单顶部5像素不处理点击
} else { //点击了图标按钮
var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
var iCol = -1
if (e.clientX < (left2 - (iconSpace / 2))) {
iCol = 0
} else if (e.clientX < (left3 - (iconSpace / 2))) {
iCol = 1
} else if (e.clientX < (left4 - (iconSpace / 2))) {
iCol = 2
} else {
iCol = 3
}
if (iRow == 0) {
iClickIndex = iCol
} else {
iClickIndex = iCol + 4
}
// console.log("点击按钮的序号: " + iClickIndex);
// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
// }
callback({
event: "clickMenu",
index: iClickIndex
})
}
})
/* nvImageMenu.addEventListener("touchstart", function(e) {
if (e.screenY > (plus.screen.resolutionHeight - 44)) {
//TODO 这里可以处理按下背景变灰的效果
}
})
nvImageMenu.addEventListener("touchmove", function(e) {
//TODO 这里可以处理按下背景变灰的效果
if (e.screenY > plus.screen.resolutionHeight - 44) {}
})
nvImageMenu.addEventListener("touchend", function(e) {
//TODO 这里可以处理释放背景恢复的效果
})
*/
}
hide() {
if (this.isShow) {
nvMask.hide()
nvImageMenu.hide()
this.isShow = false
}
}
}
export default NvImageMenu

98
pages/goods/utils/uni-share/js_sdk/uni-share.js

@ -0,0 +1,98 @@
import UniImageMenu from './uni-image-menu.js';
class UniShare extends UniImageMenu{
constructor(arg) {
super()
this.isShow = super.isShow
}
async show(param, callback){
var menus = []
plus.share.getServices(services => { //只显示有服务的项目
services = services.filter(item => item.nativeClient)
let servicesList = services.map(e => e.id)
param.menus.forEach(item => {
if (servicesList.includes(item.share.provider) || typeof(item.share) == 'string') {
menus.push(item)
}
})
super.show({
list: menus,
cancelText: param.cancelText
}, e => {
callback(e)
if(e.event == 'clickMenu'){
if (typeof(menus[e.index]['share']) == 'string') {
this[menus[e.index]['share']](param)
} else {
uni.share({
...param.content,
...menus[e.index].share,
success: res=> {
console.log("success:" + JSON.stringify(res));
super.hide()
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
// uni.showModal({
// content: JSON.stringify(err),
// showCancel: false,
// confirmText: "知道了"
// });
}
})
}
}
})
}, err => {
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
}
hide(){
super.hide()
}
copyurl(param) {
console.log('copyurl',param);
uni.setClipboardData({
data: param.content.href,
success: ()=>{
console.log('success');
uni.hideToast() //关闭自带的toast
uni.showToast({
title: '复制成功',
icon: 'none'
});
super.hide();
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err),
showCancel: false
});
}
});
}
// 使用系统分享发送分享消息
shareSystem(param) {
console.log('shareSystem',param);
plus.share.sendWithSystem({
type: 'text',
content: param.content.title + param.content.summary || '',
href: param.content.href,
}, (e)=> {
console.log('分享成功');
super.hide()
}, (err)=> {
console.log('分享失败:' + JSON.stringify(err));
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
});
}
}
export default UniShare

80
pages/goods/utils/uni-share/package.json

@ -0,0 +1,80 @@
{
"id": "uni-share",
"displayName": "uni-share",
"version": "2.0.2",
"description": "底部弹出宫格图标式的分享菜单,可覆盖原生组件。",
"keywords": [
"分享菜单"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "n",
"Android Browser": "n",
"微信浏览器(Android)": "n",
"QQ浏览器(Android)": "n"
},
"H5-pc": {
"Chrome": "n",
"IE": "n",
"Edge": "n",
"Firefox": "n",
"Safari": "n"
},
"小程序": {
"微信": "n",
"阿里": "n",
"百度": "n",
"字节跳动": "n",
"QQ": "n"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

95
pages/goods/utils/uni-share/readme.md

@ -0,0 +1,95 @@
#### 本功能基于[底部图标菜单](https://ext.dcloud.net.cn/plugin?id=4858)封装而成。
### 示例代码
```
<template>
<button type="default" @click="uniShare">显示</button>
</template>
<script>
import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
export default {
onBackPress({from}) {
console.log(from);
if(from=='backbutton'){
this.$nextTick(function(){
uniShare.hide()
})
return uniShare.isShow;
}
},
methods: {
uniShare() {
uniShare.show({
content: { //公共的分享参数配置 类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: 'https://uniapp.dcloud.io/',
title: '标题',
summary: '描述',
imageUrl: 'https://img-cdn-aliyun.dcloud.net.cn/stream/icon/__UNI__HelloUniApp.png'
},
menus: [{
"img": "/static/app-plus/sharemenu/wechatfriend.png",
"text": "微信好友",
"share": { //当前项的分享参数配置。可覆盖公共的配置如下:分享到微信小程序,配置了type=5
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/app-plus/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSceneTimeline"
}
},
{
"img": "/static/app-plus/sharemenu/mp_weixin.png",
"text": "微信小程序",
"share": {
provider: "weixin",
scene: "WXSceneSession",
type: 5,
miniProgram: {
id: '123',
path: '/pages/list/detail',
webUrl: '/#/pages/list/detail',
type: 0
},
}
},
{
"img": "/static/app-plus/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/app-plus/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/app-plus/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
},
{
"img": "/static/app-plus/sharemenu/more.png",
"text": "更多",
"share": "shareSystem"
}
],
cancelText: "取消分享",
}, e => { //callback
console.log(uniShare.isShow);
console.log(e);
})
}
}
}
</script>
```

20
pages/goods/utils/util.js

@ -0,0 +1,20 @@
// const pddApi = uniCloud.importObject('pdd-serve')
// // 查询是否备案
// export const checkAuthority = function(pid = '') {
// return new Promise((resolve, reject) => {
// pddApi.authority_query(pid).then(res => {
// console.log('备案数:', res.data.authority_query_response.bind)
// if (res.data.authority_query_response && res.data.authority_query_response.bind ===
// 0) {
// pddApi.authority_generate(pid).then(res => {
// let data = res.data.rp_promotion_url_generate_response
// .url_list[0]
// console.log('备案链接:', data);
// resolve(data)
// })
// } else {
// resolve(true)
// }
// })
// })
// }

26
pages/home/components/HotCommodity.vue

@ -12,7 +12,7 @@
<swiper-item v-for="(goods, index) in goodsList" :key="index" class="carousel-item"> <swiper-item v-for="(goods, index) in goodsList" :key="index" class="carousel-item">
<view class="goods-list-box x-f"> <view class="goods-list-box x-f">
<block v-for="mgoods in goods" :key="mgoods.id"> <block v-for="mgoods in goods" :key="mgoods.id">
<view class="min-goods" @tap="jump('/pages/shop/GoodsCon/index',{id:mgoods.id})"> <view class="min-goods" @tap="routerGo(mgoods)">
<view class="img-box"> <view class="img-box">
<view class="tag">hot</view> <view class="tag">hot</view>
<image class="img" :src="mgoods.image" mode="widthFix"></image> <image class="img" :src="mgoods.image" mode="widthFix"></image>
@ -20,7 +20,12 @@
<view class="price-box"> <view class="price-box">
<view class="y-f"> <view class="y-f">
<text class="seckill-current">{{ mgoods.price }}</text> <text class="seckill-current">{{ mgoods.price }}</text>
<text class="original">销量{{ mgoods.sales }}{{mgoods.unitName}}</text> <text class="original" v-if="mgoods.salesTip">
销量 {{mgoods.salesTip}}
</text>
<text class="original" v-else>
销量{{ mgoods.sales }}{{mgoods.unitName}}
</text>
</view> </view>
</view> </view>
<view class="title"> <view class="title">
@ -89,6 +94,23 @@
query, query,
}); });
}, },
routerGo(item) {
if (item.goodSign) {
this.$yrouter.push({
path: '/pages/goods/goodDetail',
query: {
goodSign: item.goodSign
},
})
} else {
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.id
},
})
}
},
} }
} }
</script> </script>

103
pages/map/index.vue

@ -1,57 +1,82 @@
<template> <template>
<map <map id="map" :longitude="map.longitude" :latitude="map.latitude" :markers="mapConfig" scale="12" show-location
id="map" @regionchange="test" style="width: 100%; height: 100%;"></map>
:longitude="map.longitude"
:latitude="map.latitude"
:markers="mapConfig"
scale="15"
show-location
style="width: 100%; height: 100%;"
></map>
</template> </template>
<script> <script>
export default { import {
getFishIndex,
getFishPlaceInfo
} from '@/api/fish'
export default {
name: "Index", name: "Index",
components: {}, components: {},
props: {}, props: {},
data: function() { data: function() {
return { return {
mapConfig: { mapConfig: [],
latitude: "",
longitude: "",
name: "",
address: ""
},
map: { map: {
latitude: "", latitude: 30.579150542191858,
longitude: "" longitude: 114.31590683471099
} },
}; };
}, },
onShow: function() { onShow: function() {
this.map = {
latitude: this.$yroute.query.latitude, this._mapContext = uni.createMapContext("map", this);
longitude: this.$yroute.query.longitude this._mapContext.moveToLocation()
};
this.mapConfig = [{ let that = this;
id: 1,
width: 50, // uni.getLocation({
height: 50, // success(localtionRs) {
iconPath: this.$yroute.query.image, // that.refresh(localtionRs);
latitude: this.$yroute.query.latitude, // },
longitude: this.$yroute.query.longitude, // })
title: this.$yroute.query.name, },
name: this.$yroute.query.name, methods: {
address: this.$yroute.query.detailedAddress test(res) {
}]; console.log("res",res)
console.log(this.mapConfig); let that = this;
if (res.type == "end") {
console.log(this._mapContext)
this._mapContext.getCenterLocation({
success(res){
that.refresh(res)
}
})
}
},
refresh(location){
let that = this;
getFishIndex(location).then(res => {
console.log(res.data)
if (res.data) {
res.data.forEach(e => {
// ,marker
//
that.mapConfig.push({
alpha: .8,
height: 30,
width: 30,
id: e.id,
name: e.placeName,
latitude: Number(e.latitude),
longitude: Number(e.longitude),
iconPath: e.mode == 0 ? "/static/public_fish.png" :
"/static/business_fish.png"
})
})
}
})
}, },
methods: {} }
}; };
</script> </script>
<style lang="less"> <style lang="less">
page { page {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>

BIN
static/business_fish.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/point.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/public_fish.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Loading…
Cancel
Save