| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- <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 === 0 ? 'sale' : 'purchase'">
- {{ productInfo.type === 0 ? '出售' : '收购' }}
- </view>
- </view>
- </view>
- <!-- 核心信息展示卡片 -->
- <view class="info-card">
- <view class="info-row">
- <text class="info-label">分类</text>
- <text class="info-value">{{ getDictLabel('agricultural_category',productInfo.categoryId) }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">{{ productInfo.type === 0 ? '单价' : '收购价' }}</text>
- <text class="info-value price">¥{{ productInfo.price }}/{{ getDictLabel('agricultural_unit',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> -->
- <LocationPicker class="info-value location"
- v-model="productInfo.location"
- mode="view"
- />
- </view>
-
- </view>
- <!-- 补充说明区域 -->
- <view class="description-card">
- <view class="card-title">
- <text>{{ productInfo.type === 0 ? '产品详情' : '收购要求' }}</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.contactName }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">联系电话</text>
- <text class="info-value phone">{{ productInfo.contactPhone }}</text>
- </view>
- <view class="info-row">
- <text class="info-label">发布时间</text>
- <text class="info-value">{{ productInfo.publishTime }}</text>
- </view>
- </view>
- </view>
-
- <!-- 审批意见 -->
- <view class="description-card" v-if="productInfo.status === 4">
- <view class="card-title">
- <text>审核结果</text>
- </view>
- <view class="description-content" style="border-left: 2px solid red">
- <text class="description-text" >
- {{ productInfo.remark || '无' }}
- </text>
- </view>
- </view>
- <!-- 底部操作按钮 -->
- <view class="action-buttons" v-if="shouldShowActionButtons">
- <!-- 当前用户发布的内容
- <!-- <template v-if="isOwnProduct">
- <!-- 已上架状态:显示编辑和下架
- <template v-if="productStatus === '2'">
- <!-- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn remove-btn" @click="removeProduct">
- 下架
- </button>
- </template>
-
- <!-- 审核中状态:显示编辑和撤销
- <template v-else-if="productStatus === '1'">
- <!-- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn cancel-btn" @click="cancelProduct">
- 撤销
- </button>
- </template>
-
- <!-- 已下架状态:不显示任何按钮
- <template v-else-if="productStatus === '3'">
- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn cancel-btn" @click="cancelProduct">
- 发布
- </button>
- </template>
- <!-- 未通过
- <template v-else-if="productStatus === '4'">
- <button class="action-btn edit-btn" @click="editProduct">
- 编辑
- </button>
- <button class="action-btn cancel-btn" @click="cancelProduct">
- 删除
- </button>
- </template>
- </template> -->
- <!-- 当前用户发布的内容 -->
- <template v-if="isOwnProduct">
- <button
- v-for="(btn, index) in actionMap[productStatus] || []"
- :key="index"
- class="action-btn"
- :class="btn.class"
- @click="handleAction(btn.action)"
- >
- {{ btn.label }}
- </button>
- </template>
-
- <!-- 他人发布的内容 -->
- <template v-else>
- <button class="action-btn contact-btn" @click="contactPublisher">
- 立即联系
- </button>
- </template>
- </view>
- </view>
- </template>
- <script>
- import LocationPicker from "@/components/common/LocationPicker.vue"
- import {
- getProductInfoById,editProductInfo
- } from '@/api/services/productInfo.js';
- import dictMixin from '@/utils/mixins/dictMixin';
- export default {
- mixins: [dictMixin],
- components: { LocationPicker },
- data() {
- return {
- dictTypeList: ['agricultural_category','agricultural_unit'],
- currentImageIndex: 0,
- source: '', // 页面来源,myPublish表示来自我的发布页面
- productStatus: '', // 产品状态:1-pending, 2-approved, 3-rejected
- productInfo: {
- id: '',
- type: '0', // 0-sale: 出售, 1-purchase: 收购
- title: '',
- categoryId: '',
- price: '',
- quantity: '',
- unit: '',
- location: '',
- description: '',
- contactName:'',
- contactPhone:'',
- publishTime: '',
- images: [],
- remark: ''
- },
- imageList: [],
- isOwnProduct: false ,// 是否为当前用户发布的产品
- // 状态按钮映射
- actionMap: {
- '1': [ // 审核中
- // { label: '编辑', class: 'edit-btn', action: 'editProduct' },
- // { label: '撤销', class: 'cancel-btn', action: 'cancelProduct' }
- ],
- '2': [ // 已上架
- // { label: '编辑', class: 'edit-btn', action: 'editProduct' },
- { label: '下架', class: 'remove-btn', action: 'removeProduct' }
- ],
- '3': [ // 已下架
- { label: '编辑', class: 'edit-btn', action: 'editProduct' },
- { label: '发布', class: 'cancel-btn', action: 'publishProduct' }
- ],
- '4': [ // 未通过
- { label: '编辑', class: 'edit-btn', action: 'editProduct' },
- // { label: '删除', class: 'cancel-btn', action: 'cancelProduct' }
- ]
- }
- }
- },
- onShow() {
- console.log("onshow",this.productInfo);
- this.loadProductDetail(this.productInfo.id)
- },
- 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: {
- // getUnitLabel(value) {
- // console.log("this.dictData",this.dictData);
- // const unit = this.dictData.agricultural_category.find(u => u.dictValue == value)
- // return unit ? unit.dictLabel : ''
- // },
- handleAction(action) {
- this[action] && this[action](); // 动态调用 editProduct/removeProduct 等方法
- },
- getDictLabel(dictKey, value) {
- if (!this.dictData || !this.dictData[dictKey]) {
- return ''
- }
- const list = this.dictData[dictKey] || []
- const item = list.find(u => u.dictValue == value)
- return item ? item.dictLabel : ''
- },
- // 加载产品详情
- loadProductDetail(id) {
- // 根据类型模拟不同的数据结构
-
- uni.showLoading({
- title: '加载中'
- });
- getProductInfoById(id).then(res=>{
- if (res.data.code === 200) {
- const { data } = res.data;
- this.productInfo = data
- console.log("this.goodsDetail", this.productInfo);
- // 处理图片数据
- if (this.productInfo.imageUrl) {
- try {
- this.imageList = this.productInfo.imageUrl.split(',')
- console.log('解析后的图片数据:', this.imageList);
- } catch (e) {
- console.error('解析图片数据失败:', e);
- this.imageList = [];
- }
- } else {
- this.imageList = [];
- }
- uni.hideLoading();
- } else {
- uni.showToast({
- title: res.data.msg || '获取农品信息失败',
- icon: 'none'
- });
- }
- })
-
- // 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 === 1) {
- // 收购信息跳转到收购编辑页面
- 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}`
- });
- }
- },
-
- publishProduct(){
- uni.showModal({
- title: '确认发布审核',
- content: `确定要发布这条信息吗?审核通过后将在${this.productInfo.type === 0 ? '销售' : '收购'}页面展示`,
- confirmText: '确认发布',
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- // 执行下架操作
- this.handlePublishProduct();
- }
- }
- });
- },
-
- // 处理发布操作
- handlePublishProduct() {
- // 模拟下架API调用
- uni.showLoading({ title: '发布中...' });
- const data = {
- id: this.productInfo.id,
- status: 1 // 审核中
- }
- editProductInfo(data).then(res=>{
- uni.hideLoading();
- if(res.data.code === 200){
- uni.showToast({
- title: '发布成功',
- icon: 'success'
- });
- // 返回上一页
- setTimeout(() => {
- uni.navigateBack();
- }, 1000);
- }else{
- uni.showToast({
- title: res.data.msg || '发布失败,请稍后重试',
- icon: 'none'
- });
- }
- })
- },
-
- // 下架产品
- removeProduct() {
- uni.showModal({
- title: '确认下架',
- content: '确定要下架这条信息吗?下架后其他用户将无法查看。',
- confirmText: '确认下架',
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- // 执行下架操作
- this.handleRemoveProduct();
- }
- }
- });
- },
-
- // 处理下架操作
- handleRemoveProduct() {
- // 模拟下架API调用
- uni.showLoading({ title: '下架中...' });
- const data = {
- id: this.productInfo.id,
- status: 3 // 下架
- }
- editProductInfo(data).then(res=>{
- uni.hideLoading();
- if(res.data.code === 200){
- uni.showToast({
- title: '下架成功',
- icon: 'success'
- });
- // 返回上一页
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }else{
- uni.showToast({
- title: res.data.msg || '下架失败,请稍后重试',
- icon: 'none'
- });
- }
- })
- },
-
- // 联系发布者
- 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>
|