3用户信息展示

上一篇完成了AdminLTE的整合,接下来就要把页面中的逻辑一一填充进来了,先从展示用户信息开始吧。
我们需要用户点击账户信息按钮后被导航到账户信息页。所以需要给账户信息按钮添加router-link,点击时调用router进行页面跳转。

账户信息按钮

第一步:在账户信息的HTML代码处添加事件
<router-link to="/userProfile/travelCount">
    <button href="#" class="btn btn-primary btn-flat ch">账户信息</button>
</router-link>
第二步:新建一个userProfile.vue和一个travelCount.vue。userProfile用来展示用户的基本信息,travelCount用来展示用户的出差记录。travelCount是被嵌套在userProfile中的。

userProfile.vue:

<template>
    <!-- Main content -->
    <section class="content">
        <div class="row">
            <div class="col-md-3">
                <!-- Profile Image -->
                <div class="box box-primary">
                    <div class="box-body box-profile">
                        <img class="profile-user-img img-responsive img-circle" src="../assets/img/avatar5.png" alt="User profile picture">
                        <h3 class="profile-username text-center ch">{{displayName}}</h3>
                        <p class="text-muted text-center ch">{{duty}}</p>
                        <ul class="list-group list-group-unbordered">
                            <li class="list-group-item">
                                <b class="ch">用户名:</b> <b class="pull-right ch">{{displayName}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">登录名:</b> <b class="pull-right ch">{{name}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">邮箱地址:</b> <b class="pull-right ch">{{email}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">所属部门:</b> <b class="pull-right ch">{{department}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">职务:</b> <b class="pull-right ch">{{duty}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">办公地点:</b> <b class="pull-right ch">{{location}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">办公电话:</b> <b class="pull-right ch">{{tel}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">手机:</b> <b class="pull-right ch">{{phone}}</b>
                            </li>
                            <li class="list-group-item">
                                <b class="ch">上级领导:</b> <b class="pull-right ch">{{superior}}</b>
                            </li>
                        </ul>

                        <strong class="ch"><i class="fa fa-pencil margin-r-5"></i>技能标签</strong>
                        <p style="padding-top:5px">
                            <button v-for="skill in skills" class="label btn-primary ch" style="margin:2px; color:white">{{skill}}</button>
                        </p>
                    </div>
                    <!-- /.box-body -->
                </div>
                <!-- /.box -->
            </div>
            <!-- /.col -->
            <div class="col-md-9">
                <div class="nav-tabs-custom">
                    <ul class="nav nav-tabs">
                        <li class="ch active" data-toggle="tab">
                            <router-link to="/userProfile/travelCount">
                                <span>出差统计</span>
                            </router-link>
                        </li>
                        <li class="ch" data-toggle="tab">
                            <router-link to="/userProfile/workCircle">
                                <span>我的工作圈</span>
                            </router-link>
                        </li>
                    </ul>
                    <div class="tab-content">
                        <router-view></router-view><!--这里是要显示travelCount内容的地方-->
                    </div>
                    <!-- /.content -->
                </div>
            </div>
        </div>
    </section>
</template>

<script>
    export default {
        data() {//这里对应用户的基本信息
            return {
                displayName: null,
                duty: null,
                name: null,
                email: null,
                department: null,
                location: null,
                tel: null,
                phone: null,
                superior: null,
                skills: null
            }
        },
        mounted (){//使用mounted在挂在DOM时通过restful api获取用户基本信息并填充到data中。这个之后详细说明。
            this.$http.get(
                'https://192.168.227.1:8443/userInfo' , 
                {
                    headers: {'token' : localStorage.token}//在requestHeader中携带之前产生的token用来在后端验证用户权限。
                }
            )
                .then(
                    //success
                    response => {
                        this.displayName = response.data.displayName;
                        this.duty = response.data.duty;
                        this.name = response.data.name;
                        this.email = response.data.email;
                        this.department = response.data.department;
                        this.location = response.data.location;
                        this.tel = response.data.tel;
                        this.phone = response.data.phone;
                        this.superior = response.data.superior;
                        this.skills = response.data.skills;
                    }, 
                    //error
                    response => {

                    }
                )
        }
    }
</script>

<style scoped>
    @font-face
    {
        font-family: yaHeiFont;
        src: url('../assets/font/yaHei.ttf')
    }
    .ch
    {
        font-family:yaHeiFont;
        color: black;
    }
</style>
第三步,在main.js中引入userProfile.vue文件并且为userProfile添加路由。这里因为userProfile内容要显示的地方是在红框区域内,如下图:

显示区域

而红框区域内的路由出口是在index.vue中定义的,所以如果想要userProfile的内容正确渲染到红框区域内,则需要把userProfile嵌套在index中,需要用到vue-router的嵌套路由。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
import store from './store/store'
//bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/js/bootstrap.min.js'
//AdminLTE
import './assets/css/skins/_all-skins.min.css'
import './assets/css/AdminLTE.min.css'
import './assets/js/app.min.js'
//font-awesome
import 'font-awesome/css/font-awesome.min.css'
//echarts
import echarts from 'echarts'
//components
import App from './App'
import Login from './components/login'
import Index from './components/index'
import DeviceCatalog from './components/deviceCatalog'
import UserProfile from './components/userProfile'
import TravelCount from './components/travelCount'
import WorkCircle from './components/workCircle'

Vue.use(VueRouter)
Vue.use(VueResource)

//注册echarts的一种方法
// Object.defineProperties(Vue.prototype, {
//   $echarts: { get: () => echarts }
// });

//Vue-Resource提交方式设置
Vue.http.options.emulateJSON = true;

const routes = [
  //登录页
  {
    path: '/login',
    component : Login
  },
  //导航页
  {
    path: '/index',
    component: Index,
    //导航页子页面,children中的component将被渲染到之前说的红色区域内
    children: [
      //设备目录页
      {
        path: '/deviceCatalog',
        component: DeviceCatalog
      },
      //账户信息页
      {
        path: '/userProfile',
        component: UserProfile,
        //账户信息子页面
        children: [
          //出差统计页
          {
            path: '/userProfile/travelCount',
            component: TravelCount
          },
          //工作圈子页
          {
            path: '/userProfile/workCircle',
            component: WorkCircle
          }
        ]
      },
    ]
  },
]

const router = new VueRouter({
  routes
})

//默认导航到登录页
// router.push('/login')

/*
全局路由钩子
访问资源时需要验证localStorage中是否存在token
以及token是否过期
验证成功可以继续跳转
失败返回登录页重新登录
 */
router.beforeEach((to, from, next) => {
  if(to.path == '/login'){
    next()
  }
  if(localStorage.token && new Date().getTime() < localStorage.tokenExpired){
    next()
  }
  else{
    next('/login')
  }
})

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  router:router,
  store: store,
  echarts: echarts//注册echarts的另一种方法
  }
})
做完之后点击用户信息按钮应该就可以跳转到用户信息页了,看下效果

用户信息

第四步出差统计信息,这里想使用echarts图表来进行展示(这里我跳了一个坑)。首先在项目中使用npm install echarts –save将echarts下载到项目中。然后在main.js中引用,对应第三步main.js中
import echarts from 'echarts'
在travelCount中使用,travelCount.vue。这里有几点需要注意
1.echarts挂载的dom必须设置一个高度,否则不能显示出来。
2.echarts的配置需要放在mounted中。
3.使用echarts的resize方法配合js中onresize重绘图表以动态适应屏幕尺寸。
<template>
    <div id="main" style="height:730px"></div>
</template>

<script>
export default {
    mounted() {
        var myChart = this.$root.$options.echarts.init(document.getElementById('main'));//这里注意
        var option = {
            grid : {
                left : '1%',
                right : '2%',
                bottom : '1%',
                containLabel : true
            },
            xAxis : {
                type : 'value',
                boundaryGap : [ 0, 0.01 ]
            },
            yAxis : {
                type : 'category',
                axisLabel : {
                    inside : true,
                    textStyle : {
                        fontWeight : 'bold'
                    },
                },
                z : 100,
                data : ['A国:2016-01-01至2016-02-01' , 'B国:2016-03-01至2016-04-01' , 'C国:2016-06-01至2016-06-01']
            },
            series : [ {
                type : 'bar',
                barGap : '10%',
                itemStyle : {
                    normal : {
                        color : 'LightSkyBlue'
                    }
                },
                data : [100 , 200 , 300]
            } ]
        }
        myChart.setOption(option);
        //窗口尺寸变化时重新绘制chart
        window.onresize = () => {
            myChart.resize()    
        }
    }
}
</script>
这里要说下我跳的坑,引入echarts时,上面的代码使用了
this.$root.$options.echarts
如果这样引用的话,需要在main.js的Vue根实例中注册echarts,见第三步main.js配置。还有一种方法可以使用this.$echarts的方式引用(这个方法是Vue论坛中tomi-li老师指点的,谢谢老师)。
这种方法需要使用js的Object.defineProperties将echarts手动添加到Vue对象中,见第三步main.js配置。使用这种方法时不需要在根实例中注册echarts。
Object.defineProperties(Vue.prototype, {
   $echarts: { get: () => echarts }
});
如果没有手动添加的话,在其他Vue文件中使用echarts时会报错,告诉你echarts没有定义过。
看下效果

信息展示

OK,前端的部分完成了,现在出差信息是静态数据,因为来处理、记录这些数据的服务可能还要依赖其他服务,我们先用静态数据代替。但是用户基本信息是从Ldap中取出来的,之前第二步中不是使用了vur-resourse到这个地址获取用户数据么。
this.$http.get(
     'https://192.168.227.1:8443/userInfo' , 
      {
            headers: {'token' : localStorage.token}
      }
)
后端处理这个请求的controller。因为在分布式架构下这个controller通过restful对外提供获取用户信息的服务,所以需要使用@CrossOrigin注解满足跨域的需求。
getUserInfo方法做这几件事情
1.拿到header中的用户token,解密后判断用户凭证是否过期、是否拥有某种权限角色。
2.如果判断没有问题,使用token中的用户名作为入参,调用SpringLdap取得用户信息,并使用EmployeeAttributesMapper 填充我们自己的POJO类。返回response信息。
3.如果判断有问题,返回403表示认证没有通过。
package an.userinfo;

import static org.springframework.ldap.query.LdapQueryBuilder.query;
import java.util.Date;
import javax.naming.directory.Attributes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import an.entity.Employee;
import io.jsonwebtoken.Jwts;

@RestController("/userInfo")
public class UserInfoWeb {

    //jwt加密密匙
    @Value("${jwt.key}")
    private String jwtKey;

    //ldap模板
    @Autowired
    private LdapTemplate ldapTemplate;

    /**
     * 将域用户属性通过EmployeeAttributesMapper填充到Employee类中,返回一个填充信息的Employee实例
     */
    private class EmployeeAttributesMapper implements AttributesMapper<Employee> {
        public Employee mapFromAttributes(Attributes attrs) throws NamingException, javax.naming.NamingException {
            Employee employee = new Employee();
            employee.setName((String) attrs.get("sAMAccountName").get());
            employee.setDisplayName((String) attrs.get("displayName").get());
            employee.setEmail((String) attrs.get("userprincipalname").get());
            employee.setDuty((String) attrs.get("title").get());
            employee.setDepartment((String) attrs.get("department").get());
            employee.setSuperior((String) attrs.get("manager").get());
            employee.setLocation((String) attrs.get("physicaldeliveryofficename").get());
            employee.setTel((String) attrs.get("homephone").get());
            employee.setPhone((String) attrs.get("mobile").get());
            String skill = (String) attrs.get("description").get();
            String skills[] = skill.split(";");
            employee.setSkills(skills);
            return employee;
        }
    }

    /**
     * 使用用户凭证取得用户信息
     * @param token 用户凭证
     * @return
     */
    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> getUserInfo(@RequestHeader("token") String token){
        //解析token
        String username = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token).getBody().getSubject();
        String roles = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token).getBody().getAudience();
        long expiration = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token).getBody().getExpiration().getTime();
        long current = new Date().getTime();
        //验证token过期时间、用户权限
        if(current > expiration || roles.indexOf("ROLE_USER") == -1) {
            return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
        }
        //查询并产生用户信息
        Employee employee = ldapTemplate
                .search(query().where("objectclass").is("person").and("sAMAccountName").is(username),
                        new EmployeeAttributesMapper())
                .get(0);
        return new ResponseEntity<String>(JSON.toJSONString(employee , SerializerFeature.DisableCircularReferenceDetect) , HttpStatus.OK);
    }

}
写完收工,文字表达能力实在是差,各位费眼了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现展示用户信息功能需要以下步骤: 1. 创建一个SQLite数据库,定义表结构和字段,用于存储用户信息。 2. 在Android应用中创建一个SQLiteOpenHelper类,用于创建和升级数据库。 3. 在应用中创建一个数据访问对象(DAO)类,用于与数据库进行交互。 4. 在应用中创建一个实体类,用于表示一个用户信息。 5. 在应用中创建一个Activity用于展示用户信息。 6. 在Activity中,使用DAO类访问数据库,获取用户信息展示。 以下是一个简单的实现步骤: 1. 创建SQLite数据库和表 在SQLiteOpenHelper类中实现onCreate()方法,在其中创建数据库和表: ```java public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, gender TEXT)"); } ``` 2. 实现DAO类 DAO类用于与数据库进行交互,包括增删改查等操作。例如,实现一个UserDAO类,包含获取所有用户信息的方法: ```java public class UserDAO { private SQLiteDatabase db; private SQLiteOpenHelper dbHelper; public UserDAO(Context context) { dbHelper = new MyDatabaseHelper(context); db = dbHelper.getWritableDatabase(); } public List<User> getAllUsers() { List<User> userList = new ArrayList<>(); Cursor cursor = db.query("users", null, null, null, null, null, null); while (cursor.moveToNext()) { User user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex("id"))); user.setName(cursor.getString(cursor.getColumnIndex("name"))); user.setAge(cursor.getInt(cursor.getColumnIndex("age"))); user.setGender(cursor.getString(cursor.getColumnIndex("gender"))); userList.add(user); } cursor.close(); return userList; } } ``` 3. 实现实体类 实体类用于表示一个用户信息,例如: ```java public class User { private int id; private String name; private int age; private String gender; // getter and setter methods } ``` 4. 实现展示用户信息的Activity 在该Activity中,可以使用DAO类获取所有用户信息,并使用RecyclerView等组件展示。 ```java public class UserListActivity extends AppCompatActivity { private UserDAO userDAO; private RecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_list); recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); userDAO = new UserDAO(this); List<User> userList = userDAO.getAllUsers(); UserAdapter adapter = new UserAdapter(userList); recyclerView.setAdapter(adapter); } } ``` 以上是一个简单的实现方法,实际项目中可能需要更多的功能和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值