|
@@ -180,20 +180,10 @@
|
|
|
/>
|
|
/>
|
|
|
<zm-table-column label="操作" align="center" fixed="right" min-width="140" action>
|
|
<zm-table-column label="操作" align="center" fixed="right" min-width="140" action>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="openForm('update', scope.row.id)"
|
|
|
|
|
- v-hasPermi="['rd:core-technology:update']"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button link type="primary" @click="openForm('update', scope.row.id)">
|
|
|
编辑
|
|
编辑
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <el-button
|
|
|
|
|
- link
|
|
|
|
|
- type="danger"
|
|
|
|
|
- @click="handleDelete(scope.row.id)"
|
|
|
|
|
- v-hasPermi="['rd:core-technology:delete']"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button link type="danger" @click="handleDelete(scope.row.id)">
|
|
|
删除
|
|
删除
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</template>
|
|
</template>
|
|
@@ -324,6 +314,46 @@
|
|
|
:limit="10"
|
|
:limit="10"
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
+ <el-form-item label="进度明细" prop="details">
|
|
|
|
|
+ <div class="details-editor">
|
|
|
|
|
+ <div class="details-toolbar">
|
|
|
|
|
+ <span class="details-tip">最新研发/应用/成果进展</span>
|
|
|
|
|
+ <el-button type="primary" plain size="small" @click="addDetail">
|
|
|
|
|
+ <Icon icon="ep:plus" class="mr-5px" />新增进度
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div v-if="formData.details.length" class="details-list">
|
|
|
|
|
+ <div v-for="(detail, index) in formData.details" :key="index" class="detail-row">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="detail.progressDate"
|
|
|
|
|
+ type="date"
|
|
|
|
|
+ value-format="x"
|
|
|
|
|
+ placeholder="请选择进度日期"
|
|
|
|
|
+ class="detail-date"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="detail.overview"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="2"
|
|
|
|
|
+ resize="none"
|
|
|
|
|
+ placeholder="请输入进度描述"
|
|
|
|
|
+ class="detail-overview"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ link
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ class="detail-delete"
|
|
|
|
|
+ title="删除此条进度"
|
|
|
|
|
+ @click="removeDetail(index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Icon icon="ep:delete" />
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-empty v-else :image-size="48" description="暂无进度明细,点击右上角新增" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
|
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -386,7 +416,8 @@ const createDefaultForm = () => ({
|
|
|
summary: '',
|
|
summary: '',
|
|
|
principles: '',
|
|
principles: '',
|
|
|
advantages: '',
|
|
advantages: '',
|
|
|
- attachments: []
|
|
|
|
|
|
|
+ attachments: [],
|
|
|
|
|
+ details: [] as Array<{ progressDate: string | number; overview: string }>
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const formData = ref(createDefaultForm())
|
|
const formData = ref(createDefaultForm())
|
|
@@ -459,7 +490,9 @@ const openForm = async (type: 'create' | 'update', id?: number) => {
|
|
|
const data = await getTechnologyDetail(id!)
|
|
const data = await getTechnologyDetail(id!)
|
|
|
formData.value = {
|
|
formData.value = {
|
|
|
...createDefaultForm(),
|
|
...createDefaultForm(),
|
|
|
- ...data
|
|
|
|
|
|
|
+ ...data,
|
|
|
|
|
+ attachments: data.attachments || [],
|
|
|
|
|
+ details: Array.isArray(data.details) ? data.details : []
|
|
|
}
|
|
}
|
|
|
dialogVisible.value = true
|
|
dialogVisible.value = true
|
|
|
} finally {
|
|
} finally {
|
|
@@ -471,6 +504,14 @@ const closeDialog = () => {
|
|
|
formRef.value?.resetFields()
|
|
formRef.value?.resetFields()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const addDetail = () => {
|
|
|
|
|
+ formData.value.details.push({ progressDate: '', overview: '' })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const removeDetail = (index: number) => {
|
|
|
|
|
+ formData.value.details.splice(index, 1)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const submitForm = () => {
|
|
const submitForm = () => {
|
|
|
formRef.value.validate(async (valid: boolean) => {
|
|
formRef.value.validate(async (valid: boolean) => {
|
|
|
if (!valid) return
|
|
if (!valid) return
|
|
@@ -514,3 +555,88 @@ onMounted(async () => {
|
|
|
deptList2.value = await DeptApi.getSimpleDeptList()
|
|
deptList2.value = await DeptApi.getSimpleDeptList()
|
|
|
})
|
|
})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.details-editor {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ background: var(--el-fill-color-blank);
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.details-toolbar {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.details-tip {
|
|
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.details-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.detail-row {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.detail-date {
|
|
|
|
|
+ width: 170px;
|
|
|
|
|
+ flex: 0 0 170px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.detail-overview {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.detail-delete {
|
|
|
|
|
+ flex: 0 0 28px;
|
|
|
|
|
+ margin-top: 5px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.el-empty) {
|
|
|
|
|
+ padding: 12px 0 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 640px) {
|
|
|
|
|
+ .details-toolbar,
|
|
|
|
|
+ .detail-row {
|
|
|
|
|
+ align-items: stretch;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .details-toolbar {
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-row {
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-date {
|
|
|
|
|
+ width: calc(100% - 38px);
|
|
|
|
|
+ flex-basis: calc(100% - 38px);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-overview {
|
|
|
|
|
+ flex-basis: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-delete {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ margin-left: calc(100% - 28px);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|