提交 632f02b3 authored 作者: 刘宇琪's avatar 刘宇琪

fix:科技人物样式修复

上级 fead13ed
......@@ -9,7 +9,7 @@
<TextStyle />
<div class="text-title-1-show">通用样式/组件</div>
<div style="position: relative; min-height: 700px;">
<el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs">
<el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs dev-style-tabs">
<el-tab-pane label="通用" lazy>
<common-page />
</el-tab-pane>
......@@ -109,4 +109,10 @@ import RelationForceChart from './RelationForceChart/index.vue'
.box {
padding-bottom: 20px;
}
.dev-style-tabs {
:deep(.el-tabs__content) {
display: block !important;
}
}
</style>
\ No newline at end of file
......@@ -17,7 +17,8 @@
<img src="./assets/icon-star.svg" alt="" class="btn-icon" />
</div>
<div class="mainBox">
<div class="graph" id="relGraph"></div>
<div v-show="activeIndex !== '关系图'" class="graph" id="relGraph"></div>
<RelationChart v-if="activeIndex === '关系图' && graphData.rootId" :graph-data="graphData" />
</div>
</div>
</template>
......@@ -27,6 +28,7 @@ import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import { getCharacterGlobalInfo, getCharacterRelation } from "@/api/characterPage/characterPage.js";
import "default-passive-events";
import RelationChart from '@/components/base/RelationChart/index.vue';
import { useRoute } from "vue-router";
const route = useRoute();
......@@ -95,6 +97,7 @@ const nodes = ref([]);
const links = ref([]);
const characterInfo = ref({});
const CharacterRelation = ref([]);
const graphData = ref({ rootId: '', nodes: [], lines: [] });
const list = ref([
{
......@@ -108,8 +111,8 @@ const list = ref([
icon: new URL("./assets/icon-force.svg", import.meta.url).href,
},
{
value: "树形布局",
label: "树形布局",
value: "关系图",
label: "关系图",
icon: new URL("./assets/icon-tree.svg", import.meta.url).href,
},
]);
......@@ -204,6 +207,15 @@ const getCharacterRelationFn = async () => {
nodes.value = [centerNode];
links.value = [];
}
// 构建关系图数据
const gNodes = [{ id: 'center', text: characterInfo.value.name || '' }];
const gLines = [];
CharacterRelation.value.forEach((item, index) => {
gNodes.push({ id: `node_${index}`, text: item.name });
gLines.push({ from: 'center', to: `node_${index}`, text: item.relation || '' });
});
graphData.value = { rootId: 'center', nodes: gNodes, lines: gLines };
};
// ========== 渲染图表 ==========
......
......@@ -84,7 +84,7 @@ export function useBills() {
}
if (filters.selectedTimeRanges.length > 0 && !filters.selectedTimeRanges.includes('all')) {
params.years = filters.selectedTimeRanges
params.years = filters.selectedTimeRanges.map(Number)
}
params.isCN = filters.isCN
......
......@@ -68,10 +68,9 @@
color: 'rgba(59, 65, 75, 1)'
}" :row-class-name="tableRowClassName" :row-style="{ height: '60px' }" size="large">
<el-table-column prop="rank" label="排名" width="100" align="center" />
<el-table-column prop="contributor" label="贡献者" min-width="300" />
<el-table-column prop="contributor" label="贡献者" min-width="200" />
<el-table-column prop="totalAmount" label="总捐款" width="150" />
<el-table-column prop="individualAmount" label="个人捐款" width="150" />
<el-table-column prop="pacsAmount" label="PACs捐款" width="150" />
<el-table-column prop="donationYear" label="捐款年份" width="150" />
</el-table>
<div class="table-pagination">
<span class="table-pagination-total">共{{ fundTotal }}项</span>
......@@ -109,7 +108,7 @@
<img src="./assets/type1.png" alt="" v-if="item.remarks === true" /><img
src="./assets/type2.png" alt="" v-else />
</div>
<div class="content">
<div class="content" style="cursor: pointer;" @click="gotoNewsDetail(item.newsId)">
<div
:class="{ 'content-type1': item.remarks === true, 'content-type2': item.remarks === false }">
......@@ -389,7 +388,9 @@ const handleBillMoreClick = (bill) => {
};
import { useRoute } from 'vue-router';
import { useGotoNewsDetail } from '@/router/modules/news.js';
const route = useRoute();
const gotoNewsDetail = useGotoNewsDetail();
const personId = ref(route.query.personId || "Y000064");
const newsTab = ref('history')
// 处理图片代理
......@@ -490,24 +491,17 @@ const handleChangeYear = () => {
const yearList = ref([
{
label: "全部",
value: 'all'
},
{
label: "2025",
value: 2025
},
{
label: "2024",
value: 2024
},
{
label: "2023",
value: 2023
const yearList = ref([]);
const generateYearList = () => {
const currentYear = new Date().getFullYear();
const list = [{ label: "全部", value: 'all' }];
for (let i = 0; i < 5; i++) {
const year = currentYear - i;
list.push({ label: String(year), value: year });
}
]);
yearList.value = list;
};
generateYearList();
const CharacterFundSource = ref([]);
const getCharacterFundSourceFn = async () => {
......@@ -516,7 +510,7 @@ const getCharacterFundSourceFn = async () => {
pageSize: 4,
currentPage: fundCurrentPage.value - 1,
};
if (selectedOption.value !== '全部') {
if (selectedOption.value !== 'all') {
params.year = selectedOption.value;
}
......@@ -528,10 +522,9 @@ const getCharacterFundSourceFn = async () => {
CharacterFundSource.value = res.data.content.map((item, index) => {
return {
rank: index + 1,
contributor: item.orgName,
contributor: item.companyName,
totalAmount: item.totalDonation,
individualAmount: item.personalDonation,
pacsAmount: item.pacsDonation
donationYear: item.donationYear
}
});
......@@ -627,7 +620,8 @@ const getCharacterLatestDynamicFn = async () => {
time: item.time,
industryList: item.industryList || ["人工智能"],
orgName: item.orgName,
remarks: item.remarks
remarks: item.remarks,
newsId: item.newsId
}));
total.value = res.data.totalElements;
} else {
......@@ -730,7 +724,7 @@ const info = ref(["人物详情", "历史提案", "人物关系" ]);
const infoActive = ref("人物详情");
const num = ref(['全部', "2025", "2024", "2023", "2022", "2021", "2020"]);
const numActive = ref("全部");
const selectedOption = ref("全部");
const selectedOption = ref("all");
const dialogVisible = ref(false);
const currentTag = ref(null)
......
......@@ -17,7 +17,8 @@
<img src="./assets/icon-star.svg" alt="" class="btn-icon" />
</div>
<div class="mainBox">
<div class="graph" id="relGraph"></div>
<div v-show="activeIndex !== '关系图'" class="graph" id="relGraph"></div>
<RelationChart v-if="activeIndex === '关系图' && graphData.rootId" :graph-data="graphData" />
</div>
</div>
</template>
......@@ -27,6 +28,7 @@ import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import { getCharacterGlobalInfo, getCharacterRelation } from '@/api/characterPage/characterPage.js'
import { useRoute } from 'vue-router'
import RelationChart from '@/components/base/RelationChart/index.vue'
const route = useRoute()
const personId = ref(route.query.personId || 'Y000064')
......@@ -79,6 +81,7 @@ const nodes = ref([])
const links = ref([])
const characterInfo = ref({})
const CharacterRelation = ref([])
const graphData = ref({ rootId: '', nodes: [], lines: [] })
const list = ref([
{
......@@ -92,8 +95,8 @@ const list = ref([
icon: new URL('./assets/icon-force.svg', import.meta.url).href,
},
{
value: '树形布局',
label: '树形布局',
value: '关系图',
label: '关系图',
icon: new URL('./assets/icon-tree.svg', import.meta.url).href,
},
])
......@@ -193,6 +196,15 @@ const getCharacterRelationFn = async () => {
nodes.value = [centerNode]
links.value = []
}
// 构建关系图数据
const gNodes = [{ id: 'center', text: characterInfo.value.name || '' }]
const gLines = []
CharacterRelation.value.forEach((item, index) => {
gNodes.push({ id: `node_${index}`, text: item.name })
gLines.push({ from: 'center', to: `node_${index}`, text: item.relation || '' })
})
graphData.value = { rootId: 'center', nodes: gNodes, lines: gLines }
}
const handleChangeLayout = (value) => {
......
......@@ -67,7 +67,7 @@
<img src="./assets/type1.png" alt="" v-if="item.remarks === true" />
<img src="./assets/type2.png" alt="" v-else />
</div>
<div class="content">
<div class="content" style="cursor: pointer;" @click="gotoNewsDetail(item.newsId)">
<div
:class="{ 'content-type1': item.remarks === true, 'content-type2': item.remarks === false }">
<p v-if="item.remarks === true" class="content-title1">{{ item.content }}</p>
......@@ -273,7 +273,9 @@ import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
import { Close } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router';
import { useGotoNewsDetail } from '@/router/modules/news.js';
const route = useRoute();
const gotoNewsDetail = useGotoNewsDetail();
const areaList = ref([])
const personId = ref(route.query.personId || "Y000064");
const wordloading=ref(false)
......@@ -545,7 +547,8 @@ const getCharacterLatestDynamicFn = async () => {
time: item.time,
industryList: item.industryList || ["人工智能"],
orgName: item.orgName,
remarks: item.remarks
remarks: item.remarks,
newsId: item.newsId
}));
total.value = res.data.totalElements;
} else {
......
......@@ -211,8 +211,8 @@ function buildParams({ includeSearchText = false } = {}) {
currentPage: currentPage.value - 1,
pageSize,
sortFun: sortBy.value === 'publishTimeAsc',
industryIds: selectedDomains.value.includes('all') ? '' : JSON.stringify(selectedDomains.value),
years: selectedTimes.value.includes('all') ? '' : JSON.stringify(selectedTimes.value),
industryIds: selectedDomains.value.includes('all') ? '' : selectedDomains.value,
years: selectedTimes.value.includes('all') ? '' : selectedTimes.value.map(Number),
}
if (includeSearchText) {
params.searchText = searchText.value
......
......@@ -48,7 +48,7 @@
<img src="./assets/type1.png" alt="" v-if="item.remarks === true" /><img
src="./assets/type2.png" alt="" v-else />
</div>
<div class="content">
<div class="content" style="cursor: pointer;" @click="gotoNewsDetail(item.newsId)">
<div
:class="{ 'content-type1': item.remarks === true, 'content-type2': item.remarks === false }">
<p v-if="item.remarks === true" class="content-title1">
......@@ -202,7 +202,9 @@ import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
import { useRoute } from 'vue-router';
import { useGotoNewsDetail } from '@/router/modules/news.js';
const route = useRoute();
const gotoNewsDetail = useGotoNewsDetail();
const personId = ref(route.query.personId || "Y000064");
const boxHeight = computed(() => {
if(characterBasicInfo.value.organizationList==undefined) return '625px'
......@@ -370,7 +372,8 @@ const getCharacterLatestDynamicFn = async () => {
time: item.time,
industryList: item.industryList || ["人工智能"],
orgName: item.orgName,
remarks: item.remarks
remarks: item.remarks,
newsId: item.newsId
}));
total.value = res.data.totalElements;
} else {
......
......@@ -4,6 +4,20 @@
<div class="header">
<div class="avatar">
<el-avatar :size="160" shape="circle" :src="avatarUrl" />
<div class="person-tags">
<div class="person-tag-bg" v-if="characterInfo.party === 'Republican' || characterInfo.party === '共和党'">
<img :src="getTagIconUrl('1')" class="tag-icon" alt="" />
</div>
<div class="person-tag-bg" v-else-if="characterInfo.party && characterInfo.party !== 'Republican' && characterInfo.party !== '共和党'">
<img :src="getTagIconUrl('2')" class="tag-icon" alt="" />
</div>
<div class="person-tag-bg person-tag-right" v-if="isHouse(characterInfo.congress)">
<img :src="getCongressIconUrl('congress1')" class="tag-icon" alt="" />
</div>
<div class="person-tag-bg person-tag-right" v-else-if="isSenate(characterInfo.congress)">
<img :src="getCongressIconUrl('congress2')" class="tag-icon" alt="" />
</div>
</div>
</div>
<div class="info">
<p class="name-cn">{{ characterInfo.name }}</p>
......@@ -81,10 +95,9 @@
color: 'rgba(59, 65, 75, 1)'
}" :row-class-name="tableRowClassName" :row-style="{ height: '50px' }" size="large">
<el-table-column prop="rank" label="排名" width="80" align="center" />
<el-table-column prop="contributor" label="贡献者" min-width="300" />
<el-table-column prop="contributor" label="贡献者" min-width="200" />
<el-table-column prop="totalAmount" label="总捐款" width="150" align="right" />
<el-table-column prop="individualAmount" label="个人捐款" width="150" align="right" />
<el-table-column prop="pacsAmount" label="PACs捐款" width="150" align="right" />
<el-table-column prop="donationYear" label="捐款年份" width="150" align="right" />
</el-table>
<div class="table-pagination">
<span class="table-pagination-total">共{{ fundTotal }}项</span>
......@@ -122,7 +135,7 @@
</div>
<div class="timeline-line-bottom" v-if="idx !== CharacterLatestDynamic.length - 1"></div>
</div>
<div class="content">
<div class="content" :style="{ cursor: item.remarks === false ? 'pointer' : 'default' }" @click="item.remarks === false && gotoNewsDetail(item.newsId)">
<div :class="{ 'content-type1': item.remarks === true, 'content-type2': item.remarks === false }">
<p v-if="item.remarks === true" class="content-title1">{{ item.content }}</p>
<p v-else class="content-title2">{{ item.title }}</p>
......@@ -323,6 +336,7 @@
<script setup>
import { ref, computed, onMounted, nextTick } from "vue";
import { useRoute } from 'vue-router';
import { useGotoNewsDetail } from '@/router/modules/news.js';
import WordCloudChart from "@/components/base/WordCloundChart/index.vue";
import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue';
import AreaTag from '@/components/base/AreaTag/index.vue';
......@@ -351,6 +365,7 @@ const props = defineProps({
});
const route = useRoute();
const gotoNewsDetail = useGotoNewsDetail();
const config = computed(() => CHARACTER_CONFIG[Number(props.type)] || CHARACTER_CONFIG[1]);
const personIdRef = ref(props.personId || route.query.personId || "Y000064");
......@@ -384,6 +399,26 @@ const typeIcon2 = computed(() => typeAssets.value.type2 || '');
const resumeIcon01 = computed(() => typeAssets.value.icon01 || '');
const resumeIcon02 = computed(() => typeAssets.value.icon02 || '');
// 政党/国会图标(同 technologyFigures/PersonTable 逻辑)
const getTagIconUrl = (tag) => {
const icons = import.meta.glob('../../../technologyFigures/assets/images/header-icon*.png', { eager: true, as: 'url' });
const iconPath = `../../../technologyFigures/assets/images/header-icon${tag}.png`;
return icons[iconPath] || '';
};
const getCongressIconUrl = (type) => {
const icons = import.meta.glob('../../../technologyFigures/assets/images/congress*.svg', { eager: true, as: 'url' });
const iconPath = `../../../technologyFigures/assets/images/${type}.svg`;
return icons[iconPath] || '';
};
const isHouse = (text) => {
if (!text) return false;
return text.includes('众议院') || text.toLowerCase().includes('house');
};
const isSenate = (text) => {
if (!text) return false;
return text.includes('参议院') || text.toLowerCase().includes('senate');
};
// 子组件
import CharacterRelationships from '../techLeader/components/characterRelationships/index.vue';
import RelevantSituation from '../techLeader/components/relevantSituation/index.vue';
......@@ -439,12 +474,17 @@ const fundCurrentPage = ref(1);
const fundPageSize = ref(4);
const fundTotal = ref(0);
const selectedOption = ref("all");
const yearList = ref([
{ label: "全部", value: "all" },
{ label: "2025", value: 2025 },
{ label: "2024", value: 2024 },
{ label: "2023", value: 2023 }
]);
const yearList = ref([]);
const generateYearList = () => {
const currentYear = new Date().getFullYear();
const list = [{ label: "全部", value: "all" }];
for (let i = 0; i < 5; i++) {
const year = currentYear - i;
list.push({ label: String(year), value: year });
}
yearList.value = list;
};
generateYearList();
const isChecked = ref(false);
const related = ref('N');
......@@ -578,7 +618,8 @@ const getCharacterLatestDynamicFn = async () => {
time: item.time,
industryList: item.industryList || ["人工智能"],
orgName: item.orgName,
remarks: item.remarks
remarks: item.remarks,
newsId: item.newsId
}));
total.value = res.data.totalElements;
} else {
......@@ -633,10 +674,9 @@ const getCharacterFundSourceFn = async () => {
fundTotal.value = res.data.totalElements;
CharacterFundSource.value = res.data.content.map((item, index) => ({
rank: index + 1,
contributor: item.orgName,
contributor: item.companyName,
totalAmount: item.totalDonation,
individualAmount: item.personalDonation,
pacsAmount: item.pacsDonation
donationYear: item.donationYear
}));
}
} catch (error) { }
......@@ -755,13 +795,41 @@ onMounted(() => {
width: 160px;
height: 160px;
margin-right: 24px;
overflow: hidden;
position: relative;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 政党/国会标签 */
.person-tags {
display: flex;
justify-content: center;
gap: 6px;
margin-top: -23px;
width: 160px;
position: relative;
z-index: 1;
}
.person-tag-bg {
width: 36px;
height: 36px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.tag-icon {
width: 28px;
height: 28px;
object-fit: contain;
}
}
.info {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,15 +12,21 @@
<div class="table-row" v-for="(item, index) in personList" :key="index">
<!-- 人物信息列 -->
<div class="row-col col-person" @click="handleClickToCharacter(item.personId)">
<div style="margin: 7px 12px 7px 24px;">
<div style="margin: 7px 12px 7px 24px; position: relative;">
<img :src="item.avatar" class="avatar" alt="avatar" />
<div class="person-tags">
<div class="person-tag-bg" v-if="item.party === 'Republican' || item.party === '共和党'">
<img :src="getTagIconUrl('1')" class="tag-icon" alt="tag" />
</div>
<div class="person-tag-bg" v-if="item.party && item.party !== 'Republican' && item.party !== '共和党'">
<div class="person-tag-bg" v-else-if="item.party && item.party !== 'Republican' && item.party !== '共和党'">
<img :src="getTagIconUrl('2')" class="tag-icon" alt="tag" />
</div>
<div class="person-tag-bg person-tag-right" v-if="isHouse(item.congress)">
<img :src="getCongressIconUrl('congress1')" class="tag-icon" alt="congress" />
</div>
<div class="person-tag-bg person-tag-right" v-else-if="isSenate(item.congress)">
<img :src="getCongressIconUrl('congress2')" class="tag-icon" alt="congress" />
</div>
</div>
</div>
<div class="person-info">
......@@ -74,6 +80,19 @@ const getTagIconUrl = (tag) => {
const iconPath = `../assets/images/header-icon${tag}.png`;
return icons[iconPath] || '';
};
const getCongressIconUrl = (type) => {
const icons = import.meta.glob('../assets/images/congress*.svg', { eager: true, as: 'url' });
const iconPath = `../assets/images/${type}.svg`;
return icons[iconPath] || '';
};
const isHouse = (congress) => {
if (!congress) return false;
return congress.includes('众议院') || congress.toLowerCase().includes('house');
};
const isSenate = (congress) => {
if (!congress) return false;
return congress.includes('参议院') || congress.toLowerCase().includes('senate');
};
// 获取主要人物涉华观点统计
const handlegetMainCharactersViewFn = async () => {
const params = {
......@@ -91,6 +110,7 @@ const handlegetMainCharactersViewFn = async () => {
name: item.personName,
position: item.positionTitle,
party: item.party || '',
congress: item.congress || '',
chinaRelatedCount: item.remarksCount,
mediaQuoteCount: item.remarksCount,
personId:item.personId
......@@ -251,6 +271,9 @@ const getProgress = count => (count / getMaxCount()) * 100;
text-align: center;
}
.person-tag-right {
}
.person-tag-bg {
/* 椭圆 6 */
width: 20px;
......
......@@ -227,6 +227,12 @@ const handlePageChange = p => {
.source-library-avatar-wrapper {
flex-shrink: 0;
margin-right: 18px;
width: 92px;
height: 121px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.person-tags {
......@@ -252,10 +258,9 @@ const handlePageChange = p => {
}
.source-library-avatar {
/* 椭圆 142 */
width: 92px;
height: 121px;
// border-radius: 50%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.source-library-text-content {
......
......@@ -343,7 +343,7 @@
<script setup>
import RiskSignal from "@/components/base/riskSignal/index.vue";
import RiskSignalOverviewDetailDialog from "@/components/base/RiskSignalOverviewDetailDialog/index.vue";
import { onMounted, ref } from "vue";
import { onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router";
import scrollToTop from "@/utils/scrollToTop";
import DivideHeader from "@/components/DivideHeader.vue";
......@@ -371,6 +371,7 @@ import PersonTable from "./component/PersonTable.vue";
import SourceLibrary from "./component/SourceLibrary.vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
import { navigateToViewRiskSignal } from "@/utils/riskSignalOverviewNavigate";
import tipsIcon from "./assets/images/tips-icon.png";
const router = useRouter();
......@@ -513,19 +514,21 @@ const box6Chart = ref({
]
});
const box6HasData = ref(true);
const handlegetOptionAreaChangeFn = async () => {
const handlegetOptionAreaChangeFn = async (timeRange) => {
const currentYear = new Date().getFullYear();
const startYear = timeRange === "近五年" ? currentYear - 4 : currentYear - 9;
const params = {
startTime: "2015-01-01"
startTime: `${startYear}-01-01`
};
try {
const res = await getOptionAreaChange(params);
console.log("科技人物观点涉及领域变化趋势", res);
if (res.code === 200 && res.data && res.data.length > 0) {
box6HasData.value = true;
const sortedData = res.data.sort((a, b) => a.year.localeCompare(b.year));
const sortedData = res.data.sort((a, b) => a.year - b.year);
//提取年份作为 title
const years = sortedData.map(item => item.year);
const years = sortedData.map(item => String(item.year));
//收集所有行业名称
const allIndustries = new Set();
sortedData.forEach(yearData => {
......@@ -884,6 +887,11 @@ const options = [
const viewOption = ref(["行政主管", "国会议员", "科技领袖", "顶尖科学家"]);
const viewSelect = ref("国会议员");
watch(areaSelect, async (newVal) => {
await handlegetOptionAreaChangeFn(newVal);
const chart6 = getMultiLineChart(box6Chart.value.title, ...box6Chart.value.data.map(d => d.value));
setChart(chart6, "box6Chart");
});
onMounted(async () => {
......@@ -891,7 +899,7 @@ onMounted(async () => {
curnews.value = newsDynamics.value[0];
handleGetBillRiskSignalFn();
await handlegetCharacterOpinionWordCloudFn();
await handlegetOptionAreaChangeFn();
await handlegetOptionAreaChangeFn(areaSelect.value);
await handlegetPersonTypeCountFn();
handlegetareaTypeFn();
await handlgetPersonTypeFn();
......@@ -2707,7 +2715,7 @@ onMounted(async () => {
}
.data-origin-box {
display: flex;
display: none;
align-items: center;
padding: 8px 24px;
box-sizing: border-box;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论