|
|
<template>
|
|
|
<el-dialog :visible.sync="dialogVisible" width="70%" title="编辑供需">
|
|
|
<el-form :model="form" label-width="80px">
|
|
|
<el-form-item label="供需类型">
|
|
|
<el-radio-group v-model="form.type">
|
|
|
<el-radio :label="1">供应</el-radio>
|
|
|
<el-radio :label="2">需求</el-radio>
|
|
|
<el-radio :label="3">投融资</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="标题">
|
|
|
<el-input v-model="form.title" maxlength="50" show-word-limit />
|
|
|
</el-form-item>
|
|
|
<!-- 非投融资时显示原有描述与行业标签 -->
|
|
|
<el-form-item v-if="form.type !== 3" label="详细描述">
|
|
|
<el-input v-model="form.content" type="textarea" :rows="4" maxlength="200" show-word-limit />
|
|
|
</el-form-item>
|
|
|
<el-form-item v-if="form.type !== 3" label="行业标签">
|
|
|
<el-input
|
|
|
v-model="tagInput"
|
|
|
placeholder="输入后回车键确认"
|
|
|
style="margin-bottom: 8px;"
|
|
|
@keyup.enter.native="addTag"
|
|
|
@blur="addTag"
|
|
|
/>
|
|
|
<div>
|
|
|
<el-tag
|
|
|
v-for="(tag, idx) in tagList"
|
|
|
:key="tag + idx"
|
|
|
closable
|
|
|
style="margin-right: 8px;"
|
|
|
@close="removeTag(idx)"
|
|
|
>{{ tag }}</el-tag>
|
|
|
</div>
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">
|
|
|
建议添加相关行业标签,方便其他校友找到你
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 投融资专属字段:当 type === 3 时显示 -->
|
|
|
<template v-if="form.type === 3">
|
|
|
<el-form-item label="资金类型">
|
|
|
<el-select v-model="form.fund_type" placeholder="请选择资金类型" style="width: 240px;">
|
|
|
<el-option label="投资" value="投资" />
|
|
|
<el-option label="融资" value="融资" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="金额">
|
|
|
<el-input-number v-model="form.amount" :precision="2" :step="0.01" :min="0" style="width: 240px;" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="融资阶段">
|
|
|
<el-input v-model="form.fund_stage" maxlength="50" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="期望资金属性">
|
|
|
<el-input v-model="form.expect_fund_attr" maxlength="50" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="行业类型">
|
|
|
<el-input v-model="form.industry_type" maxlength="50" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="主要产品">
|
|
|
<el-input v-model="form.product" maxlength="50" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="简要描述">
|
|
|
<el-input v-model="form.desc" type="textarea" :rows="4" maxlength="200" show-word-limit />
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
|
|
|
<!-- 图片上传 -->
|
|
|
<el-form-item label="相关图片">
|
|
|
<el-upload
|
|
|
list-type="picture-card"
|
|
|
:file-list="imageList"
|
|
|
:on-preview="handlePictureCardPreview"
|
|
|
:on-remove="handleRemove"
|
|
|
:before-upload="beforeImageUpload"
|
|
|
:on-success="handleUploadSuccess"
|
|
|
:http-request="handleCustomUpload"
|
|
|
multiple
|
|
|
>
|
|
|
<i class="el-icon-plus" />
|
|
|
</el-upload>
|
|
|
<el-dialog :visible.sync="previewVisible">
|
|
|
<img width="100%" :src="previewImage" alt="">
|
|
|
</el-dialog>
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">
|
|
|
最多上传9张图片,支持jpg、png格式,单张不超过2MB
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 时效性选择 -->
|
|
|
<el-form-item label="时效性">
|
|
|
<el-radio-group v-model="form.validityType">
|
|
|
<el-radio label="longterm">长期有效</el-radio>
|
|
|
<el-radio label="specific">具体日期</el-radio>
|
|
|
</el-radio-group>
|
|
|
<div v-if="form.validityType === 'specific'" style="margin-top: 12px;">
|
|
|
<el-date-picker
|
|
|
v-model="form.expireTime"
|
|
|
type="date"
|
|
|
placeholder="选择到期日期"
|
|
|
format="yyyy-MM-dd"
|
|
|
value-format="yyyy-MM-dd"
|
|
|
:picker-options="pickerOptions"
|
|
|
/>
|
|
|
</div>
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">
|
|
|
<span v-if="form.validityType === 'longterm'">此信息长期有效</span>
|
|
|
<span v-else>到期后将归入历史供需信息,不再提供私信等操作</span>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 联系人 -->
|
|
|
<el-form-item label="联系人" required>
|
|
|
<el-input
|
|
|
v-model="form.contactName"
|
|
|
placeholder="请输入联系人姓名"
|
|
|
maxlength="20"
|
|
|
show-word-limit
|
|
|
/>
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">
|
|
|
默认为您的姓名,可修改
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="联系方式" required>
|
|
|
<div class="contact-type-group">
|
|
|
<el-button
|
|
|
:type="form.contactType === 'wechat' ? 'primary' : 'default'"
|
|
|
icon="el-icon-chat-dot-round"
|
|
|
@click="form.contactType = 'wechat'"
|
|
|
>微信</el-button>
|
|
|
<el-button
|
|
|
:type="form.contactType === 'mobile' ? 'primary' : 'default'"
|
|
|
icon="el-icon-phone"
|
|
|
@click="form.contactType = 'mobile'"
|
|
|
>电话</el-button>
|
|
|
<el-button
|
|
|
:type="form.contactType === 'email' ? 'primary' : 'default'"
|
|
|
icon="el-icon-message"
|
|
|
@click="form.contactType = 'email'"
|
|
|
>邮箱</el-button>
|
|
|
</div>
|
|
|
<div style="margin-top: 12px;">
|
|
|
<el-input
|
|
|
v-if="form.contactType === 'wechat'"
|
|
|
v-model="form.wechat"
|
|
|
placeholder="请输入微信号"
|
|
|
/>
|
|
|
<el-input
|
|
|
v-if="form.contactType === 'mobile'"
|
|
|
v-model="form.mobile"
|
|
|
placeholder="请输入手机号"
|
|
|
/>
|
|
|
<el-input
|
|
|
v-if="form.contactType === 'email'"
|
|
|
v-model="form.email"
|
|
|
placeholder="请输入邮箱"
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
<!-- 联系方式公开模式 -->
|
|
|
<div style="margin-top: 16px;">
|
|
|
<div style="margin-bottom: 8px; color: #606266; font-size: 14px;">公开模式:</div>
|
|
|
<el-radio-group v-model="form.publicWay">
|
|
|
<el-radio :label="1">直接公开</el-radio>
|
|
|
<el-radio :label="2">私信后自动公开</el-radio>
|
|
|
<el-radio :label="3">不公开</el-radio>
|
|
|
</el-radio-group>
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">
|
|
|
<span v-if="form.publicWay === 1">联系方式将直接显示给所有用户</span>
|
|
|
<span v-else-if="form.publicWay === 2">用户私信后联系方式自动公开</span>
|
|
|
<span v-else>联系方式不会公开显示</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
<el-button @click="handleCancel">取消</el-button>
|
|
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { uploads } from '@/api/uploads'
|
|
|
export default {
|
|
|
props: {
|
|
|
visible: Boolean,
|
|
|
detail: {
|
|
|
type: Object,
|
|
|
default: () => null
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
dialogVisible: false,
|
|
|
form: {
|
|
|
type: 1,
|
|
|
title: '',
|
|
|
content: '',
|
|
|
// 投融资专属字段
|
|
|
fund_type: '',
|
|
|
amount: 0,
|
|
|
fund_stage: '',
|
|
|
expect_fund_attr: '',
|
|
|
industry_type: '',
|
|
|
product: '',
|
|
|
desc: '',
|
|
|
contactType: 'mobile',
|
|
|
mobile: '',
|
|
|
wechat: '',
|
|
|
email: '',
|
|
|
publicWay: 1,
|
|
|
validityType: 'longterm',
|
|
|
expireTime: '',
|
|
|
contactName: ''
|
|
|
},
|
|
|
tagInput: '',
|
|
|
tagList: [],
|
|
|
imageList: [],
|
|
|
newUploadedFileIds: [],
|
|
|
previewVisible: false,
|
|
|
previewImage: '',
|
|
|
pickerOptions: {
|
|
|
disabledDate(time) {
|
|
|
return time.getTime() < Date.now() - 8.64e7
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
visible: {
|
|
|
immediate: true,
|
|
|
handler(val) {
|
|
|
this.dialogVisible = val
|
|
|
}
|
|
|
},
|
|
|
dialogVisible(val) {
|
|
|
this.$emit('update:visible', val)
|
|
|
},
|
|
|
detail: {
|
|
|
immediate: true,
|
|
|
handler(val) {
|
|
|
if (!val) {
|
|
|
// 如果 detail 为 null,重置表单为默认值
|
|
|
this.form = {
|
|
|
type: 1,
|
|
|
title: '',
|
|
|
content: '',
|
|
|
fund_type: '',
|
|
|
amount: 0,
|
|
|
fund_stage: '',
|
|
|
expect_fund_attr: '',
|
|
|
industry_type: '',
|
|
|
product: '',
|
|
|
desc: '',
|
|
|
contactType: 'mobile',
|
|
|
mobile: '',
|
|
|
wechat: '',
|
|
|
email: '',
|
|
|
publicWay: 1,
|
|
|
validityType: 'longterm',
|
|
|
expireTime: '',
|
|
|
contactName: ''
|
|
|
}
|
|
|
this.tagList = []
|
|
|
this.imageList = []
|
|
|
return
|
|
|
}
|
|
|
this.form = {
|
|
|
id: val.id,
|
|
|
type: val.type || 1,
|
|
|
title: val.title || '',
|
|
|
content: val.content || '',
|
|
|
fund_type: val.fund_type || '',
|
|
|
amount: typeof val.amount === 'number' ? val.amount : (parseFloat(val.amount) || 0),
|
|
|
fund_stage: val.fund_stage || '',
|
|
|
expect_fund_attr: val.expect_fund_attr || '',
|
|
|
industry_type: val.industry_type || '',
|
|
|
product: val.product || '',
|
|
|
desc: val.desc || '',
|
|
|
contactType: val.wechat ? 'wechat' : (val.email ? 'email' : 'mobile'),
|
|
|
mobile: val.mobile || '',
|
|
|
wechat: val.wechat || '',
|
|
|
email: val.email || '',
|
|
|
publicWay: val.public_way || 1,
|
|
|
validityType: val.expire_time ? 'specific' : 'longterm',
|
|
|
expireTime: val.expire_time || '',
|
|
|
contactName: val.contact_name || ''
|
|
|
}
|
|
|
this.tagList = Array.isArray(val.tag)
|
|
|
? val.tag
|
|
|
: (val.tag ? val.tag.split(',').filter(Boolean) : [])
|
|
|
this.imageList = Array.isArray(val.files)
|
|
|
? val.files.map(f => ({ id: f.id, url: f.url, name: f.original_name || '' }))
|
|
|
: (Array.isArray(val.file_ids) ? val.file_ids.map(id => ({ id, url: (val.images && val.images[id]) || '' })) : [])
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
addTag() {
|
|
|
const val = this.tagInput && this.tagInput.trim()
|
|
|
if (val && !this.tagList.includes(val)) {
|
|
|
this.tagList.push(val)
|
|
|
}
|
|
|
this.tagInput = ''
|
|
|
},
|
|
|
removeTag(idx) {
|
|
|
this.tagList.splice(idx, 1)
|
|
|
},
|
|
|
// 图片上传相关方法
|
|
|
handlePictureCardPreview(file) {
|
|
|
this.previewImage = file.url
|
|
|
this.previewVisible = true
|
|
|
},
|
|
|
handleRemove(file, fileList) {
|
|
|
this.imageList = fileList
|
|
|
// 同步移除已记录的新上传ID
|
|
|
const removedId = file.response?.id || file.id
|
|
|
if (removedId) {
|
|
|
this.newUploadedFileIds = this.newUploadedFileIds.filter(id => id !== removedId)
|
|
|
}
|
|
|
},
|
|
|
handleUploadSuccess(response, file, fileList) {
|
|
|
this.imageList = fileList
|
|
|
},
|
|
|
async handleCustomUpload({ file, onSuccess, onError }) {
|
|
|
try {
|
|
|
const formData = new FormData()
|
|
|
formData.append('file', file)
|
|
|
const res = await uploads(formData)
|
|
|
// 兼容返回结构
|
|
|
const uploadedId = res.id || res.data?.id
|
|
|
const uploadedUrl = res.url || res.data?.url
|
|
|
const responsePayload = { id: uploadedId, url: uploadedUrl }
|
|
|
// 记录ID
|
|
|
if (uploadedId) this.newUploadedFileIds.push(uploadedId)
|
|
|
// 通知 el-upload 成功
|
|
|
onSuccess(responsePayload, file)
|
|
|
} catch (e) {
|
|
|
onError(e)
|
|
|
}
|
|
|
},
|
|
|
beforeImageUpload(file) {
|
|
|
const isJPG = file.type === 'image/jpeg'
|
|
|
const isPNG = file.type === 'image/png'
|
|
|
const isLt2M = file.size / 1024 / 1024 < 2
|
|
|
const isLt9 = this.imageList.length < 9
|
|
|
|
|
|
if (!isJPG && !isPNG) {
|
|
|
this.$message.error('上传图片只能是 JPG/PNG 格式!')
|
|
|
return false
|
|
|
}
|
|
|
if (!isLt2M) {
|
|
|
this.$message.error('上传图片大小不能超过 2MB!')
|
|
|
return false
|
|
|
}
|
|
|
if (!isLt9) {
|
|
|
this.$message.error('最多只能上传9张图片!')
|
|
|
return false
|
|
|
}
|
|
|
return true
|
|
|
},
|
|
|
handleCancel() {
|
|
|
this.dialogVisible = false
|
|
|
this.newUploadedFileIds = []
|
|
|
},
|
|
|
handleSave() {
|
|
|
const data = {
|
|
|
id: this.form.id,
|
|
|
title: this.form.title,
|
|
|
content: this.form.type === 3 ? '' : this.form.content,
|
|
|
tag: this.tagList.join(','),
|
|
|
wechat: this.form.wechat,
|
|
|
mobile: this.form.mobile,
|
|
|
email: this.form.email,
|
|
|
type: this.form.type,
|
|
|
public_way: this.form.publicWay,
|
|
|
validity_type: this.form.validityType,
|
|
|
expire_time: this.form.validityType === 'specific' ? this.form.expireTime : null,
|
|
|
contact_name: this.form.contactName,
|
|
|
file_ids: this.imageList.map(item => item.response?.id || item.id).filter(Boolean)
|
|
|
}
|
|
|
// 投融资类型下提交专属字段,其它类型清空
|
|
|
if (this.form.type === 3) {
|
|
|
data.fund_type = this.form.fund_type
|
|
|
data.amount = this.form.amount
|
|
|
data.fund_stage = this.form.fund_stage
|
|
|
data.expect_fund_attr = this.form.expect_fund_attr
|
|
|
data.industry_type = this.form.industry_type
|
|
|
data.product = this.form.product
|
|
|
data.desc = this.form.desc
|
|
|
// 投融资不提交行业标签与原描述
|
|
|
data.tag = ''
|
|
|
} else {
|
|
|
data.fund_type = ''
|
|
|
data.amount = 0
|
|
|
data.fund_stage = ''
|
|
|
data.expect_fund_attr = ''
|
|
|
data.industry_type = ''
|
|
|
data.product = ''
|
|
|
data.desc = ''
|
|
|
}
|
|
|
// 如果存在新上传的文件,确保它们都包含在 file_ids 中
|
|
|
if (this.newUploadedFileIds && this.newUploadedFileIds.length) {
|
|
|
const fileIdSet = new Set(data.file_ids)
|
|
|
this.newUploadedFileIds.forEach(id => fileIdSet.add(id))
|
|
|
data.file_ids = Array.from(fileIdSet)
|
|
|
}
|
|
|
if (this.form.contactType !== 'wechat') data.wechat = ''
|
|
|
if (this.form.contactType !== 'mobile') data.mobile = ''
|
|
|
if (this.form.contactType !== 'email') data.email = ''
|
|
|
this.$emit('save', data)
|
|
|
this.dialogVisible = false
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
.contact-type-group {
|
|
|
display: flex;
|
|
|
gap: 12px;
|
|
|
margin-bottom: 8px;
|
|
|
}
|
|
|
</style>
|