Sfoglia il codice sorgente

1. Xbar-R、Xbar-S控制图字段修改
2. SPC任务管理自动生成任务编号
3. SPC控制图、过程能力指标上下限规则自定义

luofeng 3 settimane fa
parent
commit
cedebe48ff

+ 10 - 0
src/api/dict/index.ts

@@ -94,6 +94,16 @@ export function getDictPage(queryParams: object): AxiosPromise<any> {
     data: queryParams,
   });
 }
+/**
+ * 字典列表
+ */
+export function getDictList(queryParams: object): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/sys/dictData/list",
+    method: "post",
+    data: queryParams,
+  });
+}
 
 /**
  * 获取字典表单数据

+ 2 - 2
src/views/analysis/process/Xbar-RList.vue

@@ -331,7 +331,7 @@
               <!--              <el-form-item label="分析人" prop="analyseUser">
                 <el-input v-model="addData.analyseUser" />
               </el-form-item>-->
-              <el-form-item label="处置措施" prop="measure">
+              <el-form-item label="处置措施" prop="measure" v-if="addData.id">
                 <el-input v-model="addData.measure" />
               </el-form-item>
             </el-form>
@@ -356,7 +356,7 @@ import {
 import Search from "@/components/Search/index.vue";
 import { XBarRCompute, collectData } from "@/api/analysis";
 import { useCrud } from "@/hooks/userCrud";
-import {ElMessage, ElMessageBox} from "element-plus";
+import {ElMessageBox} from "element-plus";
 
 const { Utils } = useCrud({
   src: "/api/v1/spc/pDownloadTemplate",

+ 1 - 1
src/views/analysis/process/Xbar-SList.vue

@@ -330,7 +330,7 @@
               <!--              <el-form-item label="分析人" prop="analyseUser">-->
               <!--                <el-input v-model="addData.analyseUser" />-->
               <!--              </el-form-item>-->
-              <el-form-item label="处置措施" prop="measure">
+              <el-form-item label="处置措施" prop="measure" v-if="addData.id">
                 <el-input v-model="addData.measure" />
               </el-form-item>
             </el-form>

+ 254 - 15
src/views/analysis/process/index.vue

@@ -38,26 +38,129 @@
               :value="item.remark"
             />
           </el-select>
-          <div class="text" style="margin-top: 20px">
-            上限(3σ):{{ value ? JSON.parse(value).ucl : "-" }}
+          <!--          <div class="text" style="margin-top: 20px">-->
+          <!--            上限(3σ):{{ value ? JSON.parse(value).ucl : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            上限子界限(2σ):{{ value ? JSON.parse(value).ucl_c : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            上限子界限(σ):{{ value ? JSON.parse(value).ucl_b : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            中心线:{{ value ? JSON.parse(value).cl : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            下限子界限(σ):{{ value ? JSON.parse(value).lcl_c : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            下限子界限(2σ):{{ value ? JSON.parse(value).lcl_b : "-" }}-->
+          <!--          </div>-->
+          <!--          <div class="text">-->
+          <!--            下限(3σ):{{ value ? JSON.parse(value).lcl : "-" }}-->
+          <!--          </div>-->
+
+          <div
+            class="edit-item"
+            @dblclick="startEdit('ucl')"
+            style="margin-top: 20px"
+          >
+            <span v-if="!editing.ucl" class="text"
+              >上限(3σ):{{ displayValue.ucl }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.ucl"
+              ref="uclInput"
+              @blur="saveEdit('ucl')"
+              @keyup.enter="saveEdit('ucl')"
+              @keyup.escape="cancelEdit1('ucl')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            上限子界限(2σ):{{ value ? JSON.parse(value).ucl_c : "-" }}
+          <div class="edit-item" @dblclick="startEdit('ucl_c')">
+            <span v-if="!editing.ucl_c" class="text"
+              >上限子界限(2σ):{{ displayValue.ucl_c }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.ucl_c"
+              ref="ucl_cInput"
+              @blur="saveEdit('ucl_c')"
+              @keyup.enter="saveEdit('ucl_c')"
+              @keyup.escape="cancelEdit1('ucl_c')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            上限子界限(σ):{{ value ? JSON.parse(value).ucl_b : "-" }}
+          <div class="edit-item" @dblclick="startEdit('ucl_b')">
+            <span v-if="!editing.ucl_b" class="text"
+              >上限子界限(σ):{{ displayValue.ucl_b }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.ucl_b"
+              ref="ucl_bInput"
+              @blur="saveEdit('ucl_b')"
+              @keyup.enter="saveEdit('ucl_b')"
+              @keyup.escape="cancelEdit1('ucl_b')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            中心线:{{ value ? JSON.parse(value).cl : "-" }}
+          <div class="edit-item" @dblclick="startEdit('cl')">
+            <span v-if="!editing.cl" class="text"
+              >中心线:{{ displayValue.cl }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.cl"
+              ref="clInput"
+              @blur="saveEdit('cl')"
+              @keyup.enter="saveEdit('cl')"
+              @keyup.escape="cancelEdit1('cl')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            下限子界限(σ):{{ value ? JSON.parse(value).lcl_c : "-" }}
+          <div class="edit-item" @dblclick="startEdit('lcl_c')">
+            <span v-if="!editing.lcl_c" class="text"
+              >下限子界限(σ):{{ displayValue.lcl_c }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.lcl_c"
+              ref="lcl_cInput"
+              @blur="saveEdit('lcl_c')"
+              @keyup.enter="saveEdit('lcl_c')"
+              @keyup.escape="cancelEdit1('lcl_c')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            下限子界限(2σ):{{ value ? JSON.parse(value).lcl_b : "-" }}
+          <div class="edit-item" @dblclick="startEdit('lcl_b')">
+            <span v-if="!editing.lcl_b" class="text"
+              >下限子界限(2σ):{{ displayValue.lcl_b }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.lcl_b"
+              ref="lcl_bInput"
+              @blur="saveEdit('lcl_b')"
+              @keyup.enter="saveEdit('lcl_b')"
+              @keyup.escape="cancelEdit1('lcl_b')"
+              class="edit-input"
+            />
           </div>
-          <div class="text">
-            下限(3σ):{{ value ? JSON.parse(value).lcl : "-" }}
+          <div class="edit-item" @dblclick="startEdit('lcl')">
+            <span v-if="!editing.lcl" class="text"
+              >下限(3σ):{{ displayValue.lcl }}</span
+            >
+            <input
+              v-else
+              v-model.number="editValue.lcl"
+              ref="lclInput"
+              @blur="saveEdit('lcl')"
+              @keyup.enter="saveEdit('lcl')"
+              @keyup.escape="cancelEdit1('lcl')"
+              class="edit-input"
+            />
           </div>
         </div>
       </div>
@@ -175,6 +278,108 @@ import EWMA from "@/views/analysis/process/EWMA.vue";
 import IMR from "@/views/analysis/process/I-MR.vue";
 import U from "@/views/analysis/process/U.vue";
 
+import { getDictList, updateDict } from "@/api/dict";
+
+const operationList = ref();
+const initOpOptions = () => {
+  getDictList({ dictCode: "spc_operation" }).then(({ data }) => {
+    operationList.value = data;
+    opOptions.value = data;
+  });
+};
+initOpOptions();
+
+// 初始值
+let initialValue = ref({
+  ucl: 0,
+  ucl_c: 0,
+  ucl_b: 0,
+  cl: 0,
+  lcl_c: 0,
+  lcl_b: 0,
+  lcl: 0,
+});
+
+// 显示的值
+const displayValue = ref(reactive({ ...initialValue.value }));
+
+// 编辑状态
+const editing = reactive({
+  ucl: false,
+  ucl_c: false,
+  ucl_b: false,
+  cl: false,
+  lcl_c: false,
+  lcl_b: false,
+  lcl: false,
+});
+
+// 编辑时的临时值
+const editValue = reactive({ ...initialValue.value });
+
+// 输入框引用
+const uclInput = ref(null);
+const ucl_cInput = ref(null);
+const ucl_bInput = ref(null);
+const clInput = ref(null);
+const lcl_cInput = ref(null);
+const lcl_bInput = ref(null);
+const lclInput = ref(null);
+
+// 开始编辑
+const startEdit = (field) => {
+  editing[field] = true;
+  editValue[field] = displayValue.value[field];
+
+  nextTick(() => {
+    let inputRef = null;
+    switch (field) {
+      case "ucl":
+        inputRef = uclInput.value;
+        break;
+      case "ucl_c":
+        inputRef = ucl_cInput.value;
+        break;
+      case "ucl_b":
+        inputRef = ucl_bInput.value;
+        break;
+      case "cl":
+        inputRef = clInput.value;
+        break;
+      case "lcl_c":
+        inputRef = lcl_cInput.value;
+        break;
+      case "lcl_b":
+        inputRef = lcl_bInput.value;
+        break;
+      case "lcl":
+        inputRef = lclInput.value;
+        break;
+    }
+    inputRef?.focus();
+    inputRef?.select();
+  });
+};
+
+// 保存编辑
+const saveEdit = (field) => {
+  editing[field] = false;
+  displayValue.value[field] = editValue[field];
+  console.log(`保存${field}值:`, displayValue.value[field]);
+  operationList.value.forEach((v) => {
+    if (v.dictLabel === showLable.value) {
+      v.remark = JSON.stringify(displayValue.value);
+      updateDict(v);
+      value.value = JSON.stringify(displayValue.value);
+    }
+  });
+};
+
+// 取消编辑
+const cancelEdit1 = (field) => {
+  editing[field] = false;
+};
+
 const handleDataFromChildXbarR = async (data) => {
   await nextTick();
   xbarRRefMethod(data);
@@ -292,6 +497,7 @@ const xbarsListRef = ref("xbarsListRef");
 const showLable = ref("调阻");
 const changeSelect = () => {
   setTimeout(() => {
+    displayValue.value = JSON.parse(value.value);
     showLable.value = selectRef.value.currentPlaceholder;
     opOptions.value.forEach((item) => {
       if (item.dictLabel == showLable.value) {
@@ -640,6 +846,7 @@ onMounted(async () => {
   });
   value2.value = "Xbar-R";
   xbarrListRef.value.init(lableValue.value);
+  displayValue.value = JSON.parse(value.value);
 });
 onBeforeUnmount(() => {
   // window.removeEventListener("resize", setView);
@@ -652,6 +859,38 @@ onBeforeUnmount(() => {
     margin-left: -18%;
   }
 }
+.ctext {
+  margin-bottom: 20px;
+}
+.double-edit-container {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.edit-item {
+  padding: 8px 0px;
+  border-radius: 4px;
+  cursor: pointer;
+  transition: background-color 0.2s;
+  font-size: 15px;
+}
+
+.edit-item:hover {
+  background-color: #f5f5f5;
+}
+
+.edit-input {
+  width: 100px;
+  padding: 4px 8px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  outline: none;
+}
+
+.edit-input:focus {
+  border-color: #409eff;
+}
 
 .ellipsis-text {
   white-space: nowrap; /* 禁止换行 */
@@ -672,7 +911,7 @@ onBeforeUnmount(() => {
   background-color: white;
 
   .infobox {
-    width: 230px;
+    width: 250px;
 
     .header {
       //height: 120px;

+ 13 - 0
src/views/analysis/spc/index.vue

@@ -195,6 +195,7 @@ import {
   deleteData,
 } from "@/api/spc";
 import { ElMessage, ElMessageBox } from "element-plus";
+import { DatetimeFormat } from "vue-i18n";
 defineOptions({
   name: "SPCrules",
 });
@@ -355,6 +356,18 @@ const rules = {
 const opInfoData = ref([]);
 const toAdd = () => {
   addStatus.value = true;
+  formData.value.taskCode = "RW" + getCurrentTime();
+};
+const getCurrentTime = () => {
+  const now = new Date();
+  const year = now.getFullYear();
+  const month = String(now.getMonth() + 1).padStart(2, "0");
+  const day = String(now.getDate()).padStart(2, "0");
+  const hours = String(now.getHours()).padStart(2, "0");
+  const minutes = String(now.getMinutes()).padStart(2, "0");
+  const seconds = String(now.getSeconds()).padStart(2, "0");
+
+  return `${year}${month}${day}${hours}${minutes}${seconds}`;
 };
 const setEditFormData = (row) => {
   opInfoData.value.forEach((item, index) => {

+ 129 - 2
src/views/analysis/target/index/index.vue

@@ -18,11 +18,40 @@
         </el-select>
       </div>
       <div class="body">
-        <div class="text">上限:{{ value ? JSON.parse(value).up : "-" }}</div>
-        <div class="text">下限:{{ value ? JSON.parse(value).down : "-" }}</div>
+        <!--        <div class="text">上限:{{ value ? JSON.parse(value).up : "-" }}</div>-->
+        <!--        <div class="text">下限:{{ value ? JSON.parse(value).down : "-" }}</div>-->
         <!--        <div class="text">-->
         <!--          计量单位:{{ value ? JSON.parse(value).unit : "-" }}-->
         <!--        </div>-->
+        <div class="edit-item" @dblclick="startEdit('up')">
+          <span v-if="!editing.up" class="text"
+            >上限:{{ displayValue.up }}</span
+          >
+          <input
+            v-else
+            v-model.number="editValue.up"
+            ref="upInput"
+            @blur="saveEdit('up')"
+            @keyup.enter="saveEdit('up')"
+            @keyup.escape="cancelEdit1('up')"
+            class="edit-input"
+          />
+        </div>
+
+        <div class="edit-item" @dblclick="startEdit('down')">
+          <span v-if="!editing.down" class="text"
+            >下限:{{ displayValue.down }}</span
+          >
+          <input
+            v-else
+            v-model.number="editValue.down"
+            ref="downInput"
+            @blur="saveEdit('down')"
+            @keyup.enter="saveEdit('down')"
+            @keyup.escape="cancelEdit1('down')"
+            class="edit-input"
+          />
+        </div>
       </div>
     </div>
     <div class="databox">
@@ -714,6 +743,69 @@ import {
 } from "@/api/analysis";
 import Search from "@/components/Search/index.vue";
 import { ElMessage, ElMessageBox } from "element-plus";
+import { getDictList, updateDict } from "@/api/dict";
+
+const operationList = ref();
+const initOpOptions = () => {
+  getDictList({ dictCode: "spc_operation" }).then(({ data }) => {
+    operationList.value = data;
+    opOptions.value = data;
+  });
+};
+initOpOptions();
+
+// 初始值
+let initialValue = ref({
+  up: 0, // 默认上限值
+  down: 0, // 默认下限值
+});
+
+// 显示的值
+const displayValue = ref(reactive({ ...initialValue.value }));
+
+// 编辑状态
+const editing = reactive({
+  up: false,
+  down: false,
+});
+
+// 编辑时的临时值
+const editValue = reactive({ ...initialValue.value });
+
+// 输入框引用
+const upInput = ref(null);
+const downInput = ref(null);
+
+// 开始编辑
+const startEdit = (field) => {
+  editing[field] = true;
+  editValue[field] = displayValue.value[field];
+
+  nextTick(() => {
+    const inputRef = field === "up" ? upInput.value : downInput.value;
+    inputRef?.focus();
+    inputRef?.select();
+  });
+};
+
+// 保存编辑
+const saveEdit = (field) => {
+  editing[field] = false;
+  displayValue.value[field] = editValue[field];
+  console.log(`保存${field}值:`, displayValue.value[field]);
+  operationList.value.forEach((v) => {
+    if (v.dictLabel === showLable.value) {
+      v.remark = JSON.stringify(displayValue.value);
+      updateDict(v);
+      value.value = JSON.stringify(displayValue.value);
+    }
+  });
+};
+
+// 取消编辑
+const cancelEdit1 = (field) => {
+  editing[field] = false;
+};
 
 // 在你的组件 setup 中
 const loadingRows = ref({});
@@ -1145,6 +1237,7 @@ const lableValue = ref("");
 const changeSelect = () => {
   setTimeout(() => {
     getTaskOption();
+    displayValue.value = JSON.parse(value.value);
     showLable.value = selectRef.value.currentPlaceholder;
     opOptions.value.forEach((item) => {
       if (item.dictLabel == showLable.value) {
@@ -1544,6 +1637,7 @@ onMounted(() => {
       lableValue.value = item.dictValue;
     }
   });
+  displayValue.value = JSON.parse(value.value);
   getTableData();
   // nextTick(() => {
   //   charts1.value = echarts.init(document.getElementById("charts"));
@@ -1600,6 +1694,39 @@ onMounted(() => {
     alignitems: center;
   }
 }
+.ctext {
+  margin-bottom: 20px;
+}
+.double-edit-container {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.edit-item {
+  padding: 8px 0px;
+  border-radius: 4px;
+  cursor: pointer;
+  transition: background-color 0.2s;
+  font-size: 15px;
+}
+
+.edit-item:hover {
+  background-color: #f5f5f5;
+}
+
+.edit-input {
+  width: 100px;
+  padding: 4px 8px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  outline: none;
+}
+
+.edit-input:focus {
+  border-color: #409eff;
+}
+
 .ellipsis-text {
   white-space: nowrap; /* 禁止换行 */
   overflow: hidden; /* 隐藏超出部分 */