form.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <script lang="ts">
  2. import Vue from 'vue'
  3. import { getFormInfo, submitForm, getLocationList, getJobList } from '@/api/form'
  4. import { getExpoInfo } from '@/api/expo'
  5. import countryCode from '@/lib/countryCode.json'
  6. import login from '@/views/login/index.vue'
  7. export default Vue.extend({
  8. name: 'Index',
  9. data() {
  10. return {
  11. from_data: [],
  12. expo_key: '',
  13. expo_id: '',
  14. countryCode,
  15. locationList: [],
  16. locationPage: 0,
  17. locationTotal: 1,
  18. provinceL: [],
  19. cityL: [],
  20. jobList: [],
  21. jobPage: 0,
  22. jobTotal: 1,
  23. jobL: [],
  24. loading: false,
  25. isOk: false
  26. }
  27. },
  28. computed: {
  29. user() { return this.$store.state.user.user },
  30. token() { return this.$store.state.user.token }
  31. },
  32. mounted() {
  33. this.init()
  34. },
  35. methods: {
  36. init() {
  37. this.expo_key = this.$route.params.url
  38. if (this.token) {
  39. getExpoInfo(this.expo_key).then(res => {
  40. this.from_data = res.data
  41. this.expo_id = res.data.id
  42. }).catch(err => {
  43. console.log('err')
  44. })
  45. } else {
  46. this.$router.push({
  47. name: 'userRegister',
  48. query: {
  49. expo_key: this.expo_key
  50. }
  51. })
  52. }
  53. },
  54. getJob() {
  55. if (this.loading || this.jobPage >= this.jobTotal) {
  56. return
  57. }
  58. this.loading = true
  59. getJobList(++this.jobPage, 10).then(res => {
  60. this.jobList = this.jobList.concat(res.data.data)
  61. this.jobTotal = res.data.last_page
  62. this.jobPage = res.data.current_page
  63. this.loading = false
  64. }).catch(err => {
  65. this.loading = false
  66. })
  67. },
  68. getLocation() {
  69. if (this.loading || this.locationPage >= this.locationTotal) {
  70. return
  71. }
  72. this.loading = true
  73. getLocationList(++this.locationPage, 10).then(res => {
  74. this.locationList = this.locationList.concat(res.data.data)
  75. this.locationTotal = res.data.last_page
  76. this.locationPage = res.data.current_page
  77. this.loading = false
  78. }).catch(err => {
  79. this.loading = false
  80. })
  81. },
  82. submit() {
  83. if(this.loading) {
  84. return
  85. }
  86. this.loading = true
  87. let form_data = {}
  88. for (let i = 0; i < this.from_data.form_fields.length; i++) {
  89. form_data[this.from_data.form_fields[i].field_name] = this.from_data.form_fields[i].value
  90. if (this.from_data.form_fields[i].is_required && !this.from_data.form_fields[i].value) {
  91. this.$message.error('请填写必填项')
  92. this.loading = false
  93. return
  94. }
  95. }
  96. submitForm(this.expo_id, form_data).then(res => {
  97. this.isOk = true
  98. this.loading = false
  99. }).catch(err => {
  100. this.loading = false
  101. })
  102. },
  103. returnWidth(name) {
  104. if (['email', 'address'].includes(name)) {
  105. return 6
  106. }
  107. if (['id_number', 'mobile'].includes(name)) {
  108. return 4
  109. }
  110. if (['first_name', 'last_name', 'interested_products', 'business_type'].includes(name)) {
  111. return 3
  112. }
  113. return 2
  114. }
  115. }
  116. })
  117. </script>
  118. <template>
  119. <div class="body">
  120. <div class="head">
  121. <div class="form-name">
  122. {{ from_data.expo_name }}
  123. </div>
  124. </div>
  125. <div class="form">
  126. <div class="desc">
  127. {{ from_data.content }}
  128. </div>
  129. <div v-if="isOk" class="form-body ok">
  130. <div class="icon el-icon-success"></div>
  131. <div class="text">表单提交完成</div>
  132. </div>
  133. <div v-else class="form-body">
  134. <div v-for="item in from_data.form_fields" :key="item.id" :style="{gridColumn:'span '+returnWidth(item.field_name)}" class="form-item">
  135. <div class="label" :class="item.is_required?'required':''">{{ item.field_label }}</div>
  136. <el-select v-if="item.field_name==='id_type'" v-model="item.value">
  137. <el-option value="Passport" label="护照" />
  138. <el-option value="ID Card" label="身份证" />
  139. </el-select>
  140. <el-select v-else-if="item.field_name==='mobile_country_code'" v-model="item.value" filterable>
  141. <el-option v-for="(code,index) in countryCode" :key="code.country_code+index" :label="'+'+code.phone_code+'('+code.chinese_name+')'" :value="code.phone_code" />
  142. </el-select>
  143. <el-popover
  144. v-else-if="item.field_name==='country'"
  145. placement="bottom"
  146. width="260"
  147. popper-class="popover"
  148. trigger="click"
  149. @show="if(locationList.length===0){getLocation()}"
  150. >
  151. <div class="cont">
  152. <div v-for="loca in locationList" :key="loca.id" class="item" @click="item.value=loca.name;from_data.form_fields.push();provinceL=loca.child">
  153. {{ loca.name }}
  154. </div>
  155. <div v-if="locationPage < locationTotal" class="item" @click="getLocation()">加载更多</div>
  156. </div>
  157. <el-input slot="reference" :value="item.value" />
  158. </el-popover>
  159. <el-popover
  160. v-else-if="item.field_name==='province'"
  161. placement="bottom"
  162. width="260"
  163. popper-class="popover"
  164. trigger="click"
  165. >
  166. <div class="cont">
  167. <div v-for="loca in provinceL" :key="loca.id" class="item" @click="item.value=loca.name;from_data.form_fields.push();if(loca.child){cityL=loca.child}else{cityL=[{id:0,name:loca.name}]}">
  168. {{ loca.name }}
  169. </div>
  170. <div v-if="provinceL.length===0" class="item">请先选择国家</div>
  171. </div>
  172. <el-input slot="reference" :value="item.value" />
  173. </el-popover>
  174. <el-popover
  175. v-else-if="item.field_name==='city'"
  176. placement="bottom"
  177. width="260"
  178. popper-class="popover"
  179. trigger="click"
  180. >
  181. <div class="cont">
  182. <div v-for="loca in cityL" :key="loca.id" class="item" @click="item.value=loca.name;from_data.form_fields.push()">
  183. {{ loca.name }}
  184. </div>
  185. <div v-if="cityL.length===0" class="item">请先选择省份</div>
  186. </div>
  187. <el-input slot="reference" :value="item.value" />
  188. </el-popover>
  189. <el-popover
  190. v-else-if="item.field_name==='department'"
  191. placement="bottom"
  192. width="260"
  193. popper-class="popover"
  194. trigger="click"
  195. @show="if(jobList.length===0){getJob()}"
  196. >
  197. <div class="cont">
  198. <div v-for="job in jobList" :key="job.id" class="item" @click="item.value=job.name;from_data.form_fields.push();jobL=job.child">
  199. {{ job.name }}
  200. </div>
  201. <div v-if="jobPage < jobTotal" class="item" @click="getJob()">加载更多</div>
  202. </div>
  203. <el-input slot="reference" :value="item.value" />
  204. </el-popover>
  205. <el-popover
  206. v-else-if="item.field_name==='position'"
  207. placement="bottom"
  208. width="260"
  209. popper-class="popover"
  210. trigger="click"
  211. >
  212. <div class="cont">
  213. <div v-for="job in jobL" :key="job.id" class="item" @click="item.value=job.name;from_data.form_fields.push()">
  214. {{ job.name }}
  215. </div>
  216. <div v-if="jobL.length===0" class="item">请先选择部门</div>
  217. </div>
  218. <el-input slot="reference" :value="item.value" />
  219. </el-popover>
  220. <el-input v-else v-model="item.value" />
  221. </div>
  222. </div>
  223. <div v-if="!isOk" class="button">
  224. <el-button :disabled="loading" type="primary" @click="submit()">
  225. 提交表单
  226. <span v-if="loading" class="el-icon-loading"></span>
  227. </el-button>
  228. </div>
  229. </div>
  230. </div>
  231. </template>
  232. <style scoped>
  233. .body{
  234. margin: 36px auto;
  235. max-width: 800px;
  236. width: 100%;
  237. .form{
  238. border-radius: 8px;
  239. margin-top: 16px;
  240. padding: 24px;
  241. box-shadow: 0 0 8px 0 #00000008;
  242. background: white;
  243. .button{
  244. margin-top: 12px;
  245. display: flex;
  246. justify-content: flex-end;
  247. }
  248. .desc{
  249. color: gray;
  250. margin-bottom: 32px;
  251. }
  252. .form-body{
  253. display: grid;
  254. grid-template-columns: repeat(6, 1fr);
  255. grid-gap: 8px;
  256. &.ok{
  257. display: flex;
  258. flex-direction: column;
  259. align-items: center;
  260. justify-content: center;
  261. padding: 120px 0;
  262. .icon{
  263. color: #67C23A;
  264. font-size: 86px;
  265. }
  266. .text{
  267. margin-top: 24px;
  268. }
  269. }
  270. .form-item{
  271. .label{
  272. font-size: 15px;
  273. color: gray;
  274. margin-bottom: 8px;
  275. &.required{
  276. &::after{
  277. content: '*';
  278. color: red;
  279. }
  280. }
  281. }
  282. }
  283. }
  284. }
  285. .head{
  286. padding: 0 8px;
  287. display: flex;
  288. gap: 16px;
  289. align-items: flex-end;
  290. .form-name{
  291. margin-bottom: 8px;
  292. font-size: 24px;
  293. font-weight: 600;
  294. }
  295. }
  296. }
  297. </style>
  298. <style>
  299. body{
  300. background: #F9FAFB;
  301. .popover{
  302. overflow: hidden;
  303. padding: 0;
  304. .cont{
  305. padding: 8px 0;
  306. max-height: 220px;
  307. overflow: auto;
  308. .item{
  309. cursor: pointer;
  310. padding: 8px 16px;
  311. &:hover{
  312. background: #F5F7FA;
  313. }
  314. }
  315. }
  316. }
  317. }
  318. </style>