userInfo.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. <template>
  2. <div class="userInfoWarp">
  3. <div class="left">
  4. <div class="avater">
  5. <el-upload
  6. v-if="isEdit"
  7. :show-file-list="false"
  8. :http-request="customRequest"
  9. :before-upload="beforeAvatarUpload"
  10. :limit="1"
  11. >
  12. <img v-if="form.avatar" :src="form.avatar" class="avatar" />
  13. <el-icon v-else class="avatar-uploader-icon">
  14. <Plus />
  15. </el-icon>
  16. </el-upload>
  17. <img
  18. v-else
  19. :src="originForm.avatar"
  20. alt=""
  21. />
  22. </div>
  23. <div class="desc">你好,尊敬的用户 {{ originForm.name }}</div>
  24. <div class="info">
  25. <div class="info_item">
  26. <div class="item_icon">
  27. <img src="../../assets/images/Slice12x.png" alt="" />
  28. </div>
  29. <div class="">用户名:{{ originForm.name }}</div>
  30. </div>
  31. <div class="info_item">
  32. <div class="item_icon">
  33. <img src="../../assets/images/Slice22x.png" alt="" />
  34. </div>
  35. <div class="">用户ID:{{ originForm.userName }}</div>
  36. </div>
  37. <div class="info_item">
  38. <div class="item_icon">
  39. <img src="../../assets/images/Slice32x.png" alt="" />
  40. </div>
  41. <div class="">性别:隐藏</div>
  42. </div>
  43. <div class="info_item">
  44. <div class="item_icon">
  45. <img src="../../assets/images/Slice42x.png" alt="" />
  46. </div>
  47. <div class="">登录时间:{{ originForm.lastLoginDate }}</div>
  48. </div>
  49. </div>
  50. </div>
  51. <div class="middle"></div>
  52. <div class="right">
  53. <div class="title">
  54. <div class="titlemodf"></div>
  55. <div>账号信息</div>
  56. </div>
  57. <div class="setWarp">
  58. <div class="setInput">
  59. <div class="name">姓名</div>
  60. <div class="gk"></div>
  61. <div class="ipt">
  62. <input v-if="isEdit" v-model="form.name" placeholder="请输入姓名" type="text" />
  63. <p v-else>{{ form.name || '--' }}</p>
  64. </div>
  65. <template v-if="!isEdit">
  66. <div v-if="form.name" class="idft">已设置</div>
  67. <div v-else class="idft red">未设置</div>
  68. </template>
  69. </div>
  70. <div class="setInput">
  71. <div class="name">安全手机</div>
  72. <div class="gk"></div>
  73. <div class="ipt">
  74. <input v-if="isEdit" v-model="form.mobile" placeholder="请输入手机号" type="text" />
  75. <p v-else>{{ form.mobile || '--' }}</p>
  76. </div>
  77. <template v-if="!isEdit">
  78. <div v-if="form.mobile" class="idft">已设置</div>
  79. <div v-else class="idft red">未设置</div>
  80. </template>
  81. </div>
  82. <div class="setInput">
  83. <div class="name">安全邮箱</div>
  84. <div class="gk"></div>
  85. <div class="ipt">
  86. <input v-if="isEdit" v-model="form.email" placeholder="请输入安全邮箱" type="text" />
  87. <p v-else>{{ form.email || '--' }}</p>
  88. </div>
  89. <template v-if="!isEdit">
  90. <div v-if="form.email" class="idft">已设置</div>
  91. <div v-else class="idft red">未设置</div>
  92. </template>
  93. </div>
  94. </div>
  95. <div class="btnWarp">
  96. <div class="editBtn" @click="changeInfo">{{ isEdit ? '保存' : '编辑用户信息' }}</div>
  97. <div v-if="isEdit" class="editBtn cancel" @click="cancelInfo">取消</div>
  98. <div class="modBtn" @click="isPwdDialogVisible = true">修改密码</div>
  99. </div>
  100. </div>
  101. <el-dialog v-model="isPwdDialogVisible" title="修改密码" width="500">
  102. <el-form ref="pwdFormRef" :model="pwdForm" :rules="pwdRules" label-width="120px">
  103. <el-form-item label="旧密码" prop="oldPassword">
  104. <el-input v-model="pwdForm.oldPassword" type="password" autocomplete="off"></el-input>
  105. </el-form-item>
  106. <el-form-item label="新密码" prop="newPassword">
  107. <el-input v-model="pwdForm.newPassword" type="password" autocomplete="off"></el-input>
  108. </el-form-item>
  109. <el-form-item label="确认密码" prop="enterPassword">
  110. <el-input v-model="pwdForm.enterPassword" type="password" autocomplete="off"></el-input>
  111. </el-form-item>
  112. </el-form>
  113. <template #footer>
  114. <span class="dialog-footer">
  115. <el-button @click="cancelPassword">取消</el-button>
  116. <el-button type="primary" @click="changePassword">确定</el-button>
  117. </span>
  118. </template>
  119. </el-dialog>
  120. </div>
  121. </template>
  122. <script setup>
  123. import { getUserInfo, upChangePassword, updateUserInfo, uploadPhoto } from '@/api/system/person'
  124. import { Encrypt } from '@/utils/aes'
  125. import { useUserStore } from '@/store/user.js'
  126. import router from '@/router'
  127. const pwdFormRef = ref(null)
  128. const isPwdDialogVisible = ref(false)
  129. const isEdit = ref(false)
  130. const pwdForm = ref({
  131. oldPassword: '',
  132. newPassword: '',
  133. enterPassword: ''
  134. })
  135. const originForm = ref({
  136. avatar: null,
  137. email: '',
  138. mobile: '',
  139. userName: '',
  140. name: ''
  141. })
  142. const form = ref({
  143. avatar: null,
  144. email: '',
  145. mobile: '',
  146. name: ''
  147. })
  148. const pwdRules = ref({
  149. oldPassword: [
  150. { required: true, message: '请输入旧密码', trigger: 'blur' }
  151. ],
  152. newPassword: [
  153. { required: true, message: '请输入新密码', trigger: 'blur' },
  154. { min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
  155. ],
  156. enterPassword: [
  157. { required: true, message: '请再次输入新密码', trigger: 'blur' },
  158. { min: 6, message: '密码长度不能小于6位', trigger: 'blur' },
  159. // 添加一个自定义校验规则来确保新密码和确认密码一致
  160. {
  161. validator: (rule, value, callback) => {
  162. if (value !== pwdForm.value.newPassword) {
  163. callback(new Error('两次输入的密码不一致'))
  164. } else {
  165. callback()
  166. }
  167. }, trigger: 'blur'
  168. }
  169. ]
  170. })
  171. onMounted(() => {
  172. getList()
  173. })
  174. function getList() {
  175. getUserInfo().then((res) => {
  176. if (res.code == 200) {
  177. originForm.value = res.data
  178. form.value = { ...originForm.value }
  179. } else {
  180. ElMessage({
  181. message: res.msg,
  182. type: 'error'
  183. })
  184. }
  185. })
  186. }
  187. function changeInfo() {
  188. if (!isEdit.value) {
  189. form.value = { ...originForm.value }
  190. form.value.avatar = null
  191. isEdit.value = true
  192. } else {
  193. console.log('保存了')
  194. // 保存
  195. if (!form.value.mobile.length || !form.value.name.length || !form.value.email.length) {
  196. ElMessage({
  197. message: '信息填写不完整',
  198. type: 'warning'
  199. })
  200. } else {
  201. let { avatar, email, mobile, name } = form.value
  202. updateUserInfo({
  203. avatar,
  204. email,
  205. mobile,
  206. name
  207. }
  208. ).then((res) => {
  209. if (res.code == 200) {
  210. isEdit.value = false
  211. getList()
  212. ElMessage({
  213. message: '修改成功',
  214. type: 'success'
  215. })
  216. }
  217. })
  218. }
  219. }
  220. }
  221. function cancelInfo() {
  222. isEdit.value = false
  223. form.value = { ...originForm.value }
  224. }
  225. function changePassword() {
  226. pwdFormRef.value.validate((valid) => {
  227. if (valid) {
  228. // 执行密码修改逻辑
  229. upChangePassword({
  230. oldPassword: Encrypt(pwdForm.value.oldPassword),
  231. newPassword: Encrypt(pwdForm.value.newPassword),
  232. enterPassword: Encrypt(pwdForm.value.enterPassword)
  233. }).then((res) => {
  234. if (res.code == 200) {
  235. console.log('密码修改成功', pwdForm.value)
  236. cancelPassword()
  237. ElMessage.success('密码修改成功')
  238. useUserStore().logOut().then(() => {
  239. router.push('/login')
  240. })
  241. } else {
  242. ElMessage.error(res.msg)
  243. }
  244. })
  245. } else {
  246. ElMessage.error('表单数据有误,请按提示修改后再提交')
  247. return false
  248. }
  249. })
  250. }
  251. function cancelPassword() {
  252. pwdForm.value = {
  253. oldPassword: '',
  254. newPassword: '',
  255. enterPassword: ''
  256. }
  257. isPwdDialogVisible.value = false
  258. }
  259. function customRequest(content) {
  260. const dFormData = new FormData()
  261. dFormData.append('file', content.file)
  262. console.log(content.file, '12312')
  263. uploadPhoto(dFormData).then((res) => {
  264. if (res.code == '200') {
  265. form.value.avatar = res.data.link
  266. }
  267. })
  268. }
  269. function beforeAvatarUpload(rawFile) {
  270. if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') { // 允许JPG和PNG格式
  271. ElMessage.error('只能上传JPG或PNG格式的图片!')
  272. return false
  273. } else if (rawFile.size / 1024 / 1024 > 2) {
  274. ElMessage.error('头像尺寸不可以大于2MB!')
  275. return false
  276. }
  277. return true
  278. }
  279. </script>
  280. <style lang='scss' scoped>
  281. .avatar-uploader .el-upload {
  282. border: 1px dashed var(--el-border-color);
  283. border-radius: 6px;
  284. cursor: pointer;
  285. position: relative;
  286. overflow: hidden;
  287. transition: var(--el-transition-duration-fast);
  288. }
  289. .avatar-uploader .el-upload:hover {
  290. border-color: var(--el-color-primary);
  291. }
  292. .el-icon.avatar-uploader-icon {
  293. font-size: 28px;
  294. color: #8c939d;
  295. width: 113px;
  296. height: 113px;
  297. text-align: center;
  298. }
  299. .userInfoWarp {
  300. width: 100%;
  301. background: #ffffff;
  302. display: flex;
  303. .left {
  304. width: 40%;
  305. display: flex;
  306. flex-direction: column;
  307. align-items: center;
  308. font-family: Alibaba PuHuiTi 3, Alibaba PuHuiTi 30;
  309. font-weight: normal;
  310. font-size: 16px;
  311. color: #000000;
  312. .avater {
  313. width: 113px;
  314. height: 113px;
  315. border-radius: 50%;
  316. overflow: hidden;
  317. margin-top: 60px;
  318. img {
  319. width: 100%;
  320. height: 100%;
  321. }
  322. }
  323. .desc {
  324. margin-top: 24px;
  325. }
  326. .info {
  327. margin-top: 96px;
  328. .info_item {
  329. display: flex;
  330. align-items: center;
  331. margin-bottom: 50px;
  332. .item_icon {
  333. width: 32px;
  334. height: 32px;
  335. overflow: hidden;
  336. margin-right: 68px;
  337. img {
  338. width: 100%;
  339. height: 100%;
  340. }
  341. }
  342. }
  343. }
  344. }
  345. .middle {
  346. height: 600px;
  347. width: 1px;
  348. background: #ccc;
  349. margin: 60px 0;
  350. }
  351. .right {
  352. width: 60%;
  353. display: flex;
  354. flex-direction: column;
  355. align-items: center;
  356. .title {
  357. width: 564px;
  358. text-align: left;
  359. margin-top: 85px;
  360. display: flex;
  361. align-items: center;
  362. font-family: Alibaba PuHuiTi 3, Alibaba PuHuiTi 30;
  363. font-weight: normal;
  364. font-size: 20px;
  365. color: #000000;
  366. .titlemodf {
  367. width: 10px;
  368. height: 23px;
  369. background: #0071bb;
  370. border-radius: 0px 0px 0px 0px;
  371. margin-right: 17px;
  372. }
  373. }
  374. .setWarp {
  375. margin-top: 55px;
  376. margin-bottom: 90px;
  377. .setInput {
  378. position: relative;
  379. width: 564px;
  380. height: 66px;
  381. background: #f5f5f5;
  382. border-radius: 10px 10px 10px 10px;
  383. margin-bottom: 34px;
  384. display: flex;
  385. align-items: center;
  386. .name {
  387. font-weight: normal;
  388. font-size: 16px;
  389. color: #7b7b7b;
  390. padding-left: 47px;
  391. width: 105px;
  392. }
  393. .gk {
  394. width: 1px;
  395. height: 28px;
  396. margin-right: 50px;
  397. background: #cccccc;
  398. }
  399. .ipt {
  400. margin-right: 50px;
  401. input {
  402. border: none;
  403. outline: none;
  404. height: 22px;
  405. font-size: 16px;
  406. color: grey;
  407. background: #f5f5f5;
  408. border-bottom: 1px solid #ccc;
  409. }
  410. }
  411. .idft {
  412. position: absolute;
  413. right: 20px;
  414. width: 70px;
  415. height: 30px;
  416. line-height: 30px;
  417. background: #5bd458;
  418. border-radius: 17px 17px 17px 17px;
  419. font-size: 14px;
  420. color: #ffffff;
  421. text-align: center;
  422. &.red {
  423. background: red;
  424. }
  425. }
  426. }
  427. }
  428. .btnWarp {
  429. display: flex;
  430. .editBtn {
  431. width: 146px;
  432. height: 54px;
  433. line-height: 54px;
  434. color: #ffffff;
  435. text-align: center;
  436. background: #4a75d9;
  437. border-radius: 10px 10px 10px 10px;
  438. margin-right: 40px;
  439. &.cancel {
  440. background: grey;
  441. }
  442. }
  443. .modBtn {
  444. width: 146px;
  445. height: 54px;
  446. line-height: 54px;
  447. color: #ffffff;
  448. text-align: center;
  449. background: #ff954b;
  450. border-radius: 10px 10px 10px 10px;
  451. }
  452. }
  453. }
  454. }
  455. </style>