OpTicketBlackCode.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. <template>
  2. <div class="car_add">
  3. <div>
  4. <div class="communal-title">
  5. <div>{{ title }}</div>
  6. </div>
  7. </div>
  8. <div style="display: flex;">
  9. <div style="text-align:left;font-size: 17px;font-weight: 600;color: #555;">
  10. 团组成本预算 - 机票的预算:
  11. </div>
  12. <div style="margin-left:20px;color: #555;" v-if="airGroupCostParameter != null">
  13. 经济舱: {{ airGroupCostParameter.jjccb }}元/人 {{ airGroupCostParameter.jjcrs }}人
  14. 共:{{ airGroupCostParameter.jjccb * airGroupCostParameter.jjcrs
  15. }}元&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  16. 公务舱: {{ airGroupCostParameter.gwccb }}元/人 {{ airGroupCostParameter.gwcrs }}人
  17. 共:{{ airGroupCostParameter.gwccb * airGroupCostParameter.gwcrs
  18. }}元&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  19. </div>
  20. <div style="margin-left:20px;" v-else>
  21. 团组成本暂未开放此团数据!
  22. </div>
  23. </div>
  24. <hr style='background-color:#5555; height:1px; border:none;margin: 10px 0;' />
  25. <div>
  26. <el-form :model="delegationInfo" label-width="100px" class="demo-ruleForm">
  27. <div style="display: flex;">
  28. <div style="width: 25%;">
  29. <el-form-item label="团组名称:" label-width="160px">
  30. <el-select v-model="DiId" clearable filterable placeholder="团组选择"
  31. @change="AirTicketResChange" :disabled="isShow" style="width: 100%;">
  32. <el-option v-for="item in DelegationSelect" :key="item.id" :label="item.groupName"
  33. :value="item.id">
  34. </el-option>
  35. </el-select>
  36. </el-form-item>
  37. </div>
  38. <div style="width: 25%;">
  39. <el-form-item label="团 号:" prop="tourCode" label-width="160px">
  40. <el-input placeholder="团号" v-model="delegationInfo.tourCode" :disabled="true">
  41. </el-input>
  42. </el-form-item>
  43. </div>
  44. <div style="width: 25%;">
  45. <el-form-item label="客户:" prop="clientName" label-width="160px">
  46. <el-input placeholder="客户" v-model="delegationInfo.clientName" :disabled="true">
  47. </el-input>
  48. </el-form-item>
  49. </div>
  50. <div style="width: 25%;">
  51. <el-form-item label="出访国家:" prop="visitCountry" label-width="160px">
  52. <el-input placeholder="出访国家" v-model="delegationInfo.visitCountry" :disabled="true">
  53. </el-input>
  54. </el-form-item>
  55. </div>
  56. </div>
  57. </el-form>
  58. <el-form :model="OpTicketBlackCodeData" :rules="OpTicketBlackCodeRules" ref="OpTicketBlackCodeData"
  59. label-width="100px" class="demo-ruleForm">
  60. <div>
  61. <el-form-item label="标题:" prop="title" label-width="160px">
  62. <el-input placeholder="标题" v-model="OpTicketBlackCodeData.title">
  63. </el-input>
  64. </el-form-item>
  65. </div>
  66. <div>
  67. <span style="color: red; padding-left: 100px;">
  68. 请严格遵守此格式!!! 1.KL1723 SU06DEC AMSBRU 0925 1010 -- -- ERJ190 45M (是中转情况下末尾添加[中转])
  69. </span>
  70. </div>
  71. <div style="display: flex;">
  72. <div style="width: 60%;">
  73. <el-form-item label="黑屏代码:" prop="blackCode" label-width="160px">
  74. <el-input @input="parseAirData" type="textarea" :rows="14"
  75. placeholder="请严格遵守此格式!!! 1. EK363 R1 WE08MAR CANDXB HK7 0015 0515 SEAME 2 3 (注意空格以及多条数据换行)"
  76. v-model="OpTicketBlackCodeData.blackCode"></el-input>
  77. </el-form-item>
  78. </div>
  79. <div style="width: 40%;">
  80. <el-form-item label="公务舱现价:" label-width="160px">
  81. <el-input placeholder="公务舱现价" v-model="OpTicketBlackCodeData.nowPrice">
  82. </el-input>
  83. <!-- <el-input type="textarea" :rows="3" placeholder="全价说明"
  84. v-model="OpTicketBlackCodeData.price"></el-input> -->
  85. </el-form-item>
  86. <el-form-item label="经济舱现价:" label-width="160px">
  87. <!-- <el-input type="textarea" :rows="3" placeholder="现价说明"
  88. v-model="OpTicketBlackCodeData.nowPrice"></el-input> -->
  89. <el-input placeholder="经济舱现价" v-model="OpTicketBlackCodeData.price">
  90. </el-input>
  91. </el-form-item>
  92. <el-form-item label="公务舱全价:" label-width="160px">
  93. <el-input placeholder="公务舱全价" v-model="OpTicketBlackCodeData.bcPrice">
  94. </el-input>
  95. </el-form-item>
  96. <el-form-item label="经济舱全价:" label-width="160px">
  97. <el-input placeholder="经济舱全价" v-model="OpTicketBlackCodeData.ecPrice">
  98. </el-input>
  99. </el-form-item>
  100. <el-form-item>
  101. </el-form-item>
  102. </div>
  103. </div>
  104. <div style="display: flex;">
  105. <div style="width: 60%;">
  106. <el-form-item label="备注:" prop="remark" label-width="160px">
  107. <el-input type="textarea" :rows="3" placeholder="备注"
  108. v-model="OpTicketBlackCodeData.remark"></el-input>
  109. </el-form-item>
  110. </div>
  111. <div style="width: 40%;text-align:right;margin-top: 2%;">
  112. <div>
  113. <el-button type="primary" @click="addBtn">保存</el-button>
  114. <el-button @click="back()">取消</el-button>
  115. </div>
  116. </div>
  117. </div>
  118. </el-form>
  119. </div>
  120. <div id="testTable">
  121. <el-table border :data="tableData" style="width: 100%">
  122. <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
  123. :width="column.width">
  124. <template slot-scope="scope">
  125. <el-input v-model="scope.row[column.prop]" :disabled="column.prop === 'id'"></el-input>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. </div>
  130. </div>
  131. </template>
  132. <script>
  133. export default {
  134. data() {
  135. return {
  136. title: "新增机票行程代码录入",
  137. token: '',
  138. userId: 0,
  139. id: '',
  140. DiId: '',
  141. isShow: false,
  142. delegationInfo: {},
  143. DelegationSelect: [],//团组下拉框
  144. airGroupCostParameter: {},//机票成本预算
  145. OpTicketBlackCodeData: {
  146. status: 0,
  147. id: 0,
  148. diId: 0,
  149. blackCode: '',
  150. price: '',
  151. nowPrice: '',
  152. bcPrice: '',
  153. ecPrice: '',
  154. createUserId: 0,
  155. remark: '',
  156. title: ''
  157. },
  158. OpTicketBlackCodeRules: {
  159. blackCode: [
  160. { required: true, message: '该信息为必填信息', trigger: ['blur', 'change'] },
  161. ],
  162. price: [
  163. { required: true, message: '该信息为必填信息', trigger: ['blur', 'change'] },
  164. ],
  165. nowPrice: [
  166. { required: true, message: '该信息为必填信息', trigger: ['blur', 'change'] },
  167. ],
  168. bcPrice: [
  169. { required: true, message: '请输入机票单价', trigger: ['blur', 'change'] },
  170. { pattern: /^(([1-9]?\d{0,8}(\.\d{1,2})?)|999999999|999999999\.(0){1,2})$/, message: '请输入正确的金额(最多2位小数)' }
  171. ],
  172. ecPrice: [
  173. { required: true, message: '请输入机票单价', trigger: ['blur', 'change'] },
  174. { pattern: /^(([1-9]?\d{0,8}(\.\d{1,2})?)|999999999|999999999\.(0){1,2})$/, message: '请输入正确的金额(最多2位小数)' }
  175. ],
  176. title: [
  177. { required: true, message: '该信息为必填信息', trigger: ['blur', 'change'] },
  178. ],
  179. },
  180. //-------------------------
  181. flightData: [
  182. {
  183. type: "经济现价",
  184. prices: {
  185. },
  186. total: 0
  187. },
  188. {
  189. type: "经济全价",
  190. prices: {
  191. },
  192. total: 0
  193. },
  194. {
  195. type: "公务现价",
  196. prices: {
  197. },
  198. total: 0
  199. },
  200. {
  201. type: "公务全价",
  202. prices: {
  203. },
  204. total: 0
  205. },
  206. {
  207. type: "头等现价",
  208. prices: {
  209. },
  210. total: 0
  211. },
  212. {
  213. type: "头等全价",
  214. prices: {
  215. },
  216. total: 0
  217. }
  218. ],
  219. tableData: [],
  220. columns: [
  221. ],
  222. PushColumns: [],
  223. fiexedColumns: [{ prop: 'type', label: '票价类型', width: 180 },
  224. { prop: 'total', label: '合计', width: 180 }],
  225. settingValue: {
  226. "经济现价": "price",
  227. "经济全价": "ecPrice",
  228. "公务现价": "nowPrice",
  229. "公务全价": "bcPrice",
  230. "头等现价": "fcNowPrice",
  231. "头等全价": "fcPrice"
  232. }
  233. }
  234. },
  235. methods: {
  236. //团组下拉框
  237. DelegationSelectFun() {
  238. var url = "/api/Business/GetGroupNameList"
  239. var that = this
  240. this.$axios({
  241. method: 'post',
  242. url: url,
  243. headers: {
  244. Authorization: 'Bearer ' + this.token
  245. },
  246. data: {
  247. "portType": 1,
  248. "pageIndex": 0,
  249. "pageSize": 0
  250. }
  251. }).then(function (res) {
  252. if (res.data.code == 200) {
  253. that.DelegationSelect = res.data.data;
  254. }
  255. })
  256. },
  257. QueryTicketBlackCodeById() {
  258. var url = "/api/Resource/QueryTicketBlackCodeById"
  259. var that = this
  260. this.$axios({
  261. method: 'post',
  262. url: url,
  263. headers: {
  264. Authorization: 'Bearer ' + this.token
  265. },
  266. data: {
  267. Id: that.id,
  268. DiId: that.DiId
  269. }
  270. }).then(function (res) {
  271. if (res.data.code == 200) {
  272. that.delegationInfo = res.data.data.delegationInfo;
  273. that.airGroupCostParameter = res.data.data.groupCostParameter;
  274. if (res.data.data.ticketBlackCode) {
  275. var TicketBlackCode = res.data.data.ticketBlackCode;
  276. that.OpTicketBlackCodeData.id = TicketBlackCode.id
  277. that.OpTicketBlackCodeData.diId = TicketBlackCode.diId
  278. that.OpTicketBlackCodeData.blackCode = TicketBlackCode.blackCode
  279. that.OpTicketBlackCodeData.price = TicketBlackCode.price
  280. that.OpTicketBlackCodeData.nowPrice = TicketBlackCode.nowPrice
  281. that.OpTicketBlackCodeData.bcPrice = TicketBlackCode.bcPrice
  282. that.OpTicketBlackCodeData.ecPrice = TicketBlackCode.ecPrice
  283. that.OpTicketBlackCodeData.remark = TicketBlackCode.remark
  284. that.OpTicketBlackCodeData.title = TicketBlackCode.title;
  285. for (var key in that.settingValue) {
  286. that.flightData.filter(item => item.type == key)[0].total = TicketBlackCode[that.settingValue[key]];
  287. }
  288. }
  289. }
  290. that.parseAirData();
  291. })
  292. },
  293. //跳转
  294. back() {
  295. this.$router.push({
  296. path: "/home/TicketBlackCode",
  297. query: {
  298. DiId: this.DiId,
  299. }
  300. })
  301. },
  302. //团组下拉框选择事件
  303. AirTicketResChange() {
  304. this.QueryTicketBlackCodeById()
  305. },
  306. //点击保存事件
  307. addBtn() {
  308. if (!this.DiId) {
  309. this.$message.error("请选择团组名称");
  310. return;
  311. }
  312. const that = this;
  313. that.$refs.OpTicketBlackCodeData.validate((valid) => {
  314. if (valid) {
  315. that.parseAirData();
  316. var url = "/api/Resource/OpTicketBlackCode"
  317. that.OpTicketBlackCodeData.createUserId = that.userId;
  318. that.OpTicketBlackCodeData.diId = that.DiId
  319. that.OpTicketBlackCodeData.price = that.OpTicketBlackCodeData.price.toString();
  320. that.OpTicketBlackCodeData.nowPrice = that.OpTicketBlackCodeData.nowPrice.toString();
  321. that.$axios({
  322. method: 'post',
  323. url: url,
  324. headers: {
  325. Authorization: 'Bearer ' + that.token
  326. },
  327. data: that.OpTicketBlackCodeData
  328. }).then(function (res) {
  329. if (res.data.code == 200) {
  330. that.$message({
  331. message: res.data.msg,
  332. type: 'success'
  333. });
  334. setTimeout(() => {
  335. that.back();
  336. // that.$router.push('/home/TicketBlackCode')
  337. }, 1000);
  338. } else {
  339. that.$message.error(res.data.msg);
  340. }
  341. })
  342. } else {
  343. this.$message.error('请完善信息在保存!');
  344. return false;
  345. }
  346. })
  347. },
  348. parseAirData() {
  349. var data = this.OpTicketBlackCodeData.blackCode;
  350. // 按行分割数据
  351. const lines = data.trim().split('\n');
  352. // 提取航司的函数
  353. function extractAirline(line) {
  354. // 使用正则表达式匹配航司代码(两个大写字母或一个大写字母加一个数字)
  355. const match = line.match(/[A-Z]{2}|[A-Z]\d/);
  356. return match ? match[0] : null;
  357. }
  358. // 解析每一行并提取航司
  359. var flightNumbers = lines.map(line => {
  360. // 使用正则表达式匹配航班号(假设航班号是字母+数字的组合)
  361. const match = line.match(/[A-Z]{2}\d+/);
  362. console.log(match, "match ");
  363. return match ? match[0] : null;
  364. });
  365. flightNumbers = flightNumbers.filter(item => item);
  366. //console.log(flightNumbers, "flightNumbers ");
  367. this.PushColumns = flightNumbers.map(flightNumber => {
  368. return {
  369. prop: flightNumber,
  370. label: flightNumber,
  371. width: 100
  372. }
  373. })
  374. // {
  375. // type: "公务全价",
  376. // prices: {
  377. // FM: 55320,
  378. // EK: 22883,
  379. // "3U": 33608
  380. // },
  381. // total: 111811
  382. // }
  383. var that = this;
  384. //console.log(this.tableData, "this.tableData ");
  385. this.tableData.forEach(item => {
  386. that.flightData.forEach(flight => {
  387. if (flight.type == item.type) {
  388. var columns = that.PushColumns.map(x => x.prop);
  389. for (var i = 0; i < columns.length; i++) {
  390. flight.prices[columns[i]] = item[columns[i]];
  391. }
  392. }
  393. })
  394. for (var key in that.settingValue) {
  395. if (item.type == key) {
  396. that.OpTicketBlackCodeData[that.settingValue[key]] = Number(item.total);
  397. break;
  398. }
  399. }
  400. })
  401. this.flightData.forEach(item => {
  402. //遍历item.prices
  403. for (var key in item.prices) {
  404. //判断key是否存在that.PushColumns中
  405. var isExist = false;
  406. for (var i = 0; i < that.PushColumns.length; i++) {
  407. if (that.PushColumns[i].prop == key) {
  408. isExist = true;
  409. break;
  410. }
  411. }
  412. //不存在就删除item.prices中的key
  413. if (!isExist) {
  414. delete item.prices[key];
  415. }
  416. }
  417. that.PushColumns.forEach(column => {
  418. //判断item.prices中是否存在column.prop
  419. if (item.prices[column.prop]) {
  420. return;
  421. } else {
  422. item.prices[column.prop] = 0;
  423. }
  424. })
  425. })
  426. console.log(this.flightData, "this.flightData ");
  427. console.log(this.columns, "this.columns ");
  428. this.transformData();
  429. },
  430. //----------------------
  431. transformData() {
  432. this.columns = [];
  433. this.columns.push(...this.fiexedColumns);
  434. this.columns.splice(1, 0, ...this.PushColumns);
  435. this.tableData = [];
  436. this.tableData = this.flightData.map(item => {
  437. const tableItem = { type: item.type, total: item.total };
  438. for (let column of this.columns) {
  439. if (column.prop !== 'type' && column.prop !== 'total') {
  440. tableItem[column.prop] = item.prices[column.prop];
  441. }
  442. }
  443. return tableItem;
  444. });
  445. },
  446. },
  447. mounted() {
  448. this.token = JSON.parse(localStorage.getItem('userinif')).token;
  449. this.userId = JSON.parse(localStorage.getItem('userinif')).userInfo.userId
  450. this.id = this.$route.query.id
  451. this.DiId = parseInt(this.$route.query.DiId)
  452. this.DelegationSelectFun()
  453. var that = this
  454. if (that.DiId && that.id) {
  455. that.OpTicketBlackCodeData.status = 2;
  456. that.isShow = true
  457. } else {
  458. that.isShow = false
  459. that.OpTicketBlackCodeData.status = 1;
  460. }
  461. that.QueryTicketBlackCodeById();
  462. //-------
  463. //this.transformData();
  464. }
  465. }
  466. </script>
  467. <style>
  468. .communal-list {
  469. background-color: #fff;
  470. padding: 10px;
  471. box-shadow: 0 0 5px #0005;
  472. border-radius: 10px;
  473. }
  474. .car_add .communal-title {
  475. display: flex;
  476. font-size: 17px;
  477. font-weight: 600;
  478. color: #555;
  479. margin-bottom: 20px;
  480. justify-content: space-between;
  481. align-items: center;
  482. }
  483. .appraise-box {
  484. display: flex;
  485. flex-wrap: wrap;
  486. justify-content: space-between;
  487. margin: 50px 0;
  488. }
  489. .appraise-box>div {
  490. width: 30%;
  491. }
  492. .communal-box {
  493. display: flex;
  494. }
  495. .communal-box>button {
  496. margin-left: 10px;
  497. padding: 8px 20px;
  498. }
  499. .car_add {
  500. background-color: #fff;
  501. padding: 20px;
  502. box-shadow: 0 0 5px #0005;
  503. border-radius: 10px;
  504. }
  505. @media screen and (max-width: 1700px) {
  506. .appraise-box>div {
  507. width: 48%;
  508. }
  509. .appraise-box>div el-form-item__content {
  510. width: 260px !important;
  511. }
  512. }
  513. </style>