index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <template>
  2. <view class="jnpf-upload-img">
  3. <view :class="'jnpf-upload jnpf-upload-'+align" v-if="!simple">
  4. <template v-if="fileList.length">
  5. <view class="u-list-item u-preview-wrap" v-for="(item, index) in fileList" :key="index">
  6. <view v-if="!disabled&&!detailed" class="u-delete-icon" @tap.stop="deleteItem(index)">
  7. <u-icon class="u-icon" name="close" size="20" color="#ffffff"></u-icon>
  8. </view>
  9. <image class="u-preview-image" :src="baseURL+(item.thumbUrl||item.url)" mode="aspectFill"
  10. @tap.stop="doPreviewImage(baseURL+item.url)"></image>
  11. </view>
  12. </template>
  13. <u-upload v-if="!detailed" width="150" height="150" :action="comUploadUrl+'annexpic'"
  14. :header="uploadHeaders" :form-data="params" @on-list-change="onListChange" :max-size="maxSize"
  15. :max-count="realLimit" :show-upload-list="false" :show-progress="false" :deletable="deletable"
  16. @on-success="onSuccess" @on-error="handleError" ref="uUpload" :file-list="lists" :disabled='disabled'>
  17. </u-upload>
  18. </view>
  19. <view class="tipText u-p-l-20" v-if="!simple">
  20. {{tipText}}
  21. </view>
  22. <view class="text-primary" v-if="simple" @tap.stop="doPreviewImage(baseURL+fileList[0].url)">查看图片</view>
  23. </view>
  24. </template>
  25. <script>
  26. const units = {
  27. KB: 1024,
  28. MB: 1024 * 1024,
  29. GB: 1024 * 1024 * 1024
  30. }
  31. export default {
  32. name: 'jnpf-upload-img',
  33. props: {
  34. modelValue: {
  35. type: [Array, String],
  36. default: () => []
  37. },
  38. tipText: {
  39. type: String,
  40. default: ''
  41. },
  42. limit: {
  43. type: Number,
  44. default: 99
  45. },
  46. sizeUnit: {
  47. type: String,
  48. default: 'MB'
  49. },
  50. pathType: {
  51. type: String,
  52. default: 'defaultPath'
  53. },
  54. isAccount: {
  55. type: Number,
  56. default: 0
  57. },
  58. folder: {
  59. type: String,
  60. default: ''
  61. },
  62. fileSize: {
  63. type: Number,
  64. default: 10
  65. },
  66. disabled: {
  67. type: Boolean,
  68. default: false
  69. },
  70. detailed: {
  71. type: Boolean,
  72. default: false
  73. },
  74. simple: {
  75. type: Boolean,
  76. default: false
  77. },
  78. align: {
  79. type: String,
  80. default: 'right'
  81. },
  82. sortRule: {
  83. type: Array,
  84. default: () => ([])
  85. },
  86. timeFormat: {
  87. type: String,
  88. default: ''
  89. },
  90. },
  91. data() {
  92. return {
  93. fileList: [],
  94. realLimit: 0,
  95. deletable: true,
  96. uploadHeaders: {
  97. Authorization: ''
  98. },
  99. params: {
  100. pathType: this.pathType,
  101. isAccount: this.isAccount,
  102. folder: this.folder,
  103. sortRule: (this.sortRule || []).join(),
  104. timeFormat: this.timeFormat,
  105. },
  106. lists: [],
  107. maxSize: ''
  108. }
  109. },
  110. watch: {
  111. limit(val) {
  112. this.realLimit = val
  113. },
  114. modelValue: {
  115. immediate: true,
  116. handler(val) {
  117. this.fileList = Array.isArray(val) ? JSON.parse(JSON.stringify(val)) : []
  118. }
  119. }
  120. },
  121. created() {
  122. this.uploadHeaders.Authorization = uni.getStorageSync('token')
  123. this.maxSize = this.fileSize ? this.fileSize * units[this.sizeUnit] : 10000000000000
  124. this.$nextTick(() => {
  125. this.lists = this.fileList || []
  126. })
  127. this.realLimit = this.limit
  128. if (this.disabled) this.deletable = false
  129. },
  130. computed: {
  131. baseURL() {
  132. return this.define.baseURL
  133. },
  134. comUploadUrl() {
  135. return this.define.comUploadUrl
  136. },
  137. },
  138. methods: {
  139. onSuccess(data, index, lists, name) {
  140. if (data.code == 200) {
  141. this.fileList.push({
  142. name: lists[index].file.name,
  143. fileId: data.data.name,
  144. url: data.data.url,
  145. thumbUrl: data.data.thumbUrl,
  146. })
  147. this.$emit('update:modelValue', this.fileList)
  148. this.$emit('change', this.fileList)
  149. } else {
  150. lists.splice(index, 1)
  151. this.$u.toast(data.msg)
  152. }
  153. },
  154. handleError(res, index, lists, name) {
  155. lists.splice(index, 1)
  156. },
  157. deleteItem(index) {
  158. uni.showModal({
  159. title: '提示',
  160. content: '您确定要删除此项吗?',
  161. success: res => {
  162. if (res.confirm) {
  163. this.$refs.uUpload.remove(index);
  164. this.fileList.splice(index, 1)
  165. this.$emit('update:modelValue', this.fileList)
  166. this.$emit('change', this.fileList)
  167. uni.showToast({
  168. title: '移除成功',
  169. icon: 'none'
  170. });
  171. }
  172. }
  173. });
  174. },
  175. onListChange(lists) {
  176. this.lists = lists || [];
  177. },
  178. doPreviewImage(url) {
  179. const images = this.fileList.map(item => this.baseURL + item.url);
  180. uni.previewImage({
  181. urls: images,
  182. current: url,
  183. success: () => {},
  184. fail: () => {
  185. uni.showToast({
  186. title: '预览图片失败',
  187. icon: 'none'
  188. });
  189. }
  190. });
  191. }
  192. }
  193. }
  194. </script>
  195. <style lang="scss" scoped>
  196. .jnpf-upload-img {
  197. width: 100%;
  198. .tipText {
  199. color: #606266;
  200. word-break: break-all;
  201. line-height: 48rpx;
  202. text-align: right;
  203. }
  204. .jnpf-upload {
  205. width: 100%;
  206. display: flex;
  207. flex-wrap: wrap;
  208. align-items: center;
  209. &.jnpf-upload-right {
  210. justify-content: flex-end;
  211. }
  212. &.jnpf-upload-left {
  213. justify-content: flex-start;
  214. }
  215. :deep(.u-upload) {
  216. .u-list-item {
  217. margin: 0 !important;
  218. }
  219. }
  220. .u-preview-wrap {
  221. width: 150rpx;
  222. height: 150rpx;
  223. border: 1px solid #ebecee;
  224. overflow: hidden;
  225. margin: 10rpx;
  226. background: rgb(244, 245, 246);
  227. position: relative;
  228. border-radius: 10rpx;
  229. /* #ifndef APP-NVUE */
  230. display: flex;
  231. /* #endif */
  232. align-items: center;
  233. justify-content: center;
  234. .u-preview-image {
  235. display: block;
  236. width: 100%;
  237. height: 100%;
  238. border-radius: 10rpx;
  239. }
  240. .u-delete-icon {
  241. position: absolute;
  242. top: 10rpx;
  243. right: 10rpx;
  244. z-index: 10;
  245. background-color: $u-type-error;
  246. border-radius: 100rpx;
  247. width: 44rpx;
  248. height: 44rpx;
  249. /* #ifndef APP-NVUE */
  250. display: flex;
  251. /* #endif */
  252. align-items: center;
  253. justify-content: center;
  254. }
  255. .u-icon {
  256. /* #ifndef APP-NVUE */
  257. display: flex;
  258. /* #endif */
  259. align-items: center;
  260. justify-content: center;
  261. }
  262. }
  263. }
  264. }
  265. </style>