BaseSetting.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <div class="account-padding" :class="[`${prefixCls}`]">
  3. <div class="user-setting-top">
  4. <div class="account-avatar">
  5. <CropperAvatar
  6. :uploadApi="uploadImg"
  7. :showBtn="false"
  8. :value="avatar"
  9. :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
  10. @change="updateAvatar"
  11. width="80"
  12. />
  13. <div class="account-right">
  14. <div v-if="!isEdit">
  15. <span class="font-size-17 account-name">{{ userInfo.realname }}</span>
  16. <a-tooltip content="编辑姓名">
  17. <Icon class="pointer font-size-17 gray-bd account-icon" icon="ant-design:edit-outlined"
  18. @click="editHandleClick" />
  19. </a-tooltip>
  20. </div>
  21. <div v-else>
  22. <a-input ref="accountNameEdit" :maxlength="100" v-model:value="userInfo.realname" @blur="editRealName" />
  23. </div>
  24. <div class="use-day">
  25. 使用:<span>{{userInfo.createTimeText}}</span>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="account-data">
  31. <!-- 详细资料 -->
  32. <div class="account-detail">
  33. <div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">详细资料</div>
  34. <div class="margin-bottom-10 font-size-13">
  35. <span class="gray-75 item-label">生日</span>
  36. <span class="gray-3">{{ userInfo.birthday }}</span>
  37. </div>
  38. <div class="margin-bottom-10 font-size-13">
  39. <span class="gray-75 item-label">性别</span>
  40. <span class="gray-3">{{ userInfo.sexText }}</span>
  41. </div>
  42. <div class="margin-bottom-10 nowarp font-size-13">
  43. <span class="gray-75 item-label">职位</span>
  44. <span class="gray-3">{{ userInfo.postText ? userInfo.postText : "未填写" }}</span>
  45. </div>
  46. <div class="font-size-13">
  47. <span class="item-label"></span>
  48. <span class="item-label pointer" style="color:#1e88e5" @click="openEditModal">编辑</span>
  49. </div>
  50. </div>
  51. <!-- 联系信息 -->
  52. <div class="account-info">
  53. <div class="font-size-15 font-bold font-color-gray" style="margin-bottom: 16px">联系信息</div>
  54. <div class="margin-bottom-10 font-size-13">
  55. <span class="gray-75 item-label">邮箱</span>
  56. <span class="gray-3">{{ userInfo.email ? userInfo.email : "未填写" }}</span>
  57. </div>
  58. <div class="margin-bottom-10 font-size-13">
  59. <span class="gray-75 item-label">手机</span>
  60. <span class="gray-3">{{ userInfo.phone ? userInfo.phone : "未填写" }}</span>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. <UserAccountModal @register="registerModal" @success="getUserDetail"></UserAccountModal>
  66. </template>
  67. <script lang="ts" setup>
  68. import { computed, onMounted, ref } from 'vue';
  69. import { CollapseContainer } from '/@/components/Container';
  70. import { CropperAvatar } from '/@/components/Cropper';
  71. import { useMessage } from '/@/hooks/web/useMessage';
  72. import headerImg from '/@/assets/images/header.jpg';
  73. import { defHttp } from '/@/utils/http/axios';
  74. import { useUserStore } from '/@/store/modules/user';
  75. import { uploadImg } from '/@/api/sys/upload';
  76. import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
  77. import dayjs from 'dayjs';
  78. import { ajaxGetDictItems, getDictItemsByCode, initDictOptions } from '/@/utils/dict';
  79. import { userEdit, getUserData, queryNameByCodes } from './UserSetting.api';
  80. import UserAccountModal from './commponents/UserAccountModal.vue';
  81. import { useModal } from '/@/components/Modal';
  82. import { cloneDeep } from 'lodash-es';
  83. import { useDesign } from '/@/hooks/web/useDesign';
  84. //TODO 当字典租户隔离时,数据会查不到,默认一个
  85. const sexOption = getDictItemsByCode("sex") || [{text:'男',value:'1'},{text:'女',value:'2'}];
  86. const { createMessage } = useMessage();
  87. const userStore = useUserStore();
  88. const { prefixCls } = useDesign('j-base-setting-container');
  89. //是否编辑
  90. const isEdit = ref<boolean>(false);
  91. //用户信息
  92. const userInfo = ref<any>({});
  93. //编辑时input触发事件
  94. const accountNameEdit = ref();
  95. const [registerModal, { openModal }] = useModal();
  96. //头像动态计算
  97. const avatar = computed(() => {
  98. return getFileAccessHttpUrl(userInfo.value.avatar) || headerImg;
  99. });
  100. /**
  101. * 更新用户头像
  102. */
  103. function updateAvatar(src: string, data: string) {
  104. const userinfo = userStore.getUserInfo;
  105. userinfo.avatar = data;
  106. userStore.setUserInfo(userinfo);
  107. if (data) {
  108. updateUserInfo({ avatar: data, id: userinfo.id });
  109. }
  110. }
  111. /**
  112. * 更新用户信息
  113. * @params 参数
  114. */
  115. function updateUserInfo(params) {
  116. userEdit(params).then((res) => {
  117. if (!res.success) {
  118. createMessage.warn(res.message);
  119. }
  120. });
  121. }
  122. /**
  123. * 编辑按钮点击事件
  124. */
  125. function editHandleClick() {
  126. isEdit.value = true;
  127. setTimeout(() => {
  128. accountNameEdit.value.focus();
  129. }, 100);
  130. }
  131. /**
  132. * 修改真实姓名
  133. */
  134. function editRealName() {
  135. if (userInfo.value.realname) {
  136. updateUserInfo({ realname: userInfo.value.realname, id: userInfo.value.id });
  137. userStore.setUserInfo(userInfo.value);
  138. } else {
  139. createMessage.warn("请输入姓名");
  140. }
  141. isEdit.value = false;
  142. }
  143. /**
  144. * 获取生日信息
  145. */
  146. function getBirthDay(val) {
  147. if (val) {
  148. return dayjs(val).format("YYYY-MM-DD");
  149. } else {
  150. return "未填写";
  151. }
  152. }
  153. /**
  154. * 获取性别
  155. * @param val
  156. */
  157. function getSex(val) {
  158. let findOption = sexOption.find(item => parseInt(item.value) === val);
  159. let sex = "未填写";
  160. if (findOption) {
  161. sex = findOption.text;
  162. }
  163. return sex;
  164. }
  165. /**
  166. * 打开编辑弹窗
  167. */
  168. function openEditModal() {
  169. let value = cloneDeep(userInfo.value);
  170. openModal(true, {
  171. record: value
  172. });
  173. }
  174. /**
  175. * 获取用户信息
  176. */
  177. function getUserDetail() {
  178. getUserData().then((async res => {
  179. if (res.success) {
  180. if (res.result) {
  181. res.result.sexText = getSex(res.result.sex);
  182. res.result.birthday = getBirthDay(res.result.birthday);
  183. res.result.createTimeText = getDiffDay(res.result.createTime);
  184. userInfo.value = res.result;
  185. } else {
  186. userInfo.value = {};
  187. }
  188. }
  189. }));
  190. }
  191. /**
  192. * 获取使用时间
  193. * @param date
  194. */
  195. function getDiffDay(date) {
  196. // 计算两个日期之间的天数差值
  197. let totalDays, diffDate
  198. let createDate = Date.parse(date);
  199. let nowDate = new Date().getTime();
  200. // 将两个日期都转换为毫秒格式,然后做差
  201. diffDate = Math.abs(nowDate - createDate) // 取相差毫秒数的绝对值
  202. totalDays = Math.floor(diffDate / (1000 * 3600 * 24)) // 向下取整
  203. return totalDays+" 天";
  204. }
  205. onMounted(async () => {
  206. getUserDetail();
  207. });
  208. </script>
  209. <style lang="less">
  210. // update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
  211. @prefix-cls: ~'@{namespace}-j-base-setting-container';
  212. .@{prefix-cls}{
  213. .user-setting-top {
  214. padding-top: 40px;
  215. width: 100%;
  216. border-bottom: 1px solid @border-color-base;
  217. display: flex;
  218. padding-bottom: 40px;
  219. }
  220. .account-avatar {
  221. align-items: center;
  222. display: flex;
  223. margin-right: 30px;
  224. flex: 1;
  225. }
  226. .change-avatar {
  227. img {
  228. display: block;
  229. margin-bottom: 15px;
  230. border-radius: 50%;
  231. }
  232. }
  233. .account-right {
  234. margin-left: 25px !important;
  235. }
  236. .font-size-15 {
  237. font-size: 15px;
  238. }
  239. .font-size-17 {
  240. font-size: 17px;
  241. }
  242. .pointer {
  243. cursor: pointer;
  244. }
  245. .account-name {
  246. white-space: nowrap;
  247. overflow: hidden;
  248. width: 200px;
  249. text-overflow: ellipsis;
  250. line-height: 32px !important;
  251. /*begin 兼容暗夜模式*/
  252. color: @text-color;
  253. /*end 兼容暗夜模式*/
  254. font-weight: 500;
  255. }
  256. .gray-bd {
  257. color: #bdbdbd;
  258. }
  259. .account-icon {
  260. margin-left: 4px;
  261. }
  262. .account-data {
  263. width: 100% !important;
  264. display: flex;
  265. min-width: 0;
  266. }
  267. .account-detail {
  268. width: 40%;
  269. display: flex;
  270. flex-direction: column;
  271. padding: 40px 0;
  272. .item-label {
  273. display: inline-block;
  274. text-align: left;
  275. width: 80px;
  276. }
  277. }
  278. .font-bold {
  279. font-weight: 700 !important;
  280. }
  281. .margin-bottom-10 {
  282. margin-bottom: 10px;
  283. }
  284. .account-info {
  285. width: 60%;
  286. display: flex;
  287. flex-direction: column;
  288. padding: 40px 0;
  289. box-sizing: border-box;
  290. margin-left: 10px;
  291. .item-label {
  292. display: inline-block;
  293. text-align: left;
  294. width: 80px;
  295. }
  296. }
  297. .nowarp {
  298. overflow: hidden;
  299. white-space: nowrap;
  300. text-overflow: ellipsis;
  301. }
  302. .account-padding {
  303. padding-left: 20px !important;
  304. padding-right: 40px !important;
  305. }
  306. .use-day {
  307. /*begin 兼容暗夜模式*/
  308. color: @text-color;
  309. /*end 兼容暗夜模式*/
  310. margin-top: 10px;
  311. font-size: 13px;
  312. span {
  313. color: #1e88e5;
  314. margin-left: 5px;
  315. }
  316. }
  317. .font-size-13 {
  318. font-size: 13px;
  319. }
  320. }
  321. // update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
  322. </style>