wangfukang 1 week ago
parent
commit
552121a34c
  1. 2
      package1/buyFood/buyFood.vue
  2. 2
      package1/order/orderDetail.vue
  3. 2
      package1/planet/index.vue
  4. 145
      package1/tabbar/fishRelease.vue

2
package1/buyFood/buyFood.vue

@ -800,7 +800,7 @@
let shopId = this.createdOrderInfo.shopId || this.shopItem.id || this.shopItem.shopId || '';
return {
title: '天灵灵地灵灵,这个价格不拼真的不行!😭',
title: this.shopItem.shopName + '(任选商品即可省钱参团!这个价格不拼真的不行!😭)',
path: buildGroupHomeSharePath({
shopId: shopId,
groupId: groupId,

2
package1/order/orderDetail.vue

@ -1115,7 +1115,7 @@
let shopId = that.orderDetail.shopId || that.shopItem.id || '';
return {
title: '快来一起拼单吧!',
title: that.shopItem.shopName + '(任选商品即可省钱参团!这个价格不拼真的不行!😭)',
path: buildGroupHomeSharePath({
shopId: shopId,
groupId: groupId,

2
package1/planet/index.vue

@ -2540,7 +2540,7 @@
position: relative;
margin-top: 10rpx;
color: #8A6A26;
font-size: 26rpx;
font-size: 35rpx;
font-weight: 800;
}

145
package1/tabbar/fishRelease.vue

@ -4,11 +4,11 @@
<view class="back" @tap="back">
<uni-icons type="left" size="22" color="#18372f"></uni-icons>
</view>
<view class="header-title">发布校园二手</view>
<view class="header-title">{{isEdit ? '编辑校园二手' : '发布校园二手'}}</view>
<view class="header-sub">实名发布线下面交请勿提前转账</view>
<view class="tabs">
<view class="tab" :class="{ active: publishType == 'sell' }" @tap="switchType('sell')">出售</view>
<view class="tab" :class="{ active: publishType == 'want' }" @tap="switchType('want')">求购</view>
<view class="tab" :class="{ active: publishType == 'sell', disabled: isEdit }" @tap="switchType('sell')">出售</view>
<view class="tab" :class="{ active: publishType == 'want', disabled: isEdit }" @tap="switchType('want')">求购</view>
</view>
</view>
@ -57,7 +57,7 @@
<sp-editor
editor-id="fishReleaseEditor"
:toolbar-config="editorToolbarConfig"
:maxlength="2000"
:maxlength="1000"
:placeholder="publishType == 'sell' ? '描述成色、尺寸、交易地点、可取时间等' : '描述想要的物品、预算、交易地点、可取时间等'"
@init="initEditor"
@input="inputEditor"
@ -87,7 +87,7 @@
<view class="bottom-space"></view>
</view>
<view class="submit-bar" v-if="!keyboardOpen">
<view class="submit-bar">
<view class="submit-btn" :class="{ disabled: submitting }" @tap="submit">{{submitting ? '提交中...' : '提交发布'}}</view>
</view>
<view class="audit-mask" v-if="submitting">
@ -112,9 +112,11 @@
import SpEditor from '@/package1/components/sp-editor/components/sp-editor/sp-editor.vue'
import {
listFishCategories,
getFishGoodsDetail,
getFishWantDetail,
publishFishGoods,
publishFishWant,
uploadFishImage
uploadFishReleaseImage
} from '@/common/fishMarketApi.js'
export default {
@ -126,6 +128,10 @@
return {
statusBarTop: 24,
publishType: 'sell',
editId: '',
isEdit: false,
pendingEditDetail: null,
pendingEditorHtml: '',
categories: [],
selectedCategoryIndex: -1,
submitting: false,
@ -171,10 +177,17 @@
if (options && (options.type == 'want' || options.type == 'sell')) {
this.publishType = options.type
}
if (options && options.mode == 'edit' && options.id) {
this.isEdit = true
this.editId = options.id
}
if (uni.getMenuButtonBoundingClientRect) {
this.statusBarTop = uni.getMenuButtonBoundingClientRect().top || this.statusBarTop
}
this.loadCategories()
if (this.isEdit) {
this.loadEditDetail()
}
this.ensurePublishVerified()
this.bindKeyboardListener()
},
@ -194,6 +207,7 @@
uni.navigateBack({ fail: () => uni.switchTab({ url: '/pages/index/index' }) })
},
switchType(type) {
if (this.isEdit) return
this.publishType = type
if (type == 'want' && this.form.images.length > 1) {
this.form.images = this.form.images.slice(0, 1)
@ -215,7 +229,77 @@
const area = this.getArea()
listFishCategories(area.id || '').then(list => {
this.categories = Array.isArray(list) ? list : []
this.applyEditCategory()
})
},
loadEditDetail() {
const request = this.publishType == 'want' ? getFishWantDetail(this.editId) : getFishGoodsDetail(this.editId)
request.then(detail => {
if (!detail) return
this.pendingEditDetail = detail
this.applyEditDetail(detail)
})
},
applyEditDetail(detail) {
const contact = this.parseJsonObject(detail.contactInfo)
const imageList = detail.imageList && detail.imageList.length ? detail.imageList : this.parseJsonList(detail.images)
const tagList = this.publishType == 'sell' ? this.parseJsonList(detail.tags) : []
const content = detail.content || ''
this.form.title = detail.title || ''
this.form.price = String(this.publishType == 'want' ? (detail.expectedPrice || '') : (detail.price || ''))
this.form.originPrice = this.publishType == 'sell' && detail.originPrice ? String(detail.originPrice) : ''
this.form.content = content
this.form.contentText = this.extractText(content)
this.form.images = imageList.slice(0, this.maxImageCount)
this.form.wechat = contact.wechat || ''
this.form.phone = contact.phone || ''
this.form.tags = tagList.length ? tagList : (this.publishType == 'sell' ? ['可小刀'] : [])
this.pendingEditorHtml = content
this.applyEditCategory()
this.applyPendingEditorContent()
},
applyEditCategory() {
const detail = this.pendingEditDetail
if (!detail || !this.categories.length) return
const index = this.categories.findIndex(item => String(item.id) == String(detail.categoryId) || item.name == detail.categoryName)
this.selectedCategoryIndex = index > -1 ? index : this.selectedCategoryIndex
},
applyPendingEditorContent() {
if (!this.editorIns || !this.pendingEditorHtml) return
if (this.editorIns.setContents) {
this.editorIns.setContents({
html: this.pendingEditorHtml
})
}
},
parseJsonList(value) {
if (!value) return []
if (Array.isArray(value)) return value
try {
const parsed = JSON.parse(value)
return Array.isArray(parsed) ? parsed : []
} catch (e) {
return []
}
},
parseJsonObject(value) {
if (!value) return {}
if (typeof value === 'object') return value
try {
return JSON.parse(value) || {}
} catch (e) {
return {}
}
},
extractText(html) {
return String(html || '')
.replace(/<img[^>]*>/gi, '')
.replace(/<[^>]+>/g, '')
.replace(/&nbsp;/g, ' ')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&')
.trim()
},
async ensurePublishVerified() {
const profile = await getIeProfile().catch(() => null)
@ -242,14 +326,20 @@
success: async (res) => {
const paths = res.tempFilePaths || []
uni.showLoading({ title: '上传中...', mask: true })
const failMessages = []
try {
for (let i = 0; i < paths.length; i++) {
const url = await uploadFishImage(paths[i])
if (url) this.form.images.push(url)
const result = await uploadFishReleaseImage(paths[i])
if (result && result.passed && result.url) {
this.form.images.push(result.url)
} else {
failMessages.push((result && result.message) || '图片审核未通过,请更换图片')
}
}
} finally {
uni.hideLoading()
}
this.showUploadAuditFail(failMessages)
}
})
},
@ -258,32 +348,47 @@
},
initEditor(editor) {
this.editorIns = editor
this.applyPendingEditorContent()
},
inputEditor(e) {
this.form.content = e && e.html ? e.html : ''
this.form.contentText = e && e.text ? e.text : ''
},
overEditorMax() {
uni.showToast({ title: '内容最多2000字', icon: 'none' })
uni.showToast({ title: '内容最多1000字', icon: 'none' })
},
async upinEditorImage(tempFiles, editorCtx) {
const files = Array.isArray(tempFiles) ? tempFiles : []
if (!files.length || !editorCtx) return
uni.showLoading({ title: '上传中...', mask: true })
const failMessages = []
try {
for (let i = 0; i < files.length; i++) {
const filePath = files[i].tempFilePath || files[i].path
const url = filePath ? await uploadFishImage(filePath) : ''
if (url) {
const result = filePath ? await uploadFishReleaseImage(filePath) : null
if (result && result.passed && result.url) {
editorCtx.insertImage({
src: url,
src: result.url,
width: '90%'
})
} else {
failMessages.push((result && result.message) || '图片审核未通过,请更换图片')
}
}
} finally {
uni.hideLoading()
}
this.showUploadAuditFail(failMessages)
},
showUploadAuditFail(messages) {
if (!messages || !messages.length) return
const uniq = Array.from(new Set(messages.filter(Boolean)))
uni.showModal({
title: '图片审核未通过',
content: uniq.join('\n'),
showCancel: false,
confirmText: '知道了'
})
},
toggleTag(tag) {
const index = this.form.tags.indexOf(tag)
@ -327,7 +432,7 @@
if (this.publishType == 'want' && this.form.images.length > 1) return '求购最多上传1张图片'
if (!contentText) return this.publishType == 'sell' ? '请填写商品介绍' : '请填写求购内容'
if (contentText.length < 5) return this.publishType == 'sell' ? '商品介绍至少5个字' : '求购内容至少5个字'
if (!wechat && !phone) return '请至少填写一种联系方式'
if (contentText.length > 1000) return this.publishType == 'sell' ? '商品介绍最多1000字' : '求购内容最多1000字'
if (wechat && !this.isValidWechat(wechat)) return '请输入正确的微信号'
if (phone && !this.isValidPhone(phone)) return '请输入正确的手机号'
return ''
@ -366,11 +471,13 @@
const area = this.getArea()
const category = this.categories[this.selectedCategoryIndex]
const payload = {
id: this.isEdit ? this.editId : undefined,
publishType: this.publishType,
regionId: area.id || '',
regionName: area.title || '',
title: this.form.title,
content: this.form.content,
contentText: this.form.contentText,
price: this.publishType == 'sell' ? Number(this.form.price) : undefined,
originPrice: this.form.originPrice ? Number(this.form.originPrice) : undefined,
expectedPrice: this.publishType == 'want' ? Number(this.form.price) : undefined,
@ -385,11 +492,11 @@
negotiable: this.form.tags.indexOf('可小刀') > -1 ? 1 : 0
}
this.submitting = true
this.auditTitle = '提交中,等待审核'
this.auditTitle = this.isEdit ? '保存中,等待审核' : '提交中,等待审核'
const res = this.publishType == 'sell' ? await publishFishGoods(payload) : await publishFishWant(payload)
if (res) {
submitSuccess = true
this.auditTitle = '提交成功,等待审核'
this.auditTitle = this.isEdit ? '保存成功,等待审核' : '提交成功,等待审核'
setTimeout(() => uni.navigateBack(), 800)
}
} finally {
@ -403,7 +510,7 @@
return {
badge: '校园二手',
title: '实名认证',
content: '根据法律法规要求,对应流程需要实名认证。',
content: '根据法律法规要求,对应流程需要调用阿里云实名认证。半径里不会存储您的实名信息。',
steps: []
}
}
@ -486,6 +593,10 @@
box-shadow: 0 8rpx 18rpx rgba(36, 185, 121, 0.22);
}
.tab.disabled {
opacity: .72;
}
.form-card {
margin: 0 24rpx;
padding: 4rpx 26rpx 26rpx;
@ -755,6 +866,6 @@
}
.bottom-space {
height: 160rpx;
height: 240rpx;
}
</style>

Loading…
Cancel
Save