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

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