yujialong 1 year ago
parent d1f4161e8c
commit 7f80bfc473
  1. 49
      public/styles/css/editor.css
  2. 127
      src/components/modules/content.vue
  3. 5
      src/const/modules.js
  4. 2
      src/mixins/page/index.js
  5. 80
      src/pages/article/add/editor.js
  6. 18
      src/pages/article/add/index.vue
  7. 289
      src/pages/column/add/index.vue
  8. 7
      src/pages/column/page/iasf.vue
  9. 2
      src/pages/column/page/lightSources.vue

@ -1,4 +1,3 @@
@font-face { @font-face {
font-family: SFProDisplay; font-family: SFProDisplay;
src: url('./styles/font/SF-Pro-Display-Regular.otf'); src: url('./styles/font/SF-Pro-Display-Regular.otf');
@ -7,7 +6,7 @@
font-family: ProximaNova; font-family: ProximaNova;
src: url('./styles/font/ProximaNova-Regular.otf'); src: url('./styles/font/ProximaNova-Regular.otf');
} }
.mce-content-body:not([dir=rtl]) blockquote { .mce-content-body:not([dir='rtl']) blockquote {
padding: 8px 15px; padding: 8px 15px;
border-left: 0; border-left: 0;
background-color: #ededed; background-color: #ededed;
@ -19,6 +18,9 @@
/* width: 900px; */ /* width: 900px; */
margin: 0 auto; margin: 0 auto;
} }
.tiny-wrap .blue {
color: #1583ff;
}
.tiny-wrap blockquote p { .tiny-wrap blockquote p {
margin: 0; margin: 0;
font-style: italic; font-style: italic;
@ -42,10 +44,12 @@
font-weight: 400; font-weight: 400;
color: #101010; color: #101010;
line-height: 32px; line-height: 32px;
white-space: pre-wrap;
} }
.tiny-wrap .en-block p, .tiny-wrap .en-block .img-des { .tiny-wrap .en-block p,
.tiny-wrap .en-block .img-des {
font-family: ProximaNova; font-family: ProximaNova;
letter-spacing: -.0135em; letter-spacing: -0.0135em;
line-height: 1.5em; line-height: 1.5em;
} }
.tiny-wrap .block .tiny-title { .tiny-wrap .block .tiny-title {
@ -81,3 +85,40 @@
width: 300px; width: 300px;
height: 190px; height: 190px;
} }
.tiny-wrap .people {
display: flex;
align-items: center;
margin-bottom: 30px;
}
.tiny-wrap .people .pic {
max-width: 400px;
margin-right: 50px;
}
.tiny-wrap .people h6 {
font-size: 24px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
}
.tiny-wrap .people h6 {
margin-top: 20px;
font-size: 18px;
color: #333;
line-height: 35px;
}
.tiny-wrap .p-title {
display: flex;
align-items: center;
margin: 0 0 10px;
font-size: 22px;
font-weight: 400;
color: #333;
}
.tiny-wrap .p-title:before {
content: '';
width: 5px;
height: 19px;
margin-right: 8px;
background: #1583ff;
border-radius: 4px;
}

@ -1,69 +1,110 @@
<template> <template>
<!-- 内容 --> <!-- 内容 -->
<div> <div>
<el-dialog title="编辑内容" :visible.sync="visible" width="600px" custom-class="module" :close-on-click-modal="false" :before-close="close"> <el-dialog title="编辑内容"
<el-form ref="form" :model="data.form" :rules="rules" label-width="60px"> :visible.sync="visible"
<el-form-item v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label"> width="700px"
<el-input v-if="item.type === 'input'" v-model="data.form[item.prop]" placeholder="请输入" maxlength="100"></el-input> custom-class="module"
<el-input v-if="item.type === 'textarea'" v-model="data.form[item.prop]" type="textarea" placeholder="请输入" maxlength="300"></el-input> :close-on-click-modal="false"
<el-upload :before-close="close">
v-if="item.type === 'upload' && item.crop" <el-form ref="form"
:model="data.form"
:rules="rules"
label-width="60px">
<el-form-item v-for="(item, i) in data.forms"
:key="i"
:prop="item.prop"
:label="item.label">
<el-input v-if="item.type === 'input'"
v-model="data.form[item.prop]"
placeholder="请输入"
maxlength="100"></el-input>
<el-input v-if="item.type === 'textarea'"
v-model="data.form[item.prop]"
type="textarea"
placeholder="请输入"
maxlength="300"></el-input>
<Editor v-if="item.type === 'editor'"
api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
v-model="data.form[item.prop]"
:init="editorConfig" />
<el-upload v-if="item.type === 'upload' && item.crop"
class="uploader" class="uploader"
accept=".jpg,.png,.jpeg,.gif" accept=".jpg,.png,.jpeg,.gif"
:on-change="res => changeFile(res, data.form)" :on-change="res => changeFile(res, data.form)"
:show-file-list="false" :show-file-list="false"
:action="api.upload" :action="api.upload"
:auto-upload="false"> :auto-upload="false">
<img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar"> <img v-if="data.form[item.prop]"
<div class="uploader-default" v-else> :src="data.form[item.prop]"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传图片</p> <p>上传图片</p>
</div> </div>
<div slot="tip" class="el-upload__tip"> <div slot="tip"
class="el-upload__tip">
<p>只支持.jpg,.png格式</p> <p>只支持.jpg,.png格式</p>
</div> </div>
</el-upload> </el-upload>
<el-upload <el-upload v-if="item.type === 'upload' && !item.crop"
v-if="item.type === 'upload' && !item.crop"
class="uploader" class="uploader"
accept=".jpg,.png,.jpeg" accept=".jpg,.png,.jpeg"
:on-success="res => uploadSuccess(res, data.form)" :on-success="res => uploadSuccess(res, data.form)"
:show-file-list="false" :show-file-list="false"
:headers="headers" :headers="headers"
:action="api.upload"> :action="api.upload">
<img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar"> <img v-if="data.form[item.prop]"
<div class="uploader-default" v-else> :src="data.form[item.prop]"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传图片</p> <p>上传图片</p>
</div> </div>
<div slot="tip" class="el-upload__tip"> <div slot="tip"
class="el-upload__tip">
<p>只支持.jpg,.png格式</p> <p>只支持.jpg,.png格式</p>
</div> </div>
</el-upload> </el-upload>
<template v-if="item.type === 'pic'"> <template v-if="item.type === 'pic'">
<img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar"> <img v-if="data.form[item.prop]"
<div class="uploader-default" v-else> :src="data.form[item.prop]"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-picture-outline"></i> <i class="el-icon-picture-outline"></i>
</div> </div>
</template> </template>
<div v-if="item.type === 'link'" class="flex"> <div v-if="item.type === 'link'"
<el-input class="m-r-10" v-model="data.form.link.linkName"></el-input> class="flex">
<el-input class="m-r-10"
v-model="data.form.link.linkName"></el-input>
<el-button @click="toLink(data.form)">设置链接</el-button> <el-button @click="toLink(data.form)">设置链接</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer"
class="dialog-footer">
<el-button @click="$emit('update:visible', false)">取消</el-button> <el-button @click="$emit('update:visible', false)">取消</el-button>
<el-button type="primary" @click="contentSubmit">确定</el-button> <el-button type="primary"
@click="contentSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<Link ref="link" :visible.sync="linkVisible" :data.sync="linkForm" @linkSubmit="linkSubmit" /> <Link ref="link"
:visible.sync="linkVisible"
:data.sync="linkForm"
@linkSubmit="linkSubmit" />
<!-- 剪裁组件弹窗 --> <!-- 剪裁组件弹窗 -->
<el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false"> <el-dialog title="图片裁剪"
<Cropper append-to-body
ref="cropper" :visible.sync="cropperModel"
width="1100px"
:close-on-click-modal="false">
<Cropper ref="cropper"
:img-file.sync="file" :img-file.sync="file"
:is-upload="isUpload" :is-upload="isUpload"
:fixed="fixed" :fixed="fixed"
@ -78,18 +119,22 @@ import Link from '@/components/modules/link'
import Setting from '@/setting' import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import Cropper from '@/components/img-upload/Cropper' import Cropper from '@/components/img-upload/Cropper'
import Editor from '@tinymce/tinymce-vue'
import editorConfig from '@/components/editor'
import Axios from 'axios' import Axios from 'axios'
export default { export default {
props: ['data', 'visible'], props: ['data', 'visible'],
components: { components: {
Link, Link,
Cropper Cropper,
Editor,
}, },
data() { data () {
return { return {
headers: { headers: {
token: Util.local.get(Setting.tokenKey) token: Util.local.get(Setting.tokenKey)
}, },
editorConfig,
rules: {}, rules: {},
linkVisible: false, linkVisible: false,
linkForm: {}, linkForm: {},
@ -104,17 +149,17 @@ export default {
}; };
}, },
watch: { watch: {
visible(open) { visible (open) {
// //
open && this.handleForm() open && this.handleForm()
} }
}, },
mounted() { mounted () {
this.handleForm() this.handleForm()
}, },
methods: { methods: {
// form // form
handleForm() { handleForm () {
const { forms, type } = this.data const { forms, type } = this.data
// //
if (type === 'form' || type === 'introduce') { if (type === 'form' || type === 'introduce') {
@ -139,17 +184,17 @@ export default {
}) })
} }
}, },
close() { close () {
this.$emit('update:visible', false) this.$emit('update:visible', false)
}, },
// //
customUpload(data) { customUpload (data) {
const formData = new FormData() const formData = new FormData()
formData.append('file', data, this.file.name) formData.append('file', data, this.file.name)
this.imgUpload(formData) this.imgUpload(formData)
}, },
// //
compress(img) { compress (img) {
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d') const ctx = canvas.getContext('2d')
// let initSize = img.src.length; // let initSize = img.src.length;
@ -166,7 +211,7 @@ export default {
return ndata return ndata
}, },
// base64bolb // base64bolb
dataURItoBlob(base64Data) { dataURItoBlob (base64Data) {
let byteString let byteString
if (base64Data.split(',')[0].indexOf('base64') >= 0) { if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]) byteString = atob(base64Data.split(',')[1])
@ -186,7 +231,7 @@ export default {
}) })
}, },
// //
imgUpload(formData) { imgUpload (formData) {
this.isUpload = true this.isUpload = true
Axios({ Axios({
method: 'post', method: 'post',
@ -198,13 +243,13 @@ export default {
}, },
}).then(({ data }) => { }).then(({ data }) => {
this.$set(this.curForm, 'pic', data.url) this.$set(this.curForm, 'pic', data.url)
}).catch(res => {}) }).catch(res => { })
this.$refs.cropper.isDisabled = false this.$refs.cropper.isDisabled = false
this.isUpload = false this.isUpload = false
this.cropperModel = false this.cropperModel = false
}, },
// //
changeFile(file, form) { changeFile (file, form) {
const { size, name } = file const { size, name } = file
const ext = name.substring(name.lastIndexOf('.') + 1) const ext = name.substring(name.lastIndexOf('.') + 1)
if (!Util.isImg(ext)) { if (!Util.isImg(ext)) {
@ -226,17 +271,17 @@ export default {
}) })
}, },
// //
uploadSuccess(res, row) { uploadSuccess (res, row) {
this.$set(row, 'pic', res.url) this.$set(row, 'pic', res.url)
}, },
// //
toLink(row, i = 0) { toLink (row, i = 0) {
this.linkVisible = true this.linkVisible = true
this.curIndex = i this.curIndex = i
this.linkForm = row.link this.linkForm = row.link
}, },
// //
linkSubmit() { linkSubmit () {
const el = this.$refs.link const el = this.$refs.link
const data = this.data.form ? this.data.form.link : this.data.list[this.curIndex].link const data = this.data.form ? this.data.form.link : this.data.list[this.curIndex].link
let name let name
@ -267,7 +312,7 @@ export default {
this.linkVisible = false this.linkVisible = false
}, },
// //
contentSubmit() { contentSubmit () {
this.$emit('contentSubmit') this.$emit('contentSubmit')
}, },
} }

@ -6706,7 +6706,7 @@ export default {
required: true required: true
}, },
{ {
type: 'textarea', type: 'editor',
prop: 'des', prop: 'des',
label: '描述' label: '描述'
} }
@ -9015,6 +9015,7 @@ export default {
stations: '', stations: '',
status: '', status: '',
time: '', time: '',
status: '',
} }
] ]
}, },
@ -9647,7 +9648,7 @@ export default {
} }
}, },
{ {
type: 'introduce', type: 'form',
forms: [ forms: [
{ {
type: 'upload', type: 'upload',

@ -78,7 +78,7 @@ export default {
e.originForm = modules[i].originForm e.originForm = modules[i].originForm
} }
}) })
// this.modules = list this.modules = list
console.log("🚀 ~ file: index.js:85 ~ this.$post ~ list:", list) console.log("🚀 ~ file: index.js:85 ~ this.$post ~ list:", list)
} }
}).catch(err => {}) }).catch(err => {})

@ -179,7 +179,8 @@ export default {
branding: false, branding: false,
width: 940, width: 940,
height: 650, //编辑器高度 height: 650, //编辑器高度
min_height: 400, // min_height: 400,
max_height: 650,
content_css: [ //可设置编辑区内容展示的css,谨慎使用 content_css: [ //可设置编辑区内容展示的css,谨慎使用
'./styles/css/editor.css', './styles/css/editor.css',
], ],
@ -297,6 +298,83 @@ export default {
</div> </div>
</div> </div>
` `
},
{ title: '人物详情', description: '', content: `
<div class="tiny-wrap">
<div class="people">
<img class="pic" src="http://10.10.11.7/images/team/5.png"/>
<div class="texts">
<h6>谢明远 XIE Mingyuan</h6>
<div class="text">
<p>同步辐射光源工程经理部 生物医药组 副研究员</p>
<p>负责深圳产业光源生物安全防护晶体学与成像实验站建设</p>
<p>深圳市海外高层次人才孔雀计划C类 </p>
</div>
</div>
</div>
<div class="block">
<h6 class="p-title">基本简介</h6>
<div class="block">
<p>职称副教授</p>
<p>学位博士</p>
<p>毕业学校美国马里兰大学帕克分校</p>
<p>电子邮件<span class="blue">xiemy@mail.iasf.ac.cn</span></p>
</div>
</div>
<div class="block">
<h6 class="p-title">学术经历 </h6>
<div class="block">
<p>2014 毕业于中山大学获理学博士学位</p>
<p>2014-2015 香港理工大学从事博士后研究工作</p>
<p>2015-2016 北京理工大学珠海学院信息学院任讲师主要从事高功率单模光纤激光器大芯径高功率多模光纤激光器以及基于光纤的系统的研发工作</p>
<p>2016-2019 于中山大学物理学院任副研究员主要开展藻类捕光蛋白结构和功能研究</p>
<p>2019-2021 获得广东省青年优秀人才海外派出计划资助赴德国电子同步加速器实验室DESY任访问学者共同搭建世界上首台基于光学参量放大过程的波形相干合成光源</p>
<p>2021年至今 深圳综合粒子设施研究院同步辐射光源经理部生物医药组任副研究员负责深圳产业光源生物安全防护晶体学与成像实验站建设</p>
</div>
</div>
<div class="block">
<h6 class="p-title">学科方向</h6>
<div class="block">
<p>所在学科材料物理</p>
<p>研究方向分子模拟计算材料学统计力学</p>
<p>研究兴趣软物质及复杂流体界面的分子模拟熔盐传蓄热材料热物性的计算模拟</p>
</div>
</div>
<div class="block">
<h6 class="p-title">学术业绩</h6>
<div class="block">
<p>长期从事材料界面软物质和能源材料的分子模拟工作迄今为止以第一作者或通讯作者发表论文16篇</p>
<p>主持科研项目</p>
<p>国家自然科学基金青年项目2019-2021超级电容器双电层结构的多尺度模拟研究11804400</p>
<p>国家自然科学基金面上项目2022-2025接枝表面上液体输运性质的多尺度模拟12174457</p>
</div>
</div>
<div class="block">
<h6 class="p-title">荣誉获奖</h6>
<div class="block">
<p>百千万人才工程国家杰出青年科学基金项目青年千人计划中国科学院百人计划珠江人才青年拔尖人才深圳市高层次人</p>
</div>
</div>
<div class="block">
<h6 class="p-title">代表论著</h6>
<div class="block">
<p>1) F. Liang, J. Ding and S. Liu*, Collective Solvation and Transport at TetrahydrofuranSilica Interfaces for Separation of Aromatic Compounds: Insight from Molecular Dynamics Simulations, Langmuir, 2021, 37, 2091-2103.</p>
<p>2) K. Ren, Y.-P. Wang and S. Liu*, The role of solute polarity on methanolsilica interfacial solvation: a molecular dynamics study, Phys. Chem. Chem. Phys., 2021, 23, 1092-1102.</p>
<p>3) Y.-P. Wang, K. Ren and S. Liu*, The joint effect of surface polarity and concentration on the structure and dynamics of acetonitrile solution: a molecular dynamics simulation study, Phys. Chem. Chem. Phys., 2020, 22, 10322-10334.</p>
<p>4) K. Ren and S. Liu*, The effect of surface polarity on the structure and collective dynamics of liquid ethanol, Phys. Chem. Chem. Phys., 2020, 22, 1204-1213.</p>
<p>5) R. C. Remsing, S. Liu and J. D. Weeks, Long-ranged Contributions to Solvation Free Energies from Theory and Short-ranged Models, Proc. Natl. Acad. Sci. 113, 2819-2826(2016).</p>
<p>6) S. Liu, J. Savage and G. A. Voth, Mesoscale Study of Proton Transport in Proton Exchange Membranes: Role of Morphologies. J. Phys. Chem. C., 119, 1753-1762 (2015).</p>
<p>7) S. Liu and J. T. Fourkas, Orientational Time Correlati.</p>
</div>
</div>
</div>
`
} }
], ],
// content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js", // content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js",

@ -240,7 +240,7 @@
end-placeholder="结束日期"> end-placeholder="结束日期">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item v-else-if="!isJournal" <el-form-item v-else-if="!isJournal && !isThesis"
prop="author" prop="author"
label="作者"> label="作者">
<el-input placeholder="请输入作者" <el-input placeholder="请输入作者"
@ -270,7 +270,7 @@
class="inline-input"></el-input> class="inline-input"></el-input>
</el-form-item> </el-form-item>
</div> </div>
<div v-if="form.articleTemplate === 22 || form.articleTemplate === 23" <div v-if="form.articleTemplate === 22 || form.articleTemplate === 23 || isOrg"
class="item-line"> class="item-line">
<el-form-item prop="edit" <el-form-item prop="edit"
label="编辑"> label="编辑">
@ -335,7 +335,7 @@
</el-form-item> </el-form-item>
</template> </template>
<div v-if="form.articleTemplate === 22 || form.articleTemplate === 23" <div v-if="form.articleTemplate === 22 || form.articleTemplate === 23 || isOrg"
class="item-line"> class="item-line">
<el-form-item prop="source" <el-form-item prop="source"
label="所属分类"> label="所属分类">
@ -372,7 +372,7 @@
@click="setLabel">设置</el-button> @click="setLabel">设置</el-button>
</el-form-item> </el-form-item>
</div> </div>
<el-form-item v-if="form.articleTemplate === 22 || form.articleTemplate === 23" <el-form-item v-if="form.articleTemplate === 22 || form.articleTemplate === 23 || isPeople || isOrg"
prop="summary" prop="summary"
label="摘要"> label="摘要">
<el-input style="width: 940px" <el-input style="width: 940px"
@ -461,14 +461,14 @@
</div> </div>
</template> </template>
<el-form-item v-if="form.articleTemplate !== 24 && form.articleTemplate !== 26" <el-form-item v-if="form.articleTemplate !== 24 && form.articleTemplate !== 26 && !isPublication"
prop="mainBody" prop="mainBody"
label="正文"> label="正文">
<Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' <Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
v-model="form.mainBody" v-model="form.mainBody"
:init="editorConfig" /> :init="editorConfig" />
</el-form-item> </el-form-item>
<template v-if="isJournal"> <template v-if="isJournal || isPublication">
<el-form-item prop="publicationTypeId" <el-form-item prop="publicationTypeId"
label="出版物类型"> label="出版物类型">
<el-select style="width: 234px;" <el-select style="width: 234px;"
@ -901,6 +901,10 @@ export default {
isPeople () { isPeople () {
return this.form.articleTemplate === 72 return this.form.articleTemplate === 72
}, },
//
isOrg () {
return this.form.articleTemplate === 69
},
getModelData: { getModelData: {
get () { get () {
const data = this.classifications.find(item => item.id === this.form.classificationId) const data = this.classifications.find(item => item.id === this.form.classificationId)
@ -1412,6 +1416,8 @@ export default {
// banner // banner
this.fixedNumber = isBanner ? this.fixedNumber = isBanner ?
[1, 0.26] : [1, 0.26] :
this.isPeople ?
[1, 1] :
this.isJournal ? this.isJournal ?
[1, 1.5] : [1, 1.5] :
[1.76, 1] [1.76, 1]

@ -1,20 +1,23 @@
<template> <template>
<div class="page" v-show="loaded"> <div class="page"
v-show="loaded">
<p class="page-name mb">栏目</p> <p class="page-name mb">栏目</p>
<el-form :model="form" :rules="rules" class="input-form model" label-width="120px"> <el-form :model="form"
:rules="rules"
class="input-form model"
label-width="120px">
<div class="item-line"> <div class="item-line">
<el-form-item prop="columnName" label="栏目名称"> <el-form-item prop="columnName"
<el-input label="栏目名称">
placeholder="请输入栏目名称" <el-input placeholder="请输入栏目名称"
v-model="form.columnName" v-model="form.columnName"
clearable clearable
maxlength="40" maxlength="40"
@input="nameChange" @input="nameChange"></el-input>
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="fatherId" label="设置上级"> <el-form-item prop="fatherId"
<el-cascader label="设置上级">
ref="fatherId" <el-cascader ref="fatherId"
v-model="form.fatherId" v-model="form.fatherId"
:options="columns" :options="columns"
:props="columnProps" :props="columnProps"
@ -23,22 +26,26 @@
</el-form-item> </el-form-item>
</div> </div>
<div class="item-line"> <div class="item-line">
<el-form-item prop="typeId" label="栏目类型"> <el-form-item prop="typeId"
<el-select v-model="form.typeId" @change="typeChange"> label="栏目类型">
<el-option <el-select v-model="form.typeId"
v-for="item in types" @change="typeChange">
<el-option v-for="item in types"
:key="item.id" :key="item.id"
:label="item.name" :label="item.name"
:value="item.id"> :value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="pageSize" label="分页条数"> <el-form-item prop="pageSize"
<el-input-number v-model="form.pageSize" :min="0" class="auto"></el-input-number> label="分页条数">
<el-input-number v-model="form.pageSize"
:min="0"
class="auto"></el-input-number>
</el-form-item> </el-form-item>
<el-form-item prop="menuVisible" label="导航菜单可见"> <el-form-item prop="menuVisible"
<el-switch label="导航菜单可见">
v-model="form.menuVisible" <el-switch v-model="form.menuVisible"
:active-value="0" :active-value="0"
:inactive-value="1"> :inactive-value="1">
</el-switch> </el-switch>
@ -46,65 +53,83 @@
</div> </div>
<div class="line"></div> <div class="line"></div>
<template v-if="form.typeId === 1 || form.typeId === 4"> <template v-if="form.typeId === 1 || form.typeId === 4">
<el-form-item prop="columnBanner" label="栏目Banner"> <el-form-item prop="columnBanner"
<el-upload label="栏目Banner">
class="avatar-uploader avatar-uploader-lg" <el-upload class="avatar-uploader avatar-uploader-lg"
accept=".jpg,.png,.jpeg,.gif" accept=".jpg,.png,.jpeg,.gif"
:on-change="changeFile" :on-change="changeFile"
:show-file-list="false" :show-file-list="false"
:action="this.api.upload" :action="this.api.upload"
:auto-upload="false" :auto-upload="false">
> <img v-if="form.columnBanner"
<img v-if="form.columnBanner" :src="form.columnBanner" class="avatar-lg"> :src="form.columnBanner"
<div class="uploader-default" v-else> class="avatar-lg">
<img class="plus" src="@/assets/images/plus.png" alt=""> <div class="uploader-default"
v-else>
<img class="plus"
src="@/assets/images/plus.png"
alt="">
<p>点击上传</p> <p>点击上传</p>
</div> </div>
<div slot="tip" class="el-upload__tip"> <div slot="tip"
class="el-upload__tip">
<p>请上传1920x500PX5M以内的jpgbmppng格式</p> <p>请上传1920x500PX5M以内的jpgbmppng格式</p>
</div> </div>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item prop="subtitle" label="栏目副标题"> <el-form-item prop="subtitle"
<el-input label="栏目副标题">
type="textarea" <el-input type="textarea"
placeholder="请输入栏目副标题" placeholder="请输入栏目副标题"
v-model="form.subtitle" v-model="form.subtitle"></el-input>
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="templateId" label="栏目模板"> <el-form-item prop="templateId"
<el-select v-model="form.templateId" @change="getStyle"> label="栏目模板">
<el-option <el-select v-model="form.templateId"
v-for="item in templates" @change="getStyle">
<el-option v-for="item in templates"
:key="item.id" :key="item.id"
:label="item.templateType" :label="item.templateType"
:value="item.id"> :value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="listStyleId" label="列表样式"> <el-form-item prop="listStyleId"
label="列表样式">
<ul class="styles"> <ul class="styles">
<li v-for="(item, i) in listStyle" :key="i" @click="form.listStyleId = item.id"> <li v-for="(item, i) in listStyle"
:key="i"
@click="form.listStyleId = item.id">
<div class="review"> <div class="review">
<img style="width: 90px;max-height: 110px;" :src="require('@/assets/images/style/' + item.id + '.png')" alt=""> <img style="width: 90px;max-height: 110px;"
:src="require('@/assets/images/style/' + item.id + '.png')"
alt="">
</div> </div>
<el-radio v-model="form.listStyleId" :label="item.id">{{ item.style }}</el-radio> <el-radio v-model="form.listStyleId"
:label="item.id">{{ item.style }}</el-radio>
</li> </li>
</ul> </ul>
</el-form-item> </el-form-item>
<el-form-item prop="detailStyleId" label="详情样式"> <el-form-item prop="detailStyleId"
label="详情样式">
<ul class="styles"> <ul class="styles">
<li v-for="(item, i) in detailStyleId" :key="i" @click="form.detailStyleId = item.id"> <li v-for="(item, i) in detailStyleId"
:key="i"
@click="form.detailStyleId = item.id">
<div class="review"> <div class="review">
<img :style="{width: item.id == 24 ? '50px' : '90px', 'max-height': '110px'}" :src="require('@/assets/images/style/' + item.id + '.png')" alt=""> <img :style="{width: item.id == 24 ? '50px' : '90px', 'max-height': '110px'}"
:src="require('@/assets/images/style/' + item.id + '.png')"
alt="">
</div> </div>
<el-radio v-model="form.detailStyleId" :label="item.id">{{ item.style }}</el-radio> <el-radio v-model="form.detailStyleId"
:label="item.id">{{ item.style }}</el-radio>
</li> </li>
</ul> </ul>
</el-form-item> </el-form-item>
</template> </template>
<template v-if="form.typeId === 2"> <template v-if="form.typeId === 2">
<el-form-item prop="connectionType" label="连接类型"> <el-form-item prop="connectionType"
label="连接类型">
<el-radio-group v-model="form.connectionType"> <el-radio-group v-model="form.connectionType">
<el-radio :label="1">站内链接</el-radio> <el-radio :label="1">站内链接</el-radio>
<el-radio :label="2">站外链接</el-radio> <el-radio :label="2">站外链接</el-radio>
@ -113,17 +138,16 @@
</el-form-item> </el-form-item>
<template v-if="form.connectionType === 1"> <template v-if="form.connectionType === 1">
<el-form-item label="站内链接"> <el-form-item label="站内链接">
<el-cascader <el-cascader v-model="links"
v-model="links"
:options="columns" :options="columns"
:props="columnProps" :props="columnProps"
clearable clearable
@change="getArticle"></el-cascader> @change="getArticle"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item label="文章"> <el-form-item label="文章">
<el-select v-model="article" clearable> <el-select v-model="article"
<el-option clearable>
v-for="item in articles" <el-option v-for="item in articles"
:key="item.id" :key="item.id"
:label="item.title" :label="item.title"
:value="item.id"> :value="item.id">
@ -131,18 +155,19 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</template> </template>
<el-form-item v-show="form.connectionType === 2" prop="linkAddress" label="站外链接"> <el-form-item v-show="form.connectionType === 2"
<el-input prop="linkAddress"
placeholder="请输入站外链接" label="站外链接">
<el-input placeholder="请输入站外链接"
v-model.trim="form.linkAddress" v-model.trim="form.linkAddress"
clearable clearable></el-input>
></el-input>
</el-form-item> </el-form-item>
<template v-if="form.connectionType === 3"> <template v-if="form.connectionType === 3">
<el-form-item prop="siteSelection" label="站点选择"> <el-form-item prop="siteSelection"
<el-select v-model="form.siteSelection" @change="getOtherColumn"> label="站点选择">
<el-option <el-select v-model="form.siteSelection"
v-for="item in sites" @change="getOtherColumn">
<el-option v-for="item in sites"
:key="item.id" :key="item.id"
:label="item.siteName" :label="item.siteName"
:value="item.id"> :value="item.id">
@ -150,17 +175,16 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="栏目"> <el-form-item label="栏目">
<el-cascader <el-cascader v-model="otherLink"
v-model="otherLink"
:options="otherColumns" :options="otherColumns"
:props="columnProps" :props="columnProps"
clearable clearable
@change="getArticle"></el-cascader> @change="getArticle"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item label="文章"> <el-form-item label="文章">
<el-select v-model="otherArticle" clearable> <el-select v-model="otherArticle"
<el-option clearable>
v-for="item in otherArticles" <el-option v-for="item in otherArticles"
:key="item.id" :key="item.id"
:label="item.title" :label="item.title"
:value="item.id"> :value="item.id">
@ -168,30 +192,35 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</template> </template>
<el-form-item prop="isOpen" label="新窗口打开"> <el-form-item prop="isOpen"
<el-switch label="新窗口打开">
v-model="form.isOpen" <el-switch v-model="form.isOpen"
:active-value="1" :active-value="1"
:inactive-value="0"> :inactive-value="0">
</el-switch> </el-switch>
</el-form-item> </el-form-item>
</template> </template>
<template v-if="form.typeId === 3"> <template v-if="form.typeId === 3">
<el-form-item prop="templateId" label="栏目模板"> <el-form-item prop="templateId"
label="栏目模板">
<el-select v-model="form.templateId"> <el-select v-model="form.templateId">
<el-option <el-option label="长页模板"
label="长页模板"
:value="9"> :value="9">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="listStyleId" label="列表样式"> <el-form-item prop="listStyleId"
label="列表样式">
<ul class="styles"> <ul class="styles">
<li v-for="(item, i) in pageStyle" :key="i" @click="form.listStyleId = item.id"> <li v-for="(item, i) in pageStyle"
:key="i"
@click="form.listStyleId = item.id">
<div class="review"> <div class="review">
<img :src="require('@/assets/images/page/' + item.pic + '.png')" alt=""> <img :src="require('@/assets/images/page/' + item.pic + '.png')"
alt="">
</div> </div>
<el-radio v-model="form.listStyleId" :label="item.id">{{ item.style }}</el-radio> <el-radio v-model="form.listStyleId"
:label="item.id">{{ item.style }}</el-radio>
</li> </li>
</ul> </ul>
</el-form-item> </el-form-item>
@ -205,13 +234,17 @@
</el-form-item> --> </el-form-item> -->
</el-form> </el-form>
<div class="btns"> <div class="btns">
<el-button type="primary" @click="submit(0)">确定</el-button> <el-button type="primary"
@click="submit(0)">确定</el-button>
<el-button @click="$router.push('/column')">取消</el-button> <el-button @click="$router.push('/column')">取消</el-button>
</div> </div>
<!-- 剪裁组件弹窗 --> <!-- 剪裁组件弹窗 -->
<el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false"> <el-dialog title="图片裁剪"
<Cropper append-to-body
ref="cropper" :visible.sync="cropperModel"
width="1100px"
:close-on-click-modal="false">
<Cropper ref="cropper"
:img-file.sync="file" :img-file.sync="file"
:is-upload="isUpload" :is-upload="isUpload"
:fixed="true" :fixed="true"
@ -228,7 +261,7 @@ import Cropper from '@/components/img-upload/Cropper'
import Axios from 'axios' import Axios from 'axios'
import Modules from '@/const/modules' import Modules from '@/const/modules'
export default { export default {
data() { data () {
return { return {
loaded: false, loaded: false,
userId: +this.$store.state.user.userId, userId: +this.$store.state.user.userId,
@ -271,7 +304,7 @@ export default {
listStyleId: 1, listStyleId: 1,
detailStyleId: 1, detailStyleId: 1,
connectionType: 1, connectionType: 1,
linkAddress : '', linkAddress: '',
showWithDetails: 0, showWithDetails: 0,
siteSelection: '', siteSelection: '',
status: 1, status: 1,
@ -320,7 +353,7 @@ export default {
'userName' 'userName'
]) ])
}, },
mounted() { mounted () {
this.$store.commit('user/setCrumbs', [ this.$store.commit('user/setCrumbs', [
{ {
name: '站点管理', name: '站点管理',
@ -345,14 +378,14 @@ export default {
watch: { watch: {
// , // ,
form: { form: {
handler(val){ handler (val) {
this.updateTime++ this.updateTime++
}, },
deep:true deep: true
}, },
}, },
// //
beforeRouteLeave(to, from, next) { beforeRouteLeave (to, from, next) {
if (this.submiting) { if (this.submiting) {
next() next()
} else { } else {
@ -374,12 +407,12 @@ export default {
}, },
methods: { methods: {
// //
getList() { getList () {
this.$post(this.api.listWithTree, { this.$post(this.api.listWithTree, {
siteId: this.site.id, siteId: this.site.id,
columnName: '', columnName: '',
templateId: '', templateId: '',
typeId : '', typeId: '',
isSort: 1 isSort: 1
}).then(({ data }) => { }).then(({ data }) => {
this.columns = data this.columns = data
@ -390,17 +423,17 @@ export default {
this.getOtherColumn() this.getOtherColumn()
this.loaded = true this.loaded = true
} }
}).catch(err => {}) }).catch(err => { })
}, },
// disabled // disabled
handleId(list) { handleId (list) {
list.forEach(e => { list.forEach(e => {
if (this.isEdit && e.id == this.form.id) e.disabled = true if (this.isEdit && e.id == this.form.id) e.disabled = true
e.children.length ? this.handleId(e.children) : delete e.children e.children.length ? this.handleId(e.children) : delete e.children
}) })
}, },
// //
getArticle() { getArticle () {
// / // /
const inner = this.form.connectionType === 1 const inner = this.form.connectionType === 1
const id = inner ? this.links[this.links.length - 1] : this.otherLink[this.otherLink.length - 1] const id = inner ? this.links[this.links.length - 1] : this.otherLink[this.otherLink.length - 1]
@ -414,10 +447,10 @@ export default {
isDisable: 0 isDisable: 0
}).then(({ data }) => { }).then(({ data }) => {
this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) // this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) //
}).catch(err => {}) }).catch(err => { })
}, },
// //
getData() { getData () {
this.$post(`${this.api.findColumn}?id=${this.form.id}`).then(({ data }) => { this.$post(`${this.api.findColumn}?id=${this.form.id}`).then(({ data }) => {
this.form = data this.form = data
if (data.typeId === 1 || data.typeId === 4) this.getStyle(0) if (data.typeId === 1 || data.typeId === 4) this.getStyle(0)
@ -452,16 +485,16 @@ export default {
this.updateTime = 1 this.updateTime = 1
}) })
this.loaded = true this.loaded = true
}).catch(err => {}) }).catch(err => { })
} }
} else { } else {
this.loaded = true this.loaded = true
} }
this.getOtherColumn() this.getOtherColumn()
}).catch(err => {}) }).catch(err => { })
}, },
// //
typeChange(val) { typeChange (val) {
if (val === 1 || val === 4) { if (val === 1 || val === 4) {
this.form.templateId = 1 this.form.templateId = 1
this.getStyle() this.getStyle()
@ -471,11 +504,11 @@ export default {
} }
}, },
// //
getTemplate() { getTemplate () {
this.$post(this.api.listOfColumnTemplates).then(({ data }) => { this.$post(this.api.listOfColumnTemplates).then(({ data }) => {
this.templates = data this.templates = data
this.isEdit || this.getStyle() this.isEdit || this.getStyle()
}).catch(err => {}) }).catch(err => { })
this.$post(this.api.longPageListStyle).then(({ data }) => { this.$post(this.api.longPageListStyle).then(({ data }) => {
// path // path
@ -490,22 +523,24 @@ export default {
e.pic = pic e.pic = pic
}) })
this.pageStyle = data this.pageStyle = data
}).catch(err => {}) }).catch(err => { })
}, },
// id // id
getStyle(set = 1) { getStyle (set = 1) {
const { templateId } = this.form const { templateId } = this.form
this.$post(`${this.api.theTemplateIdGetsTheStyle}?templateId=${templateId}`).then(({ data }) => { this.$post(`${this.api.theTemplateIdGetsTheStyle}?templateId=${templateId}`).then(({ data }) => {
this.listStyle = data.listingTemplateTypes this.listStyle = data.listingTemplateTypes
this.detailStyleId = data.detailsTypeOfTheTemplate const detailList = data.detailsTypeOfTheTemplate
if (templateId == 11) detailList.shift() //
this.detailStyleId = detailList
if (set) { if (set) {
this.form.listStyleId = this.listStyle[templateId === 1 ? 1 : 0].id this.form.listStyleId = this.listStyle[templateId === 1 ? 1 : 0].id
this.form.detailStyleId = this.detailStyleId[0].id this.form.detailStyleId = this.detailStyleId[templateId === 7 ? 1 : 0].id
} }
}).catch(err => {}) }).catch(err => { })
}, },
// //
getSite() { getSite () {
this.$post(this.api.site, { this.$post(this.api.site, {
page: 1, page: 1,
limit: 1000, limit: 1000,
@ -513,15 +548,15 @@ export default {
}).then(({ data }) => { }).then(({ data }) => {
data.records.splice(data.records.findIndex(e => e.id == this.site.id), 1) // data.records.splice(data.records.findIndex(e => e.id == this.site.id), 1) //
this.sites = data.records this.sites = data.records
}).catch(e => {}) }).catch(e => { })
}, },
// //
getOtherColumn(val) { getOtherColumn (val) {
this.form.siteSelection && this.$post(this.api.listWithTree, { this.form.siteSelection && this.$post(this.api.listWithTree, {
siteId: this.form.siteSelection, siteId: this.form.siteSelection,
columnName: '', columnName: '',
templateId: '', templateId: '',
typeId : '', typeId: '',
isSort: 1 isSort: 1
}).then(({ data }) => { }).then(({ data }) => {
if (val) { if (val) {
@ -530,10 +565,10 @@ export default {
this.otherLink = '' this.otherLink = ''
} }
this.otherColumns = data this.otherColumns = data
}).catch(err => {}) }).catch(err => { })
}, },
// //
nameChange(){ nameChange () {
clearTimeout(this.nameTimer) clearTimeout(this.nameTimer)
this.nameTimer = setTimeout(() => { this.nameTimer = setTimeout(() => {
const { columnName, fatherId, id } = this.form const { columnName, fatherId, id } = this.form
@ -549,19 +584,19 @@ export default {
}).catch(res => { }).catch(res => {
this.nameRepeat = true this.nameRepeat = true
}) })
}else{ } else {
this.nameRepeat = false this.nameRepeat = false
} }
}, 500) }, 500)
}, },
// //
fatherIdChange(val) { fatherIdChange (val) {
const check = this.$refs.fatherId.getCheckedNodes() const check = this.$refs.fatherId.getCheckedNodes()
this.form.level = check.length ? check[0].level + 1 : 1 // level this.form.level = check.length ? check[0].level + 1 : 1 // level
this.nameChange() this.nameChange()
}, },
// //
customUpload(data) { customUpload (data) {
const formData = new FormData() const formData = new FormData()
formData.append('file', data, this.file.name) formData.append('file', data, this.file.name)
formData.append('quote', this.form.columnName) formData.append('quote', this.form.columnName)
@ -571,10 +606,10 @@ export default {
this.imgUpload(formData) this.imgUpload(formData)
}, },
// //
compress(img) { compress (img) {
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d') const ctx = canvas.getContext('2d')
console.log("🚀 ~ file: index.vue:540 ~ compress ~ ctx", ctx,img.width) console.log("🚀 ~ file: index.vue:540 ~ compress ~ ctx", ctx, img.width)
// let initSize = img.src.length; // let initSize = img.src.length;
const width = img.width const width = img.width
const height = img.height const height = img.height
@ -589,7 +624,7 @@ export default {
return ndata return ndata
}, },
// base64bolb // base64bolb
dataURItoBlob(base64Data) { dataURItoBlob (base64Data) {
let byteString let byteString
if (base64Data.split(',')[0].indexOf('base64') >= 0) { if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]) byteString = atob(base64Data.split(',')[1])
@ -609,7 +644,7 @@ export default {
}) })
}, },
// //
imgUpload(formData) { imgUpload (formData) {
this.isUpload = true this.isUpload = true
Axios({ Axios({
method: 'post', method: 'post',
@ -621,16 +656,16 @@ export default {
}, },
}).then(({ data }) => { }).then(({ data }) => {
let url = this.form.columnBanner let url = this.form.columnBanner
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => {}).catch(e => {}) // url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => { }).catch(e => { }) //
this.form.columnBanner = data.url this.form.columnBanner = data.url
this.fileId = data.id this.fileId = data.id
}).catch(res => {}) }).catch(res => { })
this.$refs.cropper.isDisabled = false this.$refs.cropper.isDisabled = false
this.isUpload = false this.isUpload = false
this.cropperModel = false this.cropperModel = false
}, },
// //
changeFile(file) { changeFile (file) {
const { size, name } = file const { size, name } = file
const ext = name.substring(name.lastIndexOf('.') + 1) const ext = name.substring(name.lastIndexOf('.') + 1)
if (!Util.isImg(ext)) { if (!Util.isImg(ext)) {
@ -651,7 +686,7 @@ export default {
}) })
}, },
// //
updateFile(form, quoteId) { updateFile (form, quoteId) {
this.fileId && this.$post(this.api.updateFile, { this.fileId && this.$post(this.api.updateFile, {
id: this.fileId, id: this.fileId,
isRelease: 1, isRelease: 1,
@ -659,10 +694,10 @@ export default {
quoteId quoteId
}).then(res => { }).then(res => {
this.fileId = '' this.fileId = ''
}).catch(err => {}) }).catch(err => { })
}, },
// //
submit(next) { submit (next) {
if (this.submiting) return false if (this.submiting) return false
const { form } = this const { form } = this
if (!form.columnName) return Util.errorMsg('请填写栏目名称') if (!form.columnName) return Util.errorMsg('请填写栏目名称')
@ -710,7 +745,7 @@ export default {
} }
}, },
// //
savePage(columnId) { savePage (columnId) {
const { listStyleId } = this.form const { listStyleId } = this.form
const module = Modules[this.pageStyle.find(e => e.id == listStyleId).path] // module.js const module = Modules[this.pageStyle.find(e => e.id == listStyleId).path] // module.js
if (module) { if (module) {
@ -722,7 +757,7 @@ export default {
editorId: this.userId, editorId: this.userId,
jsonBeforeEditing: module, jsonBeforeEditing: module,
theEditedJson: module, theEditedJson: module,
}).then(res => {}).catch(err => {}) }).then(res => { }).catch(err => { })
} }
} }
} }
@ -738,7 +773,7 @@ $upload-lg-height: 102px;
position: relative; position: relative;
width: $upload-width; width: $upload-width;
height: $upload-height; height: $upload-height;
border: 1px solid #DCDEE0; border: 1px solid #dcdee0;
border-radius: 2px; border-radius: 2px;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
@ -749,7 +784,7 @@ $upload-lg-height: 102px;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-align: center; text-align: center;
background: #FAFAFA; background: #fafafa;
p { p {
margin-top: 10px; margin-top: 10px;
font-size: 14px; font-size: 14px;
@ -803,7 +838,7 @@ $upload-lg-height: 102px;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
&:hover .review { &:hover .review {
border-color: #2962FF; border-color: #2962ff;
} }
} }
.review { .review {
@ -813,7 +848,7 @@ $upload-lg-height: 102px;
width: 170px; width: 170px;
height: 112px; height: 112px;
margin-bottom: 10px; margin-bottom: 10px;
border: 1px solid #DCDEE0; border: 1px solid #dcdee0;
border-radius: 2px; border-radius: 2px;
img { img {
width: 50px; width: 50px;

@ -317,7 +317,12 @@
<ul class="tools"> <ul class="tools">
<li v-for="(item, i) in modules[18].list" <li v-for="(item, i) in modules[18].list"
:key="i">{{ item.title }}</li> :key="i">
<img :src="'http://10.10.11.7/images/iasf/icon' + (i < 4 ? i + 1 : 1) + '.png'"
alt=""
class="icon">
{{ item.title }}
</li>
<div class="cover" <div class="cover"
@click="toSet(18)">点击更换导航</div> @click="toSet(18)">点击更换导航</div>
</ul> </ul>

@ -95,7 +95,6 @@
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>序号</th>
<th>光源名称</th> <th>光源名称</th>
<th>国家</th> <th>国家</th>
<th>地点</th> <th>地点</th>
@ -105,6 +104,7 @@
<th>重复频率/Hz Repetition rate</th> <th>重复频率/Hz Repetition rate</th>
<th>设施长度/m Overall length</th> <th>设施长度/m Overall length</th>
<th>线站数量</th> <th>线站数量</th>
<th>状态</th>
<th>出光时间</th> <th>出光时间</th>
</tr> </tr>
</thead> </thead>

Loading…
Cancel
Save