소스 검색

开发ing

zhoujump 2 달 전
부모
커밋
1be8fee13e

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "file-saver": "2.0.1",
     "font-awesome": "^4.7.0",
     "fuse.js": "3.4.4",
+    "hugerte": "^1.0.9",
     "js-cookie": "2.2.0",
     "js-md5": "^0.8.3",
     "jsonlint": "1.6.3",

+ 1 - 1
src/App.vue

@@ -63,7 +63,7 @@ export default {
             next()
           } else {
             next({
-              name: 'login'
+              name: 'userRegister'
             })
           }
         }

+ 52 - 2
src/api/form.js

@@ -86,14 +86,16 @@ export function saveForm(id,template_name,description,fields){
 /**
  * 发送邀请函
  * @param form_ids
+ * @param content
  * @returns {*}
  */
- export function sentInvitation(form_ids) {
+ export function sentInvitation(form_ids,content) {
    return request({
      url: '/api/form/send-invitation',
      method: 'post',
      data:{
-       form_ids
+       form_ids,
+       content
      }
    })
  }
@@ -113,4 +115,52 @@ export function submitForm(expo_id,form_data) {
      }
    })
 }
+/**
+ * 获取位置列表
+ * @returns {AxiosPromise}
+ */
+export function getLocationList(page, page_size){
+  return request({
+    url: '/api/location/list',
+    method: 'get',
+    params: {
+      page,
+      page_size
+    }
+  })
+}
+
+export function  getJobList(page, page_size){
+  return request({
+    url: '/api/job/list',
+    method: 'get',
+    params: {
+      page,
+      page_size
+    }
+  })
+}
+
+/**
+ * 获取观众列表
+ * @param page
+ * @param page_size
+ * @param keyword
+ * @param is_export
+ * @param expo_id
+ * @returns {*}
+ */
+export function getAudienceList(page, page_size,keyword,is_export,expo_id){
+  return request({
+    url: '/api/form/list',
+    method: 'get',
+    params: {
+      keyword,
+      page,
+      page_size,
+      is_export,
+      expo_id
+    }
+  })
+}
 

+ 4 - 2
src/api/system.js

@@ -57,9 +57,10 @@ export function getMailSettings() {
  * @param smtp_port
  * @param smtp_server
  * @param auth_code
+ * @param is_ssl
  * @returns {*}
  */
-export function saveMailSetting(id,from_name,from_email,smtp_port,smtp_server,auth_code) {
+export function saveMailSetting(id,from_name,from_email,smtp_port,smtp_server,auth_code,is_ssl) {
   return request({
     url: '/api/user/mail-setting',
     method: 'post',
@@ -69,7 +70,8 @@ export function saveMailSetting(id,from_name,from_email,smtp_port,smtp_server,au
       from_email,
       smtp_port,
       smtp_server,
-      auth_code
+      auth_code,
+      is_ssl
     }
   })
 }

+ 18 - 0
src/api/user.js

@@ -99,3 +99,21 @@ export function  register(email,phone,valid_code,register_type,country_code) {
     }
   })
 }
+/**
+ * 确认邮箱接口
+ * @param pre_register_key
+ * @param password
+ * @param confirm_password
+ * @returns {*}
+ */
+export function  confirmEmail(pre_register_key,password,confirm_password) {
+  return request({
+    url: '/api/user/confirm-register',
+    method: 'post',
+    data: {
+      pre_register_key,
+      password,
+      confirm_password
+    }
+  })
+}

+ 4 - 4
src/router/index.js

@@ -128,19 +128,19 @@ export const constantRoutes = [
           path: 'list',
           component: () => import('@/views/invitationManage/list'),
           name: 'invitationManageList',
-          meta: { title: '邀请函模板管理', icon: 'el-icon-edit', roles: 'invitation' }
+          meta: { title: '邀请函模板管理', icon: 'el-icon-edit', roles: 'invitation',collapse: false }
         },
         {
           path: 'add',
           component: () => import('@/views/invitationManage/edit'),
           name: 'invitationAdd',
-          meta: { title: '邀请函模板新增', icon: 'el-icon-document-add', roles: 'invitation.add' }
+          meta: { title: '邀请函模板新增', icon: 'el-icon-document-add', roles: 'invitation.add',collapse: true }
         },
         {
           path: 'edit/:id',
           component: () => import('@/views/invitationManage/edit'),
           name: 'invitationEdit',
-          meta: { title: '邀请函模板编辑', icon: 'el-icon-edit', hidden: true, roles: 'invitation.edit' }
+          meta: { title: '邀请函模板编辑', icon: 'el-icon-edit', hidden: true, roles: 'invitation.edit',collapse: true }
         }
         ]
       },
@@ -206,7 +206,7 @@ export const constantRoutes = [
     hidden: true
   },
   {
-    path: '/user/form',
+    path: '/user/form/:url',
     name: 'userForm',
     component: () => import('@/views/user/form.vue'),
     hidden: true

+ 322 - 30
src/views/audienceManage/index.vue

@@ -1,61 +1,304 @@
 <script>
 import Vue from 'vue'
+import hugerte from 'hugerte'
+import 'hugerte/models/dom'
+import 'hugerte/icons/default'
+import 'hugerte/themes/silver'
+import 'hugerte/skins/ui/oxide/skin.js'
+import 'hugerte/skins/ui/oxide/content.js'
+import 'hugerte/skins/content/default/content.js'
 
+import { getAudienceList, sentInvitation } from '@/api/form'
+import { getExpoList, getMyExpoInfo } from '@/api/expo'
+import { getTemplateList } from '@/api/template'
+import expoPopover from '@/views/components/expoPopover.vue'
 export default Vue.extend({
-  name: "index"
+  name: 'Index',
+  components: { expoPopover },
+  data() {
+    return {
+      expoList: [],
+      userList: [],
+      invitation_data: {
+        code: '',
+        tempIndex: 0,
+        data: [],
+        exhibitorSetting: {},
+        userSetting: {},
+        show: false,
+        page: 0,
+        last_page: 1,
+        is_sending: false,
+      },
+      loading: false,
+      searchTimer: null,
+      searchWord: '',
+      is_export: 0,
+      expo_id: 0,
+      current_page: 0,
+      page_size: 20,
+      last_page: 1,
+      total: 0,
+      ossUrl: process.env.VUE_APP_OSS_DOMAIN
+    }
+  },
+  mounted() {
+    this.getAudience()
+    this.getExpoList()
+    this.getInvitationList()
+  },
+  methods: {
+    getInvitationList() {
+      getTemplateList(++this.invitation_data.page, 10).then(res => {
+        console.log(res)
+        this.invitation_data.data = res.data.data
+        this.last_page = res.data.last_page
+        this.page = res.data.current_page
+      }).catch(err => {
+
+      })
+    },
+    getExpoList() {
+      getExpoList(1, 1000).then(res => {
+        this.expoList = res.data.data
+      }).catch(err => {
+
+      })
+    },
+    search(event) {
+      if (this.searchTimer) {
+        clearTimeout(this.searchTimer)
+      }
+      this.searchTimer = setTimeout(() => {
+        this.current_page = 1
+        this.getAudience()
+      }, 500)
+    },
+    getAudience() {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+      getAudienceList(this.current_page, this.page_size, this.searchWord, this.is_export, this.expo_id).then(res => {
+        this.current_page = res.data.current_page
+        this.last_page = res.data.last_page
+        this.total = res.data.total
+        this.userList = res.data.data
+        this.loading = false
+      }).catch(err => {
+        this.loading = false
+      })
+    },
+    openDialog(row) {
+      this.invitation_data.show = true
+      this.invitation_data.userSetting = row
+      getMyExpoInfo(row.expo_id).then(res => {
+        this.invitation_data.exhibitorSetting = res.data
+        this.changeTemp(0)
+      }).catch(err => {})
+    },
+    changeTemp(index) {
+      hugerte.init({
+        selector: '#editor',
+        skin_url: 'default',
+        content_css: 'default',
+        statusbar: false,
+        toolbar: false,
+        menubar: false,
+        height: '100%',
+        width: '100%'
+      }).then(editor => {
+        this.invitation_data.tempIndex = index
+        this.parseCode(this.invitation_data.data[index].content)
+      })
+    },
+    parseCode(code) {
+      const regex = /\{\{([^}]+)\}\}/g
+      code = code.replace(regex, (match, key) => {
+        const trimmedKey = key.trim()
+        if (Object.prototype.hasOwnProperty.call(this.invitation_data.exhibitorSetting, trimmedKey)) {
+          return this.invitation_data.exhibitorSetting[trimmedKey]
+        }
+        if (Object.prototype.hasOwnProperty.call(this.invitation_data.userSetting, trimmedKey)) {
+          return this.invitation_data.userSetting[trimmedKey]
+        }
+        return match
+      })
+      this.invitation_data.code = code
+      hugerte.activeEditor.setContent(code)
+    },
+    closeDialog() {
+      this.invitation_data.show = false
+      hugerte.remove('#editor')
+    },
+    sendInvitation() {
+      this.invitation_data.is_sending = true
+      const content = hugerte.activeEditor.getContent()
+      sentInvitation([this.invitation_data.userSetting.id], content).then(res => {
+        console.log(res)
+        this.closeDialog()
+        this.$message.success('发送成功')
+        this.invitation_data.is_sending = false
+      }).catch(err => {
+
+      })
+    }
+  }
 })
 </script>
 
 <template>
   <div class="main-box">
     <div class="head">
-      <el-input prefix-icon="el-icon-search" placeholder="搜索观众姓名/手机号/邮箱" class="input"></el-input>
+      <el-input v-model="searchWord" prefix-icon="el-icon-search" placeholder="搜索观众姓名/手机号/邮箱" class="input" @input="search">
+        <el-button v-if="searchWord" slot="append" icon="el-icon-delete" @click="searchWord='';search()" />
+      </el-input>
+      <el-select v-model="expo_id" class="select" placeholder="请选择参展名称" @change="search()">
+        <el-option :value="0" label="全部展会" />
+        <el-option v-for="item in expoList" :value="item.id" :label="item.expo_name" />
+      </el-select>
       <el-button icon="el-icon-plus" type="primary">添加观众</el-button>
       <el-button icon="el-icon-upload2">导入</el-button>
       <el-button icon="el-icon-download">导出</el-button>
     </div>
     <div class="body">
-      <el-table height="100%" class="table">
-        <el-table-column
-          label="姓名">
-        </el-table-column>
-        <el-table-column
-          label="手机号">
+      <el-table v-loading="loading" :data="userList" height="100%" class="table">
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <el-form class="expand-form" :inline="true" label-position="left">
+              <el-form-item label="姓名">
+                {{ props.row.full_name }}
+              </el-form-item>
+              <el-form-item label="参展名称">
+                <expo-popover placement="bottom" trigger="hover" :expo-id="''+props.row.expo_id">
+                  {{ props.row.expo_name }}
+                </expo-popover>
+              </el-form-item>
+              <el-form-item label="邮箱">
+                {{ props.row.email }}
+              </el-form-item>
+              <el-form-item label="区号">
+                {{ props.row.mobile_country_code }}
+              </el-form-item>
+              <el-form-item label="电话">
+                {{ props.row.mobile }}
+              </el-form-item>
+              <el-form-item label="国家">
+                {{ props.row.country }}
+              </el-form-item>
+              <el-form-item label="省份">
+                {{ props.row.province }}
+              </el-form-item>
+              <el-form-item label="城市">
+                {{ props.row.city }}
+              </el-form-item>
+              <el-form-item label="地址">
+                {{ props.row.address }}
+              </el-form-item>
+              <el-form-item label="公司">
+                {{ props.row.company }}
+              </el-form-item>
+              <el-form-item label="部门">
+                {{ props.row.department }}
+              </el-form-item>
+              <el-form-item label="职位">
+                {{ props.row.position }}
+              </el-form-item>
+            </el-form>
+          </template>
         </el-table-column>
         <el-table-column
-          label="邮箱"
-          width="260">
-        </el-table-column>
+          label="姓名"
+          prop="full_name"
+        />
         <el-table-column
-          label="公司"
-          width="260">
+          label="参展名称"
+          prop="expo_name"
+          width="400"
+          :show-overflow-tooltip="true"
+        >
+          <template slot-scope="props">
+            <expo-popover placement="bottom" trigger="click" :expo-id="''+props.row.expo_id">
+              <span style="cursor: pointer">{{ props.row.expo_name }}</span>
+            </expo-popover>
+          </template>
         </el-table-column>
         <el-table-column
-          label="职位">
-        </el-table-column>
+          label="邮箱"
+          prop="email"
+        />
         <el-table-column
-          label="注册时间">
-        </el-table-column>
+          label="区号"
+          width="80"
+          prop="mobile_country_code"
+        />
         <el-table-column
-          label="状态">
-        </el-table-column>
+          label="电话"
+          prop="mobile"
+        />
         <el-table-column
-          label="操作">
+          label="操作"
+          fixed="right"
+        >
+          <template slot-scope="scope">
+            <span class="button" @click="openDialog(scope.row)">发送邀请函</span>
+          </template>
         </el-table-column>
       </el-table>
     </div>
     <div class="foot">
       <el-pagination
         background
-        :page-size="100"
-        layout="total, prev, pager, next"
-        :total="1000">
-      </el-pagination>
+        :page-size="page_size"
+        layout="total"
+        :total="total"
+      />
+      <el-pagination
+        background
+        :page-size="page_size"
+        layout="prev, pager, next"
+        :total="total"
+        @current-change="current_page=$event;getAudience()"
+      />
     </div>
+    <el-dialog
+      top="10vh"
+      custom-class="invitation-dialog"
+      :append-to-body="true"
+      title="发送邀请函"
+      :visible.sync="invitation_data.show"
+      width="60%"
+      @close="closeDialog()"
+    >
+      <div class="dialog-body">
+        <div class="temp-list">
+          <div
+            v-for="(temp,index) in invitation_data.data"
+            :key="temp.id"
+            class="temp-item"
+            :class="index===invitation_data.tempIndex?'active':''"
+            @click="changeTemp(index)"
+          >
+            <img v-if="temp.pic" :src="ossUrl+temp.pic">
+          </div>
+        </div>
+        <div class="view">
+          <div id="editor" />
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDialog()">取 消</el-button>
+        <el-button :disabled="invitation_data.is_sending" type="primary" @click="sendInvitation()">
+          发 送
+          <span v-if="invitation_data.is_sending" class="el-icon-loading"></span>
+        </el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
-<style scoped>
+<style scoped lang="scss">
+  @use '@/styles/variables.scss' as *;
   .main-box{
     height: 100%;
     display: grid;
@@ -64,7 +307,11 @@ export default Vue.extend({
     .head{
       display: flex;
       .input{
-        width: 50%;
+        width: 30%;
+        margin-right: 12px;
+      }
+      .select{
+        width: 20%;
         margin-right: auto;
       }
     }
@@ -77,15 +324,60 @@ export default Vue.extend({
         position: absolute;
         top: 0;
         left: 0;
+        .button{
+          cursor: pointer;
+          padding: 0 5px;
+          color: $menuActiveText;
+          &.del{
+            color: #DC2626;
+          }
+        }
+        .expand-form{
+          display: grid;
+          grid-template-columns: 1fr 1fr 1fr;
+          .el-form-item{
+            margin: 0;
+          }
+        }
       }
     }
     .foot{
-      .el-pagination{
-        display: flex;
-        .el-pagination__total{
-          margin-right: auto;
+      display: flex;
+      justify-content: space-between;
+    }
+  }
+</style>
+<style lang="scss">
+.invitation-dialog{
+  .dialog-body{
+    height: 60vh;
+    display: grid;
+    grid-template-columns: 240px 1fr;
+    grid-gap: 12px;
+    .view{
+      width: 100%;
+      height: 100%;
+    }
+    .temp-list{
+      padding: 6px;
+      overflow: hidden;
+      overflow-y: auto;
+      width: 100%;
+      height: 100%;
+      .temp-item{
+        margin-bottom: 12px;
+        width: 100%;
+        border-radius: 6px;
+        overflow: hidden;
+        cursor: pointer;
+        &.active,&:hover{
+          box-shadow: 0 0 0 2px #FFFFFF,0 0 0 4px #409EFF ;
+        }
+        img{
+          width: 100%;
         }
       }
     }
   }
+}
 </style>

+ 197 - 0
src/views/components/expoPopover.vue

@@ -0,0 +1,197 @@
+<script lang="ts">
+import Vue from 'vue'
+import { getMyExpoInfo } from '@/api/expo'
+export default Vue.extend({
+  name: "expoPopover",
+  data() {
+    return {
+      popover_data: {},
+      ossUrl: process.env.VUE_APP_OSS_DOMAIN
+    }
+  },
+  props: {
+    expoId: String,
+    placement: String,
+    trigger: String,
+  },
+  methods: {
+    goto(url) {
+      window.open(url, '_blank')
+    },
+    getDetail(id) {
+      getMyExpoInfo(id).then(res => {
+        this.popover_data = res.data
+        this.popover_data.images = JSON.parse(res.data.images)
+        this.popover_data.social_links = JSON.parse(res.data.social_links)
+      })
+    },
+    copyUrl() {
+      let rootPath = window.location.origin
+      navigator.clipboard.writeText(rootPath+'/#/user/form/'+this.popover_data.urla)
+      this.$message.success('复制成功')
+    }
+  }
+})
+</script>
+
+<template>
+  <el-popover popper-class="popover" :trigger="trigger" :placement="placement" width="600" @show="popover_data={}" @after-enter="getDetail(expoId)">
+    <div class="expo-info">
+      <div class="cover loading">
+        <img v-if="popover_data.images" :src="ossUrl+popover_data.images[0]">
+        <div v-if="popover_data.form_template_id && popover_data.urla" @click="copyUrl()" class="button">复制表单地址</div>
+      </div>
+      <div class="info-body">
+        <div class="avatar-name">
+          <div class="avatar loading">
+            <img v-if="popover_data.logo" :src="ossUrl+popover_data.logo">
+          </div>
+          <div class="name-cont">
+            <div :class="['name',popover_data.expo_name!==undefined?'':'loading']">{{ popover_data.expo_name }}</div>
+            <div :class="['sub-name',popover_data.organizer!==undefined?'':'loading']">{{ popover_data.organizer }}</div>
+            <div class="contact">
+              <div class="phone">
+                <i class="icon el-icon-mobile-phone" />
+                <div :class="['phone-num link',popover_data.contact_phone!==undefined?'':'loading']" @click="goto('tel:'+popover_data.contact_phone)">{{ popover_data.contact_phone }}</div>
+              </div>
+              <div class="email">
+                <i class="icon el-icon-message" />
+                <div :class="['email-addr link',popover_data.contact_email!==undefined?'':'loading']" @click="goto('mailto:'+popover_data.contact_email)">{{ popover_data.contact_email }}</div>
+              </div>
+              <div class="date">
+                <i class="icon el-icon-date" />
+                <div :class="['date-range',popover_data.start_date!==undefined?'':'loading']">{{ popover_data.start_date }} - {{ popover_data.end_date }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div :class="['desc',popover_data.content!==undefined?'':'loading']">
+          {{ popover_data.content }}
+        </div>
+        <div v-if="popover_data.social_links" class="social_links">
+          <div class="social-title">社交媒体</div>
+          <div v-if="popover_data.social_links.facebook" class="social-item">
+            <span>facebook:</span><span class="link" @click="goto(popover_data.social_links.facebook)">{{ popover_data.social_links.facebook }}</span>
+          </div>
+          <div v-if="popover_data.social_links.twitter" class="social-item">
+            <span>twitter:</span><span class="link" @click="goto(popover_data.social_links.twitter)">{{ popover_data.social_links.twitter }}</span>
+          </div>
+          <div v-if="popover_data.social_links.linkedin" class="social-item">
+            <span>linkedin:</span><span class="link" @click="goto(popover_data.social_links.linkedin)">{{ popover_data.social_links.linkedin }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <span slot="reference" class="button">
+      <slot></slot>
+    </span>
+  </el-popover>
+</template>
+
+<style>
+.popover{
+  overflow: hidden;
+  padding: 0;
+  .expo-info{
+    position: relative;
+    width: 100%;
+    .link{
+      cursor: pointer;
+      text-decoration: underline;
+    }
+    .info-body{
+      padding: 16px;
+      .social_links{
+        margin-top: 12px;
+        .social-title{
+          font-weight: bold;
+        }
+        .social-item{
+
+        }
+      }
+      .desc{
+        margin-top: 12px;
+        &.loading{
+          height: 60px;
+          width: 100%;
+        }
+      }
+      .avatar-name{
+        display: flex;
+        grid-gap: 8px;
+        .name-cont{
+          flex: 1;
+          .name{
+            font-size: 20px;
+            font-weight: bold;
+            &.loading{
+              height: 26px;
+              width: 120px;
+            }
+          }
+          .sub-name{
+            color: gray;
+            &.loading{
+              margin-top: 8px;
+              margin-bottom: 8px;
+              height: 20px;
+              width: 160px;
+            }
+          }
+          .contact{
+            flex-wrap: wrap;
+            display: flex;
+            grid-gap: 0 12px;
+            .phone,.email,.date{
+              display: flex;
+              align-items: center;
+              grid-gap: 4px;
+              div{
+                &.loading{
+                  height: 16px;
+                  width: 120px;
+                }
+              }
+            }
+          }
+        }
+        .avatar{
+          width: 70px;
+          height: 70px;
+          border-radius: 50%;
+          overflow: hidden;
+          img{
+            display: block;
+            object-fit: cover;
+            width: 100%;
+            height: 100%;
+          }
+        }
+      }
+    }
+    .cover{
+      position: relative;
+      width: 100%;
+      aspect-ratio: 3/1;
+      .button{
+        cursor: pointer;
+        background: #00000044;
+        padding: 4px 12px;
+        border-radius: 24px;
+        border: 2px solid white;
+        color: white;
+        position: absolute;
+        right: 16px;
+        top: 16px;
+      }
+      img{
+        display: block;
+        object-fit: cover;
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+}
+</style>

src/views/guide/index.vue → src/views/components/guidePopover.vue


+ 17 - 155
src/views/exhibitorManage/exhibitorList.vue

@@ -1,6 +1,7 @@
 <script>
 import Vue from 'vue'
-import { getExpoList, deleteExpo, setExpoStatus, getMyExpoInfo } from '@/api/expo'
+import expoPopover from '@/views/components/expoPopover.vue'
+import { getExpoList, deleteExpo, setExpoStatus } from '@/api/expo'
 export default Vue.extend({
   name: 'Index',
   data() {
@@ -17,23 +18,19 @@ export default Vue.extend({
       ossUrl: process.env.VUE_APP_OSS_DOMAIN
     }
   },
+  components: {
+    expoPopover
+  },
   mounted() {
     this.getList()
   },
   methods: {
-    getDetail(row) {
-      getMyExpoInfo(row.id).then(res => {
-        this.popover_data = res.data
-        this.popover_data.images = JSON.parse(res.data.images)
-        this.popover_data.social_links = JSON.parse(res.data.social_links)
-      })
-    },
     search(event) {
       if (this.searchTimer) {
         clearTimeout(this.searchTimer)
       }
       this.searchTimer = setTimeout(() => {
-        this.current_page = 0
+        this.current_page = 1
         this.getList()
       }, 500)
     },
@@ -86,7 +83,7 @@ export default Vue.extend({
     getList() {
       if (this.loading || this.current_page >= this.last_page) return
       this.loading = true
-      getExpoList(++this.current_page, this.page_size, this.searchWord).then(res => {
+      getExpoList(this.current_page, this.page_size, this.searchWord).then(res => {
         console.log(res)
         this.current_page = res.data.current_page
         this.last_page = res.data.last_page
@@ -97,9 +94,6 @@ export default Vue.extend({
     },
     add() {
       this.$router.push({ path: '/exhibitor/add' })
-    },
-    goto(url) {
-      window.open(url, '_blank')
     }
   }
 })
@@ -133,6 +127,12 @@ export default Vue.extend({
             </div>
           </template>
         </el-table-column>
+        <<el-table-column
+          label="预约观众"
+          width="80"
+          prop="form_count"
+        >
+        </el-table-column>
         <el-table-column
           label="展会地点"
           prop="location"
@@ -176,54 +176,9 @@ export default Vue.extend({
           width="200"
         >
           <template slot-scope="scope">
-            <el-popover popper-class="popover" trigger="click" placement="left" width="600" @show="popover_data={}" @after-enter="getDetail(scope.row)">
-              <div class="expo-info">
-                <div class="cover loading">
-                  <img v-if="popover_data.images" :src="ossUrl+popover_data.images[0]">
-                </div>
-                <div class="info-body">
-                  <div class="avatar-name">
-                    <div class="avatar loading">
-                      <img v-if="popover_data.logo" :src="ossUrl+popover_data.logo">
-                    </div>
-                    <div class="name-cont">
-                      <div :class="['name',popover_data.expo_name!==undefined?'':'loading']">{{ popover_data.expo_name }}</div>
-                      <div :class="['sub-name',popover_data.organizer!==undefined?'':'loading']">{{ popover_data.organizer }}</div>
-                      <div class="contact">
-                        <div class="phone">
-                          <i class="icon el-icon-mobile-phone" />
-                          <div :class="['phone-num link',popover_data.contact_phone!==undefined?'':'loading']" @click="goto('tel:'+popover_data.contact_phone)">{{ popover_data.contact_phone }}</div>
-                        </div>
-                        <div class="email">
-                          <i class="icon el-icon-message" />
-                          <div :class="['email-addr link',popover_data.contact_email!==undefined?'':'loading']" @click="goto('mailto:'+popover_data.contact_email)">{{ popover_data.contact_email }}</div>
-                        </div>
-                        <div class="date">
-                          <i class="icon el-icon-date" />
-                          <div :class="['date-range',popover_data.start_date!==undefined?'':'loading']">{{ popover_data.start_date }} - {{ popover_data.end_date }}</div>
-                        </div>
-                      </div>
-                    </div>
-                  </div>
-                  <div :class="['desc',popover_data.content!==undefined?'':'loading']">
-                    {{ popover_data.content }}
-                  </div>
-                  <div v-if="popover_data.social_links" class="social_links">
-                    <div class="social-title">社交媒体</div>
-                    <div v-if="popover_data.social_links.facebook" class="social-item">
-                      <span>facebook:</span><span class="link" @click="goto(popover_data.social_links.facebook)">{{ popover_data.social_links.facebook }}</span>
-                    </div>
-                    <div v-if="popover_data.social_links.twitter" class="social-item">
-                      <span>twitter:</span><span class="link" @click="goto(popover_data.social_links.twitter)">{{ popover_data.social_links.twitter }}</span>
-                    </div>
-                    <div v-if="popover_data.social_links.linkedin" class="social-item">
-                      <span>linkedin:</span><span class="link" @click="goto(popover_data.social_links.linkedin)">{{ popover_data.social_links.linkedin }}</span>
-                    </div>
-                  </div>
-                </div>
-              </div>
-              <span slot="reference" class="button">预览</span>
-            </el-popover>
+            <expo-popover placement="left" trigger="click" :expo-id="''+scope.row.id">
+              <span class="button">预览</span>
+            </expo-popover>
             <span class="button" @click="edit(scope.row)">编辑</span>
             <span class="button" @click="setStatus(scope.row)">{{scope.row.status?'启用':'禁用'}}</span>
             <span class="button del" @click="del(scope.row)">删除</span>
@@ -239,6 +194,7 @@ export default Vue.extend({
         :total="total"
       />
       <el-pagination
+        @current-change="current_page=$event;getList()"
         background
         :page-size="page_size"
         layout="prev, pager, next"
@@ -300,97 +256,3 @@ export default Vue.extend({
     }
   }
 </style>
-<style lang="scss">
-  .popover{
-    padding: 0;
-    .expo-info{
-      position: relative;
-      width: 100%;
-      .link{
-        cursor: pointer;
-        text-decoration: underline;
-      }
-      .info-body{
-        padding: 16px;
-        .social_links{
-          margin-top: 12px;
-          .social-title{
-            font-weight: bold;
-          }
-          .social-item{
-
-          }
-        }
-        .desc{
-          margin-top: 12px;
-          &.loading{
-            height: 60px;
-            width: 100%;
-          }
-        }
-        .avatar-name{
-          display: flex;
-          grid-gap: 8px;
-          .name-cont{
-            flex: 1;
-            .name{
-              font-size: 20px;
-              font-weight: bold;
-              &.loading{
-                height: 26px;
-                width: 120px;
-              }
-            }
-            .sub-name{
-              color: gray;
-              &.loading{
-                margin-top: 8px;
-                margin-bottom: 8px;
-                height: 20px;
-                width: 160px;
-              }
-            }
-            .contact{
-              flex-wrap: wrap;
-              display: flex;
-              grid-gap: 0 12px;
-              .phone,.email,.date{
-                display: flex;
-                align-items: center;
-                grid-gap: 4px;
-                div{
-                  &.loading{
-                    height: 16px;
-                    width: 120px;
-                  }
-                }
-              }
-            }
-          }
-          .avatar{
-            width: 70px;
-            height: 70px;
-            border-radius: 50%;
-            overflow: hidden;
-            img{
-              display: block;
-              object-fit: cover;
-              width: 100%;
-              height: 100%;
-            }
-          }
-        }
-      }
-      .cover{
-        width: 100%;
-        aspect-ratio: 3/1;
-        img{
-          display: block;
-          object-fit: cover;
-          width: 100%;
-          height: 100%;
-        }
-      }
-    }
-  }
-</style>

+ 16 - 1
src/views/exhibitorManage/exhibitorSetting.vue

@@ -1,6 +1,7 @@
 <script>
 import Vue from 'vue'
 import { saveExpo, getMyExpoInfo } from '@/api/expo'
+import { getFormList } from '@/api/form'
 import { upload } from '@/api/system'
 export default Vue.extend({
   name: 'ExhibitorSetting',
@@ -24,12 +25,12 @@ export default Vue.extend({
           linkedin: ''
         },
         form_template_id: '',
-        page_template_id: '',
         urla: '',
         seo_title: '',
         seo_description: '',
         seo_keywords: ''
       },
+      formList: [],
       loading: false,
       ossUrl: process.env.VUE_APP_OSS_DOMAIN
     }
@@ -52,6 +53,11 @@ export default Vue.extend({
           this.loading = false
           console.log(err)
         })
+        getFormList(1, 1000).then(res => {
+          this.formList = res.data.data
+        }).catch(err => {
+          console.log(err)
+        })
       }
     },
     uploadImage(event, type) {
@@ -192,6 +198,12 @@ export default Vue.extend({
           </div>
         </div>
         <div class="form-item required">
+          <div class="label">表单模板</div>
+          <el-select v-model="exhibitorSetting.form_template_id">
+            <el-option v-for="item in formList" :key="item.id" :value="item.id" :label="item.template_name"></el-option>
+          </el-select>
+        </div>
+        <div class="form-item required">
           <div class="label">url短名称</div>
           <el-input v-model="exhibitorSetting.urla" class="input" placeholder="请输入url" />
         </div>
@@ -273,6 +285,9 @@ export default Vue.extend({
       }
       .form-item{
         margin: 16px 0;
+        .el-select{
+          width: 100%;
+        }
         .label{
           margin-bottom: 8px;
         }

+ 2 - 2
src/views/invitationManage/edit.vue

@@ -274,7 +274,7 @@ export default Vue.extend({
       </div>
 
       <el-popover
-        popper-class="popover"
+        popper-class="invitation-popover"
         placement="left-start"
         width="500"
         trigger="click"
@@ -365,7 +365,7 @@ export default Vue.extend({
 }
 </style>
 <style>
-.popover{
+.invitation-popover{
   .body{
     display: flex;
     flex-direction: column;

+ 2 - 1
src/views/invitationManage/list.vue

@@ -21,7 +21,7 @@ export default Vue.extend({
     getList() {
       if (this.loading) return
       this.loading = true
-      getTemplateList(++this.current_page, this.page_size).then(res => {
+      getTemplateList(this.current_page, this.page_size).then(res => {
         this.tempList = res.data.data
         this.total = res.data.total
       }).then(res => {
@@ -72,6 +72,7 @@ export default Vue.extend({
       />
       <el-pagination
         background
+        @current-change="current_page=$event;getList()"
         :page-size="page_size"
         layout="prev, pager, next"
         :total="total"

+ 1 - 1
src/views/preRegManage/edit.vue

@@ -1,7 +1,7 @@
 <script lang="ts">
 import Vue from 'vue'
 import { saveForm, getFormInfo } from '@/api/form'
-import guide from '@/views/guide/index'
+import guide from '@/views/components/guidePopover.vue'
 import draggable from 'vuedraggable'
 import countryCode from '@/lib/countryCode.json'
 

+ 1 - 1
src/views/preRegManage/editBack.vue

@@ -1,7 +1,7 @@
 <script lang="ts">
 import Vue from 'vue'
 import { saveForm, getFormInfo } from '@/api/form'
-import guide from '@/views/guide/index'
+import guide from '@/views/components/guidePopover.vue'
 import draggable from 'vuedraggable'
 import countryCode from '@/lib/countryCode.json'
 import {

+ 3 - 2
src/views/preRegManage/list.vue

@@ -27,7 +27,7 @@ export default Vue.extend({
         clearTimeout(this.searchTimer)
       }
       this.searchTimer = setTimeout(() => {
-        this.current_page = 0
+        this.current_page = 1
         this.getList()
       }, 500)
     },
@@ -74,7 +74,7 @@ export default Vue.extend({
     getList() {
       if (this.loading || this.current_page >= this.last_page) return
       this.loading = true
-      getFormList(++this.current_page, this.page_size, this.searchWord).then(res => {
+      getFormList(this.current_page, this.page_size, this.searchWord).then(res => {
         this.current_page = res.data.current_page
         this.last_page = res.data.last_page
         this.total = res.data.total
@@ -149,6 +149,7 @@ export default Vue.extend({
       />
       <el-pagination
         background
+        @current-change="current_page=$event;getList()"
         :page-size="page_size"
         layout="prev, pager, next"
         :total="total"

+ 1 - 1
src/views/setting/systemSetting.vue

@@ -34,7 +34,7 @@ export default Vue.extend({
         return
       }
       this.loading = true
-      saveMailSetting(this.mailSetting.id,this.mailSetting.from_name,this.mailSetting.from_email,this.mailSetting.auth_code,this.mailSetting.smtp_server,this.mailSetting.smtp_port,this.mailSetting.is_ssl).then(res => {
+      saveMailSetting(this.mailSetting.id,this.mailSetting.from_name,this.mailSetting.from_email,this.mailSetting.smtp_port,this.mailSetting.smtp_server,this.mailSetting.auth_code,this.mailSetting.is_ssl).then(res => {
         this.loading = false
         this.init()
       })

+ 206 - 14
src/views/user/form.vue

@@ -1,12 +1,28 @@
 <script lang="ts">
 import Vue from 'vue'
-import { getFormInfo } from '@/api/form'
+import { getFormInfo, submitForm, getLocationList, getJobList } from '@/api/form'
+import { getExpoInfo } from '@/api/expo'
+import countryCode from '@/lib/countryCode.json'
+import login from '@/views/login/index.vue'
 export default Vue.extend({
   name: 'Index',
   data() {
     return {
       from_data: [],
-      form_id: ''
+      expo_key: '',
+      expo_id: '',
+      countryCode,
+      locationList: [],
+      locationPage: 0,
+      locationTotal: 1,
+      provinceL: [],
+      cityL: [],
+      jobList: [],
+      jobPage: 0,
+      jobTotal: 1,
+      jobL: [],
+      loading: false,
+      isOk: false
     }
   },
   computed: {
@@ -18,10 +34,11 @@ export default Vue.extend({
   },
   methods: {
     init() {
+      this.expo_key = this.$route.params.url
       if (this.token) {
-        this.form_id = this.$route.query.id
-        getFormInfo(this.form_id).then(res => {
+        getExpoInfo(this.expo_key).then(res => {
           this.from_data = res.data
+          this.expo_id = res.data.id
         }).catch(err => {
           console.log('err')
         })
@@ -29,12 +46,60 @@ export default Vue.extend({
         this.$router.push({
           name: 'userRegister',
           query: {
-            form_id: this.$route.query.id,
-            expo_key: this.$route.query.expo
+            expo_key: this.expo_key
           }
         })
       }
     },
+    getJob() {
+      if (this.loading || this.jobPage >= this.jobTotal) {
+        return
+      }
+      this.loading = true
+      getJobList(++this.jobPage, 10).then(res => {
+        this.jobList = this.jobList.concat(res.data.data)
+        this.jobTotal = res.data.last_page
+        this.jobPage = res.data.current_page
+        this.loading = false
+      }).catch(err => {
+        this.loading = false
+      })
+    },
+    getLocation() {
+      if (this.loading || this.locationPage >= this.locationTotal) {
+        return
+      }
+      this.loading = true
+      getLocationList(++this.locationPage, 10).then(res => {
+        this.locationList = this.locationList.concat(res.data.data)
+        this.locationTotal = res.data.last_page
+        this.locationPage = res.data.current_page
+        this.loading = false
+      }).catch(err => {
+        this.loading = false
+      })
+    },
+    submit() {
+      if(this.loading) {
+        return
+      }
+      this.loading = true
+      let form_data = {}
+      for (let i = 0; i < this.from_data.form_fields.length; i++) {
+        form_data[this.from_data.form_fields[i].field_name] = this.from_data.form_fields[i].value
+        if (this.from_data.form_fields[i].is_required && !this.from_data.form_fields[i].value) {
+          this.$message.error('请填写必填项')
+          this.loading = false
+          return
+        }
+      }
+      submitForm(this.expo_id, form_data).then(res => {
+        this.isOk = true
+        this.loading = false
+      }).catch(err => {
+        this.loading = false
+      })
+    },
     returnWidth(name) {
       if (['email', 'address'].includes(name)) {
         return 6
@@ -55,21 +120,112 @@ export default Vue.extend({
   <div class="body">
     <div class="head">
       <div class="form-name">
-        {{ from_data.template_name }}
+        {{ from_data.expo_name }}
       </div>
     </div>
     <div class="form">
       <div class="desc">
-        {{ from_data.description }}
+        {{ from_data.content }}
+      </div>
+      <div v-if="isOk" class="form-body ok">
+        <div class="icon el-icon-success"></div>
+        <div class="text">表单提交完成</div>
       </div>
-      <div class="form-body">
-        <div v-for="item in from_data.fields" :key="item.id" :style="{gridColumn:'span '+returnWidth(item.field_name)}" class="form-item">
-          <div class="label" :class="item.required?'required':''">{{ item.field_label }}</div>
-          <el-input v-model="item.value"></el-input>
+      <div v-else class="form-body">
+        <div v-for="item in from_data.form_fields" :key="item.id" :style="{gridColumn:'span '+returnWidth(item.field_name)}" class="form-item">
+          <div class="label" :class="item.is_required?'required':''">{{ item.field_label }}</div>
+          <el-select v-if="item.field_name==='id_type'" v-model="item.value">
+            <el-option value="Passport" label="护照" />
+            <el-option value="ID Card" label="身份证" />
+          </el-select>
+          <el-select v-else-if="item.field_name==='mobile_country_code'" v-model="item.value" filterable>
+            <el-option v-for="(code,index) in countryCode" :key="code.country_code+index" :label="'+'+code.phone_code+'('+code.chinese_name+')'" :value="code.phone_code" />
+          </el-select>
+          <el-popover
+            v-else-if="item.field_name==='country'"
+            placement="bottom"
+            width="260"
+            popper-class="popover"
+            trigger="click"
+            @show="if(locationList.length===0){getLocation()}"
+          >
+            <div class="cont">
+              <div v-for="loca in locationList" :key="loca.id" class="item" @click="item.value=loca.name;from_data.form_fields.push();provinceL=loca.child">
+                {{ loca.name }}
+              </div>
+              <div v-if="locationPage < locationTotal" class="item" @click="getLocation()">加载更多</div>
+            </div>
+            <el-input slot="reference" :value="item.value" />
+          </el-popover>
+          <el-popover
+            v-else-if="item.field_name==='province'"
+            placement="bottom"
+            width="260"
+            popper-class="popover"
+            trigger="click"
+          >
+            <div class="cont">
+              <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}]}">
+                {{ loca.name }}
+              </div>
+              <div v-if="provinceL.length===0" class="item">请先选择国家</div>
+            </div>
+            <el-input slot="reference" :value="item.value" />
+          </el-popover>
+          <el-popover
+            v-else-if="item.field_name==='city'"
+            placement="bottom"
+            width="260"
+            popper-class="popover"
+            trigger="click"
+          >
+            <div class="cont">
+              <div v-for="loca in cityL" :key="loca.id" class="item" @click="item.value=loca.name;from_data.form_fields.push()">
+                {{ loca.name }}
+              </div>
+              <div v-if="cityL.length===0" class="item">请先选择省份</div>
+            </div>
+            <el-input slot="reference" :value="item.value" />
+          </el-popover>
+          <el-popover
+            v-else-if="item.field_name==='department'"
+            placement="bottom"
+            width="260"
+            popper-class="popover"
+            trigger="click"
+            @show="if(jobList.length===0){getJob()}"
+          >
+            <div class="cont">
+              <div v-for="job in jobList" :key="job.id" class="item" @click="item.value=job.name;from_data.form_fields.push();jobL=job.child">
+                {{ job.name }}
+              </div>
+              <div v-if="jobPage < jobTotal" class="item" @click="getJob()">加载更多</div>
+            </div>
+            <el-input slot="reference" :value="item.value" />
+          </el-popover>
+          <el-popover
+            v-else-if="item.field_name==='position'"
+            placement="bottom"
+            width="260"
+            popper-class="popover"
+            trigger="click"
+          >
+            <div class="cont">
+              <div v-for="job in jobL" :key="job.id" class="item" @click="item.value=job.name;from_data.form_fields.push()">
+                {{ job.name }}
+              </div>
+              <div v-if="jobL.length===0" class="item">请先选择部门</div>
+            </div>
+            <el-input slot="reference" :value="item.value" />
+          </el-popover>
+          <el-input v-else v-model="item.value" />
         </div>
       </div>
-      <div class="button">
-        <el-button type="primary">提交表单</el-button>
+      <div v-if="!isOk" class="button">
+        <el-button :disabled="loading" type="primary" @click="submit()">
+          提交表单
+          <span v-if="loading" class="el-icon-loading"></span>
+        </el-button>
       </div>
     </div>
   </div>
@@ -99,11 +255,31 @@ export default Vue.extend({
       display: grid;
       grid-template-columns: repeat(6, 1fr);
       grid-gap: 8px;
+      &.ok{
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 120px 0;
+        .icon{
+          color: #67C23A;
+          font-size: 86px;
+        }
+        .text{
+          margin-top: 24px;
+        }
+      }
       .form-item{
         .label{
           font-size: 15px;
           color: gray;
           margin-bottom: 8px;
+          &.required{
+            &::after{
+              content: '*';
+              color: red;
+            }
+          }
         }
       }
     }
@@ -124,5 +300,21 @@ export default Vue.extend({
 <style>
 body{
   background: #F9FAFB;
+  .popover{
+    overflow: hidden;
+    padding: 0;
+    .cont{
+      padding: 8px 0;
+      max-height: 220px;
+      overflow: auto;
+      .item{
+        cursor: pointer;
+        padding: 8px 16px;
+        &:hover{
+          background: #F5F7FA;
+        }
+      }
+    }
+  }
 }
 </style>

+ 191 - 25
src/views/user/register.vue

@@ -1,7 +1,8 @@
 <script lang="ts">
 import Vue from 'vue'
 import countryCode from '@/lib/countryCode.json'
-import { sendSmsCode, sentEmailCode, register } from '@/api/user'
+import { sendSmsCode, sentEmailCode, register, confirmEmail } from '@/api/user'
+import { getExpoInfo } from '@/api/expo'
 export default Vue.extend({
   name: 'Index',
   data() {
@@ -11,23 +12,48 @@ export default Vue.extend({
       loginInfo: {
         phone: '',
         countryCode: '86',
+        password: '',
+        password_2: '',
         smsCode: '',
         email: '',
-        emailCode: ''
+        emailCode: '',
+        pre_register_key: '',
+        showPasswordDialog: false,
       },
       emailCounter: 0,
       emailTimer: null,
       smsCounter: 0,
-      smsTimer: null
+      smsTimer: null,
+      expoData: {},
+      expo_key: '',
+      subTimer: '',
+      subTime: '',
+      isLogin: false
     }
   },
   computed: {
     user() { return this.$store.state.user.user }
   },
   mounted() {
-
+    this.init()
+  },
+  beforeDestroy() {
+    clearInterval(this.subTimer)
   },
   methods: {
+    init() {
+      if (this.$route.query.expo_key) {
+        this.expo_key = this.$route.query.expo_key
+        getExpoInfo(this.expo_key).then(res => {
+          this.expoData = res.data
+          this.subTimer = setInterval(() => {
+            this.subTime = Date.parse(res.data.end_date) - Date.now()
+          }, 1000)
+        }).catch(err => {
+
+        })
+      }
+    },
     sentSms() {
       if (this.loginInfo.phone === '') {
         this.$message.error('请填写电话号码!')
@@ -72,20 +98,86 @@ export default Vue.extend({
         })
       }
     },
-    register() {
+    submitLogin() {
+      let username = ''
+      let password = ''
       if (this.regWay) {
-        register(this.loginInfo.email,'',this.loginInfo.emailCode,1,'').then(res=>{
+        if (this.loginInfo.email === '' || this.loginInfo.password === '') {
+          this.$message.error('请填写账号与密码!')
+          return
+        }
+        username = this.loginInfo.email
+        password = this.loginInfo.password
+      } else {
+        if (this.loginInfo.smsCode === '' || this.loginInfo.phone === '') {
+          this.$message.error('请填写手机号码与验证码!')
+          return
+        }
+        username = this.loginInfo.phone
+        password = this.loginInfo.smsCode
+      }
+      this.$store.dispatch('login', {
+        username: username,
+        password: password,
+        phone: username,
+        vaild_code: password,
+        login_type: this.regWay ? '0' : '1',
+        login_portal: 0
+      }).then(res => {
+        console.log(res)
+        this.gotoForm()
+      }).catch(err => {
 
-        }).catch(err=>{
+      })
+    },
+    gotoForm() {
+      if (this.expo_key) {
+        this.$router.push({
+          name: 'userForm',
+          params: {
+            url: this.expo_key
+          }
+        })
+      }
+    },
+    register() {
+      if (this.regWay) {
+        if (this.loginInfo.email === '' || this.loginInfo.emailCode === '') {
+          this.$message.error('请填写邮箱与验证码!')
+          return
+        }
+        register(this.loginInfo.email, '', this.loginInfo.emailCode, 1, '').then(res => {
+          this.loginInfo.pre_register_key = res.data.pre_register_key
+          this.loginInfo.showPasswordDialog = true
+          console.log(res)
+        }).catch(err => {
 
         })
       } else {
-        register('',this.loginInfo.phone,this.loginInfo.smsCode,0,this.loginInfo.countryCode).then(res=>{
-
-        }).catch(err=>{
+        if (this.loginInfo.phone === '' || this.loginInfo.smsCode === '') {
+          this.$message.error('请填写手机号码与验证码!')
+          return
+        }
+        register('', this.loginInfo.phone, this.loginInfo.smsCode, 0, this.loginInfo.countryCode).then(res => {
+          this.isLogin = true
+          this.$message.success('注册成功!请前往登录')
+        }).catch(err => {
 
         })
       }
+    },
+    checkPassword() {
+      if (this.loginInfo.password !== this.loginInfo.password_2) {
+        this.$message.error('两次密码输入不一致!')
+        return false
+      }
+      this.loginInfo.showPasswordDialog = false
+      confirmEmail(this.loginInfo.pre_register_key, this.loginInfo.password, this.loginInfo.password_2).then(res => {
+        this.isLogin = true
+        this.$message.success('注册成功!请前往登录')
+      }).catch(err=>{
+
+      })
     }
   }
 })
@@ -94,45 +186,92 @@ export default Vue.extend({
   <div class="body">
     <div class="head">
       <div class="title">
-        注册账号
+        {{ isLogin?'登录账号':'注册账号' }}
       </div>
       <div class="desc">
-        中国大陆观众建议使用手机号码进行注册登录。如无法接收验证短信可点击下方微信
+        中国大陆观众建议使用手机号码进行注册登录。
       </div>
     </div>
-    <div class="time-counter">
+    <div v-if="expo_key" class="time-counter">
       <div class="title">距离展览开幕时间</div>
       <div class="counter-list">
         <div class="counter-item">
-          <div class="num">73</div>
+          <div class="num">{{ new Date(subTime).getDate() || '0' }}</div>
           <div class="unit">天</div>
         </div>
         <div class="counter-item">
-          <div class="num">73</div>
-          <div class="unit"></div>
+          <div class="num">{{ new Date(subTime).getHours() || '0' }}</div>
+          <div class="unit"></div>
         </div>
         <div class="counter-item">
-          <div class="num">73</div>
-          <div class="unit"></div>
+          <div class="num">{{ new Date(subTime).getMinutes() || '0' }}</div>
+          <div class="unit"></div>
         </div>
         <div class="counter-item">
-          <div class="num">73</div>
-          <div class="unit">天</div>
+          <div class="num">{{ new Date(subTime).getSeconds() || '0' }}</div>
+          <div class="unit">秒</div>
+        </div>
+      </div>
+    </div>
+    <div v-if="isLogin" class="register-body">
+      <div class="tab">
+        <div class="tab-item" :class="regWay?'':'active'" @click="regWay=0">验证码登录</div>
+        <div class="tab-item" :class="regWay?'active':''" @click="regWay=1">账号密码登录</div>
+      </div>
+      <template v-if="regWay">
+        <div class="form-item">
+          <div class="label">账号</div>
+          <el-input v-model="loginInfo.email" placeholder="请输入账号" />
+        </div>
+        <div class="form-item">
+          <div class="label">密码</div>
+          <div class="sms-cont">
+            <el-input show-password v-model="loginInfo.password" placeholder="请输入密码" />
+          </div>
+        </div>
+      </template>
+      <template v-else>
+        <div class="form-item">
+          <div class="label">
+            国家/地区
+          </div>
+          <el-select v-model="loginInfo.countryCode" placeholder="请选择国家/地区">
+            <el-option v-for="(item,index) in countryCode" :key="item.country_code+index" :label="'+'+item.phone_code+'('+item.chinese_name+')'" :value="item.phone_code" />
+          </el-select>
+        </div>
+        <div class="form-item">
+          <div class="label">手机号码</div>
+          <el-input v-model="loginInfo.phone" placeholder="请输入手机号码" />
         </div>
+        <div class="form-item">
+          <div class="label">验证码</div>
+          <div class="sms-cont">
+            <el-input v-model="loginInfo.smsCode" placeholder="请输入验证码" />
+            <el-button :disabled="!!smsTimer" type="primary" @click="sentSms()">{{ smsTimer?smsCounter+'秒后重新获取':'获取验证码' }}</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="piracy">
+        登录即表示同意
+        <span>《隐私政策》</span>
+        、
+        <span>《用户协议》</span>
       </div>
+      <el-button type="primary" @click="submitLogin()">登录</el-button>
+      <el-button type="text" @click="isLogin=false">没有账号?去注册。</el-button>
     </div>
-    <div class="register-body">
+    <div v-else class="register-body">
       <div class="tab">
         <div class="tab-item" :class="regWay?'':'active'" @click="regWay=0">手机注册</div>
         <div class="tab-item" :class="regWay?'active':''" @click="regWay=1">邮箱注册</div>
       </div>
       <template v-if="regWay">
         <div class="form-item">
-          <div class="label">电子邮箱</div>
-          <el-input v-model="loginInfo.email" placeholder="去输入电子邮箱地址" />
+          <div class="label">账号</div>
+          <el-input v-model="loginInfo.email" placeholder="输入电子邮箱地址" />
         </div>
         <div class="form-item">
-          <div class="label">验证码</div>
+          <div class="label">码</div>
           <div class="sms-cont">
             <el-input v-model="loginInfo.emailCode" placeholder="请输入验证码" />
             <el-button :disabled="emailTimer" type="primary" @click="sentEmail()">{{ emailTimer?emailCounter+'秒后重新获取':'获取验证码' }}</el-button>
@@ -156,7 +295,7 @@ export default Vue.extend({
           <div class="label">验证码</div>
           <div class="sms-cont">
             <el-input v-model="loginInfo.smsCode" placeholder="请输入验证码" />
-            <el-button :disabled="smsTimer" type="primary" @click="sentSms()">{{ smsTimer?smsCounter+'秒后重新获取':'获取验证码' }}</el-button>
+            <el-button :disabled="!!smsTimer" type="primary" @click="sentSms()">{{ smsTimer?smsCounter+'秒后重新获取':'获取验证码' }}</el-button>
           </div>
         </div>
       </template>
@@ -167,7 +306,27 @@ export default Vue.extend({
         <span>《用户协议》</span>
       </div>
       <el-button type="primary" @click="register()">注册</el-button>
+      <el-button type="text" @click="isLogin=true">已有账号?去登陆。</el-button>
+    </div>
+    <el-dialog
+      title="设置初始密码"
+      custom-class="password-dialog"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="false"
+      :visible.sync="loginInfo.showPasswordDialog"
+      width="30%"
+    >
+    <div class="dialog-body">
+      <div class="label">请设置密码</div>
+      <el-input placeholder="请设置密码" show-password v-model="loginInfo.password"></el-input>
+      <div class="label">请再次输入密码</div>
+      <el-input placeholder="请再次输入密码" show-password v-model="loginInfo.password_2"></el-input>
     </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="checkPassword()" type="primary">确 定</el-button>
+    </span>
+    </el-dialog>
   </div>
 </template>
 <style scoped lang="scss">
@@ -269,5 +428,12 @@ export default Vue.extend({
 <style>
 body{
   background: #F9FAFB;
+  .password-dialog{
+    .dialog-body{
+      .label{
+        margin: 6px 0;
+      }
+    }
+  }
 }
 </style>