7.31更新
This commit is contained in:
parent
1de17afa1c
commit
56f2300ba3
@ -18,7 +18,7 @@ export default {
|
||||
switchEnSuccess: 'Switched to English'
|
||||
},
|
||||
home: {
|
||||
heroTitle: 'One Platform · Intelligent Leap · Across All Industries.',
|
||||
heroTitle: 'Make AI Everywhere, Make AI Easy',
|
||||
heroSubtitle: '',
|
||||
heroSlogan: 'Make AI Everywhere, Make AI Easy',
|
||||
solutionsBtn: 'Solutions',
|
||||
|
||||
@ -57,6 +57,14 @@
|
||||
<button v-if="!isNcmatchDomain" type="button" class="nav-item" @click.stop="goHomeAnchor('news')">
|
||||
{{ $t('topbar.news') }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nav-item"
|
||||
:class="{ active: $route.path.includes('/homePage/about') }"
|
||||
@click.stop="navigateTo('/homePage/about')"
|
||||
>
|
||||
{{ aboutUsText }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="user-actions">
|
||||
@ -327,6 +335,9 @@ export default Vue.extend({
|
||||
langToggleTitle() {
|
||||
return this.activeLocale === 'en-US' ? 'Switch to Chinese' : '切换到英文'
|
||||
},
|
||||
aboutUsText() {
|
||||
return this.activeLocale === 'en-US' ? 'About Us' : '关于我们'
|
||||
},
|
||||
localizedProductMenuItems() {
|
||||
const isEn = this.activeLocale === 'en-US'
|
||||
const labels = {
|
||||
@ -488,7 +499,7 @@ export default Vue.extend({
|
||||
if (yuanJingWindow) yuanJingWindow.close()
|
||||
this.$message.error((res && res.msg) || '获取元境授权参数失败')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const loginUrl = `${yuanJingBaseUrl}/#/getCookie?deerer=${encodeURIComponent(deerer)}`
|
||||
if (yuanJingWindow) yuanJingWindow.location.href = loginUrl
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<h1>{{ $t('home.heroTitle') }}</h1>
|
||||
</div>
|
||||
<h2 v-if="$t('home.heroSubtitle')">{{ $t('home.heroSubtitle') }}</h2>
|
||||
<p>{{ $t('home.heroSlogan') }}</p>
|
||||
<!-- <p>{{ $t('home.heroSlogan') }}</p> -->
|
||||
<div class="hero-actions">
|
||||
<button type="button" class="use-btn" @click="goSolution">{{ $t('home.solutionsBtn') }}</button>
|
||||
<div class="outline-btn" @click="contactSales">{{ $t('home.contactSalesBtn') }}</div>
|
||||
@ -37,6 +37,14 @@
|
||||
@mouseleave="startSolutionCarousel"
|
||||
@click="setSolutionIndex(item.index)"
|
||||
>
|
||||
<button
|
||||
v-if="item.card.scenarioPath"
|
||||
type="button"
|
||||
class="solution-card__scenario-link"
|
||||
@click.stop="goSolutionScenario(item.card.scenarioPath)"
|
||||
>
|
||||
{{ $i18n && $i18n.locale === 'en-US' ? 'Scenarios→' : item.card.scenarioLabel }}
|
||||
</button>
|
||||
<div class="solution-card__front">
|
||||
<div class="solution-card__icon" v-html="item.card.icon"></div>
|
||||
<h3>{{ item.card.title }}</h3>
|
||||
@ -71,7 +79,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 成功案例 -->
|
||||
<!-- 成功案例 -->
|
||||
<section id="cases-section" class="case-section">
|
||||
<div class="case-inner">
|
||||
<div class="case-head">
|
||||
@ -101,7 +109,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="case-cta" :style="{ backgroundImage: `url(${caseCtaBg})` }">
|
||||
@ -129,7 +137,7 @@
|
||||
<div class="news-list">
|
||||
<article
|
||||
v-for="(item, index) in localizedNewsList"
|
||||
:key="item.title"
|
||||
:key="item.id"
|
||||
class="news-card"
|
||||
:class="{ 'news-card-active': index === activeNewsIndex }"
|
||||
@mouseenter="activeNewsIndex = index"
|
||||
@ -213,6 +221,8 @@ export default {
|
||||
],
|
||||
bg: 'linear-gradient(145deg, rgba(208, 236, 249, 0.72) 0%, rgba(168, 216, 244, 0.64) 44%, rgba(124, 196, 238, 0.58) 100%)',
|
||||
shadow: '0 18px 54px rgba(80, 150, 220, 0.2), 0 4px 16px rgba(80, 150, 220, 0.08)',
|
||||
scenarioLabel: '投策智能体→',
|
||||
scenarioPath: '/homePage/agentStore/decisionCase',
|
||||
icon: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="24" cy="18" r="6"/><circle cx="10" cy="34" r="5"/><circle cx="38" cy="34" r="5"/><line x1="20" y1="23" x2="13" y2="30"/><line x1="28" y1="23" x2="35" y2="30"/><circle cx="36" cy="14" r="3.5"/><circle cx="12" cy="14" r="3.5"/></svg>'
|
||||
},
|
||||
{
|
||||
@ -303,6 +313,8 @@ export default {
|
||||
],
|
||||
bg: 'linear-gradient(145deg, rgba(200, 214, 242, 0.72) 0%, rgba(158, 180, 230, 0.64) 44%, rgba(116, 146, 216, 0.58) 100%)',
|
||||
shadow: '0 18px 54px rgba(60, 80, 160, 0.18), 0 4px 16px rgba(60, 80, 160, 0.08)',
|
||||
scenarioLabel: '合同智能审查→',
|
||||
scenarioPath: '/homePage/agentStore/contractCase',
|
||||
icon: '<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 6h16l10 10v26a4 4 0 0 1-4 4H12a4 4 0 0 1-4-4V10a4 4 0 0 1 4-4z"/><polyline points="28,6 28,16 38,16"/><line x1="14" y1="24" x2="34" y2="24"/><line x1="14" y1="31" x2="30" y2="31"/></svg>'
|
||||
},
|
||||
{
|
||||
@ -378,7 +390,29 @@ export default {
|
||||
})
|
||||
},
|
||||
localizedNewsList() {
|
||||
return this.newsList
|
||||
const isEnglish = this.$i18n && this.$i18n.locale === 'en-US'
|
||||
return this.newsList.map((item) => {
|
||||
const tag = isEnglish
|
||||
? (item.tagEn || item.tagZh || this.$t('home.news.tag'))
|
||||
: (item.tagZh || item.tagEn || this.$t('home.news.tag'))
|
||||
const title = isEnglish
|
||||
? (item.titleEn || item.titleZh || '')
|
||||
: (item.titleZh || item.titleEn || '')
|
||||
const desc = isEnglish
|
||||
? (item.descEn || item.descZh || '')
|
||||
: (item.descZh || item.descEn || '')
|
||||
const date = isEnglish
|
||||
? (item.dateEn || item.dateZh || '')
|
||||
: (item.dateZh || item.dateEn || '')
|
||||
|
||||
return {
|
||||
...item,
|
||||
tag,
|
||||
title,
|
||||
desc,
|
||||
date
|
||||
}
|
||||
})
|
||||
},
|
||||
visibleSolutionCards() {
|
||||
const slots = [-3, -2, -1, 0, 1, 2, 3]
|
||||
@ -430,6 +464,9 @@ export default {
|
||||
block: 'start'
|
||||
})
|
||||
},
|
||||
goSolutionScenario(path) {
|
||||
this.navigateTo(path)
|
||||
},
|
||||
contactSales() {
|
||||
this.$store.commit('setShowTalk', true)
|
||||
},
|
||||
@ -455,11 +492,15 @@ export default {
|
||||
normalizeHomeNewsItem(row, index) {
|
||||
return {
|
||||
id: row.id,
|
||||
tag: row.article_type || this.$t('home.news.tag'),
|
||||
tagClass: this.getNewsTagClass(index),
|
||||
date: row.publish_time || row.publishTime || '',
|
||||
title: row.title || '',
|
||||
desc: row.summary || row.desc || row.description || ''
|
||||
tagZh: row.article_type_zh || row.article_type || '',
|
||||
tagEn: row.article_type_en || '',
|
||||
dateZh: row.publish_time_zh || row.publish_time || row.publishTime || '',
|
||||
dateEn: row.publish_time_en || '',
|
||||
titleZh: row.title_zh || row.title || '',
|
||||
titleEn: row.title_en || '',
|
||||
descZh: row.summary_zh || row.summary || row.desc || row.description || '',
|
||||
descEn: row.summary_en || ''
|
||||
}
|
||||
},
|
||||
getResponseList(res) {
|
||||
@ -481,8 +522,7 @@ export default {
|
||||
this.newsList = []
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
nextSolution() {
|
||||
this.switchSolution(1)
|
||||
},
|
||||
@ -690,7 +730,6 @@ body.dark-theme .bg-orb {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
&:hover {
|
||||
background: #fff;
|
||||
transform: translateY(-2px);
|
||||
@ -824,6 +863,39 @@ body.dark-theme .bg-orb {
|
||||
transition: all 0.28s ease;
|
||||
}
|
||||
|
||||
.solution-card__scenario-link {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
z-index: 3;
|
||||
padding: 5px 9px;
|
||||
color: #1d4ed8;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
background: rgba(255, 255, 255, 0.58);
|
||||
border: 1px solid rgba(255, 255, 255, 0.72);
|
||||
border-radius: 999px;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
pointer-events: none;
|
||||
transform: translateY(-4px);
|
||||
transition: background 0.2s ease, color 0.2s ease, opacity 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.solution-card:hover .solution-card__scenario-link {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.solution-card__scenario-link:hover {
|
||||
color: #1e40af;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.solution-card__icon {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@ -865,15 +937,12 @@ body.dark-theme .bg-orb {
|
||||
transition: all 0.25s ease;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
border-radius: 999px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
strong {
|
||||
@ -1546,8 +1615,6 @@ body.dark-theme .bg-orb {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes heroFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
|
||||
<div class="article-editor" :class="{ 'is-editor-fullscreen': editorFullscreen }">
|
||||
<div class="article-editor__left">
|
||||
<div class="article-editor__left" :class="{ 'has-language-form': showEnglishForm }">
|
||||
<div class="article-editor__form">
|
||||
<el-form :model="form" label-width="76px" size="small">
|
||||
<el-form-item>
|
||||
@ -71,11 +71,27 @@
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="language-trigger">
|
||||
<div class="language-trigger__title">
|
||||
<span class="language-trigger__badge">EN</span>
|
||||
<div>
|
||||
<strong>多语言输入</strong>
|
||||
<small>添加英文版文章内容</small>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="language-trigger__button"
|
||||
:aria-expanded="showEnglishForm.toString()"
|
||||
@click="showEnglishForm = !showEnglishForm"
|
||||
>
|
||||
{{ showEnglishForm ? '收起英文版' : '添加英文版' }}
|
||||
<i :class="showEnglishForm ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="dialogVisible" class="wang-editor-wrap">
|
||||
|
||||
<Toolbar
|
||||
class="wang-toolbar"
|
||||
:editor="editor"
|
||||
@ -90,6 +106,92 @@
|
||||
@onCreated="handleEditorCreated"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<section v-if="showEnglishForm" class="article-editor__language-section">
|
||||
<div class="language-section-head">
|
||||
<div>
|
||||
<span class="language-section-head__eyebrow">ENGLISH VERSION</span>
|
||||
<h3>英文版文章</h3>
|
||||
<p>英文内容会与中文内容一并保存或发布。</p>
|
||||
</div>
|
||||
<span class="language-section-head__tag">English</span>
|
||||
</div>
|
||||
|
||||
<div class="language-form-grid">
|
||||
<div class="language-field language-field--wide">
|
||||
<label>Article Title</label>
|
||||
<el-input v-model.trim="english.title" placeholder="Enter article title" />
|
||||
</div>
|
||||
<div class="language-field language-field--wide">
|
||||
<label>English Summary</label>
|
||||
<el-input
|
||||
v-model.trim="english.summary"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
maxlength="120"
|
||||
show-word-limit
|
||||
placeholder="Enter article summary"
|
||||
/>
|
||||
</div>
|
||||
<div class="language-field">
|
||||
<label>Category</label>
|
||||
<el-select v-model="english.category" placeholder="Select category">
|
||||
<el-option label="Corporate News" value="Corporate News" />
|
||||
<el-option label="Product News" value="Product News" />
|
||||
<el-option label="Industry Insights" value="Industry Insights" />
|
||||
<el-option label="Event News" value="Event News" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="language-field">
|
||||
<label>Date</label>
|
||||
<el-date-picker
|
||||
v-model="english.publishTime"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="Select date"
|
||||
/>
|
||||
</div>
|
||||
<div class="language-field language-field--wide">
|
||||
<label>Cover</label>
|
||||
<div class="language-cover">
|
||||
<button type="button" class="language-cover__upload" @click="$refs.englishCoverInput.click()">
|
||||
<i class="el-icon-upload2" />
|
||||
Upload cover
|
||||
</button>
|
||||
<el-input
|
||||
v-model.trim="english.coverUrl"
|
||||
class="language-cover__input"
|
||||
placeholder="Upload an image or paste its URL"
|
||||
/>
|
||||
<span v-if="english.coverName" class="language-cover__name">{{ english.coverName }}</span>
|
||||
<input ref="englishCoverInput" type="file" accept="image/*" class="hidden-input" @change="handleEnglishCoverUpload">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="language-richtext">
|
||||
<div class="language-richtext__head">
|
||||
<span>English Content</span>
|
||||
<small>Rich text editor</small>
|
||||
</div>
|
||||
<div v-if="dialogVisible" class="wang-editor-wrap wang-editor-wrap--english">
|
||||
<Toolbar
|
||||
class="wang-toolbar"
|
||||
:editor="englishEditor"
|
||||
:default-config="toolbarConfig"
|
||||
:mode="editorMode"
|
||||
/>
|
||||
<Editor
|
||||
v-model="english.content"
|
||||
class="wang-editor"
|
||||
:default-config="englishEditorConfig"
|
||||
:mode="editorMode"
|
||||
@onCreated="handleEnglishEditorCreated"
|
||||
@onDestroyed="handleEnglishEditorDestroyed"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -157,6 +259,7 @@ export default {
|
||||
dirty: false,
|
||||
// 保存 wangEditor 实例,组件销毁时需要手动释放。
|
||||
editor: null,
|
||||
englishEditor: null,
|
||||
// wangEditor 模式配置。
|
||||
editorMode: 'default',
|
||||
// wangEditor 工具栏配置。
|
||||
@ -166,7 +269,7 @@ export default {
|
||||
placeholder: '请输入文章内容...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
customUpload: async (file, insertFn) => {
|
||||
customUpload: async(file, insertFn) => {
|
||||
try {
|
||||
// 正文图片上传到文件接口,正文中保存可回显的图片地址。
|
||||
const url = await this.uploadNewsImage(file)
|
||||
@ -178,13 +281,33 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
englishEditorConfig: {
|
||||
placeholder: 'Start writing the English version of your article...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
customUpload: async(file, insertFn) => {
|
||||
try {
|
||||
const url = await this.uploadNewsImage(file)
|
||||
insertFn(normalizeImageUrl(url), file.name, normalizeImageUrl(url))
|
||||
} catch (error) {
|
||||
this.$message.error('英文正文图片上传失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 上传封面的本地预览地址,只用于页面显示,不提交给接口。
|
||||
coverPreview: '',
|
||||
imageUploading: false,
|
||||
englishImageUploading: false,
|
||||
editorFullscreen: false,
|
||||
editorFullscreenObserver: null,
|
||||
// 右侧预览区域宽度。
|
||||
previewWidth: 400,
|
||||
// 控制英文版区域展开状态。
|
||||
showEnglishForm: false,
|
||||
// 英文版内容,与中文字段一起提交到文章保存接口。
|
||||
english: this.createEmptyEnglishForm(),
|
||||
// 标记预览区域是否正在拖拽调整宽度。
|
||||
resizing: false,
|
||||
// 记录拖拽开始时的鼠标位置。
|
||||
@ -230,6 +353,12 @@ export default {
|
||||
// 任意表单字段变化后标记为未保存。
|
||||
this.dirty = true
|
||||
}
|
||||
},
|
||||
english: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.dirty = true
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
@ -238,12 +367,16 @@ export default {
|
||||
this.editor.destroy()
|
||||
this.editor = null
|
||||
}
|
||||
if (this.englishEditor) {
|
||||
this.englishEditor.destroy()
|
||||
this.englishEditor = null
|
||||
}
|
||||
// 清理拖拽监听事件。
|
||||
this.removeResizeListeners()
|
||||
this.stopObserveEditorFullscreen()
|
||||
this.editorFullscreen = false
|
||||
},
|
||||
methods: {
|
||||
methods: {
|
||||
createEmptyForm() {
|
||||
// 创建新增文章时使用的默认表单结构。
|
||||
return {
|
||||
@ -259,17 +392,58 @@ export default {
|
||||
coverName: ''
|
||||
}
|
||||
},
|
||||
createEmptyEnglishForm() {
|
||||
return {
|
||||
title: '',
|
||||
summary: '',
|
||||
category: '',
|
||||
publishTime: '',
|
||||
coverUrl: '',
|
||||
coverName: '',
|
||||
content: ''
|
||||
}
|
||||
},
|
||||
handleOpen() {
|
||||
// 弹窗打开时合并默认值和待编辑文章数据。
|
||||
const article = this.article || {}
|
||||
const english = article.english || {}
|
||||
this.form = {
|
||||
...this.createEmptyForm(),
|
||||
...(this.article || {})
|
||||
...article,
|
||||
title: article.title || article.title_zh || '',
|
||||
summary: article.summary || article.summary_zh || '',
|
||||
type: article.type || article.article_type_zh || '企业动态',
|
||||
publishTime: article.publishTime || article.publish_time_zh || article.publish_time || '',
|
||||
content: article.content || article.content_zh || '',
|
||||
coverUrl: article.coverUrl || article.cover_img_zh || article.cover_img || '',
|
||||
coverName: article.coverName || article.cover_name_zh || article.cover_name || ''
|
||||
}
|
||||
// 没有发布时间时默认使用当天日期。
|
||||
if (!this.form.publishTime) this.form.publishTime = this.today
|
||||
// 初始化封面预览。
|
||||
this.coverPreview = this.form.coverUrl || ''
|
||||
this.editorFullscreen = false
|
||||
this.imageUploading = false
|
||||
this.englishImageUploading = false
|
||||
this.english = {
|
||||
...this.createEmptyEnglishForm(),
|
||||
...english,
|
||||
title: english.title || article.title_en || '',
|
||||
summary: english.summary || article.summary_en || '',
|
||||
category: english.category || article.article_type_en || '',
|
||||
publishTime: english.publishTime || article.publish_time_en || '',
|
||||
content: english.content || article.content_en || '',
|
||||
coverUrl: english.coverUrl || article.cover_img_en || '',
|
||||
coverName: english.coverName || article.cover_name_en || ''
|
||||
}
|
||||
this.showEnglishForm = Boolean(
|
||||
this.english.title ||
|
||||
this.english.summary ||
|
||||
this.english.category ||
|
||||
this.english.publishTime ||
|
||||
this.english.coverUrl ||
|
||||
this.english.content
|
||||
)
|
||||
this.$nextTick(() => {
|
||||
// 表单初始化完成后重置未保存状态。
|
||||
this.dirty = false
|
||||
@ -280,6 +454,12 @@ export default {
|
||||
// 保存编辑器实例,后续销毁时使用。
|
||||
this.editor = Object.seal(editor)
|
||||
},
|
||||
handleEnglishEditorCreated(editor) {
|
||||
this.englishEditor = Object.seal(editor)
|
||||
},
|
||||
handleEnglishEditorDestroyed() {
|
||||
this.englishEditor = null
|
||||
},
|
||||
handleDialogClose() {
|
||||
this.stopObserveEditorFullscreen()
|
||||
this.editorFullscreen = false
|
||||
@ -398,6 +578,23 @@ export default {
|
||||
event.target.value = ''
|
||||
}
|
||||
},
|
||||
async handleEnglishCoverUpload(event) {
|
||||
const file = event.target.files && event.target.files[0]
|
||||
if (!file) return
|
||||
|
||||
this.english.coverName = file.name
|
||||
this.englishImageUploading = true
|
||||
try {
|
||||
this.english.coverUrl = await this.uploadNewsImage(file)
|
||||
this.$message.success('英文封面图片上传成功')
|
||||
} catch (error) {
|
||||
this.english.coverName = ''
|
||||
this.$message.error('英文封面图片上传失败')
|
||||
} finally {
|
||||
this.englishImageUploading = false
|
||||
event.target.value = ''
|
||||
}
|
||||
},
|
||||
handleCoverUrlInput() {
|
||||
// 用户手动输入图片路径时,清空本地上传预览状态。
|
||||
this.coverPreview = ''
|
||||
@ -469,13 +666,16 @@ export default {
|
||||
this.$message.warning('请输入文章正文')
|
||||
return
|
||||
}
|
||||
if (this.imageUploading) {
|
||||
if (this.imageUploading || this.englishImageUploading) {
|
||||
this.$message.warning('图片上传中,请稍后保存')
|
||||
return
|
||||
}
|
||||
// 第六步:组装保存参数,status 由按钮决定是草稿还是发布。
|
||||
const payload = {
|
||||
...this.form,
|
||||
english: {
|
||||
...this.english
|
||||
},
|
||||
publish_time: this.form.publishTime,
|
||||
status
|
||||
}
|
||||
@ -572,6 +772,21 @@ export default {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.article-editor__left.has-language-form {
|
||||
overflow-y: auto;
|
||||
scrollbar-color: #cbd5e1 transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.article-editor__left.has-language-form .article-editor__form {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.article-editor__left.has-language-form .wang-editor-wrap {
|
||||
flex: 0 0 420px;
|
||||
min-height: 420px;
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
position: relative;
|
||||
flex: 0 0 10px;
|
||||
@ -614,6 +829,70 @@ export default {
|
||||
border-bottom: 1px solid #edf0f5;
|
||||
}
|
||||
|
||||
.language-trigger {
|
||||
min-height: 48px;
|
||||
margin: 2px 0 12px 88px;
|
||||
padding: 9px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
background: linear-gradient(90deg, #f8fbff 0%, #f7f5ff 100%);
|
||||
border: 1px dashed #bfdbfe;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.language-trigger__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.language-trigger__badge {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #4f46e5;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
background: #ede9fe;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
.language-trigger__title strong,
|
||||
.language-trigger__title small {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.language-trigger__title strong {
|
||||
color: #334155;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.language-trigger__title small {
|
||||
margin-top: 2px;
|
||||
color: #94a3b8;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.language-trigger__button {
|
||||
padding: 5px 8px;
|
||||
color: #4f46e5;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.language-trigger__button i {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.article-editor__inline {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
@ -671,6 +950,219 @@ export default {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.article-editor__language-section {
|
||||
flex-shrink: 0;
|
||||
margin-top: 22px;
|
||||
padding: 24px 18px 40px 0;
|
||||
border-top: 1px solid #dbeafe;
|
||||
}
|
||||
|
||||
.language-section-head {
|
||||
margin-bottom: 18px;
|
||||
padding: 16px 18px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
background: linear-gradient(135deg, #f5f9ff 0%, #f7f5ff 100%);
|
||||
border: 1px solid #dbeafe;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.language-section-head__eyebrow {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
color: #6366f1;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
}
|
||||
|
||||
.language-section-head h3 {
|
||||
margin: 0;
|
||||
color: #1e293b;
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.language-section-head p {
|
||||
margin: 5px 0 0;
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.language-section-head__tag {
|
||||
padding: 4px 9px;
|
||||
color: #4f46e5;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
background: #ede9fe;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.language-form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.language-field--wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.language-field label {
|
||||
display: block;
|
||||
margin-bottom: 7px;
|
||||
color: #475569;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.language-field .el-select,
|
||||
.language-field .el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.language-cover {
|
||||
min-height: 32px;
|
||||
padding: 5px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
background: #fff;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.language-cover__upload {
|
||||
padding: 5px 9px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
background: #409eff;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.language-cover__upload i {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.language-cover__input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.language-cover__name {
|
||||
max-width: 120px;
|
||||
overflow: hidden;
|
||||
color: #16a34a;
|
||||
font-size: 11px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.language-richtext {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.language-richtext .wang-editor-wrap {
|
||||
height: 420px;
|
||||
min-height: 420px;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.language-richtext .wang-toolbar {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.language-richtext__head {
|
||||
padding: 12px 14px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #fff;
|
||||
border: 1px solid #edf0f5;
|
||||
border-bottom: 0;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
|
||||
.language-richtext__head span {
|
||||
color: #334155;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.language-richtext__head small {
|
||||
color: #94a3b8;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.language-richtext__toolbar {
|
||||
min-height: 38px;
|
||||
padding: 0 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
color: #64748b;
|
||||
background: #f8fafc;
|
||||
border-top: 1px solid #edf2f7;
|
||||
border-bottom: 1px solid #edf2f7;
|
||||
}
|
||||
|
||||
.language-richtext__toolbar > span {
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
padding: 0 5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.language-richtext__toolbar > span:not(.language-richtext__divider):hover {
|
||||
color: #2563eb;
|
||||
background: #eff6ff;
|
||||
}
|
||||
|
||||
.language-richtext__strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.language-richtext__italic {
|
||||
font-family: Georgia, serif;
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.language-richtext__toolbar .language-richtext__divider {
|
||||
min-width: 1px;
|
||||
width: 1px;
|
||||
height: 18px;
|
||||
padding: 0;
|
||||
margin: 0 4px;
|
||||
background: #dbe2ea;
|
||||
}
|
||||
|
||||
.language-richtext__canvas {
|
||||
min-height: 230px;
|
||||
padding: 16px;
|
||||
color: #c0c7d1;
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
cursor: text;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.language-richtext__canvas:empty::before {
|
||||
content: attr(data-placeholder);
|
||||
color: #c0c7d1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.article-editor__preview {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
|
||||
@ -53,6 +53,16 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEnglish() {
|
||||
return this.$i18n && this.$i18n.locale === 'en-US'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isEnglish() {
|
||||
this.getNewsDetail()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getNewsDetail()
|
||||
},
|
||||
@ -84,6 +94,10 @@ export default {
|
||||
if (/^(https?:|blob:|data:|\/\/)/.test(url)) return url
|
||||
return `${window.location.origin}/idfile?path=${url}`
|
||||
},
|
||||
getLocalizedField(row, zhField, enField, legacyField) {
|
||||
if (this.isEnglish && row[enField]) return row[enField]
|
||||
return row[zhField] || row[legacyField] || row[enField] || ''
|
||||
},
|
||||
getResponseDetail(res) {
|
||||
if (res.data && res.data.data && !Array.isArray(res.data.data)) return res.data.data
|
||||
if (res.data && !Array.isArray(res.data)) return res.data
|
||||
@ -94,12 +108,12 @@ export default {
|
||||
normalizeArticle(row) {
|
||||
return {
|
||||
id: row.id || this.$route.params.id,
|
||||
title: row.title || '未命名文章',
|
||||
summary: row.summary || '',
|
||||
articleType: row.article_type || row.type || '企业动态',
|
||||
publishTime: row.publish_time || row.publishTime || '',
|
||||
coverImg: this.normalizeImageUrl(row.cover_img || row.coverImg || ''),
|
||||
content: row.content || ''
|
||||
title: this.getLocalizedField(row, 'title_zh', 'title_en', 'title') || '未命名文章',
|
||||
summary: this.getLocalizedField(row, 'summary_zh', 'summary_en', 'summary'),
|
||||
articleType: this.getLocalizedField(row, 'article_type_zh', 'article_type_en', 'article_type') || row.type || '企业动态',
|
||||
publishTime: this.getLocalizedField(row, 'publish_time_zh', 'publish_time_en', 'publish_time') || row.publishTime || '',
|
||||
coverImg: this.normalizeImageUrl(this.getLocalizedField(row, 'cover_img_zh', 'cover_img_en', 'cover_img') || row.coverImg || ''),
|
||||
content: this.getLocalizedField(row, 'content_zh', 'content_en', 'content')
|
||||
}
|
||||
},
|
||||
async getNewsDetail() {
|
||||
|
||||
@ -291,16 +291,25 @@ export default {
|
||||
// 将接口字段统一转换成页面表格和编辑弹窗使用的字段。
|
||||
return {
|
||||
id: row.id,
|
||||
title: row.title || '',
|
||||
summary: row.summary || '',
|
||||
type: row.article_type || row.type || '企业动态',
|
||||
title: row.title_zh || row.title || '',
|
||||
summary: row.summary_zh || row.summary || '',
|
||||
type: row.article_type_zh || row.article_type || row.type || '企业动态',
|
||||
status: this.getViewStatus(row.status),
|
||||
publishTime: row.publish_time || row.publishTime || '',
|
||||
publishTime: row.publish_time_zh || row.publish_time || row.publishTime || '',
|
||||
updateTime: row.update_time || row.updateTime || '',
|
||||
views: row.read_count || row.views || 0,
|
||||
content: row.content || '',
|
||||
coverUrl: row.cover_img || row.coverUrl || '',
|
||||
coverName: row.cover_name || row.coverName || ''
|
||||
content: row.content_zh || row.content || '',
|
||||
coverUrl: row.cover_img_zh || row.cover_img || row.coverUrl || '',
|
||||
coverName: row.cover_name_zh || row.cover_name || row.coverName || '',
|
||||
english: {
|
||||
title: row.title_en || '',
|
||||
summary: row.summary_en || '',
|
||||
category: row.article_type_en || '',
|
||||
publishTime: row.publish_time_en || '',
|
||||
content: row.content_en || '',
|
||||
coverUrl: row.cover_img_en || '',
|
||||
coverName: row.cover_name_en || ''
|
||||
}
|
||||
}
|
||||
},
|
||||
getResponseList(res) {
|
||||
@ -325,17 +334,24 @@ export default {
|
||||
)
|
||||
},
|
||||
buildArticlePayload(article) {
|
||||
// 将编辑弹窗字段转换成新增/编辑接口需要的字段。
|
||||
// 将中文、英文编辑字段转换成新增/编辑接口需要的双语字段。
|
||||
const english = article.english || {}
|
||||
return {
|
||||
...(article.id ? { id: article.id } : {}),
|
||||
url_link: window.location.href,
|
||||
title: article.title,
|
||||
article_type: article.type,
|
||||
summary: article.summary,
|
||||
title_zh: article.title,
|
||||
title_en: english.title || '',
|
||||
article_type_zh: article.type,
|
||||
article_type_en: english.category || '',
|
||||
summary_zh: article.summary,
|
||||
summary_en: english.summary || '',
|
||||
update_time: article.update_time || article.updateTime,
|
||||
publish_time: article.publish_time || article.publishTime,
|
||||
cover_img: article.coverUrl,
|
||||
content: article.content,
|
||||
publish_time_zh: article.publish_time_zh || article.publishTime,
|
||||
publish_time_en: english.publishTime || '',
|
||||
cover_img_zh: article.coverUrl,
|
||||
cover_img_en: english.coverUrl || '',
|
||||
content_zh: article.content,
|
||||
content_en: english.content || '',
|
||||
status: this.getApiStatus(article.status)
|
||||
}
|
||||
},
|
||||
@ -726,4 +742,4 @@ export default {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -11,10 +11,9 @@
|
||||
<div class="hero-content">
|
||||
<span class="hero-badge">COMPANY NEWS</span>
|
||||
<div class="hero-title-row">
|
||||
<h1>企业动态</h1>
|
||||
<button type="button" class="about-link" @click="goAbout">关于我们 →</button>
|
||||
<h1>{{ isEnglish ? 'Company News' : '企业动态' }}</h1>
|
||||
</div>
|
||||
<p>了解开元云最新动态,把握AI行业前沿资讯,与我们一起见证智能跃迁</p>
|
||||
<p>{{ isEnglish ? 'Stay up to date with Open Computing AI, explore the latest AI industry insights, and witness the intelligent leap with us.' : '了解开元云最新动态,把握AI行业前沿资讯,与我们一起见证智能跃迁' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -101,7 +100,7 @@
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
@ -109,13 +108,12 @@
|
||||
<script>
|
||||
import { reqNewsList } from '@/api/newsapi/newsapi'
|
||||
export default {
|
||||
name: 'NewsView',
|
||||
name: 'NewsView',
|
||||
data() {
|
||||
return {
|
||||
fallbackNewsImage: require('@/assets/image/news.jpg'),
|
||||
activeCategory: 'all',
|
||||
page: 1,
|
||||
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
filterTabs: [
|
||||
@ -129,6 +127,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEnglish() {
|
||||
return this.$i18n && this.$i18n.locale === 'en-US'
|
||||
},
|
||||
featuredNews() {
|
||||
return this.newsList[0]
|
||||
},
|
||||
@ -142,6 +143,11 @@ export default {
|
||||
return Array.from({ length: Math.min(this.totalPages, 3) }, (_, index) => index + 1)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isEnglish() {
|
||||
this.getNewsList()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getNewsList()
|
||||
},
|
||||
@ -187,26 +193,34 @@ export default {
|
||||
企业动态: 'rgba(16,185,129,0.85)',
|
||||
产品动态: 'rgba(99,102,241,0.85)',
|
||||
行业洞察: 'rgba(13,148,136,0.85)',
|
||||
活动资讯: 'rgba(245,158,11,0.85)'
|
||||
活动资讯: 'rgba(245,158,11,0.85)',
|
||||
'Corporate News': 'rgba(16,185,129,0.85)',
|
||||
'Product News': 'rgba(99,102,241,0.85)',
|
||||
'Industry Insights': 'rgba(13,148,136,0.85)',
|
||||
'Event News': 'rgba(245,158,11,0.85)'
|
||||
}
|
||||
return map[type] || 'rgba(99,102,241,0.85)'
|
||||
},
|
||||
getLocalizedField(row, zhField, enField, legacyField) {
|
||||
if (this.isEnglish && row[enField]) return row[enField]
|
||||
return row[zhField] || row[legacyField] || row[enField] || ''
|
||||
},
|
||||
normalizeImageUrl(url) {
|
||||
if (!url) return ''
|
||||
if (/^(https?:|blob:|data:|\/\/)/.test(url)) return url
|
||||
return `${window.location.origin}/idfile?path=${url}`
|
||||
},
|
||||
normalizeNewsItem(row) {
|
||||
const type = row.article_type || '企业动态'
|
||||
const type = this.getLocalizedField(row, 'article_type_zh', 'article_type_en', 'article_type') || '企业动态'
|
||||
return {
|
||||
id: row.id,
|
||||
category: type,
|
||||
tag: type,
|
||||
tagColor: this.getTagColor(type),
|
||||
date: row.publish_time || '',
|
||||
title: row.title || '未命名文章',
|
||||
desc: row.summary || '',
|
||||
img: this.normalizeImageUrl(row.cover_img || ''),
|
||||
date: this.getLocalizedField(row, 'publish_time_zh', 'publish_time_en', 'publish_time'),
|
||||
title: this.getLocalizedField(row, 'title_zh', 'title_en', 'title') || '未命名文章',
|
||||
desc: this.getLocalizedField(row, 'summary_zh', 'summary_en', 'summary'),
|
||||
img: this.normalizeImageUrl(this.getLocalizedField(row, 'cover_img_zh', 'cover_img_en', 'cover_img')),
|
||||
views: row.read_count || 0
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
custom-class="forgot-password-dialog"
|
||||
:visible="visible"
|
||||
width="540px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-dialog custom-class="forgot-password-dialog" :visible="visible" width="540px" :close-on-click-modal="false"
|
||||
destroy-on-close append-to-body @open="handleOpen" @close="handleClose">
|
||||
<div slot="title" class="forgot-dialog-title">
|
||||
<div class="title-icon">
|
||||
<i class="el-icon-lock"></i>
|
||||
@ -25,19 +17,16 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="新密码" prop="password">
|
||||
<el-input v-model="form.password" clearable show-password autocomplete="new-password" placeholder="请输入新密码"></el-input>
|
||||
<el-input v-model="form.password" clearable show-password autocomplete="new-password"
|
||||
placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="验证码" prop="vcode">
|
||||
<div class="code-row">
|
||||
<el-input v-model="form.vcode" clearable autocomplete="off" placeholder="请输入验证码"></el-input>
|
||||
<el-button
|
||||
class="code-btn"
|
||||
:disabled="isDisabled || isGettingCode"
|
||||
:loading="isGettingCode"
|
||||
@click="debouncedGetCode"
|
||||
>
|
||||
{{ sendCodeText }}
|
||||
<el-button class="code-btn" :disabled="isDisabled || isGettingCode" :loading="isGettingCode"
|
||||
@click="debouncedGetCode">
|
||||
{{ sendCodeText }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@ -288,18 +277,21 @@ export default {
|
||||
}
|
||||
|
||||
.code-btn {
|
||||
width: 118px;
|
||||
height: 48px;
|
||||
color: #2f6bff;
|
||||
background: #eef4ff;
|
||||
border-color: #cfe0ff;
|
||||
padding: 0 18px;
|
||||
color: #1d4ed8;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #ffffff;
|
||||
background: #2f6bff;
|
||||
border-color: #2f6bff;
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user