uni-app 25后端api开发和前后端交互(51-60)

简介: uni-app 25后端api开发和前后端交互(51-60)

51待处理好友申请数量提示

先看效果图

/pages/babbar/mail/mail.vue

<template>
  <view>
    <!-- 导航栏 -->
    <free-nav-bar title="通讯录"></free-nav-bar>
    <!-- 通讯录列表 -->
      <scroll-view scroll-y="true" :style="'height:'+scrollHeight+'px;'"  :scroll-into-view="scrollInto">
        <free-list-item v-for="(item,index) in topList" :key="item.id"  :title="item.title" :cover="item.cover" :showRight="item.id==='friend'"  @click=""  :showRightIcon='false'>
          <free-badge slot="right" :value="applyCount"></free-badge>
        </free-list-item>
        
        <view v-for="(item,index) in list" :key="index" v-if="item.data.length>0" :id="'item-'+item.letter">
          <view class="py-2 px-3 border-bottom bg-light">
            <text class="font-md text-dark">{{item.letter}}</text>
          </view>
          <free-list-item v-for="(item2,index2) in item.data" :key="index2"  :title="item2" cover="/static/images/mail/friend.png" @click=""></free-list-item>
        </view>
      </scroll-view>
      <!-- 侧边导航条 -->
      <view class="position-fixed right-0 bottom-0 flex  flex-column" :style="'top:'+top+'rpx;'" style="width: 50rpx;" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" >
        <view class="flex-1 flex align-center justify-center" v-for="(item,index) in list" :key="index">
          <text class="font-sm text-muted">{{item.letter}}</text>
        </view>
      </view>
      
      <!-- <block v-if="current"> -->
      <view class="position-fixed rounded-circle bg-light border flex align-center justify-center" style="width: 150rpx;height: 150rpx; left: 300rpx;" :style="'top:'+modalTop+'px;'" v-if="current!=''">
        <text class="font-lg" >{{current}}</text>
      </view>
      <!-- </block> -->
  </view>
</template>
<script>
  import freeNavBar from "@/components/free-ui/free-nav-bar.vue";
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeBadge from '@/components/free-ui/free-badge.vue';
  import { mapState } from 'vuex'; 
  import auth from '@/common/mixin/auth.js';
  export default {
    mixins:[auth],
    components:{
      freeNavBar,
      freeListItem,
      freeBadge
    },
    computed:{
      ...mapState({
        applyCount:state=>state.user.apply.count
      }),
      modalTop(){
        return (this.scrollHeight-uni.upx2px(150))/2;
      },
      itemHeight(){
        let count = this.list.length;
        if(count<1){
          return 0;
        }
        return this.scrollHeight/count;
      }
    },
    onLoad() {
      let res = uni.getSystemInfoSync();
      this.top = res.statusBarHeight + uni.upx2px(90);
      this.scrollHeight = res.windowHeight-this.top;
    },
    data() {
      return {
        scrollInto:'',
        top:0,
        scrollHeight:0,
        current:'',
        topList:[
          {
            id:'friend',
            title:"新的朋友",
            cover:"/static/images/mail/friend.png",
            event:""
          },
          {
            id:'group',
            title:"群聊",
            cover:"/static/images/mail/group.png",
            event:""
          },
          {
            id:'tag',
            title:"标签",
            cover:"/static/images/mail/tag.png",
            event:""
          }
        ],
        list:[{
          "letter":"A",
          "data":[
            "阿苏",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉",
            "阿拉"
          ]
        },{
          "letter":"B",
          "data":[
            "baba",
            "霸占",
            "吧拉"
          ]
        },
        {
          "letter":"C",
          "data":[
            "吃好",
            "车霸占",
            "才吧拉"
          ]
        },
        {
          "letter":"D",
          "data":[
            "Dd",
            "dd",
            "滴滴滴"
          ]
        }]
      }
    },
    methods: {
      touchstart(e){
        this.changeScrollInto(e);
      },
      touchmove(e){
        this.changeScrollInto(e);
      },
      touchend(){
        this.current = '';
      },
      // 联动
      changeScrollInto(e){
        // let Y = e.touches[0].pageY;
        // let index = Math.floor(Y / this.itemHeight);
        // let item = this.list[index];
        // if(item){
        //  this.scrollInto = 'item-'+item.letter;
        //  this.current = item.letter;
        // }
        
        let Y = e.touches[0].pageY
      
        // #ifdef MP
          Y = Y - this.top
        // #endif
        
        let index = Math.floor(Y / this.itemHeight)
        let item = this.list[index]
        if(item){
          this.scrollInto = 'item-'+item.letter
          this.current = item.letter
        }
      }
    }
  }
</script>
<style>
</style>

vuex中的/sotre/module/user.js

import $U from '@/common/free-lib/util.js';
import $H from '@/common/free-lib/request.js';
export default{
  state:{
    user:false,
    apply:{
      rows:[],
      count:0,
    }
  },
  actions:{
    // 登录后处理
    login({state,dispatch},user){
      // 存到状态种
      state.user=user;
      // 存储到本地存储中
      $U.setStorage('token',user.token);
      $U.setStorage('user',JSON.stringify(user));
      $U.setStorage('user_id',user.id);
      // 更新角标提示
      dispatch('updateMailBadge');
    },
    // 退出登录
    logout({state}){
      // 清除登录状态
      state.user = false;
      // 清除本地存储数据
      $U.removeStorage('token');
      $U.removeStorage('user');
      $U.removeStorage('user_id');
      // 跳转到登录页
      uni.reLaunch({
        url:'/pages/common/login/login'
      })
    },
    // 初始化登录状态
    initLogin({ state,dispatch }){
      // 拿到存储的数据
      let user = $U.getStorage('user');
      if(user){
        // 初始化登录状态
        state.user=JSON.parse(user);
          // 连接socket
        // 获取离线信息
        // 获取好友申请列表
        dispatch('getApply');
      }
    },
    // 获取好友申请列表
    getApply({ state,dispatch },page=1){
      $H.get('/apply/'+page).then(res=>{
        console.log(res);
        state.apply = res;
        
        // 更新通讯录角标提示
        dispatch('updateMailBadge');
      });
    },
    // 更新通讯录角标提示
    updateMailBadge({ state }){
      let count = state.apply.count > 99 ? '99+' : state.apply.count.toString();
      console.log(state.apply.count);
      if(state.apply.count>0){
        return uni.setTabBarBadge({
          index:1,
          text:count
        })
      }
      
      uni.removeTabBarBadge({
        index:1
      })
      
    }
  },
}

52待处理好友申请列表(一)

先看效果图

下面是apply-list.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="好友申请列表" showBack :showRight="false">
    </free-nav-bar>
    
    <free-list-item v-for="(item,index) in applyList" :key="index" :title="item.user.nickname ? item.user.nickname : item.user.username" :cover="item.user.avatar ? item.user.avatar : '/static/images/userpic.png'" :showRight="true" :showRightIcon="false">
      <free-main-button slot="right" v-if="item.status==='pending'" name="同意"></free-main-button>
      <text slot="right" v-else class="text-muted font-sm">{{item|formatTitle}}</text>
    </free-list-item>
  </view>
</template>
<script>
  import freeMainButton from '@/components/free-ui/free-main-button.vue';
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import $H from '@/common/free-lib/request.js';
  import auth from '@/common/mixin/auth.js';
  import { mapState } from 'vuex';
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeMainButton,
      freeListItem,
      freeDivider
    },
    filters:{
      formatTitle(value){
        let obj = {
          agree:'已通过',
          refuse:'已拒绝',
          ignore:'已忽略'
        }
        return obj[value.status];
      }
    },
    computed:{
      ...mapState({
        applyList:state=>state.user.apply.rows
      })
    },
    data() {
      return {
        form:{
          friend_id:0,
          nickname:"",
          lookme:1,
          lookhim:1
        },
        id:0
      }
    },
    onLoad(e) {
      
    },
    methods: {
      
    }
  }
</script>
<style>
</style>

53待处理好友申请列表(二)

直接看效果图

apply-list.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="好友申请列表" showBack :showRight="false">
    </free-nav-bar>
    
    <free-list-item v-for="(item,index) in applyList" :key="index" :title="item.user.nickname ? item.user.nickname : item.user.username" :cover="item.user.avatar ? item.user.avatar : '/static/images/userpic.png'" :showRight="true" :showRightIcon="false">
      <free-main-button slot="right" v-if="item.status==='pending'" name="同意"></free-main-button>
      <text slot="right" v-else class="text-muted font-sm">{{item|formatTitle}}</text>
    </free-list-item>
    <!-- 上拉加载 -->
    <view class="flex align-center justify-center py-4 bg-light">
      <text class="text-muted font">{{loadmore}}</text>
    </view>
  </view>
</template>
<script>
  import freeMainButton from '@/components/free-ui/free-main-button.vue';
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import $H from '@/common/free-lib/request.js';
  import auth from '@/common/mixin/auth.js';
  import { mapState } from 'vuex';
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeMainButton,
      freeListItem,
      freeDivider
    },
    filters:{
      formatTitle(value){
        let obj = {
          agree:'已通过',
          refuse:'已拒绝',
          ignore:'已忽略'
        }
        return obj[value.status];
      }
    },
    computed:{
      ...mapState({
        applyList:state=>state.user.apply.rows
      })
    },
    data() {
      return {
        form:{
          friend_id:0,
          nickname:"",
          lookme:1,
          lookhim:1
        },
        id:0,
        page:1,
        loadmore:'上拉加载更多',// 没有更多了,加载中...
      }
    },
    // 监听下拉刷新
    onPullDownRefresh() {
      this.page = 1;
      this.$store.dispatch('getApply',this.page).then(res=>{
        uni.showToast({
          title:'刷新成功',
          icon:'none'
        })
        uni.stopPullDownRefresh()
      })
    },
    onLoad(e) {
      
    },
    // 监听触底事件
    onReachBottom() {
      if(this.loadmore !== '上拉加载更多'){
        return;
      }
      this.loadmore = '加载中...';
      this.page = this.page+1;
      this.$store.dispatch('getApply',this.page).then(res=>{
        console.log(res)
        
        this.loadmore = this.applyList.length == this.page*10 ? '上拉加载更多' : '没有更多了';
      }).catch(err=>{
        this.page = this.page-1;
        this.loadmore = '上拉加载更多';
      })
    },
    methods: {
      
    }
  }
</script>
<style>
</style>

54处理好友申请功能

先看效果图

下面是代码

apply-list.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="好友申请列表" showBack :showRight="false">
    </free-nav-bar>
    
    <free-list-item v-for="(item,index) in applyList" :key="index" :title="item.user.nickname ? item.user.nickname : item.user.username" :cover="item.user.avatar ? item.user.avatar : '/static/images/userpic.png'" :showRight="true" :showRightIcon="false">
      <free-main-button slot="right" v-if="item.status==='pending'" name="同意" @click='handle(item)'></free-main-button>
      <text slot="right" v-else class="text-muted font-sm">{{item|formatTitle}}</text>
    </free-list-item>
    <!-- 上拉加载 -->
    <view class="flex align-center justify-center py-4 bg-light">
      <text class="text-muted font">{{loadmore}}</text>
    </view>
  </view>
</template>
<script>
  import freeMainButton from '@/components/free-ui/free-main-button.vue';
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import $H from '@/common/free-lib/request.js';
  import auth from '@/common/mixin/auth.js';
  import { mapState } from 'vuex';
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeMainButton,
      freeListItem,
      freeDivider
    },
    filters:{
      formatTitle(value){
        let obj = {
          agree:'已通过',
          refuse:'已拒绝',
          ignore:'已忽略'
        }
        return obj[value.status];
      }
    },
    computed:{
      ...mapState({
        applyList:state=>state.user.apply.rows
      })
    },
    data() {
      return {
        form:{
          friend_id:0,
          nickname:"",
          lookme:1,
          lookhim:1
        },
        id:0,
        page:1,
        loadmore:'上拉加载更多',// 没有更多了,加载中...
      }
    },
    // 监听下拉刷新
    onPullDownRefresh() {
      this.page = 1;
      this.$store.dispatch('getApply',this.page).then(res=>{
        uni.showToast({
          title:'刷新成功',
          icon:'none'
        })
        uni.stopPullDownRefresh()
      })
    },
    onLoad(e) {
      
    },
    // 监听触底事件
    onReachBottom() {
      if(this.loadmore !== '上拉加载更多'){
        return;
      }
      this.loadmore = '加载中...';
      this.page = this.page+1;
      this.$store.dispatch('getApply',this.page).then(res=>{
        console.log(res)
        
        this.loadmore = this.applyList.length == this.page*10 ? '上拉加载更多' : '没有更多了';
      }).catch(err=>{
        this.page = this.page-1;
        this.loadmore = '上拉加载更多';
      })
    },
    onShow() {
      this.page = 1;
      this.$store.dispatch('getApply',this.page)
    },
    methods: {
      handle(item){
        uni.navigateTo({
          url:'../add-friend/add-friend?id='+item.id,
        })
      }
    }
  }
</script>
<style>
</style>

add-friend.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="添加好友" showBack :showRight="false">
    </free-nav-bar>
    <view class="flex flex-column">
      <text class="font-sm text-secondary px-3 py-2">备注名</text>
      <input type="text" class="font-md border bg-white px-3" placeholder="请填写备注名" style="height: 100rpx;" v-model="form.nickname"/>
    </view>
    <free-divider></free-divider>
    <free-list-item title="不让他看我" :showLeftIcon="false"
    showRight :showRightIcon="false">
      <switch slot="right" :checked="!!form.lookme" color="#08C060" @change="form.lookme = form.lookme ? 0 : 1"/>
    </free-list-item>
    <free-list-item title="不看他" :showLeftIcon="false"
    showRight :showRightIcon="false">
      <switch slot="right" :checked="!!form.lookhim" color="#08C060" @change="form.lookhim = form.lookhim ? 0 : 1"/>
    </free-list-item>
    <free-divider></free-divider>
    <view class="py-3 flex align-center justify-center bg-white"
    hover-class="bg-light" @click="submit">
      <text class="font-md text-primary">{{ id > 0 ? '同意' : '点击添加' }}</text>
    </view>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import $H from '@/common/free-lib/request.js';
  import auth from '@/common/mixin/auth.js';
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeListItem,
      freeDivider
    },
    data() {
      return {
        form:{
          friend_id:0,
          nickname:"",
          lookme:1,
          lookhim:1
        },
        id:0
      }
    },
    onLoad(e) {
      if(e.params){
        this.form = JSON.parse(e.params)
      }
      if(e.id){
        this.id = e.id
      }
    },
    methods: {
      submit(){
        // 添加好友
        if(this.id == 0){
          return $H.post('/apply/addfriend',this.form).then(res=>{
            uni.showToast({
              title: '申请成功',
              icon: 'none'
            });
            uni.navigateBack({
              delta: 1
            });
          })
        }
        // 处理好友申请
        $H.post('/apply/handle/'+this.id,{
          ...this.form,
          status:"agree"
        }).then(res=>{
          uni.showToast({ title: '处理成功', icon: 'none' });
          uni.navigateBack({ delta: 1 });
          // this.$store.dispatch('getMailList')
        })
      }
    }
  }
</script>
<style>
</style>

55通讯录列表功能实现

先看效果图

如下是dm

mail.vue

<template>
  <view>
    <!-- 导航栏 -->
    <free-nav-bar title="通讯录"></free-nav-bar>
    <!-- 通讯录列表 -->
      <scroll-view scroll-y="true" :style="'height:'+scrollHeight+'px;'"  :scroll-into-view="scrollInto">
        <free-list-item v-for="(item,index) in topList" :key="item.id"  :title="item.title" :cover="item.cover" :showRight="item.id==='friend'"  @click="navigate(item.path)"  :showRightIcon='false'>
          <free-badge v-if="applyCount>0" slot="right" :num="applyCount"></free-badge>
        </free-list-item>
        
        <view v-for="(item,index) in list" :key="index" v-if="item.list.length>0" :id="'item-'+item.title">
          <view class="py-2 px-3 border-bottom bg-light">
            <text class="font-md text-dark">{{item.title}}</text>
          </view>
          <free-list-item v-for="(item2,index2) in item.list" :key="index2"  :title="item2.name" :cover="item2.avatar ? item2.avatar : '/static/images/userpic.png'" @click=""></free-list-item>
        </view>
      </scroll-view>
      <!-- 侧边导航条 -->
      <view class="position-fixed right-0 bottom-0 flex  flex-column" :style="'top:'+top+'rpx;'" style="width: 50rpx;" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" >
        <view class="flex-1 flex align-center justify-center" v-for="(item,index) in list" :key="index">
          <text class="font-sm text-muted">{{item.title}}</text>
        </view>
      </view>
      
      <!-- <block v-if="current"> -->
      <view class="position-fixed rounded-circle bg-light border flex align-center justify-center" style="width: 150rpx;height: 150rpx; left: 300rpx;" :style="'top:'+modalTop+'px;'" v-if="current!=''">
        <text class="font-lg" >{{current}}</text>
      </view>
      <!-- </block> -->
  </view>
</template>
<script>
  import freeNavBar from "@/components/free-ui/free-nav-bar.vue";
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeBadge from '@/components/free-ui/free-badge.vue';
  import { mapState } from 'vuex'; 
  import auth from '@/common/mixin/auth.js';
  export default {
    mixins:[auth],
    components:{
      freeNavBar,
      freeListItem,
      freeBadge
    },
    computed:{
      ...mapState({
        applyCount:state=>state.user.apply.count,
        list:state=>state.user.mailList
      }),//state.user.apply.count
      modalTop(){
        return (this.scrollHeight-uni.upx2px(150))/2;
      },
      itemHeight(){
        let count = this.list.length;
        if(count<1){
          return 0;
        }
        return this.scrollHeight/count;
      }
    },
    onLoad() {
      let res = uni.getSystemInfoSync();
      this.top = res.statusBarHeight + uni.upx2px(90);
      this.scrollHeight = res.windowHeight-this.top;
      this.$store.dispatch('getMailList');
    },
    data() {
      return {
        scrollInto:'',
        top:0,
        scrollHeight:0,
        current:'',
        topList:[
          {
            id:'friend',
            title:"新的朋友",
            cover:"/static/images/mail/friend.png",
            path:"mail/apply-list/apply-list"
          },
          {
            id:'group',
            title:"群聊",
            cover:"/static/images/mail/group.png",
            path:""
          },
          {
            id:'tag',
            title:"标签",
            cover:"/static/images/mail/tag.png",
            path:""
          }
        ]
        
      }
    },
    methods: {
      touchstart(e){
        this.changeScrollInto(e);
      },
      touchmove(e){
        this.changeScrollInto(e);
      },
      touchend(){
        this.current = '';
      },
      // 联动
      changeScrollInto(e){
        // let Y = e.touches[0].pageY;
        // let index = Math.floor(Y / this.itemHeight);
        // let item = this.list[index];
        // if(item){
        //  this.scrollInto = 'item-'+item.letter;
        //  this.current = item.letter;
        // }
        
        let Y = e.touches[0].pageY
      
        // #ifdef MP
          Y = Y - this.top
        // #endif
        
        let index = Math.floor(Y / this.itemHeight)
        let item = this.list[index]
        if(item){
          this.scrollInto = 'item-'+item.letter
          this.current = item.letter
        }
      }
    }
  }
</script>
<style>
</style>

/store/modules/user.js

import $U from '@/common/free-lib/util.js';
import $H from '@/common/free-lib/request.js';
export default {
  state: {
    user: false,
    apply: {
      rows: [],
      count: 0,
    },
    mailList:[]
  },
  actions: {
    // 登录后处理
    login({
      state,
      dispatch
    }, user) {
      // 存到状态种
      state.user = user;
      // 存储到本地存储中
      $U.setStorage('token', user.token);
      $U.setStorage('user', JSON.stringify(user));
      $U.setStorage('user_id', user.id);
      // 更新角标提示
      dispatch('updateMailBadge');
    },
    // 退出登录
    logout({
      state
    }) {
      // 清除登录状态
      state.user = false;
      // 清除本地存储数据
      $U.removeStorage('token');
      $U.removeStorage('user');
      $U.removeStorage('user_id');
      // 跳转到登录页
      uni.reLaunch({
        url: '/pages/common/login/login'
      })
    },
    // 初始化登录状态
    initLogin({
      state,
      dispatch
    }) {
      // 拿到存储的数据
      let user = $U.getStorage('user');
      if (user) {
        // 初始化登录状态
        state.user = JSON.parse(user);
        // 连接socket
        // 获取离线信息
        // 获取好友申请列表
        dispatch('getApply');
      }
    },
    // 获取好友申请列表
    getApply({
      state,
      dispatch
    }, page = 1) {
      $H.get('/apply/' + page).then(res => {
        if (page === 1) {
          state.apply = res
        } else {
          // 下拉刷新
          state.apply.rows = [...state.apply.rows, ...res.rows]
          state.apply.count = res.count
        }
        // 更新通讯录角标提示
        dispatch('updateMailBadge');
      });
    },
    // 更新通讯录角标提示
    updateMailBadge({
      state
    }) {
      let count = state.apply.count > 99 ? '99+' : state.apply.count.toString();
      console.log(state.apply.count);
      if (state.apply.count > 0) {
        return uni.setTabBarBadge({
          index: 1,
          text: count
        })
      }
      uni.removeTabBarBadge({
        index: 1
      })
    },
    // 获取通讯录列表
    getMailList({state}){
      $H.get('/friend/list').then(res=>{
        state.mailList = res.rows.newList ? res.rows.newList : [];
      })
    }
  },
}

56完善查看个人资料页

先看效果图

下面是代码

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar showBack :showRight="detail.friend" bgColor="bg-white">
      <free-icon-button slot="right" v-if="detail.friend"><text class="iconfont font-md" @click="openAction">&#xe6fd;</text></free-icon-button>
    </free-nav-bar>
    <view class="px-3 py-4 flex align-center bg-white border-bottom">
      <free-avatar :src="detail.avatar" size="120"></free-avatar>
      
      <view class="flex flex-column ml-3 flex-1">
        <view class="font-lg font-weight-bold flex justify-between">
          <text class="font-lg font-weight-bold mb-1">{{detail.nickname}}</text>
          <image v-if="detail.star" src="/static/images/star.png" style="width: 40rpx;height: 40rpx;"></image>
        </view>
        <text class="font-md text-light-muted mb-1">账号:{{detail.username}}</text>
        <!-- <text class="font-md text-light-muted">地区:广东广州</text> -->
      </view>
    </view>
    
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">标签</text>
        <text class="font-md text-light-muted mr-2" v-for="(item,index) in detail.tagList" :key="index">{{item}}</text>
      </view>
    </free-list-item>
    <free-divider></free-divider>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">朋友圈</text>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
      </view>
    </free-list-item>
    <free-list-item title="更多信息" showRight :showLeftIcon="false"></free-list-item>
    <free-divider></free-divider>
    <view v-if="detail.friend" class="py-3 flex align-center justify-center bg-white" hover-class="bg-light">
      <text class="iconfont text-primary mr-1" v-if="!detail.isBlack">&#xe64e;</text>
      <text class="font-md text-primary">{{detail.isBlack ? '移除黑名单' : '发信息'}}</text>
    </view>
    
    <view v-else class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="navigate(addFriend())">
      <text class="font-md text-primary">添加好友</text>
    </view>
    
    <!-- 扩展菜单 -->
    <free-popup ref="action" bottom transformOrigin="center bottom" maskColor>
      <scroll-view style="height: 580rpx;" scroll-y="true" class="bg-white" :show-scrollbar="false">
        <free-list-item v-for="(item,index) in actions"  :key="index" :title="item.title" :showRight="false" :border="false" @click="popupEvent(item)">
          <text slot="icon" class="iconfont font-lg py-1">{{item.icon}}</text>
        </free-list-item>
      </scroll-view>
    </free-popup>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeIconButton from '@/components/free-ui/free-icon-button.vue';
  import freeChatItem from '@/components/free-ui/free-chat-item.vue';
  import freePopup from '@/components/free-ui/free-popup.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import freeAvatar from '@/components/free-ui/free-avatar.vue';
  import auth from '@/common/mixin/auth.js';
  import $H from '@/common/free-lib/request.js';
  
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeIconButton,
      freeChatItem,
      freePopup,
      freeListItem,
      freeDivider,
      freeAvatar
    },
    data() {
      return {
        detail:{
          id:0,
          username:'',
          nickname:'',
          avatar:'',
          sex:'',
          sign:'',
          area:'',
          friend:false,
          lookhim:1,
          lookme:1,
          star:0,
          isblack:0,
          tags:[]
        },
      }
    },
    onLoad(e) {
      uni.$on('saveRemarkTag',(e)=>{
        this.detail.tagList = e.detail.tagList
        this.nickname = e.nickname;
      })
      if(!e.user_id){
        return this.backToast();
      }
      this.detail.id =  e.user_id;
      // 获取当前用户资料
      this.getData();
    },
    beforeDestroy() {
      this.$refs.action.hide();
      uni.$off('saveRemarkTag')
    },
    computed:{
      tagPath(){
        return "mail/user-remark-tag/user-remark-tag"
      },
      actions(){
          return [{
            icon:"\ue6b3",
            title:"设置备注和标签",
            type:"navigate",
            path:this.tagPath
          },{
            icon:"\ue613",
            title:"把他推荐给朋友",
            type:"navigate",
            path:"mail/send-card/send-card"
          },{
            icon:"\ue6b0",
            title:this.detail.star ? '取消星标好友' : "设为星标朋友",
            type:"event",
            event:"setStar"
          },{
            icon:"\ue667",
            title:"设置朋友圈和动态权限",
            type:"navigate",
            path:"mail/user-moments-auth/user-moments-auth"
          },{
            icon:"\ue638",
            title:this.detail.isblack ? '移出黑名单' : "加入黑名单",
            type:"event",
            event:"setBlack"
          },{
            icon:"\ue61c",
            title:"投诉",
            type:"navigate",
            path:"mail/user-report/user-report"
          },{
            icon:"\ue638",
            title:"删除",
            type:"event",
            event:"deleteItem"
          }]
        }
    },
    methods: {
      addFriend(){
        let obj = {
              friend_id:this.detail.id,
          nickname:this.detail.nickname,
          lookme:typeof this.detail.lookme==='number' ? this.detail.lookme : 1,
          lookhim:typeof this.detail.lookhim==='number' ? this.detail.lookhim : 1,
        };
        return 'mail/add-friend/add-friend?params='+JSON.stringify(obj);
      },
      getData(){
        $H.get('/friend/read/'+this.detail.id).then(res=>{
          if(!res){
            return this.backToast('该用户不存在');
          }
          this.detail = res;
          console.log(res);
        });
      },
      openAction(){
        this.$refs.action.show()
      },
      navigate(url){
        console.log(url)
        uni.navigateTo({
          url: '/pages/'+url,
        });
      },
      // 操作菜单事件
            popupEvent(e){
        if(!e.type){
          return;
        }
        switch(e.type){
          case 'navigate':
          this.navigate(e.path);
          break;
          case 'event':
          this[e.event](e);
          break;
        }
        setTimeout(()=>{
          // 关闭弹出层
          this.$refs.action.hide();
        },150);
      },
      // 设为星标
      setStar(e){
        this.detail.star = !this.detail.star
      },
      // 加入黑名单
      setBlack(e){
        let msg  = '加入黑名单';
        if(this.detail.isBlack){
          msg = '移出黑名单';
        }
        uni.showModal({
          content:'是否要'+msg,
          success:(res)=>{
            if(res.confirm){
              this.detail.isBlack = !this.detail.isBlack;
              e.title = this.isBlack ? '移出黑名单' : '加入黑名单';
              uni.showToast({
                title:msg+'成功',
                icon:'none'
              })
            }
          }
        })
      }
    }
  }
</script>
<style>
</style>

57设置星标好友和设置黑名单功能

先看图

代码

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar showBack :showRight="detail.friend" bgColor="bg-white">
      <free-icon-button slot="right" v-if="detail.friend"><text class="iconfont font-md"
          @click="openAction">&#xe6fd;</text></free-icon-button>
    </free-nav-bar>
    <view class="px-3 py-4 flex align-center bg-white border-bottom">
      <free-avatar :src="detail.avatar" size="120"></free-avatar>
      <view class="flex flex-column ml-3 flex-1">
        <view class="font-lg font-weight-bold flex justify-between">
          <text class="font-lg font-weight-bold mb-1">{{detail.nickname}}</text>
          <image v-if="detail.star" src="/static/images/star.png" style="width: 40rpx;height: 40rpx;"></image>
        </view>
        <text class="font-md text-light-muted mb-1">账号:{{detail.username}}</text>
        <!-- <text class="font-md text-light-muted">地区:广东广州</text> -->
      </view>
    </view>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">标签</text>
        <text class="font-md text-light-muted mr-2" v-for="(item,index) in detail.tagList"
          :key="index">{{item}}</text>
      </view>
    </free-list-item>
    <free-divider></free-divider>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">朋友圈</text>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
      </view>
    </free-list-item>
    <free-list-item title="更多信息" showRight :showLeftIcon="false"></free-list-item>
    <free-divider></free-divider>
    <view v-if="detail.friend" class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="doEvent">
      <text class="iconfont text-primary mr-1" v-if="!detail.isBlack">&#xe64e;</text>
      <text class="font-md text-primary">{{detail.isblack ? '移除黑名单' : '发信息'}}</text>
    </view>
    <view v-else class="py-3 flex align-center justify-center bg-white" hover-class="bg-light"
      @click="navigate(addFriend())">
      <text class="font-md text-primary">添加好友</text>
    </view>
    <!-- 扩展菜单 -->
    <free-popup ref="action" bottom transformOrigin="center bottom" maskColor>
      <scroll-view style="height: 580rpx;" scroll-y="true" class="bg-white" :show-scrollbar="false">
        <free-list-item v-for="(item,index) in actions" :key="index" :title="item.title" :showRight="false"
          :border="false" @click="popupEvent(item)">
          <text slot="icon" class="iconfont font-lg py-1">{{item.icon}}</text>
        </free-list-item>
      </scroll-view>
    </free-popup>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeIconButton from '@/components/free-ui/free-icon-button.vue';
  import freeChatItem from '@/components/free-ui/free-chat-item.vue';
  import freePopup from '@/components/free-ui/free-popup.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import freeAvatar from '@/components/free-ui/free-avatar.vue';
  import auth from '@/common/mixin/auth.js';
  import $H from '@/common/free-lib/request.js';
  export default {
    mixins: [auth],
    components: {
      freeNavBar,
      freeIconButton,
      freeChatItem,
      freePopup,
      freeListItem,
      freeDivider,
      freeAvatar
    },
    data() {
      return {
        detail: {
          id: 0,
          username: '',
          nickname: '',
          avatar: '',
          sex: '',
          sign: '',
          area: '',
          friend: false,
          lookhim: 1,
          lookme: 1,
          star: 0,
          isblack: 0,
          tags: []
        },
      }
    },
    onLoad(e) {
      uni.$on('saveRemarkTag', (e) => {
        this.detail.tagList = e.detail.tagList
        this.nickname = e.nickname;
      })
      if (!e.user_id) {
        return this.backToast();
      }
      this.detail.id = e.user_id;
      // 获取当前用户资料
      this.getData();
    },
    beforeDestroy() {
      this.$refs.action.hide();
      uni.$off('saveRemarkTag')
    },
    computed: {
      tagPath() {
        return "mail/user-remark-tag/user-remark-tag"
      },
      actions() {
        return [{
          icon: "\ue6b3",
          title: "设置备注和标签",
          type: "navigate",
          path: this.tagPath
        }, {
          icon: "\ue613",
          title: "把他推荐给朋友",
          type: "navigate",
          path: "mail/send-card/send-card"
        }, {
          icon: "\ue6b0",
          title: this.detail.star ? '取消星标好友' : "设为星标朋友",
          type: "event",
          event: "setStar"
        }, {
          icon: "\ue667",
          title: "设置朋友圈和动态权限",
          type: "navigate",
          path: "mail/user-moments-auth/user-moments-auth"
        }, {
          icon: "\ue638",
          title: this.detail.isblack ? '移出黑名单' : "加入黑名单",
          type: "event",
          event: "setBlack"
        }, {
          icon: "\ue61c",
          title: "投诉",
          type: "navigate",
          path: "mail/user-report/user-report"
        }, {
          icon: "\ue638",
          title: "删除",
          type: "event",
          event: "deleteItem"
        }]
      }
    },
    methods: {
      addFriend() {
        let obj = {
          friend_id: this.detail.id,
          nickname: this.detail.nickname,
          lookme: typeof this.detail.lookme === 'number' ? this.detail.lookme : 1,
          lookhim: typeof this.detail.lookhim === 'number' ? this.detail.lookhim : 1,
        };
        return 'mail/add-friend/add-friend?params=' + JSON.stringify(obj);
      },
      getData() {
        $H.get('/friend/read/' + this.detail.id).then(res => {
          if (!res) {
            return this.backToast('该用户不存在');
          }
          this.detail = res;
          console.log(res);
        });
      },
      openAction() {
        this.$refs.action.show()
      },
      navigate(url) {
        console.log(url)
        uni.navigateTo({
          url: '/pages/' + url,
        });
      },
      // 操作菜单事件
      popupEvent(e) {
        if (!e.type) {
          return;
        }
        setTimeout(() => {
          // 关闭弹出层
          this.$refs.action.hide()
        }, 300)
        switch (e.type) {
          case 'navigate':
            this.navigate(e.path);
            break;
          case 'event':
            this[e.event](e);
            break;
        }
      },
      // 设为星标
      setStar(e) {
        let star = this.detail.star == 0 ? 1 : 0;
        $H.post('/friend/setstar/' + this.detail.id, {
          star
        }).then(res => {
          this.detail.star = star;
          e.title = this.detail.star ? '取消标星好友' : '设为标星好友';
        });
      },
      // 加入黑名单
      setBlack(e) {
        let msg = this.detail.isblack ? '移出黑名单' : '加入黑名单';
      
        uni.showModal({
          content: '是否要' + msg,
          success: (res) => {
            if (res.confirm) {
              let isblack = this.detail.isblack == 0 ? 1:0
              $H.post('/friend/setblack/' + this.detail.id, {
                isblack
              }).then(res => {
                this.detail.isblack = isblack;
              });
              // this.detail.isBlack = !this.detail.isBlack;
              // e.title = this.isBlack ? '移出黑名单' : '加入黑名单';
              uni.showToast({
                title: msg + '成功',
                icon: 'none'
              })
            }
          }
        })
      },
        // 发送消息
      doEvent(e){
        if(this.detail.isblack){
          return this.setBlack();
        }
      }
    }
  }
</script>
<style>
</style>

58设置朋友圈权限功能实现

先看图

代码

user-base.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar showBack :showRight="detail.friend" bgColor="bg-white">
      <free-icon-button slot="right" v-if="detail.friend"><text class="iconfont font-md"
          @click="openAction">&#xe6fd;</text></free-icon-button>
    </free-nav-bar>
    <view class="px-3 py-4 flex align-center bg-white border-bottom">
      <free-avatar :src="detail.avatar" size="120"></free-avatar>
      <view class="flex flex-column ml-3 flex-1">
        <view class="font-lg font-weight-bold flex justify-between">
          <text class="font-lg font-weight-bold mb-1">{{detail.nickname}}</text>
          <image v-if="detail.star" src="/static/images/star.png" style="width: 40rpx;height: 40rpx;"></image>
        </view>
        <text class="font-md text-light-muted mb-1">账号:{{detail.username}}</text>
        <!-- <text class="font-md text-light-muted">地区:广东广州</text> -->
      </view>
    </view>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">标签</text>
        <text class="font-md text-light-muted mr-2" v-for="(item,index) in detail.tagList"
          :key="index">{{item}}</text>
      </view>
    </free-list-item>
    <free-divider></free-divider>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">朋友圈</text>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
      </view>
    </free-list-item>
    <free-list-item title="更多信息" showRight :showLeftIcon="false"></free-list-item>
    <free-divider></free-divider>
    <view v-if="detail.friend" class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="doEvent">
      <text class="iconfont text-primary mr-1" v-if="!detail.isBlack">&#xe64e;</text>
      <text class="font-md text-primary">{{detail.isblack ? '移除黑名单' : '发信息'}}</text>
    </view>
    <view v-else class="py-3 flex align-center justify-center bg-white" hover-class="bg-light"
      @click="navigate(addFriend())">
      <text class="font-md text-primary">添加好友</text>
    </view>
    <!-- 扩展菜单 -->
    <free-popup ref="action" bottom transformOrigin="center bottom" maskColor>
      <scroll-view style="height: 580rpx;" scroll-y="true" class="bg-white" :show-scrollbar="false">
        <free-list-item v-for="(item,index) in actions" :key="index" :title="item.title" :showRight="false"
          :border="false" @click="popupEvent(item)">
          <text slot="icon" class="iconfont font-lg py-1">{{item.icon}}</text>
        </free-list-item>
      </scroll-view>
    </free-popup>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeIconButton from '@/components/free-ui/free-icon-button.vue';
  import freeChatItem from '@/components/free-ui/free-chat-item.vue';
  import freePopup from '@/components/free-ui/free-popup.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import freeAvatar from '@/components/free-ui/free-avatar.vue';
  import auth from '@/common/mixin/auth.js';
  import $H from '@/common/free-lib/request.js';
  export default {
    mixins: [auth],
    components: {
      freeNavBar,
      freeIconButton,
      freeChatItem,
      freePopup,
      freeListItem,
      freeDivider,
      freeAvatar
    },
    data() {
      return {
        detail: {
          id: 0,
          username: '',
          nickname: '',
          avatar: '',
          sex: '',
          sign: '',
          area: '',
          friend: false,
          lookhim: 1,
          lookme: 1,
          star: 0,
          isblack: 0,
          tags: []
        },
      }
    },
    onShow() {
      this.getData();
    },
    onLoad(e) {
      uni.$on('saveRemarkTag', (e) => {
        this.detail.tagList = e.detail.tagList
        this.nickname = e.nickname;
      })
      if (!e.user_id) {
        return this.backToast();
      }
      this.detail.id = e.user_id;
      // 获取当前用户资料
      this.getData();
    },
    beforeDestroy() {
      this.$refs.action.hide();
      uni.$off('saveRemarkTag')
    },
    computed: {
      tagPath() {
        return "mail/user-remark-tag/user-remark-tag"
      },
      actions() {
        return [{
          icon: "\ue6b3",
          title: "设置备注和标签",
          type: "navigate",
          path: this.tagPath
        }, {
          icon: "\ue613",
          title: "把他推荐给朋友",
          type: "navigate",
          path: "mail/send-card/send-card"
        }, {
          icon: "\ue6b0",
          title: this.detail.star ? '取消星标好友' : "设为星标朋友",
          type: "event",
          event: "setStar"
        }, {
          icon: "\ue667",
          title: "设置朋友圈和动态权限",
          type: "navigate",
          path: "mail/user-moments-auth/user-moments-auth?user_id="+this.detail.id+"&params="+JSON.stringify({
            lookme:this.detail.lookme,
            lookhim:this.detail.lookhim,
          })
        }, {
          icon: "\ue638",
          title: this.detail.isblack ? '移出黑名单' : "加入黑名单",
          type: "event",
          event: "setBlack"
        }, {
          icon: "\ue61c",
          title: "投诉",
          type: "navigate",
          path: "mail/user-report/user-report"
        }, {
          icon: "\ue638",
          title: "删除",
          type: "event",
          event: "deleteItem"
        }]
      }
    },
    methods: {
      addFriend() {
        let obj = {
          friend_id: this.detail.id,
          nickname: this.detail.nickname,
          lookme: typeof this.detail.lookme === 'number' ? this.detail.lookme : 1,
          lookhim: typeof this.detail.lookhim === 'number' ? this.detail.lookhim : 1,
        };
        return 'mail/add-friend/add-friend?params=' + JSON.stringify(obj);
      },
      getData() {
        $H.get('/friend/read/' + this.detail.id).then(res => {
          if (!res) {
            return this.backToast('该用户不存在');
          }
          this.detail = res;
          console.log(res);
        });
      },
      openAction() {
        this.$refs.action.show()
      },
      navigate(url) {
        console.log(url)
        uni.navigateTo({
          url: '/pages/' + url,
        });
      },
      // 操作菜单事件
      popupEvent(e) {
        if (!e.type) {
          return;
        }
        setTimeout(() => {
          // 关闭弹出层
          this.$refs.action.hide()
        }, 300)
        switch (e.type) {
          case 'navigate':
            this.navigate(e.path);
            break;
          case 'event':
            this[e.event](e);
            break;
        }
      },
      // 设为星标
      setStar(e) {
        let star = this.detail.star == 0 ? 1 : 0;
        $H.post('/friend/setstar/' + this.detail.id, {
          star
        }).then(res => {
          this.detail.star = star;
          e.title = this.detail.star ? '取消标星好友' : '设为标星好友';
        });
      },
      // 加入黑名单
      setBlack(e) {
        let msg = this.detail.isblack ? '移出黑名单' : '加入黑名单';
      
        uni.showModal({
          content: '是否要' + msg,
          success: (res) => {
            if (res.confirm) {
              let isblack = this.detail.isblack == 0 ? 1:0
              $H.post('/friend/setblack/' + this.detail.id, {
                isblack
              }).then(res => {
                this.detail.isblack = isblack;
              });
              // this.detail.isBlack = !this.detail.isBlack;
              // e.title = this.isBlack ? '移出黑名单' : '加入黑名单';
              uni.showToast({
                title: msg + '成功',
                icon: 'none'
              })
            }
          }
        })
      },
        // 发送消息
      doEvent(e){
        if(this.detail.isblack){
          return this.setBlack();
        }
      }
    }
  }
</script>
<style>
</style>

user-moment-auth.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="设置朋友圈动态权限" showBack :showRight="false">
    </free-nav-bar>
    
    <free-list-item title="不让他看我" :showLeftIcon="false" showRight :showRightIcon="false">
      <switch slot="right" :checked="!!form.lookme" @change="change('lookme')" color="#08C060"/>
    </free-list-item>
    <free-list-item title="不看他" :showLeftIcon="false" showRight :showRightIcon="false">
      <switch slot="right" :checked="!!form.lookhim" @change="change('lookhim')" color="#08C060"/>
    </free-list-item>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import $H from '@/common/free-lib/request.js';
  export default {
    components:{
      freeNavBar,
      freeListItem
    },
    data() {
      return {
        id:0,
        form:{
          lookme:1,
          lookhim:1
        }
      }
    },
    onLoad(e) {
      if(e.user_id){
        this.id= e.user_id
      }
      if(e.params){
        this.form= JSON.parse(e.params);
      }
    },
    methods: {
      change(key){
        this.form[key] = this.form[key] ? 0 : 1;
        this.submit()
      },
      submit(){
        $H.post('/friend/setmomentauth/'+this.id,this.form).then(res=>{
          uni.showToast({
            title:'修改成功',
            icon:'none'
          })
        })
      }
    }
  }
</script>
<style>
</style>

59设置备注和标签功能实现

先看效果图

看代码

user-base.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar showBack :showRight="detail.friend" bgColor="bg-white">
      <free-icon-button slot="right" v-if="detail.friend"><text class="iconfont font-md"
          @click="openAction">&#xe6fd;</text></free-icon-button>
    </free-nav-bar>
    <view class="px-3 py-4 flex align-center bg-white border-bottom">
      <free-avatar :src="detail.avatar" size="120"></free-avatar>
      <view class="flex flex-column ml-3 flex-1">
        <view class="font-lg font-weight-bold flex justify-between">
          <text class="font-lg font-weight-bold mb-1">{{detail.nickname}}</text>
          <image v-if="detail.star" src="/static/images/star.png" style="width: 40rpx;height: 40rpx;"></image>
        </view>
        <text class="font-md text-light-muted mb-1">账号:{{detail.username}}</text>
        <!-- <text class="font-md text-light-muted">地区:广东广州</text> -->
      </view>
    </view>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false" @click="navigate(tagPath)">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">标签</text>
        <text class="font-md text-light-muted mr-2" v-for="(item,index) in detail.tags"
          :key="index">{{item}}</text>
      </view>
    </free-list-item>
    <free-divider></free-divider>
    <free-list-item v-if="detail.friend" showRight :showLeftIcon="false">
      <view class="flex align-center">
        <text class="font-md text-dark mr-3">朋友圈</text>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
        <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image>
      </view>
    </free-list-item>
    <free-list-item title="更多信息" showRight :showLeftIcon="false"></free-list-item>
    <free-divider></free-divider>
    <view v-if="detail.friend" class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="doEvent">
      <text class="iconfont text-primary mr-1" v-if="!detail.isBlack">&#xe64e;</text>
      <text class="font-md text-primary">{{detail.isblack ? '移除黑名单' : '发信息'}}</text>
    </view>
    <view v-else class="py-3 flex align-center justify-center bg-white" hover-class="bg-light"
      @click="navigate(addFriend())">
      <text class="font-md text-primary">添加好友</text>
    </view>
    <!-- 扩展菜单 -->
    <free-popup ref="action" bottom transformOrigin="center bottom" maskColor>
      <scroll-view style="height: 580rpx;" scroll-y="true" class="bg-white" :show-scrollbar="false">
        <free-list-item v-for="(item,index) in actions" :key="index" :title="item.title" :showRight="false"
          :border="false" @click="popupEvent(item)">
          <text slot="icon" class="iconfont font-lg py-1">{{item.icon}}</text>
        </free-list-item>
      </scroll-view>
    </free-popup>
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeIconButton from '@/components/free-ui/free-icon-button.vue';
  import freeChatItem from '@/components/free-ui/free-chat-item.vue';
  import freePopup from '@/components/free-ui/free-popup.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import freeDivider from '@/components/free-ui/free-divider.vue';
  import freeAvatar from '@/components/free-ui/free-avatar.vue';
  import auth from '@/common/mixin/auth.js';
  import $H from '@/common/free-lib/request.js';
  export default {
    mixins: [auth],
    components: {
      freeNavBar,
      freeIconButton,
      freeChatItem,
      freePopup,
      freeListItem,
      freeDivider,
      freeAvatar
    },
    data() {
      return {
        detail: {
          id: 0,
          username: '',
          nickname: '',
          avatar: '',
          sex: '',
          sign: '',
          area: '',
          friend: false,
          lookhim: 1,
          lookme: 1,
          star: 0,
          isblack: 0,
          tags: []
        },
      }
    },
    onShow() {
      this.getData();
    },
    onLoad(e) {
      uni.$on('saveRemarkTag', (e) => {
        this.detail.tagList = e.detail.tagList
        this.nickname = e.nickname;
      })
      if (!e.user_id) {
        return this.backToast();
      }
      this.detail.id = e.user_id;
      // 获取当前用户资料
      this.getData();
    },
    beforeDestroy() {
      this.$refs.action.hide();
      uni.$off('saveRemarkTag')
    },
    computed: {
      tagPath() {
        return "mail/user-remark-tag/user-remark-tag?params="+JSON.stringify({
          user_id:this.detail.id,
          nickname:this.detail.nickname,
          tags:this.detail.tags.join(',')
        })
      },
      actions() {
        return [{
          icon: "\ue6b3",
          title: "设置备注和标签",
          type: "navigate",
          path: this.tagPath
        }, {
          icon: "\ue613",
          title: "把他推荐给朋友",
          type: "navigate",
          path: "mail/send-card/send-card"
        }, {
          icon: "\ue6b0",
          title: this.detail.star ? '取消星标好友' : "设为星标朋友",
          type: "event",
          event: "setStar"
        }, {
          icon: "\ue667",
          title: "设置朋友圈和动态权限",
          type: "navigate",
          path: "mail/user-moments-auth/user-moments-auth?user_id="+this.detail.id+"&params="+JSON.stringify({
            lookme:this.detail.lookme,
            lookhim:this.detail.lookhim,
          })
        }, {
          icon: "\ue638",
          title: this.detail.isblack ? '移出黑名单' : "加入黑名单",
          type: "event",
          event: "setBlack"
        }, {
          icon: "\ue61c",
          title: "投诉",
          type: "navigate",
          path: "mail/user-report/user-report"
        }, {
          icon: "\ue638",
          title: "删除",
          type: "event",
          event: "deleteItem"
        }]
      }
    },
    methods: {
      addFriend() {
        let obj = {
          friend_id: this.detail.id,
          nickname: this.detail.nickname,
          lookme: typeof this.detail.lookme === 'number' ? this.detail.lookme : 1,
          lookhim: typeof this.detail.lookhim === 'number' ? this.detail.lookhim : 1,
        };
        return 'mail/add-friend/add-friend?params=' + JSON.stringify(obj);
      },
      getData() {
        $H.get('/friend/read/' + this.detail.id).then(res => {
          if (!res) {
            return this.backToast('该用户不存在');
          }
          this.detail = res;
          console.log(res);
        });
      },
      openAction() {
        this.$refs.action.show()
      },
      navigate(url) {
        console.log(url)
        uni.navigateTo({
          url: '/pages/' + url,
        });
      },
      // 操作菜单事件
      popupEvent(e) {
        if (!e.type) {
          return;
        }
        setTimeout(() => {
          // 关闭弹出层
          this.$refs.action.hide()
        }, 300)
        switch (e.type) {
          case 'navigate':
            this.navigate(e.path);
            break;
          case 'event':
            this[e.event](e);
            break;
        }
      },
      // 设为星标
      setStar(e) {
        let star = this.detail.star == 0 ? 1 : 0;
        $H.post('/friend/setstar/' + this.detail.id, {
          star
        }).then(res => {
          this.detail.star = star;
          e.title = this.detail.star ? '取消标星好友' : '设为标星好友';
        });
      },
      // 加入黑名单
      setBlack(e) {
        let msg = this.detail.isblack ? '移出黑名单' : '加入黑名单';
      
        uni.showModal({
          content: '是否要' + msg,
          success: (res) => {
            if (res.confirm) {
              let isblack = this.detail.isblack == 0 ? 1:0
              $H.post('/friend/setblack/' + this.detail.id, {
                isblack
              }).then(res => {
                this.detail.isblack = isblack;
              });
              // this.detail.isBlack = !this.detail.isBlack;
              // e.title = this.isBlack ? '移出黑名单' : '加入黑名单';
              uni.showToast({
                title: msg + '成功',
                icon: 'none'
              })
            }
          }
        })
      },
        // 发送消息
      doEvent(e){
        if(this.detail.isblack){
          return this.setBlack();
        }
      }
    }
  }
</script>
<style>
</style>

user-remark-tag.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="设置备注和标签" showBack :showRight="true">
      <free-main-button name="完成" slot="right" @click="submit"></free-main-button>
    </free-nav-bar>
    
    <view class="flex flex-column">
      <text class="font-sm text-secondary px-3 py-2">备注名</text>
      <input type="text" class="font-md border bg-white px-3" placeholder="请填写备注名" style="height: 100rpx;" v-model="nickname"/>
    </view>
    
    <view class="flex flex-column">
      <text class="font-sm text-secondary px-3 py-2">标签</text>
      <view class="border bg-white px-3 flex align-center flex-wrap pt-3 pb-2" @click="openTagSet">
        <view class="border border-main rounded-circle px-2 py-1 mr-1 mb-1" v-for="(item,index) in tagList" :key="index">
          <text class="font main-text-color">{{item}}</text>
        </view>
      </view>
    </view>
    
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeMainButton from '@/components/free-ui/free-main-button.vue';
  import auth from '@/common/mixin/auth.js';
  import $H from '@/common/free-lib/request.js';
  export default {
    mixins:[auth],
    components: {
      freeNavBar,
      freeMainButton
    },
    data() {
      return {
        id:0,
        nickname:"",
        tagList:['朋友','同学','家人']
      }
    },
    onLoad(e) {
      if(!e.params){
        return this.backToast()
      }
      let params = JSON.parse(e.params)
      this.id = params.user_id
      this.nickname = params.nickname
      this.tagList = params.tags == '' ? [] : params.tags.split(',')
      uni.$on('updateTag',(e)=>{
        this.tagList = e
      })
    },
    beforeDestroy() {
      uni.$off('updateTag')
    },
    methods: {
      openTagSet(){
        uni.navigateTo({
          url: '../user-tag-set/user-tag-set?detail='+JSON.stringify(this.tagList)
        });
      },
      // 完成
      submit(){
        uni.$emit('saveRemarkTag',{
          nickname:this.nickname,
          tagList:this.tagList
        });
        // uni.navigateBack({
        //  delta:1
        // })
        $H.post('/friend/setremarktag/'+this.id,{
          nickname:this.nickname,
          tags:this.tagList.join(',')
        }).then(res=>{
          uni.showToast({
            title: '修改成功',
            icon: 'none'
          });
          uni.navigateBack({
            delta: 1
          });
        })
      }
    }
  }
</script>
<style>
</style>

60举报投诉好友功能实现

我们先看页面

代码部分

user-report.vue

<template>
  <view class="page">
    <!-- 导航栏 -->
    <free-nav-bar title="用户投诉" showBack :showRight="true" bgColor="bg-white">
      <free-main-button name="投诉" slot="right" @click="submit"></free-main-button>
    </free-nav-bar>
  
    <picker mode="selector" :range="range" @change="change">
      <view>
        <free-list-item :showLeftIcon="false" :title="form.category ? form.category : '请选择分类'" showRight></free-list-item>
      </view>
    </picker>
    <textarea placeholder="请填写投诉内容..." class="bg-white p-2 font-md" v-model="form.content" style="width: 100%;" />
  </view>
</template>
<script>
  import freeNavBar from '@/components/free-ui/free-nav-bar.vue';
  import freeMainButton from '@/components/free-ui/free-main-button.vue';
  import freeListItem from '@/components/free-ui/free-list-item.vue';
  import $H from '@/common/free-lib/request.js';
  import auth from '@/common/mixin/auth.js';
  export default {
    mixins:[auth],
    components:{
      freeNavBar,
      freeMainButton,
      freeListItem
    },
    data() {
      return {
        range:['分类一','分类二','分类三','分类四','分类五'],
        form:{
          reported_id:0,
          reported_type:'user',
          category:'',
          content:''
        }
      }
    },
    onLoad(e) {
      if(!e.params){
        return this.backToast()
      }
      let params = JSON.parse(e.params);
      this.form.reported_id = params.user_id,
      this.form.reported_type = params.type
    },
    methods: {
      change(e){
        this.form.category = this.range[e.detail.value];
      },
      submit(){
        if(!this.form.category){
          return uni.showToast({
            title:'请选择分类',
            icon:'none'
          })
        }
        if(!this.form.content){
          return uni.showToast({
            title:'请填写投诉内容',
            icon:'none'
          })
        }
        
        // 请求服务器
        $H.post('/report/save',this.form).then(res=>{
          console.log(res)
          uni.navigateBack({
            delta:1
          });
          uni.showToast({
            title:'投诉成功',
            icon:'none'
          })
        })
        
      }
    }
  }
</script>
<style>
</style>


目录
相关文章
|
19天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
23 0
|
7天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的进阶之路
【4月更文挑战第20天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为一种新兴的分布式系统设计方式,以其独立部署、易于扩展和维护的特点,成为解决这一问题的关键。本文将深入探讨微服务的核心概念、设计原则以及在后端开发实践中如何构建一个高效的微服务架构。我们将从服务划分、通信机制、数据一致性、服务发现与注册等方面入手,提供一系列实用的策略和建议,帮助开发者优化后端系统的性能和可维护性。
|
2天前
|
持续交付 API 开发者
构建高效微服务架构:后端开发的新范式
【4月更文挑战第24天】 随着现代软件系统的复杂性日益增加,传统的单体应用已难以满足快速迭代与灵活扩展的需求。微服务架构作为一种新兴的软件开发模式,以其服务的细粒度、独立部署和弹性伸缩等优势,正在逐渐成为后端开发的重要趋势。本文将深入探讨微服务架构的设计原则、关键技术以及在实际业务中的应用实践,旨在为后端开发者提供构建和维护高效微服务架构的参考指南。
|
3天前
|
人工智能 机器人 API
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
7 0
|
3天前
|
缓存 人工智能 API
【Python+微信】【企业微信开发入坑指北】2. 如何利用企业微信API主动给用户发应用消息
【Python+微信】【企业微信开发入坑指北】2. 如何利用企业微信API主动给用户发应用消息
8 0
|
4天前
|
监控 API 持续交付
构建高效微服务架构:后端开发的新趋势
【4月更文挑战第23天】 随着现代软件开发实践的不断演进,微服务架构已经成为企业追求敏捷、可扩展和弹性解决方案的首选。本文深入探讨了如何构建一个高效的微服务架构,涵盖了关键的设计原则、技术选型以及实践建议。通过分析微服务的独立性、分布式特性和容错机制,我们将揭示如何利用容器化、服务网格和API网关等技术手段,来优化后端系统的可维护性和性能。文章旨在为后端开发人员提供一套全面的指南,以应对不断变化的业务需求和技术挑战。
|
9天前
|
监控 持续交付 开发者
构建高效微服务架构:后端开发的新趋势
【4月更文挑战第18天】在数字化转型的浪潮中,微服务架构已成为企业提升系统灵活性、加速产品迭代的关键。此文深入探讨了构建高效微服务架构的实践方法,包括服务划分原则、容器化部署、持续集成/持续部署(CI/CD)流程以及监控与日志管理等关键技术点。通过分析具体案例,揭示了微服务在提高开发效率、降低维护成本及促进团队协作方面的显著优势。
|
12天前
|
监控 负载均衡 API
构建高性能微服务架构:后端开发的最佳实践
【4月更文挑战第14天】 在当今快速发展的软件开发领域,微服务架构已成为构建可扩展、灵活且容错的系统的首选方法。本文深入探讨了后端开发人员在设计和维护高性能微服务时需要遵循的一系列最佳实践。我们将从服务划分原则、容器化部署、API网关使用、负载均衡、服务监控与故障恢复等方面展开讨论,并结合实际案例分析如何优化微服务性能及可靠性。通过本文的阅读,读者将获得实施高效微服务架构的实用知识与策略。
|
14天前
|
小程序 前端开发 API
小程序全栈开发中的RESTful API设计
【4月更文挑战第12天】本文探讨了小程序全栈开发中的RESTful API设计,旨在帮助开发者理解和掌握相关技术。RESTful API基于REST架构风格,利用HTTP协议进行数据交互,遵循URI、客户端-服务器架构、无状态通信、标准HTTP方法和资源表述等原则。在小程序开发中,通过资源建模、设计API接口、定义资源表述及实现接口,实现前后端高效分离,提升开发效率和代码质量。小程序前端利用微信API与后端交互,确保数据流通。掌握这些实践将优化小程序全栈开发。
|
14天前
|
小程序 前端开发 JavaScript
小程序全栈开发:前端与后端的完美结合
【4月更文挑战第12天】本文介绍了小程序全栈开发,涵盖前端和后端的关键点。前端使用WXML和WXSS进行页面结构和样式设计,JavaScript处理逻辑及组件使用;后端采用Node.js等语言处理业务逻辑、数据库设计和API接口开发。前端与后端通过数据交互实现结合,采用前后端分离模式,支持跨平台运行。调试测试后,提交微信审核并上线运营。掌握前端后端结合是小程序成功的关键。