From 3471290659516cf21db3211a9053daff5f283e03 Mon Sep 17 00:00:00 2001
From: zhuguifei <312353457@qq.com>
Date: 星期五, 20 三月 2026 15:50:18 +0800
Subject: [PATCH] feat: 基础数据仪器管理、判定依据、判定依据明细

---
 ruoyi-plus-soybean/src/views/qm/checkitem/modules/checkitem-operate-drawer.vue |  280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 280 insertions(+), 0 deletions(-)

diff --git a/ruoyi-plus-soybean/src/views/qm/checkitem/modules/checkitem-operate-drawer.vue b/ruoyi-plus-soybean/src/views/qm/checkitem/modules/checkitem-operate-drawer.vue
new file mode 100755
index 0000000..e4af1c5
--- /dev/null
+++ b/ruoyi-plus-soybean/src/views/qm/checkitem/modules/checkitem-operate-drawer.vue
@@ -0,0 +1,280 @@
+<script setup lang="ts">
+import { computed, ref, watch } from 'vue';
+import { jsonClone } from '@sa/utils';
+import {
+  fetchCreateCheckitem,
+  fetchGetRid,
+  fetchUpdateCheckitem
+} from '@/service/api/qm/checkitem';
+import { fetchGetInstrumentList } from '@/service/api/md/instrument';
+import { useFormRules, useNaiveForm } from '@/hooks/common/form';
+import { $t } from '@/locales';
+
+defineOptions({
+  name: 'CheckitemOperateDrawer'
+});
+
+interface Props {
+  /** the type of operation */
+  operateType: NaiveUI.TableOperateType;
+  /** the edit row data */
+  rowData?: Api.Qm.Checkitem | null;
+  /** preset stdCode for add */
+  stdCode?: string | null;
+}
+
+const props = defineProps<Props>();
+
+interface Emits {
+  (e: 'submitted'): void;
+}
+
+const emit = defineEmits<Emits>();
+
+const visible = defineModel<boolean>('visible', {
+  default: false
+});
+
+const { formRef, validate, restoreValidation } = useNaiveForm();
+const { createRequiredRule } = useFormRules();
+
+const title = computed(() => {
+  const titles: Record<NaiveUI.TableOperateType, string> = {
+    add: '鏂板瑙勭▼妫�楠岄」鐩�',
+    edit: '缂栬緫瑙勭▼妫�楠岄」鐩�'
+  };
+  return titles[props.operateType];
+});
+
+const enableOptions = [
+  { label: '鍚敤', value: 1 },
+  { label: '鍋滅敤', value: 0 }
+];
+
+const categoryOptions = [
+  { label: '鎴愬搧', value: 0 },
+  { label: '杈呮枡', value: 1 }
+];
+
+const checkLevelOptions = [
+  { label: 'A', value: 'A' },
+  { label: 'B', value: 'B' },
+  { label: 'C', value: 'C' },
+  { label: 'D', value: 'D' }
+];
+
+const ismixOptions = [
+  { label: '鏄�', value: 1 },
+  { label: '鍚�', value: 0 }
+];
+
+const delOptions = [
+  { label: '姝e父', value: 0 },
+  { label: '鍒犻櫎', value: 1 }
+];
+
+type Model = Api.Qm.CheckitemOperateParams;
+
+const model = ref<Model>(createDefaultModel());
+const ridOptions = ref<{ label: string; value: string | number }[]>([]);
+const instrumentOptions = ref<{ label: string; value: string | number }[]>([]);
+
+async function fetchRidOptions(searchText?: string) {
+  const params: any = {};
+  if (searchText) {
+    params.itemName = searchText;
+  }
+  if (props.stdCode) {
+    params.stdCode = props.stdCode;
+  }
+
+  const { data } = await fetchGetRid(params);
+  if (data) {
+    ridOptions.value = data;
+  } else {
+    ridOptions.value = [];
+  }
+}
+
+function handleRidSelectSearch(query: string) {
+  fetchRidOptions(query);
+}
+
+async function fetchInstrumentOptions(searchText?: string) {
+  const params: any = {};
+  if (searchText) {
+    params.instrumentName = searchText;
+  }
+  const { data } = await fetchGetInstrumentList(params);
+  if (data && data.rows) {
+    instrumentOptions.value = data.rows.map(item => ({
+      label: item.instrumentName,
+      value: item.instrumentCode
+    }));
+  } else {
+    instrumentOptions.value = [];
+  }
+}
+
+function handleInstrumentSelectSearch(query: string) {
+  fetchInstrumentOptions(query);
+}
+
+
+function createDefaultModel(): Model {
+  return {
+      id: '',
+      itemCode: '',
+      itemName: '',
+      unit: '',
+      enable: 1,
+      del: 0,
+      itemDes: '',
+      stdCode: '',
+      instrumentDes: '',
+      location: '',
+      checkLevel: '',
+      ismix: null,
+      rid: null,
+      category: null,
+      instrumentCode: '',
+      score: null
+  };
+}
+
+type RuleKey = Extract<
+  keyof Model,
+  | 'id'
+>;
+
+const rules: Record<RuleKey, App.Global.FormRule> = {
+  id: createRequiredRule('缂栫爜涓嶈兘涓虹┖'),
+};
+
+async function handleUpdateModelWhenEdit() {
+  model.value = createDefaultModel();
+  ridOptions.value = []; // Clear options initially
+
+  if (props.operateType === 'edit' && props.rowData) {
+    Object.assign(model.value, jsonClone(props.rowData));
+  }
+
+  // Fetch options for rid
+  await fetchRidOptions();
+  // Fetch options for instrument
+  await fetchInstrumentOptions();
+
+  if (props.operateType === 'add' && props.stdCode) {
+    model.value.stdCode = props.stdCode;
+  }
+}
+
+function closeDrawer() {
+  visible.value = false;
+}
+
+async function handleSubmit() {
+  await validate();
+
+  const { id, itemCode, itemName, unit, enable, del, itemDes, stdCode, instrumentDes, location, checkLevel, ismix, rid, category, instrumentCode, score } = model.value;
+
+  // request
+  if (props.operateType === 'add') {
+    const payload = { itemCode, itemName, unit, enable, del, itemDes, stdCode, instrumentDes, location, checkLevel, ismix, rid, category, instrumentCode, score };
+    const { error } = await fetchCreateCheckitem(payload);
+    if (error) return;
+  }
+
+  if (props.operateType === 'edit') {
+    const payload = { id, itemCode, itemName, unit, enable, del, itemDes, stdCode, instrumentDes, location, checkLevel, ismix, rid, category, instrumentCode, score };
+    const { error } = await fetchUpdateCheckitem(payload);
+    if (error) return;
+  }
+
+  window.$message?.success($t('common.updateSuccess'));
+  closeDrawer();
+  emit('submitted');
+}
+
+watch(visible, () => {
+  if (visible.value) {
+    handleUpdateModelWhenEdit();
+    restoreValidation();
+  }
+});
+</script>
+
+<template>
+  <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
+    <NDrawerContent :title="title" :native-scrollbar="false" closable>
+      <NForm ref="formRef" :model="model" :rules="rules">
+        <NFormItem label="妫�楠岄」鐩唬鐮�" path="itemCode">
+          <NInput v-model:value="model.itemCode" placeholder="璇疯緭鍏ユ楠岄」鐩唬鐮�" />
+        </NFormItem>
+        <NFormItem label="妫�楠岄」鐩悕绉�" path="itemName">
+          <NInput v-model:value="model.itemName" placeholder="璇疯緭鍏ユ楠岄」鐩悕绉�" />
+        </NFormItem>
+        <NFormItem label="鍗曚綅" path="unit">
+          <NInput v-model:value="model.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+        </NFormItem>
+        <NFormItem label="鍚敤" path="enable">
+          <NSelect v-model:value="model.enable" :options="enableOptions" placeholder="璇烽�夋嫨鍚敤" clearable />
+        </NFormItem>
+        <NFormItem label="鍒犻櫎" path="del">
+          <NSelect v-model:value="model.del" :options="delOptions" placeholder="璇烽�夋嫨鍒犻櫎" clearable />
+        </NFormItem>
+        <NFormItem label="妫�楠岄」鎻忚堪" path="itemDes">
+          <NInput v-model:value="model.itemDes" placeholder="璇疯緭鍏ユ楠岄」鎻忚堪" />
+        </NFormItem>
+        <NFormItem label="妫�娴嬩华鍣�" path="instrumentCode">
+          <NSelect
+            v-model:value="model.instrumentCode"
+            :options="instrumentOptions"
+            placeholder="璇烽�夋嫨妫�娴嬩华鍣�"
+            clearable
+            filterable
+            @search="handleInstrumentSelectSearch"
+            @focus="() => fetchInstrumentOptions()"
+          />
+        </NFormItem>
+        <NFormItem label="浠櫒鎻忚堪" path="instrumentDes">
+          <NInput v-model:value="model.instrumentDes" placeholder="璇疯緭鍏ヤ华鍣ㄦ弿杩�" />
+        </NFormItem>
+        <NFormItem label="缂洪櫡浣嶇疆" path="location">
+          <NInput v-model:value="model.location" placeholder="璇疯緭鍏ョ己闄蜂綅缃�-澶栬鐢�" />
+        </NFormItem>
+        <NFormItem label="绾у埆" path="checkLevel">
+          <NSelect v-model:value="model.checkLevel" :options="checkLevelOptions" placeholder="璇烽�夋嫨绾у埆" clearable />
+        </NFormItem>
+        <NFormItem label="鏄惁鍚堟垚椤�" path="ismix">
+          <NSelect v-model:value="model.ismix" :options="ismixOptions" placeholder="璇烽�夋嫨鏄惁鍚堟垚椤�" clearable />
+        </NFormItem>
+        <NFormItem label="涓婄骇椤�" path="rid">
+          <NSelect
+            v-model:value="model.rid"
+            :options="ridOptions"
+            placeholder="璇烽�夋嫨涓婄骇椤�"
+            clearable
+            filterable
+            @search="handleRidSelectSearch"
+            @focus="() => fetchRidOptions()"
+          />
+        </NFormItem>
+        <NFormItem label="绫诲埆" path="category">
+          <NSelect v-model:value="model.category" :options="categoryOptions" placeholder="璇烽�夋嫨绫诲埆" clearable />
+        </NFormItem>
+        <NFormItem label="鍒嗗��" path="score">
+          <NInputNumber v-model:value="model.score" placeholder="璇疯緭鍏ュ垎鍊�" :precision="2" />
+        </NFormItem>
+      </NForm>
+      <template #footer>
+        <NSpace :size="16">
+          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
+          <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
+        </NSpace>
+      </template>
+    </NDrawerContent>
+  </NDrawer>
+</template>
+
+<style scoped></style>

--
Gitblit v1.9.3