Merge branch 'dev' of http://47.109.205.240:3000/Web/daimp-front into dev
This commit is contained in:
commit
4f271fcb1d
@ -26,6 +26,29 @@ export function getGoodDetail(id, params) {
|
||||
});
|
||||
}
|
||||
|
||||
// 获取购物车商品数量
|
||||
export function getGoodNum(params) {
|
||||
return request('user-center/shoppingCart/getShopCartGoodsCount', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
// 商品加入购物车
|
||||
export function addToCart(params) {
|
||||
return request('/user-center/shoppingCart/addToCart', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 立即购买商品按钮
|
||||
export function quicklyBuy(data = {}) {
|
||||
return request('goods/goodInfoManage/contentPage', {
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户评价列表
|
||||
export function agriculturalContent(data = {}) {
|
||||
return request('goods/goodInfoManage/contentPage', {
|
||||
|
BIN
sub-operation-service/src/assets/images/basic/QRCodeYYY.png
Normal file
BIN
sub-operation-service/src/assets/images/basic/QRCodeYYY.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
BIN
sub-operation-service/src/assets/images/basic/QRCodeZWY.png
Normal file
BIN
sub-operation-service/src/assets/images/basic/QRCodeZWY.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
BIN
sub-operation-service/src/assets/images/logo1.png
Normal file
BIN
sub-operation-service/src/assets/images/logo1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
100
sub-operation-service/src/components/breadComp.vue
Normal file
100
sub-operation-service/src/components/breadComp.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 保留原有 el-breadcrumb 的 class 和 separator-icon -->
|
||||
<el-breadcrumb :separator-icon="ArrowRight" class="breadcrumb">
|
||||
<!-- 保留原有 el-breadcrumb-item 的 class 结构 -->
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in breadcrumbs"
|
||||
:key="index"
|
||||
:class="['breadcrumb-item', { 'last-item': index === breadcrumbs.length - 1 }]"
|
||||
class="breadcrumb-item"
|
||||
@click="handleBreadcrumbClick(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { ArrowRight } from '@element-plus/icons-vue';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const breadcrumbs = ref([]);
|
||||
|
||||
// 自定义点击处理(保留参数的核心)
|
||||
const handleBreadcrumbClick = (item) => {
|
||||
// 关键点:使用完整路径(包含params和query)
|
||||
router.push(item.fullPath || item.path);
|
||||
};
|
||||
|
||||
watch(
|
||||
route,
|
||||
(newRoute) => {
|
||||
breadcrumbs.value = newRoute.matched
|
||||
.filter((item) => !item.meta?.hideInBread)
|
||||
.map((item) => {
|
||||
// 精准解析路径(兼容name和path两种形式)
|
||||
const resolved = item.name
|
||||
? router.resolve({
|
||||
name: item.name,
|
||||
params: newRoute.params,
|
||||
query: newRoute.query,
|
||||
})
|
||||
: router.resolve({
|
||||
path: item.path,
|
||||
params: newRoute.params,
|
||||
query: newRoute.query,
|
||||
});
|
||||
|
||||
return {
|
||||
title: item.meta?.title || item.name,
|
||||
path: item.path, // 基础路径
|
||||
fullPath: resolved.href, // 完整路径(含参数)
|
||||
meta: item.meta,
|
||||
};
|
||||
});
|
||||
|
||||
// 保留原有sessionStorage逻辑
|
||||
window.sessionStorage.setItem('currentChild', newRoute.name);
|
||||
if (newRoute.name === 'main' || newRoute.name === 'smartFarmMain') {
|
||||
window.sessionStorage.setItem('currentOpen', '0');
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 完全保留原有样式 */
|
||||
.breadcrumb {
|
||||
padding: 0 10px 10px 10px;
|
||||
font-size: 14px;
|
||||
/* 保留hover效果 */
|
||||
:deep(.el-breadcrumb__inner:not(.last-item):hover) {
|
||||
color: var(--el-color-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 保留面包屑项的样式 */
|
||||
:deep(.breadcrumb-item) {
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
:deep(.el-breadcrumb__inner) {
|
||||
font-weight: bold;
|
||||
}
|
||||
:deep(.last-item .el-breadcrumb__inner) {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
:deep(.last-item .el-breadcrumb__inner:hover) {
|
||||
color: var(--el-text-color-regular);
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -53,7 +53,6 @@ watch(
|
||||
imgUrl.value = props.url;
|
||||
isViewVal.value = props.isView;
|
||||
srcList = props.previewList;
|
||||
console.log('getAssetsFile', getAssetsFile(imgUrl));
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
|
@ -14,10 +14,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-header-top-right">
|
||||
<el-badge :hidden="goodNum < 1" :value="goodNum" :max="99" class="item" :offset="[-3, 10]">
|
||||
<span class="block-icon" @click="toCart">
|
||||
<div class="iconfont icon-shopcar" style="font-size: 12px"></div>
|
||||
<span>购物车</span>
|
||||
</span>
|
||||
</el-badge>
|
||||
<span>商家中心</span>
|
||||
<span @click="toUserCenter">个人中心</span>
|
||||
<span class="block-icon" @click="toHome">
|
||||
@ -30,7 +32,7 @@
|
||||
<div class="layout-header-bottom-left">
|
||||
<div class="layout-header-bottom-search">
|
||||
<div class="title">
|
||||
<img :src="getAssetsFile('images/logo.png')" />
|
||||
<img :src="getAssetsFile('images/logo1.png')" />
|
||||
</div>
|
||||
<div class="search-warp">
|
||||
<el-input v-model="keyword" placeholder="请输入关键词进行搜索"></el-input>
|
||||
@ -41,12 +43,12 @@
|
||||
<div class="layout-header-bottom-right">
|
||||
<div class="layout-header-bottom-right-qr">
|
||||
<div class="layout-header-bottom-right-qr-img">
|
||||
<img :src="qrImg" alt="" />
|
||||
<p>下载数农App</p>
|
||||
<img :src="getAssetsFile('images/basic/QRCodeZWY.png')" alt="" />
|
||||
<p>政务云App</p>
|
||||
</div>
|
||||
<div class="layout-header-bottom-right-qr-img">
|
||||
<img :src="qrImg" alt="" />
|
||||
<p>打开数农小程序</p>
|
||||
<img :src="getAssetsFile('images/basic/QRCodeYYY.png')" alt="" />
|
||||
<p>运营云APP</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -63,11 +65,13 @@
|
||||
</template>
|
||||
|
||||
<script setup name="layout-header">
|
||||
import { ref } from 'vue';
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||
import { qrImg } from './base64img';
|
||||
import AppLink from '../Menu/Link.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { getAssetsFile } from '@/utils';
|
||||
import { getGoodNum } from '@/apis/agricultural.js';
|
||||
import { useMethodsStore } from '@/store/modules/methods';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@ -105,6 +109,26 @@ const meuns = ref([
|
||||
},
|
||||
]);
|
||||
|
||||
const goodNum = ref(0);
|
||||
|
||||
const methodsStore = useMethodsStore();
|
||||
|
||||
const getGoods = () => {
|
||||
getGoodNum().then((res) => {
|
||||
goodNum.value = res.data ? res.data : 0;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getGoods();
|
||||
methodsStore.registerOuterMethod(getGoods);
|
||||
});
|
||||
|
||||
// 组件卸载时清除方法
|
||||
onBeforeUnmount(() => {
|
||||
methodsStore.registerOuterMethod(null);
|
||||
});
|
||||
|
||||
function Search() {
|
||||
console.log(keyword.value, 'search');
|
||||
}
|
||||
@ -235,26 +259,34 @@ const toCart = () => {
|
||||
.title {
|
||||
font-size: 45px;
|
||||
white-space: nowrap;
|
||||
img {
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
.search-warp {
|
||||
position: relative;
|
||||
padding-left: 36px;
|
||||
width: 80%;
|
||||
.el-input {
|
||||
width: 50%;
|
||||
width: 76%;
|
||||
height: 50px;
|
||||
font-size: 18px;
|
||||
flex-grow: 1;
|
||||
border-radius: 14px;
|
||||
:deep(.el-input__wrapper) {
|
||||
padding-right: 100px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgb(49, 202, 141);
|
||||
box-shadow: none !important; /* 移除默认的阴影边框 */
|
||||
}
|
||||
}
|
||||
.el-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 25%;
|
||||
right: 11.8%;
|
||||
border-radius: 12px;
|
||||
padding: 0 24px;
|
||||
height: 42px;
|
||||
height: 43px;
|
||||
font-size: 18px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
@ -297,4 +329,7 @@ const toCart = () => {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
.layout-header-bottom-right {
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -383,29 +383,36 @@ export const constantRoutes = [
|
||||
meta: { title: '电商交易' },
|
||||
children: [
|
||||
{
|
||||
path: '/ecommerce',
|
||||
path: '/sub-operation-service/ecommerce-agricultural',
|
||||
component: Views,
|
||||
redirect: '/sub-operation-service/ecommerce-agricultural',
|
||||
name: 'agriculturalParent',
|
||||
name: 'agricultural',
|
||||
meta: { title: '农资交易', headerActive: 'ecommerce' },
|
||||
children: [
|
||||
{
|
||||
path: '/sub-operation-service/ecommerce-agricultural',
|
||||
path: '',
|
||||
component: () => import('@/views/ecommerce/index.vue'),
|
||||
name: 'agricultural',
|
||||
meta: { title: '农资交易', headerActive: 'ecommerce' },
|
||||
name: 'agriculturalMain',
|
||||
meta: { title: '农资交易', headerActive: 'ecommerce', hideInBread: true },
|
||||
},
|
||||
{
|
||||
path: '/sub-operation-service/ecommerce-agriculturalDetail',
|
||||
path: 'ecommerce-agriculturalDetail',
|
||||
component: Views,
|
||||
name: 'agriculturalDetails',
|
||||
meta: { title: '农资详情', headerActive: 'ecommerce' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/ecommerce/agriculturalDetail.vue'),
|
||||
name: 'agriculturalDetail',
|
||||
meta: { title: '农资详情', headerActive: 'ecommerce' },
|
||||
meta: { title: '农资详情', headerActive: 'ecommerce', hideInBread: true },
|
||||
},
|
||||
{
|
||||
path: '/sub-operation-service/ecommerce-sourceCodeDetail',
|
||||
path: 'source',
|
||||
component: () => import('@/views/ecommerce/sourceCodeDetail.vue'),
|
||||
name: 'sourceCodeDetail',
|
||||
meta: { title: '溯源详情', headerActive: 'ecommerce' },
|
||||
meta: { title: '农产品溯源详情', headerActive: 'ecommerce' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -430,12 +437,39 @@ export const constantRoutes = [
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/sub-operation-service/ecommerce-supplier',
|
||||
component: () => import('@/views/ecommerce/supplier.vue'),
|
||||
component: Views,
|
||||
name: 'supplier',
|
||||
meta: { title: '供应商服务', headerActive: 'ecommerce' },
|
||||
meta: { title: '农产品交易', headerActive: 'ecommerce' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/ecommerce/supplier.vue'),
|
||||
name: 'supplierMain',
|
||||
meta: { title: '农产品交易', headerActive: 'ecommerce', hideInBread: true },
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: Views,
|
||||
name: 'supplierDetails',
|
||||
meta: { title: '农产品详情', headerActive: 'ecommerce' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/ecommerce/supplierDetail.vue'),
|
||||
name: 'supplierDetail',
|
||||
meta: { title: '农产品详情', headerActive: 'ecommerce', hideInBread: true },
|
||||
},
|
||||
{
|
||||
path: 'source',
|
||||
component: () => import('@/views/ecommerce/sourceCodeDetail.vue'),
|
||||
name: 'sourceDetail',
|
||||
meta: { title: '溯源详情', headerActive: 'ecommerce' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/sub-operation-service/ecommerce-land',
|
||||
|
21
sub-operation-service/src/store/modules/methods.js
Normal file
21
sub-operation-service/src/store/modules/methods.js
Normal file
@ -0,0 +1,21 @@
|
||||
// store/methodsStore.js
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useMethodsStore = defineStore('methods', {
|
||||
state: () => ({
|
||||
outerMethod: null, // 存储外层组件的方法
|
||||
}),
|
||||
actions: {
|
||||
// 注册外层组件的方法
|
||||
registerOuterMethod(method) {
|
||||
this.outerMethod = method;
|
||||
},
|
||||
// 调用外层组件的方法
|
||||
callOuterMethod(...args) {
|
||||
if (this.outerMethod && typeof this.outerMethod === 'function') {
|
||||
return this.outerMethod(...args);
|
||||
}
|
||||
console.warn('外层方法未注册');
|
||||
},
|
||||
},
|
||||
});
|
@ -3,13 +3,6 @@
|
||||
<common current-name="agricultural">
|
||||
<template #main>
|
||||
<div class="agricultural-detail-info">
|
||||
<div class="top-title">
|
||||
<div class="father-title" @click="toBack(-1)">
|
||||
<el-icon><ArrowLeftBold /></el-icon>商品信息
|
||||
</div>
|
||||
<div class="current-title">查看详情</div>
|
||||
</div>
|
||||
|
||||
<div class="top-info">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
@ -64,10 +57,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-btn">
|
||||
<div class="item-btn sign">
|
||||
<div class="item-btn sign" @click="buyGood">
|
||||
<span>立即购买</span>
|
||||
</div>
|
||||
<div class="item-btn reservation">
|
||||
<div class="item-btn reservation" @click="addGoodToCart">
|
||||
<span>加入购物车</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -148,6 +141,11 @@ import { qrImg } from '@/layouts/component/Header/base64img.js';
|
||||
import evaluate from './components/evaluate.vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { getGoodDetail } from '@/apis/agricultural.js';
|
||||
import { addToCart, quicklyBuy } from '../../apis/agricultural.js';
|
||||
import { useMethodsStore } from '@/store/modules/methods';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const methodsStore = useMethodsStore();
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@ -331,11 +329,17 @@ let saveInfo = reactive({
|
||||
onMounted(() => {
|
||||
showDetail.value = false;
|
||||
// const num = Number(pId);
|
||||
getGoodDetail(goodId).then(async (res) => {
|
||||
getGoodDetail(goodId)
|
||||
.then(async (res) => {
|
||||
if (res.code === 200) {
|
||||
currentGood.value = res.data;
|
||||
// 数据转义
|
||||
await formattedData(res.data);
|
||||
showDetail.value = true;
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
// if (num === 55) {
|
||||
// // 1. 获取前四个元素的索引(0, 1, 2, 3)
|
||||
@ -388,22 +392,42 @@ const formattedData = (data) => {
|
||||
currentGood.value.attribute = Object.entries(data.attribute).map(([key, value]) => ({ key, value }));
|
||||
}
|
||||
if (currentGood.value.detailUrl) {
|
||||
currentGood.value.detailUrl = currentGood.value.detailUrl.replace(/'/g, '"');
|
||||
currentGood.value.detailUrl = JSON.parse(currentGood.value.detailUrl);
|
||||
currentGood.value.detailUrl = currentGood.value.detailUrl.split(',');
|
||||
}
|
||||
currentGood.value.goodUrls = data.goodUrl.split(',');
|
||||
console.log(currentGood.value);
|
||||
};
|
||||
|
||||
const toCodeDetail = () => {
|
||||
let id = '01';
|
||||
router.push('/sub-operation-service/ecommerce-sourceCodeDetail?id=' + id);
|
||||
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail/source?id=' + goodId);
|
||||
};
|
||||
|
||||
const toBack = (level) => {
|
||||
router.go(level);
|
||||
};
|
||||
|
||||
const buyGood = () => {
|
||||
const obj = {
|
||||
goodsId: goodId,
|
||||
weightId: currentGood.value.netWeight[currentWeight.value].id, // 规格ID
|
||||
quantity: saveInfo.num,
|
||||
};
|
||||
// quicklyBuy(obj).then((res) => {});
|
||||
};
|
||||
|
||||
const addGoodToCart = () => {
|
||||
const obj = {
|
||||
goodsId: goodId, // 商品ID
|
||||
weightId: currentGood.value.netWeight[currentWeight.value].id, // 规格ID
|
||||
quantity: saveInfo.num, // 数量,不填写默认是1
|
||||
};
|
||||
addToCart(obj).then((res) => {
|
||||
if (res.code === 200) {
|
||||
methodsStore.callOuterMethod();
|
||||
ElMessage.success('添加成功');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const toCopy = () => {};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@ -587,9 +611,17 @@ const toCopy = () => {};
|
||||
line-height: 42px;
|
||||
&.sign {
|
||||
background: $color-main;
|
||||
cursor: pointer;
|
||||
}
|
||||
&.sign:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); /* 添加阴影效果 */
|
||||
}
|
||||
&.reservation {
|
||||
background: $color-warning;
|
||||
cursor: pointer;
|
||||
}
|
||||
&.reservation:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); /* 添加阴影效果 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
</template>
|
||||
</div>
|
||||
<div class="common-content">
|
||||
<bread-comp></bread-comp>
|
||||
<slot v-if="$slots.main" name="main"></slot>
|
||||
<template v-else></template>
|
||||
</div>
|
||||
|
@ -1,5 +1,28 @@
|
||||
<template>
|
||||
<div class="filter-top-warp">
|
||||
<div style="width: 40%; margin-left: 10px">
|
||||
<div class="search-container">
|
||||
<div class="search-box">
|
||||
<input type="text" placeholder="请输入农资商品名称" class="search-input" />
|
||||
<button class="search-button">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(n, index) in maxLevelAndNodes.LevelKey" :key="index" class="filter-item">
|
||||
<div class="single-item">
|
||||
<div class="single-li all" :class="maxLevelAndNodes.LevelVal[n].id == '' ? 'li-act' : ''" @click="selectAll(n)">全部</div>
|
||||
@ -127,6 +150,10 @@ const selectAll = (key) => {
|
||||
const emit = defineEmits(['select']);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-input-group--append > .el-input__wrapper {
|
||||
border-top-left-radius: 16px !important;
|
||||
border-bottom-left-radius: 16px !important;
|
||||
}
|
||||
.filter-top-warp {
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
@ -162,4 +189,51 @@ const emit = defineEmits(['select']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 0 16px 0 0;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid black;
|
||||
border-radius: 14px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
outline: none;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 55%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.search-button:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
</style>
|
||||
|
@ -26,6 +26,10 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: () => 1,
|
||||
},
|
||||
});
|
||||
|
||||
const handleImageError = (e) => {
|
||||
@ -33,7 +37,11 @@ const handleImageError = (e) => {
|
||||
};
|
||||
|
||||
const toDetail = (id, pid) => {
|
||||
router.push('/sub-operation-service/ecommerce-agriculturalDetail?id=' + id + '&pid=' + pid);
|
||||
if (props.type === 2) {
|
||||
router.push('/sub-operation-service/ecommerce-supplier/detail?id=' + id + '&pid=' + pid);
|
||||
} else {
|
||||
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail?id=' + id + '&pid=' + pid);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@ -46,13 +54,11 @@ const toDetail = (id, pid) => {
|
||||
width: 100%;
|
||||
height: 168px;
|
||||
border-radius: 16px;
|
||||
::v-deep() {
|
||||
.el-image {
|
||||
:deep(.el-image) {
|
||||
width: 100%;
|
||||
height: 168px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.goods-name {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
|
@ -4,11 +4,6 @@
|
||||
<template #main>
|
||||
<div class="source-code-detail-info">
|
||||
<div class="top-warp-b">
|
||||
<div class="top-title">
|
||||
<div class="father-title" @click="toBack(-2)">农资交易</div>
|
||||
<div class="father-title father-after" @click="toBack(-1)">查看详情</div>
|
||||
<div class="current-title">溯源详情</div>
|
||||
</div>
|
||||
<div class="top-img-txt">
|
||||
<el-image :src="getAssetsFile('images/ecommerce/' + 'tracetxt.png')?.href ?? ''" fit="cover" />
|
||||
</div>
|
||||
@ -184,7 +179,7 @@
|
||||
</common>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="ecommerce">
|
||||
<script setup>
|
||||
import common from './components/common.vue';
|
||||
import { ref, reactive, onMounted, watch, computed } from 'vue';
|
||||
import { isEmpty, getAssetsFile } from '@/utils';
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="goods-list">
|
||||
<template v-for="(n, index) in list" :key="n.id">
|
||||
<div class="goods-item">
|
||||
<goodsItem :data="n"></goodsItem>
|
||||
<goodsItem :data="n" :type="2"></goodsItem>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@ -90,35 +90,11 @@ const handleCurrentChange = (val) => {
|
||||
getList();
|
||||
};
|
||||
|
||||
const sortTreeByDescendingId = (nodes) => {
|
||||
if (!nodes || !nodes.length) return [];
|
||||
|
||||
// 对当前层级节点排序(BigInt 安全比较)
|
||||
const sortedNodes = [...nodes].sort((a, b) => {
|
||||
const idA = BigInt(a.id);
|
||||
const idB = BigInt(b.id);
|
||||
return idA > idB ? -1 : idA < idB ? 1 : 0; // 降序
|
||||
});
|
||||
|
||||
// 递归排序每个节点的 children
|
||||
sortedNodes.forEach((node) => {
|
||||
if (node.children && node.children.length) {
|
||||
node.children = sortTreeByDescendingId(node.children);
|
||||
}
|
||||
});
|
||||
|
||||
return sortedNodes;
|
||||
};
|
||||
|
||||
const getTree = () => {
|
||||
transaction().then((res) => {
|
||||
if (res.code === 200) {
|
||||
// 2. 使用排序函数
|
||||
const sortedData = sortTreeByDescendingId(res.data);
|
||||
treeList.splice(0, treeList.length, ...sortedData);
|
||||
// let a = res.data.sort((a, b) => Number(b.id) - Number(a.id));
|
||||
// treeList.splice(0, treeList.length, ...a);
|
||||
// console.log('treeList', treeList);
|
||||
let a = res.data.sort((a, b) => Number(b.id) - Number(a.id));
|
||||
treeList.splice(0, treeList.length, ...a);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
692
sub-operation-service/src/views/ecommerce/supplierDetail.vue
Normal file
692
sub-operation-service/src/views/ecommerce/supplierDetail.vue
Normal file
@ -0,0 +1,692 @@
|
||||
<template>
|
||||
<div class="agricultural-detail-warp">
|
||||
<common current-name="agricultural">
|
||||
<template #main>
|
||||
<div class="agricultural-detail-info">
|
||||
<div class="top-info">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<banner
|
||||
v-if="currentGood.goodUrls.length > 0"
|
||||
name="landdetail"
|
||||
:imglist="currentGood.goodUrls"
|
||||
:is-montage="false"
|
||||
indicator-pos="none"
|
||||
arrow="always"
|
||||
height="340px"
|
||||
:is-view="true"
|
||||
>
|
||||
</banner>
|
||||
</el-col>
|
||||
<el-col :span="12" class="top-info-txt">
|
||||
<h1 class="title">{{ currentGood.goodName }}</h1>
|
||||
<div class="price-sold">
|
||||
<span class="price">{{ currentPrice }}</span>
|
||||
<span class="sold">{{ currentGood.salesVolume }}</span>
|
||||
</div>
|
||||
<div class="tips-list">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">发货地址:{{ currentGood.detailAddress }}</el-col>
|
||||
<el-col :span="24"
|
||||
>保 障:{{
|
||||
currentGood.safeguard ? currentGood.safeguard.options[0].text : ''
|
||||
}}</el-col
|
||||
>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="spu-sku-list">
|
||||
<div class="spu-title">规格:</div>
|
||||
<div class="spu-sku-warp">
|
||||
<div
|
||||
v-for="(item, index) in currentGood.netWeight"
|
||||
:key="index"
|
||||
class="spu-sku-item"
|
||||
:class="[index === currentWeight ? 'act' : 'normal']"
|
||||
@click="currentWeight = index"
|
||||
>
|
||||
{{ item.goodSpecs }}{{ item.unit }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-num">
|
||||
<div class="num-title">数量:</div>
|
||||
<div class="num-warp">
|
||||
<el-input-number v-model="saveInfo.num" :min="1" :max="10" />
|
||||
<span v-if="currentStock !== 0" class="is-have">有货: {{ currentStock }}</span>
|
||||
<span v-else class="is-have">售罄</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-btn">
|
||||
<div class="item-btn sign">
|
||||
<span>立即购买</span>
|
||||
</div>
|
||||
<div class="item-btn reservation">
|
||||
<span>加入购物车</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<signProcess></signProcess>
|
||||
</div>
|
||||
|
||||
<div class="agricultural-detail-content">
|
||||
<div class="detail-content">
|
||||
<div class="tab-top">
|
||||
<el-radio-group v-model="tabVal">
|
||||
<el-radio-button v-for="(t, indext) in tabList" :key="t.name" :value="t.value">{{ t.label }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<div class="tab-content">
|
||||
<div v-if="tabVal === 'detail'" class="content-detail">
|
||||
<div v-if="showDetail" style="display: flex; justify-content: center">
|
||||
<el-descriptions class="detail-des" title=" " :column="2" size="large" border>
|
||||
<el-descriptions-item v-for="item in currentGood.attribute" :key="item.key">
|
||||
<template #label>
|
||||
<div class="cell-item">{{ item.value.name }}</div>
|
||||
</template>
|
||||
<span>{{ item.value.value }}</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: center; flex-wrap: wrap">
|
||||
<el-image
|
||||
v-for="(item, index) in currentGood.detailUrl"
|
||||
:key="index"
|
||||
:src="item"
|
||||
style="width: 90%; margin: 5px 0"
|
||||
fit="contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tabVal == 'sourceCode'" class="content-source-code">
|
||||
<div class="code-warp">
|
||||
<div class="code-img">
|
||||
<el-image :src="qrImg" fit="cover" />
|
||||
</div>
|
||||
<div class="code-down">
|
||||
<el-icon><Download /></el-icon>
|
||||
<a>下载溯源码</a>
|
||||
</div>
|
||||
<div class="code-copy">
|
||||
<div class="code-txt">
|
||||
<span class="txt-ellipsis clamp1" style="width: 100%">10.5488754215478XE254.10405488754215478XE254201</span>
|
||||
</div>
|
||||
<div class="do-copy">
|
||||
<el-button type="primary" @click="toCopy">复制</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-to-detail">
|
||||
<el-button type="primary" @click="toCodeDetail">点击查看溯源详情</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tabVal == 'evaluate'" class="content-evaluate">
|
||||
<evaluate :good-id="goodId" :good-url="currentGood.goodUrls[0]"></evaluate>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</common>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="ecommerce">
|
||||
import common from './components/common.vue';
|
||||
import banner from './components/banner.vue';
|
||||
import { onMounted, reactive, ref, computed } from 'vue';
|
||||
import { getAssetsFile } from '@/utils';
|
||||
import { qrImg } from '@/layouts/component/Header/base64img.js';
|
||||
import evaluate from './components/evaluate.vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { getGoodDetail } from '@/apis/agricultural.js';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const goodId = route.query.id; // 获取参数
|
||||
const pId = route.query.pid;
|
||||
const currentWeight = ref(0);
|
||||
|
||||
let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner.png']);
|
||||
const tabList = reactive([
|
||||
{ label: '详情介绍', value: 'detail' },
|
||||
{ label: '溯源码', value: 'sourceCode' },
|
||||
{ label: '评价', value: 'evaluate' },
|
||||
]);
|
||||
|
||||
const currentIndex = ref(0);
|
||||
const showDetail = ref(true);
|
||||
|
||||
const currentGood = ref({
|
||||
showPic: false,
|
||||
goodUrls: [],
|
||||
attribute: [],
|
||||
});
|
||||
|
||||
const currentPrice = computed(() => {
|
||||
return currentGood.value?.netWeight?.[currentWeight.value]?.goodPrice ?? 0;
|
||||
});
|
||||
|
||||
const currentStock = computed(() => {
|
||||
return currentGood.value?.netWeight?.[currentWeight.value]?.goodStock ?? 0;
|
||||
});
|
||||
|
||||
const mockData = [
|
||||
{
|
||||
goodName: '甜糯玉米种子',
|
||||
sold: 1200,
|
||||
price: 25,
|
||||
sendAddress: '河南信阳',
|
||||
safeguard: '七天保价',
|
||||
weight: ['100g', '200g'],
|
||||
goodUrl: ['images/mockPic/cornTop.png'],
|
||||
detailUrl: ['cornBottom1.png', 'cornBottom2.png', 'cornBottom3.png', 'cornBottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '张塘王豇豆种子种籽',
|
||||
sold: 1200,
|
||||
price: 4.35,
|
||||
sendAddress: '山东潍坊',
|
||||
safeguard: '七天保价',
|
||||
weight: ['100粒', '200粒'],
|
||||
goodUrl: ['images/mockPic/beanTop.png'],
|
||||
detailUrl: ['beanBottom1.png', 'beanBottom2.png', 'beanBottom3.png', 'beanBottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '茄子种子种籽',
|
||||
sold: 1200,
|
||||
price: 3.92,
|
||||
sendAddress: '山东潍坊',
|
||||
safeguard: '七天保价',
|
||||
weight: ['100粒', '200粒'],
|
||||
goodUrl: ['images/mockPic/eggplantTop.png'],
|
||||
detailUrl: ['eggplantBottom1.png', 'eggplantBottom2.png', 'eggplantBottom3.png', 'eggplantBottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '正宗绿贝贝南瓜种籽',
|
||||
sold: 1200,
|
||||
price: 6.8,
|
||||
sendAddress: '安徽马鞍山',
|
||||
safeguard: '七天保价',
|
||||
weight: ['10粒', '20粒'],
|
||||
goodUrl: ['images/mockPic/pumpkinTop.png'],
|
||||
detailUrl: ['pumpkinBottom1.png', 'pumpkinBottom2.png', 'pumpkinBottom3.png', 'pumpkinBottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '复合肥料18-5-7',
|
||||
sold: 1200,
|
||||
price: 154,
|
||||
sendAddress: '浙江金华',
|
||||
safeguard: '七天保价',
|
||||
weight: ['25kg', '50kg'],
|
||||
goodUrl: ['images/mockPic/fertilizerTop.png'],
|
||||
detailUrl: ['fertilizerBottom1.png', 'fertilizerBottom2.png'],
|
||||
},
|
||||
{
|
||||
goodName: '正宗硫酸钾 农用钾肥',
|
||||
sold: 1200,
|
||||
price: 13.5,
|
||||
sendAddress: '内蒙古',
|
||||
safeguard: '七天保价',
|
||||
weight: ['5斤', '10斤'],
|
||||
goodUrl: ['images/mockPic/KSO4Top.png'],
|
||||
detailUrl: ['KSO4Bottom1.png', 'KSO4Bottom2.png', 'KSO4Bottom3.png', 'KSO4Bottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '噻虫嗪农药',
|
||||
sold: 1200,
|
||||
price: 8.6,
|
||||
sendAddress: '内蒙古',
|
||||
safeguard: '七天保价',
|
||||
weight: ['500g'],
|
||||
goodUrl: ['images/mockPic/pesticideTop.png'],
|
||||
detailUrl: ['pesticideBottom1.png', 'pesticideBottom2.png', 'pesticideBottom3.png', 'pesticideBottom4.png', 'pesticideBottom5.png'],
|
||||
},
|
||||
{
|
||||
goodName: '11.6%甲维氯笨氣虫苯甲铣胺酰胺笨甲先胺水稻钻心虫农药杀虫剂',
|
||||
sold: 1200,
|
||||
price: 35.6,
|
||||
sendAddress: '山东烟台',
|
||||
safeguard: '七天保价',
|
||||
weight: ['500g', '1000g'],
|
||||
goodUrl: ['images/mockPic/nyTop.png'],
|
||||
detailUrl: ['nyBottom1.png', 'nyBottom2.png', 'nyBottom3.png', 'nyBottom4.png'],
|
||||
},
|
||||
{
|
||||
goodName: '铁皮石斛种子',
|
||||
sold: 13,
|
||||
price: '80/g',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['1g', '2g', '5g', '10g'],
|
||||
goodUrl: ['images/mockPic/shihuTop.png'],
|
||||
detailUrl: ['shihuBottom0.png', 'shihuBottom1.png', 'shihuBottom2.png', 'shihuBottom3.png'],
|
||||
},
|
||||
{
|
||||
goodName: '黑皮甘蔗苗',
|
||||
sold: 1400,
|
||||
price: '0.7/株',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['10株', '50株', '200株', '500株'],
|
||||
goodUrl: ['images/mockPic/ganzheTop.png'],
|
||||
detailUrl: ['ganzheBottom0.png', 'ganzheBottom1.png', 'ganzheBottom2.png', 'ganzheBottom3.png'],
|
||||
},
|
||||
{
|
||||
goodName: '美人椒种子 -辣椒种子',
|
||||
sold: 548,
|
||||
price: '43/斤',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['1斤', '2斤'],
|
||||
goodUrl: ['images/mockPic/chiliTop.png'],
|
||||
detailUrl: ['chiliBottom0.png', 'chiliBottom1.png', 'chiliBottom2.png', 'chiliBottom3.png'],
|
||||
},
|
||||
{
|
||||
goodName: '四季青种子',
|
||||
sold: 548,
|
||||
price: '19.5/包',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['1包(500-2000粒)', '2包', '4包'],
|
||||
goodUrl: ['images/mockPic/leafyTop.png'],
|
||||
detailUrl: ['leafyBottom0.png', 'leafyBottom1.png', 'leafyBottom2.png'],
|
||||
},
|
||||
{
|
||||
goodName: '青花菜种子',
|
||||
sold: 548,
|
||||
price: '10/包',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['1包(300-800粒)', '2包', '4包'],
|
||||
goodUrl: ['images/mockPic/broccoliTop.png'],
|
||||
detailUrl: ['broccoliBottom2.png', 'broccoliBottom1.png', 'broccoliBottom0.png'],
|
||||
},
|
||||
{
|
||||
goodName: '黑叶小白菜种子',
|
||||
sold: 82,
|
||||
price: '60/公斤',
|
||||
sendAddress: '耿马县',
|
||||
safeguard: '七天保价',
|
||||
weight: ['1公斤', '2公斤', '5公斤'],
|
||||
goodUrl: ['images/mockPic/choyTop.png'],
|
||||
detailUrl: ['choyBottom0.png', 'choyBottom1.png', 'choyBottom2.png', 'choyBottom3.png'],
|
||||
},
|
||||
];
|
||||
|
||||
let tabVal = ref('detail');
|
||||
|
||||
let saveInfo = reactive({
|
||||
num: 0,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
showDetail.value = false;
|
||||
// const num = Number(pId);
|
||||
getGoodDetail(goodId)
|
||||
.then(async (res) => {
|
||||
if (res.code === 200) {
|
||||
currentGood.value = res.data;
|
||||
// 数据转义
|
||||
await formattedData(res.data);
|
||||
showDetail.value = true;
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
// if (num === 55) {
|
||||
// // 1. 获取前四个元素的索引(0, 1, 2, 3)
|
||||
// const allIndices = [0, 1, 2, 3];
|
||||
// // 2. 随机打乱索引顺序
|
||||
// const shuffledIndices = [...allIndices].sort(() => Math.random() - 0.5);
|
||||
// // 3. 选择第一个
|
||||
// currentIndex.value = shuffledIndices.slice(0, 1)[0];
|
||||
// } else if (num === 61) {
|
||||
// // 1. 获取前四个元素的索引(0, 1, 2, 3)
|
||||
// const allIndices = [4, 5];
|
||||
// // 2. 随机打乱索引顺序
|
||||
// const shuffledIndices = [...allIndices].sort(() => Math.random() - 0.5);
|
||||
// // 3. 选择第一个
|
||||
// currentIndex.value = shuffledIndices.slice(0, 1)[0];
|
||||
// } else if (num === 65) {
|
||||
// // 1. 获取前四个元素的索引(0, 1, 2, 3)
|
||||
// const allIndices = [6, 7];
|
||||
// // 2. 随机打乱索引顺序
|
||||
// const shuffledIndices = [...allIndices].sort(() => Math.random() - 0.5);
|
||||
// // 3. 选择第一个
|
||||
// currentIndex.value = shuffledIndices.slice(0, 1)[0];
|
||||
// }
|
||||
// if (Number(goodId) === 2140012566 || Number(goodId) === 2140012569) {
|
||||
// getGoodDetail(Number(goodId)).then(async (res) => {
|
||||
// currentGood = res.data;
|
||||
// // 数据转义
|
||||
// await formattedData(res.data);
|
||||
// showDetail.value = true;
|
||||
// });
|
||||
// currentIndex.value = 8;
|
||||
// } else if (Number(goodId) === 2140012546 || Number(goodId) === 2140012547) {
|
||||
// currentIndex.value = 9;
|
||||
// } else if (Number(goodId) === 2140012562) {
|
||||
// currentIndex.value = 2;
|
||||
// } else if (Number(goodId) === 2140012563) {
|
||||
// currentIndex.value = 10;
|
||||
// } else if (Number(goodId) === 2140012586) {
|
||||
// currentIndex.value = 11;
|
||||
// } else if (Number(goodId) === 2140012587) {
|
||||
// currentIndex.value = 12;
|
||||
// } else if (Number(goodId) === 2140012588) {
|
||||
// currentIndex.value = 13;
|
||||
// }
|
||||
});
|
||||
|
||||
// 转义数据格式
|
||||
const formattedData = (data) => {
|
||||
if (currentGood.value.attribute) {
|
||||
currentGood.value.attribute = Object.entries(data.attribute).map(([key, value]) => ({ key, value }));
|
||||
}
|
||||
if (currentGood.value.detailUrl) {
|
||||
currentGood.value.detailUrl = currentGood.value.detailUrl.split(',');
|
||||
}
|
||||
currentGood.value.goodUrls = data.goodUrl.split(',');
|
||||
};
|
||||
|
||||
const toCodeDetail = () => {
|
||||
router.push('/sub-operation-service/ecommerce-supplier/detail/source?id=' + goodId);
|
||||
};
|
||||
|
||||
const toBack = (level) => {
|
||||
router.go(level);
|
||||
};
|
||||
|
||||
const toCopy = () => {};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.agricultural-detail-warp {
|
||||
width: 100%;
|
||||
.agricultural-detail-info {
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
padding: 10px 24px;
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
background: $color-fff;
|
||||
.top-title {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
.father-title,
|
||||
.current-title {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
.father-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
.current-title {
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
padding: 0 8px;
|
||||
font-size: 16px;
|
||||
color: $color-main;
|
||||
}
|
||||
.current-title::before {
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
left: 0;
|
||||
content: '.';
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
.top-info {
|
||||
margin: 16px 0;
|
||||
text-align: left;
|
||||
::v-deep() {
|
||||
.ecommerce-banner {
|
||||
position: relative;
|
||||
padding: 0 48px !important;
|
||||
}
|
||||
.el-carousel {
|
||||
position: unset !important;
|
||||
}
|
||||
.el-carousel__arrow--left {
|
||||
left: 0 !important;
|
||||
}
|
||||
.el-carousel__arrow--right {
|
||||
right: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.price-sold {
|
||||
margin: 16px 0;
|
||||
.price {
|
||||
position: relative;
|
||||
padding: 0 16px;
|
||||
font-size: 32px;
|
||||
color: $color-main;
|
||||
}
|
||||
.price::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
font-size: 16px;
|
||||
content: '¥';
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.sold {
|
||||
font-size: 16px;
|
||||
color: $color-999;
|
||||
}
|
||||
.sold::before {
|
||||
content: '已售';
|
||||
}
|
||||
}
|
||||
.tag-list {
|
||||
display: inline-flex;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
color: $color-999;
|
||||
gap: 10px;
|
||||
.tag-item {
|
||||
position: relative;
|
||||
padding-left: 32px;
|
||||
.iconfont {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
&.icon-see {
|
||||
font-size: 24px;
|
||||
}
|
||||
&.icon-ci {
|
||||
font-size: 20px;
|
||||
}
|
||||
&.icon-time {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.tips-list {
|
||||
margin: 16px 0;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.spu-sku-list {
|
||||
width: 100%;
|
||||
.spu-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.spu-sku-warp {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
margin-top: 16px;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
.spu-sku-item {
|
||||
width: calc((100% - 16px) / 2);
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
&.normal {
|
||||
border: 1px solid $color-da;
|
||||
color: $color-999;
|
||||
}
|
||||
&.act {
|
||||
border: 1px solid $color-main;
|
||||
color: $color-main;
|
||||
}
|
||||
}
|
||||
}
|
||||
.spu-sku-warp::after {
|
||||
content: '';
|
||||
flex: auto;
|
||||
}
|
||||
}
|
||||
.goods-num {
|
||||
margin: 16px 0;
|
||||
.num-warp,
|
||||
.num-title {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.num-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.num-warp {
|
||||
.is-have {
|
||||
display: inline-block;
|
||||
padding-left: 8px;
|
||||
font-size: 12px;
|
||||
color: $color-999;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top-btn {
|
||||
.item-btn {
|
||||
display: inline-block;
|
||||
margin: 8px 24px 8px 0;
|
||||
margin-top: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 20px;
|
||||
border-radius: 12px;
|
||||
color: $color-fff;
|
||||
line-height: 42px;
|
||||
&.sign {
|
||||
background: $color-main;
|
||||
}
|
||||
&.reservation {
|
||||
background: $color-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
.agricultural-detail-content {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
.detail-content {
|
||||
.tab-top {
|
||||
margin: 42px 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
::v-deep() {
|
||||
.el-radio-button:first-child .el-radio-button__inner {
|
||||
border-radius: 16px 0 0 16px;
|
||||
}
|
||||
.el-radio-button:last-child .el-radio-button__inner {
|
||||
border-radius: 0 16px 16px 0;
|
||||
}
|
||||
.el-radio-button__inner {
|
||||
padding-right: 48px !important;
|
||||
padding-left: 48px !important;
|
||||
font-size: 20px;
|
||||
line-height: 32px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tab-content {
|
||||
margin: 24px 0;
|
||||
width: 100%;
|
||||
.content-detail,
|
||||
.content-source-code,
|
||||
.content-evaluate {
|
||||
width: 100%;
|
||||
}
|
||||
.content-detail {
|
||||
.detail-des {
|
||||
margin-bottom: 24px;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
.content-source-code {
|
||||
.code-warp {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
.code-img {
|
||||
margin: auto;
|
||||
width: 230px;
|
||||
height: 230px;
|
||||
}
|
||||
.code-down {
|
||||
margin: 16px 0;
|
||||
color: $color-main;
|
||||
.el-icon,
|
||||
a {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 22px;
|
||||
}
|
||||
a {
|
||||
font-size: 16px;
|
||||
color: $color-main;
|
||||
}
|
||||
}
|
||||
.code-copy {
|
||||
.code-txt {
|
||||
display: inline-block;
|
||||
padding: 12px 8px;
|
||||
width: 200px;
|
||||
border-radius: 16px 0 0 16px;
|
||||
background: $color-main-table-header;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.do-copy {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
margin-left: -6px;
|
||||
.el-button {
|
||||
padding: 21px 16px;
|
||||
font-size: 16px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.code-to-detail {
|
||||
margin: 24px 0;
|
||||
.el-button {
|
||||
padding: 16px 116px;
|
||||
height: 48px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
border-radius: 24px;
|
||||
line-height: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -8,6 +8,7 @@
|
||||
</template>
|
||||
</div>
|
||||
<div class="common-content">
|
||||
<bread-comp></bread-comp>
|
||||
<slot v-if="$slots.main" name="main"></slot>
|
||||
<template v-else></template>
|
||||
</div>
|
||||
@ -17,6 +18,7 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, watch } from 'vue';
|
||||
import leftMenu from './leftMenu.vue';
|
||||
import BreadComp from '@/components/breadComp.vue';
|
||||
|
||||
const props = defineProps({
|
||||
currentName: { type: String, default: 'agricultural' },
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -107,7 +107,8 @@ onMounted(async () => {
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div class="video-wrapper">
|
||||
<video v-if="num === 1" ref="videoPlayer" src="../components/jiankong.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 2" ref="videoPlayer" src="../components/jiankong1.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 2" ref="videoPlayer" src="../components/jiankong6.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 3" ref="videoPlayer" src="../components/jiankong5.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 4" ref="videoPlayer" src="../components/jiankong2.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 5" ref="videoPlayer" src="../components/jiankong3.mp4" controls loop autoplay muted></video>
|
||||
<video v-else-if="num === 6" ref="videoPlayer" src="../components/jiankong4.mp4" controls loop autoplay muted></video>
|
||||
|
@ -147,7 +147,7 @@ const chooseIcon = (type) => {
|
||||
</div>
|
||||
<div style="margin-top: 10px; display: flex; justify-content: space-between">
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 10px">
|
||||
<stream :title="'病害监测监控'" :devices="devices" style="width: 60%; height: fit-content"></stream>
|
||||
<stream :title="'病害监测监控'" :num="3" :devices="devices" style="width: 60%; height: fit-content"></stream>
|
||||
<div style="width: 38%">
|
||||
<el-card style="border-radius: 16px; padding: 10px">
|
||||
<div style="font-size: 16px; font-weight: bold; text-align: left; color: #000">病害数据</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user