风险测评小程序前端代码仓库
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.

300 lines
6.7 KiB

  1. <template>
  2. <view class="page__view">
  3. <navbar title="意见反馈" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" />
  4. <view class="bg">
  5. <view class="title">Hello</view>
  6. <view class="desc">有什么好的建议可以告诉我们哦</view>
  7. </view>
  8. <view class="main">
  9. <view class="form">
  10. <uv-form
  11. ref="form"
  12. :model="form"
  13. errorType="toast"
  14. >
  15. <view class="form-item">
  16. <uv-form-item prop="textDetails" :customStyle="formItemStyle">
  17. <view class="card">
  18. <view class="editor-header">
  19. <view class="editor-header-content">
  20. <view>反馈内容</view>
  21. <view class="editor-icon">
  22. <uv-icon name="star-fill" color="#FFFFFF" size="26rpx"></uv-icon>
  23. </view>
  24. </view>
  25. </view>
  26. <view class="editor__view">
  27. <editor id="editor" class="editor"
  28. placeholder="请填写10个字以上的内容,以便我们为您提供更好的服务"
  29. @ready="onEditorReady"
  30. @input="onEditroInput"
  31. ></editor>
  32. <view class="editor-tools">
  33. <button @click="insertImage" plain class="flex btn">
  34. <!-- todo: 缺切图 -->
  35. <uv-icon name="camera-fill" color="#014FA2" size="56rpx"></uv-icon>
  36. </button>
  37. </view>
  38. </view>
  39. </view>
  40. </uv-form-item>
  41. </view>
  42. <view class="form-item">
  43. <uv-form-item prop="phone" :customStyle="formItemStyle">
  44. <view class="flex card phone">
  45. <view class="label">联系电话</view>
  46. <input
  47. v-model="form.phone"
  48. placeholder-style="color: #999999; font-size: 28rpx;"
  49. placeholder="请输入手机号"
  50. />
  51. </view>
  52. </uv-form-item>
  53. </view>
  54. </uv-form>
  55. </view>
  56. </view>
  57. </view>
  58. </template>
  59. <script>
  60. export default {
  61. data() {
  62. return {
  63. form: {
  64. textDetails: null,
  65. phone: null,
  66. },
  67. formItemStyle: { padding: 0 },
  68. }
  69. },
  70. onReady() {
  71. this.$refs.form.setRules(this.getRules());
  72. },
  73. methods: {
  74. onEditorReady() {
  75. uni.createSelectorQuery().select('#editor').context((res) => {
  76. this.editorCtx = res.context
  77. }).exec()
  78. },
  79. onEditroInput(e) {
  80. const { text } = e.detail
  81. this.descLen = text?.length || 0
  82. },
  83. insertImage() {
  84. uni.chooseImage({
  85. count: 1,
  86. success: (res) => {
  87. // this.editorCtx.insertImage({
  88. // src: res.tempFilePaths[0],
  89. // alt: '图像',
  90. // })
  91. // todo: check
  92. this.$Oss.ossUpload(res.tempFilePaths[0]).then(url => {
  93. this.editorCtx.insertImage({
  94. src: url,
  95. alt: '图像',
  96. })
  97. })
  98. }
  99. })
  100. },
  101. setEditorContents(html) {
  102. if (!this.editorCtx) {
  103. setTimeout(() => {
  104. this.setEditorContents(html)
  105. }, 200)
  106. return
  107. }
  108. this.editorCtx.setContents({ html })
  109. },
  110. getEditorContents() {
  111. return new Promise((resolve, reject) => {
  112. this.editorCtx.getContents({
  113. success: (e) => {
  114. const { html, text } = e
  115. resolve({ html, text })
  116. },
  117. fail: () => {
  118. reject()
  119. }
  120. })
  121. })
  122. },
  123. getRules() {
  124. const textDetailsValidator = async (rule, value, callback) => {
  125. const textDetails = (await this.getEditorContents())?.html
  126. if (textDetails) {
  127. callback()
  128. return
  129. }
  130. callback(new Error('请填写10个字以上的内容,以便我们为您提供更好的服务'))
  131. }
  132. return {
  133. 'phone': {
  134. type: 'string',
  135. required: true,
  136. message: '请输入手机号',
  137. },
  138. 'textDetails': {
  139. asyncValidator: textDetailsValidator,
  140. },
  141. }
  142. },
  143. async onSubmit(headImage) {
  144. try {
  145. await this.$refs.form.validate()
  146. const textDetails = (await this.getEditorContents())?.html
  147. const {
  148. phone,
  149. } = this.form
  150. const params = {
  151. phone,
  152. textDetails,
  153. }
  154. // todo
  155. // await this.$fetch('saveOrUpdateArticleShare', params)
  156. uni.showToast({
  157. title: '提交成功',
  158. icon: 'none'
  159. })
  160. setTimeout(uni.navigateBack, 1000, -1)
  161. } catch (err) {
  162. }
  163. },
  164. },
  165. }
  166. </script>
  167. <style scoped lang="scss">
  168. .page__view {
  169. background: #F5F5F5;
  170. /deep/ .nav-bar__view {
  171. position: fixed;
  172. top: 0;
  173. left: 0;
  174. }
  175. }
  176. .bg {
  177. width: 100%;
  178. height: 501rpx;
  179. padding-top: 203rpx;
  180. box-sizing: border-box;
  181. color: #FFFFFF;
  182. background: linear-gradient(164deg, #014FA2 30%, #4C8FD6);
  183. .title {
  184. padding: 0 73rpx;
  185. font-size: 64rpx;
  186. font-weight: 600;
  187. }
  188. .desc {
  189. margin-top: 18rpx;
  190. padding: 0 68rpx;
  191. box-sizing: border-box;
  192. font-size: 28rpx;
  193. }
  194. }
  195. .main {
  196. width: 100%;
  197. padding: 0 28rpx;
  198. box-sizing: border-box;
  199. background: #F5F5F5;
  200. }
  201. .form {
  202. // transform: translateY(-98rpx);
  203. transform: translateY(-46rpx);
  204. &-item {
  205. & + & {
  206. margin-top: 36rpx;
  207. }
  208. }
  209. }
  210. .editor__view {
  211. padding: 43rpx 30rpx;
  212. background-color: #FFFFFF;
  213. border-radius: 12rpx;
  214. }
  215. .editor-header {
  216. position: absolute;
  217. top: 0;
  218. left: 12rpx;
  219. transform: translateY(-100%);
  220. // margin-left: 12rpx;
  221. &-content {
  222. position: relative;
  223. padding: 9rpx 20rpx 3rpx 20rpx;
  224. font-size: 28rpx;
  225. font-weight: 600;
  226. color: #FFFFFF;
  227. border-top-left-radius: 30rpx;
  228. background: linear-gradient(to right, #014FA2, #6A9ACE);
  229. }
  230. }
  231. .editor-icon {
  232. position: absolute;
  233. top: 0;
  234. right: 0;
  235. transform: translate(30rpx, -4rpx);
  236. }
  237. .editor {
  238. height: 462rpx;
  239. &-tools {
  240. padding: 0 7rpx;
  241. .btn {
  242. width: 133rpx;
  243. height: 133rpx;
  244. border: 2rpx dashed #014FA2;
  245. }
  246. }
  247. }
  248. .card {
  249. position: relative;
  250. }
  251. .phone {
  252. justify-content: flex-start;
  253. padding: 44rpx 27rpx;
  254. column-gap: 31rpx;
  255. background: #FFFFFF;
  256. border-radius: 15rpx;
  257. .label {
  258. font-size: 28rpx;
  259. color: #000000;
  260. }
  261. }
  262. </style>