【前端】智能库房综合管理系统前端项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
10 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. <template>
  2. <div class="app-container">
  3. <el-row class="container-main" :gutter="20">
  4. <el-col class="container-left" :xs="24" :sm="24" :md="8" :lg="6" :xl="5">
  5. <span class="right-top-line" />
  6. <span class="left-bottom-line" />
  7. <div class="user-content">
  8. <h4 class="info-title">个人信息</h4>
  9. <div class="el-upload">
  10. <div class="user-img-cover">
  11. <img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" title="点击上传头像" class="avatar" :onerror="defaultImg" @click="toggleShow">
  12. </div>
  13. <myUpload
  14. v-model="show"
  15. :headers="headers"
  16. :url="updateAvatarApi"
  17. @crop-upload-success="cropUploadSuccess"
  18. />
  19. </div>
  20. <ul class="user-info">
  21. <li><div style="height: 100%"><i class="iconfont icon-dengluzhanghao-fanbai" /> 登录账号<div class="user-right">{{ user.username }}</div></div></li>
  22. <li><i class="iconfont icon-yonghunicheng-fanbai" /> 用户昵称 <div class="user-right">{{ user.nickName }}</div></li>
  23. <li><i class="iconfont icon-suoshubumen-fanbai" /> 所属部门 <div class="user-right"> {{ user.dept.name }}</div></li>
  24. <li><i class="iconfont icon-shoujihaoma-fanbai" /> 手机号码 <div class="user-right">{{ user.phone }}</div></li>
  25. <li><i class="iconfont icon-yonghuyouxiang-fanbai" /> 用户邮箱 <div class="user-right">{{ user.email }}</div></li>
  26. <li>
  27. <i class="iconfont icon-anquanshezhi-fanbai" /> 安全设置
  28. <div class="user-right">
  29. <a @click="$refs.pass.dialog = true">修改密码</a>
  30. </div>
  31. </li>
  32. </ul>
  33. </div>
  34. </el-col>
  35. <el-col class="container-right tab-content" :xs="24" :sm="24" :md="16" :lg="18" :xl="19">
  36. <span class="right-top-line" />
  37. <span class="left-bottom-line" />
  38. <div class="user-right-content">
  39. <ul class="tab-nav">
  40. <li :class="{'active-tab-nav': activeIndex == 0}" @click="handleClick(0)">用户资料<i /></li>
  41. <li :class="{'active-tab-nav': activeIndex == 1}" @click="handleClick(1)">我的消息<i /></li>
  42. <li :class="{'active-tab-nav': activeIndex == 2}" @click="handleClick(2)">操作日志<i /></li>
  43. <!-- 最右侧装饰img -->
  44. <span class="tab-right-img" />
  45. </ul>
  46. <div v-if="activeIndex == 0" class="tab-item">
  47. <el-form ref="form" :model="form" :rules="rules" size="small" label-width="65px">
  48. <el-form-item label="昵称" prop="nickName">
  49. <el-input v-model="form.nickName" style="width: 35%" />
  50. <span style="color:#999;margin-left: 22px;">用户昵称不作为登录使用</span>
  51. </el-form-item>
  52. <el-form-item label="手机号" prop="phone">
  53. <el-input v-model="form.phone" style="width: 35%;" />
  54. <span style="color: #999;margin-left: 22px;">手机号码不能重复</span>
  55. </el-form-item>
  56. <el-form-item label="性别">
  57. <el-radio-group v-model="form.gender" style="width: 178px">
  58. <el-radio label="男"></el-radio>
  59. <el-radio label="女"></el-radio>
  60. </el-radio-group>
  61. </el-form-item>
  62. <el-form-item label="">
  63. <el-button :loading="saveLoading" size="mini" type="primary" @click="doSubmit">保存配置</el-button>
  64. </el-form-item>
  65. </el-form>
  66. </div>
  67. <!-- 我的消息 -->
  68. <div v-if="activeIndex == 1" class="tab-item">
  69. <messageCenter />
  70. </div>
  71. <!-- 操作日志 -->
  72. <div v-if="activeIndex == 2" class="tab-item">
  73. <el-table v-loading="loading" :data="data" style="width: 100%;">
  74. <el-table-column prop="description" label="行为" />
  75. <el-table-column prop="requestIp" label="IP" />
  76. <el-table-column :show-overflow-tooltip="true" prop="address" label="IP来源" />
  77. <el-table-column prop="browser" label="浏览器" />
  78. <el-table-column prop="time" label="请求耗时" align="center">
  79. <template slot-scope="scope">
  80. <el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
  81. <el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
  82. <el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
  83. </template>
  84. </el-table-column>
  85. <el-table-column align="right">
  86. <template slot="header">
  87. <div style="display:inline-block;float: right;cursor: pointer" @click="init">创建日期<i class="el-icon-refresh" style="margin-left: 40px" /></div>
  88. </template>
  89. <template slot-scope="scope">
  90. <span>{{ scope.row.createTime }}</span>
  91. </template>
  92. </el-table-column>
  93. </el-table>
  94. <!--分页组件-->
  95. <el-pagination
  96. :total="total"
  97. :current-page="page + 1"
  98. style="margin-top: 8px;"
  99. layout="total, prev, pager, next, sizes"
  100. @size-change="sizeChange"
  101. @current-change="pageChange"
  102. />
  103. </div>
  104. </div></el-col>
  105. </el-row>
  106. <updateEmail ref="email" :email="user.email" />
  107. <updatePass ref="pass" />
  108. </div>
  109. </template>
  110. <script>
  111. import myUpload from 'vue-image-crop-upload'
  112. import { mapGetters } from 'vuex'
  113. import updatePass from './center/updatePass'
  114. import updateEmail from './center/updateEmail'
  115. import { getToken } from '@/utils/auth'
  116. import store from '@/store'
  117. import { isvalidPhone } from '@/utils/validate'
  118. import crud from '@/mixins/crud'
  119. import { editUser } from '@/api/system/user'
  120. import Avatar from '@/assets/images/avatar.png'
  121. import messageCenter from './messageCenter/index.vue'
  122. export default {
  123. name: 'Center',
  124. components: { updatePass, updateEmail, myUpload, messageCenter },
  125. mixins: [crud],
  126. data() {
  127. // 自定义验证
  128. const validPhone = (rule, value, callback) => {
  129. if (!value) {
  130. callback(new Error('请输入电话号码'))
  131. } else if (!isvalidPhone(value)) {
  132. callback(new Error('请输入正确的11位手机号码'))
  133. } else {
  134. callback()
  135. }
  136. }
  137. return {
  138. defaultImg: 'this.src="' + require('@/assets/images/avatar.png') + '"',
  139. show: false,
  140. Avatar: Avatar,
  141. activeIndex: 0,
  142. saveLoading: false,
  143. headers: {
  144. 'Authorization': getToken()
  145. },
  146. form: {},
  147. rules: {
  148. nickName: [
  149. { required: true, message: '请输入用户昵称', trigger: 'blur' },
  150. { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  151. ],
  152. phone: [
  153. { required: true, trigger: 'blur', validator: validPhone }
  154. ]
  155. }
  156. }
  157. },
  158. computed: {
  159. ...mapGetters([
  160. 'user',
  161. 'updateAvatarApi',
  162. 'baseApi'
  163. ])
  164. },
  165. created() {
  166. this.form = { id: this.user.id, nickName: this.user.nickName, gender: this.user.gender, phone: this.user.phone }
  167. store.dispatch('GetInfo').then(() => {})
  168. if (this.$route.query) {
  169. this.activeIndex = this.$route.query.activeIndex
  170. }
  171. },
  172. methods: {
  173. toggleShow() {
  174. this.show = !this.show
  175. },
  176. handleClick(index) {
  177. this.activeIndex = index
  178. if (this.activeIndex === 2) {
  179. this.init()
  180. }
  181. },
  182. beforeInit() {
  183. this.url = 'api/logs/user'
  184. return true
  185. },
  186. cropUploadSuccess(jsonData, field) {
  187. store.dispatch('GetInfo').then(() => {})
  188. },
  189. doSubmit() {
  190. if (this.$refs['form']) {
  191. this.$refs['form'].validate((valid) => {
  192. if (valid) {
  193. this.saveLoading = true
  194. editUser(this.form).then(() => {
  195. this.editSuccessNotify()
  196. store.dispatch('GetInfo').then(() => {})
  197. this.saveLoading = false
  198. }).catch(() => {
  199. this.saveLoading = false
  200. })
  201. }
  202. })
  203. }
  204. }
  205. }
  206. }
  207. </script>
  208. <style rel="stylesheet/scss" lang="scss" scoped>
  209. .user-content{
  210. color: #fff;
  211. .iconfont{
  212. margin-right: 12px;
  213. }
  214. }
  215. .info-title{
  216. margin: 0;
  217. height: 40px;
  218. line-height: 40px;
  219. font-size: 16px;
  220. font-weight: bold;
  221. color: #359AFC;
  222. text-align: center;
  223. letter-spacing: 2px;
  224. background-color: #02255F;
  225. }
  226. .el-upload{
  227. display: block;
  228. width: 120px;
  229. height: 120px;
  230. border-radius: 50%;
  231. margin: 40px auto 60px auto;
  232. overflow: hidden;
  233. .user-img-cover{
  234. width: 120px;
  235. height: 120px;
  236. line-height: 120px;
  237. }
  238. .avatar {
  239. width: 100%;
  240. height: 100%;
  241. }
  242. }
  243. .user-info {
  244. padding: 0 22px;
  245. list-style: none;
  246. li{
  247. border-bottom: 1px dashed #113D72;
  248. font-size: 14px;
  249. height: 41px;
  250. line-height: 40px;
  251. }
  252. .user-right {
  253. float: right;
  254. a{
  255. margin-left: 20px;
  256. color: #3A99FD;
  257. }
  258. }
  259. }
  260. .container-left,
  261. .container-right{
  262. min-height: calc(100vh - 230px);
  263. }
  264. .tab-content{
  265. ::v-deep .el-form{
  266. padding: 0 20px;
  267. .el-form-item__label{
  268. color: #339CFF;
  269. }
  270. .el-input__inner{
  271. height: 36px;
  272. line-height: 36px;
  273. color: #fff;
  274. border: 1px solid #339CFF;
  275. background: transparent;
  276. }
  277. .el-radio{
  278. color: #fff;
  279. }
  280. .el-button{
  281. font-size: 16px;
  282. padding: 7px 20px;
  283. color: #fff;
  284. background: #3A99FD;
  285. }
  286. }
  287. }
  288. input:-webkit-autofill,
  289. textarea:-webkit-autofill,
  290. select:-webkit-autofill {
  291. -webkit-text-fill-color: #fff !important;
  292. background-color: transparent;
  293. transition: background-color 50000s ease-in-out 0s;
  294. }
  295. input {
  296. background-color: transparent;
  297. }
  298. .app-container{
  299. margin-bottom: 0;
  300. }
  301. </style>