Browse Source

添加互动图

master
xh-pan1 5 months ago
parent
commit
a36d48303f
  1. 12
      .gitignore
  2. 8
      components/canvasShow/config/mixin/funMixin.js
  3. 2
      config/api.js
  4. 6
      locale/en.json
  5. 5
      locale/zh-Hans.json
  6. 5
      pages.json
  7. 235
      pages_category_page1/goodsModule/components/InteractionDiagramImage.vue
  8. 187
      pages_category_page1/goodsModule/interactionDiagramDetail.vue

12
.gitignore

@ -9,17 +9,7 @@
*.njsproj
*.sln
*.hbuilderx
/unpackage/dist/dev
/unpackage/dist/static
/unpackage/dist/build/mp-alipay/
/unpackage/dist/build/mp-weixin/
/unpackage/dist/build/app-plus/
/unpackage/dist/build/.automator
/unpackage/cache/
/unpackage/cache/apk
/unpackage/release
/unpackage/res
/unpackage/resources
/unpackage
/node_modules
package-lock.json

8
components/canvasShow/config/mixin/funMixin.js

@ -38,6 +38,9 @@ export const tool = {
case '商品':
this.jumpProductDetail(linkObj.data)
break
case '互动图':
this.jumpInteractionDiagramDetail(linkObj.data)
break
case '自定义':
// router.push("/category");
case '公告':
@ -82,6 +85,11 @@ export const tool = {
.skuId
})
},
jumpInteractionDiagramDetail(item){
uni.navigateTo({
url: '/pages_category_page1/goodsModule/interactionDiagramDetail?interactionDiagramId=' + item.interactionDiagramId
})
},
// 跳转到秒杀专区
jumpSeckills(item){
if(item.shopId){

2
config/api.js

@ -171,6 +171,8 @@ module.exports = {
getProducts: WX_API_BASE + '/canvas/getProducts', // 选择商品查询
getProductsV2: WX_API_BASE + '/canvas/getProducts2', // 选择商品查询
//互动图
getInteractionDiagramDetail: WX_API_BASE + '/cereInteractionDiagram/getById', // 获取互动图详情
//服务协议
Query: WX_API_BASE + '/dict/getByName', // 查询分类层级

6
locale/en.json

@ -629,6 +629,10 @@
"user.myserver": "My Service",
"user.otherserver": "Other Service",
"user.growthvalue": "Growth Value",
"common.refund_only":"Refund only",
"common.refunds_and_returns":"Refunds and Returns"
"common.refunds_and_returns":"Refunds and Returns",
"page.interactiondiagramdetail":"InteractionDiagramDetail"
}

5
locale/zh-Hans.json

@ -629,6 +629,9 @@
"user.myserver": "我的服务",
"user.otherserver": "其他服务",
"user.growthvalue": "成长值",
"common.refund_only":"仅退款",
"common.refunds_and_returns":"退款退货"
"common.refunds_and_returns":"退款退货",
"page.interactiondiagramdetail":"互动图详情"
}

5
pages.json

@ -159,6 +159,11 @@
"navigationBarTitleText": "%page.goodsdetail%"
}
}, {
"path": "goodsModule/interactionDiagramDetail",
"style": {
"navigationBarTitleText": "%page.interactiondiagramdetail%"
}
},{
"path": "goodsModule/qADetail",
"style": {
"navigationBarTitleText": "%page.qadetail%"

235
pages_category_page1/goodsModule/components/InteractionDiagramImage.vue

@ -0,0 +1,235 @@
<template>
<div class="mainContent">
<div class="canvasContent" ref="canvasContent" :style="{ width: `${canvasWidth}rpx`, height: `${canvasHeight}rpx` }"
v-if="interactionDiagramDetailData.interactionDiagramImage">
<img class="img-bg" ref="canvasBgContent" :src="interactionDiagramDetailData.interactionDiagramImage" />
<div class="drap-container-item" v-for="(point, index) in pointList" :key="index"
:style="{ top: `${canvasHeight * point.pointY}rpx`, left: `${canvasWidth * point.pointX}rpx` }"
@click="handleClick(point, index)">
<div :class="showPoint == point ? 'point_source_active' : 'point_source'" />
<div class="product-detail" @click="toProductDetail" v-if="showPoint == point && (point.product && point.product.productName)">
<div class="product-name">{{ (point.product && point.product.productName) ? point.product.productName : '' }}</div>
<div class="product-price">{{ (point.product && point.product.price) ? point.product.price : '' }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
interactionDiagramDetailData:{},
showPoint: {},
pointList: [],
canvasWidth: 0,
canvasHeight: 0
}
},
methods: {
toProductDetail () {
this.$emit('clickProductDetail', {
productId: this.productData.productId
})
},
//
handleClick(row, index) {
console.log("handleClick");
if(this.showPoint == row){
this.showPoint = null
}else{
this.showPoint = row
}
},
setParams (data, pointList) {
this.interactionDiagramDetailData = data
this.pointList = pointList
const position = {
height: 750,
width: 750
}
//
var naturalWidth = this.interactionDiagramDetailData.imageWidth;
var naturalHeight = this.interactionDiagramDetailData.imageHeight;
//
var showWidth = position.width;
var showHeight = naturalHeight * showWidth / naturalWidth;
this.canvasWidth = showWidth;
this.canvasHeight = showHeight;
}
}
}
</script>
<style lang="scss" scoped>
.point_source_active{
align-items: center;
background: hsla(0,0%,47%,.5);
border: 3rpx solid transparent;
border-radius: 50%;
display: flex;
height: 48rpx;
justify-content: center;
opacity: 1;
padding: 0;
transition: border-color .25s ease-in-out,opacity .25s ease-in-out,visibility .25s ease-in-out;
width: 48rpx;
&:after {
background: #fff;
border-radius: 50%;
box-shadow: 0 1rpx 4rpx #0000008c;
content: "";
display: block;
height: 18rpx;
position: relative;
transition: transform .25s ease-in-out;
width: 18rpx;
transform: scale(.667);
}
}
.point_source {
align-items: center;
background: hsla(0,0%,47%,.5);
border: 3rpx solid transparent;
border-radius: 50%;
display: flex;
height: 48rpx;
justify-content: center;
opacity: 1;
padding: 0;
transition: border-color .25s ease-in-out,opacity .25s ease-in-out,visibility .25s ease-in-out;
width: 48rpx;
&:after {
background: #fff;
border-radius: 50%;
box-shadow: 0 1px 4px #0000008c;
content: "";
display: block;
height: 18rpx;
position: relative;
transition: transform .25s ease-in-out;
width: 18rpx;
}
}
.mainContent {
margin: 0 auto;
width: 750rpx;
height: auto;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: flex-start;
align-items: flex-start;
.canvasContent {
width: 100%;
height: 100%;
position: relative;
.img-bg {
width: 100%;
height: 100%;
object-fit: contain;
}
.drap-container-item {
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
position: absolute;
user-select: none;
cursor: pointer;
border: 1px solid transparent;
.drap-item-img {
width: 40rpx;
height: 40rpx;
object-fit: contain;
}
.drap-item-name {
text-align: center;
}
.product-detail-top{
position: relative;
top: -100rpx;
}
.product-detail-bottom{
}
.product-detail-left{
position: relative;
left: -100rpx;
}
.product-detail-right{
}
.product-detail-centerv{
margin-top: -25%;
margin-bottom: 25%;
}
.product-detail-centerh{
margin-left: -25%;
margin-right: 25%;
}
.product-detail{
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: center;
align-items: flex-start;
background: white;
padding-left: 10rpx;
padding-right: 10rpx;
padding-top: 8rpx;
padding-bottom: 8rpx;
border-radius: 4rpx;
margin-left: -25%;
margin-right: 25%;
.product-name{
width: 100%;
height: auto;
font-size: 16rpx;
font-family: Source Han Sans CN;
font-weight: bold;
color: #252744;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 20px;
text-align: left;
}
.product-price{
width: auto;
height: 20rpx;
line-height: 20rpx;
font-size: 14rpx;
font-family: Source Han Sans CN;
font-weight: bold;
color: #252744;
}
}
}
.drap-container-item-active {
border: 1rpx solid skyblue;
}
}
}
</style>

187
pages_category_page1/goodsModule/interactionDiagramDetail.vue

@ -0,0 +1,187 @@
<template>
<view>
<global-loading/>
<div class="interactionDiagramPage">
<div class="top">
<!-- 互动图 -->
<InteractionDiagramImage
ref="interactionDiagramImage"
@clickProductDetail="clickProductDetail"
>
</InteractionDiagramImage>
</div>
<div class="bottom">
<!-- 商品信息列表 -->
<div class="productList">
<div class="product-detail" @click="clickProductDetail(point)" v-for="(point, index) in showPointList"
:key="index">
<div class="image-container">
<img class="product-image" v-if="point.product.image" :src="point.product.image" />
</div>
<div class="product-info">
<div class="product-name">{{ (point.product && point.product.productName) ? point.product.productName : '' }}
</div>
<div class="product-price">{{ (point.product && point.product.price) ? point.product.price : '' }}</div>
</div>
</div>
</div>
</div>
</div>
</view>
</template>
<script>
const NET = require('../../utils/request')
const API = require('../../config/api')
import InteractionDiagramImage from './components/InteractionDiagramImage.vue'
export default {
name: 'interactionDiagramDetail',
components: {
InteractionDiagramImage
},
data() {
return {
interactionDiagramDetailData: {},
pointList: [],
showPointList: []
}
},
created() {
this.interactionDiagramId = JSON.parse(this.$route.query.interactionDiagramId)
this.getInteractionDiagramDetail()
},
methods: {
//
async getInteractionDiagramDetail() {
const response = await NET.request(API.getInteractionDiagramDetail, {
interactionDiagramId: this.interactionDiagramId
}, 'GET')
const res = response
this.interactionDiagramDetailData = res.data
if (this.interactionDiagramDetailData.pointData) {
this.pointList = JSON.parse(this.interactionDiagramDetailData.pointData);
}
this.showPointList = this.pointList.filter(item => item.product)
let productIdList = this.showPointList.map(item => item.product.productId)
const getProductsResponse = await NET.request(API.getProducts, {
ids: productIdList,
page: 1,
pageSize: productIdList.length
}, 'GET')
let productList = getProductsResponse.data.list
if (productList) {
this.pointList.forEach(item => {
if (item.product) {
let newProduct = productList.find(newItem => newItem.productId == item.product.productId)
if (newProduct) {
item.product = newProduct
}
}
})
}
this.$refs.interactionDiagramImage.setParams(this.interactionDiagramDetailData, this.pointList)
},
clickProductDetail(prointData) {
if (prointData.product) {
uni.navigateTo({
url: '/pages_category_page1/goodsModule/goodsDetails?shopId=' + prointData.product.shopId
+ '&productId=' + prointData.product.productId
+ '&skuId=' + prointData.product.skuId
})
}
}
}
}
</script>
<style lang="scss" scoped>
.interactionDiagramPage {
background-color: #F5F5F5;
padding: 0 0 20px 0;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: flex-start;
align-items: flex-start;
height: 100%;
.top {
margin-bottom: 5px;
}
.bottom {
margin-top: 5px;
flex: 1;
overflow-y: auto;
.productList {
.product-detail {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: flex-start;
align-items: flex-start;
margin-bottom: 15px;
.image-container {
width: 80px;
height: 80px;
.product-image {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.product-info {
margin-left: 8px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: flex-start;
align-items: flex-start;
}
.product-name {
width: 100%;
height: auto;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: bold;
color: #252744;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 20px;
text-align: left;
}
.product-price {
width: auto;
height: 20px;
line-height: 20px;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: bold;
color: #252744;
margin-top: 6px;
}
}
}
}
}
</style>
Loading…
Cancel
Save