|
|
@@ -11,70 +11,87 @@
|
|
|
destroyOnClose
|
|
|
:bodyStyle="{ padding: '20px' }"
|
|
|
>
|
|
|
- <!-- 查看模式 -->
|
|
|
- <div class="que-container" v-if="mode === 'view'">
|
|
|
- <div class="que-status">
|
|
|
- <div>矿井状态:</div>
|
|
|
- <div>
|
|
|
- <span :class="getStatusClass(currentRecord?.mineLinkStatus)" class="status-dot">
|
|
|
- {{ getStatusText(currentRecord?.mineLinkStatus) }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="que-item"
|
|
|
- v-for="(item, index) in queList"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <div class="que-details">
|
|
|
- <div class="que-field">
|
|
|
- <span class="que-value que-goafName">{{ item.goafName || '-' }}</span>
|
|
|
- </div>
|
|
|
- <div class="que-field">
|
|
|
- <span class="que-label">问题描述:</span>
|
|
|
- <span class="que-value">{{ item.queCon || '-' }}</span>
|
|
|
- </div>
|
|
|
- <div class="que-field time-field">
|
|
|
- <span class="que-label">时间:</span>
|
|
|
- <span class="que-value">{{ formatDate(item.startTime) || '-' }}</span>
|
|
|
- <span class="time-separator">-----</span>
|
|
|
- <span class="que-value">{{ formatDate(item.endTime) || '-' }}</span>
|
|
|
+ <a-form
|
|
|
+ ref="formRef"
|
|
|
+ :model="formData"
|
|
|
+ :rules="formRules"
|
|
|
+ layout="horizontal"
|
|
|
+ :label-col="{ span: 4 }"
|
|
|
+ :wrapper-col="{ span: 20 }"
|
|
|
+ >
|
|
|
+ <!-- 查看模式 -->
|
|
|
+ <div class="que-container" v-if="mode === 'view'">
|
|
|
+ <div class="que-status">
|
|
|
+ <div>矿井状态:</div>
|
|
|
+ <div>
|
|
|
+ <span :class="getStatusClass(currentRecord?.mineLinkStatus)" class="status-dot">
|
|
|
+ {{ getStatusText(currentRecord?.mineLinkStatus) }}
|
|
|
+ </span>
|
|
|
</div>
|
|
|
- <div class="que-field">
|
|
|
- <span class="que-label">参数:</span>
|
|
|
- <span class="que-value">{{ (item.param || '-').replace(/,/g, ' ') }}</span>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="que-item"
|
|
|
+ v-for="(item, index) in queList"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <div class="que-details">
|
|
|
+ <div class="que-field">
|
|
|
+ <span class="que-value que-goafName">{{ item.goafName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="que-field">
|
|
|
+ <span class="que-label">问题描述:</span>
|
|
|
+ <span class="que-value">{{ item.queCon || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="que-field time-field">
|
|
|
+ <span class="que-label">时间:</span>
|
|
|
+ <span class="que-value">{{ formatDate(item.startTime) || '-' }}</span>
|
|
|
+ <span class="time-separator">-----</span>
|
|
|
+ <span class="que-value">{{ formatDate(item.endTime) || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="que-field">
|
|
|
+ <span class="que-label">参数:</span>
|
|
|
+ <span class="que-value">{{ (item.param || '-').replace(/,/g, ' ') }}</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 编辑/新增模式 -->
|
|
|
- <div v-else class="edit-container">
|
|
|
- <!-- 动态渲染topFormSchema字段(编辑/新增模式) -->
|
|
|
- <div class="mine-base-info" v-if="mode === 'add'">
|
|
|
- <div class="form-item" v-for="schema in topFormSchema" :key="schema.field">
|
|
|
- <div class="form-label">{{ schema.label }}:</div>
|
|
|
- <component
|
|
|
- :is="getComponent(schema.component)"
|
|
|
- v-model:value="currentRecord[schema.field]"
|
|
|
- v-bind="schema.componentProps"
|
|
|
- :placeholder="`请输入${schema.label}`"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
+
|
|
|
+ <!-- 编辑/新增模式 -->
|
|
|
+ <div v-else class="edit-container">
|
|
|
+ <!-- 动态渲染topFormSchema字段(编辑/新增模式) -->
|
|
|
+ <div class="mine-base-info" v-if="mode === 'add'">
|
|
|
+ <a-form-item
|
|
|
+ v-for="schema in topFormSchema"
|
|
|
+ :key="schema.field"
|
|
|
+ :name="schema.field"
|
|
|
+ :label="schema.label"
|
|
|
+ :rules="schema.rules"
|
|
|
+ >
|
|
|
+ <component
|
|
|
+ :is="getComponent(schema.component)"
|
|
|
+ v-model:value="currentRecord[schema.field]"
|
|
|
+ v-bind="schema.componentProps"
|
|
|
+ :placeholder="`请输入${schema.label}`"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
|
- <!-- 问题项编辑区 -->
|
|
|
- <div
|
|
|
- class="que-item"
|
|
|
- v-for="(item, index) in queList"
|
|
|
- :key="item.orderNum || index"
|
|
|
- >
|
|
|
- <div class="que-index">问题 {{ index + 1 }}</div>
|
|
|
- <div class="edit-fields">
|
|
|
- <template v-for="schema in formSchema" :key="schema.field">
|
|
|
- <div class="form-item">
|
|
|
- <div class="form-label">{{ schema.label }}:</div>
|
|
|
+ <!-- 问题项编辑区 -->
|
|
|
+ <div
|
|
|
+ class="que-item"
|
|
|
+ v-for="(item, index) in queList"
|
|
|
+ :key="item.orderNum || index"
|
|
|
+ >
|
|
|
+ <div class="que-index">问题 {{ index + 1 }}</div>
|
|
|
+ <div class="edit-fields">
|
|
|
+ <a-form-item
|
|
|
+ v-for="schema in formSchema"
|
|
|
+ :key="`${schema.field}-${index}`"
|
|
|
+ :name="[`queList`, index, schema.field]"
|
|
|
+ :label="schema.label"
|
|
|
+ :rules="schema.rules"
|
|
|
+ >
|
|
|
<component
|
|
|
:is="getComponent(schema.component)"
|
|
|
v-model:value="item[schema.field]"
|
|
|
@@ -82,41 +99,41 @@
|
|
|
:placeholder="`请输入${schema.label}`"
|
|
|
style="width: 100%"
|
|
|
/>
|
|
|
+ </a-form-item>
|
|
|
+ <div class="form-actions">
|
|
|
+ <a-button
|
|
|
+ type="text"
|
|
|
+ danger
|
|
|
+ @click="removeItem(index)"
|
|
|
+ :disabled="queList.length <= 1"
|
|
|
+ >
|
|
|
+ 删除
|
|
|
+ </a-button>
|
|
|
</div>
|
|
|
- </template>
|
|
|
- <div class="form-actions">
|
|
|
- <a-button
|
|
|
- type="text"
|
|
|
- danger
|
|
|
- @click="removeItem(index)"
|
|
|
- :disabled="queList.length <= 1"
|
|
|
- >
|
|
|
- 删除
|
|
|
- </a-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
|
- <a-button
|
|
|
- type="dashed"
|
|
|
- class="add-btn"
|
|
|
- @click="addNewItem"
|
|
|
- >
|
|
|
- <plus-outlined /> 新增问题
|
|
|
- </a-button>
|
|
|
- </div>
|
|
|
+ <a-button
|
|
|
+ type="dashed"
|
|
|
+ class="add-btn"
|
|
|
+ @click="addNewItem"
|
|
|
+ >
|
|
|
+ <plus-outlined /> 新增问题
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ </a-form>
|
|
|
</BasicModal>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, computed } from 'vue';
|
|
|
+import { ref, computed, reactive, watch } from 'vue';
|
|
|
import { BasicModal, useModalInner } from '/@/components/Modal';
|
|
|
import { formSchema, topFormSchema } from '../dataQuality.data';
|
|
|
-import { Button as AButton, Select, Input, DatePicker } from 'ant-design-vue';
|
|
|
+import { Select, Input, DatePicker, message, } from 'ant-design-vue';
|
|
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
|
|
import dayjs, { Dayjs } from 'dayjs';
|
|
|
-// 请根据实际项目路径调整 MineCascader 引入路径
|
|
|
import MineCascader from '/@/components/Form/src/jeecg/components/MineCascader/MineCascader.vue';
|
|
|
+import type { FormInstance, RuleObject } from 'ant-design-vue/es/form';
|
|
|
|
|
|
// 组件映射表
|
|
|
const componentMap = {
|
|
|
@@ -143,6 +160,75 @@ const currentRecord = ref<any>({
|
|
|
// 问题列表
|
|
|
const queList = ref<any[]>([]);
|
|
|
|
|
|
+// 表单实例(用于校验)
|
|
|
+const formRef = ref<FormInstance>();
|
|
|
+// 表单数据聚合(适配Form组件的model)
|
|
|
+const formData = reactive({
|
|
|
+ mineCode: '',
|
|
|
+ queList: queList.value
|
|
|
+});
|
|
|
+
|
|
|
+// 合并表单规则(从schema中提取)
|
|
|
+const formRules = reactive({
|
|
|
+ mineCode: topFormSchema.find(item => item.field === 'mineCode')?.rules || [],
|
|
|
+ queList: {
|
|
|
+ type: 'array',
|
|
|
+ required: true,
|
|
|
+ validator: (rule: RuleObject, value: any[], callback: Function) => {
|
|
|
+ // 校验每个问题项
|
|
|
+ if (value.length === 0) {
|
|
|
+ callback(new Error('至少需要填写一条问题信息'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 逐个校验问题项的必填字段
|
|
|
+ for (let i = 0; i < value.length; i++) {
|
|
|
+ const item = value[i];
|
|
|
+ // 校验工作面名称
|
|
|
+ if (!item.goafName) {
|
|
|
+ callback(new Error(`第${i+1}条问题:工作面名称不能为空`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验问题描述
|
|
|
+ if (!item.queCon) {
|
|
|
+ callback(new Error(`第${i+1}条问题:问题描述不能为空`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验开始时间
|
|
|
+ if (!item.startTime) {
|
|
|
+ callback(new Error(`第${i+1}条问题:开始时间不能为空`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验结束时间
|
|
|
+ if (!item.endTime) {
|
|
|
+ callback(new Error(`第${i+1}条问题:结束时间不能为空`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验结束时间不能早于开始时间
|
|
|
+ if (dayjs(item.endTime).isBefore(dayjs(item.startTime))) {
|
|
|
+ callback(new Error(`第${i+1}条问题:结束时间不能早于开始时间`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验参数
|
|
|
+ if (!item.param) {
|
|
|
+ callback(new Error(`第${i+1}条问题:参数不能为空`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 监听queList变化,同步到formData
|
|
|
+watch(queList, (newVal) => {
|
|
|
+ formData.queList = newVal;
|
|
|
+}, { deep: true });
|
|
|
+
|
|
|
+// 监听currentRecord变化,同步mineCode到formData
|
|
|
+watch(() => currentRecord.value.mineCode, (newVal) => {
|
|
|
+ formData.mineCode = newVal;
|
|
|
+});
|
|
|
+
|
|
|
// 根据组件名获取对应组件
|
|
|
const getComponent = (componentName: string) => {
|
|
|
return componentMap[componentName as keyof typeof componentMap];
|
|
|
@@ -179,6 +265,8 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
|
|
|
updateTime: '',
|
|
|
createTime: ''
|
|
|
};
|
|
|
+ // 同步mineCode到formData
|
|
|
+ formData.mineCode = currentRecord.value.mineCode;
|
|
|
|
|
|
// 初始化问题列表
|
|
|
if (mode.value === 'add') {
|
|
|
@@ -205,6 +293,8 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
|
|
|
startTime: item.startTime ? dayjs(item.startTime) : null,
|
|
|
endTime: item.endTime ? dayjs(item.endTime) : null
|
|
|
}));
|
|
|
+ // 同步到formData
|
|
|
+ formData.queList = queList.value;
|
|
|
} catch (error) {
|
|
|
console.error('解析问题数据失败:', error);
|
|
|
queList.value = [{
|
|
|
@@ -217,6 +307,10 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
|
|
|
}];
|
|
|
}
|
|
|
}
|
|
|
+ // 重置表单校验状态
|
|
|
+ if (formRef.value) {
|
|
|
+ formRef.value.resetFields();
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
// 模态框标题计算属性
|
|
|
@@ -253,30 +347,40 @@ const removeItem = (index: number) => {
|
|
|
// 提交表单处理
|
|
|
async function handleSubmit() {
|
|
|
try {
|
|
|
+ // 查看模式直接提交
|
|
|
+ if (mode.value === 'view') {
|
|
|
+ closeModal();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 表单校验
|
|
|
+ if (!formRef.value) return;
|
|
|
+ const validateResult = await formRef.value.validate();
|
|
|
+ if (!validateResult) return;
|
|
|
+
|
|
|
setModalProps({ confirmLoading: true });
|
|
|
- // 1. 处理问题列表数据(空日期字段置空,避免空字符串)
|
|
|
+ // 2. 处理问题列表数据(空日期字段置空,避免空字符串)
|
|
|
const submitQueList = queList.value.map((item) => ({
|
|
|
...item,
|
|
|
startTime: item.startTime ? item.startTime.format('YYYY-MM-DD HH:mm:ss') : null,
|
|
|
endTime: item.endTime ? item.endTime.format('YYYY-MM-DD HH:mm:ss') : null,
|
|
|
}));
|
|
|
- // 2. 构造完整提交数据(修正 createTime/updateTime 逻辑)
|
|
|
+ // 3. 构造完整提交数据
|
|
|
const now = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
|
const result = {
|
|
|
...currentRecord.value,
|
|
|
queJson: JSON.stringify(submitQueList),
|
|
|
- // 新增模式:创建时间=当前时间,状态=未解决;编辑模式:保留原有创建时间
|
|
|
createTime: mode.value === 'add' ? now : (currentRecord.value.createTime || now),
|
|
|
- // 无论新增/编辑,更新时间都为当前时间
|
|
|
updateTime: now,
|
|
|
- // 新增模式默认未解决,编辑模式保留原有状态
|
|
|
isOk: mode.value === 'add' ? false : currentRecord.value.isOk,
|
|
|
};
|
|
|
console.log('最终提交数据:', result);
|
|
|
emit('success', result);
|
|
|
closeModal();
|
|
|
- } catch (error) {
|
|
|
+ } catch (error: any) {
|
|
|
console.error('提交失败:', error);
|
|
|
+ // 显示校验错误提示
|
|
|
+ message.error(error.message || '表单校验失败,请检查必填项');
|
|
|
} finally {
|
|
|
setModalProps({ confirmLoading: false });
|
|
|
}
|