OtherSetting.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import React, { useEffect, useState } from 'react';
  2. import { Button, Divider, Form, Grid, Header, Modal } from 'semantic-ui-react';
  3. import { API, showError, showSuccess } from '../helpers';
  4. import { marked } from 'marked';
  5. const OtherSetting = () => {
  6. let [inputs, setInputs] = useState({
  7. Footer: '',
  8. Notice: '',
  9. About: '',
  10. HomePageContent: '',
  11. });
  12. let originInputs = {};
  13. let [loading, setLoading] = useState(false);
  14. const [showUpdateModal, setShowUpdateModal] = useState(false);
  15. const [updateData, setUpdateData] = useState({
  16. tag_name: '',
  17. content: '',
  18. });
  19. const getOptions = async () => {
  20. const res = await API.get('/api/option');
  21. const { success, message, data } = res.data;
  22. if (success) {
  23. let newInputs = {};
  24. data.forEach((item) => {
  25. if (item.key in inputs) {
  26. newInputs[item.key] = item.value;
  27. }
  28. });
  29. setInputs(newInputs);
  30. originInputs = newInputs;
  31. } else {
  32. showError(message);
  33. }
  34. };
  35. useEffect(() => {
  36. getOptions().then();
  37. }, []);
  38. const updateOption = async (key, value) => {
  39. setLoading(true);
  40. const res = await API.put('/api/option', {
  41. key,
  42. value,
  43. });
  44. const { success, message } = res.data;
  45. if (success) {
  46. setInputs((inputs) => ({ ...inputs, [key]: value }));
  47. } else {
  48. showError(message);
  49. }
  50. setLoading(false);
  51. };
  52. const handleInputChange = async (e, { name, value }) => {
  53. setInputs((inputs) => ({ ...inputs, [name]: value }));
  54. };
  55. const submitNotice = async () => {
  56. await updateOption('Notice', inputs.Notice);
  57. };
  58. const submitFooter = async () => {
  59. await updateOption('Footer', inputs.Footer);
  60. };
  61. const submitAbout = async () => {
  62. await updateOption('About', inputs.About);
  63. };
  64. const submitOption = async (key) => {
  65. await updateOption(key, inputs[key]);
  66. };
  67. const openGitHubRelease = () => {
  68. window.location =
  69. 'https://github.com/songquanpeng/one-api/releases/latest';
  70. };
  71. const checkUpdate = async () => {
  72. const res = await API.get(
  73. 'https://api.github.com/repos/songquanpeng/one-api/releases/latest'
  74. );
  75. const { tag_name, body } = res.data;
  76. if (tag_name === process.env.REACT_APP_VERSION) {
  77. showSuccess(`已是最新版本:${tag_name}`);
  78. } else {
  79. setUpdateData({
  80. tag_name: tag_name,
  81. content: marked.parse(body),
  82. });
  83. setShowUpdateModal(true);
  84. }
  85. };
  86. return (
  87. <Grid columns={1}>
  88. <Grid.Column>
  89. <Form loading={loading}>
  90. <Header as='h3'>通用设置</Header>
  91. <Form.Button onClick={checkUpdate}>检查更新</Form.Button>
  92. <Form.Group widths='equal'>
  93. <Form.TextArea
  94. label='公告'
  95. placeholder='在此输入新的公告内容'
  96. value={inputs.Notice}
  97. name='Notice'
  98. onChange={handleInputChange}
  99. style={{ minHeight: 150, fontFamily: 'JetBrains Mono, Consolas' }}
  100. />
  101. </Form.Group>
  102. <Form.Button onClick={submitNotice}>保存公告</Form.Button>
  103. <Divider />
  104. <Header as='h3'>个性化设置</Header>
  105. <Form.Group widths='equal'>
  106. <Form.TextArea
  107. label='首页内容'
  108. placeholder='在此输入首页内容,支持 Markdown & HTML 代码,设置后首页的状态信息将不再显示'
  109. value={inputs.HomePageContent}
  110. name='HomePageContent'
  111. onChange={handleInputChange}
  112. style={{ minHeight: 300, fontFamily: 'JetBrains Mono, Consolas' }}
  113. />
  114. </Form.Group>
  115. <Form.Button onClick={()=>submitOption('HomePageContent')}>保存首页内容</Form.Button>
  116. <Form.Group widths='equal'>
  117. <Form.TextArea
  118. label='关于'
  119. placeholder='在此输入新的关于内容,支持 Markdown & HTML 代码'
  120. value={inputs.About}
  121. name='About'
  122. onChange={handleInputChange}
  123. style={{ minHeight: 150, fontFamily: 'JetBrains Mono, Consolas' }}
  124. />
  125. </Form.Group>
  126. <Form.Button onClick={submitAbout}>保存关于</Form.Button>
  127. <Form.Group widths='equal'>
  128. <Form.Input
  129. label='页脚'
  130. placeholder='在此输入新的页脚,留空则使用默认页脚,支持 HTML 代码'
  131. value={inputs.Footer}
  132. name='Footer'
  133. onChange={handleInputChange}
  134. />
  135. </Form.Group>
  136. <Form.Button onClick={submitFooter}>设置页脚</Form.Button>
  137. </Form>
  138. </Grid.Column>
  139. <Modal
  140. onClose={() => setShowUpdateModal(false)}
  141. onOpen={() => setShowUpdateModal(true)}
  142. open={showUpdateModal}
  143. >
  144. <Modal.Header>新版本:{updateData.tag_name}</Modal.Header>
  145. <Modal.Content>
  146. <Modal.Description>
  147. <div dangerouslySetInnerHTML={{ __html: updateData.content }}></div>
  148. </Modal.Description>
  149. </Modal.Content>
  150. <Modal.Actions>
  151. <Button onClick={() => setShowUpdateModal(false)}>关闭</Button>
  152. <Button
  153. content='详情'
  154. onClick={() => {
  155. setShowUpdateModal(false);
  156. openGitHubRelease();
  157. }}
  158. />
  159. </Modal.Actions>
  160. </Modal>
  161. </Grid>
  162. );
  163. };
  164. export default OtherSetting;