|
|
@@ -123,15 +123,20 @@
|
|
|
<span class="suffix-hint">公开后将显示在任务模板市场</span>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="封面图">
|
|
|
- <el-upload
|
|
|
- class="avatar-uploader"
|
|
|
- action="/api/upload"
|
|
|
- :show-file-list="false"
|
|
|
- :on-success="handleUploadSuccess"
|
|
|
- >
|
|
|
- <img v-if="form.coverImage" :src="form.coverImage" class="avatar">
|
|
|
- <i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
|
|
- </el-upload>
|
|
|
+ <div class="cover-uploader">
|
|
|
+ <el-upload
|
|
|
+ class="avatar-uploader"
|
|
|
+ :action="uploadActionUrl"
|
|
|
+ :headers="uploadHeaders"
|
|
|
+ :data="{ category: 'guide-packages' }"
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-success="handleUploadSuccess"
|
|
|
+ >
|
|
|
+ <img v-if="form.coverImage" :src="form.coverImage" class="avatar">
|
|
|
+ <i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
|
|
+ </el-upload>
|
|
|
+ <el-button size="small" plain icon="el-icon-picture-outline" @click="assetPickerVisible = true">从素材库选择</el-button>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="详细介绍">
|
|
|
<el-input type="textarea" v-model="form.description" :rows="4"></el-input>
|
|
|
@@ -212,25 +217,44 @@
|
|
|
</el-dialog>
|
|
|
|
|
|
</el-table>
|
|
|
+ <!-- 素材库选择器 -->
|
|
|
+ <AssetPicker
|
|
|
+ :visible.sync="assetPickerVisible"
|
|
|
+ mode="single"
|
|
|
+ asset-type="image"
|
|
|
+ category="guide-packages"
|
|
|
+ @select="onAssetPicked"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import SortMixin from '@/mixins/SortMixin'
|
|
|
import { getMyPackages, getGuidePackage, getGuidePackageItems, createPackage, updatePackage, submitPackageForReview, publishPackage, addPackageItem, updatePackageItem, deletePackageItem } from '@/api/guidePackage'
|
|
|
+import AssetPicker from '@/components/AssetPicker.vue'
|
|
|
|
|
|
export default {
|
|
|
name: 'GuidePackages',
|
|
|
mixins: [SortMixin],
|
|
|
+ components: { AssetPicker },
|
|
|
computed: {
|
|
|
tableHeight() {
|
|
|
return window.innerHeight - 340
|
|
|
+ },
|
|
|
+ uploadActionUrl() {
|
|
|
+ const baseURL = process.env.VUE_APP_BASE_API || ''
|
|
|
+ return baseURL + '/api/admin/file-record/upload'
|
|
|
+ },
|
|
|
+ uploadHeaders() {
|
|
|
+ const token = localStorage.getItem('token')
|
|
|
+ return token ? { Authorization: 'Bearer ' + token } : {}
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
loading: false,
|
|
|
saving: false,
|
|
|
+ assetPickerVisible: false,
|
|
|
tableData: [],
|
|
|
sortableColumns: { id: 'ID', name: '任务模板名称', cycleDays: '周期', price: '价格', category: '分类', status: '状态', shareCode: '分享码', createdAt: '创建时间' },
|
|
|
searchForm: { status: '' },
|
|
|
@@ -360,7 +384,21 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
handleUploadSuccess(res) {
|
|
|
- this.form.coverImage = res.data
|
|
|
+ // 素材库上传接口返回记录对象({ url, id, ... }),取原始 URL 入库
|
|
|
+ const url = res && res.data && res.data.url ? res.data.url : (res && res.data)
|
|
|
+ if (!url) {
|
|
|
+ this.$message.error('上传失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.form.coverImage = url
|
|
|
+ this.$message.success('上传成功')
|
|
|
+ },
|
|
|
+ onAssetPicked(records) {
|
|
|
+ const record = records && records[0]
|
|
|
+ if (!record) return
|
|
|
+ // 存库使用后端返回的原始 URL(生产为京东云绝对地址),避免把代理前缀写入数据库
|
|
|
+ this.form.coverImage = record.url
|
|
|
+ this.$message.success('已选择封面')
|
|
|
},
|
|
|
async handleSubmit(row) {
|
|
|
try {
|
|
|
@@ -456,6 +494,11 @@ export default {
|
|
|
<style scoped>
|
|
|
|
|
|
.code-text { font-family: monospace; color: var(--adm-primary); }
|
|
|
+.cover-uploader {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-end;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
.avatar-uploader .el-upload {
|
|
|
border: 1px dashed var(--adm-border-base);
|
|
|
border-radius: 6px;
|