textFileEditDialog.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <template>
  2. <view>
  3. <view
  4. class="dialogMask"
  5. v-if="isShow"
  6. :style="{
  7. height: height + 'px',
  8. }"
  9. >
  10. <view
  11. class="dialogContent"
  12. @click.stop
  13. >
  14. <view
  15. class="dialogHead"
  16. @click="hide"
  17. >
  18. <view>
  19. <text class="title">{{ title }}</text>
  20. </view>
  21. <view>
  22. <image
  23. src="@/devTools/page/static/unfold.png"
  24. class="fold"
  25. />
  26. </view>
  27. </view>
  28. <scroll-view
  29. scroll-y
  30. class="scrollList"
  31. :style="{
  32. height: dialogHeight + 'px',
  33. }"
  34. >
  35. <textarea
  36. :style="{
  37. height: dialogHeight - (canSave ? 90 : 40) + 'px',
  38. }"
  39. v-model="value"
  40. type="text"
  41. placeholder="请输入..."
  42. class="fileEditInput"
  43. maxlength="-1"
  44. />
  45. <view
  46. class="saveBtn"
  47. v-if="canSave"
  48. @click="saveFile"
  49. >
  50. <text class="saveBtnText">保存</text>
  51. </view>
  52. </scroll-view>
  53. </view>
  54. </view>
  55. </view>
  56. </template>
  57. <script>
  58. let success, error;
  59. export default {
  60. data() {
  61. return {
  62. /**
  63. * 是否展示
  64. */
  65. isShow: false,
  66. /**
  67. * 屏幕高度
  68. */
  69. height: uni.getSystemInfoSync().windowHeight,
  70. dialogHeight: uni.getSystemInfoSync().windowHeight * 0.8,
  71. /**
  72. * 弹窗标题
  73. */
  74. title: "",
  75. /**
  76. * 文本内容
  77. */
  78. value: "",
  79. /**
  80. * 是否为文件编辑模式
  81. */
  82. isFileEdit: true,
  83. /**
  84. * 文件路径
  85. */
  86. path: "",
  87. /**
  88. * 是否允许保存
  89. */
  90. canSave: false,
  91. /**
  92. * 是否为新建文件
  93. */
  94. isNewFile: false,
  95. };
  96. },
  97. mounted() {
  98. let that = this;
  99. uni.$on("devTools_showTextEditDialog", (options) => {
  100. that
  101. .show(options)
  102. .then((val) => {
  103. uni.$emit("devTools_showTextEditDialogSave", val);
  104. })
  105. .catch(() => {
  106. uni.$emit("devTools_showTextEditDialogHide");
  107. });
  108. });
  109. },
  110. unmounted() {
  111. uni.$off("devTools_showTextEditDialog");
  112. },
  113. methods: {
  114. /**
  115. * 展示弹窗
  116. */
  117. show(options) {
  118. let that = this;
  119. return new Promise((yes, err) => {
  120. success = yes;
  121. error = err;
  122. that.title = options.title;
  123. that.canSave = Boolean(options.canSave);
  124. that.isShow = true;
  125. if (options.isFileEdit === false) {
  126. // 仅为文件编辑模式
  127. that.isFileEdit = false;
  128. try {
  129. that.value = JSON.stringify(JSON.parse(options.value), null, 2);
  130. } catch (error) {
  131. that.value = options.value;
  132. }
  133. return;
  134. }
  135. that.isFileEdit = true;
  136. that.value = "文件读取中...";
  137. that.path = options.path;
  138. that.isNewFile = Boolean(options.isNewFile);
  139. // #ifdef APP-PLUS
  140. if (that.isNewFile) {
  141. that.value = "";
  142. } else {
  143. plus.io.resolveLocalFileSystemURL(
  144. that.path,
  145. (entry) => {
  146. // 可通过entry对象操作test.html文件
  147. entry.file((file) => {
  148. var fileReader = new plus.io.FileReader();
  149. fileReader.readAsText(file, "utf-8");
  150. fileReader.onloadend = function (evt) {
  151. let res = "";
  152. try {
  153. res = JSON.stringify(JSON.parse(evt.target.result), null, 2);
  154. } catch (error) {
  155. res = evt.target.result;
  156. }
  157. that.value = res;
  158. };
  159. fileReader.onerror = function () {
  160. that.value = `[${that.path}]文件读取失败!_code_2`;
  161. };
  162. });
  163. },
  164. function (e) {
  165. that.value = `[${that.path}]文件读取失败!` + e.message;
  166. }
  167. );
  168. }
  169. // #endif
  170. // #ifdef MP-WEIXIN
  171. let fs = wx.getFileSystemManager();
  172. if (options.size != 0) {
  173. fs.readFile({
  174. filePath: that.path,
  175. encoding: "utf8",
  176. position: 0,
  177. length: options.size,
  178. success({ data }) {
  179. try {
  180. that.value = JSON.stringify(JSON.parse(data), null, 2);
  181. } catch (error) {
  182. that.value = data;
  183. }
  184. },
  185. fail(e) {
  186. console.log(e);
  187. that.value = `[${that.path}]文件读取失败!` + e;
  188. },
  189. });
  190. } else {
  191. that.value = "";
  192. }
  193. // #endif
  194. });
  195. },
  196. /**
  197. * 关闭弹窗
  198. */
  199. hide() {
  200. this.isShow = false;
  201. error();
  202. },
  203. /**
  204. * 保存
  205. */
  206. save() {
  207. this.isShow = false;
  208. success(this.value);
  209. },
  210. /**
  211. * 保存文件
  212. */
  213. saveFile() {
  214. let that = this;
  215. if (!that.isFileEdit) {
  216. // 非文件编辑模式
  217. that.isShow = false;
  218. success(that.value);
  219. return;
  220. }
  221. uni.showLoading({
  222. title: "保存中",
  223. });
  224. // #ifdef APP-PLUS
  225. let fileName = that.path.split("/").pop();
  226. let path = that.path.substring(0, that.path.length - fileName.length);
  227. plus.io.resolveLocalFileSystemURL(
  228. path,
  229. (entry) => {
  230. entry.getFile(
  231. fileName,
  232. {
  233. create: true,
  234. },
  235. (fileEntry) => {
  236. fileEntry.createWriter((writer) => {
  237. writer.onwrite = (e) => {
  238. uni.hideLoading();
  239. uni.showToast({
  240. title: "文件保存成功!",
  241. icon: "success",
  242. });
  243. that.isShow = false;
  244. that.$emit("getPage");
  245. };
  246. writer.onerror = () => {
  247. uni.hideLoading();
  248. uni.showToast({
  249. title: "文件保存失败!_写入文件失败",
  250. icon: "none",
  251. });
  252. };
  253. writer.write(that.value);
  254. });
  255. }
  256. );
  257. },
  258. () => {
  259. uni.hideLoading();
  260. uni.showToast({
  261. title: "文件保存失败!_打开目录失败",
  262. icon: "none",
  263. });
  264. }
  265. );
  266. // #endif
  267. // #ifdef MP-WEIXIN
  268. let fs = wx.getFileSystemManager();
  269. fs.writeFile({
  270. filePath: that.path,
  271. encoding: "utf-8",
  272. data: that.value,
  273. success() {
  274. uni.hideLoading();
  275. uni.showToast({
  276. title: "文件保存成功!",
  277. icon: "success",
  278. });
  279. that.isShow = false;
  280. that.$emit("getPage");
  281. },
  282. fail() {
  283. uni.hideLoading();
  284. uni.showToast({
  285. title: "文件保存失败!_打开目录失败",
  286. icon: "none",
  287. });
  288. },
  289. });
  290. // #endif
  291. },
  292. },
  293. };
  294. </script>
  295. <style lang="scss" scoped>
  296. .dialogMask {
  297. display: flex;
  298. flex-direction: column-reverse;
  299. background-color: rgba(0, 0, 0, 0.3);
  300. width: 750rpx;
  301. flex: 1;
  302. /* #ifndef APP-PLUS */
  303. height: 100vh;
  304. backdrop-filter: blur(1px);
  305. /* #endif */
  306. position: fixed;
  307. left: 0;
  308. top: 0;
  309. z-index: 999;
  310. .dialogContent {
  311. display: flex;
  312. flex-direction: column;
  313. width: 750rpx;
  314. background-color: #fff;
  315. border-radius: 20rpx 20rpx 0 0;
  316. .dialogHead {
  317. display: flex;
  318. flex-direction: row;
  319. align-items: center;
  320. justify-content: space-between;
  321. height: 80rpx;
  322. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  323. width: 750rpx;
  324. .title {
  325. margin-left: 20rpx;
  326. font-size: 24rpx;
  327. line-height: 24rpx;
  328. color: #333;
  329. }
  330. .fold {
  331. width: 20rpx;
  332. height: 20rpx;
  333. margin-right: 20rpx;
  334. }
  335. }
  336. .scrollList {
  337. width: 750rpx;
  338. padding: 20rpx;
  339. .fileEditInput {
  340. font-size: 20rpx;
  341. }
  342. .saveBtn {
  343. display: flex;
  344. flex-direction: row;
  345. align-items: center;
  346. justify-content: center;
  347. margin-top: 20rpx;
  348. height: 35px;
  349. width: 710rpx;
  350. border-radius: 10rpx;
  351. background-color: #ff2d55;
  352. .saveBtnText {
  353. color: #fff;
  354. font-size: 24rpx;
  355. line-height: 24rpx;
  356. }
  357. }
  358. }
  359. }
  360. }
  361. </style>