members.vue 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. <template>
  2. <div class="main-contain">
  3. <div class="position">
  4. <bread-crumb :crumbs='crumbs'></bread-crumb>
  5. <el-button style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加会员</el-button>
  6. </div>
  7. <div class="app-container">
  8. <div style="margin-bottom: 10px">
  9. <el-row :gutter="24">
  10. <el-col :span="8">
  11. <el-input style="width: 300px" v-model="listQuery.search" placeholder="请输入您需要搜索的内容"></el-input>
  12. <el-button type="primary" icon="el-icon-search" @click="changeKey">搜索</el-button>
  13. </el-col>
  14. </el-row>
  15. </div>
  16. <div class="cell clearfix">
  17. <label class="title"> <span class="name">创建时间</span>: </label>
  18. <el-date-picker v-model="listQuery.start_time" prefix-icon="el-icon-date" @change="changeTime" :editable="false" style="width: 196px;" type="date" placeholder="选择日期时间"
  19. align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
  20. <span class>-</span>
  21. <el-date-picker v-model="listQuery.end_time" prefix-icon="el-icon-date" @change="changeTime" :editable="false" style="width: 196px;" type="date" placeholder="选择日期时间"
  22. align="right" format="yyyy-MM-dd" value-format="yyyy-MM-dd" ></el-date-picker>
  23. </div>
  24. <div class="cell clearfix">
  25. <label class="title"><span class="name">等级</span>:</label>
  26. <div class="time">
  27. <ul class="">
  28. <li :class="0==levelType?'active':''" @click="selectLevel(0)">全部</li>
  29. <li :class="item.id==levelType?'active':''" v-for="item in levelCards" :key="item.id" @click="selectLevel(item.id)">{{item.card_name}}</li>
  30. </ul>
  31. </div>
  32. </div>
  33. <div class="cell clearfix">
  34. <label class="title"><span class="name">来源方式</span>:</label>
  35. <div class="time">
  36. <ul class="">
  37. <li :class="0==sourceType?'active':''" @click="selectSource(0)">全部</li>
  38. <li :class="item.id==sourceType?'active':''" v-for="item in sourceOptions" :key="item.id" @click="selectSource(item.id)">{{item.name}}</li>
  39. </ul>
  40. </div>
  41. </div>
  42. <div class="cell clearfix">
  43. <label class="title"><span class="name">标签</span>:</label>
  44. <div class="time">
  45. <ul class="">
  46. <li :class="0==tagType?'active':''" @click="selectTag(0)">全部</li>
  47. <li :class="item.id==tagType?'active':''" v-for="item in tagOptions" :key="item.id" @click="selectTag(item.id)">{{item.tag_name}}</li>
  48. </ul>
  49. </div>
  50. </div>
  51. <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
  52. <el-checkbox style="width: 30px" @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
  53. <el-button size="small" icon="el-icon-delete" @click="openDeleteMembers">批量删除</el-button>
  54. <el-button size="small" icon="el-icon-edit" @click="openAddMembersTags">添加标签</el-button>
  55. <el-button size="small" icon="el-icon-message" @click="openSendMessage">发送短信</el-button>
  56. </div>
  57. <el-table ref="multipleTable" @selection-change="handleSelectionChange" :cell-class-name="cellStyleName" :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="membersData" border fit highlight-current-row style="width: 100%;margin-top: 10px;">
  58. <el-table-column
  59. align="center"
  60. type="selection"
  61. width="55">
  62. </el-table-column>
  63. <el-table-column label="会员" align="center" >
  64. <template slot-scope="scope">
  65. <div style="display:flex;align-items: center;">
  66. <img :src="memberAvatar(scope.row)" alt="" srcset="" style="width:50px;height:50px; border-radius:50%;margin-right:5px;" >
  67. <div>
  68. <span>{{scope.row.name}}</span>
  69. </div>
  70. </div>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="等级" align="center">
  74. <template slot-scope="scope">
  75. <img v-if="scope.row.user_card && scope.row.user_card.card" :src="vip" alt="" srcset="" style="width:16px;height:16px;margin-bottom: -2px;" >
  76. <span>{{memberLevel(scope.row)}}</span>
  77. </template>
  78. </el-table-column>
  79. <el-table-column label="标签" align="center">
  80. <template slot-scope="scope">
  81. <el-tag size="small" v-for="(tag, index) in scope.row.tags" :key="index">{{tag.tag_name}}</el-tag>
  82. </template>
  83. </el-table-column>
  84. <el-table-column label="创建时间" align="center">
  85. <template slot-scope="scope">
  86. <span>{{memberCreateTime(scope.row.created_time)}}</span>
  87. </template>
  88. </el-table-column>
  89. <el-table-column label="来源方式" align="center">
  90. <template slot-scope="scope">
  91. <span>{{memberSource(scope.row.sources)}}</span>
  92. </template>
  93. </el-table-column>
  94. <el-table-column label="操作" align="center">
  95. <template slot-scope="scope">
  96. <el-tooltip class="item" effect="dark" content="编辑" placement="top">
  97. <el-button size="mini" type="primary" icon="el-icon-edit-outline" @click="openEdit(scope.row, scope.$index)" ></el-button>
  98. </el-tooltip>
  99. <el-tooltip class="item" effect="dark" content="标签" placement="top">
  100. <el-button size="mini" type="warning" icon="el-icon-edit" @click="openTags(scope.row, scope.$index)" ></el-button>
  101. </el-tooltip>
  102. <el-tooltip class="item" effect="dark" content="会员卡" placement="top">
  103. <el-button size="mini" type="success" icon="el-icon-tickets" @click="openCard(scope.row, scope.$index)" ></el-button>
  104. </el-tooltip>
  105. <el-tooltip class="item" effect="dark" content="删除" placement="top">
  106. <el-button size="mini" type="danger" icon="el-icon-delete" @click="openDelete(scope.row, scope.$index)" ></el-button>
  107. </el-tooltip>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. <el-pagination
  112. @size-change="handleSizeChange"
  113. @current-change="handleCurrentChange"
  114. :page-sizes="[10,20,50,100]"
  115. :page-size="10"
  116. background
  117. style="margin-top:20px;"
  118. align="right"
  119. layout="total, sizes, prev, pager, next, jumper"
  120. :total="total">
  121. </el-pagination>
  122. <!--create-member-form 添加会员-->
  123. <create-member-form ref="createMemberForm" :levelCards="levelCards" :membersData="membersData" :illnessOptions="illnessOptions" :treatTypeOptions="treatTypeOptions" :tagOptions="tagOptions"></create-member-form>
  124. <!--edit-member-form 编辑会员-->
  125. <edit-member-form ref="editMemberForm" :levelCards="levelCards" :memberIndex="memberIndex" :form="memberData" :membersData="membersData" :illnessOptions="illnessOptions" :treatTypeOptions="treatTypeOptions" :tagOptions="tagOptions"></edit-member-form>
  126. <!--edit-member-tags-form 为单个会员编辑标签-->
  127. <edit-member-tags-form ref="editMemberTagsForm" :memberIndex="memberIndex" :form="memberData" :membersData="membersData" :tagOptions="tagOptions"></edit-member-tags-form>
  128. <!--add-members-tags-form 为所选会员添加标签-->
  129. <add-members-tags-form ref="addMembersTagsForm" :form="memberData" :membersData="membersData" :tagOptions="tagOptions"></add-members-tags-form>
  130. <!--edit-member-card-form 为单个会员设置会员卡-->
  131. <edit-member-card-form ref="editMemberCardForm" :form="cardFormData" :memberIndex="memberIndex" :membersData="membersData" :cardOptions="levelCards"></edit-member-card-form>
  132. </div>
  133. </div>
  134. </template>
  135. <script>
  136. import {GetMembers,DeleteMembers} from "@/api/member/member";
  137. import BreadCrumb from '../components/bread-crumb'
  138. import {uParseTime} from "@/utils/tools";
  139. import CreateMemberForm from "./components/CreateMemberForm";
  140. import EditMemberForm from "./components/EditMemberForm";
  141. import EditMemberTagsForm from "./components/EditMemberTagsForm";
  142. import AddMembersTagsForm from "./components/AddMembersTagsForm";
  143. import EditMemberCardForm from "./components/EditMemberCardForm";
  144. export default {
  145. name: 'commentList',
  146. components:{
  147. BreadCrumb,
  148. CreateMemberForm,
  149. EditMemberForm,
  150. EditMemberTagsForm,
  151. AddMembersTagsForm,
  152. EditMemberCardForm,
  153. },
  154. data(){
  155. return{
  156. crumbs: [
  157. { path: false, name: '会员管理' },
  158. { path: false, name: '会员列表' }
  159. ],
  160. time: '',
  161. vip:'https://images.shengws.com/member-ship-card-vip.png',
  162. checkAllStatus:false,
  163. active: true,
  164. levelType: 0,
  165. levelCards:[],
  166. sourceType: 0,
  167. sourceOptions:{},
  168. treatTypeOptions:{},
  169. tagType: 0,
  170. tagOptions:[],
  171. membersData:[],
  172. illnessOptions:[],
  173. memberData:{
  174. name:'',
  175. mobile:'',
  176. gender:0,
  177. birthday:'',
  178. city:[],
  179. province_id:0,
  180. city_id:0,
  181. district_id:0,
  182. illness:[],
  183. ill_date:'',
  184. treat_type:'',
  185. tags:[],
  186. remark:'',
  187. avatar:'',
  188. id:0,
  189. ids:[],
  190. },
  191. cardFormData:{
  192. id:0,
  193. card_id:''
  194. },
  195. selectedMembers:[],
  196. memberIndex:-1,
  197. total:0,
  198. listQuery:{
  199. page:1,
  200. limit:10,
  201. search:'',
  202. start_time:'',
  203. end_time:'',
  204. source:0,
  205. tag:0,
  206. level:0,
  207. init:1,
  208. },
  209. }
  210. },
  211. methods:{
  212. GetMembers(){
  213. GetMembers(this.listQuery).then(response=>{
  214. var res = response.data;
  215. console.log("res是谁?",res)
  216. if(res.state == 1) {
  217. this.membersData = res.data.members;
  218. this.total = res.data.total;
  219. if(typeof(res.data.cards) != 'undefined') {
  220. this.levelCards = res.data.cards;
  221. }
  222. if(typeof(res.data.tags) != 'undefined') {
  223. this.tagOptions = res.data.tags;
  224. }
  225. if(typeof(res.data.illness) != 'undefined') {
  226. this.illnessOptions = res.data.illness;
  227. }
  228. this.listQuery.init = 0;
  229. }else {
  230. this.$message.error(res.msg);
  231. }
  232. }).catch(e=>{});
  233. },
  234. openSendMessage(){
  235. this.$message.error("功能开发中...");
  236. return false;
  237. if (this.selectedMembers.length==0) {
  238. this.$message.error("请选择要发送短信的会员");
  239. return false;
  240. }
  241. },
  242. openAddMembersTags() {
  243. if (this.selectedMembers.length==0) {
  244. this.$message.error("请选择要添加标签的会员");
  245. return false;
  246. }
  247. this.memberData.tags = [];
  248. this.memberData.ids = [];
  249. for (const index in this.selectedMembers) {
  250. this.memberData.ids.push(this.selectedMembers[index].id);
  251. }
  252. this.$refs.addMembersTagsForm.open();
  253. },
  254. openDeleteMembers(){
  255. if (this.selectedMembers.length==0) {
  256. this.$message.error("请选择要删除的会员");
  257. return false;
  258. }
  259. this.$confirm('确认要删除所选的会员吗?<br>删除后,会员信息将无法恢复', '删除提示', {
  260. dangerouslyUseHTMLString:true,
  261. confirmButtonText: '确定',
  262. cancelButtonText: '取消',
  263. type: 'warning'
  264. }).then(() => {
  265. var ids = [];
  266. var idMap = {};
  267. for (const index in this.selectedMembers) {
  268. ids.push(this.selectedMembers[index].id);
  269. idMap[this.selectedMembers[index].id] = this.selectedMembers[index].id;
  270. }
  271. DeleteMembers({ids:ids}).then(response=>{
  272. var res = response.data;
  273. if (res.state === 1) {
  274. var membersDataLength = this.membersData.length;
  275. for (let index = membersDataLength-1; index >= 0; index--) {
  276. if(this.membersData[index].id in idMap) {
  277. this.membersData.splice(index, 1);
  278. }
  279. }
  280. this.$message.success("删除会员成功");
  281. }else {
  282. this.$message.error(res.msg);
  283. }
  284. }).catch(e=>{});
  285. }).catch(() => {
  286. return false
  287. });
  288. },
  289. openDelete(row, index) {
  290. this.$confirm('确认要删除该会员吗?<br>删除后,该会员信息将无法恢复', '删除提示', {
  291. dangerouslyUseHTMLString:true,
  292. confirmButtonText: '确定',
  293. cancelButtonText: '取消',
  294. type: 'warning'
  295. }).then(() => {
  296. var ids = [];
  297. ids.push(row.id);
  298. DeleteMembers({ids:ids}).then(response=>{
  299. var res = response.data;
  300. if (res.state === 1) {
  301. this.membersData.splice(index, 1);
  302. this.$message.success("删除会员成功");
  303. }else {
  304. this.$message.error(res.msg);
  305. }
  306. }).catch(e=>{});
  307. }).catch(() => {
  308. return false
  309. });
  310. },
  311. openCard(row, index){
  312. this.cardFormData.id = row.id;
  313. this.cardFormData.card_id = '';
  314. this.memberIndex = index;
  315. if (row.user_card && row.user_card.card) {
  316. this.cardFormData.card_id = row.user_card.card_id;
  317. }
  318. this.$refs.editMemberCardForm.open();
  319. },
  320. openTags(row, index) {
  321. this.memberData.tags = [];
  322. this.memberData.id = row.id;
  323. let tags = row.tags;
  324. for (const index in tags) {
  325. this.memberData.tags.push(tags[index].id);
  326. }
  327. this.memberIndex = index;
  328. this.$refs.editMemberTagsForm.open();
  329. },
  330. openEdit(row, index){
  331. this.memberData.illness = [];
  332. this.memberData.city = [];
  333. this.memberData.birthday = '';
  334. this.memberData.ill_date = '';
  335. this.memberData.treat_type = '';
  336. for (const key in this.memberData) {
  337. if (key === "illness" && row.illness) {
  338. let illness = row.illness;
  339. for (const index in illness) {
  340. this.memberData.illness.push(illness[index].illness_id);
  341. }
  342. } else if (key === "tags" && row.tags) {
  343. let tags = row.tags;
  344. for (const index in tags) {
  345. this.memberData.tags.push(tags[index].id);
  346. }
  347. } else if (key === "treat_type" && row.treat_type>0) {
  348. this.memberData.treat_type = row.treat_type;
  349. } else if (key === "city") {
  350. if (row.province_id > 0) {
  351. this.memberData.city.push(row.province_id);
  352. this.memberData.city.push(row.city_id);
  353. this.memberData.city.push(row.district_id);
  354. }
  355. } else if (key === "birthday" && row.birthday!=0) {
  356. this.memberData.birthday = uParseTime(row.birthday, "{y}-{m}-{d}");
  357. } else if (key === "ill_date" && row.ill_date!=0) {
  358. this.memberData.ill_date = uParseTime(row.ill_date, "{y}-{m}-{d}");
  359. } else if (key in row) {
  360. this.memberData[key] = row[key];
  361. }
  362. }
  363. // this.memberData = row;
  364. this.memberIndex = index;
  365. this.$refs.editMemberForm.open();
  366. },
  367. openCreate(){
  368. this.$refs.createMemberForm.open();
  369. },
  370. memberAvatar(row) {
  371. if(typeof(row.avatar) == "undefined" || !row.avatar || row.avatar.length==0) {
  372. if(row.gender == 2) {
  373. return 'https://images.shengws.com/201809182128222.png';
  374. }else {
  375. return 'https://images.shengws.com/201809182128111.png';
  376. }
  377. }else {
  378. return row.avatar
  379. }
  380. },
  381. memberLevel(row) {
  382. if(row.user_card && row.user_card.card) {
  383. return row.user_card.card.card_name;
  384. } else {
  385. return '普通会员'
  386. }
  387. },
  388. memberCreateTime(time) {
  389. return uParseTime(time, "{y}-{m}-{d} {h}:{i}:{s}");
  390. },
  391. memberSource(source) {
  392. if (source in this.sourceOptions) {
  393. return this.sourceOptions[source].name;
  394. }else {
  395. return '--';
  396. }
  397. },
  398. changeCheck(){
  399. this.$refs.multipleTable.clearSelection();
  400. if (this.checkAllStatus) {
  401. this.$refs.multipleTable.toggleAllSelection();
  402. }
  403. },
  404. handleSelectionChange(val){
  405. this.selectedMembers = val;
  406. },
  407. cellStyleName({row, column, rowIndex, columnIndex}){
  408. if (columnIndex===1) {
  409. return 'member-name-box';
  410. }
  411. return '';
  412. },
  413. selectSource(id) {
  414. this.listQuery.source = id;
  415. this.sourceType = id;
  416. this.GetMembers();
  417. },
  418. selectLevel(id) {
  419. this.listQuery.level = id;
  420. this.levelType = id;
  421. this.GetMembers();
  422. },
  423. selectTag(id) {
  424. this.listQuery.tag = id;
  425. this.tagType = id;
  426. this.GetMembers();
  427. },
  428. changeKey(){
  429. this.GetMembers();
  430. },
  431. changeTime(){
  432. this.GetMembers();
  433. },
  434. handleSizeChange(limit) {
  435. this.listQuery.limit = limit;
  436. this.GetMembers();
  437. },
  438. handleCurrentChange(page) {
  439. this.listQuery.page = page;
  440. this.GetMembers();
  441. }
  442. },
  443. created(){
  444. this.sourceOptions = this.$store.getters.members.sources;
  445. this.treatTypeOptions = this.$store.getters.members.treat_type;
  446. this.GetMembers();
  447. }
  448. }
  449. </script>
  450. <style scoped>
  451. .el-tag {
  452. margin: 1px;
  453. }
  454. /*.app-container .cell.clearfix .time ul li {*/
  455. /*float: left;*/
  456. /*list-style: none;*/
  457. /*cursor: pointer;*/
  458. /*padding: 6px 20px;*/
  459. /*color: #606266;*/
  460. /*border-radius: 4px;*/
  461. /*margin: 0 8px 0 0;*/
  462. /*font-size: 14px;*/
  463. /*text-align: center;*/
  464. /*}*/
  465. </style>
  466. <style>
  467. .member-name-box .cell{
  468. float: left;
  469. text-align: left;
  470. };
  471. </style>