queryPart.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. <template>
  2. <div class="productInfoList-wrap" style="position: relative;">
  3. <!-- 搜索条件 -->
  4. <div class="table-page-search-wrapper">
  5. <a-form layout="inline" @keyup.enter.native="searchTable">
  6. <a-row :gutter="15">
  7. <a-col :md="4" :sm="24">
  8. <a-form-item label="产品名称">
  9. <a-input id="productInfoList-name" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
  10. </a-form-item>
  11. </a-col>
  12. <a-col :md="4" :sm="24">
  13. <a-form-item label="产品编码">
  14. <a-input id="productInfoList-code" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
  15. </a-form-item>
  16. </a-col>
  17. <a-col :md="4" :sm="24" v-if="hasPrompActive">
  18. <a-form-item label="产品类型">
  19. <a-select allowClear v-model.trim="queryParam.promotionFlag" :dropdownMatchSelectWidth="false" placeholder="请选择产品类型">
  20. <a-select-option value="0">
  21. 正常产品
  22. </a-select-option>
  23. <a-select-option value="REGULAR">
  24. 正价产品(活动)
  25. </a-select-option>
  26. <a-select-option value="DISCOUNT">
  27. 特价产品
  28. </a-select-option>
  29. <a-select-option value="GIFT">
  30. 促销产品
  31. </a-select-option>
  32. <a-select-option value="convertPromoGiftsFlag" v-if="showConvertPromoGifts">
  33. 促销产品(转采购额)
  34. </a-select-option>
  35. <a-select-option value="GATE">
  36. 门槛产品
  37. </a-select-option>
  38. </a-select>
  39. </a-form-item>
  40. </a-col>
  41. <a-col :md="4" :sm="24">
  42. <a-form-item label="下推类型">
  43. <a-select allowClear v-model.trim="queryParam.pushProductType" :dropdownMatchSelectWidth="false" placeholder="请选择下推类型">
  44. <a-select-option value="">
  45. 全部产品
  46. </a-select-option>
  47. <a-select-option value="ABLE">
  48. 剩余待下推数量>0的产品
  49. </a-select-option>
  50. <a-select-option value="ALL">
  51. 可全部下推的产品
  52. </a-select-option>
  53. <a-select-option value="NOTALL">
  54. 不可全部下推的产品
  55. </a-select-option>
  56. </a-select>
  57. </a-form-item>
  58. </a-col>
  59. <a-col :md="4" :sm="24">
  60. <a-form-item label="出库仓库">
  61. <chooseWarehouse ref="warehouse" v-model="queryParam.warehouseSn"></chooseWarehouse>
  62. </a-form-item>
  63. </a-col>
  64. <a-col :md="4" :sm="24" style="margin-bottom: 10px;">
  65. <a-button type="primary" @click="searchTable" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
  66. <a-button style="margin-left: 5px" @click="resetSearchForm(null)" id="productInfoList-reset">重置</a-button>
  67. </a-col>
  68. </a-row>
  69. </a-form>
  70. </div>
  71. <!-- alert -->
  72. <div style="margin-bottom: 10px;display: flex;align-items: center;" v-if="detailData">
  73. <div style="display: flex;align-items: center;">
  74. <span v-if="selectedRowKeys.length">已选 {{ selectedRowKeys.length }} 项</span>
  75. <a-button id="dispatch-plAdd" type="primary" :disabled="newLoading" class="button-info" @click="handlePlAdd">批量添加</a-button>
  76. <a-button
  77. id="dispatch-plPurchase"
  78. type="primary"
  79. :disabled="newLoading"
  80. class="button-info"
  81. v-if="showConvertPromoGifts"
  82. @click="handlePlPurchase">批量转采购额</a-button>
  83. <a-button
  84. id="dispatch-plCancel"
  85. type="primary"
  86. v-if="hasNormalProduct"
  87. ghost
  88. style="margin-left:6px;"
  89. :disabled="newLoading"
  90. @click="handlePlCancel">批量取消</a-button>
  91. <a-button
  92. id="dispatch-cancelAll"
  93. type="primary"
  94. v-if="hasPrompActive&&hasNoPushedActive"
  95. ghost
  96. style="margin-left:6px;"
  97. :disabled="newLoading"
  98. @click="handleAllCancel">整单取消</a-button>
  99. <a-tooltip placement="top" v-if="hasPrompActive&&hasNoPushedActive" style="margin-left:6px;">
  100. <template slot="title">
  101. <span>参加促销活动的产品,不能单独取消,只能整单取消。</span>
  102. </template>
  103. <a-icon style="font-size: 14px;" type="question-circle" />
  104. </a-tooltip>
  105. <v-select
  106. v-if="hasJGtire"
  107. :disabled="stockDisabled"
  108. style="margin-left: 15px;width:150px;"
  109. v-model="stockType"
  110. id="dispatch-stockType"
  111. code="TIRE_STOCK_TYPE"
  112. placeholder="请选择库存类型"
  113. @change="stockTypeChange"
  114. ></v-select>
  115. <a-button
  116. v-if="hasJGtire && stockType=='LOCK_STOCK'"
  117. @click="confirPurchaseModal"
  118. :loading="loading"
  119. type="primary"
  120. style="margin-left: 6px"
  121. class="button-info"
  122. id="dispatch-updateStock">轮胎转采购单</a-button>
  123. </div>
  124. <div style="padding-left: 20px;">
  125. 总销售数量:<strong>{{ detailData&&(detailData.totalQty || detailData.totalQty==0) ? detailData.totalQty : '--' }}</strong>;
  126. 已取消数量:<strong>{{ detailData&&(detailData.totalCancelQty || detailData.totalCancelQty==0) ? detailData.totalCancelQty : '--' }}</strong>;
  127. 已下推数量:<strong>{{ detailData&&(detailData.totalPushedQty || detailData.totalPushedQty==0) ? detailData.totalPushedQty : '--' }}</strong>;
  128. 待下推数量:<strong>{{ detailData&&(detailData.totalUnpushedQty || detailData.totalUnpushedQty==0) ? detailData.totalUnpushedQty : '--' }}</strong>;
  129. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">总售价:<strong>{{ detailData&&(detailData.totalAmount || detailData.totalAmount==0) ? toThousands(detailData.totalAmount) : '--' }}</strong>;</span>
  130. <span v-if="$hasPermissions('B_salesDispatch_costPrice')">总成本:<strong>{{ detailData&&(detailData.totalCost || detailData.totalCost==0) ? toThousands(detailData.totalCost) : '--' }}</strong>;</span>
  131. <span v-if="$hasPermissions('B_salesDispatch_costPrice')&&$hasPermissions('B_salesDispatch_salesPrice')">总毛利:<strong>{{ detailData&&(detailData.grossProfit || detailData.grossProfit==0) ? toThousands(detailData.grossProfit) : '--' }}</strong>;</span>
  132. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已取消金额:<strong>{{ detailData&&(detailData.totalCancelAmount || detailData.totalCancelAmount==0) ? toThousands(detailData.totalCancelAmount) : '--' }}</strong>;</span>
  133. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已下推金额:<strong>{{ detailData&&(detailData.totalPushedAmount || detailData.totalPushedAmount==0) ? toThousands(detailData.totalPushedAmount) :'--' }}</strong>;</span>
  134. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">待下推金额:<strong>{{ detailData&&(detailData.totalUnpushedAmount || detailData.totalUnpushedAmount==0) ? toThousands(detailData.totalUnpushedAmount) : '--' }}</strong>;</span>
  135. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')&&detailData&&detailData.totalConvertPromoGiftsAmount" style="color:red;">促销产品转采购额金额:<strong>{{ toThousands(detailData.totalConvertPromoGiftsAmount) }}</strong>;</span>
  136. </div>
  137. </div>
  138. <a-spin :spinning="spinning" tip="Loading...">
  139. <ve-table
  140. border-y
  141. :scroll-width="0"
  142. :max-height="tableHeight"
  143. :show-header="showTableHead"
  144. :row-style-option="{clickHighlight: true}"
  145. :cellSelectionOption="{enable: false}"
  146. :virtual-scroll-option="{enable: true}"
  147. :columns="columns"
  148. :table-data="tableData"
  149. row-key-field-name="id"
  150. :cell-style-option="cellStyleOption"
  151. :cell-span-option="cellSpanOption"
  152. :column-width-resize-option="columnWidthResizeOption"
  153. :checkbox-option="checkboxOption"
  154. />
  155. <div v-show="showEmpty" class="empty-data-0"><a-empty description="暂无数据" :image="simpleImage"/></div>
  156. <!-- 活动规则详情 -->
  157. <detailModal :openModal="openDetailModal" :itemSn="detailSn" @close="closeDetailModal"></detailModal>
  158. <!-- 转采购单 -->
  159. <toPurchaseModal :openModal="openPurchaseModal" @ok="showLockStockQty = true" @close="openPurchaseModal=false" ref="purchaseModal"></toPurchaseModal>
  160. </a-spin>
  161. </div>
  162. </template>
  163. <script>
  164. import { commonMixin } from '@/utils/mixin'
  165. import { STable, VSelect } from '@/components'
  166. import { Empty } from 'ant-design-vue'
  167. import detailModal from '@/views/promotionRulesManagement/dealerPromotions/detailModal.vue'
  168. import toPurchaseModal from './toPurchaseModal'
  169. import chooseWarehouse from '@/views/common/chooseWarehouse'
  170. // 接口
  171. import { queryAwaitDispatch } from '@/api/salesDetailNew'
  172. import { getCreatePurchaseFlag } from '@/api/salesNew'
  173. export default {
  174. name: 'QueryPart',
  175. mixins: [commonMixin],
  176. components: { STable, VSelect, chooseWarehouse, detailModal, toPurchaseModal },
  177. props: {
  178. newLoading: { // loading
  179. type: Boolean,
  180. default: false
  181. },
  182. maxHeight: { // 最大高度
  183. type: [String, Number],
  184. default: '300'
  185. },
  186. showHeader: { // 是否显示表格头部
  187. type: Boolean,
  188. default: true
  189. },
  190. activeList: { // 参与的活动列表
  191. type: Array,
  192. default: () => []
  193. }
  194. },
  195. data () {
  196. return {
  197. loading: false,
  198. advanced: true, // 高级搜索 展开/关闭
  199. openDetailModal: false, // 活动规则详情弹框
  200. openPurchaseModal: false, // 转采购单弹框
  201. simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
  202. detailSn: null, // 活动详情sn
  203. productType: [], // 产品类型
  204. salesBillSn: '', // 销售单sn
  205. detailData: null, // 详情数据
  206. queryParam: {
  207. pushProductType: '', // 类型
  208. productCode: '', // 产品编码
  209. productName: '', // 产品名称
  210. promotionFlag: undefined, // 是否促销品
  211. brandSn: undefined, // 产品品牌
  212. productTypeSn1: '', // 产品一级分类
  213. productTypeSn2: '', // 产品二级分类
  214. productTypeSn3: '', // 产品三级分类
  215. salesBillSn: '', // 销售单sn
  216. warehouseSn: undefined, // 仓库sn
  217. convertPromoGiftsFlag: undefined // 转采购额
  218. },
  219. disabled: false, // 查询、重置按钮是否可操作
  220. spinning: false,
  221. dataSource: [], // 原始数据
  222. tableData: [], // 表格数据
  223. cellStyleOption: {
  224. bodyCellClass: ({ row, column, rowIndex }) => {
  225. if (row.id.indexOf('promo-') >= 0 && column.field === 'no') {
  226. return 'table-body-cell-no'
  227. }
  228. }
  229. },
  230. // 可拖曳调整列宽
  231. columnWidthResizeOption: {
  232. enable: true,
  233. minWidth: 50
  234. },
  235. // 自定义单元格
  236. cellSpanOption: {
  237. bodyCellSpan: this.bodyCellSpan
  238. },
  239. showEmpty: false, // 空图片
  240. showTableHead: true, // 表格头部
  241. disableSelectedRowKeys: [], // 禁用数据
  242. selectedRowKeys: [], // 已选数据
  243. colspanNums: 16, // 列合并数量
  244. hasNormalProduct: false, // 是否有正常产品
  245. showLockStockQty: false, // 是否显示锁定库存列
  246. stockType: undefined, // 默认锁定库存
  247. hasJGtire: false, // 是否轮胎产品
  248. stockDisabled: false
  249. }
  250. },
  251. computed: {
  252. // 表格高度
  253. tableHeight () {
  254. return (this.showEmpty ? 200 : this.maxHeight) + 'px'
  255. },
  256. // 是否有促销活动产品
  257. hasPrompActive () {
  258. return this.detailData && this.detailData.promoFlag == 1
  259. },
  260. // 是否有下推产品
  261. hasNoPushedActive () {
  262. return this.detailData && this.detailData.totalPushedQty == 0 || !this.detailData.totalPushedQty
  263. },
  264. // 是否有转采购额
  265. hasConvertPromoGifts () {
  266. return this.detailData && this.detailData.totalConvertPromoGiftsAmount > 0
  267. },
  268. // 是否显示转采购额选项
  269. showConvertPromoGifts () {
  270. return this.activeList && this.activeList.find(item => item.enabledFlag == 1 && item.promotionRule && item.promotionRule.convertExpenseFlag == 1 && item.promotionRule.promotionRuleType == 'BUY_PROD_GIVE_PROD')
  271. },
  272. // 表格复选框
  273. checkboxOption () {
  274. return {
  275. disableSelectedRowKeys: this.disableSelectedRowKeys,
  276. selectedRowKeys: this.selectedRowKeys,
  277. hideSelectAll: this.disableSelectedRowKeys.length == this.tableData.length,
  278. // 行选择改变事件
  279. selectedRowChange: ({ row, isSelected, selectedRowKeys }) => {
  280. this.selectedRowChange({ row, isSelected, selectedRowKeys })
  281. },
  282. // 全选改变事件
  283. selectedAllChange: ({ isSelected, selectedRowKeys }) => {
  284. this.selectedAllChange({ isSelected, selectedRowKeys })
  285. }
  286. }
  287. },
  288. columns () {
  289. const _this = this
  290. // 价格
  291. const priceFormat = function (record, data, h) {
  292. return (
  293. <div>
  294. {_this.toThousands(data)}
  295. {record.promotionFlag.indexOf('GIFT') >= 0 || record.promotionFlag.indexOf('DISCOUNT') >= 0 ? (
  296. <span title="原价">({ _this.toThousands(record.origPrice)})</span>
  297. ) : ''}
  298. </div>
  299. )
  300. }
  301. // 数字
  302. const numsFormat = function (data) {
  303. return data || data == 0 ? data : '--'
  304. }
  305. // 单号
  306. const codeFormat = function (record, data, h) {
  307. return (
  308. <div>
  309. <span style="padding-right: 10px;">{data}</span>
  310. {record.promotionFlag.indexOf('GIFT') >= 0 ? <a-badge count="促" numberStyle={{ backgroundColor: '#52c41a', zoom: '0.7' }}/> : ''}
  311. {record.promotionFlag.indexOf('GATE') >= 0 ? <a-badge count="槛" numberStyle={{ backgroundColor: '#108ee9', zoom: '0.7' }}/> : ''}
  312. {record.promotionFlag.indexOf('REGULAR') >= 0 ? <a-badge count="正" numberStyle={{ backgroundColor: '#ff5500', zoom: '0.7' }}/> : ''}
  313. {record.promotionFlag.indexOf('DISCOUNT') >= 0 ? <a-badge count="特" numberStyle={{ backgroundColor: '#faad14', zoom: '0.7' }}/> : ''}
  314. {Number((record.tireFlag != 0 ? record.lockStockQty : record.stockQty) || 0) < Number(record.unpushedQty || 0) && record.borrowFlag != '1' ? (<a-badge count="缺" numberStyle={{ zoom: '0.7' }}></a-badge>) : ''}
  315. {record.bakConvertPromoGiftsQty ? (<a-badge count="转" numberStyle={{ backgroundColor: '#0055ff', zoom: '0.7' }}></a-badge>) : ''}
  316. </div>
  317. )
  318. }
  319. // 取消数量输入框
  320. const inputFormat = function (record, data, h) {
  321. if (record.unpushedQty > 0) {
  322. return (
  323. <div>
  324. <a-input-number
  325. id={'dispacth-cancelNums-' + record.productSn}
  326. size="small"
  327. value={record.cancelNums}
  328. onChange={e => _this.cancelNumsChange(e, record)}
  329. precision={0}
  330. min={0}
  331. max={record.unpushedQty}
  332. style="width: 100%;"
  333. placeholder="请输入" />
  334. </div>
  335. )
  336. }
  337. return '--'
  338. }
  339. // 转采购额数量输入框
  340. const inputFormat1 = function (record, data, h) {
  341. if (record.unpushedQty >= 0 && record.convertPromoGiftsFlag == 1) {
  342. // 已选
  343. if (_this.selectedRowKeys.includes(record.id)) {
  344. return (
  345. <div>
  346. <a-input-number
  347. id={'dispacth-maxConvertNums-' + record.productSn}
  348. size="small"
  349. value={record.convertPromoGiftsQty}
  350. onChange={e => _this.convertPromoGiftsChange(e, record)}
  351. precision={0}
  352. min={0}
  353. max={record.maxConvertNums}
  354. style="width: 100%;"
  355. placeholder="请输入" />
  356. </div>
  357. )
  358. } else {
  359. return record.convertPromoGiftsQty || 0
  360. }
  361. }
  362. return '--'
  363. }
  364. // 操作按钮
  365. const actionFormat = function (record, data, h) {
  366. if (record.unpushedQty > 0) {
  367. return (
  368. <div>
  369. <a-button
  370. id={'dispacth-handleAdd-' + record.productSn}
  371. size="small"
  372. type="link"
  373. class="button-info"
  374. onClick={() => _this.handleAdd(record)}
  375. >添加</a-button>
  376. </div>
  377. )
  378. }
  379. return '--'
  380. }
  381. // 编号,并且格式化活动分类行
  382. const noFormat = function (record, data, h) {
  383. return (
  384. <div>
  385. {record.id.indexOf('promo-active') >= 0 ? (
  386. <div class="active-title">参与促销的产品</div>
  387. ) : (<span>{data}</span>)}
  388. </div>
  389. )
  390. }
  391. let arr = [
  392. { title: '', field: 'acheck', key: 'acheck', width: 50, type: 'checkbox', align: 'center' },
  393. { title: '序号', field: 'no', key: 'a', width: 50, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return noFormat(row, row[column.field], h) } },
  394. { title: '产品编码', field: 'productCode', key: 'b', width: 150, align: 'left', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return codeFormat(row, row[column.field], h) } },
  395. { title: '产品名称', field: 'productName', key: 'c', width: 220, align: 'left', operationColumn: false, ellipsis: { showTitle: true }, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  396. { title: '原厂编码', field: 'productOrigCode', key: 'd', width: 150, align: 'left', operationColumn: false, ellipsis: { showTitle: true }, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  397. { title: '出库仓库', field: 'warehouseName', key: 'e', width: 100, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } }
  398. ]
  399. // 单元格合并数量
  400. this.colspanNums = this.showConvertPromoGifts ? 7 : 6
  401. if (this.hasPrompActive) {
  402. this.colspanNums = this.colspanNums + 1
  403. arr.splice(4, 0, {
  404. title: '规则数量',
  405. field: 'rulesNums',
  406. key: '4',
  407. width: 60,
  408. align: 'center',
  409. operationColumn: false,
  410. renderBodyCell: ({ row, column, rowIndex }, h) => {
  411. return (
  412. row.useRuleQty || row.promoRuleSnList && row.promoRuleSnList.length
  413. ? <a-popover placement="right">
  414. <template slot="content">
  415. {row.promoRuleSnList.map(item => {
  416. return (
  417. <div
  418. id={'dispacth-ruleDetail-' + row.productSn}
  419. title="点击查看详情"
  420. style="padding:5px 0;cursor: pointer;"
  421. onClick={() => _this.showRuleDetail(item)}
  422. >{ _this.activeRuleFilter(item) }</div>
  423. )
  424. })}
  425. </template>
  426. <a-button type="link" id={'dispacth-ruleSn-' + row.productSn} size="small" class="button-info">{row.useRuleQty || row.promoRuleSnList && row.promoRuleSnList.length}<span style="zoom:0.6;color: #666;">个 ∨</span></a-button>
  427. </a-popover> : '--'
  428. )
  429. }
  430. })
  431. }
  432. if (this.$hasPermissions('B_salesDispatch_salesPrice')) { // 售价权限
  433. this.colspanNums = this.colspanNums + 1
  434. arr.push({ title: '销售价', field: 'price', width: 80, key: 'f', align: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return priceFormat(row, row[column.field], h) } })
  435. }
  436. if (this.$hasPermissions('B_salesDispatch_costPrice')) { // 成本价权限
  437. this.colspanNums = this.colspanNums + 1
  438. arr.push({ title: '成本价', field: 'showCost', width: 80, key: 'g', align: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return _this.toThousands(row[column.field]) || '--' } })
  439. }
  440. this.colspanNums = this.colspanNums + 8
  441. arr = arr.concat([
  442. { title: '单位', field: 'productOrigUnit', key: 'i', width: 80, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  443. { title: '可用库存', field: 'stockQty', width: 80, key: 'j', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } }
  444. ])
  445. if (this.showLockStockQty) {
  446. this.colspanNums = this.colspanNums + 1
  447. arr.push({ title: '锁定库存', field: 'lockStockQty', width: 80, key: 'jk', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } })
  448. }
  449. arr = arr.concat([
  450. { title: '销售数量', field: 'qty', width: 80, key: 'k', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  451. { title: '已取消', field: 'cancelQty', width: 80, key: 'o', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  452. { title: '已下推', field: 'pushedQty', width: 80, key: 'p', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  453. { title: '待下推', field: 'unpushedQty', width: 80, key: 'q', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  454. { title: '取消数量', field: 'cancelNums', width: 80, key: 'r', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return inputFormat(row, row[column.field], h) } }
  455. ])
  456. // 是否显示转采购额
  457. if (this.showConvertPromoGifts) {
  458. arr.push({ title: '转采购额数量',
  459. field: 'convertPromoGiftsQty',
  460. width: 80,
  461. key: 'z',
  462. align: 'center',
  463. fixed: 'right',
  464. operationColumn: false,
  465. renderBodyCell: ({ row, column, rowIndex }, h) => {
  466. return inputFormat1(row, row[column.field], h)
  467. } })
  468. }
  469. arr.push({ title: '操作', field: 'action', width: 80, key: 's', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return actionFormat(row, row[column.field], h) } })
  470. return arr
  471. }
  472. },
  473. methods: {
  474. // 关闭详情弹窗
  475. closeDetailModal () {
  476. this.detailSn = null
  477. this.openDetailModal = false
  478. },
  479. // 参与规则名称
  480. activeRuleFilter (val) {
  481. const row = this.activeList.length && this.activeList.find(item => item.promoRuleSn == val)
  482. return row ? row.promotionRule.description + '-' + row.promotion.description : ''
  483. },
  484. // 查看参与规则详情
  485. showRuleDetail (promoRuleSn) {
  486. this.detailSn = promoRuleSn
  487. this.openDetailModal = true
  488. },
  489. // 合并活动分类单元格
  490. bodyCellSpan ({ row, column, rowIndex }) {
  491. if (row.id.indexOf('promo-') >= 0) {
  492. if (column.field == 'no') {
  493. return {
  494. rowspan: 1,
  495. colspan: this.colspanNums
  496. }
  497. } else {
  498. return {
  499. rowspan: 0,
  500. colspan: 0
  501. }
  502. }
  503. }
  504. },
  505. // 取消数量变更
  506. cancelNumsChange (v, record) {
  507. record.cancelNums = v
  508. this.dataSource.splice()
  509. },
  510. // 转采购数量变更
  511. convertPromoGiftsChange (v, record) {
  512. record.convertPromoGiftsQty = v
  513. this.dataSource.splice()
  514. },
  515. // 选择单元格
  516. selectedRowChange ({ row, isSelected, selectedRowKeys }) {
  517. // console.log(row, isSelected, selectedRowKeys);
  518. this.selectedRowKeys = selectedRowKeys
  519. if (!isSelected) {
  520. row.convertPromoGiftsQty = row.bakConvertPromoGiftsQty
  521. }
  522. },
  523. // 全选行
  524. selectedAllChange ({ isSelected, selectedRowKeys }) {
  525. this.selectedRowKeys = selectedRowKeys
  526. // 取消全选后,重置数量
  527. if (!isSelected && this.showConvertPromoGifts) {
  528. this.dataSource.filter(item => item.convertPromoGiftsQty).map(item => {
  529. item.convertPromoGiftsQty = item.bakConvertPromoGiftsQty
  530. })
  531. }
  532. },
  533. // 查询列表
  534. async searchTable () {
  535. this.selectedRowKeys = []
  536. this.disableSelectedRowKeys = []
  537. this.dataSource = []
  538. this.disabled = true
  539. this.spinning = true
  540. this.queryParam.salesBillSn = this.salesBillSn
  541. this.queryParam.showStock = true
  542. const params = this.queryParam
  543. // 所有活动接口
  544. const active = this.activeList
  545. // 是否查询正常产品
  546. const hasSearchNormal = !params.promotionFlag || params.promotionFlag == 0
  547. const proList = hasSearchNormal ? await queryAwaitDispatch({ ...params, detailPromoFlag: 0 }).then(res => res.data) : []
  548. this.hasNormalProduct = proList.length > 0 // 是否有正常产品
  549. // 没有活动时不显示正常产品标题行
  550. let listData = proList
  551. // 获取活动产品列表,查询条件未选正常产品
  552. if (params.promotionFlag != 0) {
  553. const acparams = { ...params, detailPromoFlag: 1, promoProductClz: params.promotionFlag }
  554. acparams.promotionFlag = undefined
  555. const aclist = await queryAwaitDispatch(acparams).then(res => res.data)
  556. // 没用活动产品,不显示
  557. const retList = aclist.length ? [{
  558. id: 'promo-active'
  559. }, ...aclist] : []
  560. // 将活动产品数据拼接
  561. listData = aclist && aclist.length ? listData.concat(retList) : listData
  562. }
  563. this.dataSource = listData
  564. // 格式化数据
  565. let f = 0
  566. this.dataSource.map((item, i) => {
  567. const isTjRow = item.id.indexOf('promo-') >= 0
  568. if (isTjRow) { f = f - 1 }
  569. item.no = i + 1 + f
  570. const productCode = (item.productEntity && item.productEntity.code) || (item.dealerProductEntity && item.dealerProductEntity.code)
  571. const productName = (item.productEntity && item.productEntity.name) || (item.dealerProductEntity && item.dealerProductEntity.name)
  572. const productOrigCode = (item.productEntity && item.productEntity.origCode) || (item.dealerProductEntity && item.dealerProductEntity.origCode)
  573. const productOrigUnit = (item.productEntity && item.productEntity.unit) || (item.dealerProductEntity && item.dealerProductEntity.unit)
  574. item.productCode = productCode || '--'
  575. item.productName = productName || '--'
  576. item.productOrigCode = productOrigCode == ' ' ? '--' : productOrigCode
  577. item.productOrigUnit = productOrigUnit || '--'
  578. item.promoRuleSnList = item.promotionRuleList && item.promotionRuleList.map(item => item.promotionRuleSn) // 规则sn
  579. item.cancelNums = item.unpushedQty // 取消数量
  580. // 转采购额最大数量
  581. if (item.convertPromoGiftsFlag == 1) {
  582. item.maxConvertNums = item.unpushedQty + item.convertPromoGiftsQty
  583. } else {
  584. item.maxConvertNums = 0
  585. }
  586. const productBrand = (item.productEntity && item.productEntity.productBrandName) || (item.dealerProductEntity && item.dealerProductEntity.productBrandName)
  587. const productType3 = (item.productEntity && item.productEntity.productTypeName3) || (item.dealerProductEntity && item.dealerProductEntity.productTypeName3)
  588. // 判断是否有箭冠轮胎产品
  589. if (productBrand && productBrand.indexOf('箭冠') >= 0 && productBrand && productType3.indexOf('轮胎') >= 0) {
  590. this.hasJGtire = true
  591. // 默认锁定库存类型
  592. if (!this.stockType) {
  593. this.stockType = 'LOCK_STOCK'
  594. this.stockTypeChange('LOCK_STOCK')
  595. }
  596. }
  597. // 转采购额数量
  598. item.bakConvertPromoGiftsQty = item.convertPromoGiftsQty
  599. // 库存为0或待下推数为0,不可添加
  600. if (!item.convertPromoGiftsQty && (!item.unpushedQty || item.unpushedQty < 0) || isTjRow) {
  601. this.disableSelectedRowKeys.push(item.id)
  602. }
  603. })
  604. this.showEmpty = this.dataSource.length <= 0
  605. this.tableData = this.dataSource
  606. this.spinning = false
  607. this.disabled = false
  608. },
  609. // 重置
  610. resetSearchForm (detailData) {
  611. this.queryParam.pushProductType = ''
  612. this.queryParam.productCode = ''
  613. this.queryParam.productName = ''
  614. this.queryParam.promotionFlag = undefined
  615. this.queryParam.brandSn = undefined
  616. this.queryParam.productTypeSn1 = ''
  617. this.queryParam.productTypeSn2 = ''
  618. this.queryParam.productTypeSn3 = ''
  619. this.queryParam.warehouseSn = undefined
  620. this.queryParam.convertPromoGiftsFlag = undefined
  621. this.productType = []
  622. this.dataSource = []
  623. this.clearSelectTable()
  624. this.searchTable()
  625. if (detailData) {
  626. this.detailData = detailData
  627. }
  628. },
  629. pageInit (salesBillSn, detailData) {
  630. this.salesBillSn = salesBillSn
  631. this.detailData = detailData
  632. // 是否转过采购单
  633. this.hasCreatePurchaseFlag()
  634. this.searchTable()
  635. },
  636. // 清空选项
  637. clearSelectTable () {
  638. this.selectedRowKeys = []
  639. },
  640. // 修改库存类型
  641. stockTypeChange (val) {
  642. this.$emit('updateStockType', val)
  643. },
  644. // 添加
  645. handleAdd (row) {
  646. const isLt = row && row.productEntity && row.productEntity.productBrandName == '箭冠' && row.productEntity.productTypeName3 == '轮胎'
  647. // 如果库存类型是锁定库存 且 轮胎产品
  648. if (this.stockType && this.stockType == 'LOCK_STOCK' && isLt) {
  649. if (!row.lockStockQty) {
  650. this.$message.warning('锁定库存为0,不可添加!')
  651. } else {
  652. this.$emit('addProduct', [row.salesBillDetailSn])
  653. }
  654. } else {
  655. // 库存类型可用库存或非轮胎产品
  656. if (row.stockQty > 0) { // 可用库存大于0才可添加
  657. this.$emit('addProduct', [row.salesBillDetailSn])
  658. } else {
  659. this.$message.warning('库存为0,不可添加!')
  660. }
  661. }
  662. },
  663. // 批量转采购额
  664. handlePlPurchase () {
  665. const _this = this
  666. const chooseList = this.selectedRowKeys
  667. if (chooseList.length == 0) {
  668. _this.$message.warning('请先选择产品!')
  669. return
  670. }
  671. const chooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.convertPromoGiftsFlag == 1)
  672. const noChooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && !item.convertPromoGiftsFlag)
  673. const obj = []
  674. const noObj = []
  675. noChooseRow && noChooseRow.map(item => {
  676. noObj.push(item.productCode)
  677. })
  678. chooseRow && chooseRow.map(item => {
  679. obj.push({
  680. 'convertPromoGiftsQty': item.convertPromoGiftsQty,
  681. 'salesBillDetailSn': item.salesBillDetailSn
  682. })
  683. })
  684. if (obj.length) {
  685. this.$confirm({
  686. title: '提示',
  687. content: <div><div style="text-align:center;padding:10px 0;font-weight:bold;">确定将选中的促销产品转成采购额吗?</div>{noObj.length ? <div style="text-align:center;"><div>总共选择了 {chooseList.length} 个产品,其中 {obj.length} 个产品可转采购额。</div><div style="color:red;"> 产品 ({noObj.toString()}) 不可转采购额!</div></div> : ''}<div style="font-size:12px;color:#999;padding:10px 0;text-align:center;">
  688. 当该销售单完结后,可将采购额转成费用报销单。</div></div>,
  689. centered: true,
  690. closable: true,
  691. class: 'confirm-center',
  692. onOk () {
  693. _this.$emit('convertPromoGifts', obj)
  694. }
  695. })
  696. } else {
  697. _this.$message.warning('所选产品都不可转采购额!')
  698. }
  699. },
  700. // 批量添加
  701. handlePlAdd () {
  702. const _this = this
  703. const chooseList = this.selectedRowKeys
  704. if (chooseList.length == 0) {
  705. _this.$message.warning('请先选择产品!')
  706. return
  707. }
  708. let noStockRow = []
  709. let noLockStockRow = []
  710. // 库存类型是 锁定库存
  711. if (this.stockType && this.stockType == 'LOCK_STOCK') {
  712. // 库存为0的产品,不包括箭冠轮胎产品
  713. noStockRow = this.dataSource.filter(item => chooseList.includes(item.id) && !item.stockQty && item.productEntity && item.productEntity.productBrandName != '箭冠' && item.productEntity.productTypeName3 != '轮胎')
  714. // 锁定库存为0的产品,只判断箭冠轮胎产品
  715. noLockStockRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.productEntity && item.productEntity.productBrandName == '箭冠' && item.productEntity.productTypeName3 == '轮胎' && !item.lockStockQty)
  716. } else {
  717. // 库存类型是 可用库存
  718. noStockRow = this.dataSource.filter(item => chooseList.includes(item.id) && !item.stockQty)
  719. }
  720. // 库存为0产品编码列表
  721. const noObj = []
  722. const noObjSn = []
  723. noStockRow && noStockRow.map(item => {
  724. noObj.push(item.productCode)
  725. noObjSn.push(item.salesBillDetailSn)
  726. })
  727. // 锁定库存为0的产品
  728. const noLockObj = []
  729. const noLockObjSn = []
  730. noLockStockRow && noLockStockRow.map(item => {
  731. noLockObj.push(item.productCode)
  732. noLockObjSn.push(item.salesBillDetailSn)
  733. })
  734. // 可添加产品,不包括库存未0和箭冠轮胎锁定库存为0的产品
  735. const chooseRow = this.dataSource.filter(item => {
  736. return chooseList.includes(item.id) && !noObjSn.includes(item.salesBillDetailSn) && !noLockObjSn.includes(item.salesBillDetailSn)
  737. })
  738. // 可添加产品sn列表
  739. const obj = []
  740. chooseRow && chooseRow.map(item => {
  741. obj.push(item.salesBillDetailSn)
  742. })
  743. if (obj.length) {
  744. this.$confirm({
  745. title: '提示',
  746. content: <div><div style="text-align:center;padding:10px 0;font-weight:bold;">确认要批量添加到待下推列表吗?</div>{(noObj.length || noLockObj.length) ? <div><div>总共选择了 {chooseList.length} 个产品,其中 {obj.length} 个产品可添加。</div>{noObj.length ? <div>产品 ({noObj.toString()}) 因库存为0不可添加!</div> : ''}</div> : ''}<div>{noLockObj.length ? <div>产品 ({noLockObj.toString()}) 因锁定库存为0不可添加!</div> : ''}</div></div>,
  747. centered: true,
  748. closable: true,
  749. class: 'confirm-center',
  750. onOk () {
  751. _this.$emit('addProduct', obj)
  752. }
  753. })
  754. } else {
  755. _this.$message.warning(noLockObj.length ? '所选产品锁定库存都为0,不可添加!' : '所选产品库存都为0,不可添加!')
  756. }
  757. },
  758. // 整单取消
  759. handleAllCancel () {
  760. const _this = this
  761. this.$confirm({
  762. title: '提示',
  763. content: '确定整单取消订单?',
  764. centered: true,
  765. closable: true,
  766. onOk () {
  767. _this.$emit('cancelAll')
  768. }
  769. })
  770. },
  771. // 批量取消
  772. handlePlCancel () {
  773. const _this = this
  774. const chooseList = this.selectedRowKeys
  775. if (chooseList.length == 0) {
  776. _this.$message.warning('请先选择产品!')
  777. return
  778. }
  779. const chooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.id.indexOf('promo-') < 0)
  780. const hasActive = chooseRow && chooseRow.filter(item => item.promotionFlag != 0)
  781. if (hasActive.length > 0) {
  782. _this.$message.warning('参与促销的产品只可进行整单取消!')
  783. return
  784. }
  785. const obj = []
  786. chooseRow && chooseRow.map(item => {
  787. obj.push({
  788. 'cancelQty': item.cancelNums,
  789. 'salesBillDetailSn': item.salesBillDetailSn
  790. })
  791. })
  792. this.$emit('cancelProduct', obj)
  793. },
  794. // 确认整单转采购单
  795. confirPurchaseModal () {
  796. this.loading = true
  797. getCreatePurchaseFlag({ salesBillSn: this.salesBillSn }).then(res => {
  798. if (res.status == '200') {
  799. // 没有转过
  800. if (res.data == 0) {
  801. this.showPurchaseModal()
  802. } else {
  803. // 转过,弹确认框
  804. const _this = this
  805. this.$confirm({
  806. title: '提示',
  807. content: '已转过采购单,是否再次转单?',
  808. centered: true,
  809. closable: true,
  810. onOk () {
  811. _this.showPurchaseModal()
  812. }
  813. })
  814. }
  815. }
  816. this.loading = false
  817. })
  818. },
  819. // 打开转采购单弹框
  820. showPurchaseModal () {
  821. this.openPurchaseModal = true
  822. this.$refs.purchaseModal.setDetail(this.detailData)
  823. },
  824. // 是否转过采购单
  825. hasCreatePurchaseFlag () {
  826. getCreatePurchaseFlag({ salesBillSn: this.salesBillSn }).then(res => {
  827. this.showLockStockQty = res.data && res.data == 1
  828. })
  829. }
  830. }
  831. }
  832. </script>
  833. <style lang="less">
  834. .empty-data-0{
  835. color: #999;
  836. text-align: center;
  837. padding: 10px;
  838. position: absolute;
  839. bottom: 0;
  840. width: 100%;
  841. }
  842. .ve-table-body-td{
  843. .active-title{
  844. display: flex;
  845. align-items: center;
  846. justify-content: space-between;
  847. padding: 10px;
  848. background: #f3f8fa;
  849. }
  850. }
  851. .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-body-tr td.table-body-cell-no,
  852. .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-expand-tr td.table-body-cell-no{
  853. padding: 0;
  854. }
  855. .ve-table .ve-table-container .ve-table-content-wrapper{
  856. border-bottom: 1px solid #ddd;
  857. }
  858. </style>