index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. <!-- 采购订单修订—— 列表 -->
  2. <script>
  3. import { TableColumns, SearchColumns, TabColumns, SelectColumns } from "./column";
  4. import orderApi from "@/api/business/purchase/purchase-order";
  5. import {
  6. initPage,
  7. initParams,
  8. initColumns,
  9. initDicts,
  10. } from "@/utils/init";
  11. import { clearTimeout } from "timers";
  12. export default {
  13. name: "PuchaseOrder",
  14. dicts: initDicts(SelectColumns),
  15. components: {
  16. AddDrawer: () => import('./add/index.vue'),
  17. SeeDrawer: () => import('./see/index.vue'),
  18. EditDrawer: () => import('./edit/index.vue'),
  19. },
  20. data() {
  21. const initTabColumns = () => TabColumns;
  22. return {
  23. loading: false,
  24. isSimpleSearch: true,
  25. pageSizes: [10, 20, 50, 100],
  26. page: initPage(),
  27. searchColumns: SearchColumns,
  28. params: initParams(SearchColumns),
  29. tableColumns: TableColumns,
  30. tableData: [],
  31. tabColumns: initTabColumns(),
  32. tabName: "puOrderItemList",
  33. tabTableDatas: {
  34. puOrderItemList: [],
  35. puOrderExecuteList: [],
  36. },
  37. checkedList: [],
  38. // 子表Select
  39. checkedTabList: [],
  40. // 主表点击信息
  41. primaryResource:{},
  42. timer:300,
  43. timeOut:null,
  44. };
  45. },
  46. computed: {
  47. showSearchColumns() {
  48. return this.isSimpleSearch
  49. ? this.searchColumns.slice(0, 4)
  50. : this.searchColumns;
  51. },
  52. },
  53. created() {
  54. // this.fetchList(this.params, this.page);
  55. this.handleRefreshList();
  56. },
  57. methods: {
  58. async fetchList(data, params) {
  59. try {
  60. this.loading = true;
  61. params['isAsc'] = 'desc';
  62. params['orderByColumn'] = 'updateTime';
  63. const { code, msg, rows, total } = await orderApi.list(data, params);
  64. if (code === 200) {
  65. this.page.total = total;
  66. this.tableData = rows;
  67. }
  68. } catch (err) {
  69. //
  70. } finally {
  71. this.loading = false;
  72. for (const key in this.tabTableDatas) {
  73. this.tabTableDatas[key] = [];
  74. }
  75. }
  76. },
  77. handleSearchChange() {
  78. this.isSimpleSearch = !this.isSimpleSearch;
  79. },
  80. // 刷新操作
  81. handleRefreshList() {
  82. this.page = initPage();
  83. this.checkedList = [];
  84. this.checkedTabList = [];
  85. this.primaryResource = {};
  86. this.fetchList(this.params, this.page);
  87. },
  88. // 查询操作
  89. handleQueryList() {
  90. let {date} = this.params;
  91. this.params.startDate = date ? date[0] :'';
  92. this.params.endDate = date ? date[1] : '';
  93. this.fetchList(this.params, this.page);
  94. },
  95. // 重置操作
  96. handleResetList() {
  97. this.page = initPage();
  98. this.params = initParams(SearchColumns);
  99. this.fetchList(this.params, this.page);
  100. },
  101. handleTabClick() { },
  102. // 新增
  103. handleOpenAddDrawer(copyVal) {
  104. const { setVisible, setCopyParams } = this.$refs.addDrawerFef;
  105. setVisible(true,(copyVal.id && copyVal.id != '') ? true :false);
  106. copyVal.id && copyVal.id != '' && setCopyParams(copyVal.id);
  107. },
  108. // 复制
  109. handleCopy() {
  110. // let rowDetails = {
  111. // ... this.checkedList[0],
  112. // id: '',
  113. // code: '',
  114. // status: '0',
  115. // source: '3',
  116. // };
  117. this.handleOpenAddDrawer(this.checkedList[0]);
  118. },
  119. // 查看
  120. async handleOpenSeeDrawer(row) {
  121. window.clearInterval(this.timeOut);
  122. const { id } = row;
  123. const { setVisible, fetchItem } = this.$refs.seeDrawerFef;
  124. await setVisible(true);
  125. await fetchItem(id);
  126. },
  127. // 编辑、修订
  128. async handleOpenEditDrawer(row) {
  129. const { id } = row;
  130. const { setVisible, fetchItem } = this.$refs.editDrawerFef;
  131. await setVisible(true);
  132. await fetchItem(id);
  133. },
  134. // 获取子表信息
  135. handleDetailsData(row) {
  136. window.clearTimeout(this.timeOut)
  137. this.timeOut = setTimeout(async () =>{
  138. try {
  139. this.primaryResource = row;
  140. this.checkedTabList = [];
  141. const { code, msg, data } = await orderApi.details(row.id);
  142. if (code === 200) {
  143. // 物料信息:puOrderItemList 执行结果:puOrderExecuteList
  144. for (const key in this.tabTableDatas) {
  145. this.tabTableDatas[key] = data[key];
  146. }
  147. }
  148. } catch (err) {}
  149. },this.timer)
  150. },
  151. // 操作提示弹窗
  152. handleConfirmTips(success){
  153. this.$confirm('是否继续此操作?', '提示', {
  154. confirmButtonText: '确定',
  155. cancelButtonText: '取消',
  156. type: 'warning'
  157. }).then(() => {
  158. success();
  159. }).catch(() => {
  160. this.$message({
  161. type: 'info',
  162. message: '已取消操作!'
  163. });
  164. });
  165. },
  166. // 删除操作
  167. handleDeleteList(row) {
  168. try {
  169. this.loading = true;
  170. this.handleConfirmTips(async()=>{
  171. const { id } = row;
  172. const { code } = await orderApi.remove(id);
  173. if (code === 200) {
  174. this.handleRefreshList();
  175. }
  176. })
  177. } catch (err) {
  178. //
  179. } finally {
  180. this.loading = false;
  181. }
  182. },
  183. // 提交
  184. handleSubmit(row) {
  185. try {
  186. this.handleConfirmTips(async()=>{
  187. let { code } = await orderApi.submit({ puOrderId: row.id });
  188. if (code == 200) {
  189. this.handleRefreshList();
  190. }
  191. })
  192. } catch (error) {
  193. } finally {
  194. }
  195. },
  196. // 判断“整单退回”按钮
  197. judgeIsAllReturn() {
  198. if (this.checkedList.length == 1) {
  199. // 非手工、状态:自由/驳回
  200. if (this.checkedList[0].source != 3 && (this.checkedList[0].status == 0 || this.checkedList[0].status == 3)) {
  201. return false
  202. }
  203. }
  204. return true;
  205. },
  206. // 整单退回
  207. handleAllReturn() {
  208. this.handleReturn(this.checkedList[0].id,[]);
  209. },
  210. // 判断“行退回”按钮
  211. judgeIsLineReturn() {
  212. if (this.checkedTabList.length == 1) {
  213. // 主信息:非手工、状态:自由/驳回
  214. if(this.primaryResource.source != 3 &&
  215. (this.primaryResource.status == 0 || this.primaryResource.status == 3) ){
  216. return false
  217. }
  218. }
  219. return true;
  220. },
  221. // 行退回
  222. handleLineReturn(){
  223. let ids = this.checkedTabList.map(checked => checked.id);
  224. console.log(ids,'行退回ids');
  225. this.handleReturn(this.primaryResource.id,ids);
  226. },
  227. // 退回接口
  228. handleReturn(id,documentIds){
  229. this.$prompt('请输入退回原因', '提示', {
  230. confirmButtonText: '确定',
  231. cancelButtonText: '取消',
  232. inputPattern: /\s*\S+?/,
  233. inputErrorMessage: '退回原因不能为空'
  234. }).then(async ({ value }) => {
  235. let data = {
  236. id,
  237. documentIds,
  238. baskCause: value,
  239. };
  240. console.log(data);
  241. try {
  242. let { code, msg } = await orderApi.documentsReturn(data);
  243. if (code === 200) {
  244. this.handleRefreshList();
  245. }
  246. } catch (error) {
  247. console.log(error,'error------------');
  248. }
  249. }).catch(() => { });
  250. },
  251. // 判断是否满足整单关闭
  252. judgeIsAllClose() {
  253. if (this.checkedList.length == 1) {
  254. if (this.checkedList[0].status == 0) {
  255. // 未审批状态下整单关闭
  256. return false
  257. }
  258. }
  259. return true;
  260. },
  261. // 整单关闭
  262. handleAllClose() {
  263. // 未审批状态下整单关闭
  264. try {
  265. this.handleDeleteList(async() =>{
  266. let puOrderIds = this.checkedList.map(order => {
  267. return order.id;
  268. })
  269. let { code } = await orderApi.close({ puOrderIds });
  270. if (code === 200) {
  271. this.handleRefreshList();
  272. }
  273. })
  274. } catch (error) { }
  275. },
  276. // 付款协议
  277. async handlePaymentRequest(){
  278. // name:工号
  279. try {
  280. // let {name} = this.$store.state.user;
  281. let {code,msg} = await orderApi.payRequest();
  282. if(code == 200){
  283. msg.replace(/\/n/g,'');
  284. let url = `uclient://start/http://172.16.100.2:8081?ssoKey=${msg}&uiloader=nc.uap.lfw.applet.PortalUILoader&nodeId=40040407`
  285. window.location.href = url;
  286. }
  287. } catch (error) {
  288. }
  289. },
  290. // 主表Select框
  291. handleSelect(selection, row) {
  292. this.checkedList = selection;
  293. console.log(this.checkedList, 'this.checkedList');
  294. },
  295. // 子表Select框
  296. handleTabSelect(selection, row){
  297. this.checkedTabList = selection;
  298. console.log(this.checkedTabList, 'this.checkedTabList');
  299. },
  300. }
  301. };
  302. </script>
  303. <template>
  304. <el-card
  305. v-loading="loading"
  306. style="width: calc(100% - 24px); height: 100%; margin: 10px"
  307. :body-style="{ padding: 0 }"
  308. >
  309. <SeeDrawer ref="seeDrawerFef"></SeeDrawer>
  310. <AddDrawer ref="addDrawerFef" @close="handleRefreshList"></AddDrawer>
  311. <EditDrawer ref="editDrawerFef" @close="handleRefreshList"></EditDrawer>
  312. <el-form
  313. size="mini"
  314. label-position="right"
  315. label-width="100px"
  316. :model="params"
  317. style="padding: 20px 0 0 0"
  318. >
  319. <el-row :gutter="24" >
  320. <el-col :span="20">
  321. <el-row :gutter="20" style="display:flex; flex-wrap: wrap;">
  322. <el-col
  323. v-for="column in showSearchColumns"
  324. :key="column.title"
  325. :xl="6" :lg="6" :md="8" :sm="12" :xs="24"
  326. >
  327. <el-form-item :prop="column.key" :label="column.title">
  328. <el-input v-if="column.inputType === 'Input'"
  329. v-model="params[column.key]"
  330. :placeholder="column.placeholder"
  331. @keyup.enter.native="fetchList(params, page)"
  332. ></el-input>
  333. <dr-popover-select v-if="column.inputType === 'PopoverSelect'"
  334. v-model="params[column.key]"
  335. :source.sync="params"
  336. :title="column.title"
  337. :type="column.referName"
  338. :multiple="column.multiple"
  339. :readonly="column.readonly"
  340. :value-key="column.valueKey"
  341. :placeholder="column.placeholder"
  342. :data-mapping="column.dataMapping"
  343. :query-params="column.queryParams"
  344. :clearable="column.clearable"
  345. @keyup.enter.native="fetchList(params, page)"
  346. ></dr-popover-select>
  347. <!-- @keyup.enter.native="useQuery(params, page)" -->
  348. <el-select v-if="column.inputType === 'Select'"
  349. v-model="params[column.key]"
  350. :disabled="column.disabled"
  351. :clearable="column.clearable"
  352. :placeholder="column.placeholder"
  353. :multiple="column.multiple"
  354. :collapse-tags="column.tags"
  355. style="width: 100%"
  356. @keyup.enter.native="fetchList(params, page)"
  357. >
  358. <el-option
  359. v-for="item in dict.type[column.referName]"
  360. :key="item.value"
  361. :label="item.label"
  362. :value="item.value"
  363. ></el-option>
  364. </el-select>
  365. <!-- 只有是否 -->
  366. <el-select v-if="column.inputType === 'SelectCheck'"
  367. v-model="params[column.key]"
  368. :disabled="column.disabled"
  369. :clearable="column.clearable"
  370. :placeholder="column.placeholder"
  371. style="width: 100%"
  372. @keyup.enter.native="fetchList(params, page)"
  373. >
  374. <el-option key="N" label="否" value="N"></el-option>
  375. <el-option key="Y" label="是" value="Y"></el-option>
  376. </el-select>
  377. <el-date-picker v-if="column.inputType === 'DatePicker'"
  378. v-model="params[column.key]"
  379. size="mini"
  380. type="daterange"
  381. :value-format="column.valueFormat"
  382. :unlink-panels="column.unlinkPanels"
  383. :picker-options="column.pickerOptions"
  384. :range-separator="column.rangeSeparator"
  385. :end-placeholder="column.endPlaceholder"
  386. :start-placeholder="column.startPlaceholder"
  387. :clearable="column.clearable"
  388. style="width: 100%"
  389. @keyup.enter.native="fetchList(params, page)"
  390. >
  391. </el-date-picker>
  392. </el-form-item>
  393. </el-col>
  394. </el-row>
  395. </el-col>
  396. <el-col :span="4" style="text-align: right; padding-right: 40px">
  397. <el-button type="primary" size="mini" @click="handleQueryList"
  398. v-hasPermi="['material:order:query']">搜索</el-button>
  399. <el-button size="mini" @click="handleResetList">重置</el-button>
  400. </el-col>
  401. </el-row>
  402. </el-form>
  403. <el-divider>
  404. <i :class="isSimpleSearch ? 'el-icon-arrow-down' : 'el-icon-arrow-up'" style="cursor: pointer"
  405. @click="handleSearchChange"></i>
  406. </el-divider>
  407. <!-- 操作 -->
  408. <el-row :gutter="24" style="padding: 0 20px">
  409. <!-- <el-col :span="6">123</el-col> -->
  410. <el-col :span="24" style="text-align: right;margin: 0 10px 0 0">
  411. <!-- <el-button-group style="margin-left: 10px"> -->
  412. <el-button size="mini" type="primary" plain @click="handleOpenAddDrawer"
  413. v-hasPermi="['material:order:add']">新增</el-button>
  414. <!-- </el-button-group> -->
  415. <el-button-group style="margin-left: 10px">
  416. <el-button size="mini" :disabled="checkedList.length != 1" @click="handleCopy">复制</el-button>
  417. </el-button-group>
  418. <el-button-group style="margin-left: 10px" :key="checkedList.length + 1">
  419. <el-button size="mini" @click="handleAllReturn" :disabled="judgeIsAllReturn()">整单退回</el-button>
  420. <el-button size="mini" @click="handleAllClose" :disabled="judgeIsAllClose()">整单关闭</el-button>
  421. </el-button-group>
  422. <el-button-group style="margin-left: 10px">
  423. <!-- <el-button size="mini">采购退货</el-button> -->
  424. <el-button size="mini" @click="handlePaymentRequest">付款申请</el-button>
  425. <!-- <el-button size="mini">附件管理</el-button>
  426. <el-button size="mini">单据追溯</el-button> -->
  427. </el-button-group>
  428. </el-col>
  429. </el-row>
  430. <el-table
  431. @row-dblclick="handleOpenSeeDrawer"
  432. @row-click="handleDetailsData"
  433. :data="tableData"
  434. size="mini"
  435. highlight-current-row
  436. @select="handleSelect"
  437. height="450"
  438. style="width: 100%; margin: 20px 0 0 0"
  439. >
  440. <el-table-column type="selection" width="45" ></el-table-column>
  441. <el-table-column type="index" width="50" label="序号"></el-table-column>
  442. <el-table-column
  443. v-for="(column, index) in tableColumns"
  444. :key="index"
  445. :prop="column.key"
  446. :label="column.title"
  447. :width="column.width || 180"
  448. :show-overflow-tooltip="column.showOverflowTooltip || true"
  449. >
  450. <template slot-scope="scope">
  451. <dict-tag v-if="column.inputType === 'Select'"
  452. size="small"
  453. :value="scope.row[column.key]"
  454. :options="dict.type[column.referName]"
  455. />
  456. <el-checkbox v-else-if="column.inputType === 'Checkbox'"
  457. v-model="scope.row[column.key]"
  458. disabled
  459. true-label="Y"
  460. false-label="N"
  461. > </el-checkbox>
  462. <span v-else>{{ scope.row[column.key] }}</span>
  463. </template>
  464. </el-table-column>
  465. <el-table-column fixed="right" label="操作" width="120">
  466. <template slot-scope="scope">
  467. <!-- <el-button @click.stop="handleOpenSeeDrawer(scope.row)" type="text" size="small">查看</el-button> -->
  468. <el-button
  469. v-if="scope.row.status == '2'"
  470. type="text"
  471. size="small"
  472. @click.stop="handleOpenEditDrawer(scope.row)"
  473. v-hasPermi="['material:order:edit']">
  474. 修订
  475. </el-button>
  476. <el-button
  477. v-if="scope.row.status == '0' || scope.row.status == '3'"
  478. type="text"
  479. size="small"
  480. @click.stop="handleOpenEditDrawer(scope.row)"
  481. v-hasPermi="['material:order:edit']">
  482. 编辑
  483. </el-button>
  484. <!-- 0=自由态,1=审批中,2=已审核,3=已驳回 4=提交中-->
  485. <el-button
  486. v-if="(scope.row.status == '0' || scope.row.status == '3') && scope.row.source == '3'"
  487. type="text"
  488. size="small"
  489. @click.stop="handleDeleteList(scope.row)"
  490. v-hasPermi="['material:order:remove']"
  491. >删除</el-button>
  492. <el-button
  493. v-if="scope.row.status == '0' || scope.row.status == '3'"
  494. type="text"
  495. size="mini"
  496. v-hasPermi="['material:order:toOa']"
  497. @click.stop="handleSubmit(scope.row)"
  498. >提交</el-button>
  499. </template>
  500. </el-table-column>
  501. </el-table>
  502. <pagination
  503. v-show="page.total>0"
  504. :total="page.total"
  505. :page.sync="page.pageNum"
  506. :limit.sync="page.pageSize"
  507. @pagination="fetchList(params, page)"
  508. />
  509. <div style="position: relative; padding-top: 10px;">
  510. <el-row style="position: absolute; top: 30px; right: 20px;z-index: 10;">
  511. <el-button
  512. size="mini"
  513. @click="handleLineReturn"
  514. :disabled="judgeIsLineReturn()"
  515. >行退回</el-button>
  516. </el-row>
  517. <el-tabs v-model="tabName" @tab-click="handleTabClick" style="width: 100%;padding: 20px 10px">
  518. <el-tab-pane
  519. v-for="(column, index) in tabColumns"
  520. :key="index"
  521. :label="column.title"
  522. :name="column.key"
  523. >
  524. <el-table
  525. :data="tabTableDatas[column.key]"
  526. style="width: 100%"
  527. highlight-current-row
  528. :height="tabTableDatas[column.key].length ? 300 : 100"
  529. @select="handleTabSelect"
  530. >
  531. <el-table-column
  532. v-if=" tabName === 'puOrderItemList'"
  533. type="selection"
  534. width="45"
  535. ></el-table-column>
  536. <el-table-column type="index" width="50" label="序号"></el-table-column>
  537. <el-table-column
  538. v-for="(cColumn, cIndex) in column.tableColumns"
  539. :key="cIndex"
  540. :prop="cColumn.key"
  541. :label="cColumn.title"
  542. :width="cColumn.width || 180"
  543. :show-overflow-tooltip="cColumn.showOverflowTooltip || true"
  544. >
  545. <template slot-scope="scope">
  546. <dict-tag v-if="cColumn.referName"
  547. size="small"
  548. :value="scope.row[cColumn.key]"
  549. :options="dict.type[cColumn.referName]"
  550. />
  551. <el-checkbox v-else-if="cColumn.inputType === 'Checkbox'"
  552. v-model="scope.row[cColumn.key]"
  553. disabled
  554. true-label="Y"
  555. false-label="N"
  556. ></el-checkbox>
  557. <span v-else>{{ scope.row[cColumn.key] }}</span>
  558. </template>
  559. </el-table-column>
  560. </el-table>
  561. </el-tab-pane>
  562. </el-tabs>
  563. </div>
  564. </el-card>
  565. </template>