index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. <!-- 采购订单修订—— 列表 -->
  2. <script>
  3. import { TableColumns, SearchColumns, TabColumns, SelectColumns } from "./column";
  4. import orderApi from "@/api/business/purchase/purchase-order";
  5. import {saveAs} from "file-saver";
  6. import { blobValidate } from "@/utils/ruoyi";
  7. import {
  8. initPage,
  9. initParams,
  10. // initDicts,
  11. } from "@/utils/init/index.js";
  12. import { initDicts } from "@/utils/init.js";
  13. const allColumns = [...TableColumns, ...SearchColumns];
  14. TabColumns.forEach(column =>{
  15. allColumns.push(...column.tableColumns)
  16. })
  17. export default {
  18. name: "PuchaseOrder",
  19. // dicts: initDicts(SelectColumns),
  20. dicts: [...initDicts(allColumns)],
  21. components: {
  22. AddDrawer: () => import('./add/index.vue'),
  23. SeeDrawer: () => import('./see/index.vue'),
  24. EditDrawer: () => import('./edit/index.vue'),
  25. PurchaseReturnDrawer: () => import('./purchaseReturn/index.vue'),
  26. ElSuperTable: () => import("@/components/super-table/index.vue"),
  27. ElSuperSearch: () => import("@/components/super-search/index.vue"),
  28. },
  29. data() {
  30. const initTabColumns = () => TabColumns;
  31. return {
  32. loading: false,
  33. tabLoading:false,
  34. page: { pageNum: 1, pageSize: 100, total: 0 },
  35. searchColumns: SearchColumns,
  36. params: initParams(SearchColumns),
  37. tableColumns: TableColumns,
  38. tableData: [],
  39. tabColumns: initTabColumns(),
  40. tabName: "puOrderItemList",
  41. tabTableDatas: {
  42. puOrderItemList: [],
  43. puOrderExecuteList: [],
  44. },
  45. checkedList: [],
  46. // 子表Select
  47. checkedTabList: [],
  48. // 主表点击信息
  49. primaryResource:{},
  50. timer:300,
  51. timeOut:null,
  52. };
  53. },
  54. computed: {
  55. $dicts: {
  56. get: function () {
  57. return this.dict.type;
  58. },
  59. },
  60. },
  61. created() {
  62. this.fetchList(this.params, this.page);
  63. // this.handleRefreshList();
  64. },
  65. methods: {
  66. async fetchList(data, params) {
  67. try {
  68. this.loading = true;
  69. params['isAsc'] = 'desc';
  70. params['orderByColumn'] = 'updateTime';
  71. const { code, msg, rows, total } = await orderApi.list(data, params);
  72. if (code === 200) {
  73. this.page.total = total;
  74. this.tableData = rows;
  75. }
  76. } catch (err) {
  77. //
  78. } finally {
  79. this.loading = false;
  80. for (const key in this.tabTableDatas) {
  81. this.tabTableDatas[key] = [];
  82. }
  83. }
  84. },
  85. async handleDownload(){
  86. console.log(this.params,'条件');
  87. this.download('/pu/order/export', {...this.params}, `采购订单维护${new Date().getTime()}.xlsx`);
  88. // try {
  89. // this.loading = true;
  90. // orderApi.orderExport({...this.params}).then(res=>{
  91. // const isBlob = blobValidate(res);
  92. // if (isBlob) {
  93. // const blob = new Blob([res]);
  94. // saveAs(blob, `采购订单维护${new Date().getTime()}.xlsx`);
  95. // }
  96. // })
  97. // } catch (error) {
  98. // }finally{
  99. // this.loading = false;
  100. // }
  101. },
  102. async jumpFlow(row){
  103. const {name} = this.$store.state.user;
  104. try {
  105. let {code,msg,oaUrl} = await orderApi.toOA(name,row.flowId);
  106. if(code == 200){
  107. window.open(oaUrl)
  108. }
  109. } catch (error) {
  110. }finally{
  111. }
  112. },
  113. setSelectable(){
  114. return true
  115. },
  116. setTabSelectable(){
  117. if(this.tabName === 'puOrderItemList'){
  118. return true
  119. }
  120. return false
  121. },
  122. // 刷新操作
  123. handleRefreshList() {
  124. this.page.pageNum = 1;
  125. this.page.pageSize = 10;
  126. this.$refs.purchaseTable.$refs.superTable.clearSelection();
  127. for (const key in this.tabTableDatas) {
  128. this.tabTableDatas[key] = []
  129. }
  130. this.$refs.puOrderItemList[0].$refs.superTable.clearSelection();
  131. // this.checkedList = [];
  132. // this.checkedTabList = [];
  133. this.primaryResource = {};
  134. this.fetchList(this.params, this.page);
  135. },
  136. // 查询操作
  137. handleQueryList() {
  138. let {date} = this.params;
  139. this.params.startDate = date ? date[0] :'';
  140. this.params.endDate = date ? date[1] : '';
  141. this.fetchList(this.params, this.page);
  142. },
  143. // 重置操作
  144. handleResetList() {
  145. this.page.pageNum = 1;
  146. this.page.pageSize = 10;
  147. this.params = initParams(SearchColumns);
  148. this.fetchList(this.params, this.page);
  149. },
  150. handleTabClick() { },
  151. // 新增
  152. handleOpenAddDrawer(copyVal) {
  153. const { setVisible, setCopyParams } = this.$refs.addDrawerFef;
  154. setVisible(true,(copyVal.id && copyVal.id != '') ? true :false);
  155. copyVal.id && copyVal.id != '' && setCopyParams(copyVal.id);
  156. },
  157. // 复制
  158. handleCopy() {
  159. this.handleOpenAddDrawer(this.checkedList[0]);
  160. },
  161. // 查看
  162. async handleOpenSeeDrawer(row) {
  163. window.clearInterval(this.timeOut);
  164. const { id } = row;
  165. const { setVisible, fetchItem } = this.$refs.seeDrawerRef;
  166. await setVisible(true);
  167. await fetchItem(id);
  168. },
  169. // 编辑、修订
  170. async handleOpenEditDrawer(row) {
  171. const { id } = row;
  172. const { setVisible, fetchItem } = this.$refs.editDrawerRef;
  173. await setVisible(true);
  174. await fetchItem(id);
  175. },
  176. // 获取子表信息
  177. handleDetailsData(row) {
  178. window.clearTimeout(this.timeOut);
  179. this.timeOut = setTimeout(async () =>{
  180. try {
  181. this.tabLoading = true;
  182. this.primaryResource = row;
  183. this.checkedTabList = [];
  184. const { code, msg, data } = await orderApi.details(row.id);
  185. if (code === 200) {
  186. // 物料信息:puOrderItemList 执行结果:puOrderExecuteList
  187. for (const key in this.tabTableDatas) {
  188. this.tabTableDatas[key] = data[key];
  189. }
  190. }
  191. } catch (err) {}
  192. finally{
  193. this.tabLoading = false;
  194. }
  195. },this.timer)
  196. },
  197. // 操作提示弹窗
  198. handleConfirmTips(success){
  199. this.$confirm('是否继续此操作?', '提示', {
  200. confirmButtonText: '确定',
  201. cancelButtonText: '取消',
  202. type: 'warning'
  203. }).then(() => {
  204. success();
  205. }).catch(() => {
  206. });
  207. },
  208. // 删除操作
  209. handleDeleteList(row) {
  210. try {
  211. this.loading = true;
  212. this.handleConfirmTips(async()=>{
  213. const { id } = row;
  214. const { code } = await orderApi.remove(id);
  215. if (code === 200) {
  216. this.handleRefreshList();
  217. }
  218. })
  219. } catch (err) {
  220. //
  221. } finally {
  222. this.loading = false;
  223. }
  224. },
  225. // 批量提交
  226. handleBatchSubmit(){
  227. let inconformity = this.checkedList.filter(row => !((row.status == '0' || row.status == '3') && row.isEnd === 'N'));
  228. if(!inconformity.length && this.checkedList.length){
  229. let puOrderIds = this.checkedList.map( item => Number(item.id));
  230. this.fetchSubmit(puOrderIds);
  231. }else{
  232. this.$notify({
  233. title: '警告',
  234. message: '当前选中存在不满足提交条件的数据!',
  235. type: 'warning'
  236. });
  237. }
  238. },
  239. // 提交
  240. handleSubmit(row) {
  241. let puOrderIds = [Number(row.id)];
  242. this.fetchSubmit(puOrderIds);
  243. },
  244. fetchSubmit(puOrderIds){
  245. let _this = this;
  246. this.handleConfirmTips(async()=>{
  247. try {
  248. _this.loading = true;
  249. let { code,msg } = await orderApi.submit({ puOrderIds,checkAmount:true});
  250. console.log(code,'code');
  251. if (code == 200) {
  252. _this.handleRefreshList();
  253. }else if(code == 10000){
  254. _this.$alert(msg, '提示', {
  255. showCancelButton: true,
  256. confirmButtonText: '置为0并提交',
  257. cancelButtonText: '取消',
  258. beforeClose: async(action, instance, done) => {
  259. if (action === 'confirm') {
  260. try {
  261. instance.confirmButtonLoading = true;
  262. instance.confirmButtonText = '执行中...';
  263. let { code,msg } = await orderApi.submit({ puOrderIds,checkAmount:false});
  264. if(code == 200){
  265. done();
  266. _this.handleRefreshList();
  267. }
  268. } catch (error) {
  269. }finally{
  270. instance.confirmButtonLoading = false;
  271. }
  272. } else {
  273. done();
  274. }
  275. }
  276. });
  277. }
  278. } catch (error) {}
  279. finally{
  280. this.loading = false;
  281. }
  282. })
  283. },
  284. // 判断“整单退回”按钮
  285. judgeIsAllReturn() {
  286. if (this.checkedList.length == 1) {
  287. // 非手工、状态:自由/驳回
  288. if (this.judgeIsOption('return',this.checkedList[0])) {
  289. // if (this.checkedList[0].source != 3 &&
  290. // (this.checkedList[0].status == 0 || this.checkedList[0].status == 3)
  291. // ) {
  292. return false
  293. }
  294. }
  295. return true;
  296. },
  297. // 整单退回
  298. handleAllReturn() {
  299. this.handleReturn(this.checkedList[0].id,[]);
  300. },
  301. // 判断“行退回”按钮
  302. judgeIsLineReturn() {
  303. if (this.checkedTabList.length == 1) {
  304. // 主信息:非手工、状态:自由/驳回
  305. if(this.judgeIsOption('return',this.primaryResource)){
  306. // if(this.primaryResource.source != 3 &&
  307. // (this.primaryResource.status == 0 || this.primaryResource.status == 3) ){
  308. return false
  309. }
  310. }
  311. return true;
  312. },
  313. // 行退回
  314. handleLineReturn(){
  315. let ids = this.checkedTabList.map(checked => checked.id);
  316. console.log(ids,'行退回ids');
  317. this.handleReturn(this.primaryResource.id,ids);
  318. },
  319. // 退回接口
  320. handleReturn(id,documentIds){
  321. this.$prompt('请输入退回原因', '提示', {
  322. confirmButtonText: '确定',
  323. cancelButtonText: '取消',
  324. inputPattern: /\s*\S+?/,
  325. inputErrorMessage: '退回原因不能为空'
  326. }).then(async ({ value }) => {
  327. let data = {
  328. id:Number(id),
  329. documentIds:documentIds.map(ids =>Number(ids)),
  330. baskCause: value,
  331. };
  332. console.log(data);
  333. try {
  334. let { code, msg } = await orderApi.documentsReturn(data);
  335. if (code === 200) {
  336. this.handleRefreshList();
  337. }
  338. } catch (error) {
  339. console.log(error,'error------------');
  340. }
  341. }).catch(() => { });
  342. },
  343. // 判断是否满足整单关闭
  344. judgeIsAllClose() {
  345. if (this.checkedList.length == 1) {
  346. // if (this.checkedList[0].status == 0) {
  347. if (this.judgeIsOption('allClose',this.checkedList[0])) {
  348. // 未审批状态下整单关闭
  349. return false
  350. }
  351. }
  352. return true;
  353. },
  354. // 整单关闭
  355. handleAllClose() {
  356. // 未审批状态下整单关闭
  357. try {
  358. this.handleConfirmTips(async() =>{
  359. let puOrderIds = this.checkedList.map(order => Number(order.id));
  360. let { code } = await orderApi.close({ puOrderIds });
  361. if (code === 200) {
  362. this.handleRefreshList();
  363. }
  364. })
  365. } catch (error) { }
  366. },
  367. // 付款协议
  368. async handlePaymentRequest(){
  369. // name:工号
  370. try {
  371. let {code,msg} = await orderApi.payRequest();
  372. if(code == 200){
  373. msg.replace(/\/n/g,'');
  374. let url = `uclient://start/http://172.16.100.2:8081?ssoKey=${msg}&uiloader=nc.uap.lfw.applet.PortalUILoader&nodeId=40040407`
  375. window.location.href = url;
  376. }
  377. } catch (error) {}
  378. },
  379. // 退货
  380. async handlePurchaseReturn(){
  381. const { id } = this.checkedList[0];
  382. const { setVisible, fetchStorage } = this.$refs.PurchaseReturnDrawerRef;
  383. await setVisible(true);
  384. await fetchStorage(id);
  385. },
  386. // 主表Select框
  387. handleSelect(selection, row) {
  388. this.checkedList = selection;
  389. console.log(this.checkedList, 'this.checkedList');
  390. },
  391. handleSelectionChange(selection){
  392. this.checkedList = selection;
  393. },
  394. // 子表Select框
  395. handleTabSelect(selection, row){
  396. this.checkedTabList = selection;
  397. console.log(this.checkedTabList, 'this.checkedTabList');
  398. },
  399. handleTabSelectionChange(selection){
  400. this.checkedTabList = selection;
  401. },
  402. // 保留两位小数,补位
  403. keepTwoDecimalStr(num) {
  404. if(num){
  405. const result = Number(num.toString().match(/^\d+(?:\.\d{0,2})?/));
  406. let s = result.toString();
  407. let rs = s.indexOf('.');
  408. if (rs < 0) {
  409. rs = s.length;
  410. s += '.';
  411. }
  412. while (s.length <= rs + 2) {
  413. s += '0';
  414. }
  415. return s;
  416. }else{
  417. return '';
  418. }
  419. },
  420. judgeIsOption(type,source){
  421. // status: 0=自由态,1=审批中,2=已审核,3=已驳回 4=提交中
  422. // source: 1=自动协议直采,2=协议直采,3=手工
  423. // isEnd:整单关闭标识
  424. switch(type){
  425. case 'edit':
  426. return (source.status == '0' || source.status == '3') && source.isEnd === 'N';
  427. case 'revise':
  428. return source.status == '2' && source.isEnd === 'N';
  429. case 'del':
  430. return (source.status == '0' || source.status == '3') && source.source == '3' && source.isEnd === 'N';
  431. case 'submit':
  432. return (source.status == '0' || source.status == '3') && source.isEnd === 'N';
  433. case 'allClose':
  434. return source.status == 0 && source.isEnd === 'N';
  435. case 'return':
  436. return source.source != 3 && source.isEnd === 'N' &&
  437. (source.status == 0 || source.status == 3);
  438. default:
  439. return false;
  440. }
  441. }
  442. }
  443. };
  444. </script>
  445. <template>
  446. <el-card
  447. v-loading="loading"
  448. style="width: calc(100% - 24px); height: 100%; margin: 10px;padding: 10px;"
  449. :body-style="{ padding: 0 }"
  450. >
  451. <SeeDrawer ref="seeDrawerRef"></SeeDrawer>
  452. <AddDrawer ref="addDrawerFef" @close="handleRefreshList"></AddDrawer>
  453. <EditDrawer ref="editDrawerRef" @close="handleRefreshList"></EditDrawer>
  454. <PurchaseReturnDrawer ref="PurchaseReturnDrawerRef" @close="handleRefreshList"></PurchaseReturnDrawer>
  455. <el-super-search
  456. v-model="params"
  457. :size="'mini'"
  458. :dict="dict"
  459. :columns="searchColumns"
  460. @reset="handleResetList"
  461. @submit="handleQueryList"
  462. ></el-super-search>
  463. <!-- 操作 -->
  464. <el-row :gutter="24" type="flex" justify="end" style="margin: 20px 0;">
  465. <el-col :span="24" style="text-align: right;">
  466. <el-button size="mini" type="primary" @click="handleOpenAddDrawer"
  467. v-hasPermi="['material:order:add']">新增</el-button>
  468. <el-button-group style="margin-left: 10px">
  469. <el-button type="primary" size="mini" :disabled="checkedList.length != 1" @click="handleCopy">复制</el-button>
  470. <el-button type="primary" size="mini" @click="handleBatchSubmit">批量提交</el-button>
  471. </el-button-group>
  472. <el-button-group style="margin-left: 10px" :key="checkedList.length + 1">
  473. <el-button type="primary" size="mini" @click="handleAllReturn" :disabled="judgeIsAllReturn()">整单退回</el-button>
  474. <el-button type="primary" size="mini" @click="handleAllClose" :disabled="judgeIsAllClose()">整单关闭</el-button>
  475. </el-button-group>
  476. <el-button-group style="margin:0 10px">
  477. <!-- <el-button size="mini"
  478. :disabled="!(checkedList.length == 1 && checkedList[0].deliveryStatus == '0')"
  479. :key="checkedList.length"
  480. @click="handlePurchaseReturn"
  481. >采购退货</el-button> -->
  482. <el-button type="primary" size="mini" @click="handlePaymentRequest">付款申请</el-button>
  483. <el-button
  484. type="primary"
  485. size="mini"
  486. @click="handleDownload"
  487. >批量导出</el-button>
  488. </el-button-group>
  489. </el-col>
  490. </el-row>
  491. <div style="display: flex;height:420px;">
  492. <el-super-table
  493. class="purchaseTable"
  494. v-model="tableData"
  495. ref="purchaseTable"
  496. :dict="dict"
  497. :columns="tableColumns"
  498. :selectable="setSelectable"
  499. index
  500. checkbox
  501. pagination
  502. :page="page"
  503. convenitentOperation
  504. @pagination="fetchList(params, page)"
  505. @row-dblclick="handleOpenSeeDrawer"
  506. @row-click="handleDetailsData"
  507. @selection-change="handleSelectionChange"
  508. @select="handleSelect"
  509. >
  510. <el-table-column fixed="right" label="操作" width="120">
  511. <template slot-scope="scope">
  512. <el-button
  513. v-if="judgeIsOption('revise',scope.row)"
  514. type="text"
  515. size="small"
  516. @click.stop="handleOpenEditDrawer(scope.row)"
  517. v-hasPermi="['material:order:edit']">
  518. 修订
  519. </el-button>
  520. <el-button
  521. v-if="judgeIsOption('edit',scope.row)"
  522. type="text"
  523. size="small"
  524. @click.stop="handleOpenEditDrawer(scope.row)"
  525. v-hasPermi="['material:order:edit']">
  526. 编辑
  527. </el-button>
  528. <!-- 0=自由态,1=审批中,2=已审核,3=已驳回 4=提交中-->
  529. <el-button
  530. v-if="judgeIsOption('del',scope.row)"
  531. type="text"
  532. size="small"
  533. @click.stop="handleDeleteList(scope.row)"
  534. v-hasPermi="['material:order:remove']"
  535. >删除</el-button>
  536. <el-button
  537. v-if="judgeIsOption('submit',scope.row)"
  538. type="text"
  539. size="mini"
  540. v-hasPermi="['material:order:toOa']"
  541. @click.stop="handleSubmit(scope.row)"
  542. >提交</el-button>
  543. <el-button
  544. v-if="scope.row.flowId && scope.row.flowId !== ''"
  545. type="text"
  546. size="mini"
  547. @click.stop="jumpFlow(scope.row)"
  548. >流程跳转</el-button>
  549. </template>
  550. </el-table-column>
  551. </el-super-table>
  552. </div>
  553. <div style="position: relative; padding-top: 10px;" v-loading="tabLoading">
  554. <el-row style="position: absolute; top: 30px; right: 20px;z-index: 10;">
  555. <el-button
  556. size="mini"
  557. @click="handleLineReturn"
  558. :disabled="judgeIsLineReturn()"
  559. >行退回</el-button>
  560. </el-row>
  561. <el-tabs
  562. v-model="tabName"
  563. @tab-click="handleTabClick"
  564. style="width: 100%;padding: 20px 10px;">
  565. <el-tab-pane
  566. v-for="(column, index) in tabColumns"
  567. :key="index"
  568. :label="column.title"
  569. :name="column.key"
  570. >
  571. <div style="height:580px;display:flex">
  572. <el-super-table
  573. v-model="tabTableDatas[column.key]"
  574. :ref="column.key"
  575. :dict="dict"
  576. :columns="column.tableColumns"
  577. :selectable="setTabSelectable"
  578. :checkbox="setTabSelectable()"
  579. convenitentOperation
  580. @select="handleTabSelect"
  581. @selection-change="handleTabSelectionChange"
  582. >
  583. </el-super-table>
  584. </div>
  585. </el-tab-pane>
  586. </el-tabs>
  587. </div>
  588. </el-card>
  589. </template>
  590. <style lang="scss">
  591. </style>