You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

494 lines
22 KiB

<!-- pages/goods-update/goods-update.wxml -->
<view class="goods-update-page">
<!-- 商品详情内容 -->
<view class="goods-detail-content">
<!-- 商品媒体轮播(支持图片和视频) -->
<view class="goods-image-slider">
<swiper
indicator-dots="{{true}}"
autoplay="{{true}}"
interval="3000"
duration="500"
indicator-color="rgba(255, 255, 255, 0.5)"
indicator-active-color="#ffffff"
circular="{{true}}"
>
<block wx:for="{{goodsDetail.mediaItems}}" wx:key="index">
<swiper-item>
<!-- 视频处理:根据类型字段判断 -->
<video
wx:if="{{item.type === 'video'}}"
src="{{item.url}}"
class="slider-media"
mode="aspectFill"
show-center-play-btn="{{true}}"
show-play-btn="{{false}}"
controls="{{true}}"
autoplay="{{true}}"
loop="{{true}}"
muted="{{true}}"
initial-time="0"
show-mute-btn="{{true}}"
enable-progress-gesture="{{true}}"
enable-play-gesture="{{true}}"
object-fit="fill"
poster="" >
</video>
<!-- 图片处理 -->
<image
wx:else
src="{{item.url}}"
mode="aspectFill"
class="slider-media"
bindtap="previewImage"
data-urls="{{goodsDetail.imageUrls}}"
data-index="{{index}}"
loading="lazy"
/>
</swiper-item>
</block>
</swiper>
</view>
<!-- 商品基本信息 -->
<view class="goods-info">
<view class="goods-header">
<view class="goods-name-container">
<view class="supply-status-badge">{{goodsDetail.supplyStatus || '暂无状态'}}</view>
<text class="goods-name">{{goodsDetail.name}}</text>
<span class="verified-badge">V</span>
</view>
<view class="source-type-container">
<view class="source-type-badge">
<text style="color: {{goodsDetail.sourceTypeColor}}; font-weight: bold;">{{goodsDetail.sourceType || '暂无'}}</text>
</view>
</view>
</view>
<view class="goods-price">
<view class="price-item">
<text class="price-symbol">销售价格:</text>
<text class="price-value">{{goodsDetail.price || '暂无'}}</text>
</view>
<view class="price-item">
<text class="price-symbol">采购价格:</text>
<text class="price-value">{{goodsDetail.costprice || '暂无'}}</text>
</view>
</view>
</view>
<!-- 规格信息 -->
<view class="weight-quantity-info" wx:if="{{(goodsDetail.weightQuantityData && goodsDetail.weightQuantityData.length > 0) || goodsDetail.specInfo || goodsDetail.spec}}">
<view class="wq-title">规格信息</view>
<view class="wq-block-list">
<block wx:if="{{goodsDetail.weightQuantityData && goodsDetail.weightQuantityData.length > 0}}">
<view class="wq-block-row" wx:for="{{goodsDetail.weightQuantityData}}" wx:key="index">
<view class="wq-block spec-block"><text class="block-text weight-spec-text">{{item.weightSpec}}</text></view>
<view class="wq-block quantity-block"><text class="block-text quantity-text">【{{item.quantity}}】</text></view>
<view class="wq-block costprice-block"><text class="block-text costprice-text" wx:if="{{item.costprice && item.costprice !== '暂无'}}">¥{{item.costprice}}</text></view>
<view class="wq-block price-block"><text class="block-text price-text" wx:if="{{item.price && item.price !== '暂无'}}">¥{{item.price}}</text></view>
</view>
</block>
<block wx:elif="{{goodsDetail.specInfo && goodsDetail.specInfo.length > 0}}">
<view class="wq-block-row" wx:for="{{goodsDetail.specInfo}}" wx:key="index">
<view class="wq-block spec-block" style="flex: 0 0 100%;"><text class="block-text weight-spec-text">{{item}}</text></view>
</view>
</block>
<block wx:else>
<view class="wq-block-row">
<view class="wq-block spec-block" style="flex: 0 0 100%;"><text class="block-text weight-spec-text">{{goodsDetail.spec || '暂无规格信息'}}</text></view>
</view>
</block>
</view>
</view>
<!-- 商品详细信息网格 -->
<view class="info-grid">
<view class="info-row">
<view class="info-item">
<view class="info-label-container">
<text class="info-label">地区</text>
</view>
<view class="info-value-container">
<text class="info-value">{{goodsDetail.region || '暂无'}}</text>
</view>
</view>
<view class="info-item">
<view class="info-label-container">
<text class="info-label">新鲜程度</text>
</view>
<view class="info-value-container">
<text class="info-value">{{goodsDetail.freshness || '暂无'}}</text>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label-container">
<text class="info-label">蛋黄</text>
</view>
<view class="info-value-container">
<text class="info-value">{{goodsDetail.yolk || '暂无'}}</text>
</view>
</view>
<view class="info-item">
<view class="info-label-container">
<text class="info-label">产品包装</text>
</view>
<view class="info-value-container">
<text class="info-value">{{goodsDetail.producting || '暂无'}}</text>
</view>
</view>
</view>
</view>
<!-- 货源描述 -->
<view class="goods-description" wx:if="{{goodsDetail.description || goodsDetail.remark || true}}">
<view class="wq-title">货源描述</view>
<view class="wq-list">
<view class="wq-item">
<text class="wq-text">{{goodsDetail.description || goodsDetail.remark || '暂无描述'}}</text>
</view>
</view>
</view>
<!-- 联系信息 -->
<view class="contact-info">
<view class="contact-content">
<view class="contact-item">
<text class="contact-icon user-icon">👤</text>
<text class="contact-label-text">联系人:</text>
<text class="contact-text">{{goodsDetail.product_contact || '暂无'}}</text>
</view>
<view class="contact-item phone-item">
<text class="contact-icon phone-icon">📞</text>
<view class="phone-info">
<text class="contact-label-text">联系电话:</text>
<text class="contact-text">{{goodsDetail.contact_phone || '暂无'}}</text>
</view>
</view>
</view>
</view>
<!-- 创建人信息 -->
<view class="creator-info">
<view class="creator-item">
<text class="creator-label">创建人:</text>
<text class="creator-name">{{goodsDetail.creatorName || '暂无'}}</text>
</view>
<view class="creator-item">
<text class="creator-label">创建时间:</text>
<text class="create-time">{{goodsDetail.formattedCreatedAt || '暂无'}}</text>
</view>
<view class="creator-item">
<text class="creator-label">修改时间:</text>
<text class="create-time">{{goodsDetail.formattedUpdatedAt || '暂无'}}</text>
</view>
</view>
<!-- 产品日志信息 -->
<view class="product-log-info">
<view class="log-title">价格变更日志</view>
<view class="log-list">
<block wx:if="{{goodsDetail.product_log && goodsDetail.product_log.length > 0}}">
<view class="log-item" wx:for="{{goodsDetail.product_log}}" wx:key="index">
<view class="log-index">日志{{index + 1}}</view>
<view class="log-content">
<!-- 处理旧的用 | 分隔的日志格式,将其拆分成多条显示 -->
<block wx:if="{{item.indexOf(' | ') > -1}}">
<text class="log-full-text" wx:for="{{item.split(' | ')}}" wx:for-item="logPart" wx:for-index="partIndex" wx:key="partIndex">
{{logPart}}
<text wx:if="{{partIndex < item.split(' | ').length - 1}}">
</text>
</text>
</block>
<!-- 处理新的单条日志格式 -->
<block wx:else>
<text class="log-full-text">{{item}}</text>
</block>
</view>
</view>
</block>
<block wx:else>
<view class="log-item">
<view class="log-index">日志</view>
<view class="log-content">
<text class="log-full-text">暂无价格变更日志</text>
</view>
</view>
</block>
</view>
</view>
</view>
<!-- 操作按钮区域 -->
<view class="action-buttons">
<button
class="edit-button bottom-button"
bindtap="showEditModal"
>
编辑货源
</button>
<button
class="bottom-button"
bindtap="prepareUnpublishSupply"
disabled="{{goodsDetail.status == 'sold_out'}}"
style="background-color: {{goodsDetail.status == 'sold_out' ? '#d9d9d9' : '#52c41a'}}; color: {{goodsDetail.status == 'sold_out' ? '#999999' : '#ffffff'}}; border: 2px solid {{goodsDetail.status == 'sold_out' ? '#d9d9d9' : '#52c41a'}}; box-shadow: {{goodsDetail.status == 'sold_out' ? 'none' : '0 2px 8px rgba(82, 196, 26, 0.2)'}}; opacity: {{goodsDetail.status == 'sold_out' ? '0.8' : '1'}}"
>
{{goodsDetail.status == 'sold_out' ? '已下架' : '下架'}}
</button>
</view>
<!-- 编辑货源弹窗(全屏) -->
<view class="modal" wx:if="{{showEditModal}}">
<!-- 顶部导航栏 -->
<view class="modal-header">
<view class="modal-btn cancel-btn" bindtap="hideEditModal">取消</view>
<view class="modal-title">编辑货源</view>
<view class="modal-btn confirm-btn" bindtap="saveEdit">提交</view>
</view>
<scroll-view scroll-y="true" style="height: calc(100vh - 160rpx); overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 160rpx 60rpx 40rpx; box-sizing: border-box;">
<view>
<!-- 动态生成多个价格输入框 -->
<block wx:if="{{editSupply.specArray && editSupply.specArray.length > 1}}">
<view class="dynamic-price-container">
<view class="price-item" wx:for="{{editSupply.specArray}}" wx:key="index">
<view class="spec-label">
{{item}}
<text class="costprice-info" wx:if="{{editSupply.costpriceArray[index] !== undefined && editSupply.costpriceArray[index] !== null && editSupply.costpriceArray[index] !== ''}}">(采购价:¥{{editSupply.costpriceArray[index]}})</text>
</view>
<input
class="edit-form-input price-input"
type="text"
placeholder="请输入价格"
bindinput="onEditPriceInput"
data-index="{{index}}"
value="{{editSupply.priceArray[index] || ''}}"
></input>
</view>
</view>
</block>
<!-- 单个规格时显示普通输入框 -->
<block wx:else>
<view class="spec-label single-spec-label">
{{editSupply.specArray[0] || ''}}
<text class="costprice-info" wx:if="{{editSupply.costpriceArray[0] || editSupply.costprice}}">(采购价:¥{{editSupply.costpriceArray[0] || editSupply.costprice}})</text>
</view>
<input
class="edit-form-input"
type="text"
placeholder="请输入销售价格"
bindinput="onEditPriceInput"
data-index="0"
value="{{editSupply.priceArray[0] || editSupply.price || ''}}"
></input>
</block>
<view class="edit-form-label">联系人</view>
<view class="edit-form-select" bindtap="openSalesPersonModal">
<text class="select-text">{{editSupply.product_contact || '请选择联系人'}}</text>
<text class="select-arrow">▼</text>
</view>
<view class="edit-form-label">联系电话</view>
<input class="edit-form-input" type="number" placeholder="请输入联系电话" bindinput="onEditInput" data-field="contact_phone" value="{{editSupply.contact_phone}}"></input>
<!-- 添加底部空白区域 -->
<view style="height: 20vh; background: transparent;"></view>
</view>
</scroll-view>
</view>
<!-- 图片预览弹窗 -->
<view class="image-preview-mask" wx:if="{{showImagePreview}}" catchtouchmove="true" bindtap="closeImagePreview">
<view class="image-preview-content">
<swiper
class="image-preview-swiper"
current="{{previewImageIndex}}"
bindchange="onPreviewImageChange"
indicator-dots="true"
indicator-color="rgba(255,255,255,0.5)"
indicator-active-color="#fff">
<block wx:for="{{previewImageUrls}}" wx:key="*this">
<swiper-item>
<image
src="{{item}}"
mode="aspectFit"
class="preview-image"
style="transform: scale({{scale}}) translate({{offsetX}}px, {{offsetY}}px);"
bindtap="handleImageTap"
bindtouchstart="handleTouchStart"
bindtouchmove="handleTouchMove"
bindtouchend="handleTouchEnd"
bindload="onPreviewImageLoad"
></image>
</swiper-item>
</block>
</swiper>
<view class="image-preview-close">
<text bindtap="closeImagePreview">×</text>
</view>
</view>
</view>
<!-- 自定义规格选择弹窗 - 适配原生风格 -->
<view class="spec-select-modal" wx:if="{{showSpecSelectModal}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; justify-content: center; z-index: 9999;" catchtouchmove="true">
<view style="position: fixed; bottom: 0; left: 0; right: 0; background: white; border-radius: 20rpx 20rpx 0 0; max-height: 80vh;">
<!-- 顶部操作栏:取消和确定按钮 -->
<view style="padding: 20rpx; display: flex; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #eee;">
<view bindtap="closeSpecSelectModal" style="font-size: 32rpx; color: #333; padding: 10rpx 20rpx;">取消</view>
<view bindtap="confirmSpecSelection" style="font-size: 32rpx; color: #07c160; padding: 10rpx 20rpx;">确定</view>
</view>
<!-- 搜索框区域 -->
<view style="padding: 20rpx;">
<view style="position: relative; background: #f5f5f5; border-radius: 40rpx; padding: 0 30rpx;">
<input
type="text"
placeholder="搜索规格"
value="{{modalSpecSearchKeyword}}"
bindinput="onModalSpecSearchInput"
confirm-type="search"
style="width: 100%; height: 70rpx; line-height: 70rpx; font-size: 28rpx; background: transparent;"
/>
<view
wx:if="{{modalSpecSearchKeyword}}"
bindtap="clearModalSpecSearch"
style="position: absolute; right: 30rpx; top: 50%; transform: translateY(-50%); color: #999;"
>
</view>
</view>
</view>
<!-- 规格列表 -->
<scroll-view
scroll-y="true"
style="max-height: 60vh; padding: 0; -webkit-overflow-scrolling: touch;"
enable-back-to-top="false"
>
<view
wx:for="{{filteredModalSpecOptions}}"
wx:key="index"
class="spec-item {{selectedModalSpecIndex === index ? 'selected' : ''}}"
bindtap="onModalSpecSelect"
data-index="{{index}}"
style="padding: 30rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; font-size: 28rpx; color: {{selectedModalSpecIndex === index ? '#07c160' : '#333'}}; text-align: left;"
>
{{item}}
</view>
</scroll-view>
</view>
</view>
<!-- 商品名称选择弹窗 - 白色样式 -->
<view class="custom-select-modal" wx:if="{{showNameSelectModal}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; justify-content: center; z-index: 9999;" catchtouchmove="true">
<view style="position: fixed; bottom: 0; left: 0; right: 0; background: white; border-radius: 20rpx 20rpx 0 0; max-height: 80vh;">
<!-- 顶部操作栏:取消和确定按钮 -->
<view style="padding: 20rpx; display: flex; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #eee;">
<view bindtap="closeNameSelectModal" style="font-size: 32rpx; color: #333; padding: 10rpx 20rpx;">取消</view>
<view bindtap="confirmNameSelection" style="font-size: 32rpx; color: #07c160; padding: 10rpx 20rpx;">确定</view>
</view>
<!-- 商品名称列表 -->
<scroll-view
scroll-y="true"
style="max-height: 60vh; padding: 0; -webkit-overflow-scrolling: touch;"
enable-back-to-top="false"
>
<view
wx:for="{{productNameOptions}}"
wx:key="index"
class="select-item {{selectedNameIndex === index ? 'selected' : ''}}"
bindtap="onNameSelect"
data-index="{{index}}"
style="padding: 32rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; font-size: 32rpx; color: {{selectedNameIndex === index ? '#07c160' : '#131413'}}; text-align: center;"
>
{{item}}
</view>
</scroll-view>
</view>
</view>
<!-- 蛋黄选择弹窗 - 白色样式 -->
<view class="custom-select-modal" wx:if="{{showYolkSelectModal}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; justify-content: center; z-index: 9999;" catchtouchmove="true">
<view style="position: fixed; bottom: 0; left: 0; right: 0; background: white; border-radius: 20rpx 20rpx 0 0; max-height: 80vh;">
<!-- 顶部操作栏:取消和确定按钮 -->
<view style="padding: 20rpx; display: flex; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #eee;">
<view bindtap="closeYolkSelectModal" style="font-size: 32rpx; color: #333; padding: 10rpx 20rpx;">取消</view>
<view bindtap="confirmYolkSelection" style="font-size: 32rpx; color: #07c160; padding: 10rpx 20rpx;">确定</view>
</view>
<!-- 蛋黄列表 -->
<scroll-view
scroll-y="true"
style="max-height: 60vh; padding: 0; -webkit-overflow-scrolling: touch; -webkit-scrollbar: none; scrollbar-width: none;"
enable-back-to-top="false"
>
<view
wx:for="{{yolkOptions}}"
wx:key="index"
class="select-item {{selectedYolkIndex === index ? 'selected' : ''}}"
bindtap="onYolkSelect"
data-index="{{index}}"
style="padding: 32rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; font-size: 32rpx; color: {{selectedYolkIndex === index ? '#07c160' : '#131413'}}; text-align: center;"
>
{{item}}
</view>
</scroll-view>
</view>
</view>
<!-- 销售员选择弹窗 - 白色样式 -->
<view class="custom-select-modal" wx:if="{{showSalesPersonSelectModal}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; justify-content: center; z-index: 9999;" catchtouchmove="true">
<view style="position: fixed; bottom: 0; left: 0; right: 0; background: white; border-radius: 20rpx 20rpx 0 0; height: 70vh;">
<!-- 顶部操作栏:取消和确定按钮 -->
<view style="padding: 20rpx; display: flex; justify-content: space-between; align-items: center; border-bottom: 1rpx solid #eee;">
<view bindtap="closeSalesPersonSelectModal" style="font-size: 32rpx; color: #333; padding: 10rpx 20rpx;">取消</view>
<view bindtap="confirmSalesPersonSelection" style="font-size: 32rpx; color: #07c160; padding: 10rpx 20rpx;">确定</view>
</view>
<!-- 搜索框区域 -->
<view style="padding: 20rpx;">
<view style="position: relative; background: #f5f5f5; border-radius: 40rpx; padding: 0 30rpx;">
<input
type="text"
placeholder="搜索销售员"
value="{{modalSalesPersonSearchKeyword}}"
bindinput="onModalSalesPersonSearchInput"
confirm-type="search"
style="width: 100%; height: 70rpx; line-height: 70rpx; font-size: 28rpx; background: transparent;"
/>
<view
wx:if="{{modalSalesPersonSearchKeyword}}"
bindtap="clearModalSalesPersonSearch"
style="position: absolute; right: 30rpx; top: 50%; transform: translateY(-50%); color: #999;"
>
</view>
</view>
</view>
<!-- 销售员列表 -->
<scroll-view
scroll-y="true"
style="height: calc(60vh - 170rpx); padding: 0; -webkit-overflow-scrolling: touch; -webkit-scrollbar: none; scrollbar-width: none;"
enable-back-to-top="false"
>
<view
wx:for="{{filteredSalesPersonnelOptions}}"
wx:key="index"
class="select-item {{selectedSalesPersonIndex === index ? 'selected' : ''}}"
bindtap="onSalesPersonSelect"
data-index="{{index}}"
style="padding: 32rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; text-align: left;"
>
<view style="font-size: 32rpx; color: {{selectedSalesPersonIndex === index ? '#07c160' : '#131413'}}; font-weight: 500;">{{item.name}}</view>
<view style="font-size: 24rpx; color: #999; margin-top: 8rpx;">{{item.phoneNumber || '暂无电话'}}</view>
</view>
</scroll-view>
</view>
</view>
</view>