董国庆
2025-04-10 97859a83884898fb2e87040bfae254acf7848e6b
新增的页面
2 文件已重命名
3个文件已修改
5个文件已添加
2187 ■■■■ 已修改文件
src/router/index.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleManage/addSample.vue 683 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleManage/list.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleRecordList/changeRecord.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleRecordList/components/confirmDialog.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleRecordList/components/sampleDialog.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleRecordList/list.vue 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleSubmissionList/components/receiveConfirmDialog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleSubmissionList/list.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/sampleSubmissionList/submission.vue 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js
@@ -206,6 +206,40 @@
                            keepAlive: true,
                        },
                        component: () => import("../views/dataManagement/sampleManage/addSample"),
                    }, {
                        path: "record",
                        meta: {
                            title: "取样操作记录列表",
                            keepAlive: true,
                        },
                        component: () => import("../views/dataManagement/sampleRecordList/list.vue"),
                    },
                    {
                        path: "changeRecord",
                        name: "changeRecord",
                        meta: {
                            title: "填写取样操作记录",
                            hide: true,
                            keepAlive: true,
                        },
                        component: () => import("../views/dataManagement/sampleRecordList/changeRecord"),
                    },{
                        path: "submissionList",
                        meta: {
                            title: "送样单列表",
                            keepAlive: true,
                        },
                        component: () => import("../views/dataManagement/sampleSubmissionList/list.vue"),
                    },
                    {
                        path: "submission",
                        name: "submission",
                        meta: {
                            title: "送样单详情",
                            hide: true,
                            keepAlive: true,
                        },
                        component: () => import("../views/dataManagement/sampleSubmissionList/submission"),
                    },
                ]
                
src/views/dataManagement/sampleManage/addSample.vue
@@ -3,21 +3,12 @@
    <div class="header-title-left">
      <img src="@/assets/public/headercard.png" />
      <div>所属实验调度</div>
      <el-button
        v-if="isEngineer"
        @click="showScheduling = true"
        class="el-icon-plus"
        type="primary"
      >
        选择实验调度</el-button
      >
      <el-button v-if="isEngineer" @click="showScheduling = true" class="el-icon-plus" type="primary">
        选择实验调度</el-button>
    </div>
    <Table :data="schedulingData" :total="schedulingTotal" :height="null">
      <template>
        <el-table-column
          prop="planCode"
          label="所属项目课题方案"
        ></el-table-column>
        <el-table-column prop="planCode" label="所属项目课题方案"></el-table-column>
        <el-table-column prop="planName" label="实验编号"></el-table-column>
        <el-table-column prop="planName" label="实验名称"></el-table-column>
        <el-table-column prop="stage" label="通知时间"></el-table-column>
@@ -33,14 +24,23 @@
      <div class="header-title-left" style="margin-top: 38px">
        <img src="@/assets/public/headercard.png" />
        <span>送样-收样记录</span>
        <el-button type="primary" class="el-icon-plus" @click="showPendingColumns = !showPendingColumns">
          {{ showPendingColumns ? "收起待收样详情" : "展开待收样详情" }}
        </el-button>
        <el-button type="primary" class="el-icon-plus" @click="showReceivedColumns = !showReceivedColumns">
          {{ showReceivedColumns ? "收起已收样详情" : "展开已收样详情" }}
        </el-button>
      </div>
      <div class="sample-code">取样单编号:{{ form.sampleCode || 'DD-25010BS01' }}</div>
      <div class="sample-code">
        取样单编号:{{ form.sampleCode || "DD-25010BS01" }}
      </div>
      <!-- 待收样列表 -->
      <div class="pending-samples">
        <div class="sub-title">待收样列表</div>
        <el-button type="primary" class="batch-receive" @click="handleBatchReceive">批量接收</el-button>
        <Table :data="pendingSamples" :total="pendingSamplesTotal" :height="null" @selection-change="handleSelectionChange">
        <Table :data="pendingSamples" :total="pendingSamplesTotal" :height="null"
          @selection-change="handleSelectionChange">
          <template>
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column prop="index" label="序号" width="80"></el-table-column>
@@ -51,7 +51,16 @@
            <el-table-column prop="sendTime" label="送样时间"></el-table-column>
            <el-table-column prop="sender" label="送样人"></el-table-column>
            <el-table-column prop="status" label="状态"></el-table-column>
            <el-table-column label="操作" width="100">
            <template v-if="showPendingColumns">
              <el-table-column prop="temperature" label="温度" width="150"></el-table-column>
              <el-table-column prop="waterAmount" label="加水量" width="150"></el-table-column>
              <el-table-column prop="additive1" label="加辅1" width="150"></el-table-column>
              <el-table-column prop="additive2" label="加辅2" width="150"></el-table-column>
              <el-table-column prop="additive3" label="加辅3" width="150"></el-table-column>
              <el-table-column prop="additive4" label="加辅4" width="150"></el-table-column>
              <el-table-column prop="additive5" label="加辅5" width="150"></el-table-column>
            </template>
            <el-table-column label="操作" width="100" fixed="right">
              <template slot-scope="scope">
                <el-button type="text" @click="handleReceive(scope.row)">接收</el-button>
              </template>
@@ -68,240 +77,108 @@
            <el-table-column prop="index" label="序号" width="80"></el-table-column>
            <el-table-column prop="sampleName" label="取样名称"></el-table-column>
            <el-table-column prop="sampleCode" label="取样样品编号"></el-table-column>
            <el-table-column prop="temperature" label="温度" width="150"></el-table-column>
            <el-table-column prop="waterAmount" label="加水量" width="150"></el-table-column>
            <el-table-column prop="ph" label="PH"></el-table-column>
            <template v-if="showReceivedColumns">
              <el-table-column prop="additive1" label="加辅1" width="150"></el-table-column>
              <el-table-column prop="additive2" label="加辅2" width="150"></el-table-column>
              <el-table-column prop="additive3" label="加辅3" width="150"></el-table-column>
              <el-table-column prop="additive4" label="加辅4" width="150"></el-table-column>
              <el-table-column prop="additive5" label="加辅5" width="150"></el-table-column>
            </template>
            <el-table-column prop="sampleAmount" label="取样量"></el-table-column>
            <el-table-column prop="sendTime" label="送样时间"></el-table-column>
            <el-table-column prop="sender" label="送样人"></el-table-column>
            <el-table-column prop="receiveTime" label="收样时间"></el-table-column>
            <el-table-column prop="receiver" label="收样人"></el-table-column>
            <el-table-column prop="status" label="状态"></el-table-column>
            <el-table-column prop="status" label="状态" fixed="right"></el-table-column>
          </template>
        </Table>
      </div>
    </div>
    <!-- 非化验师部分 -->
    <div v-if="!isAssayer">
    <!-- 工程师部分 -->
    <div v-if="isEngineer">
      <div class="header-title-left" style="margin-top: 38px">
        <img src="@/assets/public/headercard.png" />
        <span>基础信息</span>
      </div>
      <el-form
        v-if="!isExperimenter"
        ref="form"
        :model="form"
        :rules="rules"
        inline
        label-position="top"
      >
      <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
        <el-form-item label="取样单编号" prop="sampleCode">
          <el-input
            v-model="form.sampleCode"
            :disabled="!isExperimenter"
            :placeholder="isExperimenter ? '请输入取样单编号' : '自动生成'"
          />
          <el-input v-model="form.sampleCode" :disabled="true" placeholder="自动生成" />
        </el-form-item>
      </el-form>
      <div v-else class="number">取样单编号:213421241</div>
      <div class="header-title-left" style="margin-top: 38px">
        <img src="@/assets/public/headercard.png" />
        <span>取样操作记录</span>
        <el-button
          v-if="isEngineer"
          type="primary"
          class="el-icon-plus"
          @click="showAddTime = true"
        >
        <el-button type="primary" class="el-icon-plus" @click="showAddTime = true">
          新增工艺时间
        </el-button>
        <el-button
          type="primary"
          class="el-icon-plus"
          @click="showAdditives = !showAdditives"
        >
        <el-button type="primary" class="el-icon-plus" @click="showAdditives = !showAdditives">
          {{ showAdditives ? "收起辅料详情" : "展开辅料详情" }}
        </el-button>
      </div>
    </div>
    <Table v-if="!isAssayer" :data="sampleData" :total="sampleTotal" :height="null">
      <template>
        <el-table-column prop="index" label="序号" width="80"></el-table-column>
        <el-table-column
          prop="processTime"
          label="工艺时间"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="sampleName"
          label="取样名称"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="sampleCode"
          label="取样样品编号"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="temperature"
          label="温度"
          width="150"
        ></el-table-column>
        <el-table-column prop="ph" label="PH" width="150"></el-table-column>
        <el-table-column
          prop="waterAmount"
          label="加水量"
          width="150"
        ></el-table-column>
        <template v-if="showAdditives">
          <el-table-column
            prop="additive1"
            label="加辅1"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive2"
            label="加辅2"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive3"
            label="加辅3"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive4"
            label="加辅4"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive5"
            label="加辅5"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive6"
            label="加辅6"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive7"
            label="加辅7"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive8"
            label="加辅8"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive9"
            label="加辅9"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive10"
            label="加辅10"
            width="150"
          ></el-table-column>
        </template>
        <el-table-column
          prop="sampleAmount"
          label="取样量"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="sampleTime"
          label="取样时间"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="remark"
          label="拍照"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="operator"
          label="操作人员"
          width="150"
        ></el-table-column>
        <el-table-column
          v-if="isExperimenter"
          fixed="right"
          label="操作"
          width="150"
        >
          <template slot-scope="scope">
            <el-button type="text" @click="handleEdit(scope.$index, scope.row)"
              >编辑</el-button
            >
      <Table :data="sampleData" :total="sampleTotal" :height="null">
        <template>
          <el-table-column prop="index" label="序号" width="80"></el-table-column>
          <el-table-column prop="processTime" label="工艺时间" width="150"></el-table-column>
          <el-table-column prop="sampleName" label="取样名称" width="150"></el-table-column>
          <el-table-column prop="sampleCode" label="取样样品编号" width="150"></el-table-column>
          <el-table-column prop="temperature" label="温度" width="150"></el-table-column>
          <el-table-column prop="ph" label="PH" width="150"></el-table-column>
          <el-table-column prop="waterAmount" label="加水量" width="150"></el-table-column>
          <template v-if="showAdditives">
            <el-table-column prop="additive1" label="加辅1" width="150"></el-table-column>
            <el-table-column prop="additive2" label="加辅2" width="150"></el-table-column>
            <el-table-column prop="additive3" label="加辅3" width="150"></el-table-column>
            <el-table-column prop="additive4" label="加辅4" width="150"></el-table-column>
            <el-table-column prop="additive5" label="加辅5" width="150"></el-table-column>
            <el-table-column prop="additive6" label="加辅6" width="150"></el-table-column>
            <el-table-column prop="additive7" label="加辅7" width="150"></el-table-column>
            <el-table-column prop="additive8" label="加辅8" width="150"></el-table-column>
            <el-table-column prop="additive9" label="加辅9" width="150"></el-table-column>
            <el-table-column prop="additive10" label="加辅10" width="150"></el-table-column>
          </template>
        </el-table-column>
      </template>
    </Table>
    <div class="remark-section" v-if="isExperimenter && !isAssayer">
      <el-form :model="form" label-position="top">
        <el-form-item label="备注">
          <el-input
            type="textarea"
            v-model="form.remark"
            :rows="4"
            placeholder="请输入备注信息"
          ></el-input>
        </el-form-item>
      </el-form>
          <el-table-column prop="sampleAmount" label="取样量" width="150"></el-table-column>
          <el-table-column prop="sampleTime" label="取样时间" width="150"></el-table-column>
          <el-table-column prop="remark" label="拍照" width="150"></el-table-column>
          <el-table-column prop="operator" label="操作人员" width="150"></el-table-column>
        </template>
      </Table>
      <div class="add-project-footer">
        <el-button type="primary" class="save-btn" @click="handleSave">保存</el-button>
        <el-button>存草稿</el-button>
      </div>
    </div>
    <div class="add-project-footer" v-if="!isAssayer">
      <el-button type="primary" class="save-btn" @click="handleSave">保存</el-button>
      <el-button>存草稿</el-button>
    </div>
    <experimentalScheduling :show="showScheduling" />
    <addTime :show.sync="showAddTime" @confirm="handleAddTime" />
    <sample-dialog
      :visible.sync="showSampleDialog"
      :data="currentSampleData"
      @submit="handleSampleSubmit"
    />
    <confirm-dialog
      :visible.sync="showConfirmDialog"
      :form-data="form"
      :sample-data="sampleData"
      @confirm="handleConfirm"
    />
    <receive-confirm-dialog
      :visible.sync="showReceiveConfirm"
      :sample-count="selectedSamples.length"
      @confirm="confirmReceive"
    />
    <receive-confirm-dialog :visible.sync="showReceiveConfirm" :sample-count="selectedSamples.length"
      @confirm="confirmReceive" />
  </Card>
</template>
<script>
import experimentalScheduling from "./components/experimental-scheduling.vue";
import addTime from "./components/addTime.vue";
import SampleDialog from "./components/sampleDialog.vue";
import ConfirmDialog from './components/confirmDialog.vue';
import ReceiveConfirmDialog from './components/receiveConfirmDialog.vue'
import ReceiveConfirmDialog from "./components/receiveConfirmDialog.vue";
export default {
  name: "AddConfirmationSheet",
  name: "AddSample",
  components: {
    experimentalScheduling,
    addTime,
    SampleDialog,
    ConfirmDialog,
    ReceiveConfirmDialog
    ReceiveConfirmDialog,
  },
  props: {},
  data() {
    return {
      showScheduling: false,
      showAddTime: false,
      showAdditives: true,
      showSampleDialog: false,
      showConfirmDialog: false,
      showReceiveConfirm: false,
      currentSampleData: {},
      currentEditIndex: -1,
      showPendingColumns: true,
      showReceivedColumns: true,
      schedulingData: [],
      schedulingTotal: 0,
      sampleData: [
@@ -326,7 +203,7 @@
          sampleAmount: "100ml",
          sampleTime: "2024-03-20 10:00:00",
          remark: "",
          operator: "张三"
          operator: "张三",
        },
        {
          index: 2,
@@ -355,15 +232,13 @@
      sampleTotal: 2,
      form: {
        sampleCode: "",
        remark: "",
      },
      rules: {
        sampleCode: [
          { required: true, message: "请输入取样单编号", trigger: "blur" },
        ],
      },
      menu: [],
      userRole: "experimenter", // 用户角色,可以是 'engineer'、'experimenter' 或 'assayer'
      userRole: "assayer", // engineer默认设置为工程师assayer化验师
      // 化验师相关数据
      pendingSamples: [
        {
@@ -374,7 +249,7 @@
          sampleAmount: "34",
          sendTime: "2025-1-9 15:26:08",
          sender: "李四",
          status: "待接收"
          status: "待接收",
        },
        {
          index: 2,
@@ -384,7 +259,7 @@
          sampleAmount: "23",
          sendTime: "2025-1-9 15:26:08",
          sender: "李四",
          status: "待接收"
          status: "待接收",
        },
        {
          index: 3,
@@ -394,8 +269,8 @@
          sampleAmount: "23",
          sendTime: "2025-1-13 16:38:17",
          sender: "李四",
          status: "待接收"
        }
          status: "待接收",
        },
      ],
      pendingSamplesTotal: 3,
      receivedSamples: [
@@ -409,7 +284,7 @@
          sender: "李四",
          receiveTime: "2025-1-15 14:00:50",
          receiver: "段向蒙",
          status: "已接收"
          status: "已接收",
        },
        {
          index: 2,
@@ -421,7 +296,7 @@
          sender: "李四",
          receiveTime: "2025-1-15 14:00:50",
          receiver: "傅彦涛",
          status: "已接收"
          status: "已接收",
        },
        {
          index: 3,
@@ -433,196 +308,23 @@
          sender: "李四",
          receiveTime: "2025-1-15 14:00:50",
          receiver: "王乐康",
          status: "已接收"
        }
          status: "已接收",
        },
      ],
      receivedSamplesTotal: 3,
      selectedSamples: []
      selectedSamples: [],
    };
  },
  computed: {
    height() {
      return this.$baseTableHeight();
    },
    isEngineer() {
      return this.userRole === "engineer";
    },
    isExperimenter() {
      return this.userRole === "experimenter";
    },
    isAssayer() {
      return this.userRole === "assayer";
    },
  },
  watch: {},
  created() {},
  mounted() {},
  methods: {
    setSelectedIds(arr, selectKeyList) {
      function traverse(item) {
        item.selected = selectKeyList.includes(item.menuId);
        if (item.children && item.children.length > 0) {
          item.children.forEach(traverse);
        }
      }
      arr.forEach(traverse);
      return arr;
    },
    onSubmit() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.getSelectedIds(this.menu).length == 0) {
            this.msgwarning("请勾选操作权限");
            return;
          }
          let obj = {
            ...this.form,
            menuIds: this.getSelectedIds(this.menu),
          };
          if (this.$route.query && this.$route.query.roleId) {
            obj.roleId = this.$route.query.roleId;
            edit(obj).then(() => {
              this.msgsuccess("保存成功");
              this.$router.go(-1);
            });
          } else {
            add(obj).then(() => {
              this.msgsuccess("保存成功");
              this.form = {
                roleName: "",
                remark: "",
              };
              this.menu = [];
              this.$router.go(-1);
            });
          }
        }
      });
    },
    getSelectedIds(arr) {
      let result = [];
      function traverse(item) {
        if (item.selected) {
          result.push(item.menuId);
        }
        if (item.children && item.children.length > 0) {
          for (let children of item.children) {
            traverse(children);
          }
        }
      }
      for (let item of arr) {
        traverse(item);
      }
      return result;
    },
    setCheckStatus1(id, status) {
      //点击第1级
      if (!status) {
        this.menu = this.menu.map((item) => {
          if (item.menuId == id) {
            item.selected = status;
            if (item.children.length > 0) {
              item.children = item.children.map((item1) => {
                item1.selected = status;
                if (item1.children.length > 0) {
                  item1.children = item1.children.map((item2) => {
                    item2.selected = status;
                    return { ...item2 };
                  });
                }
                return { ...item1 };
              });
            }
          }
          return { ...item };
        });
      } else {
        this.menu = this.menu.map((item) => {
          if (item.menuId == id) {
            item.selected = true;
          }
          return { ...item };
        });
      }
    },
    setCheckStatus2(id, status, aId) {
      //点击第2级
      this.menu = this.menu.map((item) => {
        if (item.menuId == aId) {
          item.selected = true;
          if (item.children.length > 0) {
            item.children = item.children.map((item1) => {
              if (item1.menuId == id) {
                item1.selected = status;
              }
              return { ...item1 };
            });
          }
        }
        return { ...item };
      });
    },
    setCheckStatus3(id, status, bId, aId) {
      //点击第3级
      this.menu = this.menu.map((item) => {
        if (item.menuId == aId) {
          item.selected = true;
          if (item.children.length > 0) {
            item.children = item.children.map((item1) => {
              if (item1.menuId == bId) {
                item1.selected = true;
                if (item1.children.length > 0) {
                  item1.children = item1.children.map((item2) => {
                    if (item2.menuId == id) {
                      item2.selected = status;
                    }
                    return { ...item2 };
                  });
                }
              }
              return { ...item1 };
            });
          }
        }
        return { ...item };
      });
    },
    handleEdit(index, row) {
      this.currentEditIndex = index;
      this.currentSampleData = { ...row };
      this.showSampleDialog = true;
    },
    handleSampleSubmit(formData) {
      if (this.currentEditIndex > -1) {
        // 更新表格数据
        this.$set(this.sampleData, this.currentEditIndex, {
          ...this.sampleData[this.currentEditIndex],
          ...formData,
        });
        this.currentEditIndex = -1;
      }
      this.showSampleDialog = false;
    },
    handleDelete(index, row) {
      this.$confirm("确认删除该记录吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.sampleData.splice(index, 1);
          // 重新计算序号
          this.sampleData.forEach((item, i) => {
            item.index = i + 1;
          });
          this.$message.success("删除成功");
        })
        .catch(() => {});
    },
    handleAddTime(processTime) {
      if (!this.isEngineer) return;
      const newRow = {
        index: this.sampleData.length + 1,
        processTime,
@@ -650,20 +352,12 @@
      this.$message.success("添加工艺时间成功");
    },
    handleSave() {
      if (this.isExperimenter) {
        this.showConfirmDialog = true;
      } else {
        this.submitForm();
      }
      this.submitForm();
    },
    handleConfirm(signature) {
      this.submitForm(signature);
    },
    submitForm(signature = null) {
    submitForm() {
      // 在这里实现表单提交逻辑
      console.log('提交表单数据', { signature });
      this.$message.success('保存成功');
      this.showConfirmDialog = false;
      console.log("提交表单数据");
      this.$message.success("保存成功");
    },
    handleSelectionChange(selection) {
      this.selectedSamples = selection;
@@ -674,162 +368,43 @@
    },
    handleBatchReceive() {
      if (this.selectedSamples.length === 0) {
        this.$message.warning('请先选择要接收的样品');
        this.$message.warning("请先选择要接收的样品");
        return;
      }
      this.showReceiveConfirm = true;
    },
    confirmReceive(signature) {
      // 这里处理接收确认逻辑
      const sampleIds = this.selectedSamples.map(item => item.id);
      console.log('接收样品', { sampleIds, signature });
      const sampleIds = this.selectedSamples.map((item) => item.id);
      console.log("接收样品", { sampleIds, signature });
      // 模拟接收成功
      this.$message.success(`成功接收 ${this.selectedSamples.length} 个样品`);
      // 更新数据
      this.selectedSamples.forEach(sample => {
        const index = this.pendingSamples.findIndex(item => item.id === sample.id);
      this.selectedSamples.forEach((sample) => {
        const index = this.pendingSamples.findIndex(
          (item) => item.id === sample.id
        );
        if (index > -1) {
          this.pendingSamples.splice(index, 1);
          this.receivedSamples.unshift({
            ...sample,
            receiveTime: new Date().toLocaleString(),
            receiver: '当前用户',
            status: '已接收'
            receiver: "当前用户",
            status: "已接收",
          });
        }
      });
      // 清空选择
      this.selectedSamples = [];
    }
    },
  },
};
</script>
<style lang="less" scoped>
.title_box {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  font-weight: bold;
  div:first-child {
    width: 4px;
    height: 16px;
    background: #598dec;
    margin-right: 8px;
  }
}
.no-data {
  height: 100%;
  background-color: #fff;
  border-radius: 0 0 6px 6px;
  border-left: 1px solid #e8e8e8;
  border-right: 1px solid #e8e8e8;
  border-bottom: 1px solid #e8e8e8;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 14px;
}
.add-project-footer {
  margin-top: 43px;
  button {
    width: 220px;
  }
  .save-btn {
    margin-right: 20px;
  }
}
.el-checkbox {
  display: flex;
  align-items: center;
}
.number{
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0,0,0,0.88);
}
.row,
.header {
  display: flex;
  align-items: center;
  border: 1px solid #e8e8e8;
  .w20 {
    width: 15%;
    padding: 8px 20px;
  }
  .sconed {
    flex: 1;
    .subpage {
      .title {
        border: 1px solid #e8e8e8;
        border-top: none;
        border-bottom: none;
      }
      .two {
        display: flex;
        align-items: center;
        border: 1px solid #e8e8e8;
        border-top: none;
        border-right: none;
        .left {
          width: 200px;
          padding: 13px 20px;
          border-right: 1px solid #e8e8e8;
        }
        .right {
          display: flex;
          flex: 1;
          div {
            padding: 13px 0 13px 20px;
          }
        }
      }
      .two:last-child {
        border-bottom: none;
      }
      .btns {
        display: flex;
        align-items: center;
        padding: 0 20px;
      }
    }
  }
}
.header {
  border-radius: 16px 16px 0 0;
  background-color: #fafafa;
  color: #909399;
  .subpage {
    display: flex;
  }
  .title {
    width: 200px;
    padding: 8px 20px;
  }
}
.header-title-left {
  display: flex;
  align-items: center;
@@ -859,6 +434,7 @@
      margin-right: 4px;
    }
  }
  span {
    flex-shrink: 0;
    font-weight: bold;
@@ -869,39 +445,15 @@
  }
}
.remark-section {
  margin-top: 20px;
.add-project-footer {
  margin-top: 43px;
  .el-form-item {
    width: 100%;
    .el-textarea {
      width: 100%;
    }
  }
}
.signature-section {
  margin-top: 26px;
}
.add-group {
  padding-left: 25px;
  margin-top: 14px;
  display: flex;
  align-items: center;
  margin-bottom: 19px;
  div {
    color: #f56c6c;
  button {
    width: 220px;
  }
  span {
    font-weight: 500;
    font-size: 14px;
    color: #222222;
    line-height: 21px;
    margin: 0 32px 0 8px;
  .save-btn {
    margin-right: 20px;
  }
}
@@ -910,7 +462,7 @@
    font-family: PingFangSC, PingFang SC;
    font-weight: 400;
    font-size: 14px;
    color: rgba(0,0,0,0.88);
    color: rgba(0, 0, 0, 0.88);
    margin: 20px 0;
  }
@@ -927,7 +479,8 @@
    margin-bottom: 16px;
  }
  .pending-samples, .received-samples {
  .pending-samples,
  .received-samples {
    // margin-top: 20px;
  }
}
src/views/dataManagement/sampleManage/list.vue
@@ -9,6 +9,9 @@
          <el-form-item label="实验编号:">
            <el-input v-model="form.planCode" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="创建人:" v-if="isChemist">
            <el-input v-model="form.creator" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="创建时间:">
            <el-date-picker
              v-model="form.createTime"
@@ -19,8 +22,11 @@
              value-format="yyyy-MM-dd"
            ></el-date-picker>
          </el-form-item>
          <el-form-item label="状态:">
          <el-form-item label="状态:" v-if="!isChemist">
            <el-input v-model="form.approver" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验名称:" v-if="isChemist">
            <el-input v-model="form.experimentName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="">
            <el-button type="default" @click="resetForm">重置</el-button>
@@ -49,54 +55,14 @@
      </template>
      <template #table>
        <el-table-column
          prop="planCode"
          label="项目课题方案编号"
          v-for="(column, index) in currentColumns"
          :key="index"
          :prop="column.prop"
          :label="column.label"
        ></el-table-column>
        <el-table-column
          prop="planName"
          label="项目课题方案名称"
        ></el-table-column>
        <el-table-column prop="stage" label="项目阶段"></el-table-column>
        <el-table-column prop="creator" label="创建人"></el-table-column>
        <el-table-column prop="createTime" label="创建日期"></el-table-column>
        <el-table-column prop="status" label="审批状态">
        <el-table-column label="操作" width="100">
          <template slot-scope="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="approver" label="审批人"></el-table-column>
        <el-table-column prop="approveTime" label="审批时间"></el-table-column>
        <el-table-column label="操作" width="250">
          <template slot-scope="scope">
            <el-button
              v-if="scope.row.status === 'pending'"
              type="text"
              @click="handleApprove(scope.row)"
              >审批</el-button
            >
            <el-button
              v-if="scope.row.status === 'approved'"
              type="text"
              @click="handleRevokeApprove(scope.row)"
              >撤销审批</el-button
            >
            <el-button
              v-if="scope.row.status === 'rejected'"
              type="text"
              @click="handleEdit(scope.row)"
              >编辑</el-button
            >
            <el-button
              v-if="scope.row.status === 'rejected'"
              type="text"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
            <el-button type="text" @click="handleDetail(scope.row)"
              >详情</el-button
            >
            <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button>
          </template>
        </el-table-column>
      </template>
@@ -122,6 +88,7 @@
  },
  data() {
    return {
      userRole: 'chemist', // 用户角色
      currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱
      form: {
        planName: "",
@@ -130,62 +97,111 @@
        createTime: [],
        approver: "",
        status: "",
        experimentName: "",
        sampleCount: "",
        receivedStatus: ""
      },
      tableData: [],
      total: 0,
      // 不同角色的表头配置
      columnConfig: {
        default: [
          { prop: 'projectPlan', label: '所属项目课题方案' },
          { prop: 'experimentNo', label: '实验编号' },
          { prop: 'experimentName', label: '实验名称' },
          { prop: 'sampleNo', label: '取样单编号' },
          { prop: 'creator', label: '创建人' },
          { prop: 'createTime', label: '创建时间' },
          { prop: 'sendTo', label: '发送对象' },
          { prop: 'sendTime', label: '发送时间' }
        ],
        chemist: [
          { prop: 'projectPlan', label: '所属项目课题方案' },
          { prop: 'experimentNo', label: '实验编号' },
          { prop: 'experimentName', label: '实验名称' },
          { prop: 'sampleNo', label: '取样单编号' },
          { prop: 'creator', label: '创建人' },
          { prop: 'createTime', label: '创建时间' },
          { prop: 'sampleCount', label: '样品总数' },
          { prop: 'receivedCount', label: '待接收' },
          { prop: 'completedCount', label: '已接收' }
        ]
      },
      // 模拟数据
      mockListData: [
        {
          planCode: 'PLAN-2024-001',
          planName: '2024年度实验室设备升级方案',
          stage: '规划阶段',
          id: '1',
          projectPlan: '2024年度实验室设备性能评估方案',
          experimentNo: 'EXP20240315001',
          experimentName: '设备性能测试实验A',
          sampleNo: 'SAMPLE20240315001',
          creator: '张三',
          createTime: '2024-03-15',
          status: 'pending',
          approver: '李四',
          approveTime: '2024-03-16'
          createTime: '2024-03-15 09:30:00',
          sendTo: '质检部门',
          sendTime: '2024-03-15 10:00:00',
          sampleCount: 5,
          receivedCount: 2,
          completedCount: 3
        },
        {
          planCode: 'PLAN-2024-002',
          planName: '实验室安全管理制度更新方案',
          stage: '实施阶段',
          id: '2',
          projectPlan: '新型材料研究项目方案',
          experimentNo: 'EXP20240315002',
          experimentName: '材料强度测试实验',
          sampleNo: 'SAMPLE20240315002',
          creator: '李四',
          createTime: '2024-03-15 11:30:00',
          sendTo: '研发部门',
          sendTime: '2024-03-15 14:00:00',
          sampleCount: 3,
          receivedCount: 1,
          completedCount: 2
        },
        {
          id: '3',
          projectPlan: '环境监测系统优化方案',
          experimentNo: 'EXP20240315003',
          experimentName: '空气质量检测实验',
          sampleNo: 'SAMPLE20240315003',
          creator: '王五',
          createTime: '2024-03-14',
          status: 'approved',
          approver: '赵六',
          approveTime: '2024-03-15'
          createTime: '2024-03-15 15:30:00',
          sendTo: '环境监测组',
          sendTime: '2024-03-15 16:00:00'
        },
        {
          planCode: 'PLAN-2024-003',
          planName: '实验室人员培训计划',
          stage: '准备阶段',
          creator: '孙七',
          createTime: '2024-03-13',
          status: 'rejected',
          approver: '周八',
          approveTime: '2024-03-14'
          id: '4',
          projectPlan: '生物样本分析项目',
          experimentNo: 'EXP20240315004',
          experimentName: '细胞活性测试',
          sampleNo: 'SAMPLE20240315004',
          creator: '赵六',
          createTime: '2024-03-15 16:30:00',
          sendTo: '生物实验室',
          sendTime: '2024-03-15 17:00:00'
        }
      ],
      mockDraftData: [
        {
          planCode: 'DRAFT-2024-001',
          planName: '实验室设备采购计划(草稿)',
          stage: '规划阶段',
          creator: '张三',
          createTime: '2024-03-16',
          status: 'draft',
          approver: '',
          approveTime: ''
          id: '5',
          projectPlan: '化学反应监测方案',
          experimentNo: 'EXP20240316001',
          experimentName: '催化剂效率测试',
          sampleNo: 'SAMPLE20240316001',
          creator: '孙七',
          createTime: '2024-03-16 09:30:00',
          sendTo: '化学实验室',
          sendTime: '2024-03-16 10:00:00'
        },
        {
          planCode: 'DRAFT-2024-002',
          planName: '实验室改造方案(草稿)',
          stage: '准备阶段',
          creator: '李四',
          createTime: '2024-03-15',
          status: 'draft',
          approver: '',
          approveTime: ''
          id: '6',
          projectPlan: '药物稳定性研究方案',
          experimentNo: 'EXP20240316002',
          experimentName: '药物降解测试',
          sampleNo: 'SAMPLE20240316002',
          creator: '周八',
          createTime: '2024-03-16 11:30:00',
          sendTo: '药物研究部',
          sendTime: '2024-03-16 14:00:00'
        }
      ],
      approvalDialogVisible: false,
@@ -193,10 +209,27 @@
      currentApprovalData: null,
    };
  },
  computed: {
    // 获取当前角色的表头配置
    currentColumns() {
      return this.columnConfig[this.userRole] || this.columnConfig.default;
    },
    // 判断是否为化验师角色
    isChemist() {
      return this.userRole === 'chemist';
    }
  },
  created() {
    this.getUserRole();
    this.getTableData();
  },
  methods: {
    // 获取用户角色
    async getUserRole() {
      // TODO: 从用户信息或接口中获取角色
      // 示例:this.userRole = await getUserRole();
      this.userRole = 'chemist'; // 临时写死,实际应该从接口获取
    },
    resetForm() {
      this.form = {
        planName: "",
@@ -205,6 +238,9 @@
        createTime: [],
        approver: "",
        status: "",
        experimentName: "",
        sampleCount: "",
        receivedStatus: ""
      };
    },
    handleSearch() {
@@ -233,7 +269,7 @@
    },
    handleAddSample() {
      this.$router.push({
        path: "/dataManagement/addSample",
        path: "/sampleManage/addSample",
      });
    },
    handleApprove(row) {
@@ -267,10 +303,13 @@
      // 实现删除逻辑
      console.log("删除数据:", row);
    },
    handleDetail(row) {
      this.currentApprovalData = row;
      this.approvalDialogType = 'view';
      this.approvalDialogVisible = true;
    handleDetail(id) {
      this.$router.push({
        path: "/sampleManage/addSample",
        query: {
          id: id
        }
      });
    },
    handleTypeChange(type) {
      this.currentType = type;
src/views/dataManagement/sampleRecordList/changeRecord.vue
New file
@@ -0,0 +1,327 @@
<template>
  <Card>
    <div class="header-title-left" style="margin-top: 38px">
      <img src="@/assets/public/headercard.png" />
      <span>基础信息</span>
    </div>
    <div class="number">取样单编号:213421241</div>
    <div class="header-title-left" style="margin-top: 38px">
      <img src="@/assets/public/headercard.png" />
      <span>取样操作记录</span>
      <el-button
        type="primary"
        class="el-icon-plus"
        @click="showAdditives = !showAdditives"
      >
        {{ showAdditives ? "收起辅料详情" : "展开辅料详情" }}
      </el-button>
    </div>
    <Table :data="sampleData" :total="sampleTotal" :height="null">
      <template>
        <el-table-column prop="index" label="序号" width="80"></el-table-column>
        <el-table-column
          prop="processTime"
          label="工艺时间"
          width="120"
        ></el-table-column>
        <el-table-column
          prop="sampleName"
          label="取样名称"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="sampleCode"
          label="取样样品编号"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="temperature"
          label="温度"
          width="100"
        ></el-table-column>
        <el-table-column prop="ph" label="PH" width="100"></el-table-column>
        <el-table-column
          prop="waterAmount"
          label="加水量"
          width="100"
        ></el-table-column>
        <template v-if="showAdditives">
          <el-table-column
            prop="additive1"
            label="加辅1"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive2"
            label="加辅2"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive3"
            label="加辅3"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive4"
            label="加辅4"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive5"
            label="加辅5"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive6"
            label="加辅6"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive7"
            label="加辅7"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive8"
            label="加辅8"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive9"
            label="加辅9"
            width="150"
          ></el-table-column>
          <el-table-column
            prop="additive10"
            label="加辅10"
            width="150"
          ></el-table-column>
        </template>
        <el-table-column
          prop="sampleAmount"
          label="取样量"
          width="100"
        ></el-table-column>
        <el-table-column
          prop="sampleTime"
          label="取样时间"
          width="150"
        ></el-table-column>
        <el-table-column
          prop="remark"
          label="拍照"
          width="100"
        ></el-table-column>
        <el-table-column
          prop="operator"
          label="操作人员"
          width="100"
        ></el-table-column>
        <el-table-column
          fixed="right"
          label="操作"
          width="100"
        >
          <template slot-scope="scope">
            <el-button type="text" @click="handleEdit(scope.$index, scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
      </template>
    </Table>
    <div class="remark-section">
      <el-form :model="form" label-position="top">
        <el-form-item label="备注">
          <el-input
            type="textarea"
            v-model="form.remark"
            :rows="4"
            placeholder="请输入备注信息"
          ></el-input>
        </el-form-item>
      </el-form>
    </div>
    <div class="add-project-footer">
      <el-button type="primary" class="save-btn" @click="handleSave">保存</el-button>
      <el-button>存草稿</el-button>
    </div>
    <sample-dialog
      :visible.sync="showSampleDialog"
      :data="currentSampleData"
      @submit="handleSampleSubmit"
    />
    <confirm-dialog
      :visible.sync="showConfirmDialog"
      :form-data="form"
      :sample-data="sampleData"
      @confirm="handleConfirm"
    />
  </Card>
</template>
<script>
import SampleDialog from "./components/sampleDialog.vue";
import ConfirmDialog from './components/confirmDialog.vue';
export default {
  name: "ChangeRecord",
  components: {
    SampleDialog,
    ConfirmDialog
  },
  data() {
    return {
      showSampleDialog: false,
      showConfirmDialog: false,
      currentSampleData: {},
      currentEditIndex: -1,
      showAdditives: true,
      sampleData: [
        {
          index: 1,
          processTime: "2h",
          sampleName: "样品A",
          sampleCode: "SP001",
          temperature: "25℃",
          ph: "7.0",
          waterAmount: "500ml",
          additive1: "10g",
          additive2: "5g",
          additive3: "3g",
          additive4: "",
          additive5: "",
          additive6: "",
          additive7: "",
          additive8: "",
          additive9: "",
          additive10: "",
          sampleAmount: "100ml",
          sampleTime: "2024-03-20 10:00:00",
          remark: "",
          operator: "张三"
        },
        {
          index: 2,
          processTime: "4min",
          sampleName: "样品B",
          sampleCode: "SP002",
          temperature: "30℃",
          ph: "6.5",
          waterAmount: "300ml",
          additive1: "8g",
          additive2: "4g",
          additive3: "",
          additive4: "",
          additive5: "",
          additive6: "",
          additive7: "",
          additive8: "",
          additive9: "",
          additive10: "",
          sampleAmount: "50ml",
          sampleTime: "2024-03-20 10:30:00",
          remark: "",
          operator: "李四",
        },
      ],
      sampleTotal: 2,
      form: {
        remark: "",
      },
    };
  },
  methods: {
    handleEdit(index, row) {
      this.currentEditIndex = index;
      this.currentSampleData = { ...row };
      this.showSampleDialog = true;
    },
    handleSampleSubmit(formData) {
      if (this.currentEditIndex > -1) {
        // 更新表格数据
        this.$set(this.sampleData, this.currentEditIndex, {
          ...this.sampleData[this.currentEditIndex],
          ...formData,
        });
        this.currentEditIndex = -1;
      }
      this.showSampleDialog = false;
    },
    handleSave() {
      this.showConfirmDialog = true;
    },
    handleConfirm(signature) {
      this.submitForm(signature);
    },
    submitForm(signature = null) {
      // 在这里实现表单提交逻辑
      console.log('提交表单数据', { signature });
      this.$message.success('保存成功');
      this.showConfirmDialog = false;
    }
  }
};
</script>
<style lang="less" scoped>
.header-title-left {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 20px;
  img {
    width: 12px;
    height: 19px;
  }
  div, span {
    flex-shrink: 0;
    font-weight: bold;
    font-size: 18px;
    color: #222222;
    line-height: 27px;
    font-family: "Source Han Sans CN Bold Bold";
  }
  div:before {
    content: "*";
    color: #f56c6c;
    margin-right: 4px;
  }
  .el-button {
    margin-left: 16px;
  }
}
.add-project-footer {
  margin-top: 43px;
  button {
    width: 220px;
  }
  .save-btn {
    margin-right: 20px;
  }
}
.number {
  font-family: PingFangSC, PingFang SC;
  font-weight: 400;
  font-size: 14px;
  color: rgba(0,0,0,0.88);
}
.remark-section {
  margin-top: 20px;
  .el-form-item {
    width: 100%;
    .el-textarea {
      width: 100%;
    }
  }
}
</style>
src/views/dataManagement/sampleRecordList/components/confirmDialog.vue
src/views/dataManagement/sampleRecordList/components/sampleDialog.vue
src/views/dataManagement/sampleRecordList/list.vue
New file
@@ -0,0 +1,297 @@
<template>
  <div class="list">
    <TableCustom :queryForm="form" :tableData="tableData" :total="total">
      <template #search>
        <el-form :model="form" labelWidth="auto" inline>
          <el-form-item label="所属项目课题方案:">
            <el-input v-model="form.planName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验名称:">
            <el-input v-model="form.planCode" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验编号:">
            <el-input v-model="form.planCode" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="状态:">
            <el-input v-model="form.approver" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="">
            <el-button type="default" @click="resetForm">重置</el-button>
            <el-button type="primary" @click="handleSearch">查询</el-button>
          </el-form-item>
        </el-form>
      </template>
      <template #setting>
        <div class="tableTitle">
          <div class="flex a-center">
            <div
            class="title"
              :class="{active:currentType === 'list'}"
              @click="handleTypeChange('list')"
            >{{ type === 'draft' ? '草稿箱' : '取样操作记录列表' }}</div>
          </div>
        </div>
      </template>
      <template #table>
        <el-table-column
          prop="planName"
          label="所属项目课题方案"
        ></el-table-column>
        <el-table-column
          prop="experimentNo"
          label="实验编号"
        ></el-table-column>
        <el-table-column
          prop="experimentName"
          label="实验名称"
        ></el-table-column>
        <el-table-column
          prop="sampleNo"
          label="取样单编号"
        ></el-table-column>
        <el-table-column prop="creator" label="创建人"></el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column prop="status" label="当前状态">
          <template slot-scope="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template slot-scope="scope">
            <el-button
              type="text"
              @click="handleEdit(scope.row)"
              >编辑</el-button>
            <el-button
              type="text"
              @click="handleDetail(scope.row)"
              >详情</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCustom>
    <!-- 审批弹窗 -->
    <!-- <approval-dialog
      :visible.sync="approvalDialogVisible"
      :type="approvalDialogType"
      :data="currentApprovalData"
      @approve="handleApproveSubmit"
      @reject="handleRejectSubmit"
    /> -->
  </div>
</template>
<script>
// import ApprovalDialog from './components/approvalDialog.vue'
export default {
  name: "ProjectList",
  components: {
    // ApprovalDialog
  },
  data() {
    return {
      type: 'list',
      currentType: 'list',
      form: {
        planName: "",
        planCode: "",
        creator: "",
        createTime: [],
        approver: "",
        status: "",
      },
      tableData: [],
      total: 0,
      // 模拟数据
      mockListData: [
        {
          planName: '2024年度实验室设备升级方案',
          experimentNo: '31423764',
          experimentName: '设备性能测试',
          sampleNo: '2024-05-28',
          creator: '刘大大',
          createTime: '2025-1-2 16:27:17',
          status: 'pending'
        }
      ],
      mockDraftData: [
        {
          planCode: 'DRAFT-2024-001',
          planName: '实验室设备采购计划(草稿)',
          stage: '规划阶段',
          creator: '张三',
          createTime: '2024-03-16',
          status: 'draft',
          approver: '',
          approveTime: ''
        },
        {
          planCode: 'DRAFT-2024-002',
          planName: '实验室改造方案(草稿)',
          stage: '准备阶段',
          creator: '李四',
          createTime: '2024-03-15',
          status: 'draft',
          approver: '',
          approveTime: ''
        }
      ],
      approvalDialogVisible: false,
      approvalDialogType: 'approve',
      currentApprovalData: null,
    };
  },
  created() {
    this.getTableData();
  },
  methods: {
    resetForm() {
      this.form = {
        planName: "",
        planCode: "",
        creator: "",
        createTime: [],
        approver: "",
        status: "",
      };
    },
    handleSearch() {
      // 实现查询逻辑
      console.log("查询条件:", this.form);
    },
    getStatusType(status) {
      const statusMap = {
        pending: "warning",
        rejected: "danger",
        approved: "success",
        archived: "info",
        draft: "info"
      };
      return statusMap[status] || "info";
    },
    getStatusText(status) {
      const statusMap = {
        pending: "待审批",
        rejected: "已驳回",
        approved: "已通过",
        archived: "已封存",
        draft: "草稿"
      };
      return statusMap[status] || "未知";
    },
    handleAddSample() {
      this.$router.push({
        path: "/sampleManage/changeRecord",
      });
    },
    handleApprove(row) {
      this.currentApprovalData = row;
      this.approvalDialogType = 'approve';
      this.approvalDialogVisible = true;
    },
    handleApproveSubmit(data) {
      // 处理审批通过
      console.log('审批通过:', data);
      this.approvalDialogVisible = false;
      this.$message.success('审批通过成功');
      this.getTableData();
    },
    handleRejectSubmit(data) {
      // 处理审批驳回
      console.log('审批驳回:', data);
      this.approvalDialogVisible = false;
      this.$message.success('审批驳回成功');
      this.getTableData();
    },
    handleRevokeApprove(row) {
      // 实现撤销审批逻辑
      console.log("撤销审批数据:", row);
    },
    handleEdit(row) {
      this.$router.push({
        path: "/sampleManage/changeRecord",
        query: {
          type: 'edit',
          id: row.id
        }
      });
    },
    handleDelete(row) {
      // 实现删除逻辑
      console.log("删除数据:", row);
    },
    handleDetail(row) {
      this.$router.push({
        path: "/sampleManage/changeRecord",
        query: {
          type: 'view',
          id: row.id
        }
      });
    },
    handleTypeChange(type) {
      this.currentType = type;
      this.type = type;
      this.getTableData();
    },
    getTableData() {
      // 根据currentType请求不同的数据
      if (this.currentType === 'list') {
        this.tableData = this.mockListData;
        this.total = this.mockListData.length;
      } else {
        this.tableData = this.mockDraftData;
        this.total = this.mockDraftData.length;
      }
    },
  },
};
</script>
<style scoped lang="less">
.list {
  height: 100%;
}
.flex {
  display: flex;
  align-items: center;
}
.tableTitle {
  display: flex;
  padding-bottom: 20px;
  justify-content: space-between;
  align-items: center;
  .title {
    background: #fafafc;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #dcdfe6;
    padding: 16px 29px;
    font-weight: bold;
    font-size: 18px;
    color: #606266;
    width: unset;
    cursor: pointer;
  }
  .drafts {
    padding: 16px 65px;
    background: #fafafc;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #dcdfe6;
    font-weight: 400;
    font-size: 18px;
    color: #606266;
    margin-left: 16px;
    cursor: pointer;
  }
  .active{
    color: #049c9a;
    background: #ffffff;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #049c9a;
  }
}
</style>
src/views/dataManagement/sampleSubmissionList/components/receiveConfirmDialog.vue
New file
@@ -0,0 +1,149 @@
<template>
  <el-dialog
    title="发送签字确认"
    :visible.sync="visible"
    width="500px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="receive-dialog">
      <div class="receive-tip">
        您已选中 <span class="sample-count">{{ sampleCount }}</span> 条样品发送,请签字确认
      </div>
      <div class="approval-dialog-approve">
        <div class="add-group">
          <div>*</div>
          <span>签字确认</span>
          <el-button type="primary" class="el-icon-plus" @click="openSignature">签名</el-button>
        </div>
        <img
          v-if="imgSrc"
          style="width: 200px; height: 100px; margin-left: 25px"
          :src="imgSrc"
          fit="fit"
        />
      </div>
    </div>
    <div slot="footer" class="dialog-footer select-member-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc">
        确认发送
      </el-button>
    </div>
    <SignatureCanvas
      :visible="signatureDialogVisible"
      @confirm="handleSignatureConfirm"
      @close="signatureDialogVisible = false"
    />
  </el-dialog>
</template>
<script>
import SignatureCanvas from "@/components/SignatureCanvas.vue";
export default {
  name: "ReceiveConfirmDialog",
  components: {
    SignatureCanvas,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    sampleCount: {
      type: Number,
      default: 1,
    },
  },
  data() {
    return {
      signatureDialogVisible: false,
      imgSrc: "",
    };
  },
  methods: {
    handleClose() {
      this.$emit("update:visible", false);
      this.imgSrc = "";
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureConfirm(imageData) {
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
    },
    handleConfirm() {
      if (!this.imgSrc) {
        this.$message.warning("请先完成签名确认");
        return;
      }
      this.$emit("confirm", this.imgSrc);
      this.handleClose();
    },
  },
};
</script>
<style lang="less" scoped>
::v-deep .el-dialog__header {
  border-bottom: 1px solid #e4e7ed;
}
.receive-dialog {
  padding: 20px;
  .receive-tip {
    font-size: 14px;
    color: #333;
    margin-bottom: 20px;
    .sample-count {
      color: #409EFF;
      font-weight: bold;
    }
  }
}
.approval-dialog-approve {
  margin-top: 26px;
  img {
    border: 2px dashed #049c9a;
  }
}
.add-group {
  padding-left: 25px;
  margin-top: 14px;
  display: flex;
  align-items: center;
  margin-bottom: 19px;
  div {
    color: #f56c6c;
  }
  span {
    font-weight: 500;
    font-size: 14px;
    color: #222222;
    line-height: 21px;
    margin: 0 32px 0 8px;
  }
}
.dialog-footer {
  align-items: center;
  display: flex;
  justify-content: center;
  button {
    width: 150px;
  }
}
</style>
src/views/dataManagement/sampleSubmissionList/list.vue
New file
@@ -0,0 +1,199 @@
<template>
  <div class="list">
    <TableCustom :queryForm="form" :tableData="tableData" :total="total">
      <template #search>
        <el-form :model="form" labelWidth="auto" inline>
          <el-form-item label="所属项目课题方案:">
            <el-input v-model="form.planName" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="实验编号:">
            <el-input
              v-model="form.planCode"
              placeholder="请输入"
            ></el-input> </el-form-item
          ><el-form-item label="实验名称:">
            <el-input v-model="form.planCode" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="状态:">
            <el-input v-model="form.approver" placeholder="请输入"></el-input>
          </el-form-item>
          <el-form-item label="">
            <el-button type="default" @click="resetForm">重置</el-button>
            <el-button type="primary" @click="handleSearch">查询</el-button>
          </el-form-item>
        </el-form>
      </template>
      <template #setting>
        <div class="tableTitle">
          <div class="flex a-center">
            <div class="title">
              取样操作记录列表
            </div>
          </div>
        </div>
      </template>
      <template #table>
        <el-table-column
          prop="planName"
          label="所属项目课题方案"
        ></el-table-column>
        <el-table-column
          prop="experimentNo"
          label="实验编号"
        ></el-table-column>
        <el-table-column
          prop="experimentName"
          label="实验名称"
        ></el-table-column>
        <el-table-column
          prop="sampleNo"
          label="取样单编号"
        ></el-table-column>
        <el-table-column
          prop="creator"
          label="创建人"
        ></el-table-column>
        <el-table-column
          prop="createTime"
          label="创建时间"
        ></el-table-column>
        <el-table-column
          prop="sampleStatus"
          label="样品总数/待送达/待接收/已接收"
        ></el-table-column>
        <el-table-column label="操作" width="100">
          <template slot-scope="scope">
            <el-button type="text" @click="handleDetail(scope.row)">详情</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCustom>
    <!-- 审批弹窗 -->
    <!-- <approval-dialog
      :visible.sync="approvalDialogVisible"
      :type="approvalDialogType"
      :data="currentApprovalData"
      @approve="handleApproveSubmit"
      @reject="handleRejectSubmit"
    /> -->
  </div>
</template>
<script>
// import ApprovalDialog from './components/approvalDialog.vue'
export default {
  name: "ProjectList",
  components: {
    // ApprovalDialog
  },
  data() {
    return {
      form: {
        planName: "",
        planCode: "",
        creator: "",
        createTime: [],
        approver: "",
        status: "",
      },
      tableData: [],
      total: 0,
      // 模拟数据
      mockListData: [
        {
          planCode: "PLAN-2024-001",
          planName: "2024年度实验室设备升级方案",
          stage: "规划阶段",
          creator: "张三",
          createTime: "2024-03-15",
          status: "pending",
          approver: "李四",
          approveTime: "2024-03-16",
        },
        {
          planCode: "PLAN-2024-002",
          planName: "实验室安全管理制度更新方案",
          stage: "实施阶段",
          creator: "王五",
          createTime: "2024-03-14",
          status: "approved",
          approver: "赵六",
          approveTime: "2024-03-15",
        },
        {
          planCode: "PLAN-2024-003",
          planName: "实验室人员培训计划",
          stage: "准备阶段",
          creator: "孙七",
          createTime: "2024-03-13",
          status: "rejected",
          approver: "周八",
          approveTime: "2024-03-14",
        },
      ],
    };
  },
  created() {
    this.getTableData();
  },
  methods: {
    resetForm() {
      this.form = {
        planName: "",
        planCode: "",
        creator: "",
        createTime: [],
        approver: "",
        status: "",
      };
    },
    handleSearch() {
      // 实现查询逻辑
      console.log("查询条件:", this.form);
      this.getTableData();
    },
    handleDetail(row) {
      this.$router.push({
        path: "/sampleManage/submission",
        query: {
          id: row.id,
          type: 'view'
        }
      });
    },
    getTableData() {
      // 获取列表数据
      this.tableData = this.mockListData;
      this.total = this.mockListData.length;
    },
  },
};
</script>
<style scoped lang="less">
.list {
  height: 100%;
}
.flex {
  display: flex;
  align-items: center;
}
.tableTitle {
  display: flex;
  padding-bottom: 20px;
  justify-content: space-between;
  align-items: center;
  .title {
    background: #ffffff;
    border-radius: 8px 8px 0px 0px;
    border: 1px solid #049c9a;
    padding: 16px 29px;
    font-weight: bold;
    font-size: 18px;
    color: #049c9a;
    width: unset;
  }
}
</style>
src/views/dataManagement/sampleSubmissionList/submission.vue
New file
@@ -0,0 +1,279 @@
<template>
  <Card>
    <div class="header-title-left">
      <img src="@/assets/public/headercard.png" />
      <div>所属实验调度</div>
    </div>
    <Table :data="schedulingData" :total="schedulingTotal" :height="null">
      <template>
        <el-table-column prop="planCode" label="所属项目课题方案" width="150"></el-table-column>
        <el-table-column prop="experimentCode" label="实验编号" width="150"></el-table-column>
        <el-table-column prop="experimentName" label="实验名称" width="150"></el-table-column>
        <el-table-column prop="notifyTime" label="通知时间" width="150"></el-table-column>
        <el-table-column prop="startTime" label="实验开始时间" width="150"></el-table-column>
        <el-table-column prop="endTime" label="实验结束时间" width="150"></el-table-column>
        <el-table-column prop="participants" label="参加人员" width="150"></el-table-column>
        <el-table-column prop="status" label="状态" width="100"></el-table-column>
      </template>
    </Table>
    <!-- 送样-收样记录部分 -->
    <div class="sample-record-section">
      <div class="header-title-left" style="margin-top: 38px">
        <img src="@/assets/public/headercard.png" />
        <span>送样-收样记录</span>
        <el-button
          type="primary"
          class="el-icon-plus"
          @click="showAdditives = !showAdditives"
        >
          {{ showAdditives ? "收起辅料详情" : "展开辅料详情" }}
        </el-button>
      </div>
      <div class="sample-code">取样单编号:{{ form.sampleCode || 'DD-25010BS01' }}</div>
      <div class="sample-table">
        <div class="table-header">
          <el-button type="primary" class="batch-send" @click="handleBatchSend">批量发送</el-button>
        </div>
        <Table :data="sampleList" :total="sampleTotal" :height="null" @selection-change="handleSelectionChange">
          <template>
            <el-table-column type="selection" width="55"></el-table-column>
            <el-table-column prop="index" label="序号" width="80"></el-table-column>
            <el-table-column prop="processTime" label="工艺时间间/h" width="120"></el-table-column>
            <el-table-column prop="sampleName" label="取样名称" width="150"></el-table-column>
            <el-table-column prop="sampleCode" label="取样样品编号" width="150"></el-table-column>
            <el-table-column prop="temperature" label="温度" width="100"></el-table-column>
            <el-table-column prop="ph" label="PH" width="100"></el-table-column>
            <el-table-column prop="waterAmount" label="加水量" width="100"></el-table-column>
            <template v-if="showAdditives">
              <el-table-column prop="additive1" label="加辅1" width="150"></el-table-column>
              <el-table-column prop="additive2" label="加辅2" width="150"></el-table-column>
              <el-table-column prop="additive3" label="加辅3" width="150"></el-table-column>
              <el-table-column prop="additive4" label="加辅4" width="150"></el-table-column>
              <el-table-column prop="additive5" label="加辅5" width="150"></el-table-column>
              <el-table-column prop="additive6" label="加辅6" width="150"></el-table-column>
              <el-table-column prop="additive7" label="加辅7" width="150"></el-table-column>
              <el-table-column prop="additive8" label="加辅8" width="150"></el-table-column>
              <el-table-column prop="additive9" label="加辅9" width="150"></el-table-column>
              <el-table-column prop="additive10" label="加辅10" width="150"></el-table-column>
            </template>
            <el-table-column prop="sampleAmount" label="取样量" width="100"></el-table-column>
            <el-table-column prop="sampleTime" label="取样时间" width="150"></el-table-column>
            <el-table-column prop="photo" label="拍照" width="100">
              <template slot-scope="scope">
                <img v-if="scope.row.photo" :src="scope.row.photo" class="sample-photo" />
              </template>
            </el-table-column>
            <el-table-column prop="operator" label="操作人" width="100"></el-table-column>
            <el-table-column prop="status" label="状态" width="100"></el-table-column>
            <el-table-column label="操作" width="100" fixed="right">
              <template slot-scope="scope">
                <el-button type="text" @click="handleSend(scope.row)" v-if="scope.row.status === '待发送'">发送</el-button>
              </template>
            </el-table-column>
          </template>
        </Table>
      </div>
    </div>
    <receive-confirm-dialog
      :visible.sync="showReceiveConfirm"
      :sample-count="selectedSamples.length"
      @confirm="confirmSend"
    />
  </Card>
</template>
<script>
import ReceiveConfirmDialog from './components/receiveConfirmDialog.vue'
export default {
  name: "SampleSubmission",
  components: {
    ReceiveConfirmDialog
  },
  data() {
    return {
      showReceiveConfirm: false,
      showAdditives: true,
      schedulingData: [{
        planCode: 'DD-EX001',
        experimentCode: 'DD-EX001',
        experimentName: '名称名称名称',
        notifyTime: '2025-1-2 14:50:19',
        startTime: '2025-02-27',
        endTime: '2025-06-06',
        participants: '张弘, 李天浩, 陈三, 李四',
        status: '已确认'
      }],
      schedulingTotal: 1,
      form: {
        sampleCode: "DD-25010BS01",
      },
      sampleList: [
        {
          index: 1,
          processTime: "2",
          sampleName: "名称名称名称",
          sampleCode: "314234321",
          temperature: "34",
          ph: "34",
          waterAmount: "34",
          additive1: "10g",
          additive2: "5g",
          additive3: "3g",
          additive4: "",
          additive5: "",
          additive6: "",
          additive7: "",
          additive8: "",
          additive9: "",
          additive10: "",
          sampleAmount: "34",
          sampleTime: "2025-1-9 15:26:08",
          photo: "@/assets/sample-photos/photo1.jpg",
          operator: "张三",
          status: "待发送"
        },
        {
          index: 2,
          processTime: "4",
          sampleName: "名称名称名称",
          sampleCode: "314234321",
          temperature: "23",
          ph: "23",
          waterAmount: "23",
          additive1: "8g",
          additive2: "4g",
          additive3: "",
          additive4: "",
          additive5: "",
          additive6: "",
          additive7: "",
          additive8: "",
          additive9: "",
          additive10: "",
          sampleAmount: "23",
          sampleTime: "2025-1-9 15:26:08",
          photo: "@/assets/sample-photos/photo2.jpg",
          operator: "李四",
          status: "待接收"
        },
        {
          index: 3,
          processTime: "8",
          sampleName: "名称名称名称",
          sampleCode: "314234321",
          temperature: "23",
          ph: "23",
          waterAmount: "23",
          additive1: "",
          additive2: "",
          additive3: "",
          additive4: "",
          additive5: "",
          additive6: "",
          additive7: "",
          additive8: "",
          additive9: "",
          additive10: "",
          sampleAmount: "23",
          sampleTime: "2025-1-9 15:26:08",
          photo: "@/assets/sample-photos/photo3.jpg",
          operator: "王五",
          status: "已接收"
        }
      ],
      sampleTotal: 3,
      selectedSamples: []
    };
  },
  methods: {
    handleSelectionChange(selection) {
      this.selectedSamples = selection;
    },
    handleSend(row) {
      this.selectedSamples = [row];
      this.showReceiveConfirm = true;
    },
    handleBatchSend() {
      if (this.selectedSamples.length === 0) {
        this.$message.warning('请先选择要发送的样品');
        return;
      }
      this.showReceiveConfirm = true;
    },
    confirmSend(signature) {
      // 处理发送确认逻辑
      const sampleIds = this.selectedSamples.map(item => item.id);
      console.log('发送样品', { sampleIds, signature });
      // 更新状态
      this.selectedSamples.forEach(sample => {
        const index = this.sampleList.findIndex(item => item.id === sample.id);
        if (index > -1) {
          this.sampleList[index].status = '待接收';
        }
      });
      this.$message.success(`成功发送 ${this.selectedSamples.length} 个样品`);
      this.selectedSamples = [];
    }
  }
};
</script>
<style lang="less" scoped>
.header-title-left {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 20px;
  img {
    width: 12px;
    height: 19px;
  }
  div, span {
    flex-shrink: 0;
    font-weight: bold;
    font-size: 18px;
    color: #222222;
    line-height: 27px;
    font-family: "Source Han Sans CN Bold Bold";
  }
  div:before {
    content: "*";
    color: #f56c6c;
    margin-right: 4px;
  }
  .el-button {
    margin-left: 16px;
  }
}
.sample-record-section {
  .sample-code {
    font-family: PingFangSC, PingFang SC;
    font-weight: 400;
    font-size: 14px;
    color: rgba(0,0,0,0.88);
    margin: 20px 0;
  }
  .table-header {
    margin-bottom: 16px;
    text-align: left;
  }
  .sample-photo {
    width: 60px;
    height: 60px;
    object-fit: cover;
  }
}
</style>