checkInventory.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. <template>
  2. <div class="bg-in-stock" id="deliverySheet">
  3. <div ref="printId">
  4. <div class="title">
  5. <h2 v-if="checkType == 'first'">出库单</h2>
  6. <h2 v-else>入库单</h2>
  7. </div>
  8. <div class="numOrder">
  9. <barcode :value="barcodeValue"></barcode>
  10. </div>
  11. <el-form
  12. ref="goodsExchangeAddForm"
  13. :model="goodsExchangeAddForm"
  14. :rules="goodsExchangeAddFormRule"
  15. label-width="120px"
  16. inline
  17. class="change-form"
  18. >
  19. <el-form-item
  20. label="订单:"
  21. prop="order_id"
  22. class="change-form-item"
  23. v-if="checkType == 'second'"
  24. >
  25. {{ goodsExchangeAddForm.order_id }}
  26. </el-form-item>
  27. <el-form-item
  28. v-if="checkType == 'first'"
  29. label="出库仓库:"
  30. class="change-form-item"
  31. >
  32. {{ warehouseName(goodsExchangeAddForm.warehouse_id) }}
  33. </el-form-item>
  34. <el-form-item v-else label="入库仓库:" class="change-form-item">
  35. {{ warehouseName(goodsExchangeAddForm.warehouse_id) }}
  36. </el-form-item>
  37. <el-form-item label="类型:" prop="type" class="change-form-item">
  38. {{ warehouseType(goodsExchangeAddForm.type) }}
  39. </el-form-item>
  40. <el-form-item
  41. label="备注:"
  42. prop="memo"
  43. class="change-form-item"
  44. style="width: 61%"
  45. >
  46. <span v-if="checkType == 'first'">{{ goodsExchangeAddForm.notes}}</span>
  47. <span v-else>{{ goodsExchangeAddForm.memo }}</span>
  48. </el-form-item>
  49. <div class="mx">
  50. <h3>商品明细</h3>
  51. </div>
  52. <div style="width: 100%; display: block">
  53. <el-form-item style="width: 100%">
  54. <el-table
  55. :data="goodsExchangeAddForm.product_list"
  56. border
  57. :cell-style="{ textAlign: 'center' }"
  58. row-key="id"
  59. :header-cell-style="{ textAlign: 'center' }"
  60. class="draggable-table"
  61. style="width: 100%; margin-top: 20px"
  62. >
  63. <el-table-column label="商品编号">
  64. <template slot-scope="scope">
  65. {{ scope.row.goods_vo.sn }}
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="商品名称">
  69. <template slot-scope="scope">
  70. {{ scope.row.goods_vo.name }}
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="条码">
  74. <template slot-scope="scope">
  75. <!-- {{ scope.row.bar_code }} -->
  76. <span v-if="id">{{ scope.row.product_vo.bar_code }}</span>
  77. <span v-else>{{ scope.row.bar_code }}</span>
  78. </template>
  79. </el-table-column>
  80. <el-table-column label="序列号">
  81. <template slot-scope="scope">
  82. <span v-for="item in scope.row.sn_code_list" :key="item.id">{{item.sn_code}},</span>
  83. <!--<span v-if="id">{{ scope.row.product_vo.sn_code }}</span>
  84. <span v-else>{{ scope.row.sn_code }}</span> -->
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="product_vo.spec_name" label="规格型号" v-if="id">
  88. <!-- <template slot-scope="scope">
  89. {{ scope.row.product_vo.spec_name.join("/") }}
  90. </template> -->
  91. </el-table-column>
  92. <el-table-column prop="spec_name" label="规格型号" v-else>
  93. <!-- <template slot-scope="scope">
  94. {{ scope.row.spec_name.join("/") }}
  95. </template> -->
  96. </el-table-column>
  97. <el-table-column label="单位">
  98. <template slot-scope="scope">
  99. <span v-if="id">{{ scope.row.product_vo.unit }}</span>
  100. <span v-else>{{ scope.row.unit }}</span>
  101. </template>
  102. </el-table-column>
  103. <!-- <el-table-column label="订单数量"> </el-table-column> -->
  104. <el-table-column v-if="checkType == 'first'" label="出库数量">
  105. <template slot-scope="scope">
  106. <el-input
  107. v-model="scope.row.out_num"
  108. type="number"
  109. :min="0"
  110. :maxlength="20"
  111. :disabled="true"
  112. ></el-input>
  113. </template>
  114. </el-table-column>
  115. <el-table-column v-else label="入库数量">
  116. <template slot-scope="scope">
  117. <el-input
  118. v-model="scope.row.num"
  119. type="number"
  120. :min="0"
  121. :maxlength="20"
  122. :disabled="true"
  123. ></el-input>
  124. </template>
  125. </el-table-column>
  126. <el-table-column label="库存数量" v-if="checkType == 'first'">
  127. <template slot-scope="scope">
  128. {{ scope.row.usable_stock }}
  129. </template>
  130. </el-table-column>
  131. <!-- <el-table-column label="差异">
  132. <template slot-scope="scope">
  133. 入库减去库存
  134. {{ scope.row.num - scope.row.already_num || 0 }}
  135. </template>
  136. </el-table-column>-->
  137. <el-table-column label="操作" v-if="false">
  138. <template slot-scope="scope">
  139. <el-button
  140. size="mini"
  141. type="danger"
  142. @click="
  143. goodsExchangeAddForm.product_list.splice(scope.$index, 1)
  144. "
  145. >删除</el-button
  146. >
  147. </template>
  148. </el-table-column>
  149. </el-table>
  150. </el-form-item>
  151. </div>
  152. </el-form>
  153. </div>
  154. <div class="footer">
  155. <el-button @click="handlePrintGoodsLend">打印</el-button>
  156. <el-button @click="$router.back()">返回</el-button>
  157. </div>
  158. </div>
  159. </template>
  160. <script>
  161. import { mapGetters } from "vuex";
  162. import { Foundation, RegExp } from "~/ui-utils";
  163. import * as API_GoodsExchange from "@/api/goodsExchange";
  164. import * as API_Setting from "@/api/setting";
  165. import * as API_BasicSetting from "@/api/basicSetting";
  166. import * as API_Erp from "@/api/erp";
  167. import * as API_Auth from "@/api/auth";
  168. import Print from "print-js";
  169. import html2canvas from "html2canvas";
  170. import Sortable from "sortablejs";
  171. export default {
  172. name: "goodsExchangeAdd",
  173. data() {
  174. const checkPrice = (rule, value, callback) => {
  175. if (!value && value !== 0) {
  176. return callback(new Error("换货金额不能为空"));
  177. } else if (!RegExp.money.test(value)) {
  178. callback(new Error("请输入正整数或者两位小数"));
  179. } else if (parseFloat(value) > 99999999) {
  180. callback(new Error("换货金额设置超过上限值"));
  181. } else {
  182. callback();
  183. }
  184. };
  185. return {
  186. typeList: [
  187. /* {
  188. real_name: "采购入库",
  189. id: "采购入库",
  190. },
  191. {
  192. real_name: "租赁返回",
  193. id: "租赁返回",
  194. },
  195. {
  196. real_name: "其他入库",
  197. id: "其他入库",
  198. }, */
  199. ],
  200. adminList: [],
  201. dialogVisible: false,
  202. warehouseList: [],
  203. deptList: [],
  204. deptListAll: [],
  205. orderList: [],
  206. id: "",
  207. type: "",
  208. /** 出库单表单*/
  209. goodsExchangeAddForm: {
  210. change_amount: 0,
  211. change_list: [],
  212. return_list: [],
  213. product_list: [],
  214. },
  215. /** 校验规则 */
  216. goodsExchangeAddFormRule: {
  217. // change_amount: [
  218. // { required: true, message: '请输入换货金额', trigger: 'blur' },
  219. // { validator: checkPrice, trigger: 'blur' }
  220. // ]
  221. },
  222. warehouseProduct: null,
  223. scanDialogVisible: false,
  224. scanGoodsForm: {},
  225. routeName: "",
  226. // 出库商品明细
  227. goodsVisible: false,
  228. goodsData: [],
  229. // 暂存已勾选商品
  230. goodsList: [],
  231. // 条形码
  232. barcodeValue: "",
  233. // 类型
  234. checkType: "",
  235. warehouseList: [],
  236. };
  237. },
  238. mounted() {
  239. // this.routeName = this.$route.name;
  240. this.id = this.$route.params.id;
  241. this.checkType = this.$route.params.type;
  242. this.GET_WarehouseList();
  243. this.GET_DeptList();
  244. this.GET_goodsExchangeAddDetail();
  245. this.rowDrop();
  246. },
  247. watch: {
  248. // $route: {
  249. // immediate: true,
  250. // },
  251. },
  252. computed: {
  253. ...mapGetters(["user"]),
  254. },
  255. methods: {
  256. /* 获取类型 */
  257. warehouseType(val) {
  258. let name = "";
  259. this.typeList.map((el) => {
  260. if (el.value == val) {
  261. return (name = el.label);
  262. }
  263. });
  264. return name;
  265. },
  266. //获取仓库名称
  267. warehouseName(val) {
  268. let name = "";
  269. this.warehouseList.map((el) => {
  270. if (el.id == val) {
  271. return (name = el.name);
  272. }
  273. });
  274. return name;
  275. },
  276. /* 仓库 */
  277. GET_WarehouseList(e) {
  278. API_BasicSetting.getWarehouseListAll().then((response) => {
  279. this.warehouseList = response;
  280. });
  281. },
  282. //行拖拽
  283. rowDrop() {
  284. const tbody = document.querySelector(
  285. ".draggable-table .el-table__body-wrapper tbody"
  286. );
  287. const _this = this;
  288. Sortable.create(tbody, {
  289. animation: 300,
  290. onEnd({ newIndex, oldIndex }) {
  291. const currRow = _this.goodsExchangeAddForm.product_list.splice(
  292. oldIndex,
  293. 1
  294. )[0];
  295. _this.goodsExchangeAddForm.product_list.splice(newIndex, 0, currRow);
  296. },
  297. });
  298. },
  299. // 打印功能
  300. printIng() {},
  301. /** 出入库单 */
  302. handlePrintGoodsLend() {
  303. // Print({
  304. // printable: 'deliverySheet',
  305. // type: 'html',
  306. // targetStyles: ['*'],
  307. // ignoreElements: ['no-logs', 'goods-image', 'no-btn']
  308. // })
  309. const printContent = this.$refs.printId;
  310. // 获取dom 宽度 高度
  311. const width = printContent.clientWidth;
  312. const height = printContent.clientHeight;
  313. // 创建一个canvas节点
  314. const canvas = document.createElement("canvas");
  315. const scale = 4; // 定义任意放大倍数,支持小数;越大,图片清晰度越高,生成图片越慢。
  316. canvas.width = width * scale; // 定义canvas 宽度 * 缩放
  317. canvas.height = height * scale; // 定义canvas高度 *缩放
  318. canvas.style.width = width * scale + "px";
  319. canvas.style.height = height * scale + "px";
  320. canvas.getContext("2d").scale(scale, scale); // 获取context,设置scale
  321. const scrollTop =
  322. document.documentElement.scrollTop || document.body.scrollTop; // 获取滚动轴滚动的长度
  323. const scrollLeft =
  324. document.documentElement.scrollLeft || document.body.scrollLeft; // 获取水平滚动轴的长度
  325. html2canvas(printContent, {
  326. canvas,
  327. backgroundColor: null,
  328. useCORS: true,
  329. windowHeight: document.body.scrollHeight,
  330. scrollX: -scrollLeft, // 解决水平偏移问题,防止打印的内容不全
  331. scrollY: -scrollTop,
  332. })
  333. .then((canvas) => {
  334. const url = canvas.toDataURL("image/png");
  335. printJS({
  336. printable: url,
  337. type: "image",
  338. documentTitle: "", // 标题
  339. style: "@page{size:auto;margin: 0cm 1cm 0cm 1cm;}", // 去除页眉页脚
  340. });
  341. })
  342. .catch((err) => {
  343. console.error(err);
  344. });
  345. },
  346. toSearch() {
  347. API_GoodsExchange.getGoodsInfo({
  348. barcode: this.scanGoodsForm.bar_code,
  349. }).then((res) => {
  350. console.log(res);
  351. });
  352. },
  353. /** 获取人员列表 */
  354. GET_AdministratorList() {
  355. API_Auth.getAdministratorList({
  356. page_no: 1,
  357. page_size: 9999,
  358. user_state: 0,
  359. }).then((response) => {
  360. this.adminList = response.data;
  361. });
  362. },
  363. /** 获取仓库 */
  364. GET_WarehouseList(e) {
  365. API_BasicSetting.getWarehouseListAll().then((response) => {
  366. this.warehouseList = response;
  367. });
  368. },
  369. /** 获取部门 */
  370. GET_DeptList() {
  371. API_Setting.getDeptList().then((response) => {
  372. this.deptList = Foundation.buildTree(response, "0");
  373. this.deptListAll = response;
  374. });
  375. },
  376. /** 获取详情页面数据 getGoodsWarehouseOut*/
  377. GET_goodsExchangeAddDetail() {
  378. this.$nextTick(() => {
  379. if (this.checkType == "first") {
  380. API_GoodsExchange.getGoodsWarehouseOut(this.id).then((response) => {
  381. API_Setting.getPage({ dictType: "out_warehouse_type" }).then(
  382. (res) => {
  383. this.typeList = res.data;
  384. }
  385. );
  386. this.goodsExchangeAddForm = response;
  387. this.barcodeValue = response.sn;
  388. this.goodsExchangeAddForm.distribution_name = response.staff_name;
  389. this.goodsExchangeAddForm.product_list =
  390. response.product_list; /* .map(
  391. (item) => {
  392. item.name = item.goods_vo.name;
  393. item.sn = item.goods_vo.sn;
  394. item.sn_code = item.goods_vo.sn_code;
  395. item.bar_code = item.goods_vo.bar_code;
  396. item.entry_price = item.amount;
  397. item.goods_specification = item.specification;
  398. item.goods_unit = item.goods_vo.goods_unit;
  399. item.warehouse_entry_sn = item.stock_sn;
  400. item.usable_stock = item.goods_vo.usable_stock;
  401. return item;
  402. }
  403. ); */
  404. });
  405. } else {
  406. API_GoodsExchange.getGoodsExchangeInfo(this.id).then((response) => {
  407. API_Setting.getPage({ dictType: "warehouse_entry_type" }).then(
  408. (res) => {
  409. this.typeList = res.data;
  410. }
  411. );
  412. this.goodsExchangeAddForm = response;
  413. this.barcodeValue = response.sn;
  414. this.goodsExchangeAddForm.distribution_name = response.staff_name;
  415. this.goodsExchangeAddForm.product_list = response.product_list.map(
  416. (item) => {
  417. item.name = item.goods_do.name;
  418. item.sn = item.goods_do.sn;
  419. item.sn_code = item.goods_do.sn_code;
  420. item.bar_code = item.goods_do.bar_code;
  421. item.entry_price = item.amount;
  422. item.goods_specification = item.specification;
  423. item.goods_unit = item.goods_do.goods_unit;
  424. item.warehouse_entry_sn = item.stock_sn;
  425. item.usable_stock = item.goods_do.usable_stock;
  426. return item;
  427. }
  428. );
  429. });
  430. }
  431. });
  432. },
  433. },
  434. };
  435. </script>
  436. <style type="text/scss" lang="scss" scoped>
  437. @media print {
  438. .barcode-container {
  439. border: none;
  440. }
  441. }
  442. /** 底部步骤 */
  443. .footer {
  444. width: 100%;
  445. padding: 10px;
  446. bottom: 0px;
  447. text-align: center;
  448. z-index: 999;
  449. }
  450. .mx {
  451. display: flex;
  452. align-items: center;
  453. width: 100%;
  454. .button {
  455. margin-left: 10px;
  456. }
  457. }
  458. .change-form {
  459. display: flex;
  460. justify-content: flex-start;
  461. align-items: flex-start;
  462. flex-wrap: wrap;
  463. min-width: 900px;
  464. .change-form-item {
  465. width: 49%;
  466. margin: 0 10px 20px 0;
  467. display: flex;
  468. flex-direction: row;
  469. flex-wrap: nowrap;
  470. }
  471. /deep/ {
  472. .el-form-item__content {
  473. flex: 1;
  474. width: 100%;
  475. }
  476. .el-date-editor,
  477. .el-cascader,
  478. .el-select {
  479. width: 100%;
  480. }
  481. }
  482. }
  483. .bg-in-stock {
  484. background-color: #fff;
  485. margin: 10px;
  486. padding: 25px;
  487. .title {
  488. text-align: center;
  489. }
  490. .numOrder {
  491. display: flex;
  492. justify-content: center;
  493. }
  494. }
  495. .goods-info {
  496. display: flex;
  497. .goods-name-box {
  498. text-align: left;
  499. .goods-name {
  500. text-overflow: ellipsis;
  501. display: -webkit-box;
  502. -webkit-line-clamp: 2;
  503. -webkit-box-orient: vertical;
  504. overflow: hidden;
  505. line-height: 16px;
  506. }
  507. .specs {
  508. color: #999999;
  509. }
  510. }
  511. }
  512. /deep/ {
  513. .el-input--suffix .el-input__inner {
  514. padding-right: 10px;
  515. }
  516. .error-input {
  517. .el-input__inner {
  518. border: 1px solid red;
  519. }
  520. }
  521. }
  522. </style>