You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

form-image.vue 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <template>
  2. <view>
  3. <view
  4. class="as-gravity-center"
  5. style="
  6. display: flex;
  7. flex-direction: row;
  8. flex-wrap: wrap;
  9. position: relative;
  10. "
  11. :style="
  12. 'justify-content:' +
  13. (imageList.length === 0 ? 'flex-start' : 'space-between')
  14. "
  15. >
  16. <!-- 嵌套这层就over了 -->
  17. <view
  18. :style="
  19. 'margin-left: ' +
  20. (retract + 10) +
  21. 'rpx;margin-right: ' +
  22. retract +
  23. 'rpx'
  24. "
  25. style="
  26. justify-content: flex-start;
  27. align-items: center;
  28. display: flex;
  29. flex-direction: row;
  30. flex-wrap: wrap;
  31. "
  32. >
  33. <block v-for="(image, indexs) in imageList" :key="indexs">
  34. <view
  35. :style="
  36. 'width:' + innerWidth + 'px;' + 'height:' + innerWidth + 'px'
  37. "
  38. style="
  39. display: block;
  40. margin-left: 5px;
  41. margin-top: 5px;
  42. opacity: 0.7;
  43. "
  44. >
  45. <view
  46. class="as-gravity-center"
  47. @tap="previewImage(indexs, imageList)"
  48. :style="
  49. 'width:' +
  50. (isDelete ? innerWidth / 2 : innerWidth / 2) +
  51. 'px;' +
  52. 'height:' +
  53. innerWidth +
  54. 'px'
  55. "
  56. style="position: absolute; z-index: 3; opacity: 1"
  57. >
  58. <image
  59. v-show="isDelete"
  60. :src="`${$imgUrl}common/big.png`"
  61. style="width: 40rpx; height: 40rpx"
  62. mode="aspectFill"
  63. >
  64. </image>
  65. </view>
  66. <view
  67. v-show="isDelete"
  68. class="as-gravity-center"
  69. @tap="removeImg(indexs, imageList)"
  70. :style="
  71. 'width:' +
  72. innerWidth / 2 +
  73. 'px;' +
  74. 'height:' +
  75. innerWidth +
  76. 'px;' +
  77. 'margin-left: ' +
  78. innerWidth / 2 +
  79. 'px;'
  80. "
  81. style="position: absolute; z-index: 3; opacity: 1"
  82. >
  83. <image
  84. :src="`${$imgUrl}common/remove.png`"
  85. style="width: 40rpx; height: 40rpx"
  86. mode="aspectFill"
  87. >
  88. </image>
  89. </view>
  90. <view
  91. :style="
  92. 'width:' + innerWidth + 'px;' + 'height:' + innerWidth + 'px'
  93. "
  94. style="
  95. position: absolute;
  96. z-index: 2;
  97. background-color: #b2b2b2;
  98. opacity: 0.5;
  99. "
  100. ></view>
  101. <image
  102. :style="
  103. 'width:' + innerWidth + 'px;' + 'height:' + innerWidth + 'px'
  104. "
  105. class="as-radius-8px"
  106. style="position: relative; display: block"
  107. :src="isUrl ? urls + image : image"
  108. :data-src="isUrl ? urls + image : image"
  109. mode="aspectFill"
  110. >
  111. </image>
  112. </view>
  113. </block>
  114. <view
  115. v-if="canChoose"
  116. class="layout4 as-gravity-center"
  117. @tap="chooseImage(item)"
  118. :style="'width:' + innerWidth + 'px;height:' + innerWidth + 'px'"
  119. style="
  120. display: flex;
  121. flex-direction: column;
  122. margin-top: 8px;
  123. margin-left: 5px;
  124. "
  125. >
  126. <image
  127. mode="aspectFill"
  128. :src="`${$imgUrl}common/photo.png`"
  129. style="height: 56rpx; width: 56rpx"
  130. ></image>
  131. <view v-if="showTxt" class="text8" style="margin-top: 8px"
  132. >上传图片</view
  133. >
  134. </view>
  135. </view>
  136. </view>
  137. </view>
  138. </template>
  139. <script>
  140. import { pathToBase64 } from "@/utils/util/imageTool.js";
  141. import { request } from "@/utils/network/request";
  142. import { fileUpload } from "@/utils/network/api";
  143. import { stringToJson } from "@/utils/network/encryption";
  144. export default {
  145. name: "form-image",
  146. props: {
  147. showImageList: {
  148. /* 图片数组*/
  149. type: Array,
  150. default: function () {
  151. return [];
  152. },
  153. },
  154. imgWidth: {
  155. /*获取屏幕宽度*/
  156. type: Number,
  157. default: 0,
  158. required: false,
  159. },
  160. retract: {
  161. /*缩进*/
  162. type: Number,
  163. default: 0,
  164. },
  165. isChoose: {
  166. /*是否选择图片*/
  167. type: Boolean,
  168. default: true,
  169. },
  170. isDelete: {
  171. /* 是否具备删除*/
  172. type: Boolean,
  173. default: true,
  174. },
  175. isUrl: {
  176. /* 是否拼接图片地址*/
  177. type: Boolean,
  178. default: false,
  179. },
  180. count: {
  181. /* 图片上传数量*/
  182. type: Number,
  183. default: 9,
  184. },
  185. showTxt: {
  186. /* 是否显示上传图片文字*/
  187. type: Boolean,
  188. default: true,
  189. },
  190. },
  191. created() {
  192. let { showImageList } = this;
  193. if (showImageList.length > 0) {
  194. this.imageList = showImageList;
  195. }
  196. let _this = this;
  197. //console.log('输出内容', this.imgWidth)
  198. if (isNaN(this.imgWidth) || this.imgWidth === 0) {
  199. //判断是否不是数字
  200. uni.getSystemInfo({
  201. success: function (res) {
  202. _this.innerWidth = res.windowWidth / 4 - 18;
  203. },
  204. });
  205. } else {
  206. _this.innerWidth = this.imgWidth - 18;
  207. }
  208. },
  209. mounted() {
  210. //当视图运行完后执行
  211. },
  212. data() {
  213. return {
  214. sourceTypeIndex: 2,
  215. innerWidth: 0,
  216. imageList: [],
  217. item: {},
  218. urls: "",
  219. update: true,
  220. canChoose: this.isChoose,
  221. };
  222. },
  223. watch: {
  224. //计算属性
  225. imageList(val) {
  226. //console.log('图片数据改变了', this.imageList.length);
  227. },
  228. },
  229. methods: {
  230. previewImage(e, item) {
  231. //放大图片
  232. // var current = this.isUrl ? this.urls + item[e] : item[e]
  233. if (this.isUrl) {
  234. for (var i = 0; i < item.length; i++) {
  235. if (item[i].indexOf("http") == -1) {
  236. item[i] = this.urls + item[i];
  237. }
  238. }
  239. }
  240. var current = item[e];
  241. console.log("输出内容", current);
  242. uni.previewImage({
  243. current: current,
  244. urls: item,
  245. });
  246. },
  247. removeImg(e, item) {
  248. //删除图片
  249. this.$emit("removeImg", item, e);
  250. item.splice(e, 1);
  251. this.canChoose = this.imageList.length === this.count ? false : true;
  252. },
  253. chooseImage: function (item) {
  254. //选择相机或相册时
  255. let _this = this;
  256. if (_this.imageList === undefined) {
  257. _this.imageList = [];
  258. }
  259. if (_this.imageList.length === this.count) {
  260. uni.showToast({
  261. icon: "none",
  262. title: "最多只能选择" + _this.count + "张图片",
  263. });
  264. return;
  265. }
  266. /* 图片选择 */
  267. uni.chooseImage({
  268. count: _this.count,
  269. success: (res) => {
  270. //选择成功
  271. // _this.imageList = _this.imageList.concat(res.tempFilePaths);
  272. const tempFilePaths = res.tempFilePaths;
  273. const imgUrl = "";
  274. //_this.$emit('backImg', _this.imageList) //测试环境下(正式环境请切换至接口返回地址)
  275. this.canChoose = _this.imageList.length === this.count ? false : true;
  276. for (var i = 0; i < tempFilePaths.length; i++) {
  277. pathToBase64(tempFilePaths[i])
  278. .then((path) => {
  279. var data = { fileBase64: path };
  280. const options = {
  281. type: 2,
  282. data: data,
  283. method: "POST",
  284. showLoading: true,
  285. };
  286. request(fileUpload, options).then((res) => {
  287. const data = stringToJson(res.bizContent);
  288. _this.imageList.push(data.data.url);
  289. _this.$emit("backImg", _this.imageList); //测试环境下(正式环境请切换至接口返回地址)
  290. });
  291. })
  292. .catch((error) => {console.log(error)});
  293. /* 图片上传 */
  294. // uni.uploadFile({
  295. // url: 'https://www.example.com/upload', //仅为示例,非真实的接口地址
  296. // filePath: tempFilePaths[i],
  297. // name: 'file',
  298. // header: {
  299. // 'X-Access-Token': uni.getStorageSync('token')
  300. // },
  301. // formData: {
  302. // biz: 'app'
  303. // },
  304. // success: (uploadFileRes) => {
  305. // let imgData = JSON.parse(uploadFileRes.data)
  306. // /* 数据拼接 */
  307. // if (imgUrl === undefined || imgUrl === '') {
  308. // imgUrl = imgData.message
  309. // } else {
  310. // imgUrl += ',' + imgData.message
  311. // }
  312. // _this.$emit('backImg', _this.imageList) //正式环境下
  313. // },
  314. // fail: (res) => {
  315. // console.log(res);
  316. // }
  317. // });
  318. }
  319. },
  320. fail: (err) => {
  321. if (err.errMsg.indexOf("cancel") !== "-1") {
  322. return;
  323. }
  324. uni.getSetting({
  325. success: (res) => {
  326. let authStatus = false;
  327. switch (this.sourceTypeIndex) {
  328. case 0:
  329. authStatus = res.authSetting["scope.camera"];
  330. break;
  331. case 1:
  332. authStatus = res.authSetting["scope.album"];
  333. break;
  334. case 2:
  335. authStatus =
  336. res.authSetting["scope.album"] &&
  337. res.authSetting["scope.camera"];
  338. break;
  339. default:
  340. break;
  341. }
  342. if (!authStatus) {
  343. uni.showModal({
  344. title: "授权失败",
  345. content:
  346. "需要从您的相机或相册获取图片,请在设置界面打开相关权限",
  347. success: (res) => {
  348. if (res.confirm) {
  349. uni.openSetting();
  350. }
  351. },
  352. });
  353. }
  354. },
  355. });
  356. },
  357. });
  358. },
  359. },
  360. };
  361. </script>
  362. <style>
  363. .text8 {
  364. font-size: 26rpx;
  365. font-family: PingFang SC;
  366. color: #333333;
  367. opacity: 1;
  368. }
  369. .layout4 {
  370. background: #f3f3f3;
  371. opacity: 1;
  372. border-radius: 8px;
  373. border: 1px solid #dcdcdc;
  374. }
  375. </style>