小说小程序前端代码仓库(小程序)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
4.8 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <view class="page">
  3. <navbar title="新建章节" leftClick @leftClick="$utils.navigateBack" />
  4. <view class="form-box top-fixed">
  5. <view class="form-item">
  6. <text class="required">*</text>
  7. <text class="label">章节名称</text>
  8. <input class="input" type="text" placeholder='请输入章节号与章节名。例如:"第十章天降奇缘"' v-model="form.title" />
  9. </view>
  10. <view class="form-item">
  11. <text class="required">*</text>
  12. <text class="label">章节内容</text>
  13. <textarea class="textarea" placeholder="请输入章节内容" v-model="form.content" />
  14. </view>
  15. </view>
  16. <view class="footer-btns">
  17. <button class="btn save-btn" @click="onSave">保存</button>
  18. <button class="btn publish-btn" @click="onPublish">发布</button>
  19. </view>
  20. </view>
  21. </template>
  22. <script>
  23. export default {
  24. data() {
  25. return {
  26. formats: {},
  27. form: {
  28. title: '',
  29. content: '',
  30. },
  31. }
  32. },
  33. onLoad() {
  34. },
  35. methods: {
  36. onInput(e){
  37. console.log(e.detail);
  38. },
  39. onEditorReady() {
  40. uni.createSelectorQuery().select('#editor').context((res) => {
  41. this.editorCtx = res.context
  42. }).exec()
  43. },
  44. undo() {
  45. this.editorCtx.undo()
  46. },
  47. redo() {
  48. this.editorCtx.redo()
  49. },
  50. format(e) {
  51. let {
  52. name,
  53. value
  54. } = e.target.dataset
  55. if (!name) return
  56. // console.log('format', name, value)
  57. this.editorCtx.format(name, value)
  58. },
  59. onStatusChange(e) {
  60. const formats = e.detail
  61. this.formats = formats
  62. },
  63. insertDivider() {
  64. this.editorCtx.insertDivider({
  65. success: function() {
  66. console.log('insert divider success')
  67. }
  68. })
  69. },
  70. clear() {
  71. uni.showModal({
  72. title: '清空编辑器',
  73. content: '确定清空编辑器全部内容?',
  74. success: res => {
  75. if (res.confirm) {
  76. this.editorCtx.clear({
  77. success: function(res) {
  78. console.log("clear success")
  79. }
  80. })
  81. }
  82. }
  83. })
  84. },
  85. removeFormat() {
  86. this.editorCtx.removeFormat()
  87. },
  88. insertDate() {
  89. const date = new Date()
  90. const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
  91. this.editorCtx.insertText({
  92. text: formatDate
  93. })
  94. },
  95. insertImage() {
  96. uni.chooseImage({
  97. count: 1,
  98. success: (res) => {
  99. this.editorCtx.insertImage({
  100. src: res.tempFilePaths[0],
  101. alt: '图像',
  102. success: function() {
  103. console.log('insert image success')
  104. }
  105. })
  106. }
  107. })
  108. },
  109. onSave() {
  110. // 保存逻辑
  111. const newChapter = {
  112. title: this.form.title,
  113. content: this.form.content
  114. };
  115. // 获取原有章节
  116. let chapters = uni.getStorageSync('chapters') || [];
  117. chapters.push(newChapter);
  118. uni.setStorageSync('chapters', chapters);
  119. // 跳转并传递参数
  120. uni.redirectTo({
  121. url: '/pages_order/novel/chapterList?fromSave=1'
  122. });
  123. },
  124. onPublish() {
  125. // 发布逻辑
  126. const newChapter = {
  127. title: this.form.title,
  128. content: this.form.content,
  129. time: Date.now()
  130. };
  131. // 保存到已发布章节
  132. let publishedChapters = uni.getStorageSync('publishedChapters') || [];
  133. publishedChapters.push(newChapter);
  134. uni.setStorageSync('publishedChapters', publishedChapters);
  135. // 跳转到bookshelf作品tab并弹窗
  136. uni.redirectTo({
  137. url: '/pages/index/bookshelf?fromPublish=1'
  138. });
  139. },
  140. }
  141. }
  142. </script>
  143. <style scoped lang="scss">
  144. .page {
  145. margin-top: -920rpx;
  146. margin-left: 30rpx;
  147. margin-right: 30rpx;
  148. min-height: 100vh;
  149. background: #f7f8fa;
  150. display: flex;
  151. flex-direction: column;
  152. justify-content: space-between;
  153. }
  154. .form-box {
  155. background: #fff;
  156. margin: 0;
  157. padding: 0 32rpx 0 32rpx;
  158. border-radius: 0;
  159. position: relative;
  160. }
  161. .top-fixed {
  162. margin-top: 0;
  163. }
  164. .form-item {
  165. display: flex;
  166. flex-direction: column;
  167. margin-top: 32rpx;
  168. position: relative;
  169. }
  170. .label {
  171. font-size: 28rpx;
  172. color: #222;
  173. margin-bottom: 12rpx;
  174. margin-left: 32rpx;
  175. }
  176. .required {
  177. color: #f44;
  178. position: absolute;
  179. left: 0;
  180. top: 0;
  181. font-size: 32rpx;
  182. }
  183. .input {
  184. border: none;
  185. border-bottom: 1rpx solid #eee;
  186. font-size: 28rpx;
  187. padding: 16rpx 0;
  188. background: transparent;
  189. }
  190. .textarea {
  191. min-height: 180rpx;
  192. border: none;
  193. border-bottom: 1rpx solid #eee;
  194. font-size: 28rpx;
  195. padding: 16rpx 0;
  196. background: transparent;
  197. resize: none;
  198. }
  199. .footer-btns {
  200. position: fixed;
  201. left: 0;
  202. bottom: 0;
  203. width: 100vw;
  204. background: #fff;
  205. display: flex;
  206. justify-content: space-between;
  207. padding: 24rpx 48rpx 32rpx 48rpx;
  208. box-sizing: border-box;
  209. z-index: 10;
  210. box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.03);
  211. }
  212. .btn {
  213. flex: 1;
  214. height: 80rpx;
  215. font-size: 32rpx;
  216. border-radius: 40rpx;
  217. margin: 0 12rpx;
  218. font-weight: 500;
  219. }
  220. .save-btn {
  221. background: #fff;
  222. color: #0a225f;
  223. border: 2rpx solid #0a225f;
  224. }
  225. .publish-btn {
  226. background: #0a225f;
  227. color: #fff;
  228. border: none;
  229. }
  230. </style>