resultSetAll.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. <template>
  2. <div class="box-all">
  3. <PageHead :phName="packageName"></PageHead>
  4. <div class="main">
  5. <div class="flex-box-ce" style="padding: 10px 0;border-bottom: 1px solid #f1f1f1;margin-bottom: 20px;">
  6. <span :class="{ active: activeName == 'noEntering' }" style="width: 80px;"
  7. @click="activeName = 'noEntering'">未录入({{ noStatusListTotal }})</span>
  8. <span :class="{ active: activeName == 'entering' }" style="width: 80px;" @click="activeName = 'entering'">已录入({{
  9. statusListTotal }})</span>
  10. </div>
  11. <div>
  12. <el-select v-model="employee_ids" multiple filterable clearable placeholder="请输入或选择人员"
  13. style="width: 250px;margin-right: 10px;">
  14. <el-option v-for="(item, index) in employee_map" :key="index" :label="item.name" :value="item.id"></el-option>
  15. </el-select>
  16. <el-button type="default" style="margin: 0 15px 15px 0;" @click="clearFilter">清除所有过滤器</el-button>
  17. </div>
  18. <el-alert type="warning" title="可以根据指标名称,标准值,权重,目标值进行分类,便于对多人且同个指标的结果值录入" style="margin: 0 0 15px 0;"
  19. :closable="false"></el-alert>
  20. <el-table :data="tempData" ref="filterTable" border :header-cell-style="{ background: '#ECF5FF' }"
  21. :header-cell-class-name="handleHeaderClass" @header-click="handleHeaderClick" @sort-change="handleTableSort"
  22. @selection-change="handleSelectionChange">
  23. <el-table-column type="selection" min-width="55" align="center">
  24. </el-table-column>
  25. <el-table-column prop="employee_name" label="姓名" align="center" min-width="120">
  26. </el-table-column>
  27. <el-table-column prop="index_name" label="指标名称" min-width="200" sortable="custom" :filters="index_name_list"
  28. :filter-method="filterMethods" align="center"></el-table-column>
  29. <el-table-column prop="index_standard" label="考核标准" min-width="200" sortable="custom" align="center"
  30. :filters="index_standard_list" :filter-method="filterMethods">
  31. </el-table-column>
  32. <el-table-column prop="target" label="目标值" sortable="custom" align="center" :filters="target_list"
  33. :filter-method="filterMethods">
  34. <template slot-scope="scope">
  35. <span>{{ scope.row.target }}{{ scope.row.unit }}</span>
  36. </template>
  37. </el-table-column>
  38. <el-table-column prop="index_weight" label="权重%" sortable="custom" align="center" :filters="index_weight_list"
  39. :filter-method="filterMethods"></el-table-column>
  40. <el-table-column prop="index_remark" label="备注" min-width="200" align="center"></el-table-column>
  41. <el-table-column label="结果值附件" min-width="200" :render-header="(h, obj) => renderHeader(h, obj, 'upload')">
  42. <template slot-scope="scope">
  43. <div style="margin-bottom: 20px;" @click="openActive(scope.row)">
  44. <uploadOss :key="scope.row.id" :headers="$xtoken" class="avatar-uploader" :action="$action"
  45. :show-file-list="true" :file-list="scope.row.result_file.images" :on-preview="onFilePreView"
  46. :before-upload="beforeUpload" :on-remove="onFileRemove" :data-item="scope.row" :limit="3"
  47. :on-success="handleSuccessImg" :accept="$acceptImg" :multiple="true">
  48. <el-button class="primaryBtn" icon="el-icon-picture-outline" plain size="mini">图片</el-button>
  49. <!-- (最多选择3张) -->
  50. </uploadOss>
  51. </div>
  52. <div @click="openActive(scope.row)">
  53. <uploadOss :key="scope.row.id" class="avatar-uploader" :headers="$xtoken" :show-file-list="true"
  54. :multiple="true" :limit="5" :accept="$acceptFile" :file-list="scope.row.result_file.append"
  55. :action="$action" :on-preview="onFilePreView2" :on-success="handleSuccess" :on-remove="handleRemove"
  56. :before-upload="beforeFilesUpload">
  57. <el-button class="primaryBtn" icon="el-icon-paperclip" plain size="mini">附件</el-button>
  58. <!-- (仅支持上传xlsx,xls,doc,docx,pdf,txt,最多一份附件) -->
  59. </uploadOss>
  60. </div>
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="实际完成结果值" min-width="150" :render-header="(h, obj) => renderHeader(h, obj, 'result_cache')">
  64. <template slot-scope="scope">
  65. <div class="flex-box-ce" v-if="scope.row.index_type == 1">
  66. <el-input type="textarea" @input="[(scope.row.result_cache = isFloor(scope.row.result_cache))]"
  67. style="min-width: 130px;" :rows="1" v-model="scope.row.result_cache" placeholder="请输入"></el-input>
  68. <span style="width: 40px;padding-left: 5px;" class="font-flex-word">{{ scope.row.unit }}</span>
  69. </div>
  70. <div v-else>--</div>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. </div>
  75. <footer class="footer flex-box-end"
  76. v-if="activeName == 'noEntering' && multipleSelection && multipleSelection.length > 0">
  77. <el-button class="primaryBtn" @click="save(1)">暂存</el-button>
  78. <el-button type="primary" @click="save(0)">提交结果值</el-button>
  79. </footer>
  80. <footer class="footer flex-box-end"
  81. v-if="activeName == 'entering' && returnIsShow && multipleSelection && multipleSelection.length > 0">
  82. <el-button type="primary" @click="save(3)">提交结果值</el-button>
  83. </footer>
  84. <BatchUpload :isUploadShow="isUploadShow" :isUploadImg="isUploadImg" :isUploadFile="isUploadFile"
  85. :isResultCache="isResultCache" @close="closeBatchUpload" @confirm="getImgs"></BatchUpload>
  86. <!-- 图片查看 -->
  87. <el-dialog title="图片查看" :visible.sync="isShowImg" width="50%">
  88. <img :src="imgUrl" style="width: 100%;" />
  89. <span slot="footer" class="dialog-footer">
  90. <el-button @click="closePreview">关闭</el-button>
  91. </span>
  92. </el-dialog>
  93. <!-- 图片查看 -->
  94. <!-- 提交结果 -->
  95. <el-dialog title="提交结果" :visible.sync="isResult" width="800" :close-on-click-modal="false"
  96. :close-on-press-escape="false" :show-close="false">
  97. <div>
  98. <el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
  99. <div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
  100. <div class="flex-box-ce results" style="font-weight: 600;">
  101. <div style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
  102. <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
  103. <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
  104. <div class="flex-2">提交结果</div>
  105. </div>
  106. <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
  107. <div style="border-right: 1px solid #f1f1f1;width: 50px;">{{ results.length - index }}</div>
  108. <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
  109. <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
  110. <div class="flex-2 red" v-if="item.msg">{{ item.msg }}</div>
  111. <div class="flex-2 green" v-else>提交成功</div>
  112. </div>
  113. </div>
  114. <span slot="footer">
  115. <div class="flex-box-end" style="margin-top: 20px;">
  116. <el-button type="primary" @click="isResult = false" size="small">确 定</el-button>
  117. </div>
  118. </span>
  119. </div>
  120. </el-dialog>
  121. <!-- 提交结果 -->
  122. </div>
  123. </template>
  124. <script>
  125. import PageHead from '@/components/PageHead'; //头部---返回
  126. import uploadOss from '@/components/upload';
  127. import { _debounce } from '@/utils/auth';
  128. import BatchUpload from "./resultSetComp/BatchUpload.vue"
  129. export default {
  130. components: { PageHead, uploadOss, BatchUpload },
  131. name: 'resultSet',
  132. data() {
  133. return {
  134. tableData: [],
  135. pe_ids: [],
  136. pe_flows: [],
  137. activeName: 'noEntering',
  138. noStatusListAll: [],
  139. noStatusList: [],
  140. noStatusListDx: [],
  141. noStatusListTotal: 0,
  142. statusList: [],
  143. statusListTotal: 0,
  144. id: '', //员工考核记录id
  145. // 上传图标与附件
  146. img_fileList: [], // 图片附件
  147. file_fileList: [], //文件附件
  148. imgs: [],
  149. doc: '',
  150. isShowImg: false,
  151. imgUrl: '',
  152. selectItem: {},
  153. // 长连接结果
  154. results: [], //提交的返回结果集合
  155. isResult: false,
  156. percentage: 0,
  157. resultList: [], //要发送数据的集合
  158. resultIndex: 0,
  159. employee_ids: [],
  160. employee_map: [],
  161. tempData: [], // 表格数据
  162. sortList: [], // 用于表格数据排序
  163. index_name_list: [], // 指标名称过滤数据
  164. index_standard_list: [], // 指标标准过滤数据
  165. target_list: [], // 目标过滤数据
  166. index_weight_list: [], // 权重过滤
  167. multipleSelection: [], // 选择的数据
  168. isUploadShow: false,
  169. upLoadImages: [],
  170. isUploadImg: false,
  171. isUploadFile: false,
  172. isResultCache: false,
  173. };
  174. },
  175. computed: {
  176. returnIsShow() {
  177. let is = false
  178. this.tempData.forEach(item => {
  179. if (item.isUpdate) {
  180. is = true;
  181. }
  182. })
  183. return is
  184. },
  185. },
  186. watch: {
  187. activeName(val) {
  188. this.multipleSelection = [];
  189. this.clearFilter();
  190. this.initTableData();
  191. },
  192. isResult(val) {
  193. if (!val) {
  194. this.results = []; //提交的返回结果集合
  195. this.isResult = false;
  196. this.percentage = 0;
  197. this.resultList = []; //要发送数据的集合
  198. this.resultIndex = 0;
  199. this.getPackageDtail();
  200. }
  201. },
  202. employee_ids() {
  203. this.getPackageDtail();
  204. },
  205. peIds() {
  206. this.getPackageDtail();
  207. },
  208. },
  209. created() {
  210. if (this.$route.query.pe_ids) {
  211. this.pe_ids = this.$route.query.pe_ids;
  212. this.packageName = this.$route.query.name;
  213. if (this.$route.query.is) {
  214. this.activeName = 'entering';
  215. }
  216. this.getPackageDtail();
  217. }
  218. },
  219. methods: {
  220. closeBatchUpload() {
  221. this.isUploadShow = false;
  222. },
  223. getImgs(data) {
  224. let { imgs, files, result_cache } = data
  225. this.multipleSelection && this.multipleSelection.forEach(item => {
  226. if (imgs && imgs.length > 0) item.result_file.images = imgs.filter(img => { return img.url })
  227. if (files && files.length > 0) item.result_file.append = files.filter(file => { return file.url })
  228. if (item.index_type == 1) {
  229. if (result_cache) item.result_cache = result_cache;
  230. }
  231. })
  232. this.isUploadShow = false;
  233. },
  234. // 初始化表格数据
  235. initTableData() {
  236. let statusList = []; //已录入指标
  237. let noStatusList = []; //未录入指标
  238. this.tableData && this.tableData.forEach(item => {
  239. // 已录入指标
  240. if (item.index_result_status == 1) {
  241. noStatusList.push(item);
  242. }
  243. // 未录入指标
  244. if (item.index_result_status == 2) {
  245. item.isUpdate = true;
  246. this.pe_flows.forEach(e => {
  247. if (e.pe_id == item.pe_id) {
  248. item.isUpdate = this.returnIs(e.flow);
  249. }
  250. })
  251. statusList.push(item);
  252. }
  253. });
  254. this.noStatusList = noStatusList;
  255. this.statusList = statusList;
  256. this.statusListTotal = statusList.length;
  257. this.noStatusListTotal = noStatusList.length;
  258. if (this.activeName == 'noEntering') {
  259. this.tempData = noStatusList; // 默认展示未录入的数据
  260. } else {
  261. this.tempData = statusList; // 默认展示未录入的数据
  262. }
  263. // 初始化员工姓名过滤数据
  264. this.tempData.forEach(item => {
  265. let obj = {
  266. id: null,
  267. name: null
  268. }
  269. obj.id = item.employee_id
  270. obj.name = item.employee_name
  271. this.employee_map.push(obj)
  272. })
  273. // 初始化指标名称过滤数组
  274. this.index_name_list = this.tempData.map(item => {
  275. return {
  276. text: item.index_name,
  277. value: item.index_name,
  278. }
  279. })
  280. // 初始化指标标准过滤数组
  281. this.index_standard_list = this.tempData.map(item => {
  282. return {
  283. text: item.index_standard,
  284. value: item.index_standard,
  285. }
  286. })
  287. // 初始化目标过滤数组
  288. this.target_list = this.tempData.map(item => {
  289. return {
  290. text: item.target,
  291. value: item.target,
  292. }
  293. })
  294. // 初始化权重过滤数组
  295. this.index_weight_list = this.tempData.map(item => {
  296. return {
  297. text: item.index_weight,
  298. value: item.index_weight,
  299. }
  300. })
  301. this.employee_map = Array.from(new Set(this.employee_map.map(JSON.stringify))).map(JSON.parse);
  302. // 数组去重
  303. this.index_name_list = Array.from(new Set(this.index_name_list.map(JSON.stringify))).map(JSON.parse);
  304. // 数组去重
  305. this.index_standard_list = Array.from(new Set(this.index_standard_list.map(JSON.stringify))).map(JSON.parse);
  306. // 数组去重
  307. this.target_list = Array.from(new Set(this.target_list.map(JSON.stringify))).map(JSON.parse);
  308. // 数组去重
  309. this.index_weight_list = Array.from(new Set(this.index_weight_list.map(JSON.stringify))).map(JSON.parse);
  310. },
  311. handleSelectionChange(val) {
  312. this.multipleSelection = val;
  313. },
  314. filterMethods(value, row, column) {
  315. this.multipleSelection = [];
  316. this.$refs.filterTable.clearSelection();
  317. const property = column["property"];
  318. return row[property] === value
  319. },
  320. // -----------------------------------------自定义函数-----------------------------------------------
  321. updateSortOrder(column) {
  322. // column.order 默认只能有一个不为 null,也就是说其它列的 order 改变时,原有的 order 会被置为 null
  323. // 所以用另一个字段 multiOrder 保存 order 状态
  324. column.multiOrder = column.order
  325. // 更新 sortList
  326. const index = this.sortList.findIndex(item => item.prop === column.property)
  327. if (index !== -1) {
  328. this.sortList.splice(index, 1)
  329. }
  330. if (column.order !== null) {
  331. this.sortList.push({ prop: column.property, order: column.order })
  332. }
  333. // sort
  334. this.sortTableData()
  335. },
  336. // 根据某一项比较
  337. compareData(prop, a, b, order) {
  338. const orderFactor = order === 'ascending' ? 1 : -1
  339. if (a[prop] < b[prop]) {
  340. return -1 * orderFactor
  341. }
  342. if (a[prop] > b[prop]) {
  343. return 1 * orderFactor
  344. }
  345. return 0
  346. },
  347. // 根据 sortList 对 data 进行排序
  348. sortTableData() {
  349. this.tempData = Object.assign([], this.tempData)
  350. this.tempData.sort((a, b) => {
  351. for (const item of this.sortList) {
  352. const tempResult = this.compareData(item.prop, a, b, item.order)
  353. if (tempResult) {
  354. return tempResult
  355. }
  356. }
  357. return 0
  358. })
  359. },
  360. // -----------------------------------------el-table 事件-----------------------------------------------
  361. // 点击表头
  362. // bug: 监听不到点击箭头
  363. handleHeaderClick(column) {
  364. // this.updateSortOrder(column)
  365. },
  366. // 点击箭头
  367. handleTableSort({ column }) {
  368. this.updateSortOrder(column)
  369. },
  370. // 把 multiOrder 同步给 order
  371. handleHeaderClass({ column }) {
  372. column.order = column.multiOrder
  373. },
  374. clearFilter() {
  375. this.employee_ids = [];
  376. this.$refs.filterTable.clearFilter();
  377. this.filterData = [];
  378. this.multipleSelection = [];
  379. },
  380. // 自定义表头
  381. renderHeader(h, { column, $index }, type) {
  382. let that = this;
  383. if (that.multipleSelection && that.multipleSelection.length > 0) {
  384. if (type == 'upload') return h(
  385. 'div', {
  386. style: { display: "flex", alignItems: "center", justifyContent: "center" }
  387. }, [
  388. h('el-button', {
  389. props: {
  390. icon: 'el-icon-edit'
  391. },
  392. style: 'margin-left: 5px;',
  393. on: {
  394. click: function () {
  395. that.clickButton('img');
  396. }
  397. }
  398. }, '图片'),
  399. // 按钮
  400. h('el-button', {
  401. props: {
  402. icon: 'el-icon-edit'
  403. },
  404. style: 'margin-left: 5px;',
  405. on: {
  406. click: function () {
  407. that.clickButton('file');
  408. }
  409. }
  410. }, '附件')
  411. ],
  412. )
  413. else return h(
  414. 'div', {
  415. style: { display: "flex", alignItems: "center", justifyContent: "center" }
  416. }, [
  417. h('el-button', {
  418. props: {
  419. icon: 'el-icon-edit'
  420. },
  421. style: 'margin-left: 5px;',
  422. on: {
  423. click: function () {
  424. that.clickButton('result_cache');
  425. }
  426. }
  427. }, '实际完成结果值')
  428. ],
  429. )
  430. } else {
  431. return h(
  432. 'div', {
  433. style: { display: "flex", alignItems: "center", justifyContent: "center" }
  434. }, [
  435. // 列名称
  436. h('span', column.label),
  437. ],
  438. )
  439. }
  440. },
  441. // 按钮点击事件
  442. clickButton(type) {
  443. if (type == 'img') {
  444. this.isUploadImg = true;
  445. this.isUploadFile = false;
  446. this.isResultCache = false;
  447. }
  448. if (type == 'file') {
  449. this.isUploadImg = false;
  450. this.isUploadFile = true;
  451. this.isResultCache = false;
  452. }
  453. if (type == 'result_cache') {
  454. this.isUploadImg = false;
  455. this.isUploadFile = false;
  456. this.isResultCache = true;
  457. }
  458. this.openBatchUpload();
  459. },
  460. openBatchUpload() {
  461. this.isUploadShow = true;
  462. },
  463. closePreview() {
  464. this.imgUrl = "";
  465. this.isShowImg = false;
  466. },
  467. isFloor(el) {
  468. var obj = event.target;
  469. var t = el.charAt(0);
  470. el = el
  471. .replace('.', '$#$') //把第一个字符'.'替换成'$#$'
  472. .replace(/\./g, '') //把其余的字符'.'替换为空
  473. .replace('$#$', '.') //把字符'$#$'替换回原来的'.'
  474. .replace(/[^\d.]/g, '') //只能输入数字和'.'
  475. .replace(/^\./g, '') //不能以'.'开头
  476. .replace(/([0-9]+\.[0-9]{2})[0-9]*/, '$1'); //只保留2位小数
  477. if (t == '-') {
  478. el = '-' + el;
  479. }
  480. return el || null;
  481. },
  482. openActive(item) {
  483. this.selectItem = item;
  484. },
  485. handleSuccessImg: _debounce(function (response, file, fileList) {
  486. let result_file = JSON.parse(JSON.stringify(this.selectItem)).result_file;
  487. result_file.images = fileList.filter(item => {
  488. return item.url;
  489. });
  490. this.selectItem.result_file = result_file;
  491. }),
  492. // 图片上传
  493. beforeUpload(file) {
  494. const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
  495. const isLt2M = file.size / 1024 / 1024 < 5;
  496. if (!isJPG) {
  497. this.$message.error('上传图片只能是 jpeg|png|jpg 格式!');
  498. this.filData(1);
  499. }
  500. if (!isLt2M) {
  501. this.$message.error('上传图片大小不能超过 5MB!');
  502. }
  503. return isJPG && isLt2M;
  504. },
  505. onFilePreView(file) {
  506. if (file.url) {
  507. this.imgUrl = file.url;
  508. this.isShowImg = true;
  509. }
  510. },
  511. onFileRemove(file, fileList) {
  512. setTimeout(() => {
  513. this.selectItem.result_file.images = fileList;
  514. }, 500);
  515. },
  516. handleSuccess: _debounce(function (response, file, fileList) {
  517. let result_file = JSON.parse(JSON.stringify(this.selectItem)).result_file;
  518. result_file.append = fileList.filter(item => {
  519. return item.url;
  520. });
  521. this.selectItem.result_file = result_file;
  522. }),
  523. onFilePreView2(file) {
  524. window.open(file.url, '_blank');
  525. },
  526. handleRemove(file, fileList) {
  527. setTimeout(() => {
  528. this.selectItem.result_file.append = fileList;
  529. }, 500);
  530. },
  531. beforeFilesUpload(file) {
  532. const $ext_list = ['xlsx', 'xls', 'doc', 'docx', 'pdf', 'XLSX', 'XLS', 'DOC', 'DOCX', 'PDF'];
  533. const isLt2M = file.size / 1024 / 1024 < 5;
  534. let len = file.name.split('.').length - 1;
  535. const $ext_name = file.name.split('.')[len];
  536. let isFile = $ext_list.indexOf($ext_name) != -1;
  537. if (!isLt2M) {
  538. this.$message.error('文件大小不能超过 5MB!');
  539. }
  540. if (!isFile) {
  541. this.$message.warning('文件格式上传错误,仅支持上传xlsx,xls,doc,docx,pdf)');
  542. }
  543. return isFile && isLt2M;
  544. },
  545. // 提交
  546. save(num) {
  547. let isLr = false;
  548. let parameterArr = [];
  549. let err = '';
  550. let isPost = true;
  551. let str = '';
  552. let arr = this.multipleSelection;
  553. arr.forEach(item => {
  554. let result_info = [];
  555. result_info.push({
  556. dimension_key: item.dimension_id, //维度索引
  557. index_key: item.index_key, //指标索引
  558. index_id: item.index_id, //指标ID
  559. result_file: item.result_file
  560. });
  561. if (item.index_type == 1) {
  562. result_info[0].result = item.result_cache
  563. }
  564. let data = {
  565. id: item.pe_id, //个人考核包ID
  566. cache: num == 1 ? 1 : 0, //是否暂存 1 是 0 否(提交)
  567. info: item,
  568. result_info: JSON.stringify(result_info),
  569. sub: num == 3 ? 0 : 1
  570. };
  571. if (num == 3) { //编辑
  572. if (item.isUpdate) {
  573. if (item.index_type == 1) {
  574. if (!item.result_cache) {
  575. isPost = false;
  576. str = item.index_name + ': 请输入结果值'
  577. return true
  578. }
  579. } else {
  580. if (item.result_file.append.length == 0 && item.result_file.images.length == 0) {
  581. isPost = false;
  582. str = item.index_name + ': 至少添加一份附件'
  583. return true
  584. }
  585. }
  586. }
  587. } else{
  588. if (item.index_type == 1) {
  589. if (item.result_cache !== null && item.result_cache !== '') parameterArr.push(data);
  590. }
  591. if (item.index_type != 1) {
  592. if (item.result_file.append.length > 0 || item.result_file.images.length > 0) parameterArr.push(data);
  593. }
  594. }
  595. });
  596. if (num == 3) {
  597. if (!isPost) {
  598. this.$message({ type: 'error', message: str, duration: 3000, center: true });
  599. return false;
  600. }
  601. } else {
  602. if (parameterArr.length == 0) {
  603. this.$message({ type: 'error', message: '至少输入一项结果值或非量化指标添加一份附件', duration: 3000, center: true });
  604. return false;
  605. }
  606. }
  607. // return
  608. this.webSocket(parameterArr);
  609. },
  610. webSocket(data) {
  611. this.resultList = data;
  612. this.resultIndex = 0;
  613. this.percentage = 0;
  614. this.results = [];
  615. this.isResult = true;
  616. this.opneWebSocket();
  617. },
  618. opneWebSocket() {
  619. let wsData = this.resultList;
  620. if (wsData[this.resultIndex]) {
  621. this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
  622. this.onmessageWS(wsData[this.resultIndex], true);
  623. }).catch(e => {
  624. let data = wsData[this.resultIndex];
  625. data.msg = e.data.msg;
  626. this.onmessageWS(data, false);
  627. });
  628. }
  629. },
  630. onmessageWS(data, isJx) {
  631. this.results.unshift(data);
  632. this.resultIndex++;
  633. if (!isJx) {
  634. return false
  635. }
  636. this.opneWebSocket();
  637. // 进度条
  638. let lng = this.resultList.length;
  639. this.percentage += Math.floor(100 / lng);
  640. if (lng == this.results.length) {
  641. this.percentage = 100;
  642. }
  643. this.multipleSelection = [];
  644. this.clearFilter();
  645. },
  646. getPackageDtail() {
  647. this.$axiosUser('get', '/api/pro/per/package/result_job_list',
  648. {
  649. pe_ids: this.pe_ids,
  650. page: 1,
  651. page_size: 2000,
  652. employee_ids: JSON.stringify(this.employee_ids)
  653. }).then(res => {
  654. this.tableData = res.data.data.list;
  655. this.pe_flows = res.data.data.pe_flows;
  656. this.initTableData();
  657. });
  658. },
  659. //判断评分节点是否有人评了分
  660. returnIs(list) {
  661. let is = true;
  662. list.forEach(item => {
  663. if (item.code == 'score_supervisor' || item.code == 'special_scorer') {
  664. item.target.forEach(e => {
  665. if (e.status == 2) {
  666. is = false;
  667. }
  668. })
  669. }
  670. })
  671. return is
  672. },
  673. conformityData(arr) {
  674. let returnArr = [];
  675. let strs = new Set(
  676. arr.map(item => {
  677. return item.wdName;
  678. })
  679. );
  680. strs.forEach(item => {
  681. let obj = {
  682. wdName: item,
  683. list: arr.filter(e => {
  684. return e.wdName == item;
  685. })
  686. };
  687. returnArr.push(obj);
  688. });
  689. return returnArr;
  690. }
  691. }
  692. };
  693. </script>
  694. <style scoped lang="scss">
  695. .wd-title {
  696. margin: 20px 0;
  697. padding-left: 10px;
  698. border-left: 3px solid #409EFF;
  699. }
  700. .box-all {
  701. position: relative;
  702. background-color: #fff;
  703. font-size: 14px;
  704. padding: 20px;
  705. box-sizing: border-box
  706. }
  707. .main {
  708. margin-bottom: 60px;
  709. }
  710. .footer {
  711. position: fixed;
  712. bottom: 0;
  713. left: 0;
  714. right: 0;
  715. background-color: #fff;
  716. border-top: 1px solid #e8e8e8;
  717. padding: 12px 30px;
  718. z-index: 2;
  719. }
  720. .active {
  721. color: #409EFF;
  722. }
  723. .results {
  724. border-bottom: 1px solid #f1f1f1;
  725. text-align: center;
  726. }
  727. .results div {
  728. padding: 10px;
  729. box-sizing: border-box;
  730. }
  731. /* 设置滚动条的宽度和背景色 */
  732. ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
  733. width: 10px;
  734. height: 10px;
  735. background-color: #f9f9f9;
  736. }
  737. /* 设置滚动条滑块的样式 */
  738. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
  739. border-radius: 6px;
  740. background-color: #c1c1c1;
  741. }
  742. /* 设置滚动条滑块hover样式 */
  743. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  744. background-color: #a8a8a8;
  745. }
  746. /* 设置滚动条轨道的样式 */
  747. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
  748. box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
  749. border-radius: 6px;
  750. background: #ededed;
  751. }
  752. </style>