|
|
@@ -57,9 +57,7 @@
|
|
|
|
|
|
<div class="form-actions">
|
|
|
<el-button @click="handleBack">返回列表</el-button>
|
|
|
- <el-button v-if="isEditable" @click="handleSaveDraft" :loading="saving">保存草稿</el-button>
|
|
|
<el-button v-if="isEditable" type="primary" @click="handleSubmit" :loading="submitting">提交</el-button>
|
|
|
- <el-button v-if="isEditable" @click="handleReset">重置</el-button>
|
|
|
</div>
|
|
|
</el-form>
|
|
|
</div>
|
|
|
@@ -72,18 +70,21 @@ defineOptions({ name: 'IqcApplicationForm' })
|
|
|
import { reactive, ref, computed, onMounted } from 'vue'
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
import IqcStatusBadge from '@/components/Qms/StatusBadge.vue'
|
|
|
-import { useQmsApplicationStore } from '@/store/modules/qms/application'
|
|
|
import { getQmsModuleConfig, DEFAULT_QMS_MODULE } from '@/config/qmsModules'
|
|
|
+import { createIqcApply, getIqcApply, updateIqcApply } from '@/api/qms/iqc/apply'
|
|
|
|
|
|
const route = useRoute()
|
|
|
const router = useRouter()
|
|
|
-const applicationStore = useQmsApplicationStore()
|
|
|
-
|
|
|
const moduleCode = computed(() => (route.meta.module as string) || DEFAULT_QMS_MODULE)
|
|
|
-const formConfig = computed(() => getQmsModuleConfig(moduleCode.value).applicationForm)
|
|
|
+const moduleConfig = computed(() => getQmsModuleConfig(moduleCode.value))
|
|
|
+const isIqcModule = computed(() => moduleCode.value === 'iqc')
|
|
|
+const formConfig = computed(() => moduleConfig.value.applicationForm)
|
|
|
+const listPath = computed(() => {
|
|
|
+ const navItem = moduleConfig.value.navItems?.find((item: any) => item.key === 'applications')
|
|
|
+ return navItem?.path || `/qms/${moduleConfig.value.code}/apply/list`
|
|
|
+})
|
|
|
|
|
|
const loading = ref(false)
|
|
|
-const saving = ref(false)
|
|
|
const submitting = ref(false)
|
|
|
const applicationData = ref<any>(null)
|
|
|
|
|
|
@@ -93,6 +94,7 @@ const isCreate = computed(() => route.meta.mode === 'create')
|
|
|
const isEdit = computed(() => route.meta.mode === 'edit')
|
|
|
const isView = computed(() => route.meta.mode === 'view')
|
|
|
const isEditable = computed(() => isCreate.value || isEdit.value)
|
|
|
+const routeId = computed(() => String(route.params.id || ''))
|
|
|
|
|
|
const pageTitle = computed(() => {
|
|
|
if (isCreate.value) return `新建${formConfig.value.title}`
|
|
|
@@ -120,7 +122,7 @@ const getFieldComponent = (field: any) => {
|
|
|
}
|
|
|
|
|
|
const getFieldProps = (field: any) => {
|
|
|
- if (field.type === 'datetime') return { type: 'datetime', placeholder: '请选择时间', format: 'YYYY-MM-DD HH:mm', 'value-format': 'YYYY-MM-DD HH:mm:ss', style: 'width: 100%' }
|
|
|
+ if (field.type === 'datetime') return { type: 'datetime', placeholder: '请选择时间', format: 'YYYY-MM-DD HH:mm:ss', 'value-format': 'x', style: 'width: 100%' }
|
|
|
if (field.type === 'textarea') return { type: 'textarea', rows: field.rows || 3, placeholder: `请输入${field.label}` }
|
|
|
return { placeholder: `请输入${field.label}`, style: 'width: 100%' }
|
|
|
}
|
|
|
@@ -142,24 +144,110 @@ const getDetailProps = (column: any) => {
|
|
|
|
|
|
const handleAddDetail = () => { formData.details.push(createDetailRow()) }
|
|
|
const handleDeleteDetail = (index: number) => { formData.details.splice(index, 1); if (!formData.details.length) formData.details.push(createDetailRow()) }
|
|
|
-const handleBack = () => { router.push(`/qms/${moduleCode.value}/apply/list`) }
|
|
|
-const handleReset = () => { initFormData(); formData.details = [createDetailRow()] }
|
|
|
-
|
|
|
-const handleSaveDraft = async () => {
|
|
|
- saving.value = true
|
|
|
- try { ElMessage.success('保存成功'); handleBack() }
|
|
|
- catch { ElMessage.error('保存失败') }
|
|
|
- finally { saving.value = false }
|
|
|
-}
|
|
|
-
|
|
|
+const handleBack = () => { router.push(listPath.value) }
|
|
|
const handleSubmit = async () => {
|
|
|
submitting.value = true
|
|
|
- try { ElMessage.success('提交成功'); handleBack() }
|
|
|
+ try {
|
|
|
+ await saveApplication()
|
|
|
+ ElMessage.success('提交成功')
|
|
|
+ handleBack()
|
|
|
+ }
|
|
|
catch { ElMessage.error('提交失败') }
|
|
|
finally { submitting.value = false }
|
|
|
}
|
|
|
|
|
|
-onMounted(() => { initFormData(); formData.details = [createDetailRow()] })
|
|
|
+const unwrapResult = (result: any) => (result && result.data !== undefined ? result.data : result)
|
|
|
+
|
|
|
+const toTimestamp = (value: any) => {
|
|
|
+ if (value === null || value === undefined || value === '') return undefined
|
|
|
+ if (value instanceof Date) return value.getTime()
|
|
|
+ if (typeof value === 'number') return value
|
|
|
+ const text = String(value).trim()
|
|
|
+ if (/^\d+$/.test(text)) return Number(text)
|
|
|
+ const normalized = text.includes('T') ? text : text.replace(' ', 'T')
|
|
|
+ const parsed = new Date(normalized)
|
|
|
+ if (Number.isNaN(parsed.getTime())) return undefined
|
|
|
+ return parsed.getTime()
|
|
|
+}
|
|
|
+
|
|
|
+const buildPayload = () => ({
|
|
|
+ id: isEdit.value ? routeId.value : undefined,
|
|
|
+ applyTime: toTimestamp(formData.applyTime || applicationData.value?.applyTime),
|
|
|
+ businessType: formData.businessType || undefined,
|
|
|
+ department: formData.department || undefined,
|
|
|
+ remark: formData.remark || undefined,
|
|
|
+ details: (formData.details || []).map((detail: any) => ({
|
|
|
+ materialCode: detail.materialCode || '',
|
|
|
+ materialName: detail.materialName || '',
|
|
|
+ specification: detail.specification || '',
|
|
|
+ batch: detail.batch || '',
|
|
|
+ quantity: detail.quantity ?? 0,
|
|
|
+ unit: detail.unit || '',
|
|
|
+ remark: detail.remark || ''
|
|
|
+ }))
|
|
|
+})
|
|
|
+
|
|
|
+const applyResponseToForm = (data: any) => {
|
|
|
+ initFormData()
|
|
|
+ formData.applicantName = data?.applicantName || ''
|
|
|
+ formData.applyTime = toTimestamp(data?.applyTime)
|
|
|
+ formData.businessType = data?.businessType || ''
|
|
|
+ formData.department = data?.department || ''
|
|
|
+ formData.remark = data?.remark || ''
|
|
|
+ formData.details = (data?.details && data.details.length)
|
|
|
+ ? data.details.map((detail: any) => ({
|
|
|
+ materialCode: detail.materialCode || '',
|
|
|
+ materialName: detail.materialName || '',
|
|
|
+ specification: detail.specification || '',
|
|
|
+ batch: detail.batch || '',
|
|
|
+ quantity: detail.quantity ?? 0,
|
|
|
+ unit: detail.unit || '',
|
|
|
+ remark: detail.remark || ''
|
|
|
+ }))
|
|
|
+ : [createDetailRow()]
|
|
|
+}
|
|
|
+
|
|
|
+const fetchApplication = async () => {
|
|
|
+ if (isCreate.value) {
|
|
|
+ initFormData()
|
|
|
+ formData.details = [createDetailRow()]
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!isIqcModule.value) {
|
|
|
+ initFormData()
|
|
|
+ formData.details = [createDetailRow()]
|
|
|
+ return
|
|
|
+ }
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const result = await getIqcApply(routeId.value)
|
|
|
+ const data = unwrapResult(result)
|
|
|
+ applicationData.value = data
|
|
|
+ applyResponseToForm(data)
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取申请详情失败')
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const saveApplication = async () => {
|
|
|
+ if (!isIqcModule.value) return
|
|
|
+ const payload = buildPayload()
|
|
|
+ if (!payload.applyTime) {
|
|
|
+ ElMessage.warning('申请时间不能为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (isCreate.value) {
|
|
|
+ await createIqcApply(payload)
|
|
|
+ } else {
|
|
|
+ await updateIqcApply(payload)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ fetchApplication()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|