酒店预订平台
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.
 
 
 
 
 
 

618 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. shortcuts: [{
  388. text: '今天',
  389. onClick(picker) {
  390. picker.$emit('pick', new Date());
  391. }
  392. }, {
  393. text: '昨天',
  394. onClick(picker) {
  395. const date = new Date();
  396. date.setTime(date.getTime() - 3600 * 1000 * 24);
  397. picker.$emit('pick', date);
  398. }
  399. }, {
  400. text: '一周前',
  401. onClick(picker) {
  402. const date = new Date();
  403. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
  404. picker.$emit('pick', date);
  405. }
  406. }]
  407. },
  408. }
  409. },
  410. created() {
  411. window.addEventListener("message", e => {
  412. this.editShow = false
  413. this.addShow = false
  414. this.getData(1)
  415. });
  416. this.getSupplierList()
  417. this.getAdminUser();
  418. this.getChannelList();
  419. this.getProvince();
  420. this.getConfig()
  421. this.getData(1)
  422. },
  423. watch: {
  424. "search.province" : function (newVal,oldVal){
  425. this.city = []
  426. this.area = []
  427. this.search.city=""
  428. this.search.area=""
  429. if (newVal==''){
  430. return false;
  431. }
  432. let row = {
  433. "province":newVal
  434. }
  435. axios.post("/hotel.php/ajax/areaList", row).then((response) => {
  436. let data = response.data;
  437. if (data.flag) {
  438. this.city = data.data;
  439. } else {
  440. this.$message.error(data.msg);
  441. }
  442. }).catch(function (error) {
  443. console.log(error);
  444. });
  445. },
  446. "search.city" : function (newVal,oldVal){
  447. this.area = []
  448. this.search.area=""
  449. if (newVal == "") {
  450. return false;
  451. }
  452. let row = {
  453. province:this.search.province,
  454. city:newVal
  455. }
  456. axios.post("/hotel.php/ajax/areaList", row).then((response) => {
  457. let data = response.data;
  458. if (data.flag) {
  459. this.area = data.data;
  460. } else {
  461. this.$message.error(data.msg);
  462. }
  463. }).catch(function (error) {
  464. console.log(error);
  465. });
  466. },
  467. },
  468. methods: {
  469. getSupplierList(){
  470. axios.post("/hotel.php/cf_suplier_info/getList", this.search).then((response) => {
  471. console.log(response)
  472. let data = response.data;
  473. this.supplierList = data.list;
  474. }).catch(function (error) {
  475. console.log(error);
  476. });
  477. },
  478. getTypeName(info) {
  479. for (let i = 0; i < this.type_list.length; i++) {
  480. if (this.type_list[i].id == info.item_type) {
  481. return this.type_list[i].name
  482. }
  483. }
  484. return ""
  485. },
  486. getConfig(){
  487. axios.post("/hotel.php/general/config/getList?key=site.item_category", {}).then((response) => {
  488. let data = response.data;
  489. this.type_list = data.list;
  490. }).catch(function (error) {
  491. console.log(error);
  492. });
  493. },
  494. paymentOrderStatus(info){
  495. if (info.payment_order_id ==0) {
  496. return "-"
  497. }
  498. for (let i = 0; i < this.paymentOrderStatusList.length; i++) {
  499. if (this.paymentOrderStatusList[i].id == info.payment_order_status) {
  500. return this.paymentOrderStatusList[i].value
  501. }
  502. }
  503. return "-"
  504. },
  505. confirmStatusName(info){
  506. for (let i = 0; i < this.confirmStatusList.length; i++) {
  507. if (this.confirmStatusList[i].id == info.confirm_status) {
  508. return this.confirmStatusList[i].name
  509. }
  510. }
  511. return "-"
  512. },
  513. getReceiptOrderStatus(info){
  514. for (let i = 0; i < this.receiptStatus.length; i++) {
  515. if (this.receiptStatus[i].id == info.receipt_order_status) {
  516. return this.receiptStatus[i].name
  517. }
  518. }
  519. return "-"
  520. },
  521. getChannelList(){
  522. axios.post("/hotel.php/cf_channel_info/getList", this.search).then((response) => {
  523. console.log(response)
  524. let data = response.data;
  525. this.channelList = data.list;
  526. }).catch(function (error) {
  527. console.log(error);
  528. });
  529. },
  530. getUserName(info) {
  531. for (let i = 0; i < this.userList.length; i++) {
  532. if (this.userList[i].id == info.create_id) {
  533. return this.userList[i].name
  534. }
  535. }
  536. return "-"
  537. },
  538. getOrderMainStatus(info){
  539. for (let i = 0; i < this.orderMainStatus.length; i++) {
  540. if (this.orderMainStatus[i].id == info.order_status) {
  541. return this.orderMainStatus[i].name
  542. }
  543. }
  544. return "-"
  545. },
  546. getAdminUser() {
  547. axios.post("/hotel.php/auth/admin/getList", this.search).then((response) => {
  548. this.userList = response.data.list;
  549. }).catch(function (error) {
  550. console.log(error);
  551. });
  552. },
  553. getProvince(){
  554. axios.post("/hotel.php/ajax/areaList", {}).then((response) => {
  555. let data = response.data;
  556. if (data.flag) {
  557. this.province = data.data;
  558. } else {
  559. this.$message.error(data.msg);
  560. }
  561. }).catch(function (error) {
  562. console.log(error);
  563. });
  564. },
  565. sizeChange(pageSize) {
  566. this.search.pageSize = pageSize;
  567. this.getData(this.search.pageNum)
  568. },
  569. edit(id){
  570. this.editPageShowUrl="/view/order_main/edit.html?id="+id+"&rd="+Math.random();
  571. this.editShow=true;
  572. },
  573. //獲取列表
  574. getData(page) {
  575. this.search.pageNum = page;
  576. axios.post("/hotel.php/order_main/getOrderList", this.search).then((response) => {
  577. let data = response.data;
  578. if (data.flag) {
  579. this.tableData = data.data.list;
  580. this.total = data.data.total;
  581. } else {
  582. this.$message.error(response.msg);
  583. }
  584. }).catch(function (error) {
  585. console.log(error);
  586. });
  587. },
  588. }
  589. })
  590. </script>
  591. <style lang="scss" scoped>
  592. .el-table thead {
  593. background-color: #5a5e66 !important;
  594. }
  595. .header-search {
  596. font-size: 14px;
  597. font-weight: 900;
  598. }
  599. body {
  600. background-color: white;
  601. }
  602. .table {
  603. width: 100%;
  604. font-size: 12px;
  605. margin-top: 12px;
  606. background-color: white;
  607. }
  608. .el-form-item{
  609. margin-bottom: 5px !important;
  610. }
  611. </style>
  612. </html>