edit.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-dialog-select');
  4. ComponentHelper::loadComponentView('com-image');
  5. ?>
  6. <div id="app" v-cloak>
  7. <el-card class="box-card" v-loading="loading" shadow="never" style="border:0;min-width: 1200px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  8. <div slot="header">
  9. <div>
  10. <span>标签设置</span>
  11. </div>
  12. </div>
  13. <div class="form_box">
  14. <template>
  15. <el-form :model="ruleForm" :rules="rules" size="small" ref="ruleForm" label-width="150px" @submit.native.prevent>
  16. <el-card style="margin-top: 10px" shadow="never">
  17. <el-col :span="50" >
  18. <el-form-item label="标签名称" style='display: flex;' prop="name" >
  19. <el-input v-model="ruleForm.name" placeholder="请输入标签名称,最多20个字" ></el-input>
  20. </el-form-item>
  21. <el-form-item label="标签类型" style='display: flex;'>
  22. <el-radio-group v-model="ruleForm.type" >
  23. <el-radio :label="2">自动标签</el-radio>
  24. <el-radio :label="1">手动标签</el-radio>
  25. </el-radio-group>
  26. </el-form-item>
  27. <el-form-item label="满足条件" v-if='ruleForm.type == 2' style='display: flex;'>
  28. <div style="color:red;">标签创建后新满足条件的会员会实时打标,标签创建前已满足条件的会员会在次日凌晨进行打标。</div>
  29. </el-form-item>
  30. <el-form-item label="标签颜色" style='display: flex;'>
  31. <el-color-picker v-model="ruleForm.color"></el-color-picker>
  32. </el-form-item>
  33. </el-col>
  34. <el-col :span="14" v-if='ruleForm.type == 2' style="padding-left: 148px;">
  35. <el-form-item label="" style='display: flex;'>
  36. <el-radio-group v-model="ruleForm.satisfy_type" >
  37. <el-radio label="1">满足任意一个被选中的条件即可</el-radio>
  38. <el-radio label="2">必须满足所有被选中的条件</el-radio>
  39. </el-radio-group>
  40. </el-form-item>
  41. <el-form-item label="">
  42. <el-col :span="20">
  43. <div class="margin-button-20px flex">
  44. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.last_consume.select_status" style="margin-right: 20px;" >最后消费时间</el-checkbox>
  45. <div class="enter flex">
  46. <el-radio-group v-model="ruleForm.condition.last_consume.condition.type">
  47. <div class="flex flex-y-center">
  48. <el-radio label = "1" true-label = "1" false-label ="2">最近</el-radio>
  49. <el-input v-model="ruleForm.condition.last_consume.condition.content.day" onkeyup="value=toNumber(value)" class='inp'></el-input>
  50. <div class="inp-text" style="padding-top: 6px;">天</div>
  51. </div>
  52. <div class="time_last_consume">
  53. <el-radio label = "2" true-label = "2" false-label ="1" >自定义</el-radio>
  54. <el-date-picker
  55. v-model="ruleForm.condition.last_consume.time"
  56. type="datetimerange"
  57. value-format="yyyy-MM-dd HH:mm:ss"
  58. range-separator="至"
  59. start-placeholder="开始日期"
  60. end-placeholder="结束日期">
  61. </el-date-picker>
  62. </div>
  63. </el-radio-group>
  64. </div>
  65. </div>
  66. <div class="margin-button-20px flex">
  67. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.consume_num.select_status" style="margin-right: 20px;">消费次数</el-checkbox>
  68. <div class="enter flex">
  69. <div class="flex flex-y-center">
  70. <el-input :disabled='!ruleForm.condition.consume_num' onkeyup=" value = value.replace(/[^\d]/g,'')" v-model="ruleForm.condition.consume_num.condition.start" class='inp'></el-input>
  71. <div class="inp-text">次</div>
  72. </div>
  73. <div class="segmentation">-</div>
  74. <div class="flex flex-y-center">
  75. <el-input :disabled='!ruleForm.condition.consume_num' onkeyup= " value = value.replace(/[^\d]/g,'')" v-model="ruleForm.condition.consume_num.condition.end" class='inp'></el-input>
  76. <div class="inp-text">次</div>
  77. </div>
  78. </div>
  79. </div>
  80. <div class="margin-button-20px flex">
  81. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.consume_money.select_status" style="margin-right: 20px;">消费金额</el-checkbox>
  82. <div class="enter flex">
  83. <div class="flex flex-y-center">
  84. <el-input :disabled='!ruleForm.condition.consume_money' v-model="ruleForm.condition.consume_money.condition.start" onInput="value=toNumber(value,2)" class='inp'></el-input>
  85. <div class="inp-text">元</div>
  86. </div>
  87. <div class="segmentation">-</div>
  88. <div class="flex flex-y-center">
  89. <el-input :disabled='!ruleForm.condition.consume_money' v-model="ruleForm.condition.consume_money.condition.end" onInput="value=toNumber(value,2)" class='inp'></el-input>
  90. <div class="inp-text">元</div>
  91. </div>
  92. </div>
  93. </div>
  94. <div class="margin-button-20px flex">
  95. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.average_money.select_status" style="margin-right: 20px;">客单价</el-checkbox>
  96. <div class="enter flex">
  97. <div class="flex flex-y-center">
  98. <el-input style="margin-left: 13px;" :disabled='!ruleForm.condition.average_money' v-model="ruleForm.condition.average_money.condition.start" onInput="value=toNumber(value,2)" class='inp'></el-input>
  99. <div class="inp-text">元</div>
  100. </div>
  101. <div class="segmentation">-</div>
  102. <div class="flex flex-y-center">
  103. <el-input :disabled='!ruleForm.condition.average_money' v-model="ruleForm.condition.average_money.condition.end" onInput="value=toNumber(value,2)" class='inp'></el-input>
  104. <div class="inp-text">元</div>
  105. </div>
  106. </div>
  107. </div>
  108. <div class="margin-button-20px flex">
  109. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.recharge_money.select_status" style="margin-right: 20px;">充值金额</el-checkbox>
  110. <div class="enter flex">
  111. <div class="flex flex-y-center">
  112. <el-input :disabled='!ruleForm.condition.recharge_money' v-model="ruleForm.condition.recharge_money.condition.start" onInput="value=toNumber(value,2)" class='inp'></el-input>
  113. <div class="inp-text">元</div>
  114. </div>
  115. <div class="segmentation">-</div>
  116. <div class="flex flex-y-center">
  117. <el-input :disabled='!ruleForm.condition.recharge_money' v-model="ruleForm.condition.recharge_money.condition.end" onInput="value=toNumber(value,2)" class='inp'></el-input>
  118. <div class="inp-text">元</div>
  119. </div>
  120. </div>
  121. </div>
  122. <div class="margin-button-20px flex">
  123. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.follow.select_status" style="margin-right: 20px;">关注公众号时间</el-checkbox>
  124. <div class="enter flex">
  125. <el-date-picker
  126. v-model="ruleForm.condition.follow.time"
  127. type="datetimerange"
  128. value-format="yyyy-MM-dd HH:mm:ss"
  129. range-separator="至"
  130. start-placeholder="开始日期"
  131. end-placeholder="结束日期">
  132. </el-date-picker>
  133. </div>
  134. </div>
  135. </el-col>
  136. <el-col>
  137. <div class="margin-button-20px flex">
  138. <el-checkbox value = "1" true-label = "1" false-label ="0" v-model="ruleForm.condition.goods.select_status" style="margin-right: 20px;">购买指定商品</el-checkbox>
  139. <div class="enter flex">
  140. <el-radio-group v-model="ruleForm.goods_ids">
  141. <com-dialog-select :multiple="true" @selected="goodsSelect" title="商品选择">
  142. <el-button type="text">选择商品</el-button>
  143. </com-dialog-select>
  144. </el-radio-group>
  145. <el-form-item v-if="goods_list">
  146. <template>
  147. <div style="color: #ff4544; padding-left: 10px;">最多可关联20个商品</div>
  148. <div style="max-height: 100%;overflow-y: auto; width: 100%">
  149. <el-table :data="goods_list" style="width: 100%;" :show-header="false" border >
  150. <el-table-column label="">
  151. <template slot-scope="scope">
  152. <div flex>
  153. <div style="padding-right: 10px;flex-grow: 0">
  154. <com-image mode="aspectFill" :src="scope.row.cover_pic"></com-image>
  155. </div>
  156. <div style="flex-grow: 1;">
  157. <com-ellipsis :line="2">{{scope.row.goods_name}}</com-ellipsis>
  158. <com-ellipsis :line="2" style="color: red;">¥{{scope.row.price}}</com-ellipsis>
  159. </div>
  160. <div style="flex-grow: 0;">
  161. <el-button @click="deleteGoods(scope.$index)" type="text" circle size="mini">
  162. 删除
  163. </el-button>
  164. </div>
  165. </div>
  166. </template>
  167. </el-table-column>
  168. </el-table>
  169. </div>
  170. </template>
  171. </el-form-item>
  172. </div>
  173. </div>
  174. </el-col>
  175. </el-form-item>
  176. </el-col>
  177. <el-col>
  178. <el-button :loading="btnLoading" class="button-item" type="primary" style="margin-top: 24px;" @click="store('ruleForm')" size="small">保存</el-button>
  179. </el-col>
  180. </el-card>
  181. </template>
  182. </div>
  183. </el-card>
  184. </div>
  185. <script>
  186. const app = new Vue({
  187. el: '#app',
  188. data() {
  189. return {
  190. loading: false,
  191. btnLoading: false,
  192. time:[],
  193. goods_list:[],
  194. ruleForm: {
  195. id:'',
  196. name:'',
  197. type: 2,
  198. satisfy_type:"1",
  199. select_data:['goods'],
  200. goods_ids:[],
  201. condition:{
  202. last_consume:{
  203. condition: {
  204. type:"1",// 类型,1=最近N天,2=自定义时间
  205. content:{
  206. day: '1',// type=1的时候
  207. start: '',// type=2的时候
  208. end: '',// type=2的时候
  209. },
  210. },
  211. time:[],
  212. select_status: "0",
  213. },
  214. consume_num:{
  215. condition:{
  216. start:"",
  217. end:"",
  218. },
  219. select_status:"0",//1是选中 2是取消
  220. },
  221. consume_money:{
  222. condition:{
  223. start:"",
  224. end:"",
  225. },
  226. select_status:"0",//1是选中 2是取消
  227. },
  228. average_money:{
  229. condition:{
  230. start:"",
  231. end:"",
  232. },
  233. select_status:"0",//1是选中 2是取消
  234. },
  235. recharge_money:{
  236. condition:{
  237. start:"",
  238. end:"",
  239. },
  240. select_status:"0",//1是选中 2是取消
  241. },
  242. follow:{
  243. condition:{
  244. start:"",
  245. end:"",
  246. },
  247. time:[],
  248. select_status:"0",//1是选中 2是取消
  249. },
  250. goods:{
  251. condition:{
  252. },
  253. select_status:"0",//1是选中 2是取消
  254. },
  255. },
  256. },
  257. rules: {
  258. name: [{
  259. required: true,
  260. message: '请输入标签名称',
  261. trigger: 'change'
  262. },
  263. {
  264. validator: (rule, value, callback) => {
  265. if(value.length>20||value.length<0){
  266. callback('最大长度在1-20个字内');
  267. }
  268. callback();
  269. }
  270. },
  271. ],
  272. sort: [{
  273. required: true,
  274. message: '请输入排序',
  275. trigger: 'change'
  276. }, ],
  277. },
  278. error_data: {
  279. verage_money: "客单价",
  280. consume_money: "消费金额",
  281. consume_num: "消费次数",
  282. follow: "关注公众号",
  283. goods: "购买指定商品",
  284. last_consume: "最后消费时间",
  285. recharge_money: "充值金额",
  286. },
  287. }
  288. },
  289. mounted: function() {
  290. this.ruleForm.id = getQuery('id');
  291. this.loadData();
  292. },
  293. methods: {
  294. loadData() {
  295. this.loading = true;
  296. let id = getQuery('id');
  297. request({
  298. params: {
  299. r: 'mall/user-label/edit',
  300. id: getQuery('id')
  301. },
  302. method: 'get'
  303. }).then(e => {
  304. this.loading = false;
  305. if (e.data.code == 0) {
  306. if(id){
  307. this.error_data = e.data.data.cond_enum;
  308. var old_condition = this.ruleForm.condition;
  309. this.ruleForm = e.data.data;
  310. if(e.data.data.conf.length < 1) {
  311. this.ruleForm.condition = old_condition;
  312. } else{
  313. this.ruleForm.condition = e.data.data.conf;
  314. }
  315. this.ruleForm.satisfy_type = e.data.data.satisfy_type+"";
  316. this.select_status();
  317. this.ruleForm.goods_ids = [];
  318. if(!isEmpty(e.data.data.conf.goods.condition)){
  319. var goods_ids = e.data.data.conf.goods.condition;
  320. if(goods_ids.toString().search(",") != -1){
  321. this.ruleForm.goods_ids = goods_ids.split(',');
  322. }else{
  323. this.ruleForm.goods_ids.push(goods_ids);
  324. }
  325. }else{
  326. this.ruleForm.goods_ids = [];
  327. }
  328. }
  329. }
  330. }).catch(e => {
  331. this.loading = false;
  332. })
  333. },
  334. deleteGoods(index) {
  335. this.goods_list.splice(index, 1);
  336. this.ruleForm.goods_ids.splice(index, 1);
  337. this.goods_id = '';
  338. //console.log(this.ruleForm.goods_ids,index,8888);
  339. },
  340. goodsSelect(param) {
  341. for (let j in param) {
  342. if(this.goods_list.length>19){
  343. this.$message.error('最多可以选择20件商品');
  344. break;
  345. }
  346. let item = param[j];
  347. var is_set = true;
  348. if(inArray(item.id,this.ruleForm.goods_ids)){
  349. is_set = false;
  350. }
  351. this.ruleForm.goods_ids.push(item.id);
  352. var goods_data = {
  353. id: item.id,
  354. goods_name: item.goods_name,
  355. price: item.price,
  356. cover_pic: item.cover_pic,
  357. };
  358. if(is_set){
  359. this.goods_list.push(goods_data);
  360. }
  361. }
  362. },
  363. // 选择商品
  364. handleSelect(item) {
  365. },
  366. get_errormsg(key){
  367. var value = '';
  368. $.each(this.error_data,function(k,v){
  369. if(k==key){
  370. value = v;
  371. }
  372. });
  373. return value;
  374. },
  375. //选中对象选项进行处理
  376. select_status(){
  377. console.log(this.ruleForm.condition,888);
  378. if(this.ruleForm.goods_list){
  379. this.goods_list = this.ruleForm.goods_list;
  380. }
  381. if(this.ruleForm.condition){
  382. $.each(this.ruleForm.condition,function(k,v){
  383. v.select_status = v.select_status +"";
  384. if(k=='last_consume'){
  385. v.condition.type = v.condition.type + "";
  386. if(v.condition.content.start && v.condition.content.end) v.time = [v.condition.content.start,v.condition.content.end];
  387. }
  388. if(v.condition.start && v.condition.end) v.time = [v.condition.start,v.condition.end];
  389. });
  390. }
  391. },
  392. //进行验证
  393. check_params(){
  394. if(this.ruleForm.type==1) return true;//手动标签不需要进行验证
  395. if(this.ruleForm.condition){
  396. var pass_status = 1;
  397. let _seft = this;
  398. //console.log(this.ruleForm.condition.follow,6666);
  399. if(!isEmpty(this.ruleForm.goods_ids)) {
  400. this.ruleForm.condition.goods.condition = this.ruleForm.goods_ids.join(',');
  401. }else{
  402. this.ruleForm.condition.goods.condition = "";
  403. }
  404. if(!isEmpty(this.ruleForm.condition.follow.time)) {
  405. this.ruleForm.condition.follow.condition.start = this.ruleForm.condition.follow.time[0];
  406. this.ruleForm.condition.follow.condition.end = this.ruleForm.condition.follow.time[1];
  407. }
  408. if(!isEmpty(this.ruleForm.condition.last_consume.time) && this.ruleForm.condition.last_consume.condition.type == 2 ) {
  409. this.ruleForm.condition.last_consume.condition.content.start = this.ruleForm.condition.last_consume.time[0];
  410. this.ruleForm.condition.last_consume.condition.content.end = this.ruleForm.condition.last_consume.time[1];
  411. }
  412. $num = 0;
  413. $.each(this.ruleForm.condition,function(k,v){
  414. //验证最近
  415. if(v.select_status == "1"){
  416. $num ++;
  417. if(k=='last_consume'){
  418. if(v.condition.type==1){
  419. if(parseFloat(v.condition.content.day) <= 0 || !v.condition.content.day){
  420. _seft.$message.error('请输入正确的最近天数');
  421. pass_status = 0;
  422. return false;
  423. }
  424. }
  425. if(v.condition.type==2){
  426. var start = v.condition.content.start.toString();//处理0等于false问题,判断失效
  427. var end = v.condition.content.end.toString();//处理0等于false问题,判断失效
  428. if(!start || !end || parseFloat(v.condition.content.start) <0 || parseFloat(v.condition.content.end) <0){
  429. _seft.$message.error('请选择日期');
  430. pass_status = 0;
  431. return false;
  432. }
  433. }
  434. }else if(k=='goods'){
  435. if(isEmpty(v.condition)){
  436. _seft.$message.error('请选择商品');
  437. pass_status = 0;
  438. return false;
  439. }
  440. } else{
  441. var start = v.condition.start.toString();// 处理0等false问题
  442. var end = v.condition.end.toString();// 处理0等false问题
  443. if(!start || !end || parseFloat(v.condition.start) <0 || parseFloat(v.condition.end) <0){
  444. _seft.$message.error('请在'+_seft.get_errormsg(k)+'选项中正确数值');
  445. pass_status = 0;
  446. return false;
  447. };
  448. if(k!='follow' && parseFloat(v.condition.start) >= parseFloat(v.condition.end)){
  449. _seft.$message.error(_seft.get_errormsg(k)+'开始数值不能大于等于结束值');
  450. pass_status = 0;
  451. return false;
  452. }
  453. }
  454. }
  455. })
  456. if($num<1){
  457. _seft.$message.error('自动标签达标条件至少勾选一个');
  458. return false;
  459. }
  460. }
  461. if(pass_status == 1){
  462. return true;
  463. }else{
  464. return false;
  465. }
  466. },
  467. store(formName) {
  468. let formData = JSON.stringify(this.dataForm);
  469. //进行验证
  470. if(!this.check_params())return false;
  471. this.$refs[formName].validate((valid) => {
  472. if (valid) {
  473. this.btnLoading = true;
  474. request({
  475. params: {
  476. r: 'mall/user-label/edit',
  477. },
  478. method: 'post',
  479. data: {
  480. form: this.ruleForm,
  481. }
  482. }).then(e => {
  483. this.btnLoading = false;
  484. if (e.data.code == 0) {
  485. this.$message.success(e.data.msg);
  486. navigateTo({
  487. r: 'mall/user-label/index'
  488. })
  489. } else {
  490. this.$message.error(e.data.msg);
  491. }
  492. }).catch(e => {
  493. this.$message.error(e);
  494. this.btnLoading = false;
  495. })
  496. } else {
  497. this.btnLoading = false;
  498. return false;
  499. }
  500. });
  501. },
  502. }
  503. });
  504. </script>
  505. <style>
  506. .inp-text{
  507. color: #afacac;
  508. }
  509. .form_box {
  510. background-color: #f3f3f3;
  511. padding: 0 0 20px;
  512. }
  513. .button-item {
  514. margin-top: 12px;
  515. padding: 9px 25px;
  516. }
  517. .margin-button-20px {
  518. margin-bottom: 20px;
  519. }
  520. .time_last_consume{
  521. padding-top: 20px;
  522. }
  523. .el-input-group__append {
  524. background-color: #fff;
  525. color: #353535;
  526. }
  527. .el-form-item>div {
  528. margin: 0 !important;
  529. }
  530. .title {
  531. display: flex;
  532. align-items: center;
  533. font-size: 12px;
  534. padding-left: 50px;
  535. margin-bottom: 16px;
  536. }
  537. .title-one {
  538. padding-left: 29px;
  539. font-size: 15px;
  540. margin-right: 10px;
  541. }
  542. .segmentation {
  543. padding: 0 10px;
  544. font-size: 20px;
  545. }
  546. .inp {
  547. width: 140px;
  548. }
  549. .inp .el-input__inner {
  550. border-radius: 4px 0 0 4px;
  551. }
  552. .inp2 {
  553. width: 60px;
  554. }
  555. .inp-text {
  556. background: #EFEFEF;
  557. border: 1px solid #E3E2E5;
  558. font-size: 15px;
  559. padding: 0px 15px;
  560. border-radius: 0 4px 4px 0;
  561. height: 32px;
  562. }
  563. /* flex公共样式 */
  564. .flex {
  565. display: -webkit-box;
  566. display: -webkit-flex;
  567. display: flex;
  568. }
  569. .flex-x-center {
  570. display: -webkit-box;
  571. display: -webkit-flex;
  572. display: flex;
  573. -webkit-box-pack: center;
  574. -webkit-justify-content: center;
  575. -ms-flex-pack: center;
  576. justify-content: center;
  577. }
  578. .flex-x-between {
  579. display: -webkit-box;
  580. display: -webkit-flex;
  581. display: flex;
  582. -webkit-box-pack: space-between;
  583. -webkit-justify-content: space-between;
  584. -ms-flex-pack: space-between;
  585. justify-content: space-between;
  586. }
  587. .flex-y-center {
  588. display: -webkit-box;
  589. display: -webkit-flex;
  590. display: flex;
  591. -webkit-box-align: center;
  592. -webkit-align-items: center;
  593. -ms-flex-align: center;
  594. -ms-grid-row-align: center;
  595. align-items: center;
  596. }
  597. .flex-y-bottom {
  598. display: -webkit-box;
  599. display: -webkit-flex;
  600. display: flex;
  601. -webkit-box-align: end;
  602. -webkit-align-items: flex-end;
  603. -ms-flex-align: end;
  604. -ms-grid-row-align: flex-end;
  605. align-items: flex-end;
  606. }
  607. </style>