|
|
@@ -158,16 +158,16 @@
|
|
|
{{ scope.row.note || '-' }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="created_by" label="创建人" width="100" />
|
|
|
- <el-table-column prop="created_at" label="创建时间" width="180">
|
|
|
+ <el-table-column prop="creator_name" label="创建人" width="100" />
|
|
|
+ <el-table-column prop="created_time" label="创建时间" width="180">
|
|
|
<template #default="scope">
|
|
|
- {{ formatDateTime(scope.row.created_at) }}
|
|
|
+ {{ formatDateTime(scope.row.created_time) }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="updated_by" label="修改人" width="100" />
|
|
|
- <el-table-column prop="updated_at" label="修改时间" width="180">
|
|
|
+ <el-table-column prop="updater_name" label="修改人" width="100" />
|
|
|
+ <el-table-column prop="updated_time" label="修改时间" width="180">
|
|
|
<template #default="scope">
|
|
|
- {{ formatDateTime(scope.row.updated_at) }}
|
|
|
+ {{ formatDateTime(scope.row.updated_time) }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="180" fixed="right" align="center">
|
|
|
@@ -289,9 +289,15 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
- <el-col :span="12" v-if="infoType === 'basis'">
|
|
|
+ <el-col :span="24" v-if="infoType === 'basis'">
|
|
|
<el-form-item label="参编单位">
|
|
|
- <el-input v-model="editForm.participating_units" placeholder="请输入参编单位" />
|
|
|
+ <div v-for="(unit, index) in participatingUnitsList" :key="index" class="dynamic-input-row">
|
|
|
+ <el-input v-model="participatingUnitsList[index]" placeholder="请输入参编单位" />
|
|
|
+ <div class="row-actions">
|
|
|
+ <el-button :icon="Plus" circle size="small" @click="addListItem(participatingUnitsList)" />
|
|
|
+ <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(participatingUnitsList, index)" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
@@ -301,9 +307,15 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
- <el-col :span="12" v-if="infoType === 'basis'">
|
|
|
+ <el-col :span="24" v-if="infoType === 'basis'">
|
|
|
<el-form-item label="引用依据">
|
|
|
- <el-input v-model="editForm.reference_basis" placeholder="请输入引用依据" />
|
|
|
+ <div v-for="(basis, index) in referenceBasisList" :key="index" class="dynamic-input-row">
|
|
|
+ <el-input v-model="referenceBasisList[index]" placeholder="请输入引用依据" />
|
|
|
+ <div class="row-actions">
|
|
|
+ <el-button :icon="Plus" circle size="small" @click="addListItem(referenceBasisList)" />
|
|
|
+ <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(referenceBasisList, index)" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
@@ -363,8 +375,14 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="编制依据">
|
|
|
- <el-input v-model="editForm.compilation_basis" type="textarea" :rows="3" placeholder="请输入编制依据,多个依据请用逗号分隔" />
|
|
|
+ <el-form-item label="施工标准规范">
|
|
|
+ <div v-for="(basis, index) in compilationBasisList" :key="index" class="dynamic-input-row">
|
|
|
+ <el-input v-model="compilationBasisList[index]" placeholder="请输入施工标准规范" />
|
|
|
+ <div class="row-actions">
|
|
|
+ <el-button :icon="Plus" circle size="small" @click="addListItem(compilationBasisList)" />
|
|
|
+ <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(compilationBasisList, index)" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</template>
|
|
|
@@ -389,7 +407,7 @@
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="文件链接">
|
|
|
+ <el-form-item label="文件预览链接" v-if="false">
|
|
|
<el-input v-model="editForm.file_url" placeholder="请输入文件预览链接 (URL)" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
@@ -410,6 +428,18 @@
|
|
|
<el-descriptions-item :label="dateLabel">{{ formatDate(currentItem?.release_date) }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="文档类型" v-if="infoType === 'basis' || infoType === 'job'">{{ currentItem?.document_type || '-' }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="专业领域" v-if="infoType === 'basis'">{{ currentItem?.professional_field || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="参编单位" v-if="infoType === 'basis'">
|
|
|
+ <div v-if="currentItem?.participating_units">
|
|
|
+ <div v-for="(unit, idx) in currentItem.participating_units.split(';')" :key="idx">{{ unit }}</div>
|
|
|
+ </div>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="引用依据" v-if="infoType === 'basis'">
|
|
|
+ <div v-if="currentItem?.reference_basis">
|
|
|
+ <div v-for="(basis, idx) in currentItem.reference_basis.split(';')" :key="idx">{{ basis }}</div>
|
|
|
+ </div>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </el-descriptions-item>
|
|
|
<el-descriptions-item label="时效性" v-if="infoType === 'basis'">
|
|
|
<el-tag :type="getValidityType(currentItem?.validity)">{{ currentItem?.validity || '现行' }}</el-tag>
|
|
|
</el-descriptions-item>
|
|
|
@@ -422,10 +452,17 @@
|
|
|
<el-descriptions-item label="三级分类">{{ currentItem?.level_3_classification || '-' }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="四级分类">{{ currentItem?.level_4_classification || '-' }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="方案摘要">{{ currentItem?.plan_summary || '-' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="编制依据">{{ currentItem?.compilation_basis || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="施工标准规范">
|
|
|
+ <div v-if="currentItem?.compilation_basis">
|
|
|
+ <div v-for="(basis, idx) in currentItem.compilation_basis.split(';')" :key="idx">{{ basis }}</div>
|
|
|
+ </div>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </el-descriptions-item>
|
|
|
</template>
|
|
|
- <el-descriptions-item label="创建人">{{ currentItem?.created_by }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="创建时间">{{ formatDateTime(currentItem?.created_at) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建人">{{ currentItem?.creator_name || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建时间">{{ formatDateTime(currentItem?.created_time) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="修改人">{{ currentItem?.updater_name || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="修改时间">{{ formatDateTime(currentItem?.updated_time) }}</el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
<template #footer>
|
|
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
|
|
@@ -466,12 +503,13 @@
|
|
|
<script setup lang="ts">
|
|
|
import { ref, onMounted, computed, watch, reactive } from 'vue'
|
|
|
import { useRoute } from 'vue-router'
|
|
|
-import { Search, View, Monitor, Download, Edit, Delete, Refresh, Plus, Document } from '@element-plus/icons-vue'
|
|
|
+import { Search, View, Monitor, Download, Edit, Delete, Refresh, Plus, Minus, Document } from '@element-plus/icons-vue'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import request from '@/api/request'
|
|
|
import type { ApiResponse } from '@/types/auth'
|
|
|
import dayjs from 'dayjs'
|
|
|
import { downloadFile } from '@/utils/download'
|
|
|
+import { getFileExtension } from '@/utils/file'
|
|
|
import { useAuthStore } from '@/stores/auth'
|
|
|
|
|
|
const route = useRoute()
|
|
|
@@ -491,6 +529,23 @@ const previewLoading = ref(false)
|
|
|
const previewUrl = ref('')
|
|
|
const previewTitle = ref('')
|
|
|
|
|
|
+// 动态列表字段存储
|
|
|
+const participatingUnitsList = ref<string[]>([''])
|
|
|
+const referenceBasisList = ref<string[]>([''])
|
|
|
+const compilationBasisList = ref<string[]>([''])
|
|
|
+
|
|
|
+const addListItem = (list: string[]) => {
|
|
|
+ list.push('')
|
|
|
+}
|
|
|
+
|
|
|
+const removeListItem = (list: string[], index: number) => {
|
|
|
+ if (list.length > 1) {
|
|
|
+ list.splice(index, 1)
|
|
|
+ } else {
|
|
|
+ list[0] = ''
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// 当前操作的数据
|
|
|
const currentItem = ref<any>(null)
|
|
|
const editForm = reactive<any>({
|
|
|
@@ -584,7 +639,7 @@ const infoType = computed(() => {
|
|
|
|
|
|
const pageTitle = computed(() => {
|
|
|
switch (infoType.value) {
|
|
|
- case 'basis': return '编制依据管理'
|
|
|
+ case 'basis': return '施工标准规范管理'
|
|
|
case 'work': return '施工方案管理'
|
|
|
case 'job': return '办公制度管理'
|
|
|
default: return '基本信息管理'
|
|
|
@@ -593,7 +648,7 @@ const pageTitle = computed(() => {
|
|
|
|
|
|
const moduleName = computed(() => {
|
|
|
switch (infoType.value) {
|
|
|
- case 'basis': return '编制依据'
|
|
|
+ case 'basis': return '施工标准规范'
|
|
|
case 'work': return '施工方案'
|
|
|
case 'job': return '办公制度'
|
|
|
default: return ''
|
|
|
@@ -712,7 +767,10 @@ const getValidityType = (validity: string) => {
|
|
|
const proxyPreviewUrl = computed(() => {
|
|
|
if (!previewUrl.value) return ''
|
|
|
// 使用后端代理接口查看外部网页,附加 token 以通过认证
|
|
|
- const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'
|
|
|
+ let baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'
|
|
|
+ if (baseUrl.includes('localhost') && window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
|
|
|
+ baseUrl = baseUrl.replace('localhost', window.location.hostname)
|
|
|
+ }
|
|
|
return `${baseUrl}/api/v1/sample/documents/proxy-view?url=${encodeURIComponent(previewUrl.value)}&token=${authStore.token}`
|
|
|
})
|
|
|
|
|
|
@@ -743,7 +801,9 @@ const handleAction = async (action: string, row: any) => {
|
|
|
break
|
|
|
case 'download':
|
|
|
if (row.file_url) {
|
|
|
- downloadFile(row.file_url, row.title)
|
|
|
+ const ext = getFileExtension(row)
|
|
|
+ const filename = row.title.endsWith(ext) ? row.title : `${row.title}${ext}`
|
|
|
+ downloadFile(row.file_url, filename)
|
|
|
} else {
|
|
|
ElMessage.warning('该文档暂无下载链接')
|
|
|
}
|
|
|
@@ -752,6 +812,11 @@ const handleAction = async (action: string, row: any) => {
|
|
|
Object.keys(editForm).forEach(key => {
|
|
|
editForm[key] = row[key] || ''
|
|
|
})
|
|
|
+ // 处理动态列表字段
|
|
|
+ participatingUnitsList.value = row.participating_units ? row.participating_units.split(';') : ['']
|
|
|
+ referenceBasisList.value = row.reference_basis ? row.reference_basis.split(';') : ['']
|
|
|
+ compilationBasisList.value = row.compilation_basis ? row.compilation_basis.split(';') : ['']
|
|
|
+
|
|
|
editForm.id = row.id
|
|
|
formDialogVisible.value = true
|
|
|
break
|
|
|
@@ -787,6 +852,11 @@ const handleAdd = () => {
|
|
|
editForm[key] = ''
|
|
|
}
|
|
|
})
|
|
|
+ // 初始化动态列表字段
|
|
|
+ participatingUnitsList.value = ['']
|
|
|
+ referenceBasisList.value = ['']
|
|
|
+ compilationBasisList.value = ['']
|
|
|
+
|
|
|
editForm.id = null
|
|
|
formDialogVisible.value = true
|
|
|
}
|
|
|
@@ -796,6 +866,11 @@ const submitForm = async () => {
|
|
|
return ElMessage.warning('请输入名称')
|
|
|
}
|
|
|
|
|
|
+ // 提交前合并动态列表字段,过滤掉空行并用分号连接
|
|
|
+ editForm.participating_units = participatingUnitsList.value.filter(item => item.trim() !== '').join(';')
|
|
|
+ editForm.reference_basis = referenceBasisList.value.filter(item => item.trim() !== '').join(';')
|
|
|
+ editForm.compilation_basis = compilationBasisList.value.filter(item => item.trim() !== '').join(';')
|
|
|
+
|
|
|
submitting.value = true
|
|
|
try {
|
|
|
const isEdit = !!editForm.id
|
|
|
@@ -820,8 +895,8 @@ const submitForm = async () => {
|
|
|
}
|
|
|
|
|
|
const openInNewWindow = () => {
|
|
|
- if (previewUrl.value) {
|
|
|
- window.open(previewUrl.value, '_blank')
|
|
|
+ if (proxyPreviewUrl.value) {
|
|
|
+ window.open(proxyPreviewUrl.value, '_blank')
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -876,6 +951,23 @@ onMounted(() => {
|
|
|
margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
+.dynamic-input-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-input-row:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.row-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 5px;
|
|
|
+ margin-left: 10px;
|
|
|
+}
|
|
|
+
|
|
|
.table-card {
|
|
|
padding: 10px;
|
|
|
}
|