<template>
|
<div>
|
<Card>
|
<div class="header-title" style="width: 100%;">
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>所属项目组</div>
|
</div>
|
<div class="header-title-right">
|
<el-button @click="showChoose = true" class="el-icon-circle-plus-outline" type="primary">
|
选择项目组</el-button>
|
</div>
|
|
</div>
|
<Table :height="null" :queryForm="queryForm" :total="0" :data="projectData">
|
<template>
|
<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">
|
<div class="header-title" style="width: 100%;">
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>报告编号</div>
|
</div>
|
</div>
|
<el-form-item prop="reportCode" style="margin-top: 38px">
|
<el-input v-model="form.reportCode" 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>
|
</div>
|
<el-form-item prop="reportName" style="margin-top: 38px">
|
<el-input v-model="form.reportName" 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>
|
</div>
|
<el-form-item prop="reportText" style="margin-top: 38px">
|
<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>
|
</div>
|
<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>
|
</el-upload>
|
</el-form-item>
|
<div class="header-title" style="width: 100%;">
|
<div class="header-title-left">
|
<img src="@/assets/public/headercard.png" />
|
<div>菌种实验员操作评定</div>
|
</div>
|
</div>
|
|
<div class="header-title" style="width: 100%;display: flex; align-items: center;">
|
<div class="header-title-left mt-unset">
|
<!-- <img src="@/assets/public/headercard.png" /> -->
|
<div>菌种实验员</div>
|
</div>
|
<div class="header-title-right">
|
<el-button @click="getMember" class="el-icon-circle-plus-outline" type="primary">
|
选择菌种实验员</el-button>
|
</div>
|
</div>
|
<div class="member-list">
|
<div v-if="selectedMember" class="member-list-card" v-for="(item, index) in selectedMember"
|
:key="index">
|
<div class="member-item">
|
<div class="member-title">
|
菌种实验员
|
</div>
|
<div class="member-name-box">
|
<div class="member-name">
|
{{ item.nickName }}
|
</div>
|
</div>
|
<div class="member-change">
|
<div class="member-change-btn" @click="handleModifyMember(item)">修改</div>
|
</div>
|
</div>
|
</div>
|
<div v-else class="member-list-card empty-state">
|
<div class="member-item">
|
<div class="member-title">
|
菌种实验员
|
</div>
|
<div class="member-name-box">
|
<div class="empty-text">请选择菌种实验员</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<div class="table" style="margin-top: 38px">
|
<el-table :data="assessmentTable" border style="width: 100%" :show-summary="true"
|
:span-method="tableSpanMethod" :summary-method="getTableSummary">
|
<el-table-column prop="category" label="菌种实验员专业能力考核项" width="180"></el-table-column>
|
<el-table-column prop="score" label="该项评分" width="120">
|
<template slot-scope="scope">
|
<el-radio-group v-if="scope.row.category !== '5.实验失败'"
|
v-model="scope.row.selectedScore">
|
<el-radio :label="0">0分</el-radio>
|
<el-radio :label="1">1分</el-radio>
|
<el-radio :label="2">2分</el-radio>
|
</el-radio-group>
|
<el-radio-group v-else v-model="scope.row.selectedScore">
|
<el-radio :label="0">否0分</el-radio>
|
<el-radio :label="-3">是-3分</el-radio>
|
</el-radio-group>
|
</template>
|
</el-table-column>
|
<el-table-column prop="criteria" label="该项评分参考标准"></el-table-column>
|
<el-table-column prop="desc" label="评分规则说明">
|
<template slot-scope="scope">
|
<p> 【0分】 实验操作失误或实验方案设计无效导致实验失败、数据不可用。</p>
|
<p> 【1分】存在操作有误及实验过程出现问题,没有严格按照操作规程运行;如实验准备不充分,取样遗漏等。</p>
|
<p> 【2分】完整按照操作规程及实验室管理制度运行,无任何问题。</p>
|
</template>
|
</el-table-column>
|
<el-table-column prop="rule" label="考评规则">
|
<template slot-scope="scope">
|
菌种工程师以分题内容考核菌种实验员。
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
<div class="end-btn" style="margin-top: 38px">
|
<el-button type="primary" @click="addData">发送</el-button>
|
<el-button type="default" @click="saveData">存草稿</el-button>
|
</div>
|
</el-form>
|
</Card>
|
<chooseProject @submit="getProjectData" :show="showChoose" @close="showChoose = false"></chooseProject>
|
<SelectMember ref="selectMember" @submit="selectUser" :singleSelect="true" />
|
|
</div>
|
|
</template>
|
<script>
|
import { Card } from 'element-ui';
|
import AiEditor from '@/components/AiEditor'
|
import ChooseProject from '@/components/chooseProject/index.vue'
|
import SelectMember from '@/components/SelectMember'
|
import { add } from './service'
|
|
export default {
|
components: { AiEditor, ChooseProject, SelectMember },
|
data() {
|
return {
|
form: {
|
planName: "",
|
planCode: "",
|
stage: "",
|
creator: "",
|
createTime: "",
|
approvalComment: "",
|
status: "pending",
|
approver: "",
|
approveTime: ""
|
},
|
projectData: [], // 存储选中的项目组数据
|
fileList: [], // 附件列表
|
showChoose: false,
|
radio1: 1,
|
rules: {
|
reportCode: [
|
{ required: true, message: '请输入报告编号', trigger: 'blur' }
|
],
|
reportName: [
|
{ required: true, message: '请输入报告名称', trigger: 'blur' }
|
]
|
},
|
status: "1",
|
remark: "",
|
queryForm: {
|
|
},
|
assessmentTable: [
|
{
|
category: '1.该分题的菌种专业知识',
|
selectedScore: 0,
|
criteria: '1.1 能讲生物学基础,掌握各类微生物形态特性、生化特性及鉴定方法。1.2 菌种选育技术,了解掌握自然选育、诱变选育、基因工程育种。',
|
desc: '',
|
rule: ''
|
},
|
{
|
category: '2.操作能力',
|
selectedScore: 0,
|
criteria: '1.菌种分离无菌操作规范 2.菌种培养无菌操作规范 3.菌种保存无菌操作规范 4.菌种鉴定无菌操作规范',
|
desc: '',
|
rule: ''
|
},
|
{
|
category: '3.仪器设备使用',
|
selectedScore: 0,
|
criteria: '能正确使用实验仪器,如移液器、恒温箱等,操作规范。',
|
desc: '',
|
rule: ''
|
},
|
{
|
category: '4.实验数据记录与分析',
|
selectedScore: 0,
|
criteria: '实验数据记录及时、准确、完整,能简单分析数据。',
|
desc: '',
|
rule: ''
|
},
|
{
|
category: '5.实验失败',
|
selectedScore: 0,
|
criteria: '无论何种原因,本次实验失败。',
|
desc: '',
|
rule: ''
|
}
|
],
|
selectedMember: null, // 存储选中的菌种实验员
|
}
|
},
|
computed: {
|
totalScore() {
|
return this.assessmentTable.reduce((sum, row) => sum + Number(row.selectedScore), 0)
|
}
|
},
|
methods: {
|
addData() {
|
console.log('qeqweqeqwqrew',this.form,this.projectData);
|
|
this.$refs.form.validate(async (valid) => {
|
if (!valid) return;
|
if (this.$refs.materialEditor.getContent() == '<p></p>') {
|
this.$message.error('请输入报告正文')
|
return
|
}
|
if (!this.projectData.length) {
|
this.$message.warning('请选择项目组');
|
return;
|
}
|
if (!this.selectedMember || !this.selectedMember[0]) {
|
this.$message.warning('请选择菌种实验员');
|
return;
|
}
|
try {
|
const params = {
|
isDraft: 0,
|
evaluateId:this.selectedMember[0].id,
|
projectId: this.projectData[0].id,
|
reportCode: this.form.reportCode,
|
reportContent: this.$refs.materialEditor.getContent(),
|
reportName: this.form.reportName,
|
reportType: 1
|
};
|
add(params).then(res => {
|
if (res.code == 200) {
|
this.$message.success('发送成功');
|
this.$router.push('/strainReportLibrary/reportLibraryOne');
|
}
|
})
|
} catch (e) {
|
this.$message.error('发送失败');
|
}
|
});
|
},
|
saveData() {
|
this.$refs.form.validate(async (valid) => {
|
if (!valid) return;
|
|
try {
|
const params = {
|
isDraft: 1,
|
projectId: this.projectData[0].id,
|
evaluateId:this.selectedMember[0].id,
|
reportCode: this.form.reportCode,
|
reportContent: this.$refs.materialEditor.getContent(),
|
reportName: this.form.reportName,
|
reportType: 1
|
};
|
add(params).then(res => {
|
if (res.code == 200) {
|
this.$message.success('保存成功');
|
this.$router.push('/strainReportLibrary/reportLibraryOne');
|
}
|
})
|
} catch (e) {
|
this.$message.error('保存失败');
|
}
|
});
|
}, getProjectData(data) {
|
this.projectData = [data]; // 将选中的项目组数据存储到数组中
|
this.showChoose = false
|
},
|
selectUser(data) {
|
this.selectedMember = data;
|
console.log('qweqweqwe', data);
|
this.$refs.selectMember.close()
|
},
|
getMember() {
|
this.$refs.selectMember.open(null);
|
},
|
handleModifyMember(member) {
|
this.$refs.selectMember.open(member);
|
},
|
tableSpanMethod({ row, column, rowIndex, columnIndex }) {
|
// 评分规则说明(desc)和考评规则(rule)列合并所有行
|
// desc列索引为3,rule列索引为4(从0开始)
|
if (columnIndex === 3 || columnIndex === 4) {
|
if (rowIndex === 0) {
|
return [this.assessmentTable.length, 1]; // 合并所有行
|
} else {
|
return [0, 0]; // 其他行隐藏
|
}
|
}
|
return [1, 1];
|
},
|
getTableSummary(param) {
|
const { columns } = param;
|
const sums = [];
|
columns.forEach((column, index) => {
|
if (index === 0) {
|
sums[index] = '合计';
|
} else if (index === 1) {
|
sums[index] = this.totalScore + '分';
|
} else {
|
sums[index] = '';
|
}
|
});
|
return sums;
|
},
|
},
|
}
|
|
</script>
|
|
<style lang="less" scoped>
|
.mt-unset {
|
margin-top: unset !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;
|
}
|
}
|
|
.end-btn {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
|
button {
|
width: 180px;
|
height: 36px;
|
// background: #409EFF;
|
}
|
}
|
|
.member-list {
|
margin-top: 18px;
|
display: flex;
|
flex-wrap: wrap;
|
gap: 28px;
|
|
.member-list-card {
|
width: 340px;
|
height: 400px;
|
border-radius: 8px;
|
border: 1px solid #dcdfe6;
|
background: linear-gradient(to bottom,
|
rgba(5, 160, 193, 0.2) 0%,
|
rgba(5, 242, 194, 0) 70%);
|
|
&.empty-state {
|
background: #f5f7fa;
|
|
.empty-text {
|
color: #909399;
|
font-size: 14px;
|
}
|
}
|
|
.member-item {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
|
.member-title {
|
margin-top: 20px;
|
width: 100%;
|
font-family: "Source Han Sans CN Bold Bold";
|
font-weight: bold;
|
font-size: 16px;
|
color: rgba(0, 0, 0, 0.8);
|
line-height: 16px;
|
text-align: center;
|
}
|
|
.flex1 {
|
flex: 1;
|
}
|
|
.member-name-box {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.member-name-box-2 {
|
flex: 1;
|
padding: 0 20px;
|
padding-top: 40px;
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 20px;
|
justify-items: center;
|
align-items: start;
|
}
|
|
.member-name {
|
width: 60px;
|
height: 60px;
|
background: #7d8b79;
|
border-radius: 50%;
|
text-align: center;
|
line-height: 60px;
|
font-weight: 500;
|
font-size: 16px;
|
color: #ffffff;
|
margin: 0;
|
}
|
|
.member-change {
|
display: flex;
|
justify-content: center;
|
padding: 10px 0;
|
margin-top: auto;
|
cursor: pointer;
|
|
.member-change-btn {
|
background: #fff1f0;
|
border-radius: 4px;
|
border: 1px solid #ffccc7;
|
padding: 1px 8px;
|
font-weight: 400;
|
font-size: 12px;
|
color: #ff4d4f;
|
}
|
}
|
}
|
}
|
}
|
</style>
|