financialAccount.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. <template>
  2. <div>
  3. <basic-container>
  4. <avue-crud
  5. ref="crud"
  6. :data="data"
  7. :option="option"
  8. :table-loading="loading"
  9. @row-update="rowUpdate"
  10. @row-del="rowDel"
  11. @saveColumn="saveColumn"
  12. @resetColumn="resetColumn"
  13. >
  14. <template slot="menuLeft" slot-scope="{size}">
  15. <el-button type="primary"
  16. icon="el-icon-plus"
  17. size="small"
  18. :loading="submitButton"
  19. @click="entering"
  20. >录入
  21. </el-button>
  22. </template>
  23. <template slot-scope="{row,index}" slot="menu">
  24. <el-button
  25. type="text"
  26. size="small"
  27. icon="el-icon-edit"
  28. @click="rowCell(row,index)"
  29. >{{ row.$cellEdit ? '保存' : '修改' }}
  30. </el-button>
  31. <el-button
  32. type="text"
  33. icon="el-icon-delete"
  34. size="small"
  35. @click="rowDel(row,index)"
  36. >删除</el-button>
  37. </template>
  38. <template slot-scope="{row,index}" slot="corpId">
  39. <span v-if="row.$cellEdit && category != 2" class="required_fields" style="float: left;line-height: 32px">*</span>
  40. <span v-if="row.$cellEdit && category != 2" style="display: flex">
  41. <el-select
  42. v-model="corpId"
  43. placeholder="请选择"
  44. size="small"
  45. style="width:60%"
  46. filterable
  47. >
  48. <el-option
  49. v-for="item in corpOption"
  50. :key="item.id"
  51. :label="item.cname"
  52. :value="item.id"
  53. />
  54. </el-select>
  55. <el-button
  56. icon="el-icon-search"
  57. size="small"
  58. @click="openDialog(row, index, 1)"
  59. ></el-button>
  60. </span>
  61. <span v-else>{{corpsName}}</span>
  62. </template>
  63. <template slot-scope="{row,index}" slot="costType">
  64. <breakdown-select
  65. v-if="row.$cellEdit"
  66. v-model="row.costType"
  67. style="width: 90%"
  68. :configuration="configuration"
  69. @selectValue="(value) => {getFeeValue(row, value)}"
  70. >
  71. </breakdown-select>
  72. <span v-else>{{ row.costName }}</span>
  73. </template>
  74. <template slot-scope="{row,index}" slot="billNo">
  75. <el-select placeholder="请选择"
  76. v-if="row.$cellEdit"
  77. v-model="row.billNo"
  78. size="small"
  79. filterable
  80. allow-create
  81. default-first-option
  82. clearable>
  83. <el-option
  84. v-for="item in row.billNoList"
  85. :key="item"
  86. :label="item"
  87. :value="item"
  88. ></el-option>
  89. </el-select>
  90. <span v-else>{{ row.billNo }}</span>
  91. </template>
  92. <template slot-scope="{row,index}" slot="taxRate">
  93. <el-input
  94. v-model="row.taxRate"
  95. v-if="row.$cellEdit"
  96. size="small"
  97. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d\d\d\d\d).*$/, "$1.$2")'
  98. autocomplete="off"
  99. >
  100. <i slot="suffix" style="margin-right: 10px;top:6px">%</i>
  101. </el-input>
  102. <span v-else>{{ row.taxRate }}</span>
  103. </template>
  104. <template slot-scope="{row,index}" slot="currency">
  105. <span v-if="row.$cellEdit" class="required_fields">*</span>
  106. <el-select v-if="row.$cellEdit" v-model="row.currency" size="small" placeholder="请选择" style="width: 90%" @change="currencyChange(row)" clearable filterable>
  107. <el-option v-for="(item,index) in currencyDic" :key="index" :label="item.dictValue" :value="item.dictValue"></el-option>
  108. </el-select>
  109. <span v-else>{{ row.currency }}</span>
  110. </template>
  111. <template slot-scope="{row,index}" slot="unit">
  112. <el-select v-if="row.$cellEdit" v-model="row.unit" size="small" style="width: 90%" placeholder="请选择" clearable filterable>
  113. <el-option v-for="(item,index) in unitDic" :key="index" :label="item.dictValue" :value="item.dictValue"></el-option>
  114. </el-select>
  115. <span v-else>{{ row.unit }}</span>
  116. </template>
  117. <template slot-scope="{row,index}" slot="price">
  118. <el-input-number
  119. v-if="row.$cellEdit"
  120. v-model="row.price"
  121. size="small"
  122. :controls="false"
  123. :precision="2"
  124. @input="amountChange(row)"
  125. style="width: 100%"
  126. />
  127. <span v-else>{{ Number(row.price).toFixed(2) }}</span>
  128. </template>
  129. <template slot-scope="{row,index}" slot="quantity">
  130. <el-input-number
  131. v-if="row.$cellEdit"
  132. v-model="row.quantity"
  133. size="small"
  134. :controls="false"
  135. :precision="0"
  136. @input="amountChange(row)"
  137. style="width: 100%"
  138. />
  139. <span v-else>{{ row.quantity }}</span>
  140. </template>
  141. </avue-crud>
  142. <div class="dialogButton">
  143. <el-button size="small" :loading="submitButton" @click="$emit('choceFun')">取消</el-button>
  144. <el-button type="primary" size="small" :loading="submitButton" @click="submit()">确定</el-button>
  145. </div>
  146. </basic-container>
  147. <containerTitle v-if="billId" title="历史账单"></containerTitle>
  148. <basic-container v-if="billId">
  149. <avue-crud :option="historyOption"
  150. :data="historyDataList"
  151. ref="historyCrud"
  152. v-model="historyForm"
  153. :page.sync="page"
  154. :table-loading="historyLoading"
  155. @on-load="onLoad">
  156. </avue-crud>
  157. </basic-container>
  158. <el-dialog
  159. title="客户、供应商"
  160. :visible.sync="corpVisible"
  161. width="80%"
  162. top="5vh"
  163. append-to-body
  164. @closed="closeCorp"
  165. class="el-dialogDeep"
  166. v-dialog-drag
  167. >
  168. <span>
  169. <el-row>
  170. <el-col :span="4">
  171. <el-scrollbar>
  172. <basic-container>
  173. <avue-tree
  174. :option="corpTreeOption"
  175. :data="treeData"
  176. @node-click="corpNodeClick"
  177. :style="treeStyle"
  178. />
  179. </basic-container>
  180. </el-scrollbar>
  181. </el-col>
  182. <el-col :span="20">
  183. <avue-crud
  184. :option="KHOption"
  185. :data="corpData"
  186. ref="crud"
  187. :page.sync="corpPage"
  188. :search.sync="corpSearch"
  189. @search-change="corpSearchChange"
  190. @search-reset="corpSearchReset"
  191. @selection-change="selectionChange"
  192. @current-change="corpCurrentChange"
  193. @size-change="corpSizeChange"
  194. @on-load="corpOnLoad"
  195. @tree-load="corpTreeLoad"
  196. @saveColumn="saveColumn"
  197. @resetColumn="resetColumn"
  198. @refresh-change="corpRefreshChange"
  199. :table-loading="dialogLoading"
  200. >
  201. </avue-crud>
  202. </el-col>
  203. </el-row>
  204. </span>
  205. <span slot="footer" class="dialog-footer">
  206. <el-button @click="corpVisible = false">取 消</el-button>
  207. <el-button
  208. type="primary"
  209. @click="importCorp"
  210. :disabled="selectionList.length != 1"
  211. >确 定</el-button
  212. >
  213. </span>
  214. </el-dialog>
  215. </div>
  216. </template>
  217. <script>
  218. import {applyLoan, paymentApply} from "@/api/financialManagement/paymentRequest";
  219. import option from "./config/option.json"
  220. import historyOption from "../bill/config/application.json"
  221. import {getUserInfo} from "@/api/system/user";
  222. import { getBillList } from "@/api/financialManagement/paymentRequest";
  223. import {customerList, getDeptLazyTree} from "@/api/basicData/customerInformation";
  224. import { getDeptLazyTree as getFeeLazyTree, customerList as feeList } from "@/api/basicData/basicFeesDesc";
  225. import corpOption from './config/corpOption.json'
  226. export default {
  227. name: "financialAccount",
  228. props: {
  229. billId:{
  230. type:String
  231. },
  232. billType: {
  233. type: String
  234. },
  235. srcType: {
  236. type: Number,
  237. default: 1,
  238. },
  239. billData: {
  240. type: Object
  241. },
  242. choceFun: {
  243. type: Function
  244. },
  245. arrList: {
  246. type: Array,
  247. default: []
  248. },
  249. checkData: {
  250. type: Object,
  251. default: {
  252. url: null,
  253. pageStatus: null,
  254. pageLabel: null,
  255. checkType: null
  256. },
  257. },
  258. belongCompany: {
  259. type: String,
  260. }
  261. },
  262. data(){
  263. return {
  264. data: [],
  265. corpId:'',
  266. corpsName: '',
  267. option:option,
  268. loading:false,
  269. submitButton:false,
  270. currencyDic:[],
  271. unitDic:[],
  272. configuration: {
  273. multipleChoices: false,
  274. multiple: false,
  275. disabled: true,
  276. searchShow: true,
  277. collapseTags: false,
  278. placeholder: '请点击右边按钮选择',
  279. dicData: []
  280. },
  281. category: '',
  282. historyLoading:false,
  283. historyOption:historyOption,
  284. historyDataList:[],
  285. historyForm:{},
  286. page: {
  287. pageSize: 10,
  288. pagerCount: 1,
  289. total: 0,
  290. },
  291. corpOption: [], //客户
  292. feeOption: [], // 费用
  293. rowData: null,
  294. corpVisible: false,
  295. feeVisible: false,
  296. treeStyle:'height:'+(window.innerHeight - 315)+'px',
  297. corpTreeOption: {
  298. nodeKey: "id",
  299. lazy: true,
  300. addBtn: false,
  301. menu: false,
  302. size: "small",
  303. props: {
  304. labelText: "标题",
  305. label: "title",
  306. value: "value",
  307. children: "children"
  308. }
  309. },
  310. treeCorpId: '',
  311. selectionList: [],
  312. corpPage: {
  313. currentPage: 1,
  314. pageSize: 10,
  315. total: 0
  316. },
  317. corpSearch: {},
  318. dialogLoading: false,
  319. KHOption: corpOption,
  320. corpData: [],
  321. }
  322. },
  323. created() {
  324. this.historyOption.searchShow = false
  325. customerList({
  326. size: 10000,
  327. current: 1
  328. }).then(res => {
  329. // this.corpOption = res.data.data.records? res.data.data.records: [];
  330. if (res.data.data.total > 0) {
  331. this.corpOption = res.data.data.records;
  332. if (Math.ceil(res.data.data.total / 10) > 1) {
  333. for (let i = 2; i <= Math.ceil(res.data.data.total / 10); i++) {
  334. customerList({current: i, size: 10}).then(e => {
  335. this.corpOption = this.corpOption.concat(e.data.data.records);
  336. });
  337. }
  338. }
  339. }
  340. })
  341. this.loading = true;
  342. feeList({size: 10000, current: 1}).then(res => {
  343. this.feeOption = res.data.data.records? res.data.data.records: [];
  344. this.init()
  345. }).finally(() => {
  346. this.loading = false;
  347. })
  348. getUserInfo().then(res=>{
  349. this.category = res.data.data.billType
  350. if (this.category == 2) {
  351. }
  352. })
  353. //币别
  354. this.getWorkDicts("currency").then(res => {
  355. this.currencyDic = res.data.data
  356. })
  357. this.getWorkDicts("unit").then(res => {
  358. this.unitDic = res.data.data
  359. })
  360. },
  361. mounted() {
  362. // this.init()
  363. },
  364. watch:{
  365. billId(val, oldVal) {
  366. if(val != oldVal){
  367. this.onLoad(this.page)
  368. }
  369. },
  370. },
  371. methods:{
  372. init(){
  373. if(this.arrList.length === 0){
  374. this.corpId = this.billData.corpId
  375. this.corpsName = this.billData.corpsName[0].cname
  376. this.feeOption.forEach(item => {
  377. if (this.billData.costType == item.id) {
  378. this.$set(this.billData, 'costName', item.cname)
  379. }
  380. })
  381. this.data.push(this.billData)
  382. }else{
  383. this.billData = this.arrList[0]
  384. this.corpId = this.arrList[0].corpId
  385. this.corpsName = this.arrList[0].corpsName[0].cname
  386. this.arrList.forEach(item=>{
  387. this.feeOption.forEach(e => {
  388. if (item.costType == e.id) {
  389. this.$set(item, 'costName', e.cname)
  390. }
  391. })
  392. this.data.push(item)
  393. })
  394. }
  395. //删除 提单号
  396. if(this.billData.optionType !== "JK"){
  397. this.option.column.forEach(item =>{
  398. if(item.prop === "billNo"){
  399. item.hide = true
  400. }else{
  401. item.hide = false
  402. }
  403. })
  404. }
  405. },
  406. currencyChange(row){
  407. this.currencyDic.forEach(item =>{
  408. if(item.dictValue === row.currency){
  409. row.exchangeRate = item.remark
  410. }
  411. })
  412. },
  413. rowCell(row,index){
  414. // this.$refs.crud.rowCell(row, index)
  415. if (row.$cellEdit == true) {
  416. this.$set(row, '$cellEdit', false)
  417. } else {
  418. this.$set(row, '$cellEdit', true)
  419. }
  420. },
  421. rowDel(row,index){
  422. this.$confirm("确定将选择数据删除?", {
  423. confirmButtonText: "确定",
  424. cancelButtonText: "取消",
  425. type: "warning"
  426. }).then(() => {
  427. this.data.splice(index, 1);
  428. })
  429. },
  430. rowUpdate(row, index, done, loading) {
  431. done(row);
  432. },
  433. entering(){
  434. if(this.data.length !== 0){
  435. //取第一条数据的 合同号 以及客户
  436. let params = {
  437. ...this.billData,
  438. srcOrderno:this.data[0].srcOrderno,
  439. corpId:this.data[0].corpId
  440. }
  441. this.$refs.crud.rowCellAdd(params);
  442. }else{
  443. this.$refs.crud.rowCellAdd(this.billData);
  444. }
  445. },
  446. onLoad(page,params = {}) {
  447. this.historyLoading = true;
  448. params.srcParentId = this.billId
  449. params.flag = 1
  450. getBillList(page.currentPage, page.pageSize,params).then(res=>{
  451. this.historyDataList = res.data.data.records
  452. }).finally(()=>{
  453. this.historyLoading = false;
  454. })
  455. },
  456. submit(){
  457. for(let i = 0;i<this.data.length;i++){
  458. if (this.corpId === (null || "")) {
  459. return this.$message.error(`请输入第${i + 1}行的客户`);
  460. }
  461. if (this.data[i].costType === (null || "")) {
  462. return this.$message.error(`请输入第${i + 1}行的费用名称`);
  463. }
  464. if (this.data[i].accDate === (null || "")) {
  465. return this.$message.error(`请输入第${i + 1}行的合同日期`);
  466. }
  467. if (this.data[i].amount === (null || "")) {
  468. return this.$message.error(`请输入第${i + 1}行的金额`);
  469. }
  470. if (this.data[i].currency === (null || "")) {
  471. return this.$message.error(`请输入第${i + 1}行的币别`);
  472. }
  473. if (this.data[i].exchangeRate === (null || "")) {
  474. return this.$message.error(`请输入第${i + 1}行的汇率`);
  475. }
  476. if (this.data[i].taxRate === (null || "")) {
  477. return this.$message.error(`请输入第${i + 1}行的税率`);
  478. }
  479. }
  480. this.submitButton = true
  481. const itemsList = this.data.map(item => {
  482. item.corpId = this.corpId;
  483. item.tradeType = this.billData.optionType?this.billData.optionType: item.tradeType
  484. item.srcType = this.srcType
  485. return item
  486. })
  487. const params = {
  488. url: this.checkData.url,
  489. pageStatus: this.checkData.pageStatus,
  490. pageLabel: this.checkData.pageLabel,
  491. checkType: this.checkData.checkType,
  492. billType : this.billType,
  493. DC : this.billData.itemType === "采购"?"C":"D", //账单明细会根据D C区分采购 销售搜索
  494. itemsList: itemsList,
  495. belongCompany: this.belongCompany // 所属公司
  496. }
  497. // 采购申请货款 销售申请退款 都会走申请 走审核 => 付款申请
  498. if(this.billType === "申请"){
  499. applyLoan(params).then(res =>{
  500. if(res.data.success){
  501. this.$message.success("操作成功!")
  502. this.$emit("choceFun");
  503. //跳转付款申请页面
  504. // if(this.$store.getters.pqStatus){
  505. // this.$alert("无法自动跳,因为付费申请页面已存在!", "温馨提示", {
  506. // confirmButtonText: "确定",
  507. // type: 'warning',
  508. // callback: action => {
  509. // }
  510. // });
  511. // }else{
  512. // //关闭一下存在的列表页 跳转
  513. // this.$router.$avueRouter.closeTag('/financialManagement/paymentRequest/index');
  514. // this.$router.push({
  515. // path: "/financialManagement/paymentRequest/index",
  516. // query: {params: res.data.data.id},
  517. // });
  518. // }
  519. }
  520. }).finally(()=>{
  521. this.submitButton = false
  522. })
  523. }
  524. //采购退款结算 销售收款结算 不需申请请核 直接结算 => 结算
  525. if(this.billType === "收费"){
  526. paymentApply(params).then(res=>{
  527. if(res.data.success){
  528. this.$message.success("操作成功!")
  529. this.$emit("choceFun");
  530. }
  531. }).finally(()=>{
  532. this.submitButton = false
  533. })
  534. }
  535. },
  536. saveColumn(){
  537. },
  538. resetColumn(){
  539. },
  540. amountChange(row) {
  541. if (!row.quantity) {
  542. row.quantity = 0;
  543. }
  544. if (!row.price) {
  545. row.price = 0;
  546. }
  547. row.amount = Number(row.price) * Number(row.quantity)
  548. },
  549. // 客户、费用弹窗
  550. openDialog(row, index, type) {
  551. this.rowData = {
  552. ...row,
  553. index
  554. }
  555. // 1客户 2费用
  556. if (type == 1) {
  557. this.corpTreeOption.treeLoad = function(node, resolve) {
  558. const parentId = node.level === 0 ? 0 : node.data.id;
  559. getDeptLazyTree({
  560. parentId: parentId,
  561. corpType: "KG"
  562. }).then(res => {
  563. resolve(
  564. res.data.data.map(item => {
  565. return {
  566. ...item,
  567. leaf: !item.hasChildren
  568. };
  569. })
  570. );
  571. });
  572. };
  573. this.corpVisible = !this.corpVisible;
  574. } else if (type == 2) {
  575. this.feeVisible = !this.feeVisible;
  576. }
  577. },
  578. selectionChange(list) {
  579. this.selectionList = list;
  580. },
  581. closeCorp() {
  582. this.selectionList = [];
  583. this.treeCorpId = "";
  584. this.reData = null;
  585. },
  586. corpNodeClick(data) {
  587. this.treeCorpId = data.id;
  588. this.corpPage.currentPage = 1;
  589. this.corpOnLoad(this.corpPage);
  590. },
  591. //列表内展开树节点
  592. corpTreeLoad(tree, treeNode, resolve) {
  593. const parentId = tree.id;
  594. customerList({ parentId: parentId }).then(res => {
  595. resolve(res.data.data.records);
  596. });
  597. },
  598. //点击搜索按钮触发
  599. corpSearchChange(params, done) {
  600. this.corpPage.currentPage = 1;
  601. this.corpOnLoad(this.corpPage, params);
  602. done();
  603. },
  604. corpSearchReset() {
  605. this.treeCorpId = null;
  606. },
  607. corpSizeChange(val) {
  608. this.corpPage.pageSize = val;
  609. this.corpOnLoad();
  610. },
  611. corpCurrentChange(val) {
  612. this.corpPage.currentPage = val;
  613. this.corpOnLoad();
  614. },
  615. corpRefreshChange() {
  616. this.corpOnLoad(this.corpPage, this.corpSearch);
  617. },
  618. corpOnLoad(page, params = { parentId: 0 }) {
  619. let queryParams = Object.assign({}, params, {
  620. size: page.pageSize,
  621. current: page.currentPage,
  622. corpsTypeId: this.treeDeptId,
  623. corpType: 'KG'
  624. });
  625. this.dialogLoading = true;
  626. customerList(queryParams)
  627. .then(res => {
  628. this.corpData = res.data.data.records;
  629. this.corpPage.total = res.data.data.total;
  630. if (this.corpPage.total) {
  631. this.KHOption.height = window.innerHeight - 350;
  632. }
  633. })
  634. .finally(() => {
  635. this.dialogLoading = false;
  636. });
  637. },
  638. importCorp() {
  639. this.corpData.forEach((item, index) => {
  640. if (index == this.rowData.index) {
  641. item.corpId = this.selectionList[0].id;
  642. }
  643. })
  644. this.corpVisible = false;
  645. },
  646. getFeeValue(row, value) {
  647. this.$set(row, 'costName', value.cname)
  648. }
  649. }
  650. }
  651. </script>
  652. <style scoped lang="scss">
  653. .required_fields{
  654. color: #F56C6C;
  655. display:inline-block;
  656. width: 7%
  657. }
  658. </style>