|
|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
<template>
|
|
|
|
|
<el-dialog :visible.sync="visible" width="70%" title="编辑供需">
|
|
|
|
|
<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">
|
|
|
|
|
@ -8,48 +8,105 @@
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="标题">
|
|
|
|
|
<el-input v-model="form.title" maxlength="50" show-word-limit></el-input>
|
|
|
|
|
<el-input v-model="form.title" maxlength="50" show-word-limit />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="详细描述">
|
|
|
|
|
<el-input type="textarea" v-model="form.content" :rows="4" maxlength="200" show-word-limit></el-input>
|
|
|
|
|
<el-input v-model="form.content" type="textarea" :rows="4" maxlength="200" show-word-limit />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="行业标签">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="tagInput"
|
|
|
|
|
placeholder="输入后回车键确认"
|
|
|
|
|
style="margin-bottom: 8px;"
|
|
|
|
|
@keyup.enter.native="addTag"
|
|
|
|
|
@blur="addTag"
|
|
|
|
|
style="margin-bottom: 8px;"
|
|
|
|
|
/>
|
|
|
|
|
<div>
|
|
|
|
|
<el-tag
|
|
|
|
|
v-for="(tag, idx) in tagList"
|
|
|
|
|
:key="tag + idx"
|
|
|
|
|
closable
|
|
|
|
|
@close="removeTag(idx)"
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<!-- 图片上传 -->
|
|
|
|
|
<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'"
|
|
|
|
|
@click="form.contactType = 'wechat'"
|
|
|
|
|
icon="el-icon-chat-dot-round"
|
|
|
|
|
@click="form.contactType = 'wechat'"
|
|
|
|
|
>微信</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
:type="form.contactType === 'mobile' ? 'primary' : 'default'"
|
|
|
|
|
@click="form.contactType = 'mobile'"
|
|
|
|
|
icon="el-icon-phone"
|
|
|
|
|
@click="form.contactType = 'mobile'"
|
|
|
|
|
>电话</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
:type="form.contactType === 'email' ? 'primary' : 'default'"
|
|
|
|
|
@click="form.contactType = 'email'"
|
|
|
|
|
icon="el-icon-message"
|
|
|
|
|
@click="form.contactType = 'email'"
|
|
|
|
|
>邮箱</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="margin-top: 12px;">
|
|
|
|
|
@ -69,44 +126,121 @@
|
|
|
|
|
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="$emit('update:visible', false)">取消</el-button>
|
|
|
|
|
<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: Object
|
|
|
|
|
detail: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => null
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
dialogVisible: false,
|
|
|
|
|
form: {
|
|
|
|
|
type: 1,
|
|
|
|
|
title: '',
|
|
|
|
|
content: '',
|
|
|
|
|
contactType: 'mobile',
|
|
|
|
|
mobile: '',
|
|
|
|
|
wechat: '',
|
|
|
|
|
email: ''
|
|
|
|
|
email: '',
|
|
|
|
|
publicWay: 1,
|
|
|
|
|
validityType: 'longterm',
|
|
|
|
|
expireTime: '',
|
|
|
|
|
contactName: ''
|
|
|
|
|
},
|
|
|
|
|
tagInput: '',
|
|
|
|
|
tagList: []
|
|
|
|
|
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: '',
|
|
|
|
|
contactType: 'mobile',
|
|
|
|
|
mobile: '',
|
|
|
|
|
wechat: '',
|
|
|
|
|
email: '',
|
|
|
|
|
publicWay: 1,
|
|
|
|
|
validityType: 'longterm',
|
|
|
|
|
expireTime: '',
|
|
|
|
|
contactName: ''
|
|
|
|
|
}
|
|
|
|
|
this.tagList = []
|
|
|
|
|
this.imageList = []
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.form = {
|
|
|
|
|
...val,
|
|
|
|
|
contactType: val.wechat ? 'wechat' : val.email ? 'email' : 'mobile'
|
|
|
|
|
id: val.id,
|
|
|
|
|
type: val.type || 1,
|
|
|
|
|
title: val.title || '',
|
|
|
|
|
content: val.content || '',
|
|
|
|
|
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]) || '' })) : [])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -121,6 +255,63 @@ export default {
|
|
|
|
|
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,
|
|
|
|
|
@ -130,13 +321,24 @@ export default {
|
|
|
|
|
wechat: this.form.wechat,
|
|
|
|
|
mobile: this.form.mobile,
|
|
|
|
|
email: this.form.email,
|
|
|
|
|
type: this.form.type
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
// 如果存在新上传的文件,确保它们都包含在 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.$emit('update:visible', false)
|
|
|
|
|
this.dialogVisible = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -147,4 +349,4 @@ export default {
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</style>
|
|
|
|
|
|