Config.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <div class="config-container">
  3. <div class="editor-container">
  4. <vue-monaco-editor
  5. v-model:value="code"
  6. :options="MONACO_EDITOR_OPTIONS"
  7. />
  8. </div>
  9. <div class="footer">
  10. <div>
  11. <a-button @click="resetConfig">恢复默认</a-button>
  12. <a-button @click="showHelp = true">
  13. <QuestionCircleOutlined />
  14. </a-button>
  15. </div>
  16. <div>
  17. <a-button @click="closeConfig">取消</a-button>
  18. <a-button type="primary" @click="saveConfig">保存配置</a-button>
  19. </div>
  20. </div>
  21. <a-modal
  22. title="配置格式说明"
  23. v-model:visible="showHelp"
  24. :footer="null"
  25. width="600px"
  26. >
  27. <ScrollRect scroll="vertical" :height="260" containerClass="help-content">
  28. <div class="help-section">
  29. <p class="help-text">配置文件使用JSON格式,包含一个应用数组。每个应用对象支持以下字段:</p>
  30. </div>
  31. <div class="help-section">
  32. <h4 class="help-field-title">必填字段</h4>
  33. <ul class="help-list">
  34. <li><code>id</code>: 应用ID(数字类型,唯一)</li>
  35. <li><code>title</code>: 应用显示标题(字符串类型)</li>
  36. <li><code>url</code>: 应用地址URL(字符串类型)</li>
  37. </ul>
  38. </div>
  39. <div class="help-section">
  40. <h4 class="help-field-title">可选字段</h4>
  41. <ul class="help-list">
  42. <li><code>keepScreenSize</code>: 是否保持显示尺寸比例(布尔类型,默认false)</li>
  43. <li><code>aspectRatio</code>: 屏幕尺寸比例(字符串类型,例如 "16/9")</li>
  44. </ul>
  45. </div>
  46. <div class="help-section">
  47. <h4 class="help-field-title">配置示例</h4>
  48. <div class="help-code">
  49. <pre>{{ configExample }}</pre>
  50. </div>
  51. </div>
  52. <div class="help-section">
  53. <h4 class="help-field-title">使用说明</h4>
  54. <ul class="help-list">
  55. <li>每个应用必须有唯一的ID</li>
  56. <li>URL必须是完整的地址(包含http://或https://)</li>
  57. <li>设置<code>keepScreenSize</code>为true时,建议同时设置<code>aspectRatio</code></li>
  58. <li>修改配置后点击"保存配置"按钮生效</li>
  59. </ul>
  60. </div>
  61. </ScrollRect>
  62. </a-modal>
  63. </div>
  64. </template>
  65. <script setup lang="ts">
  66. import { Modal } from 'ant-design-vue'
  67. import { onMounted, ref } from 'vue'
  68. import { QuestionCircleOutlined } from '@ant-design/icons-vue'
  69. import { ScrollRect } from '@imengyu/vue-scroll-rect'
  70. const code = ref('')
  71. const MONACO_EDITOR_OPTIONS = {
  72. language: 'json',
  73. }
  74. const showHelp = ref(false)
  75. const configExample = ref(`[
  76. {
  77. "id": 1,
  78. "title": "Google",
  79. "url": "https://www.google.com"
  80. },
  81. {
  82. "id": 2,
  83. "title": "百度",
  84. "url": "https://www.baidu.com",
  85. "keepScreenSize": true,
  86. "aspectRatio": "16/9"
  87. },
  88. {
  89. "id": 3,
  90. "title": "GitHub",
  91. "url": "https://github.com"
  92. }
  93. ]`)
  94. onMounted(() => {
  95. window.electronAPI.loadAppsJson().then((data) => {
  96. code.value = JSON.stringify(data, null, 2)
  97. })
  98. })
  99. function resetConfig() {
  100. window.electronAPI.loadDefaultAppsJson().then((data) => {
  101. code.value = JSON.stringify(data, null, 2)
  102. })
  103. }
  104. function closeConfig() {
  105. window.close()
  106. }
  107. function saveConfig() {
  108. try {
  109. JSON.parse(code.value);
  110. } catch (error) {
  111. Modal.error({
  112. title: '解析JSON失败',
  113. content: '请检查JSON格式是否正确。' + error,
  114. });
  115. return;
  116. }
  117. window.electronAPI.saveAppsJson(code.value)
  118. Modal.success({
  119. title: '保存成功',
  120. content: '配置已保存。',
  121. onOk() {
  122. closeConfig()
  123. }
  124. })
  125. }
  126. </script>
  127. <style lang="scss">
  128. .config-container {
  129. display: flex;
  130. flex-direction: column;
  131. width: 100%;
  132. height: 100%;
  133. .editor-container {
  134. flex: 1;
  135. position: relative;
  136. }
  137. .footer {
  138. padding: 10px;
  139. gap: 6px;
  140. display: flex;
  141. flex-direction: row;
  142. justify-content: space-between;
  143. margin-top: 10px;
  144. > div {
  145. display: flex;
  146. flex-direction: row;
  147. gap: 6px;
  148. }
  149. }
  150. }
  151. .help-content {
  152. max-height: 60vh;
  153. padding-right: 10px;
  154. .help-section {
  155. margin-bottom: 20px;
  156. &:last-child {
  157. margin-bottom: 0;
  158. }
  159. }
  160. .help-section-title {
  161. font-size: 16px;
  162. font-weight: 600;
  163. color: #333;
  164. margin: 0 0 10px 0;
  165. padding-bottom: 5px;
  166. border-bottom: 1px solid #e8e8e8;
  167. }
  168. .help-field-title {
  169. font-size: 14px;
  170. font-weight: 600;
  171. color: #555;
  172. margin: 0 0 8px 0;
  173. }
  174. .help-text {
  175. font-size: 14px;
  176. color: #666;
  177. line-height: 1.5;
  178. margin: 0 0 12px 0;
  179. }
  180. .help-list {
  181. font-size: 14px;
  182. color: #666;
  183. line-height: 1.6;
  184. margin: 0 0 12px 0;
  185. padding-left: 20px;
  186. li {
  187. margin-bottom: 4px;
  188. &:last-child {
  189. margin-bottom: 0;
  190. }
  191. }
  192. code {
  193. background-color: #f5f5f5;
  194. padding: 2px 4px;
  195. border-radius: 3px;
  196. font-family: 'Courier New', Courier, monospace;
  197. font-size: 13px;
  198. color: #d73a49;
  199. }
  200. }
  201. .help-code {
  202. background-color: #f6f8fa;
  203. border: 1px solid #e1e4e8;
  204. border-radius: 6px;
  205. padding: 12px;
  206. margin: 8px 0;
  207. pre {
  208. margin: 0;
  209. font-family: 'Courier New', Courier, monospace;
  210. font-size: 13px;
  211. line-height: 1.5;
  212. color: #24292e;
  213. white-space: pre-wrap;
  214. word-wrap: break-word;
  215. }
  216. }
  217. }
  218. </style>