From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mp/draft/components/NewsForm.vue |  306 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 306 insertions(+), 0 deletions(-)

diff --git a/src/views/mp/draft/components/NewsForm.vue b/src/views/mp/draft/components/NewsForm.vue
new file mode 100644
index 0000000..9711334
--- /dev/null
+++ b/src/views/mp/draft/components/NewsForm.vue
@@ -0,0 +1,306 @@
+<template>
+  <el-container>
+    <el-aside width="40%">
+      <div class="select-item">
+        <div v-for="(news, index) in newsList" :key="index">
+          <div
+            class="news-main father"
+            v-if="index === 0"
+            :class="{ activeAddNews: activeNewsIndex === index }"
+            @click="activeNewsIndex = index"
+          >
+            <div class="news-content">
+              <img class="material-img" :src="news.thumbUrl" />
+              <div class="news-content-title">{{ news.title }}</div>
+            </div>
+            <div class="child" v-if="newsList.length > 1">
+              <el-button type="info" circle size="small" @click="() => moveDownNews(index)">
+                <Icon icon="ep:arrow-down-bold" />
+              </el-button>
+              <el-button
+                v-if="isCreating"
+                type="danger"
+                circle
+                size="small"
+                @click="() => removeNews(index)"
+              >
+                <Icon icon="ep:delete" />
+              </el-button>
+            </div>
+          </div>
+          <div
+            class="news-main-item father"
+            v-if="index > 0"
+            :class="{ activeAddNews: activeNewsIndex === index }"
+            @click="activeNewsIndex = index"
+          >
+            <div class="news-content-item">
+              <div class="news-content-item-title">{{ news.title }}</div>
+              <div class="news-content-item-img">
+                <img class="material-img" :src="news.thumbUrl" width="100%" />
+              </div>
+            </div>
+            <div class="child">
+              <el-button
+                v-if="newsList.length > index + 1"
+                circle
+                type="info"
+                size="small"
+                @click="() => moveDownNews(index)"
+              >
+                <Icon icon="ep:arrow-down-bold" />
+              </el-button>
+              <el-button
+                v-if="index > 0"
+                type="info"
+                circle
+                size="small"
+                @click="() => moveUpNews(index)"
+              >
+                <Icon icon="ep:arrow-up-bold" />
+              </el-button>
+              <el-button
+                v-if="isCreating"
+                type="danger"
+                size="small"
+                circle
+                @click="() => removeNews(index)"
+              >
+                <Icon icon="ep:delete" />
+              </el-button>
+            </div>
+          </div>
+        </div>
+        <el-row justify="center" class="ope-row">
+          <el-button
+            type="primary"
+            circle
+            @click="plusNews"
+            v-if="newsList.length < 8 && isCreating"
+          >
+            <Icon icon="ep:plus" />
+          </el-button>
+        </el-row>
+      </div>
+    </el-aside>
+    <el-main>
+      <div v-if="newsList.length > 0">
+        <!-- 鏍囬銆佷綔鑰呫�佸師鏂囧湴鍧� -->
+        <el-row :gutter="20">
+          <el-input v-model="activeNewsItem.title" placeholder="璇疯緭鍏ユ爣棰橈紙蹇呭~锛�" />
+          <el-input
+            v-model="activeNewsItem.author"
+            placeholder="璇疯緭鍏ヤ綔鑰�"
+            style="margin-top: 5px"
+          />
+          <el-input
+            v-model="activeNewsItem.contentSourceUrl"
+            placeholder="璇疯緭鍏ュ師鏂囧湴鍧�"
+            style="margin-top: 5px"
+          />
+        </el-row>
+        <!-- 灏侀潰鍜屾憳瑕� -->
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <CoverSelect v-model="activeNewsItem" :is-first="activeNewsIndex === 0" />
+          </el-col>
+          <el-col :span="12">
+            <p>鎽樿:</p>
+            <el-input
+              :rows="8"
+              type="textarea"
+              v-model="activeNewsItem.digest"
+              placeholder="璇疯緭鍏ユ憳瑕�"
+              class="digest"
+              maxlength="120"
+            />
+          </el-col>
+        </el-row>
+        <!--瀵屾枃鏈紪杈戝櫒缁勪欢-->
+        <el-row>
+          <Editor v-model="activeNewsItem.content" :editor-config="editorConfig" />
+        </el-row>
+      </div>
+    </el-main>
+  </el-container>
+</template>
+
+<script lang="ts" setup>
+import { Editor } from '@/components/Editor'
+import { createEditorConfig } from '../editor-config'
+import CoverSelect from './CoverSelect.vue'
+import { type NewsItem, createEmptyNewsItem } from './types'
+
+defineOptions({ name: 'NewsForm' })
+
+const message = useMessage()
+
+const props = defineProps<{
+  isCreating: boolean
+  modelValue: NewsItem[] | null
+}>()
+
+const accountId = inject<number>('accountId')
+
+// ========== 鏂囦欢涓婁紶 ==========
+const UPLOAD_URL = import.meta.env.VITE_BASE_URL + '/admin-api/mp/material/upload-permanent' // 涓婁紶姘镐箙绱犳潗鐨勫湴鍧�
+const editorConfig = createEditorConfig(UPLOAD_URL, unref(accountId))
+
+// v-model=newsList
+const emit = defineEmits<{
+  (e: 'update:modelValue', v: NewsItem[])
+}>()
+const newsList = computed<NewsItem[]>({
+  get() {
+    return props.modelValue === null ? [createEmptyNewsItem()] : props.modelValue
+  },
+  set(val) {
+    emit('update:modelValue', val)
+  }
+})
+
+const activeNewsIndex = ref(0)
+const activeNewsItem = computed<NewsItem>(() => newsList.value[activeNewsIndex.value])
+
+// 灏嗗浘鏂囧悜涓嬬Щ鍔�
+const moveDownNews = (index: number) => {
+  const temp = newsList.value[index]
+  newsList.value[index] = newsList.value[index + 1]
+  newsList.value[index + 1] = temp
+  activeNewsIndex.value = index + 1
+}
+
+// 灏嗗浘鏂囧悜涓婄Щ鍔�
+const moveUpNews = (index: number) => {
+  const temp = newsList.value[index]
+  newsList.value[index] = newsList.value[index - 1]
+  newsList.value[index - 1] = temp
+  activeNewsIndex.value = index - 1
+}
+
+// 鍒犻櫎鎸囧畾 index 鐨勫浘鏂�
+const removeNews = async (index: number) => {
+  try {
+    await message.confirm('纭畾鍒犻櫎璇ュ浘鏂囧悧?')
+    newsList.value.splice(index, 1)
+    if (activeNewsIndex.value === index) {
+      activeNewsIndex.value = 0
+    }
+  } catch {
+    // empty
+  }
+}
+
+// 娣诲姞涓�涓浘鏂�
+const plusNews = () => {
+  newsList.value.push(createEmptyNewsItem())
+  activeNewsIndex.value = newsList.value.length - 1
+}
+</script>
+
+<style lang="scss" scoped>
+.ope-row {
+  padding-top: 5px;
+  margin-top: 5px;
+  text-align: center;
+  border-top: 1px solid #eaeaea;
+}
+
+.el-row {
+  margin-bottom: 20px;
+}
+
+.el-row:last-child {
+  margin-bottom: 0;
+}
+
+.digest {
+  display: inline-block;
+  width: 100%;
+  vertical-align: top;
+}
+
+/* 鏂板鍥炬枃 */
+.news-main {
+  width: 100%;
+  height: 120px;
+  margin: auto;
+  background-color: #fff;
+}
+
+.news-content {
+  position: relative;
+  width: 100%;
+  height: 120px;
+  background-color: #acadae;
+}
+
+.news-content-title {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  display: inline-block;
+  width: 98%;
+  height: 25px;
+  padding: 1%;
+  overflow: hidden;
+  font-size: 15px;
+  color: #fff;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  background-color: black;
+  opacity: 0.65;
+}
+
+.news-main-item {
+  width: 100%;
+  padding: 5px 0;
+  margin: auto;
+  background-color: #fff;
+  border-top: 1px solid #eaeaea;
+}
+
+.news-content-item {
+  position: relative;
+  margin-left: -3px;
+}
+
+.news-content-item-title {
+  display: inline-block;
+  width: 70%;
+  font-size: 12px;
+}
+
+.news-content-item-img {
+  display: inline-block;
+  width: 25%;
+  background-color: #acadae;
+}
+
+.select-item {
+  width: 60%;
+  padding: 10px;
+  margin: 0 auto 10px;
+  border: 1px solid #eaeaea;
+
+  .activeAddNews {
+    border: 5px solid #2bb673;
+  }
+}
+
+.father .child {
+  position: relative;
+  bottom: 25px;
+  display: none;
+  text-align: center;
+}
+
+.father:hover .child {
+  display: block;
+}
+
+.material-img {
+  width: 100%;
+  height: 100%;
+}
+</style>

--
Gitblit v1.8.0