桩点支架分批次上传
This commit is contained in:
@ -93,6 +93,8 @@ export const addProjectFacilities = (data: any) => {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export const addProjectPilePoint = (data: any) => {
|
export const addProjectPilePoint = (data: any) => {
|
||||||
|
console.log("🚀 ~ addProjectPilePoint ~ data:", data)
|
||||||
|
|
||||||
return request({
|
return request({
|
||||||
url: '/facility/photovoltaicPanelPoint/parts/geoJson',
|
url: '/facility/photovoltaicPanelPoint/parts/geoJson',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
@ -201,11 +201,16 @@ const handleUploadError = () => {
|
|||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
const handleUploadSuccess = (res: any, file: UploadFile) => {
|
const handleUploadSuccess = (res: any, file: UploadFile) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
if (res.data) {
|
||||||
uploadList.value.push({
|
uploadList.value.push({
|
||||||
name: res.data.fileName,
|
name: res.data.fileName,
|
||||||
url: res.data.url,
|
url: res.data.url,
|
||||||
ossId: res.data.ossId
|
ossId: res.data.ossId
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
uploadList.value.push({});
|
||||||
|
}
|
||||||
|
|
||||||
uploadedSuccessfully();
|
uploadedSuccessfully();
|
||||||
} else {
|
} else {
|
||||||
number.value--;
|
number.value--;
|
||||||
@ -242,6 +247,8 @@ const uploadedSuccessfully = () => {
|
|||||||
proxy?.$modal.msgSuccess('导入成功');
|
proxy?.$modal.msgSuccess('导入成功');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(number.value, uploadList.value);
|
||||||
|
|
||||||
if (number.value > 0 && uploadList.value.length === number.value) {
|
if (number.value > 0 && uploadList.value.length === number.value) {
|
||||||
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
|
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
|
||||||
uploadList.value = [];
|
uploadList.value = [];
|
||||||
|
@ -89,6 +89,7 @@ import * as turf from '@turf/turf';
|
|||||||
import { FeatureCollection } from 'geojson';
|
import { FeatureCollection } from 'geojson';
|
||||||
import { TreeInstance } from 'element-plus';
|
import { TreeInstance } from 'element-plus';
|
||||||
import { addProjectFacilities, addProjectPilePoint, addProjectSquare, listDXFProject, addInverter, addBoxTransformer } from '@/api/project/project';
|
import { addProjectFacilities, addProjectPilePoint, addProjectSquare, listDXFProject, addInverter, addBoxTransformer } from '@/api/project/project';
|
||||||
|
import { BatchUploader } from '@/utils/batchUpload';
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -322,8 +323,8 @@ const handleMenuItemClick = (option: string) => {
|
|||||||
if (selectLayer.value.some((item) => item.location.name === contextMenu.value.name)) {
|
if (selectLayer.value.some((item) => item.location.name === contextMenu.value.name)) {
|
||||||
return proxy?.$modal.msgError('已选择该图层,请勿重复选择');
|
return proxy?.$modal.msgError('已选择该图层,请勿重复选择');
|
||||||
}
|
}
|
||||||
if (selectLayer.value.some((item) => item.option !== '名称')) {
|
if (selectLayer.value.some((item) => item.option !== '名称' && item.option !== '箱变')) {
|
||||||
if (option !== '名称') return proxy?.$modal.msgError('只能选择一个类型');
|
if (option !== '名称' && option !== '箱变') return proxy?.$modal.msgError('只能选择一个类型');
|
||||||
}
|
}
|
||||||
selectLayer.value.push({ location: contextMenu.value, option });
|
selectLayer.value.push({ location: contextMenu.value, option });
|
||||||
console.log('selectLayer.value', selectLayer.value);
|
console.log('selectLayer.value', selectLayer.value);
|
||||||
@ -365,63 +366,6 @@ const onUnmounted = () => {
|
|||||||
window.removeEventListener('click', closeMenuOnClickOutside);
|
window.removeEventListener('click', closeMenuOnClickOutside);
|
||||||
};
|
};
|
||||||
|
|
||||||
// const addFacilities = async () => {
|
|
||||||
// console.log(layerType.value);
|
|
||||||
|
|
||||||
// if (!layerType.value) {
|
|
||||||
// return proxy?.$modal.msgError('请选择图层类型');
|
|
||||||
// }
|
|
||||||
// if (!selectLayer.value.length) {
|
|
||||||
// return proxy?.$modal.msgError('请选择需要上传的图层');
|
|
||||||
// }
|
|
||||||
// const data = {
|
|
||||||
// projectId: props.projectId,
|
|
||||||
// nameGeoJson: null,
|
|
||||||
// locationGeoJson: null,
|
|
||||||
// pointGeoJson: null
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if (layerType.value == 1) {
|
|
||||||
// if (!checkOptions(selectLayer.value, '光伏板')) {
|
|
||||||
// return proxy?.$modal.msgError('请选择名称和光伏板');
|
|
||||||
// }
|
|
||||||
// loading.value = true;
|
|
||||||
// if (selectLayer.value[0].option == '名称') {
|
|
||||||
// data.nameGeoJson = treeData.value[selectLayer.value[0].location.index];
|
|
||||||
// data.locationGeoJson = treeData.value[selectLayer.value[1].location.index];
|
|
||||||
// } else {
|
|
||||||
// data.nameGeoJson = treeData.value[selectLayer.value[1].location.index];
|
|
||||||
// data.locationGeoJson = treeData.value[selectLayer.value[0].location.index];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await addProjectFacilities(data);
|
|
||||||
// await proxy?.$modal.msgSuccess('添加成功');
|
|
||||||
// } else if (layerType.value == 2) {
|
|
||||||
// if (selectLayer.value.length > 1) return proxy?.$modal.msgError('最多选择一个桩点/支架');
|
|
||||||
// if (selectLayer.value[0].option != '桩点/支架') return proxy?.$modal.msgError('请选择类型为桩点/支架');
|
|
||||||
// loading.value = true;
|
|
||||||
// data.pointGeoJson = treeData.value[selectLayer.value[0].location.index];
|
|
||||||
// await addProjectPilePoint(data);
|
|
||||||
// await proxy?.$modal.msgSuccess('添加成功');
|
|
||||||
// } else if (layerType.value == 3) {
|
|
||||||
// if (!checkOptions(selectLayer.value, '方阵')) {
|
|
||||||
// return proxy?.$modal.msgError('请选择名称和方阵');
|
|
||||||
// }
|
|
||||||
// loading.value = true;
|
|
||||||
// if (selectLayer.value[0].option == '名称') {
|
|
||||||
// data.nameGeoJson = treeData.value[selectLayer.value[0].location.index];
|
|
||||||
// data.locationGeoJson = treeData.value[selectLayer.value[1].location.index];
|
|
||||||
// } else {
|
|
||||||
// data.nameGeoJson = treeData.value[selectLayer.value[1].location.index];
|
|
||||||
// data.locationGeoJson = treeData.value[selectLayer.value[0].location.index];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await addProjectSquare(data);
|
|
||||||
// await proxy?.$modal.msgSuccess('添加成功');
|
|
||||||
// }
|
|
||||||
// reset();
|
|
||||||
// loading.value = false;
|
|
||||||
// };
|
|
||||||
type LayerConfig = {
|
type LayerConfig = {
|
||||||
optionB: string;
|
optionB: string;
|
||||||
apiFunc: (data: any) => Promise<any>;
|
apiFunc: (data: any) => Promise<any>;
|
||||||
@ -439,7 +383,7 @@ const showSuccess = (msg: string) => proxy?.$modal.msgSuccess(msg);
|
|||||||
|
|
||||||
const getGeoJsonData = (nameOption = '名称', secondOption: string): { nameGeoJson: any[]; locationGeoJson: any | null } | null => {
|
const getGeoJsonData = (nameOption = '名称', secondOption: string): { nameGeoJson: any[]; locationGeoJson: any | null } | null => {
|
||||||
const nameLayers = selectLayer.value.filter((item) => item.option === nameOption);
|
const nameLayers = selectLayer.value.filter((item) => item.option === nameOption);
|
||||||
const secondLayer = selectLayer.value.find((item) => item.option === secondOption);
|
const secondLayer = selectLayer.value.filter((item) => item.option === secondOption);
|
||||||
|
|
||||||
if (!nameLayers.length || !secondLayer) {
|
if (!nameLayers.length || !secondLayer) {
|
||||||
showError(`请选择${nameOption}和${secondOption}`);
|
showError(`请选择${nameOption}和${secondOption}`);
|
||||||
@ -447,7 +391,7 @@ const getGeoJsonData = (nameOption = '名称', secondOption: string): { nameGeoJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
const nameGeoJson = nameLayers.map((item) => treeData.value[item.location.index]);
|
const nameGeoJson = nameLayers.map((item) => treeData.value[item.location.index]);
|
||||||
const locationGeoJson = treeData.value[secondLayer.location.index];
|
const locationGeoJson = secondLayer.map((item) => treeData.value[item.location.index]);
|
||||||
|
|
||||||
return { nameGeoJson, locationGeoJson };
|
return { nameGeoJson, locationGeoJson };
|
||||||
};
|
};
|
||||||
@ -472,16 +416,35 @@ const handlePointUpload = async () => {
|
|||||||
if (selectLayer.value.length > 1) return showError('最多选择一个桩点/支架');
|
if (selectLayer.value.length > 1) return showError('最多选择一个桩点/支架');
|
||||||
if (selectLayer.value[0].option !== '桩点/支架') return showError('请选择类型为桩点/支架');
|
if (selectLayer.value[0].option !== '桩点/支架') return showError('请选择类型为桩点/支架');
|
||||||
|
|
||||||
const data = {
|
const features = treeData.value[selectLayer.value[0].location.index]?.features || [];
|
||||||
projectId: props.projectId,
|
if (!features.length) return showError('桩点数据为空');
|
||||||
nameGeoJson: null,
|
|
||||||
locationGeoJson: null,
|
|
||||||
pointGeoJson: treeData.value[selectLayer.value[0].location.index]
|
|
||||||
};
|
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await addProjectPilePoint(data);
|
const sessionId = new Date().getTime().toString(36) + Math.random().toString(36).substring(2, 15);
|
||||||
await showSuccess('添加成功');
|
const uploader = new BatchUploader({
|
||||||
|
dataList: features,
|
||||||
|
chunkSize: 15000,
|
||||||
|
delay: 200,
|
||||||
|
uploadFunc: async (chunk, batchNum, totalBatch) => {
|
||||||
|
await addProjectPilePoint({
|
||||||
|
projectId: props.projectId,
|
||||||
|
locationGeoJson: {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: chunk
|
||||||
|
},
|
||||||
|
sessionId,
|
||||||
|
totalBatch,
|
||||||
|
batchNum
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onComplete: () => {
|
||||||
|
showSuccess('桩点上传完成');
|
||||||
|
reset();
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await uploader.start();
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFacilities = async () => {
|
const addFacilities = async () => {
|
||||||
@ -512,21 +475,6 @@ const reset = () => {
|
|||||||
}
|
}
|
||||||
layerType.value = null;
|
layerType.value = null;
|
||||||
};
|
};
|
||||||
//校验
|
|
||||||
function checkOptions(arr, type) {
|
|
||||||
let hasName = false;
|
|
||||||
let hasJson = false;
|
|
||||||
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
if (arr[i].option === '名称') {
|
|
||||||
hasName = true;
|
|
||||||
} else if (arr[i].option === type) {
|
|
||||||
hasJson = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasName && hasJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.designId,
|
() => props.designId,
|
||||||
|
73
src/utils/batchUpload.ts
Normal file
73
src/utils/batchUpload.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// 文件路径:utils/BatchUploader.ts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BatchUploader 批量上传工具类
|
||||||
|
* 用于将大量数据分批发送到后端,避免单次请求数据过大导致失败。
|
||||||
|
* 支持设置每批数据大小、批次间延迟、上传函数和完成回调。
|
||||||
|
*/
|
||||||
|
export class BatchUploader<T> {
|
||||||
|
private dataList: T[]; // 需要上传的数据列表
|
||||||
|
private chunkSize: number; // 每批上传的条数
|
||||||
|
private delay: number; // 每批上传之间的延迟时间(单位:毫秒)
|
||||||
|
private uploadFunc: (chunk: T[], batchIndex: number, totalBatches: number) => Promise<void>; // 每一批次的上传函数
|
||||||
|
private onComplete?: () => void; // 所有批次完成后的回调函数(可选)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,初始化批量上传器
|
||||||
|
* @param options 配置参数
|
||||||
|
*/
|
||||||
|
constructor(options: {
|
||||||
|
dataList: T[]; // 待上传的数据
|
||||||
|
chunkSize?: number; // 每批数据大小(默认 8000)
|
||||||
|
delay?: number; // 每批之间的延迟(默认 200ms)
|
||||||
|
uploadFunc: (chunk: T[], batchIndex: number, totalBatches: number) => Promise<void>; // 上传逻辑函数
|
||||||
|
onComplete?: () => void; // 所有批次完成后的回调函数(可选)
|
||||||
|
}) {
|
||||||
|
const { dataList, chunkSize = 8000, delay = 200, uploadFunc, onComplete } = options;
|
||||||
|
this.dataList = dataList;
|
||||||
|
this.chunkSize = chunkSize;
|
||||||
|
this.delay = delay;
|
||||||
|
this.uploadFunc = uploadFunc;
|
||||||
|
this.onComplete = onComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动批量上传任务
|
||||||
|
*/
|
||||||
|
public async start() {
|
||||||
|
const total = Math.ceil(this.dataList.length / this.chunkSize); // 计算总批次数
|
||||||
|
|
||||||
|
// 循环执行每一批上传任务
|
||||||
|
for (let i = 0; i < total; i++) {
|
||||||
|
// 截取当前批次的数据
|
||||||
|
const chunk = this.dataList.slice(i * this.chunkSize, (i + 1) * this.chunkSize);
|
||||||
|
|
||||||
|
// 调用传入的上传函数处理该批次数据
|
||||||
|
await this.uploadFunc(chunk, i + 1, total);
|
||||||
|
|
||||||
|
// 如果不是最后一批,添加延迟
|
||||||
|
if (this.delay > 0 && i + 1 < total) {
|
||||||
|
await new Promise((res) => setTimeout(res, this.delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所有批次上传完成后,执行完成回调(如果有的话)
|
||||||
|
this.onComplete?.();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//使用示例
|
||||||
|
// const uploader = new BatchUploader({
|
||||||
|
// dataList: features,
|
||||||
|
// chunkSize: 15000,
|
||||||
|
// delay: 200,
|
||||||
|
// uploadFunc: async (chunk, batchNum, totalBatch) => {
|
||||||
|
// await addProjectPilePoint();//异步方法
|
||||||
|
// },
|
||||||
|
// onComplete: () => {
|
||||||
|
// console.log('桩点上传完成');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await uploader.start();
|
@ -210,6 +210,7 @@ const clickOpen = (row: any) => {
|
|||||||
expandRowKeys.value = [...new Set(expandRowKeys.value)];
|
expandRowKeys.value = [...new Set(expandRowKeys.value)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defineExpose({ openDialog });
|
||||||
const emit = defineEmits(['getProgressList']);
|
const emit = defineEmits(['getProgressList']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -66,16 +66,20 @@
|
|||||||
<el-table-column label="总量" align="center" prop="total" width="100" />
|
<el-table-column label="总量" align="center" prop="total" width="100" />
|
||||||
<el-table-column label="总进度" align="center" prop="projectId">
|
<el-table-column label="总进度" align="center" prop="projectId">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.total" status="success" />
|
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
|
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
|
||||||
<el-table-column label="计划中" align="center" prop="projectId">
|
<el-table-column label="计划中" align="center" prop="projectId">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.planTotal" />
|
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.planTotalPercentage" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="对比" align="center" prop="unitType" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.completed + '/' + row.total }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="对比" align="center" prop="unitType" width="100" />
|
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@ -103,7 +107,7 @@
|
|||||||
icon="Plus"
|
icon="Plus"
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="openDialog(scope.row, 'planStatus', scope.row.name + '计划创建')"
|
@click="planRef.openDialog(scope.row)"
|
||||||
v-hasPermi="['progress:progressCategory:add']"
|
v-hasPermi="['progress:progressCategory:add']"
|
||||||
>
|
>
|
||||||
计划
|
计划
|
||||||
@ -113,7 +117,7 @@
|
|||||||
icon="Plus"
|
icon="Plus"
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="openDialog(scope.row, 'dailyStatus', scope.row.name + '日报填写')"
|
@click="dailyRef.openDialog(scope.row)"
|
||||||
v-hasPermi="['progress:progressCategory:add']"
|
v-hasPermi="['progress:progressCategory:add']"
|
||||||
>
|
>
|
||||||
日报
|
日报
|
||||||
@ -132,7 +136,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="总进度" align="center" prop="projectId">
|
<el-table-column label="总进度" align="center" prop="projectId">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.total" status="success" />
|
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -143,17 +147,17 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel('importDataStatus')">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 导入表格对话框 -->
|
<!-- 导入表格对话框 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.importTableStatus" width="800px" append-to-body>
|
<el-dialog :title="dialog.title" v-model="dialog.importTableStatus" width="500px" append-to-body>
|
||||||
<file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50" :file-type="['xls', 'xlsx']" />
|
<file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50" :file-type="['xls', 'xlsx']" />
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel('importTableStatus')">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -274,9 +278,9 @@ const getTreeselect = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
const cancel = () => {
|
const cancel = (visible) => {
|
||||||
reset();
|
reset();
|
||||||
dialog.visible = false;
|
dialog[visible] = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表单重置
|
// 表单重置
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
// 允许默认导入
|
// 允许默认导入
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"forceConsistentCasingInFileNames": true
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "."
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts", "vite.config.ts"],
|
"include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts", "vite.config.ts"],
|
||||||
"exclude": ["node_modules", "dist", "**/*.js", "**/*.md", "src/**/*.md"]
|
"exclude": ["node_modules", "dist", "**/*.js", "**/*.md", "src/**/*.md"]
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user