|
| 1 | +<template> |
| 2 | + <div class="m-publish-headline-notice" v-if="visible"> |
| 3 | + <div class="m-publish-headline-notice__card"> |
| 4 | + <div class="u-accent-line"></div> |
| 5 | + <div class="u-left"> |
| 6 | + <span class="u-status" :class="statusClass"> |
| 7 | + <span class="u-pulse-dot"></span> |
| 8 | + <span>{{ statusText }}</span> |
| 9 | + </span> |
| 10 | + <p class="u-title"> |
| 11 | + <span>你的作品即将在</span> |
| 12 | + <span class="u-time">{{ publishTime }}</span |
| 13 | + >登上<span class="u-highlight">魔盒头条</span> |
| 14 | + </p> |
| 15 | + </div> |
| 16 | + <div class="u-right"> |
| 17 | + <span class="u-suffix">※ 根据实际情况可能会调整</span> |
| 18 | + </div> |
| 19 | + </div> |
| 20 | + </div> |
| 21 | +</template> |
| 22 | + |
| 23 | +<script> |
| 24 | +import dayjs from "dayjs"; |
| 25 | +import { getUpcomingDesignTask } from "@/service/publish/cms"; |
| 26 | +
|
| 27 | +export default { |
| 28 | + name: "PublishHeadlineNotice", |
| 29 | + props: { |
| 30 | + sourceType: { |
| 31 | + type: String, |
| 32 | + default: "", |
| 33 | + }, |
| 34 | + sourceId: { |
| 35 | + type: [String, Number], |
| 36 | + default: "", |
| 37 | + }, |
| 38 | + client: { |
| 39 | + type: String, |
| 40 | + default: "", |
| 41 | + }, |
| 42 | + }, |
| 43 | + data() { |
| 44 | + return { |
| 45 | + task: null, |
| 46 | + }; |
| 47 | + }, |
| 48 | + computed: { |
| 49 | + visible() { |
| 50 | + return !!this.task?.published_at; |
| 51 | + }, |
| 52 | + title() { |
| 53 | + if (!this.visible) return ""; |
| 54 | + return `你的作品即将在${this.publishTime}登上魔盒头条(根据实际情况可能会调整)`; |
| 55 | + }, |
| 56 | + publishTime() { |
| 57 | + if (!this.visible) return ""; |
| 58 | + return dayjs(this.task.published_at).format("YYYY-MM-DD HH:mm:ss"); |
| 59 | + }, |
| 60 | + statusText() { |
| 61 | + const map = { |
| 62 | + 0: "未开始", |
| 63 | + 1: "进行中", |
| 64 | + 2: "已就绪", |
| 65 | + }; |
| 66 | + return map[this.task?.flow] || "未开始"; |
| 67 | + }, |
| 68 | + statusClass() { |
| 69 | + const map = { |
| 70 | + 0: "is-pending", |
| 71 | + 1: "is-progress", |
| 72 | + 2: "is-ready", |
| 73 | + }; |
| 74 | + return map[this.task?.flow] || "is-pending"; |
| 75 | + }, |
| 76 | + queryKey() { |
| 77 | + return [this.sourceType, this.sourceId, this.client].join("|"); |
| 78 | + }, |
| 79 | + isMock() { |
| 80 | + const query = `${location.search}&${location.hash.split("?")[1] || ""}`; |
| 81 | + return new URLSearchParams(query).get("headline_mock") === "1"; |
| 82 | + }, |
| 83 | + }, |
| 84 | + watch: { |
| 85 | + queryKey: { |
| 86 | + immediate: true, |
| 87 | + handler() { |
| 88 | + this.loadData(); |
| 89 | + }, |
| 90 | + }, |
| 91 | + }, |
| 92 | + methods: { |
| 93 | + loadData() { |
| 94 | + if (this.isMock) { |
| 95 | + this.task = { |
| 96 | + id: 0, |
| 97 | + flow: 2, |
| 98 | + published_at: dayjs().add(3, "day").format("YYYY-MM-DD HH:mm:ss"), |
| 99 | + }; |
| 100 | + return; |
| 101 | + } |
| 102 | +
|
| 103 | + if (!this.sourceType || !this.sourceId) { |
| 104 | + this.task = null; |
| 105 | + return; |
| 106 | + } |
| 107 | +
|
| 108 | + getUpcomingDesignTask({ |
| 109 | + source_type: this.sourceType, |
| 110 | + source_id: String(this.sourceId), |
| 111 | + client: this.client || undefined, |
| 112 | + }) |
| 113 | + .then((res) => { |
| 114 | + const data = res.data.data; |
| 115 | + this.task = data?.exists ? data.task : null; |
| 116 | + }) |
| 117 | + .catch(() => { |
| 118 | + this.task = null; |
| 119 | + }); |
| 120 | + }, |
| 121 | + }, |
| 122 | +}; |
| 123 | +</script> |
| 124 | +
|
| 125 | +<style lang="less"> |
| 126 | +.m-publish-headline-notice { |
| 127 | + margin-top: 12px; |
| 128 | +
|
| 129 | + &__card { |
| 130 | + position: relative; |
| 131 | + overflow: hidden; |
| 132 | + display: flex; |
| 133 | + align-items: center; |
| 134 | + justify-content: space-between; |
| 135 | + gap: 8px; |
| 136 | + width: 100%; |
| 137 | + max-width: 100%; |
| 138 | + min-height: 48px; |
| 139 | + padding: 10px 20px 10px 24px; |
| 140 | + box-sizing: border-box; |
| 141 | + border: 1px solid #f1f5f9; |
| 142 | + border-radius: 6px; |
| 143 | + background-color: #f8fafc; |
| 144 | + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); |
| 145 | + } |
| 146 | +
|
| 147 | + .u-accent-line { |
| 148 | + position: absolute; |
| 149 | + left: 0; |
| 150 | + top: 8px; |
| 151 | + bottom: 8px; |
| 152 | + width: 4px; |
| 153 | + border-top-right-radius: 999px; |
| 154 | + border-bottom-right-radius: 999px; |
| 155 | + background: linear-gradient(180deg, #ec4899 0%, #f43f5e 100%); |
| 156 | + box-shadow: 1px 0 6px rgba(236, 72, 153, 0.3); |
| 157 | + } |
| 158 | +
|
| 159 | + .u-left { |
| 160 | + display: flex; |
| 161 | + align-items: center; |
| 162 | + gap: 12px; |
| 163 | + min-width: 0; |
| 164 | + } |
| 165 | +
|
| 166 | + .u-right { |
| 167 | + flex-shrink: 0; |
| 168 | + } |
| 169 | +
|
| 170 | + .u-suffix { |
| 171 | + white-space: nowrap; |
| 172 | + font-size: 12px; |
| 173 | + font-weight: 500; |
| 174 | + color: #94a3b8; |
| 175 | + } |
| 176 | +
|
| 177 | + .u-title { |
| 178 | + min-width: 0; |
| 179 | + margin: 0; |
| 180 | + overflow: hidden; |
| 181 | + text-overflow: ellipsis; |
| 182 | + white-space: nowrap; |
| 183 | + font-size: 14px; |
| 184 | + line-height: 1.5; |
| 185 | + letter-spacing: 0.025em; |
| 186 | + color: #475569; |
| 187 | + } |
| 188 | +
|
| 189 | + .u-time { |
| 190 | + font-weight: 750; |
| 191 | + color: #1e293b; |
| 192 | + } |
| 193 | +
|
| 194 | + .u-highlight { |
| 195 | + font-weight: 750; |
| 196 | + color: #db2777; |
| 197 | + } |
| 198 | +
|
| 199 | + .u-status { |
| 200 | + flex-shrink: 0; |
| 201 | + display: inline-flex; |
| 202 | + align-items: center; |
| 203 | + gap: 6px; |
| 204 | + height: 28px; |
| 205 | + padding: 0 10px; |
| 206 | + border: 1px solid rgba(251, 207, 232, 0.8); |
| 207 | + border-radius: 999px; |
| 208 | + background-color: #fdf2f8; |
| 209 | + color: #be185d; |
| 210 | + white-space: nowrap; |
| 211 | + font-size: 12px; |
| 212 | + font-weight: 600; |
| 213 | + line-height: 28px; |
| 214 | + } |
| 215 | +
|
| 216 | + .u-status.is-pending { |
| 217 | + color: #475569; |
| 218 | + background-color: #f8fafc; |
| 219 | + border-color: #cbd5e1; |
| 220 | + } |
| 221 | +
|
| 222 | + .u-status.is-progress { |
| 223 | + color: #c2410c; |
| 224 | + background-color: #fff7ed; |
| 225 | + border-color: #fed7aa; |
| 226 | + } |
| 227 | +
|
| 228 | + .u-status.is-ready { |
| 229 | + color: #be185d; |
| 230 | + background-color: #fdf2f8; |
| 231 | + border-color: rgba(251, 207, 232, 0.8); |
| 232 | + } |
| 233 | +
|
| 234 | + .u-pulse-dot { |
| 235 | + width: 6px; |
| 236 | + height: 6px; |
| 237 | + border-radius: 50%; |
| 238 | + background-color: currentColor; |
| 239 | + animation: headline-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
| 240 | + } |
| 241 | +
|
| 242 | + @keyframes headline-pulse { |
| 243 | + 0%, |
| 244 | + 100% { |
| 245 | + opacity: 1; |
| 246 | + } |
| 247 | + 50% { |
| 248 | + opacity: 0.4; |
| 249 | + } |
| 250 | + } |
| 251 | +} |
| 252 | +</style> |
0 commit comments