diff --git a/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java b/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java index 53565685b2..ce7ef459dc 100644 --- a/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java +++ b/backend/src/main/java/io/metersphere/api/service/ShareInfoService.java @@ -5,11 +5,15 @@ import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.share.*; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ShareInfo; +import io.metersphere.base.domain.TestPlanApiCase; +import io.metersphere.base.domain.TestPlanApiScenario; import io.metersphere.base.mapper.ShareInfoMapper; import io.metersphere.base.mapper.ext.ExtShareInfoMapper; +import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.SessionUtils; -import io.metersphere.service.SystemParameterService; +import io.metersphere.track.service.TestPlanApiCaseService; +import io.metersphere.track.service.TestPlanScenarioCaseService; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,7 +35,9 @@ public class ShareInfoService { @Resource ShareInfoMapper shareInfoMapper; @Resource - SystemParameterService systemParameterService; + TestPlanApiCaseService testPlanApiCaseService; + @Resource + TestPlanScenarioCaseService testPlanScenarioCaseService; public List findApiDocumentSimpleInfoByRequest(ApiDocumentRequest request) { if (this.isParamLegitimacy(request)) { @@ -440,4 +446,33 @@ public class ShareInfoService { public ShareInfo get(String id) { return shareInfoMapper.selectByPrimaryKey(id); } + + public void validate(String shareId, String customData) { + ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(shareId); + if (shareInfo == null) { + MSException.throwException("shareInfo not exist!"); + } else { + if (!StringUtils.equals(customData, shareInfo.getCustomData())) { + MSException.throwException("validate failure!"); + } + } + } + + public void apiReportValidate(String shareId, String testId) { + ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(shareId); + String planId = shareInfo.getCustomData(); + TestPlanApiCase testPlanApiCase = testPlanApiCaseService.getById(testId); + if (!StringUtils.equals(planId, testPlanApiCase.getTestPlanId())) { + MSException.throwException("validate failure!"); + } + } + + public void scenarioReportValidate(String shareId, String reportId) { + ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(shareId); + String planId = shareInfo.getCustomData(); + TestPlanApiScenario testPlanApiScenario = testPlanScenarioCaseService.selectByReportId(reportId); + if (!StringUtils.equals(planId, testPlanApiScenario.getTestPlanId())) { + MSException.throwException("validate failure!"); + } + } } diff --git a/backend/src/main/java/io/metersphere/controller/ShareController.java b/backend/src/main/java/io/metersphere/controller/ShareController.java index 6dd654ec81..0431b65ea8 100644 --- a/backend/src/main/java/io/metersphere/controller/ShareController.java +++ b/backend/src/main/java/io/metersphere/controller/ShareController.java @@ -6,23 +6,20 @@ import io.metersphere.api.dto.automation.TestPlanFailureApiDTO; import io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO; import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.ApiScenarioReportService; +import io.metersphere.api.service.ShareInfoService; import io.metersphere.base.domain.IssuesDao; import io.metersphere.track.dto.TestPlanCaseDTO; import io.metersphere.track.dto.TestPlanLoadCaseDTO; import io.metersphere.track.dto.TestPlanSimpleReportDTO; import io.metersphere.track.service.*; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.util.List; -@Controller +@RestController @RequestMapping("share") public class ShareController { @@ -42,60 +39,60 @@ public class ShareController { TestPlanLoadCaseService testPlanLoadCaseService; @Resource IssuesService issuesService; + @Resource + ShareInfoService shareInfoService; - // Todo 鉴权 - - @ResponseBody - @GetMapping("/issues/plan/get/{planId}") - public List getIssuesByPlanoId(@PathVariable String planId) { + @GetMapping("/issues/plan/get/{shareId}/{planId}") + public List getIssuesByPlanoId(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return issuesService.getIssuesByPlanoId(planId); } - @ResponseBody - @GetMapping("/test/plan/report/{planId}") - public TestPlanSimpleReportDTO getReport(@PathVariable String planId) { + @GetMapping("/test/plan/report/{shareId}/{planId}") + public TestPlanSimpleReportDTO getReport(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return testPlanService.getReport(planId); } - @ResponseBody - @GetMapping("/report/export/{planId}") - public void exportHtmlReport(@PathVariable String planId, HttpServletResponse response) throws UnsupportedEncodingException { + @GetMapping("/report/export/{shareId}/{planId}") + public void exportHtmlReport(@PathVariable String shareId, @PathVariable String planId, HttpServletResponse response) throws UnsupportedEncodingException { + shareInfoService.validate(shareId, planId); testPlanService.exportPlanReport(planId, response); } - @ResponseBody - @GetMapping("/test/plan/case/list/failure/{planId}") - public List getFailureCases(@PathVariable String planId) { + @GetMapping("/test/plan/case/list/failure/{shareId}/{planId}") + public List getFailureCases(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return testPlanTestCaseService.getFailureCases(planId); } - @ResponseBody - @GetMapping("/test/plan/load/case/list/failure/{planId}") - public List getLoadFailureCases(@PathVariable String planId) { + @GetMapping("/test/plan/load/case/list/failure/{shareId}/{planId}") + public List getLoadFailureCases(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return testPlanLoadCaseService.getFailureCases(planId); } - @ResponseBody - @GetMapping("/test/plan/api/case/list/failure/{planId}") - public List getApiFailureList(@PathVariable String planId) { + @GetMapping("/test/plan/api/case/list/failure/{shareId}/{planId}") + public List getApiFailureList(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return testPlanApiCaseService.getFailureList(planId); } - @ResponseBody - @GetMapping("/test/plan/scenario/case/list/failure/{planId}") - public List getScenarioFailureList(@PathVariable String planId) { + @GetMapping("/test/plan/scenario/case/list/failure/{shareId}/{planId}") + public List getScenarioFailureList(@PathVariable String shareId, @PathVariable String planId) { + shareInfoService.validate(shareId, planId); return testPlanScenarioCaseService.getFailureList(planId); } - @ResponseBody - @GetMapping("/api/definition/report/getReport/{testId}") - public APIReportResult getApiReport(@PathVariable String testId) { + @GetMapping("/api/definition/report/getReport/{shareId}/{testId}") + public APIReportResult getApiReport(@PathVariable String shareId, @PathVariable String testId) { + shareInfoService.apiReportValidate(shareId, testId); return apiDefinitionService.getDbResult(testId); } - @ResponseBody - @GetMapping("/api/scenario/report/get/{reportId}") - public APIScenarioReportResult get(@PathVariable String reportId) { + @GetMapping("/api/scenario/report/get/{shareId}/{reportId}") + public APIScenarioReportResult get(@PathVariable String shareId, @PathVariable String reportId) { + shareInfoService.scenarioReportValidate(shareId, reportId); return apiScenarioReportService.get(reportId); } } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java index 517e1f3c80..7cc3ddc57b 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java @@ -441,4 +441,14 @@ public class TestPlanScenarioCaseService { buildUserInfo(apiTestCases); return apiTestCases; } + + public TestPlanApiScenario selectByReportId(String reportId) { + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria().andReportIdEqualTo(reportId); + List testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(testPlanApiScenarios)) { + return testPlanApiScenarios.get(0); + } + return null; + } } diff --git a/backend/src/main/resources/db/migration/V93__v1.12_release.sql b/backend/src/main/resources/db/migration/V93__v1.12_release.sql index 7b447f65b4..df96b89fa7 100644 --- a/backend/src/main/resources/db/migration/V93__v1.12_release.sql +++ b/backend/src/main/resources/db/migration/V93__v1.12_release.sql @@ -92,5 +92,5 @@ ALTER TABLE `api_scenario_report` ADD `end_time` bigint(13) ; -- 修改文档分享表 ALTER TABLE api_document_share RENAME TO share_info; ALTER TABLE share_info change - column share_api_id custom_data longtextCHARACTER + column share_api_id custom_data longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Share Custom Data'; diff --git a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue index f30d089202..6798e0068d 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue @@ -79,7 +79,8 @@ export default { debug: Boolean, isTemplate: Boolean, templateReport: Object, - isShare: Boolean + isShare: Boolean, + shareId: String }, watch: { reportId() { @@ -241,7 +242,7 @@ export default { this.report = this.templateReport; this.buildReport(); } else if (this.isShare) { - getShareScenarioReport(this.reportId, (data) => { + getShareScenarioReport(this.shareId, this.reportId, (data) => { this.report = data || {}; this.buildReport(); }); diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanApiReport.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanApiReport.vue index 5f42581230..f8b051f4a1 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanApiReport.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanApiReport.vue @@ -5,7 +5,7 @@ - + @@ -28,7 +28,7 @@ export default { }; }, props: [ - 'report', 'planId', 'isTemplate', 'isShare' + 'report', 'planId', 'isTemplate', 'isShare', 'shareId' ], methods: { handleClick(tab, event) { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanFunctionalReport.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanFunctionalReport.vue index 6fd28fde68..00be7ced5b 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanFunctionalReport.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanFunctionalReport.vue @@ -5,10 +5,10 @@ - + - + @@ -33,7 +33,7 @@ export default { }; }, props: [ - 'report','planId', 'isTemplate', 'isShare' + 'report','planId', 'isTemplate', 'isShare', 'shareId' ], methods: { handleClick(tab, event) { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanLoadReport.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanLoadReport.vue index 056bbba682..45a501f828 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanLoadReport.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanLoadReport.vue @@ -5,7 +5,7 @@ - + @@ -35,7 +35,8 @@ export default { 'report', 'planId', 'isTemplate', - 'isShare' + 'isShare', + 'shareId' ], methods: { handleClick(tab, event) { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanReportContent.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanReportContent.vue index c3fbe6724c..85b5d8bf4a 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanReportContent.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/TestPlanReportContent.vue @@ -5,18 +5,6 @@
- - - - - - - - - - - - @@ -32,9 +20,9 @@
- - - + + + @@ -97,7 +85,7 @@ export default { if (this.isTemplate) { this.report = "#report"; } else if (this.isShare) { - this.result = getShareTestPlanReport(this.planId, (data) => { + this.result = getShareTestPlanReport(this.shareId, this.planId, (data) => { this.report = data; }); } else { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiCaseFailureResult.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiCaseFailureResult.vue index b79db5f46f..d1761135cf 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiCaseFailureResult.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiCaseFailureResult.vue @@ -72,7 +72,8 @@ export default { planId: String, isTemplate: Boolean, report: Object, - isShare: Boolean + isShare: Boolean, + shareId: String }, data() { return { @@ -92,7 +93,7 @@ export default { this.rowClick(this.apiCases[0]); } } else if (this.isShare) { - this.result = getSharePlanApiFailureCase(this.planId, (data) => { + this.result = getSharePlanApiFailureCase(this.shareId, this.planId, (data) => { this.apiCases = data; if (data && data.length > 0) { this.rowClick(data[0]); @@ -111,7 +112,7 @@ export default { if (this.isTemplate) { this.response = JSON.parse(row.response); } else if (this.isShare) { - getShareApiReport(row.id, (data) => { + getShareApiReport(this.shareId, row.id, (data) => { this.response = JSON.parse(data.content); }); } else { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiFailureResult.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiFailureResult.vue index 5234796d22..7e898c0da4 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiFailureResult.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiFailureResult.vue @@ -2,10 +2,10 @@
- + - +
@@ -29,7 +29,8 @@ export default { planId: String, isTemplate: Boolean, isShare: Boolean, - report: {} + report: {}, + shareId: String }, data() { return { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiScenarioFailureResult.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiScenarioFailureResult.vue index c6287fb159..5165ad07af 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiScenarioFailureResult.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/ApiScenarioFailureResult.vue @@ -45,7 +45,7 @@ - + @@ -69,7 +69,8 @@ export default { planId: String, isTemplate: Boolean, report: Object, - isShare: Boolean + isShare: Boolean, + shareId: String }, data() { return { @@ -90,7 +91,7 @@ export default { this.rowClick(this.scenarioCases[0]); } } else if (this.isShare) { - this.result = getSharePlanScenarioFailureCase(this.planId, (data) => { + this.result = getSharePlanScenarioFailureCase(this.shareId, this.planId, (data) => { this.scenarioCases = data; if (data && data.length > 0) { this.reportId = data[0].reportId; diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalFailureResult.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalFailureResult.vue index 42a543fb7b..8c2d141f46 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalFailureResult.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalFailureResult.vue @@ -77,7 +77,8 @@ export default { planId: String, isTemplate: Boolean, isShare: Boolean, - report: {} + report: {}, + shareId: String }, data() { return { @@ -92,7 +93,7 @@ export default { if (this.isTemplate) { this.failureTestCases = this.report.failureTestCases; } else if (this.isShare) { - getSharePlanFunctionFailureCase(this.planId, (data) => { + getSharePlanFunctionFailureCase(this.shareId, this.planId, (data) => { this.failureTestCases = data; }); } else { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalIssueList.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalIssueList.vue index 80d9c7b87f..8ac8987ddc 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalIssueList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/FunctionalIssueList.vue @@ -67,7 +67,7 @@ export default { isThirdPart: false } }, - props: ['planId', 'isTemplate', 'report', 'isShare'], + props: ['planId', 'isTemplate', 'report', 'isShare', 'shareId'], computed: { issueStatusMap() { return ISSUE_STATUS_MAP; @@ -82,7 +82,7 @@ export default { if (this.isTemplate) { this.data = this.report.issueList; } else if (this.isShare) { - this.result = getShareIssuesByPlanId(this.planId, (data) => { + this.result = getShareIssuesByPlanId(this.shareId, this.planId, (data) => { this.data = data; }); } else { diff --git a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/LoadFailureResult.vue b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/LoadFailureResult.vue index ad0f8b9807..dc0d1d735c 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/detail/component/LoadFailureResult.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/detail/component/LoadFailureResult.vue @@ -48,7 +48,8 @@ export default { planId: String, report: Object, isTemplate: Boolean, - isShare: Boolean + isShare: Boolean, + shareId: String }, data() { return { @@ -63,7 +64,7 @@ export default { if (this.isTemplate) { this.failureTestCases = this.report.loadFailureTestCases; } else if (this.isShare) { - getSharePlanLoadFailureCase(this.planId, (data) => { + getSharePlanLoadFailureCase(this.shareId, this.planId, (data) => { this.failureTestCases = data; }); } else { diff --git a/frontend/src/network/Issue.js b/frontend/src/network/Issue.js index d1b4cba7e3..d031dd5b0a 100644 --- a/frontend/src/network/Issue.js +++ b/frontend/src/network/Issue.js @@ -37,8 +37,8 @@ export function getIssuesByPlanId(planId, callback) { return planId ? baseGet('/issues/plan/get/' + planId, callback) : {}; } -export function getShareIssuesByPlanId(planId, callback) { - return planId ? baseGet('/share/issues/plan/get/' + planId, callback) : {}; +export function getShareIssuesByPlanId(shareId, planId, callback) { + return planId ? baseGet('/share/issues/plan/get/' + shareId + '/' + planId, callback) : {}; } export function buildPlatformIssue(data) { diff --git a/frontend/src/network/api.js b/frontend/src/network/api.js index f755ec244a..b51f3224dd 100644 --- a/frontend/src/network/api.js +++ b/frontend/src/network/api.js @@ -16,12 +16,12 @@ export function getApiReport(testId, callback) { return testId ? baseGet('/api/definition/report/getReport/' + testId, callback) : {}; } -export function getShareApiReport(testId, callback) { - return testId ? baseGet('/share/api/definition/report/getReport/' + testId, callback) : {}; +export function getShareApiReport(shareId, testId, callback) { + return testId ? baseGet('/share/api/definition/report/getReport/' + shareId + '/' + testId, callback) : {}; } -export function getShareScenarioReport(reportId, callback) { - return reportId ? baseGet('/share/api/scenario/report/get/' + reportId, callback) : {}; +export function getShareScenarioReport(shareId, reportId, callback) { + return reportId ? baseGet('/share/api/scenario/report/get/' + shareId + '/' + reportId, callback) : {}; } diff --git a/frontend/src/network/test-plan.js b/frontend/src/network/test-plan.js index effb93f19a..0b82b16688 100644 --- a/frontend/src/network/test-plan.js +++ b/frontend/src/network/test-plan.js @@ -13,9 +13,9 @@ export function getTestPlanReport(planId, callback) { } } -export function getShareTestPlanReport(planId, callback) { +export function getShareTestPlanReport(shareId, planId, callback) { if (planId) { - return get('/share/test/plan/report/' + planId, (response) => { + return get('/share/test/plan/report/' + shareId + '/' + planId, (response) => { if (callback) { callback(response.data); } @@ -33,30 +33,30 @@ export function getPlanFunctionFailureCase(planId, callback) { return planId ? baseGet('/test/plan/case/list/failure/' + planId, callback) : {}; } -export function getSharePlanFunctionFailureCase(planId, callback) { - return planId ? baseGet('/share/test/plan/case/list/failure/' + planId, callback) : {}; +export function getSharePlanFunctionFailureCase(shareId, planId, callback) { + return planId ? baseGet('/share/test/plan/case/list/failure/' + shareId + '/' + planId, callback) : {}; } export function getPlanScenarioFailureCase(planId, callback) { return planId ? baseGet('/test/plan/scenario/case/list/failure/' + planId, callback) : {}; } -export function getSharePlanScenarioFailureCase(planId, callback) { - return planId ? baseGet('/share/test/plan/scenario/case/list/failure/' + planId, callback) : {}; +export function getSharePlanScenarioFailureCase(shareId, planId, callback) { + return planId ? baseGet('/share/test/plan/scenario/case/list/failure/' + shareId + '/' + planId, callback) : {}; } export function getPlanApiFailureCase(planId, callback) { return planId ? baseGet('/test/plan/api/case/list/failure/' + planId, callback) : {}; } -export function getSharePlanApiFailureCase(planId, callback) { - return planId ? baseGet('/share/test/plan/api/case/list/failure/' + planId, callback) : {}; +export function getSharePlanApiFailureCase(shareId, planId, callback) { + return planId ? baseGet('/share/test/plan/api/case/list/failure/' + shareId + '/' + planId, callback) : {}; } export function getPlanLoadFailureCase(planId, callback) { return planId ? baseGet('/test/plan/load/case/list/failure/' + planId, callback) : {}; } -export function getSharePlanLoadFailureCase(planId, callback) { - return planId ? baseGet('/share/test/plan/load/case/list/failure/' + planId, callback) : {}; +export function getSharePlanLoadFailureCase(shareId, planId, callback) { + return planId ? baseGet('/share/test/plan/load/case/list/failure/' + shareId + '/' + planId, callback) : {}; } diff --git a/frontend/src/template/report/plan/share/SharePlanReportTemplate.vue b/frontend/src/template/report/plan/share/SharePlanReportTemplate.vue index 74196d4bdb..fc1a44cc5c 100644 --- a/frontend/src/template/report/plan/share/SharePlanReportTemplate.vue +++ b/frontend/src/template/report/plan/share/SharePlanReportTemplate.vue @@ -1,5 +1,5 @@