373 lines
12 KiB
Vue
373 lines
12 KiB
Vue
<template>
|
|
<el-dialog
|
|
:model-value="visible"
|
|
title="新增樣板"
|
|
modal-penetrable
|
|
style="max-width: 800px; width: 90%"
|
|
@close="onClose"
|
|
>
|
|
<!-- 通用對話框 -->
|
|
<VerificationSettingDialog
|
|
v-model:visible="dialogVisibility.verification"
|
|
@add="(item) => addItem('verification', item)"
|
|
/>
|
|
<InspectionItemDialog
|
|
v-model:visible="dialogVisibility.inspection"
|
|
@add="(item) => addItem('inspection', item)"
|
|
/>
|
|
<CheckItemsDialog
|
|
v-model:visible="dialogVisibility.checkItems"
|
|
@add="(item) => addItem('checkItems', item)"
|
|
/>
|
|
|
|
<el-form :model="form">
|
|
<el-divider content-position="left">樣板資訊</el-divider>
|
|
<el-row :gutter="20">
|
|
<el-col :xs="24" :sm="12">
|
|
<el-form-item label="電廠">
|
|
<el-select v-model="form.factory" placeholder="請選擇電廠">
|
|
<el-option label="四磺子坪" value="四磺子坪" />
|
|
<el-option label="硫磺子坪" value="硫磺子坪" />
|
|
<el-option label="大清水" value="大清水" />
|
|
<el-option label="小清水" value="小清水" />
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12">
|
|
<el-form-item label="模板">
|
|
<el-select v-model="form.template" placeholder="請選擇模板類型">
|
|
<el-option label="巡檢表" value="1" />
|
|
<el-option label="點檢表" value="2" />
|
|
<el-option label="高壓特每日自動檢查表" value="3" />
|
|
<el-option label="高壓特每月自動檢查表" value="4" />
|
|
<el-option label="一班作業安全許可申請表" value="5" />
|
|
<el-option label="侷限作業安全許可申請表" value="6" />
|
|
<el-option label="動火作業安全許可申請表" value="7" />
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="12">
|
|
<el-form-item label="母版">
|
|
<el-select v-model="form.isParent" placeholder="請選擇">
|
|
<el-option label="是" value="是" />
|
|
<el-option label="否" value="否" />
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="24">
|
|
<el-form-item label="樣板名稱">
|
|
<el-input
|
|
v-model="form.templateName"
|
|
placeholder="請輸入樣板名稱"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :xs="24" :sm="24">
|
|
<el-form-item label="備註">
|
|
<el-input
|
|
v-model="form.remark"
|
|
placeholder="請輸入備註"
|
|
type="textarea"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<!-- 動態渲染樣板內容欄位 -->
|
|
<template v-if="activeSchema">
|
|
<template v-for="section in activeSchema.sections" :key="section.title">
|
|
<el-divider content-position="left">{{ section.title }}</el-divider>
|
|
<el-row :gutter="20">
|
|
<el-col
|
|
v-for="field in section.fields"
|
|
:key="field.key"
|
|
:xs="24"
|
|
:sm="field.span"
|
|
>
|
|
<el-form-item :label="field.label">
|
|
<!-- 下拉選單 -->
|
|
<el-select
|
|
v-if="field.type === 'select'"
|
|
v-model="form[field.key]"
|
|
:placeholder="`請選擇${field.label}`"
|
|
>
|
|
<el-option
|
|
v-for="option in field.options"
|
|
:key="option.value"
|
|
:label="option.label"
|
|
:value="option.value"
|
|
/>
|
|
</el-select>
|
|
<!-- 多行文本 -->
|
|
<el-input
|
|
v-else-if="field.type === 'textarea'"
|
|
v-model="form[field.key]"
|
|
type="textarea"
|
|
:rows="3"
|
|
:placeholder="`請輸入${field.label}`"
|
|
/>
|
|
<!-- 一般文本輸入 -->
|
|
<el-input
|
|
v-else
|
|
v-model="dynamicFields[field.key]"
|
|
:placeholder="`請輸入${field.label}`"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</template>
|
|
|
|
<!-- 動態渲染表格 -->
|
|
<template v-for="table in activeSchema.tables" :key="table.key">
|
|
<el-row :align="'middle'" justify="space-between">
|
|
<h3>{{ table.title }}</h3>
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
@click="openDialog(table.dialogType)"
|
|
>
|
|
{{ table.addButtonText }}
|
|
</el-button>
|
|
</el-row>
|
|
|
|
<!-- 使用分頁表格或一般表格 -->
|
|
<PaginatedTable
|
|
v-if="table.usePagination"
|
|
:data="dynamicTableData[table.key] || []"
|
|
:page-sizes="[5, 10]"
|
|
row-key="index"
|
|
>
|
|
<el-table-column
|
|
v-for="column in table.columns"
|
|
:key="column.prop"
|
|
:prop="column.prop"
|
|
:label="column.label"
|
|
:width="column.width"
|
|
/>
|
|
<el-table-column label="功能" width="140" fixed="right">
|
|
<template #default="scope">
|
|
<el-button size="small" type="primary" plain>修改</el-button>
|
|
<el-button
|
|
size="small"
|
|
type="danger"
|
|
plain
|
|
@click="deleteItem(table.key, scope.$index)"
|
|
>
|
|
刪除
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</PaginatedTable>
|
|
|
|
<el-table
|
|
v-else
|
|
:data="dynamicTableData[table.key] || []"
|
|
:border="true"
|
|
>
|
|
<el-table-column
|
|
v-for="column in table.columns"
|
|
:key="column.prop"
|
|
:prop="column.prop"
|
|
:label="column.label"
|
|
:width="column.width"
|
|
/>
|
|
<el-table-column
|
|
label="功能"
|
|
min-width="80"
|
|
width="140"
|
|
fixed="right"
|
|
>
|
|
<template #default="scope">
|
|
<el-button size="small" type="primary" plain>修改</el-button>
|
|
<el-button
|
|
size="small"
|
|
type="danger"
|
|
plain
|
|
@click="deleteItem(table.key, scope.$index)"
|
|
>
|
|
刪除
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</template>
|
|
|
|
<!-- 動態渲染驗證區塊 -->
|
|
<template v-if="activeSchema.verification?.enabled">
|
|
<el-divider content-position="left">樣板查證</el-divider>
|
|
<el-row :align="'middle'" justify="space-between">
|
|
<h3>{{ activeSchema.verification.title }}</h3>
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
@click="openDialog(activeSchema.verification.dialogType)"
|
|
>
|
|
{{ activeSchema.verification.addButtonText }}
|
|
</el-button>
|
|
</el-row>
|
|
|
|
<el-table :data="dynamicTableData.verification || []" :border="true">
|
|
<el-table-column
|
|
v-for="column in activeSchema.verification.columns"
|
|
:key="column.prop"
|
|
:prop="column.prop"
|
|
:label="column.label"
|
|
:width="column.width"
|
|
/>
|
|
<el-table-column
|
|
label="功能"
|
|
min-width="80"
|
|
width="140"
|
|
fixed="right"
|
|
>
|
|
<template #default="scope">
|
|
<el-button size="small" type="primary" plain>修改</el-button>
|
|
<el-button
|
|
size="small"
|
|
type="danger"
|
|
plain
|
|
@click="deleteItem('verification', scope.$index)"
|
|
>
|
|
刪除
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</template>
|
|
</template>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="onClose">取消</el-button>
|
|
<el-button type="primary" @click="onConfirm">確定</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, watch, reactive } from "vue";
|
|
import PaginatedTable from "../Common/PaginatedTable.vue";
|
|
import VerificationSettingDialog from "./VerificationSettingDialog.vue";
|
|
import InspectionItemDialog from "./InspectionItemDialog.vue";
|
|
import CheckItemsDialog from "./CheckItemsDialog.vue";
|
|
import {
|
|
getTemplateSchema,
|
|
initializeTableData,
|
|
initializeFieldData,
|
|
} from "../../constants/templateSchemas.js";
|
|
|
|
const props = defineProps({
|
|
visible: { type: Boolean, default: false },
|
|
form: { type: Object, required: true },
|
|
});
|
|
|
|
const emit = defineEmits(["update:visible", "confirm", "close"]);
|
|
|
|
// 當前模板的 schema
|
|
const activeSchema = computed(() => {
|
|
const schema = getTemplateSchema(props.form.template);
|
|
if (!schema) return null;
|
|
|
|
// 過濾只顯示於樣板的內容
|
|
return {
|
|
...schema,
|
|
sections: schema.sections?.filter(s => s.showInTemplate !== false) || [],
|
|
tables: schema.tables?.filter(t => t.showInTemplate !== false) || [],
|
|
verification: schema.verification, // 查證始終顯示
|
|
};
|
|
});
|
|
|
|
// 動態欄位資料
|
|
const dynamicFields = reactive({});
|
|
|
|
// 動態表格資料
|
|
const dynamicTableData = reactive({});
|
|
|
|
// 對話框顯示狀態
|
|
const dialogVisibility = reactive({
|
|
dutyLog: false,
|
|
handover: false,
|
|
inspection: false,
|
|
verification: false,
|
|
checkItems: false,
|
|
});
|
|
|
|
// 監聽模板類型變化,重新初始化資料
|
|
watch(
|
|
() => props.form.template,
|
|
(newTemplate) => {
|
|
if (!newTemplate) return;
|
|
|
|
const schema = getTemplateSchema(newTemplate);
|
|
if (!schema) return;
|
|
|
|
// 重置動態欄位
|
|
Object.keys(dynamicFields).forEach((key) => delete dynamicFields[key]);
|
|
Object.assign(dynamicFields, initializeFieldData(schema));
|
|
|
|
// 重置動態表格
|
|
Object.keys(dynamicTableData).forEach(
|
|
(key) => delete dynamicTableData[key]
|
|
);
|
|
Object.assign(dynamicTableData, initializeTableData(schema));
|
|
}
|
|
);
|
|
|
|
// 打開對話框
|
|
function openDialog(dialogType) {
|
|
if (dialogType === "dutyLog") {
|
|
dialogVisibility.dutyLog = true;
|
|
} else if (dialogType === "handover") {
|
|
dialogVisibility.handover = true;
|
|
} else if (dialogType === "inspection") {
|
|
dialogVisibility.inspection = true;
|
|
} else if (dialogType === "verification") {
|
|
dialogVisibility.verification = true;
|
|
} else if (dialogType === "checkItems") {
|
|
dialogVisibility.checkItems = true;
|
|
}
|
|
// 其他 dialogType 可以根據需要擴展
|
|
}
|
|
|
|
// 通用新增項目方法
|
|
function addItem(tableKey, item) {
|
|
if (!dynamicTableData[tableKey]) {
|
|
dynamicTableData[tableKey] = [];
|
|
}
|
|
const arr = dynamicTableData[tableKey];
|
|
arr.push({ index: arr.length + 1, ...item });
|
|
}
|
|
|
|
// 刪除項目
|
|
function deleteItem(tableKey, index) {
|
|
if (dynamicTableData[tableKey]) {
|
|
dynamicTableData[tableKey].splice(index, 1);
|
|
// 重新計算項次
|
|
dynamicTableData[tableKey].forEach((item, idx) => {
|
|
item.index = idx + 1;
|
|
});
|
|
}
|
|
}
|
|
|
|
function onClose() {
|
|
emit("update:visible", false);
|
|
emit("close");
|
|
}
|
|
|
|
function onConfirm() {
|
|
// 可以在這裡整合 dynamicFields 和 dynamicTableData 到 form
|
|
const templateData = {
|
|
...props.form,
|
|
fields: dynamicFields,
|
|
tables: dynamicTableData,
|
|
};
|
|
emit("confirm", templateData);
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.el-divider--horizontal {
|
|
margin-top: 30px;
|
|
margin-bottom: 20px;
|
|
}
|
|
</style>
|