开源软件列表查询及批量校验相关问题修复

This commit is contained in:
付民康
2025-03-15 20:32:13 +08:00
parent c57c932e45
commit 236942a229
7 changed files with 1234 additions and 210 deletions

View File

@@ -0,0 +1,78 @@
<template>
<div>
<!-- 文件上传按钮 -->
<d-button
class="mr-2"
variant="solid"
:loading="loading"
@click="triggerFileInput"
>
{{ buttonText }}
</d-button>
<!-- 隐藏的文件上传输入框 -->
<input
ref="fileInput"
type="file"
:accept="accept"
style="display: none"
@change="handleFileUpload"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 定义组件属性
const props = defineProps({
buttonText: {
type: String,
default: '上传文件',
},
accept: {
type: String,
default: '.xml', // 默认接受 XML 文件
},
onFileUpload: {
type: Function,
required: true,
},
});
// 文件输入框的引用
const fileInput = ref(null);
// 加载状态
const loading = ref(false);
// 触发文件选择
const triggerFileInput = () => {
fileInput.value.click(); // 触发文件选择
};
// 处理文件上传
const handleFileUpload = async (event) => {
const file = event.target.files[0]; // 获取选择的文件
if (file) {
// 检查文件类型
if (file.type === 'text/xml' || file.name.endsWith('.xml')) {
loading.value = true; // 显示加载状态
try {
await props.onFileUpload(file); // 调用父组件传递的上传方法
} catch (error) {
console.error('文件上传失败:', error);
alert('文件上传失败,请重试!');
} finally {
loading.value = false; // 隐藏加载状态
}
} else {
alert('请选择有效的 XML 文件!');
}
}
};
</script>
<style lang="scss" scoped>
/* 自定义样式 */
</style>

View File

@@ -0,0 +1,555 @@
<template>
<div class="secret-container">
<div class="mt-3 px-20">
<d-table :key="tableKey" class="jyh-table" v-if="tableData.length" :striped="false" :data="tableData" table-layout="auto">
<!-- 索引列 -->
<d-column type="index" width="40"></d-column>
<!-- 动态渲染列 -->
<template v-for="column in columns" :key="column.key">
<d-column
v-if="column.visible"
:field="column.key"
:header="column.label"
:filterable="column.filterable"
:filter-list="column.filterList"
:sortable="column.sortable"
@filter-change="handleFilterChange"
>
<!-- 自定义列内容 -->
<template #default="scope">
<template v-if="column.key === 'versionName'">
<a>{{ scope.row.versionName }}</a>
</template>
<template v-else-if="column.key === 'version'">
<a @click="gotoDetail(scope.row)">{{ scope.row.version }}</a>
</template>
<template v-else-if="column.key === 'softwareVersion'">
<a @click="gotoDetail(scope.row)">{{ scope.row.softwareVersion }}</a>
</template>
<template v-else-if="column.key === 'smStatus'">
<a>{{ scope.row.smStatus }}</a>
</template>
<template v-else-if="column.key === 'industryCategory'">
<d-tag type="success">{{ scope.row.industryCategory }}</d-tag>
</template>
<template v-else-if="column.key === 'programmingLanguage'">
<d-tag type="success">{{ scope.row.programmingLanguage }}</d-tag>
</template>
<template v-else-if="column.key === 'contributorCountries'">
<span class="mr-2">美国 3.57%</span>
<d-tag color="gray">+3</d-tag>
</template>
<template v-else-if="column.key === 'contributorOrganizations'">
<span class="mr-2">microsoft 3.57%</span>
<d-tag color="gray">+3</d-tag>
</template>
<template v-else-if="column.key === 'sourceCodeDownload'">
<a>{{ scope.row.sourceCodeDownload }}</a>
</template>
<template v-else>
{{ scope.row[column.key] }}
</template>
</template>
</d-column>
</template>
</d-table>
<DataPanel v-else skeleton :card="false" :empty="true">
</DataPanel>
</div>
<div class="mt-20 mb-20 flex justify-end">
<d-pagination size="md" :page-size-options="[10, 20, 50]" :total="pager.total"
v-model:pageSize="pager.pageSize" v-model:pageIndex="pager.pageIndex" :max-items="5"
:can-change-page-size="true" :can-view-total="true" total-item-text="总计" @page-index-change="changeIndex()"
@page-size-change="changeSize()" />
</div>
</div>
</template>
<script setup lang="ts">
import AdvanceSearch from '@/components/AdvanceSearch/index.vue'
import SettingTitle from '@/components/Setting/SettingTitle/index.vue';
import SettingText from '@/components/Setting/SettingText/index.vue';
import { ref,reactive, onMounted } from 'vue';
import { getGroupClaList, setGroupClaStatus, deleteGroupCla } from '@/api/cla';
import { useRouter, useRoute } from 'vue-router';
import { GModal } from '@/components/Setting/index';
import TableSetting from '@/components/TableSetting/index.vue';
import { reqCatch } from '@/utils/catch';
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
import { Message } from 'vue-devui';
import { storeToRefs } from 'pinia';
import { useAccountStore } from '@/stores/user';
const { namespace } = getOrgInfo();
const userInfo = useAccountStore();
const { isLogin } = storeToRefs(userInfo);
// 定义 tableKey用于强制刷新表格
const tableKey = ref(0);
const tableData = ref([
{
softwareName: 'eslint-plugin-import',
softwareVersion: '2.29.0',
releaseDate: '2025-03-10',
licenseCount: 3,
dependencyCount: 15,
productComponentUsage: ['供应链系统A', '供应链系统B'],
codeSize: '150KB',
vulnerabilityCount: 5,
industryCategory: '软件开发工具',
developer: 'ESLint团队',
contributorCountries: ['美国', '中国', '德国'],
contributorOrganizations: ['Google', 'Microsoft', 'Alibaba'],
programmingLanguage: 'JavaScript',
communityHash: 'a1b2c3d4',
softwareScore: 8.5,
sourceCodeDownload: 'https://github.com/eslint/eslint-plugin-import',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-1234',
versionDescription: '修复了若干安全漏洞',
compatibilityRisk: '低',
communityEOL: '2028-12-31',
},
{
softwareName: 'react',
softwareVersion: '18.2.0',
releaseDate: '2025-02-15',
licenseCount: 1,
dependencyCount: 10,
productComponentUsage: ['供应链系统C'],
codeSize: '500KB',
vulnerabilityCount: 2,
industryCategory: '前端框架',
developer: 'Facebook',
contributorCountries: ['美国', '加拿大', '英国'],
contributorOrganizations: ['Facebook', 'Netflix', 'Airbnb'],
programmingLanguage: 'JavaScript',
communityHash: 'e5f6g7h8',
softwareScore: 9.0,
sourceCodeDownload: 'https://github.com/facebook/react',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-5678',
versionDescription: '新增了并发渲染功能',
compatibilityRisk: '中',
communityEOL: '2030-12-31',
},
{
softwareName: 'vue',
softwareVersion: '3.2.0',
releaseDate: '2025-01-20',
licenseCount: 1,
dependencyCount: 8,
productComponentUsage: ['供应链系统D'],
codeSize: '300KB',
vulnerabilityCount: 1,
industryCategory: '前端框架',
developer: 'Evan You',
contributorCountries: ['中国', '美国', '日本'],
contributorOrganizations: ['Alibaba', 'Tencent', 'Baidu'],
programmingLanguage: 'JavaScript',
communityHash: 'i9j0k1l2',
softwareScore: 9.2,
sourceCodeDownload: 'https://github.com/vuejs/vue',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-9101',
versionDescription: '优化了性能',
compatibilityRisk: '低',
communityEOL: '2029-12-31',
},
{
softwareName: 'webpack',
softwareVersion: '5.75.0',
releaseDate: '2025-04-05',
licenseCount: 2,
dependencyCount: 20,
productComponentUsage: ['供应链系统E'],
codeSize: '1MB',
vulnerabilityCount: 3,
industryCategory: '构建工具',
developer: 'Webpack团队',
contributorCountries: ['美国', '德国', '俄罗斯'],
contributorOrganizations: ['Google', 'Microsoft', 'Yandex'],
programmingLanguage: 'JavaScript',
communityHash: 'm3n4o5p6',
softwareScore: 8.8,
sourceCodeDownload: 'https://github.com/webpack/webpack',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-1122',
versionDescription: '修复了构建性能问题',
compatibilityRisk: '高',
communityEOL: '2027-12-31',
},
{
softwareName: 'babel',
softwareVersion: '7.20.0',
releaseDate: '2025-03-25',
licenseCount: 1,
dependencyCount: 12,
productComponentUsage: ['供应链系统F'],
codeSize: '400KB',
vulnerabilityCount: 4,
industryCategory: '编译器',
developer: 'Babel团队',
contributorCountries: ['美国', '英国', '印度'],
contributorOrganizations: ['Facebook', 'Netflix', 'Uber'],
programmingLanguage: 'JavaScript',
communityHash: 'q7r8s9t0',
softwareScore: 8.7,
sourceCodeDownload: 'https://github.com/babel/babel',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-3344',
versionDescription: '新增了对新语法的支持',
compatibilityRisk: '中',
communityEOL: '2026-12-31',
},
{
softwareName: 'typescript',
softwareVersion: '5.0.0',
releaseDate: '2025-05-01',
licenseCount: 1,
dependencyCount: 5,
productComponentUsage: ['供应链系统G'],
codeSize: '2MB',
vulnerabilityCount: 0,
industryCategory: '编程语言',
developer: 'Microsoft',
contributorCountries: ['美国', '中国', '加拿大'],
contributorOrganizations: ['Microsoft', 'Google', 'Alibaba'],
programmingLanguage: 'TypeScript',
communityHash: 'u1v2w3x4',
softwareScore: 9.5,
sourceCodeDownload: 'https://github.com/microsoft/TypeScript',
copyright: 'Apache License 2.0',
externalVulnerabilitySource: '无',
versionDescription: '新增了装饰器功能',
compatibilityRisk: '低',
communityEOL: '2035-12-31',
},
{
softwareName: 'jest',
softwareVersion: '29.0.0',
releaseDate: '2025-06-10',
licenseCount: 1,
dependencyCount: 18,
productComponentUsage: ['供应链系统H'],
codeSize: '600KB',
vulnerabilityCount: 2,
industryCategory: '测试工具',
developer: 'Facebook',
contributorCountries: ['美国', '德国', '法国'],
contributorOrganizations: ['Facebook', 'Netflix', 'Spotify'],
programmingLanguage: 'JavaScript',
communityHash: 'y5z6a7b8',
softwareScore: 9.1,
sourceCodeDownload: 'https://github.com/facebook/jest',
copyright: 'MIT License',
externalVulnerabilitySource: 'CVE-2025-5566',
versionDescription: '优化了测试性能',
compatibilityRisk: '中',
communityEOL: '2032-12-31',
},
{
softwareName: 'docker',
softwareVersion: '24.0.0',
releaseDate: '2025-07-15',
licenseCount: 1,
dependencyCount: 25,
productComponentUsage: ['供应链系统I'],
codeSize: '10MB',
vulnerabilityCount: 6,
industryCategory: '容器化工具',
developer: 'Docker Inc.',
contributorCountries: ['美国', '英国', '澳大利亚'],
contributorOrganizations: ['Docker Inc.', 'Google', 'Amazon'],
programmingLanguage: 'Go',
communityHash: 'c9d0e1f2',
softwareScore: 9.3,
sourceCodeDownload: 'https://github.com/docker/docker',
copyright: 'Apache License 2.0',
externalVulnerabilitySource: 'CVE-2025-7788',
versionDescription: '新增了对ARM架构的支持',
compatibilityRisk: '高',
communityEOL: '2030-12-31',
},
{
softwareName: 'kubernetes',
softwareVersion: '1.28.0',
releaseDate: '2025-08-20',
licenseCount: 1,
dependencyCount: 30,
productComponentUsage: ['供应链系统J'],
codeSize: '15MB',
vulnerabilityCount: 8,
industryCategory: '容器编排工具',
developer: 'CNCF',
contributorCountries: ['美国', '中国', '德国'],
contributorOrganizations: ['Google', 'Red Hat', 'IBM'],
programmingLanguage: 'Go',
communityHash: 'g3h4i5j6',
softwareScore: 9.4,
sourceCodeDownload: 'https://github.com/kubernetes/kubernetes',
copyright: 'Apache License 2.0',
externalVulnerabilitySource: 'CVE-2025-9900',
versionDescription: '优化了集群管理功能',
compatibilityRisk: '高',
communityEOL: '2033-12-31',
},
{
softwareName: 'postgresql',
softwareVersion: '15.0.0',
releaseDate: '2025-09-25',
licenseCount: 1,
dependencyCount: 7,
productComponentUsage: ['供应链系统K'],
codeSize: '8MB',
vulnerabilityCount: 3,
industryCategory: '数据库',
developer: 'PostgreSQL团队',
contributorCountries: ['美国', '加拿大', '日本'],
contributorOrganizations: ['PostgreSQL Inc.', 'Amazon', 'Microsoft'],
programmingLanguage: 'C',
communityHash: 'k7l8m9n0',
softwareScore: 9.6,
sourceCodeDownload: 'https://github.com/postgres/postgres',
copyright: 'PostgreSQL License',
externalVulnerabilitySource: 'CVE-2025-1122',
versionDescription: '新增了JSONB索引功能',
compatibilityRisk: '低',
communityEOL: '2035-12-31',
},
]);
const formData = ref({ title: '',type: '', useType: '',formData:'',select: '',time1:null,name:'',versionCode:'',pulishTime:'' });
const typeOptions = reactive(['主软件', '依赖软件']);
const riskOptions = reactive(['低', '中', '高']);
const useTypeOptions = reactive(['软件', '文档', '文档+软件']);
const isUseOptions = reactive(['是', '否']);
const newFormData = ref({
license: '',
searchWord: '',
version: '',
dependentSoftware: '',
programmingLanguage: '',
dateRange: ['', '']
})
const pager = ref({
total: 10,
pageIndex: 1,
pageSize: 10
});
// 删除弹窗
const item = ref('');
const deleteModal = ref();
const deletevModels = ref(false);
const openDelete = (row: any) => {
item.value = row;
deleteModal.value.showFlag = true;
deletevModels.value = true;
};
// 定义 columns 数据
const columns = ref([
{ key: 'softwareName', label: '软件名称', visible: true, filterable: true, sortable: false },
{ key: 'softwareVersion', label: '软件版本', visible: true, filterable: true, sortable: false },
{ key: 'releaseDate', label: '版本发布时间', visible: true, filterable: true, sortable: true },
{ key: 'licenseCount', label: 'License数量', visible: true, filterable: false, sortable: false },
{ key: 'dependencyCount', label: '依赖软件数', visible: true, filterable: false, sortable: false },
{ key: 'productComponentUsage', label: '产品成分使用量', visible: false, filterable: false, sortable: false },
{ key: 'codeSize', label: '代码量', visible: true, filterable: false, sortable: false },
{ key: 'vulnerabilityCount', label: '漏洞数量', visible: true, filterable: false, sortable: false },
{ key: 'industryCategory', label: '行业分类', visible: true, filterable: true, sortable: false },
{ key: 'developer', label: '开发商', visible: false, filterable: true, sortable: false },
{ key: 'contributorCountries', label: '贡献者国家/地区分布', visible: true, filterable: false, sortable: false },
{ key: 'contributorOrganizations', label: '贡献者组织/公司分布', visible: true, filterable: false, sortable: false },
{ key: 'programmingLanguage', label: '编程语言', visible: false, filterable: true, sortable: false },
{ key: 'communityHash', label: '社区hash值', visible: false, filterable: false, sortable: false },
{ key: 'softwareScore', label: '软件评分', visible: false, filterable: false, sortable: true },
{ key: 'sourceCodeDownload', label: '源码包下载地址', visible: true, filterable: false, sortable: false },
{ key: 'copyright', label: 'CopyRight', visible: false, filterable: false, sortable: false },
{ key: 'externalVulnerabilitySource', label: '外部漏洞源的软件名称', visible: false, filterable: true, sortable: false },
{ key: 'versionDescription', label: '版本描述', visible: false, filterable: false, sortable: false },
{ key: 'compatibilityRisk', label: '兼容性风险描述', visible: false, filterable: false, sortable: false },
{ key: 'communityEOL', label: '社区EOL时间', visible: false, filterable: true, sortable: true },
]);
// 定义 showColumnList 状态
const showColumnList = ref(false);
// 更新 showColumnList 的方法
const updateShowColumnList = (newValue) => {
showColumnList.value = newValue;
tableKey.value++; // 更新 tableKey强制刷新表格
};
const router = useRouter();
const route = useRoute();
// 跳转
const gotoDetail = (row) => {
// 后续请换成params暂时params传参没传过去
router.push({
path: 'repoDetail/' + row.version
});
};
// 分页
const changeIndex = () => {
// getGroupClaListData();
};
const changeSize = () => {
pager.value.pageIndex = 1;
// getGroupClaListData();
};
const repoFun = (arr: any) => {
return arr ? (arr.length > 3 ? arr.slice(0, 3) : arr) : [];
};
// 编辑
const editRow = (row: any) => {
// 后续请换成params暂时params传参没传过去
router.push({
path: 'cla/edit/' + row.object_id,
query: { cla: row.cla, pageType: 'edit' }
});
};
// 确认删除
const confirmDelete = async (e: any) => {
// const res = await reqCatch(deleteGroupCla, { group_id: namespace.value, cla_id: item.value.object_id });
// if (!res.error) {
// getGroupClaListData();
// }
};
// 去成员页
const goMember = (row: any) => {
// 后续请换成params暂时params传参没传过去,注意路由有个:claID
router.push({
path: 'cla/claId/member',
query: { claId: row.object_id, claName: row.cla_name, group_path: namespace.value, pageType: 'edit' }
});
};
const getGroupClaListData = async () => {
// const params = {
// group_id: namespace.value,
// page: pager.value.pageIndex,
// per_page: pager.value.pageSize
// };
// const res = await reqCatch(getGroupClaList, params);
// if (!res.error) {
// tableData.value = res?.data?.data?.content;
// pager.value.total = res.data.data.total;
// }
};
getGroupClaListData();
const setClaStatus = async (row: any) => {
// const params = {
// group_id: namespace.value,
// cla_id: row.object_id,
// status: row.status
// };
// const res = await reqCatch(setGroupClaStatus, params);
// if (!res.error) {
// Message.success('操作成功!');
// getGroupClaListData();
// }
};
const signCla = (row: any) => {
router.push('/cla/' + row.object_id);
};
onMounted(() => {
const query: any = route.query;
newFormData.value = {
...query
};
});
</script>
<style scoped lang="scss">
@import 'devui-theme/styles-var/devui-var.scss';
.secret-container {
position: relative;
.secret-op {
position: absolute;
right: 0;
top: 0;
}
}
.error {
color: $devui-contrast;
}
:deep(.devui-table__row td) {
padding-top: 16px;
padding-bottom: 16px;
}
:deep(.devui-tag .devui-tag--default) {
background-color: #fff;
border-radius: 12px;
padding: 4px 8px;
font-size: 12px;
line-height: 16px;
margin-right: 8px;
border: 1px solid #E3E3EE;
}
.one-line {
word-break: break-all;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.title {
font-size: 14px;
font-weight: 400;
color: #9a9b9c;
line-height: 20px;
}
.cur-title {
font-size: 14px;
font-weight: 500;
color: #2d2d2e;
line-height: 20px;
}
.search-form {
position: relative;
border-radius: 8px 0px 8px 8px;
//background: #F2F5FC;
.left-btn {
position: absolute;
right: 28px;
bottom: 4px;
}
.output-btn {
color: #191919;
font-family: HarmonyOS Sans SC;
font-weight: regular;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
}
.secret-breadcrumb {
padding: 7px 20px 12px;
background: #ffffff;
}
</style>

View File

@@ -1,43 +1,102 @@
<template>
<d-dropdown>
<d-button class="output-btn" icon="icon-form-settings" variant="text">设置</d-button>
<template #menu>
<!-- <ul class="list-menu">-->
<!-- <d-dropdown :position="position" :offset="0">-->
<!--&lt;!&ndash; <li class="menu-item">&ndash;&gt;-->
<!--&lt;!&ndash; Item 1&ndash;&gt;-->
<!--&lt;!&ndash; <i class="icon icon-chevron-right"></i>&ndash;&gt;-->
<!--&lt;!&ndash; </li>&ndash;&gt;-->
<!--&lt;!&ndash; <template #menu>&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <ul class="list-menu">&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <d-dropdown :position="position" :offset="0" >&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <li class="menu-item">&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; Item 1-1&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <i class="icon icon-chevron-right"></i>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; </li>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <template #menu>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <ul class="list-menu">&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <li class="menu-item">Item 1-1-1</li>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <li class="menu-item">Item 1-1-2</li>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <li class="menu-item">Item 1-1-3</li>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; </ul>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; </template>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; </d-dropdown>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; <li class="menu-item">Item 1-2</li>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash; </ul>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash; </template>&ndash;&gt;-->
<!-- </d-dropdown>-->
<!-- <li class="menu-item">Item 2</li>-->
<!-- </ul>-->
</template>
</d-dropdown>
<div class="TableSetting">
<d-button @click.stop="toggleColumnList" class="output-btn" icon="icon-form-settings" variant="text">设置</d-button>
<!-- 多选列表 -->
<div v-if="showColumnList" class="column-list">
<div class="column-list-header">
<span class="title1">展示列设置</span>
<a class="title2">恢复默认</a>
</div>
<div class="column-list-body">
<d-checkbox
v-for="column in columns"
:key="column.key"
v-model="column.visible"
>
{{ column.label }}
</d-checkbox>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ref, defineProps, defineEmits } from 'vue';
const position = ref(['right-start', 'right-end']);
const props = defineProps({
columns: {
type: Array,
required: true,
},
showColumnList: {
type: Boolean,
required: true,
},
});
// 定义 emit用于更新 showColumnList
const emits = defineEmits(['update:show-column-list']);
// 切换多选列表的显示
const toggleColumnList = () => {
const newValue = !props.showColumnList;
emits('update:show-column-list', newValue); // 触发事件,更新父组件的 showColumnList
};
</script>
<style lang="scss" scoped>
.TableSetting {
display: inline-block;
position: relative;
//padding: 20px;
}
.column-list {
position: absolute;
top: 40px;
left: -222px;
width: 280px;
z-index: 1000;
border-radius: 4px;
background: #FFFFFF;
box-shadow: 0px 2px 9px 0px #252B3A28;
padding: 20px;
}
.column-list-header {
display: flex;
justify-content: space-between;
.title1 {
color: #191919;
font-family: 鸿蒙黑体;
font-weight: SemiBold;
font-size: 16px;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.title2 {
color: #5E7CE0;
font-family: 苹方-;
font-weight: regular;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: right;
}
}
.column-list-body {
margin-top: 20px;
//padding: 10px;
> div {
margin-bottom: 8px;
}
}
.d-checkbox {
display: block;
margin-bottom: 8px;
}
</style>