Commit 09609131d9b5854e4b23076303ea2bcf4a2b0cb5

Authored by gesilong
1 parent 9552dd98

commit: 巡检保养相关联调修改

... ... @@ -32,3 +32,23 @@ export const updateInspectionStatus = (params) => {
32 32 params,
33 33 });
34 34 };
  35 +
  36 +/**
  37 + * 详情
  38 + */
  39 +export const getInsPlanDetail = (params) => {
  40 + return defHttp.get<any>({
  41 + url: `/inspectionPlan/detail`,
  42 + params,
  43 + });
  44 +};
  45 +
  46 +/**
  47 + * 更新
  48 + */
  49 +export const updateInsStatus = (params) => {
  50 + return defHttp.post<any>({
  51 + url: `/inspectionPlan/changeStatus`,
  52 + params,
  53 + });
  54 +};
... ...
... ... @@ -23,3 +23,22 @@ export const deleteInsRecord = (params) => {
23 23 params,
24 24 });
25 25 };
  26 +/**
  27 + * 新增
  28 + */
  29 +export const saveInsRecord = (params) => {
  30 + return defHttp.post<any>({
  31 + url: `/inspectionRecord/save`,
  32 + params,
  33 + });
  34 +};
  35 +
  36 +/**
  37 + * 详情
  38 + */
  39 +export const getInsRecordDetail = (params) => {
  40 + return defHttp.get<any>({
  41 + url: `/inspectionRecord/detail`,
  42 + params,
  43 + });
  44 +};
... ...
... ... @@ -24,6 +24,16 @@ export const deleteServePlan = (params) => {
24 24 };
25 25
26 26 /**
  27 + * 详情
  28 + */
  29 +export const getPreserveDetail = (params) => {
  30 + return defHttp.get<any>({
  31 + url: `/preservePlan/detail`,
  32 + params,
  33 + });
  34 +};
  35 +
  36 +/**
27 37 * 更新
28 38 */
29 39 export const updateServiceStatus = (params) => {
... ... @@ -32,3 +42,13 @@ export const updateServiceStatus = (params) => {
32 42 params,
33 43 });
34 44 };
  45 +
  46 +/**
  47 + * 新增
  48 + */
  49 +export const savePreservePlan = (params) => {
  50 + return defHttp.post<any>({
  51 + url: `/preservePlan/save`,
  52 + params,
  53 + });
  54 +};
... ...
... ... @@ -22,3 +22,34 @@ export const deleteServeRecord = (params) => {
22 22 params,
23 23 });
24 24 };
  25 +/**
  26 + * 根据保养计划获取保养明细分页接口
  27 + */
  28 +export const serveRecordDetail = (params) => {
  29 + const { page, pageSize } = params;
  30 + const otherParams = omit(params, ['page', 'pageSize']);
  31 + return defHttp.post<any>({
  32 + url: `/preservePlan/pageDetail?page=${page}&pageSize=${pageSize}`,
  33 + params: otherParams,
  34 + });
  35 +};
  36 +
  37 +
  38 +/**
  39 + * 新增
  40 + */
  41 +export const savePreserveRecord = (params) => {
  42 + return defHttp.post<any>({
  43 + url: `/preserveRecord/save`,
  44 + params,
  45 + });
  46 +};
  47 +/**
  48 + * 详情
  49 + */
  50 +export const getRecordDetail = (params) => {
  51 + return defHttp.get<any>({
  52 + url: `/preserveRecord/detail`,
  53 + params,
  54 + });
  55 +};
... ...
1 1 export default {
2 2 listText: '保养计划',
  3 + preserveDetailText: '保养明细',
3 4 preserveNameText: '计划名称',
4 5 preserveCodeText: '计划编号',
5 6 statusText: '状态',
... ...
... ... @@ -3,6 +3,7 @@
3 3 ref="tree"
4 4 class="organization-tree flex relative items-center py-4"
5 5 :class="foldFlag ? '' : 'pl-4'"
  6 + :style="treeStyle"
6 7 >
7 8 <div
8 9 class="cursor-pointer flex py-4 fold-icon absolute rounded svg:fill-gray-400 hover:bg-gray-200"
... ... @@ -33,8 +34,8 @@
33 34 import { useI18n } from '/@/hooks/web/useI18n';
34 35
35 36 const props = defineProps<OrganizationTreePropsType>();
36   -
37 37 const attrs = useAttrs();
  38 +
38 39 const tree = ref<Nullable<HTMLDivElement>>();
39 40 const emit = defineEmits(['select', 'register']);
40 41 const treeData = ref<TreeItem[]>([]);
... ... @@ -42,6 +43,7 @@
42 43 const treeExpandData = ref<string[]>([]);
43 44
44 45 const innerProps = ref<OrganizationTreePropsType>({});
  46 + const treeStyle = ref<any>({})
45 47
46 48 //获取所有父级id
47 49 function findForAllId(data: Recordable[] = [], arr: string[] = []) {
... ... @@ -59,11 +61,12 @@
59 61 selectedKeys.value = [];
60 62 }
61 63
62   - const foldFlag = ref(true);
  64 + const foldFlag = ref(false);
63 65 const handleFold = () => {
64 66 foldFlag.value = !unref(foldFlag);
65 67 };
66 68
  69 +
67 70 const setTreeHeight = () => {
68 71 const rect = getBoundingClientRect(unref(tree)!);
69 72 if (rect) {
... ... @@ -75,6 +78,12 @@
75 78 };
76 79
77 80 onMounted(async () => {
  81 + if (attrs?.isOpen) {
  82 + foldFlag.value = false;
  83 + treeStyle.value.height = '50vh'
  84 + }else {
  85 + treeStyle.value.height = '100vh'
  86 + }
78 87 let api:any;
79 88 if (attrs?.listType === 'equipment') {
80 89 api = getAllCategory()
... ... @@ -128,7 +137,7 @@
128 137
129 138 <style scoped lang="less">
130 139 .organization-tree {
131   - max-height: 100vh;
  140 + //max-height: 100vh;
132 141
133 142 .expand {
134 143 opacity: 0;
... ...
  1 +import insPlanModal from './insPlanModal.vue';
  2 +
  3 +export { insPlanModal };
... ...
  1 +<template>
  2 + <a-modal
  3 + v-model:visible="visible"
  4 + :title="modalTitle"
  5 + width="80vw"
  6 + @ok="handleOk"
  7 + @cancel="handleCancel"
  8 + >
  9 + <a-form :model="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }" style="margin-top: 32px" :rules="rules">
  10 + <a-row :gutter="16">
  11 + <a-col :span="12">
  12 + <a-form-item label="计划编号" name="code">
  13 + <a-input v-model:value="form.code" :disabled="isViewMode" />
  14 + </a-form-item>
  15 + </a-col>
  16 + <a-col :span="12">
  17 + <a-form-item label="计划名称" name="name">
  18 + <a-input v-model:value="form.name" :disabled="isViewMode" />
  19 + </a-form-item>
  20 + </a-col>
  21 + </a-row>
  22 + <a-row :gutter="16">
  23 + <a-col :span="12">
  24 + <a-form-item label="开始时间" name="startTime">
  25 + <a-date-picker
  26 + v-model:value="form.startTime"
  27 + :disabled="isViewMode"
  28 + placeholder="请选择"
  29 + style="width: 100%"
  30 + />
  31 + </a-form-item>
  32 + </a-col>
  33 + <a-col :span="12">
  34 + <a-form-item label="结束时间" name="endTime">
  35 + <a-date-picker
  36 + v-model:value="form.endTime"
  37 + :disabled="isViewMode"
  38 + placeholder="请选择"
  39 + style="width: 100%"
  40 + />
  41 + </a-form-item>
  42 + </a-col>
  43 + </a-row>
  44 + <a-row :gutter="16">
  45 + <a-col :span="12">
  46 + <a-form-item label="计划状态" name="status">
  47 + <a-select
  48 + v-model:value="form.status"
  49 + :disabled="isViewMode"
  50 + placeholder="请选择"
  51 + :options="[
  52 + {label:'未开始',value:'NOT_START'},
  53 + {label:'进行中',value:'UNDERWAY'},
  54 + {label:'已完成',value:'FINISH'},
  55 + {label:'停用',value:'STOP'},
  56 + ]"
  57 + >
  58 + </a-select>
  59 + </a-form-item>
  60 + </a-col>
  61 + </a-row>
  62 + <a-row :gutter="16">
  63 + <a-col :span="24">
  64 + <a-form-item label="计划备注" name="remark">
  65 + <a-textarea
  66 + v-model:value="form.remark"
  67 + :disabled="isViewMode"
  68 + >
  69 + </a-textarea>
  70 + </a-form-item>
  71 + </a-col>
  72 + </a-row>
  73 + <a-form-item label="巡检明细" name="tkCheckDetailsDTOList">
  74 + <div style="text-align: end">
  75 + <a-button class="editable-add-btn" type="primary" @click="handleAdd" style="margin-bottom: 8px" :disabled="isViewMode">
  76 + <template #icon>
  77 + <PlusOutlined/>
  78 + </template>
  79 + 新增
  80 + </a-button>
  81 + <a-table bordered :data-source="tableData" :columns="columns">
  82 + <template #code="{ text, record, index }">
  83 + <div>
  84 + <a-input v-model:value="record.code" :disabled="isViewMode"/>
  85 + </div>
  86 + </template>
  87 + <template #checkDeviceId="{ text, record, index }">
  88 + <div>
  89 + <a-select
  90 + v-model:value="record.checkDeviceId"
  91 + :options="Options"
  92 + :disabled="isViewMode"
  93 + :field-names="{ label: 'name', value: 'id' }"
  94 + placeholder="请选择"
  95 + />
  96 + </div>
  97 + </template>
  98 + <template #checkPlanId="{ text, record, index }">
  99 + <div>
  100 + <a-select
  101 + v-model:value="record.checkPlanId"
  102 + :options="planOptions"
  103 + :disabled="isViewMode"
  104 + :fieldNames="{ label: 'name', value: 'id' }"
  105 + placeholder="请选择"
  106 + />
  107 + </div>
  108 + </template>
  109 + <template #planDetails="{ text, record, index }">
  110 + <div>
  111 + <a-textarea v-model:value="record.planDetails" :disabled="isViewMode"/>
  112 + </div>
  113 + </template>
  114 + <template #operation="{ text, record, index }">
  115 + <div>
  116 + <a-button type="link" @click="handleDelete(index)" :disabled="isViewMode">删除</a-button>
  117 + </div>
  118 + </template>
  119 + </a-table>
  120 + </div>
  121 + </a-form-item>
  122 + </a-form>
  123 + </a-modal>
  124 +</template>
  125 +<script setup lang="ts">
  126 +// 定义 props
  127 +import {onMounted, ref, watch} from "vue";
  128 +import {getLedgerList} from "/@/api/equipment/ledger";
  129 +import {getPlanList} from "/@/api/equipment/chenkPlan";
  130 +const Options = ref([]);
  131 +const planOptions = ref([]);
  132 +const props = defineProps({
  133 + initialData: {
  134 + type: Object,
  135 + default: () => ({
  136 + form: {
  137 + code: '',
  138 + name: '',
  139 + status: '',
  140 + enabled: '',
  141 + startTime: '',
  142 + endTime: '',
  143 + remark: '',
  144 + },
  145 + tableData: [],
  146 + }),
  147 + },
  148 + visible: {
  149 + type: Boolean,
  150 + default: false,
  151 + },
  152 + isViewMode: {
  153 + type: Boolean,
  154 + default: false,
  155 + },
  156 + modalTitle: {
  157 + type: String,
  158 + default: '',
  159 + },
  160 +});
  161 +
  162 +const columns = [
  163 + {
  164 + title: '明细编号',
  165 + dataIndex: 'code',
  166 + slots: { customRender: 'code' },
  167 + width: '160px'
  168 + },
  169 + {
  170 + title: '巡检设备',
  171 + dataIndex: 'checkDeviceId',
  172 + slots: { customRender: 'checkDeviceId' },
  173 + width: '180px'
  174 + },
  175 + {
  176 + title: '巡检方案',
  177 + dataIndex: 'checkPlanId',
  178 + slots: { customRender: 'checkPlanId' },
  179 + width: '180px'
  180 + },
  181 + {
  182 + title: '方案明细',
  183 + dataIndex: 'planDetails',
  184 + slots: { customRender: 'planDetails' },
  185 + width: '160px'
  186 + },
  187 + {
  188 + title: '操作',
  189 + dataIndex: 'operation',
  190 + slots: { customRender: 'operation' },
  191 + width: '120px'
  192 + }
  193 +];
  194 +const rules = {
  195 + code: [
  196 + { required: true, message: '请输入', trigger: 'blur' },
  197 + ],
  198 + name: [
  199 + { required: true, message: '请输入', trigger: 'blur' },
  200 + ],
  201 + remark: [
  202 + { required: true, message: '请输入', trigger: 'blur' },
  203 + ],
  204 + status: [{ required: true, message: '请选择', trigger: 'change' }],
  205 +};
  206 +const visible = ref(props.visible);
  207 +const isViewMode = ref(props.isViewMode);
  208 +const modalTitle = ref(props.modalTitle);
  209 +const form = ref({ ...props.initialData.form });
  210 +const tableData = ref([...props.initialData.tableData]);
  211 +const emit = defineEmits(['update:visible', 'submit']);
  212 +// 监听 visible 的变化
  213 +watch(
  214 + () => props.visible,
  215 + (newVal) => {
  216 + visible.value = newVal;
  217 + }
  218 +);
  219 +
  220 +watch(
  221 + () => props.isViewMode,
  222 + (newVal) => {
  223 + isViewMode.value = newVal;
  224 + }
  225 +);
  226 +
  227 +// 监听 visible 的变化并通知父组件
  228 +watch(
  229 + () => visible.value,
  230 + (newVal) => {
  231 + emit('update:visible', newVal);
  232 + }
  233 +);
  234 +
  235 +// 监听 initialData 的变化
  236 +watch(
  237 + () => props.initialData,
  238 + (newVal) => {
  239 + form.value = { ...newVal.form };
  240 + tableData.value = [...newVal.tableData];
  241 + },
  242 + { deep: true }
  243 +);
  244 +
  245 +
  246 +onMounted(() => {
  247 + fetchAgeOptions();
  248 +});
  249 +
  250 +const fetchAgeOptions = async () => {
  251 + try {
  252 + const response = await getLedgerList({ page: 1, pageSize: 999 }); // 调用接口
  253 + const response1 = await getPlanList({ page: 1, pageSize: 999, type: 'INSPECTION' }); // 调用接口
  254 + Options.value = response.items?.map((item: any) => {
  255 + return {
  256 + value: item?.id,
  257 + label: item?.name
  258 + }
  259 + })
  260 + planOptions.value = response1.items?.map((item: any) => {
  261 + return {
  262 + value: item?.id,
  263 + label: item?.name
  264 + }
  265 + });
  266 + } catch (error) {
  267 + console.error('失败:', error);
  268 + }
  269 +};
  270 +const handleAdd = () => {
  271 + tableData.value.push({
  272 + code: '',
  273 + checkDeviceId: undefined,
  274 + checkPlanId: undefined,
  275 + planDetails: '',
  276 + });
  277 +};
  278 +
  279 +const handleDelete = (index) => {
  280 + tableData.value.splice(index, 1);
  281 +};
  282 +
  283 +const handleOk = () => {
  284 + if (isViewMode.value) {
  285 + visible.value = false;
  286 + return;
  287 + }
  288 + const objData = { ...form.value, tkCheckDetailsDTOList: tableData.value };
  289 + emit('submit', objData); // 将数据提交给父组件
  290 + resetForm();
  291 +}
  292 +
  293 +const handleCancel = () => {
  294 + resetForm();
  295 + visible.value = false;
  296 +};
  297 +// 清空表单和表格数据
  298 +const resetForm = () => {
  299 + form.value = {
  300 + code: '',
  301 + name: '',
  302 + status: '',
  303 + enabled: '',
  304 + startTime: '',
  305 + endTime: '',
  306 + remark: '',
  307 + };
  308 + tableData.value = [];
  309 + isViewMode.value = false;
  310 +};
  311 +</script>
... ...
... ... @@ -3,7 +3,7 @@
3 3 <BasicTable :clickToRowSelect="false" @register="registerTable">
4 4 <template #toolbar>
5 5 <Authority value="api:yt:product:category:post">
6   - <Button type="primary">
  6 + <Button type="primary" @click="handleCreate">
7 7 {{ t('inspection.inspectionPlan.createCategoryText') }}
8 8 </Button>
9 9 </Authority>
... ... @@ -26,10 +26,16 @@
26 26 <TableAction
27 27 :actions="[
28 28 {
  29 + label: t('common.viewText'),
  30 + auth: 'api:yt:product:category:update',
  31 + icon: 'ant-design:eye-outlined',
  32 + onClick: handleViewDetail.bind(null, record),
  33 + },
  34 + {
29 35 label: t('common.editText'),
30 36 auth: 'api:yt:product:category:update',
31 37 icon: 'clarity:note-edit-line',
32   - // onClick: handleEdit.bind(null, record),
  38 + onClick: handleEdit.bind(null, record),
33 39 ifShow: () => record.status === 'NOT_START',
34 40 },
35 41 {
... ... @@ -77,17 +83,47 @@
77 83 />
78 84 </template>
79 85 </BasicTable>
  86 + <insPlanModal
  87 + v-model:visible="modalVisible"
  88 + :initial-data="initialData"
  89 + :is-view-mode="isViewMode"
  90 + @submit="handleSubmit"
  91 + :title="modalTitle"
  92 + />
80 93 </div>
81 94 </template>
82 95 <script setup lang="ts">
83 96 import { BasicTable, useTable, TableAction } from '/@/components/Table';
84   -import {deleteInspectionPlan, getInspectionPlanList, updateInspectionStatus} from '/@/api/inspection/inspectionPlan';
  97 +import {
  98 + deleteInspectionPlan,
  99 + getInspectionPlanList,
  100 + getInsPlanDetail,
  101 + updateInspectionStatus, updateInsStatus
  102 +} from '/@/api/inspection/inspectionPlan';
85 103 import { columns, searchFormSchema } from './index';
86 104 import { useI18n } from '/@/hooks/web/useI18n';
87   -import { Button, Tag } from 'ant-design-vue';
  105 +import {Button, message, Tag} from 'ant-design-vue';
88 106 import {useMessage} from "/@/hooks/web/useMessage";
  107 +import { insPlanModal } from "./components/index"
  108 +import {ref} from "vue";
  109 +import {dateFormat} from "/@/utils/common/compUtils";
89 110 const { t } = useI18n();
90 111 const { createMessage } = useMessage();
  112 +const modalVisible = ref(false);
  113 +const isViewMode = ref(false);
  114 +const modalTitle = ref('');
  115 +const initialData = ref({
  116 + form: {
  117 + code: '',
  118 + name: '',
  119 + status: '',
  120 + enabled: '',
  121 + startTime: '',
  122 + endTime: '',
  123 + remark: '',
  124 + },
  125 + tableData: [],
  126 +});
91 127
92 128 const [
93 129 registerTable,
... ... @@ -139,20 +175,21 @@ const handleReload = () => {
139 175 };
140 176
141 177 const handleUpdateStatus = async (record?: any,value?: string) => {
142   - let _status = '';
  178 + let id = record.id;
  179 + let status = '';
143 180 if (record.status === 'NOT_START') {
144   - _status = 'UNDERWAY'
  181 + status = 'UNDERWAY'
145 182 }else if(record.status === 'UNDERWAY'){
146   - _status = 'FINISH'
  183 + status = 'FINISH'
147 184 }else if(record.status === 'FINISH'){
148   - _status = 'STOP'
  185 + status = 'STOP'
149 186 }
150 187 if (value === 'STOP') {
151   - _status = 'STOP'
  188 + status = 'STOP'
152 189 }
153 190 try {
154 191 setLoading(true);
155   - await updateInspectionStatus({ ...record,status: _status });
  192 + await updateInsStatus({ id,status });
156 193 createMessage.success(t('common.editSuccessText'));
157 194 handleReload();
158 195 } catch (error) {
... ... @@ -162,4 +199,71 @@ const handleUpdateStatus = async (record?: any,value?: string) => {
162 199 }
163 200 }
164 201
  202 +const handleViewDetail = async (record?: any) => {
  203 + let id = record.id;
  204 + modalTitle.value = '查看';
  205 + try {
  206 + const response = await getInsPlanDetail({id})
  207 + initialData.value = {
  208 + form: response, // 表单数据
  209 + tableData: response.tkCheckDetailsDTOList, // 表格数据
  210 + };
  211 + modalVisible.value = true; // 打开弹框
  212 + isViewMode.value = true;
  213 + }catch (error) {
  214 + throw error;
  215 + }finally {
  216 +
  217 + }
  218 +}
  219 +
  220 +const handleEdit = async (record?: any) => {
  221 + let id = record.id;
  222 + modalTitle.value = '修改';
  223 + try {
  224 + const response = await getInsPlanDetail({id})
  225 + initialData.value = {
  226 + form: response, // 表单数据
  227 + tableData: response.tkCheckDetailsDTOList, // 表格数据
  228 + };
  229 + modalVisible.value = true; // 打开弹框
  230 + }catch (error) {
  231 + throw error;
  232 + }finally {
  233 +
  234 + }
  235 +}
  236 +
  237 +// 新增
  238 +const handleCreate = () => {
  239 + modalTitle.value = '新增';
  240 + initialData.value = {
  241 + form: {
  242 + code: '',
  243 + name: '',
  244 + status: '',
  245 + enabled: '',
  246 + startTime: '',
  247 + endTime: '',
  248 + remark: '',
  249 + },
  250 + tableData: [],
  251 + }
  252 + modalVisible.value = true;
  253 +};
  254 +
  255 +const handleSubmit = async (data) => {
  256 + const format = 'yyyy-MM-dd hh:mm:ss';
  257 + const _data = {
  258 + ...data,
  259 + startTime: dateFormat(data?.startTime, format),
  260 + endTime: dateFormat(data?.endTime, format),
  261 + }
  262 + modalVisible.value = false;
  263 + await updateInspectionStatus(_data)
  264 + message.success('提交成功');
  265 + handleReload()
  266 +};
  267 +
  268 +
165 269 </script>
... ...
  1 +import insRecordModal from './insRecordModal.vue';
  2 +
  3 +export { insRecordModal };
... ...
  1 +<template>
  2 + <a-modal
  3 + v-model:visible="visible"
  4 + :title="modalTitle"
  5 + width="80vw"
  6 + @ok="handleOk"
  7 + @cancel="handleCancel"
  8 + >
  9 + <a-form :model="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }" style="margin-top: 32px" :rules="rules">
  10 + <a-row :gutter="16">
  11 + <a-col :span="12">
  12 + <a-form-item label="巡检计划" name="inspectionPlanId">
  13 + <a-select
  14 + v-model:value="form.inspectionPlanId"
  15 + :options="planOptions"
  16 + :disabled="isViewMode"
  17 + placeholder="请选择"
  18 + @change="handleChange"
  19 + />
  20 + </a-form-item>
  21 + </a-col>
  22 + <a-col :span="12">
  23 + <a-form-item label="巡检计划编号" name="code">
  24 + <a-input v-model:value="form.code" :disabled="true" />
  25 + </a-form-item>
  26 + </a-col>
  27 + </a-row>
  28 + <a-row :gutter="16">
  29 + <a-col :span="12">
  30 + <a-form-item label="巡检日期" name="checkDate">
  31 + <a-date-picker
  32 + v-model:value="form.checkDate"
  33 + :disabled="isViewMode"
  34 + placeholder="请选择"
  35 + style="width: 100%"
  36 + />
  37 + </a-form-item>
  38 + </a-col>
  39 + <a-col :span="12">
  40 + <a-form-item label="巡检结果" name="recordResult">
  41 + <a-select
  42 + v-model:value="form.recordResult"
  43 + :options="[{label: '正常',value: true},{label: '异常',value: false}]"
  44 + :disabled="isViewMode"
  45 + placeholder="请选择"
  46 + >
  47 + </a-select>
  48 + </a-form-item>
  49 + </a-col>
  50 + </a-row>
  51 + <a-row :gutter="16">
  52 + <a-col :span="12">
  53 + <a-form-item label="巡检人" name="preserveByName">
  54 + <div style="display: flex">
  55 + <a-input
  56 + v-model:value="form.inspectorName"
  57 + placeholder="请选择"
  58 + :disabled="true"
  59 + >
  60 + </a-input>
  61 + <a-button
  62 + type="primary"
  63 + @click="goChoose"
  64 + :disabled="isViewMode"
  65 + >
  66 + 选人
  67 + </a-button>
  68 + </div>
  69 + </a-form-item>
  70 + </a-col>
  71 +
  72 + </a-row>
  73 + <a-form-item label="巡检明细" name="tkInspectionDetailsDTOList">
  74 + <a-table bordered :data-source="tableData" :columns="columns">
  75 + <template #tkDeviceAccountDTO="{ text, record, index }">
  76 + <div>
  77 + {{record?.tkDeviceAccountDTO?.name}}
  78 + </div>
  79 + </template>
  80 + <template #recordResult="{ text, record, index }">
  81 + <div>
  82 + <a-select
  83 + v-model:value="record.recordResult"
  84 + :options="[{label: '正常',value: true},{label: '异常',value: false}]"
  85 + :disabled="isViewMode"
  86 + placeholder="请选择"
  87 + />
  88 + </div>
  89 + </template>
  90 + <template #operation="{ text, record, index }">
  91 + <div>
  92 + <a-button type="link" @click="handleDelete(index)" :disabled="isViewMode">删除</a-button>
  93 + </div>
  94 + </template>
  95 + </a-table>
  96 + </a-form-item>
  97 + </a-form>
  98 + <a-modal
  99 + v-model:visible="userVisible"
  100 + :title="userModalTitle"
  101 + width="60vw"
  102 + height="50vh"
  103 + @ok="handleUserOk"
  104 + @cancel="handleUserCancel"
  105 + >
  106 + <div style="padding: 20px;display: flex">
  107 + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" isOpen="true"/>
  108 + <div style="margin-top: 20px;margin-left: 30px">
  109 + <a-radio-group v-model:value="selectedItem">
  110 + <template v-for="item in Options" :key="`${item.id}`">
  111 + <a-radio :style="radioStyle" :value="item">{{ item.username }}</a-radio>
  112 + </template>
  113 + </a-radio-group>
  114 + </div>
  115 + </div>
  116 + </a-modal>
  117 + </a-modal>
  118 +</template>
  119 +<script setup lang="ts">
  120 +import {computed, onMounted, reactive, ref, unref, watch} from "vue";
  121 +import {getInspectionPlanList, getInsPlanDetail} from "/@/api/inspection/inspectionPlan";
  122 +import { ApiTreeSelect } from '/@/components/Form';
  123 +import {OrganizationListItem} from "/@/api/system/model/systemModel";
  124 +import {getOrganizationList} from "/@/api/system/system";
  125 +import {getUserListByOrg} from "/@/api/equipment/ledger";
  126 +import {useUserStore} from "/@/store/modules/user";
  127 +import {useI18n} from "/@/hooks/web/useI18n";
  128 +import {useMessage} from "/@/hooks/web/useMessage";
  129 +import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
  130 +interface Value {
  131 + value?: string;
  132 + label?: string;
  133 +}
  134 +const rules = {
  135 + code: [{ required: true, message: '请输入', trigger: 'blur' },],
  136 + inspectionPlanId: [{ required: true, message: '请输入', trigger: 'blur' },],
  137 + orgId: [{ required: true, message: '请选择', trigger: 'change' }],
  138 + inspectorId: [{ required: true, message: '请选择', trigger: 'change' }],
  139 + inspectorName: [{ required: true, message: '请选择', trigger: 'change' }],
  140 +
  141 +};
  142 +const columns = [
  143 + {
  144 + title: '巡检设备',
  145 + dataIndex: 'tkDeviceAccountDTO',
  146 + slots: { customRender: 'tkDeviceAccountDTO' },
  147 + width: '180px'
  148 + },
  149 + {
  150 + title: '巡检内容',
  151 + dataIndex: 'planDetails',
  152 + width: '180px'
  153 + },
  154 + {
  155 + title: '巡检结果',
  156 + dataIndex: 'recordResult',
  157 + slots: { customRender: 'recordResult' },
  158 + width: '160px'
  159 + },
  160 + {
  161 + title: '操作',
  162 + dataIndex: 'operation',
  163 + slots: { customRender: 'operation' },
  164 + width: '120px'
  165 + }
  166 +];
  167 +
  168 +const props = defineProps({
  169 + initialData: {
  170 + type: Object,
  171 + default: () => ({
  172 + form: {
  173 + code: '',
  174 + inspectionPlanId: '',
  175 + inspectorId: '',
  176 + inspectorName: '',
  177 + checkDate: '',
  178 + recordResult: '',
  179 + orgId: '',
  180 + },
  181 + tableData: [],
  182 + }),
  183 + },
  184 + visible: {
  185 + type: Boolean,
  186 + default: false,
  187 + },
  188 + isViewMode: {
  189 + type: Boolean,
  190 + default: false,
  191 + },
  192 + modalTitle: {
  193 + type: String,
  194 + default: '',
  195 + },
  196 +});
  197 +const visible = ref(props.visible);
  198 +const isViewMode = ref(props.isViewMode);
  199 +const modalTitle = ref(props.modalTitle);
  200 +const form = ref({ ...props.initialData.form });
  201 +const tableData = ref([...props.initialData.tableData]);
  202 +const emit = defineEmits(['update:visible', 'submit']);
  203 +const planOptions = ref([]);
  204 +const Options = ref([]);
  205 +const userInfo = useUserStore();
  206 +const timespan = ref(Date.now());
  207 +const orgList = ref<Recordable[]>([]);
  208 +const { t } = useI18n();
  209 +const needReload = ref(true);
  210 +
  211 +const { createMessage } = useMessage();
  212 +
  213 +const searchInfo = reactive<Recordable>({});
  214 +const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
  215 +const userVisible = ref(false);
  216 +const userModalTitle = ref('选人');
  217 +const selectedItem = ref<{ id: number; username: string } | null>(null);
  218 +const radioStyle = reactive({
  219 + display: 'block',
  220 + height: '30px',
  221 + lineHeight: '30px',
  222 +});
  223 +
  224 +// 监听 visible 的变化
  225 +watch(
  226 + () => props.visible,
  227 + (newVal) => {
  228 + visible.value = newVal;
  229 + }
  230 +);
  231 +
  232 +watch(
  233 + () => props.isViewMode,
  234 + (newVal) => {
  235 + isViewMode.value = newVal;
  236 + }
  237 +);
  238 +
  239 +// 监听 visible 的变化并通知父组件
  240 +watch(
  241 + () => visible.value,
  242 + (newVal) => {
  243 + emit('update:visible', newVal);
  244 + }
  245 +);
  246 +
  247 +// 监听 initialData 的变化
  248 +watch(
  249 + () => props.initialData,
  250 + (newVal) => {
  251 + console.log(newVal?.form,'66666')
  252 + form.value = { ...newVal.form, inspectorId: newVal.form?.userDTO?.id || '',inspectorName: newVal.form?.userDTO?.realName || ''};
  253 +
  254 + tableData.value = [...newVal.tableData];
  255 + },
  256 + { deep: true }
  257 +);
  258 +
  259 +const goChoose = () => {
  260 + userVisible.value = true;
  261 + selectedItem.value = null;
  262 +}
  263 +
  264 +const handleDelete = (index) => {
  265 + tableData.value.splice(index, 1);
  266 +};
  267 +
  268 +// 确认按钮的回调
  269 +const handleUserOk = () => {
  270 + if (!selectedItem.value) {
  271 + createMessage.warning('请选择一个用户');
  272 + return;
  273 + }
  274 + form.value.inspectorId = selectedItem.value.id
  275 + form.value.inspectorName = selectedItem.value.username
  276 +
  277 + userVisible.value = false; // 关闭弹框
  278 +};
  279 +
  280 +const handleUserCancel = () => {
  281 + selectedItem.value = null;
  282 + userVisible.value = false;
  283 +};
  284 +
  285 +const handleSelect = async (organizationId: string) => {
  286 + searchInfo.organizationId = organizationId;
  287 + const _data = {
  288 + page: '1',
  289 + pageSize: '999',
  290 + tenantId: userInfo.getUserInfo.tenantId!,
  291 + organizationId: organizationId
  292 + }
  293 + const response = await getUserListByOrg(_data); // 调用接口
  294 + Options.value = response.items;
  295 +
  296 +};
  297 +onMounted(() => {
  298 + fetchAgeOptions();
  299 +});
  300 +
  301 +const fetchAgeOptions = async () => {
  302 + try {
  303 + const response = await getInspectionPlanList({ page: 1, pageSize: 999 }); // 调用接口
  304 + planOptions.value = response.items?.map((item: any) => {
  305 + return {
  306 + value: item?.id,
  307 + label: item?.name
  308 + }
  309 + });
  310 + } catch (error) {
  311 + console.error('失败:', error);
  312 + }
  313 +};
  314 +
  315 +const getBindProps = computed<Recordable>(() => {
  316 + const params = {}
  317 + return {
  318 + replaceFields: { children: 'children', key: 'id', title: 'name', value: 'id' },
  319 + getPopupContainer: () => document.body,
  320 + placeholder: t('deviceManagement.device.organizationPlaceholderText'),
  321 + maxLength: 250,
  322 + value: form.orgId,
  323 + dropdownStyle: { maxHeight: '300px' },
  324 + api: async (params: OrganizationListItem) => {
  325 + try {
  326 + const result = ((await getOrganizationList(params)) as unknown as Recordable[]) || [];
  327 + orgList.value = result;
  328 + needReload.value = false;
  329 + return result;
  330 + } catch (error) {
  331 + return unref(orgList);
  332 + }
  333 + },
  334 + params: {
  335 + ...params,
  336 + _t: unref(timespan),
  337 + },
  338 + onChange: async (...args: any[]) => {
  339 + const _data = {
  340 + page: '1',
  341 + pageSize: '999',
  342 + tenantId: userInfo.getUserInfo.tenantId!,
  343 + organizationId: args?.[0]
  344 + }
  345 + const response = await getUserListByOrg(_data); // 调用接口
  346 + Options.value = response.items?.map((item: any) => {
  347 + return {
  348 + label: item.username,
  349 + value: item.id,
  350 + }
  351 + });
  352 + form.orgId.value = args?.[0]
  353 +
  354 + },
  355 + };
  356 +});
  357 +
  358 +const handleChange = async (value: Value) => {
  359 + const res = await getInsPlanDetail({id:value})
  360 + form.value.code = res.code
  361 + tableData.value = res?.tkCheckDetailsDTOList?.map((item: any) => {
  362 + return {
  363 + checkDeviceId: item?.checkDeviceId || '',
  364 + recordResult: true,
  365 + planDetails: item?.checkDeviceId || '',
  366 + tkDeviceAccountDTO: item?.tkDeviceAccountDTO
  367 + }
  368 + }) || []
  369 +};
  370 +
  371 +const handleOk = () => {
  372 + if (isViewMode.value) {
  373 + visible.value = false;
  374 + return;
  375 + }
  376 + const objData = { ...form.value, tkInspectionDetailsDTOList: tableData.value };
  377 + emit('submit', objData); // 将数据提交给父组件
  378 + resetForm();
  379 +}
  380 +const handleCancel = () => {
  381 + resetForm();
  382 + visible.value = false;
  383 +}
  384 +
  385 +// 清空表单和表格数据
  386 +const resetForm = () => {
  387 + form.value = {
  388 + code: '',
  389 + inspectionPlanId: '',
  390 + inspectorId: '',
  391 + inspectorName: '',
  392 + checkDate: '',
  393 + recordResult: '',
  394 + orgId: '',
  395 + };
  396 + tableData.value = [];
  397 + isViewMode.value = false;
  398 +};
  399 +
  400 +</script>
... ...
... ... @@ -3,7 +3,7 @@
3 3 <BasicTable :clickToRowSelect="false" @register="registerTable">
4 4 <template #toolbar>
5 5 <Authority value="api:yt:product:category:post">
6   - <Button type="primary" >
  6 + <Button type="primary" @click="handleCreate">
7 7 {{ t('inspection.inspectionRecord.createRecordText') }}
8 8 </Button>
9 9 </Authority>
... ... @@ -20,10 +20,16 @@
20 20 <TableAction
21 21 :actions="[
22 22 {
  23 + label: t('common.viewText'),
  24 + auth: 'api:yt:product:category:update',
  25 + icon: 'ant-design:eye-outlined',
  26 + onClick: handleViewDetail.bind(null, record),
  27 + },
  28 + {
23 29 label: t('common.editText'),
24 30 auth: 'api:yt:product:category:update',
25 31 icon: 'clarity:note-edit-line',
26   - // onClick: handleEdit.bind(null, record),
  32 + onClick: handleEdit.bind(null, record),
27 33 },
28 34 {
29 35 label: t('common.delText'),
... ... @@ -39,18 +45,46 @@
39 45 />
40 46 </template>
41 47 </BasicTable>
  48 + <insRecordModal
  49 + v-model:visible="modalVisible"
  50 + :initial-data="initialData"
  51 + :is-view-mode="isViewMode"
  52 + :title="modalTitle"
  53 + @submit="handleSubmit"
  54 + />
42 55 </div>
43 56 </template>
44 57 <script setup lang="ts">
  58 + import {ref} from "vue";
45 59 import { BasicTable, useTable, TableAction } from '/@/components/Table';
46   - import { getInspectionRecordList, deleteInsRecord } from '/@/api/inspection/inspectionRecord';
  60 + import {
  61 + getInspectionRecordList,
  62 + deleteInsRecord,
  63 + saveInsRecord, getInsRecordDetail
  64 + } from '/@/api/inspection/inspectionRecord';
47 65 import { columns, searchFormSchema } from './index';
48 66 import { useI18n } from '/@/hooks/web/useI18n';
49   - import { Button, Tag } from 'ant-design-vue';
  67 + import {Button, message, Tag} from 'ant-design-vue';
50 68 import {useMessage} from "/@/hooks/web/useMessage";
  69 + import { insRecordModal } from "./components/index"
51 70 const { t } = useI18n();
52 71 const { createMessage } = useMessage();
53   -
  72 + const modalVisible = ref(false);
  73 + const isViewMode = ref(false);
  74 + const modalTitle = ref('');
  75 + import { dateFormat } from '/@/utils/common/compUtils';
  76 + import {getRecordDetail} from "/@/api/inspection/serviceRecord";
  77 + const initialData = ref({
  78 + form: {
  79 + code: '',
  80 + inspectionPlanId: '',
  81 + inspectorId: '',
  82 + checkDate: '',
  83 + recordResult: '',
  84 + orgId: '',
  85 + },
  86 + tableData: [],
  87 + });
54 88 const [
55 89 registerTable,
56 90 { reload, setLoading, getSelectRowKeys, setSelectedRowKeys, getRowSelection },
... ... @@ -95,8 +129,71 @@
95 129 }
96 130 };
97 131
  132 + const handleCreate = () => {
  133 + modalTitle.value = '新增';
  134 + initialData.value = {
  135 + form: {
  136 + code: '',
  137 + inspectionPlanId: '',
  138 + inspectorId: '',
  139 + checkDate: '',
  140 + recordResult: '',
  141 + orgId: '',
  142 + },
  143 + tableData: [],
  144 + }
  145 + modalVisible.value = true;
  146 + }
  147 +
98 148 const handleReload = () => {
99 149 setSelectedRowKeys([]);
100 150 reload();
101 151 };
  152 +
  153 + const handleSubmit = async (data) => {
  154 + const format = 'yyyy-MM-dd hh:mm:ss';
  155 + modalVisible.value = false;
  156 + const _data = {
  157 + ...data,
  158 + checkDate: dateFormat(data?.checkDate, format)
  159 + }
  160 + await saveInsRecord(_data)
  161 + message.success('提交成功');
  162 + handleReload()
  163 + };
  164 +
  165 + const handleViewDetail = async (record?: any) => {
  166 + let id = record.id;
  167 + modalTitle.value = '查看';
  168 + try {
  169 + const response = await getInsRecordDetail({id})
  170 + initialData.value = {
  171 + form: response, // 表单数据
  172 + tableData: response.tkInspectionDetailsDTOList, // 表格数据
  173 + };
  174 + modalVisible.value = true; // 打开弹框
  175 + isViewMode.value = true;
  176 + }catch (error) {
  177 + throw error;
  178 + }finally {
  179 +
  180 + }
  181 + }
  182 +
  183 + const handleEdit = async (record?: any) => {
  184 + let id = record.id;
  185 + modalTitle.value = '修改';
  186 + try {
  187 + const response = await getInsRecordDetail({id})
  188 + initialData.value = {
  189 + form: response, // 表单数据
  190 + tableData: response.tkInspectionDetailsDTOList, // 表格数据
  191 + };
  192 + modalVisible.value = true; // 打开弹框
  193 + }catch (error) {
  194 + throw error;
  195 + }finally {
  196 + }
  197 + }
  198 +
102 199 </script>
... ...
1 1 <template>
2   - <div>
3   - <BasicModal
4   - v-bind="$attrs"
5   - width="30rem"
6   - :title="getTitle"
7   - @register="register"
8   - @cancel="handleCancel"
9   - @ok="handleOk"
10   - destroyOnClose
11   - >
12   - <div>
13   - <BasicForm @register="registerForm" />
14   - </div>
15   - </BasicModal>
16   - </div>
  2 + <a-modal
  3 + v-model:visible="visible"
  4 + :title="modalTitle"
  5 + width="80vw"
  6 + @ok="handleOk"
  7 + @cancel="handleCancel"
  8 + >
  9 + <a-form :model="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }" style="margin-top: 32px" :rules="rules">
  10 + <a-row :gutter="16">
  11 + <a-col :span="12">
  12 + <a-form-item label="计划编号" name="preserveCode">
  13 + <a-input v-model:value="form.preserveCode" :disabled="isViewMode" />
  14 + </a-form-item>
  15 + </a-col>
  16 + <a-col :span="12">
  17 + <a-form-item label="计划名称" name="preserveName">
  18 + <a-input v-model:value="form.preserveName" :disabled="isViewMode" />
  19 + </a-form-item>
  20 + </a-col>
  21 + </a-row>
  22 + <a-row :gutter="16">
  23 + <a-col :span="12">
  24 + <a-form-item label="保养设备" name="status">
  25 + <a-select
  26 + v-model:value="form.status"
  27 + :options="statusOptions"
  28 + :disabled="isViewMode"
  29 + placeholder="请选择"
  30 + />
  31 + </a-form-item>
  32 + </a-col>
  33 + <a-col :span="12">
  34 + <a-form-item label="次数" name="times">
  35 + <a-input v-model:value="form.times" :disabled="isViewMode" />
  36 + </a-form-item>
  37 + </a-col>
  38 + </a-row>
  39 + <a-row :gutter="16">
  40 + <a-col :span="12">
  41 + <a-form-item label="频率" name="frequency">
  42 + <a-input v-model:value="form.frequency" :disabled="isViewMode" />
  43 + </a-form-item>
  44 + </a-col>
  45 + </a-row>
  46 + <a-form-item label="保养明细" name="preserveDetailList">
  47 + <div style="text-align: end">
  48 + <a-button class="editable-add-btn" type="primary" @click="handleAdd" style="margin-bottom: 8px" :disabled="isViewMode">
  49 + <template #icon>
  50 + <PlusOutlined/>
  51 + </template>
  52 + 新增
  53 + </a-button>
  54 + </div>
  55 + <a-table bordered :data-source="tableData" :columns="columns">
  56 + <template #detailCode="{ text, record, index }">
  57 + <div>
  58 + <a-input v-model:value="record.detailCode" :disabled="isViewMode"/>
  59 + </div>
  60 + </template>
  61 + <template #deviceId="{ text, record, index }">
  62 + <div>
  63 + <a-select
  64 + v-model:value="record.deviceId"
  65 + :options="Options"
  66 + :disabled="isViewMode"
  67 + :field-names="{ label: 'name', value: 'id' }"
  68 + placeholder="请选择"
  69 + />
  70 + </div>
  71 + </template>
  72 + <template #checkPlanId="{ text, record, index }">
  73 + <div>
  74 + <a-select
  75 + v-model:value="record.checkPlanId"
  76 + :options="planOptions"
  77 + :disabled="isViewMode"
  78 + :fieldNames="{ label: 'name', value: 'id' }"
  79 + placeholder="请选择"
  80 + />
  81 + </div>
  82 + </template>
  83 + <template #preserveDetail="{ text, record, index }">
  84 + <div>
  85 + <a-textarea v-model:value="record.preserveDetail" :disabled="isViewMode"/>
  86 + </div>
  87 + </template>
  88 + <template #operation="{ text, record, index }">
  89 + <div>
  90 + <a-button type="link" @click="handleDelete(index)" :disabled="isViewMode">删除</a-button>
  91 + </div>
  92 + </template>
  93 + </a-table>
  94 + </a-form-item>
  95 + </a-form>
  96 + </a-modal>
17 97 </template>
  98 +
18 99 <script setup lang="ts">
19   -import {computed, ref, unref} from "vue";
20   -import {useI18n} from "/@/hooks/web/useI18n";
21   -import {useForm} from "/@/components/Form";
22   -import {schemas} from "../index";
23   -import {useModalInner} from "/@/components/Modal";
  100 +import { ref, onMounted, watch } from 'vue';
  101 +import { getLedgerList } from "/@/api/equipment/ledger";
  102 +import { getPlanList } from "/@/api/equipment/chenkPlan";
  103 +import { useI18n } from "/@/hooks/web/useI18n";
  104 +import { message } from 'ant-design-vue';
  105 +
  106 +
  107 +const Options = ref([]);
  108 +const planOptions = ref([]);
24 109 const { t } = useI18n();
25   -const isUpdate = ref<Boolean>(false);
26   -const recordInfo = ref<any>({});
27   -const emit = defineEmits(['handleReload', 'register']);
28   -
29   -const getTitle = computed(() =>
30   - !unref(isUpdate)
31   - ? t('inspection.servicePlan.createPlanText')
32   - : t('inspection.servicePlan.editPlanText')
  110 +// 定义 props
  111 +const props = defineProps({
  112 + initialData: {
  113 + type: Object,
  114 + default: () => ({
  115 + form: {
  116 + preserveCode: '',
  117 + preserveName: '',
  118 + status: '',
  119 + times: '',
  120 + frequency: '',
  121 + },
  122 + tableData: [],
  123 + }),
  124 + },
  125 + visible: {
  126 + type: Boolean,
  127 + default: false,
  128 + },
  129 + isViewMode: {
  130 + type: Boolean,
  131 + default: false,
  132 + },
  133 + modalTitle: {
  134 + type: String,
  135 + default: '',
  136 + },
  137 +});
  138 +const visible = ref(props.visible);
  139 +const isViewMode = ref(props.isViewMode);
  140 +const modalTitle = ref(props.modalTitle);
  141 +const rules = {
  142 + preserveCode: [
  143 + { required: true, message: '请输入', trigger: 'blur' },
  144 + ],
  145 + preserveName: [
  146 + { required: true, message: '请输入', trigger: 'blur' },
  147 + ],
  148 +
  149 + frequency: [
  150 + { required: true, message: '请输入', trigger: 'blur' },
  151 + ],
  152 +
  153 + times: [
  154 + { required: true, message: '请输入', trigger: 'blur' },
  155 + ],
  156 + status: [{ required: true, message: '请选择', trigger: 'change' }],
  157 + preserveDetailList: [{ required: true, message: '请选择', trigger: 'change' }],
  158 +
  159 +};
  160 +
  161 +const statusOptions = [
  162 + { label: t('inspection.servicePlan.NOTSTART'), value: 'NOTSTART' },
  163 + { label: t('inspection.servicePlan.UNDERWAY'), value: 'UNDERWAY' },
  164 + { label: t('inspection.servicePlan.COMPLETED'), value: 'COMPLETED' },
  165 + { label: t('inspection.servicePlan.STOP'), value: 'STOP' },
  166 +];
  167 +const form = ref({ ...props.initialData.form });
  168 +const tableData = ref([...props.initialData.tableData]);
  169 +const emit = defineEmits(['update:visible', 'submit']);
  170 +onMounted(() => {
  171 + fetchAgeOptions();
  172 +});
  173 +
  174 +const fetchAgeOptions = async () => {
  175 + try {
  176 + const response = await getLedgerList({ page: 1, pageSize: 999 }); // 调用接口
  177 + const response1 = await getPlanList({ page: 1, pageSize: 999, type: 'MAINTENANCE' }); // 调用接口
  178 + Options.value = response.items?.map((item: any) => {
  179 + return {
  180 + value: item?.id,
  181 + label: item?.name
  182 + }
  183 + })
  184 + planOptions.value = response1.items?.map((item: any) => {
  185 + return {
  186 + value: item?.id,
  187 + label: item?.name
  188 + }
  189 + });
  190 + } catch (error) {
  191 + console.error('失败:', error);
  192 + }
  193 +};
  194 +
  195 +// 监听 visible 的变化
  196 +watch(
  197 + () => props.visible,
  198 + (newVal) => {
  199 + visible.value = newVal;
  200 + }
33 201 );
34 202
35   -const [registerForm, { getFieldsValue, setFieldsValue, validate, updateSchema }] = useForm({
36   - labelWidth: 140,
37   - schemas,
38   - actionColOptions: {
39   - span: 14,
  203 +watch(
  204 + () => props.isViewMode,
  205 + (newVal) => {
  206 + isViewMode.value = newVal;
  207 + }
  208 +);
  209 +
  210 +// 监听 visible 的变化并通知父组件
  211 +watch(
  212 + () => visible.value,
  213 + (newVal) => {
  214 + emit('update:visible', newVal);
  215 + }
  216 +);
  217 +
  218 +// 监听 initialData 的变化
  219 +watch(
  220 + () => props.initialData,
  221 + (newVal) => {
  222 + form.value = { ...newVal.form };
  223 + tableData.value = [...newVal.tableData];
40 224 },
41   - showActionButtonGroup: false,
42   -});
  225 + { deep: true }
  226 +);
43 227
44   -const [register, { closeModal, setModalProps }] = useModalInner(async (data) => {
45   - setModalProps({ confirmLoading: false, loading: true });
46   - isUpdate.value = data?.isUpdate;
47   - recordInfo.value = data?.record;
48   - if (data?.record) {
49   - setFieldsValue(data?.record);
  228 +const columns = [
  229 + {
  230 + title: '明细编号',
  231 + dataIndex: 'detailCode',
  232 + slots: { customRender: 'detailCode' },
  233 + width: '160px'
  234 + },
  235 + {
  236 + title: '保养设备',
  237 + dataIndex: 'deviceId',
  238 + slots: { customRender: 'deviceId' },
  239 + width: '180px'
  240 + },
  241 + {
  242 + title: '保养方案',
  243 + dataIndex: 'checkPlanId',
  244 + slots: { customRender: 'checkPlanId' },
  245 + width: '180px'
  246 + },
  247 + {
  248 + title: '方案明细',
  249 + dataIndex: 'preserveDetail',
  250 + slots: { customRender: 'preserveDetail' },
  251 + width: '160px'
  252 + },
  253 + {
  254 + title: '操作',
  255 + dataIndex: 'operation',
  256 + slots: { customRender: 'operation' },
  257 + width: '120px'
50 258 }
51   - setModalProps({ loading: false });
52   -});
  259 +];
53 260
54   -const handleCancel = () => {
55   - closeModal();
  261 +const handleAdd = () => {
  262 + tableData.value.push({
  263 + detailCode: '',
  264 + deviceId: undefined,
  265 + checkPlanId: undefined,
  266 + preserveDetail: '',
  267 + });
56 268 };
57 269
58   -const handleOk = async () => {
  270 +const handleDelete = (index) => {
  271 + tableData.value.splice(index, 1);
  272 +};
  273 +
  274 +const handleOk = () => {
  275 + if (isViewMode.value) {
  276 + visible.value = false;
  277 + return;
  278 + }
  279 + const objData = { ...form.value, preserveDetailList: tableData.value };
  280 + emit('submit', objData); // 将数据提交给父组件
  281 + resetForm();
  282 +};
59 283
60   -}
  284 +const handleCancel = () => {
  285 + resetForm();
  286 + visible.value = false;
  287 +};
  288 +// 清空表单和表格数据
  289 +const resetForm = () => {
  290 + form.value = {
  291 + serveCode: '',
  292 + preserveName: '',
  293 + status: '',
  294 + times: '',
  295 + frequency: '',
  296 +};
  297 + tableData.value = [];
  298 + isViewMode.value = false;
  299 +};
61 300 </script>
... ...
1   -import { FormSchema } from '/@/components/Form';
  1 +import {FormSchema} from '/@/components/Form';
2 2 import { useI18n } from '/@/hooks/web/useI18n';
3 3 import { BasicColumn } from '/@/components/Table';
4 4 const { t } = useI18n();
5 5
  6 +
6 7 export const searchFormSchema: FormSchema[] = [
7 8 {
8 9 field: 'preserveName',
9 10 label: t('inspection.servicePlan.preserveNameText'),
10 11 component: 'Input',
11   - colProps: { span: 8 },
  12 + colProps: { span: 6 },
12 13 },
13 14 ];
14 15
... ... @@ -37,49 +38,4 @@ export const columns: BasicColumn[] = [
37 38 ];
38 39
39 40
40   -export const schemas: FormSchema[] = [
41   - {
42   - field: 'code',
43   - label: t('equipment.checkPlan.nameCode'),
44   - component: 'Input',
45   - colProps: { span: 21 },
46   - required: true,
47   - componentProps: {
48   - maxLength: 20,
49   - },
50   - },
51   - {
52   - field: 'name',
53   - label: t('equipment.checkPlan.nameText'),
54   - component: 'Input',
55   - colProps: { span: 21 },
56   - required: true,
57   - componentProps: {
58   - maxLength: 20,
59   - },
60   - },
61   - {
62   - field: 'type',
63   - label: t('equipment.checkPlan.typeText'),
64   - component: 'RadioButtonGroup',
65   - defaultValue: 'INSPECTION',
66 41
67   - },
68   - {
69   - field: 'status',
70   - label: t('equipment.checkPlan.statusText'),
71   - component: 'RadioButtonGroup',
72   - defaultValue: 'ENABLE',
73   -
74   - },
75   - {
76   - field: 'planDetails',
77   - label: t('equipment.checkPlan.nameDetail'),
78   - component: 'InputTextArea',
79   - colProps: { span: 21 },
80   - required: true,
81   - componentProps: {
82   - maxLength: 200,
83   - },
84   - },
85   -];
... ...
... ... @@ -26,10 +26,16 @@
26 26 <TableAction
27 27 :actions="[
28 28 {
  29 + label: t('common.viewText'),
  30 + auth: 'api:yt:product:category:update',
  31 + icon: 'ant-design:eye-outlined',
  32 + onClick: handleViewDetail.bind(null, record),
  33 + },
  34 + {
29 35 label: t('common.editText'),
30 36 auth: 'api:yt:product:category:update',
31 37 icon: 'clarity:note-edit-line',
32   - // onClick: handleEdit.bind(null, record),
  38 + onClick: handleEdit.bind(null, record),
33 39 ifShow: () => record.status === 'NOTSTART',
34 40 },
35 41 {
... ... @@ -77,22 +83,43 @@
77 83 />
78 84 </template>
79 85 </BasicTable>
80   - <servicePlanModal @register="registerModal" @handleReload="handleReload" />
  86 + <servicePlanModal
  87 + v-model:visible="modalVisible"
  88 + :initial-data="initialData"
  89 + :is-view-mode="isViewMode"
  90 + @submit="handleSubmit"
  91 + :title="modalTitle"
  92 + />
81 93
82 94 </div>
83 95 </template>
84 96 <script setup lang="ts">
85 97 import { BasicTable, useTable, TableAction } from '/@/components/Table';
86   - import {deleteServePlan, getServicePlanList, updateServiceStatus} from '/@/api/inspection/servicePlan';
  98 + import {deleteServePlan, getServicePlanList, updateServiceStatus, savePreservePlan, getPreserveDetail} from '/@/api/inspection/servicePlan';
  99 + import { servicePlanModal } from "./components/index"
87 100 import { columns, searchFormSchema } from './index';
88 101 import { useI18n } from '/@/hooks/web/useI18n';
89   - import { Button, Tag } from 'ant-design-vue';
  102 + import {Button, message, Tag} from 'ant-design-vue';
90 103 import {useModal} from "/@/components/Modal";
91 104 import {useMessage} from "/@/hooks/web/useMessage";
92 105 const { t } = useI18n();
  106 + import { ref } from "vue"
  107 + import {getPreservePlanDetail} from "/@/api/inspection/inspectionPlan";
93 108 const [registerModal, { openModal }] = useModal();
94 109 const { createMessage } = useMessage();
95   -
  110 + const modalVisible = ref(false);
  111 + const isViewMode = ref(false);
  112 + const modalTitle = ref('');
  113 + const initialData = ref({
  114 + form: {
  115 + preserveCode: '',
  116 + preserveName: '',
  117 + status: '',
  118 + times: '',
  119 + frequency: '',
  120 + },
  121 + tableData: [],
  122 + });
96 123 const [
97 124 registerTable,
98 125 { reload, setLoading, getSelectRowKeys, setSelectedRowKeys, getRowSelection },
... ... @@ -125,9 +152,27 @@
125 152
126 153 // 新增
127 154 const handleCreate = () => {
128   - openModal(true, {
129   - isUpdate: false,
130   - });
  155 + modalTitle.value = '新增';
  156 + initialData.value = {
  157 + form: {
  158 + preserveCode: '',
  159 + preserveName: '',
  160 + status: '',
  161 + times: '',
  162 + frequency: '',
  163 + },
  164 + tableData: [],
  165 + }
  166 + modalVisible.value = true;
  167 + };
  168 +
  169 + const handleSubmit = async (data) => {
  170 + console.log('提交的数据:', data);
  171 +
  172 + modalVisible.value = false;
  173 + await savePreservePlan(data)
  174 + message.success('提交成功');
  175 + handleReload()
131 176 };
132 177
133 178 const handleReload = () => {
... ... @@ -135,6 +180,41 @@
135 180 reload();
136 181 };
137 182
  183 + const handleViewDetail = async (record?: any) => {
  184 + let id = record.id;
  185 + modalTitle.value = '查看';
  186 + try {
  187 + const response = await getPreserveDetail({id})
  188 + initialData.value = {
  189 + form: response, // 表单数据
  190 + tableData: response.preserveDetailList, // 表格数据
  191 + };
  192 + modalVisible.value = true; // 打开弹框
  193 + isViewMode.value = true;
  194 + }catch (error) {
  195 + throw error;
  196 + }finally {
  197 +
  198 + }
  199 + }
  200 +
  201 + const handleEdit = async (record?: any) => {
  202 + let id = record.id;
  203 + modalTitle.value = '修改';
  204 + try {
  205 + const response = await getPreserveDetail({id})
  206 + initialData.value = {
  207 + form: response, // 表单数据
  208 + tableData: response.preserveDetailList, // 表格数据
  209 + };
  210 + modalVisible.value = true; // 打开弹框
  211 + }catch (error) {
  212 + throw error;
  213 + }finally {
  214 +
  215 + }
  216 + }
  217 +
138 218 const handleDelete = async (record?: any) => {
139 219 let id = record.id;
140 220 try {
... ...
  1 +import serviceRecordModal from './serviceRecordModal.vue';
  2 +
  3 +export { serviceRecordModal };
... ...
  1 +<template>
  2 + <a-modal
  3 + v-model:visible="visible"
  4 + :title="modalTitle"
  5 + width="80vw"
  6 + @ok="handleOk"
  7 + @cancel="handleCancel"
  8 + >
  9 + <a-form :model="form" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }" style="margin-top: 32px" :rules="rules">
  10 + <a-row :gutter="16">
  11 + <a-col :span="12">
  12 + <a-form-item label="记录编号" name="recordCode">
  13 + <a-input v-model:value="form.recordCode" :disabled="isViewMode" />
  14 + </a-form-item>
  15 + </a-col>
  16 + <a-col :span="12">
  17 + <a-form-item label="保养计划" name="preservePlanId">
  18 + <a-select
  19 + v-model:value="form.preservePlanId"
  20 + :options="planOptions"
  21 + :disabled="isViewMode"
  22 + placeholder="请选择"
  23 + @change="handleChange"
  24 + />
  25 + </a-form-item>
  26 + </a-col>
  27 + </a-row>
  28 +
  29 + <a-row :gutter="16">
  30 + <a-col :span="12">
  31 + <a-form-item label="保养日期" name="preserveDate">
  32 + <a-date-picker
  33 + v-model:value="form.preserveDate"
  34 + :disabled="isViewMode"
  35 + placeholder="请选择"
  36 + style="width: 100%"
  37 + />
  38 + </a-form-item>
  39 + </a-col>
  40 + <a-col :span="12">
  41 + <a-form-item label="维护结果" name="preserveStatus">
  42 + <a-select
  43 + v-model:value="form.preserveStatus"
  44 + :disabled="isViewMode"
  45 + placeholder="请选择"
  46 + :options="[{label:'未完成',value:'INCOMPLETE'},{label:'已完成',value:'COMPLETE'}]"
  47 + ></a-select>
  48 + </a-form-item>
  49 + </a-col>
  50 + </a-row>
  51 + <a-row :gutter="16">
  52 + <a-col :span="12">
  53 + <a-form-item label="保养人" name="preserveByName">
  54 + <div style="display: flex">
  55 + <a-input
  56 + v-model:value="form.preserveByName"
  57 + placeholder="请选择"
  58 + :disabled="true"
  59 + >
  60 + </a-input>
  61 + <a-button
  62 + type="primary"
  63 + @click="goChoose"
  64 + :disabled="isViewMode"
  65 + >
  66 + 选人
  67 + </a-button>
  68 + </div>
  69 +
  70 + </a-form-item>
  71 + </a-col>
  72 + </a-row>
  73 + <a-form-item label="保养明细" name="preserveDetailList">
  74 + <a-table bordered :data-source="tableData" :columns="columns">
  75 + <template #deviceInfo="{ text, record, index }">
  76 + <div>
  77 + {{record?.deviceInfo.name}}
  78 + </div>
  79 + </template>
  80 + <template #status="{ text, record, index }">
  81 + <div>
  82 + <a-select
  83 + v-model:value="record.status"
  84 + :options="defaultOptions"
  85 + :disabled="isViewMode"
  86 + :field-names="{ label: 'name', value: 'id' }"
  87 + placeholder="请选择"
  88 + />
  89 + </div>
  90 + </template>
  91 + <template #operation="{ text, record, index }">
  92 + <div>
  93 + <a-button type="link" @click="handleDelete(index)" :disabled="isViewMode">删除</a-button>
  94 + </div>
  95 + </template>
  96 + </a-table>
  97 + </a-form-item>
  98 + </a-form>
  99 + <a-modal
  100 + v-model:visible="userVisible"
  101 + :title="userModalTitle"
  102 + width="60vw"
  103 + height="50vh"
  104 + @ok="handleUserOk"
  105 + @cancel="handleUserCancel"
  106 + >
  107 + <div style="padding: 20px;display: flex">
  108 + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" isOpen="true"/>
  109 + <div style="margin-top: 20px;margin-left: 30px">
  110 + <a-radio-group v-model:value="selectedItem">
  111 + <template v-for="item in Options" :key="`${item.id}`">
  112 + <a-radio :style="radioStyle" :value="item">{{ item.username }}</a-radio>
  113 + </template>
  114 + </a-radio-group>
  115 + </div>
  116 + </div>
  117 + </a-modal>
  118 + </a-modal>
  119 +</template>
  120 +<script setup lang="ts">
  121 +// 定义 props
  122 +import {computed, onMounted, ref, unref, watch, reactive} from "vue";
  123 +import {getServicePlanList} from "/@/api/inspection/servicePlan";
  124 +import { ApiTreeSelect } from '/@/components/Form';
  125 +import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
  126 +import {OrganizationListItem} from "/@/api/system/model/systemModel";
  127 +import {getOrganizationList} from "/@/api/system/system";
  128 +import {useI18n} from "/@/hooks/web/useI18n";
  129 +import {getUserListByOrg} from "/@/api/equipment/ledger";
  130 +import {useUserStore} from "/@/store/modules/user";
  131 +import {serveRecordDetail} from "/@/api/inspection/serviceRecord";
  132 +import {useMessage} from "/@/hooks/web/useMessage";
  133 +const { createMessage } = useMessage();
  134 +
  135 +const searchInfo = reactive<Recordable>({});
  136 +const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
  137 +const userVisible = ref(false);
  138 +const userModalTitle = ref('选人');
  139 +const selectedItem = ref<{ id: number; username: string } | null>(null);
  140 +const radioStyle = reactive({
  141 + display: 'block',
  142 + height: '30px',
  143 + lineHeight: '30px',
  144 +});
  145 +
  146 +interface Value {
  147 + value?: string;
  148 + label?: string;
  149 +}
  150 +const props = defineProps({
  151 + initialData: {
  152 + type: Object,
  153 + default: () => ({
  154 + form: {
  155 + recordCode: '',
  156 + preserveName: '',
  157 + preservePlanId: '',
  158 + preserveDate: '',
  159 + preserveStatus: '',
  160 + orgId: '',
  161 + preserveBy: '',
  162 + preserveByName: '',
  163 + },
  164 + tableData: [],
  165 + }),
  166 + },
  167 + visible: {
  168 + type: Boolean,
  169 + default: false,
  170 + },
  171 + isViewMode: {
  172 + type: Boolean,
  173 + default: false,
  174 + },
  175 + modalTitle: {
  176 + type: String,
  177 + default: '',
  178 + },
  179 +});
  180 +const visible = ref(props.visible);
  181 +const isViewMode = ref(props.isViewMode);
  182 +const modalTitle = ref(props.modalTitle);
  183 +const defaultOptions = [
  184 + {
  185 + label: '未执行',
  186 + value: 'UNEXECUTED',
  187 + },
  188 + {
  189 + label: '已执行',
  190 + value: 'EXECUTED',
  191 + },
  192 +]
  193 +const form = ref({ ...props.initialData.form });
  194 +const tableData = ref([...props.initialData.tableData]);
  195 +const emit = defineEmits(['update:visible', 'submit']);
  196 +const planOptions = ref([]);
  197 +const Options = ref([]);
  198 +const rules = {
  199 + recordCode: [
  200 + { required: true, message: '请输入', trigger: 'blur' },
  201 + ],
  202 + preservePlanId: [{ required: true, message: '请选择', trigger: 'change' }],
  203 + orgId: [{ required: true, message: '请选择', trigger: 'change' }],
  204 + preserveBy: [{ required: true, message: '请选择', trigger: 'change' }],
  205 + preserveByName: [{ required: true, message: '请选择', trigger: 'change' }],
  206 + preserveStatus: [{ required: true, message: '请选择', trigger: 'change' }],
  207 +};
  208 +
  209 +const columns = [
  210 + {
  211 + title: '保养明细编号',
  212 + dataIndex: 'detailCode',
  213 + slots: { customRender: 'detailCode' },
  214 + width: '160px'
  215 + },
  216 + {
  217 + title: '保养设备',
  218 + dataIndex: 'deviceInfo',
  219 + slots: { customRender: 'deviceInfo' },
  220 + width: '180px'
  221 + },
  222 + {
  223 + title: '保养明细',
  224 + dataIndex: 'preserveDetail',
  225 + width: '180px'
  226 + },
  227 + {
  228 + title: '执行状态',
  229 + dataIndex: 'status',
  230 + slots: { customRender: 'status' },
  231 + width: '160px'
  232 + },
  233 + {
  234 + title: '操作',
  235 + dataIndex: 'operation',
  236 + slots: { customRender: 'operation' },
  237 + width: '120px'
  238 + }
  239 +];
  240 +
  241 +
  242 +const userInfo = useUserStore();
  243 +const timespan = ref(Date.now());
  244 +const orgList = ref<Recordable[]>([]);
  245 +const { t } = useI18n();
  246 +const needReload = ref(true);
  247 +const getBindProps = computed<Recordable>(() => {
  248 + const params = {}
  249 + return {
  250 + replaceFields: { children: 'children', key: 'id', title: 'name', value: 'id' },
  251 + getPopupContainer: () => document.body,
  252 + placeholder: t('deviceManagement.device.organizationPlaceholderText'),
  253 + maxLength: 250,
  254 + value: form.orgId,
  255 + dropdownStyle: { maxHeight: '300px' },
  256 + api: async (params: OrganizationListItem) => {
  257 + try {
  258 + const result = ((await getOrganizationList(params)) as unknown as Recordable[]) || [];
  259 + orgList.value = result;
  260 + needReload.value = false;
  261 + return result;
  262 + } catch (error) {
  263 + return unref(orgList);
  264 + }
  265 + },
  266 + params: {
  267 + ...params,
  268 + _t: unref(timespan),
  269 + },
  270 + onChange: async (...args: any[]) => {
  271 + const _data = {
  272 + page: '1',
  273 + pageSize: '999',
  274 + tenantId: userInfo.getUserInfo.tenantId!,
  275 + organizationId: args?.[0]
  276 + }
  277 + const response = await getUserListByOrg(_data); // 调用接口
  278 + Options.value = response.items?.map((item: any) => {
  279 + return {
  280 + label: item.username,
  281 + value: item.id,
  282 + }
  283 + });
  284 + form.orgId.value = args?.[0]
  285 +
  286 + },
  287 + };
  288 +});
  289 +
  290 +
  291 +// 监听 initialData 的变化
  292 +watch(
  293 + () => props.initialData,
  294 + (newVal) => {
  295 + form.value = { ...newVal.form };
  296 + tableData.value = [...newVal.tableData];
  297 + },
  298 + { deep: true }
  299 +);
  300 +
  301 +
  302 +const handleDelete = (index) => {
  303 + tableData.value.splice(index, 1);
  304 +};
  305 +
  306 +const handleChange = async (value: Value) => {
  307 + const res = await serveRecordDetail({preservePlanId:value,page:'1',pageSize:'999'})
  308 + tableData.value = res?.items?.map((item: any) => {
  309 + return {
  310 + detailCode: item?.detailCode || '',
  311 + preserveDetail: item?.preserveDetail || '',
  312 + deviceInfo: item?.deviceInfo || {},
  313 + preserveDetailId: item?.id || '',
  314 + status: 'UNEXECUTED'
  315 + }
  316 + }) || []
  317 +};
  318 +
  319 +// 监听 visible 的变化
  320 +watch(
  321 + () => props.visible,
  322 + (newVal) => {
  323 + visible.value = newVal;
  324 + }
  325 +);
  326 +
  327 +watch(
  328 + () => props.isViewMode,
  329 + (newVal) => {
  330 + isViewMode.value = newVal;
  331 + }
  332 +);
  333 +
  334 +// 监听 visible 的变化并通知父组件
  335 +watch(
  336 + () => visible.value,
  337 + (newVal) => {
  338 + emit('update:visible', newVal);
  339 + }
  340 +);
  341 +
  342 +onMounted(() => {
  343 + fetchAgeOptions();
  344 +});
  345 +
  346 +const fetchAgeOptions = async () => {
  347 + try {
  348 + const response = await getServicePlanList({ page: 1, pageSize: 999 }); // 调用接口
  349 + planOptions.value = response.items?.map((item: any) => {
  350 + return {
  351 + value: item?.id,
  352 + label: item?.preserveName
  353 + }
  354 + });
  355 + } catch (error) {
  356 + console.error('失败:', error);
  357 + }
  358 +};
  359 +
  360 +const handleOk = () => {
  361 + if (isViewMode.value) {
  362 + visible.value = false;
  363 + return;
  364 + }
  365 + const objData = { ...form.value, preserveDetailStatusList: tableData.value };
  366 + emit('submit', objData); // 将数据提交给父组件
  367 + resetForm();
  368 +}
  369 +const handleCancel = () => {
  370 + resetForm();
  371 + visible.value = false;
  372 +}
  373 +
  374 +// 清空表单和表格数据
  375 +const resetForm = () => {
  376 + form.value = {
  377 + recordCode: '',
  378 + preserveName: '',
  379 + preservePlanId: '',
  380 + preserveDate: '',
  381 + preserveStatus: '',
  382 + orgId: '',
  383 + preserveBy: '',
  384 + preserveByName: '',
  385 + };
  386 + tableData.value = [];
  387 + isViewMode.value = false;
  388 +};
  389 +
  390 +const goChoose = () => {
  391 + userVisible.value = true;
  392 + selectedItem.value = null;
  393 +}
  394 +
  395 +const handleSelect = async (organizationId: string) => {
  396 + searchInfo.organizationId = organizationId;
  397 + const _data = {
  398 + page: '1',
  399 + pageSize: '999',
  400 + tenantId: userInfo.getUserInfo.tenantId!,
  401 + organizationId: organizationId
  402 + }
  403 + const response = await getUserListByOrg(_data); // 调用接口
  404 + Options.value = response.items;
  405 +
  406 +};
  407 +
  408 +// 确认按钮的回调
  409 +const handleUserOk = () => {
  410 + if (!selectedItem.value) {
  411 + createMessage.warning('请选择一个用户');
  412 + return;
  413 + }
  414 + form.value.preserveBy = selectedItem.value.id
  415 + form.value.preserveByName = selectedItem.value.username
  416 +
  417 + userVisible.value = false; // 关闭弹框
  418 +};
  419 +
  420 +const handleUserCancel = () => {
  421 + selectedItem.value = null;
  422 + userVisible.value = false;
  423 +};
  424 +</script>
  425 +
... ...
... ... @@ -3,7 +3,7 @@
3 3 <BasicTable :clickToRowSelect="false" @register="registerTable">
4 4 <template #toolbar>
5 5 <Authority value="api:yt:product:category:post">
6   - <Button type="primary" >
  6 + <Button type="primary" @click="handleCreate">
7 7 {{ t('inspection.serviceRecord.createCategoryText') }}
8 8 </Button>
9 9 </Authority>
... ... @@ -24,10 +24,16 @@
24 24 <TableAction
25 25 :actions="[
26 26 {
  27 + label: t('common.viewText'),
  28 + auth: 'api:yt:product:category:update',
  29 + icon: 'ant-design:eye-outlined',
  30 + onClick: handleViewDetail.bind(null, record),
  31 + },
  32 + {
27 33 label: t('common.editText'),
28 34 auth: 'api:yt:product:category:update',
29 35 icon: 'clarity:note-edit-line',
30   - // onClick: handleEdit.bind(null, record),
  36 + onClick: handleEdit.bind(null, record),
31 37 },
32 38 {
33 39 label: t('common.delText'),
... ... @@ -43,17 +49,46 @@
43 49 />
44 50 </template>
45 51 </BasicTable>
  52 + <serviceRecordModal
  53 + v-model:visible="modalVisible"
  54 + :initial-data="initialData"
  55 + :is-view-mode="isViewMode"
  56 + :title="modalTitle"
  57 + @submit="handleSubmit"
  58 + />
46 59 </div>
47 60 </template>
48 61 <script setup lang="ts">
49 62 import { BasicTable, useTable, TableAction } from '/@/components/Table';
50   -import { getServiceRecordList, deleteServeRecord } from '/@/api/inspection/serviceRecord';
  63 +import {
  64 + getServiceRecordList,
  65 + deleteServeRecord,
  66 + savePreserveRecord, getRecordDetail
  67 +} from '/@/api/inspection/serviceRecord';
51 68 import { columns, searchFormSchema } from './index';
52 69 import { useI18n } from '/@/hooks/web/useI18n';
53   -import { Button, Tag } from 'ant-design-vue';
  70 +import {Button, message, Tag} from 'ant-design-vue';
54 71 import {useMessage} from "/@/hooks/web/useMessage";
  72 +import { serviceRecordModal } from "./components/index"
  73 +import {ref} from "vue";
55 74 const { t } = useI18n();
56 75 const { createMessage } = useMessage();
  76 +const modalVisible = ref(false);
  77 +const isViewMode = ref(false);
  78 +const modalTitle = ref('');
  79 +import { dateFormat } from '/@/utils/common/compUtils';
  80 +const initialData = ref({
  81 + form: {
  82 + recordCode: '',
  83 + preservePlanId: '',
  84 + preserveStatus: '',
  85 + preserveBy: '',
  86 + preserveByName: '',
  87 + preserveDate: '',
  88 + orgId: '',
  89 + },
  90 + tableData: [],
  91 +});
57 92
58 93 const [
59 94 registerTable,
... ... @@ -104,4 +139,69 @@ const handleReload = () => {
104 139 reload();
105 140 };
106 141
  142 +const handleCreate = () => {
  143 + modalTitle.value = '新增';
  144 + initialData.value = {
  145 + form: {
  146 + recordCode: '',
  147 + preservePlanId: '',
  148 + preserveStatus: '',
  149 + preserveBy: '',
  150 + preserveByName: '',
  151 + preserveDate: '',
  152 + orgId: '',
  153 + },
  154 + tableData: [],
  155 + }
  156 + modalVisible.value = true;
  157 +}
  158 +
  159 +const handleSubmit = async (data) => {
  160 + const format = 'yyyy-MM-dd hh:mm:ss';
  161 + modalVisible.value = false;
  162 + const _data = {
  163 + ...data,
  164 + preserveDate: dateFormat(data?.preserveDate, format)
  165 + }
  166 + await savePreserveRecord(_data)
  167 + message.success('提交成功');
  168 + handleReload()
  169 +};
  170 +
  171 +const handleEdit = async (record?: any) => {
  172 + let id = record.id;
  173 + modalTitle.value = '修改';
  174 + try {
  175 + const response = await getRecordDetail({id})
  176 + console.log(response,'res')
  177 + initialData.value = {
  178 + form: response, // 表单数据
  179 + tableData: response.preserveDetailStatusList, // 表格数据
  180 + };
  181 + modalVisible.value = true; // 打开弹框
  182 + }catch (error) {
  183 + throw error;
  184 + }finally {
  185 +
  186 + }
  187 +}
  188 +
  189 +const handleViewDetail = async (record?: any) => {
  190 + let id = record.id;
  191 + modalTitle.value = '查看';
  192 + try {
  193 + const response = await getRecordDetail({id})
  194 + initialData.value = {
  195 + form: response, // 表单数据
  196 + tableData: response.preserveDetailStatusList, // 表格数据
  197 + };
  198 + modalVisible.value = true; // 打开弹框
  199 + isViewMode.value = true;
  200 + }catch (error) {
  201 + throw error;
  202 + }finally {
  203 +
  204 + }
  205 +}
  206 +
107 207 </script>
... ...