Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
e8d2ca6f33
|
@ -12,7 +12,7 @@
|
|||
<ms-recent-list :options="projectRecent"/>
|
||||
<el-divider class="menu-divider"/>
|
||||
<ms-show-all :index="'/api/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/api/project/create'"
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/api/project/create'"
|
||||
:title="$t('project.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
<ms-recent-list :options="testRecent"/>
|
||||
<el-divider class="menu-divider"/>
|
||||
<ms-show-all :index="'/api/test/list/all'"/>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/api/test/create'"
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/api/test/create'"
|
||||
:title="$t('load_test.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-row type="flex" justify="center">
|
||||
<ms-create-test :show="isCurrentWorkspaceUser" :to="'/api/test/create'"/>
|
||||
<ms-create-test v-if="isTestManagerOrTestUser" :to="'/api/test/create'"/>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="8"/>
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
<script>
|
||||
|
||||
import {checkoutCurrentWorkspace} from "../../../../common/js/utils";
|
||||
import {checkoutCurrentWorkspace, checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||
import MsRecentList from "../../common/head/RecentList";
|
||||
import MsShowAll from "../../common/head/ShowAll";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
|
@ -58,6 +58,7 @@
|
|||
data() {
|
||||
return {
|
||||
isCurrentWorkspaceUser: false,
|
||||
isTestManagerOrTestUser: false,
|
||||
projectRecent: {
|
||||
title: this.$t('project.recent'),
|
||||
url: "/project/recent/5",
|
||||
|
@ -90,6 +91,7 @@
|
|||
},
|
||||
mounted() {
|
||||
this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
|
||||
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
</template>
|
||||
<el-table :data="tableData" class="table-content" @row-click="link">
|
||||
<el-table-column prop="name" :label="$t('commons.name')" width="150" show-overflow-tooltip/>
|
||||
<el-table-column width="200" :label="$t('commons.create_time')">
|
||||
<el-table-column width="250" :label="$t('commons.create_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200" :label="$t('commons.update_time')">
|
||||
<el-table-column width="250" :label="$t('commons.update_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" prop="status" :label="$t('commons.status')">
|
||||
<el-table-column prop="status" :label="$t('commons.status')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-api-report-status :row="row"/>
|
||||
</template>
|
||||
|
|
|
@ -29,10 +29,8 @@
|
|||
</el-table-column>
|
||||
<el-table-column width="150" :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button :is-tester-permission="true" @click="handleView(scope.row)" type="primary"
|
||||
icon="el-icon-s-data" size="mini" circle/>
|
||||
<el-button :is-tester-permission="true" @click="handleDelete(scope.row)" type="danger"
|
||||
icon="el-icon-delete" size="mini" circle/>
|
||||
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data" @exec="handleView(scope.row)" type="primary"/>
|
||||
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')" icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -50,9 +48,12 @@
|
|||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import MsApiReportStatus from "./ApiReportStatus";
|
||||
import {_filter, _sort} from "../../../../common/js/utils";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
|
||||
export default {
|
||||
components: {MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination},
|
||||
components: {
|
||||
MsTableOperatorButton,
|
||||
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {hasRoles} from "../../../../common/js/utils";
|
||||
import {checkoutTestManagerOrTestUser, hasRoles} from "../../../../common/js/utils";
|
||||
import {ROLE_TEST_MANAGER, ROLE_TEST_USER} from "../../../../common/js/constants";
|
||||
|
||||
export default {
|
||||
|
@ -39,7 +39,7 @@
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.isTesterPermission &&!hasRoles(ROLE_TEST_USER, ROLE_TEST_MANAGER)) {
|
||||
if (this.isTesterPermission && !checkoutTestManagerOrTestUser()) {
|
||||
this.disabled = true;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<script>
|
||||
import MsTableButton from "./MsTableButton";
|
||||
import MsTipButton from "./MsTipButton";
|
||||
import {hasRoles} from "../../../../common/js/utils";
|
||||
import {checkoutTestManagerOrTestUser, hasRoles} from "../../../../common/js/utils";
|
||||
import {ROLE_TEST_MANAGER, ROLE_TEST_USER} from "../../../../common/js/constants";
|
||||
export default {
|
||||
name: "MsTableOperatorButton",
|
||||
|
@ -43,7 +43,7 @@
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.isTesterPermission && !hasRoles(ROLE_TEST_USER, ROLE_TEST_MANAGER)) {
|
||||
if (this.isTesterPermission && !checkoutTestManagerOrTestUser()) {
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<ms-recent-list :options="projectRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/performance/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/performance/project/create'" :title="$t('project.create')"/>
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/performance/project/create'" :title="$t('project.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser"
|
||||
|
@ -22,7 +22,7 @@
|
|||
<ms-recent-list :options="testRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/performance/test/all'"/>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/performance/test/create'" :title="$t('load_test.create')"/>
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/performance/test/create'" :title="$t('load_test.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser"
|
||||
|
@ -36,7 +36,7 @@
|
|||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-row type="flex" justify="center">
|
||||
<ms-create-test :show="isCurrentWorkspaceUser" :to="'/performance/test/create'"/>
|
||||
<ms-create-test v-if="isTestManagerOrTestUser" :to="'/performance/test/create'"/>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="8"/>
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
<script>
|
||||
|
||||
import {checkoutCurrentWorkspace} from "../../../../common/js/utils";
|
||||
import {checkoutCurrentWorkspace, checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||
import MsCreateTest from "../../common/head/CreateTest";
|
||||
import MsRecentList from "../../common/head/RecentList";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
|
@ -63,6 +63,7 @@
|
|||
data() {
|
||||
return {
|
||||
isCurrentWorkspaceUser: false,
|
||||
isTestManagerOrTestUser: false,
|
||||
projectRecent: {
|
||||
title: this.$t('project.recent'),
|
||||
url: "/project/recent/5",
|
||||
|
@ -96,6 +97,7 @@
|
|||
},
|
||||
mounted() {
|
||||
this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
|
||||
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
</template>
|
||||
<el-table :data="tableData" class="table-content" @row-click="link">
|
||||
<el-table-column prop="name" :label="$t('commons.name')" width="150" show-overflow-tooltip/>
|
||||
<el-table-column width="200" :label="$t('commons.create_time')">
|
||||
<el-table-column width="250" :label="$t('commons.create_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200" :label="$t('commons.update_time')">
|
||||
<el-table-column width="250" :label="$t('commons.update_time')">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" prop="status" :label="$t('commons.status')">
|
||||
<el-table-column prop="status" :label="$t('commons.status')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-performance-report-status :row="row"/>
|
||||
</template>
|
||||
|
|
|
@ -53,15 +53,6 @@
|
|||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column-->
|
||||
<!-- prop="updateTime"-->
|
||||
<!-- sortable-->
|
||||
<!-- width="250"-->
|
||||
<!-- :label="$t('commons.update_time')">-->
|
||||
<!-- <template v-slot:default="scope">-->
|
||||
<!-- <span>{{ scope.row.updateTime | timestampFormatDate }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column
|
||||
prop="status"
|
||||
column-key="status"
|
||||
|
@ -75,8 +66,8 @@
|
|||
width="150"
|
||||
:label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button :is-tester-permission="true" @click="handleEdit(scope.row)" type="primary" icon="el-icon-s-data" size="mini" circle/>
|
||||
<el-button :is-tester-permission="true" @click="handleDelete(scope.row)" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data" @exec="handleEdit(scope.row)" type="primary"/>
|
||||
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')" icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -93,10 +84,11 @@
|
|||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import MsPerformanceReportStatus from "./PerformanceReportStatus";
|
||||
import {_filter, _sort} from "../../../../common/js/utils";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
|
||||
export default {
|
||||
name: "PerformanceTestReport",
|
||||
components: {MsPerformanceReportStatus, MsTablePagination, MsContainer, MsMainContainer},
|
||||
components: {MsTableOperatorButton, MsPerformanceReportStatus, MsTablePagination, MsContainer, MsMainContainer},
|
||||
created: function () {
|
||||
this.initTableData();
|
||||
},
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<span class="node-title">{{node.label}}</span>
|
||||
|
||||
<span v-if="type == 'edit'" class="node-operate child" v-permission="['test_manager', 'test_user']">
|
||||
<span v-if="type == 'edit' && !disabled" class="node-operate child">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
|
@ -56,7 +56,7 @@
|
|||
<script>
|
||||
import NodeEdit from "./NodeEdit";
|
||||
import {ROLE_TEST_MANAGER, ROLE_TEST_USER} from "../../../../common/js/constants";
|
||||
import {hasRoles} from "../../../../common/js/utils";
|
||||
import {checkoutTestManagerOrTestUser, hasRoles} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "NodeTree",
|
||||
|
@ -97,7 +97,7 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
if (!hasRoles(ROLE_TEST_USER, ROLE_TEST_MANAGER)) {
|
||||
if (!checkoutTestManagerOrTestUser()) {
|
||||
this.disabled = true;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<ms-recent-list :options="projectRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/track/project/all'"/>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/track/project/create'" :title="$t('project.create')"/>
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/track/project/create'" :title="$t('project.create')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser"
|
||||
|
@ -23,7 +23,7 @@
|
|||
<el-divider/>
|
||||
<ms-show-all :index="'/track/case/all'"/>
|
||||
<el-menu-item :index="testCaseEditPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/track/case/create'" :title="$t('test_track.case.create_case')"/>
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/track/case/create'" :title="$t('test_track.case.create_case')"/>
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser" index="7" popper-class="submenu">
|
||||
|
@ -32,7 +32,7 @@
|
|||
<el-divider/>
|
||||
<ms-show-all :index="'/track/plan/all'"/>
|
||||
<el-menu-item :index="testPlanViewPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager', 'test_user']" :index="'/track/plan/create'" :title="$t('test_track.plan.create_plan')"/>
|
||||
<ms-create-button v-if="isTestManagerOrTestUser" :index="'/track/plan/create'" :title="$t('test_track.plan.create_plan')"/>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
|
@ -43,7 +43,7 @@
|
|||
</template>
|
||||
<script>
|
||||
|
||||
import {checkoutCurrentWorkspace} from "../../../../common/js/utils";
|
||||
import {checkoutCurrentWorkspace, checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||
import MsShowAll from "../../common/head/ShowAll";
|
||||
import MsRecentList from "../../common/head/RecentList";
|
||||
import MsCreateButton from "../../common/head/CreateButton";
|
||||
|
@ -54,6 +54,7 @@
|
|||
data() {
|
||||
return {
|
||||
isCurrentWorkspaceUser: false,
|
||||
isTestManagerOrTestUser: false,
|
||||
testPlanViewPath: '',
|
||||
isRouterAlive: true,
|
||||
testCaseEditPath: '',
|
||||
|
@ -100,6 +101,7 @@
|
|||
},
|
||||
mounted() {
|
||||
this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
|
||||
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" class="head-right">
|
||||
<el-button v-permission="['test_manager', 'test_user']" plain size="mini" @click="handleSave">{{$t('commons.save')}}</el-button>
|
||||
<el-button v-permission="['test_manager', 'test_user']" plain size="mini" @click="handleEdit">{{$t('test_track.plan_view.edit_component')}}</el-button>
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleSave">{{$t('commons.save')}}</el-button>
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleEdit">{{$t('test_track.plan_view.edit_component')}}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {jsonToMap, mapToJson} from "../../../../../../../common/js/utils";
|
||||
import {checkoutTestManagerOrTestUser, jsonToMap, mapToJson} from "../../../../../../../common/js/utils";
|
||||
import BaseInfoComponent from "./TemplateComponent/BaseInfoComponent";
|
||||
import TestResultChartComponent from "./TemplateComponent/TestResultChartComponent";
|
||||
import TestResultComponent from "./TemplateComponent/TestResultComponent";
|
||||
|
@ -70,9 +70,13 @@
|
|||
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
|
||||
[4, { name: this.$t('test_track.plan_view.custom_component'), id: 4 ,type: 'custom'}]
|
||||
]
|
||||
)
|
||||
),
|
||||
isTestManagerOrTestUser: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||
},
|
||||
methods: {
|
||||
listenGoBack() {
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
REFRESH_SESSION_USER_URL,
|
||||
ROLE_ORG_ADMIN,
|
||||
ROLE_ADMIN,
|
||||
ROLE_TEST_MANAGER,
|
||||
ROLE_TEST_USER,
|
||||
ROLE_TEST_VIEWER,
|
||||
|
@ -14,6 +15,7 @@ export function hasRole(role) {
|
|||
return roles.indexOf(role) > -1;
|
||||
}
|
||||
|
||||
// 是否含有某个角色
|
||||
export function hasRoles(...roles) {
|
||||
let user = getCurrentUser();
|
||||
let rs = user.roles.map(r => r.id);
|
||||
|
@ -25,21 +27,44 @@ export function hasRoles(...roles) {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function checkoutCurrentOrganization() {
|
||||
export function hasRolePermission(role) {
|
||||
let user = getCurrentUser();
|
||||
for (let ur of user.userRoles) {
|
||||
if (role === ur.roleId) {
|
||||
if (ur.roleId === ROLE_ADMIN) {
|
||||
return true;
|
||||
} else if (ur.roleId === ROLE_ORG_ADMIN && user.lastOrganizationId === ur.sourceId) {
|
||||
return true;
|
||||
} else if (user.lastWorkspaceId === ur.sourceId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//是否含有对应组织或工作空间的角色
|
||||
export function hasRolePermissions(...roles) {
|
||||
for (let role of roles) {
|
||||
if (hasRolePermission(role)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function checkoutCurrentOrganization() {
|
||||
// 查看当前用户是否是 lastOrganizationId 的组织管理员
|
||||
return user.userRoles.filter(ur => hasRole(ROLE_ORG_ADMIN) && user.lastOrganizationId === ur.sourceId).length > 0;
|
||||
return hasRolePermissions(ROLE_ORG_ADMIN);
|
||||
}
|
||||
|
||||
export function checkoutCurrentWorkspace() {
|
||||
let user = getCurrentUser();
|
||||
// 查看当前用户是否是 lastWorkspaceId 的工作空间用户
|
||||
return user.userRoles.filter(ur => hasRoles(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER) && user.lastWorkspaceId === ur.sourceId).length > 0;
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER);
|
||||
}
|
||||
|
||||
export function checkoutTestManagerOrTestUser() {
|
||||
let user = getCurrentUser();
|
||||
return user.userRoles.filter(ur => hasRoles(ROLE_TEST_MANAGER, ROLE_TEST_USER) && user.lastWorkspaceId === ur.sourceId).length > 0;
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER);
|
||||
}
|
||||
|
||||
export function getCurrentOrganizationId() {
|
||||
|
|
|
@ -364,7 +364,9 @@ export default {
|
|||
total: "Total",
|
||||
test_name: "Test",
|
||||
request_result: "Result",
|
||||
sub_result: "Sub Result"
|
||||
sub_result: "Sub Result",
|
||||
detail: "Report detail",
|
||||
delete: "Delete report",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "Track",
|
||||
|
|
|
@ -363,7 +363,9 @@ export default {
|
|||
total: "全部",
|
||||
test_name: "所属测试",
|
||||
request_result: "请求结果",
|
||||
sub_result: "子请求"
|
||||
sub_result: "子请求",
|
||||
detail: "报告详情",
|
||||
delete: "删除报告",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "测试跟踪",
|
||||
|
|
|
@ -362,7 +362,9 @@ export default {
|
|||
total: "全部",
|
||||
test_name: "所屬測試",
|
||||
request_result: "請求結果",
|
||||
sub_result: "子請求"
|
||||
sub_result: "子請求",
|
||||
detail: "報告詳情",
|
||||
delete: "刪除報告",
|
||||
},
|
||||
test_track: {
|
||||
test_track: "測試跟踪",
|
||||
|
|
Loading…
Reference in New Issue