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

257 lines
5.9 KiB

2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
  1. <template>
  2. <view class="work-item" @click.stop="handleClick">
  3. <view class="cover-wrapper">
  4. <image class="cover" :src="work.image && work.image.split(',')[0]" mode="aspectFill"></image>
  5. <view class="tag original" v-if="work.isOriginal == 'Y'">原创</view>
  6. </view>
  7. <view class="info">
  8. <text class="title">{{work.name}}</text>
  9. <view class="readers">
  10. <text class="readers-count">达成成就人{{work.readers || 0}}</text>
  11. </view>
  12. <!-- 状态标签 -->
  13. <view class="status-wrapper">
  14. <view class="status-tag" :class="statusClass">
  15. {{statusText}}
  16. </view>
  17. <!-- 发布状态标签 -->
  18. <view class="publish-status"
  19. :class="bookStatusClass"
  20. >
  21. <text>{{bookStatusText}}</text>
  22. </view>
  23. <!-- 设置状态标签 -->
  24. <view class="publish-status"
  25. :class="toolStatusClass"
  26. >
  27. <text>{{toolStatusText}}</text>
  28. </view>
  29. </view>
  30. </view>
  31. <!-- 添加右箭头图标 -->
  32. <!-- <text class="iconfont icon-arrow">&#xe65f;</text> -->
  33. </view>
  34. </template>
  35. <script>
  36. export default {
  37. props: {
  38. work: {
  39. type: Object,
  40. default: {},
  41. },
  42. isManaging: {
  43. type: Boolean,
  44. default: false
  45. },
  46. },
  47. computed: {
  48. statusClass() {
  49. const statusMap = {
  50. 'draft': 'new',
  51. '0': 'ongoing',
  52. '1': 'completed'
  53. };
  54. return statusMap[this.work.status] || 'ongoing';
  55. },
  56. statusText() {
  57. // 优先使用 dictText,如果没有则使用默认映射
  58. if (this.work.status_dictText) {
  59. return this.work.status_dictText;
  60. }
  61. const textMap = {
  62. '0': '连载中',
  63. '1': '已完结'
  64. };
  65. return textMap[this.work.status] || '连载中';
  66. },
  67. toolStatusClass() {
  68. const toolStatusMap = {
  69. '0': 'completed',
  70. '1': 'error',
  71. // '2': 'error',
  72. };
  73. return toolStatusMap[this.work.toolStatus] || '';
  74. },
  75. toolStatusText() {
  76. // 优先使用 dictText,如果没有则使用默认映射
  77. if (this.work.toolStatus_dictText) {
  78. return this.work.toolStatus_dictText;
  79. }
  80. const textMap = {
  81. '0': '设置审核中',
  82. '1': '设置审核通过',
  83. '2': '设置审核不通过'
  84. };
  85. return textMap[this.work.toolStatus] || '';
  86. },
  87. bookStatusClass() {
  88. const bookStatusMap = {
  89. '0': 'ongoing',
  90. '1': 'completed',
  91. '2': 'error',
  92. };
  93. return bookStatusMap[this.work.bookStatus] || '';
  94. },
  95. bookStatusText() {
  96. // 优先使用 dictText,如果没有则使用默认映射
  97. if (this.work.bookStatus_dictText) {
  98. return this.work.bookStatus_dictText;
  99. }
  100. const textMap = {
  101. '0': '发布审核中',
  102. '1': '发布审核通过',
  103. '2': '发布审核不通过'
  104. };
  105. return textMap[this.work.bookStatus] || '';
  106. },
  107. },
  108. methods: {
  109. handleClick() {
  110. console.log('handleClick called, isManaging:', this.isManaging);
  111. // 在编辑模式下,只触发选中事件
  112. if (this.isManaging) {
  113. this.$emit('click');
  114. return;
  115. }
  116. // 非编辑模式下,跳转到章节列表页面
  117. uni.navigateTo({
  118. url: '/pages_order/author/chapterList?id=' + this.work.id
  119. });
  120. },
  121. handleDelete() {
  122. this.$emit('delete');
  123. }
  124. }
  125. }
  126. </script>
  127. <style lang="scss" scoped>
  128. .work-item {
  129. width: 100%;
  130. display: flex;
  131. padding: 24rpx 0;
  132. border-bottom: 1rpx solid #f0f0f0;
  133. position: relative;
  134. align-items: center;
  135. .cover-wrapper {
  136. position: relative;
  137. width: 170rpx;
  138. height: 230rpx;
  139. margin-right: 20rpx;
  140. border-radius: 6rpx;
  141. overflow: hidden;
  142. flex-shrink: 0;
  143. .cover {
  144. width: 100%;
  145. height: 100%;
  146. }
  147. .tag {
  148. position: absolute;
  149. top: 0;
  150. left: 0;
  151. font-size: 20rpx;
  152. color: #fff;
  153. padding: 2rpx 8rpx;
  154. border-radius: 6rpx;
  155. &.original {
  156. background-color: #ffa502;
  157. }
  158. }
  159. }
  160. .info {
  161. flex: 1;
  162. display: flex;
  163. flex-direction: column;
  164. .title {
  165. font-size: 28rpx;
  166. color: #333;
  167. font-weight: bold;
  168. margin-bottom: 10rpx;
  169. line-height: 1.3;
  170. overflow: hidden;
  171. text-overflow: ellipsis;
  172. display: -webkit-box;
  173. -webkit-line-clamp: 1;
  174. -webkit-box-orient: vertical;
  175. }
  176. .readers {
  177. margin-top: 20rpx;
  178. .readers-count {
  179. font-size: 24rpx;
  180. color: #999;
  181. }
  182. }
  183. .status-wrapper {
  184. flex-shrink: 0;
  185. display: flex;
  186. align-items: center;
  187. margin-top: 20rpx;
  188. gap: 10rpx;
  189. .status-tag {
  190. font-size: 22rpx;
  191. padding: 4rpx 16rpx;
  192. border-radius: 20rpx;
  193. text-align: center;
  194. width: fit-content;
  195. &.new {
  196. background-color: #e8f3ff;
  197. color: #5cadff;
  198. }
  199. &.ongoing {
  200. background-color: #fff7e6;
  201. color: #ff9900;
  202. }
  203. &.completed {
  204. background-color: #f0f9eb;
  205. color: #67c23a;
  206. }
  207. }
  208. .publish-status {
  209. &.error{
  210. color: #666;
  211. background-color: #f5f5f5;
  212. }
  213. &.completed {
  214. background-color: #67c23a;
  215. color: #fff;
  216. }
  217. font-size: 22rpx;
  218. color: #666;
  219. background-color: #f5f5f5;
  220. padding: 4rpx 16rpx;
  221. border-radius: 20rpx;
  222. white-space: nowrap;
  223. }
  224. }
  225. }
  226. .icon-arrow {
  227. color: #999;
  228. font-size: 16px;
  229. margin-left: 10rpx;
  230. }
  231. }
  232. </style>