選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

addOrUpdate.vue 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. <template>
  2. <div>
  3. <el-form label-position="right" label-width="140px" :model="addForm" :rules="rules"
  4. :ref="(el) => dataFormRef = el" v-loading="formLoding" :inline-message="true">
  5. <el-card class="box-card">
  6. <template #header>
  7. <div class="card-header">
  8. <span>基础信息</span>
  9. </div>
  10. </template>
  11. <div>
  12. <el-form-item label="备货单号" prop="applyNo" v-if="typeOption !== 'add'">
  13. <el-input maxlength="60" v-trim clearable v-model="addForm.applyNo" :disabled="true"/>
  14. </el-form-item>
  15. <el-form-item label="入库仓库名称" prop="storeCodeList">
  16. <el-cascader v-model="addForm.storeCodeList"
  17. :disabled="typeOption === 'view' || typeOption === 'sure'" :options="interfaceLowerListArr"
  18. :props="props2" clearable @change="handleChange"/>
  19. </el-form-item>
  20. <el-form-item label="产权" prop="ownType">
  21. <el-select clearable v-model="addForm.ownType" placeholder="请选择产权"
  22. :disabled="typeOption === 'view' || typeOption === 'sure'">
  23. <el-option v-for="item in OWN_TYPE" :key="item.value" :label="item.label"
  24. :value="item.value"/>
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item label="入库设备类型" prop="inventoryType">
  28. <el-select clearable v-model="addForm.inventoryType" placeholder="请选择入库设备类型"
  29. :disabled="typeOption === 'view' || typeOption === 'sure'" @change="changeDeviceType">
  30. <el-option v-for="item in deviceTypeList" :key="item.value" :label="item.label"
  31. :value="item.value"/>
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item label="设备型号" prop="version">
  35. <el-select clearable v-model="addForm.version" placeholder="请选择设备型号"
  36. :disabled="typeOption === 'view' || typeOption === 'sure'">
  37. <el-option v-if="addForm.inventoryType === 'CARD'" v-for="item in cardDeviceVersion"
  38. :key="item.value" :label="item.label" :value="item.value"/>
  39. <el-option v-if="addForm.inventoryType === 'OBU'" v-for="item in obuDeviceVersion"
  40. :key="item.value" :label="item.label" :value="item.value"/>
  41. </el-select>
  42. </el-form-item>
  43. <el-form-item label="采购厂商" prop="brand">
  44. <el-select clearable v-model="addForm.brand" placeholder="请选择设备厂商"
  45. :disabled="typeOption === 'view' || typeOption === 'sure'">
  46. <el-option v-if="addForm.inventoryType === 'OBU'" v-for="item in manufacturerList"
  47. :key="item?.value" :label="item.label" :value="item.value"/>
  48. <el-option v-if="addForm.inventoryType === 'CARD'" v-for="item in cardManufacturerList"
  49. :key="item.value" :label="item.label" :value="item.value"/>
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item label="签类型" prop="obuType" v-if="addForm.inventoryType === 'OBU'">
  53. <el-select clearable v-model="addForm.obuType" placeholder="请选择签类型"
  54. :disabled="typeOption === 'view' || typeOption === 'sure'">
  55. <el-option v-for="item in obuType" :key="item.value" :label="item.label"
  56. :value="item.value"/>
  57. </el-select>
  58. </el-form-item>
  59. <el-form-item label="卡种" prop="cardType" v-if="addForm.inventoryType === 'CARD'">
  60. <el-select clearable v-model="addForm.cardType" placeholder="请选择卡类型"
  61. :disabled="typeOption === 'view' || typeOption === 'sure'">
  62. <el-option v-for="item in cardType" :key="item.value" :label="item.label"
  63. :value="item.value"/>
  64. </el-select>
  65. </el-form-item>
  66. </div>
  67. </el-card>
  68. <el-card class="box-card">
  69. <template #header>
  70. <div class="card-header">
  71. <span>设备明细</span>
  72. <el-upload style="display: inline-block; margin-left: 20px" ref="upload"
  73. v-if="typeOption === 'add' || typeOption === 'edit'" :on-exceed="handleExceed"
  74. :before-upload="beforeAvatarUpload" :data="data" :action="uploadUrl"
  75. @success="onSuccess($event)" accept=".xlsx" :limit="1" :multiple="false"
  76. :show-file-list="false">
  77. <el-button type="primary">导入备货号段</el-button>
  78. </el-upload>
  79. <el-button v-if="typeOption === 'add' || typeOption === 'edit'"
  80. style="display: inline-block; margin-left: 20px" type="primary"
  81. @click="templateDownload">下载模板
  82. </el-button>
  83. </div>
  84. </template>
  85. <div>
  86. <el-table :data="addForm.detailList" :border="true" show-summary :span-method="arraySpanMethod"
  87. :ref="(el) => tableListRef = el" :summary-method="getSummaries">
  88. <el-table-column type="index" header-align="center" align="center" width="60"></el-table-column>
  89. <el-table-column label="起始号段">
  90. <template v-slot="scope">
  91. <div class="input-wrap">
  92. <el-form-item label="" :prop="`startId-${scope.$index}-${scope.row.startId}`"
  93. label-width="0px" style="width: 100%" :rules="{
  94. validator: validateStartId,
  95. trigger: 'blur',
  96. required: true,
  97. }">
  98. <el-input maxlength="60" v-trim clearable v-model="scope.row.startId"
  99. placeholder="请输入起始号段"
  100. :disabled="typeOption === 'view' || typeOption === 'sure'"
  101. @input="handleApplyCount(scope.row, scope.$index)"/>
  102. </el-form-item>
  103. </div>
  104. </template>
  105. </el-table-column>
  106. <el-table-column label="结束号段">
  107. <template v-slot="scope">
  108. <div class="input-wrap">
  109. <el-form-item label="" :prop="`endId-${scope.$index}-${scope.row.endId}`"
  110. label-width="0px" style="width: 100%" :rules="{
  111. validator: validateEndId,
  112. trigger: 'blur',
  113. required: true,
  114. }">
  115. <el-input maxlength="60" v-trim clearable v-model="scope.row.endId"
  116. placeholder="请输入结束号段"
  117. :disabled="typeOption === 'view' || typeOption === 'sure'"
  118. @input="handleApplyCount(scope.row, scope.$index)"/>
  119. </el-form-item>
  120. </div>
  121. </template>
  122. </el-table-column>
  123. <!-- addForm.deviceType === 'OBU' addForm.obuType === 'SINGLE_CHIP'-->
  124. <!-- <el-table-column label="到期时间" width="200">
  125. <template v-slot="scope"> -->
  126. <!-- <el-select clearable v-model="scope.row.warranty" style="width: 100%" placeholder="请选择设备质保期"
  127. :disabled="typeOption === 'view' || typeOption === 'sure'">
  128. <el-option v-for="item in warrantyList" :key="item.value" :label="item.label"
  129. :value="item.value" />
  130. </el-select> -->
  131. <!-- <el-date-picker unlink-panels v-model="scope.row.warranty" type="date"
  132. placeholder="请选择到期时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
  133. style="width: 100%" /> -->
  134. <!-- </template>
  135. </el-table-column> -->
  136. <el-table-column label="操作" width="340" v-if="typeOption === 'add' || typeOption === 'edit'">
  137. <template v-slot="scope">
  138. <el-button class="op-btn" type="primary"
  139. @click="validHandle(scope.row, scope.$index)">校验
  140. </el-button>
  141. <el-button class="op-btn" type="danger" v-if="scope.$index > 0"
  142. @click="deleteHandle(scope.row, scope.$index)">删除
  143. </el-button>
  144. <el-button class="op-btn" type="success"
  145. v-if="scope.$index === (addForm.detailList.length - 1)"
  146. @click="addMoreHandle(scope.row)">继续添加
  147. </el-button>
  148. </template>
  149. </el-table-column>
  150. </el-table>
  151. </div>
  152. </el-card>
  153. </el-form>
  154. <div class="btn-wrap">
  155. <el-button type="primary" @click="backHandle">关闭</el-button>
  156. <el-button type="primary" v-if="typeOption === 'add' || typeOption === 'edit'" @click="saveHandle"
  157. v-loading="btnLoding">备货保存
  158. </el-button>
  159. <el-button type="primary" v-if="typeOption === 'sure'" @click="sureHandle"
  160. v-loading="btnLoding">确认入库
  161. </el-button>
  162. </div>
  163. </div>
  164. </template>
  165. <script setup lang='ts'>
  166. import {reactive, ref, toRaw, getCurrentInstance, onMounted, toRefs, nextTick, computed} from 'vue'
  167. import {ElNotification, ElMessage, UploadInstance, UploadProps, UploadRawFile, genFileId} from "element-plus";
  168. import {IObject} from "@/types/interface";
  169. import {useDebounce, getDictLabel, isNumber, treeDataTranslate, bigNumSub, bigNumAdd} from "@/utils/utils";
  170. import {cloneDeep} from "lodash"
  171. import BaseService from "@/utils/baseService";
  172. import {
  173. getInfoApi,
  174. sureApi,
  175. checkNumApi,
  176. checkNumDetailApi,
  177. addApi,
  178. updateApi,
  179. lowerListApi,
  180. agencyApi,
  181. importReturnApi
  182. } from "@/api/inventoryControl/putInstorage";
  183. import $storeinitData from "@/store/initData"; //引入tab vuex
  184. // 声明事件
  185. const emit = defineEmits([
  186. "closeHandle",
  187. "refreshDataList"
  188. ])
  189. const handleChange = (value) => {
  190. console.log(value)
  191. }
  192. const uploadUrl = "/minIo/upload"
  193. const data = {bucket: ""};
  194. const upload = ref<UploadInstance>()
  195. const dataFormRef = ref();
  196. const tableListRef = ref();
  197. const formLoding = ref(false);
  198. const active = ref(1);
  199. const typeOption = ref(""); // 是新增还是修改
  200. const dateValue = ref();
  201. const initForm = {
  202. id: "",
  203. storeId: "",
  204. inventoryType: "",
  205. version: "",
  206. applyId: "",
  207. brand: "",
  208. detailList: [
  209. {
  210. startId: "",
  211. endId: "",
  212. // warranty: "",
  213. count: 0,
  214. isShowBtn: false,
  215. failTotal: 0,
  216. successTotal: 0,
  217. total: 0
  218. }
  219. ]
  220. }
  221. const templateDownload = () => {
  222. let url = import.meta.env.VITE_APP_UPLOAD_URL + 'zhywpt-issuer/template/invw/设备备货号段导入模板.xlsx';
  223. console.log(url, 'bizContent.exportExcelUrlbizContent.exportExcelUrl')
  224. BaseService.getDownload(url, '设备备货号段导入模板')
  225. }
  226. const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  227. // if (rawFile.type !== 'application/vnd.android.package-archive') {
  228. // ElMessage.error('请上传正确的应用文件')
  229. // return false
  230. // } else if (rawFile.size / 1024 / 1024 > 200) {
  231. // ElMessage.error('文件大小不能超过 200MB!')
  232. // return false
  233. // }
  234. return true
  235. }
  236. const state = reactive({
  237. btnLoding: false,
  238. addForm: cloneDeep(initForm),
  239. warrantyList: [] as IObject[],
  240. allList: [] as IObject[],
  241. treeData: [] as IObject[],
  242. summary: false
  243. })
  244. const interfaceLowerListArr = ref([]);
  245. const interfaceAgencyArr = ref([]);
  246. const deviceTypeList = computed(() => {
  247. // return $storeinitData.state.dictData['DEVICE_TYPE'] || [];
  248. return $storeinitData.state.dictData['INVENTORY_TYPE'] || [];
  249. })
  250. const OWN_TYPE = computed(() => {
  251. return $storeinitData.state.dictData['OWN_TYPE'] || [];
  252. })
  253. const cardDeviceVersion = computed(() => {
  254. return $storeinitData.state.dictData['DEVICE_VERSION'] || [];
  255. })
  256. const obuDeviceVersion = computed(() => {
  257. return $storeinitData.state.dictData['DEVICE_VERSION'] || [];
  258. // return $storeinitData.state.dictData['DEVICE_VERSION_OBU'] || [];
  259. })
  260. const deviceModelList = computed(() => {
  261. return $storeinitData.state.dictData['UNIT_TYPE'] || [];
  262. })
  263. const manufacturerList = computed(() => {
  264. // return $storeinitData.state.dictData['EQUIPMENT_MANUFACTURER_TYPE'] || [];
  265. return $storeinitData.state.dictData['OBU_BRAND'] || [];
  266. })
  267. const cardManufacturerList = computed(() => {
  268. // return $storeinitData.state.dictData['CARD_EQUIPMENT_MANUFACTURER_TYPE'] || [];
  269. return $storeinitData.state.dictData['CARD_BRAND'] || [];
  270. })
  271. const cardType = computed(() => {
  272. return $storeinitData.state.dictData['CARD_TYPE'] || [];
  273. })
  274. const obuType = computed(() => {
  275. return $storeinitData.state.dictData['OBU_TYPE'] || [];
  276. })
  277. const {addForm, warrantyList, allList, treeData, btnLoding, summary}: any = toRefs(state)
  278. const rules = reactive({
  279. storeCodeList: [{required: true, message: "请选择入库仓库", trigger: "blur"}],
  280. ownType: [{required: true, message: "请选择产权", trigger: "blur"}],
  281. version: [{required: true, message: "请选择设备型号", trigger: "blur"}],
  282. inventoryType: [{required: true, message: "请选择设备类型", trigger: "blur"}],
  283. brand: [{required: true, message: "请选择设备厂商", trigger: "blur"}],
  284. })
  285. const props2 = {
  286. value: "id",
  287. label: "name",
  288. children: "subordinateModel",
  289. // multiple: true,
  290. checkStrictly: true,
  291. }
  292. const handleExceed: UploadProps['onExceed'] = (files) => {
  293. upload.value!.clearFiles()
  294. const file = files[0] as UploadRawFile
  295. file.uid = genFileId()
  296. upload.value!.handleStart(file)
  297. upload.value!.submit()
  298. }
  299. function changeDeviceType() {
  300. addForm.value.version = ''
  301. addForm.value.brand = ''
  302. }
  303. // 初始化
  304. function init(row: any) {
  305. console.log("测试:",row)
  306. getLowerList();
  307. // getAgency();
  308. clearData();
  309. warrantyList.value = [
  310. {
  311. label: "一年质保期",
  312. value: "1年"
  313. },
  314. {
  315. label: "两年质保期",
  316. value: "2年"
  317. },
  318. {
  319. label: "三年质保期",
  320. value: "3年"
  321. },
  322. {
  323. label: "四年质保期",
  324. value: "4年"
  325. },
  326. {
  327. label: "五年质保期",
  328. value: "5年"
  329. }
  330. ]
  331. if (row && row.id) {
  332. getInfo(row.id)
  333. }
  334. }
  335. // 获取详情
  336. function getInfo(id: string) {
  337. formLoding.value = true;
  338. ///invw/inventory/inventorydetailbyid
  339. BaseService.postN('/invw/api/enterApply/view', {id: id}).then((res: any) => {
  340. if (res && res.code === 0) {
  341. let bizContent = res.data
  342. let data = bizContent.enterApply || {};
  343. console.log("===data", data);
  344. let detailList = bizContent.applyDetailsList || [];
  345. let list: any = [];
  346. detailList.map((item) => {
  347. let start = item.startId.slice(3);
  348. let end = item.endId.slice(3);
  349. let num = parseInt(end) - parseInt(start) + 1;
  350. list.push(
  351. {
  352. ...item,
  353. count: num,
  354. isShowBtn: true,
  355. failTotal: 0,
  356. successTotal: 0,
  357. total: 0
  358. }
  359. )
  360. })
  361. addForm.value = {
  362. ...data,
  363. detailList: list
  364. }
  365. //addForm.value.detailList = list;
  366. formLoding.value = false;
  367. } else {
  368. formLoding.value = false;
  369. ElMessage.error(res.message)
  370. }
  371. })
  372. }
  373. function onSuccess(response: any) {
  374. console.log(response)
  375. BaseService.postN('/invw/api/enterApply/parseExcel', {excelUrl: response.data.ossFilePath}).then((res: any) => {
  376. if (res && res.code === 0) {
  377. let bizContent = res.data;
  378. console.log(bizContent)
  379. let info = bizContent.modelList || "";
  380. let data = bizContent.modelList
  381. let newarr: any = []
  382. data.forEach((column, index) => {
  383. return newarr.push(
  384. {
  385. startId: column.startId,
  386. endId: column.endId,
  387. count: column.endId - column.startId,
  388. isShowBtn: false
  389. }
  390. );
  391. })
  392. addForm.value.detailList = newarr;
  393. ElMessage.success(info)
  394. } else {
  395. ElMessage.error(res.message)
  396. }
  397. })
  398. }
  399. // 初始化还原数据
  400. function clearData() {
  401. addForm.value = cloneDeep(initForm);
  402. allList.value = [];
  403. treeData.value = [];
  404. }
  405. function backHandle() {
  406. clearData();
  407. emit("closeHandle");
  408. }
  409. function validHandle(row: IObject, index) {
  410. dataFormRef.value.validate((valid) => {
  411. if (!valid) {
  412. return false;
  413. }
  414. let params: any = {
  415. startId: row.startId,
  416. endId: row.endId,
  417. cardType: addForm.value.cardType,
  418. obuType: addForm.value.obuType,
  419. inventoryType: addForm.value.inventoryType,
  420. }
  421. if (row.id) {
  422. params.detailId = row.id;
  423. }
  424. ///invw/inventory/checkinventorysegment
  425. BaseService.postN('/invw/api/enterApply/codeValid', params).then((res: any) => {
  426. if (res && res.code === 0) {
  427. // let bizContent = res.data
  428. // let data = {
  429. // failTotal: bizContent.failTotal,
  430. // successTotal: bizContent.successTotal,
  431. // total: bizContent.total,
  432. // }
  433. // summary.value = true;
  434. // addForm.value.detailList[index] = {
  435. // ...addForm.value.detailList[index],
  436. // isShowBtn: true,
  437. // failTotal: bizContent.failTotal,
  438. // successTotal: bizContent.successTotal,
  439. // total: bizContent.total,
  440. // }
  441. // let msg = `${bizContent.info}, 总数:${bizContent.total},成功:${bizContent.successTotal},失败:${bizContent.failTotal}`
  442. ElMessage.success(res.message);
  443. } else {
  444. addForm.value.detailList[index].isShowBtn = true;
  445. ElMessage.error(res.message)
  446. }
  447. })
  448. })
  449. }
  450. function validDetailHandle(row: IObject) {
  451. let params: any = {
  452. startId: row.startId,
  453. endId: row.endId
  454. }
  455. if (row.applyId) {
  456. params.applyId = row.applyId;
  457. }
  458. if (row.id) {
  459. params.detailId = row.id;
  460. }
  461. BaseService.postN('/invw/inventory/checkinventorysegmentdetail', params).then((res: any) => {
  462. if (res && res.code === 0) {
  463. let bizContent = res.data
  464. let url = bizContent.url || "";
  465. let fileName = bizContent.fileName ? `${bizContent.fileName}` : '校验结果明细'
  466. if (url) {
  467. // window.open(import.meta.env.VITE_APP_UPLOAD_URL+url);
  468. BaseService.getDownload(import.meta.env.VITE_APP_UPLOAD_URL + url, fileName);
  469. } else {
  470. ElMessage.error("未返回文件地址");
  471. }
  472. } else {
  473. ElMessage.error(res.message)
  474. }
  475. })
  476. }
  477. function deleteHandle(row: IObject, index: number) {
  478. let list = [...addForm.value.detailList];
  479. list.splice(index, 1);
  480. addForm.value.detailList = list;
  481. }
  482. // 继续添加
  483. function addMoreHandle(row: IObject) {
  484. addForm.value.detailList.push({
  485. startId: "",
  486. endId: "",
  487. // warranty: "",
  488. count: 0,
  489. isShowBtn: false,
  490. failTotal: 0,
  491. successTotal: 0,
  492. total: 0
  493. });
  494. }
  495. // 校验结束编号
  496. //编号规则。设备类型是卡的话,位数是20位 设备类型是OBU的话,位数的16位
  497. function validateEndId(rule: any, value: string, callback: (e?: Error) => any) {
  498. let inventoryType = addForm.value.inventoryType;
  499. let indexArr = rule.field.split("-");
  500. let index = indexArr[1];
  501. let val = indexArr[2];
  502. if (!isNumber(val)) {
  503. return callback(new Error("必须是数字!"));
  504. }
  505. let length = val.length;
  506. if (inventoryType === "CARD" && length !== 20) {
  507. return callback(new Error("卡编号位数是20!"));
  508. } else if (inventoryType === "OBU" && length !== 16) {
  509. return callback(new Error("OBU编号位数是16!"));
  510. }
  511. if (
  512. val &&
  513. addForm.value.detailList[index].startId &&
  514. val < addForm.value.detailList[index].startId
  515. ) {
  516. return callback(new Error("结束编号不能小于开始编号"));
  517. }
  518. if (
  519. val && addForm.value.detailList.length < index &&
  520. addForm.value.detailList[index + 1].startId &&
  521. val >= addForm.value.detailList[index + 1].startId
  522. ) {
  523. return callback(new Error("结束编号要小于下一段的开始编号"));
  524. }
  525. // 列表中不能重复校验
  526. let endIds = addForm.value.detailList.filter((item) => item.endId === val);
  527. if (endIds.length > 1) {
  528. callback(new Error("请检查,结束编号有重复"));
  529. }
  530. callback();
  531. }
  532. // 校验开始编号
  533. function validateStartId(
  534. rule: any,
  535. value: string,
  536. callback: (e?: Error) => any
  537. ) {
  538. let inventoryType = addForm.value.inventoryType;
  539. let indexArr = rule.field.split("-");
  540. let index = indexArr[1];
  541. let val = indexArr[2];
  542. if (!isNumber(val)) {
  543. return callback(new Error("必须是数字!"));
  544. }
  545. let length = val.length;
  546. //长度校验
  547. if (inventoryType === "CARD" && length !== 20) {
  548. return callback(new Error("卡编号位数是20!"));
  549. } else if (inventoryType === "OBU" && length !== 16) {
  550. return callback(new Error("OBU编号位数是16!"));
  551. }
  552. // 开始编号不能大于结束编号校验
  553. if (
  554. val &&
  555. addForm.value.detailList[index].endId &&
  556. val > addForm.value.detailList[index].endId
  557. ) {
  558. return callback(new Error("开始编号不能大于结束编号"));
  559. }
  560. if (
  561. val && index > 0 &&
  562. addForm.value.detailList[index - 1].endId &&
  563. val <= addForm.value.detailList[index - 1].endId
  564. ) {
  565. return callback(new Error("开始编号要大于上一段的结束编号"));
  566. }
  567. // 列表中不能重复校验
  568. let startIds = addForm.value.detailList.filter((item) => item.startId === val);
  569. if (startIds.length > 1) {
  570. callback(new Error("请检查,起始编号有重复"));
  571. }
  572. callback();
  573. }
  574. // 导出
  575. function exportHandle(list: IObject[]) {
  576. let header: string[] = [
  577. "序号",
  578. "申请单编号",
  579. "起始编号",
  580. "结束编号",
  581. "入库结果",
  582. "失败原因",
  583. "重复编号列表",
  584. ];
  585. const resultString = {
  586. ALL_SUCCESS: "全部成功",
  587. PART_SUCESS: "部分成功",
  588. ALL_FAIL: "全部失败"
  589. }
  590. let data: any = [];
  591. let countMony = 0;
  592. let num = 0;
  593. list.map((item, index) => {
  594. let value: any = [];
  595. value.push(index + 1);
  596. value.push(item.applyId);
  597. value.push(item.startId);
  598. value.push(item.endId);
  599. value.push(item.result ? resultString[item.result] : '');
  600. value.push(item.failReason);
  601. value.push(item.duplicatedIds);
  602. data.push(value);
  603. });
  604. import("@/utils/Export2Excel").then((excel) => {
  605. //保存excel
  606. excel.export_json_to_excel({
  607. header: header,
  608. data,
  609. //导出的文件名
  610. filename: "入库结果",
  611. });
  612. });
  613. btnLoding.value = false;
  614. }
  615. // 备货保存
  616. function saveHandle() {
  617. btnLoding.value = true;
  618. if (typeOption.value === "add") {
  619. if (addForm.value.storeCodeList !== undefined && addForm.value.storeCodeList !== null && addForm.value.storeCodeList.length !== 0) {
  620. addForm.value.storeCode = addForm.value.storeCodeList[addForm.value.storeCodeList.length - 1]
  621. }
  622. }
  623. dataFormRef.value.validate((valid) => {
  624. if (!valid) {
  625. btnLoding.value = false;
  626. return false;
  627. }
  628. let params: any = {
  629. ...addForm.value
  630. }
  631. let list: any = [];
  632. // 过滤掉仅前端展示的参数和计算的参数。再提交
  633. const keys = ["isShowBtn", "failTotal", "total", "successTotal", "count"]
  634. params.detailList.map((item) => {
  635. let tem = {};
  636. for (let key in item) {
  637. if (keys.indexOf(key) < 0) {
  638. tem[key] = item[key]
  639. }
  640. }
  641. list.push(tem);
  642. })
  643. console.log(params);
  644. let params2 = {}
  645. params2.enterApplyDetailModels = list;
  646. params2.brand = params.brand;
  647. params2.inventoryType = params.inventoryType;
  648. params2.ownType = params.ownType;
  649. params2.storeCode = params.storeCode;
  650. params2.agencyId = interfaceLowerListArr.value.find(item => item.id === params.storeCode).agencyId;
  651. params2.version = params.version;
  652. params2.cardType = params.cardType;
  653. params2.obuType = params.obuType;
  654. // let api = '/invw/inventory/addinventoryapply';
  655. let api = '/invw/api/enterApply/apply';
  656. console.log("typeOption.value", typeOption.value)
  657. if (typeOption.value === 'add') {
  658. delete params2.id
  659. }
  660. if (typeOption.value === 'edit') {
  661. params2.id = params.id
  662. api = '/invw/api/enterApply/update';
  663. }
  664. BaseService.postN(api, params2).then((res: any) => {
  665. if (res && res.code === 0) {
  666. btnLoding.value = false;
  667. clearData();
  668. emit("refreshDataList");
  669. emit("closeHandle");
  670. ElMessage.success("备货保存成功");
  671. } else {
  672. btnLoding.value = false;
  673. ElMessage.error(res.message);
  674. }
  675. })
  676. })
  677. }
  678. // 确认入库
  679. function sureHandle() {
  680. btnLoding.value = true;
  681. if (addForm.value.id) {
  682. let params = {
  683. id: addForm.value.id
  684. }
  685. ///invw/inventory/inventoryinstorage
  686. BaseService.postN('/invw/api/enterApply/confirm', params).then((res: any) => {
  687. if (res && res.code === 0) {
  688. // let bizContent = res.data
  689. // let url = bizContent.url || "";
  690. // let fileName = bizContent.fileName ? `${bizContent.fileName}` : '初始设备入库明细'
  691. // if (url) {
  692. // //window.open(url)
  693. // //处理下载有文件名
  694. // BaseService.getDownloadFileName(import.meta.env.VITE_APP_UPLOAD_URL + url, fileName)
  695. // btnLoding.value = false;
  696. // clearData();
  697. // emit("refreshDataList");
  698. // emit("closeHandle");
  699. // ElMessage.success("确认入库成功");
  700. // } else {
  701. // ElMessage.error("入库成功文件未返回");
  702. // }
  703. btnLoding.value = false;
  704. clearData();
  705. emit("refreshDataList");
  706. emit("closeHandle");
  707. ElMessage.success(res.message);
  708. } else {
  709. btnLoding.value = false;
  710. ElMessage.error(res.message);
  711. }
  712. })
  713. }
  714. }
  715. // 计算conut
  716. function handleApplyCount(row: IObject, index) {
  717. let startId = row.startId;
  718. let endId = row.endId;
  719. let inventoryType = addForm.value.inventoryType;
  720. let num = 0;
  721. if (inventoryType === 'CARD' && startId && endId) {
  722. // let start = startId.toString().slice(3);
  723. // let end = endId.toString().slice(3);
  724. // num = parseInt(end) - parseInt(start) + 1;
  725. let start: any = startId.toString().slice(3);
  726. let end: any = endId.toString().slice(3);
  727. let tem = bigNumSub(end, start);
  728. num = bigNumAdd(tem, '1');
  729. } else if (inventoryType === 'OBU' && startId && endId) {
  730. //num = parseInt(endId) - parseInt(startId) + 1;
  731. let tem = bigNumSub(endId, startId);
  732. num = bigNumAdd(tem, '1');
  733. }
  734. //解决合计刷新
  735. let receiveVoValue = cloneDeep(addForm.value.detailList);
  736. receiveVoValue[index].count = num;
  737. addForm.value.detailList = receiveVoValue;
  738. }
  739. // 合并合计行
  740. function arraySpanMethod({row, column, rowIndex, columnIndex}) {
  741. //table合计行合并单元格
  742. nextTick(() => {
  743. if (tableListRef.value.$el) {
  744. let current = tableListRef.value.$el
  745. .querySelector('.el-table__footer-wrapper')
  746. .querySelector('.el-table__footer')
  747. let cell = current.rows[0].cells
  748. cell[1].colSpan = '4'
  749. }
  750. })
  751. }
  752. // 合计行计算
  753. function getSummaries(param) {
  754. //table自定义合计行方法summary-method
  755. const {columns, data} = param;
  756. const sums: any = [];
  757. columns.forEach((column, index) => {
  758. if (index === 0) {
  759. sums[index] = '合计';
  760. return
  761. }
  762. if (index === 2) {
  763. const values = data.map((item) => Number(item.count));
  764. sums[1] = values.reduce((prev, curr) => {
  765. return prev + curr
  766. }, 0)
  767. sums[1] = sums[1]
  768. }
  769. })
  770. // let str = "";
  771. // if (sums[1]) {
  772. // str = `共${data.length}号段,${sums[1]}个设备`;
  773. // if (summary.value) {
  774. // console.log(data, '-----');
  775. // const successTotal = data.map((item) => Number(item.successTotal));
  776. // console.log(successTotal.value);
  777. // console.log(4535);
  778. // let totalNum = sums[1] = successTotal.reduce((prev, curr) => {
  779. // return prev + curr
  780. // }, 0)
  781. // str = str + '已校验可入库数量' + totalNum
  782. // }
  783. // }
  784. sums[1] = `共${data.length}号段,${sums[1]}个设备`;
  785. return sums
  786. }
  787. // 获取仓库状态
  788. function getLowerList() {
  789. // console.log("获取仓库列表")
  790. let params = {
  791. allType: 0
  792. }
  793. BaseService.postN('/invw/api/warehouse/getWarehouseIdNames', params).then((res: any) => {
  794. // console.log(res)
  795. if (res && res.code === 0) {
  796. let bizContent = res.data
  797. // console.log(bizContent)
  798. let data = bizContent.idNames || [];
  799. interfaceLowerListArr.value = data
  800. } else {
  801. ElMessage.error(res.message)
  802. }
  803. })
  804. }
  805. // 获取仓库状态
  806. function getAgency() {
  807. // console.log("获取产权列表")
  808. BaseService.postN('/invw/agency/list').then((res: any) => {
  809. if (res && res.code === 0) {
  810. let bizContent = res.data
  811. // console.log(bizContent)
  812. let data = bizContent.idNames || [];
  813. let agencyList: any = [];
  814. data.map((item) => {
  815. // console.log(item)
  816. agencyList.push({
  817. label: item.agencyName,
  818. value: item.ownType
  819. })
  820. })
  821. interfaceAgencyArr.value = agencyList
  822. } else {
  823. ElMessage.error(res.message)
  824. }
  825. })
  826. }
  827. defineExpose({
  828. init,
  829. addForm,
  830. typeOption,
  831. clearData
  832. })
  833. </script>
  834. <style lang='scss' scoped>
  835. .btn-wrap {
  836. display: flex;
  837. justify-content: center;
  838. }
  839. .box-card {
  840. margin-bottom: 16px;
  841. }
  842. .op-btn {
  843. padding: 8px;
  844. }
  845. .input-wrap {
  846. display: flex;
  847. .el-form-item {
  848. margin-bottom: 0;
  849. }
  850. }
  851. .btn-read {
  852. margin-left: 10px;
  853. }
  854. </style>