Commit 57104fe8 authored by liyang's avatar liyang

fix:修复若干bug

parent 9d43fca6
......@@ -10,20 +10,35 @@
size="mini"
@click="handleAdd"
v-hasPermi="['aboutSts:edit']"
>新增</el-button>
>新增</el-button
>
</el-col>
</el-row>
<el-table v-loading="loading" :data="list" border>
<el-table-column label="序号" type="index" align="center" width="55" />
<el-table-column label="排序" align="center" prop="sortOrder" width="80" />
<el-table-column label="标题" align="center" prop="title" show-overflow-tooltip />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<el-table-column
label="标题"
align="center"
prop="title"
show-overflow-tooltip
/>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="180"
>
<template slot-scope="scope">
<el-button
size="mini"
......@@ -31,14 +46,16 @@
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['aboutSts:edit']"
>修改</el-button>
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['aboutSts:edit']"
>删除</el-button>
>删除</el-button
>
</template>
</el-table-column>
</el-table>
......@@ -47,7 +64,12 @@
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="排序" prop="sortOrder">
<el-input-number v-model="form.sortOrder" :min="0" controls-position="right" style="width: 100%" />
<el-input-number
v-model="form.sortOrder"
:min="0"
controls-position="right"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="请输入标题" />
......@@ -65,13 +87,19 @@
</template>
<script>
import { listAboutSts, getAboutSts, addAboutSts, updateAboutSts, delAboutSts } from "@/api/aboutSts"
import Editor from "@/components/Editor"
import {
listAboutSts,
getAboutSts,
addAboutSts,
updateAboutSts,
delAboutSts,
} from "@/api/aboutSts";
import Editor from "@/components/Editor";
export default {
name: "AboutSts",
components: {
Editor
Editor,
},
data() {
return {
......@@ -81,86 +109,90 @@ export default {
open: false,
form: {
id: undefined,
title: '',
content: '',
sortOrder: 0
title: "",
content: "",
sortOrder: 0,
},
rules: {
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
]
}
}
title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
},
};
},
created() {
this.getList()
this.getList();
},
methods: {
getList() {
this.loading = true
listAboutSts().then(response => {
this.list = response.data || []
this.loading = false
}).catch(() => {
this.loading = false
})
this.loading = true;
listAboutSts()
.then((response) => {
this.list = response.data || [];
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
cancel() {
this.open = false
this.resetForm()
this.open = false;
this.resetForm();
},
handleAdd() {
this.resetForm()
this.open = true
this.title = "添加关于STS"
this.resetForm();
this.open = true;
this.title = "添加关于STS";
},
handleUpdate(row) {
this.resetForm()
const id = row.id || this.ids
getAboutSts(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改关于STS"
})
this.resetForm();
const id = row.id || this.ids;
getAboutSts(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改关于STS";
});
},
handleDelete(row) {
this.$modal.confirm('是否确认删除标题为"' + row.title + '"的数据项?').then(() => {
return delAboutSts(row.id)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
this.$modal
.confirm('是否确认删除标题为"' + row.title + '"的数据项?')
.then(() => {
return delAboutSts(row.id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.id) {
updateAboutSts(this.form).then(() => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addAboutSts(this.form).then(() => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
})
});
},
resetForm() {
this.form = {
id: undefined,
title: '',
content: '',
sortOrder: 0
}
title: "",
content: "",
sortOrder: 0,
};
if (this.$refs.form) {
this.$refs.form.resetFields()
this.$refs.form.resetFields();
}
}
}
}
},
},
};
</script>
......@@ -5,32 +5,70 @@
<el-card>
<div slot="header" class="clearfix">
<span>介绍详情</span>
<el-button type="primary" size="mini" @click="enterEdit" v-hasPermi="['homepage:introduction:edit']">编辑</el-button>
<el-button
type="primary"
size="mini"
@click="enterEdit"
v-hasPermi="['homepage:introduction:edit']"
>编辑</el-button
>
</div>
<el-descriptions :column="1" border>
<el-descriptions-item label="标题">
{{ form.title || '未设置' }}
</el-descriptions-item>
<el-descriptions-item label="简介">
{{ form.summary || '未设置' }}
</el-descriptions-item>
<el-descriptions-item label="图片">
<div v-if="form.images && form.images.length">
<img v-for="(img, index) in form.images" :key="index" :src="img" style="max-width: 200px; max-height: 150px; margin-right: 10px;" />
</div>
<span v-else>未设置</span>
</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag :type="form.status === '0' ? 'success' : 'danger'">
{{ form.status ? dict.type.sys_normal_disable.find(item => item.value === form.status).label : '未知' }}
</el-tag>
</el-descriptions-item>
</el-descriptions>
<el-form ref="detailForm" :model="form" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="标题">
<span class="detail-value">{{ form.title || "未设置" }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="简介">
<span class="detail-value">{{ form.summary || "未设置" }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="图片">
<div v-if="form.images && form.images.length">
<img
v-for="(img, index) in form.images.split(',')"
:key="index"
:src="img"
style="
max-width: 200px;
max-height: 150px;
margin-right: 10px;
"
/>
</div>
<span v-else class="detail-value">未设置</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态">
<el-tag :type="form.status === '0' ? 'success' : 'danger'">
{{
form.status
? dict.type.sys_normal_disable.find(
(item) => item.value === form.status
).label
: "未知"
}}
</el-tag>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
<!-- 编辑视图 -->
<el-form v-else ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
<el-form
v-else
ref="form"
:model="form"
:rules="rules"
label-width="80px"
v-loading="loading"
>
<el-row>
<el-col :span="24">
<el-form-item label="标题" prop="title">
......@@ -39,12 +77,16 @@
</el-col>
<el-col :span="24">
<el-form-item label="简介" prop="summary">
<el-input v-model="form.summary" type="textarea" placeholder="请输入简介" />
<el-input
v-model="form.summary"
type="textarea"
placeholder="请输入简介"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="图片" prop="images">
<image-upload v-model="form.images" :multiple="true"/>
<image-upload v-model="form.images" :multiple="true" />
</el-form-item>
</el-col>
<el-col :span="24">
......@@ -54,13 +96,19 @@
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
>{{ dict.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="submitForm" v-hasPermi="['homepage:introduction:edit']">保 存</el-button>
<el-button
type="primary"
@click="submitForm"
v-hasPermi="['homepage:introduction:edit']"
>保 存</el-button
>
<el-button @click="cancelEdit">取消</el-button>
</el-form-item>
</el-form>
......@@ -68,11 +116,15 @@
</template>
<script>
import { getIntroduction, addIntroduction, updateIntroduction } from "@/api/homepage/introduction"
import {
getIntroduction,
addIntroduction,
updateIntroduction,
} from "@/api/homepage/introduction";
export default {
name: "Introduction",
dicts: ['sys_normal_disable'],
dicts: ["sys_normal_disable"],
data() {
return {
loading: true,
......@@ -82,73 +134,87 @@ export default {
title: undefined,
summary: undefined,
images: undefined,
status: "0"
status: "0",
},
rules: {
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
],
summary: [
{ required: true, message: "简介不能为空", trigger: "blur" }
]
}
}
title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
summary: [{ required: true, message: "简介不能为空", trigger: "blur" }],
},
};
},
created() {
this.getIntroductionData()
this.getIntroductionData();
},
methods: {
getIntroductionData() {
this.loading = true
getIntroduction().then(response => {
if (response.data) {
this.form = response.data
} else {
this.loading = true;
getIntroduction()
.then((response) => {
if (response.data) {
this.form = response.data;
} else {
this.form = {
introId: undefined,
title: undefined,
summary: undefined,
images: undefined,
status: "0",
};
}
this.loading = false;
})
.catch(() => {
this.form = {
introId: undefined,
title: undefined,
summary: undefined,
images: undefined,
status: "0"
}
}
this.loading = false
}).catch(() => {
this.form = {
introId: undefined,
title: undefined,
summary: undefined,
images: undefined,
status: "0"
}
this.loading = false
})
status: "0",
};
this.loading = false;
});
},
enterEdit() {
this.editing = true
this.editing = true;
},
cancelEdit() {
this.editing = false
this.editing = false;
},
submitForm: function() {
this.$refs["form"].validate(valid => {
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.introId != undefined) {
updateIntroduction(this.form).then(() => {
this.$modal.msgSuccess("保存成功")
this.getIntroductionData()
this.editing = false
})
this.$modal.msgSuccess("保存成功");
this.getIntroductionData();
this.editing = false;
});
} else {
addIntroduction(this.form).then(() => {
this.$modal.msgSuccess("保存成功")
this.getIntroductionData()
this.editing = false
})
this.$modal.msgSuccess("保存成功");
this.getIntroductionData();
this.editing = false;
});
}
}
})
}
});
},
},
};
</script>
<style lang="scss" scoped>
.detail-value {
color: #606266;
line-height: 32px;
}
.clearfix {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
&::after {
display: none;
}
}
</script>
</style>
......@@ -5,34 +5,71 @@
<el-card>
<div slot="header" class="clearfix">
<span>概况详情</span>
<el-button type="primary" size="mini" @click="enterEdit" v-hasPermi="['homepage:overview:edit']">编辑</el-button>
<el-button
type="primary"
size="mini"
@click="enterEdit"
v-hasPermi="['homepage:overview:edit']"
>编辑</el-button
>
</div>
<el-descriptions :column="1" border>
<el-descriptions-item label="标题">
{{ form.title || '未设置' }}
</el-descriptions-item>
<el-descriptions-item label="简介">
{{ form.summary || '未设置' }}
</el-descriptions-item>
<el-descriptions-item label="图片">
<img v-if="form.image" :src="form.image" style="max-width: 300px; max-height: 200px;" />
<span v-else>未设置</span>
</el-descriptions-item>
<el-descriptions-item label="视频">
<a v-if="form.video" :href="form.video" target="_blank">查看视频</a>
<span v-else>未设置</span>
</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag :type="form.status === '0' ? 'success' : 'danger'">
{{ form.status ? dict.type.sys_normal_disable.find(item => item.value === form.status).label : '未知' }}
</el-tag>
</el-descriptions-item>
</el-descriptions>
<el-form ref="detailForm" :model="form" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="标题">
<span class="detail-value">{{ form.title || "未设置" }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="简介">
<span class="detail-value">{{ form.summary || "未设置" }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="图片">
<img
v-if="form.image"
:src="form.image"
style="max-width: 300px; max-height: 200px"
/>
<span v-else class="detail-value">未设置</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="视频">
<a v-if="form.video" :href="form.video" target="_blank"
>查看视频</a
>
<span v-else class="detail-value">未设置</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态">
<el-tag :type="form.status === '0' ? 'success' : 'danger'">
{{
form.status
? dict.type.sys_normal_disable.find(
(item) => item.value === form.status
).label
: "未知"
}}
</el-tag>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
<!-- 编辑视图 -->
<el-form v-else ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
<el-form
v-else
ref="form"
:model="form"
:rules="rules"
label-width="80px"
v-loading="loading"
>
<el-row>
<el-col :span="24">
<el-form-item label="标题" prop="title">
......@@ -41,12 +78,16 @@
</el-col>
<el-col :span="24">
<el-form-item label="简介" prop="summary">
<el-input v-model="form.summary" type="textarea" placeholder="请输入简介" />
<el-input
v-model="form.summary"
type="textarea"
placeholder="请输入简介"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="图片" prop="image">
<image-upload v-model="form.image"/>
<image-upload v-model="form.image" />
</el-form-item>
</el-col>
<el-col :span="24">
......@@ -66,13 +107,19 @@
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
>{{ dict.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="submitForm" v-hasPermi="['homepage:overview:edit']">保 存</el-button>
<el-button
type="primary"
@click="submitForm"
v-hasPermi="['homepage:overview:edit']"
>保 存</el-button
>
<el-button @click="cancelEdit">取消</el-button>
</el-form-item>
</el-form>
......@@ -80,15 +127,19 @@
</template>
<script>
import { getOverview, addOverview, updateOverview } from "@/api/homepage/overview"
import FileUpload from "@/components/FileUpload"
import {
getOverview,
addOverview,
updateOverview,
} from "@/api/homepage/overview";
import FileUpload from "@/components/FileUpload";
export default {
name: "Overview",
components: {
FileUpload
FileUpload,
},
dicts: ['sys_normal_disable'],
dicts: ["sys_normal_disable"],
data() {
return {
loading: true,
......@@ -99,72 +150,90 @@ export default {
summary: undefined,
image: undefined,
video: undefined,
status: "0"
status: "0",
},
rules: {
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
]
}
}
title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
},
};
},
created() {
this.getOverviewData()
this.getOverviewData();
},
methods: {
getOverviewData() {
this.loading = true
getOverview().then(response => {
if (response.data) {
this.form = response.data
} else {
this.loading = true;
getOverview()
.then((response) => {
if (response.data) {
this.form = response.data;
} else {
this.form = {
overviewId: undefined,
title: undefined,
summary: undefined,
image: undefined,
video: undefined,
status: "0",
};
}
this.loading = false;
})
.catch(() => {
this.form = {
overviewId: undefined,
title: undefined,
summary: undefined,
image: undefined,
video: undefined,
status: "0"
}
}
this.loading = false
}).catch(() => {
this.form = {
overviewId: undefined,
title: undefined,
summary: undefined,
image: undefined,
video: undefined,
status: "0"
}
this.loading = false
})
status: "0",
};
this.loading = false;
});
},
enterEdit() {
this.editing = true
this.editing = true;
},
cancelEdit() {
this.editing = false
this.editing = false;
},
submitForm: function() {
this.$refs["form"].validate(valid => {
submitForm: function () {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.overviewId != undefined) {
updateOverview(this.form).then(() => {
this.$modal.msgSuccess("保存成功")
this.getOverviewData()
this.editing = false
})
this.$modal.msgSuccess("保存成功");
this.getOverviewData();
this.editing = false;
});
} else {
addOverview(this.form).then(() => {
this.$modal.msgSuccess("保存成功")
this.getOverviewData()
this.editing = false
})
this.$modal.msgSuccess("保存成功");
this.getOverviewData();
this.editing = false;
});
}
}
})
}
});
},
},
};
</script>
<style lang="scss" scoped>
.detail-value {
color: #606266;
line-height: 32px;
}
.clearfix {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
&::after {
display: none;
}
}
</script>
</style>
......@@ -10,20 +10,35 @@
size="mini"
@click="handleAdd"
v-hasPermi="['system:sciencePlan:add']"
>新增</el-button>
>新增</el-button
>
</el-col>
</el-row>
<el-table v-loading="loading" :data="list" border>
<el-table-column label="序号" type="index" align="center" width="55" />
<el-table-column label="排序" align="center" prop="sortOrder" width="80" />
<el-table-column label="标题" align="center" prop="title" show-overflow-tooltip />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<el-table-column
label="标题"
align="center"
prop="title"
show-overflow-tooltip
/>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="180"
>
<template slot-scope="scope">
<el-button
size="mini"
......@@ -31,14 +46,16 @@
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:sciencePlan:edit']"
>修改</el-button>
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:sciencePlan:remove']"
>删除</el-button>
>删除</el-button
>
</template>
</el-table-column>
</el-table>
......@@ -47,7 +64,12 @@
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="排序" prop="sortOrder">
<el-input-number v-model="form.sortOrder" :min="0" controls-position="right" style="width: 100%" />
<el-input-number
v-model="form.sortOrder"
:min="0"
controls-position="right"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="请输入标题" />
......@@ -65,13 +87,19 @@
</template>
<script>
import { listSciencePlan, getSciencePlan, addSciencePlan, updateSciencePlan, delSciencePlan } from "@/api/system/sciencePlan"
import Editor from "@/components/Editor"
import {
listSciencePlan,
getSciencePlan,
addSciencePlan,
updateSciencePlan,
delSciencePlan,
} from "@/api/system/sciencePlan";
import Editor from "@/components/Editor";
export default {
name: "SciencePlan",
components: {
Editor
Editor,
},
data() {
return {
......@@ -81,86 +109,90 @@ export default {
open: false,
form: {
id: undefined,
title: '',
content: '',
sortOrder: 0
title: "",
content: "",
sortOrder: 0,
},
rules: {
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
]
}
}
title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
},
};
},
created() {
this.getList()
this.getList();
},
methods: {
getList() {
this.loading = true
listSciencePlan().then(response => {
this.list = response.data || []
this.loading = false
}).catch(() => {
this.loading = false
})
this.loading = true;
listSciencePlan()
.then((response) => {
this.list = response.data || [];
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
cancel() {
this.open = false
this.resetForm()
this.open = false;
this.resetForm();
},
handleAdd() {
this.resetForm()
this.open = true
this.title = "添加科研计划与国际合作"
this.resetForm();
this.open = true;
this.title = "添加科研计划与国际合作";
},
handleUpdate(row) {
this.resetForm()
const id = row.id || this.ids
getSciencePlan(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改科研计划与国际合作"
})
this.resetForm();
const id = row.id || this.ids;
getSciencePlan(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改科研计划与国际合作";
});
},
handleDelete(row) {
this.$modal.confirm('是否确认删除标题为"' + row.title + '"的数据项?').then(() => {
return delSciencePlan(row.id)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
this.$modal
.confirm('是否确认删除标题为"' + row.title + '"的数据项?')
.then(() => {
return delSciencePlan(row.id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs["form"].validate((valid) => {
if (valid) {
if (this.form.id) {
updateSciencePlan(this.form).then(() => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addSciencePlan(this.form).then(() => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
})
});
},
resetForm() {
this.form = {
id: undefined,
title: '',
content: '',
sortOrder: 0
}
title: "",
content: "",
sortOrder: 0,
};
if (this.$refs.form) {
this.$refs.form.resetFields()
this.$refs.form.resetFields();
}
}
}
}
},
},
};
</script>
......@@ -198,23 +198,46 @@
</el-dialog>
<el-dialog title="查看详情" :visible.sync="viewOpen" width="780px" append-to-body>
<el-descriptions :column="1" border>
<el-descriptions-item label="标题">{{ viewData.title }}</el-descriptions-item>
<el-descriptions-item label="图片">
<el-image
v-if="viewData.image"
style="width: 200px; height: 200px"
:src="viewData.image"
:preview-src-list="[viewData.image]"
/>
</el-descriptions-item>
<el-descriptions-item label="概述">{{ viewData.summary }}</el-descriptions-item>
<el-descriptions-item label="富文本">
<div v-html="viewData.content"></div>
</el-descriptions-item>
<el-descriptions-item label="发布时间">{{ parseTime(viewData.publishTime) }}</el-descriptions-item>
<el-descriptions-item label="发布人">{{ viewData.publishBy }}</el-descriptions-item>
</el-descriptions>
<el-form ref="viewForm" :model="viewData" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="标题">
<span class="detail-value">{{ viewData.title }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="图片">
<el-image
v-if="viewData.image"
style="width: 200px; height: 200px"
:src="viewData.image"
:preview-src-list="[viewData.image]"
/>
<span v-else class="detail-value">未设置</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="概述">
<span class="detail-value">{{ viewData.summary }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="富文本">
<div class="detail-content" v-html="viewData.content"></div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发布时间">
<span class="detail-value">{{ parseTime(viewData.publishTime) }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发布人">
<span class="detail-value">{{ viewData.publishBy }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="viewOpen = false">关 闭</el-button>
</div>
......@@ -351,3 +374,16 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.detail-value {
color: #606266;
line-height: 32px;
}
.detail-content {
color: #606266;
line-height: 1.6;
max-height: 300px;
overflow-y: auto;
}
</style>
......@@ -5,8 +5,6 @@
<template #header>
<div class="card-header">
<span>项目实施进展</span>
<el-button type="primary" size="small" @click="toggleEdit" v-if="!isEditing">编辑</el-button>
<el-button type="success" size="small" @click="handleSave" v-if="isEditing">保存</el-button>
</div>
</template>
......@@ -16,8 +14,7 @@
<el-form-item label="标题" prop="title">
<el-input
v-model="form.title"
placeholder="请输入标题"
:disabled="!isEditing"
placeholder="请输入标题"
maxlength="50"
show-word-limit
></el-input>
......@@ -27,10 +24,13 @@
<el-form-item label="详细介绍" prop="content">
<editor
v-model="form.content"
:disabled="!isEditing"
></editor>
</el-form-item>
<div class="button-center">
<el-button type="primary" size="small" @click="handleSave">保存</el-button>
</div>
</el-card>
</el-form>
</div>
</template>
......@@ -111,4 +111,9 @@ export default {
justify-content: space-between;
align-items: center;
}
.button-center {
display: flex;
justify-content: center;
margin-top: 20px;
}
</style>
......@@ -15,17 +15,41 @@
</el-button>
</div>
<div class="project-intro">
<el-descriptions :column="2" border>
<el-descriptions-item label="项目名称">{{ form.projectName }}</el-descriptions-item>
<el-descriptions-item label="实施周期">{{ form.implementationPeriod }}</el-descriptions-item>
<el-descriptions-item label="牵头单位">{{ form.leadUnit }}</el-descriptions-item>
<el-descriptions-item label="核心参与单位">{{ form.coreUnits }}</el-descriptions-item>
<el-descriptions-item label="项目背景" :span="2">{{ form.projectBackground }}</el-descriptions-item>
<el-descriptions-item label="总体目标" :span="2">{{ form.overallGoal }}</el-descriptions-item>
<el-descriptions-item label="项目详情" :span="2">
<div v-html="form.projectDetail"></div>
</el-descriptions-item>
</el-descriptions>
<el-form ref="viewForm" :model="form" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称">
<span class="form-view-text">{{ form.projectName }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实施周期">
<span class="form-view-text">{{ form.implementationPeriod }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="牵头单位">
<span class="form-view-text">{{ form.leadUnit }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="核心参与单位">
<span class="form-view-text">{{ form.coreUnits }}</span>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="项目背景">
<span class="form-view-text">{{ form.projectBackground }}</span>
</el-form-item>
<el-form-item label="总体目标">
<span class="form-view-text">{{ form.overallGoal }}</span>
</el-form-item>
<el-form-item label="项目详情">
<div class="form-view-text" v-html="form.projectDetail"></div>
</el-form-item>
</el-form>
</div>
</el-card>
......@@ -162,4 +186,8 @@ export default {
.project-intro {
padding: 20px;
}
.form-view-text {
color: #606266;
}
</style>
......@@ -41,6 +41,12 @@ export const constantRoutes = [
component: () => import('@/views/portal/Achievement'),
meta: { title: '科研成果' }
},
{
path: 'achievement/detail',
name: 'PortalAchievementDetail',
component: () => import('@/views/portal/AchievementDetail'),
meta: { title: '科研成果详情' }
},
{
path: 'application',
name: 'PortalApplication',
......
......@@ -8,30 +8,57 @@
<span class="title">科研成果</span>
</div>
<div class="sidebar-decorator">
<div class="decorator-segment" style="background-color: #4B9F37"></div>
<div class="decorator-segment" style="background-color: #C51A2D"></div>
<div class="decorator-segment" style="background-color: #E37221"></div>
<div class="decorator-segment" style="background-color: #0298DB"></div>
<div class="decorator-segment" style="background-color: #F8C72E"></div>
<div class="decorator-segment" style="background-color: #D0103A"></div>
<div class="decorator-segment" style="background-color: #028542"></div>
<div class="decorator-segment" style="background-color: #BF8B2E"></div>
<div class="decorator-segment" style="background-color: #0B97D9"></div>
<div
class="decorator-segment"
style="background-color: #4b9f37"
></div>
<div
class="decorator-segment"
style="background-color: #c51a2d"
></div>
<div
class="decorator-segment"
style="background-color: #e37221"
></div>
<div
class="decorator-segment"
style="background-color: #0298db"
></div>
<div
class="decorator-segment"
style="background-color: #f8c72e"
></div>
<div
class="decorator-segment"
style="background-color: #d0103a"
></div>
<div
class="decorator-segment"
style="background-color: #028542"
></div>
<div
class="decorator-segment"
style="background-color: #bf8b2e"
></div>
<div
class="decorator-segment"
style="background-color: #0b97d9"
></div>
</div>
<div class="sidebar-menu">
<div
<div
class="menu-item"
:class="{ active: currentMenu === 'overview' }"
@click="handleMenuClick('overview')"
>
成果总体描述
</div>
<div
<div
class="menu-item"
:class="{ active: currentMenu === 'sdgsat1' }"
@click="handleMenuClick('sdgsat1')"
>
SDGSAT-1 科学成果
科学成果
</div>
</div>
</div>
......@@ -40,46 +67,59 @@
<!-- 右侧内容区域 -->
<div class="right-content">
<div class="content-card" v-loading="loading">
<div class="content-header">
<div class="content-header" v-if="currentMenu === 'overview'">
<span class="title">{{ currentTitle }}</span>
</div>
<div class="content-body">
<!-- 成果总体描述内容 -->
<div v-if="currentMenu === 'overview'" class="overview-content">
<div class="rich-text" v-html="overviewData.content || '<p>暂无内容</p>'"></div>
<div
class="rich-text"
v-html="overviewData.content || '<p>暂无内容</p>'"
></div>
</div>
<!-- SDGSAT-1 科学成果内容 -->
<!-- 科学成果内容 -->
<div v-if="currentMenu === 'sdgsat1'" class="sdgsat1-content">
<div class="sdgsat1-overview">
<h3>SDGSAT-1 卫星科学成果</h3>
<p class="overview-desc">
SDGSAT-1(可持续发展科学卫星1号)是全球首颗专门服务于联合国2030可持续发展目标的科学卫星,
于2021年11月5日成功发射。该卫星搭载了热红外、微光和多光谱成像仪,
为全球可持续发展目标监测提供了独特的数据支撑。
</p>
</div>
<section class="sdgsat1-achievements-list">
<div class="achievements-list">
<div class="achievement-card" v-for="(item, index) in sdgsat1AchievementList" :key="index">
<div
class="achievement-card"
v-for="(item, index) in sdgsat1AchievementList"
:key="index"
>
<div class="achievement-header">
<h3 class="achievement-title">{{ item.achievementName }}</h3>
<h3 class="achievement-title">
{{ item.achievementName }}
</h3>
</div>
<div class="achievement-body">
<div class="achievement-left">
<div class="achievement-introduction" v-if="item.introduction">
<p>{{ item.introduction }}</p>
<div
class="achievement-introduction"
v-if="item.introduction"
>
<div class="rich-text" v-html="item.introduction"></div>
</div>
<div class="achievement-actions">
<el-button type="primary" size="small" @click="viewDetail(item.id)">
<el-button
type="primary"
size="small"
@click="viewDetail(item.id)"
>
查看详情
</el-button>
</div>
</div>
<div class="achievement-right">
<div class="achievement-thumbnail" v-if="item.thumbnail">
<img :src="item.thumbnail" :alt="item.achievementName" />
<div
class="achievement-thumbnail"
v-if="item.thumbnail"
>
<img
:src="item.thumbnail"
:alt="item.achievementName"
/>
</div>
</div>
</div>
......@@ -106,86 +146,91 @@
</template>
<script>
import { getSdgsat1AchievementList, getAchievementOverview } from '@/api/portal/achievement'
import {
getSdgsat1AchievementList,
getAchievementOverview,
} from "@/api/portal/achievement";
export default {
name: 'Achievement',
name: "Achievement",
data() {
return {
loading: true,
currentMenu: 'overview',
currentMenu: "overview",
overviewData: {
title: '',
content: ''
title: "",
content: "",
},
selectedField: '',
selectedType: '',
selectedField: "",
selectedType: "",
sdgsat1AchievementList: [],
sdgsat1Total: 0,
sdgsat1PageSize: 10,
sdgsat1PageNum: 1
}
sdgsat1PageNum: 1,
};
},
computed: {
currentTitle() {
return this.currentMenu === 'overview' ? '成果总体描述' : 'SDGSAT-1 科学成果'
}
return this.currentMenu === "overview"
? "成果总体描述"
: "科学成果";
},
},
mounted() {
this.fetchAchievementOverview()
this.fetchAchievementOverview();
},
methods: {
async fetchAchievementOverview() {
this.loading = true
this.loading = true;
try {
const response = await getAchievementOverview()
const response = await getAchievementOverview();
if (response.code === 200 && response.data) {
this.overviewData = response.data
this.overviewData = response.data;
}
} catch (error) {
console.error('获取成果总体描述失败:', error)
console.error("获取成果总体描述失败:", error);
} finally {
this.loading = false
this.loading = false;
}
},
async fetchSdgsat1Achievements() {
this.loading = true
this.loading = true;
try {
const response = await getSdgsat1AchievementList({
pageNum: this.sdgsat1PageNum,
pageSize: this.sdgsat1PageSize
})
pageSize: this.sdgsat1PageSize,
});
if (response.code === 200) {
this.sdgsat1AchievementList = response.rows || []
this.sdgsat1Total = response.total || 0
this.sdgsat1AchievementList = response.rows || [];
this.sdgsat1Total = response.total || 0;
}
} catch (error) {
console.error('获取SDGSAT-1成果列表失败:', error)
this.$message.error('获取成果列表失败')
console.error("获取SDGSAT-1成果列表失败:", error);
this.$message.error("获取成果列表失败");
} finally {
this.loading = false
this.loading = false;
}
},
handleSdgsat1PageChange(page) {
this.sdgsat1PageNum = page
this.fetchSdgsat1Achievements()
this.sdgsat1PageNum = page;
this.fetchSdgsat1Achievements();
},
viewDetail(id) {
this.$router.push({
path: '/portal/achievement/detail',
query: { id }
})
path: "/portal/achievement/detail",
query: { id },
});
},
handleMenuClick(menu) {
this.currentMenu = menu
if (menu === 'overview') {
this.fetchAchievementOverview()
} else if (menu === 'sdgsat1') {
this.fetchSdgsat1Achievements()
this.currentMenu = menu;
if (menu === "overview") {
this.fetchAchievementOverview();
} else if (menu === "sdgsat1") {
this.fetchSdgsat1Achievements();
}
}
}
}
},
},
};
</script>
<style lang="scss" scoped>
......@@ -216,7 +261,7 @@ export default {
}
.sidebar-header {
background: #1EA8C5;
background: #1ea8c5;
// padding: 30px 24px;
height: 58px;
display: flex;
......@@ -225,15 +270,14 @@ export default {
padding-left: 19px;
.title {
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 18px;
color: #FFFFFF;
line-height: 18px;
text-align: left;
font-style: normal;
text-transform: none;
font-family: Microsoft YaHei, Microsoft YaHei;
font-weight: bold;
font-size: 18px;
color: #ffffff;
line-height: 18px;
text-align: left;
font-style: normal;
text-transform: none;
}
}
......
......@@ -62,5 +62,5 @@ pagehelper:
# 防止XSS攻击
xss:
enabled: true
excludes: /system/notice
excludes: /system/notice,/system/sciencePlan
urlPatterns: /system/*,/monitor/*,/tool/*
package com.ruoyi.common.filter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.html.EscapeUtil;
/**
* XSS过滤处理
*
* @author ruoyi
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
{
/**
* @param request
*/
public XssHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
@Override
public String[] getParameterValues(String name)
{
String[] values = super.getParameterValues(name);
if (values != null)
{
int length = values.length;
String[] escapesValues = new String[length];
for (int i = 0; i < length; i++)
{
// 防xss攻击和过滤前后空格
escapesValues[i] = EscapeUtil.clean(values[i]).trim();
}
return escapesValues;
}
return super.getParameterValues(name);
}
@Override
public ServletInputStream getInputStream() throws IOException
{
if (!isJsonRequest())
{
return super.getInputStream();
}
String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json))
{
return super.getInputStream();
}
json = cleanJsonString(json);
json = EscapeUtil.clean(json).trim();
byte[] jsonBytes = json.getBytes("utf-8");
final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes);
return new ServletInputStream()
{
@Override
public boolean isFinished()
{
return true;
}
@Override
public boolean isReady()
{
return true;
}
@Override
public int available() throws IOException
{
return jsonBytes.length;
}
@Override
public void setReadListener(ReadListener readListener)
{
}
@Override
public int read() throws IOException
{
return bis.read();
}
};
}
private String cleanJsonString(String json)
{
json = json.replaceAll("\\\\", "");
json = json.replaceAll("`", "");
return json;
}
/**
* 是否是Json请求
*
* @param request
*/
public boolean isJsonRequest()
{
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
}
package com.ruoyi.common.filter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.html.EscapeUtil;
/**
* XSS过滤处理
*
* @author ruoyi
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
{
/**
* @param request
*/
public XssHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
@Override
public String[] getParameterValues(String name)
{
String[] values = super.getParameterValues(name);
if (values != null)
{
int length = values.length;
String[] escapesValues = new String[length];
for (int i = 0; i < length; i++)
{
// 防xss攻击和过滤前后空格
escapesValues[i] = EscapeUtil.clean(values[i]).trim();
}
return escapesValues;
}
return super.getParameterValues(name);
}
@Override
public ServletInputStream getInputStream() throws IOException
{
if (!isJsonRequest())
{
return super.getInputStream();
}
String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json))
{
return super.getInputStream();
}
json = cleanJsonString(json);
json = EscapeUtil.clean(json).trim();
byte[] jsonBytes = json.getBytes("utf-8");
final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes);
return new ServletInputStream()
{
@Override
public boolean isFinished()
{
return true;
}
@Override
public boolean isReady()
{
return true;
}
@Override
public int available() throws IOException
{
return jsonBytes.length;
}
@Override
public void setReadListener(ReadListener readListener)
{
}
@Override
public int read() throws IOException
{
return bis.read();
}
};
}
private String cleanJsonString(String json)
{
// 移除反斜杠会影响JSON转义字符(如\n换行符),改为只移除特定的危险字符
// json = json.replaceAll("\\\\", "");
json = json.replaceAll("`", "");
return json;
}
/**
* 是否是Json请求
*
* @param request
*/
public boolean isJsonRequest()
{
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
}
}
\ No newline at end of file
......@@ -361,7 +361,7 @@ public class SysMenuServiceImpl implements ISysMenuService
public boolean checkRouteConfigUnique(SysMenu menu)
{
Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
Long parentId = menu.getParentId();
Long parentId = StringUtils.isNull(menu.getParentId()) ? MENU_ROOT_ID : menu.getParentId();
String path = menu.getPath();
String routeName = StringUtils.isEmpty(menu.getRouteName()) ? path : menu.getRouteName();
List<SysMenu> sysMenuList = menuMapper.selectMenusByPathOrRouteName(path, routeName);
......
......@@ -30,8 +30,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<select id="selectSysAchievementList" parameterType="SysAchievement" resultMap="SysAchievementResult">
select id, achievement_name, thumbnail, achievement_category, research_field, research_unit, researchers, publish_time, publisher, sort, status, create_by, create_time, update_by, update_time, remark
from sys_achievement
<include refid="selectSysAchievementVo"/>
<where>
<if test="achievementName != null and achievementName != ''">
AND achievement_name like concat('%', #{achievementName}, '%')
......@@ -59,8 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="selectSysAchievementById" parameterType="Long" resultMap="SysAchievementResult">
select id, achievement_name, thumbnail, achievement_category, research_field, research_unit, researchers, publish_time, publisher, sort, status, create_by, create_time, update_by, update_time, remark
from sys_achievement
<include refid="selectSysAchievementVo"/>
where id = #{id}
</select>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment