addOutbound.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. <template>
  2. <div class="bg-in-stock">
  3. <el-form ref="goodsExchangeAddFormRef" :model="goodsExchangeAddForm" :rules="goodsExchangeAddFormRule" label-width="160px" inline class="change-form">
  4. <el-form-item prop="warehouse_id" :label="$t('outBound')+$t('warechouse')" class="change-form-item">
  5. <el-select v-model="goodsExchangeAddForm.warehouse_id" :disabled="type === 'view' || type === 'audit'">
  6. <el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
  7. </el-select>
  8. </el-form-item>
  9. <el-form-item :label="$t('type')" prop="type" class="change-form-item">
  10. <el-select v-model="goodsExchangeAddForm.type" filterable allow-create clearable default-first-option :disabled="type === 'view' || type === 'audit'">
  11. <el-option
  12. v-for="item in typeList"
  13. :key="item.value"
  14. :label="item.label"
  15. :value="item.value"
  16. :disabled="item.value == 'SALE_OUT' || item.value == 'HAIL_OUT' || item.value == 'DAMAGE_OUT' || item.value == 'TRANSFER_OUT'"
  17. />
  18. </el-select>
  19. </el-form-item>
  20. <el-form-item :label="$t('notes')" prop="notes" class="change-form-item" style="width: 61%">
  21. <el-input
  22. style="flex: 1"
  23. v-model="goodsExchangeAddForm.notes"
  24. type="textarea"
  25. :disabled="type === 'view' || type === 'audit'"
  26. maxlength="250"
  27. :autosize="{ minRows: 3, maxRows: 4 }"
  28. :laceholder="$t('place')"
  29. ></el-input>
  30. </el-form-item>
  31. <div class="mx">
  32. <h3>{{$t('goods_inventory')}}</h3>
  33. <el-button class="button" size="mini" type="primary" v-if="type !== 'view' && type !== 'audit'" @click="scanCode">{{$t('scan_code')}}</el-button>
  34. <el-button class="button" size="mini" type="primary" v-if="type !== 'view' && type !== 'audit'" @click="handleSelectWarehouseEntryBatch"
  35. >{{$t('select')}}</el-button
  36. >
  37. </div>
  38. <div style="width: 100%; display: block">
  39. <el-form-item style="width: 100%">
  40. <el-table
  41. :data="goodsExchangeAddForm.product_list"
  42. border
  43. :cell-style="{ textAlign: 'center' }"
  44. :header-cell-style="{ textAlign: 'center' }"
  45. style="width: 100%; margin-top: 20px"
  46. >
  47. <el-table-column :label="$t('warechouse_code')">
  48. <template #default="scope">
  49. <el-popover placement="right" trigger="click" v-if="scope.row.area_stock_list">
  50. <div>
  51. <p v-for="item in scope.row.area_stock_list" :key="item.id">{{ item.warehouse_area_name }}</p>
  52. </div>
  53. <span slot="reference" v-if="scope.row.area_stock_list.length !== 0">{{ scope.row.area_stock_list[0].warehouse_area_name }}</span>
  54. </el-popover>
  55. </template>
  56. </el-table-column>
  57. <!-- <el-table-column label="商品编号">
  58. <template #default="scope">
  59. <span v-if="id">{{ scope.row.goods_vo.sn }}</span>
  60. <span v-else>{{ scope.row.goods_vo.sn }}</span>
  61. </template>
  62. </el-table-column> -->
  63. <el-table-column :label="$t('goods_name')">
  64. <template #default="scope">
  65. <span v-if="id">{{ scope.row.product_vo.name }}</span>
  66. <span v-else>{{ scope.row.product_vo.name }}</span>
  67. </template>
  68. </el-table-column>
  69. <el-table-column label="sku">
  70. <template #default="scope">
  71. <span v-if="id">{{ scope.row.product_vo.sku }}</span>
  72. <span v-else>{{ scope.row.product_vo.sku }}</span>
  73. </template>
  74. </el-table-column>
  75. <!-- <el-table-column label="序列号" v-if="sn_code_list">
  76. <template #default="scope">
  77. <div class="sn-code-container">
  78. <span v-for="item in scope.row.sn_code_list" :key="item.id">
  79. <p>{{ item.sn_code }}</p>
  80. </span>
  81. </div>
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="product_vo.spec_name" label="规格型号" v-if="id"> </el-table-column>
  85. <el-table-column prop="product_vo.spec_name" label="规格型号" v-else> </el-table-column>-->
  86. <el-table-column :label="$t('goods_unit')">
  87. <template #default="scope">
  88. {{ scope.row.product_vo.unit }}
  89. <!-- <span v-if="id">{{ scope.row.product_vo.unit }}</span>
  90. <span v-else>{{ scope.row.product_vo.unit }}</span> -->
  91. </template>
  92. </el-table-column>
  93. <el-table-column :label="$t('out_num')">
  94. <template #default="scope">
  95. <el-input v-model="scope.row.out_num" type="number" :min="0" :maxlength="20" :disabled="type === 'view' || type === 'audit'"></el-input>
  96. </template>
  97. </el-table-column>
  98. <!-- <el-table-column label="订单数量">
  99. <template #default="scope">
  100. {{ scope.row.order_num }}
  101. </template>
  102. </el-table-column> -->
  103. <el-table-column :label="$t('usable_stock')">
  104. <template #default="scope">
  105. {{ scope.row.usable_stock }}
  106. </template>
  107. </el-table-column>
  108. <el-table-column :label="$t('actual_stock')">
  109. <template #default="scope">
  110. {{ scope.row.actual_stock }}
  111. </template>
  112. </el-table-column>
  113. <el-table-column width="200" :label="$t('operate')" v-if="type !== 'view' && type !== 'audit'">
  114. <template #default="scope">
  115. <el-button size="mini" type="danger" @click="goodsExchangeAddForm.product_list.splice(scope.$index, 1)">{{$t('delete')}}</el-button>
  116. </template>
  117. </el-table-column>
  118. </el-table>
  119. </el-form-item>
  120. </div>
  121. </el-form>
  122. <div class="footer"><!-- && checkPermission(['warehouseOut2:add']) -->
  123. <el-button v-if="type !== 'audit' && type !== 'view' " type="primary" @click="saveGoodsExchangeAddForm"
  124. >{{$t('save')}}
  125. </el-button><!-- && checkPermission(['warehouseOut:update']) -->
  126. <el-button v-if="type !== 'audit' && type !== 'view'" type="primary" @click="submitGoodsExchangeAddForm"
  127. >{{$t('outBound')}}
  128. </el-button>
  129. <el-button @click="printIng" v-if="type == 'audit'">{{$t('print')}}</el-button>
  130. <el-button @click="toBack()">{{$t('return')}}</el-button>
  131. </div>
  132. <el-dialog :title="$t('prompt')" v-model:visible="dialogVisible" width="30%">
  133. <el-form ref="goodsExchangeAddForm" :model="goodsExchangeAddForm" label-width="120px" inline style="width: 900px">
  134. <el-form-item :label="$t('reject')" prop="reject_reason">
  135. <el-input v-model="goodsExchangeAddForm.reject_reason" type="textarea" :minlength="0" :maxlength="100"></el-input>
  136. </el-form-item>
  137. </el-form>
  138. <template #footer>
  139. <el-button @click="dialogVisible = false">{{$t('cancel')}}</el-button>
  140. <el-button type="primary" @click="handleRejectGoodsExchange()">{{$t('submit')}}</el-button>
  141. </template>
  142. </el-dialog>
  143. <el-dialog :title="$t('out_code')" v-model:visible="scanDialogVisible" width="30%" :close-on-click-modal="false">
  144. <el-form ref="scanGoodsForm" :model="scanGoodsForm" label-width="120px" inline>
  145. <el-form-item label="sku" prop="bar_code">
  146. <el-input v-model="scanGoodsForm.bar_code" ref="input" @keyup.enter="toSearch()" :minlength="0" :maxlength="100"></el-input>
  147. </el-form-item>
  148. <el-form-item label="序列号" prop="sn_code">
  149. <el-input v-model="sn_code" ref="sn_input" @keyup.enter="toSnCode()" :minlength="0" :maxlength="100"></el-input>
  150. </el-form-item>
  151. </el-form>
  152. </el-dialog>
  153. <el-dialog :title="$t('outBound')+$t('goods_info')" v-model="goodsVisible" width="1000px" @close="closeGoosData">
  154. <div style="display: flex; align-items: center; justify-content: flex-end; padding: 10px 0">
  155. <span>{{$t('search')+$t('goods_info')}}:</span><el-input v-model="params.keyWord" style="width: 200px; margin-right: 5px"></el-input>
  156. <el-button @click="searchGoodEvent"> {{$t('search')}} </el-button>
  157. </div>
  158. <el-table :data="goodsData.records" border style="width: 100%" @selection-change="handleSelectionChange">
  159. <el-table-column type="selection" width="55" />
  160. <el-table-column prop="product_vo.name" :label="$t('goods_name')"></el-table-column>
  161. <el-table-column prop="product_vo.sku" label="sku"> </el-table-column>
  162. <el-table-column prop="" :label="$t('brand')">
  163. <template #default="scope">
  164. {{ scope.row.product_vo.brand }}
  165. </template>
  166. </el-table-column>
  167. <el-table-column prop="product_vo.weight" :label="$t('weight')"> </el-table-column>
  168. <el-table-column prop="product_vo.unit" :label="$t('goods_unit')"> </el-table-column>
  169. </el-table>
  170. <el-pagination
  171. @size-change="goodsPageSizeChange"
  172. @current-change="goodsPageCurrentChange"
  173. :current-page="goodsData.current"
  174. :page-sizes="[10, 20, 50, 100]"
  175. :page-size="goodsData.size"
  176. layout="total, sizes, prev, pager, next, jumper"
  177. :total="goodsData.total"
  178. >
  179. </el-pagination>
  180. <template #footer>
  181. <el-button @click="closeGoosData">{{$t('cancel')}}</el-button>
  182. <el-button type="primary" @click="submitGoosData()">{{$t('submit')}}</el-button>
  183. </template>
  184. </el-dialog>
  185. </div>
  186. </template>
  187. <script setup>
  188. import { ref, onMounted, computed, watch, reactive,nextTick } from 'vue';
  189. import { useStore, mapGetters } from 'vuex';
  190. import * as API_GoodsExchange from '@/api/goodsExchange';
  191. import * as API_Setting from '@/api/setting';
  192. import * as API_BasicSetting from '@/api/basicSetting';
  193. import { useRoute, useRouter } from 'vue-router';
  194. import { ElMessageBox, ElMessage } from 'element-plus';
  195. import { useI18n } from 'vue-i18n';
  196. const { t } = useI18n();
  197. const route = useRoute();
  198. const router = useRouter();
  199. /* import * as API_Erp from '@/api/erp';
  200. import * as API_Auth from '@/api/auth'; */
  201. const store = useStore();
  202. const goodsExchangeAddForm = ref({
  203. /* order_list: [
  204. {
  205. order_id: '1752156400898293761',
  206. order_item_list: [
  207. {
  208. batch_list: [
  209. {
  210. batch_id: 0,
  211. batch_sn: '',
  212. out_num: 0,
  213. remain_num: 0,
  214. warehouse_entry_sn: '',
  215. },
  216. ],
  217. num: 0,
  218. order_item_id: 0,
  219. product_id: 0,
  220. product_name: 'string',
  221. product_sn: 'string',
  222. product_specification: 'string',
  223. product_unit: 'string',
  224. },
  225. ],
  226. order_sn: '',
  227. },
  228. ], */
  229. product_list: [],
  230. type: '',
  231. });
  232. const goodsExchangeAddFormRule = ref({
  233. warehouse_id: [{ required: true, message: t('change')+t('outBound')+t('warechouse'), trigger: 'change' }],
  234. type: [{ required: true, message: t('change')+t('outBound')+t('type'), trigger: 'change' }],
  235. });
  236. const typeList = ref([]);
  237. const adminList = ref([]);
  238. const dialogVisible = ref(false);
  239. const warehouseList = ref([]);
  240. const deptList = ref([]);
  241. const deptListAll = ref([]);
  242. const orderList = ref([]);
  243. const id = ref('');
  244. const type = ref('');
  245. const warehouseProduct = ref(null);
  246. const scanDialogVisible = ref(false);
  247. const scanGoodsForm = ref({});
  248. const routeName = ref('');
  249. const sttorageType = ref('');
  250. const goodsVisible = ref(false);
  251. const goodsData = ref([]);
  252. const snCodeVisible = ref(false);
  253. const sn_code = ref('');
  254. const sku = ref('');
  255. const sn_code_list = ref([]);
  256. const index = ref('');
  257. const user = computed(() => store.getters.user);
  258. const checkPrice = (rule, value, callback) => {
  259. if (!value && value !== 0) {
  260. return callback(new Error('换货金额不能为空'));
  261. } else if (!RegExp.money.test(value)) {
  262. callback(new Error('请输入正整数或者两位小数'));
  263. } else if (parseFloat(value) > 99999999) {
  264. callback(new Error('换货金额设置超过上限值'));
  265. } else {
  266. callback();
  267. }
  268. };
  269. const toBack = () => {
  270. router.push({
  271. name: 'goodsOutBound',
  272. });
  273. };
  274. /* 扫描sku */
  275. const toSnCode = async () => {
  276. if (sku.value == '') return ElMessage.error('请录入正确的sku');
  277. await API_GoodsExchange.getSnCode('out', sku.value, sn_code.value.replace(/\s+/g, '')).then(async (res) => {
  278. sn_code.value = '';
  279. let exists = goodsExchangeAddForm.value.product_list[index.value].sn_code_list.find((item) => item.sn_code === res.sn_code && item.sku === res.sku);
  280. if (!exists) {
  281. if (id.value) {
  282. await API_GoodsExchange.skuRedis({
  283. send_order_id: id.value,
  284. item_id: goodsExchangeAddForm.value.product_list[index.value].id,
  285. sku: res,
  286. }).then((response) => {
  287. goodsExchangeAddForm.value.product_list[index.value].sn_code_list.push(res);
  288. });
  289. } else {
  290. goodsExchangeAddForm.value.product_list[index.value].sn_code_list.push(res);
  291. }
  292. }
  293. goodsExchangeAddForm.value.product_list[index.value].out_num = goodsExchangeAddForm.value.product_list[index.value].sn_code_list.length;
  294. scanGoodsForm.value.bar_code = '';
  295. nextTick(() => {
  296. refs.input.focus();
  297. });
  298. });
  299. };
  300. const addSnCode = (row, index) => {
  301. sku.value = row.product_vo.sku;
  302. index.value = index;
  303. snCodeVisible.value = true;
  304. };
  305. const outType = () => {
  306. API_Setting.getPage({ dictType: 'out_warehouse_type' }).then((res) => {
  307. typeList.value = res.data;
  308. });
  309. };
  310. const printIng = () => {};
  311. /* 扫描序列号 */
  312. const toSearch = () => {
  313. API_GoodsExchange.getProduct(goodsExchangeAddForm.value.warehouse_id, scanGoodsForm.value.bar_code.replace(/\s+/g, '')).then((res) => {
  314. res.sn_code_list = [];
  315. sku.value = res.product_vo.sku;
  316. const indexs = goodsExchangeAddForm.value.product_list.findIndex((el) => {
  317. return el.goods_id === res.goods_id && el.product_id === res.product_id && el.product_vo.sku === res.product_vo.sku;
  318. });
  319. if (indexs === -1) {
  320. index.value = goodsExchangeAddForm.value.product_list.length;
  321. goodsExchangeAddForm.value.product_list.push(res);
  322. } else {
  323. index.value = indexs;
  324. }
  325. if (res.product_vo.have_sn) {
  326. nextTick(() => {
  327. refs.sn_input.focus();
  328. });
  329. } else {
  330. goodsExchangeAddForm.value.product_list[index.value].num += 1;
  331. }
  332. });
  333. };
  334. const scanCode = () => {
  335. if (!goodsExchangeAddForm.value.warehouse_id) {
  336. ElMessage.error(t('change')+t('warechouse')+'!');
  337. return;
  338. }
  339. scanDialogVisible.value = true;
  340. nextTick(() => {
  341. refs.input.focus();
  342. });
  343. };
  344. const GET_AdministratorList = () => {
  345. API_Auth.getAdministratorList({
  346. page_no: 1,
  347. page_size: 9999,
  348. user_state: 0,
  349. }).then((response) => {
  350. adminList.value = response.data;
  351. });
  352. };
  353. const GET_WarehouseList = (e) => {
  354. API_BasicSetting.getWarehouseListAll().then((response) => {
  355. warehouseList.value = response;
  356. });
  357. };
  358. const goodsExchangeAddFormRef = ref();
  359. const saveGoodsExchangeAddForm = () => {
  360. goodsExchangeAddFormRef.value.validate((valid) => {
  361. if (valid) {
  362. const { id } = goodsExchangeAddForm.value;
  363. const params = { ...goodsExchangeAddForm.value };
  364. params.save_or_submit = 'save';
  365. params.warehouse_consignee_id = deptListAll.value.id;
  366. params.out_time = Date.parse(new Date());
  367. params.staff_name = goodsExchangeAddForm.value.distribution_name;
  368. if (params.warehouse_id) {
  369. params.warehouse_name = warehouseList.value.find((ware) => ware.id === params.warehouse_id).name;
  370. }
  371. if (params.handled_by_id) {
  372. params.handled_by = adminList.value.find((admin) => admin.id === params.handled_by_id).real_name;
  373. }
  374. params.change_time = Math.floor(params.change_time / 1000);
  375. if (!goodsExchangeAddForm.value.product_list.length) {
  376. return;
  377. }
  378. if (params.type == 'OTHER_OUT' || params.type == 'BORROW_OUT') {
  379. const isStockSufficient = params.product_list.map((el) => {
  380. if (el.out_num > el.usable_stock) {
  381. ElMessage.error(t('goods_tips'));
  382. return false;
  383. }
  384. return true;
  385. });
  386. if (!isStockSufficient) {
  387. return;
  388. }
  389. }
  390. if (type.value == 'edit') {
  391. API_GoodsExchange.editWarehouseOut(id, params).then((response) => {
  392. ElMessage.success(t('edit_success')+'!');
  393. /* const { callback } = this.$route.params;
  394. if (typeof callback === 'function') callback();
  395. store.dispatch('delCurrentViews', {
  396. view: this.$route,
  397. $router: this.$router,
  398. }); */
  399. router.push({ name: 'goodsOutBound' });
  400. });
  401. } else {
  402. console.log(params);
  403. params.product_list.map((el) => {
  404. el.product_stock_id = el.id;
  405. el.id = '';
  406. });
  407. API_GoodsExchange.warehouseOut(params).then(() => {
  408. ElMessage.success(t('add_success')+'!');
  409. /* const { callback } = this.$route.params;
  410. if (typeof callback === 'function') callback();
  411. store.dispatch('delCurrentViews', {
  412. view: this.$route,
  413. $router: this.$router,
  414. }); */
  415. router.push({ name: 'goodsOutBound' });
  416. });
  417. }
  418. }
  419. });
  420. };
  421. const submitGoodsExchangeAddForm = () => {
  422. goodsExchangeAddFormRef.value.validate((valid) => {
  423. if (valid) {
  424. const { id } = goodsExchangeAddForm.value;
  425. const params = { ...goodsExchangeAddForm.value };
  426. params.save_or_submit = 'submit';
  427. params.warehouse_consignee_id = deptListAll.value.id;
  428. params.out_time = Date.parse(new Date());
  429. params.staff_name = goodsExchangeAddForm.value.distribution_name;
  430. if (params.warehouse_id) {
  431. params.warehouse_name = warehouseList.value.find((ware) => ware.id === params.warehouse_id).name;
  432. }
  433. if (params.handled_by_id) {
  434. params.handled_by = adminList.value.find((admin) => admin.id === params.handled_by_id).real_name;
  435. }
  436. params.change_time = Math.floor(params.change_time / 1000);
  437. if (!goodsExchangeAddForm.value.product_list.length) {
  438. ElMessage.error(t('change')+t('goods_info')+'!');
  439. return;
  440. }
  441. if (params.type == 'OTHER_OUT' || params.type == 'BORROW_OUT') {
  442. const isStockSufficient = params.product_list.map((el) => {
  443. if (el.out_num > el.usable_stock) {
  444. ElMessage.error(t('goods_tips'));
  445. return false;
  446. }
  447. return true;
  448. });
  449. if (!isStockSufficient) {
  450. return;
  451. }
  452. }
  453. if (type.value == 'edit') {
  454. API_GoodsExchange.editWarehouseOut(id, params).then((response) => {
  455. ElMessage.success(t('edit_success')+'!');
  456. /* const { callback } = this.$route.params;
  457. if (typeof callback === 'function') callback();
  458. store.dispatch('delCurrentViews', {
  459. view: this.$route,
  460. $router: this.$router,
  461. }); */
  462. router.push({ name: 'goodsOutBound' });
  463. });
  464. } else {
  465. params.product_list.map((el) => {
  466. el.product_stock_id = el.id;
  467. el.id = '';
  468. });
  469. API_GoodsExchange.warehouseOut(params).then(() => {
  470. ElMessage.success(t('add_success')+'!');
  471. /* const { callback } = this.$route.params;
  472. if (typeof callback === 'function') callback();
  473. store.dispatch('delCurrentViews', {
  474. view: this.$route,
  475. $router: this.$router,
  476. }); */
  477. router.push({ name: 'goodsOutBound' });
  478. });
  479. }
  480. }
  481. });
  482. };
  483. /* 关闭入库窗口 */
  484. const closeGoosData = () => {
  485. goodsVisible.value = false;
  486. };
  487. /* 打开商品弹窗 */
  488. const params = reactive({
  489. page_no: 1,
  490. page_size: 10,
  491. keyWord: '',
  492. });
  493. const handleSelectWarehouseEntryBatch = async () => {
  494. if (!goodsExchangeAddForm.value.warehouse_id) {
  495. ElMessage.error(t('change')+t('warechouse')+'!');
  496. return;
  497. }
  498. API_GoodsExchange.getGoodsInfo(params, goodsExchangeAddForm.value.warehouse_id, 'gt').then((res) => {
  499. goodsData.value = res;
  500. goodsVisible.value = true;
  501. });
  502. };
  503. /* 选中的商品列表 */
  504. const goodsList = ref([]);
  505. const handleSelectionChange = (val) => {
  506. goodsList.value = val.map((el) => {
  507. return el;
  508. });
  509. };
  510. const submitGoosData = () => {
  511. if (goodsList.value.length >= 1) {
  512. goodsExchangeAddForm.value.product_list = goodsList.value.map((el) => {
  513. return el;
  514. });
  515. goodsVisible.value = false;
  516. } else {
  517. ElMessage.error(t('change')+t('goods_info')+'!');
  518. }
  519. };
  520. const goodsPageSizeChange = (size) => {
  521. params.page_size = size;
  522. searchGoodEvent();
  523. };
  524. const goodsPageCurrentChange = (page) => {
  525. params.page_no = page;
  526. searchGoodEvent();
  527. };
  528. const handleSelectOrderSn = async () => {
  529. const orders = await this.$EnPickerOrder({
  530. orderApi: 'admin/erp/order',
  531. selectedIds: [goodsExchangeAddForm.value.order_sn],
  532. limit: 1,
  533. });
  534. this.$set(goodsExchangeAddForm.value, 'distribution_name', orders[0].distribution_name);
  535. const orderIds = orders.map((v) => v.sn);
  536. this.$set(goodsExchangeAddForm.value, 'order_sn', orderIds.join(','));
  537. GET_WarehouseOutProduct();
  538. };
  539. const GET_WarehouseOutProduct = async () => {
  540. const res = await API_Erp.getWarehouseOutProduct({
  541. order_sn: goodsExchangeAddForm.value.order_sn,
  542. });
  543. goodsExchangeAddForm.value.return_list = res.data.map((item) => {
  544. item.amount = item.product_price;
  545. item.product_sn = item.product_sn;
  546. item.product_name = item.product_name;
  547. item.specification = item.product_specification;
  548. item.product_id = item.product_id;
  549. item.unit = item.product_unit;
  550. item.out_num = item.return_num;
  551. item.stock_sn = item.warehouse_entry_sn;
  552. item.cost_price = item.product_cost_price;
  553. return item;
  554. });
  555. };
  556. const GET_DeptList = () => {
  557. API_GoodsExchange.getInfo().then((response) => {
  558. deptListAll.value = response;
  559. deptListAll.value.password = '';
  560. });
  561. };
  562. const handleChangeWareHouse = (val) => {
  563. // this.goodsExchangeAddForm.product_list = []change_list
  564. };
  565. const GET_goodsExchangeAddDetail = () => {
  566. nextTick(() => {
  567. API_GoodsExchange.getGoodsWarehouseOut(route.query.id).then((response) => {
  568. goodsExchangeAddForm.value = response;
  569. GET_WarehouseList({ dept_id: response.warehouse_id });
  570. goodsExchangeAddForm.value.change_time = Math.floor(goodsExchangeAddForm.value.change_time * 1000);
  571. /* response.product_list.map((el) => {
  572. el.order_num = el.out_num;
  573. el.out_num = 0;
  574. if (!el.sn_code_list) {
  575. el.sn_code_list = [];
  576. } else {
  577. el.out_num = el.sn_code_list;
  578. }
  579. }); */
  580. goodsExchangeAddForm.value.distribution_name = response.staff_name;
  581. goodsExchangeAddForm.value.product_list = response.product_list;
  582. });
  583. });
  584. };
  585. onMounted(() => {
  586. if (route.query.type == 'view') {
  587. type.value = 'view';
  588. GET_goodsExchangeAddDetail();
  589. } else if (route.query.type == 'edit') {
  590. type.value = 'edit';
  591. GET_goodsExchangeAddDetail();
  592. }
  593. routeName.value = route.name;
  594. sttorageType.value = route.params.type;
  595. GET_WarehouseList();
  596. GET_DeptList();
  597. outType();
  598. });
  599. /* watch(() => route, {
  600. immediate: true,
  601. handler(newVal) {
  602. if (route.name === 'goodsExchangeEdit') {
  603. type.value = 'edit';
  604. } else if (route.name === 'goodsExchangeAudit') {
  605. type.value = 'audit';
  606. } else if (route.name === 'goodsExchangeReturn') {
  607. type.value = 'return';
  608. } else if (route.name === 'goodsExchangeAdd') {
  609. type.value = 'add';
  610. GET_WarehouseList({ dept_id: user.value.dept_id });
  611. set(goodsExchangeAddForm.value, 'change_time', new Date().getTime());
  612. } else if (route.name === 'goodsExchangeDetail') {
  613. type.value = 'detail';
  614. }
  615. if (route.params.id) {
  616. id.value = route.params.id;
  617. GET_goodsExchangeAddDetail();
  618. }
  619. GET_AdministratorList();
  620. },
  621. }); */
  622. </script>
  623. <style scoped>
  624. .footer {
  625. width: 100%;
  626. padding: 10px;
  627. bottom: 0px;
  628. text-align: center;
  629. z-index: 999;
  630. }
  631. .mx {
  632. display: flex;
  633. align-items: center;
  634. width: 100%;
  635. }
  636. .mx .button {
  637. margin-left: 10px;
  638. }
  639. .change-form {
  640. display: flex;
  641. justify-content: flex-start;
  642. align-items: flex-start;
  643. flex-wrap: wrap;
  644. min-width: 900px;
  645. }
  646. .change-form .change-form-item {
  647. width: 30%;
  648. margin: 0 10px 20px 0;
  649. display: flex;
  650. flex-direction: row;
  651. flex-wrap: nowrap;
  652. }
  653. .change-form .el-form-item__content,
  654. .change-form .el-date-editor,
  655. .change-form .el-cascader,
  656. .change-form .el-select {
  657. flex: 1;
  658. width: 100%;
  659. }
  660. .bg-in-stock {
  661. background-color: #fff;
  662. margin: 10px;
  663. padding: 25px;
  664. }
  665. .goods-info {
  666. display: flex;
  667. }
  668. .goods-info .goods-name-box {
  669. text-align: left;
  670. }
  671. .goods-info .goods-name-box .goods-name {
  672. text-overflow: ellipsis;
  673. display: -webkit-box;
  674. -webkit-line-clamp: 2;
  675. -webkit-box-orient: vertical;
  676. overflow: hidden;
  677. line-height: 16px;
  678. }
  679. .goods-info .goods-name-box .specs {
  680. color: #999999;
  681. }
  682. .sn-code-container {
  683. max-height: 100px;
  684. overflow-y: auto;
  685. }
  686. .el-input--suffix .el-input__inner {
  687. padding-right: 10px;
  688. }
  689. .error-input .el-input__inner {
  690. border: 1px solid red;
  691. }
  692. </style>