From f56e474c81bb25845b46cf99c85bd313dbfcd3b5 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期六, 31 一月 2026 19:26:25 +0800
Subject: [PATCH] 项目初始化+首页+公告详情页面

---
 src/views/login/index.vue |  201 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 201 insertions(+), 0 deletions(-)

diff --git a/src/views/login/index.vue b/src/views/login/index.vue
new file mode 100644
index 0000000..aad58df
--- /dev/null
+++ b/src/views/login/index.vue
@@ -0,0 +1,201 @@
+<template>
+  <el-dialog
+    v-model="loginDialogVisible"
+    width="500"
+    align-center
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+  >
+    <div class="px-4">
+      <el-row justify="center">
+        <el-text class="text-2xl font-bold">{{ title }}</el-text>
+      </el-row>
+      <el-form v-if="loginType == 'mobile'" ref="accountForm" :model="form" :rules="rules" class="pt-6 pb-3">
+        <el-form-item prop="mobile">
+          <el-input v-model="form.mobile" placeholder="璇疯緭鍏ユ墜鏈哄彿" />
+        </el-form-item>
+        <el-form-item prop="code" class="mb-2">
+          <el-input v-model="form.code" placeholder="璇疯緭鍏ラ獙璇佺爜">
+            <template #append>
+              <el-row style="width: 70px;justify-content: center;">
+                <el-button 
+                  v-if="countdown == 180"
+                  style="color: var(--el-color-primary);"
+                  class="cursor-p" 
+                  :loading="sendCodeLoading"
+                  @click="sendCode()"
+                >
+                  鑾峰彇楠岃瘉鐮�
+                </el-button>
+                <el-text v-else>{{ countdown }}s</el-text>
+              </el-row>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="agreement" style="height: 30px;">
+          <el-checkbox v-model="form.agreement" label="鍚屾剰xxx鏈嶅姟鍗忚" size="large" />
+        </el-form-item>
+
+        <el-button class="mt-1" @click="submitLogin()" type="primary" size="large" style="width: 100%;">
+          <el-text class="text-lg text-white">鐧诲綍</el-text>
+        </el-button>
+      </el-form>
+
+      <el-row v-else-if="loginType == 'qrCode'" justify="center" class="mt-7">
+        <el-image style="width: 200px;" :src="$getImageUrl('/qrCode.png')"></el-image>
+      </el-row>
+
+      <el-form v-else-if="loginType == 'register'" ref="registerForm" :model="form" :rules="rules" class="pt-6 pb-3">
+        <el-form-item prop="name" class="mb-2">
+          <el-input v-model="form.name" placeholder="璇疯緭鍏ュ鍚�" />
+        </el-form-item>
+        <el-form-item prop="sex" style="height: 20px;">
+          <el-radio-group v-model="form.sex">
+            <el-radio :value="1">鐢�</el-radio>
+            <el-radio :value="0">濂�</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item prop="idCard">
+          <el-input v-model="form.idCard" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" />
+        </el-form-item>
+        <el-form-item prop="mobile">
+          <el-input v-model="form.mobile" placeholder="璇疯緭鍏ユ墜鏈哄彿" />
+        </el-form-item>
+        <el-form-item prop="code" class="mb-2">
+          <el-input v-model="form.code" placeholder="璇疯緭鍏ラ獙璇佺爜">
+            <template #append>
+              <el-row style="width: 70px;justify-content: center;">
+                <el-button 
+                  v-if="countdown == 180"
+                  style="color: var(--el-color-primary);"
+                  class="cursor-p" 
+                  :loading="sendCodeLoading"
+                  @click="sendCode()"
+                >
+                  鑾峰彇楠岃瘉鐮�
+                </el-button>
+                <el-text v-else>{{ countdown }}s</el-text>
+              </el-row>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="agreement" style="height: 30px;">
+          <el-checkbox v-model="form.agreement" label="鍚屾剰xxx鏈嶅姟鍗忚" size="large" />
+        </el-form-item>
+
+        <el-button class="mt-1" @click="submitRegister()" type="primary" size="large" style="width: 100%;">
+          <el-text class="text-lg text-white">娉ㄥ唽</el-text>
+        </el-button>
+      </el-form>
+      
+      <el-row class="mt-7" justify="center">
+        <el-button v-if="loginType!='register'" text type="primary" @click="changeLoginType('register')">娉ㄥ唽璐﹀彿</el-button>
+        <el-divider v-if="loginType!='register'" direction="vertical" class="m-0 mt-1 mx-4" style="height: 24px !important" />
+        <el-button v-if="loginType!='qrCode'" text type="primary" @click="changeLoginType('qrCode')">浜岀淮鐮佺櫥褰�</el-button>
+        <el-divider v-if="loginType=='register'" direction="vertical" class="m-0 mt-1 mx-4" style="height: 24px !important" />
+        <el-button v-if="loginType!='mobile'" text type="primary" @click="changeLoginType('mobile')">鎵嬫満鍙风櫥褰�</el-button>
+      </el-row>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { useLoginStore } from '@/stores/login.js'
+import { storeToRefs } from 'pinia';
+export default {
+  components: {},
+  setup() {
+    const { loginDialogVisible } = storeToRefs(useLoginStore())
+    return { loginDialogVisible }
+  },
+  data() {
+    return {
+      loginType: 'mobile', // mobile銆乹rCode
+      form: {
+        name: '',
+        sex: 1,
+        idCard: '',
+        mobile: '13537719675',
+        code: '',
+        agreement: false
+      },
+      rules: {
+        name: [ this.$rules.required('璇疯緭鍏ュ鍚�') ],
+        idCard: [ this.$rules.required('璇疯緭鍏ヨ韩浠借瘉鍙�') ],
+        mobile: [ this.$rules.required('璇疯緭鍏ユ墜鏈哄彿'), this.$rules.phone() ],
+        code: [ this.$rules.required('璇峰~鍐欓獙璇佺爜'), this.$rules.code() ],
+        agreement: [ this.$rules.checkbox('璇烽槄璇诲苟鍕鹃�夊悓鎰忓崗璁�') ]
+      },
+      countdown: 180,
+      countdownInterval: null,
+      sendCodeLoading: false,
+    }
+  },
+  computed: {
+    title() {
+      let obj = {
+        register: '娉� 鍐�',
+        mobile: '鎵� 鏈� 鍙风櫥 褰�',
+        qrCode: '寰� 淇� 鎵� 鐮� 鐧� 褰�'
+      }
+      return obj[this.loginType]
+    }
+  },
+  created() {
+    
+  },
+  unmounted() {
+    this.clearCountdownInterval()
+  },
+  watch: {
+    
+  },
+  methods: {
+    async sendCode() {
+      try {
+        await this.$refs.accountForm.validateField('mobile')
+        this.startCountdownInterval()
+        this.$message.success('宸插彂閫侀獙璇佺爜锛岃娉ㄦ剰鏌ユ敹')
+      } catch (error) {
+        this.$message.error('璇疯緭鍏ユ墜鏈哄彿鐮�')
+      }
+    },
+    startCountdownInterval() {
+      this.clearCountdownInterval()
+      this.countdown--
+      this.countdownInterval = setInterval(() => {
+        if (this.countdown > 0) {
+          this.countdown--
+        } else {
+          this.countdown = 180
+          this.clearCountdownInterval()
+        }
+      }, 1000)
+    },
+    clearCountdownInterval() {
+      clearInterval(this.countdownInterval)
+      this.countdownInterval = null
+    },
+    async submitLogin() {
+      try {
+        await this.$refs.accountForm.validate()
+      } catch (error) {
+        console.log()
+      }
+    },
+    async submitRegister() {
+      try {
+        await this.$refs.registerForm.validate()
+      } catch (error) {
+        console.log()
+      }
+    },
+    changeLoginType(type) {
+      this.loginType = type
+    }
+  }
+}
+</script>
+
+<style scoped>
+</style>
\ No newline at end of file

--
Gitblit v1.8.0