董国庆
2025-05-26 ecf7c21425a3bbd8c48bb76534608072402d3211
辅料,产品报批对接口
2个文件已添加
7个文件已修改
1476 ■■■■ 已修改文件
laboratory/src/views/chemistQa/pilotAndProduction/add.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/productApproval/add.vue 255 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/productApproval/components/approval/index.vue 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/productApproval/index.vue 234 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/productApproval/service.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/rawMaterials/add.vue 254 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/rawMaterials/components/approval/index.vue 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/rawMaterials/index.vue 232 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/rawMaterials/service.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
laboratory/src/views/chemistQa/pilotAndProduction/add.vue
@@ -101,7 +101,7 @@
                developPerson: "",
                developPersonName: "",
                developDate: "",
                reportType: 2,
                reportType: 1,
                status: 1,
                teamId: "",
                qaReportFiles: [],
laboratory/src/views/chemistQa/productApproval/add.vue
@@ -1,6 +1,6 @@
<template>
    <div>
        <Card>
    <div class="add-container" :loading="loading">
        <Card v-loading="loading">
            <div class="header-title" style="width: 100%;">
                <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
@@ -10,97 +10,259 @@
                    <el-button @click="showChoose = true" class="el-icon-circle-plus-outline" type="primary">
                        选择项目组</el-button>
                </div>
            </div>
            <Table :height="null" :queryForm="queryForm" :total="0">
            <Table :height="null" :data="tableData" :queryForm="queryForm" :total="0">
                <template>
                    <el-table-column prop="name" label="项目组名称" />
                    <el-table-column prop="age" label="项目负责人" />
                    <el-table-column prop="age" label="项目组成员" />
                    <el-table-column prop="age" label="创建时间" />
                    <el-table-column prop="teamName" label="项目组名称" />
                    <el-table-column prop="personCharge" label="项目负责人" />
                    <el-table-column prop="staffName" label="项目组成员" />
                    <el-table-column prop="createTime" label="创建时间" />
                </template>
            </Table>
            <el-form ref="form" :model="form" :rules="rules" inline label-position="top" style="margin-top: 38px">
            <el-form ref="form" :model="form" :rules="rules" inline label-position="top" style="margin-top: 18px">
                <el-row :gutter="20">
                    <el-col :span="24">
                        <el-form-item prop="name" label="报告内容">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告内容" />
                        <el-form-item prop="reportTitle" label="报告标题">
                            <el-input v-model="form.reportTitle" style="width: 100%;" placeholder="请输入报告标题" />
                        </el-form-item>
                        <el-form-item prop="name" label="报告编号" style="margin-left: 100px;">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                        <el-form-item prop="reportCode" label="报告编号" style="margin-left: 100px;">
                            <el-input v-model="form.reportCode" style="width: 100%;" placeholder="请输入报告编号" disabled />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item prop="name" label="制定人">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入制定人" />
                        <el-form-item prop="developPersonName" label="制定人">
                            <el-input v-model="form.developPersonName" style="width: 100%;" placeholder="请输入制定人" disabled />
                        </el-form-item>
                        <el-form-item prop="name" label="制定日期" style="margin-left: 100px;">
                            <el-date-picker :prefix-icon="null" v-model="form.createTime"  type="date" placeholder="请选择日期" />
                        <el-form-item prop="developDate" label="制定日期" style="margin-left: 100px;">
                            <el-date-picker :prefix-icon="null" v-model="form.developDate" type="date" disabled
                                placeholder="请选择日期" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <div class="header-title" style="width: 100%;">
                    <div class="header-title-left">
                        <img src="@/assets/public/headercard.png" />
                        <div>报告正文</div>
                    </div>
                </div>
                <form-item prop="name" style="margin-top: 38px">
                    <ai-editor v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                </form-item>
                <el-form-item prop="reportText" style="margin-top: 18px">
                    <ai-editor ref="materialEditor" :value="form.reportText" style="width: 100%;"
                        placeholder="请输入报告正文" />
                </el-form-item>
                <div class="header-title" style="width: 100%;">
                    <div class="header-title-left">
                        <img src="@/assets/public/headercard.png" />
                        <div>附件</div>
                        <div class="noRequire">附件</div>
                    </div>
                </div>
                <el-form-item prop="name" style="margin-top: 38px">
                    <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList">
                <el-form-item prop="name" style="margin-top: 18px">
                    <el-upload
                        action="#"
                        :file-list="fileList"
                        :http-request="handleUpload"
                        :before-upload="beforeUpload"
                        :on-remove="handleRemove">
                        <el-button size="small" type="primary">点击上传</el-button>
                        <div slot="tip" class="el-upload__tip">支持任意格式文件上传</div>
                    </el-upload>
                </el-form-item>
                <div class="end-btn" style="margin-top: 38px">
                    <el-button type="primary">发送</el-button>
                    <el-button type="default">存草稿</el-button>
                    <el-button type="primary" @click="submit" :loading="loading">发送</el-button>
                    <el-button type="default" @click="save" :loading="loading">存草稿</el-button>
                </div>
            </el-form>
        </Card>
        <chooseProject @submit="getProjectData" :show="showChoose" @close="showChoose = false"></chooseProject>
    </div>
</template>
<script>
import { Card } from 'element-ui';
import AiEditor from '@/components/AiEditor'
import chooseProject from '@/components/chooseProject'
import { addData, getDetail, editData } from './service'
export default {
    components: { AiEditor },
    components: {
        AiEditor,
        chooseProject
    },
    data() {
        return {
            loading: false,
            form: {
                planName: "",
                planCode: "",
                stage: "",
                creator: "",
                createTime: "",
                approvalComment: "",
                status: "pending",
                approver: "",
                approveTime: ""
                reportCode: "",
                reportTitle: "",
                reportText: "",
                developPerson: "",
                developPersonName: "",
                developDate: "",
                reportType: 3,
                status: 1,
                teamId: "",
                qaReportFiles: [],
                commitPersonId: null,
            },
            tableData: [],
            fileList: [], // 附件列表
            showChoose: false,
            radio1: 1,
            rules: {},
            status: "1",
            remark: "",
            queryForm: {
            }
            rules: {
                reportTitle: [
                    { required: true, message: '请输入报告标题', trigger: 'blur' }
                ],
            },
            queryForm: {}
        }
    }
}
    },
    mounted() {
        this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).userId;
        this.form.developPersonName = JSON.parse(sessionStorage.getItem('userInfo')).nickName;
        this.form.commitPersonId = JSON.parse(sessionStorage.getItem('userInfo')).userId
        this.form.developDate = new Date().toISOString().split('T')[0];
        if (this.$route.query.id) {
            this.getDetail()
        }
    },
    methods: {
        getDetail() {
            getDetail(this.$route.query.id).then(res => {
                this.form = res
                this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }]
                this.fileList = res.fileList || []
            })
        },
        getProjectData(data) {
            this.tableData = [data]
            this.$forceUpdate()
            this.showChoose = false
        },
        submit() {
            if (this.tableData.length == 0) {
                this.$message.error('请选择项目组')
                return
            }
            this.$refs.form.validate((valid) => {
                if (this.$refs.materialEditor.getContent() == '<p></p>') {
                    this.$message.error('请输入报告正文')
                    return
                }
                let data = {
                    ...this.form,
                    reportText: this.$refs.materialEditor.getContent(),
                    teamId: this.tableData[0].id,
                    status: 1, // 待审核状态
                    commitPersonId: JSON.parse(sessionStorage.getItem('userInfo')).userId
                }
                if (valid) {
                    this.loading = true
                    if (this.$route.query.id) {
                        editData({ ...data, id: this.$route.query.id }).then(res => {
                            if (res.code === 200) {
                                this.$message.success('修改成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    } else {
                        addData(data).then(res => {
                            if (res.code === 200) {
                                this.$message.success('发布成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    }
                }
            })
        },
        save() {
            this.$refs.form.validate((valid) => {
                let data = {
                    ...this.form,
                    reportText: this.$refs.materialEditor.getContent(),
                    teamId: this.tableData[0].id,
                    status: -1, // 草稿箱状态
                    commitPersonId: JSON.parse(sessionStorage.getItem('userInfo')).userId
                }
                if (valid) {
                    this.loading = true
                    if (this.$route.query.id) {
                        // 编辑草稿
                        editData({ ...data, id: this.$route.query.id }).then(res => {
                            if (res.code === 200) {
                                this.$message.success('草稿保存成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    } else {
                        // 新增草稿
                        addData(data).then(res => {
                            if (res.code === 200) {
                                this.$message.success('草稿保存成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    }
                }
            })
        },
        beforeUpload(file) {
            return true;
        },
        handleUpload(options) {
            const file = options.file;
            const fileObj = {
                fileName: file.name,
                fileSize: file.size,
                createTime: new Date().toISOString(),
                createBy: '当前用户',
                reportType: 4,
                status: 1,
                id: Date.now().toString(),
                fileUrl: 'https://example.com/default-file-url'
            };
            this.fileList.push({
                name: file.name,
                url: fileObj.fileUrl
            });
            this.form.qaReportFiles.push(fileObj);
            this.$message.success('文件上传成功');
        },
        handleRemove(file) {
            const index = this.fileList.findIndex(item => item.name === file.name);
            if (index !== -1) {
                this.fileList.splice(index, 1);
                this.form.qaReportFiles.splice(index, 1);
            }
        },
    },
}
</script>
<style lang="less" scoped>
@@ -166,7 +328,6 @@
    button {
        width: 180px;
        height: 36px;
        // background: #409EFF;
    }
}
</style>
laboratory/src/views/chemistQa/productApproval/components/approval/index.vue
@@ -1,5 +1,5 @@
<template>
    <el-dialog :title="dialogTitle" :visible.sync="visible" width="80%" po :close-on-click-modal="false"
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="80%" :close-on-click-modal="false"
        @close="handleClose">
        <div class="approval-dialog">
            <!-- 左侧审批内容 -->
@@ -12,38 +12,38 @@
                                <div>所属项目组</div>
                            </div>
                        </div>
                        <Table :height="null" :queryForm="queryForm" :total="0" @currentChange="handleCurrentChange"
                            @sizeChange="handleSizeChange">
                        <Table :height="null" :total="0">
                            <template>
                                <el-table-column prop="name" label="项目组名称" />
                                <el-table-column prop="age" label="项目负责人" />
                                <el-table-column prop="age" label="项目组成员" />
                                <el-table-column prop="age" label="创建时间" />
                                <el-table-column prop="teamName" label="项目组名称" />
                                <el-table-column prop="personCharge" label="项目负责人" />
                                <el-table-column prop="staffName" label="项目组成员" />
                                <el-table-column prop="createTime" label="创建时间" />
                            </template>
                        </Table>
                        <el-form ref="form" :model="form" :rules="rules" inline label-position="top"
                            style="margin-top: 38px">
                            style="margin-top: 18px">
                            <el-row :gutter="20">
                                <el-col :span="24">
                                    <el-form-item prop="name" label="报告内容">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告内容" />
                                    <el-form-item prop="reportTitle" label="报告标题">
                                        <el-input v-model="form.reportTitle" style="width: 100%;" placeholder="请输入报告标题"
                                            disabled />
                                    </el-form-item>
                                    <el-form-item prop="name" label="报告编号" style="margin-left: 100px;">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                                    <el-form-item prop="reportCode" label="报告编号" style="margin-left: 100px;">
                                        <el-input v-model="form.reportCode" style="width: 100%;" placeholder="请输入报告编号"
                                            disabled />
                                    </el-form-item>
                                </el-col>
                                <el-col :span="24">
                                    <el-form-item prop="name" label="制定人">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入制定人" />
                                    <el-form-item prop="developPerson" label="制定人">
                                        <el-input v-model="form.developPerson" style="width: 100%;" placeholder="请输入制定人"
                                            disabled />
                                    </el-form-item>
                                    <el-form-item prop="name" label="制定日期" style="margin-left: 100px;">
                                        <el-date-picker :prefix-icon="null" v-model="form.createTime" type="date"
                                            placeholder="请选择日期" />
                                    <el-form-item prop="developDate" label="制定日期" style="margin-left: 100px;">
                                        <el-date-picker :prefix-icon="null" v-model="form.developDate" type="date"
                                            disabled placeholder="请选择日期" />
                                    </el-form-item>
                                </el-col>
                            </el-row>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
@@ -51,28 +51,33 @@
                                    <div>报告正文</div>
                                </div>
                            </div>
                            <el-form-item prop="name" style="margin-top: 38px">
                                <ai-editor v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                            <el-form-item prop="reportText" style="margin-top: 18px">
                                <ai-editor :value="form.reportText" style="width: 100%;" placeholder="请输入报告正文"
                                    :readOnly="true" />
                            </el-form-item>
                            <el-form-item prop="name" style="margin-top: 38px">
                                <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList">
                                    <el-button size="small" type="primary">点击上传</el-button>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
                                    <img src="@/assets/public/headercard.png" />
                                    <span class="noRequire">附件</span>
                                </div>
                            </div>
                            <el-form-item prop="name" style="margin-top: 18px">
                                <el-upload action="#" :file-list="fileList" disabled>
                                    <el-button size="small" type="primary" disabled>点击上传</el-button>
                                </el-upload>
                            </el-form-item>
                        </el-form>
                    </template>
                    <!-- <SelectMember ref="selectMember" /> -->
                </Card>
            </div>
            <!-- 右侧审批流程 -->
            <div class="approval-flow">
                <div class="flow-content">
                    <approval-process :status="form.status" :submit-time="form.createTime" :approver="form.approver"
                        :approve-time="form.approveTime" />
                    <approval-process :processData="form.processData" />
                </div>
            </div>
        </div>
        <div class="approval-dialog-approve">
        <div class="approval-dialog-approve" v-if="type == 'approve'">
            <el-row :span="24">
                <el-col :span="12">
                    <div class="status">
@@ -94,12 +99,10 @@
                    </div>
                </el-col>
            </el-row>
        </div>
        <div slot="footer" class="dialog-footer">
            <el-button @click="handleClose">取 消</el-button>
            <el-button type="primary" @click="handleApprove" v-if="type === 'approve'">通过</el-button>
            <el-button type="primary" @click="handleApprove" v-if="type == 'approve'">确 定</el-button>
        </div>
    </el-dialog>
</template>
@@ -107,6 +110,7 @@
<script>
import ApprovalProcess from '@/components/approvalProcess'
import AiEditor from '@/components/AiEditor'
import { getDetail, audit } from '../../service'
export default {
    name: "ApprovalDialog",
@@ -130,18 +134,23 @@
    },
    data() {
        return {
            dialogVisible: false,
            form: {
                planName: "",
                planCode: "",
                stage: "",
                creator: "",
                createTime: "",
                approvalComment: "",
                status: "pending",
                approver: "",
                approveTime: ""
                reportCode: "",
                reportTitle: "",
                reportText: "",
                developPerson: "",
                developPersonName: "",
                developDate: "",
                reportType: 2,
                status: 1,
                teamId: "",
                qaReportFiles: [],
                commitPersonId: null,
                processData:[]
            },
            radio1: 1,
            tableData: [],
            fileList: [], // 附件列表
            rules: {},
            status: "1",
            remark: "",
@@ -149,44 +158,115 @@
    },
    computed: {
        dialogTitle() {
            return this.type === "approve" ? "审批" : "审批详情";
            return this.type == "approve" ? "审批" : "审批详情";
        },
    },
    watch: {
        data: {
        visible: {
            handler(val) {
                if (val) {
                    this.form = { ...val };
                this.dialogVisible = val;
                if (val && this.data.id) {
                    this.getDetail();
                }
            },
            immediate: true,
        },
            immediate: true
        }
    },
    methods: {
        getDetail() {
            getDetail(this.data.id).then(res => {
                if (res) {
                    this.form = { ...res, processData: [] };
                    // 组装流程数据
                    let processData = [];
                    // 提交节点
                    processData.push({
                        type: "primary",
                        mode: "list",
                        fields: [
                            { label: "提交人:", value: res.updateBy || "" },
                            { label: "提交时间:", value: res.createTime || "" },
                        ],
                    });
                    if (res.status == 2 || res.status == 4) {
                        processData.push({
                            type:
                                res.status == 2
                                    ? "primary"
                                    : res.status == 4
                                        ? "primary"
                                        : "warning",
                            mode: "list",
                            fields: [
                                {
                                    label: "审核结果:",
                                    value:
                                        res.status == 2
                                            ? "通过"
                                            : res.status == 4
                                                ? "驳回"
                                                : "待审批",
                                },
                                { label: "审批意见:", value: res.auditRemark || "" },
                                { label: "审核人:", value: res.auditPersonName || res.auditPersonId||"" },
                                { label: "审核时间:", value: res.auditTime || "" },
                            ],
                        });
                    } else {
                        processData.push({
                            type: "warning",
                            mode: "list",
                            fields: [
                                { label: "等待审核" },
                            ],
                        });
                    }
                    this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }];
                    this.fileList = res.qaReportFileList.map(item => {
                        return {
                            ...item,
                            name: item.fileName,
                            url: item.fileUrl
                        }
                    }) || [];
                    this.$nextTick(() => {
                        this.form.processData = processData;
                    })
                } else {
                    this.$message.error(res.message || '获取详情失败');
                }
            }).catch(err => {
                console.error('获取详情失败:', err);
                this.$message.error('获取详情失败');
            });
        },
        handleClose() {
            this.$emit("close");
            this.form.approvalComment = "";
        },
        handleApprove() {
            if (!this.form.approvalComment) {
            if (this.status == "2" && !this.remark) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("approve", {
                ...this.form,
                status: "approved",
            const params = {
                id: this.data.id,
                auditStatus: this.status == "1" ? 2 : 4, // 1=通过(2),2=驳回(4)
                auditRemark: this.remark
            };
            audit(params).then(res => {
                if (res) {
                    this.$message.success("审批成功");
                    this.$emit("close");
                } else {
                    this.$message.error(res.message || "审批失败");
                }
            }).catch(err => {
                console.error("审批失败:", err);
                this.$message.error("审批失败");
            });
        },
        handleReject() {
            if (!this.form.approvalComment) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("reject", {
                ...this.form,
                status: "rejected",
            });
        },
        }
    },
};
</script>
@@ -210,7 +290,6 @@
    .approval-flow {
        padding: 40px 20px;
        // width: 405px;
        flex: 2;
        background: #ffffff;
        box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
@@ -240,7 +319,6 @@
}
.header-title {
    // display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 20px;
@@ -315,7 +393,6 @@
.approval-dialog-approve {
    padding: 38px 20px;
    // display: flex;
    align-content: center;
    .status {
@@ -323,7 +400,6 @@
        max-width: 60%;
    }
    //   align-items: center;
    .status-title {
        color: #222222;
        font-family: "SourceHanSansCN-Medium";
@@ -344,7 +420,6 @@
            border-radius: 10px;
            flex: 1;
            font-size: 16px;
            // padding: 5px 55px;
            font-weight: 400;
            color: #333333;
            cursor: pointer;
@@ -359,7 +434,6 @@
            border-radius: 10px;
            font-size: 16px;
            line-height: 32px;
            // padding: 5px 55px;
            font-weight: 400;
            color: #333333;
            cursor: pointer;
laboratory/src/views/chemistQa/productApproval/index.vue
@@ -1,139 +1,257 @@
<template>
    <div class="list">
        <TableCustom :queryForm="queryForm" :total="total" @currentChange="handleCurrentChange"
            @sizeChange="handleSizeChange">
        <TableCustom :queryForm="queryForm" :total="total" @currentChange="handleCurrentChange" :height="null"
            @sizeChange="handleSizeChange" :tableData="tableData">
            <template #search>
                <el-form :model="form" label-width="auto" inline>
                    <el-form-item label="所属项目组:">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.teamName" placeholder="请输入项目组名称"></el-input>
                    </el-form-item>
                    <el-form-item label="报告标题">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.reportTitle" placeholder="请输入报告标题"></el-input>
                    </el-form-item>
                    <el-form-item label="报告编号">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.reportCode" placeholder="请输入报告编号"></el-input>
                    </el-form-item>
                    <el-form-item label="状态:">
                        <el-select v-model="form.status" placeholder="请选择">
                            <el-option label="草稿箱" value="-1"></el-option>
                            <el-option label="待审核" value="1"></el-option>
                            <el-option label="已通过" value="0"></el-option>
                            <el-option label="已驳回" value="2"></el-option>
                            <el-option label="已通过待评定" value="2"></el-option>
                            <el-option label="已评定" value="3"></el-option>
                            <el-option label="已驳回" value="4"></el-option>
                            <el-option label="已撤销" value="5"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="" style="margin-left: 63px;">
                        <el-button type="default" style="margin-right: 10px;">重置</el-button>
                        <el-button type="primary">查询</el-button>
                        <el-button type="default" @click="resetForm" style="margin-right: 10px;">重置</el-button>
                        <el-button type="primary" @click="getList">查询</el-button>
                    </el-form-item>
                </el-form>
            </template>
            <template #setting>
                <div class="table-setting">
                    <div class="flex a-center">
                        <div class="table-title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')">
                            原辅料、包材、竞品检验分析报告
                        <div class="table-title" :class="{ active: currentType == 'list' }" @click="handleTypeChange('list')">
                            产品报批及项目工作总结报告
                        </div>
                        <div class="table-tit" :class="{ active: currentType === 'draft' }" @click="handleTypeChange('draft')">
                        <div v-if="isChemist" class="table-tit" :class="{ active: currentType == 'draft' }" @click="handleTypeChange('draft')">
                            草稿箱
                        </div>
                    </div>
                    <el-button @click="handleAddProject" class="el-icon-plus" type="primary">
                    <el-button v-if="isChemist" @click="handleAddProject" class="el-icon-plus" type="primary">
                        新增</el-button>
                </div>
            </template>
            <template #table>
                <el-table-column prop="name" label="所属项目组" />
                <el-table-column prop="age" label="报告标题" />
                <el-table-column prop="age" label="报告编号" />
                <el-table-column prop="age" label="制定人" />
                <el-table-column prop="age" label="制定日期" />
                <el-table-column prop="age" label="操作">
                <el-table-column prop="teamName" label="所属项目组" />
                <el-table-column prop="reportTitle" label="报告标题" />
                <el-table-column prop="reportCode" label="报告编号" />
                <el-table-column prop="createBy" label="制定人" />
                <el-table-column prop="createTime" label="制定日期" />
                <el-table-column prop="status" label="状态">
                    <template #default="{ row }">
                        <el-button type="text" @click="showApproval = true">详情</el-button>
                        <el-tag :type="getStatusType(row.status)">
                            {{ getStatusText(row.status) }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="200">
                    <template #default="{ row }">
                        <!-- 化验师的按钮 -->
                        <template v-if="isChemist">
                            <template v-if="currentType == 'draft'">
                                <el-button type="text" @click="handleEdit(row)">编辑</el-button>
                                <el-button type="text" @click="handleDelete(row)">删除</el-button>
                            </template>
                            <el-button v-else type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                        <!-- 工艺工程师的按钮 -->
                        <template v-else-if="isProcessEngineer">
                            <el-button v-if="row.status == 1" type="text" @click="handleApprove(row)">审批</el-button>
                            <el-button v-else type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                        <!-- 其他角色的按钮 -->
                        <template v-else>
                            <el-button type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                    </template>
                </el-table-column>
            </template>
        </TableCustom>
        <Approval :visible="showApproval" @close="showApproval = false" />
        <ShowDelConfirm :show="showDelConfirm" @close="showDelConfirm = false" @confirm="handleDelConfirm" />
        <ShowDelConfirm :title="changeStatusTitle" :tip="changeStatusTip" :show="changeStatus"
            @close="changeStatus = false" @confirm="handleChangeStatusConfirm" />
        <Approval
            :visible.sync="showApproval"
            :type="approvalType"
            :data="approvalData"
            @close="handleApprovalClose"
        />
        <ShowDelConfirm
            :show="showDelConfirm"
            title="确认删除"
            tip="删除后数据将无法恢复,是否确认删除?"
            @close="showDelConfirm = false"
            @confirm="handleDelConfirm"
        />
    </div>
</template>
<script>
import Approval from './components/approval'
import ShowDelConfirm from "@/components/showDelConfirm/index.vue";
import { getDataList, deleteById } from './service'
export default {
    name: 'ProjectList',
    components: {
        Approval
        Approval,
        ShowDelConfirm
    },
    data() {
        return {
            currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱
            form: {
                name: '',
                teamName: '',
                reportTitle: '',
                reportCode: '',
                status: '',
                pageNum: 1,
                pageSize: 10
            },
            showDelConfirm: false,
            rowId: '',
            changeStatus: false,
            showApproval: false,
            changeStatusTitle: '',
            changeStatusTip: '',
            approvalType: 'view',
            approvalData: {},
            queryForm: {
                pageSize: 10,
                pageNum: 1
            },
            total: 0
            total: 0,
            tableData: [] // 添加表格数据
        }
    },
    methods: {
        handleAddProject() {
            this.$router.push('/chemistQa/addPilot')
    computed: {
        isChemist() {
            const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
            return userInfo.roleType == 4; // 4是化验师
        },
        handleDel(row) {
            this.rowId = row.id
            this.showDelConfirm = true
        isProcessEngineer() {
            const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
            return userInfo.roleType == 3; // 3是工艺工程师
        }
    },
    created() {
        this.getList();
    },
    methods: {
        resetForm() {
            this.form = {
                teamName: '',
                reportTitle: '',
                reportCode: '',
                status: this.currentType == 'draft' ? -1 : '',
                pageNum: 1,
                pageSize: 10
            };
            this.getList();
        },
        handleAddProject() {
            this.$router.push('/chemistQa/addProductApproval')
        },
        handleEdit(row) {
            this.$router.push({
                path: '/chemistQa/editProductApproval',
                query: { id: row.id }
            });
        },
        handleDelete(row) {
            this.rowId = row.id;
            this.showDelConfirm = true;
        },
        handleDelConfirm() {
            this.showDelConfirm = false
            this.msgsuccess('删除成功')
            this.rowId = ''
            this.getList()
            // 调用删除API
            deleteById({ id: this.rowId }).then(res => {
                if (res.code == 200) {
                    this.$message.success('删除成功');
                    this.showDelConfirm = false;
                    this.getList();
                } else {
                    this.$message.error(res.msg || '删除失败');
                }
            }).catch(err => {
                console.error('删除失败:', err);
                this.$message.error('删除失败');
            });
        },
        handleChangeStatus(row, status) {
            this.rowId = row.id
            this.changeStatusTitle = status == 1 ? '确认要封存这个项目组吗?' : '确认要解封该项目组吗?'
            this.changeStatusTip = status == 1 ? '封存后项目组内人员看不到数据,审批人仍然可见数据。' : '解封后项目组内人员数据恢复。'
            this.changeStatus = true
        handleApprove(row) {
            this.approvalType = 'approve';
            this.approvalData = row;
            this.showApproval = true;
        },
        handleChangeStatusConfirm() {
            this.changeStatus = false
            this.msgsuccess('操作成功')
            this.rowId = ''
            this.changeStatusTitle = ''
            this.changeStatusTip = ''
            this.getList()
        handleDetail(row) {
            this.approvalType = 'view';
            this.approvalData = row;
            this.showApproval = true;
        },
        handleCurrentChange(page) {
            this.queryForm.pageNum = page
            this.getList()
            this.queryForm.pageNum = page;
            this.getList();
        },
        handleSizeChange(size) {
            this.queryForm.pageSize = size
            this.getList()
            this.queryForm.pageSize = size;
            this.getList();
        },
        getList() {
            const params = {
                ...this.form,
                pageNum: this.queryForm.pageNum,
                pageSize: this.queryForm.pageSize,
                // reportType: 2  // 原辅料、包材、竞品检验分析报告
            };
            getDataList(params).then(res => {
                if (res.code == 200) {
                    this.tableData = res.data.records || [];
                    this.total = res.data.total || 0;
                } else {
                    this.$message.error(res.msg || '获取数据失败');
                }
            }).catch(err => {
                console.error('获取数据失败:', err);
                this.$message.error('获取数据失败');
            });
        },
        handleTypeChange(type) {
            this.currentType = type;
            this.form.status = type === 'draft' ? -1 : '';
            this.form.status = type == 'draft' ? -1 : '';
            this.getList();
        },
        getStatusType(status) {
            const statusMap = {
                '-1': 'info',
                '1': 'warning',
                '2': 'success',
                '3': 'success',
                '4': 'danger',
                '5': 'info'
            };
            return statusMap[status] || 'info';
        },
        getStatusText(status) {
            const statusMap = {
                '-1': '草稿箱',
                '1': '待审核',
                '2': '已通过待评定',
                '3': '已评定',
                '4': '已驳回',
                '5': '已撤销'
            };
            return statusMap[status] || '未知状态';
        },
        handleApprovalClose() {
            this.showApproval = false;
            this.approvalData = {};
            this.getList(); // 刷新列表数据
        }
    }
}
laboratory/src/views/chemistQa/productApproval/service.js
New file
@@ -0,0 +1,43 @@
import axios from '@/utils/request';
// 查询列表
export function getDataList(data) {
  return axios.post('/api/t-qa-produce-report/pageList', { ...data })
}
// 添加
export function addData(data) {
  return axios.post('/api/t-qa-produce-report/add', { ...data })
}
//修改
export function editData(data) {
  return axios.post('/api/t-qa-produce-report/update', { ...data })
}
//获取详情
export function getDetail(id) {
  return axios.get(`/open/t-qa-produce-report/getDetailById?id=${id}`)
}
//审核
export function audit(data) {
  console.log(data)
  return axios.post('/api/t-qa-produce-report/auditReport', { ...data })
}
//撤销审批
export function revokeAudit(data) {
  return axios.put(`/open/t-qa-produce-report/revokedReport?id=${data.id}`)
}
//删除
export function deleteData(data) {
  return axios.delete(`/open/t-qa-produce-report/deleteById?id=${data.id}`)
}
laboratory/src/views/chemistQa/rawMaterials/add.vue
@@ -1,6 +1,6 @@
<template>
    <div>
        <Card>
    <div class="add-container" :loading="loading">
        <Card v-loading="loading">
            <div class="header-title" style="width: 100%;">
                <div class="header-title-left">
                    <img src="@/assets/public/headercard.png" />
@@ -10,97 +10,259 @@
                    <el-button @click="showChoose = true" class="el-icon-circle-plus-outline" type="primary">
                        选择项目组</el-button>
                </div>
            </div>
            <Table :height="null" :queryForm="queryForm" :total="0">
            <Table :height="null" :data="tableData" :queryForm="queryForm" :total="0">
                <template>
                    <el-table-column prop="name" label="项目组名称" />
                    <el-table-column prop="age" label="项目负责人" />
                    <el-table-column prop="age" label="项目组成员" />
                    <el-table-column prop="age" label="创建时间" />
                    <el-table-column prop="teamName" label="项目组名称" />
                    <el-table-column prop="personCharge" label="项目负责人" />
                    <el-table-column prop="staffName" label="项目组成员" />
                    <el-table-column prop="createTime" label="创建时间" />
                </template>
            </Table>
            <el-form ref="form" :model="form" :rules="rules" inline label-position="top" style="margin-top: 38px">
            <el-form ref="form" :model="form" :rules="rules" inline label-position="top" style="margin-top: 18px">
                <el-row :gutter="20">
                    <el-col :span="24">
                        <el-form-item prop="name" label="报告内容">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告内容" />
                        <el-form-item prop="reportTitle" label="报告标题">
                            <el-input v-model="form.reportTitle" style="width: 100%;" placeholder="请输入报告标题" />
                        </el-form-item>
                        <el-form-item prop="name" label="报告编号" style="margin-left: 100px;">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                        <el-form-item prop="reportCode" label="报告编号" style="margin-left: 100px;">
                            <el-input v-model="form.reportCode" style="width: 100%;" placeholder="请输入报告编号" disabled />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item prop="name" label="制定人">
                            <el-input v-model="form.name" style="width: 100%;" placeholder="请输入制定人" />
                        <el-form-item prop="developPersonName" label="制定人">
                            <el-input v-model="form.developPersonName" style="width: 100%;" placeholder="请输入制定人" disabled />
                        </el-form-item>
                        <el-form-item prop="name" label="制定日期" style="margin-left: 100px;">
                            <el-date-picker :prefix-icon="null" v-model="form.createTime"  type="date" placeholder="请选择日期" />
                        <el-form-item prop="developDate" label="制定日期" style="margin-left: 100px;">
                            <el-date-picker :prefix-icon="null" v-model="form.developDate" type="date" disabled
                                placeholder="请选择日期" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <div class="header-title" style="width: 100%;">
                    <div class="header-title-left">
                        <img src="@/assets/public/headercard.png" />
                        <div>报告正文</div>
                    </div>
                </div>
                <form-item prop="name" style="margin-top: 38px">
                    <ai-editor v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                </form-item>
                <el-form-item prop="reportText" style="margin-top: 18px">
                    <ai-editor ref="materialEditor" :value="form.reportText" style="width: 100%;"
                        placeholder="请输入报告正文" />
                </el-form-item>
                <div class="header-title" style="width: 100%;">
                    <div class="header-title-left">
                        <img src="@/assets/public/headercard.png" />
                        <div>附件</div>
                        <div class="noRequire">附件</div>
                    </div>
                </div>
                <el-form-item prop="name" style="margin-top: 38px">
                    <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList">
                <el-form-item prop="name" style="margin-top: 18px">
                    <el-upload
                        action="#"
                        :file-list="fileList"
                        :http-request="handleUpload"
                        :before-upload="beforeUpload"
                        :on-remove="handleRemove">
                        <el-button size="small" type="primary">点击上传</el-button>
                        <div slot="tip" class="el-upload__tip">支持任意格式文件上传</div>
                    </el-upload>
                </el-form-item>
                <div class="end-btn" style="margin-top: 38px">
                    <el-button type="primary">发送</el-button>
                    <el-button type="default">存草稿</el-button>
                    <el-button type="primary" @click="submit" :loading="loading">发送</el-button>
                    <el-button type="default" @click="save" :loading="loading">存草稿</el-button>
                </div>
            </el-form>
        </Card>
        <chooseProject @submit="getProjectData" :show="showChoose" @close="showChoose = false"></chooseProject>
    </div>
</template>
<script>
import { Card } from 'element-ui';
import AiEditor from '@/components/AiEditor'
import chooseProject from '@/components/chooseProject'
import { addData, getDetail, editData } from './service'
export default {
    components: { AiEditor },
    components: {
        AiEditor,
        chooseProject
    },
    data() {
        return {
            loading: false,
            form: {
                planName: "",
                planCode: "",
                stage: "",
                creator: "",
                createTime: "",
                approvalComment: "",
                status: "pending",
                approver: "",
                approveTime: ""
                reportCode: "",
                reportTitle: "",
                reportText: "",
                developPerson: "",
                developPersonName: "",
                developDate: "",
                reportType: 2,
                status: 1,
                teamId: "",
                qaReportFiles: [],
                commitPersonId: null,
            },
            tableData: [],
            fileList: [], // 附件列表
            showChoose: false,
            radio1: 1,
            rules: {},
            status: "1",
            remark: "",
            queryForm: {
            }
            rules: {
                reportTitle: [
                    { required: true, message: '请输入报告标题', trigger: 'blur' }
                ],
            },
            queryForm: {}
        }
    }
}
    },
    mounted() {
        this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).userId;
        this.form.developPersonName = JSON.parse(sessionStorage.getItem('userInfo')).nickName;
        this.form.commitPersonId = JSON.parse(sessionStorage.getItem('userInfo')).userId
        this.form.developDate = new Date().toISOString().split('T')[0];
        if (this.$route.query.id) {
            this.getDetail()
        }
    },
    methods: {
        getDetail() {
            getDetail(this.$route.query.id).then(res => {
                this.form = res
                this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }]
                this.fileList = res.fileList || []
            })
        },
        getProjectData(data) {
            this.tableData = [data]
            this.$forceUpdate()
            this.showChoose = false
        },
        submit() {
            if (this.tableData.length == 0) {
                this.$message.error('请选择项目组')
                return
            }
            this.$refs.form.validate((valid) => {
                if (this.$refs.materialEditor.getContent() == '<p></p>') {
                    this.$message.error('请输入报告正文')
                    return
                }
                let data = {
                    ...this.form,
                    reportText: this.$refs.materialEditor.getContent(),
                    teamId: this.tableData[0].id,
                    status: 1, // 待审核状态
                    commitPersonId: JSON.parse(sessionStorage.getItem('userInfo')).userId
                }
                if (valid) {
                    this.loading = true
                    if (this.$route.query.id) {
                        editData({ ...data, id: this.$route.query.id }).then(res => {
                            if (res.code === 200) {
                                this.$message.success('修改成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    } else {
                        addData(data).then(res => {
                            if (res.code === 200) {
                                this.$message.success('发布成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    }
                }
            })
        },
        save() {
            this.$refs.form.validate((valid) => {
                let data = {
                    ...this.form,
                    reportText: this.$refs.materialEditor.getContent(),
                    teamId: this.tableData[0].id,
                    status: -1, // 草稿箱状态
                    commitPersonId: JSON.parse(sessionStorage.getItem('userInfo')).userId
                }
                if (valid) {
                    this.loading = true
                    if (this.$route.query.id) {
                        // 编辑草稿
                        editData({ ...data, id: this.$route.query.id }).then(res => {
                            if (res.code === 200) {
                                this.$message.success('草稿保存成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    } else {
                        // 新增草稿
                        addData(data).then(res => {
                            if (res.code === 200) {
                                this.$message.success('草稿保存成功')
                                this.$router.back()
                            } else {
                                this.$message.error(res.message)
                            }
                        }).finally(() => {
                            this.loading = false
                        })
                    }
                }
            })
        },
        beforeUpload(file) {
            return true;
        },
        handleUpload(options) {
            const file = options.file;
            const fileObj = {
                fileName: file.name,
                fileSize: file.size,
                createTime: new Date().toISOString(),
                createBy: '当前用户',
                reportType: 3,
                status: 1,
                id: Date.now().toString(),
                fileUrl: 'https://example.com/default-file-url'
            };
            this.fileList.push({
                name: file.name,
                url: fileObj.fileUrl
            });
            this.form.qaReportFiles.push(fileObj);
            this.$message.success('文件上传成功');
        },
        handleRemove(file) {
            const index = this.fileList.findIndex(item => item.name === file.name);
            if (index !== -1) {
                this.fileList.splice(index, 1);
                this.form.qaReportFiles.splice(index, 1);
            }
        },
    },
}
</script>
<style lang="less" scoped>
laboratory/src/views/chemistQa/rawMaterials/components/approval/index.vue
@@ -1,5 +1,5 @@
<template>
    <el-dialog :title="dialogTitle" :visible.sync="visible" width="80%" po :close-on-click-modal="false"
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="80%"  :close-on-click-modal="false"
        @close="handleClose">
        <div class="approval-dialog">
            <!-- 左侧审批内容 -->
@@ -12,38 +12,39 @@
                                <div>所属项目组</div>
                            </div>
                        </div>
                        <Table :height="null" :queryForm="queryForm" :total="0" @currentChange="handleCurrentChange"
                            @sizeChange="handleSizeChange">
                        <Table :height="null" :total="0">
                            <template>
                                <el-table-column prop="name" label="项目组名称" />
                                <el-table-column prop="age" label="项目负责人" />
                                <el-table-column prop="age" label="项目组成员" />
                                <el-table-column prop="age" label="创建时间" />
                                <el-table-column prop="teamName" label="项目组名称" />
                                <el-table-column prop="personCharge" label="项目负责人" />
                                <el-table-column prop="staffName" label="项目组成员" />
                                <el-table-column prop="createTime" label="创建时间" />
                            </template>
                        </Table>
                        <el-form ref="form" :model="form" :rules="rules" inline label-position="top"
                            style="margin-top: 38px">
                            style="margin-top: 18px">
                            <el-row :gutter="20">
                                <el-col :span="24">
                                    <el-form-item prop="name" label="报告内容">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告内容" />
                                    <el-form-item prop="reportTitle" label="报告标题">
                                        <el-input v-model="form.reportTitle" style="width: 100%;" placeholder="请输入报告标题"
                                            disabled />
                                    </el-form-item>
                                    <el-form-item prop="name" label="报告编号" style="margin-left: 100px;">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                                    <el-form-item prop="reportCode" label="报告编号" style="margin-left: 100px;">
                                        <el-input v-model="form.reportCode" style="width: 100%;" placeholder="请输入报告编号"
                                            disabled />
                                    </el-form-item>
                                </el-col>
                                <el-col :span="24">
                                    <el-form-item prop="name" label="制定人">
                                        <el-input v-model="form.name" style="width: 100%;" placeholder="请输入制定人" />
                                    <el-form-item prop="developPerson" label="制定人">
                                        <el-input v-model="form.developPerson" style="width: 100%;" placeholder="请输入制定人"
                                            disabled />
                                    </el-form-item>
                                    <el-form-item prop="name" label="制定日期" style="margin-left: 100px;">
                                        <el-date-picker :prefix-icon="null" v-model="form.createTime" type="date"
                                            placeholder="请选择日期" />
                                    <el-form-item prop="developDate" label="制定日期" style="margin-left: 100px;">
                                        <el-date-picker :prefix-icon="null" v-model="form.developDate" type="date"
                                            disabled placeholder="请选择日期" />
                                    </el-form-item>
                                </el-col>
                            </el-row>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
@@ -51,28 +52,33 @@
                                    <div>报告正文</div>
                                </div>
                            </div>
                            <el-form-item prop="name" style="margin-top: 38px">
                                <ai-editor v-model="form.name" style="width: 100%;" placeholder="请输入报告编号" />
                            <el-form-item prop="reportText" style="margin-top: 18px">
                                <ai-editor :value="form.reportText" style="width: 100%;" placeholder="请输入报告正文"
                                    :readOnly="true" />
                            </el-form-item>
                            <el-form-item prop="name" style="margin-top: 38px">
                                <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList">
                                    <el-button size="small" type="primary">点击上传</el-button>
                            <div class="header-title" style="width: 100%;">
                                <div class="header-title-left">
                                    <img src="@/assets/public/headercard.png" />
                                    <span class="noRequire">附件</span>
                                </div>
                            </div>
                            <el-form-item prop="name" style="margin-top: 18px">
                                <el-upload action="#" :file-list="fileList" disabled>
                                    <el-button size="small" type="primary" disabled>点击上传</el-button>
                                </el-upload>
                            </el-form-item>
                        </el-form>
                    </template>
                    <!-- <SelectMember ref="selectMember" /> -->
                </Card>
            </div>
            <!-- 右侧审批流程 -->
            <div class="approval-flow">
                <div class="flow-content">
                    <approval-process :status="form.status" :submit-time="form.createTime" :approver="form.approver"
                        :approve-time="form.approveTime" />
                    <approval-process :processData="form.processData" />
                </div>
            </div>
        </div>
        <div class="approval-dialog-approve">
        <div class="approval-dialog-approve" v-if="type == 'approve'">
            <el-row :span="24">
                <el-col :span="12">
                    <div class="status">
@@ -94,12 +100,10 @@
                    </div>
                </el-col>
            </el-row>
        </div>
        <div slot="footer" class="dialog-footer">
            <el-button @click="handleClose">取 消</el-button>
            <el-button type="primary" @click="handleApprove" v-if="type === 'approve'">通过</el-button>
            <el-button type="primary" @click="handleApprove" v-if="type == 'approve'">确 定</el-button>
        </div>
    </el-dialog>
</template>
@@ -107,6 +111,7 @@
<script>
import ApprovalProcess from '@/components/approvalProcess'
import AiEditor from '@/components/AiEditor'
import { getDetail, audit } from '../../service'
export default {
    name: "ApprovalDialog",
@@ -130,18 +135,23 @@
    },
    data() {
        return {
            dialogVisible: false,
            form: {
                planName: "",
                planCode: "",
                stage: "",
                creator: "",
                createTime: "",
                approvalComment: "",
                status: "pending",
                approver: "",
                approveTime: ""
                reportCode: "",
                reportTitle: "",
                reportText: "",
                developPerson: "",
                developPersonName: "",
                developDate: "",
                reportType: 2,
                status: 1,
                teamId: "",
                qaReportFiles: [],
                commitPersonId: null,
                processData:[]
            },
            radio1: 1,
            tableData: [],
            fileList: [], // 附件列表
            rules: {},
            status: "1",
            remark: "",
@@ -149,44 +159,115 @@
    },
    computed: {
        dialogTitle() {
            return this.type === "approve" ? "审批" : "审批详情";
            return this.type == "approve" ? "审批" : "审批详情";
        },
    },
    watch: {
        data: {
        visible: {
            handler(val) {
                if (val) {
                    this.form = { ...val };
                this.dialogVisible = val;
                if (val && this.data.id) {
                    this.getDetail();
                }
            },
            immediate: true,
        },
            immediate: true
        }
    },
    methods: {
        getDetail() {
            getDetail(this.data.id).then(res => {
                if (res) {
                    this.form = { ...res, processData: [] };
                    // 组装流程数据
                    let processData = [];
                    // 提交节点
                    processData.push({
                        type: "primary",
                        mode: "list",
                        fields: [
                            { label: "提交人:", value: res.updateBy || "" },
                            { label: "提交时间:", value: res.createTime || "" },
                        ],
                    });
                    if (res.status == 2 || res.status == 4) {
                        processData.push({
                            type:
                                res.status == 2
                                    ? "primary"
                                    : res.status == 4
                                        ? "primary"
                                        : "warning",
                            mode: "list",
                            fields: [
                                {
                                    label: "审核结果:",
                                    value:
                                        res.status == 2
                                            ? "通过"
                                            : res.status == 4
                                                ? "驳回"
                                                : "待审批",
                                },
                                { label: "审批意见:", value: res.auditRemark || "" },
                                { label: "审核人:", value: res.auditPersonName || res.auditPersonId||"" },
                                { label: "审核时间:", value: res.auditTime || "" },
                            ],
                        });
                    } else {
                        processData.push({
                            type: "warning",
                            mode: "list",
                            fields: [
                                { label: "等待审核" },
                            ],
                        });
                    }
                    this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }];
                    this.fileList = res.qaReportFileList.map(item => {
                        return {
                            ...item,
                            name: item.fileName,
                            url: item.fileUrl
                        }
                    }) || [];
                    this.$nextTick(() => {
                        this.form.processData = processData;
                    })
                } else {
                    this.$message.error(res.message || '获取详情失败');
                }
            }).catch(err => {
                console.error('获取详情失败:', err);
                this.$message.error('获取详情失败');
            });
        },
        handleClose() {
            this.$emit("close");
            this.form.approvalComment = "";
        },
        handleApprove() {
            if (!this.form.approvalComment) {
            if (this.status == "2" && !this.remark) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("approve", {
                ...this.form,
                status: "approved",
            const params = {
                id: this.data.id,
                auditStatus: this.status == "1" ? 2 : 4, // 1=通过(2),2=驳回(4)
                auditRemark: this.remark
            };
            audit(params).then(res => {
                if (res) {
                    this.$message.success("审批成功");
                    this.$emit("close");
                } else {
                    this.$message.error(res.message || "审批失败");
                }
            }).catch(err => {
                console.error("审批失败:", err);
                this.$message.error("审批失败");
            });
        },
        handleReject() {
            if (!this.form.approvalComment) {
                this.$message.warning("请输入审批意见");
                return;
            }
            this.$emit("reject", {
                ...this.form,
                status: "rejected",
            });
        },
        }
    },
};
</script>
laboratory/src/views/chemistQa/rawMaterials/index.vue
@@ -1,139 +1,257 @@
<template>
    <div class="list">
        <TableCustom :queryForm="queryForm" :total="total" @currentChange="handleCurrentChange"
            @sizeChange="handleSizeChange">
        <TableCustom :queryForm="queryForm" :total="total" @currentChange="handleCurrentChange" :height="null"
            @sizeChange="handleSizeChange" :tableData="tableData">
            <template #search>
                <el-form :model="form" label-width="auto" inline>
                    <el-form-item label="所属项目组:">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.teamName" placeholder="请输入项目组名称"></el-input>
                    </el-form-item>
                    <el-form-item label="报告标题">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.reportTitle" placeholder="请输入报告标题"></el-input>
                    </el-form-item>
                    <el-form-item label="报告编号">
                        <el-input v-model="form.name" placeholder="请输入"></el-input>
                        <el-input v-model="form.reportCode" placeholder="请输入报告编号"></el-input>
                    </el-form-item>
                    <el-form-item label="状态:">
                        <el-select v-model="form.status" placeholder="请选择">
                            <el-option label="草稿箱" value="-1"></el-option>
                            <el-option label="待审核" value="1"></el-option>
                            <el-option label="已通过" value="0"></el-option>
                            <el-option label="已驳回" value="2"></el-option>
                            <el-option label="已通过待评定" value="2"></el-option>
                            <el-option label="已评定" value="3"></el-option>
                            <el-option label="已驳回" value="4"></el-option>
                            <el-option label="已撤销" value="5"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="" style="margin-left: 63px;">
                        <el-button type="default" style="margin-right: 10px;">重置</el-button>
                        <el-button type="primary">查询</el-button>
                        <el-button type="default" @click="resetForm" style="margin-right: 10px;">重置</el-button>
                        <el-button type="primary" @click="getList">查询</el-button>
                    </el-form-item>
                </el-form>
            </template>
            <template #setting>
                <div class="table-setting">
                    <div class="flex a-center">
                        <div class="table-title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')">
                        <div class="table-title" :class="{ active: currentType == 'list' }" @click="handleTypeChange('list')">
                            原辅料、包材、竞品检验分析报告
                        </div>
                        <div class="table-tit" :class="{ active: currentType === 'draft' }" @click="handleTypeChange('draft')">
                        <div v-if="isChemist" class="table-tit" :class="{ active: currentType == 'draft' }" @click="handleTypeChange('draft')">
                            草稿箱
                        </div>
                    </div>
                    <el-button @click="handleAddProject" class="el-icon-plus" type="primary">
                    <el-button v-if="isChemist" @click="handleAddProject" class="el-icon-plus" type="primary">
                        新增</el-button>
                </div>
            </template>
            <template #table>
                <el-table-column prop="name" label="所属项目组" />
                <el-table-column prop="age" label="报告标题" />
                <el-table-column prop="age" label="报告编号" />
                <el-table-column prop="age" label="制定人" />
                <el-table-column prop="age" label="制定日期" />
                <el-table-column prop="age" label="操作">
                <el-table-column prop="teamName" label="所属项目组" />
                <el-table-column prop="reportTitle" label="报告标题" />
                <el-table-column prop="reportCode" label="报告编号" />
                <el-table-column prop="createBy" label="制定人" />
                <el-table-column prop="createTime" label="制定日期" />
                <el-table-column prop="status" label="状态">
                    <template #default="{ row }">
                        <el-button type="text" @click="showApproval = true">详情</el-button>
                        <el-tag :type="getStatusType(row.status)">
                            {{ getStatusText(row.status) }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="200">
                    <template #default="{ row }">
                        <!-- 化验师的按钮 -->
                        <template v-if="isChemist">
                            <template v-if="currentType == 'draft'">
                                <el-button type="text" @click="handleEdit(row)">编辑</el-button>
                                <el-button type="text" @click="handleDelete(row)">删除</el-button>
                            </template>
                            <el-button v-else type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                        <!-- 工艺工程师的按钮 -->
                        <template v-else-if="isProcessEngineer">
                            <el-button v-if="row.status == 1" type="text" @click="handleApprove(row)">审批</el-button>
                            <el-button v-else type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                        <!-- 其他角色的按钮 -->
                        <template v-else>
                            <el-button type="text" @click="handleDetail(row)">详情</el-button>
                        </template>
                    </template>
                </el-table-column>
            </template>
        </TableCustom>
        <Approval :visible="showApproval" @close="showApproval = false" />
        <ShowDelConfirm :show="showDelConfirm" @close="showDelConfirm = false" @confirm="handleDelConfirm" />
        <ShowDelConfirm :title="changeStatusTitle" :tip="changeStatusTip" :show="changeStatus"
            @close="changeStatus = false" @confirm="handleChangeStatusConfirm" />
        <Approval
            :visible.sync="showApproval"
            :type="approvalType"
            :data="approvalData"
            @close="handleApprovalClose"
        />
        <ShowDelConfirm
            :show="showDelConfirm"
            title="确认删除"
            tip="删除后数据将无法恢复,是否确认删除?"
            @close="showDelConfirm = false"
            @confirm="handleDelConfirm"
        />
    </div>
</template>
<script>
import Approval from './components/approval'
import ShowDelConfirm from "@/components/showDelConfirm/index.vue";
import { getDataList, deleteById } from './service'
export default {
    name: 'ProjectList',
    components: {
        Approval
        Approval,
        ShowDelConfirm
    },
    data() {
        return {
            currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱
            form: {
                name: '',
                teamName: '',
                reportTitle: '',
                reportCode: '',
                status: '',
                pageNum: 1,
                pageSize: 10
            },
            showDelConfirm: false,
            rowId: '',
            changeStatus: false,
            showApproval: false,
            changeStatusTitle: '',
            changeStatusTip: '',
            approvalType: 'view',
            approvalData: {},
            queryForm: {
                pageSize: 10,
                pageNum: 1
            },
            total: 0
            total: 0,
            tableData: [] // 添加表格数据
        }
    },
    methods: {
        handleAddProject() {
            this.$router.push('/chemistQa/addPilot')
    computed: {
        isChemist() {
            const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
            return userInfo.roleType == 4; // 4是化验师
        },
        handleDel(row) {
            this.rowId = row.id
            this.showDelConfirm = true
        isProcessEngineer() {
            const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
            return userInfo.roleType == 3; // 3是工艺工程师
        }
    },
    created() {
        this.getList();
    },
    methods: {
        resetForm() {
            this.form = {
                teamName: '',
                reportTitle: '',
                reportCode: '',
                status: this.currentType == 'draft' ? -1 : '',
                pageNum: 1,
                pageSize: 10
            };
            this.getList();
        },
        handleAddProject() {
            this.$router.push('/chemistQa/addRawMaterials')
        },
        handleEdit(row) {
            this.$router.push({
                path: '/chemistQa/editRawMaterials',
                query: { id: row.id }
            });
        },
        handleDelete(row) {
            this.rowId = row.id;
            this.showDelConfirm = true;
        },
        handleDelConfirm() {
            this.showDelConfirm = false
            this.msgsuccess('删除成功')
            this.rowId = ''
            this.getList()
            // 调用删除API
            deleteById({ id: this.rowId }).then(res => {
                if (res.code == 200) {
                    this.$message.success('删除成功');
                    this.showDelConfirm = false;
                    this.getList();
                } else {
                    this.$message.error(res.msg || '删除失败');
                }
            }).catch(err => {
                console.error('删除失败:', err);
                this.$message.error('删除失败');
            });
        },
        handleChangeStatus(row, status) {
            this.rowId = row.id
            this.changeStatusTitle = status == 1 ? '确认要封存这个项目组吗?' : '确认要解封该项目组吗?'
            this.changeStatusTip = status == 1 ? '封存后项目组内人员看不到数据,审批人仍然可见数据。' : '解封后项目组内人员数据恢复。'
            this.changeStatus = true
        handleApprove(row) {
            this.approvalType = 'approve';
            this.approvalData = row;
            this.showApproval = true;
        },
        handleChangeStatusConfirm() {
            this.changeStatus = false
            this.msgsuccess('操作成功')
            this.rowId = ''
            this.changeStatusTitle = ''
            this.changeStatusTip = ''
            this.getList()
        handleDetail(row) {
            this.approvalType = 'view';
            this.approvalData = row;
            this.showApproval = true;
        },
        handleCurrentChange(page) {
            this.queryForm.pageNum = page
            this.getList()
            this.queryForm.pageNum = page;
            this.getList();
        },
        handleSizeChange(size) {
            this.queryForm.pageSize = size
            this.getList()
            this.queryForm.pageSize = size;
            this.getList();
        },
        getList() {
            const params = {
                ...this.form,
                pageNum: this.queryForm.pageNum,
                pageSize: this.queryForm.pageSize,
                // reportType: 2  // 原辅料、包材、竞品检验分析报告
            };
            getDataList(params).then(res => {
                if (res.code == 200) {
                    this.tableData = res.data.records || [];
                    this.total = res.data.total || 0;
                } else {
                    this.$message.error(res.msg || '获取数据失败');
                }
            }).catch(err => {
                console.error('获取数据失败:', err);
                this.$message.error('获取数据失败');
            });
        },
        handleTypeChange(type) {
            this.currentType = type;
            this.form.status = type === 'draft' ? -1 : '';
            this.form.status = type == 'draft' ? -1 : '';
            this.getList();
        },
        getStatusType(status) {
            const statusMap = {
                '-1': 'info',
                '1': 'warning',
                '2': 'success',
                '3': 'success',
                '4': 'danger',
                '5': 'info'
            };
            return statusMap[status] || 'info';
        },
        getStatusText(status) {
            const statusMap = {
                '-1': '草稿箱',
                '1': '待审核',
                '2': '已通过待评定',
                '3': '已评定',
                '4': '已驳回',
                '5': '已撤销'
            };
            return statusMap[status] || '未知状态';
        },
        handleApprovalClose() {
            this.showApproval = false;
            this.approvalData = {};
            this.getList(); // 刷新列表数据
        }
    }
}
laboratory/src/views/chemistQa/rawMaterials/service.js
New file
@@ -0,0 +1,43 @@
import axios from '@/utils/request';
// 查询列表
export function getDataList(data) {
  return axios.post('/api/t-qa-produce-report/pageList', { ...data })
}
// 添加
export function addData(data) {
  return axios.post('/api/t-qa-produce-report/add', { ...data })
}
//修改
export function editData(data) {
  return axios.post('/api/t-qa-produce-report/update', { ...data })
}
//获取详情
export function getDetail(id) {
  return axios.get(`/open/t-qa-produce-report/getDetailById?id=${id}`)
}
//审核
export function audit(data) {
  console.log(data)
  return axios.post('/api/t-qa-produce-report/auditReport', { ...data })
}
//撤销审批
export function revokeAudit(data) {
  return axios.put(`/open/t-qa-produce-report/revokedReport?id=${data.id}`)
}
//删除
export function deleteData(data) {
  return axios.delete(`/open/t-qa-produce-report/deleteById?id=${data.id}`)
}