双击打开详情修复
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import { Ref, ref, watch, computed } from "vue"
|
||||
import { VueUiXyConfig, VueUiXyDatasetItem } from "vue-data-ui"
|
||||
|
||||
// 单个每月项目数量对象格式
|
||||
interface IData {
|
||||
mouth: string
|
||||
count: number
|
||||
}
|
||||
// 响应.data的数据格式
|
||||
interface ResData {
|
||||
data: IData[]
|
||||
}
|
||||
|
||||
function useVueDataUI(data: Ref<ResData>) {
|
||||
const initialData = [
|
||||
{
|
||||
name: "项目数量",
|
||||
series: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
type: "line",
|
||||
color: "rgb(95,139,238)",
|
||||
scaleSteps: 10,
|
||||
suffix: "个",
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
const chartData = computed<any[]>(() => {
|
||||
if (data.value) {
|
||||
const countData = data.value.data.map((it) => it.count)
|
||||
initialData[0].series = countData
|
||||
}
|
||||
return initialData
|
||||
})
|
||||
const initialConfig = {
|
||||
theme: "",
|
||||
responsive: false,
|
||||
customPalette: [],
|
||||
downsample: { threshold: 500 },
|
||||
chart: {
|
||||
fontFamily: "inherit",
|
||||
backgroundColor: "#FFFFFFff",
|
||||
color: "#1A1A1Aff",
|
||||
height: 300,
|
||||
width: 1200,
|
||||
padding: { top: 36, right: 24, bottom: 48, left: 48 },
|
||||
highlighter: { color: "#1A1A1Aff", opacity: 5, useLine: false, lineDasharray: 2, lineWidth: 1 },
|
||||
grid: {
|
||||
stroke: "#e1e5e8ff",
|
||||
showVerticalLines: false,
|
||||
showHorizontalLines: false,
|
||||
position: "middle",
|
||||
frame: {
|
||||
show: false,
|
||||
stroke: "#E1E5E8ff",
|
||||
strokeWidth: 2,
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
strokeDasharray: 0
|
||||
},
|
||||
labels: {
|
||||
show: true,
|
||||
color: "#1A1A1Aff",
|
||||
fontSize: 12,
|
||||
axis: { yLabel: "", yLabelOffsetX: 0, xLabel: "", xLabelOffsetY: 14, fontSize: 12 },
|
||||
zeroLine: { show: true },
|
||||
xAxis: { showBaseline: true },
|
||||
yAxis: {
|
||||
showBaseline: true,
|
||||
commonScaleSteps: 1,
|
||||
useIndividualScale: false,
|
||||
stacked: false,
|
||||
gap: 12,
|
||||
labelWidth: 40,
|
||||
formatter: null,
|
||||
scaleMin: 0,
|
||||
scaleMax: 20
|
||||
},
|
||||
xAxisLabels: {
|
||||
color: "#1A1A1Aff",
|
||||
show: true,
|
||||
values: [
|
||||
"一月",
|
||||
"二月",
|
||||
"三月",
|
||||
"四月",
|
||||
"五月",
|
||||
"六月",
|
||||
"七月",
|
||||
"八月",
|
||||
"九月",
|
||||
"十月",
|
||||
"十一月",
|
||||
"十二月"
|
||||
],
|
||||
fontSize: 12,
|
||||
showOnlyFirstAndLast: false,
|
||||
showOnlyAtModulo: false,
|
||||
modulo: 12,
|
||||
yOffset: 8,
|
||||
rotation: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
comments: { show: true, showInTooltip: true, width: 200, offsetX: 0, offsetY: 0 },
|
||||
labels: { fontSize: 10, prefix: "", suffix: "" },
|
||||
legend: { color: "#1A1A1Aff", show: false, fontSize: 16 },
|
||||
title: {
|
||||
text: "项目每月统计",
|
||||
color: "#1A1A1Aff",
|
||||
fontSize: 18,
|
||||
bold: true,
|
||||
textAlign: "left",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
subtitle: { color: "#CCCCCCff", text: "", fontSize: 16, bold: false },
|
||||
show: true
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
color: "#1A1A1Aff",
|
||||
backgroundColor: "#FFFFFFff",
|
||||
fontSize: 14,
|
||||
customFormat: null,
|
||||
borderRadius: 4,
|
||||
borderColor: "#e1e5e8",
|
||||
borderWidth: 1,
|
||||
backgroundOpacity: 30,
|
||||
position: "center",
|
||||
offsetY: 24,
|
||||
showValue: true,
|
||||
showPercentage: false,
|
||||
roundingValue: 0,
|
||||
roundingPercentage: 0
|
||||
},
|
||||
userOptions: {
|
||||
show: true,
|
||||
position: "right",
|
||||
buttons: {
|
||||
tooltip: true,
|
||||
pdf: true,
|
||||
csv: true,
|
||||
img: true,
|
||||
table: false,
|
||||
labels: false,
|
||||
fullscreen: true,
|
||||
sort: false,
|
||||
stack: true,
|
||||
animation: false,
|
||||
annotator: false
|
||||
},
|
||||
buttonTitles: {
|
||||
open: "打开选项",
|
||||
close: "关闭选项",
|
||||
tooltip: "切换提示开关",
|
||||
pdf: "下载为PDF",
|
||||
csv: "下载为CSV",
|
||||
img: "下载为PNG",
|
||||
table: "表格显示/隐藏",
|
||||
labels: "标签显示/隐藏",
|
||||
fullscreen: "切换全屏",
|
||||
stack: "切换stack模式"
|
||||
}
|
||||
},
|
||||
zoom: { show: false }
|
||||
},
|
||||
showTable: false
|
||||
}
|
||||
const chartConfig = computed(() => {
|
||||
if (data.value) {
|
||||
const countData = data.value.data.map((it) => it.count)
|
||||
initialConfig.chart.grid.labels.yAxis.scaleMax = Math.max(...countData)
|
||||
}
|
||||
return initialConfig
|
||||
})
|
||||
return { chartData, chartConfig }
|
||||
}
|
||||
|
||||
export default useVueDataUI
|
||||
@@ -23,7 +23,7 @@
|
||||
</a>
|
||||
</a-card>
|
||||
<div class="mt-2">管理平台版本</div>
|
||||
<a-tag class="mt-2 w-fit" color="#0fc6c2">TestPlant V0.0.3</a-tag>
|
||||
<a-tag class="mt-2 w-fit" color="#0fc6c2">TestPlant V0.0.4</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,179 +1,31 @@
|
||||
<template>
|
||||
<div class="ma-content-block p-3 mt-3 bg-white">
|
||||
<a-spin class="chartContainer" :loading="isDataLoading" tip="图标数据加载中...">
|
||||
<ma-chart height="300px" :option="loginChartOptions" v-if="!isDataLoading" />
|
||||
<a-spin class="chartContainer" :loading="isPending" tip="图标数据加载中...">
|
||||
<div class="flex justify-center items-center" v-if="!isPending">
|
||||
<template v-if="isError">
|
||||
<img class="w-[200px] h-[300px]" src="@/assets/img/ErrorLoad.svg" alt="" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<VueUiXy :dataset="chartData" :config="chartConfig" />
|
||||
</template>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from "vue"
|
||||
import { graphic } from "echarts"
|
||||
import fetchData from "@/hooks/fetchData"
|
||||
import commonApi from "@/api/common"
|
||||
// 传给hook的远程请求数据函数
|
||||
async function fetchDataFunc() {
|
||||
return await commonApi.getChartData()
|
||||
}
|
||||
const { loadingData, isDataLoading } = fetchData(
|
||||
[
|
||||
{ month: "1", count: 2 },
|
||||
{ month: "2", count: 10 }
|
||||
],
|
||||
fetchDataFunc
|
||||
)
|
||||
// 计算属性:将loadingData转为xAxis
|
||||
const xAxisData = computed(() => {
|
||||
return loadingData.value.map((item) => {
|
||||
return item.month + "月"
|
||||
})
|
||||
import { VueUiXy } from "vue-data-ui"
|
||||
import useVueDataUI from "@/views/dashboard/workplace/components/cpns/hooks/vueDataUI"
|
||||
import { useQuery } from "@tanstack/vue-query"
|
||||
// vue-query请求图表接口
|
||||
const { isPending, data, isError } = useQuery({
|
||||
queryKey: ["chart"],
|
||||
queryFn: commonApi.getChartData,
|
||||
refetchOnWindowFocus: false
|
||||
})
|
||||
const yAxisData = computed(() => {
|
||||
return loadingData.value.map((item) => {
|
||||
return item.count
|
||||
})
|
||||
})
|
||||
|
||||
function graphicFactory(side) {
|
||||
return {
|
||||
type: "text",
|
||||
bottom: "8",
|
||||
...side,
|
||||
style: {
|
||||
text: "",
|
||||
textAlign: "center",
|
||||
fill: "#4E5969",
|
||||
fontSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const graphicElements = ref([graphicFactory({ left: "3%" }), graphicFactory({ right: 0 })])
|
||||
|
||||
const loginChartOptions = computed(() => ({
|
||||
title: {
|
||||
text: `项目每月统计-${new Date().getFullYear()}年份`
|
||||
},
|
||||
grid: {
|
||||
left: "3%",
|
||||
right: "3%",
|
||||
top: "50",
|
||||
bottom: "30"
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
offset: 2,
|
||||
data: xAxisData.value,
|
||||
boundaryGap: true,
|
||||
axisLabel: {
|
||||
color: "#4E5969",
|
||||
formatter(value, idx) {
|
||||
return `${value}`
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
interval: (idx) => {
|
||||
if (idx === xAxisData.value.length - 1) return false
|
||||
return true
|
||||
},
|
||||
lineStyle: {
|
||||
color: "#E5E8EF"
|
||||
}
|
||||
},
|
||||
axisPointer: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#23ADFF",
|
||||
width: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
formatter(value, idx) {
|
||||
if (idx === 0) return value
|
||||
return `${value}`
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: "dashed",
|
||||
color: "#E5E8EF"
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
formatter(params) {
|
||||
return `<div class="login-chart">
|
||||
<p class="tooltip-title">${params[0].axisValueLabel}</p>
|
||||
<div class="content-panel"><span>项目数量</span><span class="tooltip-value">${Number(
|
||||
params[0].value
|
||||
).toLocaleString()}</span></div>
|
||||
</div>`
|
||||
}
|
||||
},
|
||||
graphic: {
|
||||
elements: graphicElements.value
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: yAxisData.value,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbolSize: 14,
|
||||
emphasis: {
|
||||
focus: "series",
|
||||
itemStyle: {
|
||||
borderWidth: 2
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: new graphic.LinearGradient(0, 0, 1, 0, [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(30, 231, 255, 1)"
|
||||
},
|
||||
{
|
||||
offset: 0.5,
|
||||
color: "rgba(36, 154, 255, 1)"
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(111, 66, 251, 1)"
|
||||
}
|
||||
])
|
||||
},
|
||||
showSymbol: false,
|
||||
areaStyle: {
|
||||
opacity: 0.8,
|
||||
color: new graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(17, 126, 255, 0.16)"
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(17, 128, 255, 0)"
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
}))
|
||||
// vue-data-ui图表
|
||||
const { chartData, chartConfig } = useVueDataUI(data)
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -180,7 +180,7 @@ const handleSubmit = async ({ values, errors }) => {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
margin-top: -255px;
|
||||
border-radius: 2px;
|
||||
border-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
|
||||
@@ -431,6 +431,13 @@ const crudColumns = ref([
|
||||
}
|
||||
])
|
||||
|
||||
// 暴露给route-view的刷新表格函数
|
||||
const refreshCrudTable = () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
|
||||
defineExpose({ refreshCrudTable })
|
||||
|
||||
defineOptions({
|
||||
name: "case"
|
||||
})
|
||||
|
||||
@@ -238,6 +238,11 @@ const handleAddFileInputDemand = () => {
|
||||
fileInputRef.value.open()
|
||||
}
|
||||
|
||||
const refreshCrudTable = () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
defineExpose({ refreshCrudTable })
|
||||
|
||||
defineOptions({
|
||||
name: "dut"
|
||||
})
|
||||
|
||||
95
cdTMP/src/views/project/round/DutSubForm/index.tsx
Normal file
95
cdTMP/src/views/project/round/DutSubForm/index.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { defineComponent, inject, ref } from "vue"
|
||||
import { TreeNodeData } from "@arco-design/web-vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import { Message } from "@arco-design/web-vue"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import dutAPI from "@/api/project/dut"
|
||||
import useOptions from "./useOptions"
|
||||
import MaForm from "@/components/ma-form/index.vue"
|
||||
|
||||
const DutSubForm = defineComponent({
|
||||
name: "DutSubForm",
|
||||
setup(props, { expose }) {
|
||||
// globals
|
||||
const route = useRoute()
|
||||
const project_id = route.query.id
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const rightViewRef = inject("rightViewRef")
|
||||
// refs
|
||||
const visible = ref(false)
|
||||
const formRef = ref<InstanceType<typeof MaForm> | null>(null)
|
||||
const formData = ref<any>({})
|
||||
// hooks
|
||||
const { options, columnOptions } = useOptions(formRef)
|
||||
// 标题
|
||||
const title = ref("被测件详情")
|
||||
// 双击打开回调
|
||||
const open = async (nodeData: TreeNodeData) => {
|
||||
// 请求数据
|
||||
try {
|
||||
const key = nodeData.key
|
||||
// 设置表单名称
|
||||
title.value = nodeData.title!
|
||||
const res = await dutAPI.getDutOne({ project_id, key })
|
||||
// 更新表单
|
||||
formData.value = res.data
|
||||
formData.value.round = key
|
||||
visible.value = true
|
||||
} catch (e) {
|
||||
visible.value = false
|
||||
}
|
||||
}
|
||||
// 异步确认按钮点击
|
||||
const handleBeforeOk = async () => {
|
||||
const isValidated = await formRef.value!.validateForm()
|
||||
if (isValidated) {
|
||||
// 失败
|
||||
return false
|
||||
} else {
|
||||
// 成功
|
||||
const res = await dutAPI.update(formData.value.id, { project_id, ...formData.value })
|
||||
treeDataStore.updateDutTreeData(res.data, project_id) // 刷新树节点信息
|
||||
!(rightViewRef as any).value.refresh()
|
||||
Message.success("修改成功")
|
||||
}
|
||||
}
|
||||
// out use
|
||||
expose({ open })
|
||||
|
||||
// Dom
|
||||
return () => (
|
||||
<a-modal
|
||||
v-model:visible={visible.value}
|
||||
width={"40%"}
|
||||
draggable
|
||||
unmount-on-close
|
||||
ok-text="保存"
|
||||
cancel-text="关闭"
|
||||
on-before-ok={handleBeforeOk}
|
||||
>
|
||||
{{
|
||||
title: () => <span>[被测件]-{title.value}</span>,
|
||||
default: () => (
|
||||
<ma-form
|
||||
ref={formRef}
|
||||
v-model={formData.value}
|
||||
options={options.value}
|
||||
columns={columnOptions.value}
|
||||
>
|
||||
{{
|
||||
"inputPrepend-version": () => <span>V</span>
|
||||
}}
|
||||
</ma-form>
|
||||
)
|
||||
}}
|
||||
</a-modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default DutSubForm
|
||||
// 组件类型导出
|
||||
type DutSubFormOrigin = InstanceType<typeof DutSubForm>
|
||||
export interface DutSubFormInstance extends DutSubFormOrigin {
|
||||
open(nodeData: TreeNodeData): void
|
||||
}
|
||||
15
cdTMP/src/views/project/round/DutSubForm/useOptions.ts
Normal file
15
cdTMP/src/views/project/round/DutSubForm/useOptions.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ref, computed } from "vue"
|
||||
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
|
||||
import tool from "@/utils/tool"
|
||||
|
||||
export default function useOptions(formRef: any) {
|
||||
const options = ref({
|
||||
showButtons: false,
|
||||
labelAlign: "center"
|
||||
})
|
||||
const { crudColumns } = useCrudRef(undefined, formRef)
|
||||
const columnOptions = computed(() => {
|
||||
return tool.renameKeyInArray(crudColumns.value, "commonRules", "rules")
|
||||
})
|
||||
return { options, columnOptions }
|
||||
}
|
||||
15
cdTMP/src/views/project/round/beiceType.ts
Normal file
15
cdTMP/src/views/project/round/beiceType.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { IDictData } from "@/utils/types/CommonType"
|
||||
|
||||
type BeiceTypeT = {
|
||||
[K in keyof IDictData<string>]: string
|
||||
}
|
||||
|
||||
const beiceType: BeiceTypeT[] = [
|
||||
{ label: "源代码", value: "SO" },
|
||||
{ label: "设计说明", value: "SJ" },
|
||||
{ label: "需求文档", value: "XQ" },
|
||||
{ label: "通信协议", value: "XY" },
|
||||
{ label: "研制总要求", value: "YZ" }
|
||||
]
|
||||
|
||||
export default beiceType
|
||||
261
cdTMP/src/views/project/round/hooks/useCrudRef.ts
Normal file
261
cdTMP/src/views/project/round/hooks/useCrudRef.ts
Normal file
@@ -0,0 +1,261 @@
|
||||
import { ref } from "vue"
|
||||
import dutApi from "@/api/project/dut"
|
||||
import { useRoute } from "vue-router"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
import beiceType from "@/views/project/round/beiceType"
|
||||
/**
|
||||
* 传入组件Ref返回其options和columnOptions
|
||||
* @param crudRef crud组件的Ref,注意不存在传递undefined
|
||||
* @param formRef ma-form组件Ref
|
||||
* @returns
|
||||
*/
|
||||
export default function useCrudRef(crudRef?, formRef?) {
|
||||
// globals
|
||||
const route = useRoute()
|
||||
const projectId = ref(route.query.id)
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const roundNumber = (route.query.key as any).split("-")[0]
|
||||
// 计算注释率计算crud/form的数据,判断
|
||||
const calcPercent = () => {
|
||||
if (crudRef) {
|
||||
const formData = crudRef.value.getFormData()
|
||||
const total_line = +formData.black_line + +formData.code_line + +formData.comment_line + +formData.mix_line
|
||||
const comment_total = +formData.comment_line + +formData.mix_line
|
||||
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
|
||||
} else if (formRef) {
|
||||
const formData = formRef.value.getFormData()
|
||||
const { code_line, comment_line, mix_line, black_line } = formData
|
||||
const total_line = +black_line + +code_line + +comment_line + +mix_line
|
||||
const comment_total = +comment_line + +mix_line
|
||||
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
|
||||
}
|
||||
}
|
||||
// refs
|
||||
const crudOptions = ref({
|
||||
api: dutApi.getDutList,
|
||||
add: { show: true, api: dutApi.save, text: "新增被测件" },
|
||||
edit: { show: true, api: dutApi.update, text: "编辑被测件" },
|
||||
delete: { show: true, api: dutApi.delete },
|
||||
// 处理添加后函数
|
||||
beforeOpenAdd: function () {
|
||||
let round_str = parseInt(route.query.key as any) + 1
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
let round_str = parseInt(route.query.key as any) + 1
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDutTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDutTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateDutTreeData(record, id)
|
||||
// 清空行选择器
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
|
||||
// 新增、编辑、删除均携带下面
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber
|
||||
},
|
||||
operationWidth: 500,
|
||||
showIndex: false,
|
||||
showTools: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 200, // 操作列宽度
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
viewType: "drawer",
|
||||
width: 600,
|
||||
mask: false
|
||||
}
|
||||
})
|
||||
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
width: 50,
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
commonRules: [{ required: true, message: "ID是必填" }],
|
||||
validateTrigger: "blur",
|
||||
display: false
|
||||
},
|
||||
{
|
||||
title: "测件标识",
|
||||
width: 150,
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
align: "center",
|
||||
dataIndex: "ident",
|
||||
search: true,
|
||||
// 这里做的标识预填
|
||||
addDefaultValue: route.query.ident + "-R" + (parseInt(route.query.key as any) + 1) + "-UT",
|
||||
addDisabled: true,
|
||||
editDisabled: true,
|
||||
validateTrigger: "blur",
|
||||
disabled: true,
|
||||
placeholder: "被测件标识未空,请检查"
|
||||
},
|
||||
{
|
||||
title: "被测类型",
|
||||
align: "center",
|
||||
dataIndex: "type",
|
||||
search: true,
|
||||
formType: "radio",
|
||||
addDefaultValue: "SO",
|
||||
dict: {
|
||||
data: beiceType,
|
||||
translation: true,
|
||||
tagColors: { XQ: "blue", SO: "green", SJ: "orangered", XY: "pinkpurple", YZ: "red" }
|
||||
},
|
||||
onControl: (value) => {
|
||||
if (value === "SO") {
|
||||
return {
|
||||
black_line: { display: true },
|
||||
code_line: { display: true },
|
||||
mix_line: { display: true },
|
||||
comment_line: { display: true },
|
||||
total_code_line: { display: true },
|
||||
total_line: { display: true },
|
||||
comment_percent: { display: true },
|
||||
release_date: { display: false }
|
||||
}
|
||||
} else {
|
||||
// 其他数据清除
|
||||
return {
|
||||
black_line: { display: false },
|
||||
code_line: { display: false },
|
||||
mix_line: { display: false },
|
||||
comment_line: { display: false },
|
||||
total_code_line: { display: false },
|
||||
total_line: { display: false },
|
||||
comment_percent: { display: false },
|
||||
release_date: { display: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "被测件名",
|
||||
width: 120,
|
||||
align: "center",
|
||||
dataIndex: "name",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "被测件名称必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "版本",
|
||||
align: "center",
|
||||
dataIndex: "version",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "版本必填" }],
|
||||
validateTrigger: "blur",
|
||||
help: "填写不带V字符",
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "用户标识",
|
||||
align: "center",
|
||||
dataIndex: "ref",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "用户标识必填" }],
|
||||
validateTrigger: "blur",
|
||||
help: "客户使用的标识"
|
||||
},
|
||||
{
|
||||
title: "单位",
|
||||
align: "center",
|
||||
dataIndex: "release_union",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "单位必选" }],
|
||||
formType: "select",
|
||||
dict: { url: "system/contact/index", props: { label: "name", value: "name" }, translation: true }
|
||||
},
|
||||
{
|
||||
title: "发布时间",
|
||||
dataIndex: "release_date",
|
||||
hide: true,
|
||||
commonRules: [{ required: true, message: "时间必填" }],
|
||||
formType: "date"
|
||||
},
|
||||
{
|
||||
title: "空行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "black_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "空行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "纯代码行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "code_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "纯代码行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "纯注释行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "comment_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "纯注释行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "混合行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "mix_line",
|
||||
formType: "input-number",
|
||||
help: "混合行是指:代码中一行即包含代码也包含注释",
|
||||
commonRules: [{ required: true, message: "混合行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "注释率 %",
|
||||
align: "center",
|
||||
dataIndex: "comment_percent",
|
||||
placeholder: "计算注释率",
|
||||
hide: true,
|
||||
addDisabled: true,
|
||||
editDisabled: true
|
||||
}
|
||||
])
|
||||
return {
|
||||
crudOptions,
|
||||
crudColumns
|
||||
}
|
||||
}
|
||||
@@ -12,251 +12,15 @@
|
||||
|
||||
<script setup lang="jsx">
|
||||
import { ref } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import dutApi from "@/api/project/dut"
|
||||
import { useTreeDataStore } from "@/store"
|
||||
const treeDataStore = useTreeDataStore()
|
||||
const route = useRoute()
|
||||
const roundNumber = route.query.key.split("-")[0]
|
||||
const projectId = ref(route.query.id)
|
||||
import useCrudRef from "@/views/project/round/hooks/useCrudRef"
|
||||
const crudRef = ref()
|
||||
|
||||
let beiceType = [
|
||||
{ label: "源代码", value: "SO" },
|
||||
{ label: "设计说明", value: "SJ" },
|
||||
{ label: "需求文档", value: "XQ" },
|
||||
{ label: "通信协议", value: "XY" },
|
||||
{ label: "研制总要求", value: "YZ" }
|
||||
]
|
||||
// crud组件
|
||||
const crudOptions = ref({
|
||||
api: dutApi.getDutList,
|
||||
add: { show: true, api: dutApi.save, text: "新增被测件" },
|
||||
edit: { show: true, api: dutApi.update, text: "编辑被测件" },
|
||||
delete: { show: true, api: dutApi.delete },
|
||||
// 处理添加后函数
|
||||
beforeOpenAdd: function () {
|
||||
let round_str = parseInt(route.query.key) + 1
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件-`
|
||||
return true
|
||||
},
|
||||
beforeOpenEdit: function (record) {
|
||||
let round_str = parseInt(route.query.key) + 1
|
||||
crudRef.value.crudFormRef.actionTitle = `${route.query.ident}>第${round_str}轮>被测件[${record.name}]-`
|
||||
return true
|
||||
},
|
||||
afterAdd: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDutTreeData(res.data, id)
|
||||
},
|
||||
afterEdit: (res) => {
|
||||
let id = projectId.value
|
||||
treeDataStore.updateDutTreeData(res.data, id)
|
||||
},
|
||||
afterDelete: (res, record) => {
|
||||
let id = projectId.value
|
||||
if (!record) {
|
||||
record = { key: route.query.key + "-X" }
|
||||
}
|
||||
treeDataStore.updateDutTreeData(record, id)
|
||||
// 清空行选择器
|
||||
crudRef.value.tableRef.selectAll(false)
|
||||
},
|
||||
const { crudOptions, crudColumns } = useCrudRef(crudRef)
|
||||
|
||||
// 新增、编辑、删除均携带下面
|
||||
parameters: {
|
||||
projectId: route.query.id,
|
||||
round: roundNumber
|
||||
},
|
||||
operationWidth: 500,
|
||||
showIndex: false,
|
||||
showTools: false,
|
||||
rowSelection: { showCheckedAll: true },
|
||||
searchColNumber: 3,
|
||||
tablePagination: false,
|
||||
operationColumnWidth: 200, // 操作列宽度
|
||||
operationColumn: true,
|
||||
operationColumnAlign: "center",
|
||||
formOption: {
|
||||
viewType: "drawer",
|
||||
width: 600,
|
||||
mask: false
|
||||
}
|
||||
})
|
||||
|
||||
// 1.计算注释率函数 -> 用于字段交互
|
||||
const calcPercent = () => {
|
||||
const formData = crudRef.value.getFormData()
|
||||
const total_line = +formData.black_line + +formData.code_line + +formData.comment_line + +formData.mix_line
|
||||
const comment_total = +formData.comment_line + +formData.mix_line
|
||||
formData.comment_percent = `${(comment_total / total_line).toFixed(2).toString()}%`
|
||||
const refreshCrudTable = () => {
|
||||
crudRef.value.refresh()
|
||||
}
|
||||
|
||||
const crudColumns = ref([
|
||||
{
|
||||
title: "ID",
|
||||
width: 50,
|
||||
align: "center",
|
||||
hide: true,
|
||||
dataIndex: "id",
|
||||
commonRules: [{ required: true, message: "ID是必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "测件标识",
|
||||
width: 150,
|
||||
sortable: { sortDirections: ["ascend"] },
|
||||
align: "center",
|
||||
dataIndex: "ident",
|
||||
search: true,
|
||||
// 这里做的标识预填
|
||||
addDefaultValue: route.query.ident + "-R" + (parseInt(route.query.key) + 1) + "-UT",
|
||||
addDisabled: true,
|
||||
editDisabled: true,
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "被测类型",
|
||||
align: "center",
|
||||
dataIndex: "type",
|
||||
search: true,
|
||||
formType: "radio",
|
||||
addDefaultValue: "SO",
|
||||
dict: {
|
||||
data: beiceType,
|
||||
translation: true,
|
||||
tagColors: { XQ: "blue", SO: "green", SJ: "orangered", XY: "pinkpurple", YZ: "red" }
|
||||
},
|
||||
onControl: (value) => {
|
||||
if (value === "SO") {
|
||||
return {
|
||||
black_line: { display: true },
|
||||
code_line: { display: true },
|
||||
mix_line: { display: true },
|
||||
comment_line: { display: true },
|
||||
total_code_line: { display: true },
|
||||
total_line: { display: true },
|
||||
comment_percent: { display: true },
|
||||
release_date: { display: false }
|
||||
}
|
||||
} else {
|
||||
// 其他数据清除
|
||||
return {
|
||||
black_line: { display: false },
|
||||
code_line: { display: false },
|
||||
mix_line: { display: false },
|
||||
comment_line: { display: false },
|
||||
total_code_line: { display: false },
|
||||
total_line: { display: false },
|
||||
comment_percent: { display: false },
|
||||
release_date: { display: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "被测件名",
|
||||
width: 120,
|
||||
align: "center",
|
||||
dataIndex: "name",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "被测件名称必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "版本",
|
||||
align: "center",
|
||||
dataIndex: "version",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "版本必填" }],
|
||||
validateTrigger: "blur",
|
||||
help: "填写不带V字符",
|
||||
openPrepend: true
|
||||
},
|
||||
{
|
||||
title: "用户标识",
|
||||
align: "center",
|
||||
dataIndex: "ref",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "用户标识必填" }],
|
||||
validateTrigger: "blur",
|
||||
help: "客户使用的标识"
|
||||
},
|
||||
{
|
||||
title: "单位",
|
||||
align: "center",
|
||||
dataIndex: "release_union",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "单位必选" }],
|
||||
formType: "select",
|
||||
dict: { url: "system/contact/index", props: { label: "name", value: "name" }, translation: true }
|
||||
},
|
||||
{
|
||||
title: "发布时间",
|
||||
dataIndex: "release_date",
|
||||
hide: true,
|
||||
commonRules: [{ required: true, message: "时间必填" }],
|
||||
formType: "date"
|
||||
},
|
||||
{
|
||||
title: "空行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "black_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "空行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "纯代码行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "code_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "纯代码行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "纯注释行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "comment_line",
|
||||
formType: "input-number",
|
||||
commonRules: [{ required: true, message: "纯注释行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "混合行",
|
||||
hide: true,
|
||||
align: "center",
|
||||
dataIndex: "mix_line",
|
||||
formType: "input-number",
|
||||
help: "混合行是指:代码中一行即包含代码也包含注释",
|
||||
commonRules: [{ required: true, message: "混合行数必填" }],
|
||||
min: 0,
|
||||
onControl: () => {
|
||||
calcPercent()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "注释率 %",
|
||||
align: "center",
|
||||
dataIndex: "comment_percent",
|
||||
placeholder: "计算注释率",
|
||||
hide: true,
|
||||
addDisabled: true,
|
||||
editDisabled: true
|
||||
}
|
||||
])
|
||||
defineExpose({ refreshCrudTable })
|
||||
|
||||
defineOptions({
|
||||
name: "round"
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { useRoute } from "vue-router"
|
||||
import { ref } from "vue"
|
||||
import { FragApi } from "@/api/system/fragment"
|
||||
import { ProductFileEnum } from "@/utils/enums/productTypes"
|
||||
import type { IDictData } from "@/utils/types/CommonType"
|
||||
import { IFragSearchCondition } from "@/api/system/types/fragmentTypes"
|
||||
|
||||
const useCrudOption = () => {
|
||||
// global
|
||||
const route = useRoute()
|
||||
const crudRef = ref()
|
||||
// 产品文档类型写死7种
|
||||
const productFileType: IDictData<ProductFileEnum>[] = Object.keys(ProductFileEnum).map((it, index) => ({
|
||||
label: ProductFileEnum[it],
|
||||
value: index + 1
|
||||
}))
|
||||
// crud-option
|
||||
// crud-options
|
||||
const crudOptions = ref<object>({
|
||||
api: FragApi.getFragList,
|
||||
add: { show: true, api: FragApi.add },
|
||||
@@ -45,10 +38,7 @@ const useCrudOption = () => {
|
||||
layout: [
|
||||
{
|
||||
formType: "grid",
|
||||
cols: [
|
||||
{ span: 12, formList: [{ dataIndex: "name" }] },
|
||||
{ span: 12, formList: [{ dataIndex: "belong_doc" }] }
|
||||
]
|
||||
cols: [{ span: 12, formList: [{ dataIndex: "name" }] }]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -72,16 +62,6 @@ const useCrudOption = () => {
|
||||
commonRules: [{ required: true, message: "片段名称必填" }],
|
||||
validateTrigger: "blur"
|
||||
},
|
||||
{
|
||||
title: "所属文档",
|
||||
align: "center",
|
||||
width: 100,
|
||||
dataIndex: "belong_doc",
|
||||
formType: "select",
|
||||
search: true,
|
||||
commonRules: [{ required: true, message: "所属文档必选" }],
|
||||
dict: { data: productFileType, translation: true }
|
||||
},
|
||||
{
|
||||
title: "替换片段",
|
||||
width: 100,
|
||||
|
||||
@@ -82,7 +82,8 @@ const useGenerateSecond = function () {
|
||||
dgGenerateApi.createInterface({ id }), // 生成-被测软件接口
|
||||
dgGenerateApi.createPerformance({ id }), // 生成-被测软件性能
|
||||
dgGenerateApi.createBaseInformation({ id }), // 生成-被测软件基本信息
|
||||
dgGenerateApi.createRequirement({ id }), // 生成-测试总体要求
|
||||
dgGenerateApi.createLevelAndType({ id }), // 生成-测试级别和测试类型 -【修改】
|
||||
dgGenerateApi.createStrategy({ id }), // 生成-测试级别和测试类型 -【新增】
|
||||
dgGenerateApi.createYzComparison({ id }), // 生成-研总-测试项对照表
|
||||
dgGenerateApi.createXqComparison({ id }), // 生成-需求规格说明-测试项对照表
|
||||
dgGenerateApi.createFanXqComparison({ id }), // 生成-反向测试项-需求规格说明对照表
|
||||
|
||||
Reference in New Issue
Block a user