Browse Source

新增功能

master
zhouhaibin 5 months ago
parent
commit
037abea8cf
  1. 3
      package.json
  2. 5
      src/main.ts
  3. 24
      src/views/informationSub/countStatistics/countStatistics.api.ts
  4. 71
      src/views/informationSub/countStatistics/countStatistics.data.ts
  5. 73
      src/views/informationSub/countStatistics/index.vue
  6. 58
      src/views/informationSub/countStatistics/modifycountStatistics.vue
  7. 138
      src/views/informationSub/monthlyJournal/addAndModify.vue
  8. 113
      src/views/informationSub/monthlyJournal/index.vue
  9. 23
      src/views/informationSub/monthlyJournal/monthlyJournal.api.ts
  10. 90
      src/views/informationSub/monthlyJournal/monthlyJournal.data.ts
  11. 57
      src/views/workSystem/organizationStructure/detail.vue
  12. 113
      src/views/workSystem/organizationStructure/index.vue
  13. 10
      src/views/workSystem/organizationStructure/organizationStructure.api.ts
  14. 71
      src/views/workSystem/organizationStructure/organizationStructure.data.ts

3
package.json

@ -111,7 +111,8 @@
"vxe-table-plugin-export-xlsx": "^3.0.4", "vxe-table-plugin-export-xlsx": "^3.0.4",
"xe-utils": "^3.5.11", "xe-utils": "^3.5.11",
"xlsx": "^0.18.5", "xlsx": "^0.18.5",
"element-plus": "2.2.28" "element-plus": "2.2.28",
"vue3-tree-org":"^4.2.2"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.6.6", "@commitlint/cli": "^17.6.6",

5
src/main.ts

@ -20,12 +20,15 @@ import { setupStore } from '@/store';
import "echarts" import "echarts"
import ECharts from "vue-echarts" import ECharts from "vue-echarts"
import vue3TreeOrg from 'vue3-tree-org';
import "vue3-tree-org/lib/vue3-tree-org.css";
import App from './App.vue'; import App from './App.vue';
async function bootstrap() { async function bootstrap() {
const app = createApp(App); const app = createApp(App);
app.use(ElementPlus) app.use(ElementPlus)
app.use(vue3TreeOrg)
// Configure store // Configure store
// 配置 store // 配置 store
setupStore(app); setupStore(app);

24
src/views/informationSub/countStatistics/countStatistics.api.ts

@ -0,0 +1,24 @@
import { defHttp } from '@/utils/http/axios';
export enum Api {
changeFieldManagePageList = '/huzhouChangefieldmanage/changeFieldManagePageList',
getchangeFieldManageById = '/huzhouChangefieldmanage/getchangeFieldManageById',
modifychangeFieldManageById='/huzhouChangefieldmanage/modifychangeFieldManageById'
}
/**
* list
*/
export const changeFieldManagePageList = (params?) =>defHttp.get({ url: Api.changeFieldManagePageList, params });
export const getchangeFieldManageById = (params?) =>defHttp.get({ url: Api.getchangeFieldManageById, params });
export const modifychangeFieldManageById = (params?) =>defHttp.post({ url: Api.modifychangeFieldManageById, params });

71
src/views/informationSub/countStatistics/countStatistics.data.ts

@ -0,0 +1,71 @@
import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table';
import { useDictStore } from '@/store/modules/dict';
export const countStatisticsColumns: BasicColumn[] = [
{
title: '责任单位',
width: 150,
dataIndex: 'fieldName',
},
{
title: '行政区划',
dataIndex: 'ischange',
width: 150,
},
{
title: '已提交稿件数量',
dataIndex: 'isuploadfile',
width: 150,
sorter: true,
}
];
export const searchFormSchema: FormSchema[] = [
{
label: '责任单位',
field: 'fieldName',
component: 'Input',
colProps: { span: 6 },
},
{
label: '行政区划',
field: 'fieldName',
component: 'Input',
colProps: { span: 6 },
},
]
export const countStatisticsFormSchema: FormSchema[] = [
{
label: '责任单位',
field: 'fieldName',
component: 'Input',
dynamicDisabled: true,
colProps: { span:12},
},
{
label: '行政区划',
field: 'ischange',
component: 'DictSelect',
componentProps: {
dictType: 'whether',
},
dynamicDisabled: true,
colProps: { span:12 },
},
{
label: '已提交稿件数量',
field: 'isuploadfile',
component: 'DictSelect',
componentProps: {
dictType: 'whether',
},
required: true,
colProps: { span: 12 },
}
];

73
src/views/informationSub/countStatistics/index.vue

@ -0,0 +1,73 @@
<template>
<PageWrapper dense>
<!--引用表格-->
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<!--操作栏-->
<template #action="{ record }">
<!-- <TableAction :actions="getTableAction(record)" /> -->
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<BasicModal @register="registechangeFieldManageModal" title="变更字段详情" width="1200px" :showOkBtn="false">
<modifycountStatistics :id="id" @exit="close" />
</BasicModal>
</PageWrapper>
</template>
<script lang="ts" name="system-user" setup>
//ts
import { ref } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import modifycountStatistics from "./modifycountStatistics.vue"
import { BasicModal, useModal } from '@/components/Modal';
import { countStatisticsColumns, searchFormSchema } from './countStatistics.data'
import { changeFieldManagePageList } from './countStatistics.api';
let id = ref();
const [registechangeFieldManageModal, { openModal: openchangeFieldManage,closeModal}] = useModal();//
const [registerTable,{reload}] = useTable({
title: '信息稿件详情',
api: changeFieldManagePageList,
columns: countStatisticsColumns,
useSearchForm: true,
actionColumn: {
width: 140,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
//
formConfig: {
schemas: searchFormSchema,
}
});
function getTableAction(record): ActionItem[] {
return [
{
label: '修改',
onClick: handlemodifympage.bind(null, record),
},
];
}
function handlemodifympage(record) {
id.value = record.id
openchangeFieldManage()
}
function close(){
closeModal()
reload()
}
</script>
<style scoped></style>

58
src/views/informationSub/countStatistics/modifycountStatistics.vue

@ -0,0 +1,58 @@
<template>
<div>
<BasicForm @register="registerchangeFieldForm" @submit="handleSubmit" />
</div>
</template>
<script lang="ts" name="changeFieldManageDetail" setup>
//ts
import { defineProps, onMounted } from 'vue';
import { useForm, BasicForm } from '@/components/Form';
import { countStatisticsFormSchema } from './countStatistics.data'
import { modifychangeFieldManageById, getchangeFieldManageById } from './countStatistics.api';
let emit = defineEmits(["exit"])
let dataTo = defineProps(["id"])
onMounted(async () => {
let res = await getchangeFieldManageById({id: dataTo.id})
console.log("结果是", res)
setFieldsValue(res)
})
const [registerchangeFieldForm,{ getFieldsValue, validate, setFieldsValue }] = useForm({
//
schemas: countStatisticsFormSchema,
//
// submitButtonOptions: { text: '', preIcon: '' },
//
resetButtonOptions: { text: '取消' },
// showActionButtonGroup: false,
//
// autoSubmitOnEnter: true,
// //
// showResetButton: false,
//
submitButtonOptions: { text: '提交' },
// 24 0-24
actionColOptions: { span: 14 },
//
// submitFunc: customSubmitFunc,
//
resetFunc: customResetFunc,
labelCol: { style: { width: '120px' } },
wrapperCol: { style: { width: 'auto' } },
// disabled:true
})
async function handleSubmit() {
if (await validate()) {
let datas = await getFieldsValue()
await modifychangeFieldManageById(datas)
emit("exit")
}
}
async function customResetFunc() {
emit("exit")
}
</script>
<style scoped></style>

138
src/views/informationSub/monthlyJournal/addAndModify.vue

@ -0,0 +1,138 @@
<template>
<!-- 自定义表单 -->
<BasicModal v-bind="$attrs" @register="registerModal" title="月度期刊详情" width="1200px" :showOkBtn="false" :showCancelBtn="false">
<el-divider content-position="left">资料信息</el-divider>
<BasicForm @register="registerProjectForm" />
<el-divider content-position="left">上传期刊资料</el-divider>
<el-form ref="importFormRef" >
<el-form-item label="上传文件:">
<el-upload class="upload-demo" ref="upload" action :http-request="httpRequest" :before-upload="beforeUpload"
:on-exceed="handleExceed" :limit="1" :on-remove="removeFile">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">文件大小且不超过500M</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitImportForm">上传</el-button>
<el-button type="info" @click="dialogVisible">关闭窗口</el-button>
</el-form-item>
</el-form>
</BasicModal>
</template>
<script lang="ts" name="addAndModify" setup>
import { ref, reactive, defineProps, watchEffect } from 'vue'
import { useForm, BasicForm } from '@/components/Form';
import { monthlyJournalformSchemas } from './monthlyJournal.data';
import { modifyPeriodicallab, addPeriodicallab, getperiodicallabById } from './monthlyJournal.api';
import { ElMessage } from 'element-plus'
import { useModalInner, BasicModal } from '@/components/Modal';
const [registerModal, { closeModal }] = useModalInner(init);
let fileList = reactive<Array<any>>([]);
let id = ref()
const emit = defineEmits(['close']);
async function init(data) {
fileList.pop()
if (data.id != null) {
id.value = data.id
let param: any = {
id: data.id
}
let res = await getperiodicallabById(param)
console.log("结果是", res)
setFieldsValue(res)
}
}
//
const [registerProjectForm, { setFieldsValue: setFieldsValue, getFieldsValue, validate }] = useForm({
//
schemas: monthlyJournalformSchemas,
showActionButtonGroup: false,
//
// autoSubmitOnEnter: true,
// //
// showResetButton: false,
//
// submitButtonOptions: { text: '', preIcon: '' },
// 24 0-24
// actionColOptions: { span: 17 },
labelCol: { style: { width: '120px' } },
wrapperCol: { style: { width: 'auto' } },
});
// fileList,
function httpRequest(option) {
fileList.push(option)
}
function removeFile(option) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].file.name == option.name) {
fileList.splice(i, 1)
}
}
console.log(fileList, option)
}
//
function beforeUpload(file) {
let fileSize = file.size
const FIVE_M = 500 * 1024 * 1024;
//5M
if (fileSize > FIVE_M) {
ElMessage.error("最大上传500M")
return false
}
return true
}
//
function handleExceed() {
ElMessage.warning("最多只能上传一个文件")
}
//Excel
async function submitImportForm() {
if (await validate()) {
let data = await getFieldsValue()
console.log("data", data)
// 使form
const params = new FormData()
if (id.value != null) {
//
if(fileList.length>0){
params.append('file', fileList[0].file)
}
params.append("id", id.value)
params.append("name", data.name)
params.append("periods", data.periods)
params.append("publishTime", data.publishTime)
await modifyPeriodicallab(params)
} else {
if (fileList.length == 0) {
ElMessage.warning("请上传文件")
return;
}
params.append('file', fileList[0].file)
params.append("name", data.name)
params.append("periods", data.periods)
params.append("publishTime", data.publishTime)
await addPeriodicallab(params)
}
dialogVisible()
}
}
function dialogVisible() {
closeModal()
emit("close")
}
</script>
<style></style>

113
src/views/informationSub/monthlyJournal/index.vue

@ -0,0 +1,113 @@
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable">
<template #action="{ record }">
<!-- <TableAction :actions="getTableAction(record)" /> -->
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
<template #tableTitle>
<el-button type="primary" round @click="handleAdd" v-if="isShowByRoles('manageOrg')">新增月度期刊</el-button>
<el-button type="primary" round @click="handleBatchdownload"> 批量导出</el-button>
</template>
</BasicTable>
<addAndModify @register="registerSubmitProjectArchive" @close="closeModel" />
</div>
</template>
<script lang="ts" name="system-user" setup>
//ts
import { ref } from 'vue';
import { ActionItem, BasicTable, TableAction, useTable } from '@/components/Table';
import { useModal } from '@/components/Modal';
import { downloadFile } from "../../../api/common/api"
import { isShowByRoles } from '@/views/projectLib/projectInfo/projectInfo.api';
import { monthlyJournalcolumns, searchFormSchema } from './monthlyJournal.data';
import addAndModify from "./addAndModify.vue"
import { periodicallabPageList, batchdownloadPeriodicallabFiles, deletePeriodicallab } from './monthlyJournal.api';
const [registerSubmitProjectArchive, { openModal }] = useModal();
const [registerTable, { reload, getForm }] = useTable({
title: '月度期刊信息',
api: periodicallabPageList,
columns: monthlyJournalcolumns,
useSearchForm: true,
actionColumn: {
width: 140,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
//
formConfig: {
schemas: searchFormSchema,
}
});
function getTableAction(record): ActionItem[] {
return [
{
label: '下载',
onClick: handledown.bind(null, record),
}
];
}
function getDropDownAction(record): ActionItem[] {
return [
{
label: '修改',
ifShow: () => {
return isShowByRoles('manageOrg')
},
onClick: handleModify.bind(null, record)
},
{
label: '删除',
ifShow: () => {
return isShowByRoles('manageOrg')
},
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
},
}
];
}
function handleAdd() {
openModal(true, { id: null })
}
function handleModify(record) {
openModal(true, { id: record.id })
}
function handleSubmit(record) {
}
function handledown(record) {
let param = {
path: record.documentPath,
}
downloadFile("/huzhouUploadfileinfo/downloadfile", record.documentName, param)
}
async function handleDelete(record) {
await deletePeriodicallab({ id: record.id })
reload()
}
function handleBatchdownload() {
let { getFieldsValue } = getForm()
let fromData = getFieldsValue()
batchdownloadPeriodicallabFiles(fromData)
}
function closeModel() {
reload()
}
</script>
<style scoped></style>

23
src/views/informationSub/monthlyJournal/monthlyJournal.api.ts

@ -0,0 +1,23 @@
import { defHttp } from '@/utils/http/axios';
import { downloadFile } from "../../../api/common/api"
export enum Api {
periodicallabPageList = '/huzhouPeriodicallab/periodicallabPageList',
addPeriodicallab="/huzhouPeriodicallab/addPeriodicallab",
modifyPeriodicallab = '/huzhouPeriodicallab/modifyPeriodicallab',
getperiodicallabById="/huzhouPeriodicallab/getperiodicallabById",
deletePeriodicallab = '/huzhouPeriodicallab/deletePeriodicallab',
batchdownloadPeriodicallabFiles="/huzhouPeriodicallab/batchdownloadPeriodicallabFiles"
}
export const periodicallabPageList = (params) => defHttp.get({ url: Api.periodicallabPageList, params })
export const getperiodicallabById = (params) => defHttp.get({ url: Api.getperiodicallabById, params })
export const batchdownloadPeriodicallabFiles = (params) => downloadFile(Api.batchdownloadPeriodicallabFiles,"批量导出.zip",params)
export const addPeriodicallab = (params?) =>defHttp.post({ url: Api.addPeriodicallab,headers:{ "Content-Type": "multipart/form-data" }, params })
export const modifyPeriodicallab = (params?) =>defHttp.post({ url: Api.modifyPeriodicallab,headers:{ "Content-Type": "multipart/form-data" }, params })
export const deletePeriodicallab = (params?) =>defHttp.post({ url: Api.deletePeriodicallab, params })

90
src/views/informationSub/monthlyJournal/monthlyJournal.data.ts

@ -0,0 +1,90 @@
import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table';
export const monthlyJournalcolumns: BasicColumn[] = [
{
title: '期刊名称',
width: 150,
dataIndex: 'name',
},
{
title: '期刊期数',
width: 150,
dataIndex: 'periods',
},
{
title: '发布日期',
width: 200,
dataIndex: 'publishTime',
},
// {
// title: '文件名称',
// dataIndex: 'documentName',
// width: 150,
// },
// {
// title: '文件大小',
// dataIndex: 'size',
// width: 150,
// customRender: ({ record }) => {
// let kbNum: number = record.size / 1024
// if (kbNum < 1024) {
// return kbNum.toFixed(2).toString() + "KB"
// } else {
// let mbNum: number = kbNum / 1024
// return mbNum.toFixed(2).toString() + "MB"
// }
// },
// },
];
export const searchFormSchema: FormSchema[] = [
{
label: '期刊期数',
field: 'periods',
component: 'Input',
colProps: { span: 5 },
},
{
label: '发布日期',
field: 'publishTime',
component: 'Input',
colProps: { span: 5 },
},
];
export const monthlyJournalformSchemas: FormSchema[] = [
{
label: '期刊名称',
field: 'name',
component: 'Input',
required: true,
colProps: { span: 12 },
},
{
label: '期刊期数',
field: 'periods',
required: true,
component: 'Input',
colProps: { span: 6 },
}, {
label: '发布日期',
field: 'publishTime',
component: 'DatePicker',
componentProps: {
valueFormat: 'YYYY-MM-DD',
},
required: true,
colProps: { span: 6},
},
];

57
src/views/workSystem/organizationStructure/detail.vue

@ -0,0 +1,57 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="用户信息详情" width="1200px" :showOkBtn="false">
<BasicTable @register="registerTable">
</BasicTable>
</BasicModal>
</template>
<script lang="ts" name="system-user" setup>
//ts
import { ref } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { useModalInner, BasicModal } from '@/components/Modal';
import { organizationStructurecolumns, searchFormSchema } from './organizationStructure.data';
import { getUsers, } from './organizationStructure.api';
const condition= ref("all")
const [registerModal] = useModalInner(init);
const [registerTable, { reload }] = useTable({
title: '用户',
api: getUsers,
columns: organizationStructurecolumns,
useSearchForm: true,
//
formConfig: {
schemas: searchFormSchema,
},
beforeFetch(param) {
param.condition=condition.value
},
});
function init(data){
if(data.name=="信息化专班"){
condition.value="all"
}else if(data.name=="信息化工作小组"){
condition.value="all"
}else if(data.name=="任务牵头处室"){
condition.value="task"
}else if(data.name=="信息化保障团队"){
condition.value="team"
}else if(data.name=="挂职人员"){
condition.value="guazhi"
}else if(data.name=="总咨询单位"){
condition.value="consult"
}else if(data.name=="项目联系人" ||data.name=="项目建设小组"){
condition.value="contact"
}
console.log(data,condition.value)
reload()
}
</script>
<style scoped></style>

113
src/views/workSystem/organizationStructure/index.vue

@ -0,0 +1,113 @@
<template>
<PageWrapper>
<div>
<div class="text-2xl mb-4 text-sky-400" >组织架构</div>
<div style="height: 480px">
<vue3-tree-org
:data="data"
:center="true"
:scalable="false"
:draggable="false"
:disabled="disaled"
:default-expand-level="3"
:horizontal="horizontal"
:collapsable="collapsable"
:only-one-node="onlyOneNode"
:node-draggable="false"
@on-node-click="onNodeClick"
>
<!-- 自定义节点内容 -->
<template v-slot="{ node }">
<div v-if="node.id==1" class="flex grow w-64 h-16 text-2xl justify-center items-center rounded-full bg-blue-600" >{{ node.label }}</div>
<div v-else-if="node.id==2" class="flex grow w-64 h-16 text-2xl justify-center items-center rounded-full bg-sky-400" >{{ node.label }}</div>
<div v-else-if="node.id==6" class="flex grow w-64 h-16 text-2xl justify-center items-center bg-sky-400" >{{ node.label }}</div>
<div v-else-if="node.id==8" class="flex grow w-64 h-16 text-2xl justify-center items-center bg-sky-400" >{{ node.label }}</div>
<div v-else-if="node.id==10" class="flex grow w-64 h-16 text-2xl justify-center items-center bg-sky-400" >{{ node.label }}</div>
<div v-else-if="node.id==9" class="flex grow w-64 h-16 text-2xl justify-center items-center outline outline-offset-2 outline-2" >{{ node.label }}</div>
<div v-else-if="node.id==11" class="flex grow w-64 h-16 text-2xl justify-center items-center outline outline-offset-2 outline-2" >{{ node.label }}</div>
<div v-else-if="node.id==12" class="flex grow w-64 h-16 text-2xl justify-center items-center outline outline-offset-2 outline-2" >{{ node.label }}</div>
</template>
</vue3-tree-org>
</div>
</div>
<detail @register="registerdetai" @close="closeModals" />
</PageWrapper>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { PageWrapper } from '@/components/Page';
import { useModal } from '@/components/Modal';
import detail from './detail.vue';
const [registerdetai, { openModal: openModal,closeModal: closeModals }] = useModal();//
const data = ref({});
data.value = {
id: 1,
label: '信息化专班',
style: { color: '#fff' },
children: [
{
id: 2,
pid: 1,
label: '信息化工作小组',
style: { color: '#fff' },
children: [
{
id: 6,
pid: 2,
label: '任务牵头处室',
style: { color: '#fff' },
},
{
id: 8,
pid: 2,
label: '信息化保障团队',
style: { color: '#fff'},
children: [
{ id: 9, pid: 8, label: '挂职人员' ,
style: { color: 'rgb(56 189 248)' },
},
{ id: 11, pid: 8, label: '总咨询单位' ,
style: { color: 'rgb(56 189 248)' },
},
],
},
{
id: 10,
pid: 2,
label: '项目建设小组',
style: { color: '#fff' },
children: [{ id: 12, pid: 10, label: '项目联系人',
style: { color: 'rgb(56 189 248)' },
}],
},
],
},
],
};
const horizontal = ref(true);
const collapsable = ref(false);
const onlyOneNode = ref(false);
const disaled = ref(true);
// const onNodeDblclick = (node,data) => {
// console.log(node,data);
// };
const onNodeClick = async (e,data) => {
console.log(data.label);
await openModal(true,{ name: data.label });
};
onMounted(() => {
console.log('mounted');
});
// import ProjectCard from './ProjectCard.vue';
</script>
<style lang="less" scoped>
.tree-org-node__content .tree-org-node__inner {
box-shadow:initial !important;
}
</style>

10
src/views/workSystem/organizationStructure/organizationStructure.api.ts

@ -0,0 +1,10 @@
import { defHttp } from '@/utils/http/axios';
import { downloadFile } from "../../../api/common/api"
export enum Api {
getUsers = '/api/auth/sys/user/getUsers',
}
export const getUsers = (params) => defHttp.get({ url: Api.getUsers, params })

71
src/views/workSystem/organizationStructure/organizationStructure.data.ts

@ -0,0 +1,71 @@
import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table';
export const organizationStructurecolumns: BasicColumn[] = [
{
title: '昵称',
width: 150,
dataIndex: 'nickname',
},
{
title: '角色',
width: 150,
dataIndex: 'role',
// format: 'dict|regulationlabCategory',
},
{
title: '性别',
width: 200,
dataIndex: 'sex',
format: 'dict|sex',
},
{
title: '手机号',
dataIndex: 'phoneNumber',
width: 150,
},
{
title: '单位名称',
dataIndex: 'workplace',
width: 150
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '昵称',
field: 'nickname',
component: 'Input',
colProps: { span: 6 },
},
{
label: '角色',
field: 'role',
component: 'Input',
// component: 'DictSelect',
// itemProps: { validateTrigger: 'blur' },
// componentProps: {
// dictType: 'regulationlabCategory'
// },
colProps: { span: 6 },
},
{
label: '手机号',
field: 'phoneNumber',
component: 'Input',
colProps: { span: 6 },
},
{
label: '单位名称',
field: 'workplace',
component: 'Input',
colProps: { span: 6 },
}
];
Loading…
Cancel
Save