Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

addOrUpdate.vue 33KB

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