edit.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-image');
  4. ComponentHelper::loadComponentView('com-qq-map');
  5. ?>
  6. <div id="app" v-cloak>
  7. <el-card shadow="never" style="border:0" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  8. <div slot="header">
  9. <div class="flex flex-x-between flex-y-center">
  10. <span>{{title}}</span>
  11. <div class='head-btns'>
  12. <el-button type="primary" @click='save'>保存</el-button>
  13. <el-button type="info" @click='back'>返回</el-button>
  14. </div>
  15. </div>
  16. </div>
  17. <div class="table-body">
  18. <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="150px" size="medium"
  19. label-position='left' class="demo-dynamic">
  20. <div class="basic_set">
  21. <div class="common_head flex flex-y-center">
  22. <div class='line'></div>
  23. <div>基本信息</div>
  24. </div>
  25. <div class='basic_body'>
  26. <el-form-item label="手机号:" prop="mobile" required>
  27. <div class="flex flex-y-center">
  28. <el-input v-model="ruleForm.mobile" placeholder="请输入手机号"
  29. @change="mobileChange" :disabled="isEdit"></el-input>
  30. </div>
  31. </el-form-item>
  32. <el-form-item label="用户昵称:" prop="nickname" required>
  33. <div class="flex flex-y-center">
  34. <el-input v-model="ruleForm.nickname" placeholder="请输入用户昵称"
  35. :disabled="isChangeUsername"></el-input>
  36. </div>
  37. </el-form-item>
  38. </div>
  39. <div class="common_head flex flex-y-center">
  40. <div class='line'></div>
  41. <div>预约信息</div>
  42. </div>
  43. <div class='basic_body'>
  44. <el-form-item label="服务和手艺人" prop="master" required>
  45. <el-table :data="ruleForm.master">
  46. <el-table-column prop="service" label="预约服务">
  47. <template slot-scope="scope">
  48. <el-select v-model="scope.row.sku_id" placeholder="请选择服务"
  49. @change="changeService" v-if="id==0">
  50. <el-option v-for="item in sku_list" :key="item.id" :label="item.goods_name" :value="item.id">
  51. </el-option>
  52. </el-select>
  53. <span v-if="id>0">{{goods_name}}</span>
  54. </template>
  55. </el-table-column>
  56. <el-table-column prop="master" label="技师">
  57. <!--需要选择完服务后再选择技师-->
  58. <template slot-scope="scope">
  59. <el-select v-model="scope.row.staff_user_id" placeholder="请选择技师"
  60. :disabled="scope.row.sku_id==0" @change="changeStaff">
  61. <el-option v-for="item in staff_user_list" :key="item.user_id" :label="item.name" :value="item.user_id">
  62. </el-option>
  63. </el-select>
  64. </template>
  65. </el-table-column>
  66. </el-table>
  67. <div v-show="serviceDuration" style="margin: 10px">项目时长:{{serviceDuration}}分钟</div>
  68. </el-form-item>
  69. <el-form-item label="预约到店时间:" prop="at_date" required>
  70. <div class="flex flex-y-center">
  71. <el-date-picker
  72. v-model="ruleForm.at_date"
  73. type="date"
  74. placeholder="选择日期"
  75. :picker-options="pickerOptionsData"
  76. @change="changeDay"
  77. >
  78. </el-date-picker>
  79. <el-time-picker
  80. v-model="ruleForm.at_time"
  81. :picker-options="{
  82. selectableRange: businessHours
  83. }"
  84. format="HH:mm"
  85. value-format="HH:mm"
  86. placeholder="选择时间"
  87. ></el-time-picker>
  88. </div>
  89. </el-form-item>
  90. <el-form-item label="服务类型:" >
  91. <el-select disabled style="width: 200px" v-model="ruleForm.service_type"
  92. placeholder="请选择服务类型" clearable
  93. v-if="isEdit ==true && secondary_card_id==0">
  94. <el-option key="1" label="上门服务" value="1"></el-option>
  95. <el-option key="2" label="到店服务" value="2"></el-option>
  96. </el-select>
  97. </el-form-item>
  98. </div>
  99. </div>
  100. </el-form>
  101. </div>
  102. </el-card>
  103. </div>
  104. <script>
  105. const app = new Vue({
  106. el: '#app',
  107. data() {
  108. return {
  109. title:'添加预约',
  110. store_name:'',
  111. sku_list:[],
  112. staff_user_list:[],
  113. activeName: '1',
  114. ruleForm: {
  115. mobile:'',
  116. nickname:'',
  117. at_date:'',
  118. at_time:'',
  119. goods_id:'',
  120. staff_user_id:'',
  121. create_type:1,
  122. master:[
  123. { sku_id: '', staff_user_id: '' },
  124. ]
  125. },
  126. submitLoading: true,
  127. dialogVisible: false,
  128. service_min:'',
  129. rules: {
  130. },
  131. pickerOptionsTime:{
  132. start: '08:30',
  133. step: '00:60',
  134. end: '18:30'
  135. },
  136. goods_name: '',
  137. id: 0,
  138. isChangeUsername: true,
  139. isEdit: false, // 是否是编辑模式
  140. sku_id: '',
  141. staff_user_id: '',
  142. pickerOptionsData: {},
  143. day_arr: [],
  144. options: [],
  145. start_time: '',
  146. end_time: '',
  147. service_time: 0,
  148. service_type_arr: [],
  149. secondary_card_id: 0
  150. };
  151. },
  152. methods: {
  153. back() {
  154. window.history.back();
  155. },
  156. mobileChange(mobile) {
  157. request({
  158. params: {
  159. r: 'reservation-service/reserve-order/get-user',
  160. mobile: mobile
  161. },
  162. method: 'get',
  163. }).then(e => {
  164. if (e.data.code === 0) {
  165. if (e.data.data) {
  166. this.ruleForm.nickname = e.data.data
  167. } else {
  168. this.isChangeUsername = false;
  169. this.ruleForm.nickname = '';
  170. }
  171. } else {
  172. this.$message.error(e.data.msg);
  173. }
  174. }).catch(e => {
  175. this.$message.error(e.data.msg);
  176. });
  177. },
  178. save() {
  179. this.ruleForm.store_images = this.store_images
  180. console.log(this.ruleForm)
  181. this.$refs['ruleForm'].validate((valid) => {
  182. if (valid) {
  183. request({
  184. params: {
  185. r: 'reservation-service/reserve-order/edit',
  186. },
  187. method: 'post',
  188. data: {
  189. form: this.ruleForm
  190. }
  191. }).then(e => {
  192. this.submitLoading = false;
  193. if (e.data.code === 0) {
  194. this.$message.success(e.data.msg);
  195. navigateTo({
  196. r: 'reservation-service/reserve-order/index',
  197. });
  198. } else {
  199. this.$message.error(e.data.msg);
  200. }
  201. }).catch(e => {
  202. this.submitLoading = false;
  203. this.$message.error(e.data.msg);
  204. });
  205. } else {
  206. console.log('error submit!!');
  207. this.submitLoading = false;
  208. return false;
  209. }
  210. });
  211. },
  212. load() {
  213. request({
  214. params: {
  215. r: 'reservation-service/reserve-order/edit',
  216. id:getQuery('id')
  217. },
  218. method: 'get',
  219. }).then(e => {
  220. this.submitLoading = false;
  221. if (e.data.code === 0) {
  222. this.store_name = e.data.data.store_name
  223. if(getQuery('id')>0){
  224. this.ruleForm = e.data.data.reserve_order;
  225. this.goods_name = e.data.data.goods_name;
  226. this.staff_user_list = e.data.data.staff_user_list;
  227. console.log(this.ruleForm);
  228. this.sku_id = this.ruleForm.master[0].sku_id;
  229. this.staff_user_id = this.ruleForm.master[0].staff_user_id;
  230. this.getReserveDay(this.sku_id, this.staff_user_id);
  231. this.isEdit = true;
  232. this.service_type_arr = e.data.data.service_type_arr;
  233. this.secondary_card_id = this.ruleForm.secondary_card_id;
  234. if (this.secondary_card_id == 0) {
  235. this.ruleForm.service_type = this.ruleForm.service_type.toString()
  236. }
  237. // 设置预约服务时长
  238. this.service_time = this.ruleForm.master[0].service_min;
  239. }
  240. this.start_time = e.data.data.start_time;
  241. this.end_time = e.data.data.end_time;
  242. } else {
  243. this.$message.error(e.data.msg);
  244. }
  245. }).catch(e => {
  246. this.submitLoading = false;
  247. this.$message.error(e.data.msg);
  248. });
  249. },
  250. changeService(value){
  251. for (var element of this.sku_list) {
  252. if(element.id==value){
  253. this.service_min = element.service_min;
  254. break;
  255. }
  256. }
  257. this.sku_id = value;
  258. this.getStaffUserList(value);
  259. // this.getReserveTime(value);
  260. },
  261. changeStaff(value) {
  262. this.staff_user_id = value;
  263. this.getReserveDay(this.sku_id, value);
  264. },
  265. changeDay(value) {
  266. console.log('===', value)
  267. this.getReserveTimes(this.sku_id, this.staff_user_id, value);
  268. },
  269. getStaffUserList(value){
  270. request({
  271. params: {
  272. r: 'reservation-service/reserve-order/get-staff-user-list',
  273. sku_id:value
  274. },
  275. method: 'get',
  276. }).then(e => {
  277. if (e.data.code === 0) {
  278. this.staff_user_list = [{name: '暂不选择技师', user_id: 0}, ...e.data.data]
  279. } else {
  280. this.$message.error(e.data.msg);
  281. }
  282. }).catch(e => {
  283. this.$message.error(e.data.msg);
  284. });
  285. },
  286. getReserveTime(sku_id, staff_user_id) {
  287. request({
  288. params: {
  289. r: 'reservation-service/reserve-order/get-reserve-time',
  290. sku_id: sku_id,
  291. staff_user_id: staff_user_id
  292. },
  293. method: 'get',
  294. }).then(e => {
  295. this.submitLoading = false;
  296. if (e.data.code === 0) {
  297. this.pickerOptionsTime = e.data.data.picker_options_time;
  298. } else {
  299. this.$message.error(e.data.msg);
  300. }
  301. }).catch(e => {
  302. this.$message.error(e.data.msg);
  303. });
  304. },
  305. getReserveTimes(sku_id, staff_user_id, day) {
  306. request({
  307. params: {
  308. r: 'reservation-service/reserve-order/get-reserve-times',
  309. sku_id: sku_id,
  310. staff_user_id: staff_user_id,
  311. date: day,
  312. },
  313. method: 'get',
  314. }).then(e => {
  315. this.submitLoading = false;
  316. if (e.data.code === 0) {
  317. this.options = e.data.data;
  318. } else {
  319. this.$message.error(e.data.msg);
  320. }
  321. }).catch(e => {
  322. this.$message.error(e.data.msg);
  323. });
  324. },
  325. getReserveDay(sku_id, staff_user_id) {
  326. request({
  327. params: {
  328. r: 'reservation-service/reserve-order/get-reserve-day',
  329. sku_id: sku_id,
  330. staff_user_id: staff_user_id
  331. },
  332. method: 'get',
  333. }).then(e => {
  334. this.submitLoading = false;
  335. if (e.data.code === 0) {
  336. this.day_arr = e.data.data.day_arr;
  337. this.pickerOptionsData = {
  338. disabledDate(time) {
  339. return !e.data.data.day_arr.includes(time.getTime())
  340. },
  341. }
  342. } else {
  343. this.$message.error(e.data.msg);
  344. }
  345. }).catch(e => {
  346. this.$message.error(e.data.msg);
  347. });
  348. },
  349. getSkuList(){
  350. let params = {
  351. r: 'reservation-service/reserve-order/get-sku-list',
  352. };
  353. request({
  354. params: params,
  355. method: 'get',
  356. }).then(e => {
  357. this.loading = false;
  358. if (e.data.code == 0) {
  359. this.sku_list = e.data.data;
  360. } else {
  361. this.$message.error(e.data.msg);
  362. }
  363. }).catch(e => {
  364. this.loading = false;
  365. });
  366. },
  367. },
  368. computed: {
  369. // 营业时间范围
  370. businessHours() {
  371. // 将分钟数转换为时:分:秒格式
  372. const formatTime = (minutes) => {
  373. const hours = Math.floor(minutes / 60);
  374. const mins = minutes % 60;
  375. return `${hours.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:00`;
  376. };
  377. return `${formatTime(this.start_time)} - ${formatTime(this.end_time)}`;
  378. },
  379. serviceDuration() {
  380. if (this.isEdit && this.service_time) {
  381. return this.service_time
  382. }
  383. // 新建模式下
  384. const sku = this.sku_list.find(item => item.id === this.ruleForm.master[0].sku_id);
  385. return sku?.service_min || 0;
  386. },
  387. },
  388. mounted() {
  389. if (getQuery('id') > 0) {
  390. this.id = getQuery('id');
  391. }
  392. this.load();
  393. this.getSkuList();
  394. }
  395. });
  396. </script>
  397. <style>
  398. .table-body {
  399. padding: 20px;
  400. background-color: #fff;
  401. }
  402. .head-btns .el-button {
  403. padding: 10px 35px;
  404. }
  405. .form-body {
  406. padding: 10px 20px 20px;
  407. background-color: #fff;
  408. margin-bottom: 30px;
  409. }
  410. /* 基础设置 */
  411. .basic_set {
  412. /* border: 1px solid #CCCCCC; */
  413. padding: 20px;
  414. border-radius: 10px;
  415. overflow-y: auto;
  416. }
  417. .common_head {
  418. border-bottom: 1px solid #CCCCCC;
  419. padding-bottom: 10px;
  420. font-size: 15px;
  421. margin-bottom: 30px;
  422. }
  423. .common_head2 {
  424. padding-bottom: 10px;
  425. font-size: 15px;
  426. margin-bottom: 20px;
  427. }
  428. .basic_body {
  429. padding-left: 25px;
  430. width: 50%;
  431. }
  432. .add_user {
  433. width: 350px;
  434. padding-left: 70px;
  435. }
  436. .line {
  437. margin-right: 10px;
  438. width: 5px;
  439. height: 23px;
  440. background: #03C5FF;
  441. }
  442. .stores {
  443. margin-bottom: 20px;
  444. }
  445. .customize-share-title {
  446. /* margin-top: 10px; */
  447. width: 100px;
  448. height: 100px;
  449. position: relative;
  450. cursor: move;
  451. }
  452. .del-btn {
  453. position: absolute;
  454. right: -8px;
  455. top: -8px;
  456. padding: 4px 4px;
  457. transform: scale(0.8);
  458. }
  459. .add-image-btn {
  460. width: 100px;
  461. height: 100px;
  462. color: #419EFB;
  463. border: 1px solid #e2e2e2;
  464. cursor: pointer;
  465. text-align: center;
  466. }
  467. .el-date-editor .el-range-separator {
  468. padding: 0;
  469. }
  470. .operate_state {
  471. padding-left: 15px;
  472. font-size: 15px;
  473. }
  474. .switchStyle {
  475. transform: scale(1.2);
  476. margin-left: 10px;
  477. }
  478. .switchStyle .el-switch__label {
  479. position: absolute;
  480. display: none;
  481. color: #fff;
  482. }
  483. .switchStyle .el-switch__label--left {
  484. z-index: 9;
  485. left: 20px;
  486. }
  487. .switchStyle .el-switch__label * {
  488. font-size: 12px !important;
  489. }
  490. .switchStyle .el-switch__label--right {
  491. z-index: 9;
  492. left: 0px;
  493. }
  494. .switchStyle .el-switch__label * {
  495. font-size: 12px !important;
  496. }
  497. .switchStyle .el-switch__label.is-active {
  498. display: block;
  499. }
  500. .switchStyle.el-switch .el-switch__core,
  501. .el-switch .el-switch__label {
  502. width: 70px !important;
  503. }
  504. .clear_style.el-form-item {
  505. margin-bottom: 0px;
  506. }
  507. .clear_style .el-input--medium .el-input__inner {
  508. width: 45%;
  509. }
  510. .add_radio .el-form-item__content {
  511. margin-top: 10px;
  512. }
  513. @media screen and (max-width: 1400px) {
  514. .basic_body {
  515. width: 70%;
  516. }
  517. .clear_style .el-input--medium .el-input__inner {
  518. width: 70%;
  519. }
  520. }
  521. /* 公共样式 */
  522. .flex {
  523. display: -webkit-box;
  524. display: -webkit-flex;
  525. /* #ifndef APP-NVUE */
  526. display: flex;
  527. /* #endif */
  528. }
  529. .flex-x-center {
  530. display: -webkit-box;
  531. display: -webkit-flex;
  532. /* #ifndef APP-NVUE */
  533. display: flex;
  534. /* #endif */
  535. -webkit-box-pack: center;
  536. -webkit-justify-content: center;
  537. -ms-flex-pack: center;
  538. justify-content: center;
  539. }
  540. .flex-x-between {
  541. display: -webkit-box;
  542. display: -webkit-flex;
  543. /* #ifndef APP-NVUE */
  544. display: flex;
  545. /* #endif */
  546. -webkit-box-pack: space-between;
  547. -webkit-justify-content: space-between;
  548. -ms-flex-pack: space-between;
  549. justify-content: space-between;
  550. }
  551. .flex-y-center {
  552. display: -webkit-box;
  553. display: -webkit-flex;
  554. /* #ifndef APP-NVUE */
  555. display: flex;
  556. /* #endif */
  557. -webkit-box-align: center;
  558. -webkit-align-items: center;
  559. -ms-flex-align: center;
  560. -ms-grid-row-align: center;
  561. align-items: center;
  562. }
  563. /* 溢出隐藏 */
  564. .over1 {
  565. text-overflow: -o-ellipsis-lastline;
  566. overflow: hidden;
  567. text-overflow: ellipsis;
  568. display: -webkit-box;
  569. -webkit-line-clamp: 1;
  570. -webkit-box-orient: vertical;
  571. }
  572. .over2 {
  573. text-overflow: -o-ellipsis-lastline;
  574. overflow: hidden;
  575. text-overflow: ellipsis;
  576. display: -webkit-box;
  577. -webkit-line-clamp: 2;
  578. -webkit-box-orient: vertical;
  579. }
  580. </style>