diandan.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. <template>
  2. <a-card :bordered="false" class="card-pd">
  3. <a-tabs v-model="tabPosTypeId" @change="tabPosTypeChange">
  4. <a-tab-pane :key="item.id" :tab="item.name" v-for="item in posTypeList"></a-tab-pane>
  5. </a-tabs>
  6. <div style="display: flex; height: calc(100vh - 350px);">
  7. <a-card style="width: 30%">
  8. <a href="#" @click="remarkModal">
  9. <a-icon type="edit" />整单备注</a>
  10. <p v-if="selectRoomOrder && selectRoomOrder.roomName">
  11. <a-icon type="user" /> 房间:{{ selectRoomOrder.roomName }},姓名:{{ selectRoomOrder.customerName }}
  12. </p>
  13. <a-table bordered :columns="columns" :data-source="selectGoodsList" :row-selection="rowSelection" rowKey="id" :scroll="{ y: 560 }">
  14. <template slot="num" slot-scope="text, record, index">
  15. <div>
  16. <a-input-number v-model="record.num" :max="record.inventory" @change="(event) => numChange(event, index)" />
  17. </div>
  18. </template>
  19. <template slot="required" slot-scope="text, record, index">
  20. <div>
  21. <a-switch v-model="record.required" />
  22. </div>
  23. </template>
  24. <span slot="action" slot-scope="text, record, index">
  25. <a @click="handleDelete(index)">删除</a>
  26. </span>
  27. </a-table>
  28. <p>数量:{{ sum }}</p>
  29. <div style="display: flex; gap: 5px; flex-flow: wrap">
  30. <a-button @click="handleClear" :disabled="btnDisabled">清空</a-button>
  31. <!-- <a-button @click="handleAdd" :disabled="btnDisabled">备注</a-button> -->
  32. <!-- <a-button :disabled="btnDisabled">退货</a-button> -->
  33. <a-button v-if="!btnDisabled" @click="handleAdd">挂单</a-button>
  34. <a-button v-else @click="handlePickingGoodsOrder">取单</a-button>
  35. <a-button v-if="selectRoomOrder && selectRoomOrder.roomName && !btnDisabled" @click="handleToRoomFeePayment">确定挂房帐</a-button>
  36. <a-button v-else @click="handleSelectCheckInRoomOrder">挂房帐</a-button>
  37. <a-button :disabled="btnDisabled" type="danger" @click="handlePayment">结账¥{{ amount.toFixed(2) }}</a-button>
  38. <a-button :disabled="btnDisabled">退货</a-button>
  39. </div>
  40. </a-card>
  41. <a-card style="width: 75%;position: relative;">
  42. <a-tabs v-model="tabgoodsTypeId" @change="tabGoodsTypeChange">
  43. <a-tab-pane key="1" tab="全部"></a-tab-pane>
  44. <a-tab-pane :key="item.id" :tab="item.name" v-for="item in goodsTypeList"></a-tab-pane>
  45. </a-tabs>
  46. <a-row :gutter="[5, 5]">
  47. <a-col v-for="item in dataSource" :key="item.id" :span="3" @click.stop="itemClick(item)">
  48. <div class="room-item check">
  49. <div class="select-cell"></div>
  50. <template v-if="item.id != '0'">
  51. <div>{{ item.name }}</div>
  52. <div style="margin-top: 10px; color: red">
  53. ¥{{ item.sellingPrice.toFixed(2) }}
  54. </div>
  55. <div style="margin-top: 10px">库{{ item.inventory }}</div>
  56. <div v-if="item.isSellClear" style="display: flex; justify-content: right">
  57. <a-tag color="#f50"> 沽清 </a-tag>
  58. </div>
  59. </template>
  60. <template v-else>
  61. <div style="font-weight: 800; text-align: center">+临时菜</div>
  62. </template>
  63. </div>
  64. </a-col>
  65. </a-row>
  66. <a-row style="margin-top:30px;">
  67. <a-space>
  68. <a-input v-if="!isSaoma" placeholder="输入名称、简拼、条码"></a-input>
  69. <a-input v-else placeholder="请扫描条码"></a-input>
  70. <a-button v-if="!isSaoma">查询</a-button>
  71. <a-button @click="isSaoma=!isSaoma">切换为{{isSaoma?'查询':'扫码'}}模式</a-button>
  72. </a-space>
  73. </a-row>
  74. </a-card>
  75. </div>
  76. <payment-modal ref="modalPaymentForm" @ok="modalFormOk"></payment-modal>
  77. <goods-modal ref="modalGoodsForm" @ok="modalFormOk2"></goods-modal>
  78. <picking-goods-order-modal ref="modalPickingGoodsOrderForm" @ok="modalPickingGoodsOrderFormOk"></picking-goods-order-modal>
  79. <select-check-in-room-order-modal ref="modalSelectCheckInRoomOrderModal" @ok="modalSelectCheckInRoomOrderFormOk"></select-check-in-room-order-modal>
  80. <a-modal @cancel="isRemarkModal = false" :visible="isRemarkModal" title="添加备注">
  81. <a-form-model>
  82. <a-form-model-item label="备注">
  83. <a-input v-model="remark" type="textarea" />
  84. </a-form-model-item>
  85. </a-form-model>
  86. </a-modal>
  87. </a-card>
  88. </template>
  89. <script>
  90. // import { JeecgListMixin } from "@/mixins/JeecgListMixin";
  91. // import PosRegionModal from "./modules/PosRegionModal";
  92. import {
  93. filterObj
  94. } from "@/utils/util";
  95. import {
  96. getAction,
  97. postAction,
  98. deleteAction
  99. } from "@/api/manage";
  100. import PaymentModal from "./modules/PaymentModal.vue";
  101. import goodsModal from "./modules/goodStock/goodsModal.vue";
  102. import PickingGoodsOrderModal from "./modules/PickingGoodsOrderModal.vue";
  103. import SelectCheckInRoomOrderModal from "./modules/SelectCheckInRoomOrderModal.vue";
  104. import {
  105. computed
  106. } from "vue";
  107. import {
  108. tree
  109. } from "@/api/good";
  110. const columns = [{
  111. title: "商品名称",
  112. dataIndex: "name",
  113. },
  114. {
  115. title: "数量",
  116. dataIndex: "num",
  117. scopedSlots: {
  118. customRender: "num"
  119. },
  120. },
  121. {
  122. title: "售价",
  123. dataIndex: "sellingPrice",
  124. },
  125. ];
  126. export default {
  127. name: "memberList",
  128. components: {
  129. PaymentModal,
  130. goodsModal,
  131. PickingGoodsOrderModal,
  132. SelectCheckInRoomOrderModal,
  133. },
  134. data() {
  135. return {
  136. isRemarkModal: false,
  137. isSaoma: false,
  138. remark:'',
  139. columns,
  140. sellClear: 0,
  141. queryParam: {},
  142. // 分页参数
  143. ipagination: {
  144. current: 1,
  145. pageSize: 99999,
  146. pageSizeOptions: ["10", "20", "30"],
  147. showTotal: (total, range) => {
  148. return range[0] + "-" + range[1] + " 共" + total + "条";
  149. },
  150. showQuickJumper: true,
  151. showSizeChanger: true,
  152. total: 0,
  153. },
  154. url: {
  155. list: "/pos/posSellClearGoods/list",
  156. delete: "/pos/posSellClearGoods/delete",
  157. deleteBatch: "/pos/posSellClearGoods/deleteBatch",
  158. exportXlsUrl: "/pos/posSellClearGoods/exportXls",
  159. importExcelUrl: "pos/posSellClearGoods/importExcel",
  160. },
  161. dictOptions: {},
  162. superFieldList: [],
  163. selectedRowKeys: [],
  164. isorter: {
  165. column: "createTime",
  166. order: "desc",
  167. },
  168. treeData: [],
  169. selectGoods: {},
  170. posTypeList: [],
  171. tabPosTypeId: "",
  172. selectGoodsList: [],
  173. goodsTypeList: [],
  174. tabgoodsTypeId: "1",
  175. dataSource: [],
  176. oldSelectGoodsList: [],
  177. selectOrderInfo: {},
  178. selectRoomOrder: {},
  179. };
  180. },
  181. provide() {
  182. return {
  183. treeData: computed(() => this.treeData),
  184. };
  185. },
  186. computed: {
  187. rowSelection() {
  188. return {
  189. onChange: (selectedRowKeys, selectedRows) => {
  190. console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  191. },
  192. getCheckboxProps: record => ({
  193. props: {
  194. disabled: record.name === 'Disabled User', // Column configuration not to be checked
  195. name: record.name,
  196. },
  197. }),
  198. };
  199. },
  200. sum() {
  201. return this.selectGoodsList.reduce(function (total, item) {
  202. return total + item.num;
  203. }, 0);
  204. },
  205. amount() {
  206. return this.selectGoodsList.reduce(function (total, item) {
  207. return total + item.sellingPrice * item.num;
  208. }, 0);
  209. },
  210. btnDisabled() {
  211. var res = this.selectGoodsList && this.selectGoodsList.length > 0;
  212. return !res;
  213. },
  214. },
  215. created() {
  216. this.dataSource = [{
  217. id: "0"
  218. }];
  219. getAction("/pos/posType/list", {
  220. pageNo: 1,
  221. pageSize: 99
  222. }).then((res) => {
  223. if (res.success) {
  224. this.posTypeList = res.result.records;
  225. if (this.posTypeList && this.posTypeList.length > 0) {
  226. this.tabPosTypeId = this.posTypeList[0].id;
  227. this.loadGoodsType();
  228. }
  229. }
  230. });
  231. this.loadTree();
  232. },
  233. methods: {
  234. remarkModal() {
  235. this.isRemarkModal = true;
  236. },
  237. loadTree() {
  238. var that = this;
  239. tree().then((res) => {
  240. if (res.success) {
  241. this.treeData = res.result;
  242. }
  243. });
  244. },
  245. modalFormOk() {},
  246. modalFormOk2(e) {
  247. console.log(e);
  248. var good = JSON.parse(JSON.stringify(e));
  249. this.$set(good, "num", 1);
  250. this.selectGoodsList.push(good);
  251. },
  252. modalSelectCheckInRoomOrderFormOk(e) {
  253. console.log(e);
  254. this.selectRoomOrder = e;
  255. },
  256. modalPickingGoodsOrderFormOk(e) {
  257. console.log(e);
  258. if (e && e.orderDetailList && e.orderDetailList.length > 0) {
  259. this.selectOrderInfo = e.orderInfo;
  260. e.orderDetailList.forEach((t) => {
  261. t.sellingPrice = t.payMoney;
  262. t.name = t.goodsName;
  263. t.id = t.goodsId;
  264. });
  265. this.selectGoodsList = e.orderDetailList;
  266. }
  267. },
  268. numChange(e, index) {
  269. console.log(e);
  270. if (e <= 0) {
  271. this.selectGoodsList.splice(index, 1);
  272. }
  273. },
  274. handleClear() {
  275. this.selectGoodsList = [];
  276. // this.selectOrderInfo = {};
  277. },
  278. tabPosTypeChange(e) {
  279. this.loadGoodsType();
  280. },
  281. tabGoodsTypeChange(e) {
  282. this.loadGoods();
  283. },
  284. loadGoodsType() {
  285. getAction("/rooms/cesStockType/getTopTypesByPosType", {
  286. posType: this.tabPosTypeId,
  287. }).then((res2) => {
  288. if (res2.success) {
  289. this.goodsTypeList = res2.result;
  290. if (this.goodsTypeList && this.goodsTypeList.length > 0) {
  291. this.loadGoods();
  292. }
  293. }
  294. });
  295. },
  296. loadGoods() {
  297. var ids = [];
  298. if (this.tabgoodsTypeId === "1") {
  299. this.goodsTypeList.forEach((t) => {
  300. ids.push(t.id);
  301. });
  302. } else {
  303. ids.push(this.tabgoodsTypeId);
  304. }
  305. this.dataSource = [{
  306. id: "0"
  307. }];
  308. getAction("/pos/posSellClearGoods/list", {
  309. pageNo: 1,
  310. pageSize: 99999,
  311. goodTypes: ids,
  312. }).then((res) => {
  313. if (res.success) {
  314. this.dataSource = [...this.dataSource, ...res.result.records];
  315. }
  316. });
  317. },
  318. handleDelete() {
  319. deleteAction("/pos/posSellClearGoods/delete", {
  320. goodsId: this.selectGoods.id,
  321. })
  322. .then((res) => {
  323. if (res.success) {
  324. this.$message.success(res.message);
  325. this.loadData();
  326. this.sellClear = 0;
  327. } else {
  328. this.$message.warning(res.message);
  329. }
  330. })
  331. .finally(() => {});
  332. },
  333. handleSelectCheckInRoomOrder() {
  334. this.$refs.modalSelectCheckInRoomOrderModal.add();
  335. this.$refs.modalSelectCheckInRoomOrderModal.title = "选择转帐人";
  336. this.$refs.modalSelectCheckInRoomOrderModal.disableSubmit = false;
  337. },
  338. handlePickingGoodsOrder() {
  339. this.$refs.modalPickingGoodsOrderForm.add();
  340. this.$refs.modalPickingGoodsOrderForm.title = "取单";
  341. this.$refs.modalPickingGoodsOrderForm.disableSubmit = false;
  342. },
  343. handleAddTempGoods() {
  344. this.$refs.modalGoodsForm.add();
  345. this.$refs.modalGoodsForm.title = "新增菜品";
  346. this.$refs.modalGoodsForm.disableSubmit = false;
  347. },
  348. handleToRoomFeePayment() {
  349. this.handleAdd();
  350. },
  351. handlePayment() {
  352. this.handleAdd((e) => {
  353. var amount = this.oldSelectGoodsList.reduce(function (total, item) {
  354. return total + item.sellingPrice * item.num;
  355. }, 0);
  356. this.$refs.modalPaymentForm.edit({
  357. billAmount: amount,
  358. deposit: 0,
  359. roomFee: amount,
  360. subjectType: 5,
  361. feeType: 2,
  362. preferentialType: 1,
  363. couponFirstAmount: 0,
  364. discount: 9,
  365. orderCode: e,
  366. });
  367. this.$refs.modalPaymentForm.title = "POS结账";
  368. this.$refs.modalPaymentForm.disableSubmit = false;
  369. });
  370. },
  371. handleAdd(callback) {
  372. if (!this.selectGoodsList || this.selectGoodsList.length <= 0) {
  373. this.$message.warning("请先选择商品");
  374. return;
  375. }
  376. var _info = JSON.parse(localStorage.getItem("storeInfo"));
  377. var model = {
  378. goodsId: this.selectGoods.id
  379. };
  380. if (_info) {
  381. model.hotelId = _info.id;
  382. }
  383. model.id = this.selectOrderInfo.id;
  384. model.toRoomFeeOrderId = this.selectRoomOrder.livingOrderId;
  385. model.posType = this.tabPosTypeId;
  386. var posOrderGoodsDetailList = [];
  387. this.selectGoodsList.forEach((t) => {
  388. posOrderGoodsDetailList.push({
  389. goodsId: t.id,
  390. num: t.num,
  391. money: t.sellingPrice,
  392. });
  393. });
  394. model.posOrderGoodsDetailList = posOrderGoodsDetailList;
  395. postAction("/pos/posOrderGoods/add", model)
  396. .then((res) => {
  397. if (res.success) {
  398. this.$message.success(res.message);
  399. this.oldSelectGoodsList = JSON.parse(
  400. JSON.stringify(this.selectGoodsList)
  401. );
  402. this.selectGoodsList = [];
  403. this.selectOrderInfo = {};
  404. this.selectRoomOrder = {};
  405. this.loadGoods();
  406. if (callback) {
  407. callback(res.result.code);
  408. }
  409. } else {
  410. this.$message.warning(res.message);
  411. }
  412. })
  413. .finally(() => {});
  414. },
  415. itemClick(row) {
  416. console.log(row);
  417. if (row.id == "0") {
  418. this.handleAddTempGoods();
  419. return;
  420. }
  421. if (row.isSellClear) {
  422. this.$message.warning("选择的商品已沽清");
  423. return;
  424. }
  425. var good = JSON.parse(JSON.stringify(row));
  426. this.$set(good, "num", 1);
  427. var find = this.selectGoodsList.find((t) => t.id === row.id);
  428. if (find) {
  429. if (find.inventory > find.num) {
  430. find.num++;
  431. }
  432. } else {
  433. this.selectGoodsList.push(good);
  434. }
  435. },
  436. },
  437. };
  438. </script>
  439. <style scoped>
  440. @import "~@assets/less/common.less";
  441. .room-item {
  442. height: 110px;
  443. /* line-height: 200px; */
  444. font-size: 13px;
  445. padding: 0px 5px;
  446. border-radius: 5px;
  447. cursor: pointer;
  448. position: relative;
  449. display: flex;
  450. flex-direction: column;
  451. justify-content: center;
  452. }
  453. .check {
  454. border: #000 solid 3px;
  455. }
  456. .ant-table-wrapper {
  457. height: calc(100vh - 500px);
  458. }
  459. /deep/ .card-pd .ant-card-body {
  460. padding: 0 !important;
  461. }
  462. .select-cell {
  463. position: absolute;
  464. width: 100%;
  465. height: 100%;
  466. left: 0;
  467. top: 0;
  468. z-index: 10;
  469. -webkit-user-select: none;
  470. -moz-user-select: none;
  471. -ms-user-select: none;
  472. user-select: none;
  473. }
  474. </style>