shinnosuke
2026-09-21 7844f5af457ff3b7d3f8eeac8799e8d281e635a1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules, UploadFile } from 'element-plus'
import { createAdminNews, uploadAdminImage } from '../api/admin'
import AdminRichTextEditor from '../components/AdminRichTextEditor.vue'
 
interface NewsForm {
  title: string
  summary: string
  source: string
  content: string
  pinned: boolean
  coverUrl: string
  sortNo: number
  status: number
}
 
const form = reactive<NewsForm>({
  title: '',
  summary: '',
  source: '',
  content: '',
  pinned: true,
  coverUrl: '',
  sortNo: 0,
  status: 1,
})
 
const router = useRouter()
const formRef = ref<FormInstance>()
 
const stripHtml = (value: string) => value.replace(/<[^>]*>/g, '').replace(/&nbsp;/g, '').trim()
const rules: FormRules = {
  title: [{ required: true, message: '请输入资讯标题', trigger: 'blur' }],
  summary: [{ required: true, message: '请输入资讯标签', trigger: 'blur' }],
  content: [{
    required: true,
    trigger: 'change',
    validator: (_rule, value: string, callback) => {
      if (!stripHtml(value || '')) callback(new Error('请输入资讯内容'))
      else callback()
    },
  }],
  coverUrl: [{ required: true, message: '请上传封面图', trigger: 'change' }],
}
 
async function uploadCover(file: UploadFile) {
  if (!file.raw) return
  const result = await uploadAdminImage(file.raw)
  form.coverUrl = result.url
  await formRef.value?.validateField('coverUrl')
  ElMessage.success('封面图上传成功')
}
 
function validateContent() {
  void formRef.value?.validateField('content')
}
 
async function saveNews() {
  const valid = await formRef.value?.validate().catch(() => false)
  if (!valid) return
  await createAdminNews({
    title: form.title.trim(),
    summary: form.summary.trim(),
    source: form.source.trim(),
    content: form.content,
    coverUrl: form.coverUrl.trim(),
    isTop: form.pinned,
    sortNo: form.sortNo,
    status: form.status,
  })
  ElMessage.success(form.status === 1 ? '资讯已发布' : '草稿已保存')
  router.push('/talent-news-management')
}
</script>
 
<template>
  <div class="news-publish-page">
    <section class="news-publish-panel">
      <h3>资讯内容</h3>
 
      <el-form ref="formRef" class="news-publish-form" :model="form" :rules="rules" label-width="96px" label-position="left">
        <el-form-item label="资讯标题" prop="title" required>
          <el-input v-model="form.title" placeholder="资讯标题" />
        </el-form-item>
 
        <el-form-item label="资讯标签" prop="summary" required>
          <el-input v-model="form.summary" placeholder="资讯标签" />
        </el-form-item>
 
        <el-form-item class="news-editor-form-item" label="资讯内容" prop="content" required>
          <AdminRichTextEditor v-model="form.content" placeholder="请输入资讯内容" @update:model-value="validateContent" />
        </el-form-item>
 
        <el-form-item label="是否置顶">
          <el-switch v-model="form.pinned" />
        </el-form-item>
 
        <el-form-item class="admin-image-size-form-item" label="封面图" prop="coverUrl" required>
          <el-upload class="article-cover-upload" accept="image/*" :auto-upload="false" :show-file-list="false" :on-change="uploadCover">
            <el-image v-if="form.coverUrl" class="article-cover-preview" :src="form.coverUrl" fit="cover" />
            <div v-else class="article-cover-upload-card"><span>+</span><small>上传图片</small></div>
          </el-upload>
          <div class="admin-image-size-tip">推荐尺寸 236 × 168 px(小程序资讯列表缩略图;首页置顶大图会按 712 × 205 裁剪)</div>
        </el-form-item>
 
        <el-form-item>
          <el-button type="primary" @click="saveNews">保存</el-button>
        </el-form-item>
      </el-form>
    </section>
  </div>
</template>