index.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. {extend name="app/shop/view/base.html"/}
  2. {block name="resources"}
  3. <link rel="stylesheet" href="ADDON_STORE_CSS/reserve_index.css">
  4. <style>
  5. .layui-layer-loading {
  6. box-shadow: unset!important;
  7. }
  8. .screen.reserve {
  9. padding: 0;
  10. margin-top: 20px;
  11. }
  12. {foreach name="reserve_state" item="vo"}
  13. .{$vo.state} {
  14. background-color: {$vo.color};
  15. border-color: {$vo.color};
  16. }
  17. .{$vo.state}-color {
  18. color: {$vo.color};
  19. }
  20. {/foreach}
  21. </style>
  22. {/block}
  23. {block name="main"}
  24. <div class="layui-card layui-form reserve-data">
  25. <div class="uni-flex panel-head">
  26. <button class="layui-btn" onclick="addReserve()">添加预约</button>
  27. <div class="status uni-flex">
  28. {foreach name="reserve_state" item="vo"}
  29. <div class="color {$vo.state}"></div>
  30. <div>{$vo.name}</div>
  31. {/foreach}
  32. </div>
  33. </div>
  34. <div class="screen reserve">
  35. <div class="layui-colla-item">
  36. <div class="layui-colla-content layui-form layui-show">
  37. <div class="layui-form-item">
  38. <div class="layui-inline">
  39. <label class="layui-form-label">客户:</label>
  40. <div class="layui-input-inline">
  41. <input type="text" name="search_text" placeholder="请输入客户名称/客户手机号" autocomplete="off" class="layui-input ">
  42. </div>
  43. </div>
  44. <div class="layui-inline">
  45. <label class="layui-form-label">预约门店:</label>
  46. <div class="layui-input-inline">
  47. <select name="store_id">
  48. <option value="">全部</option>
  49. {foreach $store_list as $k=> $v}
  50. <option value="{$v.store_id}">{$v.store_name}</option>
  51. {/foreach}
  52. </select>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="form-row">
  57. <button class="layui-btn bg-color" lay-submit lay-filter="search">筛选</button>
  58. <button type="reset" class="layui-btn layui-btn-primary">重置</button>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. <div class="panel-body">
  64. <!-- 看板类型 -->
  65. <!-- <div class="time-type">-->
  66. <!-- <span class="on" data-type="week">周</span>-->
  67. <!-- <span data-type="month">月</span>-->
  68. <!-- </div>-->
  69. <!-- 看板数据 -->
  70. <div class="time-data" id="time-data">
  71. <div class="uni-flex time-wrap">
  72. <span class="iconfont iconback_light" onclick="prevWeek()"></span>
  73. <div class="date">{$data[0]['date']} - {$data[6]['date']}</div>
  74. <span class="iconfont iconyoujiantou" onclick="nextWeek()"></span>
  75. </div>
  76. <div class="head uni-flex">
  77. {foreach name="$data" item="item"}
  78. <div>
  79. <button class="layui-btn {if $item.currday eq 0}layui-btn-primary{/if}">{$item.week}<span>{$item.date}</span></button>
  80. </div>
  81. {/foreach}
  82. </div>
  83. <div class="body uni-flex">
  84. {foreach name="$data" item="item"}
  85. <div class="common-scrollbar" data-page="1" data-total="{$item.data.page_count}" data-start="{$item.start}" data-end="{$item.end}">
  86. <div class="box">
  87. {notempty name="item.data.list"}
  88. {foreach name="item.data.list" item="vo"}
  89. <div class="panel-item {$vo.reserve_state}">
  90. <div class="username">{$vo.nickname}</div>
  91. <div class="time {$vo.reserve_state}">{:date('H:i', $vo.reserve_time)}</div>
  92. {php}
  93. $vo['reserve_item'] = explode(',', $vo['reserve_item']);
  94. {/php}
  95. {foreach name="$vo.reserve_item" item="goods_name"}
  96. <div class="service">{$goods_name}</div>
  97. {/foreach}
  98. <div class="action" data-state="{$vo.reserve_state}" data-id="{$vo.reserve_id}">
  99. <span class="iconfont iconyuandian"></span>
  100. </div>
  101. </div>
  102. {/foreach}
  103. {/notempty}
  104. </div>
  105. </div>
  106. {/foreach}
  107. </div>
  108. </div>
  109. </div>
  110. </div>
  111. {/block}
  112. {block name="script"}
  113. <!-- 周看板数据 -->
  114. <script type="text/html" id="dataTpl">
  115. <div class="uni-flex time-wrap">
  116. <span class="iconfont iconback_light" onclick="prevWeek()"></span>
  117. <div class="date">{{ d[0].date }} - {{ d[6].date }}</div>
  118. <span class="iconfont iconyoujiantou" onclick="nextWeek()"></span>
  119. </div>
  120. <div class="head uni-flex">
  121. {{# layui.each(d, function(index, item){ }}
  122. <div>
  123. <button class="layui-btn {{# if(item.currday == 0){ }}layui-btn-primary{{# } }}">{{ item.week }}<span>{{ item.date }}</span></button>
  124. </div>
  125. {{# }); }}
  126. </div>
  127. <div class="body uni-flex">
  128. {{# layui.each(d, function(index, item){ }}
  129. <div class="common-scrollbar" data-page="0" data-total="1" data-start="{{item.start}}" data-end="{{item.end}}">
  130. <div class="box"></div>
  131. </div>
  132. {{# }); }}
  133. </div>
  134. </script>
  135. <script type="text/html" id="reserveTpl">
  136. {{# layui.each(d, function(vindex, vo){ }}
  137. <div class="panel-item {{ vo.reserve_state }}">
  138. <div class="username">{{ vo.nickname }}</div>
  139. <div class="time {{ vo.reserve_state }}">{{ ns.time_to_date(vo.reserve_time, 'h:m') }}</div>
  140. {{# vo.reserve_item.split(',').forEach(function(goods_name){ }}
  141. <div class="service">{{ goods_name }}</div>
  142. {{# }); }}
  143. <div class="action" data-state="{{ vo.reserve_state }}" data-id="{{ vo.reserve_id }}">
  144. <span class="iconfont iconyuandian"></span>
  145. </div>
  146. </div>
  147. {{# }); }}
  148. </script>
  149. <!-- 月看板日期模板 -->
  150. <script type="text/html" id="month-table-tpl">
  151. <div class="uni-flex time-wrap">
  152. <span class="iconfont iconback_light" onclick="prevMonth()"></span>
  153. <div class="date">{{ data_year }}/{{ data_month < 10 ? '0' + data_month : data_month }}</div>
  154. <span class="iconfont iconyoujiantou" onclick="nextMonth()"></span>
  155. </div>
  156. <div class="month-table">
  157. <div class="table-head">
  158. <div class="table-tr">
  159. <div class="table-td">周一</div>
  160. <div class="table-td">周二</div>
  161. <div class="table-td">周三</div>
  162. <div class="table-td">周四</div>
  163. <div class="table-td">周五</div>
  164. <div class="table-td">周六</div>
  165. <div class="table-td">周日</div>
  166. </div>
  167. </div>
  168. <div class="table-body">
  169. {{# d.forEach(function(week_days, week_index){ }}
  170. <div class="table-tr">
  171. {{# week_days.forEach(function(item, index){ }}
  172. <div class="table-td {{ item.is_curr_month ? '' : 'not-curr-month' }}">
  173. <div class="top">{{ item.day }}</div>
  174. <div class="bottom" id="{{item.month}}_month_{{item.day}}_day">
  175. <!-- 每日数据 -->
  176. </div>
  177. </div>
  178. {{# }) }}
  179. </div>
  180. {{# }) }}
  181. </div>
  182. </div>
  183. </script>
  184. <!-- 月看板每日数据模板 -->
  185. <script type="text/html" id="month-table-td-tpl">
  186. {{# d.list.forEach(function(item, index){ }}
  187. <div class="item-box">
  188. <div class="item" data-reserve_id="{{ item.reserve_id }}">
  189. <span class="{{ item.reserve_state }}"></span>
  190. <span>{{ item.reserve_item }}</span>
  191. </div>
  192. <div class="detail-card">
  193. <div class="username">{{ item.nickname }}</div>
  194. <div class="time {{ item.reserve_state }}">{{ ns.time_to_date(item.reserve_time, 'h:m') }}</div>
  195. {{# item.reserve_item.split(',').forEach(function(goods_name){ }}
  196. <div class="service">{{ goods_name }}</div>
  197. {{# }); }}
  198. <div class="state {{ item.reserve_state }}-color">{{ item.reserve_state_name }}</div>
  199. </div>
  200. </div>
  201. {{# }) }}
  202. {{# if(d.count > d.list.length){ }}
  203. {{# let more_url = ns.url('store://shop/reserve/lists', {start_time:d.start_time, end_time:d.end_time}); }}
  204. <div class="more"><a href="{{ more_url }}" target="_blank">查看全部{{ d.count }}条预约 ></a></div>
  205. {{# } }}
  206. </script>
  207. {include file="reserve/reserve_action"}
  208. <script>
  209. layui.extend({
  210. dropdown: '__STATIC__/ext/layui/extend/dropdown/dropdown'
  211. });
  212. var dropdown, laytpl, form, _dropdown = {};
  213. var data_year = (new Date()).getFullYear();
  214. var data_month = (new Date()).getMonth() + 1;
  215. layui.use(['form', 'laytpl', 'dropdown'], function(){
  216. dropdown = layui.dropdown;
  217. laytpl = layui.laytpl;
  218. form = layui.form;
  219. init();
  220. /**
  221. * 搜索功能
  222. */
  223. form.on('submit(search)', function(data) {
  224. curr = 0;
  225. getWeekData();
  226. return false;
  227. });
  228. });
  229. // 触底加载
  230. $('.panel-body .common-scrollbar').scroll(function () {
  231. var top = $(this).scrollTop();
  232. var windowHeight = $(this).height();
  233. var documentHeight = $(this).find('.box').height();
  234. if (documentHeight - top - windowHeight < 20) {
  235. loadinfo($(this))
  236. }
  237. });
  238. function addReserve() {
  239. layer.open({
  240. title: '添加预约',
  241. type: 2,
  242. content: ns.url('store://shop/reserve/addreserve'),
  243. area: ['800px', '690px'],
  244. success: function () {
  245. }
  246. })
  247. }
  248. var curr = 0, repeat = false;
  249. function prevWeek() { curr -= 1; getWeekData(); }
  250. function nextWeek() { curr += 1; getWeekData(); }
  251. function getWeekData() {
  252. if (repeat) return;
  253. repeat = true;
  254. layer.load(3,{shade: [0.8, '#fff']});
  255. $.ajax({
  256. url: ns.url("store://shop/reserve/getweekday"),
  257. data: {
  258. length: curr
  259. },
  260. dataType: 'JSON',
  261. type: 'POST',
  262. success: function (res) {
  263. repeat = false;
  264. if (res.code == 0) {
  265. laytpl($('#dataTpl').html()).render(res.data, function(string){
  266. $('#time-data').html(string);
  267. layer.closeAll();
  268. $('.panel-body .common-scrollbar').scroll(function () {
  269. var top = $(this).scrollTop();
  270. var windowHeight = $(this).height();
  271. var documentHeight = $(this).find('.box').height();
  272. if (documentHeight - top - windowHeight < 20) {
  273. loadinfo($(this))
  274. }
  275. });
  276. $('.panel-body .common-scrollbar').each(function (index, item) {
  277. loadinfo($(item))
  278. })
  279. });
  280. } else {
  281. layer.msg('请求错误');
  282. }
  283. }
  284. });
  285. }
  286. function loadinfo(elem) {
  287. var page = parseInt(elem.attr('data-page')),
  288. total = elem.attr('data-total');
  289. if (page >= total) return;
  290. page += 1;
  291. $.ajax({
  292. url: ns.url("store://shop/reserve/lists"),
  293. data: {
  294. page: page,
  295. start_time: elem.attr('data-start'),
  296. end_time: elem.attr('data-end'),
  297. store_id: $('[name="store_id"]').val(),
  298. search_text: $('[name="search_text"]').val(),
  299. },
  300. dataType: 'JSON',
  301. type: 'POST',
  302. success: function (res) {
  303. if (res.code == 0 && res.data.list.length) {
  304. elem.attr('data-page', page);
  305. laytpl($('#reserveTpl').html()).render(res.data.list, function(string) {
  306. elem.find('.box').append(string);
  307. init();
  308. })
  309. }
  310. }
  311. });
  312. }
  313. function getMonthDays() {
  314. layer.load(3,{shade: [0.8, '#fff']});
  315. $.ajax({
  316. url: ns.url("store://shop/reserve/getMonthDays"),
  317. data: {
  318. year : data_year,
  319. month : data_month,
  320. },
  321. dataType: 'JSON',
  322. type: 'POST',
  323. success: function (res) {
  324. if (res.code == 0) {
  325. var month_data = [];
  326. var week_data = [];
  327. var month_day_num = res.data.length;
  328. res.data.forEach(function(item, index){
  329. week_data.push(item);
  330. if(week_data.length === 7 || index === month_day_num - 1){
  331. month_data.push(week_data);
  332. week_data = [];
  333. }
  334. });
  335. laytpl($('#month-table-tpl').html()).render(month_data, function(string){
  336. $("#time-data").html(string);
  337. layer.closeAll();
  338. res.data.forEach(function(item, index){
  339. getDayData(item);
  340. })
  341. });
  342. }
  343. }
  344. });
  345. }
  346. function getDayData(item) {
  347. $.ajax({
  348. url: ns.url("store://shop/reserve/lists"),
  349. data: {
  350. page: 1,
  351. page_size:3,
  352. start_time: ns.date_to_time(item.start_time),
  353. end_time: ns.date_to_time(item.end_time),
  354. store_id: $('[name="store_id"]').val(),
  355. search_text: $('[name="search_text"]').val(),
  356. },
  357. dataType: 'JSON',
  358. type: 'POST',
  359. success: function (res) {
  360. if (res.code == 0 && res.data.list.length) {
  361. res.data.start_time = item.start_time;
  362. res.data.end_time = item.end_time;
  363. laytpl($('#month-table-td-tpl').html()).render(res.data, function(string) {
  364. $(`#${item.month}_month_${item.day}_day`).html(string);
  365. init();
  366. })
  367. }
  368. }
  369. });
  370. }
  371. $("#time-data").on('click', '.table-td .bottom .item', function(){
  372. let reserve_id = $(this).attr('data-reserve_id');
  373. reserveEvent('detail', {reserve_id: reserve_id});
  374. });
  375. function prevMonth(){
  376. if(data_month > 1){
  377. data_month --;
  378. }else{
  379. data_month = 12;
  380. data_year --;
  381. }
  382. getMonthDays();
  383. }
  384. function nextMonth(){
  385. if(data_month < 12){
  386. data_month ++;
  387. }else{
  388. data_month = 1;
  389. data_year ++;
  390. }
  391. getMonthDays();
  392. }
  393. $(".time-type span").on('click', function(){
  394. $(this).addClass('on').siblings().removeClass('on');
  395. var type = $(this).attr('data-type');
  396. if(type === 'week'){
  397. curr = 0;
  398. getWeekData();
  399. }else{
  400. data_year = (new Date()).getFullYear();
  401. data_month = (new Date()).getMonth() + 1;
  402. getMonthDays();
  403. }
  404. });
  405. function init(){
  406. $('body .panel-item .action').each(function () {
  407. var state = $(this).attr('data-state');
  408. var reserveId = $(this).attr('data-id');
  409. var menuData = getMemuData(state);
  410. var elem = $(this);
  411. let id = $(elem).attr('id');
  412. if(id == '' || id == undefined){
  413. id = ns.gen_non_duplicate(5);
  414. $(elem).attr('id', id)
  415. }
  416. if (!_dropdown['reserve_id' + reserveId]) {
  417. dropdown.suite("#"+id, {
  418. menus: menuData,
  419. success: function ($dom) {
  420. },
  421. onItemClick: function (event, menu) {
  422. let data_id = $('#'+id).attr('data-id');
  423. reserveEvent(event, {reserve_id: data_id}, function (res) {
  424. getWeekData()
  425. });
  426. },
  427. });
  428. }
  429. })
  430. }
  431. </script>
  432. {/block}