index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <template>
  2. <view
  3. :class="[
  4. 'file_msg_container',
  5. isSelf ? 'file_msg_container_mine' : 'file_msg_container_other',
  6. ]"
  7. @tap="previewFile"
  8. >
  9. <view class="file_msg_content">
  10. <text class="name u-line-1">
  11. {{ msgBody.filename || msgBody.body.filename }}
  12. </text>
  13. <text class="size">{{
  14. formatMoney(msgBody.file_length || msgBody.body.file_length)
  15. }}</text>
  16. </view>
  17. <image
  18. class="file_msg_icon"
  19. src="/static/images/new_ui/message/file_msg_icon.png"
  20. />
  21. </view>
  22. </template>
  23. <script>
  24. import formatFileSize from "@/utils/formatFileSize";
  25. const ATTACH_KEY = "filePathCache";
  26. export default {
  27. props: {
  28. msgBody: {
  29. type: Object,
  30. default: () => ({}),
  31. },
  32. },
  33. data() {
  34. return {};
  35. },
  36. computed: {
  37. isSelf() {
  38. const { from } = this.msgBody;
  39. return (
  40. from === this.$store.state.LoginStore.loginUserBaseInfos.loginUserId
  41. );
  42. },
  43. formatMoney() {
  44. return (value) => {
  45. return formatFileSize(value);
  46. };
  47. },
  48. },
  49. methods: {
  50. storageFilePath({ id, path }) {
  51. uni.getStorage({
  52. key: ATTACH_KEY,
  53. success: (res) => {
  54. let dt = res.data || {};
  55. uni.setStorage({
  56. key: ATTACH_KEY,
  57. data: {
  58. ...dt,
  59. [id]: path,
  60. },
  61. });
  62. },
  63. fail: (e) => {
  64. uni.setStorage({
  65. key: ATTACH_KEY,
  66. data: {
  67. [id]: path,
  68. },
  69. });
  70. },
  71. });
  72. },
  73. downloadFile() {
  74. // 下载完存储filePath,下次预览直接访问
  75. console.log("this.msgBody?.url", this.msgBody?.url);
  76. uni.downloadFile({
  77. url: `${this.msgBody?.url}`,
  78. success: (res) => {
  79. console.log("downloadFile", res);
  80. let filePath = res.tempFilePath;
  81. // #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ
  82. this.saveFileUseManager(filePath);
  83. // #endif
  84. // #ifndef MP-WEIXIN || MP-TOUTIAO || MP-QQ
  85. this.saveFile(filePath);
  86. // #endif
  87. },
  88. fail: (err) => {
  89. console.log(">>>>>文件下载失败", err);
  90. uni.hideLoading();
  91. uni.showToast({
  92. icon: "none",
  93. title: "失败请重新下载",
  94. });
  95. },
  96. });
  97. },
  98. saveFile(filePath) {
  99. uni.saveFile({
  100. tempFilePath: filePath,
  101. success: (res) => {
  102. let savedFilePath = res.savedFilePath;
  103. this.storageFilePath({
  104. id: this.msgBody.id,
  105. path: savedFilePath,
  106. });
  107. this.openFile(savedFilePath);
  108. },
  109. fail: function (e) {
  110. uni.hideLoading();
  111. uni.showToast({
  112. icon: "none",
  113. title: "保存失败",
  114. });
  115. },
  116. });
  117. },
  118. saveFileUseManager(filePath) {
  119. console.log(">>>>小程序保存文件调用", filePath);
  120. const fileExtension =
  121. this.msgBody.filename.split(".").pop() ||
  122. this.msgBody.body.filename.split(".").pop();
  123. const savedFilePath =
  124. uni.env.USER_DATA_PATH + "/document." + fileExtension;
  125. uni.getFileSystemManager().copyFile({
  126. srcPath: filePath,
  127. destPath: savedFilePath,
  128. success: () => {
  129. console.log(">>>>>小程序savedFilePath", savedFilePath);
  130. this.storageFilePath({
  131. id: this.msgBody.id,
  132. path: savedFilePath,
  133. });
  134. this.openFile(savedFilePath);
  135. },
  136. fail: (e) => {
  137. uni.showToast({
  138. title: "下载失败",
  139. icon: "none",
  140. });
  141. },
  142. });
  143. },
  144. openFile(filePath) {
  145. uni.openDocument({
  146. filePath,
  147. success: function (res) {
  148. uni.hideLoading();
  149. },
  150. fail(e) {
  151. uni.showToast({
  152. title: "暂不支持此类型",
  153. duration: 2000,
  154. });
  155. uni.hideLoading();
  156. },
  157. });
  158. },
  159. previewFile() {
  160. let sysInfo = uni.getSystemInfoSync();
  161. if (sysInfo.uniPlatform === "web") {
  162. uni.showToast({
  163. title: "H5暂不支持预览文件消息",
  164. duration: 2000,
  165. icon: "none",
  166. });
  167. return;
  168. }
  169. uni.showLoading();
  170. uni.getStorage({
  171. key: ATTACH_KEY,
  172. success: (res) => {
  173. let dt = res.data || {};
  174. let path = dt[this.msgBody.id];
  175. if (path) {
  176. this.openFile(path);
  177. } else {
  178. this.downloadFile();
  179. }
  180. },
  181. fail: (e) => {
  182. this.downloadFile();
  183. },
  184. });
  185. },
  186. },
  187. };
  188. </script>
  189. <style>
  190. .file_msg_container {
  191. width: 245px;
  192. height: 60px;
  193. display: flex;
  194. align-items: center;
  195. justify-content: space-between;
  196. padding: 0 8px;
  197. box-sizing: border-box;
  198. }
  199. .file_msg_container_mine {
  200. flex-direction: row-reverse;
  201. color: #f9fafa;
  202. background-color: #009eff;
  203. border-radius: 16px 12px 4px 16px;
  204. }
  205. .file_msg_container_other {
  206. color: #171a1c;
  207. background-color: #e5f5ff;
  208. border-radius: 12px 16px 16px 4px;
  209. }
  210. .file_msg_icon {
  211. width: 44px;
  212. height: 44px;
  213. }
  214. .file_msg_content {
  215. display: flex;
  216. flex-direction: column;
  217. height: 42px;
  218. align-items: flex-start;
  219. }
  220. .file_msg_content .name {
  221. /* Credo dalle tre alle */
  222. height: 24px;
  223. /* 简体中文/次级标题/中 */
  224. font-family: "PingFang SC";
  225. font-style: normal;
  226. font-weight: 400;
  227. font-size: 16px;
  228. line-height: 22px;
  229. }
  230. .file_msg_content .size {
  231. /* Alphabet/Body/Medium */
  232. font-family: "SF Pro";
  233. font-style: normal;
  234. font-weight: 400;
  235. font-size: 14px;
  236. line-height: 18px;
  237. /* identical to box height, or 129% */
  238. letter-spacing: 0.001em;
  239. /* Neutral/95 */
  240. }
  241. </style>