hejianhao
2025-04-11 2d3a34183f5b53b4872f0053da81b9ac555cb314
工作交付评定-实验结果评定
7个文件已修改
6个文件已添加
550 ■■■■■ 已修改文件
src/assets/font/Source Han Sans CN Normal.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/font/font.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/public/active.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/public/noActive.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/EvaluateTable/index.vue 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/index.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/deliveryAssessment/experimentResults/components/detail.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/deliveryAssessment/experimentResults/index.vue 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/deliveryAssessment/restsTask/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/deliveryAssessment/taskList/components/AssessmentDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectList/addProject.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/font/Source Han Sans CN Normal.ttf
Binary files differ
src/assets/font/font.css
@@ -24,4 +24,11 @@
  src: url('./SF Compact Display Black.ttf');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'Source Han Sans CN Normal';
  src: url('./Source Han Sans CN Normal.ttf');
  font-weight: normal;
  font-style: normal;
}
src/assets/public/active.png
src/assets/public/noActive.png
src/components/EvaluateTable/index.vue
New file
@@ -0,0 +1,319 @@
<template>
    <div>
        <div class="evaluateTable-header">
            <el-row>
                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="18">
                    <el-row style="width: 100%;">
                        <el-col style="color: transparent;cursor: default;" :xs="11" :sm="11" :md="11" :lg="11"
                            :xl="11">
                            占位字
                        </el-col>
                        <el-col :offset="1" :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
                            <el-row style="width: 100%;">
                                <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                    <div class="evaluateTable-header-text">良好</div>
                                </el-col>
                                <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                    <div class="evaluateTable-header-text">正确</div>
                                </el-col>
                                <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                    <div class="evaluateTable-header-text">失误</div>
                                </el-col>
                            </el-row>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col style="color: transparent;cursor: default;" :xs="24" :sm="24" :md="24" :lg="24" :xl="6">
                    占位字
                </el-col>
            </el-row>
        </div>
        <div class="evaluateTable-body">
            <el-row>
                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="18">
                    <div class="evaluateTable-body-left">
                        <div v-for="(item, index) in list" :key="index" class="evaluateTable-body-left-item">
                            <el-row style="width: 100%;">
                                <el-col :xs="11" :sm="11" :md="11" :lg="11" :xl="11">
                                    <div class="evaluateTable-body-left-item-text">
                                        {{ item }}
                                    </div>
                                </el-col>
                                <el-col :offset="1" :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
                                    <div class="evaluateTable-body-left-item-score">
                                        <el-row v-if="index != 5" style="width: 100%;">
                                            <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                                <div class="evaluateTable-body-left-item-score-num"
                                                    :class="yesOrNoActive(sort(2, index)) && 'activeScore'">
                                                    <img v-if="yesOrNoActive(sort(2, index))"
                                                        src="@/assets/public/active.png" />
                                                    <img v-else @click="selectNum(index, 2, sort(2, index))"
                                                        src="@/assets/public/noActive.png" />
                                                    <div>2分</div>
                                                </div>
                                            </el-col>
                                            <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                                <div class="evaluateTable-body-left-item-score-num"
                                                    :class="yesOrNoActive(sort(1, index)) && 'activeScore'">
                                                    <img v-if="yesOrNoActive(sort(1, index))"
                                                        src="@/assets/public/active.png" />
                                                    <img v-else @click="selectNum(index, 1, sort(1, index))"
                                                        src="@/assets/public/noActive.png" />
                                                    <div>1分</div>
                                                </div>
                                            </el-col>
                                            <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                                <div class="evaluateTable-body-left-item-score-num"
                                                    :class="yesOrNoActive(sort(0, index)) && 'activeScore'">
                                                    <img v-if="yesOrNoActive(sort(0, index))"
                                                        src="@/assets/public/active.png" />
                                                    <img v-else @click="selectNum(index, 0, sort(0, index))"
                                                        src="@/assets/public/noActive.png" />
                                                    <div>0分</div>
                                                </div>
                                            </el-col>
                                        </el-row>
                                        <el-row v-else style="width: 100%;">
                                            <el-col :xs="16" :sm="16" :md="16" :lg="16" :xl="16">
                                                <div class="evaluateTable-body-left-item-score-num"
                                                    :class="yesOrNoActive(sort(2, index)) && 'activeScore'">
                                                    <img v-if="yesOrNoActive(sort(2, index))"
                                                        src="@/assets/public/active.png" />
                                                    <img v-else @click="selectNum(index, -3, sort(2, index))"
                                                        src="@/assets/public/noActive.png" />
                                                    <div>是(-3分)</div>
                                                </div>
                                            </el-col>
                                            <el-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
                                                <div class="evaluateTable-body-left-item-score-num"
                                                    :class="yesOrNoActive(sort(1, index)) && 'activeScore'">
                                                    <img v-if="yesOrNoActive(sort(1, index))"
                                                        src="@/assets/public/active.png" />
                                                    <img v-else @click="selectNum(index, 0, sort(1, index))"
                                                        src="@/assets/public/noActive.png" />
                                                    <div>否(0分)</div>
                                                </div>
                                            </el-col>
                                        </el-row>
                                    </div>
                                </el-col>
                            </el-row>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="6">
                    <div class="evaluateTable-body-right">
                        <div class="evaluateTable-body-right-title">总分</div>
                        <div class="evaluateTable-body-right-num">
                            <div>{{ total != null ? total : '[自动计算]' }}</div>
                        </div>
                    </div>
                </el-col>
            </el-row>
        </div>
    </div>
</template>
<script>
import store from "../../store";
export default {
    props: {
        type: {
            type: Number,
            default: 1 //1 化验师 2 实验员 3 工艺工程师
        },
        isReadonly: {
            type: Boolean,
            default: false // 是否只读
        },
        viewJson: {
            type: String,
            default: '' //回显
        }
    },
    computed: {
        list() {
            if (this.type == 1) return store.state.assay
            if (this.type == 2) return store.state.experiment
            if (this.type == 3) return store.state.craft
            return store.state.assay
        },
    },
    watch: {
        activeIndex: {
            handler(newVal, oldVal) {
                this.total = null
                this.activeIndex.map(item => {
                    this.total += item.score
                })
            },
            deep: true
        },
        isReadonly: {
            handler(newVal, oldVal) {
                if (newVal) {
                    this.activeIndex = JSON.parse(this.viewJson)
                }
            },
        }
    },
    data() {
        return {
            total: null,
            activeIndex: [
                {
                    num: null,
                    score: 0
                },
                {
                    num: null,
                    score: 0
                },
                {
                    num: null,
                    score: 0
                },
                {
                    num: null,
                    score: 0
                },
                {
                    num: null,
                    score: 0
                },
                {
                    num: null,
                    score: 0
                },
            ]
        }
    },
    methods: {
        selectNum(index, score, num) {
            if (this.isReadonly) return
            this.activeIndex[index].score = score
            this.activeIndex[index].num = num
        },
        yesOrNoActive(num) {
            let arr = this.activeIndex.filter(item => item.num == num)
            return arr.length
        },
        sort(num, index) {
            return (index + 1) * 3 - num
        }
    }
}
</script>
<style lang="less" scoped>
.evaluateTable-header {
    font-weight: 500;
    font-size: 20px;
    color: #FFFFFF;
    height: 70px;
    background: linear-gradient(270deg, #0ACBCA 0%, #049C9A 100%);
    box-shadow: 0px 6px 10px 0px rgba(4, 156, 154, 0.09);
    border-radius: 10px;
    font-family: 'SourceHanSansCN-Medium';
    padding: 0 23px 0 17px;
    &-text {
        line-height: 70px;
    }
}
.evaluateTable-body {
    background: #FFFFFF;
    box-shadow: 0px 6px 10px 0px rgba(4, 156, 154, 0.09);
    border-radius: 10px;
    margin-top: -10px;
    padding: 0 23px 27px 17px;
    height: 100%;
    &-left {
        margin-top: 21px;
        &-item {
            background: #D7EFF4;
            box-shadow: 0px 6px 10px 0px rgba(4, 156, 154, 0.09);
            border-radius: 29px;
            margin-bottom: 20px;
            &-text {
                flex-shrink: 0;
                line-height: 44px;
                background: radial-gradient(0% 50% at 50% 50%, #0ACBCA 0%, #049C9A 100%);
                box-shadow: 0px 6px 10px 0px rgba(4, 156, 154, 0.09);
                border-radius: 29px;
                text-align: center;
                font-weight: bold;
                font-family: 'Source Han Sans CN Bold Bold';
                font-size: 16px;
                color: #FFFFFF;
                letter-spacing: 1px;
            }
            &-score {
                line-height: 44px;
                display: flex;
                align-items: center;
                .activeScore {
                    color: #049C9A;
                }
                &-num {
                    display: flex;
                    align-items: center;
                    img {
                        width: 16px;
                        height: 16px;
                        margin-right: 13px;
                        cursor: pointer;
                    }
                    div {
                        flex-shrink: 0;
                    }
                }
            }
        }
        &-item:last-child {
            margin-bottom: unset;
        }
    }
    .evaluateTable-body-right {
        margin-top: 21px;
        background: linear-gradient(to top, #0ACBCA 0%, #049C9A 100%);
        border-radius: 10px;
        padding-top: 35px;
        min-height: 329px;
        display: flex;
        align-items: center;
        flex-direction: column;
        margin-left: 16px;
        &-title {
            font-family: 'Source Han Sans CN Normal';
            font-weight: 400;
            font-size: 24px;
            color: #FFFFFF;
            line-height: 24px;
        }
        &-num {
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: center;
            font-family: 'SourceHanSansCN-Medium';
            font-weight: 500;
            font-size: 44px;
            color: #FFFFFF;
        }
    }
}
</style>
src/main.js
@@ -10,6 +10,7 @@
import Card from '@/components/Card/index.vue'
import ShowDelConfirm from '@/components/showDelConfirm/index.vue'
import SelectMember from '@/components/SelectMember/index.vue'
import EvaluateTable from '@/components/EvaluateTable/index.vue'
import "aieditor/dist/style.css"
import './assets/tailwind.css'
import './styles/element-variables.less'
@@ -21,6 +22,7 @@
Vue.component('Card', Card)
Vue.component('ShowDelConfirm', ShowDelConfirm)
Vue.component('SelectMember', SelectMember)
Vue.component('EvaluateTable', EvaluateTable)
Vue.prototype.msgsuccess = function (msg) {
  this.$message({
src/router/index.js
@@ -348,6 +348,13 @@
                },
                component: () => import("../views/deliveryAssessment/clinicalTrial"),
            },
            {
                path: "experimentResults",
                meta: {
                    title: "实验结果评定",
                },
                component: () => import("../views/deliveryAssessment/experimentResults"),
            },
        ]
    }
];
src/store/index.js
@@ -8,6 +8,30 @@
    keepAliveList: localStorage.getItem('keepAliveList') ? JSON.parse(localStorage.getItem('keepAliveList')) : [],//缓存页面
    tagList: localStorage.getItem('tagList') ? JSON.parse(localStorage.getItem('tagList')) : [],//标签列表
    isFold: false,//是否折叠
    assay: [
      '检验方法正确',
      '实验检验相关记录完整',
      '检验数据准确',
      '检验过程异常问题的优化处理',
      '检验时效完成度,安全操作',
      '操作失败',
    ],//化验师评定项
    experiment: [
      '实验方案熟悉度、设备及材料准备完整度',
      '实验操作、取样、送样准确性',
      '实验记录清晰完整度',
      '实验过程异常问题的优化处理',
      '实验操作时效完成度、安全操作',
      '实验操作失败',
    ],//实验员评定项
    craft: [
      '实验工作调度安排完成度',
      '全程实验、化验异常问题处理',
      '实验方案准确度、检验方法准确度',
      '检查实验数据记录准确性',
      '实验分析报告完成度',
      '实验损失与失败',
    ],//工艺工程师评定项
  },
  mutations: {
    SET_MENUS(state, data) {
src/views/deliveryAssessment/experimentResults/components/detail.vue
New file
@@ -0,0 +1,42 @@
<template>
    <el-dialog :visible.sync="dialogVisible" title="化验师工作评定" width="79.17%" @close="handleClose">
        <EvaluateTable ref="evaluateTable" />
    </el-dialog>
</template>
<script>
export default {
    name: 'Detail',
    props: {
        modelValue: {
            type: Boolean,
            default: false
        },
        reportData: {
            type: Object,
            default: () => { }
        }
    },
    data() {
        return {
            dialogVisible: false,
        }
    },
    watch: {
        modelValue: {
            handler(val) {
                this.dialogVisible = val;
            },
            immediate: true
        },
    },
    methods: {
        handleClose() {
            console.log(this.$refs.evaluateTable.total);
            console.log(this.$refs.evaluateTable.activeIndex);
        },
    }
}
</script>
<style lang="less" scoped></style>
src/views/deliveryAssessment/experimentResults/index.vue
New file
@@ -0,0 +1,143 @@
<template>
    <div class="list">
        <TableCustom :queryForm="queryForm" :tableData="tableData" :total="total" @currentChange="handleCurrentChange"
            @sizeChange="handleSizeChange">
            <template #search>
                <el-form :model="form" label-width="140px" inline>
                    <el-form-item label="项目课题方案名称:">
                        <el-input v-model="form.name" placeholder="请输入" />
                    </el-form-item>
                    <el-form-item label="所属实验编号:">
                        <el-input v-model="form.name" placeholder="请输入" />
                    </el-form-item>
                    <el-form-item label="实验名称:">
                        <el-input v-model="form.name" placeholder="请输入" />
                    </el-form-item>
                    <el-form-item label="创建时间:">
                        <el-date-picker v-model="value1" type="daterange" range-separator="至" start-placeholder="开始日期"
                            end-placeholder="结束日期">
                        </el-date-picker>
                    </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-select>
                    </el-form-item>
                    <el-form-item class="search-btn-box">
                        <el-button>重置</el-button>
                        <el-button type="primary">查询</el-button>
                    </el-form-item>
                </el-form>
            </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="age" label="是否评定">
                    <template #default="{ row }">
                        <span :style="{ color: ['green', 'red'][row.status - 1] }">{{ ['是', '否'][row.status - 1]
                        }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="age" label="创建日期" />
                <el-table-column prop="age" label="操作">
                    <template #default="{ row }">
                        <el-button type="text">评定详情</el-button>
                    </template>
                </el-table-column>
            </template>
        </TableCustom>
        <Detail :modelValue="assessmentVisible" :reportData="currentReport" />
    </div>
</template>
<script>
import Detail from './components/detail.vue'
export default {
    name: 'ExperimentResults',
    components: {
        Detail
    },
    data() {
        return {
            form: {
            },
            tableData: [],
            queryForm: {
                pageSize: 10,
                pageNum: 1
            },
            total: 0,
            assessmentVisible: true,
            currentReport: {}
        }
    },
    methods: {
        handleCurrentChange(page) {
            this.queryForm.pageNum = page
            this.getList()
        },
        handleSizeChange(size) {
            this.queryForm.pageSize = size
            this.getList()
        },
        getList() {
        },
        handleDetail(row) {
            // 处理详情
        },
        handleAssessment(row) {
            this.currentReport = row;
            this.assessmentVisible = true;
        },
    }
}
</script>
<style scoped lang="less">
.list {
    height: 100%;
}
.top-box-integral {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 28px;
    &-card {
        flex: 1;
        background: #E8FAF6;
        box-shadow: 0px 10px 10px 0px rgba(0, 0, 0, 0.06);
        border-radius: 10px;
        padding: 21px 20px;
        &-title {
            font-family: 'SourceHanSansCN-Medium';
            font-size: 14px;
            color: rgba(0, 0, 0, 0.8);
        }
        &-num {
            font-family: 'SF Compact Display Black';
            text-align: center;
            font-weight: 900;
            font-size: 50px;
            color: #049C9A;
            line-height: 60px;
        }
    }
}
.tip-warring {
    margin-top: 20px;
    color: rgba(255, 73, 85, 1);
}
</style>
src/views/deliveryAssessment/restsTask/index.vue
@@ -40,7 +40,7 @@
import Detail from './components/detail.vue'
export default {
    name: ' RestsTask',
    name: 'RestsTask',
    components: {
        Detail
    },
src/views/deliveryAssessment/taskList/components/AssessmentDialog.vue
@@ -24,7 +24,7 @@
                            2、在可行研究阶段,工艺开发升级,重新规划工艺研究路线,则以新规划的工艺路线方案来设定课题</div>
                    </div>
                </el-col>
                <el-col style="margin-top: 5px;" :xs="24" :sm="24" :md="19" :lg="19" :xl="19">
                <el-col style="margin-top: 5px;" :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
                    <Table :total="0" :data="criteriaList" show-summary :summary-method="getSummaries"
                        :span-method="arraySpanMethod">
                        <el-table-column type="index" label="序号" width="80" />
src/views/projectList/addProject.vue
@@ -111,8 +111,6 @@
                margin-right: 4px;
            }
        }
    }
}