酒店预订平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

621 lines
28 KiB

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <!-- import CSS -->
  6. <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  7. </head>
  8. <body>
  9. <div id="app" class="table">
  10. <div>
  11. <div class="header-search" style="width: 100%;margin-bottom: 10px">
  12. <span>订单ID:</span>
  13. <el-input v-model="search.order_id" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  14. <span>订单状态:</span>
  15. <el-select v-model="search.order_status" style="width: 150px;" placeholder="请选择" clearable>
  16. <el-option
  17. v-for="item in orderMainStatus"
  18. :key="item.id"
  19. :label="item.name"
  20. :value="item.id">
  21. </el-option>
  22. </el-select>
  23. <span>收款单ID:</span>
  24. <el-input v-model="search.receipt_order_id" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  25. <span>收款单状态</span>
  26. <el-select v-model="search.receipt_order_status" style="width: 150px;" placeholder="请选择" clearable>
  27. <el-option
  28. v-for="item in receiptStatus"
  29. :key="item.id"
  30. :label="item.name"
  31. :value="item.id">
  32. </el-option>
  33. </el-select>
  34. <span>用户名</span>
  35. <el-input v-model="search.user_name" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  36. <span>手机号</span>
  37. <el-input v-model="search.user_phone" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  38. </div>
  39. <div class="header-search" style="width: 100%;margin-bottom: 10px">
  40. <span>渠道订单号:</span>
  41. <el-input v-model="search.channel_order_no" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  42. <span>渠道:</span>
  43. <el-select v-model="search.channel_id" style="width: 150px;" placeholder="请选择" clearable>
  44. <el-option
  45. v-for="item in channelList"
  46. :key="item.id"
  47. :label="item.name"
  48. :value="item.id">
  49. </el-option>
  50. </el-select>
  51. <span>专员</span>
  52. <el-select v-model="search.commissioner_id" style="width: 150px;" placeholder="请选择" clearable>
  53. <el-option
  54. v-for="item in userList"
  55. :key="item.id"
  56. :label="item.name"
  57. :value="item.id">
  58. </el-option>
  59. </el-select>
  60. <span>下单人</span>
  61. <el-select v-model="search.create_id" style="width: 150px;" placeholder="请选择" clearable>
  62. <el-option
  63. v-for="item in userList"
  64. :key="item.id"
  65. :label="item.name"
  66. :value="item.id">
  67. </el-option>
  68. </el-select>
  69. <span>时间</span>
  70. <el-date-picker
  71. style="width: 150px;"
  72. v-model="search.startTime"
  73. type="date"
  74. value-format="yyyy-MM-dd"
  75. :picker-options="pickerOptions"
  76. placeholder="选择日期">
  77. </el-date-picker>
  78. ~
  79. <el-date-picker
  80. style="width: 150px;"
  81. v-model="search.endTime"
  82. value-format="yyyy-MM-dd"
  83. type="date"
  84. :picker-options="pickerOptions"
  85. placeholder="选择日期">
  86. </el-date-picker>
  87. </div>
  88. <div class="header-search" style="width: 100%;margin-bottom: 10px">
  89. <span>金额</span>
  90. <el-input-number v-model="search.startMoney" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  91. ~
  92. <el-input-number v-model="search.endMoney" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  93. <span>成本</span>
  94. <el-input-number v-model="search.startCost" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  95. ~
  96. <el-input-number v-model="search.endCost" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  97. <span>利润</span>
  98. <el-input-number v-model="search.startProfit" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  99. ~
  100. <el-input-number v-model="search.endProfit" style="width: 170px;" placeholder="请输入内容" clearable></el-input-number>
  101. </div>
  102. <div class="header-search" style="width: 100%;margin-bottom: 10px">
  103. <span>出游人:</span>
  104. <el-input v-model="search.customer_name" style="width: 150px;" placeholder="请输入内容" clearable></el-input>
  105. <span>供应商</span>
  106. <el-select v-model="search.supplier_id" style="width: 150px;" placeholder="请选择" clearable>
  107. <el-option
  108. v-for="item in supplierList"
  109. :key="item.id"
  110. :label="item.name"
  111. :value="item.id">
  112. </el-option>
  113. </el-select>
  114. <span>入住时间</span>
  115. <el-date-picker
  116. style="width: 150px;"
  117. v-model="search.startInDate"
  118. type="date"
  119. value-format="yyyy-MM-dd"
  120. :picker-options="pickerOptions"
  121. placeholder="选择日期">
  122. </el-date-picker>
  123. ~
  124. <el-date-picker
  125. style="width: 150px;"
  126. v-model="search.endInDate"
  127. value-format="yyyy-MM-dd"
  128. type="date"
  129. :picker-options="pickerOptions"
  130. placeholder="选择日期">
  131. </el-date-picker>
  132. <span>离店时间</span>
  133. <el-date-picker
  134. style="width: 150px;"
  135. v-model="search.startOutDate"
  136. type="date"
  137. value-format="yyyy-MM-dd"
  138. :picker-options="pickerOptions"
  139. placeholder="选择日期">
  140. </el-date-picker>
  141. ~
  142. <el-date-picker
  143. style="width: 150px;"
  144. v-model="search.endOutDate"
  145. value-format="yyyy-MM-dd"
  146. type="date"
  147. :picker-options="pickerOptions"
  148. placeholder="选择日期">
  149. </el-date-picker>
  150. <el-button type="primary" icon="el-icon-search" @click="getData(1)">搜索</el-button>
  151. <el-button type="primary" icon="el-icon-plus" @click="addShow=true" >新增</el-button>
  152. </div>
  153. <el-table ref="multipleTable" :data="tableData" border tooltip-effect="dark"
  154. style="font-size:12px;width: 100%;margin-top: 12px">
  155. <el-table-column prop="id" label="订单ID" min-width="30" ></el-table-column>
  156. <el-table-column prop="commissioner" label="专员" min-width="40" ></el-table-column>
  157. <el-table-column prop="channel_order_no" label="渠道" min-width="120" >
  158. <template slot-scope="scope">
  159. <div><i class="el-icon-user" v-html="scope.row.channel_name"></i></div>
  160. <div><i class="el-icon-tickets" v-html="scope.row.channel_order_no"></i></div>
  161. </template>
  162. </el-table-column>
  163. <el-table-column prop="create_id" label="下单人" min-width="50" :formatter="getUserName"></el-table-column>
  164. <el-table-column prop="user_name" label="用户" min-width="80" >
  165. <template slot-scope="scope">
  166. <div><i class="el-icon-user-solid" v-html="scope.row.user_name"></i></div>
  167. <div><i class="el-icon-phone" v-html="scope.row.user_phone"></i></div>
  168. </template>
  169. </el-table-column>
  170. <el-table-column prop="total_amount" label="金额" min-width="80" >
  171. <template slot-scope="scope">
  172. <div v-html="'金额:'+scope.row.total_amount"></div>
  173. <div v-html="'成本:'+scope.row.cost_amount"></div>
  174. <div v-if="scope.row.profit_amount>0" v-html="'利润:'+scope.row.profit_amount"></div>
  175. <div v-if="scope.row.profit_amount<=0" v-html="'利润:'+scope.row.profit_amount" style="color: red"></div>
  176. </template>
  177. </el-table-column>
  178. <el-table-column prop="order_status" label="状态" min-width="40" :formatter="getOrderMainStatus"></el-table-column>
  179. <el-table-column prop="create_time" label="时间" min-width="100" >
  180. <template slot-scope="scope">
  181. <div ><i v-html="'下单:'+scope.row.create_time"></i></div>
  182. <div v-if="scope.row.success_time"><i v-html="'成功:'+scope.row.success_time"></i></div>
  183. <div v-if="scope.row.cancel_time"><i v-html="'取消:'+scope.row.cancel_time"></i></div>
  184. </template>
  185. </el-table-column>
  186. <el-table-column prop="receipt_order_name" label="收款单" min-width="100" >
  187. <template slot-scope="scope">
  188. <div v-if="scope.row.receipt_order_id!=0">
  189. <div v-html="'ID:'+scope.row.receipt_order_id"></div>
  190. <div v-html="'NAME:'+scope.row.receipt_order_name"></div>
  191. <div v-html="'状态:'+getReceiptOrderStatus(scope.row)" ></div>
  192. </div>
  193. </template>
  194. </el-table-column>
  195. <el-table-column label="子订单" type="expand">
  196. <template slot-scope="scope">
  197. <el-table ref="multipleTable" :data="scope.row.subOrder" border tooltip-effect="dark"
  198. style="font-size:12px;width: 94%;margin-left: 2%;margin-right: 4%">
  199. <el-table-column prop="id" label="订单ID" min-width="30" ></el-table-column>
  200. <el-table-column prop="type" label="类型" min-width="30" ></el-table-column>
  201. <el-table-column label="名称" min-width="80" >
  202. <template slot-scope="prop">
  203. <div v-if="prop.row.type=='酒店'" v-html="prop.row.hotel_name"></div>
  204. <div v-if="prop.row.type=='附加项目'" v-html="prop.row.item_name"></div>
  205. </template>
  206. </el-table-column>
  207. <el-table-column label="房型/项目类型" min-width="80" >
  208. <template slot-scope="prop">
  209. <div v-if="prop.row.type=='酒店'" v-html="prop.row.room_name"></div>
  210. <div v-if="prop.row.type=='附加项目'" v-html="getTypeName(prop.row)"></div>
  211. </template>
  212. </el-table-column>
  213. <el-table-column prop="id" label="时间" min-width="40" >
  214. <template slot-scope="prop">
  215. <div v-if="prop.row.type=='酒店'" >
  216. <div v-html="prop.row.check_in_date"></div>
  217. <div v-html="prop.row.check_out_date"></div>
  218. </div>
  219. <div v-if="prop.row.type=='附加项目'" v-html="prop.row.check_in_date"></div>
  220. </template>
  221. </el-table-column>
  222. <el-table-column prop="prod_num" label="数量" min-width="20" ></el-table-column>
  223. <el-table-column prop="customer_name" label="出游人姓名" min-width="40" ></el-table-column>
  224. <el-table-column prop="total_price" label="金额" min-width="30" ></el-table-column>
  225. <el-table-column prop="total_cost" label="成本" min-width="30" ></el-table-column>
  226. <el-table-column prop="profit" label="利润" min-width="30" >
  227. <template slot-scope="scope">
  228. <div v-if="scope.row.profit>0" v-html="scope.row.profit"></div>
  229. <div v-if="scope.row.profit<=0" v-html="scope.row.profit" style="color: red"></div>
  230. </template>
  231. </el-table-column>
  232. <el-table-column prop="supplier_name" label="供应商" min-width="30" ></el-table-column>
  233. <el-table-column label="发单状态" min-width="30" :formatter="confirmStatusName"></el-table-column>
  234. <el-table-column prop="payment_order_name" label="付款单" min-width="40" >
  235. <template slot-scope="scope">
  236. <div v-if="scope.row.payment_order_id" v-html="scope.row.payment_order_id"></div>
  237. <div v-if="scope.row.payment_order_id" v-html="scope.row.payment_order_name"></div>
  238. </template>
  239. </el-table-column>
  240. <el-table-column label="付款单状态" min-width="40" :formatter="paymentOrderStatus" ></el-table-column>
  241. </el-table>
  242. </template>
  243. </el-table-column>
  244. <el-table-column prop="receipt_order_name" label="备注" min-width="80" >
  245. <template slot-scope="scope">
  246. <el-popover
  247. placement="top-start"
  248. title=""
  249. width="200"
  250. trigger="hover"
  251. :content="scope.row.order_memo">
  252. <div slot="reference" v-html="scope.row.order_memo" style="overflow:hidden;white-space: nowrap;"></div>
  253. </el-popover>
  254. </template>
  255. </el-table-column>
  256. <el-table-column label="操作" min-width="70">
  257. <template slot-scope="scope">
  258. <el-button-group>
  259. <el-button type="primary" size="mini" @click="edit(scope.row.id)" icon="el-icon-edit">编辑</el-button>
  260. </el-button-group>
  261. </template>
  262. </el-table-column>
  263. </el-table>
  264. <el-pagination
  265. :page-size="search.pageSize"
  266. :pager-count="11"
  267. layout="total, sizes, prev, pager, next, jumper"
  268. :total="total"
  269. :current-page="search.pageNum"
  270. :page-sizes="[10, 20, 30, 40, 50]"
  271. @size-change="sizeChange"
  272. @current-change="getData"
  273. @prev-click="getData"
  274. @next-click="getData"
  275. ></el-pagination>
  276. </div>
  277. <transition name="bounce" v-if="addShow">
  278. <el-dialog title="新增订单" :visible.sync="addShow" width="90%" height="100%" top="15px">
  279. <iframe :src="'/view/order_main/add.html?rd='+Math.random()" frameborder="0" width="99%" id="addPageShow" onload="this.height=100"></iframe>
  280. </el-dialog>
  281. </transition>
  282. <transition name="bounce" v-if="editShow">
  283. <el-dialog title="编辑订单" :visible.sync="editShow" width="90%" height="100%" top="15px">
  284. <iframe :src="editPageShowUrl" frameborder="0" width="99%" id="editPageShow" onload="this.height=100"></iframe>
  285. </el-dialog>
  286. </transition>
  287. </div>
  288. </body>
  289. <!-- import Vue before Element -->
  290. <script src="/assets/js/vue/vue.js"></script>
  291. <!-- import JavaScript -->
  292. <script src="/assets/js/vue/index.js"></script>
  293. <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  294. <script type="text/javascript">
  295. function reinitIframe(){
  296. try{
  297. var iframe = document.getElementById("addPageShow");
  298. var bHeight = iframe.contentWindow.document.body.scrollHeight;
  299. var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
  300. var height = Math.max(bHeight, dHeight);
  301. iframe.height = height;
  302. console.log(height);
  303. }catch (ex){}
  304. try{
  305. var iframe1 = document.getElementById("editPageShow");
  306. var bHeight1 = iframe1.contentWindow.document.body.scrollHeight;
  307. var dHeight1 = iframe1.contentWindow.document.documentElement.scrollHeight;
  308. var height1 = Math.max(bHeight1, dHeight1);
  309. iframe1.height = height1;
  310. console.log(height1);
  311. }catch (ex){}
  312. }
  313. window.setInterval("reinitIframe()", 200);
  314. </script>
  315. <script>
  316. new Vue({
  317. el: '#app',
  318. data: function () {
  319. return {
  320. search: {
  321. "receipt_order_id":"",
  322. "receipt_order_status":"",
  323. "order_id":"",
  324. "channel_order_no":"",
  325. "channel_id":"",
  326. "order_status":"",
  327. "commissioner_id":"",
  328. "user_name":"",
  329. "user_phone":"",
  330. "create_id":"",
  331. "startMoney":"",
  332. "endMoney":"",
  333. "startCost":"",
  334. "endCost":"",
  335. "startProfit":"",
  336. "endProfit":"",
  337. "startTime":"",
  338. "endTime":"",
  339. "pageNum":1,
  340. "pageSize":10,
  341. "customer_name":"",
  342. "startInDate":"",
  343. "endInDate":"",
  344. "startOutDate":"",
  345. "endOutDate":""
  346. },
  347. total: 0,
  348. tableData: [],
  349. province: [],
  350. city: [],
  351. area:[],
  352. editShow:false,
  353. editPageShowUrl:"",
  354. addShow:false,
  355. //收款单状态 0:未收款 1:收款中 2已收款
  356. receiptStatus:[
  357. {id:0,name:"未收款"},
  358. {id:1,name:"收款中"},
  359. {id:2,name:"已收款"},
  360. ],
  361. //0待处理 1已确认 2部分取消 10已完成 11已取消
  362. orderMainStatus:[
  363. {id:0,name:"待处理"},
  364. {id:1,name:"已确认"},
  365. {id:2,name:"部分取消"},
  366. {id:3,name:"处理中"},
  367. {id:10,name:"已完成"},
  368. {id:11,name:"已取消"}
  369. ],
  370. userList: [],
  371. channelList:[],
  372. multipleSelection: [],
  373. confirmStatusList:[
  374. {id:1,name:"未发单"},
  375. {id:2,name:"已发单"},
  376. {id:3,name:"已确认"},
  377. {id:4,name:"已取消"}
  378. ],
  379. paymentOrderStatusList:[
  380. {"id": 0, 'value': "未付款"},
  381. {"id": 1, 'value': "付款中"},
  382. {"id": 2, 'value': "已付款"}
  383. ],
  384. type_list:[],
  385. supplierList:[],
  386. pickerOptions: {
  387. disabledDate(time) {
  388. return time.getTime() > Date.now();
  389. },
  390. shortcuts: [{
  391. text: '今天',
  392. onClick(picker) {
  393. picker.$emit('pick', new Date());
  394. }
  395. }, {
  396. text: '昨天',
  397. onClick(picker) {
  398. const date = new Date();
  399. date.setTime(date.getTime() - 3600 * 1000 * 24);
  400. picker.$emit('pick', date);
  401. }
  402. }, {
  403. text: '一周前',
  404. onClick(picker) {
  405. const date = new Date();
  406. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
  407. picker.$emit('pick', date);
  408. }
  409. }]
  410. },
  411. }
  412. },
  413. created() {
  414. window.addEventListener("message", e => {
  415. this.editShow = false
  416. this.addShow = false
  417. this.getData(1)
  418. });
  419. this.getSupplierList()
  420. this.getAdminUser();
  421. this.getChannelList();
  422. this.getProvince();
  423. this.getConfig()
  424. this.getData(1)
  425. },
  426. watch: {
  427. "search.province" : function (newVal,oldVal){
  428. this.city = []
  429. this.area = []
  430. this.search.city=""
  431. this.search.area=""
  432. if (newVal==''){
  433. return false;
  434. }
  435. let row = {
  436. "province":newVal
  437. }
  438. axios.post("/hotel.php/ajax/areaList", row).then((response) => {
  439. let data = response.data;
  440. if (data.flag) {
  441. this.city = data.data;
  442. } else {
  443. this.$message.error(data.msg);
  444. }
  445. }).catch(function (error) {
  446. console.log(error);
  447. });
  448. },
  449. "search.city" : function (newVal,oldVal){
  450. this.area = []
  451. this.search.area=""
  452. if (newVal == "") {
  453. return false;
  454. }
  455. let row = {
  456. province:this.search.province,
  457. city:newVal
  458. }
  459. axios.post("/hotel.php/ajax/areaList", row).then((response) => {
  460. let data = response.data;
  461. if (data.flag) {
  462. this.area = data.data;
  463. } else {
  464. this.$message.error(data.msg);
  465. }
  466. }).catch(function (error) {
  467. console.log(error);
  468. });
  469. },
  470. },
  471. methods: {
  472. getSupplierList(){
  473. axios.post("/hotel.php/cf_suplier_info/getList", this.search).then((response) => {
  474. console.log(response)
  475. let data = response.data;
  476. this.supplierList = data.list;
  477. }).catch(function (error) {
  478. console.log(error);
  479. });
  480. },
  481. getTypeName(info) {
  482. for (let i = 0; i < this.type_list.length; i++) {
  483. if (this.type_list[i].id == info.item_type) {
  484. return this.type_list[i].name
  485. }
  486. }
  487. return ""
  488. },
  489. getConfig(){
  490. axios.post("/hotel.php/general/config/getList?key=site.item_category", {}).then((response) => {
  491. let data = response.data;
  492. this.type_list = data.list;
  493. }).catch(function (error) {
  494. console.log(error);
  495. });
  496. },
  497. paymentOrderStatus(info){
  498. if (info.payment_order_id ==0) {
  499. return "-"
  500. }
  501. for (let i = 0; i < this.paymentOrderStatusList.length; i++) {
  502. if (this.paymentOrderStatusList[i].id == info.payment_order_status) {
  503. return this.paymentOrderStatusList[i].value
  504. }
  505. }
  506. return "-"
  507. },
  508. confirmStatusName(info){
  509. for (let i = 0; i < this.confirmStatusList.length; i++) {
  510. if (this.confirmStatusList[i].id == info.confirm_status) {
  511. return this.confirmStatusList[i].name
  512. }
  513. }
  514. return "-"
  515. },
  516. getReceiptOrderStatus(info){
  517. for (let i = 0; i < this.receiptStatus.length; i++) {
  518. if (this.receiptStatus[i].id == info.receipt_order_status) {
  519. return this.receiptStatus[i].name
  520. }
  521. }
  522. return "-"
  523. },
  524. getChannelList(){
  525. axios.post("/hotel.php/cf_channel_info/getList", this.search).then((response) => {
  526. console.log(response)
  527. let data = response.data;
  528. this.channelList = data.list;
  529. }).catch(function (error) {
  530. console.log(error);
  531. });
  532. },
  533. getUserName(info) {
  534. for (let i = 0; i < this.userList.length; i++) {
  535. if (this.userList[i].id == info.create_id) {
  536. return this.userList[i].name
  537. }
  538. }
  539. return "-"
  540. },
  541. getOrderMainStatus(info){
  542. for (let i = 0; i < this.orderMainStatus.length; i++) {
  543. if (this.orderMainStatus[i].id == info.order_status) {
  544. return this.orderMainStatus[i].name
  545. }
  546. }
  547. return "-"
  548. },
  549. getAdminUser() {
  550. axios.post("/hotel.php/auth/admin/getList", this.search).then((response) => {
  551. this.userList = response.data.list;
  552. }).catch(function (error) {
  553. console.log(error);
  554. });
  555. },
  556. getProvince(){
  557. axios.post("/hotel.php/ajax/areaList", {}).then((response) => {
  558. let data = response.data;
  559. if (data.flag) {
  560. this.province = data.data;
  561. } else {
  562. this.$message.error(data.msg);
  563. }
  564. }).catch(function (error) {
  565. console.log(error);
  566. });
  567. },
  568. sizeChange(pageSize) {
  569. this.search.pageSize = pageSize;
  570. this.getData(this.search.pageNum)
  571. },
  572. edit(id){
  573. this.editPageShowUrl="/view/order_main/edit.html?id="+id+"&rd="+Math.random();
  574. this.editShow=true;
  575. },
  576. //獲取列表
  577. getData(page) {
  578. this.search.pageNum = page;
  579. axios.post("/hotel.php/order_main/getOrderList", this.search).then((response) => {
  580. let data = response.data;
  581. if (data.flag) {
  582. this.tableData = data.data.list;
  583. this.total = data.data.total;
  584. } else {
  585. this.$message.error(response.msg);
  586. }
  587. }).catch(function (error) {
  588. console.log(error);
  589. });
  590. },
  591. }
  592. })
  593. </script>
  594. <style lang="scss" scoped>
  595. .el-table thead {
  596. background-color: #5a5e66 !important;
  597. }
  598. .header-search {
  599. font-size: 14px;
  600. font-weight: 900;
  601. }
  602. body {
  603. background-color: white;
  604. }
  605. .table {
  606. width: 100%;
  607. font-size: 12px;
  608. margin-top: 12px;
  609. background-color: white;
  610. }
  611. .el-form-item{
  612. margin-bottom: 5px !important;
  613. }
  614. </style>
  615. </html>