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

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