| | |
| | | mounted() { |
| | | |
| | | console.log('JSON.parse(sessionStorage.getItem(',JSON.parse(sessionStorage.getItem('userInfo'))) |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).userId; |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).nickName; |
| | | 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]; |
| | |
| | | getDetail() { |
| | | getDetail(this.$route.query.id).then(res => { |
| | | this.form = res |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }] |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.fileList || [] |
| | | }) |
| | | }, |
| | |
| | | <div>所属项目组</div> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :total="0"> |
| | | <Table :height="null" :total="0" :data="tableData" > |
| | | <template> |
| | | <el-table-column prop="teamName" label="项目组名称" /> |
| | | <el-table-column prop="personCharge" label="项目负责人" /> |
| | |
| | | } |
| | | |
| | | // this.form = res; |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }]; |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.qaReportFileList.map(item => { |
| | | return { |
| | | ...item, |
| | |
| | | }, |
| | | handleEdit(row) { |
| | | this.$router.push({ |
| | | path: '/chemistQa/editPilot', |
| | | query: { id: row.id } |
| | | path: '/chemistQa/addPilot', |
| | | query: { id: row.id, type: 'edit' } |
| | | }); |
| | | }, |
| | | handleDelete(row) { |
| | |
| | | ...this.form, |
| | | pageNum: this.queryForm.pageNum, |
| | | pageSize: this.queryForm.pageSize, |
| | | // reportType: 1 |
| | | reportType: 1 |
| | | }; |
| | | getDataList(params).then(res => { |
| | | if (res.code == 200) { |
| | |
| | | }, |
| | | |
| | | mounted() { |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).userId; |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).nickName; |
| | | 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]; |
| | |
| | | getDetail() { |
| | | getDetail(this.$route.query.id).then(res => { |
| | | this.form = res |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }] |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.fileList || [] |
| | | }) |
| | | }, |
| | |
| | | <div>所属项目组</div> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :total="0"> |
| | | <Table :height="null" :total="0" :data="tableData"> |
| | | <template> |
| | | <el-table-column prop="teamName" label="项目组名称" /> |
| | | <el-table-column prop="personCharge" label="项目负责人" /> |
| | |
| | | }); |
| | | } |
| | | |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }]; |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.qaReportFileList.map(item => { |
| | | return { |
| | | ...item, |
| | |
| | | }, |
| | | handleEdit(row) { |
| | | this.$router.push({ |
| | | path: '/chemistQa/editProductApproval', |
| | | path: '/chemistQa/addProductApproval', |
| | | query: { id: row.id } |
| | | }); |
| | | }, |
| | |
| | | ...this.form, |
| | | pageNum: this.queryForm.pageNum, |
| | | pageSize: this.queryForm.pageSize, |
| | | // reportType: 2 // 原辅料、包材、竞品检验分析报告 |
| | | reportType: 3 // 原辅料、包材、竞品检验分析报告 |
| | | }; |
| | | getDataList(params).then(res => { |
| | | if (res.code == 200) { |
| | |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>所属项目组</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <div class="header-title-right" v-if="!isDetail"> |
| | | <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="项目组成员"> |
| | | <template #default="{ row }"> |
| | | <span>{{row.staffs.map(item => item.nickName).join(',')}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="创建时间" /> |
| | | </template> |
| | | </Table> |
| | | <el-form ref="form" :model="form" :rules="rules" inline label-position="top" style="margin-top: 38px"> |
| | | <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"> |
| | | <el-input v-model="form.name" style="width: 100%;" placeholder="请输入检测项名称" /> |
| | | </form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item prop="itemName" label="检测项名称"> |
| | | <el-input v-model="form.itemName" style="width: 100%;" placeholder="请输入检测项名称" :disabled="isDetail" /> |
| | | </el-form-item> |
| | | <el-form-item prop="itemCode" label="检测项编号" style="margin-left: 100px;"> |
| | | <el-input v-model="form.itemCode" style="width: 100%;" placeholder="请输入检测项编号" :disabled="isDetail" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | <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"> |
| | | <el-input v-model="form.name" style="width: 100%;" placeholder="请输入检测项编号" /> |
| | | </form-item> |
| | | </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"> |
| | | <el-input v-model="form.name" type="textarea" :rows="4" style="width: 100%;" placeholder="请输入备注内容" /> |
| | | </form-item> |
| | | <!-- <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"> |
| | | <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList"> |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | </el-upload> |
| | | </form-item> --> |
| | | <div class="notice">备注内容</div> |
| | | |
| | | <div class="end-btn" style="margin-top: 38px"> |
| | | <el-button type="primary">发送</el-button> |
| | | <el-button type="default">存草稿</el-button> |
| | | <div prop="remark" style="margin-top: 18px"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="4" style="width: 100%;" placeholder="请输入备注内容" :disabled="isDetail" /> |
| | | </div> |
| | | |
| | | <div class="notice" style="margin: 18px 0;" v-if="isDetail">报告列表</div> |
| | | |
| | | <div class="table-setting" v-if="isDetail"> |
| | | <div class="flex a-center"> |
| | | <div class="table-title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')"> |
| | | 项目检测项、检验包列表 |
| | | </div> |
| | | <div class="table-tit" :class="{ active: currentType === 'draft' }" @click="handleTypeChange('draft')"> |
| | | 草稿箱 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <Table :data="reportTableData" :total="reportTotal" row-key="id" :height="null" @handlePageChange="handlePageChange" @handleSizeChange="handleSizeChange" |
| | | v-if="isDetail"> |
| | | <el-table-column prop="reportContent" label="报告内容"> |
| | | <template #default="{ row }"> |
| | | <span>{{ getReportContentText(row.reportContent) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="developPerson" label="制订人" /> |
| | | <el-table-column prop="developDate" label="制订日期" /> |
| | | <el-table-column prop="auditPersonId" label="审批人" /> |
| | | <el-table-column prop="auditTime" label="审批时间" /> |
| | | <el-table-column prop="status" label="状态"> |
| | | <template #default="{ row }"> |
| | | <el-tag v-if="row.status == 1" type="info" color="#fff">待审核</el-tag> |
| | | <el-tag v-if="row.status == 2" type="success" color="#fff">已通过</el-tag> |
| | | <el-tag v-if="row.status == 3" type="danger">已驳回</el-tag> |
| | | <el-tag v-if="row.status == 4" type="danger">已撤销</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="age" label="操作"> |
| | | <template #default="{ row }"> |
| | | <template v-if="row.status === 2"> |
| | | <el-button type="text" @click="handleReportDetail(row)">详情</el-button> |
| | | </template> |
| | | <template v-else-if="row.status === 1"> |
| | | <el-button type="text" @click="handleRevokeApproval(row)">撤销审批</el-button> |
| | | </template> |
| | | <template v-else-if="row.status === 3"> |
| | | <el-button type="text" @click="handleReportDetail(row)">详情</el-button> |
| | | <el-button type="text" @click="handleWithdraw(row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDelete(row)">删除</el-button> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </Table> |
| | | |
| | | <div class="end-btn" style="margin-top: 38px" v-if="!isDetail"> |
| | | <el-button type="primary" @click="submit">发送</el-button> |
| | | <el-button type="default" @click="saveDraft">存草稿</el-button> |
| | | </div> |
| | | </el-form> |
| | | </Card> |
| | | <chooseProject @submit="getProjectData" :show="showChoose" @close="showChoose = false"></chooseProject> |
| | | <!-- 删除确认弹窗 --> |
| | | <ShowDelConfirm |
| | | :title="changeStatusTitle" |
| | | :tip="changeStatusTip" |
| | | :show="changeStatus" |
| | | @close="changeStatus = false" |
| | | @confirm="handleChangeStatusConfirm" |
| | | /> |
| | | </div> |
| | | |
| | | </template> |
| | | <script> |
| | | import { Card } from 'element-ui'; |
| | | import AiEditor from '@/components/AiEditor' |
| | | import chooseProject from '@/components/chooseProject' |
| | | import ShowDelConfirm from "@/components/showDelConfirm/index.vue"; |
| | | import {addData, editData, getDetail} from './service' |
| | | |
| | | export default { |
| | | components: { AiEditor }, |
| | | components: { |
| | | AiEditor, |
| | | chooseProject,ShowDelConfirm |
| | | }, |
| | | data() { |
| | | return { |
| | | isEdit: false, |
| | | isDetail: false, |
| | | currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱 |
| | | expandRowKeys: [], |
| | | reportTableData: [], |
| | | reportTotal: 0, |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "pending", |
| | | approver: "", |
| | | approveTime: "" |
| | | id: "", |
| | | itemCode: "", |
| | | itemName: "", |
| | | remark: "", |
| | | status: -1, |
| | | teamId: "" |
| | | }, |
| | | tableData: [], |
| | | fileList: [], // 附件列表 |
| | | showChoose: false, |
| | | radio1: 1, |
| | | rules: {}, |
| | | status: "1", |
| | | remark: "", |
| | | queryForm: { |
| | | |
| | | rules: { |
| | | itemName: [ |
| | | { required: true, message: '请输入检测项名称', trigger: 'blur' } |
| | | ], |
| | | itemCode: [ |
| | | { required: true, message: '请输入检测项编号', trigger: 'blur' } |
| | | ] |
| | | }, |
| | | queryForm: {}, |
| | | changeStatus: false, |
| | | changeStatusTitle: '', |
| | | changeStatusTip: '', |
| | | currentRow: null, |
| | | currentAction: '' // 'revoke' 或 'delete' |
| | | } |
| | | }, |
| | | mounted() { |
| | | if (this.$route.query.id) { |
| | | if (this.$route.query.type === 'detail') { |
| | | this.isDetail = true |
| | | } else if (this.$route.query.type === 'edit') { |
| | | this.isEdit = true |
| | | } |
| | | this.getDetail() |
| | | } |
| | | }, |
| | | methods: { |
| | | getDetail() { |
| | | getDetail(this.$route.query.id).then(res => { |
| | | if (res) { |
| | | this.form = res |
| | | if (res.projectTeamVO) { |
| | | this.tableData = [{ |
| | | ...res.projectTeamVO, |
| | | }] |
| | | } |
| | | if(res.qaTestItemReportList.length > 0){ |
| | | this.reportTableData = res.qaTestItemReportList |
| | | } |
| | | } else { |
| | | this.$message.error(res.msg || '获取详情失败') |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取详情失败:', err) |
| | | this.$message.error('获取详情失败') |
| | | }) |
| | | }, |
| | | getProjectData(data) { |
| | | this.tableData = [data] |
| | | this.form.teamId = data.id |
| | | this.$forceUpdate() |
| | | this.showChoose = false |
| | | }, |
| | | submit() { |
| | | if (this.tableData.length === 0) { |
| | | this.$message.error('请选择项目组') |
| | | return |
| | | } |
| | | |
| | | this.$refs.form.validate((valid) => { |
| | | if (valid) { |
| | | const data = { |
| | | ...this.form, |
| | | status: 1 // 已提交状态 |
| | | } |
| | | const request = this.isEdit ? editData(data) : addData(data) |
| | | request.then(res => { |
| | | if (res.code === 200) { |
| | | this.$message.success(this.isEdit ? '修改成功' : '提交成功') |
| | | this.$router.push('/chemistQa/projectTesting') |
| | | } else { |
| | | this.$message.error(res.msg || (this.isEdit ? '修改失败' : '提交失败')) |
| | | } |
| | | }).catch(err => { |
| | | console.error(this.isEdit ? '修改失败:' : '提交失败:', err) |
| | | this.$message.error(this.isEdit ? '修改失败' : '提交失败') |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | saveDraft() { |
| | | if (this.tableData.length === 0) { |
| | | this.$message.error('请选择项目组') |
| | | return |
| | | } |
| | | |
| | | this.$refs.form.validate((valid) => { |
| | | if (valid) { |
| | | const data = { |
| | | ...this.form, |
| | | status: -1 // 草稿箱状态 |
| | | } |
| | | const request = this.isEdit ? editData(data) : addData(data) |
| | | request.then(res => { |
| | | if (res.code === 200) { |
| | | this.$message.success(this.isEdit ? '修改成功' : '保存成功') |
| | | this.$router.push('/chemistQa/projectTesting') |
| | | } else { |
| | | this.$message.error(res.msg || (this.isEdit ? '修改失败' : '保存失败')) |
| | | } |
| | | }).catch(err => { |
| | | console.error(this.isEdit ? '修改失败:' : '保存失败:', err) |
| | | this.$message.error(this.isEdit ? '修改失败' : '保存失败') |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | this.getReportList(); |
| | | }, |
| | | handleReportRowClick(row, column, event) { |
| | | if (column.label === '操作') return |
| | | if (this.expandRowKeys.includes(row.id)) { |
| | | this.expandRowKeys = this.expandRowKeys.filter(key => key !== row.id); |
| | | } else { |
| | | this.expandRowKeys.push(row.id); |
| | | } |
| | | }, |
| | | handleReportDetail(row) { |
| | | // 处理报告详情 |
| | | this.$router.push({ |
| | | path: '/chemistQa/projectTesting/add', |
| | | query: { |
| | | id: row.id, |
| | | type: 'detail' |
| | | } |
| | | }) |
| | | }, |
| | | getReportList() { |
| | | // 获取报告列表数据 |
| | | // TODO: 调用接口获取数据 |
| | | }, |
| | | handleRevokeApproval(row) { |
| | | this.currentRow = row; |
| | | this.currentAction = 'revoke'; |
| | | this.changeStatusTitle = '确认要撤销这条审批吗?'; |
| | | this.changeStatusTip = '撤销后工艺工程师将无法收到此条审批信息'; |
| | | this.changeStatus = true; |
| | | }, |
| | | handleWithdraw(row) { |
| | | this.$confirm('确认撤回该记录吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | // TODO: 调用撤回接口 |
| | | this.$message.success('撤回成功') |
| | | }).catch(() => { |
| | | this.$message.info('已取消撤回') |
| | | }) |
| | | }, |
| | | handleDelete(row) { |
| | | this.currentRow = row; |
| | | this.currentAction = 'delete'; |
| | | this.changeStatusTitle = '确认要删除这条记录吗?'; |
| | | this.changeStatusTip = '删除后记录将无法找回'; |
| | | this.changeStatus = true; |
| | | }, |
| | | handleChangeStatusConfirm() { |
| | | if (this.currentAction === 'revoke') { |
| | | // TODO: 调用撤销审批接口 |
| | | this.$message.success('撤销审批成功'); |
| | | } else if (this.currentAction === 'delete') { |
| | | // TODO: 调用删除接口 |
| | | this.$message.success('删除成功'); |
| | | } |
| | | this.changeStatus = false; |
| | | this.currentRow = null; |
| | | this.currentAction = ''; |
| | | // 刷新列表 |
| | | this.getReportList(); |
| | | }, |
| | | getReportContentText(value) { |
| | | const contentMap = { |
| | | '1': '国家标准', |
| | | '2': '分析方法开发', |
| | | '3': '方法验证报告', |
| | | '4': '方法确认', |
| | | '5': '操作规程', |
| | | '6': '方法转移记录清单' |
| | | }; |
| | | return contentMap[value] || value; |
| | | } |
| | | } |
| | | } |
| | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .notice{ |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | .header-title { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | // background: #409EFF; |
| | | } |
| | | } |
| | | |
| | | .table-setting { |
| | | display: flex; |
| | | padding-bottom: 20px; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .flex { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .table-title { |
| | | width: 220px; |
| | | height: 50px; |
| | | background: #fafafc; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #dcdfe6; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | line-height: 27px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &.active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border: 1px solid #049c9a; |
| | | } |
| | | } |
| | | |
| | | .table-tit { |
| | | width: 166px; |
| | | height: 50px; |
| | | background: #fafafc; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #dcdfe6; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | line-height: 27px; |
| | | margin-left: 16px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &.active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border: 1px solid #049c9a; |
| | | } |
| | | } |
| | | |
| | | .expand-box { |
| | | padding: 20px; |
| | | background: linear-gradient(180deg, #049C9A 0%, #0ACBCA 100%); |
| | | border-radius: 20px; |
| | | |
| | | &-title { |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | color: #FFFFFF; |
| | | line-height: 24px; |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <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" /> |
| | | <div>所属项目组</div> |
| | | <div>所属检测项</div> |
| | | </div> |
| | | <div class="header-title-right"> |
| | | <!-- <div class="header-title-right"> |
| | | <el-button @click="showChoose = true" class="el-icon-circle-plus-outline" type="primary"> |
| | | 选择项目组</el-button> |
| | | </div> --> |
| | | </div> |
| | | |
| | | </div> |
| | | <Table :height="null" :queryForm="queryForm" :total="0"> |
| | | <Table :height="null" :data="tableData" :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="itemName" label="检测项名称" /> |
| | | <el-table-column prop="itemCode" label="检测项编号" /> |
| | | <el-table-column prop="remarks" label="备注" /> |
| | | <el-table-column prop="createBy" 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="reportContent" label="报告内容"> |
| | | <el-select v-model="form.reportContent" style="width: 100%;" placeholder="请选择报告内容"> |
| | | <el-option label="国家标准" :value="1" /> |
| | | <el-option label="分析方法开发" :value="2" /> |
| | | <el-option label="方法验证报告" :value="3" /> |
| | | <el-option label="方法确认" :value="4" /> |
| | | <el-option label="操作规程" :value="5" /> |
| | | <el-option label="方法转移记录清单" :value="6" /> |
| | | </el-select> |
| | | </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> |
| | | <span class="noRequire">附件</span> |
| | | </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 { addDetail, getDetailInfo,updateDetail,getDetail } 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: "", |
| | | reportContent: "", |
| | | reportText: "", |
| | | developPerson: "", |
| | | developPersonName: "", |
| | | developDate: "", |
| | | itemId: "", |
| | | status: 1, |
| | | itemId: "", |
| | | qaReportFiles: [], |
| | | commitPersonId: null, |
| | | }, |
| | | tableData: [], |
| | | fileList: [], // 附件列表 |
| | | showChoose: false, |
| | | radio1: 1, |
| | | rules: {}, |
| | | status: "1", |
| | | remark: "", |
| | | queryForm: { |
| | | rules: { |
| | | reportContent: [ |
| | | { required: true, message: '请选择报告内容', trigger: 'change' } |
| | | ], |
| | | itemId: [ |
| | | { required: true, message: '请选择检测项', trigger: 'change' } |
| | | ] |
| | | }, |
| | | queryForm: {} |
| | | } |
| | | }, |
| | | |
| | | mounted() { |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).nickName; |
| | | 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]; |
| | | |
| | | this.form.itemId=this.$route.query.itemId |
| | | if(this.form.itemId){ |
| | | getDetail(this.form.itemId).then(res=>{ |
| | | if(res){ |
| | | let item={ |
| | | teamName:res.projectTeamVO.teamName, |
| | | teamId:res.teamId, |
| | | remark:res.remark, |
| | | |
| | | itemName:res.itemName, |
| | | itemCode:res.itemCode, |
| | | createBy:res.createBy, |
| | | createTime:res.createTime |
| | | } |
| | | this.tableData = [{ ...item }] |
| | | } |
| | | }) |
| | | } |
| | | console.log('this.$route.query.itemId',this.$route.query) |
| | | |
| | | if (this.$route.query.id) { |
| | | this.getDetail() |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | getDetail() { |
| | | getDetailInfo({id:this.$route.query.id}).then(res => { |
| | | if (res) { |
| | | this.form = { |
| | | ...res, |
| | | reportContent: Number(res.reportContent) |
| | | } |
| | | // this.tableData = [{ ...res.data.projectTeam, staffName: res.data.staffNames }] |
| | | this.fileList = res.qaReportFiles || [] |
| | | } else { |
| | | this.$message.error(res.message || '获取详情失败') |
| | | } |
| | | }) |
| | | }, |
| | | getProjectData(data) { |
| | | this.tableData = [data] |
| | | this.$forceUpdate() |
| | | this.showChoose = false |
| | | }, |
| | | submit() { |
| | | this.$refs.form.validate((valid) => { |
| | | if (!valid) return |
| | | |
| | | if (this.$refs.materialEditor.getContent() == '<p></p>') { |
| | | this.$message.error('请输入报告正文') |
| | | return |
| | | } |
| | | |
| | | let data = { |
| | | ...this.form, |
| | | reportText: this.$refs.materialEditor.getContent(), |
| | | status: 1, // 待审核状态 |
| | | } |
| | | |
| | | this.loading = true |
| | | if (this.$route.query.id) { |
| | | console.log('data updateDetail',data) |
| | | updateDetail({ ...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 { |
| | | console.log('data addDetail',data) |
| | | addDetail(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) => { |
| | | if (!valid) return |
| | | |
| | | let data = { |
| | | ...this.form, |
| | | reportText: this.$refs.materialEditor.getContent(), |
| | | status: -1, // 草稿箱状态 |
| | | } |
| | | |
| | | this.loading = true |
| | | if (this.$route.query.id) { |
| | | // 编辑草稿 |
| | | updateDetail({ ...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 { |
| | | // 新增草稿 |
| | | addDetail(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: JSON.parse(sessionStorage.getItem('userInfo')).userId, |
| | | reportType: 1, |
| | | 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> |
| | |
| | | <div class="header-title" style="width: 100%;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>所属项目组</div> |
| | | <div>所属检测项</div> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :queryForm="queryForm" :total="0" @currentChange="handleCurrentChange" |
| | | @sizeChange="handleSizeChange"> |
| | | <Table :height="null" :total="0" :data="tableData"> |
| | | <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="itemName" label="检测项名称" /> |
| | | <el-table-column prop="itemCode" label="检测项编号" /> |
| | | <el-table-column prop="remark" label="备注" /> |
| | | <el-table-column prop="createBy" 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-form-item prop="name" label="报告内容"> |
| | | <el-select v-model="form.name" placeholder="请选择报告内容"> |
| | | <el-option label="报告内容1" value="1"></el-option> |
| | | <el-option label="报告内容2" value="2"></el-option> |
| | | <el-select v-model="form.reportContent" style="width: 100%;" disabled |
| | | placeholder="请选择报告内容"> |
| | | <el-option label="国家标准" :value="1" /> |
| | | <el-option label="分析方法开发" :value="2" /> |
| | | <el-option label="方法验证报告" :value="3" /> |
| | | <el-option label="方法确认" :value="4" /> |
| | | <el-option label="操作规程" :value="5" /> |
| | | <el-option label="方法转移记录清单" :value="6" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | |
| | | <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="name" style="margin-top: 18px"> |
| | | <ai-editor :value="form.reportText" :readOnly="true" 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> |
| | | <span>附件</span> |
| | | </div> |
| | | </div> |
| | | <el-form-item prop="name" style="margin-top: 38px"> |
| | | <el-form-item prop="name" style="margin-top: 18px"> |
| | | <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList"> |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | <!-- <el-button size="small" type="primary">点击上传</el-button> --> |
| | | </el-upload> |
| | | </el-form-item> |
| | | |
| | |
| | | <!-- 右侧审批流程 --> |
| | | <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"> |
| | |
| | | <script> |
| | | import ApprovalProcess from '@/components/approvalProcess' |
| | | import AiEditor from '@/components/AiEditor' |
| | | import { getDetailInfo, getDetail,detailAuditReport } from '../../service' |
| | | |
| | | export default { |
| | | name: "ApprovalDialog", |
| | |
| | | type: Object, |
| | | default: () => ({}), |
| | | }, |
| | | id: { |
| | | type: String, |
| | | default: "", |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | planName: "", |
| | | planCode: "", |
| | | stage: "", |
| | | creator: "", |
| | | createTime: "", |
| | | approvalComment: "", |
| | | status: "pending", |
| | | approver: "", |
| | | approveTime: "" |
| | | reportText: "", |
| | | reportContent: "", |
| | | qaReportFiles: [], |
| | | processData: [], |
| | | }, |
| | | tableData: [], |
| | | fileList:[], |
| | | radio1: 1, |
| | | rules: {}, |
| | | status: "1", |
| | |
| | | }, |
| | | computed: { |
| | | dialogTitle() { |
| | | return this.type === "approve" ? "审批" : "审批详情"; |
| | | return this.type === "approve" ? "方法验证报告审批" : "方法验证报告详情"; |
| | | }, |
| | | }, |
| | | watch: { |
| | | data: { |
| | | visible: { |
| | | handler(val) { |
| | | if (val) { |
| | | this.form = { ...val }; |
| | | if (val && this.data.id) { |
| | | this.getDetailInfo() |
| | | } |
| | | if (val && this.data.itemId) { |
| | | this.getDetail() |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | methods: { |
| | | getDetailInfo() { |
| | | getDetailInfo({ id: this.data.id }).then(res => { |
| | | if (res) { |
| | | this.form = { ...res, reportContent: Number(res.reportContent), processData: [] } |
| | | this.fileList = res.qaReportFileList |
| | | // 组装流程数据 |
| | | let processData = []; |
| | | // 提交节点 |
| | | processData.push({ |
| | | type: "primary", |
| | | mode: "list", |
| | | fields: [ |
| | | { label: "提交人:", value: res.updateBy || "" }, |
| | | { label: "提交时间:", value: res.createTime || "" }, |
| | | ], |
| | | }); |
| | | if (res.status == 2 || res.status == 3) { |
| | | processData.push({ |
| | | type: |
| | | res.status === 2 |
| | | ? "primary" |
| | | : res.status === 3 |
| | | ? "danger" |
| | | : "warning", |
| | | mode: "list", |
| | | fields: [ |
| | | { |
| | | label: "审核结果:", |
| | | value: |
| | | res.status === 2 |
| | | ? "通过" |
| | | : res.status === 3 |
| | | ? "驳回" |
| | | : "待审批", |
| | | }, |
| | | { label: "审批意见:", value: res.auditRemark || "" }, |
| | | { label: "审核人:", value: res.auditPersonName || "" }, |
| | | { label: "审核时间:", value: res.auditTime || "" }, |
| | | ], |
| | | }); |
| | | } else { |
| | | processData.push({ |
| | | type: "warning", |
| | | mode: "list", |
| | | fields: [ |
| | | { label: "等待审核" }, |
| | | ], |
| | | }); |
| | | } |
| | | // 如有卡片模式,按前述结构 push |
| | | |
| | | this.$nextTick(() => { |
| | | this.form.processData = processData; |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | getDetail() { |
| | | getDetail(this.data.itemId).then(res => { |
| | | if (res) { |
| | | this.tableData = [{...res,teamName:res.projectTeamVO.teamName}] |
| | | } |
| | | }) |
| | | }, |
| | | handleClose() { |
| | | this.$emit("close"); |
| | | |
| | | this.form.approvalComment = ""; |
| | | }, |
| | | handleApprove() { |
| | | if (!this.form.approvalComment) { |
| | | if (!this.remark) { |
| | | this.$message.warning("请输入审批意见"); |
| | | return; |
| | | } |
| | | this.$emit("approve", { |
| | | ...this.form, |
| | | status: "approved", |
| | | const params = { |
| | | id: this.data.id, |
| | | auditRemark: this.remark, |
| | | auditStatus: this.status === '1' ? 2 : 3 |
| | | }; |
| | | detailAuditReport(params).then(res => { |
| | | if (res) { |
| | | this.$message.success('审核成功'); |
| | | this.$emit("close"); |
| | | } |
| | | }).catch(err => { |
| | | this.$message.error(err.message || '审核失败'); |
| | | }); |
| | | }, |
| | | handleReject() { |
| | |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | margin-top: 18px; |
| | | |
| | | img { |
| | | width: 12px; |
| | |
| | | } |
| | | |
| | | .approval-dialog-approve { |
| | | padding: 38px 20px; |
| | | padding: 18px 20px; |
| | | // display: flex; |
| | | align-content: center; |
| | | |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :title="dialogTitle" :visible.sync="visible" width="80%" :close-on-click-modal="false" |
| | | @close="handleClose"> |
| | | <div class="approval-dialog"> |
| | | <!-- 内容区域 --> |
| | | <div class="approval-content"> |
| | | <Card class="approval-content-card"> |
| | | <div class="header-title" style="width: 100%;"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>所属项目组</div> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :data="tableData" :queryForm="queryForm" :total="0"> |
| | | <template> |
| | | <el-table-column prop="teamName" label="项目组名称" /> |
| | | <el-table-column prop="personCharge" label="项目负责人" /> |
| | | <el-table-column prop="staffName" label="项目组成员"> |
| | | <template #default="{ row }"> |
| | | <span>{{row.staffs.map(item => item.nickName).join(',')}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <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-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item prop="itemName" label="检测项名称"> |
| | | <el-input v-model="form.itemName" style="width: 100%;" placeholder="请输入检测项名称" |
| | | :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item prop="itemCode" label="检测项编号" style="margin-left: 100px;"> |
| | | <el-input v-model="form.itemCode" style="width: 100%;" placeholder="请输入检测项编号" |
| | | :disabled="true" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <div class="notice">备注内容</div> |
| | | |
| | | <div prop="remark" style="margin-top: 18px"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="4" style="width: 100%;" |
| | | placeholder="请输入备注内容" :disabled="true" /> |
| | | </div> |
| | | |
| | | <div class="notice" style="margin: 18px 0;">报告列表</div> |
| | | |
| | | <div class="table-setting"> |
| | | <div class="flex a-center"> |
| | | <div class="table-title active"> |
| | | 项目检测项、检验包列表 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <Table :data="reportTableData" :total="reportTotal" row-key="id" :height="null"> |
| | | <el-table-column prop="reportContent" label="报告内容"> |
| | | <template #default="{ row }"> |
| | | <span>{{ getReportContentText(row.reportContent) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="developPerson" label="制订人" /> |
| | | <el-table-column prop="developDate" label="制订日期" /> |
| | | <el-table-column prop="auditPersonId" label="审批人" /> |
| | | <el-table-column prop="auditTime" label="审批时间" /> |
| | | <el-table-column prop="status" label="状态"> |
| | | <template #default="{ row }"> |
| | | <el-tag v-if="row.status == 1" type="info" color="#fff">待审核</el-tag> |
| | | <el-tag v-if="row.status == 2" type="success" color="#fff">已通过</el-tag> |
| | | <el-tag v-if="row.status == 3" type="danger">已驳回</el-tag> |
| | | <el-tag v-if="row.status == 4" type="danger">已撤销</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="操作"> |
| | | <template #default="{ row }"> |
| | | <el-button type="text" @click="openDetail(row)">详情</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </Table> |
| | | </el-form> |
| | | </Card> |
| | | </div> |
| | | </div> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="handleClose">关 闭</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | <ApprovalDetail :visible="showApprovalDetail" @close="showApprovalDetail = false" :data="rowData" type="view" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import ApprovalDetail from './approval/index.vue' |
| | | import { getDetail } from '../service' |
| | | |
| | | export default { |
| | | name: "ApprovalDialog", |
| | | components: { |
| | | ApprovalDetail |
| | | }, |
| | | props: { |
| | | visible: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | id: { |
| | | type: [String, Number], |
| | | default: '' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | form: { |
| | | id: "", |
| | | itemCode: "", |
| | | itemName: "", |
| | | remark: "", |
| | | teamId: "" |
| | | }, |
| | | rowId:'', |
| | | rowData:{}, |
| | | tableData: [], |
| | | reportTableData: [], |
| | | reportTotal: 0, |
| | | queryForm: {}, |
| | | showApprovalDetail:false, |
| | | rules: { |
| | | itemName: [ |
| | | { required: true, message: '请输入检测项名称', trigger: 'blur' } |
| | | ], |
| | | itemCode: [ |
| | | { required: true, message: '请输入检测项编号', trigger: 'blur' } |
| | | ] |
| | | } |
| | | }; |
| | | }, |
| | | computed: { |
| | | dialogTitle() { |
| | | return "项目检测项,检验包详情"; |
| | | }, |
| | | }, |
| | | watch: { |
| | | visible(val) { |
| | | if (val && this.id) { |
| | | this.getDetail() |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | getDetail() { |
| | | getDetail(this.id).then(res => { |
| | | if (res) { |
| | | this.form = res |
| | | if (res.projectTeamVO) { |
| | | this.tableData = [{ |
| | | ...res.projectTeamVO, |
| | | }] |
| | | } |
| | | if (res.qaTestItemReportList && res.qaTestItemReportList.length > 0) { |
| | | this.reportTableData = res.qaTestItemReportList |
| | | } |
| | | } else { |
| | | this.$message.error(res.msg || '获取详情失败') |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取详情失败:', err) |
| | | this.$message.error('获取详情失败') |
| | | }) |
| | | }, |
| | | handleClose() { |
| | | this.$emit("close"); |
| | | this.form = { |
| | | id: "", |
| | | itemCode: "", |
| | | itemName: "", |
| | | remark: "", |
| | | teamId: "" |
| | | }; |
| | | this.tableData = []; |
| | | this.reportTableData = []; |
| | | }, |
| | | getReportContentText(value) { |
| | | const contentMap = { |
| | | '1': '国家标准', |
| | | '2': '分析方法开发', |
| | | '3': '方法验证报告', |
| | | '4': '方法确认', |
| | | '5': '操作规程', |
| | | '6': '方法转移记录清单' |
| | | }; |
| | | return contentMap[value] || value; |
| | | }, |
| | | openDetail(row) { |
| | | // this.rowId = row.id; |
| | | this.rowData={ |
| | | id:row.id, |
| | | itemId:this.form.id |
| | | } |
| | | this.showApprovalDetail = true; |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .notice { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | |
| | | .table-setting { |
| | | display: flex; |
| | | padding-bottom: 20px; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .flex { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .table-title { |
| | | width: 220px; |
| | | height: 50px; |
| | | background: #fafafc; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #dcdfe6; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | line-height: 27px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &.active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border: 1px solid #049c9a; |
| | | } |
| | | } |
| | | |
| | | .table-tit { |
| | | width: 166px; |
| | | height: 50px; |
| | | background: #fafafc; |
| | | border-radius: 8px 8px 0px 0px; |
| | | border: 1px solid #dcdfe6; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #606266; |
| | | line-height: 27px; |
| | | margin-left: 16px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &.active { |
| | | color: #049c9a; |
| | | background: #ffffff; |
| | | border: 1px solid #049c9a; |
| | | } |
| | | } |
| | | |
| | | ::v-deep .el-dialog__header { |
| | | border-bottom: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | .approval-dialog { |
| | | display: flex; |
| | | height: 40vh; |
| | | |
| | | .approval-content { |
| | | flex: 3; |
| | | margin-right: 20px; |
| | | background: #ffffff; |
| | | box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); |
| | | border-radius: 10px; |
| | | } |
| | | |
| | | .approval-flow { |
| | | padding: 40px 20px; |
| | | // width: 405px; |
| | | flex: 2; |
| | | background: #ffffff; |
| | | box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); |
| | | border-radius: 10px; |
| | | |
| | | .flow-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | margin-bottom: 20px; |
| | | color: #303133; |
| | | } |
| | | |
| | | .flow-content { |
| | | height: calc(100% - 40px); |
| | | overflow-y: auto; |
| | | |
| | | .el-form--inline .el-form-item { |
| | | margin-right: 83px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .approval-content-card { |
| | | height: calc(100% - 100px) !important; |
| | | box-shadow: none !important; |
| | | } |
| | | |
| | | .header-title { |
| | | // display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 20px; |
| | | gap: 13px; |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | |
| | | img { |
| | | width: 12px; |
| | | height: 19px; |
| | | } |
| | | |
| | | div { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | |
| | | span { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | } |
| | | |
| | | .header-title-left :first-child { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .header-title:first-child { |
| | | .header-title-left { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | |
| | | .item-title { |
| | | padding-left: 25px; |
| | | |
| | | span { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | margin: 18px 0; |
| | | |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .approval-dialog-approve { |
| | | padding: 38px 20px; |
| | | // display: flex; |
| | | align-content: center; |
| | | |
| | | .status { |
| | | margin-right: 40px; |
| | | max-width: 60%; |
| | | } |
| | | |
| | | // align-items: center; |
| | | .status-title { |
| | | color: #222222; |
| | | font-family: "SourceHanSansCN-Medium"; |
| | | line-height: 14px; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .status-content { |
| | | display: flex; |
| | | align-items: center; |
| | | width: 100%; |
| | | gap: 16px; |
| | | background: #ffffff; |
| | | border-radius: 10px; |
| | | border: 1px solid rgba(4, 156, 154, 0.5); |
| | | |
| | | .resolve { |
| | | border-radius: 10px; |
| | | flex: 1; |
| | | font-size: 16px; |
| | | // padding: 5px 55px; |
| | | font-weight: 400; |
| | | color: #333333; |
| | | cursor: pointer; |
| | | line-height: 32px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center |
| | | } |
| | | |
| | | .reject { |
| | | flex: 1; |
| | | border-radius: 10px; |
| | | font-size: 16px; |
| | | line-height: 32px; |
| | | // padding: 5px 55px; |
| | | font-weight: 400; |
| | | color: #333333; |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center |
| | | } |
| | | |
| | | .activeStatus { |
| | | background: #ebfefd; |
| | | color: #049c9a; |
| | | box-shadow: 0px 0px 6px 0px rgba(10, 109, 108, 0.25); |
| | | border-radius: 10px; |
| | | } |
| | | } |
| | | |
| | | .remark-title { |
| | | color: #222222; |
| | | font-family: "SourceHanSansCN-Medium"; |
| | | line-height: 14px; |
| | | margin-bottom: 16px; |
| | | } |
| | | } |
| | | |
| | | .dialog-footer { |
| | | align-items: center; |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 20px; |
| | | |
| | | button { |
| | | width: 150px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="list"> |
| | | <TableCustom :queryForm="queryForm" :tableData="dataList" :total="total" @currentChange="handleCurrentChange" |
| | | <TableCustom :queryForm="queryForm" :height="0" :total="total" @currentChange="handleCurrentChange" |
| | | @sizeChange="handleSizeChange"> |
| | | <template #search> |
| | | <el-form :model="form" label-width="auto" inline> |
| | | <el-form ref="searchForm" :model="form" :rules="rules" 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.itemName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="检测项编号:"> |
| | | <el-input v-model="form.name" placeholder="请输入"></el-input> |
| | | <el-input v-model="form.itemCode" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="报告内容:"> |
| | | <el-input v-model="form.name" placeholder="请输入"></el-input> |
| | | <el-select v-model="form.reportContent" placeholder="请选择"> |
| | | <el-option label="国家标准" value="1"></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-option label="方法转移记录清单" value="6"></el-option> |
| | | </el-select> |
| | | </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="0"></el-option> |
| | | <el-option label="已驳回" value="2"></el-option> |
| | | <el-option label="全部" value=""></el-option> |
| | | <el-option label="草稿箱" value="-1"></el-option> |
| | | <el-option label="已提交" value="1"></el-option> |
| | | <el-option label="待评定" value="2"></el-option> |
| | | <el-option label="已评定" value="3"></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" style="margin-right: 10px;" @click="handleReset">重置</el-button> |
| | | <el-button type="primary" @click="handleSearch">查询</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 #tableCustom> |
| | | <Table :data="tableData" :total="0" @row-click="handleRowClick" row-key="id" |
| | | <Table :data="tableData" :total="total" @row-click="handleRowClick" row-key="id" :height="null" |
| | | :expand-row-keys="expandRowKeys"> |
| | | <el-table-column type="expand" width="1"> |
| | | <template #default="{ row }"> |
| | | <div class="expand-box"> |
| | | <div style="display: flex;align-items: center;"><div class="expand-box-title">报告列表 </div> <el-button style="margin-left: 10px;" @click="handleAdd" class="el-icon-plus" type="primary"> |
| | | 新增报告 </el-button> </div> |
| | | <div v-if="isChemist && currentType !== 'draft'" class="expand-box"> |
| | | <div style="display: flex;align-items: center;"> |
| | | <div class="expand-box-title">报告列表</div> |
| | | <el-button style="margin-left: 10px;" @click="handleAdd(row)" class="el-icon-plus" |
| | | type="primary"> |
| | | 新增报告 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <Table :total="0" :height="null"> |
| | | <el-table-column prop="name" label="报告内容" /> |
| | | <el-table-column prop="name" label="制订人" /> |
| | | <el-table-column prop="name" label="制订日期" /> |
| | | <el-table-column prop="name" label="审批人" /> |
| | | <el-table-column prop="name" label="审批时间" /> |
| | | <el-table-column prop="age" label="状态"> |
| | | <Table :data="reportList[row.id] || []" :total="0" :height="null"> |
| | | <el-table-column prop="reportContent" label="报告内容"> |
| | | <template #default="{ row }"> |
| | | <el-tag v-if="row.status == 0" type="info" color="#fff">待审核</el-tag> |
| | | <el-tag v-if="row.status == 1" type="success" color="#fff">已通过</el-tag> |
| | | <el-tag v-else type="danger">未通过</el-tag> |
| | | <span>{{ getReportContentText(row.reportContent) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="developPerson" label="制订人" /> |
| | | <el-table-column prop="developDate" label="制订日期" /> |
| | | <el-table-column prop="auditPersonId" label="审批人" /> |
| | | <el-table-column prop="auditTime" label="审批时间" /> |
| | | <el-table-column prop="status" label="状态"> |
| | | <template #default="{ row }"> |
| | | <el-tag v-if="row.status == 1" type="info" color="#fff">待审核</el-tag> |
| | | <el-tag v-if="row.status == 2" type="success" color="#fff">已通过</el-tag> |
| | | <el-tag v-if="row.status == 3" type="danger">已驳回</el-tag> |
| | | <el-tag v-if="row.status == 4" type="danger">已撤销</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="age" label="操作"> |
| | | <template #default="{ row }"> |
| | | <el-button type="text">详情</el-button> |
| | | <template v-if="row.status === 2"> |
| | | <el-button type="text" @click="handleReportDetail(row)">详情</el-button> |
| | | </template> |
| | | <template v-else-if="row.status === 1"> |
| | | <el-button type="text" |
| | | @click="handleRevokeApproval(row)">撤销审批</el-button> |
| | | </template> |
| | | <template v-else-if="row.status === 3"> |
| | | <el-button type="text" @click="handleReportDetail(row)">详情</el-button> |
| | | <el-button type="text" @click="handleWithdraw(row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDelete(row)">删除</el-button> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </Table> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <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="age" label="审批时间" /> |
| | | <el-table-column prop="teamName" label="所属项目组" /> |
| | | <el-table-column prop="itemName" label="检测项名称" /> |
| | | <el-table-column prop="itemCode" label="检测项编号" /> |
| | | <el-table-column prop="remark" label="备注" v-if="isChemist" /> |
| | | <el-table-column prop="reportContent" label="报告内容" v-else> |
| | | <template #default="{ row }"> |
| | | <span>{{ getReportContentText(row.reportContent) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="createBy" label="创建人" /> |
| | | <el-table-column prop="createTime" label="创建时间" /> |
| | | <el-table-column prop="auditTime" label="审批时间" v-if="!isChemist" /> |
| | | <el-table-column prop="age" label="状态"> |
| | | <template #default="{ row }"> |
| | | <el-tag v-if="row.status == 1" type="info" color="#fff">已评定</el-tag> |
| | | <el-tag v-else type="success">待评定</el-tag> |
| | | <!-- 化验师的状态显示 --> |
| | | <template v-if="isChemist"> |
| | | <el-tag v-if="row.status == -1" type="info" color="#fff">草稿箱</el-tag> |
| | | <el-tag v-else-if="row.status == 1" type="warning">已提交</el-tag> |
| | | <el-tag v-else-if="row.status == 2" type="primary">待评定</el-tag> |
| | | <el-tag v-else-if="row.status == 3" type="success">已评定</el-tag> |
| | | </template> |
| | | <!-- 其他角色的状态显示 --> |
| | | <template v-else> |
| | | <el-tag v-if="row.status == -1" type="info" color="#fff">草稿箱</el-tag> |
| | | <el-tag v-else-if="row.status == 1" type="warning">待审核</el-tag> |
| | | <el-tag v-else-if="row.status == 2" type="success">已通过</el-tag> |
| | | <el-tag v-else-if="row.status == 3" type="danger">已驳回</el-tag> |
| | | <el-tag v-else-if="row.status == 4" type="danger">已撤销</el-tag> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="age" label="操作"> |
| | | <template #default="{ row }"> |
| | | <el-button type="text" @click="showApproval = true">详情</el-button> |
| | | <!-- 化验师的操作按钮 --> |
| | | <template v-if="isChemist"> |
| | | <el-button v-if="currentType == 'draft'" type="text" |
| | | @click="handleEdit(row)">编辑</el-button> |
| | | <el-button v-if="currentType == 'draft'" type="text" |
| | | @click="handleDelete(row)">删除</el-button> |
| | | <el-button v-if="currentType == 'list' && row.status == 1" type="text" |
| | | @click="handleSubmit(row)">提交评定</el-button> |
| | | <el-button v-if="currentType == 'list'" 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> |
| | | </Table> |
| | | </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" /> |
| | | <!-- 统一的确认框组件 --> |
| | | <ShowDelConfirm :show="showDelConfirm" :title="confirmTitle" :tip="confirmTip" @close="closeConfirm" |
| | | @confirm="handleConfirm" /> |
| | | <!-- 提交评定确认框:用于提交检测项评定时的确认 --> |
| | | <ShowDelConfirm :title="submitTitle" :tip="submitTip" :show="showSubmitConfirm" |
| | | @close="showSubmitConfirm = false" @confirm="handleSubmitConfirm" /> |
| | | <Approval :visible="showApproval" @close="closeApproval" :data="rowData" :type="approvalType" /> |
| | | <ItemApproval :visible="showItemApproval" @close="showItemApproval = false" :id="rowId" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import Approval from './components/approval' |
| | | import ItemApproval from './components/itemApproval' |
| | | import { getDataList, detailPageList, getListByItemId, commitEvaluate, revokedReport, deleteDetail, deleteData } from './service' |
| | | |
| | | export default { |
| | | name: 'ProjectList', |
| | | components: { |
| | | Approval |
| | | Approval, |
| | | ItemApproval |
| | | }, |
| | | data() { |
| | | return { |
| | | currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱 |
| | | form: { |
| | | name: '', |
| | | status: '', |
| | | itemCode: '', // 检测项编号 |
| | | itemName: '', // 检测项名称 |
| | | reportContent: '', // 报告内容 |
| | | status: '', // 状态,默认为空字符串表示全部 |
| | | teamName: '', // 项目组名称 |
| | | pageNum: 1, |
| | | pageSize: 10 |
| | | }, |
| | | rules: { |
| | | itemCode: [ |
| | | { max: 50, message: '检测项编号不能超过50个字符', trigger: 'blur' } |
| | | ], |
| | | itemName: [ |
| | | { max: 100, message: '检测项名称不能超过100个字符', trigger: 'blur' } |
| | | ], |
| | | teamName: [ |
| | | { max: 100, message: '项目组名称不能超过100个字符', trigger: 'blur' } |
| | | ] |
| | | }, |
| | | showSubmitConfirm: false, |
| | | showDelConfirm: false, |
| | | confirmTitle: '', // 确认框标题 |
| | | confirmTip: '', // 确认框提示 |
| | | confirmType: '', // 确认框类型:'deleteReport'-删除报告, 'deleteItem'-删除检测项, 'revoke'-撤销审批 |
| | | rowId: '', |
| | | changeStatus: false, |
| | | showApproval: false, |
| | | changeStatusTitle: '', |
| | | changeStatusTip: '', |
| | | approvalType: '', // 新增:审批类型 |
| | | submitTitle: '', // 新增:提交评定确认框标题 |
| | | submitTip: '', // 新增:提交评定确认框提示 |
| | | queryForm: { |
| | | pageSize: 10, |
| | | pageNum: 1 |
| | | }, |
| | | tableData: [ |
| | | { |
| | | name: '项目组1', |
| | | age1: '检测项名称1', |
| | | age2: '检测项编号1', |
| | | age3: '报告内容1', |
| | | age4: '创建人1', |
| | | age5: '创建时间1', |
| | | age6: '审批时间1', |
| | | age7: '状态1' |
| | | } |
| | | ], |
| | | tableData: [], |
| | | expandRowKeys: [], |
| | | total: 0 |
| | | total: 0, |
| | | rowData: {}, |
| | | reportList: {}, // 修改为对象,用行ID作为key |
| | | currentRow: null, |
| | | currentAction: '', |
| | | showItemApproval: false, |
| | | loading: false |
| | | } |
| | | }, |
| | | computed: { |
| | | isChemist() { |
| | | const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}'); |
| | | return userInfo.roleType == 4; // 2是化验师 |
| | | }, |
| | | isProcessEngineer() { |
| | | const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}'); |
| | | return userInfo.roleType == 3; // 3是工艺工程师 |
| | | } |
| | | }, |
| | | methods: { |
| | | handleAddProject() { |
| | | this.$router.push('/chemistQa/add') |
| | | }, |
| | | handleAdd() { |
| | | this.$router.push('/chemistQa/addDetectionReport') |
| | | handleAdd(row) { |
| | | this.$router.push({ |
| | | path: '/chemistQa/addDetectionReport', |
| | | query: { |
| | | itemId: row.id, |
| | | type: 'add' |
| | | } |
| | | }) |
| | | }, |
| | | handleRowClick(row, column, event) { |
| | | if (column.label === '操作') return |
| | | closeApproval() { |
| | | this.showApproval = false; |
| | | this.rowData = {}; |
| | | this.approvalType = ''; |
| | | this.getList(); |
| | | }, |
| | | async handleRowClick(row, column, event) { |
| | | if (column.label == '操作') return |
| | | if (this.isChemist && this.currentType !== 'draft') { |
| | | try { |
| | | // 切换展开状态 |
| | | if (this.expandRowKeys.includes(row.id)) { |
| | | this.expandRowKeys = this.expandRowKeys.filter(key => key !== row.id); |
| | | // 删除该行的报告数据 |
| | | delete this.reportList[row.id]; |
| | | } else { |
| | | this.expandRowKeys.push(row.id); |
| | | // 获取报告列表 |
| | | const res = await getListByItemId({ id: row.id }); |
| | | if (res) { |
| | | // 使用行ID作为key存储报告数据 |
| | | this.$set(this.reportList, row.id, res || []); |
| | | } else { |
| | | this.msgError(res.msg || '获取报告列表失败'); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('获取报告列表失败:', error); |
| | | this.msgError('获取报告列表失败'); |
| | | } |
| | | } |
| | | }, |
| | | handleDel(row) { |
| | | handleEdit(row) { |
| | | // 编辑操作 |
| | | this.$router.push({ |
| | | path: '/chemistQa/add', |
| | | query: { |
| | | id: row.id, |
| | | type: 'edit' |
| | | } |
| | | }) |
| | | }, |
| | | handleDelete(row) { |
| | | this.currentRow = row; |
| | | this.currentAction = 'delete'; |
| | | this.confirmType = row.reportContent ? 'deleteReport' : 'deleteItem'; |
| | | this.confirmTitle = '确认要删除这条记录吗?'; |
| | | this.confirmTip = '删除后记录将无法找回'; |
| | | this.showDelConfirm = true; |
| | | }, |
| | | handleSubmit(row) { |
| | | // 提交评定操作 |
| | | this.submitTitle = '确认要提交评定吗?' |
| | | this.submitTip = '提交后将进入评定流程' |
| | | this.showSubmitConfirm = true |
| | | this.rowId = row.id |
| | | this.showDelConfirm = true |
| | | }, |
| | | handleDelConfirm() { |
| | | this.showDelConfirm = false |
| | | this.msgsuccess('删除成功') |
| | | this.rowId = '' |
| | | this.getList() |
| | | handleDetail(row) { |
| | | if (this.isChemist) { |
| | | // 化验师角色使用原有逻辑 |
| | | this.$router.push({ |
| | | path: '/chemistQa/add', |
| | | query: { |
| | | id: row.id, |
| | | type: 'detail' |
| | | } |
| | | }) |
| | | } else { |
| | | // 非化验师角色使用ItemApproval组件 |
| | | this.showItemApproval = true |
| | | this.rowId = row.itemId |
| | | this.rowData = row |
| | | } |
| | | }, |
| | | handleChangeStatus(row, status) { |
| | | handleApprove(row) { |
| | | this.showApproval = true |
| | | this.rowId = row.id |
| | | this.changeStatusTitle = status == 1 ? '确认要封存这个项目组吗?' : '确认要解封该项目组吗?' |
| | | this.changeStatusTip = status == 1 ? '封存后项目组内人员看不到数据,审批人仍然可见数据。' : '解封后项目组内人员数据恢复。' |
| | | this.changeStatus = true |
| | | this.rowData = row |
| | | this.approvalType = 'approve' |
| | | }, |
| | | handleChangeStatusConfirm() { |
| | | this.changeStatus = false |
| | | this.msgsuccess('操作成功') |
| | | this.rowId = '' |
| | | this.changeStatusTitle = '' |
| | | this.changeStatusTip = '' |
| | | this.getList() |
| | | closeConfirm() { |
| | | this.showDelConfirm = false; |
| | | this.currentRow = null; |
| | | this.currentAction = ''; |
| | | this.confirmType = ''; |
| | | this.confirmTitle = ''; |
| | | this.confirmTip = ''; |
| | | }, |
| | | async handleConfirm() { |
| | | if (!this.currentRow) return; |
| | | try { |
| | | this.loading = true; |
| | | if (this.currentAction === 'delete') { |
| | | if (this.confirmType === 'deleteReport') { |
| | | const res = await deleteDetail({ id: this.currentRow.id }); |
| | | if (res.code === 200) { |
| | | this.$message.success('删除成功'); |
| | | this.closeConfirm(); |
| | | await this.getList(); |
| | | } else { |
| | | this.$message.error(res.msg || '删除失败'); |
| | | } |
| | | } else if (this.confirmType === 'deleteItem') { |
| | | const res = await deleteData({ id: this.currentRow.id }); |
| | | if (res.code === 200) { |
| | | this.$message.success('删除成功'); |
| | | this.closeConfirm(); |
| | | await this.getList(); |
| | | } else { |
| | | this.$message.error(res.msg || '删除失败'); |
| | | } |
| | | } |
| | | } else if (this.currentAction === 'revoke') { |
| | | const res = await revokedReport({ id: this.currentRow.id }); |
| | | if (res.code === 200) { |
| | | this.$message.success('撤销审批成功'); |
| | | this.closeConfirm(); |
| | | await this.getList(); |
| | | } else { |
| | | this.$message.error(res.msg || '撤销审批失败'); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('操作失败:', error); |
| | | this.$message.error('操作失败,请重试'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | handleCurrentChange(page) { |
| | | this.queryForm.pageNum = page |
| | |
| | | this.queryForm.pageSize = size |
| | | this.getList() |
| | | }, |
| | | getList() { |
| | | |
| | | async getList() { |
| | | if (this.loading) return; |
| | | try { |
| | | this.loading = true; |
| | | const params = { |
| | | ...this.form, |
| | | pageNum: this.queryForm.pageNum, |
| | | pageSize: this.queryForm.pageSize |
| | | }; |
| | | let res; |
| | | if (this.isChemist) { |
| | | res = await getDataList(params); |
| | | } else { |
| | | res = await detailPageList(params); |
| | | } |
| | | if (res.code === 200) { |
| | | this.tableData = res.data.records || []; |
| | | this.total = res.data.total || 0; |
| | | } else { |
| | | this.$message.error(res.msg || '获取列表失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('获取列表失败:', error); |
| | | this.$message.error('获取列表失败,请重试'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | handleTypeChange(type) { |
| | | this.currentType = type; |
| | | this.form.status = type === 'draft' ? -1 : ''; |
| | | this.form.status = type == 'draft' ? -1 : ''; |
| | | this.getList(); |
| | | }, |
| | | handleReportDetail(row) { |
| | | this.rowData = row; |
| | | this.showApproval = true; |
| | | this.approvalType = 'detail'; |
| | | }, |
| | | getReportContentText(value) { |
| | | const contentMap = { |
| | | '1': '国家标准', |
| | | '2': '分析方法开发', |
| | | '3': '方法验证报告', |
| | | '4': '方法确认', |
| | | '5': '操作规程', |
| | | '6': '方法转移记录清单' |
| | | }; |
| | | return contentMap[value] || value; |
| | | }, |
| | | handleRevokeApproval(row) { |
| | | this.currentRow = row; |
| | | this.currentAction = 'revoke'; |
| | | this.confirmType = 'revoke'; |
| | | this.confirmTitle = '确认要撤销这条审批吗?'; |
| | | this.confirmTip = '撤销后工艺工程师将无法收到此条审批信息'; |
| | | this.showDelConfirm = true; |
| | | }, |
| | | handleWithdraw(row) { |
| | | // 从父级检测项获取itemId |
| | | const parentItemId = Object.keys(this.reportList).find(key => |
| | | this.reportList[key].some(report => report.id === row.id) |
| | | ); |
| | | |
| | | this.$router.push({ |
| | | path: '/chemistQa/addDetectionReport', |
| | | query: { |
| | | id: row.id, |
| | | itemId: parentItemId, |
| | | type: 'edit' |
| | | } |
| | | }) |
| | | }, |
| | | async handleSubmitConfirm() { |
| | | if (!this.rowId) return; |
| | | try { |
| | | this.loading = true; |
| | | const res = await commitEvaluate({ id: this.rowId }); |
| | | if (res.code === 200) { |
| | | this.$message.success('提交评定成功'); |
| | | this.showSubmitConfirm = false; |
| | | this.rowId = ''; |
| | | await this.getList(); |
| | | } else { |
| | | this.$message.error(res.msg || '提交评定失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('提交评定失败:', error); |
| | | this.$message.error('提交评定失败,请重试'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | async handleSearch() { |
| | | try { |
| | | this.loading = true; |
| | | await this.$refs.searchForm.validate(); |
| | | this.queryForm.pageNum = 1; |
| | | await this.getList(); |
| | | } catch (error) { |
| | | if (error === false) { |
| | | this.$message.warning('请检查表单填写是否正确'); |
| | | } else { |
| | | this.$message.error('查询失败,请重试'); |
| | | } |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | async handleReset() { |
| | | try { |
| | | this.loading = true; |
| | | this.$refs.searchForm.resetFields(); |
| | | this.form = { |
| | | itemCode: '', |
| | | itemName: '', |
| | | reportContent: '', |
| | | status: '', |
| | | teamName: '', |
| | | pageNum: 1, |
| | | pageSize: 10 |
| | | }; |
| | | this.queryForm.pageNum = 1; |
| | | await this.getList(); |
| | | } catch (error) { |
| | | this.$message.error('重置失败,请重试'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getList() |
| | | } |
| | | } |
| | | </script> |
| | |
| | | .el-icon-plus{ |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .header-content { |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 400; |
New file |
| | |
| | | import axios from '@/utils/request'; |
| | | |
| | | // 查询列表 |
| | | export function getDataList(data) { |
| | | return axios.post('/api/t-qa-test-item/pageList', { ...data }) |
| | | } |
| | | |
| | | // 添加 |
| | | export function addData(data) { |
| | | return axios.post('/api/t-qa-test-item/add', { ...data }) |
| | | } |
| | | |
| | | //修改 |
| | | export function editData(data) { |
| | | return axios.post('/api/t-qa-test-item/update', { ...data }) |
| | | } |
| | | |
| | | //获取详情 |
| | | export function getDetail(id) { |
| | | return axios.get(`/open/t-qa-test-item/getDetailById?id=${id}`) |
| | | } |
| | | |
| | | //修改QA检测项管理状态 |
| | | export function commitEvaluate(data) { |
| | | console.log(data) |
| | | return axios.put(`/open/t-qa-test-item/commitEvaluate?id=${data.id}`) |
| | | } |
| | | |
| | | //评定QA检测项管理 |
| | | export function evaluate(data) { |
| | | return axios.put(`/api/t-qa-test-item/evaluate`, { ...data }) |
| | | } |
| | | |
| | | //删除QA检测项管理 |
| | | export function deleteData(data) { |
| | | return axios.delete(`/open/t-qa-test-item/deleteById?id=${data.id}`) |
| | | } |
| | | |
| | | // 下面的是二级的接口 |
| | | |
| | | export function detailPageList(data) { |
| | | return axios.post(`/api/t-qa-test-item-report/pageList`,{...data}) |
| | | } |
| | | export function detailAuditReport(data) { |
| | | return axios.post(`/api/t-qa-test-item-report/auditReport`,{...data}) |
| | | } |
| | | export function addDetail(data) { |
| | | return axios.post(`/api/t-qa-test-item-report/add`,{...data}) |
| | | } |
| | | export function updateDetail(data) { |
| | | return axios.post(`/api/t-qa-test-item-report/update`,{...data}) |
| | | } |
| | | |
| | | export function deleteDetail(data) { |
| | | return axios.delete(`/open/t-qa-test-item-report/deleteById?id=${data.id}`) |
| | | } |
| | | export function getDetailInfo(data) { |
| | | return axios.get(`/open/t-qa-test-item-report/getDetailById?id=${data.id}`) |
| | | } |
| | | // 获取QA检测项报告管理下拉列表-化验师使用、评定使用 |
| | | export function getListByItemId(data) { |
| | | return axios.get(`/open/t-qa-test-item-report/getListByItemId?itemId=${data.id}`) |
| | | } |
| | | // 撤销QA检测项报告管理状态 |
| | | export function revokedReport(data) { |
| | | return axios.get(`/open/t-qa-test-item-report/revokedReport?id=${data.id}`) |
| | | } |
| | |
| | | }, |
| | | |
| | | mounted() { |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).userId; |
| | | this.form.developPerson = JSON.parse(sessionStorage.getItem('userInfo')).nickName; |
| | | 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]; |
| | |
| | | getDetail() { |
| | | getDetail(this.$route.query.id).then(res => { |
| | | this.form = res |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }] |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.fileList || [] |
| | | }) |
| | | }, |
| | |
| | | <div>所属项目组</div> |
| | | </div> |
| | | </div> |
| | | <Table :height="null" :total="0"> |
| | | <Table :height="null" :total="0" :data="tableData"> |
| | | <template> |
| | | <el-table-column prop="teamName" label="项目组名称" /> |
| | | <el-table-column prop="personCharge" label="项目负责人" /> |
| | |
| | | }); |
| | | } |
| | | |
| | | this.tableData = [{ ...res.projectTeam, staffName: res.staffNames }]; |
| | | this.tableData = [{ ...res.projectTeamVO,staffName:res.projectTeamVO.staffs.map(item=>item.nickName).join(',')}] |
| | | this.fileList = res.qaReportFileList.map(item => { |
| | | return { |
| | | ...item, |
| | |
| | | }, |
| | | handleEdit(row) { |
| | | this.$router.push({ |
| | | path: '/chemistQa/editRawMaterials', |
| | | path: '/chemistQa/addRawMaterials', |
| | | query: { id: row.id } |
| | | }); |
| | | }, |
| | |
| | | ...this.form, |
| | | pageNum: this.queryForm.pageNum, |
| | | pageSize: this.queryForm.pageSize, |
| | | // reportType: 2 // 原辅料、包材、竞品检验分析报告 |
| | | reportType: 2 // 原辅料、包材、竞品检验分析报告 |
| | | }; |
| | | getDataList(params).then(res => { |
| | | if (res.code == 200) { |