123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import React from "react";
  2. import Taro from "@tarojs/taro";
  3. import { View, Image, Video } from "@tarojs/components";
  4. import { Loading } from "@antmjs/vantui";
  5. import { uploadFileBase64, uploadFiles } from "@/utils/request";
  6. import { promise } from "@/utils/promise";
  7. import icon from "@/assets/icons/uploader.png";
  8. import closeIcon from "@/assets/icons/close.png";
  9. import style from "./style.modules.less";
  10. export default (props) => {
  11. // value 为数组
  12. // 单个元素结构为 { url, fileType }
  13. const { value, disabled = false, onChange } = props;
  14. const [loading, setLoading] = React.useState(false);
  15. const [valueCopy, setValueCopy] = React.useState(value);
  16. const valueCopyRef = React.useRef(valueCopy);
  17. valueCopyRef.current = valueCopy;
  18. const onAdd = (e) => {
  19. e.preventDefault();
  20. e.stopPropagation();
  21. if (disabled) return;
  22. setValueCopy(valueCopyRef.current.concat(false));
  23. setLoading(true);
  24. // eslint-disable-next-line no-undef
  25. if (IS_APP_CLIENT) {
  26. const p = promise((resolve, reject) => {
  27. // eslint-disable-next-line no-undef
  28. SmartCity.chooseImage({
  29. count : 1 // 图片张数
  30. },function(res){
  31. console.log("--------上传图片---------", res);
  32. const base64 = res[0].imageData;
  33. const fileName = res[0].name;
  34. const fileType = res[0].type;
  35. uploadFileBase64(base64, fileName, fileType).then(resp => {
  36. resolve(resp);
  37. // onChange((value || []).concat(resp));
  38. }).catch((err) => {
  39. console.error(err);
  40. reject(err);
  41. });
  42. });
  43. }, 10 * 1000);
  44. p.then((resp) => {
  45. setLoading(false);
  46. onChange((value || []).concat(resp));
  47. }).catch(() => {
  48. setValueCopy(valueCopyRef.current.filter(Boolean))
  49. setLoading(false);
  50. });
  51. } else {
  52. Taro.chooseMedia({
  53. maxDuration: 60,
  54. // sizeType: "compressed",
  55. success: (res) => {
  56. const { tempFiles } = res;
  57. uploadFiles(tempFiles)
  58. .then((resp) => {
  59. setLoading(false);
  60. onChange((value || []).concat(resp));
  61. })
  62. .catch((err) => {
  63. console.error(err);
  64. setLoading(false);
  65. });
  66. },
  67. fail: (err) => {
  68. console.error(err);
  69. setLoading(false);
  70. },
  71. });
  72. }
  73. };
  74. const onDelete = (item) => {
  75. if (!item) {
  76. setValueCopy(valueCopyRef.current.filter(Boolean));
  77. return;
  78. }
  79. const newVal = value.filter((x) => x.url != item.url);
  80. onChange(newVal);
  81. };
  82. const onPreview = (inx) => {
  83. const url = value.map((x) => x.url);
  84. // Taro.previewMedia({
  85. // sources: value.map(x => ({ url: x.url, type: x.fileType })),
  86. // current: inx,
  87. // })
  88. //H5
  89. Taro.previewImage({
  90. current: inx, // 当前显示图片的http链接
  91. urls: url,
  92. });
  93. };
  94. React.useEffect(() => {
  95. setValueCopy(value || []);
  96. }, [value]);
  97. return (
  98. <View className={style["uploader-wrapper"]}>
  99. <View className={style["uploader-box"]}>
  100. {!disabled && (
  101. <View className={style["uploader-add"]}>
  102. <Image src={icon} onClick={onAdd} />
  103. </View>
  104. )}
  105. {valueCopy.map((item, inx) => (
  106. <View key={item?.url || '123'} className={style["uploader-item"]}>
  107. {
  108. !item ? (
  109. <Loading color="gray" style={{ width: '100%', height: '100%' }} />
  110. ) : (
  111. item.fileType.indexOf("image") == 0 ? (
  112. <Image src={item.url} onClick={() => onPreview(inx)} />
  113. ) : (
  114. <Video
  115. src={item.url}
  116. controls={false}
  117. onClick={() => onPreview(inx)}
  118. />
  119. )
  120. )
  121. }
  122. {!disabled && (
  123. <View onClick={() => onDelete(item)} style={{ zIndex: 99 }}>
  124. <Image src={closeIcon} />
  125. </View>
  126. )}
  127. </View>
  128. ))}
  129. </View>
  130. </View>
  131. );
  132. };