profile.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <view class="app-page">
  3. <view v-if="loading != 'success'" class="loading-wrap pa-24">
  4. <block v-if="loading == 'loading'"></block>
  5. <view v-else-if="loading == 'error'" class="loading-error flex flex-col flex-center">
  6. <tm-empty icon="icon-wind-cry" label="加载失败"><tm-button theme="light-blue" size="m" @click="fnGetData()">重新加载</tm-button></tm-empty>
  7. </view>
  8. </view>
  9. <view class="app-page-content round-3 bg-white pa-46 pl-10 pr-10" v-else>
  10. <tm-form @submit="fnSubmit">
  11. <tm-sheet :shadow="0" :margin="[0, 0]" :padding="[0, 0]">
  12. <view class="avatar flex flex-center pa-12 bg-white">
  13. <text class="edit-icon flex flex-center"><text class=" iconfont icon-cloudupload"></text></text>
  14. <image class="avatar-img" :src="result.showAvatar" @click="fnShowUploadAvatarSelect()"></image>
  15. </view>
  16. <tm-input name="username" required title="用户名" align="right" v-model="result.username"></tm-input>
  17. <tm-input name="nickname" required title="昵称" align="right" v-model="result.nickname"></tm-input>
  18. <tm-input name="email" required title="电子邮箱" align="right" v-model="result.email"></tm-input>
  19. <tm-input
  20. name="description"
  21. :vertical="true"
  22. required
  23. :height="150"
  24. input-type="textarea"
  25. bg-color="grey-lighten-5"
  26. :maxlength="200"
  27. title="个人说明"
  28. placeholder="请输入个人说明,不超过200字符"
  29. v-model="result.description"
  30. :borderBottom="false"
  31. :adjustPosition="true"
  32. ></tm-input>
  33. <view class="pa-30"><tm-button navtie-type="form" theme="bg-gradient-blue-accent" block>保存修改</tm-button></view>
  34. </tm-sheet>
  35. </tm-form>
  36. <tm-actionSheetMenu @change="fnOnUploadAvatarChange" v-model="uploadAvatarShow" title="请选择头像" :actions="['本地上传', '附件选择']"></tm-actionSheetMenu>
  37. <!-- 附件选择文件 -->
  38. <attachment-select selectType="image" v-if="attachmentsSelectShow" @on-select="fnOnAttachmentsSelect" @on-close="attachmentsSelectShow = false"></attachment-select>
  39. </view>
  40. </view>
  41. </template>
  42. <script>
  43. import { getAdminAccessToken } from '@/utils/auth.js';
  44. import tmSkeleton from '@/tm-vuetify/components/tm-skeleton/tm-skeleton.vue';
  45. import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
  46. import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
  47. import tmForm from '@/tm-vuetify/components/tm-form/tm-form.vue';
  48. import tmInput from '@/tm-vuetify/components/tm-input/tm-input.vue';
  49. import tmImages from '@/tm-vuetify/components/tm-images/tm-images.vue';
  50. import tmActionSheetMenu from '@/tm-vuetify/components/tm-actionSheetMenu/tm-actionSheetMenu.vue';
  51. import tmSheet from '@/tm-vuetify/components/tm-sheet/tm-sheet.vue';
  52. import AttachmentSelect from '@/components/attachment-select/attachment-select.vue';
  53. export default {
  54. components: {
  55. tmSkeleton,
  56. tmButton,
  57. tmEmpty,
  58. tmForm,
  59. tmInput,
  60. tmImages,
  61. tmActionSheetMenu,
  62. tmSheet,
  63. AttachmentSelect
  64. },
  65. data() {
  66. return {
  67. loading: 'loading',
  68. queryParams: {
  69. size: 10,
  70. page: 0
  71. },
  72. result: {
  73. username: undefined,
  74. nickname: undefined,
  75. email: undefined,
  76. avatar: undefined,
  77. showAvatar: undefined,
  78. description: undefined
  79. },
  80. uploadAvatarShow: false,
  81. attachmentsSelectShow: false,
  82. verifyEmail: () => {
  83. return val => {
  84. return {
  85. check: uni.$tm.u.email(val),
  86. text: '请输入正确的邮箱'
  87. };
  88. };
  89. }
  90. };
  91. },
  92. onLoad() {
  93. this.fnSetPageTitle('个人资料');
  94. },
  95. created() {
  96. this.fnGetData();
  97. },
  98. onPullDownRefresh() {
  99. this.fnGetData();
  100. },
  101. methods: {
  102. fnGetData() {
  103. this.loading = 'loading';
  104. uni.showLoading({
  105. mask: true,
  106. title: '加载中...'
  107. });
  108. this.$httpApi.admin
  109. .getAdminProfile()
  110. .then(res => {
  111. if (res.status == 200) {
  112. let { avatar } = res.data;
  113. this.result = res.data;
  114. this.result.showAvatar = this.$utils.checkAvatarUrl(avatar);
  115. this.loading = 'success';
  116. } else {
  117. this.loading = 'error';
  118. }
  119. })
  120. .catch(err => {
  121. console.error(err);
  122. this.loading = 'error';
  123. })
  124. .finally(() => {
  125. uni.hideLoading();
  126. uni.stopPullDownRefresh();
  127. });
  128. },
  129. fnShowUploadAvatarSelect() {
  130. this.uploadAvatarShow = true;
  131. },
  132. fnOnUploadAvatarChange(e) {
  133. switch (e.index) {
  134. case 0:
  135. // 本地上传
  136. uni.chooseImage({
  137. count: 1,
  138. success: res => {
  139. uni.uploadFile({
  140. filePath: res.tempFilePaths[0],
  141. header: {
  142. 'admin-authorization': getAdminAccessToken()
  143. },
  144. url: this.$baseApiUrl + '/api/admin/attachments/upload',
  145. name: 'file',
  146. success: upladRes => {
  147. const _uploadRes = JSON.parse(upladRes.data);
  148. if (_uploadRes.status == 200) {
  149. this.result.avatar = _uploadRes.data.path;
  150. this.result.showAvatar = this.$utils.checkAvatarUrl(_uploadRes.data.path);
  151. this.$focusUpdate();
  152. } else {
  153. uni.$tm.toast(_uploadRes.message);
  154. }
  155. },
  156. fail: err => {
  157. uni.$tm.toast(err.message);
  158. }
  159. });
  160. }
  161. });
  162. break;
  163. case 1:
  164. // 从附件库选择
  165. this.attachmentsSelectShow = true;
  166. break;
  167. }
  168. },
  169. // 监听附件选择
  170. fnOnAttachmentsSelect(file) {
  171. this.result.avatar = file.path;
  172. this.result.showAvatar = this.$utils.checkAvatarUrl(file.path);
  173. this.attachmentsSelectShow = false;
  174. },
  175. fnSubmit(e) {
  176. if (e === false) return uni.$tm.toast('请填写必填项。');
  177. uni.showLoading({
  178. title: '保存中...'
  179. });
  180. this.$httpApi.admin
  181. .updateAdminProfile(this.result)
  182. .then(res => {
  183. if (res.status == 200) {
  184. uni.$tm.toast('保存成功');
  185. this.$tm.vx.commit('blogger/setBlogger', this.result);
  186. } else {
  187. uni.$tm.toast('保存失败,请重试!');
  188. }
  189. })
  190. .catch(err => {
  191. uni.$tm.toast('保存失败,请重试!');
  192. });
  193. }
  194. }
  195. };
  196. </script>
  197. <style lang="scss" scoped>
  198. .app-page {
  199. width: 100vw;
  200. min-height: 100vh;
  201. box-sizing: border-box;
  202. }
  203. .app-page-content {
  204. width: 100%;
  205. height: 100vh;
  206. box-sizing: border-box;
  207. // box-shadow: 0rpx 6rpx 24rpx rgba(0, 0, 0, 0.03);
  208. }
  209. .loading-wrap {
  210. padding: 24rpx;
  211. .loading-error {
  212. height: 65vh;
  213. }
  214. }
  215. .avatar {
  216. position: relative;
  217. &-img {
  218. width: 170rpx;
  219. height: 170rpx;
  220. box-sizing: border-box;
  221. border: 6rpx solid #fff;
  222. border-radius: 50%;
  223. box-shadow: 0rpx 6rpx 24rpx rgba(0, 0, 0, 0.03);
  224. }
  225. .edit-icon {
  226. width: 46rpx;
  227. height: 46rpx;
  228. position: absolute;
  229. left: 390rpx;
  230. bottom: 15rpx;
  231. z-index: 6;
  232. color: #0dadf2;
  233. box-sizing: border-box;
  234. border: 4rpx solid #ffffff;
  235. font-size: 24rpx;
  236. border-radius: 50%;
  237. background-color: #e4e4e4;
  238. }
  239. }
  240. </style>