index.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. <template>
  2. <view class="invoice">
  3. <nav-bar title="发票申请"></nav-bar>
  4. <view class="invoice__tabs">
  5. <u-tabs :list="list" sticky :current="current" @change="change" active-color="#007AFF"></u-tabs>
  6. </view>
  7. <view class="invoice__content">
  8. <view class="open" v-if="current == 0">
  9. <view class="form">
  10. <u-form :model="form" ref="uForm">
  11. <u-form-item label="发票类型" label-width="150" required prop="type" >
  12. <u-radio-group v-model="form.type" @change="formTypeChange">
  13. <u-radio v-for="(item, index) in typeList" :key="index" :name="item.value">
  14. {{ item.name }}
  15. </u-radio>
  16. </u-radio-group>
  17. </u-form-item>
  18. <!-- 增值税发票 -->
  19. <template v-if="form.type == 2">
  20. <u-form-item label="申请主体" label-width="150" required prop="subject">
  21. <u-radio-group v-model="form.subject">
  22. <u-radio :key="index" name="2">
  23. 企业
  24. </u-radio>
  25. </u-radio-group>
  26. </u-form-item>
  27. <u-form-item label="发票抬头" label-width="150" required prop="invoiceTitle" >
  28. <u-input placeholder="请输入发票抬头" v-model="form.invoiceTitle" />
  29. </u-form-item>
  30. <u-form-item label="纳税登记号" label-width="150" required prop="taxRegistryNumber" >
  31. <u-input placeholder="请输入纳税登记号" v-model="form.taxRegistryNumber" />
  32. </u-form-item>
  33. <u-form-item label="单位地址" label-width="150" required prop="companyAddress" >
  34. <u-input placeholder="请输入单位地址" v-model="form.companyAddress" />
  35. </u-form-item>
  36. <u-form-item label="电话号码" label-width="150" required prop="phone" >
  37. <u-input placeholder="请输入电话号码" type="number" v-model="form.phone" />
  38. </u-form-item>
  39. <u-form-item label="开户银行" label-width="150" required prop="bankName" >
  40. <u-input placeholder="请输入开户银行" v-model="form.bankName" />
  41. </u-form-item>
  42. <u-form-item label="银行账号" label-width="150" required prop="bankAccount" >
  43. <u-input placeholder="请输入银行账号" type="number" v-model="form.bankAccount" />
  44. </u-form-item>
  45. <u-form-item label="收件地址" label-width="150" required prop="receivingAddress" >
  46. <u-input placeholder="请输入收件地址" v-model="form.receivingAddress" />
  47. </u-form-item>
  48. <u-form-item label="收件人" label-width="150" required prop="receivingName" >
  49. <u-input placeholder="请输入收件人" v-model="form.receivingName" />
  50. </u-form-item>
  51. <u-form-item label="收件手机" label-width="150" required prop="receivingTel" >
  52. <u-input placeholder="请输入收件手机" v-model="form.receivingTel" />
  53. </u-form-item>
  54. </template>
  55. <!-- 增值税发票 -->
  56. <!-- 普通发票 -->
  57. <template v-else>
  58. <u-form-item label="申请主体" label-width="150" required prop="subject">
  59. <u-radio-group v-model="form.subject">
  60. <u-radio v-for="(item, index) in mainList" :key="index" :name="item.value">
  61. {{ item.name }}
  62. </u-radio>
  63. </u-radio-group>
  64. </u-form-item>
  65. <u-form-item label="发票抬头" label-width="150" required prop="invoiceTitle" >
  66. <u-input placeholder="请输入发票抬头" v-model="form.invoiceTitle" />
  67. </u-form-item>
  68. <u-form-item v-if="form.subject == '2'" label="纳税登记号" label-width="150" required prop="taxRegistryNumber" >
  69. <u-input placeholder="请输入纳税登记号" v-model="form.taxRegistryNumber" />
  70. </u-form-item>
  71. </template>
  72. <!-- 普通发票 -->
  73. <u-form-item label="选择订单" label-width="150" required prop="orderGoodsIds" right-icon="arrow-right" ref="orderGoodsIds">
  74. <view class="form-item" @click="selectOrderModal = true">
  75. <u-input placeholder="请点击选择订单" disabled @click="selectOrderModal = true" />
  76. </view>
  77. </u-form-item>
  78. <view>
  79. <view class="check-order" v-for="(item,index) in orderList" :key="index" v-if="item.disabled">
  80. <view class="close" @click="deleteOrder(index)">
  81. <u-icon name="close-circle-fill" color="#FF2D55" size="40"></u-icon>
  82. </view>
  83. <view class="title">商品名称:{{item.goodsName}}</view>
  84. <view class="number">订单编号:{{item.orderSn}}</view>
  85. <view class="price">价格:¥ {{item.goodsPrice}}</view>
  86. </view>
  87. </view>
  88. </u-form>
  89. </view>
  90. <view class="order-text">
  91. <view class="order-text__label">本次申请开票金额:</view>
  92. <view class="order-text__price">¥ {{toFixed(invoicePirce)}}</view>
  93. </view>
  94. <view class="submit" @click="formSubmit">
  95. 提交申请
  96. </view>
  97. </view>
  98. <view class="record" v-if="current == 1">
  99. <view class="nodata" v-if="!recordList.length">
  100. 您暂无相关发票记录哦~
  101. </view>
  102. <view class="record__list">
  103. <view class="record-item" @click="showDetailModal(record);" v-for="(record,index) in recordList" :key="index">
  104. <view class="item__time">{{$method.timestampToTime(record.applyTime,false,false)}}</view>
  105. <view class="item__content">
  106. <view class="top">
  107. <view class="state" :class="{wait:record.periodStatus == 1,refuse:record.periodStatus == 2,agree:record.periodStatus == 3}">
  108. <text v-if="record.periodStatus == 1">待审核</text>
  109. <text v-if="record.periodStatus == 2">驳回</text>
  110. <text v-if="record.periodStatus == 3">通过</text>
  111. <u-icon class="arrow" name="arrow-right" color="#ffffff" size="28"></u-icon>
  112. </view>
  113. </view>
  114. <view class="bottom">
  115. <view class="flex">
  116. <view class="text">发票类型</view>
  117. <view class="flex__auto">
  118. <text v-if="record.type == 1">普通发票</text>
  119. <text v-if="record.type == 2">增值税专用发票</text>
  120. </view>
  121. </view>
  122. <view class="flex">
  123. <view class="text">申请主体</view>
  124. <view class="flex__auto">
  125. <text v-if="record.subject == 1">个人</text>
  126. <text v-if="record.subject == 2">企业</text>
  127. </view>
  128. </view>
  129. <view class="flex">
  130. <view class="text">发票状态</view>
  131. <view class="flex__auto">
  132. <text class="red" v-if="record.invoiceStatus == 1">未开票</text>
  133. <text class="green" v-if="record.invoiceStatus == 2">已开票</text>
  134. <text class="red" v-if="record.invoiceStatus == -1">已退票</text>
  135. </view>
  136. </view>
  137. <view @click.stop="showOrder(record.checked,index)">
  138. <view class="flex noborder" >
  139. <view class="text">开票订单</view>
  140. <view class="flex__auto">
  141. <text style="margin-right:10rpx;">{{record.orderList.length}}</text>
  142. <u-icon v-if="!record.checked" name="arrow-down" color="#ccc" size="28"></u-icon>
  143. <u-icon v-if="record.checked" name="arrow-up" color="#ccc" size="28"></u-icon>
  144. </view>
  145. </view>
  146. <view class="order-list" v-if="record.checked">
  147. <view class="order-item" :key="orderIndex" v-for="(orderItem,orderIndex) in record.orderList">{{orderIndex+1}}.{{orderItem.goodsName}}</view>
  148. </view>
  149. </view>
  150. </view>
  151. </view>
  152. </view>
  153. </view>
  154. </view>
  155. </view>
  156. <u-popup class="modal" v-model="selectOrderModal" mode="bottom" border-radius="24">
  157. <view class="select-order">
  158. <view class="line"></view>
  159. <view class="title">选择订单</view>
  160. <u-line color="#D6D6DB" />
  161. <view>
  162. <scroll-view scroll-y="true" style="height: 500rpx;">
  163. <view>
  164. <u-checkbox-group>
  165. <view v-for="(item, index) in orderList" :key="index" >
  166. <view class="order-item">
  167. <view>
  168. <u-checkbox
  169. :disabled="item.disabled"
  170. shape="circle"
  171. :name="item.name"
  172. v-model="item.checked"
  173. >
  174. <view class="order-item__bg" :class="item.checked?'active':''" >
  175. <view>
  176. <view class="order-title">{{item.goodsName}}</view>
  177. <view class="order-number">{{item.orderSn}}</view>
  178. <view class="order-price">¥ {{item.goodsPrice}}元</view>
  179. </view>
  180. </view>
  181. </u-checkbox >
  182. </view>
  183. </view>
  184. </view>
  185. </u-checkbox-group>
  186. </view>
  187. </scroll-view>
  188. </view>
  189. <view class="confrim-btn">
  190. <view class="okBtn" @click="okPopup()">确定</view>
  191. </view>
  192. </view>
  193. </u-popup>
  194. <u-popup class="modal" v-model="orderDetailModal" mode="center" border-radius="40">
  195. <view class="order-detail">
  196. <view class="order-detail__content">
  197. <scroll-view scroll-y="true" style="height: 860rpx;">
  198. <view class="content">
  199. <view class="header">{{$method.timestampToTime(invoiceDetail.applyTime,false,false)}}</view>
  200. <view class="body">
  201. <view class="body__item">
  202. <view class="title">发票申请信息</view>
  203. <view class="content">
  204. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  205. <view slot="title">发票类型:</view>
  206. <text v-if="invoiceDetail.type == 1">普通发票</text>
  207. <text v-if="invoiceDetail.type == 2">增值税专用发票</text>
  208. </u-cell-item>
  209. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  210. <view slot="title">申请主体:</view>
  211. <text v-if="invoiceDetail.subject == 1">个人</text>
  212. <text v-if="invoiceDetail.subject == 2">企业</text>
  213. </u-cell-item>
  214. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  215. <view slot="title">发票抬头:</view>
  216. <text>{{invoiceDetail.invoiceTitle}}</text>
  217. </u-cell-item>
  218. <template v-if="invoiceDetail.subject == 2">
  219. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  220. <view slot="title">纳税登记号:</view>
  221. <text>{{invoiceDetail.taxRegistryNumber || ''}}</text>
  222. </u-cell-item>
  223. </template>
  224. <template v-if="invoiceDetail.type == 2">
  225. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  226. <view slot="title">单位地址:</view>
  227. <text>{{invoiceDetail.companyAddress || ''}}</text>
  228. </u-cell-item>
  229. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  230. <view slot="title">电话号码:</view>
  231. <text>{{invoiceDetail.phone || ''}}</text>
  232. </u-cell-item>
  233. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  234. <view slot="title">开户银行:</view>
  235. <text>{{invoiceDetail.bankName || ''}}</text>
  236. </u-cell-item>
  237. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  238. <view slot="title">银行账号:</view>
  239. <text>{{invoiceDetail.bankAccount || ''}}</text>
  240. </u-cell-item>
  241. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  242. <view slot="title">收件地址:</view>
  243. <text>{{invoiceDetail.receivingAddress || ''}}</text>
  244. </u-cell-item>
  245. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  246. <view slot="title">收件人:</view>
  247. <text>{{invoiceDetail.receivingName || ''}}</text>
  248. </u-cell-item>
  249. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false" >
  250. <view slot="title">收件手机:</view>
  251. <text>{{invoiceDetail.receivingTel || ''}}</text>
  252. </u-cell-item>
  253. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false" >
  254. <view slot="title">开票订单:</view>
  255. </u-cell-item>
  256. </template>
  257. <view class="order-list">
  258. <view class="order-item" :key="orderIndex" v-for="(orderItem,orderIndex) in invoiceDetail.orderList">
  259. <view class="order-title">{{orderItem.goodsName}}</view>
  260. <view class="order-number">{{orderItem.orderSn}}</view>
  261. <view class="order-price">¥ {{orderItem.goodsRealPrice}}元</view>
  262. </view>
  263. </view>
  264. <view class="order-text">
  265. <view class="order-text__label">本次申请开票金额:</view>
  266. <view class="order-text__price">¥ {{toFixed(invoiceDetail.amount)}}</view>
  267. </view>
  268. </view>
  269. </view>
  270. <view class="body__item">
  271. <view class="title">发票申请结果</view>
  272. <view class="content">
  273. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  274. <view slot="title">审核结果:</view>
  275. <text class="text wait" v-if="invoiceDetail.periodStatus == 1">待审核</text>
  276. <text class="text agree" v-if="invoiceDetail.periodStatus == 3">通过</text>
  277. <text class="text refuse" v-if="invoiceDetail.periodStatus == 2">驳回</text>
  278. </u-cell-item>
  279. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false" v-if="invoiceDetail.periodReason">
  280. <view slot="title">审核反馈:</view>
  281. <text class="text">{{invoiceDetail.periodReason||''}}</text>
  282. </u-cell-item>
  283. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false">
  284. <view slot="title">发票状态:</view>
  285. <text class="text refuse" v-if="invoiceDetail.invoiceStatus == 1">未开票</text>
  286. <text class="text agree" v-if="invoiceDetail.invoiceStatus == 2">已开票</text>
  287. <text class="text refuse" v-if="invoiceDetail.invoiceStatus == -1">已退票</text>
  288. </u-cell-item>
  289. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false" v-if="invoiceDetail.periodStatus == 3 && (invoiceDetail.invoiceStatus == 2 || invoiceDetail.invoiceStatus == -1) && invoiceDetail.invoiceImg">
  290. <view slot="title">发票预览:</view>
  291. <view>
  292. <image class="preview" @click="previewImg(invoiceDetail)" :src="$method.splitImgHost(invoiceDetail.invoiceImg)"></image>
  293. <view class="download-btn" @click="download(invoiceDetail)">下载电子发票</view>
  294. </view>
  295. </u-cell-item>
  296. <u-cell-item :border-bottom="false" hover-class="none" :arrow="false" v-if="invoiceDetail.periodStatus == 3 && (invoiceDetail.invoiceStatus == 2 || invoiceDetail.invoiceStatus == -1) && invoiceDetail.type == 2 && invoiceDetail.subject == 2">
  297. <view slot="title">机构发票邮寄状态:</view>
  298. <text class="text" v-if="invoiceDetail.sendInvoice == 1">是</text>
  299. <text class="text" v-else>否</text>
  300. </u-cell-item>
  301. <u-cell-item v-if="invoiceDetail.periodStatus == 3 && (invoiceDetail.invoiceStatus == 2 || invoiceDetail.invoiceStatus == -1) && invoiceDetail.sendInvoice == 1 && invoiceDetail.type == 2 && invoiceDetail.subject == 2" @click.stop="copy(invoiceDetail.trackingNum)" :border-bottom="false" hover-class="none" :arrow="false">
  302. <view slot="title">发票邮寄快递单号:(点击可复制)</view>
  303. <text class="text">{{invoiceDetail.trackingNum || ''}}</text>
  304. </u-cell-item>
  305. </view>
  306. </view>
  307. </view>
  308. </view>
  309. </scroll-view>
  310. </view>
  311. <view class="order-detail__btns" v-if="invoiceDetail.periodStatus == 1">
  312. <view class="btn" @click="orderDetailModal = false;">知道了</view>
  313. <view class="btn warm" @click="orderCancelModal = true;">撤销申请</view>
  314. </view>
  315. <view class="order-detail__btns" v-else>
  316. <view class="btn ok" @click="orderDetailModal = false;">知道了</view>
  317. </view>
  318. </view>
  319. </u-popup>
  320. <u-popup class="modal" v-model="orderCancelModal" mode="center" border-radius="24">
  321. <view class="order-cancel">
  322. <view class="header">
  323. 温馨提示
  324. </view>
  325. <view class="body">
  326. <view>撤销申请后,</view>
  327. <view>本次的发票申请内容将不存在。</view>
  328. <view>请慎重考虑。 </view>
  329. <view>您确定要取消本次发票申请吗?</view>
  330. </view>
  331. <view class="footer">
  332. <view class="btn cancel" @click="orderCancelModal = false;">取消</view>
  333. <view class="btn ok" @click="orderCancel()">确定</view>
  334. </view>
  335. </view>
  336. </u-popup>
  337. </view>
  338. </template>
  339. <script>
  340. import { mapGetters } from 'vuex';
  341. export default {
  342. components: {},
  343. data() {
  344. return {
  345. checkOrderList:[],
  346. recordList:[],
  347. list: [
  348. {
  349. name: '发票申请'
  350. },
  351. {
  352. name: '发票记录'
  353. }
  354. ],
  355. invoiceDetail:{
  356. amount:0
  357. },
  358. form:{
  359. type:'1',
  360. subject:'1',
  361. invoiceTitle:'',
  362. orderGoodsIds:'',
  363. taxRegistryNumber:'',
  364. companyAddress:'',
  365. phone:'',
  366. bankName:'',
  367. bankAccount:'',
  368. receivingAddress:'',
  369. receivingName:'',
  370. receivingTel:'',
  371. },
  372. rules: {
  373. receivingTel: [
  374. {
  375. required: true,
  376. message: '请输入收件手机',
  377. // 可以单个或者同时写两个触发验证方式
  378. trigger: ['change'],
  379. },
  380. {
  381. validator: (rule, value, callback) => {
  382. // 上面有说,返回true表示校验通过,返回false表示不通过
  383. // this.$u.test.mobile()就是返回true或者false的
  384. console.log(this.$u.test.mobile(value),'this.$u.test.mobile(value)')
  385. return this.$u.test.mobile(value);
  386. },
  387. message: '手机号码格式不正确',
  388. // 触发器可以同时用blur和change
  389. trigger: ['change'],
  390. }
  391. ],
  392. type: [
  393. {
  394. required: true,
  395. message: '请选择发票类型',
  396. // 可以单个或者同时写两个触发验证方式
  397. trigger: ['change'],
  398. }
  399. ],
  400. subject: [
  401. {
  402. required: true,
  403. message: '请选择申请主体',
  404. // 可以单个或者同时写两个触发验证方式
  405. trigger: ['change'],
  406. }
  407. ],
  408. invoiceTitle: [
  409. {
  410. required: true,
  411. message: '请输入发票抬头',
  412. // 可以单个或者同时写两个触发验证方式
  413. trigger: ['change'],
  414. },
  415. ],
  416. taxRegistryNumber: [
  417. {
  418. required: true,
  419. message: '请输入纳税登记号',
  420. // 可以单个或者同时写两个触发验证方式
  421. trigger: ['change'],
  422. },
  423. {
  424. validator: (rule, value, callback) => {
  425. // 上面有说,返回true表示校验通过,返回false表示不通过
  426. var reg = /(^[0-9A-Z]{15,20}$)/;
  427. console.log( reg.test(value),' reg.test(value)')
  428. return reg.test(value);
  429. },
  430. message: '纳税登记号格式不正确',
  431. // 触发器可以同时用blur和change
  432. trigger: ['change'],
  433. }
  434. ],
  435. companyAddress: [
  436. {
  437. required: true,
  438. message: '请输入单位地址',
  439. // 可以单个或者同时写两个触发验证方式
  440. trigger: ['change'],
  441. }
  442. ],
  443. phone: [
  444. {
  445. required: true,
  446. message: '请输入电话号码',
  447. // 可以单个或者同时写两个触发验证方式
  448. trigger: ['change'],
  449. },
  450. {
  451. validator: (rule, value, callback) => {
  452. var vartest = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
  453. var vartest1 = /^([0-9]{3,4})?[0-9]{7,8}$/;
  454. if (this.$u.test.mobile(value) || vartest.test(value) || vartest1.test(value)) {
  455. return true;
  456. } else {
  457. return false;
  458. }
  459. },
  460. message: '电话号码不正确',
  461. trigger: ['change', 'blur']
  462. }
  463. ],
  464. bankName: [
  465. {
  466. required: true,
  467. message: '请输入开户银行',
  468. // 可以单个或者同时写两个触发验证方式
  469. trigger: ['change'],
  470. },
  471. {
  472. validator: (rule, value, callback) => {
  473. var reg = /[\u4E00-\u9FA5]+/;
  474. return reg.test(value)
  475. },
  476. message: '开户银行名称不正确',
  477. trigger: ['change', 'blur']
  478. }
  479. ],
  480. bankAccount: [
  481. {
  482. required: true,
  483. message: '请输入银行账号',
  484. // 可以单个或者同时写两个触发验证方式
  485. trigger: ['change'],
  486. },
  487. {
  488. validator: (rule, value, callback) => {
  489. // 上面有说,返回true表示校验通过,返回false表示不通过
  490. var reg = /^[1-9]{1}(\d{15}|\d{18})$/;
  491. console.log( reg.test(value),' reg.test(value)')
  492. return reg.test(value);
  493. },
  494. message: '银行卡号格式不正确',
  495. // 触发器可以同时用blur和change
  496. trigger: ['change'],
  497. }
  498. ],
  499. receivingAddress: [
  500. {
  501. required: true,
  502. message: '请输入收件地址',
  503. // 可以单个或者同时写两个触发验证方式
  504. trigger: ['change'],
  505. }
  506. ],
  507. receivingName: [
  508. {
  509. required: true,
  510. message: '请输入收件人',
  511. // 可以单个或者同时写两个触发验证方式
  512. trigger: ['change'],
  513. }
  514. ],
  515. orderGoodsIds: [
  516. {
  517. required: true,
  518. message: '请选择订单',
  519. // 可以单个或者同时写两个触发验证方式
  520. trigger: ['change'],
  521. }
  522. ],
  523. },
  524. orderValue:'',
  525. orderList:[],
  526. selectOrderModal:false,
  527. orderDetailModal:false,
  528. orderCancelModal:false,
  529. current: 0,
  530. invoicePirce:0,
  531. order: [],
  532. typeList:[{
  533. name:'普通发票',
  534. value:'1'
  535. },{
  536. name:'增值税专用发票',
  537. value:'2'
  538. }],
  539. mainList:[{
  540. name:'个人',
  541. value:'1'
  542. },{
  543. name:'企业',
  544. value:'2'
  545. }]
  546. };
  547. },
  548. // onPullDownRefresh() {},
  549. onLoad(option) {
  550. this.orderInvoiceCanInvoiceList();
  551. this.$refs.uForm.setRules(this.rules)
  552. },
  553. onShow() {
  554. },
  555. methods: {
  556. orderCancel() {
  557. let invoiceDetail = JSON.parse(JSON.stringify(this.invoiceDetail))
  558. invoiceDetail.status = -1;
  559. this.$api.orderInvoiceCancel(invoiceDetail).then(res => {
  560. if(res.data.code == 200) {
  561. this.orderInvoiceList();
  562. this.orderInvoiceCanInvoiceList();
  563. this.orderDetailModal = false;
  564. this.orderCancelModal = false;
  565. uni.showToast({
  566. title:'撤销成功',
  567. icon:'none'
  568. })
  569. } else {
  570. }
  571. })
  572. },
  573. showDetailModal(item) {
  574. this.orderDetailModal = true;
  575. this.invoiceDetail = item;
  576. },
  577. toFixed(number) {
  578. console.log(number.toFixed(2))
  579. return number.toFixed(2)
  580. },
  581. /**
  582. * 获取可开发票的订单
  583. */
  584. orderInvoiceCanInvoiceList() {
  585. this.$api.orderInvoiceCanInvoiceList().then(res => {
  586. if(res.data.code == 200) {
  587. res.data.rows.forEach(item => {
  588. item.checked = false;
  589. })
  590. this.orderList = res.data.rows;
  591. }
  592. })
  593. },
  594. /**
  595. * @param {Object} checkedState 显示状态
  596. * @param {Object} index 索引值
  597. * 修改开票订单列表显示状态
  598. */
  599. showOrder(showState,index) {
  600. this.$set(this.recordList[index],'checked',!showState)
  601. },
  602. /**
  603. * 发票申请提交
  604. */
  605. formSubmit() {
  606. this.$refs.uForm.validate(valid => {
  607. console.log(valid,'valid')
  608. console.log(this.form,'this.form')
  609. if(valid) {
  610. if(this.invoicePirce > 10000) {
  611. uni.showModal({
  612. title:'提示',
  613. content:'您所选的订单总开票金额,大于10000元,超出单张发票的开票额度,请修改开票订单',
  614. showCancel:false,
  615. })
  616. return
  617. }
  618. let data = JSON.parse(JSON.stringify(this.form));
  619. data.orderGoodsIds = data.orderGoodsIds.split(',')
  620. data.amount = this.invoicePirce;
  621. if(data.subject == '1') {
  622. data.taxRegistryNumber = '';
  623. data.companyAddress = '';
  624. data.phone = '';
  625. data.bankName = '';
  626. data.bankAccount = '';
  627. data.receivingAddress = '';
  628. data.receivingName = '';
  629. data.receivingTel = '';
  630. }
  631. this.$api.orderInvoice(data).then(res => {
  632. if(res.data.code == 200) {
  633. this.orderInvoiceCanInvoiceList();
  634. this.form = {
  635. type:'1',
  636. subject:'1',
  637. invoiceTitle:'',
  638. orderGoodsIds:'',
  639. taxRegistryNumber:'',
  640. companyAddress:'',
  641. phone:'',
  642. bankName:'',
  643. bankAccount:'',
  644. receivingAddress:'',
  645. receivingName:'',
  646. receivingTel:'',
  647. };
  648. this.invoicePirce = 0;
  649. uni.showModal({
  650. title:'操作提示',
  651. content:`您本次的发票申请已经提交成功!\n机构将在3-7个工作日内进行处理,处理结果会在【发票记录】显示,请留意进度。`,
  652. showCancel:false,
  653. confirmText:'知道了'
  654. })
  655. } else {
  656. uni.showToast({
  657. icon:'none',
  658. title:res.data.msg
  659. })
  660. }
  661. })
  662. }
  663. })
  664. },
  665. /**
  666. * @param {Object} e value
  667. * 发票类型修改
  668. */
  669. formTypeChange(e) {
  670. console.log(e)
  671. if(e == '2') {
  672. this.$set(this.form,'subject','2')
  673. } else {
  674. }
  675. },
  676. /**
  677. * @param {Object} e
  678. * tabs 切换
  679. */
  680. change(e) {
  681. console.log(e)
  682. this.current = e;
  683. if(this.current == 1) {
  684. this.orderInvoiceList();
  685. } else {
  686. this.$nextTick(() => {
  687. this.$refs.uForm.setRules(this.rules)
  688. })
  689. }
  690. },
  691. orderInvoiceList() {
  692. this.$api.orderInvoiceList().then(res => {
  693. if(res.data.code == 200) {
  694. this.recordList = res.data.rows
  695. } else {
  696. uni.showToast({
  697. icon:'none',
  698. title:res.data.msg
  699. })
  700. }
  701. })
  702. },
  703. radioGroupChange(e) {
  704. console.log(e)
  705. },
  706. copy(str) {
  707. if(!str) {
  708. uni.showToast({
  709. icon:'none',
  710. title:'暂时没有可以复制的快递号'
  711. })
  712. return;
  713. }
  714. let newStr = String(str)
  715. uni.setClipboardData({
  716. data: newStr,
  717. success: function () {
  718. console.log('success');
  719. }
  720. });
  721. },
  722. okPopup() {
  723. this.selectOrderModal = false;
  724. let strArr = [];
  725. this.invoicePirce = 0;
  726. this.orderList.forEach((item,index) => {
  727. if(item.checked) {
  728. this.$set(this.orderList[index],'disabled',true)
  729. strArr.push(item.orderGoodsId)
  730. this.invoicePirce += item.goodsPrice
  731. }
  732. })
  733. this.form.orderGoodsIds = strArr.join(',')
  734. this.$nextTick(() => {
  735. this.$refs.orderGoodsIds.onFieldChange()
  736. })
  737. console.log(this.$refs.orderGoodsIds)
  738. },
  739. deleteOrder(index) {
  740. this.$set(this.orderList[index],'disabled',false)
  741. this.$set(this.orderList[index],'checked',false)
  742. let strArr = [];
  743. this.invoicePirce = 0;
  744. this.orderList.forEach((item,index) => {
  745. if(item.checked) {
  746. strArr.push(item.orderGoodsId)
  747. this.invoicePirce += item.goodsPrice
  748. }
  749. })
  750. this.form.orderGoodsIds = strArr.join(',')
  751. this.$nextTick(() => {
  752. this.$refs.orderGoodsIds.onFieldChange()
  753. })
  754. },
  755. previewImg(item) {
  756. // 预览图片
  757. uni.previewImage({
  758. urls: [this.$method.splitImgHost(item.invoiceImg,true,1000)],
  759. longPressActions: {
  760. itemList: ['发送给朋友', '保存图片', '收藏'],
  761. success: function(data) {
  762. console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
  763. },
  764. fail: function(err) {
  765. console.log(err.errMsg);
  766. }
  767. }
  768. });
  769. },
  770. download(item) {
  771. //获取相册授权
  772. uni.getSetting({
  773. success:(res) => {
  774. if (!res.authSetting['scope.writePhotosAlbum']) {
  775. uni.authorize({
  776. scope: 'scope.writePhotosAlbum',
  777. success() {
  778. //这里是用户同意授权后的回调
  779. this.saveImgToLocal(item);
  780. },
  781. fail() {//这里是用户拒绝授权后的回调
  782. }
  783. })
  784. } else {//用户已经授权过了
  785. this.saveImgToLocal(item);
  786. }
  787. }
  788. })
  789. },
  790. saveImgToLocal(item){
  791. uni.showModal({
  792. title: '提示',
  793. content: '确定保存到相册吗',
  794. success: (res) => {
  795. if (res.confirm) {
  796. uni.downloadFile({
  797. url: this.$method.splitImgHost(item.invoiceImg,true,1000),//图片地址
  798. success: (res) =>{
  799. if (res.statusCode === 200){
  800. uni.saveImageToPhotosAlbum({
  801. filePath: res.tempFilePath,
  802. success: function() {
  803. uni.showToast({
  804. title: "保存成功",
  805. icon: "none"
  806. });
  807. },
  808. fail: function() {
  809. uni.showToast({
  810. title: "保存失败",
  811. icon: "none"
  812. });
  813. }
  814. });
  815. }
  816. }
  817. })
  818. } else if (res.cancel) {
  819. }
  820. }
  821. });
  822. }
  823. },
  824. computed: { ...mapGetters(['userInfo']) }
  825. };
  826. </script>
  827. <style>
  828. page {
  829. background: #eaeef1;
  830. }
  831. </style>
  832. <style scoped lang="scss">
  833. .invoice {
  834. &__tabs {
  835. width: 100%;
  836. text-align: center;
  837. position: fixed;
  838. height: 96rpx;
  839. z-index: 999;
  840. }
  841. &__content {
  842. padding-top:96rpx;
  843. .open {
  844. padding-bottom:150rpx;
  845. margin:8rpx 24rpx 0;
  846. .form {
  847. padding:24rpx;
  848. width: 702rpx;
  849. background: #FFFFFF;
  850. border-radius: 24rpx;
  851. // /deep/ .u-input__input {
  852. // text-align: right;
  853. // }
  854. .form-item {
  855. height:78rpx;
  856. display: flex;
  857. align-items: center;
  858. .text {
  859. font-size: 28rpx;
  860. width:120rpx;
  861. // color: #999999;
  862. }
  863. .content {
  864. flex:1;
  865. text-align: left;
  866. color:#bbb;
  867. }
  868. }
  869. .check-order {
  870. margin-top:20rpx;
  871. width: 654rpx;
  872. height: 168rpx;
  873. background: #F5F5F5;
  874. border: 2px solid #F5F5F5;
  875. padding:20rpx;
  876. position:relative;
  877. .close {
  878. position:absolute;
  879. right:0;
  880. top:0;
  881. }
  882. .title,.number,.price {
  883. color:#333333;
  884. margin-top:10rpx;
  885. line-height: 30rpx;
  886. font-size: 30rpx;
  887. }
  888. .number {
  889. color:#999;
  890. }
  891. }
  892. }
  893. .order-text {
  894. margin-top:16rpx;
  895. padding:0 30rpx;
  896. width: 702rpx;
  897. height: 80rpx;
  898. background: #FFFFFF;
  899. border-radius: 24rpx;
  900. display: flex;
  901. align-items: center;
  902. &__label {
  903. font-size: 24rpx;
  904. }
  905. &__price {
  906. font-size: 30rpx;
  907. margin-left:20rpx;
  908. color:#FF2D55;
  909. }
  910. }
  911. .submit {
  912. text-align: center;
  913. line-height: 80rpx;
  914. color:#fff;
  915. font-size: 30rpx;
  916. width: 526rpx;
  917. height: 80rpx;
  918. background: #007AFF;
  919. box-shadow: 0rpx 8rpx 7rpx 1rpx rgba(0, 122, 255, 0.1);
  920. border-radius: 40rpx;
  921. position:fixed;
  922. left:50%;
  923. bottom:40rpx;
  924. z-index: 999;
  925. transform: translateX(-50%);
  926. }
  927. }
  928. .record {
  929. .nodata {
  930. padding-top:160rpx;
  931. font-size: 32rpx;
  932. text-align: center;
  933. color: #999999;
  934. }
  935. &__list {
  936. .record-item {
  937. margin:0 8rpx 10rpx;
  938. .item__time {
  939. padding:20rpx 0;
  940. text-align: center;
  941. font-size: 24rpx;
  942. color: #999999;
  943. }
  944. .item__content {
  945. background:#fff;
  946. border-radius: 16rpx;
  947. .top {
  948. padding:12rpx 0;
  949. border-bottom:1px solid #EEEEEE;
  950. .state {
  951. position:relative;
  952. text-align: center;
  953. color:#fff;
  954. font-size: 30rpx;
  955. margin:0 auto;
  956. width: 240rpx;
  957. height: 56rpx;
  958. line-height: 56rpx;
  959. background: #007AFF;
  960. border-radius: 28rpx;
  961. &.wait {
  962. background: #007AFF;
  963. }
  964. &.refuse {
  965. background: #FF3B30;
  966. }
  967. &.agree {
  968. background: #34C759;
  969. }
  970. .arrow {
  971. position:absolute;
  972. top:50%;
  973. transform: translateY(-50%);
  974. right:18rpx;
  975. }
  976. }
  977. }
  978. .bottom {
  979. padding:0 32rpx;
  980. .flex {
  981. height:80rpx;
  982. display: flex;
  983. align-items: center;
  984. border-bottom:1px solid #EEEEEE;
  985. &.noborder{
  986. border:0;
  987. }
  988. .text {
  989. font-size: 24rpx;
  990. color: #666666;
  991. }
  992. &__auto {
  993. text-align: right;
  994. flex:1;
  995. font-size: 30rpx;
  996. font-weight: bold;
  997. color: #666666;
  998. .red {
  999. color:#FF3B30;
  1000. }
  1001. .green {
  1002. color:#34C759;
  1003. }
  1004. }
  1005. }
  1006. .order-list {
  1007. padding-bottom:30rpx;
  1008. .order-item {
  1009. border-radius: 16rpx;
  1010. padding:14rpx;
  1011. background:#F5F5F5;
  1012. font-size: 30rpx;
  1013. color:#333;
  1014. margin-top:16rpx;
  1015. }
  1016. }
  1017. }
  1018. }
  1019. }
  1020. }
  1021. }
  1022. }
  1023. .modal {
  1024. .select-order {
  1025. .line {
  1026. width: 80rpx;
  1027. height: 8rpx;
  1028. background: #999999;
  1029. border-radius: 4rpx;
  1030. margin:8rpx auto 0;
  1031. }
  1032. .title {
  1033. margin:20rpx 0 15rpx;
  1034. text-align: center;
  1035. font-size: 24rpx;
  1036. color: #999999;
  1037. }
  1038. .order-item {
  1039. display: flex;
  1040. align-items: center;
  1041. padding: 20rpx;
  1042. &__bg {
  1043. width: 654rpx;
  1044. height: 168rpx;
  1045. background: #F5F5F5;
  1046. border: 2px solid #F5F5F5;
  1047. border-radius: 16rpx;
  1048. padding:20rpx;
  1049. &.active {
  1050. background: #EBF5FF;
  1051. border: 2px solid #007AFF;
  1052. }
  1053. .order-title,.order-number,.order-price {
  1054. color:#333333;
  1055. margin-top:10rpx;
  1056. line-height: 30rpx;
  1057. font-size: 30rpx;
  1058. }
  1059. .order-number {
  1060. color:#999;
  1061. }
  1062. }
  1063. }
  1064. .confrim-btn {
  1065. width: 750rpx;
  1066. height: 98rpx;
  1067. background: rgba(255, 255, 255, 0.98);
  1068. display: flex;
  1069. align-items: center;
  1070. justify-content: center;
  1071. .okBtn {
  1072. text-align: center;
  1073. line-height: 64rpx;
  1074. color:#fff;
  1075. font-size: 30rpx;
  1076. width: 200rpx;
  1077. height: 64rpx;
  1078. background: linear-gradient(0deg, #015EEA, #00C0FA);
  1079. border-radius: 32rpx;
  1080. }
  1081. }
  1082. }
  1083. .order-detail {
  1084. width: 640rpx;
  1085. height: 1000rpx;
  1086. background: #FFFFFF;
  1087. display: flex;
  1088. flex-direction: column;
  1089. &__content {
  1090. flex:1;
  1091. .content {
  1092. padding:24rpx 24rpx 0;
  1093. /deep/ .u-cell {
  1094. padding:10rpx;
  1095. &_title {
  1096. color:#999;
  1097. }
  1098. &__value {
  1099. color:#333;
  1100. text-align: left;
  1101. }
  1102. .text {
  1103. &.wait {
  1104. color:#007AFF;
  1105. }
  1106. &.agree {
  1107. color:#34C759;
  1108. }
  1109. &.refuse {
  1110. color:#FF3B30;
  1111. }
  1112. }
  1113. .preview {
  1114. width:240rpx;
  1115. height:160rpx;
  1116. }
  1117. .download-btn {
  1118. margin:10rpx 0 0;
  1119. text-align: center;
  1120. line-height: 56rpx;
  1121. color:#fff;
  1122. font-size: 30rpx;
  1123. width: 224rpx;
  1124. height: 56rpx;
  1125. background: #007AFF;
  1126. border-radius: 16rpx;
  1127. }
  1128. }
  1129. .header {
  1130. font-size: 30rpx;
  1131. font-weight: bold;
  1132. color: #333333;
  1133. line-height: 48rpx;
  1134. }
  1135. .body {
  1136. &__item {
  1137. border-bottom:1px solid #EEEEEE;
  1138. padding-bottom:30rpx;
  1139. &:last-child {
  1140. border:0;
  1141. }
  1142. .title {
  1143. margin-top:30rpx;
  1144. font-size: 24rpx;
  1145. color: #007AFF;
  1146. line-height: 48rpx;
  1147. &::before {
  1148. content:'';
  1149. width: 4rpx;
  1150. height: 24rpx;
  1151. background: #007AFF;
  1152. border-radius: 2rpx;
  1153. display: inline-block;
  1154. margin-right:10rpx;
  1155. }
  1156. }
  1157. .order-list {
  1158. .order-item {
  1159. overflow: hidden;
  1160. border-radius: 16rpx;
  1161. padding:0 14rpx 14rpx;
  1162. background:#F5F5F5;
  1163. font-size: 30rpx;
  1164. color:#333;
  1165. margin-top:16rpx;
  1166. .order-title,.order-number,.order-price {
  1167. color:#333333;
  1168. margin-top:20rpx;
  1169. line-height: 26rpx;
  1170. font-size: 26rpx;
  1171. }
  1172. .order-number {
  1173. color:#999;
  1174. }
  1175. }
  1176. }
  1177. .order-text {
  1178. margin-top:16rpx;
  1179. padding:0 30rpx;
  1180. height: 80rpx;
  1181. background: #F5F5F5;
  1182. border-radius: 16rpx;
  1183. display: flex;
  1184. align-items: center;
  1185. &__label {
  1186. font-size: 24rpx;
  1187. color:#999999;
  1188. }
  1189. &__price {
  1190. font-size: 30rpx;
  1191. margin-left:20rpx;
  1192. color:#FF2D55;
  1193. }
  1194. }
  1195. }
  1196. }
  1197. }
  1198. }
  1199. &__btns {
  1200. border-top:1px solid #EEEEEE;
  1201. padding:0 24rpx;
  1202. width: 100%;
  1203. height: 140rpx;
  1204. background: #FFFFFF;
  1205. display: flex;
  1206. justify-content: center;
  1207. align-items: center;
  1208. .btn {
  1209. text-align: center;
  1210. width: 200rpx;
  1211. height: 80rpx;
  1212. line-height: 80rpx;
  1213. background: #F5F5F5;
  1214. border-radius: 40rpx;
  1215. color:#007AFF;
  1216. font-size: 30rpx;
  1217. margin:0 10rpx;
  1218. &.warm {
  1219. background: #FF3B30;
  1220. color:#fff;
  1221. }
  1222. &.ok {
  1223. color:#fff;
  1224. width: 526rpx;
  1225. height: 80rpx;
  1226. background: #007AFF;
  1227. border-radius: 40rpx;
  1228. }
  1229. }
  1230. }
  1231. }
  1232. .order-cancel {
  1233. width: 640rpx;
  1234. height: 439rpx;
  1235. background: #FFFFFF;
  1236. padding:40rpx;
  1237. .header {
  1238. text-align: center;
  1239. font-size: 30rpx;
  1240. font-weight: bold;
  1241. color: #333333;
  1242. line-height: 48rpx;
  1243. }
  1244. .body {
  1245. margin-top:40rpx;
  1246. view {
  1247. font-size: 30rpx;
  1248. color: #666666;
  1249. line-height: 48rpx;
  1250. }
  1251. }
  1252. .footer {
  1253. margin-top:40rpx;
  1254. display: flex;
  1255. align-items: center;
  1256. justify-content: center;
  1257. .btn {
  1258. text-align: center;
  1259. line-height: 80rpx;
  1260. font-size: 30rpx;
  1261. color:#007AFF;
  1262. width: 200rpx;
  1263. height: 80rpx;
  1264. background: #F5F5F5;
  1265. border-radius: 40rpx;
  1266. margin:0 10rpx;
  1267. &.ok {
  1268. color:#fff;
  1269. background: #007AFF;
  1270. }
  1271. }
  1272. }
  1273. }
  1274. }
  1275. }
  1276. </style>