小说小程序前端代码仓库(小程序)
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.

302 lines
7.0 KiB

  1. <template>
  2. <view class="chapter-container">
  3. <navbar title="章节列表" leftClick @leftClick="$utils.navigateBack"/>
  4. <view class="tabs">
  5. <uv-tabs :list="tabs"
  6. :activeStyle="{color : '#0A2463', fontWeight : 600}"
  7. lineColor="#0A2463"
  8. :inactiveStyle="{color: '#0A2463'}"
  9. lineHeight="8rpx"
  10. lineWidth="50rpx"
  11. :scrollable="false"
  12. :current="activeTab"
  13. @click="clickTabs"></uv-tabs>
  14. </view>
  15. <view class="box">
  16. <view class="draft-header">
  17. <text class="draft-title">{{ activeTab === 0 ? '草稿箱章节' : '已发布章节' }}</text>
  18. <text class="delete-btn" @click="reverseList">{{ queryParams.reverse ? '正序' : '倒序' }}</text>
  19. </view>
  20. <view class="chapter-list">
  21. <!-- 章节列表 -->
  22. <uv-swipe-action>
  23. <uv-swipe-action-item
  24. v-for="(chapter, index) in list"
  25. :key="chapter.id"
  26. :options="swipeOptions"
  27. @click="deleteChapter(chapter, index)"
  28. >
  29. <view
  30. class="chapter-item"
  31. @click="editChapter(chapter)"
  32. >
  33. <view class="chapter-info">
  34. <text class="chapter-title">章节名</text>
  35. <text class="chapter-number">
  36. {{ chapter.title }}
  37. <text v-if="chapter.isPay == 'Y'" class="vip-tag theme-transition">付费</text>
  38. </text>
  39. </view>
  40. <uv-icon name="arrow-right" color="#999" size="28"></uv-icon>
  41. </view>
  42. </uv-swipe-action-item>
  43. </uv-swipe-action>
  44. <!-- 空状态 -->
  45. <view style="padding-bottom: 60rpx;"
  46. v-if="list.length === 0" >
  47. <uv-empty
  48. :text="activeTab === 0 ? '还没有草稿章节' : '还没有发布章节'"
  49. :icon="activeTab === 0 ? 'edit-pen' : 'list'"
  50. iconSize="60"
  51. iconColor="#ccc"
  52. textColor="#999"
  53. textSize="28"
  54. mode="data"
  55. />
  56. </view>
  57. </view>
  58. </view>
  59. <view class="bottom-actions">
  60. <button class="btn-settings" @click="handleSettings">设置作品</button>
  61. <button class="btn-new" @click="addNewChapter">新建章节</button>
  62. </view>
  63. </view>
  64. </template>
  65. <script>
  66. import mixinsList from '@/mixins/list.js'
  67. export default {
  68. mixins: [mixinsList],
  69. components: {
  70. },
  71. data() {
  72. return {
  73. tabs : [
  74. {
  75. name : '草稿箱',
  76. index : 1
  77. },
  78. {
  79. name : '已发布',
  80. index : 0
  81. }
  82. ],
  83. activeTab: 0,
  84. mixinsListApi : 'getMyShopNovelPage',
  85. id : 0,
  86. swipeOptions: [{
  87. text: '删除',
  88. style: {
  89. backgroundColor: '#f56c6c'
  90. }
  91. }]
  92. }
  93. },
  94. onLoad(options) {
  95. this.queryParams.reverse = 0
  96. // 根据tab参数决定初始tab
  97. if (options.activeTab) {
  98. this.activeTab = options.activeTab;
  99. }
  100. if(options.id){
  101. this.queryParams.bookId = options.id
  102. this.id = options.id
  103. this.queryParams.status = this.activeTab
  104. }
  105. },
  106. methods: {
  107. clickTabs(tab) {
  108. this.activeTab = tab.index;
  109. this.queryParams.status = this.activeTab
  110. this.list = []
  111. this.getData()
  112. },
  113. reverseList() {
  114. this.queryParams.reverse = [1, 0][this.queryParams.reverse]
  115. this.getData()
  116. },
  117. addNewChapter() {
  118. uni.navigateTo({
  119. url: '/pages_order/author/editor?id=' + this.id
  120. })
  121. },
  122. editChapter(chapter) {
  123. uni.navigateTo({
  124. url: '/pages_order/author/editor?cid=' + chapter.id + '&id=' + this.id
  125. })
  126. },
  127. handleSettings() {
  128. uni.navigateTo({
  129. url: '/pages_order/author/createNovel?id=' + this.id
  130. })
  131. },
  132. // 删除章节
  133. deleteChapter(chapter, index) {
  134. uni.showModal({
  135. title: '提示',
  136. content: `确定要删除章节"${chapter.title}"吗?`,
  137. success: async (res) => {
  138. if (res.confirm) {
  139. try {
  140. await this.$fetch('deleteMyNovel', {
  141. id: chapter.id
  142. })
  143. uni.showToast({
  144. title: '删除成功',
  145. icon: 'success'
  146. })
  147. // 重新获取列表数据
  148. this.getData()
  149. } catch (error) {
  150. uni.showToast({
  151. title: '删除失败',
  152. icon: 'none'
  153. })
  154. }
  155. }
  156. }
  157. })
  158. },
  159. deleteAll() {
  160. uni.showModal({
  161. title: '提示',
  162. content: '确定要删除所有草稿章节吗?',
  163. success: (res) => {
  164. if (res.confirm) {
  165. // 调用删除草稿API
  166. this.$api.deleteAllDrafts({bookId: this.id}).then(res => {
  167. if (res.code === 200) {
  168. this.$utils.showToast('删除成功')
  169. this.getData()
  170. }
  171. })
  172. }
  173. }
  174. })
  175. }
  176. }
  177. }
  178. </script>
  179. <style lang="scss" scoped>
  180. .chapter-container {
  181. min-height: 100vh;
  182. background-color: #f7f7f7;
  183. padding-bottom: 70px;
  184. .tabs{
  185. background-color: #fff;
  186. }
  187. .box{
  188. background-color: #fff;
  189. margin: 50rpx 40rpx;
  190. border-radius: 20rpx;
  191. .draft-header {
  192. padding: 20rpx 40rpx;
  193. display: flex;
  194. justify-content: space-between;
  195. align-items: center;
  196. padding-bottom: 20rpx;
  197. border-bottom: 1px dashed #eee;
  198. margin-bottom: 10rpx;
  199. .draft-title {
  200. font-size: 30rpx;
  201. color: #000;
  202. font-weight: 900;
  203. }
  204. .delete-btn {
  205. font-size: 28rpx;
  206. color: #999;
  207. }
  208. }
  209. .chapter-list {
  210. .chapter-item {
  211. padding: 20rpx 40rpx;
  212. display: flex;
  213. justify-content: space-between;
  214. align-items: center;
  215. border-bottom: 1px solid #eee;
  216. .chapter-info {
  217. .chapter-title {
  218. font-size: 14px;
  219. color: #999;
  220. margin-bottom: 5px;
  221. display: block;
  222. }
  223. .chapter-number {
  224. font-size: 16px;
  225. color: #333;
  226. display: block;
  227. }
  228. .vip-tag {
  229. background: #ffe1b2;
  230. color: #ff9900;
  231. border-radius: 20rpx;
  232. font-size: 24rpx;
  233. padding: 2rpx 18rpx;
  234. margin-left: 16rpx;
  235. }
  236. }
  237. .icon-arrow {
  238. color: #999;
  239. font-size: 16px;
  240. }
  241. }
  242. }
  243. }
  244. .bottom-actions {
  245. padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
  246. position: fixed;
  247. bottom: 0;
  248. left: 0;
  249. right: 0;
  250. display: flex;
  251. padding: 10px 15px;
  252. background: #fff;
  253. box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.05);
  254. button {
  255. flex: 1;
  256. height: 40px;
  257. border-radius: 20px;
  258. font-size: 16px;
  259. margin: 0 5px;
  260. &.btn-settings {
  261. background: #fff;
  262. border: 1px solid #ddd;
  263. color: #333;
  264. }
  265. &.btn-new {
  266. background: #2b4acb;
  267. color: #fff;
  268. border: none;
  269. }
  270. }
  271. }
  272. }
  273. </style>