| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- <template>
- <div :class="[{ bg_fff: skeletonLoad }]">
- <van-nav-bar title="结果值数据录入" left-text="" left-arrow @click-left="routerBak" />
- <VanSkeleton :skeLoad="skeletonLoad">
- <div style="height: 1rem;background-color: #fff;font-size: 0.32rem;" class="flex-box-ce flex-center-center" @click="selectUser=true">
- <span style="max-width: 4rem;" class="font-flex-word">{{userName}} </span>
- <van-icon name="arrow-down"/>
- </div>
- <header>
- <van-tabs v-model="active" swipeable><van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab></van-tabs>
- </header>
- <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all" :class="{ isIos: isIos }" :style="{height:active == 0? 'calc(100% - 4.2rem)':'calc(100% - 1rem)'}">
- <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
- <div v-for="(item, index) in rvenotList" :key="index" style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
- <div style="display:flex;border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
- <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
- <span style="font-size:.3rem;padding: 0.09rem 0px 0px 0.18rem;">{{ item.employee_name }}</span>
- <span class="font-flex-word" style="width: 4rem;display:inline-block;color:#a7a7a7;">
- <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0.14rem 0px 0px 0.15rem;display: inline-block;">
- {{ depts.dept_name }}
- <span v-if="item.dept_list.length - keys > 1">,</span>
- </span>
- </span>
- </div>
- <div>
- <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.index_name }}</div>
- <div class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att" v-if="arr.prop">
- <div style="color:#929292;font-size:.27rem;width: 1.4rem;">{{ arr.lab }}:</div>
- <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
- </div>
- <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="active == 0">
- <van-field v-model="item.result_cache" placeholder="请输入结果值" v-if="item.index_type==1" />
- <van-cell><Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
- <van-cell v-if="item.result_file.append.length>0">
- <template >
- <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
- <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
- </template>
- </van-cell>
- </div>
- <span v-else>
- <span style="color:#929292;font-size:.27rem;width: 1.4rem;display: inline-block;">结果值:</span>
- <span style="font-size:.28rem;" class="orange" v-if="item.index_type==1">{{ item.result_cache }} {{ item.unit }}</span>
- <template v-if="item.result_file.images">
- <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.result_file.images.length>0">
- <van-image @click="openImg(item.result_file.images,index2)" v-for="(e,index2) in item.result_file.images" :key="index2" style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url"/>
- </div>
- </template>
- <template v-if="item.result_file.append.length>0">
- <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
- <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
- </template>
- </span>
- </div>
- </div>
- </div>
- <van-empty description="暂无结果值录入" v-else />
- </scroller>
- <footer v-if="active == 0 && rvenotList.length > 0">
- <van-row class="footfoot">
- <van-col span="14" class="footcol" @click="save(1)">
- <div style="width:1rem;margin: auto;">
- <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
- <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
- </div>
- </van-col>
- <van-col span="10" class="footBut">
- <button style="" class="footcolButno" @click="rveno">取消</button>
- <button class="footcolButok" @click="save(0)">提交</button>
- </van-col>
- </van-row>
- </footer>
- <van-popup v-model:show="isResult" round >
- <div style="width: 7rem;padding: 0.24rem;box-sizing: border-box;">
- <div style="font-size: 0.28rem;margin-bottom: 0.24rem;">提交结果</div>
- <van-progress :percentage="percentage" stroke-width="8" />
- <div style="margin-top: 16px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
- <div class="flex-box-ce results" style="font-weight: 600;">
- <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
- <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
- <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
- <div class="flex-2">提交结果</div>
- </div>
- <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
- <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{ results.length - index }}</div>
- <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
- <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
- <div class="flex-2 red" v-if="item.msg">{{item.msg}}</div>
- <div class="flex-2 green" v-else>提交成功</div>
- </div>
- </div>
- <span slot="footer">
- <div class="flex-box-end" style="margin-top: 12px;" >
- <van-button type="primary" @click="isResult = false" size="small">确 定</van-button>
- </div>
- </span>
- </div>
- </van-popup>
- </VanSkeleton>
- <!-- 人员选择 -->
- <EmployeeSelector
- title="选择人员"
- :visible.sync="selectUser"
- @confirm="confirmCreator"
- :can_select_dept="false"
- :selected.sync="selected_data"
- ></EmployeeSelector>
- </div>
- </template>
- <script>
- import Vue from 'vue';
- import VanSkeleton from '@/performance/components/public/VanSkeleton';
- import EmployeeSelector from '@/components/EmployeeSelector';
- import Uploader from '@/components/OssUploader';
- import { Tab, Tabs,ImagePreview,Popup,Progress,DropdownMenu, DropdownItem, Icon } from 'vant';
- Vue.use(Tab).use(Tabs).use(ImagePreview).use(Popup).use(Progress).use(DropdownMenu).use(DropdownItem).use(Icon);
- export default {
- data() {
- return {
- isNeed:!this.$getCache('isAndroid'),
- skeletonLoad: true, // 骨架屏
- rvenotList: [],
- minFormactive: [{ name: '未录入', age: 0 }, { name: '已录入', age: 0 }],
- active: 0,
- pe_ids: 0, // 个人考核记录集合
- packageName: '', // 考核包名
- noStatusList: [], // 未录入指标
- statusList: [], // 已录入指标
- bootBool: false, // 防止多次请求
- isIos: this.$getCache('iPhone'),
- // 上传图标与附件
- img_fileList: [], // 图片附件
- images: [],
- accept:'image/jpeg,image/png,image/jpg',
- // 长连接结果
- results: [], //提交的返回结果集合
- isResult: false,
- percentage: 0,
- resultList: [], //要发送数据的集合
- resultIndex: 0,
- userName:'全部人员',
- selectUser:false,
- employee_list: [],
- selected_data: { dept: [], employee: [] } //传入已选部门
- };
- },
- components: {VanSkeleton,Uploader,EmployeeSelector },
- watch: {
- isResult(val) {
- if (!val) {
- this.results = []; //提交的返回结果集合
- this.isResult = false;
- this.percentage = 0;
- this.resultList = []; //要发送数据的集合
- this.resultIndex = 0;
- this.getPackageDtail();
- }
- },
- active(val) {
- if (val == 0) {
- this.rvenotList = this.noStatusList;
- } else if (val == 1) {
- this.rvenotList = this.statusList;
- }
- },
- },
- methods: {
- confirmCreator(data) {
- let userName = '';
- this.userName="全部人员"
- this.employee_list=[];
- if (data.employee !== null && data.employee.length != 0) {
- data.employee.forEach(item=>{
- this.employee_list.push(item.id);
- userName+=(item.name+',')
- })
- this.userName = userName;
- }
- this.selected_data = data;
- this.selectUser = false;
- this.getPackageDtail();
- },
- downWgt (url,name) {
- let self = this
- if(!window.plus){
- window.open(url, '_blank');
- return false
- }
- plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
- function (d, status) {
- if (status == 200) {
- plus.runtime.openFile(d.filename,{},(err)=>{
- // console.log(JSON.stringify(err))
- });
- } else {
- self.$toast.clear()
- Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
- }
- }
- ).start()
- },
- openImg(imgs,index){
- let imgArr=imgs.map(item=>{
- return item.url
- })
- ImagePreview({
- images:imgArr,
- startPosition:index,
- });
- },
- // 返回布尔值
- beforeRead(file) {
- const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
- // const isLt2M = file.size / 1024 / 1024 < 2;
- if (!isJPG) {
- this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
- }
- // if (!isLt2M) {
- // this.$toast('上传图片大小不能超过 2MB!');
- // }
- return isJPG;
- },
- // 返回上一页
- routerBak() {
- this.$route_back();
- },
- rveno() {
- // 取消
- this.$route_back();
- },
- // 提交
- save(num) {
- let isLr = false;
- let parameterArr = [];
- // let data = {
- // id: this.id, // 个人考核包ID
- // cache: num, // 是否暂存 1 是 0 否(提交)
- // result_info: '' // 结果值信息
- // };
- this.noStatusList.some(item => {
- let images=[];//图片
- let result_info = [];
- if( item.result_file.imgs){
- item.result_file.imgs.forEach(imgItem=>{
- let name=imgItem.split('/');
- let obj={
- name:name[name.length-1],
- url:imgItem,
- }
- images.push(obj)
- })
- }
- item.result_file.images=images;
- result_info.push({
- dimension_key: item.dimension_id, //维度索引
- index_key: item.index_key, //指标索引
- index_id: item.index_id, //指标ID
- result_file: item.result_file
- });
- if(item.index_type == 1){
- result_info[0].result=item.result_cache
- }
- let data = {
- id: item.pe_id, //个人考核包ID
- cache: num, //是否暂存 1 是 0 否(提交)
- info: item,
- result_info: JSON.stringify(result_info),
- sub: num==3? 0:1
- };
- if (item.index_type == 1 && item.result_cache!==null && item.result_cache!=='') {
- parameterArr.push(data);
- }
- if (item.index_type != 1 && (item.result_file.append.length > 0 || item.result_file.images.length > 0)) {
- parameterArr.push(data);
- }
- });
- if (parameterArr.length==0) {
- this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
- return false;
- }
- this.webSocket(parameterArr);
- return;
- if (this.bootBool) {
- return;
- }
- this.bootBool = true;
- this.$axiosUser('post', '/api/pro/per/package/record_result', data)
- .then(res => {
- this.$toast.success('设置成功');
- this.getPackageDtail();
- })
- .finally(() => {
- setTimeout(() => {
- this.bootBool = false;
- }, 3000);
- });
- },
- webSocket(data) {
- this.resultList = data;
- this.resultIndex = 0;
- this.percentage = 0;
- this.results = [];
- this.isResult = true;
- this.opneWebSocket();
- },
- opneWebSocket() {
- let wsData = this.resultList;
- if (wsData[this.resultIndex]) {
- this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
- this.onmessageWS(wsData[this.resultIndex],true);
- }).catch(e=>{
- let data=wsData[this.resultIndex];
- data.msg=e.data.msg;
- this.onmessageWS(data,false);
- // console.log(e)
- });
- }
- },
- onmessageWS(data,isJx) {
- this.results.unshift(data);
- this.resultIndex++;
- if(!isJx){
- return false
- }
- this.opneWebSocket();
- // 进度条
- let lng = this.resultList.length;
- this.percentage += Math.floor(100 / lng);
- if (lng == this.results.length) {
- this.percentage = 100;
- }
- },
- getPackageDtail() {
- this.$axiosUser('get', '/api/pro/per/package/result_job_list', { pe_ids: this.pe_ids, page: 1, page_size: 2000,employee_ids:JSON.stringify(this.employee_list) }).then(res => {
- let list = res.data.data.list;
- let statusList = []; // 已录入指标
- let noStatusList = []; // 未录入指标
- list.forEach(item => {
- let imgs=[];
- if(item.result_file){
- item.result_file.images.forEach(img => {
- imgs.push(img.url);
- })
- item.result_file.imgs=imgs;
- }
- item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
- item.dil = [
- { lab: '考核标准', prop: item.index_standard ? item.index_standard : null},
- { lab: '权重%', prop: item.index_weight ? item.index_weight : null },
- { lab: '备注', prop: item.index_remark ? item.index_remark : null },
- { lab: '目标值', prop: item.target ? item.target : null },
- ];
- if (item.index_result_status == 1) {
- noStatusList.push(item);
- }
- if (item.index_result_status == 2) {
- statusList.push(item);
- }
- });
- this.statusList = statusList;
- this.noStatusList = noStatusList;
- if (this.active == 0) {
- this.rvenotList = this.noStatusList;
- } else if (this.active == 1) {
- this.rvenotList = this.statusList;
- }
- this.minFormactive[0].age = noStatusList.length; // 未
- this.minFormactive[1].age = statusList.length; // 已
- })
- .finally(() => {
- this.skeletonLoad = false;
- });
- }
- },
- created() {
- if (this.$route.query.pe_ids) {
- this.pe_ids = this.$route.query.pe_ids;
- this.packageName = this.$route.query.name;
- this.getPackageDtail();
- }
- },
- mounted() {}
- };
- </script>
- <style scoped lang="less">
- .userName{
- position: absolute;
- left: 0%;
- height: 50px;
- width: 100%;
- opacity: 0;
- }
- .results {
- border-bottom: 1px solid #f1f1f1;
- text-align: center;
- font-size: 0.24rem;
- }
- .results div {
- padding: 10px;
- }
- .line-feed {
- white-space: pre-wrap;
- }
- .all {
- height: calc(100% - 3.2rem);
- position: relative !important;
- background-color: #f5f7fa;
- padding-bottom: 0.3rem;
- overflow-y: scroll;
- }
- header {
- background-color: #fff;
- font-size: 0.3rem;
- z-index: 1;
- }
- .isIos {
- height: calc(100% - 3.6rem);
- }
- footer {
- // position: fixed;
- // left: 0px;
- // bottom: 0px;
- // width: 100%;
- background-color: #ffffff;
- z-index: 999;
- border-top: 1px solid #e2e2e2;
- .footfoot {
- padding: 0.1rem;
- // padding-bottom: 0.4rem !important;
- .footcol {
- text-align: center;
- }
- .footBut {
- display: flex;
- }
- .footcolButno {
- border: 1px solid #42a8ff;
- width: 1.4rem;
- height: 0.8rem;
- font-size: 0.28rem;
- color: #2f9eff;
- background-color: #ffffff;
- border-top-left-radius: 3px;
- border-bottom-left-radius: 3px;
- }
- .footcolButok {
- border: 0;
- width: 1.4rem;
- height: 0.8rem;
- font-size: 0.28rem;
- color: #fff;
- background-color: #42a8ff;
- border-top-right-radius: 3px;
- border-bottom-right-radius: 3px;
- }
- }
- }
- </style>
|