index.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <!--test.vue-->
  2. <template>
  3. <div class="source-form-top-container" :key="componentKey">
  4. <div class="source-form-tip-container" v-if="!canWrite">
  5. <div class="source-form-content-container">
  6. <van-empty :description="notCanWriteTip" />
  7. </div>
  8. </div>
  9. <van-overlay class="show-success-dialog-container" :class="{ 'is-not-edit': !isEdit }" :show="isShowSuccessDialog" @click="successDialogShow = false">
  10. <div @click.stop class="show-success-dialog-content-container">
  11. <img v-if="useSourceFormConfig.submitSuccessImage" :src="useSourceFormConfig.submitSuccessImage" />
  12. <van-icon class="icon-close-dialog" name="clear" @click="successDialogShow = false" />
  13. </div>
  14. </van-overlay>
  15. <van-form
  16. class="source-form"
  17. @submit="onSubmit"
  18. :style="{
  19. 'background-color': useSourceFormConfig.background
  20. }"
  21. >
  22. <van-field
  23. v-if="useSourceFormConfig.company"
  24. v-model.trim="form.company"
  25. required
  26. name="公司名称"
  27. label="公司名称"
  28. placeholder="请输入准确的公司名称"
  29. />
  30. <van-field
  31. v-if="useSourceFormConfig.name"
  32. v-model.trim="form.name"
  33. required
  34. name="姓名"
  35. label="姓名"
  36. placeholder="请输入姓名"
  37. />
  38. <van-field
  39. v-if="useSourceFormConfig.phone"
  40. v-model.trim="form.phone"
  41. required
  42. name="手机号"
  43. label="手机号"
  44. placeholder="请输入准确的手机号"
  45. />
  46. <van-field name="radio" required label="你希望获得哪个行业的报告" v-if="useSourceFormConfig.source_desc">
  47. <template #input>
  48. <div class="custom-radio-type">
  49. <van-radio-group
  50. v-model="form.source_desc"
  51. >
  52. <van-radio
  53. v-for="item in useSourceFormConfig.sourceOptions"
  54. :name="item"
  55. :key="item"
  56. >
  57. <div class="other-input-box" v-if="form.source_desc === '其他' && item === '其他'">
  58. <span>{{item}}</span>
  59. <van-field
  60. v-model.trim="form.source_desc_temp"
  61. placeholder="请输入行业"
  62. />
  63. </div>
  64. <span v-else>{{item}}</span>
  65. </van-radio>
  66. </van-radio-group>
  67. </div>
  68. </template>
  69. </van-field>
  70. <div style="margin: 16px;">
  71. <van-button round block :type="btnType" :size="size" native-type="submit">{{text}}</van-button>
  72. </div>
  73. </van-form>
  74. </div>
  75. </template>
  76. <script>
  77. import { Form, Field, Button, Radio, RadioGroup, Toast, Empty, Overlay, Icon} from 'vant';
  78. import $axios from "@/service/httpServer";
  79. const DEFAULT_SOURCE_CONFIG = {
  80. background: 'transparent',
  81. source: 'default-source-h5',
  82. name: true,
  83. phone: true,
  84. company: true,
  85. source_desc: true,
  86. sourceOptions: [
  87. '建筑工程',
  88. '信息技术',
  89. '弱电安防',
  90. '医疗卫生',
  91. '服务采购',
  92. '其他'
  93. ],
  94. // 提交限制
  95. submitCountState: -1,
  96. submitTimeState: -1,
  97. submitSuccessState: -1,
  98. submitTime: [],
  99. submitSuccessTip: '提交成功',
  100. submitCountMaxTip: '您已提交该表单',
  101. submitTimeBeforeTip: '该表单暂未开始填写',
  102. submitTimeAfterTip: '该表单已结束填写',
  103. }
  104. export default {
  105. name: 'DsSourceForm',
  106. components: {
  107. [Overlay.name]: Overlay,
  108. [Empty.name]: Empty,
  109. [Icon.name]: Icon,
  110. [Form.name]: Form,
  111. [Field.name]: Field,
  112. [Radio.name]: Radio,
  113. [RadioGroup.name]: RadioGroup,
  114. [Button.name]: Button
  115. },
  116. data() {
  117. return {
  118. componentKey: 1,
  119. successDialogShow: false,
  120. form: {
  121. name: '',
  122. phone: '',
  123. company: '',
  124. source_desc: '',
  125. source_desc_temp: ''
  126. }
  127. }
  128. },
  129. props: {
  130. api: {
  131. type: String,
  132. default: '/salesLeads/official/notLogin'
  133. },
  134. btnType:{
  135. type:String,
  136. default:'info'
  137. },
  138. text: {
  139. type: String,
  140. default: '提 交'
  141. },
  142. size:{
  143. type:String,
  144. default:'large'
  145. },
  146. sourceFormConfig: {
  147. type:Object,
  148. default: () => {
  149. return DEFAULT_SOURCE_CONFIG
  150. }
  151. }
  152. },
  153. computed: {
  154. isShowSuccessDialog () {
  155. if (this.useSourceFormConfig.submitSuccessState !== 0) {
  156. return false
  157. }
  158. if (this.isEdit) {
  159. return true
  160. }
  161. return this.successDialogShow
  162. },
  163. isEdit () {
  164. return location.href.indexOf('/#/editor?id') !== -1
  165. },
  166. useSourceFormConfig () {
  167. return Object.assign({}, DEFAULT_SOURCE_CONFIG, this.sourceFormConfig)
  168. },
  169. canWrite () {
  170. let result = true
  171. if (this.needCheckWriteCount && this.hasCacheWrite) {
  172. result = false
  173. }
  174. if (!this.canTimeing) {
  175. result = false
  176. }
  177. return result
  178. },
  179. notCanWriteTip () {
  180. // 判断表单填写限制、表单过期限制
  181. let tip = ''
  182. if (this.needCheckTime) {
  183. if (!this.isTimeStart) {
  184. tip = this.useSourceFormConfig.submitTimeBeforeTip
  185. } else if (this.isTimeEnd) {
  186. tip = this.useSourceFormConfig.submitTimeAfterTip
  187. }
  188. }
  189. if (this.needCheckWriteCount) {
  190. if (this.hasCacheWrite) {
  191. tip = this.useSourceFormConfig.submitCountMaxTip
  192. }
  193. }
  194. return tip
  195. },
  196. needCheckWriteCount () {
  197. return this.useSourceFormConfig.submitCountState !== -1
  198. },
  199. needCheckTime () {
  200. return this.useSourceFormConfig.submitTimeState !== -1
  201. },
  202. canTimeing () {
  203. if (!this.needCheckTime) {
  204. return true
  205. }
  206. return this.isTimeStart && !this.isTimeEnd
  207. },
  208. hasCacheWrite () {
  209. console.log(this.componentKey, 'update key')
  210. if (this.isEdit) {
  211. return true
  212. }
  213. let result = false
  214. try {
  215. result = localStorage.getItem(window._pageData._id) === '1'
  216. } catch (e) {
  217. console.warn(e)
  218. }
  219. return result
  220. },
  221. isTimeStart () {
  222. console.log(this.componentKey, 'update key')
  223. if (this.sourceFormConfig.submitTime[0]) {
  224. return Date.now() >= this.sourceFormConfig.submitTime[0]
  225. } else {
  226. return true
  227. }
  228. },
  229. isTimeEnd () {
  230. console.log(this.componentKey, 'update key')
  231. if (this.sourceFormConfig.submitTime[1]) {
  232. return Date.now() >= this.sourceFormConfig.submitTime[1]
  233. } else {
  234. return false
  235. }
  236. },
  237. },
  238. methods: {
  239. updateComponent () {
  240. this.componentKey = Date.now()
  241. },
  242. saveCache () {
  243. try {
  244. localStorage.setItem(window._pageData._id, '1')
  245. } catch (e) {
  246. console.warn(e)
  247. }
  248. },
  249. submitSuccessCallback () {
  250. this.saveCache()
  251. this.updateComponent()
  252. switch (this.useSourceFormConfig.submitSuccessState) {
  253. case -1: {
  254. Toast(this.useSourceFormConfig.submitSuccessTip)
  255. break
  256. }
  257. case 0: {
  258. if (this.useSourceFormConfig.submitSuccessImage) {
  259. this.successDialogShow = true
  260. } else {
  261. Toast(this.useSourceFormConfig.submitSuccessTip)
  262. }
  263. break
  264. }
  265. case 1: {
  266. if (this.useSourceFormConfig.submitSuccessURL) {
  267. location.href = this.useSourceFormConfig.submitSuccessURL
  268. } else {
  269. Toast(this.useSourceFormConfig.submitSuccessTip)
  270. }
  271. break
  272. }
  273. }
  274. },
  275. onSubmit (values) {
  276. console.log(values)
  277. Toast.loading({
  278. duration: 0,
  279. forbidClick: true
  280. });
  281. const params = Object.assign({
  282. source: this.useSourceFormConfig.source,
  283. origin: location.href
  284. }, this.form, {
  285. source_desc: this.form.source_desc === '其他' ? this.form.source_desc_temp : this.form.source_desc
  286. })
  287. console.log('source-params', params)
  288. $axios.post(location.origin + this.api, JSON.stringify(params), {
  289. headers: {
  290. 'Content-Type': 'application/json;charset=utf-8'
  291. }
  292. }).then(res => {
  293. console.log('res', res)
  294. Toast.clear()
  295. if (res.data) {
  296. this.submitSuccessCallback()
  297. } else {
  298. Toast(res.error_msg || '太火爆了,请稍后重试')
  299. }
  300. }).catch(() => {
  301. Toast.clear()
  302. Toast('太火爆了,请稍后重试')
  303. })
  304. }
  305. }
  306. }
  307. </script>
  308. <style lang="scss" scoped>
  309. .other-input-box {
  310. display: flex;
  311. flex-direction: row;
  312. align-items: center;
  313. span {
  314. flex-shrink: 0;
  315. }
  316. }
  317. .custom-radio-type {
  318. display: flex;
  319. flex-direction: column;
  320. }
  321. .source-form {
  322. max-width: 375px;
  323. margin: 0 auto;
  324. width: 100%;
  325. height: 100%;
  326. padding: 16px 0;
  327. ::v-deep {
  328. .van-cell {
  329. flex-direction: column;
  330. background-color: inherit;
  331. }
  332. .van-field__label {
  333. width: 100%;
  334. }
  335. .van-radio {
  336. height: 44px;
  337. }
  338. }
  339. }
  340. .source-form-top-container {
  341. position: relative;
  342. }
  343. .show-success-dialog-container {
  344. display: flex;
  345. align-items: center;
  346. justify-content: center;
  347. &.is-not-edit {
  348. height: 100vh;
  349. width: 100vw;
  350. }
  351. }
  352. .show-success-dialog-content-container {
  353. max-width: 80%;
  354. img {
  355. max-width: 100%;
  356. border-radius: 12px;
  357. }
  358. }
  359. .icon-close-dialog {
  360. color: #fff;
  361. font-size: 24px;
  362. }
  363. .source-form-tip-container {
  364. position: absolute;
  365. top: 0;
  366. left: 0;
  367. width: 100%;
  368. height: 100%;
  369. background-color: #fff;
  370. display: flex;
  371. align-items: center;
  372. justify-content: center;
  373. z-index: 1;
  374. .source-form-content-container {
  375. background-color: #fff;
  376. }
  377. }
  378. </style>