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

343 lines
8.4 KiB

  1. <template>
  2. <!-- 新建作品页面 -->
  3. <view class="create-novel">
  4. <uv-navbar
  5. title="新建作品"
  6. :autoBack="true"
  7. fixed
  8. placeholder
  9. titleStyle="color: #333; font-weight: 500;"
  10. :border="false"
  11. ></uv-navbar>
  12. <view class="form-container">
  13. <!-- 封面信息 -->
  14. <view class="section">
  15. <view class="section-title">封面信息</view>
  16. <view class="upload-cover">
  17. <view class="sub-title">上传封面</view>
  18. <view class="cover-box" @click="chooseCover">
  19. <image v-if="formData.cover" :src="formData.cover" mode="aspectFill" class="cover-image"></image>
  20. <view v-else class="upload-placeholder">
  21. <text class="plus">+</text>
  22. </view>
  23. </view>
  24. </view>
  25. </view>
  26. <!-- 作品信息 -->
  27. <view class="section">
  28. <view class="section-title">作品信息</view>
  29. <view class="form-item">
  30. <text class="required">*</text>
  31. <text class="label">作品名称</text>
  32. <input
  33. type="text"
  34. v-model="formData.title"
  35. placeholder="请输入"
  36. placeholder-class="input-placeholder"
  37. />
  38. </view>
  39. <view class="form-item">
  40. <text class="required">*</text>
  41. <text class="label">作品类型</text>
  42. <input
  43. type="text"
  44. v-model="formData.type"
  45. placeholder="请输入"
  46. placeholder-class="input-placeholder"
  47. />
  48. </view>
  49. <view class="form-item">
  50. <text class="required">*</text>
  51. <text class="label">作品简介</text>
  52. <textarea
  53. v-model="formData.description"
  54. placeholder="请输入"
  55. placeholder-class="input-placeholder"
  56. :maxlength="500"
  57. ></textarea>
  58. </view>
  59. <view class="form-item">
  60. <text class="required">*</text>
  61. <text class="label">作品状态</text>
  62. <view class="status-options">
  63. <view
  64. class="status-item"
  65. :class="{ active: formData.status === 'serial' }"
  66. @click="formData.status = 'serial'"
  67. >
  68. <view class="radio-dot" :class="{ checked: formData.status === 'serial' }"></view>
  69. <text>连载</text>
  70. </view>
  71. <view
  72. class="status-item"
  73. :class="{ active: formData.status === 'completed' }"
  74. @click="formData.status = 'completed'"
  75. >
  76. <view class="radio-dot" :class="{ checked: formData.status === 'completed' }"></view>
  77. <text>完结</text>
  78. </view>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- 书籍信息 -->
  83. <view class="section">
  84. <view class="section-title">书籍信息</view>
  85. <view class="form-item">
  86. <text class="label">书号</text>
  87. <text class="value">9999993339393</text>
  88. </view>
  89. <view class="form-item">
  90. <text class="label">总字数</text>
  91. <text class="value">99999999</text>
  92. </view>
  93. </view>
  94. <!-- 提交按钮 -->
  95. <view class="submit-btn" @click="submitForm">提交申请</view>
  96. </view>
  97. </view>
  98. </template>
  99. <script>
  100. export default {
  101. components: {
  102. 'uv-navbar': () => import('@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue')
  103. },
  104. data() {
  105. return {
  106. formData: {
  107. cover: '',
  108. title: '',
  109. type: '',
  110. description: '',
  111. status: 'serial' // 默认连载
  112. }
  113. }
  114. },
  115. methods: {
  116. // 选择封面
  117. chooseCover() {
  118. uni.chooseImage({
  119. count: 1,
  120. success: (res) => {
  121. this.formData.cover = res.tempFilePaths[0]
  122. }
  123. })
  124. },
  125. // 提交表单
  126. submitForm() {
  127. if (!this.formData.title) {
  128. uni.showToast({
  129. title: '请输入作品名称',
  130. icon: 'none'
  131. })
  132. return
  133. }
  134. if (!this.formData.type) {
  135. uni.showToast({
  136. title: '请输入作品类型',
  137. icon: 'none'
  138. })
  139. return
  140. }
  141. if (!this.formData.description) {
  142. uni.showToast({
  143. title: '请输入作品简介',
  144. icon: 'none'
  145. })
  146. return
  147. }
  148. // 构建作品数据
  149. const workData = {
  150. id: Date.now().toString(),
  151. title: this.formData.title,
  152. cover: this.formData.cover || 'https://bookcover.yuewen.com/qdbimg/349573/1033014772/150.webp',
  153. readers: '8721',
  154. status: 'ongoing',
  155. publishStatus: '发布审核中',
  156. isOriginal: true
  157. }
  158. // 保存到全局状态
  159. getApp().globalData.submittedWork = workData
  160. // 设置需要显示提交成功提示的标记
  161. getApp().globalData.showSubmitSuccess = true
  162. // 延迟返回上一页
  163. setTimeout(() => {
  164. // 先保存当前要显示的标签
  165. uni.setStorageSync('activeBookshelfTab', 'work')
  166. // 返回上一页
  167. uni.navigateBack({
  168. delta: 1
  169. })
  170. }, 500)
  171. }
  172. }
  173. }
  174. </script>
  175. <style lang="scss">
  176. .create-novel {
  177. min-height: 100vh;
  178. background-color: #F8F8F8;
  179. .form-container {
  180. padding: 20rpx;
  181. .section {
  182. background-color: #FFFFFF;
  183. border-radius: 12rpx;
  184. padding: 30rpx;
  185. margin-bottom: 20rpx;
  186. .section-title {
  187. font-size: 32rpx;
  188. font-weight: bold;
  189. color: #333;
  190. margin-bottom: 30rpx;
  191. }
  192. .upload-cover {
  193. .sub-title {
  194. font-size: 28rpx;
  195. color: #666;
  196. margin-bottom: 20rpx;
  197. }
  198. .cover-box {
  199. width: 200rpx;
  200. height: 266rpx;
  201. background-color: #F5F5F5;
  202. border-radius: 8rpx;
  203. display: flex;
  204. align-items: center;
  205. justify-content: center;
  206. overflow: hidden;
  207. .cover-image {
  208. width: 100%;
  209. height: 100%;
  210. }
  211. .upload-placeholder {
  212. .plus {
  213. font-size: 60rpx;
  214. color: #999;
  215. }
  216. }
  217. }
  218. }
  219. .form-item {
  220. margin-bottom: 30rpx;
  221. position: relative;
  222. &:last-child {
  223. margin-bottom: 0;
  224. }
  225. .required {
  226. color: #FF0000;
  227. margin-right: 4rpx;
  228. }
  229. .label {
  230. font-size: 28rpx;
  231. color: #333;
  232. margin-bottom: 16rpx;
  233. display: block;
  234. }
  235. input, textarea {
  236. width: 100%;
  237. height: 80rpx;
  238. background-color: #F5F5F5;
  239. border-radius: 8rpx;
  240. padding: 20rpx;
  241. font-size: 28rpx;
  242. color: #333;
  243. box-sizing: border-box;
  244. position: relative;
  245. z-index: 1;
  246. }
  247. textarea {
  248. height: 200rpx;
  249. }
  250. .input-placeholder {
  251. color: #999;
  252. }
  253. .status-options {
  254. display: flex;
  255. gap: 40rpx;
  256. .status-item {
  257. display: flex;
  258. align-items: center;
  259. gap: 10rpx;
  260. .radio-dot {
  261. width: 32rpx;
  262. height: 32rpx;
  263. border: 2rpx solid #999;
  264. border-radius: 50%;
  265. position: relative;
  266. &.checked {
  267. border-color: #001351;
  268. &::after {
  269. content: '';
  270. position: absolute;
  271. width: 20rpx;
  272. height: 20rpx;
  273. background-color: #001351;
  274. border-radius: 50%;
  275. left: 50%;
  276. top: 50%;
  277. transform: translate(-50%, -50%);
  278. }
  279. }
  280. }
  281. text {
  282. font-size: 28rpx;
  283. color: #333;
  284. }
  285. }
  286. }
  287. .value {
  288. font-size: 28rpx;
  289. color: #999;
  290. }
  291. }
  292. }
  293. .submit-btn {
  294. background-color: #001351;
  295. color: #FFFFFF;
  296. font-size: 32rpx;
  297. text-align: center;
  298. padding: 24rpx 0;
  299. border-radius: 12rpx;
  300. margin-top: 40rpx;
  301. &:active {
  302. opacity: 0.9;
  303. }
  304. }
  305. }
  306. }
  307. </style>