index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. <template>
  2. <view class="user-details">
  3. <!-- #ifdef MP || APP-PLUS -->
  4. <view class="accountTitle">
  5. <view :style="{ height: getHeight.barTop + 'px' }"></view>
  6. <view
  7. class="sysTitle acea-row row-center-wrapper"
  8. :style="{ height: getHeight.barHeight + 'px' }"
  9. >
  10. <view>用户详情</view>
  11. <text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
  12. </view>
  13. </view>
  14. <view
  15. :style="{ height: getHeight.barTop + getHeight.barHeight + 'px' }"
  16. ></view>
  17. <!-- #endif -->
  18. <view class="header">
  19. <view class="picTxt acea-row row-middle">
  20. <view class="pictrue">
  21. <image :src="infoData.avatar"></image>
  22. </view>
  23. <view class="text">
  24. <view class="name acea-row row-middle">
  25. <view class="nameCon line1">{{ infoData.nickname }}</view>
  26. <view
  27. class="svip acea-row row-center-wrapper"
  28. v-if="infoData.isMember == 1"
  29. >SVIP</view
  30. >
  31. <view
  32. class="vip acea-row row-center-wrapper"
  33. v-if="infoData.level_status == 1"
  34. >
  35. <text class="iconfont icon-huiyuandengji"></text>
  36. V{{ infoData.level_grade }}
  37. </view>
  38. </view>
  39. <view v-if="infoData.phone"
  40. >{{ infoData.phone }}(ID:{{ uid }})</view
  41. >
  42. <view v-else>ID:{{ uid }}</view>
  43. </view>
  44. </view>
  45. <view class="bottom acea-row row-middle">
  46. <view class="item"
  47. >消费金额<text class="num">{{
  48. infoData.order_total_price
  49. }}</text></view
  50. >
  51. <view class="item"
  52. >消费笔数<text class="num">{{
  53. infoData.order_total_count
  54. }}</text></view
  55. >
  56. </view>
  57. </view>
  58. <view class="list">
  59. <view class="title acea-row row-between-wrapper">
  60. <view class="name">用户信息</view>
  61. <view class="tip" @click="openTap"
  62. >{{ isShow ? "展开" : "收起"
  63. }}<text
  64. class="iconfont"
  65. :class="isShow ? 'icon-ic_downarrow' : 'icon-ic_uparrow'"
  66. ></text
  67. ></view>
  68. </view>
  69. <view class="item acea-row row-between-wrapper">
  70. <view>分组</view>
  71. <view>
  72. <picker
  73. @change="bindPickerChange"
  74. :value="groupIndex"
  75. :range="groupArray"
  76. range-key="group_name"
  77. >
  78. <view class="acea-row row-middle">
  79. <view v-if="groupArray.length">
  80. <text class="not" v-if="groupIndex == -1">无</text>
  81. <text v-else>{{ groupArray[groupIndex].group_name }}</text>
  82. </view>
  83. <text class="iconfont icon-ic_rightarrow"></text>
  84. </view>
  85. </picker>
  86. </view>
  87. </view>
  88. <view class="item acea-row row-between-wrapper">
  89. <view>等级</view>
  90. <view>
  91. <picker
  92. @change="bindLevelChange"
  93. :value="levelIndex"
  94. :range="levelArray"
  95. range-key="name"
  96. >
  97. <view class="acea-row row-middle">
  98. <view v-if="levelArray.length">
  99. <text class="not" v-if="levelIndex == -1">无</text>
  100. <text v-else>{{ levelArray[levelIndex].name }}</text>
  101. </view>
  102. <text class="iconfont icon-ic_rightarrow"></text>
  103. </view>
  104. </picker>
  105. </view>
  106. </view>
  107. <view class="item">
  108. <view class="acea-row row-between-wrapper">
  109. <view>标签</view>
  110. <view class="add" @click="editLabels"
  111. ><text class="iconfont icon-ic_increase"></text>添加标签</view
  112. >
  113. </view>
  114. <view
  115. class="labelList acea-row row-middle"
  116. v-if="infoData.label_id && infoData.label_id.length"
  117. >
  118. <view
  119. class="label"
  120. v-for="(item, index) in infoData.label_id"
  121. :key="index"
  122. >{{ item.label_name }}</view
  123. >
  124. </view>
  125. </view>
  126. <view class="listn" v-if="!isShow">
  127. <view
  128. class="item acea-row row-between-wrapper"
  129. v-if="infoData.real_name"
  130. >
  131. <view>姓名</view>
  132. <view class="info">{{ infoData.real_name }}</view>
  133. </view>
  134. <view
  135. class="item acea-row row-between-wrapper"
  136. v-if="infoData.birthday"
  137. >
  138. <view>出生年月</view>
  139. <view class="info">{{ infoData.birthday }}</view>
  140. </view>
  141. <view class="item acea-row row-between-wrapper" v-if="infoData.card_id">
  142. <view>身份证号</view>
  143. <view class="info">{{ infoData.card_id }}</view>
  144. </view>
  145. <view class="item acea-row row-between" v-if="infoData.addres">
  146. <view>地址</view>
  147. <view class="info">{{ infoData.addres }}</view>
  148. </view>
  149. <view
  150. class="item acea-row row-between-wrapper"
  151. v-if="infoData._add_time"
  152. >
  153. <view>注册时间</view>
  154. <view class="info">{{ infoData._add_time }}</view>
  155. </view>
  156. </view>
  157. </view>
  158. <view class="property">
  159. <view class="title">资产信息</view>
  160. <view class="info acea-row">
  161. <view class="item" @click="balanceTap(1)">
  162. <view>积分</view>
  163. <view class="bottom acea-row row-between-wrapper">
  164. <view class="num">{{ infoData.integral }}</view>
  165. <view class="iconfont icon-ic_edit"></view>
  166. </view>
  167. </view>
  168. <view class="item" @click="balanceTap(0)">
  169. <view>余额</view>
  170. <view class="bottom acea-row row-between-wrapper">
  171. <view class="num">{{ infoData.now_money }}</view>
  172. <view class="iconfont icon-ic_edit"></view>
  173. </view>
  174. </view>
  175. </view>
  176. <view class="info acea-row">
  177. <view class="item">
  178. <view class="acea-row row-between-wrapper">
  179. <view>优惠券</view>
  180. <view
  181. class="iconfont icon-ic_rightarrow"
  182. @click="couponSeeTap"
  183. ></view>
  184. </view>
  185. <view class="bottom acea-row row-between-wrapper">
  186. <view class="num">{{ infoData.coupon_num }}张</view>
  187. <view class="give" @click="couponTap">赠送</view>
  188. </view>
  189. </view>
  190. <view class="item" @click="memberTap">
  191. <view>会员</view>
  192. <view class="bottom acea-row row-between-wrapper">
  193. <view class="num" v-if="infoData.svip_over_day">{{
  194. "剩余" + infoData.svip_over_day + "天"
  195. }}</view>
  196. <view class="num" v-else>已过期/暂未开通</view>
  197. <view class="iconfont icon-ic_edit"></view>
  198. </view>
  199. </view>
  200. </view>
  201. </view>
  202. <edit-lable
  203. ref="lable"
  204. :visible="visibleLable"
  205. @closeDrawer="lableCloseDrawer"
  206. ></edit-lable>
  207. <edit-balance
  208. ref="balance"
  209. :visible="visibleBalance"
  210. :type="type"
  211. :uid="parseInt(uid)"
  212. @closeDrawer="balanceCloseDrawer"
  213. @successChange="successChange"
  214. ></edit-balance>
  215. <member
  216. ref="member"
  217. :visible="visibleMember"
  218. :userInfo="infoData"
  219. @closeDrawer="memberCloseDrawer"
  220. @successChange="successChange"
  221. ></member>
  222. <coupon
  223. ref="coupon"
  224. :visible="visibleCoupon"
  225. :uid="parseInt(uid)"
  226. @closeDrawer="couponCloseDrawer"
  227. ></coupon>
  228. </view>
  229. </template>
  230. <script>
  231. import editLable from "./components/userLable/index.vue";
  232. import editBalance from "./components/editBalance/index.vue";
  233. import member from "./components/member/index.vue";
  234. import coupon from "./components/coupon/index.vue";
  235. import {
  236. getUserInfo,
  237. getGroupList,
  238. getLevelList,
  239. postUserUpdateOther,
  240. } from "@/api/admin";
  241. export default {
  242. components: {
  243. editLable,
  244. editBalance,
  245. member,
  246. coupon,
  247. },
  248. data() {
  249. return {
  250. getHeight: this.$util.getWXStatusHeight(),
  251. uid: 0,
  252. infoData: {},
  253. groupArray: [],
  254. levelArray: [],
  255. groupIndex: -1,
  256. levelIndex: -1,
  257. visibleLable: false,
  258. visibleBalance: false,
  259. type: 0,
  260. visibleMember: false,
  261. visibleCoupon: false,
  262. isShow: false,
  263. };
  264. },
  265. onLoad(options) {
  266. this.uid = options.uid;
  267. this.userInfo(1);
  268. },
  269. methods: {
  270. openTap() {
  271. this.isShow = !this.isShow;
  272. },
  273. couponTap() {
  274. this.$refs.coupon.userCoupon(0);
  275. this.visibleCoupon = true;
  276. },
  277. couponSeeTap() {
  278. this.$refs.coupon.userCoupon(2);
  279. this.visibleCoupon = true;
  280. },
  281. couponCloseDrawer(e) {
  282. this.visibleCoupon = false;
  283. if (e) {
  284. this.userInfo();
  285. }
  286. },
  287. memberTap() {
  288. this.visibleMember = true;
  289. },
  290. memberCloseDrawer() {
  291. this.visibleMember = false;
  292. },
  293. balanceTap(type) {
  294. this.type = type;
  295. this.visibleBalance = true;
  296. },
  297. successChange() {
  298. this.visibleBalance = false;
  299. this.visibleMember = false;
  300. this.userInfo();
  301. },
  302. balanceCloseDrawer() {
  303. this.visibleBalance = false;
  304. },
  305. lableCloseDrawer(e) {
  306. this.visibleLable = false;
  307. if (e) {
  308. this.userInfo();
  309. }
  310. },
  311. editLabels() {
  312. this.visibleLable = true;
  313. this.$refs.lable.productLabel(
  314. JSON.parse(JSON.stringify(this.infoData)),
  315. 0,
  316. []
  317. );
  318. },
  319. bindPickerChange(e) {
  320. this.groupIndex = e.detail.value;
  321. this.userUpdate(5);
  322. },
  323. bindLevelChange(e) {
  324. this.levelIndex = e.detail.value;
  325. this.userUpdate(1);
  326. },
  327. userUpdate(num) {
  328. let data = {};
  329. if (num == 5) {
  330. data = {
  331. type: 5,
  332. group_id: this.groupArray[this.groupIndex].id,
  333. };
  334. } else {
  335. data = {
  336. type: 2,
  337. level: this.levelArray[this.levelIndex].id,
  338. };
  339. }
  340. postUserUpdateOther(this.uid, data)
  341. .then((res) => {
  342. this.$util.Tips({
  343. title: res.msg,
  344. });
  345. })
  346. .catch((err) => {
  347. this.$util.Tips({
  348. title: err,
  349. });
  350. });
  351. },
  352. levelList() {
  353. getLevelList()
  354. .then((res) => {
  355. let id = this.infoData.level;
  356. res.data.list.forEach((item, index) => {
  357. if (item.id == id) {
  358. this.levelIndex = index;
  359. }
  360. });
  361. this.levelArray = res.data.list;
  362. })
  363. .catch((err) => {
  364. this.$util.Tips({
  365. title: err,
  366. });
  367. });
  368. },
  369. groupList() {
  370. getGroupList()
  371. .then((res) => {
  372. let id = this.infoData.group_id;
  373. res.data.forEach((item, index) => {
  374. if (item.id == id) {
  375. this.groupIndex = index;
  376. }
  377. });
  378. this.groupArray = res.data;
  379. })
  380. .catch((err) => {
  381. this.$util.Tips({
  382. title: err,
  383. });
  384. });
  385. },
  386. goarrow() {
  387. uni.navigateBack();
  388. },
  389. userInfo(num) {
  390. getUserInfo(this.uid)
  391. .then((res) => {
  392. this.infoData = res.data;
  393. if (num) {
  394. this.groupList();
  395. this.levelList();
  396. }
  397. })
  398. .catch((err) => {
  399. this.$util.Tips({
  400. title: err,
  401. });
  402. });
  403. },
  404. },
  405. };
  406. </script>
  407. <style lang="scss" scoped>
  408. .accountTitle {
  409. background: linear-gradient(
  410. 270deg,
  411. $gradient-primary-admin 0%,
  412. $primary-admin 100%
  413. );
  414. position: fixed;
  415. left: 0;
  416. top: 0;
  417. width: 100%;
  418. z-index: 99;
  419. .sysTitle {
  420. width: 100%;
  421. position: relative;
  422. font-weight: 500;
  423. color: #fff;
  424. font-size: 30rpx;
  425. .iconfont {
  426. position: absolute;
  427. font-size: 39rpx;
  428. left: 11rpx;
  429. width: 60rpx;
  430. font-weight: 600;
  431. }
  432. }
  433. }
  434. .user-details {
  435. padding-bottom: 1rpx;
  436. padding-bottom: calc(
  437. 1rpx + constant(safe-area-inset-bottom)
  438. ); ///兼容 IOS<11.2/
  439. padding-bottom: calc(1rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  440. .header {
  441. background: linear-gradient(
  442. 270deg,
  443. $gradient-primary-admin 0%,
  444. $primary-admin 100%
  445. );
  446. height: 346rpx;
  447. padding: 20rpx 30rpx 0 30rpx;
  448. position: relative;
  449. .picTxt {
  450. .pictrue {
  451. width: 112rpx;
  452. height: 112rpx;
  453. image {
  454. width: 100%;
  455. height: 100%;
  456. border-radius: 50%;
  457. }
  458. }
  459. .text {
  460. margin-left: 32rpx;
  461. font-size: 24rpx;
  462. font-family: PingFang SC, PingFang SC;
  463. font-weight: 400;
  464. color: rgba(255, 255, 255, 0.5);
  465. .name {
  466. margin-bottom: 12rpx;
  467. .nameCon {
  468. font-size: 32rpx;
  469. color: #fff;
  470. max-width: 300rpx;
  471. }
  472. .svip {
  473. width: 56rpx;
  474. height: 26rpx;
  475. background: linear-gradient(270deg, #484643 0%, #1f1b17 100%);
  476. border-radius: 14rpx;
  477. font-size: 18rpx;
  478. font-weight: 600;
  479. color: #fddaa4;
  480. margin-left: 12rpx;
  481. }
  482. .vip {
  483. width: 68rpx;
  484. height: 26rpx;
  485. background: #fef0d9;
  486. margin-left: 12rpx;
  487. border-radius: 50rpx;
  488. font-size: 18rpx;
  489. font-weight: 500;
  490. color: #dfa541;
  491. .iconfont {
  492. font-size: 20rpx;
  493. margin-right: 4rpx;
  494. }
  495. }
  496. }
  497. }
  498. }
  499. .bottom {
  500. font-size: 26rpx;
  501. font-family: PingFang SC, PingFang SC;
  502. font-weight: 400;
  503. color: rgba(255, 255, 255, 0.8);
  504. margin-top: 40rpx;
  505. .item {
  506. margin-right: 44rpx;
  507. .num {
  508. margin-left: 8rpx;
  509. color: #ffffff;
  510. }
  511. }
  512. }
  513. &::after {
  514. position: absolute;
  515. content: "";
  516. width: 50%;
  517. height: 88rpx;
  518. background: linear-gradient(180deg, $primary-admin 0%, #f5f5f5 100%);
  519. left: 0;
  520. bottom: 0;
  521. }
  522. &::before {
  523. position: absolute;
  524. content: "";
  525. width: 50%;
  526. height: 88rpx;
  527. background: linear-gradient(
  528. 180deg,
  529. $gradient-primary-admin 0%,
  530. #f5f5f5 100%
  531. );
  532. right: 0;
  533. bottom: 0;
  534. }
  535. }
  536. .list {
  537. width: 710rpx;
  538. background-color: #fff;
  539. border-radius: 24rpx;
  540. margin: -96rpx auto 0 auto;
  541. position: relative;
  542. font-family: PingFang SC, PingFang SC;
  543. color: #333333;
  544. padding: 32rpx 24rpx 40rpx 24rpx;
  545. .title {
  546. margin-bottom: 40rpx;
  547. .name {
  548. font-size: 30rpx;
  549. font-weight: 600;
  550. }
  551. .tip {
  552. font-size: 26rpx;
  553. font-weight: 400;
  554. color: #999999;
  555. .iconfont {
  556. font-size: 22rpx;
  557. margin-left: 4rpx;
  558. }
  559. }
  560. }
  561. .listn {
  562. margin-top: 52rpx;
  563. }
  564. .item {
  565. font-weight: 400;
  566. & ~ .item {
  567. margin-top: 52rpx;
  568. }
  569. .not {
  570. color: #999;
  571. }
  572. .iconfont {
  573. font-size: 26rpx;
  574. color: #999;
  575. margin-left: 6rpx;
  576. }
  577. .info {
  578. color: #999999;
  579. width: 465rpx;
  580. text-align: right;
  581. }
  582. .add {
  583. font-size: 24rpx;
  584. color: $primary-admin;
  585. .iconfont {
  586. margin-right: 8rpx;
  587. color: $primary-admin;
  588. }
  589. }
  590. .labelList {
  591. margin-top: 12rpx;
  592. .label {
  593. border: 1px solid $primary-admin;
  594. border-radius: 20rpx;
  595. font-size: 20rpx;
  596. color: $primary-admin;
  597. padding: 4rpx 16rpx;
  598. margin-right: 16rpx;
  599. margin-top: 16rpx;
  600. }
  601. }
  602. }
  603. }
  604. .property {
  605. width: 710rpx;
  606. background-color: #fff;
  607. border-radius: 24rpx;
  608. margin: 20rpx auto;
  609. font-family: PingFang SC, PingFang SC;
  610. .title {
  611. font-size: 30rpx;
  612. font-family: PingFang SC, PingFang SC;
  613. font-weight: 600;
  614. color: #333333;
  615. padding: 32rpx 24rpx 2rpx 24rpx;
  616. margin-bottom: 32rpx;
  617. }
  618. .info {
  619. margin: 0 26rpx;
  620. .item {
  621. width: 50%;
  622. font-size: 28rpx;
  623. font-weight: 400;
  624. color: #999999;
  625. padding: 10rpx 40rpx 40rpx 18rpx;
  626. & ~ .item {
  627. border-left: 1px solid #eeeeee;
  628. padding-left: 40rpx;
  629. padding-right: 14rpx;
  630. }
  631. .bottom {
  632. margin-top: 20rpx;
  633. .num {
  634. font-size: 30rpx;
  635. font-weight: 600;
  636. color: #333333;
  637. }
  638. .give {
  639. font-size: 24rpx;
  640. font-weight: 400;
  641. color: $primary-admin;
  642. padding-left: 40rpx;
  643. }
  644. }
  645. .icon-ic_rightarrow {
  646. font-size: 26rpx;
  647. padding: 6rpx 0 6rpx 40rpx;
  648. }
  649. }
  650. & ~ .info {
  651. border-top: 1px solid #eeeeee;
  652. .item {
  653. padding-top: 40rpx;
  654. }
  655. }
  656. }
  657. }
  658. }
  659. </style>