| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 |
- <template>
- <view class="detail-container">
- <!-- 顶部封面图轮播 -->
- <view class="image-section">
- <swiper
- class="image-swiper"
- :indicator-dots="false"
- :circular="false"
- :autoplay="false"
- @change="onSwiperChange"
- >
- <swiper-item v-for="(image, index) in imageList" :key="index" @click="previewImage(index)">
- <image :src="image" mode="aspectFill" class="cover-image" lazy-load></image>
- </swiper-item>
- </swiper>
-
- <!-- 自定义分页指示器 -->
- <view class="custom-dots" v-if="imageList.length > 1">
- <view
- class="dot"
- :class="{ active: currentImageIndex === index }"
- v-for="(item, index) in imageList"
- :key="index"
- ></view>
- </view>
- </view>
- <!-- 标题和类型标签 -->
- <view class="title-section">
- <view class="title-content">
- <text class="product-title">{{ productInfo.title }}</text>
- <view class="type-tag" :class="productInfo.type">
- {{ productInfo.type === 'sale' ? '出售' : '收购' }}
- </view>
- </view>
- </view>
- <!-- 核心信息展示卡片 -->
- <view class="info-card">
- <view class="info-row">
- <text class="info-label">分类</text>
- <text class="info-value">{{ productInfo.category }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">{{ productInfo.type === 'sale' ? '单价' : '收购价' }}</text>
- <text class="info-value price">¥{{ productInfo.price }}/{{ productInfo.unit }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">数量</text>
- <text class="info-value">{{ productInfo.quantity }}{{ productInfo.unit }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">所在地</text>
- <text class="info-value location">{{ productInfo.location }}</text>
- </view>
- </view>
- <!-- 补充说明区域 -->
- <view class="description-card">
- <view class="card-title">
- <text>{{ productInfo.type === 'sale' ? '产品详情' : '收购要求' }}</text>
- </view>
- <view class="description-content">
- <text class="description-text">
- {{ productInfo.description || '无补充说明' }}
- </text>
- </view>
- </view>
- <!-- 发布者信息卡片 -->
- <view class="publisher-card">
- <view class="card-title">
- <text>发布者信息</text>
- </view>
- <view class="publisher-info">
- <view class="info-row">
- <text class="info-label">联系人</text>
- <text class="info-value">{{ productInfo.publisher.name }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">联系电话</text>
- <text class="info-value phone">{{ productInfo.publisher.phone }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">发布时间</text>
- <text class="info-value">{{ productInfo.publishTime }}</text>
- </view>
- </view>
- </view>
- <!-- 底部操作按钮 -->
- <view class="action-buttons" v-if="shouldShowActionButtons">
- <!-- 当前用户发布的内容 -->
- <template v-if="isOwnProduct">
- <!-- 已上架状态:显示编辑和下架 -->
- <template v-if="productStatus === 'approved'">
- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn remove-btn" @click="removeProduct">
- 下架
- </button>
- </template>
-
- <!-- 审核中状态:显示编辑和撤销 -->
- <template v-else-if="productStatus === 'pending'">
- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn cancel-btn" @click="cancelProduct">
- 撤销
- </button>
- </template>
-
- <!-- 已下架状态:不显示任何按钮 -->
- </template>
-
- <!-- 他人发布的内容 -->
- <template v-else>
- <button class="action-btn contact-btn" @click="contactPublisher">
- 立即联系
- </button>
- </template>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- currentImageIndex: 0,
- source: '', // 页面来源,myPublish表示来自我的发布页面
- productStatus: '', // 产品状态:pending, approved, rejected
- productInfo: {
- id: '',
- type: 'sale', // sale: 出售, purchase: 收购
- title: '',
- category: '',
- price: '',
- quantity: '',
- unit: '',
- location: '',
- description: '',
- publisher: {
- name: '',
- phone: '',
- userId: ''
- },
- publishTime: '',
- images: []
- },
- imageList: [],
- isOwnProduct: false // 是否为当前用户发布的产品
- }
- },
-
- onLoad(options) {
- // 获取页面参数
- if (options.id) {
- this.source = options.source || '';
- this.productStatus = options.status || '';
- this.loadProductDetail(options.id, options.type);
- }
- },
-
- computed: {
- // 判断是否显示操作按钮
- shouldShowActionButtons() {
- if (!this.isOwnProduct) {
- // 他人发布的内容始终显示联系按钮
- return true;
- } else {
- // 自己发布的内容,已下架状态不显示任何按钮
- return this.productStatus !== 'rejected';
- }
- }
- },
-
- methods: {
- // 加载产品详情
- loadProductDetail(id, type) {
- // 根据类型模拟不同的数据结构
- let mockData;
-
- if (type === 'purchase') {
- // 收购信息的数据结构
- mockData = {
- id: id,
- type: 'purchase',
- title: '高价收购优质土豆',
- category: '蔬菜',
- price: '3.5',
- quantity: '1000',
- unit: '斤',
- location: '山东·烟台',
- description: '大量收购优质土豆,要求新鲜无病害,无青皮,规格统一。支持长期合作,价格优惠,现金结算。有货源的农户欢迎联系,我们提供上门收购服务。',
- publisher: {
- name: '李**',
- phone: '138****5678',
- userId: 'user456'
- },
- publishTime: '2025-01-21 10:30',
- images: [
- '/static/images/products/agriculture-tools.jpg',
- '/static/images/products/organic-fertilizer-new.jpg',
- '/static/images/products/plastic-film.jpg'
- ]
- };
- } else {
- // 出售信息的数据结构
- mockData = {
- id: id,
- type: type || 'sale',
- title: '2024年红富士苹果',
- category: '水果',
- price: '8.5',
- quantity: '1000',
- unit: '斤',
- location: '山东·烟台',
- description: '自家果园种植的红富士苹果,个大味甜,果形端正,色泽鲜艳。采用有机种植方式,无农药残留,口感清脆香甜。现大量上市,欢迎各地客商前来洽谈合作。支持批发零售,量大价优。',
- publisher: {
- name: '张**',
- phone: '188****1234',
- userId: 'user123'
- },
- publishTime: '2025-01-21 14:20',
- images: [
- '/static/images/products/corn-seeds-new.jpg',
- '/static/images/products/rice-seeds.jpg',
- '/static/images/products/seeds-packets.jpg',
- '/static/images/products/greenhouse-film.jpg'
- ]
- };
- }
-
- this.productInfo = mockData;
- this.imageList = mockData.images;
-
- // 判断是否为当前用户发布的产品
- // 如果来源是我的发布页面,则表示是自己的产品
- this.isOwnProduct = this.source === 'myPublish';
- },
-
- // 轮播图切换
- onSwiperChange(e) {
- this.currentImageIndex = e.detail.current;
- },
-
- // 预览图片
- previewImage(index) {
- uni.previewImage({
- current: index,
- urls: this.imageList
- });
- },
-
- // 编辑产品
- editProduct() {
- if (this.productInfo.type === 'purchase') {
- // 收购信息跳转到收购编辑页面
- uni.navigateTo({
- url: `/pages/service/purchase-publish?action=edit&id=${this.productInfo.id}`
- });
- } else {
- // 销售信息跳转到销售编辑页面
- uni.navigateTo({
- url: `/pages/service/sales-publish?action=edit&id=${this.productInfo.id}&type=${this.productInfo.type}`
- });
- }
- },
-
- // 下架产品
- removeProduct() {
- uni.showModal({
- title: '确认下架',
- content: '确定要下架这条信息吗?下架后其他用户将无法查看。',
- confirmText: '确认下架',
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- // 执行下架操作
- this.handleRemoveProduct();
- }
- }
- });
- },
-
- // 处理下架操作
- handleRemoveProduct() {
- // 模拟下架API调用
- uni.showLoading({ title: '下架中...' });
-
- setTimeout(() => {
- uni.hideLoading();
- uni.showToast({
- title: '下架成功',
- icon: 'success'
- });
-
- // 返回上一页
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }, 1000);
- },
-
- // 联系发布者
- contactPublisher() {
- // 获取真实电话号码并拨打
- const realPhone = this.getRealPhoneNumber();
-
- uni.showModal({
- title: '联系发布者',
- content: `确定要拨打 ${realPhone} 吗?`,
- confirmText: '拨打',
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- uni.makePhoneCall({
- phoneNumber: realPhone,
- fail: () => {
- uni.showToast({
- title: '拨号失败',
- icon: 'none'
- });
- }
- });
- }
- }
- });
- },
-
- // 撤销产品(审核中状态)
- cancelProduct() {
- uni.showModal({
- title: '确认撤销',
- content: '确定要撤销这条发布信息吗?撤销后需要重新提交审核。',
- confirmText: '确认撤销',
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- // 执行撤销操作
- this.handleCancelProduct();
- }
- }
- });
- },
-
- // 处理撤销操作
- handleCancelProduct() {
- // 模拟撤销API调用
- uni.showLoading({ title: '撤销中...' });
-
- setTimeout(() => {
- uni.hideLoading();
- uni.showToast({
- title: '撤销成功',
- icon: 'success'
- });
-
- // 返回上一页
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }, 1000);
- },
-
- // 获取真实电话号码(实际应用中从API获取)
- getRealPhoneNumber() {
- // 模拟从API获取真实电话号码
- return '18812341234';
- }
- }
- }
- </script>
- <style lang="scss">
- .detail-container {
- min-height: 100vh;
- background-color: #f5f5f5;
- padding-bottom: 120rpx;
- }
- // 顶部封面图轮播
- .image-section {
- position: relative;
- margin: 20rpx;
- border-radius: 16rpx;
- overflow: hidden;
- background-color: #fff;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
- }
- .image-swiper {
- width: 100%;
- height: 500rpx;
- }
- swiper-item {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: 100%;
- }
- .cover-image {
- width: 100%;
- height: 100%;
- }
- .custom-dots {
- position: absolute;
- bottom: 20rpx;
- left: 50%;
- transform: translateX(-50%);
- display: flex;
- gap: 12rpx;
- }
- .dot {
- width: 12rpx;
- height: 12rpx;
- border-radius: 6rpx;
- background-color: rgba(255, 255, 255, 0.5);
- transition: all 0.3s ease;
-
- &.active {
- background-color: #fff;
- width: 24rpx;
- }
- }
- // 标题和类型标签
- .title-section {
- margin: 0 20rpx 20rpx;
- background-color: #fff;
- border-radius: 16rpx;
- padding: 30rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
- }
- .title-content {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- gap: 20rpx;
- }
- .product-title {
- flex: 1;
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- line-height: 1.4;
- }
- .type-tag {
- padding: 8rpx 16rpx;
- border-radius: 20rpx;
- font-size: 24rpx;
- font-weight: bold;
- flex-shrink: 0;
-
- &.sale {
- background-color: #e8f5e8;
- color: #4CAF50;
- }
-
- &.purchase {
- background-color: #e6f7ff;
- color: #1890ff;
- }
- }
- // 信息卡片通用样式
- .info-card, .description-card, .publisher-card {
- margin: 0 20rpx 20rpx;
- background-color: #fff;
- border-radius: 16rpx;
- padding: 30rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
- }
- .card-title {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 24rpx;
- padding-bottom: 16rpx;
- border-bottom: 2rpx solid #f5f5f5;
- }
- // 核心信息展示
- .info-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 16rpx 0;
- border-bottom: 1rpx solid #f8f8f8;
-
- &:last-child {
- border-bottom: none;
- }
- }
- .info-label {
- font-size: 28rpx;
- color: #666;
- flex-shrink: 0;
- width: 120rpx;
- }
- .info-value {
- font-size: 28rpx;
- color: #333;
- font-weight: 500;
- text-align: right;
- flex: 1;
-
- &.price {
- color: #ff6b35;
- font-weight: bold;
- font-size: 30rpx;
- }
-
- &.location {
- color: #4CAF50;
- }
-
- &.phone {
- color: #1890ff;
- }
- }
- // 补充说明区域
- .description-content {
- padding: 20rpx;
- background-color: #f8f9fa;
- border-radius: 12rpx;
- border-left: 4rpx solid #4CAF50;
- }
- .description-text {
- font-size: 26rpx;
- color: #666;
- line-height: 1.6;
- }
- // 发布者信息
- .publisher-info {
- .info-row {
- padding: 20rpx 0;
- }
- }
- // 底部操作按钮
- .action-buttons {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- padding: 20rpx 30rpx;
- padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
- background-color: #fff;
- border-top: 1rpx solid #f0f0f0;
- display: flex;
- gap: 20rpx;
- z-index: 100;
- }
- .action-btn {
- flex: 1;
- height: 80rpx;
- border-radius: 40rpx;
- font-size: 28rpx;
- font-weight: bold;
- border: none;
- transition: all 0.3s ease;
-
- &.edit-btn {
- background-color: #fff;
- color: #4CAF50;
- border: 2rpx solid #4CAF50;
-
- &:active {
- background-color: #f0fdf4;
- }
- }
-
- &.remove-btn {
- background-color: #fff;
- color: #ff4757;
- border: 2rpx solid #ff4757;
-
- &:active {
- background-color: #fff5f5;
- }
- }
-
- &.cancel-btn {
- background-color: #fff;
- color: #fa8c16;
- border: 2rpx solid #fa8c16;
-
- &:active {
- background-color: #fff7e6;
- }
- }
-
- &.contact-btn {
- background-color: #4CAF50;
- color: #fff;
-
- &:active {
- background-color: #45a049;
- }
- }
- }
- // 防止按钮点击状态样式被覆盖
- button[disabled] {
- opacity: 0.6;
- }
- button::after {
- border: none;
- }
- </style>
|