|
|
@@ -1,710 +1,955 @@
|
|
|
<template>
|
|
|
- <view class="purchase-publish-container">
|
|
|
- <!-- 表单内容 -->
|
|
|
- <view class="form-container">
|
|
|
- <!-- 收购标题 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">收购标题</text>
|
|
|
- <text class="required">*</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <input
|
|
|
- class="form-input"
|
|
|
- v-model="formData.title"
|
|
|
- placeholder="请输入收购标题"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- maxlength="30"
|
|
|
- @input="onTitleInput"
|
|
|
- />
|
|
|
- <view class="char-count">{{ titleLength }}/30</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 收购品类 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">收购品类</text>
|
|
|
- <text class="required">*</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <view class="category-selector" @click="showCategoryPicker = true">
|
|
|
- <text class="selector-text" :class="{ placeholder: !formData.category }">
|
|
|
- {{ formData.category || '请选择收购品类' }}
|
|
|
- </text>
|
|
|
- <text class="arrow-icon">></text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 收购数量 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">收购数量</text>
|
|
|
- <text class="required">*</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <view class="input-with-unit">
|
|
|
- <input
|
|
|
- class="form-input"
|
|
|
- v-model="formData.quantity"
|
|
|
- placeholder="请输入收购数量"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- type="number"
|
|
|
- />
|
|
|
- <text class="unit-text">斤</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 单价预算 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">单价预算</text>
|
|
|
- <text class="required">*</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <view class="input-with-unit">
|
|
|
- <text class="currency-symbol">¥</text>
|
|
|
- <input
|
|
|
- class="form-input"
|
|
|
- v-model="formData.budgetPrice"
|
|
|
- placeholder="请输入单价预算"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- type="digit"
|
|
|
- />
|
|
|
- <text class="unit-text">元/斤</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 补充说明 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">补充说明</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <textarea
|
|
|
- class="form-textarea"
|
|
|
- v-model="formData.description"
|
|
|
- placeholder="请描述交货要求、时间等补充信息"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- maxlength="200"
|
|
|
- auto-height
|
|
|
- @input="onDescInput"
|
|
|
- />
|
|
|
- <view class="char-count">{{ descLength }}/200</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 上传参考图片 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">参考图片</text>
|
|
|
- <text class="optional">(最多2张)</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <view class="image-upload-area">
|
|
|
- <view
|
|
|
- class="image-item"
|
|
|
- v-for="(image, index) in formData.images"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <image class="uploaded-image" :src="image" mode="aspectFill"></image>
|
|
|
- <view class="image-delete" @click="removeImage(index)">×</view>
|
|
|
- </view>
|
|
|
- <view
|
|
|
- class="image-upload-btn"
|
|
|
- v-if="formData.images.length < 2"
|
|
|
- @click="chooseImage"
|
|
|
- >
|
|
|
- <text class="upload-icon">+</text>
|
|
|
- <text class="upload-text">上传图片</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 联系人信息 -->
|
|
|
- <view class="form-item">
|
|
|
- <view class="item-label">
|
|
|
- <text class="label-text">联系人信息</text>
|
|
|
- </view>
|
|
|
- <view class="item-content">
|
|
|
- <view class="contact-input-row">
|
|
|
- <text class="contact-label">联系人:</text>
|
|
|
- <input
|
|
|
- class="contact-input"
|
|
|
- v-model="formData.contactName"
|
|
|
- placeholder="请输入联系人姓名"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- maxlength="10"
|
|
|
- />
|
|
|
- </view>
|
|
|
- <view class="contact-input-row">
|
|
|
- <text class="contact-label">电话:</text>
|
|
|
- <input
|
|
|
- class="contact-input"
|
|
|
- v-model="formData.contactPhone"
|
|
|
- placeholder="请输入联系电话"
|
|
|
- placeholder-style="color: #999;"
|
|
|
- type="number"
|
|
|
- maxlength="11"
|
|
|
- />
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 底部提交按钮 -->
|
|
|
- <view class="bottom-action-bar">
|
|
|
- <view class="submit-btn" @click="submitForm">
|
|
|
- <text class="btn-text">{{ isEditMode ? '保存修改' : '提交发布' }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 品类选择弹窗 -->
|
|
|
- <view class="picker-modal" v-if="showCategoryPicker" @click="showCategoryPicker = false">
|
|
|
- <view class="picker-content" @click.stop>
|
|
|
- <view class="picker-header">
|
|
|
- <text class="picker-title">选择收购品类</text>
|
|
|
- <text class="picker-close" @click="showCategoryPicker = false">×</text>
|
|
|
- </view>
|
|
|
- <view class="picker-options">
|
|
|
- <view
|
|
|
- class="picker-option"
|
|
|
- v-for="category in categoryOptions"
|
|
|
- :key="category"
|
|
|
- @click="selectCategory(category)"
|
|
|
- >
|
|
|
- <text class="option-text">{{ category }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
+ <view class="purchase-publish-container">
|
|
|
+ <!-- 表单内容 -->
|
|
|
+ <view class="form-container">
|
|
|
+ <!-- 收购标题 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">收购标题</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <input class="form-input" v-model="formData.title" placeholder="请输入收购标题"
|
|
|
+ placeholder-style="color: #999;" maxlength="30" @input="onTitleInput" />
|
|
|
+ <view class="char-count">{{ titleLength }}/30</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 收购品类 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">收购品类</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="category-selector" @click="showCategoryPicker = true">
|
|
|
+ <text class="selector-text" :class="{ placeholder: !formData.categoryId }">
|
|
|
+ <!-- {{ formData.categoryLabel || '请选择产品分类' }} -->
|
|
|
+ {{getDictLabel('agricultural_category',formData.categoryId) || '请选择产品分类' }}
|
|
|
+ </text>
|
|
|
+ <text class="arrow-icon">></text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item">
|
|
|
+ <!-- 所在地 -->
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">所在地</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <LocationPicker v-model="formData.location" mode="edit" />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 收购数量 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">收购数量</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="input-with-unit">
|
|
|
+ <input class="form-input" v-model="formData.quantity" placeholder="请输入收购数量"
|
|
|
+ placeholder-style="color: #999;" type="number" />
|
|
|
+ <!-- <text class="unit-text">斤</text> -->
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 单位-->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">单位</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="category-selector" @click="showUnitPicker = true">
|
|
|
+ <text class="selector-text" :class="{ placeholder: !formData.unit }">
|
|
|
+ <!-- {{ formData.dictLabel || '请选择价格单位' }} -->
|
|
|
+ {{ getDictLabel('agricultural_unit',formData.unit) || '请选择价格单位'}}
|
|
|
+ </text>
|
|
|
+ <text class="arrow-icon">></text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 单价预算 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">单价预算</text>
|
|
|
+ <text class="required">*</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="input-with-unit">
|
|
|
+ <text class="currency-symbol">¥</text>
|
|
|
+ <input class="form-input" v-model="formData.price" placeholder="请输入单价预算"
|
|
|
+ placeholder-style="color: #999;" type="digit" />
|
|
|
+ <!-- <text class="unit-text">元/斤</text> -->
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 补充说明 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">补充说明</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <textarea class="form-textarea" v-model="formData.description" placeholder="请描述交货要求、时间等补充信息"
|
|
|
+ placeholder-style="color: #999;" maxlength="200" auto-height @input="onDescInput" />
|
|
|
+ <view class="char-count">{{ descLength }}/200</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 上传参考图片 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">参考图片</text>
|
|
|
+ <text class="optional">(最多6张)</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="image-upload-area">
|
|
|
+ <view class="image-item" v-for="(image, index) in formData.images" :key="index">
|
|
|
+ <image class="uploaded-image" :src="image.url" mode="aspectFill"></image>
|
|
|
+ <view class="image-delete" @click="removeImage(index)">×</view>
|
|
|
+ </view>
|
|
|
+ <view class="image-upload-btn" v-if="formData.images.length < 6" @click="chooseImage">
|
|
|
+ <text class="upload-icon">+</text>
|
|
|
+ <text class="upload-text">上传图片</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 联系人信息 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label">
|
|
|
+ <text class="label-text">联系人信息</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="contact-input-row">
|
|
|
+ <text class="contact-label">联系人:</text>
|
|
|
+ <input class="contact-input" v-model="formData.contactName" placeholder="请输入联系人姓名"
|
|
|
+ placeholder-style="color: #999;" maxlength="10" />
|
|
|
+ </view>
|
|
|
+ <view class="contact-input-row">
|
|
|
+ <text class="contact-label">电话:</text>
|
|
|
+ <input class="contact-input" v-model="formData.contactPhone" placeholder="请输入联系电话"
|
|
|
+ placeholder-style="color: #999;" type="number" maxlength="11" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 底部提交按钮 -->
|
|
|
+ <view class="bottom-action-bar">
|
|
|
+ <view class="submit-btn" @click="submitForm">
|
|
|
+ <text class="btn-text">{{ isEditMode ? '保存修改' : '提交发布' }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 品类选择弹窗 -->
|
|
|
+ <view class="picker-modal" v-if="showCategoryPicker" @click="showCategoryPicker = false">
|
|
|
+ <view class="picker-content" @click.stop>
|
|
|
+ <view class="picker-header">
|
|
|
+ <text class="picker-title">选择收购品类</text>
|
|
|
+ <text class="picker-close" @click="showCategoryPicker = false">×</text>
|
|
|
+ </view>
|
|
|
+ <view class="picker-options">
|
|
|
+ <view class="picker-option"
|
|
|
+ v-for="category in dictDataOptions.agricultural_category"
|
|
|
+ :key="category.dictCode"
|
|
|
+ @click="selectCategory(category)"
|
|
|
+ :class="{ 'active': category.dictValue == formData.categoryId }">
|
|
|
+ <text class="option-text">{{ category.dictLabel }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 单位选择弹窗 -->
|
|
|
+ <view class="picker-modal" v-if="showUnitPicker" @click="showUnitPicker = false">
|
|
|
+ <view class="picker-content" @click.stop>
|
|
|
+ <view class="picker-header">
|
|
|
+ <text class="picker-title">选择价格单位</text>
|
|
|
+ <text class="picker-close" @click="showUnitPicker = false">×</text>
|
|
|
+ </view>
|
|
|
+ <view class="picker-options">
|
|
|
+ <view class="picker-option"
|
|
|
+ v-for="unit in dictDataOptions.agricultural_unit"
|
|
|
+ :key="unit.dictCode"
|
|
|
+ @click="selectUnit(unit)"
|
|
|
+ :class="{ 'active': unit.dictValue == formData.unit }">
|
|
|
+ <text class="option-text">{{ unit.dictLabel }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-export default {
|
|
|
- data() {
|
|
|
- return {
|
|
|
- isEditMode: false, // 是否为编辑模式
|
|
|
- editItemId: '', // 编辑的收购信息ID
|
|
|
- formData: {
|
|
|
- title: '',
|
|
|
- category: '',
|
|
|
- quantity: '',
|
|
|
- budgetPrice: '',
|
|
|
- description: '',
|
|
|
- images: [],
|
|
|
- contactName: '',
|
|
|
- contactPhone: ''
|
|
|
- },
|
|
|
- categoryOptions: ['蔬菜', '水果', '粮食', '其他'],
|
|
|
- showCategoryPicker: false,
|
|
|
- titleLength: 0,
|
|
|
- descLength: 0
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- onLoad(options) {
|
|
|
- // 检查是否为编辑模式
|
|
|
- if (options.action === 'edit' && options.id) {
|
|
|
- this.isEditMode = true;
|
|
|
- this.editItemId = options.id;
|
|
|
-
|
|
|
- // 设置页面标题
|
|
|
- uni.setNavigationBarTitle({
|
|
|
- title: '编辑收购信息'
|
|
|
- });
|
|
|
-
|
|
|
- // 加载收购信息数据
|
|
|
- this.loadPurchaseData();
|
|
|
- } else {
|
|
|
- // 新建模式
|
|
|
- this.isEditMode = false;
|
|
|
- uni.setNavigationBarTitle({
|
|
|
- title: '发布收购信息'
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- methods: {
|
|
|
- // 加载收购信息数据(编辑模式)
|
|
|
- loadPurchaseData() {
|
|
|
- // 模拟从API加载数据,实际应用中需要根据ID调用相应的API
|
|
|
- uni.showLoading({ title: '加载中...' });
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- // 收购信息的模拟数据
|
|
|
- const mockData = {
|
|
|
- title: '高价收购优质土豆',
|
|
|
- category: '蔬菜',
|
|
|
- quantity: '1000',
|
|
|
- budgetPrice: '3.5',
|
|
|
- description: '大量收购优质土豆,要求新鲜无病害,无青皮,规格统一。支持长期合作,价格优惠,现金结算。有货源的农户欢迎联系,我们提供上门收购服务。',
|
|
|
- images: [
|
|
|
- '/static/images/products/agriculture-tools.jpg'
|
|
|
- ],
|
|
|
- contactName: '李先生',
|
|
|
- contactPhone: '13856785678'
|
|
|
- };
|
|
|
-
|
|
|
- // 填充表单数据
|
|
|
- this.formData = { ...mockData };
|
|
|
-
|
|
|
- // 更新字符计数
|
|
|
- this.titleLength = this.formData.title.length;
|
|
|
- this.descLength = this.formData.description.length;
|
|
|
-
|
|
|
- uni.hideLoading();
|
|
|
- }, 1000);
|
|
|
- },
|
|
|
-
|
|
|
- // 标题输入处理
|
|
|
- onTitleInput(e) {
|
|
|
- this.titleLength = e.detail.value.length;
|
|
|
- },
|
|
|
-
|
|
|
- // 描述输入处理
|
|
|
- onDescInput(e) {
|
|
|
- this.descLength = e.detail.value.length;
|
|
|
- },
|
|
|
-
|
|
|
- // 选择品类
|
|
|
- selectCategory(category) {
|
|
|
- this.formData.category = category;
|
|
|
- this.showCategoryPicker = false;
|
|
|
- },
|
|
|
-
|
|
|
- // 选择图片
|
|
|
- chooseImage() {
|
|
|
- const remainingCount = 2 - this.formData.images.length;
|
|
|
- uni.chooseImage({
|
|
|
- count: remainingCount,
|
|
|
- sizeType: ['compressed'],
|
|
|
- sourceType: ['album', 'camera'],
|
|
|
- success: (res) => {
|
|
|
- this.formData.images = this.formData.images.concat(res.tempFilePaths);
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.error('选择图片失败:', err);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- // 删除图片
|
|
|
- removeImage(index) {
|
|
|
- this.formData.images.splice(index, 1);
|
|
|
- },
|
|
|
-
|
|
|
- // 表单验证
|
|
|
- validateForm() {
|
|
|
- if (!this.formData.title.trim()) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入收购标题',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.formData.category) {
|
|
|
- uni.showToast({
|
|
|
- title: '请选择收购品类',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.formData.quantity || this.formData.quantity <= 0) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入有效的收购数量',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.formData.budgetPrice || this.formData.budgetPrice <= 0) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入有效的单价预算',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.formData.contactName.trim()) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入联系人姓名',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.formData.contactPhone.trim()) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入联系电话',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 简单的手机号格式验证
|
|
|
- const phoneRegex = /^1[3-9]\d{9}$/;
|
|
|
- if (!phoneRegex.test(this.formData.contactPhone)) {
|
|
|
- uni.showToast({
|
|
|
- title: '请输入正确的手机号码',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
- },
|
|
|
-
|
|
|
- // 提交表单
|
|
|
- submitForm() {
|
|
|
- if (!this.validateForm()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 显示加载提示
|
|
|
- const loadingTitle = this.isEditMode ? '保存中...' : '提交中...';
|
|
|
- uni.showLoading({
|
|
|
- title: loadingTitle
|
|
|
- });
|
|
|
-
|
|
|
- // 模拟提交
|
|
|
- setTimeout(() => {
|
|
|
- uni.hideLoading();
|
|
|
-
|
|
|
- if (this.isEditMode) {
|
|
|
- // 编辑模式 - 保存修改
|
|
|
- uni.showModal({
|
|
|
- title: '保存成功',
|
|
|
- content: '您的修改已保存成功!',
|
|
|
- showCancel: false,
|
|
|
- success: () => {
|
|
|
- uni.navigateBack();
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 新建模式 - 提交发布
|
|
|
- uni.showToast({
|
|
|
- title: '发布成功',
|
|
|
- icon: 'success'
|
|
|
- });
|
|
|
-
|
|
|
- // 返回上一页
|
|
|
- setTimeout(() => {
|
|
|
- uni.navigateBack();
|
|
|
- }, 1500);
|
|
|
- }
|
|
|
- }, 2000);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+ import LocationPicker from "@/components/common/LocationPicker.vue"
|
|
|
+ import api from "@/config/api.js";
|
|
|
+ import storage from "@/utils/storage.js";
|
|
|
+ import {
|
|
|
+ addProductInfo,
|
|
|
+ getProductInfoById,
|
|
|
+ editProductInfo
|
|
|
+ } from '@/api/services/productInfo.js';
|
|
|
+ import dictMixin from '@/utils/mixins/dictMixin';
|
|
|
+ import {
|
|
|
+ getFormattedTime
|
|
|
+ } from '@/utils/dateUtils'
|
|
|
+ export default {
|
|
|
+ mixins: [dictMixin],
|
|
|
+ components: {
|
|
|
+ LocationPicker
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ dictTypeList: ['agricultural_unit', 'agricultural_category'],
|
|
|
+ isEditMode: false, // 是否为编辑模式
|
|
|
+ editItemId: '', // 编辑的收购信息ID
|
|
|
+ formData: {
|
|
|
+ title: '',
|
|
|
+ categoryId: '',
|
|
|
+ price: '',
|
|
|
+ description: '',
|
|
|
+ imageUrl: '',
|
|
|
+ images: [],
|
|
|
+ unit: '',
|
|
|
+ quantity: '',
|
|
|
+ contactName: '',
|
|
|
+ contactPhone: '',
|
|
|
+ location: '',
|
|
|
+ publishTime: getFormattedTime(), // 发布时间
|
|
|
+ userId: storage.getUserInfo().userid,
|
|
|
+ type: 1, // 收购
|
|
|
+ status: 1, // 审核中
|
|
|
+ },
|
|
|
+ // categoryOptions: ['蔬菜', '水果', '粮食', '其他'],
|
|
|
+ dictDataOptions: [],
|
|
|
+ showCategoryPicker: false,
|
|
|
+ showUnitPicker: false,
|
|
|
+ titleLength: 0,
|
|
|
+ descLength: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ onLoad(options) {
|
|
|
+ this.dictDataOptions = this.dictData
|
|
|
+ // 检查是否为编辑模式
|
|
|
+ if (options.action === 'edit' && options.id) {
|
|
|
+ this.isEditMode = true;
|
|
|
+ this.editItemId = options.id;
|
|
|
+
|
|
|
+ // 设置页面标题
|
|
|
+ uni.setNavigationBarTitle({
|
|
|
+ title: '编辑收购信息'
|
|
|
+ });
|
|
|
+
|
|
|
+ // 加载收购信息数据
|
|
|
+ this.loadPurchaseData();
|
|
|
+ } else {
|
|
|
+ // 新建模式
|
|
|
+ this.isEditMode = false;
|
|
|
+ uni.setNavigationBarTitle({
|
|
|
+ title: '发布收购信息'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ // 加载收购信息数据(编辑模式)
|
|
|
+ loadPurchaseData() {
|
|
|
+ // 模拟从API加载数据,实际应用中需要根据ID调用相应的API
|
|
|
+ uni.showLoading({
|
|
|
+ title: '加载中...'
|
|
|
+ });
|
|
|
+
|
|
|
+ getProductInfoById(this.editItemId).then(res=>{
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ // const { data } = res.data;
|
|
|
+ // this.formData = data
|
|
|
+ Object.assign(this.formData, res.data.data) // 保持响应式
|
|
|
+ // 更新字符计数
|
|
|
+ this.nameLength = this.formData.title.length;
|
|
|
+ this.descLength = this.formData.description.length;
|
|
|
+
|
|
|
+ console.log("this.goodsDetail", this.formData);
|
|
|
+ // 处理图片数据
|
|
|
+ if (this.formData.imageUrl) {
|
|
|
+ try {
|
|
|
+ this.formData.images = this.formData.imageUrl.split(',').map(url => ({ url,status: 'success' }))
|
|
|
+ console.log('解析后的图片数据:', this.formData.images);
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析图片数据失败:', e);
|
|
|
+ this.formData.images = [];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.formData.images = [];
|
|
|
+ }
|
|
|
+ uni.hideLoading();
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: res.data.msg || '获取农品信息失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 标题输入处理
|
|
|
+ onTitleInput(e) {
|
|
|
+ this.titleLength = e.detail.value.length;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 描述输入处理
|
|
|
+ onDescInput(e) {
|
|
|
+ this.descLength = e.detail.value.length;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选择分类
|
|
|
+ selectCategory(category) {
|
|
|
+ this.formData.categoryId = category.dictValue;
|
|
|
+ this.formData.categoryLabel = category.dictLabel;
|
|
|
+ this.showCategoryPicker = false;
|
|
|
+ },
|
|
|
+ // 选择单位
|
|
|
+ selectUnit(unit) {
|
|
|
+ this.formData.unit = unit.dictValue;
|
|
|
+ this.formData.dictLabel = unit.dictLabel;
|
|
|
+ this.showUnitPicker = false;
|
|
|
+ },
|
|
|
+ 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 : ''
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选择图片
|
|
|
+ chooseImage() {
|
|
|
+ uni.chooseImage({
|
|
|
+ count: 6 - this.formData.images.length,
|
|
|
+ sizeType: ['original', 'compressed'],
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
+ success: (res) => {
|
|
|
+ console.log('选择图片成功:', res);
|
|
|
+
|
|
|
+ // 验证文件类型和大小
|
|
|
+ const validFiles = [];
|
|
|
+ const invalidFiles = [];
|
|
|
+ const maxSize = 5 * 1024 * 1024; // 5MB 最大限制
|
|
|
+
|
|
|
+ // 检查每个文件
|
|
|
+ res.tempFiles.forEach((file, index) => {
|
|
|
+ // 检查文件类型
|
|
|
+ const isImage = /\.(jpg|jpeg|png|gif)$/i.test(file.name);
|
|
|
+ // 检查文件大小
|
|
|
+ const isValidSize = file.size <= maxSize;
|
|
|
+
|
|
|
+ if (isImage && isValidSize) {
|
|
|
+ validFiles.push(res.tempFilePaths[index]);
|
|
|
+ } else {
|
|
|
+ invalidFiles.push({
|
|
|
+ path: file.path,
|
|
|
+ size: file.size,
|
|
|
+ reason: !isImage ? '文件格式不支持' : '文件大于5MB'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 显示无效文件提示
|
|
|
+ if (invalidFiles.length > 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: `${invalidFiles.length}个文件无效,请检查格式和大小`,
|
|
|
+ icon: 'none',
|
|
|
+ duration: 2000
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有有效文件,则上传
|
|
|
+ if (validFiles.length > 0) {
|
|
|
+ this.uploadImages(validFiles);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error('选择图片失败:', err);
|
|
|
+ uni.showToast({
|
|
|
+ title: '选择图片失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传图片到服务器
|
|
|
+ uploadImages(tempFilePaths) {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '上传中...',
|
|
|
+ mask: true
|
|
|
+ });
|
|
|
+
|
|
|
+ // 上传成功的图片计数
|
|
|
+ let successCount = 0;
|
|
|
+ let failCount = 0;
|
|
|
+ const totalFiles = tempFilePaths.length;
|
|
|
+ const newImages = [];
|
|
|
+
|
|
|
+ // 遍历处理每张图片
|
|
|
+ tempFilePaths.forEach((path, index) => {
|
|
|
+ // 调用上传API
|
|
|
+ uni.uploadFile({
|
|
|
+ // url: api.serve + '/base/tasks/uploadTaskImage',
|
|
|
+ url: api.serve + '/file/upload',
|
|
|
+ filePath: path,
|
|
|
+ name: 'file', // 文件参数名称,需要与后端接口匹配
|
|
|
+ formData: {
|
|
|
+ type: 'task', // 标识文件类型,用于后端区分不同业务的文件
|
|
|
+ // directory: '/opt/app/nongxiaoyu/uploadImage' // 指定保存目录
|
|
|
+ },
|
|
|
+ header: {
|
|
|
+ 'Authorization': `Bearer ${storage.getAccessToken()}`
|
|
|
+ },
|
|
|
+ success: (res) => {
|
|
|
+ try {
|
|
|
+ const response = JSON.parse(res.data);
|
|
|
+ uni.showToast({
|
|
|
+ title: `返回: ${response.data}`,
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ if (response.code === 200) {
|
|
|
+ // 获取返回的URL
|
|
|
+ const imageUrl = response.data.url;
|
|
|
+ console.log('上传成功,返回的图片URL:', imageUrl);
|
|
|
+
|
|
|
+ // 上传成功,将图片信息添加到数组
|
|
|
+ newImages.push({
|
|
|
+ url: imageUrl, // 保存原始URL,在显示时会通过getImageUrl方法处理
|
|
|
+ path: path, // 保存本地路径用于预览
|
|
|
+ status: 'success',
|
|
|
+ fileName: response.data.fileName || '' // 保存文件名,如果后端返回的话
|
|
|
+ });
|
|
|
+ successCount++;
|
|
|
+ } else {
|
|
|
+ failCount++;
|
|
|
+ console.error('上传失败:', response.msg);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ failCount++;
|
|
|
+ uni.showToast({
|
|
|
+ title: `解析响应失败: ${e}`,
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ console.error('解析响应失败:', e);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ failCount++;
|
|
|
+ console.error('上传请求失败:', err);
|
|
|
+ uni.showToast({
|
|
|
+ title: `上传请求失败: ${err}`,
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ },
|
|
|
+ complete: () => {
|
|
|
+ // 当所有文件都已处理完成
|
|
|
+ if (successCount + failCount === totalFiles) {
|
|
|
+ if (newImages.length > 0) {
|
|
|
+ // 将新上传的图片添加到已有图片列表
|
|
|
+ this.formData.images = [...this.formData.images, ...newImages];
|
|
|
+ // 更新taskImages字段,将图片URL用逗号连接
|
|
|
+ this.formData.imageUrl = this.formData.images.map(item => item.url).join(',');
|
|
|
+ this.$set(this.formData, 'images', this.formData.images) // 确保视图刷新
|
|
|
+ // 显示成功提示
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: `成功上传${successCount}张图片`,
|
|
|
+ icon: 'success'
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 全部失败
|
|
|
+ uni.showToast({
|
|
|
+ title: `图片上传: ${newImages}`,
|
|
|
+ icon: 'none',
|
|
|
+ });
|
|
|
+ uni.hideLoading();
|
|
|
+ // uni.showToast({
|
|
|
+ // title: '图片上传失败',
|
|
|
+ // icon: 'none',
|
|
|
+ // });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ removeImage(index) {
|
|
|
+ uni.showModal({
|
|
|
+ title: '确认删除',
|
|
|
+ content: '确定要删除这张图片吗?',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ this.formData.images.splice(index, 1);
|
|
|
+
|
|
|
+ // 更新taskImages字段
|
|
|
+ this.formData.imageUrl = this.formData.images.map(item => item.url).join(',');
|
|
|
+ this.$set(this.formData, 'images', this.formData.images) // 确保视图刷新
|
|
|
+ uni.showToast({
|
|
|
+ title: '已删除',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 表单验证
|
|
|
+ validateForm() {
|
|
|
+ if (!this.formData.title.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入收购标题',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.formData.categoryId) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择收购品类',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.formData.quantity || this.formData.quantity <= 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入有效的收购数量',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.formData.price || this.formData.price <= 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入有效的单价预算',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.formData.contactName.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入联系人姓名',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.formData.contactPhone.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入联系电话',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 简单的手机号格式验证
|
|
|
+ const phoneRegex = /^1[3-9]\d{9}$/;
|
|
|
+ if (!phoneRegex.test(this.formData.contactPhone)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入正确的手机号码',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 提交表单
|
|
|
+ submitForm() {
|
|
|
+ if (!this.validateForm()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示加载提示
|
|
|
+ const loadingTitle = this.isEditMode ? '保存中...' : '提交中...';
|
|
|
+ uni.showLoading({
|
|
|
+ title: loadingTitle
|
|
|
+ });
|
|
|
+
|
|
|
+ uni.hideLoading();
|
|
|
+
|
|
|
+ if (this.isEditMode) {
|
|
|
+ editProductInfo(this.formData).then(res=>{
|
|
|
+ if(res.data.code === 200){
|
|
|
+ uni.showModal({
|
|
|
+ title: '保存成功',
|
|
|
+ content: '您的修改已保存成功!',
|
|
|
+ showCancel: false,
|
|
|
+ success: () => {
|
|
|
+ uni.navigateBack();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ uni.showToast({
|
|
|
+ title: res.data.msg || '提交失败,请稍后重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ console.error("提交异常:", err);
|
|
|
+ uni.showToast({
|
|
|
+ title: '网络错误,请检查后重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 新建模式 - 提交审核
|
|
|
+ console.log("this.formData",this.formData);
|
|
|
+ // const data = {
|
|
|
+ // userId: this.currentUserInfo.userid,
|
|
|
+ // type: 0 ,// 出售
|
|
|
+ // status: 1 ,// 审核中
|
|
|
+ // }
|
|
|
+ // this.formData = {...this.formData , ...data}
|
|
|
+ addProductInfo(this.formData).then(res=>{
|
|
|
+ console.log("新增出售农产品",res);
|
|
|
+ if(res.data.code === 200){
|
|
|
+ uni.showModal({
|
|
|
+ title: '提交成功',
|
|
|
+ content: '您的收购农产品信息已提交审核,审核通过后将在收购页面展示。',
|
|
|
+ showCancel: false,
|
|
|
+ success: () => {
|
|
|
+ uni.navigateBack();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ uni.showToast({
|
|
|
+ title: res.data.msg || '提交失败,请稍后重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ console.error("提交异常:", err);
|
|
|
+ uni.showToast({
|
|
|
+ title: '网络错误,请检查后重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
-.purchase-publish-container {
|
|
|
- min-height: 100vh;
|
|
|
- background-color: #f5f5f5;
|
|
|
- padding-bottom: calc(128rpx + env(safe-area-inset-bottom));
|
|
|
-}
|
|
|
-
|
|
|
-.form-container {
|
|
|
- padding: 20rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.form-item {
|
|
|
- background-color: #fff;
|
|
|
- border-radius: 12rpx;
|
|
|
- padding: 24rpx;
|
|
|
- margin-bottom: 16rpx;
|
|
|
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
-}
|
|
|
-
|
|
|
-.item-label {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 16rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.label-text {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
-
|
|
|
-.required {
|
|
|
- color: #ff4d4f;
|
|
|
- font-size: 28rpx;
|
|
|
- margin-left: 4rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.optional {
|
|
|
- color: #999;
|
|
|
- font-size: 24rpx;
|
|
|
- margin-left: 8rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.item-content {
|
|
|
- position: relative;
|
|
|
-}
|
|
|
-
|
|
|
-.form-input {
|
|
|
- width: 100%;
|
|
|
- height: 44rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- line-height: 44rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.form-textarea {
|
|
|
- width: 100%;
|
|
|
- min-height: 120rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- line-height: 1.5;
|
|
|
-}
|
|
|
-
|
|
|
-.char-count {
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- bottom: -4rpx;
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-
|
|
|
-// 品类选择器
|
|
|
-.category-selector {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- padding: 12rpx 0;
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
-}
|
|
|
-
|
|
|
-.selector-text {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
-
|
|
|
- &.placeholder {
|
|
|
- color: #999;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.arrow-icon {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-
|
|
|
-// 带单位的输入框
|
|
|
-.input-with-unit {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
- padding: 12rpx 0;
|
|
|
-}
|
|
|
-
|
|
|
-.currency-symbol {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- margin-right: 8rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.unit-text {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
- margin-left: 8rpx;
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
-
|
|
|
-// 图片上传
|
|
|
-.image-upload-area {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 16rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.image-item {
|
|
|
- position: relative;
|
|
|
- width: 160rpx;
|
|
|
- height: 160rpx;
|
|
|
- border-radius: 8rpx;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-
|
|
|
-.uploaded-image {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-
|
|
|
-.image-delete {
|
|
|
- position: absolute;
|
|
|
- top: -8rpx;
|
|
|
- right: -8rpx;
|
|
|
- width: 32rpx;
|
|
|
- height: 32rpx;
|
|
|
- background-color: #ff4d4f;
|
|
|
- color: #fff;
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- font-size: 20rpx;
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
-
|
|
|
-.image-upload-btn {
|
|
|
- width: 160rpx;
|
|
|
- height: 160rpx;
|
|
|
- border: 2rpx dashed #ddd;
|
|
|
- border-radius: 8rpx;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- background-color: #fafafa;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-icon {
|
|
|
- font-size: 48rpx;
|
|
|
- color: #999;
|
|
|
- margin-bottom: 8rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-
|
|
|
-// 联系人信息
|
|
|
-.contact-input-row {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 20rpx;
|
|
|
-
|
|
|
- &:last-child {
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.contact-label {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- width: 120rpx;
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
-
|
|
|
-.contact-input {
|
|
|
- flex: 1;
|
|
|
- height: 44rpx;
|
|
|
- font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- line-height: 44rpx;
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
- padding: 12rpx 0;
|
|
|
-}
|
|
|
-
|
|
|
-// 底部提交按钮
|
|
|
-.bottom-action-bar {
|
|
|
- position: fixed;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- width: 100%;
|
|
|
- background-color: #fff;
|
|
|
- border-top: 1rpx solid #f0f0f0;
|
|
|
- padding: 20rpx 30rpx;
|
|
|
- padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
|
- z-index: 1000;
|
|
|
- box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
- box-sizing: border-box;
|
|
|
-}
|
|
|
-
|
|
|
-.submit-btn {
|
|
|
- width: 100%;
|
|
|
- height: 88rpx;
|
|
|
- background-color: #4CAF50;
|
|
|
- border-radius: 12rpx;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- transition: background-color 0.2s ease;
|
|
|
- box-sizing: border-box;
|
|
|
-
|
|
|
- &:active {
|
|
|
- background-color: #45a049;
|
|
|
- }
|
|
|
-
|
|
|
- .btn-text {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #fff;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 品类选择弹窗
|
|
|
-.picker-modal {
|
|
|
- position: fixed;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background-color: rgba(0, 0, 0, 0.5);
|
|
|
- z-index: 2000;
|
|
|
- display: flex;
|
|
|
- align-items: flex-end;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-content {
|
|
|
- width: 100%;
|
|
|
- background-color: #fff;
|
|
|
- border-radius: 24rpx 24rpx 0 0;
|
|
|
- padding: 0;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-header {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- padding: 30rpx;
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-title {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-close {
|
|
|
- font-size: 36rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-options {
|
|
|
- padding: 20rpx 0;
|
|
|
-}
|
|
|
-
|
|
|
-.picker-option {
|
|
|
- padding: 24rpx 30rpx;
|
|
|
- border-bottom: 1rpx solid #f8f8f8;
|
|
|
- transition: background-color 0.2s ease;
|
|
|
-
|
|
|
- &:last-child {
|
|
|
- border-bottom: none;
|
|
|
- }
|
|
|
-
|
|
|
- &:active {
|
|
|
- background-color: #f5f5f5;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.option-text {
|
|
|
- font-size: 30rpx;
|
|
|
- color: #333;
|
|
|
-}
|
|
|
-</style>
|
|
|
+ .purchase-publish-container {
|
|
|
+ min-height: 100vh;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ padding-bottom: calc(128rpx + env(safe-area-inset-bottom));
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-container {
|
|
|
+ padding: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 24rpx;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-label {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .label-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .required {
|
|
|
+ color: #ff4d4f;
|
|
|
+ font-size: 28rpx;
|
|
|
+ margin-left: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .optional {
|
|
|
+ color: #999;
|
|
|
+ font-size: 24rpx;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-content {
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-input {
|
|
|
+ width: 100%;
|
|
|
+ height: 44rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 44rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-textarea {
|
|
|
+ width: 100%;
|
|
|
+ min-height: 120rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .char-count {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ bottom: -4rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 品类选择器
|
|
|
+ .category-selector {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 12rpx 0;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .selector-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+
|
|
|
+ &.placeholder {
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .arrow-icon {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 带单位的输入框
|
|
|
+ .input-with-unit {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+ padding: 12rpx 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .currency-symbol {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ margin-right: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .unit-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图片上传
|
|
|
+ .image-upload-area {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-item {
|
|
|
+ position: relative;
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .uploaded-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-delete {
|
|
|
+ position: absolute;
|
|
|
+ top: -8rpx;
|
|
|
+ right: -8rpx;
|
|
|
+ width: 32rpx;
|
|
|
+ height: 32rpx;
|
|
|
+ background-color: #ff4d4f;
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 20rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-upload-btn {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ border: 2rpx dashed #ddd;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: #fafafa;
|
|
|
+ }
|
|
|
+
|
|
|
+ .upload-icon {
|
|
|
+ font-size: 48rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .upload-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 联系人信息
|
|
|
+ .contact-input-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .contact-label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ width: 120rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .contact-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 44rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 44rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+ padding: 12rpx 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 底部提交按钮
|
|
|
+ .bottom-action-bar {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ width: 100%;
|
|
|
+ background-color: #fff;
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+ padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
|
+ z-index: 1000;
|
|
|
+ box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .submit-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 88rpx;
|
|
|
+ background-color: #4CAF50;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: background-color 0.2s ease;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ background-color: #45a049;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-text {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 品类选择弹窗
|
|
|
+ .picker-modal {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-color: rgba(0, 0, 0, 0.5);
|
|
|
+ z-index: 2000;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-content {
|
|
|
+ width: 100%;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 24rpx 24rpx 0 0;
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 30rpx;
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-close {
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-options {
|
|
|
+ padding: 20rpx 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-option {
|
|
|
+ padding: 24rpx 30rpx;
|
|
|
+ border-bottom: 1rpx solid #f8f8f8;
|
|
|
+ transition: background-color 0.2s ease;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .option-text {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+</style>
|