当前位置:   article > 正文

发票自动识别功能前端开发(多表单动态生成)_发票验证开发

发票验证开发

一.先上效果图(全部代码见文章尾部)

8844a28034cc43abbf8821b3530106d5.jpeg

二.整体思路 

上面部分是v-for遍历生成走马灯的item标签(el-carousel-item),el-form放在每个标签里面去动态生成。

底部是自己写的一个滚动块,滚动块index和上面走马灯item的index下标实时保持对应。

应用流程/业务逻辑如下:(ocr模块支持图片和多张发票的pdf文件扫描上传)

        新增:

       点击底部滑块+号选择图片/pdf上传  -> 读取后端返回的数组对象,遍历并添加到el-carousel-item里面,移动滑块index到最新(上面的图片如果是照片就回显,如果是pdf文件,就显示一个默认logo,点击图片/pdf都打开新页面显示出来)  -> 编辑好信息后点击确定 -> 验证是否有重复,有重复阻止提交,并提示出重复的发票。

        编辑:

        编辑我这里业务相对简单,编辑的时候回显表单数据,隐藏底部滑块(意味着+号的新增也去掉了),发票号码,代码不可编辑,只可以对部分基础数据进行编辑。

 三.入参

 oriForm:表单数据,接收为数组,el-form根据这个值生成多组form表单

opeType:是新增还是编辑  参数为add/edit

  1. props: {
  2. oriForm: {
  3. type: Array,
  4. default: [],
  5. },
  6. opeType: {
  7. type: String,
  8. default: "",
  9. },
  10. },

四.关键难点/坑点代码 

  1. <el-form
  2. :ref="'dataForm' + mainIndex" 这里ref动态赋予
  3. >
  1. <el-upload
  2. :ref="'elUpload' + mainIndex" 上传文件的ref动态赋予
  3. >
  1. this.$set(this.model[active], "statementNo", this.settlementNo); //form表单给值得时候用this.$set
  2. this.$forceUpdate(); //有时候页面无法刷新,用这个方法

五.整体代码

  1. <template>
  2. <div
  3. class="invoice-form"
  4. v-loading="pageLoading"
  5. element-loading-text="发票识别中..."
  6. >
  7. <el-carousel
  8. indicator-position="none"
  9. :autoplay="false"
  10. ref="elCarousel"
  11. :loop="false"
  12. height="490px"
  13. @change="changeCarousel"
  14. >
  15. <el-carousel-item
  16. :name="mainIndex.toString()"
  17. v-for="(mainItem, mainIndex) in model"
  18. :key="mainIndex"
  19. >
  20. <el-form
  21. :model="mainItem"
  22. :ref="'dataForm' + mainIndex"
  23. :rules="formRule"
  24. >
  25. <div class="invoice-img middle-center">
  26. <i
  27. v-if="opeType != 'edit'"
  28. class="el-icon-delete upload-delete-cl"
  29. @click.stop="deleteImg(mainIndex)"
  30. ></i>
  31. <el-upload
  32. action="/personal/ocr/invoice"
  33. :ref="'elUpload' + mainIndex"
  34. :disabled="opeType == 'edit'"
  35. drag
  36. :limit="1"
  37. :show-file-list="false"
  38. :before-upload="beforeUpload"
  39. :on-exceed="onExceed"
  40. :on-error="onError"
  41. :on-success="
  42. (row, info, c) => {
  43. return onSuccess(row, info, c, mainIndex);
  44. }
  45. "
  46. class="el-upload-block"
  47. >
  48. <div class="top-img-box">
  49. <div
  50. class="full-box"
  51. @click.stop="openPdf(mainItem.invoiceImage)"
  52. v-if="mainItem.contentType == 'application/pdf'"
  53. >
  54. <div class="block-one middle-center">
  55. <img src="../imgs/pdf4.jpg" class="pdf-img-cl" />
  56. </div>
  57. <div class="pdf-name-cl">{{ mainItem.fileName }}</div>
  58. </div>
  59. <div v-else class="full-box middle-center">
  60. <div
  61. class="upload-img-box middle-center"
  62. v-if="mainItem.invoiceImage"
  63. >
  64. <img
  65. class="top-img-cl"
  66. :src="$baseUrl + mainItem.invoiceImage"
  67. />
  68. </div>
  69. <div v-else>
  70. <i class="el-icon-upload"></i>
  71. <div class="el-upload__text">
  72. 将发票文件拖到此处自动识别,或<em>点击上传</em>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </el-upload>
  78. </div>
  79. <el-row type="flex">
  80. <el-form-item
  81. class="item-cl"
  82. :label-width="labelWidth"
  83. label="对账单编号"
  84. prop="statementNo"
  85. >
  86. <select-remote
  87. :ref="'statementSelectRemote' + mainIndex"
  88. class="input-cl"
  89. :disabled="opeType == 'edit'"
  90. keyName="settlementNo"
  91. labelName="settlementNo"
  92. size="small"
  93. valueName="settlementNo"
  94. remoteUrl="/personal/credent/reconciliation/list"
  95. @change="(row) => changeStatement(row, mainIndex)"
  96. placeholder="支持对账单编号模糊查询"
  97. queryField="settlementNo"
  98. :pagination="true"
  99. :resultLine="['data', 'list']"
  100. ></select-remote>
  101. </el-form-item>
  102. <el-form-item
  103. class="item-cl"
  104. :label-width="labelWidth"
  105. label="发票号码"
  106. prop="invoiceNo"
  107. >
  108. <el-input
  109. clearable
  110. :disabled="opeType == 'edit'"
  111. placeholder="请输入发票号码"
  112. class="input-cl"
  113. size="small"
  114. v-model.trim="mainItem.invoiceNo"
  115. />
  116. </el-form-item>
  117. </el-row>
  118. <el-row type="flex">
  119. <el-form-item
  120. class="item-cl"
  121. :label-width="labelWidth"
  122. label="发票代码"
  123. prop="invoiceCode"
  124. >
  125. <el-input
  126. clearable
  127. :disabled="opeType == 'edit'"
  128. placeholder="请输入发票代码"
  129. class="input-cl"
  130. size="small"
  131. v-model.trim="mainItem.invoiceCode"
  132. />
  133. </el-form-item>
  134. <el-form-item
  135. class="item-cl"
  136. :label-width="labelWidth"
  137. label="开票日期"
  138. prop="billingShow"
  139. >
  140. <el-date-picker
  141. :unlink-panels="true"
  142. size="small"
  143. v-model.trim="mainItem.billingShow"
  144. type="datetime"
  145. value-format="yyyy-MM-dd HH:mm:ss"
  146. placeholder="请选择开票日期"
  147. class="input-cl"
  148. :clearable="false"
  149. >
  150. </el-date-picker>
  151. </el-form-item>
  152. </el-row>
  153. <el-row type="flex">
  154. <el-form-item
  155. class="item-cl"
  156. :label-width="labelWidth"
  157. label="合计金额"
  158. prop="totalAmt"
  159. >
  160. <el-input-number
  161. size="small"
  162. class="input-cl"
  163. v-model="mainItem.totalAmt"
  164. controls-position="right"
  165. :precision="2"
  166. :min="0"
  167. ></el-input-number>
  168. </el-form-item>
  169. <el-form-item
  170. class="item-cl"
  171. :label-width="labelWidth"
  172. label="票面金额"
  173. prop="invoiceAmt"
  174. >
  175. <el-input-number
  176. size="small"
  177. class="input-cl"
  178. v-model="mainItem.invoiceAmt"
  179. controls-position="right"
  180. :precision="2"
  181. :min="0"
  182. ></el-input-number>
  183. </el-form-item>
  184. </el-row>
  185. <el-row type="flex">
  186. <el-form-item
  187. class="item-cl"
  188. :label-width="labelWidth"
  189. label="税额"
  190. prop="taxAmt"
  191. >
  192. <el-input-number
  193. size="small"
  194. class="input-cl"
  195. v-model="mainItem.taxAmt"
  196. controls-position="right"
  197. :min="0"
  198. :precision="2"
  199. ></el-input-number>
  200. </el-form-item>
  201. </el-row>
  202. </el-form>
  203. </el-carousel-item>
  204. </el-carousel>
  205. <!-- 底部滚动模块 -->
  206. <div class="img-scoll middle-center" v-if="opeType != 'edit'">
  207. <div class="left-point middle-center">
  208. <i class="el-icon-arrow-left arr-cl" @click="moveLeft"></i>
  209. </div>
  210. <div class="middle-block">
  211. <div
  212. v-for="(mainItem, mainIndex) in model"
  213. :class="{
  214. 'img-block-one': true,
  215. 'middle-center': true,
  216. 'active-class': carouselIndex == mainIndex,
  217. }"
  218. :key="mainIndex"
  219. @click="clickImg(mainIndex)"
  220. >
  221. <div class="for-center">
  222. <div
  223. v-if="mainItem.contentType == 'application/pdf'"
  224. class="bottom-img-box middle-center"
  225. >
  226. <img style="width: 70%" src="../imgs/pdf4.jpg" />
  227. </div>
  228. <div v-else class="bottom-img-box middle-center">
  229. <img
  230. style="width: 100%"
  231. v-if="mainItem.invoiceImage"
  232. :src="$baseUrl + mainItem.invoiceImage"
  233. />
  234. <el-empty
  235. v-else
  236. :image-size="50"
  237. description="描述文字"
  238. ></el-empty>
  239. </div>
  240. </div>
  241. </div>
  242. <div class="img-block-one middle-center" @click="addNewInvoice">
  243. <div class="for-center middle-center">
  244. <i class="el-icon-plus add-invoice"></i>
  245. </div>
  246. </div>
  247. </div>
  248. <div class="right-point middle-center" @click="moveRight">
  249. <i class="el-icon-arrow-right arr-cl"> </i>
  250. </div>
  251. </div>
  252. </div>
  253. </template>
  254. <script>
  255. import { getInvoiceFormRules } from "../configFiles/invoiceFormRules.js";
  256. import selectRemote from "@/components/select/selectRemote.vue";
  257. import { changeTime, changeDate } from "@/utils/public.js";
  258. import {
  259. addInvoice,
  260. fileDetail,
  261. updateInvoice,
  262. getSelectRegistList,
  263. } from "@/api/personalApi.js";
  264. export default {
  265. components: { selectRemote },
  266. props: {
  267. oriForm: {
  268. type: Array,
  269. default: [],
  270. },
  271. opeType: {
  272. type: String,
  273. default: "",
  274. },
  275. },
  276. watch: {
  277. oriForm: {
  278. handler(val) {
  279. this.model = JSON.parse(JSON.stringify(val));
  280. console.log(this.model);
  281. },
  282. immediate: true,
  283. },
  284. },
  285. created() {
  286. console.log("传入的数据为:", this.model);
  287. this.formRule = getInvoiceFormRules(); //规则加载
  288. this.$nextTick(() => {
  289. this.oriData(); //针对1个需要懒加载的select框进行处理
  290. });
  291. if (this.opeType == "edit") {
  292. this.loadFileInfo(); //加载文件信息
  293. this.formatTime();
  294. }
  295. },
  296. data() {
  297. return {
  298. labelWidth: "100px",
  299. model: [],
  300. pageLoading: false,
  301. carouselIndex: 0, //幻灯片到哪一张了
  302. settlementNo: "", //一组发票信息只有一个对账单编号,记录编号
  303. };
  304. },
  305. methods: {
  306. oriData() {
  307. //查询对账单数据
  308. let _params = {
  309. settlementNo: "",
  310. pageNum: 1,
  311. pageSize: 20,
  312. };
  313. if (this.opeType == "edit") {
  314. _params.settlementNo = this.model[0].statementNo; //对账单编号始终保持一致,任意取一个
  315. this.settlementNo = this.model[0].statementNo;
  316. }
  317. getSelectRegistList(_params).then((res) => {
  318. this.model.forEach((item, mainIndex) => {
  319. let _aimRef = `statementSelectRemote${mainIndex}`;
  320. if (this.opeType == "edit") {
  321. //编辑的情况
  322. this.$refs[_aimRef][0].loadFirstData(res, _params.settlementNo);
  323. } else {
  324. this.$refs[_aimRef][0].loadFirstData(res);
  325. }
  326. });
  327. });
  328. },
  329. changeCarousel(active, ori) {
  330. this.carouselIndex = active;
  331. //重新赋值一次最新的对账单编号
  332. this.$nextTick(() => {
  333. let _aimRef = `statementSelectRemote${active}`;
  334. this.$refs[_aimRef][0].initData(this.settlementNo);
  335. console.log("this.settlementN", this.settlementNo);
  336. this.$set(this.model[active], "statementNo", this.settlementNo);
  337. this.$forceUpdate();
  338. });
  339. },
  340. formatTime() {
  341. this.model.forEach((item, index) => {
  342. this.$set(
  343. this.model[index],
  344. "billingShow",
  345. changeDate(item.billingDate) + " " + changeTime(item.billingTime)
  346. );
  347. });
  348. },
  349. loadFileInfo() {
  350. this.setFileInfo(this.model[0].invoiceImage);
  351. },
  352. clickImg(active) {
  353. this.$refs.elCarousel.setActiveItem(active);
  354. },
  355. moveLeft() {
  356. if (this.carouselIndex > 0) {
  357. this.clickImg(this.carouselIndex - 1);
  358. }
  359. },
  360. addNewInvoice() {
  361. let _judge = this.judgeForm();
  362. if (_judge._canAdd) {
  363. this.model.push({
  364. billingShow: "",
  365. });
  366. this.$nextTick(() => {
  367. this.$refs.elCarousel.setActiveItem(this.model.length - 1);
  368. });
  369. } else {
  370. this.$message({
  371. message: _judge._errorMsg,
  372. type: "warning",
  373. });
  374. }
  375. },
  376. openPdf(fileNo) {
  377. window.open(this.$baseUrl + fileNo, "_blank");
  378. },
  379. confirm() {
  380. let _judge = this.confirmJudgeForm();
  381. if (_judge._canAdd) {
  382. console.log("即将提交的数为:", this.model);
  383. //对时间做一下处理
  384. this.dealTime();
  385. if (this.opeType == "edit") {
  386. updateInvoice(this.model[0]).then((res) => {
  387. if (res.code == 200) {
  388. this.goSuccess("更新成功!");
  389. } else {
  390. this.goError("更新失败");
  391. }
  392. });
  393. } else {
  394. addInvoice(this.model).then((res) => {
  395. if (res.code == 200) {
  396. this.goSuccess("新增成功!");
  397. } else {
  398. this.goError("新增失败");
  399. }
  400. });
  401. }
  402. } else {
  403. this.$message({
  404. message: _judge._errorMsg,
  405. type: "warning",
  406. });
  407. }
  408. },
  409. dealTime() {
  410. this.model.forEach((item) => {
  411. item.billingDate = item.billingShow.split(" ")[0].replaceAll("-", "");
  412. item.billingTime = item.billingShow.split(" ")[1].replaceAll(":", "");
  413. // delete item.billingShow;
  414. });
  415. },
  416. goSuccess(msg) {
  417. this.$emit("btnConfirm");
  418. this.$message({
  419. message: msg,
  420. type: "success",
  421. });
  422. },
  423. goError(msg) {
  424. this.$message({
  425. message: msg,
  426. type: "error",
  427. });
  428. },
  429. confirmJudgeForm() {
  430. let fiJudge = this.judgeForm();
  431. if (!fiJudge._canAdd) {
  432. return fiJudge;
  433. }
  434. //继续对重复数据的校验
  435. let fKey,
  436. sKey,
  437. countArr = [],
  438. _canAdd = true,
  439. _errorMsg = "";
  440. this.model.forEach((item, index) => {
  441. countArr[index] = 0;
  442. });
  443. this.model.forEach((fItem, fIndex) => {
  444. fKey = fItem.invoiceNo + "-" + fItem.invoiceCode;
  445. this.model.forEach((sItem, sIndex) => {
  446. sKey = sItem.invoiceNo + "-" + sItem.invoiceCode;
  447. if (fKey == sKey) {
  448. countArr[fIndex]++;
  449. }
  450. });
  451. });
  452. let _model = this.model,
  453. reArr = [],
  454. _msg = "";
  455. countArr.forEach((item, index) => {
  456. if (item > 1) {
  457. _canAdd = false;
  458. _msg =
  459. "发票号码:" +
  460. _model[index].invoiceNo +
  461. "," +
  462. "发票代码:" +
  463. _model[index].invoiceCode +
  464. "数据存在重复;" +
  465. " ";
  466. reArr.push(_msg);
  467. }
  468. });
  469. reArr = new Set(reArr);
  470. reArr = Array.from(reArr);
  471. _errorMsg = reArr.join("");
  472. return {
  473. _canAdd,
  474. _errorMsg,
  475. };
  476. },
  477. judgeForm() {
  478. let _canAdd = true,
  479. _errorMsg = "存在未填写数据";
  480. this.model.forEach((item, index) => {
  481. let _aim = `dataForm${index}`;
  482. this.$refs[_aim][0].validate((valid) => {
  483. if (!valid) {
  484. _canAdd = false;
  485. return false;
  486. }
  487. });
  488. //同时检查一下照片的invoiceImage是否存在
  489. if (!item.invoiceImage) {
  490. _canAdd = false;
  491. _errorMsg = "存在发票信息未上传";
  492. }
  493. });
  494. return {
  495. _canAdd,
  496. _errorMsg,
  497. };
  498. },
  499. moveRight() {
  500. if (this.carouselIndex < this.model.length - 1) {
  501. this.clickImg(this.carouselIndex + 1);
  502. }
  503. },
  504. beforeUpload(file) {
  505. console.log("file文件为:", file);
  506. if (
  507. file.type == "image/jpeg" ||
  508. file.type == "image/png" ||
  509. file.type == "application/pdf"
  510. ) {
  511. this.pageLoading = true;
  512. return true;
  513. } else {
  514. this.$message({
  515. message: "仅支持jpg,png,pdf格式文件",
  516. type: "error",
  517. });
  518. return false;
  519. }
  520. },
  521. changeStatement(row, mainIndex) {
  522. this.settlementNo = row.value;
  523. this.model.forEach((item, index) => {
  524. this.$set(this.model[index], "statementNo", row.value);
  525. });
  526. },
  527. deleteImg(mainIndex) {
  528. if (this.model.length == 1) {
  529. this.$message.warning("至少保留一张发票");
  530. return;
  531. }
  532. this.$confirm(`确认删除当前发票?`, "提示", {
  533. confirmButtonText: "确定",
  534. cancelButtonText: "取消",
  535. type: "warning",
  536. }).then(() => {
  537. this.model.splice(mainIndex, 1);
  538. this.$nextTick(() => {
  539. this.$refs.elCarousel.setActiveItem(mainIndex - 1);
  540. });
  541. this.$forceUpdate();
  542. });
  543. },
  544. onExceed() {
  545. this.$message.error("请先删除当前文件再进行上传");
  546. },
  547. onError() {
  548. this.pageLoading = false;
  549. },
  550. onSuccess(row, info, c, mainIndex) {
  551. console.log("发票返回信息为:", info);
  552. let _result = info.response;
  553. this.pageLoading = false;
  554. if (_result.code != 200) {
  555. this.$message({
  556. message: _result.msg,
  557. type: "error",
  558. });
  559. let _aimRef = `elUpload${mainIndex}`;
  560. this.$refs[_aimRef][0].clearFiles();
  561. return;
  562. }
  563. _result.data.forEach((item, reIndex) => {
  564. this.changeOriForm(this.model.length - 1, item, reIndex);
  565. });
  566. this.$forceUpdate();
  567. //再新增一个操作,将光标移动到最后一个位置
  568. this.$nextTick(() => {
  569. this.$refs.elCarousel.setActiveItem(this.model.length - 1);
  570. });
  571. this.$message.success("发票识别成功");
  572. },
  573. changeOriForm(_index, item, reIndex) {
  574. let _taxAmt = item.totalTax ? item.totalTax : "";
  575. let _billingShow = item.billingDate
  576. ? this.changeTimeFormat(item.billingDate, item)
  577. : "";
  578. let _invoiceAmt = item.amountTax ? item.amountTax : "";
  579. let _invoiceImage = item.fileNo ? item.fileNo : "";
  580. let _invoiceCode = item.invoiceCode ? item.invoiceCode : "";
  581. let _invoiceNo = item.invoiceNumber ? item.invoiceNumber : "";
  582. let _totalAmt = item.totalAmount ? item.totalAmount : "";
  583. let _billingTime = ""; //开票时间是没有的
  584. if (reIndex == 0) {
  585. //第一张发票覆盖,后面的push
  586. this.$set(this.model[_index], "taxAmt", _taxAmt); //税额
  587. this.$set(this.model[_index], "billingShow", _billingShow); //开票日期
  588. this.$set(this.model[_index], "invoiceAmt", _invoiceAmt); //票面金额
  589. this.$set(this.model[_index], "invoiceImage", _invoiceImage); //回显文件编号
  590. this.$set(this.model[_index], "invoiceCode", _invoiceCode); //发票代码
  591. this.$set(this.model[_index], "invoiceNo", _invoiceNo); //发票号码
  592. this.$set(this.model[_index], "totalAmt", _totalAmt); //合计金额
  593. console.log(this.model);
  594. } else {
  595. let _obj = {
  596. taxAmt: _taxAmt,
  597. billingShow: _billingShow,
  598. invoiceAmt: _invoiceAmt,
  599. invoiceImage: _invoiceImage,
  600. invoiceCode: _invoiceCode,
  601. invoiceNo: _invoiceNo,
  602. totalAmt: _totalAmt,
  603. };
  604. this.model.push(_obj);
  605. }
  606. this.setFileInfo(_invoiceImage); //同时将文件的类型合名称设置进去
  607. },
  608. setFileInfo(_invoiceNo) {
  609. let _index = this.model.length - 1;
  610. fileDetail({ fileNo: _invoiceNo }).then((res) => {
  611. this.$set(this.model[_index], "fileName", res.data.fileName);
  612. this.$set(this.model[_index], "contentType", res.data.contentType);
  613. });
  614. },
  615. changeTimeFormat(time, mainItem) {
  616. if (mainItem.billingTime) {
  617. return time + " " + item.billingTime;
  618. } else {
  619. return time + " " + "00:00:00";
  620. }
  621. },
  622. },
  623. };
  624. </script>
  625. <style lang="scss" scoped>
  626. ::-webkit-scrollbar {
  627. width: 8px;
  628. height: 8px;
  629. }
  630. /* 滚动槽 */
  631. ::-webkit-scrollbar-track {
  632. -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3);
  633. border-radius: 10px;
  634. }
  635. /* 滚动条滑块 */
  636. ::-webkit-scrollbar-thumb {
  637. border-radius: 10px;
  638. background: rgba(0, 0, 0, 0.1);
  639. -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5);
  640. }
  641. .invoice-form {
  642. .full-box {
  643. width: 100%;
  644. height: 100%;
  645. }
  646. .invoice-img {
  647. width: 100%;
  648. .top-img-box {
  649. width: 100%;
  650. height: 100%;
  651. .block-one {
  652. width: 100%;
  653. margin-top: 20px;
  654. .pdf-img-cl {
  655. width: 160px;
  656. height: 160px;
  657. }
  658. }
  659. .pdf-name-cl {
  660. width: 100%;
  661. }
  662. }
  663. .upload-img-box {
  664. width: 100%;
  665. height: 100%;
  666. overflow: auto;
  667. .top-img-cl {
  668. width: 100%;
  669. }
  670. }
  671. .upload-delete-cl {
  672. position: absolute;
  673. right: 12%;
  674. cursor: pointer;
  675. top: 0px;
  676. font-size: 18px;
  677. }
  678. .el-upload-block {
  679. margin-bottom: 15px;
  680. width: 70%;
  681. height: 230px;
  682. /deep/.el-upload {
  683. width: 100%;
  684. .el-upload-dragger {
  685. width: 100%;
  686. display: flex;
  687. align-items: center;
  688. justify-content: center;
  689. height: 220px;
  690. }
  691. .el-upload-dragger .el-icon-upload {
  692. margin: auto;
  693. line-height: 80px;
  694. }
  695. }
  696. }
  697. }
  698. .img-scoll {
  699. width: 100%;
  700. height: 98px;
  701. display: flex;
  702. margin-top: 20px;
  703. .left-point {
  704. width: 25px;
  705. height: 100%;
  706. cursor: pointer;
  707. &:hover {
  708. background: #efefef;
  709. }
  710. }
  711. .middle-block {
  712. width: calc(100% - 72px);
  713. padding: 0px 6px;
  714. white-space: nowrap;
  715. overflow: auto;
  716. display: flex;
  717. /deep/.el-empty {
  718. padding: 0px;
  719. .el-empty__description {
  720. display: none;
  721. }
  722. }
  723. .img-block-one {
  724. width: 80px;
  725. display: inline-block;
  726. height: 80px;
  727. border: 1px solid lightgray;
  728. margin-right: 10px;
  729. cursor: pointer;
  730. .add-invoice {
  731. font-size: 25px;
  732. }
  733. .for-center {
  734. width: 100%;
  735. height: 100%;
  736. .bottom-img-box {
  737. width: 100%;
  738. height: 100%;
  739. }
  740. }
  741. }
  742. .active-class {
  743. border: 2px solid #3388fb;
  744. width: 79px;
  745. height: 79px;
  746. }
  747. }
  748. .right-point {
  749. width: 25px;
  750. height: 100%;
  751. cursor: pointer;
  752. &:hover {
  753. background: #efefef;
  754. }
  755. }
  756. .arr-cl {
  757. font-size: 30px;
  758. font-weight: bold;
  759. color: lightgray;
  760. cursor: pointer;
  761. }
  762. }
  763. .item-cl {
  764. width: 50%;
  765. .input-cl {
  766. width: 90%;
  767. /deep/.el-input {
  768. width: 100%;
  769. }
  770. }
  771. }
  772. }
  773. </style>

 select-remote组件是我封装的远程搜索下拉组件,见前面的文章

invoiceFormRules.js文件是规则文件,类似如下:

  1. export function getInvoiceFormRules() {
  2. return {
  3. statementNo: [{
  4. required: true,
  5. message: "请选择对账单编号",
  6. trigger: "change",
  7. }],
  8. }
  9. }

changTime,changeDate方法比较简单

  1. export function changeDate(str) { //将yyyyMMdd转换为yyyy-MM-dd
  2. if (!str) return '';
  3. str = str.substr(0, 4) +
  4. "-" +
  5. str.substr(4, 2) +
  6. "-" +
  7. str.substr(6, 2);
  8. return str;
  9. }
  10. export function changeTime(str) { //将hhmmss转换为hh:mm:ss
  11. if (!str) return '';
  12. str = str.substr(0, 2) +
  13. ":" +
  14. str.substr(2, 2) +
  15. ":" +
  16. str.substr(4, 2);
  17. return str;
  18. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/297864
推荐阅读
相关标签
  

闽ICP备14008679号