login.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <template>
  2. <view class="warp">
  3. <view class="rect" @tap.stop>
  4. <view class="rectOne">Hi~欢迎来到{{config.title||'学吧'}}</view>
  5. <view class="rectTwo">
  6. <view class="icon">
  7. <view class="left">头像</view>
  8. <view class="right">
  9. <up-upload :fileList="form.icon" @afterRead="afterRead" @delete="deletePic" name="icon" multiple
  10. :maxCount="1"></up-upload>
  11. </view>
  12. </view>
  13. <view class="other">
  14. <view class="left">身份</view>
  15. <view class="right">
  16. <up-radio-group v-model="form.type" placement="row">
  17. <up-radio :customStyle="{marginRight: '16px'}" v-for="(item, index) in roleList"
  18. :key="index" :label="item.label" :name="item.value">
  19. </up-radio>
  20. </up-radio-group>
  21. <span v-if="errors.type" class="error-message">{{ errors.type }}</span>
  22. </view>
  23. </view>
  24. <view class="other">
  25. <view class="left">昵称</view>
  26. <view class="right">
  27. <up-input v-model="form.nick_name" placeholder="请输入昵称" border="surround"
  28. shape="circle"></up-input>
  29. <span v-if="errors.nick_name" class="error-message">{{ errors.nick_name }}</span>
  30. </view>
  31. </view>
  32. <view class="other">
  33. <view class="left">手机号</view>
  34. <view class="right">
  35. <up-input v-model="form.phone" placeholder="请输入手机号" border="surround" shape="circle"></up-input>
  36. <span v-if="errors.phone" class="error-message">{{ errors.phone }}</span>
  37. </view>
  38. </view>
  39. <view class="agree">
  40. <checkbox-group @change="changeAgree">
  41. <label>
  42. <checkbox color="#3c9cff" :checked="agree" />
  43. <text @tap.stop="toAgree()">我同意使用我所提交的信息用于{{config.title||'学吧'}}程序使用<text
  44. style="color: #2979ff;">《软件使用许可协议》</text>和 <text
  45. style="color: #2979ff;">《隐私协议》</text></text>
  46. </label>
  47. </checkbox-group>
  48. </view>
  49. <view class="button">
  50. <button class="button_1" size="default" type="default" @click="toCancel">取消</button>
  51. <button class="button_2" size="default" type="default" @click="toLogin">注册并登录</button>
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. </template>
  57. <script lang="ts" setup>
  58. const emit = defineEmits(["showChange"])
  59. import moment from 'moment';
  60. import { inject, computed, ref } from 'vue';
  61. //该依赖已内置不需要单独安装
  62. import { onShow, onPullDownRefresh } from "@dcloudio/uni-app";
  63. // 请求接口
  64. const $api = inject('$api');
  65. const $apifile = inject('$apifile');
  66. // 遮罩层
  67. const showType = ref(false);
  68. // 表单
  69. const form = ref({});
  70. //字典表
  71. const roleList = ref([]);
  72. // 用户协议
  73. const agree = ref(false);
  74. const errors = ref({});
  75. // openid
  76. const openid = computed(() => {
  77. return uni.getStorageSync('openid');
  78. })
  79. // user
  80. const user = computed(() => {
  81. return uni.getStorageSync('user');
  82. })
  83. const config = computed(() => {
  84. return uni.getStorageSync('config');
  85. })
  86. onShow(async () => {
  87. if (!user.value) await searchOther();
  88. })
  89. // 其他查询信息
  90. const searchOther = async () => {
  91. let res;
  92. // 角色
  93. res = await $api(`dictData`, 'GET', { code: 'role', is_use: '0' });
  94. if (res.errcode === 0) roleList.value = res.data;
  95. };
  96. // 删除图片
  97. const deletePic = (event) => {
  98. form.value.icon = []
  99. };
  100. // 新增图片
  101. const afterRead = async (event) => {
  102. const url = event.file[0].url
  103. const result = await $apifile(`/web/learn_user/upload`, 'file', url, 'file');
  104. if (result.errcode === 0) form.value.icon = [result]
  105. };
  106. // 选择身份
  107. const typeSelect = async (event) => {
  108. console.log(event);
  109. }
  110. // 取消
  111. const toCancel = async () => {
  112. form.value = { icon: [] }
  113. showType.value = false
  114. agree.value = false
  115. emit("showChange", false);
  116. }
  117. // 自定义的验证函数
  118. const validateObject = (obj : any) => {
  119. const errors : any = {};
  120. if (!obj.type || obj.type.trim() === '') {
  121. errors.type = '请选择身份类型!';
  122. }
  123. // 检查name属性是否填写
  124. if (!obj.nick_name || obj.nick_name.trim() === '') {
  125. errors.nick_name = '请填写昵称!';
  126. }
  127. // 检查email属性是否填写
  128. if (!obj.phone || obj.phone.trim() === '') {
  129. errors.phone = '请填写手机号!';
  130. } else {
  131. const regex = /^1[3456789]\d{9}$/;
  132. if (!regex.test(obj.phone)) errors.phone = '请填写正确的手机号码!';
  133. }
  134. // 如果有错误,返回错误对象
  135. if (Object.keys(errors).length > 0) {
  136. return errors;
  137. }
  138. // 如果没有错误,返回null或undefined
  139. return null;
  140. }
  141. // 登录
  142. const toLogin = async () => {
  143. if (agree.value) {
  144. if (openid.value) {
  145. // 调用验证函数
  146. const errorsInfo = await validateObject(form.value);
  147. // 检查是否有错误
  148. if (errorsInfo) {
  149. errors.value = errorsInfo
  150. // 遍历错误对象并显示错误信息
  151. for (const key in errorsInfo) {
  152. if (errorsInfo.hasOwnProperty(key)) {
  153. console.error(`${key} 错误: ${errorsInfo[key]}`);
  154. }
  155. }
  156. } else {
  157. uni.getUserProfile({
  158. desc: '用于展示',
  159. success: async function (res) {
  160. const type = form.value.type
  161. delete form.value.type
  162. let parmas = {
  163. openid: openid.value,
  164. status: '1',
  165. }
  166. if (!form.value.nick_name) parmas.nick_name = res.userInfo.nickName + moment().valueOf()
  167. if (!form.value.icon || form.value.icon.length === 0) parmas.icon = config.value.icon
  168. let arr;
  169. if (type == '0') arr = await $api(`teacher`, 'POST', { ...form.value, ...parmas, is_show: '1' });
  170. else arr = await $api(`student`, 'POST', { ...form.value, ...parmas });
  171. if (arr.errcode == '0') {
  172. let role_type;
  173. if (type == '0') role_type = 'Teacher'
  174. else role_type = 'Student'
  175. uni.setStorageSync('user', { ...arr.data, role_type });
  176. uni.showToast({
  177. title: '登录成功',
  178. icon: 'success'
  179. });
  180. await toCancel()
  181. } else {
  182. uni.showToast({
  183. title: arr.errmsg,
  184. icon: 'error'
  185. });
  186. }
  187. },
  188. fail: function (err) {
  189. console.log(err);
  190. }
  191. })
  192. }
  193. } else {
  194. uni.showToast({
  195. title: '系统更新中,请稍后再试!',
  196. icon: 'none'
  197. })
  198. }
  199. } else {
  200. uni.showToast({
  201. title: '请阅读并同意软件使用许可协议和隐私协议',
  202. icon: 'none'
  203. })
  204. }
  205. }
  206. // 查看隐私协议
  207. const toAgree = () => {
  208. uni.navigateTo({
  209. url: `/pagesHome/agree/index`
  210. })
  211. };
  212. // 同意隐私协议
  213. const changeAgree = () => {
  214. agree.value = !agree.value;
  215. };
  216. </script>
  217. <style lang="scss" scoped>
  218. .warp {
  219. display: flex;
  220. align-items: center;
  221. justify-content: center;
  222. height: 100%;
  223. }
  224. .rect {
  225. width: 90%;
  226. min-height: 380px;
  227. border-radius: 5px;
  228. padding: 3vw;
  229. background-color: #fff;
  230. .rectOne {
  231. padding: 2vw 0;
  232. text-align: center;
  233. font-size: var(--font16Size);
  234. }
  235. .rectTwo {
  236. .icon {
  237. width: 100%;
  238. display: flex;
  239. align-items: center;
  240. margin: 2vw 0;
  241. .left {
  242. width: 40%;
  243. font-size: var(--font14Size);
  244. }
  245. .right {
  246. width: 60%;
  247. }
  248. }
  249. .other {
  250. width: 100%;
  251. display: flex;
  252. align-items: center;
  253. margin: 3vw 0 0 0;
  254. .left {
  255. width: 15%;
  256. font-size: var(--font14Size);
  257. }
  258. .right {
  259. width: 85%;
  260. .error-message {
  261. margin: 5px 0 0 0;
  262. color: var(--ff0Color);
  263. font-size: var(--font12Size);
  264. }
  265. }
  266. }
  267. .agree {
  268. padding: 2vw;
  269. text-align: center;
  270. font-size: var(--font12Size);
  271. }
  272. .button {
  273. display: flex;
  274. justify-content: space-between;
  275. margin: 5vw 0 0 0;
  276. .button_1 {
  277. font-size: var(--font14Size);
  278. border-radius: 10vw;
  279. margin: 0 2vw;
  280. width: 35%;
  281. }
  282. .button_2 {
  283. font-size: var(--font14Size);
  284. color: var(--mainColor);
  285. background-color: var(--3c9Color);
  286. border-radius: 10vw;
  287. margin: 0 2vw;
  288. width: 55%;
  289. }
  290. }
  291. }
  292. }
  293. </style>