Browse Source

学员模块

一个番茄酱 2 years ago
parent
commit
3343a5ab13
23 changed files with 1142 additions and 42 deletions
  1. 10 0
      education_family/common/service_base/src/main/java/com/xunwang/servicebase/config/MybatisPlusConfig.java
  2. 60 0
      education_family/service/service-education/src/main/java/com/xunwang/education/controller/MyFavoriteNeedsController.java
  3. 18 5
      education_family/service/service-education/src/main/java/com/xunwang/education/controller/StudentRequirementsController.java
  4. 39 0
      education_family/service/service-education/src/main/java/com/xunwang/education/entity/MyFavoriteNeeds.java
  5. 16 0
      education_family/service/service-education/src/main/java/com/xunwang/education/mapper/MyFavoriteNeedsMapper.java
  6. 5 0
      education_family/service/service-education/src/main/java/com/xunwang/education/mapper/xml/MyFavoriteNeedsMapper.xml
  7. 35 0
      education_family/service/service-education/src/main/java/com/xunwang/education/service/MyFavoriteNeedsService.java
  8. 6 1
      education_family/service/service-education/src/main/java/com/xunwang/education/service/StudentRequirementsService.java
  9. 64 0
      education_family/service/service-education/src/main/java/com/xunwang/education/service/impl/MyFavoriteNeedsServiceImpl.java
  10. 38 4
      education_family/service/service-education/src/main/java/com/xunwang/education/service/impl/StudentRequirementsServiceImpl.java
  11. 1 1
      education_family/service/service-education/src/test/java/com/xunwang/education/CodeGenerator.java
  12. 1 1
      education_family/service/service-ucenter/src/main/java/com/xunwang/ucenter/service/impl/MiniProgramOpenidUidServiceImpl.java
  13. 1 0
      education_uni/App.vue
  14. 85 2
      education_uni/components/my-login/my-login.vue
  15. 246 0
      education_uni/components/my-requiredetail/my-requiredetail.vue
  16. 6 2
      education_uni/manifest.json
  17. 13 2
      education_uni/pages.json
  18. 179 4
      education_uni/pages/student/student.vue
  19. 11 0
      education_uni/store/user.js
  20. 4 4
      education_uni/subpkg/add_stu_require/add_stu_require.vue
  21. 218 0
      education_uni/subpkg/all_stu_require_detail/all_stu_require_detail.vue
  22. 2 2
      education_uni/subpkg/stu_require_detail/stu_require_detail.vue
  23. 84 14
      education_uni/subpkg/student_require/student_require.vue

+ 10 - 0
education_family/common/service_base/src/main/java/com/xunwang/servicebase/config/MybatisPlusConfig.java

@@ -1,7 +1,9 @@
 package com.xunwang.servicebase.config;
 
+import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.core.injector.ISqlInjector;
 import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -16,4 +18,12 @@ public class MybatisPlusConfig {
     public ISqlInjector sqlInjector() {
         return new LogicSqlInjector();
     }
+
+    /**
+     * 分页插件
+     */
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
 }

+ 60 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/controller/MyFavoriteNeedsController.java

@@ -0,0 +1,60 @@
+package com.xunwang.education.controller;
+
+
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.xunwang.commonutils.JwtUtils;
+import com.xunwang.commonutils.R;
+import com.xunwang.education.service.MyFavoriteNeedsService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Long
+ * @since 2022-12-30
+ */
+@RestController
+@RequestMapping("/education/my-favorite-needs")
+@ApiSupport(author = "Long")
+public class MyFavoriteNeedsController {
+
+    @Autowired
+    private MyFavoriteNeedsService myFavoriteNeedsService;
+
+    @ApiOperation("收藏学员需求")
+    @GetMapping("/collect")
+    public R collect(HttpServletRequest request) {
+        int collect = myFavoriteNeedsService.collect(request);
+        if (collect > 0) {
+            return R.ok().message("收藏成功");
+        }
+        return R.ok().message("收藏失败");
+    }
+
+    @ApiOperation("取消收藏学员需求")
+    @GetMapping("/cancelCollect")
+    public R cancelCollect(HttpServletRequest request) {
+        boolean b = myFavoriteNeedsService.cancelCollect(request);
+        if (b) {
+            return R.ok().message("取消收藏成功");
+        }
+        return R.ok().message("取消收藏失败");
+    }
+
+    @ApiOperation("查询个人收藏的学员需求")
+    @GetMapping("/findPersonCollect")
+    public R findPersonCollect(HttpServletRequest request) {
+        myFavoriteNeedsService.findPersonCollect(request)
+    }
+
+}
+

+ 18 - 5
education_family/service/service-education/src/main/java/com/xunwang/education/controller/StudentRequirementsController.java

@@ -1,6 +1,8 @@
 package com.xunwang.education.controller;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.xunwang.commonutils.JwtUtils;
 import com.xunwang.commonutils.R;
 import com.xunwang.education.entity.StuNeeds;
 import com.xunwang.education.service.StudentRequirementsService;
@@ -12,6 +14,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -41,14 +44,24 @@ public class StudentRequirementsController {
         }
     }
 
-    @ApiOperation("查询个人上架了需求数量 以及 提交的需求信息")
+    @ApiOperation("查询所有学员需求信息")
+    @GetMapping("getAllRequirements")
+    public R getAllRequirements(HttpServletRequest request) {
+        Map map = requirementsService.getAllRequirements(request);
+        return R.ok().data(map);
+    }
+
+    @ApiOperation("查询个人上架了需求数量 以及 个人全部的需求信息")
     @GetMapping("getPublishCounts")
     public R getPublishCounts(HttpServletRequest request) {
-        int count = requirementsService.getPublishCounts(request);
-        List<StuNeeds> list = requirementsService.getPersonCourse(request);
+        int publishCounts = requirementsService.getPublishCounts(request);
+        IPage<StuNeeds> personCourse = requirementsService.getPersonCourse(request);
+        List<StuNeeds> records = personCourse.getRecords();
+        long total = personCourse.getTotal();
         HashMap<String, Object> hashMap = new HashMap<>();
-        hashMap.put("count", count);
-        hashMap.put("list", list);
+        hashMap.put("count", total);
+        hashMap.put("publishCounts", publishCounts);
+        hashMap.put("list", records);
         return R.ok().data(hashMap);
     }
 

+ 39 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/entity/MyFavoriteNeeds.java

@@ -0,0 +1,39 @@
+package com.xunwang.education.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Long
+ * @since 2022-12-30
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="MyFavoriteNeeds对象", description="")
+public class MyFavoriteNeeds implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "自增")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "无序唯一id")
+    private String uid;
+
+    @ApiModelProperty(value = "无序唯一id")
+    private String requireId;
+
+
+}

+ 16 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/mapper/MyFavoriteNeedsMapper.java

@@ -0,0 +1,16 @@
+package com.xunwang.education.mapper;
+
+import com.xunwang.education.entity.MyFavoriteNeeds;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Long
+ * @since 2022-12-30
+ */
+public interface MyFavoriteNeedsMapper extends BaseMapper<MyFavoriteNeeds> {
+
+}

+ 5 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/mapper/xml/MyFavoriteNeedsMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.xunwang.education.mapper.MyFavoriteNeedsMapper">
+
+</mapper>

+ 35 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/service/MyFavoriteNeedsService.java

@@ -0,0 +1,35 @@
+package com.xunwang.education.service;
+
+import com.xunwang.education.entity.MyFavoriteNeeds;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Long
+ * @since 2022-12-30
+ */
+public interface MyFavoriteNeedsService extends IService<MyFavoriteNeeds> {
+
+    /**
+     * 收藏学员需求
+     * @param request
+     */
+    int collect(HttpServletRequest request);
+
+    /**
+     * 取消收藏学员需求
+     * @param request
+     */
+    boolean cancelCollect(HttpServletRequest request);
+
+    /**
+     * 查询个人收藏的学员信息
+     * @param request
+     */
+    void findPersonCollect(HttpServletRequest request);
+}

+ 6 - 1
education_family/service/service-education/src/main/java/com/xunwang/education/service/StudentRequirementsService.java

@@ -1,10 +1,12 @@
 package com.xunwang.education.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.xunwang.education.entity.StuNeeds;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -23,8 +25,11 @@ public interface StudentRequirementsService extends IService<StuNeeds> {
     int getPublishCounts(HttpServletRequest request);
 
     // 个人发布的需求
-    List<StuNeeds> getPersonCourse(HttpServletRequest request);
+    IPage<StuNeeds> getPersonCourse(HttpServletRequest request);
 
     // 更新个人需求上下架
     boolean updatePersonDisplay(HttpServletRequest request);
+
+    // 查询所有需求
+    Map getAllRequirements(HttpServletRequest request);
 }

+ 64 - 0
education_family/service/service-education/src/main/java/com/xunwang/education/service/impl/MyFavoriteNeedsServiceImpl.java

@@ -0,0 +1,64 @@
+package com.xunwang.education.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.xunwang.commonutils.JwtUtils;
+import com.xunwang.education.entity.MyFavoriteNeeds;
+import com.xunwang.education.mapper.MyFavoriteNeedsMapper;
+import com.xunwang.education.service.MyFavoriteNeedsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Long
+ * @since 2022-12-30
+ */
+@Service
+public class MyFavoriteNeedsServiceImpl extends ServiceImpl<MyFavoriteNeedsMapper, MyFavoriteNeeds> implements MyFavoriteNeedsService {
+
+    /**
+     * 收藏学员需求
+     * @param request
+     */
+    @Override
+    public int collect(HttpServletRequest request) {
+        String uid = JwtUtils.getUIdByJwtToken(request);
+        String requireId = request.getParameter("requireId");
+        MyFavoriteNeeds myFavoriteNeeds = new MyFavoriteNeeds();
+        myFavoriteNeeds.setRequireId(requireId);
+        myFavoriteNeeds.setUid(uid);
+        int insert = baseMapper.insert(myFavoriteNeeds);
+        return insert;
+    }
+
+    /**
+     * 取消收藏学员需求
+     * @param request
+     * @return
+     */
+    @Override
+    public boolean cancelCollect(HttpServletRequest request) {
+        String uid = JwtUtils.getUIdByJwtToken(request);
+        String requireId = request.getParameter("requireId");
+        boolean remove = remove(new QueryWrapper<MyFavoriteNeeds>().eq("uid", uid).eq("require_id", requireId));
+        return remove;
+    }
+
+    /**
+     * 查询个人收藏的学员信息
+     * @param request
+     */
+    @Override
+    public void findPersonCollect(HttpServletRequest request) {
+        String uid = JwtUtils.getUIdByJwtToken(request);
+        QueryWrapper<MyFavoriteNeeds> queryWrapper = new QueryWrapper<MyFavoriteNeeds>().select("require_id").eq("uid", uid);
+        List<MyFavoriteNeeds> list = list(queryWrapper);
+
+    }
+}

+ 38 - 4
education_family/service/service-education/src/main/java/com/xunwang/education/service/impl/StudentRequirementsServiceImpl.java

@@ -2,6 +2,8 @@ package com.xunwang.education.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.xunwang.commonutils.JwtUtils;
 import com.xunwang.commonutils.RedisIdWorker;
 import com.xunwang.education.entity.StuNeeds;
@@ -12,7 +14,9 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -52,7 +56,7 @@ public class StudentRequirementsServiceImpl extends ServiceImpl<StudentRequireme
     @Override
     public int getPublishCounts(HttpServletRequest request) {
         String uid = JwtUtils.getUIdByJwtToken(request);
-        int count = count(new QueryWrapper<StuNeeds>().eq("uid", uid).eq("deal", "未成交").eq("display", "上架"));
+        int count = count(new QueryWrapper<StuNeeds>().eq("uid", uid).eq("deal", "未成交").eq("display", "上架").eq("deleted", 0));
         return count;
     }
 
@@ -62,10 +66,13 @@ public class StudentRequirementsServiceImpl extends ServiceImpl<StudentRequireme
      * @return
      */
     @Override
-    public List<StuNeeds> getPersonCourse(HttpServletRequest request) {
+    public IPage<StuNeeds> getPersonCourse(HttpServletRequest request) {
         String uid = JwtUtils.getUIdByJwtToken(request);
-        List<StuNeeds> list = baseMapper.selectList(new QueryWrapper<StuNeeds>().eq("uid", uid).eq("deleted", 0));
-        return list;
+        String pageNum = request.getParameter("pageNum");
+        String pageSize = request.getParameter("pageSize");
+        Page<StuNeeds> stuNeedsPage = new Page<StuNeeds>(Long.parseLong(pageNum), Long.parseLong(pageSize));
+        IPage<StuNeeds> stuNeedsIPage = baseMapper.selectPage(stuNeedsPage, new QueryWrapper<StuNeeds>().eq("uid", uid).eq("deleted", 0).orderByDesc("datetime"));
+        return stuNeedsIPage;
     }
 
     /**
@@ -81,4 +88,31 @@ public class StudentRequirementsServiceImpl extends ServiceImpl<StudentRequireme
         boolean flag = saveOrUpdate(stuNeeds);
         return flag;
     }
+
+    /**
+     * 查询所有需求
+     * @return
+     */
+    @Override
+    public Map getAllRequirements(HttpServletRequest request) {
+
+        String pageNum = request.getParameter("pageNum");
+        String pageSize = request.getParameter("pageSize");
+        Page<StuNeeds> page = new Page<>(Long.parseLong(pageNum), Long.parseLong(pageSize));
+        IPage<StuNeeds> stuNeedsIPage = baseMapper.selectPage(page, new QueryWrapper<StuNeeds>().eq("deleted", 0).eq("deal", "未成交").eq("display", "上架"));
+
+        List<StuNeeds> stuNeeds = stuNeedsIPage.getRecords();
+        for (StuNeeds stuNeed : stuNeeds) {
+            stuNeed.setWxid(null);
+            stuNeed.setPhone(null);
+            stuNeed.setId(null);
+        }
+
+        long total = stuNeedsIPage.getTotal();
+        HashMap<String, Object> hashMap = new HashMap<>();
+        hashMap.put("total", total);
+        hashMap.put("list", stuNeeds);
+        return hashMap;
+    }
+
 }

+ 1 - 1
education_family/service/service-education/src/test/java/com/xunwang/education/CodeGenerator.java

@@ -60,7 +60,7 @@ public class CodeGenerator {
 
         // 5、策略配置
         StrategyConfig strategy = new StrategyConfig();
-        strategy.setInclude("teacher_courses");
+        strategy.setInclude("my_favorite_needs");
         strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
         strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀
 

+ 1 - 1
education_family/service/service-ucenter/src/main/java/com/xunwang/ucenter/service/impl/MiniProgramOpenidUidServiceImpl.java

@@ -79,7 +79,7 @@ public class MiniProgramOpenidUidServiceImpl extends ServiceImpl<MiniProgramOpen
             long uid = redisIdWorker.nextId("uid");
             formatUid = String.format("%08x", uid);
 
-            user.setOpenid(openid).setUnionid(unionid).setAlias(alias).setCity(city).setUid(formatUid);
+            user.setOpenid(openid).setUnionid(unionid).setAlias(alias).setCity(city).setUid(formatUid).setAvatar(avatar);
             baseMapper.insert(user);
 
         } else {

+ 1 - 0
education_uni/App.vue

@@ -21,6 +21,7 @@
 	// 设置整个项目的背景色
 	page {
 		background-color: #f5f5f5;
+		height: 100%;
 	}
 
 	/* #endif */

+ 85 - 2
education_uni/components/my-login/my-login.vue

@@ -17,14 +17,97 @@
 		name:"my-login",
 		data() {
 			return {
-				
+				queryObj: {
+					latitude: 0,
+					longitude: 0
+				}
 			};
 		},
 		methods: {
 			// 调用 mapMutations 辅助方法,把 m_user 模块中的 updateUserInfo 映射到当前组件中使用
-			...mapMutations('m_user', ['updateUserInfo', 'updateToken']),
+			...mapMutations('m_user', ['updateUserInfo', 'updateToken', 'updateLocation']),
+			
+			// 引导用户开启位置权限
+			openSetting() {
+				var that = this
+				wx.showModal({
+					title: '位置信息',
+					content: '开启后将为你推送最近的资源',
+					showCancel: true,
+					cancelText: '取消',
+					cancelColor: '#000000',
+					confirmText: '开启',
+					confirmColor: '#3CC51F',
+					success: res => {
+						if (res.confirm) {
+							wx.openSetting({
+								success(res) {
+									if (res.authSetting['scope.userFuzzyLocation']) {
+										
+										// 获取经纬度
+										wx.getFuzzyLocation({
+											type: 'wgs84',
+											success (res) {
+											   that.queryObj.latitude = res.latitude
+											   that.queryObj.longitude = res.longitude
+											   that.updateLocation(that.queryObj)
+											   that.getLogin()
+											}
+										})
+									}
+								},
+								fail(res) {
+									uni.$showMsg(res)
+								}
+							})
+						} else if(res.cancel) {
+							uni.$showMsg("需要位置权限")
+						}
+					}
+				})
+			},
+			
 			// 调用登录接口,换取永久的 token
 			async getToken() {
+				var that = this
+			
+				// 获取位置信息
+				wx.getSetting({
+					success(res) {
+						if (!res.authSetting['scope.userFuzzyLocation']) {
+							wx.authorize({
+								scope: 'scope.userFuzzyLocation',
+								success() {
+									// 获取经纬度
+									wx.getFuzzyLocation({
+										type: 'wgs84',
+										success (res) {
+										   that.queryObj.latitude = res.latitude
+										   that.queryObj.longitude = res.longitude
+										   that.updateLocation(that.queryObj)
+										   that.getLogin()
+										}
+									})
+								},
+								fail() {
+									// 拒绝后引导用户开启
+									if (wx.openSetting) {
+										that.openSetting()
+									}
+									return
+								}
+							})
+						} else {
+							that.getLogin()
+						}
+					}
+				})
+				
+			},
+			
+			// 真正的登录逻辑
+			async getLogin() {
+				
 				// 调用微信登录接口
 				const [err, res] = await uni.login().catch(err => err)
 				// 判断是否 wx.login() 调用失败

+ 246 - 0
education_uni/components/my-requiredetail/my-requiredetail.vue

@@ -0,0 +1,246 @@
+<template>
+	
+		<view class="contain">
+			<uni-row>
+				<view style="height: 20rpx;"></view>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<view class="contain-item"><text class="contain-text">需求号:</text>{{item.requireId}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<view class="contain-item"><text class="contain-text">学员ID:</text>{{item.uid}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :span="12" :push="1">
+					<view class="contain-item"><text class="contain-text">学员:</text>{{item.name}}</view>
+				</uni-col>
+				<uni-col :span="12">
+					<view><text class="contain-text">学员性别:</text>{{item.sex}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1" :span="18">
+					<view class="contain-item"><text class="contain-text">需求科目:</text>{{item.subjectBig}}/{{item.subjectSmall}}</view>
+				</uni-col>
+				<uni-col :span="6">
+					<uni-fav :checked="collect" class="favBtn" :circle="true" bg-color="#dd524d"
+										bg-color-checked="#007aff" fg-color="#ffffff" fg-color-checked="#ffffff" @click="collecting" />
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<view class="contain-item">
+					<map :longitude="location[1]" :latitude="location[0]" :markers="marker" class="map"></map>
+				</view>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<view class="contain-item"><text class="contain-text">学员地址:</text>{{item.locationStr}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<text class="contain-text">课程时间:</text>
+				</uni-col>
+			</uni-row>
+			<view class="tr-container">
+				<view class="tr_1">
+					<text class="th_0" decode="true">&ensp;&ensp;&ensp;&ensp;</text>
+					<text class="th_1">周一</text>
+					<text class="th_1">周二</text>
+					<text class="th_1">周三</text>
+					<text class="th_1">周四</text>
+					<text class="th_1">周五</text>
+					<text class="th_1">周六</text>
+					<text class="th_1">周日</text>
+				</view>
+				<view class="tr_2">
+					<checkbox-group>
+						<view class="th2_0">上午</view>
+						<label v-for="item in timeAM" :key="item.value">
+							<checkbox class="th2_1" :value="item.value" :checked="item.checked" disabled></checkbox>
+						</label>
+					</checkbox-group>
+				</view>
+				<view class="tr_2">
+					<checkbox-group>
+						<view class="th2_0">下午</view>
+						<label v-for="item in timePM" :key="item.value">
+							<checkbox class="th2_1" :value="item.value" :checked="item.checked" disabled></checkbox>
+						</label>
+					</checkbox-group>
+				</view>
+				<view class="tr_2">
+					<checkbox-group>
+						<view class="th2_0">晚上</view>
+						<label v-for="item in timeEvening" :key="item.value">
+						<checkbox class="th2_1" :value="item.value" :checked="item.checked" disabled></checkbox>
+						</label>
+					</checkbox-group>
+				</view>
+			</view>
+			<uni-row>
+				<uni-col :span="12" :push="1">
+					<view class="contain-item"><text class="contain-text">教员类型:</text>{{item.teacherType}}</view>
+				</uni-col>
+				<uni-col :span="12">
+					<view><text class="contain-text">学员学历:</text>{{item.teacherEdu}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :span="12" :push="1">
+					<view class="contain-item"><text class="contain-text">教员性别:</text>{{item.teacherGender}}</view>
+				</uni-col>
+				<uni-col :span="12">
+					<view><text class="contain-text">上课方式:</text>{{item.mode}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :span="12" :push="1">
+					<view class="contain-item"><text class="contain-text">教员头像:</text>{{item.teacherProfilePhoto}}</view>
+				</uni-col>
+				<uni-col :span="12">
+					<view><text class="contain-text">需求金额:</text>{{item.salary}}元</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<view class="contain-item"><text class="contain-text">期望目标:</text>{{item.goal}}</view>
+				</uni-col>
+			</uni-row>
+			<uni-row>
+				<uni-col :push="1">
+					<view class="contain-item"><text class="contain-text">额外要求:</text>{{item.teacherDemanded}}</view>
+				</uni-col>
+			</uni-row>
+			
+		</view>
+</template>
+
+<script>
+	import { mapState } from 'vuex';
+	
+	export default {
+		name: 'my-requiredetail',
+		data() {
+			return {
+				
+			};
+		},
+		props: {
+			item: {
+				type: Object
+			},
+			location: {
+				type: Array
+			},
+			marker: {
+				type: Array
+			},
+			timeAM: {
+				type: Array
+			},
+			timePM: {
+				type: Array
+			},
+			timeEvening: {
+				type: Array
+			},
+			collect: {
+				type: Boolean,
+				default: false
+			},
+			isShowCollect: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			// 点击收藏
+			collecting() {
+				// 触发外界通过 @click 绑定的 click 事件处理函数
+				this.$emit('click')
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+.contain {
+	background-color: #FFF2CC;
+	border-radius: 10%;
+	
+	.contain-item {
+		margin-bottom: 20rpx;
+	}
+	
+	.contain-text {
+		font-weight: 700;
+		color: #bbb;
+	}
+	
+	.map {
+		width: 100%;
+	}
+}
+.tr-container{
+	    display: flex;
+	    position: relative;
+	    width: 96%;
+	    flex-direction: column;
+	    font-size: 26rpx;
+	    /* border: 1rpx solid gray; */
+	    margin: -10px 20rpx;
+		margin-bottom: 20px;
+	}
+	
+	.tr_1 {
+	    display: flex;
+	    position: relative;
+	    height: 80rpx;
+	    line-height: 80rpx;
+	}
+	.tr_2{
+	    display: block;
+	    height: 80rpx;
+	    line-height: 80rpx;
+	}
+	
+	.th_0,
+	.th_1,
+	.th_2,
+	.th2_0,
+	.th2_1,
+	.th2_2{
+	    width: 12%;
+	    height: 80rpx;
+	    line-height: 80rpx;
+	    border-right: 1rpx solid gray;
+	    border-bottom: 1rpx solid gray;
+	    text-align: center;
+	}
+	
+	.th_0,
+	.th_1,
+	.th_2{
+	    border-top: 1rpx solid gray;
+	}
+	
+	.th_0,
+	.th2_0{
+	    border-left: 1rpx solid gray;
+	}
+	
+	.th2_0{
+	    float: left;
+	    width: 12%;
+	    height: 80rpx;
+	    line-height: 80rpx;
+	    text-align: center;
+	    /* background-color: greenyellow; */
+	}
+	
+</style>

+ 6 - 2
education_uni/manifest.json

@@ -57,7 +57,12 @@
             "postcss" : true,
             "minified" : true
         },
-        "usingComponents" : true,
+		"usingComponents" : true,
+		"permission": {
+			"scope.userLocation": {
+				"desc": "允许位置信息将为你推荐最近的资源"
+			}
+		},
 		"requiredPrivateInfos": [
 			"choosePoi",
 			"getFuzzyLocation",
@@ -65,5 +70,4 @@
 		]
     },
     "vueVersion" : "2"
-	
 }

+ 13 - 2
education_uni/pages.json

@@ -31,7 +31,8 @@
             "path" : "pages/student/student",
             "style" :                                                                                    
             {
-                "enablePullDownRefresh": false
+                "enablePullDownRefresh": true,
+				"onReachBottomDistance": 150
             }
             
         }
@@ -127,7 +128,8 @@
                     "style" :                                                                                    
                 {
                     "navigationBarTitleText": "我发布的学员需求",
-                    "enablePullDownRefresh": false,
+                    "enablePullDownRefresh": true,
+					"onReachBottomDistance": 150,
 					"app-plus": {
 						"bounce": "none"
 					}
@@ -142,6 +144,15 @@
                     "enablePullDownRefresh": false
                 }
                 
+                }
+                ,{
+                    "path" : "all_stu_require_detail/all_stu_require_detail",
+                    "style" :                                                                                    
+                {
+                    "navigationBarTitleText": "需求详情",
+                    "enablePullDownRefresh": false
+                }
+                
                 }
             ]
 		}

+ 179 - 4
education_uni/pages/student/student.vue

@@ -1,19 +1,194 @@
 <template>
-	<view>
-		
-	</view>
+		<view class="studentWrapper">
+			<view v-for="(item,index) in stuNeeds" :key="index" >
+				<view class="studentList" @click="goDetail(item)">
+				    <view class="studentLeft">
+				        <view class="studentLeftTitle">
+				            <text>{{item.name}}<text style="font-weight: 400; margin-left: 4px">学员</text></text>
+				        </view>
+				        <view class="studentNeedCourse">
+				            <text>科目:</text>
+				            <text class="needCourse">{{item.subjectBig}}/{{item.subjectSmall}}</text>
+				        </view>
+				        <view class="studentExpect">
+				            <text>期望目标:</text>
+				            <text class="expect">{{item.goal}}</text>
+				        </view>
+				    </view>
+				    <view class="studentRight">
+				        <view class="studentRightTitle">
+				            <text>{{item.salary}}/小时</text>
+				        </view>
+				        <view class="studentSex">
+				            <text>{{item.sex}}</text>
+				        </view>
+				        <view class="studentRightTitle">
+				            <text>{{item.kil}}km</text>
+				        </view>
+				    </view>
+				</view>
+			</view>
+		    
+		</view>
 </template>
 
 <script>
+	import { mapState } from 'vuex'
+	
 	export default {
+		computed: {
+			...mapState('m_user', ['location'])
+		},
 		data() {
 			return {
-				
+				stuNeeds: [],
+				queryObj: {
+					pageNum: 1,
+					pageSize: 8
+				},
+				total: 0,
+				isloading: false
 			};
+		},
+		created() {
+			this.getAllStuNeeds()
+		},
+		methods: {
+			async getAllStuNeeds(cb) {
+				// 打开节流阀
+				this.isloading = true
+				
+				// 发起请求
+				const { data: result } = await uni.$http.get('/education/student-requirements/getAllRequirements', this.queryObj)
+				
+				// 关闭节流阀
+				this.isloading = false
+				// 只要数据请求完毕,就立即按需调用 cb 回调函数
+				cb && cb()
+				
+				for (let i = 0; i < result.data.list.length; i++) {
+					let arr = result.data.list[i].locationAl.split(",")
+					let kil = this.space(arr[0], arr[1], this.location.latitude, this.location.longitude)
+					result.data.list[i].kil = kil
+				}
+				
+				// 新旧拼接
+				this.stuNeeds = [...this.stuNeeds, ...result.data.list]
+				this.total = result.data.total
+				
+				// console.log(result)
+			},
+			// 下拉刷新
+			onPullDownRefresh() {
+				if (this.isloading) return
+				
+				this.queryObj.pageNum = 1
+				this.total = 0
+				this.stuNeeds = []
+				this.isloading = false
+				
+				this.getAllStuNeeds( () => uni.stopPullDownRefresh())
+			},
+			// 触底事件
+			onReachBottom() {
+				// 判断是否有下一页
+				if (this.queryObj.pageNum * this.queryObj.pageSize >= this.total)
+				return uni.$showMsg('数据加载完毕!')
+				
+				// 判断是否正在请求数据
+				if (this.isloading) return
+				
+				this.queryObj.pageNum += 1
+				this.getAllStuNeeds()
+			},
+			space(lat1, lng1, lat2, lng2) {
+				// console.log(lat1, lng1, lat2, lng2)
+				var radLat1 = lat1 * Math.PI / 180.0;
+				var radLat2 = lat2 * Math.PI / 180.0;
+				var a = radLat1 - radLat2;
+				var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
+				var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+						Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+				s = s * 6378.137;
+				s = Math.round(s * 10000) / 10000;	// 单位千米
+				return s.toFixed(2)	// 保留两位小数
+			},
+			goDetail(item) {
+				uni.navigateTo({
+					url: '/subpkg/all_stu_require_detail/all_stu_require_detail?item=' + encodeURIComponent(JSON.stringify(item)) 
+				})
+			}
+
 		}
 	}
 </script>
 
 <style lang="scss">
+.studentWrapper{
+    height: 100%;
+    background-color: #E2F0D9;
+    padding: 20rpx;
+}
+
+.studentList{
+    display: flex;
+    position: relative;
+    /* border: 1rpx solid gray; */
+    border-radius: 20rpx;
+    background-color: #FFF2CC;
+    margin-bottom: 20rpx;
+}
+
+/* 左侧部分 */
+.studentLeft{
+    padding: 10rpx;
+    font-weight: bold;
+    font-size: 30rpx;
+}
+.studentLeftTitle,
+.studentExpect,
+.studentNeedCourse{
+    padding: 6rpx 0;
+}
+
+/* 科目 */
+.studentNeedCourse{
+    display: flex;
+}
+
+
+/* 期望目标 */
+.studentExpect{
+    display: flex;
+	font-weight: 400;
+	font-size: 26rpx;
+}
+/* 期望目标和需求科目详情 */
+.needCourse,
+.expect{
+    margin-left: 10rpx;
+    width: 240rpx;
+    display: block;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+/* 右侧部分定位 */
+.studentRight{
+    position: absolute;
+    left: 65%;
+    color: #FF0000;
+    font-size: 32rpx;
+}
 
+.studentRight,
+.studentSex{
+    padding: 10rpx 0;
+}
+/* 设置性别的字体 */
+.studentSex{
+    font-weight: bold;
+    color: #00B050;
+}
 </style>

+ 11 - 0
education_uni/store/user.js

@@ -12,6 +12,8 @@ export default {
 		authentication: uni.getStorageInfoSync('authentication') || '',
 		// 我的需求详情
 		requireDetail: JSON.parse(uni.getStorageSync('requireDeatail') || '{}'),
+		// 经纬度
+		location: uni.getStorageSync('location') || '{}'
 	}),
 	
 	// 方法
@@ -53,6 +55,15 @@ export default {
 		// 将我的需求存储到本地
 		saveRequireDetail(state) {
 			uni.setStorageSync('requireDetail', state.requireDetail)
+		},
+		// 更新经纬度
+		updateLocation(state, location) {
+			state.location = location
+			this.commit('m_user/saveLocation')
+		},
+		// 将经纬度存储到本地
+		saveLocation(state) {
+			uni.setStorageSync('location', state.location)
 		}
 	},
 	

+ 4 - 4
education_uni/subpkg/add_stu_require/add_stu_require.vue

@@ -366,8 +366,8 @@
 				this.baseFormData = item
 				this.courseWeekday = item.courseWeekday.split(",")
 				this.baseFormData.courseWeekday = this.courseWeekday
-				console.log(this.baseFormData)
-				console.log("选中的日期:" + this.courseWeekday)
+				// console.log(this.baseFormData)
+				// console.log("选中的日期:" + this.courseWeekday)
 				for (let i = 0; i < this.courseWeekday.length; i++) {
 					for (let x = 0; x < this.timeAM.length; x++) {
 						if (this.courseWeekday[i] == this.timeAM[x].value) {
@@ -562,8 +562,8 @@
 						success: res => {
 							uni.$showMsg(res.data.message)
 							setTimeout(() => {
-								uni.navigateTo({
-									url: '/subpkg/student_require/student_require'
+								uni.switchTab({
+									url: '/pages/my/my'
 								})
 							}, 1000)
 						}

+ 218 - 0
education_uni/subpkg/all_stu_require_detail/all_stu_require_detail.vue

@@ -0,0 +1,218 @@
+<template>
+	<view style="background-color: #E2F0D9;">
+		
+		<my-requiredetail :item="item" :location="location" :marker="marker" :timeAM="timeAM" :timePM="timePM" :timeEvening="timeEvening" :collect="collect" :isShowCollect="isShowCollect" @click="collecting"></my-requiredetail>
+		
+		<button type="primary" class="publish-button" @click="invite">邀请</button>
+			
+	</view>
+		
+</template>
+
+<script>
+	import { mapState } from 'vuex';
+	
+	export default {
+		data() {
+			return {
+				isShowCollect: true,
+				collect: false,
+				item: {},
+				courseWeekday: [],
+				location: [],
+				marker: [{
+					id: 1,
+					joinCluster:true,
+					latitude: 0,
+					longitude: 0,
+					width: 40,
+					height: 40,
+					iconPath: '/static/location.png',
+				}],
+				// 上课时间
+				// 上午
+				timeAM: [{
+						value: 'A1',
+						name: '1',
+						checked: false
+					},
+					{
+						name: '2',
+						value: 'A2',
+						checked: false
+					},
+					{
+						name: '3',
+						value: 'A3',
+						checked: false
+					},
+					{
+						name: '4',
+						value: 'A4',
+						checked: false
+					},
+					{
+						name: '5',
+						value: 'A5',
+						checked: false
+					},
+					{
+						name: '6',
+						value: 'A6',
+						checked: false
+					},
+					{
+						name: '7',
+						value: 'A7',
+						checked: false
+					}
+				],
+				// 下午
+				timePM: [{
+						value: 'P1',
+						name: '1',
+						checked: false
+					},
+					{
+						name: '2',
+						value: 'P2',
+						checked: false
+					},
+					{
+						name: '3',
+						value: 'P3',
+						checked: false
+					},
+					{
+						name: '4',
+						value: 'P4',
+						checked: false
+					},
+					{
+						name: '5',
+						value: 'P5',
+						checked: false
+					},
+					{
+						name: '6',
+						value: 'P6',
+						checked: false
+					},
+					{
+						name: '7',
+						value: 'P7',
+						checked: false
+					}
+				],
+				// 晚上
+				timeEvening: [{
+						name: '1',
+						value: 'E1',
+						checked: false
+					},
+					{
+						name: '2',
+						value: 'E2',
+						checked: false
+					},
+					{
+						name: '3',
+						value: 'E3',
+						checked: false
+					},
+					{
+						name: '4',
+						value: 'E4',
+						checked: false
+					},
+					{
+						name: '5',
+						value: 'E5',
+						checked: false
+					},
+					{
+						name: '6',
+						value: 'E6',
+						checked: false
+					},
+					{
+						name: '7',
+						value: 'E7',
+						checked: false
+					}
+				],
+			};
+		},
+		onLoad(option) {
+			this.item = JSON.parse(decodeURIComponent(option.item))
+			this.location = this.item.locationAl.split(",")
+			this.marker[0].latitude = Number(this.location[0])
+			this.marker[0].longitude = Number(this.location[1])
+			this.courseWeekday = this.item.courseWeekday.split(",")
+			// console.log("选中的日期:" + this.courseWeekday)
+			for (let i = 0; i < this.courseWeekday.length; i++) {
+				for (let x = 0; x < this.timeAM.length; x++) {
+					if (this.courseWeekday[i] == this.timeAM[x].value) {
+						this.timeAM[x].checked = true
+					}
+				}
+				
+				for (let y = 0; y < this.timePM.length; y++) {
+					if (this.courseWeekday[i] == this.timePM[y].value) {
+						// console.log(this.timePM[y].value)
+						this.timePM[y].checked = true
+					}
+				}
+				
+				for (let z = 0; z < this.timeEvening.length; z++) {
+					if (this.courseWeekday[i] == this.timeEvening[z].value) {
+						this.timeEvening[z].checked = true
+					}
+				}
+			}
+		},
+		methods: {
+			async collecting() {
+				// console.log(this.item)
+				const queryObj = {
+					requireId: this.item.requireId
+				}
+				
+				if (!this.collect) {
+					
+					const { data: result1 } = await uni.$http.get('/education/my-favorite-needs/collect', queryObj)
+					// console.log(result)
+					if (result1.message === '收藏成功') {
+						this.collect = true
+						
+					} else if (result1.message === '收藏失败') {
+						uni.$showMsg('收藏失败')
+					}
+					
+				} else if (this.collect) {
+					
+					const { data: result } = await uni.$http.get('/education/my-favorite-needs/cancelCollect', queryObj)
+					if (result.message === '取消收藏成功') {
+						this.collect = false
+					
+					} else if (result.message === '取消收藏失败') {
+						uni.$showMsg('取消收藏失败')
+					}
+				}
+				
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.tabbar {
+	height: 64px;
+	align-items: center;
+}
+
+.publish-button {
+	width: 65%;
+	border-radius: 15%;
+}
+</style>

+ 2 - 2
education_uni/subpkg/stu_require_detail/stu_require_detail.vue

@@ -386,7 +386,7 @@
 	
 .publish-button {
 	background-color: #E2F0D9;
-	width: 60%;
-	border-radius: 50%;
+	width: 90%;
+	border-radius: 25%;
 }
 </style>

+ 84 - 14
education_uni/subpkg/student_require/student_require.vue

@@ -47,7 +47,14 @@
 	export default {
 		data() {
 			return {
+				// 分页对象
+				queryObj: {
+					pageNum: 1,
+					pageSize: 8
+				},
+				isloading: false,
 				requirement: [],	// 需求列表
+				count: 0,	// 总数量
 				publishCount: 0,	// 上架数量
 				pattern: {
 					color: '#7A7E83',
@@ -69,32 +76,95 @@
 				})
 			},
 			// 查询个人上架了多少课程
-			async getPublishCounts() {
-				const { data: result } = await uni.$http.get('/education/student-requirements/getPublishCounts')
-				this.publishCount = result.data.count
-				this.requirement = result.data.list
-				for (let i = 0; i < this.requirement.length; i++) {
-					if (this.requirement[i].display === '上架') {
-						this.requirement[i].display = '下架'
-						this.requirement[i].options = [{text: '下架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
+			async getPublishCounts(cb) {
+				// 打开节流阀
+				this.isloading = true
+				
+				const { data: result } = await uni.$http.get('/education/student-requirements/getPublishCounts', this.queryObj)
+				
+				this.isloading = false
+				cb && cb()
+				
+				// console.log(result.data.list)
+				this.publishCount = result.data.publishCounts
+				this.count = result.data.count
+				let courses = []
+				courses = result.data.list
+				
+				for (let i = 0; i < courses.length; i++) {
+					if (courses[i].display === '上架') {
+						courses[i].display = '下架'
+						courses[i].options = [{text: '下架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
 					} else {
-						this.requirement[i].display = '上架'
-						this.requirement[i].options = [{text: '上架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
+						courses[i].display = '上架'
+						courses[i].options = [{text: '上架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
 					}
 				}
-				// console.log(this.requirement)
+				
+				this.requirement = [...this.requirement ,...courses]
+				console.log(this.requirement)
+			},
+			// 下拉刷新的事件
+			onPullDownRefresh() {
+				if (this.isloading) return
+				// 1.重置数据
+				this.queryObj.pageNum = 1
+				this.publishCount = 0
+				this.requirement = []
+				this.isloading = false
+				
+				// 2.重新发请求
+				this.getPublishCounts(() => uni.stopPullDownRefresh())
+			},
+			// 触底的事件
+			onReachBottom() {
+				// 判断是否有下一页的数据
+				if (this.queryObj.pageNum * this.queryObj.pageSize >= this.count)
+				return uni.$showMsg('数据加载完毕!')
+				
+				// 是否有其他正在请求数据
+				if (this.isloading) return
+				
+				// 页码自增
+				this.queryObj.pageNum += 1
+				this.getPublishCounts()
 			},
 			async bindClick(item) {
+				console.log(item)
+				
+				if (item.display === '上架') {
+					if (this.publishCount >= 4) return uni.$showMsg('最多发布4个需求')
+					if (item.verifyStatus !== '已通过') return uni.$showMsg('审核通过才能上架')
+					if (item.deal === '已成交') return uni.$showMsg('已成交的需求不能上架')
+				}
+				
 				const queryObj = {
 					display: item.display,
 					requireId: item.requireId
 				}
 				const { data: result } = await uni.$http.get('/education/student-requirements/updatePersonDisplay', queryObj)
+				const that = this
 				if (result.code === 20000) {
 					uni.$showMsg(item.display + '成功')
-					setTimeout(() => {
-						this.getPublishCounts()
-					}, 500)
+					
+					
+					this.queryObj.pageNum = 1
+					this.publishCount = 0
+					this.requirement = []
+					
+					const { data: result } = await uni.$http.get('/education/student-requirements/getPublishCounts', this.queryObj)
+					this.publishCount = result.data.publishCounts
+					this.count = result.data.count
+					this.requirement = result.data.list
+					for (let i = 0; i < this.requirement.length; i++) {
+						if (this.requirement[i].display === '上架') {
+							this.requirement[i].display = '下架'
+							this.requirement[i].options = [{text: '下架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
+						} else {
+							this.requirement[i].display = '上架'
+							this.requirement[i].options = [{text: '上架', style: {backgroundColor: '#E2F0D9', color: 'black'}}]
+						}
+					}
 				}
 			},
 			requireDetail(item) {