UserImg.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <div class="userimg-container" :class="{'usering-scale':scale}" @click="onClick" :title="showTitle?fullName:''">
  3. <template v-if="this.isJson(info)">
  4. <img v-if="isShowImg(userImg)&&!imgError" class="userimg-container-img" :src="userImg" @error="loadError"/>
  5. <div v-else class="userimg-container-box" :style="textStyle">
  6. <div class="usertext-container-text" :style="nameStyle">{{userName}}</div>
  7. </div>
  8. </template>
  9. </div>
  10. </template>
  11. <style lang="scss" scoped>
  12. .userimg-container {
  13. display: inline-block;
  14. max-width: 100%;
  15. max-height: 100%;
  16. position: relative;
  17. overflow: hidden;
  18. &.usering-scale {
  19. transition: all 0.2s;
  20. transform: scale(1);
  21. &:hover {
  22. z-index: 1;
  23. transform: scale(1.2);
  24. }
  25. }
  26. .userimg-container-img {
  27. width: 100%;
  28. height: 100%;
  29. display: table;
  30. }
  31. .userimg-container-box {
  32. position: absolute;
  33. top: 0;
  34. left: 0;
  35. width: 100%;
  36. height: 100%;
  37. display: flex;
  38. align-items: center;
  39. justify-content: center;
  40. font-weight: 400;
  41. color: #ffffff;
  42. .usertext-container-text {
  43. flex: 1;
  44. display: flex;
  45. align-items: center;
  46. justify-content: center;
  47. overflow: hidden;
  48. white-space: nowrap;
  49. }
  50. }
  51. }
  52. </style>
  53. <script>
  54. export default {
  55. name: 'UserImg',
  56. props: {
  57. info: {
  58. default: {} //{username, nickname, userimg}
  59. },
  60. size: {
  61. },
  62. scale: {
  63. type: Boolean,
  64. default: false
  65. },
  66. twoWords: {
  67. type: Boolean,
  68. default: false
  69. },
  70. showTitle: {
  71. type: Boolean,
  72. default: false
  73. },
  74. },
  75. data() {
  76. return {
  77. imgError: false,
  78. againUrl: '',
  79. }
  80. },
  81. computed: {
  82. textStyle() {
  83. const style = {
  84. backgroundColor: '#A0D7F1'
  85. };
  86. const {size} = this;
  87. if (size) {
  88. style.fontSize = /^\d+$/.test(size) ? (size + 'px') : size;
  89. }
  90. const {username} = this.info;
  91. if (username) {
  92. let bgColor = '';
  93. for (let i = 0; i < username.length; i++) {
  94. bgColor += parseInt(username[i].charCodeAt(0), 10).toString(16);
  95. }
  96. style.backgroundColor = '#' + bgColor.slice(1, 4);
  97. }
  98. return style;
  99. },
  100. nameStyle() {
  101. const style = {
  102. };
  103. if (this.twoWords) {
  104. if ((this.userName + "").length >= 2) {
  105. style.transform = 'scale(0.68)';
  106. }
  107. }
  108. return style;
  109. },
  110. userName() {
  111. if (!this.isJson(this.info)) {
  112. return '';
  113. }
  114. let name = this.info.send_username || this.info.username;
  115. if (this.info.nickname && !this.isEmojiPrefix(this.info.nickname)) {
  116. name = this.info.nickname;
  117. }
  118. if (this.twoWords) {
  119. if (this.allChina(name) && $A.count(name) == 3) {
  120. return name.substring(1, 3).toLocaleUpperCase();
  121. } else {
  122. return (name + " ").substring(0, 2).toLocaleUpperCase();
  123. }
  124. } else {
  125. return (name + " ").substring(0, 1).toLocaleUpperCase();
  126. }
  127. },
  128. fullName() {
  129. if (!this.isJson(this.info)) {
  130. return '';
  131. }
  132. let name = this.info.send_username || this.info.username;
  133. if (this.info.nickname && !this.isEmojiPrefix(this.info.nickname)) {
  134. name = this.info.nickname;
  135. }
  136. return name;
  137. },
  138. userImg() {
  139. if (!this.isJson(this.info)) {
  140. return '';
  141. }
  142. if (this.againUrl) {
  143. return this.againUrl;
  144. }
  145. return this.info.send_userimg || this.info.userimg;
  146. },
  147. },
  148. methods: {
  149. isJson(obj) {
  150. return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && typeof obj.length == "undefined";
  151. },
  152. isShowImg(url) {
  153. return !!(url && !$A.rightExists(url, 'images/other/avatar.png'));
  154. },
  155. isEmojiPrefix(text) {
  156. return /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text);
  157. },
  158. allChina(str) {
  159. if (/^[\u4e00-\u9fa5]+$/.test(str)) {
  160. return true; //全是中文
  161. } else {
  162. return false;
  163. }
  164. },
  165. loadError() {
  166. if (!this.againUrl) {
  167. if ($A.rightExists(this.userImg, 'images/other/system-message.png')) {
  168. this.againUrl = $A.fillUrl('images/other/system-message.png');
  169. return;
  170. } else if ($A.rightExists(this.userImg, 'images/other/group.png')) {
  171. this.againUrl = $A.fillUrl('images/other/group.png');
  172. return;
  173. }
  174. }
  175. this.imgError = true
  176. },
  177. onClick(e) {
  178. this.$emit('click', e);
  179. }
  180. }
  181. }
  182. </script>