OrderDetail.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. <template>
  2. <el-dialog
  3. :visible.sync="visible"
  4. :before-close="handleClose"
  5. title="订单信息"
  6. width="90%"
  7. >
  8. <el-form
  9. :inline="true"
  10. label-width="120px"
  11. class="dialog-info"
  12. v-if="orderData"
  13. >
  14. <el-form-item label="线下订单号">
  15. {{ orderData.orderNo }}
  16. </el-form-item>
  17. <el-form-item label="创建时间">
  18. {{ orderData.createTime | formatTime }}
  19. </el-form-item>
  20. <el-form-item label="合作方订单号">
  21. {{ orderData.partnerOrderNo }}
  22. </el-form-item>
  23. <el-form-item label="订单类型">
  24. {{ orderData.orderCategory | formatCategory }}
  25. </el-form-item>
  26. <el-form-item label="总价(¥)">
  27. {{ orderData.price }}
  28. </el-form-item>
  29. <el-form-item label="包含的票数">
  30. {{ orderData.ticketNum }}
  31. </el-form-item>
  32. <el-form-item label="支付类型">
  33. {{ orderData.payChannel }}
  34. </el-form-item>
  35. <el-form-item label="支付状态">
  36. <!-- 由于支付状态较多,且接口返回的状态码不固定,所以这里直接列出所有状态,避免遗漏 -->
  37. <div v-if="orderData.payStatus == 'CREATE'">已创建</div>
  38. <div v-if="orderData.payStatus == 'SUBMIT'">已提交</div>
  39. <div v-if="orderData.payStatus == 'PAYED'">已支付</div>
  40. <div v-if="orderData.payStatus == 'REFUNDED'">已退款</div>
  41. <div v-if="orderData.payStatus == 'CLOSED'">订单关闭</div>
  42. <div v-if="orderData.payStatus == 'FAILED'">支付失败</div>
  43. </el-form-item>
  44. <el-form-item label="支付时间">
  45. {{ orderData.payTime | formatTime }}
  46. </el-form-item>
  47. <el-form-item label="订单来源渠道">
  48. {{ orderData.otaSourceName }}
  49. </el-form-item>
  50. <el-form-item label="售票员">
  51. {{ orderData.saleAdminName }}
  52. </el-form-item>
  53. <el-form-item label="购买方名称">
  54. {{ orderData.buyerName }}
  55. </el-form-item>
  56. <el-form-item label="购买方手机号">
  57. {{ orderData.buyerPhone }}
  58. </el-form-item>
  59. <el-form-item label="购买方证件号">
  60. {{ orderData.buyerIdentify }}
  61. </el-form-item>
  62. <el-form-item label="是否是线上订单">
  63. {{ orderData.isOnlineOrder ? '是' : '否' }}
  64. </el-form-item>
  65. <el-form-item label="订单状态">
  66. <OrderStatusTag :value="orderData.status"></OrderStatusTag>
  67. </el-form-item>
  68. <el-form-item label="团队名称">
  69. {{ orderData.teamName || '无' }}
  70. </el-form-item>
  71. <el-form-item label="导游名称">
  72. {{ orderData.guideName || '无' }}
  73. </el-form-item>
  74. <el-tabs v-model="activeTab" type="card">
  75. <el-tab-pane class="block-title" label="门票信息" name="ticketCheckInfo">
  76. <div class="title" style="display: flex;justify-content: space-between;margin-bottom: 10px;">
  77. <div>
  78. 检票景点明细
  79. <el-button
  80. type="primary"
  81. style="margin-left: 20px;"
  82. @click="showColumnConfig">
  83. 设置显示列
  84. </el-button>
  85. </div>
  86. <el-input v-model="ticketNoSearch1" placeholder="输入票号查询"></el-input>
  87. </div>
  88. <el-table border :data="checkDetailList" :max-height="450">
  89. <el-table-column type="expand">
  90. <template slot-scope="props">
  91. <div class="title">检票景点</div>
  92. <el-table :data="props.row.ticketCheckScenicList" :max-height="200">
  93. <el-table-column
  94. prop="scenicName"
  95. show-overflow-tooltip
  96. width="300"
  97. label="景点"
  98. ></el-table-column>
  99. <el-table-column
  100. prop="checkLimitTimes"
  101. label="可检票次数"
  102. width="150"
  103. >
  104. <template slot-scope="scope">
  105. {{ scope.row.checkLimitTimes === -1 ? "无限制" : scope.row.checkLimitTimes }}
  106. </template>
  107. </el-table-column>
  108. <el-table-column
  109. prop="checkedTimes"
  110. width="150"
  111. label="已检票次数"
  112. ></el-table-column>
  113. <el-table-column
  114. prop="singleCheckLimitTimes"
  115. label="单日可检票次数"
  116. width="150"
  117. ></el-table-column>
  118. </el-table>
  119. </template>
  120. </el-table-column>
  121. <el-table-column
  122. v-if="isColumnVisible('ticketNo')"
  123. width="160"
  124. prop="ticketNo"
  125. label="票号">
  126. <template slot-scope="scope">
  127. <div class="">{{ scope.row.ticketNo }}</div>
  128. <img v-if="scope.row.ticketNoImg" :src="scope.row.ticketNoImg || ''" style="width: 130px;height: 130px;" alt="">
  129. </template>
  130. </el-table-column>
  131. <el-table-column
  132. v-if="isColumnVisible('ticketTypeName')"
  133. width="100"
  134. prop="ticketTypeName"
  135. label="票种"> </el-table-column>
  136. <el-table-column
  137. v-if="isColumnVisible('unitPrice')"
  138. width="80"
  139. prop="price"
  140. label="单价(¥)">
  141. <template slot-scope="scope">
  142. <div class="">{{ scope.row.checkNum ? scope.row.price / scope.row.checkNum : scope.row.price }}</div>
  143. <div v-if="scope.row.discountPrice" style="color: #bbb">原价:{{ scope.row.originalPrice }}</div>
  144. <div v-if="scope.row.discountPrice" style="color: #52c41a">优惠:{{ scope.row.discountPrice }}</div>
  145. <div v-if="scope.row.price !== scope.row.settlementPrice" style="color: #0080ff">结算价:{{ scope.row.settlementPrice }}</div>
  146. </template>
  147. </el-table-column>
  148. <el-table-column
  149. v-if="isColumnVisible('subtotal')"
  150. width="80"
  151. prop="price"
  152. label="小计"></el-table-column>
  153. <el-table-column
  154. v-if="isColumnVisible('status')"
  155. width="100"
  156. prop="status"
  157. label="状态">
  158. <template slot-scope="scope">
  159. <!-- 组件新增功能是否向左浮动展示,默认为false不浮动 -->
  160. <TicketStatusTag :float-left="true" :value="scope.row.status"></TicketStatusTag>
  161. </template>
  162. </el-table-column>
  163. <el-table-column
  164. v-if="isColumnVisible('guestInfo')"
  165. width="210"
  166. prop="guestInfo"
  167. label="游客信息">
  168. <template slot-scope="scope">
  169. <div class=""><span>姓名:</span>{{ scope.row.guestName }}</div>
  170. <div class=""><span>手机号:</span>{{ scope.row.guestPhone }}</div>
  171. <div class=""><span>证件类型:</span>{{ papersType[scope.row.guestIdentifyType] }}</div>
  172. <div class=""><span>证件号码:</span>{{ scope.row.guestIdentify }}</div>
  173. </template>
  174. </el-table-column>
  175. <el-table-column
  176. v-if="isColumnVisible('ticketCheckInfo')"
  177. width="260"
  178. prop="ticketCheckInfo"
  179. label="检票信息">
  180. <template slot-scope="scope">
  181. <div class=""><span>检票人数:</span>{{ scope.row.checkNum }}</div>
  182. <div class=""><span>首次检票时间:</span>{{ scope.row.firstCheckTime }}</div>
  183. <div class=""><span>最近一次检票时间:</span>{{ scope.row.checkTime }}</div>
  184. <div class=""><span>最近一次检票设备:</span>{{ scope.row.checkerName }}</div>
  185. </template>
  186. </el-table-column>
  187. <el-table-column
  188. v-if="isColumnVisible('ticketPrintInfo')"
  189. width="260"
  190. prop="ticketPrintInfo"
  191. label="取票信息">
  192. <template slot-scope="scope">
  193. <div class=""><span>取票状态:</span>
  194. <el-tag :type="scope.row.isPrint ? 'success' : 'info'">
  195. {{ scope.row.isPrint ? "已取票" : "未取票" }}
  196. </el-tag>
  197. </div>
  198. <div class=""><span>取票时间:</span>{{ scope.row.printTime }}</div>
  199. <div class=""><span>取票人:</span>{{ scope.row.printAdminName }}</div>
  200. <div class=""><span>取票自助机:</span>{{ scope.row.printTermName }}</div>
  201. </template>
  202. </el-table-column>
  203. <el-table-column
  204. v-if="isColumnVisible('ticketRefundInfo')"
  205. width="260"
  206. prop="ticketRefundInfo"
  207. label="退票信息">
  208. <template slot-scope="scope">
  209. <div class=""><span>退款操作人:</span>{{ scope.row.cancelAdminName }}</div>
  210. <div class=""><span>退款金额:</span>{{ scope.row.cancelPrice }}</div>
  211. <div class=""><span>退款申请时间:</span>{{ scope.row.cancelSubmitTime }}</div>
  212. <div class=""><span>退款完成时间:</span>{{ scope.row.cancelCompleteTime }}</div>
  213. <div class=""><span>是否强制取消:</span>{{ scope.row.isForceCancel ? '是' : '否' }}</div>
  214. </template>
  215. </el-table-column>
  216. <el-table-column
  217. v-if="isColumnVisible('playDate')"
  218. width="160"
  219. prop="playDateBegin"
  220. label="游玩时间">
  221. <template slot-scope="scope">
  222. <div v-if="scope.row.batchConfigName"><span>场次:</span>{{ scope.row.batchConfigName || '' }}</div>
  223. {{ scope.row.playDateBegin || scope.row.playDateEnd ? `${scope.row.playDateBegin || ''} - ${scope.row.playDateEnd || ''}` : "无限制" }}
  224. </template>
  225. </el-table-column>
  226. <el-table-column
  227. v-if="isColumnVisible('checkScenic')"
  228. min-width="180"
  229. label="检票景点">
  230. <template slot-scope="scope">
  231. {{ scope.row.ticketCheckScenicList.map(item => item.scenicName).join(',') }}
  232. </template>
  233. </el-table-column>
  234. <!-- 新增功能 -->
  235. <el-table-column width="240" prop="billingInformation" label="开票信息">
  236. <template slot-scope="scope">
  237. <div class=""><span>开票状态:</span>
  238. <el-tag :type="scope.row.isInvoice ? 'success' : 'info'">
  239. {{ scope.row.isInvoice ? "已开票" : "未开票" }}
  240. </el-tag>
  241. </div>
  242. <div class=""><span>发票信息:</span><button @click="downloadInvoice(scope.row.invoiceDownloadUrl)">点击下载</button></div>
  243. </template>
  244. </el-table-column>
  245. <el-table-column
  246. v-if="isColumnVisible('ticketCardInfo')"
  247. width="240"
  248. prop="ticketCardInfo"
  249. label="卡信息">
  250. <template slot-scope="scope" v-if="scope.row.card">
  251. <div class=""><span>卡片编号:</span>{{ scope.row.card.cardNo }}</div>
  252. <div class=""><span>有效时间:</span>{{ scope.row.card.validDateStart }} - {{ scope.row.card.validDateEnd }}</div>
  253. <div class=""><span>卡片状态:</span>{{ scope.row.card.status | filterCardStatus }}</div>
  254. <div class="" v-if="scope.row.card.status === 1"><span>开卡时间:</span>{{ scope.row.card.activeTime }}</div>
  255. <div class="" v-if="scope.row.card.status === 0"><span>退卡时间:</span>{{ scope.row.card.cardNo }}</div>
  256. <div class="" v-if="scope.row.card.status === 2"><span>挂失时间:</span>{{ scope.row.card.repealTime }}</div>
  257. </template>
  258. </el-table-column>
  259. <el-table-column
  260. v-if="isColumnVisible('ticketFaceInfo')"
  261. width="240"
  262. prop="ticketFaceInfo"
  263. label="人脸信息">
  264. <template slot-scope="scope" v-if="scope.row.face">
  265. <div class=""><span>有效时间:</span>{{ scope.row.face.validDateStart }} - {{ scope.row.face.validDateEnd }}</div>
  266. <div class=""><span>卡片状态:</span>{{ scope.row.face.status === 0 ? '可用' : '不可用' }}</div>
  267. <div class=""><span>图片地址:</span>{{ scope.row.face.imageUrl }}</div>
  268. <div class=""><span>base64:</span>{{ scope.row.face.faceData }}</div>
  269. <div class=""><span>注册状态:</span>{{ scope.row.face.registerStatus === 0 ? '未注册' : '已注册' }}</div>
  270. </template>
  271. </el-table-column>
  272. </el-table>
  273. <!-- <el-table :data="checkDetailList" :max-height="200">
  274. <el-table-column prop="ticketNo" label="票号"> </el-table-column>
  275. <el-table-column prop="ticketTypeName" label="票种"> </el-table-column>
  276. <el-table-column width="80" prop="price" label="票价(¥)">
  277. <template slot-scope="scope">
  278. {{ scope.row.checkNum ? scope.row.price / scope.row.checkNum : scope.row.price }}
  279. </template>
  280. </el-table-column>
  281. <el-table-column
  282. prop="scenicName"
  283. label="景点"
  284. ></el-table-column>
  285. <el-table-column
  286. prop="checkLimitTimes"
  287. label="可检票次数"
  288. >
  289. <template slot-scope="scope">
  290. {{ scope.row.checkLimitTimes === -1 ? "无限制" : scope.row.checkLimitTimes }}
  291. </template>
  292. </el-table-column>
  293. <el-table-column
  294. prop="checkedTimes"
  295. label="已检票次数"
  296. ></el-table-column>
  297. </el-table> -->
  298. <div class="title" style="display: flex;justify-content: space-between;margin: 10px 0;">
  299. 门票检票日志
  300. <el-input v-model="ticketNoSearch2" placeholder="输入票号查询"></el-input>
  301. </div>
  302. <el-table border :data="checkLogList" :max-height="200">
  303. <el-table-column prop="ticketNo" label="票号"> </el-table-column>
  304. <!-- <el-table-column prop="ticketTypeName" label="票种"> </el-table-column>
  305. <el-table-column width="80" prop="price" label="票价(¥)">
  306. <template slot-scope="scope">
  307. {{ scope.row.checkNum ? scope.row.price / scope.row.checkNum : scope.row.price }}
  308. </template>
  309. </el-table-column> -->
  310. <el-table-column prop="checkType" label="检票类型">
  311. <template slot-scope="prop">
  312. {{ prop.row.checkType | checkTypeFilter }}
  313. </template>
  314. </el-table-column>
  315. <el-table-column prop="scenicName" label="景点名称"> </el-table-column>
  316. <el-table-column prop="checkerAdminName" label="检票员"> </el-table-column>
  317. <el-table-column prop="checkerName" label="检票设备名称"> </el-table-column>
  318. <el-table-column prop="checkTime" label="检票时间"> </el-table-column>
  319. </el-table>
  320. <!-- 新增功能:工行分账信息,但if判断需要后续改动 -->
  321. <div class="title" v-if="orderData.payContext != null" style="display: flex;justify-content: space-between;margin: 10px 0;">
  322. 工行分账明细
  323. </div>
  324. <el-table v-if="orderData.payContext != null" border :data="checkLogList" :max-height="200">
  325. <el-table-column prop="id" label="ID"> </el-table-column>
  326. <el-table-column prop="createTime" label="创建时间"> </el-table-column>
  327. <el-table-column prop="recNum" label="拆分顺序号"> </el-table-column>
  328. <el-table-column prop="originalGhMerId" label="原交易商户编号"> </el-table-column>
  329. <el-table-column prop="ghOrderId" label="原工行订单编号"> </el-table-column>
  330. <el-table-column prop="ghAppId" label="应用APPID"> </el-table-column>
  331. <el-table-column prop="subMerId" label="分账二级商户编号"> </el-table-column>
  332. <el-table-column prop="subMerPrtclNo" label="分账二级商户协议编号"> </el-table-column>
  333. <el-table-column prop="subOrderId" label="商户子订单编号"> </el-table-column>
  334. <el-table-column prop="ghSubOrderId" label="工行子订单编号"> </el-table-column>
  335. <el-table-column prop="ghSubOrderTransactionId" label="工行交易流水号"> </el-table-column>
  336. <el-table-column prop="splitFee" label="分账金额"> </el-table-column>
  337. <el-table-column prop="termId" label="交易终端号"> </el-table-column>
  338. <el-table-column prop="status" label="分账状态"> </el-table-column>
  339. <el-table-column prop="splitSubmitTime" label="分账开始时间"> </el-table-column>
  340. <el-table-column prop="splitCompleteTime" label="分账完成时间"> </el-table-column>
  341. <el-table-column prop="splitCode" label="错误代码"> </el-table-column>
  342. <el-table-column prop="splitMsg" label="错误信息"> </el-table-column>
  343. <el-table-column prop="refundSubOrderId" label="子订单退货编号"> </el-table-column>
  344. <el-table-column prop="refundSubmitTime" label="退款提交时间"> </el-table-column>
  345. <el-table-column prop="refundCompleteTime" label="退款开始时间"> </el-table-column>
  346. <el-table-column prop="refundFee" label="退款金额"> </el-table-column>
  347. <el-table-column prop="refundCode" label="退款错误代码"> </el-table-column>
  348. <el-table-column prop="refundMsg" label="退款错误信息"> </el-table-column>
  349. </el-table>
  350. </el-tab-pane>
  351. <el-dialog
  352. title="选择显示列"
  353. :visible.sync="dialogVisible"
  354. append-to-body>
  355. <el-checkbox-group v-model="tempSelectedColumns">
  356. <el-checkbox v-for="column in fixedColumns" :key="column.value" :label="column.value">{{ column.label }}</el-checkbox>
  357. </el-checkbox-group>
  358. <span slot="footer" class="dialog-footer">
  359. <el-button @click="dialogVisible = false">取 消</el-button>
  360. <el-button type="primary" @click="saveUserConfig">确 定</el-button>
  361. </span>
  362. </el-dialog>
  363. <el-tab-pane class="block-title" label="支付信息" name="payInfo">
  364. <el-form-item label="支付方式">
  365. {{ orderData.payChannel }}
  366. </el-form-item>
  367. <template v-if="orderData.payContext">
  368. <div class="title">支付信息列表</div>
  369. <el-table border :data="orderData.payContext.payList || []">
  370. <el-table-column prop="orderNo" label="支付订单号">
  371. </el-table-column>
  372. <el-table-column prop="payStatus" label="支付状态">
  373. <template slot-scope="scope">
  374. <el-tag :type="getPayStatus(scope.row.payStatus, 'type')">
  375. {{ getPayStatus(scope.row.payStatus) }}
  376. </el-tag>
  377. </template>
  378. </el-table-column>
  379. <el-table-column prop="submitTime" label="提交时间"> </el-table-column>
  380. <el-table-column prop="payTime" label="支付完成时间">
  381. </el-table-column>
  382. <el-table-column prop="fee" label="支付金额">
  383. </el-table-column>
  384. <el-table-column prop="outOrderNo" label="合作方订单号">
  385. </el-table-column>
  386. <el-table-column prop="errMsg" label="支付错误信息">
  387. </el-table-column>
  388. </el-table>
  389. <div class="title">退款信息</div>
  390. <el-table border :data="orderData.payContext.payRefundList || []">
  391. <el-table-column prop="status" label="退款状态">
  392. <!-- 转义 -->
  393. <div v-if="orderData.payContext.payRefundList.status == 'SUBMIT'">已提交</div>
  394. <div v-if="orderData.payContext.payRefundList.status == 'UNKNOWN'">未知</div>
  395. <div v-if="orderData.payContext.payRefundList.status == 'SUCCESS'">成功</div>
  396. <div v-if="orderData.payContext.payRefundList.status == 'FAILURE'">失败</div>
  397. </el-table-column>
  398. <el-table-column prop="refundFee" label="退款金额">
  399. </el-table-column>
  400. <el-table-column prop="refundOrderNo" label="退款订单号">
  401. </el-table-column>
  402. <el-table-column prop="outRefundOrderNo" label="第三方退款单号">
  403. </el-table-column>
  404. <el-table-column prop="submitTime" label="退款提交时间">
  405. </el-table-column>
  406. <el-table-column prop="completeTime" label="退款完成时间">
  407. </el-table-column>
  408. <el-table-column prop="errMsg" label="退款错误信息">
  409. </el-table-column>
  410. </el-table>
  411. <div class="title">退款明细</div>
  412. <el-table
  413. border
  414. :data="orderData.payContext.payRefundTaskList || []">
  415. <el-table-column prop="status" label="退款明细状态">
  416. <!-- 转义 -->
  417. <div v-if="orderData.payContext.payRefundTaskList.status == 'CREATE'">已创建</div>
  418. <div v-if="orderData.payContext.payRefundTaskList.status == 'NEED_RETRY'">待重试</div>
  419. <div v-if="orderData.payContext.payRefundTaskList.status == 'UNKNOWN'">未知</div>
  420. <div v-if="orderData.payContext.payRefundTaskList.status == 'REFUND_SUCCESS'">退款成功</div>
  421. <div v-if="orderData.payContext.payRefundTaskList.status == 'SUCCESS'">退款完成</div>
  422. <div v-if="orderData.payContext.payRefundTaskList.status == 'FAILURE'">失败</div>
  423. </el-table-column>
  424. <el-table-column prop="refundFee" label="退款金额">
  425. </el-table-column>
  426. <el-table-column prop="refundRetryCount" label="退款重试次数">
  427. </el-table-column>
  428. <el-table-column prop="submitTime" label="退款提交时间">
  429. </el-table-column>
  430. <el-table-column prop="completeTime" label="退款完成时间">
  431. </el-table-column>
  432. <el-table-column prop="errMsg" label="退款错误信息">
  433. </el-table-column>
  434. </el-table>
  435. </template>
  436. </el-tab-pane>
  437. <!-- <el-tab-pane class="block-title" label="购票信息" name="customerInfo">
  438. <div style="display: flex;justify-content: space-between;">
  439. <el-form-item label="包含的票数">
  440. {{ orderData.ticketNum || 0 }}
  441. </el-form-item>
  442. <el-input v-model="ticketNoSearch" placeholder="输入票号查询"></el-input>
  443. </div>
  444. <el-table border :data="orderTicketList" :max-height="400">
  445. <el-table-column type="expand">
  446. <template slot-scope="props">
  447. <div class="title">检票景点明细</div>
  448. <el-table :data="props.row.ticketCheckScenicList" :max-height="200">
  449. <el-table-column
  450. prop="scenicName"
  451. label="景点"
  452. ></el-table-column>
  453. <el-table-column
  454. prop="checkLimitTimes"
  455. label="可检票次数"
  456. >
  457. <template slot-scope="scope">
  458. {{ scope.row.checkLimitTimes === -1 ? "无限制" : scope.row.checkLimitTimes }}
  459. </template>
  460. </el-table-column>
  461. <el-table-column
  462. prop="checkedTimes"
  463. label="已检票次数"
  464. ></el-table-column>
  465. </el-table>
  466. </template>
  467. </el-table-column>
  468. <el-table-column width="160" prop="ticketNo" label="票号"> </el-table-column>
  469. <el-table-column width="100" prop="ticketTypeName" label="票种"> </el-table-column>
  470. <el-table-column width="80" prop="price" label="票价(¥)">
  471. <template slot-scope="scope">
  472. {{ scope.row.checkNum ? scope.row.price / scope.row.checkNum : scope.row.price }}
  473. </template>
  474. </el-table-column>
  475. <el-table-column width="100" prop="guestName" label="游客姓名">
  476. </el-table-column>
  477. <el-table-column width="140" prop="guestPhone" label="游客手机号">
  478. </el-table-column>
  479. <el-table-column width="100" prop="guestIdentifyType" label="证件类型">
  480. <template slot-scope="scope">
  481. {{ papersType[scope.row.guestIdentifyType] }}
  482. </template>
  483. </el-table-column>
  484. <el-table-column prop="guestIdentify" label="证件号码">
  485. </el-table-column>
  486. <el-table-column width="80" prop="checkNum" label="检票人数">
  487. </el-table-column>
  488. <el-table-column width="160" prop="playDateBegin" label="游玩时间">
  489. <template slot-scope="scope">
  490. {{ scope.row.playDateBegin || scope.row.playDateEnd ? `${scope.row.playDateBegin || ''} - ${scope.row.playDateEnd || ''}` : "无限制" }}
  491. </template>
  492. </el-table-column>
  493. <el-table-column width="80" label="取票状态">
  494. <template slot-scope="scope">
  495. <el-tag :type="scope.row.isPrint ? 'success' : 'info'">
  496. {{ scope.row.isPrint ? "已取票" : "未取票" }}
  497. </el-tag>
  498. </template>
  499. </el-table-column>
  500. <el-table-column width="80" label="状态">
  501. <template slot-scope="scope">
  502. <TicketStatusTag :value="scope.row.status"></TicketStatusTag>
  503. </template>
  504. </el-table-column>
  505. <el-table-column width="80" prop="price" label="小计">
  506. </el-table-column>
  507. <el-table-column min-width="180" label="检票景点">
  508. <template slot-scope="scope">
  509. {{ scope.row.ticketCheckScenicList.map(item => item.scenicName).join(',') }}
  510. </template>
  511. </el-table-column>
  512. </el-table>
  513. </el-tab-pane> -->
  514. <el-tab-pane class="block-title" label="修改记录" name="orderUpdateLog">
  515. <el-table border :data="orderData.orderUpdateLogList" :max-height="400">
  516. <el-table-column prop="updateType" label="修改类型">
  517. <template slot-scope="scope">
  518. {{ scope.row.updateType | updateTypeFilter }}
  519. </template>
  520. </el-table-column>
  521. <el-table-column prop="orderNo" label="订单号">
  522. </el-table-column>
  523. <el-table-column prop="ticketNo" label="票号">
  524. </el-table-column>
  525. <el-table-column prop="oldValue" label="修改前">
  526. <template slot-scope="scope">
  527. {{ getValueDetail(scope.row, 'oldValue') }}
  528. </template>
  529. </el-table-column>
  530. <el-table-column prop="newValue" label="修改后">
  531. <template slot-scope="scope">
  532. {{ getValueDetail(scope.row, 'newValue') }}
  533. </template>
  534. </el-table-column>
  535. <el-table-column prop="updateAdminName" label="操作人">
  536. </el-table-column>
  537. <el-table-column prop="createTime" label="修改时间">
  538. </el-table-column>
  539. </el-table>
  540. </el-tab-pane>
  541. <el-tab-pane class="block-title" label="补打信息" name="secondPrintInfo">
  542. <el-table border :data="orderData.ticketSecondPrintLogList" :max-height="400">
  543. <el-table-column prop="printAdminName" label="操作人"> </el-table-column>
  544. <el-table-column prop="printTime" label="操作时间"> </el-table-column>
  545. </el-table>
  546. </el-tab-pane>
  547. </el-tabs>
  548. <el-dialog
  549. label="检票景点明细"
  550. :visible.sync="detailVisible"
  551. append-to-body
  552. >
  553. <div style="padding:20px">
  554. <el-table :data="record.ticketListScenic">
  555. <el-table-column
  556. prop="scenic_name"
  557. label="景点"
  558. ></el-table-column>
  559. <el-table-column
  560. prop="checkLimitTimes"
  561. label="可检票次数"
  562. ></el-table-column>
  563. <el-table-column
  564. prop="checked_times"
  565. label="已检票次数"
  566. ></el-table-column>
  567. </el-table>
  568. </div>
  569. </el-dialog>
  570. </el-form>
  571. </el-dialog>
  572. </template>
  573. <script>
  574. import { channelList, IDENTIFY_TYPES } from '@/assets/staticData'
  575. import { getPayStatus } from '@/utils/index'
  576. import { addUserConfig, getUserConfig } from '@/api/configSetting'
  577. import QRCode from 'qrcode'
  578. const fixedColumns = [
  579. { value: 'ticketNo', label: '票号' },
  580. { value: 'ticketTypeName', label: '票种' },
  581. { value: 'unitPrice', label: '单价(¥)' },
  582. { value: 'subtotal', label: '小计' },
  583. { value: 'status', label: '状态' },
  584. { value: 'guestInfo', label: '游客信息' },
  585. { value: 'ticketCheckInfo', label: '检票信息' },
  586. { value: 'ticketPrintInfo', label: '取票信息' },
  587. { value: 'ticketRefundInfo', label: '退票信息' },
  588. { value: 'playDate', label: '游玩时间' },
  589. { value: 'checkScenic', label: '检票景点' },
  590. { value: 'ticketCardInfo', label: '卡信息' },
  591. { value: 'ticketFaceInfo', label: '人脸信息' }
  592. ]
  593. const STAT_KEY = 'orderDetailTicketColumns'
  594. export default {
  595. created () {
  596. this.posType = this.$localStore.get('posType')
  597. },
  598. computed: {
  599. previewList () {
  600. return this.orderData.pictureRemarks.map(i => i.url)
  601. },
  602. orderTicketList () {
  603. if (!this.orderData) return []
  604. return this.orderData.ticketList.filter(i =>
  605. this.ticketNoSearch
  606. ? i.ticketNo.includes(this.ticketNoSearch)
  607. : true
  608. )
  609. },
  610. checkDetailList () {
  611. if (!this.orderData) return []
  612. return this.orderData.ticketList.filter(i =>
  613. this.ticketNoSearch1
  614. ? !!i.ticketNo.includes(this.ticketNoSearch1)
  615. : true
  616. )
  617. },
  618. checkLogList () {
  619. if (!this.orderData) return []
  620. return this.ticketCheckLogList.filter(i =>
  621. this.ticketNoSearch2
  622. ? !!i.ticketNo.includes(this.ticketNoSearch2)
  623. : true
  624. )
  625. }
  626. },
  627. data () {
  628. return {
  629. channelList,
  630. papersType: IDENTIFY_TYPES,
  631. posType: '',
  632. orderData: null,
  633. visible: false,
  634. detailVisible: false,
  635. record: {},
  636. activeTab: 'ticketCheckInfo',
  637. dialogVisible: false,
  638. fixedColumns,
  639. selectedColumns: fixedColumns.map(i => i.value),
  640. tempSelectedColumns: fixedColumns.map(i => i.value),
  641. ticketNoSearch: '',
  642. ticketNoSearch1: '',
  643. ticketNoSearch2: '',
  644. ticketCheckScenicList: [],
  645. ticketSecondPrintLogList: [],
  646. ticketCheckLogList: []
  647. }
  648. },
  649. filters: {
  650. checkTypeFilter (input) {
  651. switch (input) {
  652. case 'qrcode':
  653. return '二维码'
  654. case 'face':
  655. return '人脸'
  656. case 'card':
  657. return 'IC卡'
  658. case 'idcard':
  659. return '身份证'
  660. case 'manual_check':
  661. return '人工检票'
  662. case 'print_check':
  663. return '取票即检票'
  664. case 'buy_check':
  665. return '购买即检票'
  666. default:
  667. break
  668. }
  669. },
  670. formatCategory (input) {
  671. switch (input) {
  672. case 'ticket':
  673. return '景区门票'
  674. case 'batch':
  675. return '场次售票'
  676. case 'member':
  677. return '年卡次卡'
  678. case 'other':
  679. return '其他'
  680. default:
  681. break
  682. }
  683. },
  684. updateTypeFilter (input) {
  685. switch (input) {
  686. case 'updateOrderPayChannel':
  687. return '订单修改支付方式'
  688. case 'updatePlayDate':
  689. return '门票修改游玩日期'
  690. case 'updateScenicTimes':
  691. return '门票修改检票次数'
  692. default:
  693. break
  694. }
  695. },
  696. filterCardStatus (input) {
  697. switch (input) {
  698. case 0:
  699. return '未使用'
  700. case 1:
  701. return '使用中'
  702. case 2:
  703. return '已挂失'
  704. default:
  705. return input
  706. }
  707. }
  708. },
  709. methods: {
  710. getPayStatus,
  711. async getQrCodeImg (ticketNo) {
  712. const opts = {
  713. errorCorrectionLevel: 'H',
  714. type: 'image/png',
  715. quality: 1,
  716. color: {
  717. dark: '#000000ff', // Blue dots
  718. light: '#0000' // Transparent background
  719. }
  720. }
  721. const img = await QRCode.toDataURL(ticketNo, opts)
  722. return img
  723. },
  724. getValueDetail (row, key) {
  725. console.log(row, key)
  726. if (row.updateType === 'updatePlayDate') {
  727. try {
  728. const val = JSON.parse(row[key])
  729. if (val && val.playDateBegin && val.playDateEnd) {
  730. return `${val.playDateBegin} - ${val.playDateEnd}`
  731. }
  732. } catch (error) {
  733. return ''
  734. }
  735. }
  736. return row[key]
  737. },
  738. async show (data) {
  739. this.orderData = data
  740. this.visible = true
  741. this.loadUserConfig(true)
  742. if (data.pictureRemarks) {
  743. data.pictureRemarks = data.pictureRemarks.filter(i => i.url)
  744. }
  745. this.ticketCheckScenicList = []
  746. this.ticketCheckLogList = []
  747. this.ticketSecondPrintLogList = []
  748. if (this.orderData.ticketList) {
  749. this.orderData.ticketList.forEach(async ticket => {
  750. const { ticketNo, ticketTypeName, price, ticketCheckScenicList, ticketCheckLogList, ticketSecondPrintLogList } = ticket
  751. const ticketNoImg = await this.getQrCodeImg(ticketNo)
  752. this.$set(ticket, 'ticketNoImg', ticketNoImg)
  753. if (ticketCheckScenicList && ticketCheckScenicList.length) {
  754. ticketCheckScenicList.forEach((scenic) => {
  755. this.ticketCheckScenicList.push({
  756. ...scenic,
  757. ticketNo,
  758. ticketTypeName,
  759. price
  760. })
  761. })
  762. }
  763. if (ticketCheckLogList && ticketCheckLogList.length) {
  764. ticketCheckLogList.forEach((log) => {
  765. this.ticketCheckLogList.push({
  766. ...log,
  767. ticketNo,
  768. ticketTypeName,
  769. price
  770. })
  771. })
  772. }
  773. if (ticketSecondPrintLogList && ticketSecondPrintLogList.length) {
  774. ticketSecondPrintLogList.forEach((log) => {
  775. this.ticketSecondPrintLogList.push({
  776. ...log,
  777. ticketNo,
  778. ticketTypeName,
  779. price
  780. })
  781. })
  782. }
  783. })
  784. }
  785. },
  786. handleClose () {
  787. this.visible = false
  788. this.activeTab = 'ticketCheckInfo'
  789. this.orderData = null
  790. },
  791. showColumnConfig () {
  792. this.dialogVisible = true
  793. this.loadUserConfig(false)
  794. },
  795. loadUserConfig (applyToTable = true) {
  796. getUserConfig({ statKey: STAT_KEY }).then(config => {
  797. const fields = config?.data?.fields || config?.fields || config?.data?.columns || config?.columns || config?.data || []
  798. let nextSelected = []
  799. if (Array.isArray(fields) && fields.length) {
  800. nextSelected = fields
  801. .filter(i => Number(i.isShow) === 1)
  802. .map(i => i.fieldKey)
  803. } else {
  804. nextSelected = fixedColumns.map(i => i.value)
  805. }
  806. if (applyToTable) {
  807. this.selectedColumns = nextSelected
  808. }
  809. this.tempSelectedColumns = [...nextSelected]
  810. }).catch(() => {
  811. const nextSelected = fixedColumns.map(i => i.value)
  812. if (applyToTable) {
  813. this.selectedColumns = nextSelected
  814. }
  815. this.tempSelectedColumns = [...nextSelected]
  816. })
  817. },
  818. saveUserConfig () {
  819. const fields = this.fixedColumns.map(item => ({
  820. fieldKey: item.value,
  821. fieldName: item.label,
  822. isShow: this.tempSelectedColumns.includes(item.value) ? 1 : 0
  823. }))
  824. addUserConfig({ statKey: STAT_KEY, fields }).then(() => {
  825. this.selectedColumns = [...this.tempSelectedColumns]
  826. this.dialogVisible = false
  827. })
  828. },
  829. isColumnVisible (columnKey) {
  830. return this.selectedColumns.includes(columnKey)
  831. },
  832. copySuccess () {
  833. this.$message.success('复制成功')
  834. },
  835. copyError () {
  836. this.$message.error('复制失败')
  837. },
  838. showDetail (record) {
  839. this.record = record
  840. this.detailVisible = true
  841. },
  842. // 下载方法
  843. downloadInvoice (url) {
  844. console.log(' downloadInvoice', url)
  845. if (!url) {
  846. this.$message.warning('暂无发票可下载')
  847. return
  848. }
  849. window.open(url)
  850. }
  851. }
  852. }
  853. </script>
  854. <style lang="scss">
  855. .el-table__expanded-cell[class*=cell] {
  856. padding: 10px 20px !important;
  857. }
  858. </style>
  859. <style lang="scss" scoped>
  860. .dialog-info {
  861. .el-form-item {
  862. width: 25%;
  863. }
  864. }
  865. .el-icon-document {
  866. cursor: pointer
  867. }
  868. .pic-remark {
  869. li {
  870. display: flex;
  871. align-items: center;
  872. ::v-deep .el-image {
  873. margin-right: 10px;
  874. }
  875. }
  876. }
  877. </style>