add-edit.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-dialog-select');
  4. ComponentHelper::loadComponentView('com-select-cat');
  5. ComponentHelper::loadComponentView('com-rich-text');
  6. ComponentHelper::loadComponentView('com-image');
  7. ComponentHelper::loadComponentView('com-qq-map');
  8. ?>
  9. <div id="app" v-cloak>
  10. <el-card class="box-card" shadow="never" style="border:0;min-width: 1500px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  11. <div class="form-body">
  12. <el-form :model="ruleForm" :rules="rules" size="small" ref="ruleForm" label-width="200px" v-loading="listLoading">
  13. <el-row>
  14. <el-col :span="24">
  15. <el-form-item label="" prop="">
  16. <el-button type="primary" style="padding:9px 40px" size="small" @click.sync='chooseUser'>选择会员 </el-button>
  17. </el-form-item>
  18. <el-form-item label="选中会员" v-if="userInfo.id">
  19. <div style="display: inline-block; margin-left: 15px;">会员ID:<span>{{userInfo.id}}</span></div>
  20. <div style="display: inline-block; margin-left: 15px;">会员昵称:<span>{{userInfo.nickname}}</span></div>
  21. </el-form-item>
  22. <el-form-item label="姓名" prop="shop_owner">
  23. <el-input size="small" v-model="ruleForm.shop_owner" size="small" placeholder="请输入姓名"></el-input>
  24. </el-form-item>
  25. <el-form-item label="手机号" prop="shop_mobile">
  26. <el-input size="small" v-model="ruleForm.shop_mobile" size="small" placeholder="请输入手机号"></el-input>
  27. <span style="color: red;">*</span><span style="color:#B9B9B9;">注:手机号为商家后台登录的账号</span>
  28. </el-form-item>
  29. <el-form-item label="商户名称" prop="store_name">
  30. <el-input size="small" v-model="ruleForm.store_name" size="small" placeholder="请输入商户名称"></el-input>
  31. </el-form-item>
  32. <el-form-item label="门店分类" prop="c_id">
  33. <div class="item-box" flex="dir:left cross:center">
  34. <el-select v-model="ruleForm.c_id" class="select" size="small" style="width: 130px;">
  35. <el-option :key="0" label="所有分类" :value="0"></el-option>
  36. <el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in categorys"></el-option>
  37. </el-select>
  38. </div>
  39. </el-form-item>
  40. <el-form-item label="商户简介" prop="store_desc">
  41. <el-input type="textarea" size="small" v-model="ruleForm.store_desc" size="small" placeholder="请输入商户简介" maxlength="255" show-word-limit></el-input>
  42. </el-form-item>
  43. <el-form-item prop="logo_img" class="com-goods" label="商家LOGO">
  44. <div class="pic-url-remark">
  45. 建议尺寸 200px*200px
  46. </div>
  47. <template v-if="ruleForm.logo_img">
  48. <div style="margin-right: 20px;position: relative;display: inline-block;">
  49. <com-attachment :multiple="false" :max="1" type="images">
  50. <com-image mode="aspectFill" width="100px" height='100px' :src="ruleForm.logo_img"> </com-image>
  51. </com-attachment>
  52. <el-button class="del-btn" size="mini" type="danger" icon="el-icon-close" circle @click="delPic('logo_img')"></el-button>
  53. </div>
  54. </template>
  55. <template v-if="!ruleForm.logo_img">
  56. <com-attachment :multiple="false" :max="1" type="images" @selected="selectedImg($event, 'logo_img')">
  57. <el-tooltip class="item" effect="dark" content="建议尺寸:200px * 200px" placement="top">
  58. <div flex="main:center cross:center" class="add-image-btn">
  59. + 添加图片
  60. </div>
  61. </el-tooltip>
  62. </com-attachment>
  63. </template>
  64. </el-form-item>
  65. <el-form-item prop="license_img" class="com-goods" label="营业执照">
  66. <template v-if="ruleForm.license_img">
  67. <div style="margin-right: 20px;position: relative;display: inline-block;">
  68. <com-attachment v-model="ruleForm.license_img">
  69. <com-image v-if="ruleForm.license_img" mode="aspectFill" width="100px" height='100px' :src="ruleForm.license_img"> </com-image>
  70. </com-attachment>
  71. <el-button class="del-btn" size="mini" type="danger" icon="el-icon-close" circle @click="delPic('license_img')"></el-button>
  72. </div>
  73. </template>
  74. <template v-if="!ruleForm.license_img">
  75. <com-attachment :multiple="false" :max="1" type="images" @selected="selectedImg($event, 'license_img')">
  76. <div flex="main:center cross:center" class="add-image-btn">
  77. + 添加图片
  78. </div>
  79. </com-attachment>
  80. </template>
  81. </el-form-item>
  82. </el-col>
  83. </el-row>
  84. </el-form>
  85. </div>
  86. <el-button class="button-item" style="margin-bottom: 15px;" type="primary" @click="submitForm('ruleForm')" size="small" :loading="btnLoading">保存
  87. </el-button>
  88. </el-card>
  89. <el-dialog title="添加会员" :visible.sync="dialogVisible" width="50%">
  90. <div class="search-box">
  91. <div class="input-item">
  92. <el-input @keyup.enter.native="getUser" size="small" placeholder="请输入会员ID" v-model="searchData.user_id"> </el-input>
  93. </div>
  94. <div class="input-item">
  95. <el-input @keyup.enter.native="getUser" size="small" placeholder="会员昵称/手机号" v-model="searchData.keyword"> </el-input>
  96. </div>
  97. <el-button type="primary" size="small" @click="getUser">搜索</el-button>
  98. <el-button type="warning" size="small" @click="clereSearch" v-if="searchData.keyword || searchData.user_id" style="padding: 9px 15px !important;">清除搜索条件</el-button>
  99. </div>
  100. <el-table :data="userList" stripe v-loading="userListLoading" style="width: 100%" @current-change="clickChange">
  101. <el-table-column prop="date" width="50">
  102. <template slot-scope="scope">
  103. <el-radio v-model="userInfo" :label="scope.row"><i></i></el-radio>
  104. </template>
  105. </el-table-column>
  106. <el-table-column prop="id" label="ID" width="80"> </el-table-column>
  107. <el-table-column prop="avatar_url" label="会员" width="80">
  108. <template slot-scope="scope">
  109. <el-image style="width: 60px; height: 60px" :src="scope.row.avatar_url" fit="cover"></el-image>
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="nickname" width="180"> </el-table-column>
  113. <el-table-column prop="mobile" label="手机号" width="200">
  114. </el-table-column>
  115. <el-table-column prop="level_name" label="会员等级">
  116. <template slot-scope="scope">
  117. <div v-if="scope.row.level > 0">等级{{scope.row.level_name}}</div>
  118. <div v-else>普通用户</div>
  119. </template>
  120. </el-table-column>
  121. <el-table-column prop="parent_nickname" label="已绑定推荐人">
  122. </el-table-column>
  123. </el-table>
  124. <div style="text-align: right;margin: 20px 0;">
  125. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount"></el-pagination>
  126. </div>
  127. <span slot="footer" class="dialog-footer">
  128. <el-button @click="dialogVisible = false">取 消</el-button>
  129. <el-button type="primary" @click="selectUser">确 定</el-button>
  130. </span>
  131. </el-dialog>
  132. </div>
  133. <script>
  134. const app = new Vue({
  135. el: '#app',
  136. data() {
  137. return {
  138. listLoading: false,
  139. btnLoading: false,
  140. userListLoading: false,
  141. dialogVisible: false,
  142. ruleForm: {},
  143. categorys: [],
  144. provinces: [],
  145. provinceInfo: {},
  146. citys: [],
  147. cityInfo: {},
  148. districts: [],
  149. districtInfo: {},
  150. streets: [],
  151. streetInfo: {},
  152. userList: [],
  153. userInfo: {},
  154. searchData: {
  155. user_id: null,
  156. keyword: '',
  157. },
  158. currPage: 1,
  159. pageCount: 0,
  160. rules: {
  161. shop_owner: [{
  162. required: true,
  163. message: '姓名不能为空',
  164. trigger: 'blur'
  165. }, ],
  166. shop_mobile: [{
  167. required: true,
  168. message: '手机号不能为空',
  169. trigger: 'blur'
  170. }, ],
  171. store_name: [{
  172. required: true,
  173. message: '商户名称不能为空',
  174. trigger: 'blur'
  175. }, ],
  176. address: [{
  177. required: true,
  178. message: '商户详细地址不能为空',
  179. trigger: 'blur'
  180. }, ],
  181. },
  182. page: 1,
  183. pageCount: 0,
  184. long_lat: '', // 经纬度
  185. };
  186. },
  187. mounted() {
  188. this.loadData();
  189. },
  190. methods: {
  191. loadData() {
  192. let self = this;
  193. self.listLoading = true;
  194. request({
  195. params: {
  196. r: 'mch/store/storage',
  197. },
  198. method: 'get',
  199. }).then(e => {
  200. self.listLoading = false;
  201. if (e.data.code == 0) {
  202. self.categorys = e.data.data.list;
  203. self.provinces = e.data.data.provinces;
  204. }
  205. }).catch(e => {
  206. console.log(e);
  207. self.listLoading = false;
  208. self.$message.error('网络错误');
  209. });
  210. },
  211. submitForm(formName) {
  212. let self = this;
  213. if (!self.ruleForm.user_id) {
  214. self.$message.error('请选择关联会员');
  215. return false;
  216. }
  217. if (!self.ruleForm.logo_img) {
  218. self.$message.error('请上传商家LOGO图片');
  219. return false;
  220. }
  221. if (!self.ruleForm.license_img) {
  222. self.$message.error('请上传营业执照图片');
  223. return false;
  224. }
  225. self.ruleForm.province_id = self.provinceInfo.id;
  226. self.ruleForm.city_id = self.cityInfo.id;
  227. self.ruleForm.district_id = self.districtInfo.id;
  228. console.log('sumbit ===: ', self.ruleForm);
  229. self.btnLoading = true;
  230. self.$refs[formName].validate((valid, obj) => {
  231. if (valid) {
  232. request({
  233. params: {
  234. r: 'mch/store/storage',
  235. },
  236. method: 'post',
  237. data: self.ruleForm,
  238. }).then(e => {
  239. self.btnLoading = false;
  240. if (e.data.code == 0) {
  241. self.$message.success('保存成功');
  242. } else {
  243. self.$message.error(e.data.msg);
  244. }
  245. }).catch(e => {
  246. self.btnLoading = false;
  247. console.log(e);
  248. self.$message.error('网络错误');
  249. return false;
  250. });
  251. } else {
  252. self.btnLoading = false;
  253. var msg = '';
  254. for (let index in obj) {
  255. msg = msg + '*' + obj[index][0].message + ' ';
  256. }
  257. this.$message({
  258. message: msg,
  259. type: 'error'
  260. });
  261. return false;
  262. }
  263. });
  264. },
  265. selectedImg(e, key) {
  266. // console.log('ddddd: ', e, key);
  267. this.ruleForm[key] = e[0].url;
  268. this.$forceUpdate();
  269. },
  270. delPic(key) {
  271. this.ruleForm[key] = '';
  272. this.$forceUpdate();
  273. },
  274. // 省市区三级联动
  275. regionChange(e, level) {
  276. console.log('kkkkkkkklklk: ', e, level);
  277. let self = this;
  278. self.ruleForm.longitude = e.lng;
  279. self.ruleForm.latitude = e.lat;
  280. request({
  281. params: {
  282. r: 'mch/store/get-regions',
  283. region_id: e.id,
  284. },
  285. method: 'get',
  286. }).then(e => {
  287. if (e.data.code == 0) {
  288. switch (level) {
  289. case 1:
  290. self.citys = e.data.data;
  291. break;
  292. case 2:
  293. self.districts = e.data.data;
  294. break;
  295. case 3:
  296. self.streets = e.data.data;
  297. break;
  298. }
  299. } else {
  300. self.$message.error(e.data.msg);
  301. }
  302. }).catch(e => {
  303. console.log(e);
  304. self.$message.error('网络错误');
  305. return false;
  306. });
  307. },
  308. //地图确定事件
  309. mapEvent(e) {
  310. // console.log('map-event: ', e);
  311. this.ruleForm.longitude = e.long;
  312. this.ruleForm.latitude = e.lat;
  313. this.ruleForm.address = e.address;
  314. this.long_lat = e.lat + '-' + e.long;
  315. this.$forceUpdate();
  316. // console.log('this.ruleForm: ', this.ruleForm);
  317. },
  318. // 获取会员列表
  319. getUser() {
  320. let self = this;
  321. self.userListLoading = true;
  322. request({
  323. params: {
  324. r: 'mch/store/get-users',
  325. page: self.currPage,
  326. ...self.searchData,
  327. },
  328. method: 'get',
  329. }).then(e => {
  330. self.userListLoading = false;
  331. if (e.data.code == 0) {
  332. self.userList = e.data.data.list;
  333. self.pageCount = e.data.data.page_count;
  334. } else {
  335. self.$message.error(e.data.msg);
  336. return false;
  337. }
  338. }).catch(e => {
  339. console.log(e);
  340. self.$message.error('网络错误');
  341. return false;
  342. });
  343. },
  344. // 选择会员
  345. chooseUser() {
  346. this.getUser()
  347. this.dialogVisible = true;
  348. },
  349. // 会员列表分页
  350. pagination(currentPage) {
  351. this.currPage = currentPage;
  352. this.getUser();
  353. },
  354. // 选中会员确定回调
  355. selectUser() {
  356. console.log('selectUser === : ', this.userInfo);
  357. this.ruleForm.user_id = this.userInfo.id;
  358. this.ruleForm.shop_mobile = this.userInfo.mobile;
  359. this.dialogVisible = false;
  360. },
  361. // 会员列表选中
  362. clickChange(userInfo) {
  363. this.userInfo = userInfo;
  364. },
  365. // 清楚搜索条件
  366. clereSearch() {
  367. this.searchData.user_id = null;
  368. this.searchData.keyword = '';
  369. this.getUser();
  370. },
  371. }
  372. });
  373. </script>
  374. <style>
  375. .el-popover {
  376. padding: 30px;
  377. }
  378. .form-body {
  379. padding: 20px;
  380. background-color: #fff;
  381. margin-bottom: 20px;
  382. padding-right: 20%;
  383. min-width: 900px;
  384. }
  385. .form-body .el-form-item {
  386. padding-right: 25%;
  387. min-width: 850px;
  388. }
  389. .form-button {
  390. margin: 0;
  391. }
  392. .form-button .el-form-item__content {
  393. margin-left: 0 !important;
  394. }
  395. .button-item {
  396. padding: 9px 25px;
  397. }
  398. .check-group {
  399. font-size: 14px !important;
  400. }
  401. .check-group .el-col {
  402. display: flex;
  403. }
  404. .check-group .el-input {
  405. margin: 0 5px;
  406. }
  407. .check-group .el-col .el-checkbox {
  408. display: flex;
  409. align-items: center;
  410. }
  411. .check-group .el-col .el-input {
  412. width: 100px;
  413. }
  414. .check-group .el-col .el-input .el-input__inner {
  415. height: 30px;
  416. width: 100px;
  417. }
  418. .el-checkbox-group .el-col {
  419. margin-bottom: 10px;
  420. }
  421. .inp {
  422. width: 140px;
  423. }
  424. .inp .el-input__inner {
  425. border-radius: 4px 0 0 4px;
  426. }
  427. .inp2 {
  428. width: 60px;
  429. }
  430. .inp-text {
  431. background: #EFEFEF;
  432. border: 1px solid #E3E2E5;
  433. font-size: 15px;
  434. padding: 0px 15px;
  435. border-radius: 0 4px 4px 0;
  436. height: 32px;
  437. }
  438. /* flex公共样式 */
  439. .flex {
  440. display: -webkit-box;
  441. display: -webkit-flex;
  442. display: flex;
  443. }
  444. .flex-x-center {
  445. display: -webkit-box;
  446. display: -webkit-flex;
  447. display: flex;
  448. -webkit-box-pack: center;
  449. -webkit-justify-content: center;
  450. -ms-flex-pack: center;
  451. justify-content: center;
  452. }
  453. .flex-x-between {
  454. display: -webkit-box;
  455. display: -webkit-flex;
  456. display: flex;
  457. -webkit-box-pack: space-between;
  458. -webkit-justify-content: space-between;
  459. -ms-flex-pack: space-between;
  460. justify-content: space-between;
  461. }
  462. .flex-y-center {
  463. display: -webkit-box;
  464. display: -webkit-flex;
  465. display: flex;
  466. -webkit-box-align: center;
  467. -webkit-align-items: center;
  468. -ms-flex-align: center;
  469. -ms-grid-row-align: center;
  470. align-items: center;
  471. }
  472. .flex-y-bottom {
  473. display: -webkit-box;
  474. display: -webkit-flex;
  475. display: flex;
  476. -webkit-box-align: end;
  477. -webkit-align-items: flex-end;
  478. -ms-flex-align: end;
  479. -ms-grid-row-align: flex-end;
  480. align-items: flex-end;
  481. }
  482. .pic-url-remark {
  483. font-size: 13px;
  484. color: #c9c9c9;
  485. margin-bottom: 12px;
  486. }
  487. .add-image-btn {
  488. width: 100px;
  489. height: 100px;
  490. color: #419EFB;
  491. border: 1px solid #e2e2e2;
  492. cursor: pointer;
  493. }
  494. .del-btn {
  495. position: absolute;
  496. right: -14px;
  497. top: -14px;
  498. }
  499. /* .el-input__inner {
  500. width: 74%;
  501. } */
  502. .el-input-group {
  503. width: 69%;
  504. }
  505. .el-input.is-disabled .el-input__inner {
  506. width: 49%;
  507. }
  508. .search-box {
  509. display: flex;
  510. margin-bottom: 30px;
  511. }
  512. .input-item {
  513. width: 200px;
  514. margin-right: 16px;
  515. }
  516. </style>