瀏覽代碼

生成海报

高敬炎 2 年之前
父節點
當前提交
bec145b1b2
共有 40 個文件被更改,包括 3974 次插入291 次删除
  1. 65 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/ICircleFriendsDetailService.java
  2. 69 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/ICircleFriendsInfoService.java
  3. 142 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/impl/CircleFriendsDetailServiceImpl.java
  4. 190 0
      unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/impl/CircleFriendsInfoServiceImpl.java
  5. 5 3
      unimall-admin/config/dev.env.js
  6. 98 0
      unimall-data/src/main/java/com/iotechn/unimall/data/domain/CircleFriendsDetail.java
  7. 130 0
      unimall-data/src/main/java/com/iotechn/unimall/data/domain/CircleFriendsInfo.java
  8. 15 0
      unimall-data/src/main/java/com/iotechn/unimall/data/mapper/CircleFriendsDetailMapper.java
  9. 13 0
      unimall-data/src/main/java/com/iotechn/unimall/data/mapper/CircleFriendsInfoMapper.java
  10. 9 0
      unimall-data/src/main/resources/com/iotechn/unimall/data/mapper/CircleFriendsDetailMapper.xml
  11. 9 0
      unimall-data/src/main/resources/com/iotechn/unimall/data/mapper/CircleFriendsInfoMapper.xml
  12. 9 0
      xiaochengxu/README.md
  13. 52 0
      xiaochengxu/common/util.js
  14. 8 5
      xiaochengxu/components/ossutil/uploadFile.js
  15. 2 2
      xiaochengxu/config/index.js
  16. 18 1
      xiaochengxu/pages.json
  17. 92 178
      xiaochengxu/pages/cardHolder/cardHolder.vue
  18. 256 42
      xiaochengxu/pages/cardHolder/scanCodeAddCard.vue
  19. 13 8
      xiaochengxu/pages/cardHolder/search.vue
  20. 155 0
      xiaochengxu/pages/circle/addFriendCirlce.vue
  21. 515 0
      xiaochengxu/pages/circle/circle-item.vue
  22. 363 22
      xiaochengxu/pages/circle/detail.vue
  23. 378 0
      xiaochengxu/pages/circle/friendSCirlce.vue
  24. 18 25
      xiaochengxu/pages/mySet/myInfo.vue
  25. 5 3
      xiaochengxu/pages/mySet/mySet.vue
  26. 二進制
      xiaochengxu/static/comment.png
  27. 二進制
      xiaochengxu/static/imgs/card/bgc6.png
  28. 二進制
      xiaochengxu/static/imgs/card/buju1.png
  29. 二進制
      xiaochengxu/static/imgs/card/buju2.png
  30. 二進制
      xiaochengxu/static/imgs/card/share1.png
  31. 二進制
      xiaochengxu/static/imgs/share1.png
  32. 二進制
      xiaochengxu/static/love-fill.png
  33. 二進制
      xiaochengxu/static/love.png
  34. 二進制
      xiaochengxu/static/play.png
  35. 69 0
      xiaochengxu/uni_modules/cl-upload/changelog.md
  36. 54 0
      xiaochengxu/uni_modules/cl-upload/components/cl-image/cl-image.vue
  37. 981 0
      xiaochengxu/uni_modules/cl-upload/components/cl-upload/cl-upload.vue
  38. 240 0
      xiaochengxu/uni_modules/cl-upload/readme.md
  39. 1 1
      xiaochengxu/uni_modules/d-search-log/components/d-search-log/d-search-log.vue
  40. 0 1
      xiaochengxu/util/request.js

+ 65 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/ICircleFriendsDetailService.java

@@ -0,0 +1,65 @@
+package com.iotechn.unimall.admin.api.card;
+
+
+import com.iotechn.unimall.data.domain.CircleFriendsDetail;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+
+/**
+ * 记录朋友圈互动信息Service接口
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@HttpOpenApi(group = "admin.unimall.circleFriendsDetail", description = "记录朋友圈互动信息")
+public interface ICircleFriendsDetailService{
+	@HttpMethod(description = "新增",  permissionName = "记录朋友圈互动信息管理")
+	public Boolean add(@NotNull @HttpParam(name = "circleFriendsDetail", type = HttpParamType.COMMON, description = "记录朋友圈互动信息") CircleFriendsDetail circleFriendsDetail)throws ServiceException;
+
+	@HttpMethod(description = "列表",  permissionName = "记录朋友圈互动信息管理")
+	public Page<CircleFriendsDetail> list(
+								@HttpParam(name = "circleFriendsId", type = HttpParamType.COMMON, description = "朋友圈id") Long circleFriendsId,
+							@HttpParam(name = "commonId", type = HttpParamType.COMMON, description = "发表人id") Long commonId,
+							@HttpParam(name = "head", type = HttpParamType.COMMON, description = "头像") String head,
+							@HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "昵称") String nickname,
+							@HttpParam(name = "commentContent", type = HttpParamType.COMMON, description = "评论内容") String commentContent,
+							@HttpParam(name = "commentId", type = HttpParamType.COMMON, description = "回复的评论id") Long commentId,
+							@HttpParam(name = "interactionFlag", type = HttpParamType.COMMON, description = "标识(1点赞2评论)") String interactionFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+					@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+		@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+		throws ServiceException;
+
+	@HttpMethod(description = "删除",permissionName = "记录朋友圈互动信息管理")
+	public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")String id)throws ServiceException;
+
+	@HttpMethod(description = "修改",  permissionName = "记录朋友圈互动信息管理")
+	public Boolean update(@NotNull @HttpParam(name = "circleFriendsDetail", type = HttpParamType.COMMON, description = "记录朋友圈互动信息") CircleFriendsDetail circleFriendsDetail)throws ServiceException;
+
+	@HttpMethod(description = "查询",  permissionName = "记录朋友圈互动信息管理")
+	public CircleFriendsDetail get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+	
+	@HttpMethod(description = "导出excl表", permissionName = "记录朋友圈互动信息管理")
+	public String export(
+								@HttpParam(name = "circleFriendsId", type = HttpParamType.COMMON, description = "朋友圈id") Long circleFriendsId,
+							@HttpParam(name = "commonId", type = HttpParamType.COMMON, description = "发表人id") Long commonId,
+							@HttpParam(name = "head", type = HttpParamType.COMMON, description = "头像") String head,
+							@HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "昵称") String nickname,
+							@HttpParam(name = "commentContent", type = HttpParamType.COMMON, description = "评论内容") String commentContent,
+							@HttpParam(name = "commentId", type = HttpParamType.COMMON, description = "回复的评论id") Long commentId,
+							@HttpParam(name = "interactionFlag", type = HttpParamType.COMMON, description = "标识(1点赞2评论)") String interactionFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+				@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+	@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)throws ServiceException;
+	
+}

+ 69 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/ICircleFriendsInfoService.java

@@ -0,0 +1,69 @@
+package com.iotechn.unimall.admin.api.card;
+
+
+import com.iotechn.unimall.data.domain.CircleFriendsInfo;
+import com.iotechn.unimall.core.annotation.HttpMethod;
+import com.iotechn.unimall.core.annotation.HttpOpenApi;
+import com.iotechn.unimall.core.annotation.HttpParam;
+import com.iotechn.unimall.core.annotation.HttpParamType;
+import com.iotechn.unimall.core.annotation.param.NotNull;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+
+/**
+ * 记录朋友圈信息Service接口
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@HttpOpenApi(group = "admin.unimall.circleFriendsInfo", description = "记录朋友圈信息")
+public interface ICircleFriendsInfoService{
+	@HttpMethod(description = "新增", permissionName = "记录朋友圈信息管理")
+	public Boolean add(@NotNull @HttpParam(name = "circleFriendsInfo", type = HttpParamType.COMMON, description = "记录朋友圈信息") CircleFriendsInfo circleFriendsInfo)throws ServiceException;
+
+	@HttpMethod(description = "列表",  permissionName = "记录朋友圈信息管理")
+	public Page<CircleFriendsInfo> list(
+								@HttpParam(name = "circleId", type = HttpParamType.COMMON, description = "圈子id") Long circleId,
+								@HttpParam(name = "commonId", type = HttpParamType.COMMON, description = "朋友圈发布人id") Long commonId,
+								@HttpParam(name = "currentCommonId", type = HttpParamType.COMMON, description = "当前登录人id") Long currentCommonId,
+								@HttpParam(name = "head", type = HttpParamType.COMMON, description = "头像") String head,
+							@HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "昵称") String nickname,
+							@HttpParam(name = "content", type = HttpParamType.COMMON, description = "朋友圈内容") String content,
+							@HttpParam(name = "image", type = HttpParamType.COMMON, description = "图片") String image,
+							@HttpParam(name = "location", type = HttpParamType.COMMON, description = "位置") String location,
+							@HttpParam(name = "positioning", type = HttpParamType.COMMON, description = "定位") String positioning,
+							@HttpParam(name = "commentFlag", type = HttpParamType.COMMON, description = "允许评论(1允许)") String commentFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+					@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+		@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)
+		throws ServiceException;
+
+	@HttpMethod(description = "删除",  permissionName = "记录朋友圈信息管理")
+	public Boolean delete(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")String id)throws ServiceException;
+
+	@HttpMethod(description = "修改", permissionName = "记录朋友圈信息管理")
+	public Boolean update(@NotNull @HttpParam(name = "circleFriendsInfo", type = HttpParamType.COMMON, description = "记录朋友圈信息") CircleFriendsInfo circleFriendsInfo)throws ServiceException;
+
+	@HttpMethod(description = "查询", permissionName = "记录朋友圈信息管理")
+	public CircleFriendsInfo get(@NotNull @HttpParam(name = "id", type = HttpParamType.COMMON, description = "")Long id)throws ServiceException;
+	
+	@HttpMethod(description = "导出excl表",  permissionName = "记录朋友圈信息管理")
+	public String export(
+								@HttpParam(name = "commonId", type = HttpParamType.COMMON, description = "朋友圈发布人id") Long commonId,
+							@HttpParam(name = "head", type = HttpParamType.COMMON, description = "头像") String head,
+							@HttpParam(name = "nickname", type = HttpParamType.COMMON, description = "昵称") String nickname,
+							@HttpParam(name = "content", type = HttpParamType.COMMON, description = "朋友圈内容") String content,
+							@HttpParam(name = "image", type = HttpParamType.COMMON, description = "图片") String image,
+							@HttpParam(name = "location", type = HttpParamType.COMMON, description = "位置") String location,
+							@HttpParam(name = "positioning", type = HttpParamType.COMMON, description = "定位") String positioning,
+							@HttpParam(name = "commentFlag", type = HttpParamType.COMMON, description = "允许评论(1允许)") String commentFlag,
+							@HttpParam(name = "gmtCreate", type = HttpParamType.COMMON, description = "") Date gmtCreate,
+							@HttpParam(name = "gmtUpdate", type = HttpParamType.COMMON, description = "") Date gmtUpdate,
+							@HttpParam(name = "deleteFlag", type = HttpParamType.COMMON, description = "删除标识") Long deleteFlag,
+				@HttpParam(name = "page", type = HttpParamType.COMMON, description = "页码", valueDef = "1") Integer page,
+	@HttpParam(name = "limit", type = HttpParamType.COMMON, description = "页码长度", valueDef = "20") Integer limit)throws ServiceException;
+	
+}

+ 142 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/impl/CircleFriendsDetailServiceImpl.java

@@ -0,0 +1,142 @@
+package com.iotechn.unimall.admin.api.card.impl;
+
+import java.util.List;
+
+import com.iotechn.unimall.admin.api.card.ICircleFriendsDetailService;
+import com.iotechn.unimall.data.domain.CircleFriendsDetail;
+import com.iotechn.unimall.data.mapper.CircleFriendsDetailMapper;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 记录朋友圈互动信息Service业务层处理
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@Service
+public class CircleFriendsDetailServiceImpl implements ICircleFriendsDetailService {
+	@Autowired
+	private CircleFriendsDetailMapper circleFriendsDetailMapper;
+	
+	@Override
+	public Boolean add(CircleFriendsDetail circleFriendsDetail) throws ServiceException {
+		Date now = new Date();
+		circleFriendsDetail.setGmtCreate(now);
+		circleFriendsDetail.setGmtUpdate(now);
+		return circleFriendsDetailMapper.insert(circleFriendsDetail)>0;
+	}
+
+	@Override
+	public Page<CircleFriendsDetail> list(Long circleFriendsId,Long commonId,String head,String nickname,String commentContent,Long commentId,String interactionFlag,Date gmtCreate,Date gmtUpdate,Long deleteFlag, Integer page, Integer limit)throws ServiceException {
+		Wrapper<CircleFriendsDetail> wrapper = new EntityWrapper<CircleFriendsDetail>();
+														if (!StringUtils.isEmpty(circleFriendsId)) {
+					wrapper.eq("circle_friends_id", circleFriendsId);
+				}
+												if (!StringUtils.isEmpty(commonId)) {
+					wrapper.eq("common_id", commonId);
+				}
+												if (!StringUtils.isEmpty(head)) {
+					wrapper.eq("head", head);
+				}
+												if (!StringUtils.isEmpty(nickname)) {
+					wrapper.eq("nickname", nickname);
+				}
+												if (!StringUtils.isEmpty(commentContent)) {
+					wrapper.eq("comment_content", commentContent);
+				}
+												if (!StringUtils.isEmpty(commentId)) {
+					wrapper.eq("comment_id", commentId);
+				}
+												if (!StringUtils.isEmpty(interactionFlag)) {
+					wrapper.eq("interaction_flag", interactionFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+							wrapper.eq("delete_flag", 0);
+		List<CircleFriendsDetail> list = circleFriendsDetailMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		Integer count = circleFriendsDetailMapper.selectCount(wrapper);
+		return new Page<CircleFriendsDetail>(list, page, limit, count);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean delete(String id) {
+		String[] ids = String.valueOf(id).split(",");
+		for (String tt:ids) {
+			CircleFriendsDetail tmp =  circleFriendsDetailMapper.selectById(Long.parseLong(tt));
+			if(tmp != null){
+				tmp.setDeleteFlag(1l);
+				circleFriendsDetailMapper.updateById(tmp);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean update(CircleFriendsDetail circleFriendsDetail) throws ServiceException {
+		Date now = new Date();
+		circleFriendsDetail.setGmtUpdate(now);
+		return circleFriendsDetailMapper.updateById(circleFriendsDetail)>0;
+	}
+
+	@Override
+	public CircleFriendsDetail get(Long id) throws ServiceException {
+		return circleFriendsDetailMapper.selectById(id);
+	}
+	
+	@Override
+	public String export(Long circleFriendsId,Long commonId,String head,String nickname,String commentContent,Long commentId,String interactionFlag,Date gmtCreate,Date gmtUpdate,Long deleteFlag, Integer page, Integer limit)throws ServiceException {
+		Wrapper<CircleFriendsDetail> wrapper = new EntityWrapper<CircleFriendsDetail>();
+														if (!StringUtils.isEmpty(circleFriendsId)) {
+					wrapper.eq("circle_friends_id", circleFriendsId);
+				}
+												if (!StringUtils.isEmpty(commonId)) {
+					wrapper.eq("common_id", commonId);
+				}
+												if (!StringUtils.isEmpty(head)) {
+					wrapper.eq("head", head);
+				}
+												if (!StringUtils.isEmpty(nickname)) {
+					wrapper.eq("nickname", nickname);
+				}
+												if (!StringUtils.isEmpty(commentContent)) {
+					wrapper.eq("comment_content", commentContent);
+				}
+												if (!StringUtils.isEmpty(commentId)) {
+					wrapper.eq("comment_id", commentId);
+				}
+												if (!StringUtils.isEmpty(interactionFlag)) {
+					wrapper.eq("interaction_flag", interactionFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+							List<CircleFriendsDetail> list = circleFriendsDetailMapper.selectList(wrapper);
+		ExcelUtil<CircleFriendsDetail> util = new ExcelUtil<CircleFriendsDetail>(CircleFriendsDetail.class);
+		return util.exportExcel(list, "操作日志");
+	}
+}

+ 190 - 0
unimall-admin-api/src/main/java/com/iotechn/unimall/admin/api/card/impl/CircleFriendsInfoServiceImpl.java

@@ -0,0 +1,190 @@
+package com.iotechn.unimall.admin.api.card.impl;
+
+import java.util.List;
+
+import com.iotechn.unimall.admin.api.card.ICircleFriendsInfoService;
+import com.iotechn.unimall.data.domain.CircleFriendsDetail;
+import com.iotechn.unimall.data.domain.CircleFriendsInfo;
+import com.iotechn.unimall.data.mapper.CircleFriendsDetailMapper;
+import com.iotechn.unimall.data.mapper.CircleFriendsInfoMapper;
+import org.apache.ibatis.session.RowBounds;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.iotechn.unimall.core.exception.ServiceException;
+import com.iotechn.unimall.data.util.ExcelUtil;
+import com.iotechn.unimall.data.model.Page;
+import java.util.Date;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 记录朋友圈信息Service业务层处理
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@Service
+public class CircleFriendsInfoServiceImpl implements ICircleFriendsInfoService {
+	@Autowired
+	private CircleFriendsInfoMapper circleFriendsInfoMapper;
+	@Autowired
+	private CircleFriendsDetailMapper circleFriendsDetailMapper;
+	
+	@Override
+	public Boolean add(CircleFriendsInfo circleFriendsInfo) throws ServiceException {
+		Date now = new Date();
+		circleFriendsInfo.setGmtCreate(now);
+		circleFriendsInfo.setGmtUpdate(now);
+		return circleFriendsInfoMapper.insert(circleFriendsInfo)>0;
+	}
+
+	@Override
+	public Page<CircleFriendsInfo> list(Long circleId,Long currentCommonId,Long commonId,String head,String nickname,String content,String image,String location,String positioning,String commentFlag,Date gmtCreate,Date gmtUpdate,Long deleteFlag, Integer page, Integer limit)throws ServiceException {
+		Wrapper<CircleFriendsInfo> wrapper = new EntityWrapper<CircleFriendsInfo>();
+				if (!StringUtils.isEmpty(circleId)) {
+					wrapper.eq("circle_id", circleId);
+				}
+												if (!StringUtils.isEmpty(commonId)) {
+					wrapper.eq("common_id", commonId);
+				}
+												if (!StringUtils.isEmpty(head)) {
+					wrapper.eq("head", head);
+				}
+												if (!StringUtils.isEmpty(nickname)) {
+					wrapper.eq("nickname", nickname);
+				}
+												if (!StringUtils.isEmpty(content)) {
+					wrapper.eq("content", content);
+				}
+												if (!StringUtils.isEmpty(image)) {
+					wrapper.eq("image", image);
+				}
+												if (!StringUtils.isEmpty(location)) {
+					wrapper.eq("location", location);
+				}
+												if (!StringUtils.isEmpty(positioning)) {
+					wrapper.eq("positioning", positioning);
+				}
+												if (!StringUtils.isEmpty(commentFlag)) {
+					wrapper.eq("comment_flag", commentFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+							wrapper.eq("delete_flag", 0);
+		List<CircleFriendsInfo> list = circleFriendsInfoMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
+		if (!CollectionUtils.isEmpty(list)){
+			for (CircleFriendsInfo circleFriendsInfo:list){
+				//点赞list
+				List<CircleFriendsDetail> circleFriendsDetailList=circleFriendsDetailMapper.selectList(new EntityWrapper<CircleFriendsDetail>()
+				.eq("circle_friends_id",circleFriendsInfo.getId())
+				.eq("delete_flag",0)
+				.eq("interaction_flag","1"));
+				if(!CollectionUtils.isEmpty(circleFriendsDetailList)){
+					circleFriendsInfo.setCircleFriendsDetailList(circleFriendsDetailList);
+					circleFriendsInfo.setCount(circleFriendsDetailList.size());
+				}
+				//判断当前账号是否点赞标识
+				List<CircleFriendsDetail> circleFriendsDetailList2=circleFriendsDetailMapper.selectList(new EntityWrapper<CircleFriendsDetail>()
+						.eq("circle_friends_id",circleFriendsInfo.getId())
+						.eq("common_id",currentCommonId)
+						.eq("delete_flag",0)
+						.eq("interaction_flag","1"));
+				if(!CollectionUtils.isEmpty(circleFriendsDetailList2)){
+					circleFriendsInfo.setHelpFlag("1");
+				}
+				else {
+					circleFriendsInfo.setHelpFlag("0");
+				}
+				//评论list
+				List<CircleFriendsDetail> circleFriendsDetailList1=circleFriendsDetailMapper.selectList(new EntityWrapper<CircleFriendsDetail>()
+						.eq("circle_friends_id",circleFriendsInfo.getId())
+						.eq("delete_flag",0)
+						.eq("interaction_flag","2"));
+				if(!CollectionUtils.isEmpty(circleFriendsDetailList1)){
+					circleFriendsInfo.setCircleFriendsDetailList1(circleFriendsDetailList1);
+					circleFriendsInfo.setCount(circleFriendsDetailList1.size());
+				}
+			}
+		}
+		Integer count = circleFriendsInfoMapper.selectCount(wrapper);
+		return new Page<CircleFriendsInfo>(list, page, limit, count);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean delete(String id) {
+		String[] ids = String.valueOf(id).split(",");
+		for (String tt:ids) {
+			CircleFriendsInfo tmp =  circleFriendsInfoMapper.selectById(Long.parseLong(tt));
+			if(tmp != null){
+				tmp.setDeleteFlag(1l);
+				circleFriendsInfoMapper.updateById(tmp);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean update(CircleFriendsInfo circleFriendsInfo) throws ServiceException {
+		Date now = new Date();
+		circleFriendsInfo.setGmtUpdate(now);
+		return circleFriendsInfoMapper.updateById(circleFriendsInfo)>0;
+	}
+
+	@Override
+	public CircleFriendsInfo get(Long id) throws ServiceException {
+		return circleFriendsInfoMapper.selectById(id);
+	}
+	
+	@Override
+	public String export(Long commonId,String head,String nickname,String content,String image,String location,String positioning,String commentFlag,Date gmtCreate,Date gmtUpdate,Long deleteFlag, Integer page, Integer limit)throws ServiceException {
+		Wrapper<CircleFriendsInfo> wrapper = new EntityWrapper<CircleFriendsInfo>();
+														if (!StringUtils.isEmpty(commonId)) {
+					wrapper.eq("common_id", commonId);
+				}
+												if (!StringUtils.isEmpty(head)) {
+					wrapper.eq("head", head);
+				}
+												if (!StringUtils.isEmpty(nickname)) {
+					wrapper.eq("nickname", nickname);
+				}
+												if (!StringUtils.isEmpty(content)) {
+					wrapper.eq("content", content);
+				}
+												if (!StringUtils.isEmpty(image)) {
+					wrapper.eq("image", image);
+				}
+												if (!StringUtils.isEmpty(location)) {
+					wrapper.eq("location", location);
+				}
+												if (!StringUtils.isEmpty(positioning)) {
+					wrapper.eq("positioning", positioning);
+				}
+												if (!StringUtils.isEmpty(commentFlag)) {
+					wrapper.eq("comment_flag", commentFlag);
+				}
+												if (!StringUtils.isEmpty(gmtCreate)) {
+					wrapper.eq("gmt_create", gmtCreate);
+				}
+												if (!StringUtils.isEmpty(gmtUpdate)) {
+					wrapper.eq("gmt_update", gmtUpdate);
+				}
+												if (!StringUtils.isEmpty(deleteFlag)) {
+					wrapper.eq("delete_flag", deleteFlag);
+				}
+							List<CircleFriendsInfo> list = circleFriendsInfoMapper.selectList(wrapper);
+		ExcelUtil<CircleFriendsInfo> util = new ExcelUtil<CircleFriendsInfo>(CircleFriendsInfo.class);
+		return util.exportExcel(list, "操作日志");
+	}
+}

+ 5 - 3
unimall-admin/config/dev.env.js

@@ -1,6 +1,8 @@
 module.exports = {
     NODE_ENV: '"development"',
     ENV_CONFIG: '"dev"',
-    HOST: '"http://192.168.110.138:8182"',
-    BASE_API: '"http://192.168.110.138:8182/m.api"'
-}
+    // HOST: '"http://192.168.110.138:8182"',
+    // BASE_API: '"http://192.168.110.138:8182/m.api"'
+    HOST: '"https://cardapi.eliangeyun.com"',
+    BASE_API: '"https://cardapi.eliangeyun.com/m.api"'
+}

+ 98 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/domain/CircleFriendsDetail.java

@@ -0,0 +1,98 @@
+package com.iotechn.unimall.data.domain;
+
+import com.iotechn.unimall.data.domain.SuperDO;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.iotechn.unimall.core.framework.aspectj.lang.annotaion.Excel;
+import com.iotechn.unimall.core.framework.aspectj.lang.annotaion.Excel.ColumnType;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.annotations.TableName;
+import lombok.Data;
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.enums.FieldFill;
+import com.iotechn.unimall.core.util.StringUtils;
+import java.util.Date;
+
+/**
+ * 记录朋友圈互动信息对象 circle_friends_detail
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@Data
+@TableName("circle_friends_detail")
+public class CircleFriendsDetail extends SuperDO {
+    private static final long serialVersionUID = 1L;
+
+    /**  */
+    @TableId("id")
+    private Long id;
+
+    /** 朋友圈id */
+    @Excel(name = "朋友圈id")
+    @TableField("circle_friends_id")
+    private Long circleFriendsId;
+
+    /** 发表人id */
+    @Excel(name = "发表人id")
+    @TableField("common_id")
+    private Long commonId;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    @TableField("head")
+    private String head;
+
+    /** 昵称 */
+    @Excel(name = "昵称")
+    @TableField("nickname")
+    private String nickname;
+
+    /** 评论内容 */
+    @Excel(name = "评论内容")
+    @TableField("comment_content")
+    private String commentContent;
+
+    /** 回复的评论id */
+    @Excel(name = "回复的评论id")
+    @TableField("comment_id")
+    private Long commentId;
+
+    /** 标识(1点赞2评论) */
+    @Excel(name = "标识(1点赞2评论)")
+    @TableField("interaction_flag")
+    private String interactionFlag;
+
+    /**  */
+    @Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("gmt_create")
+    private Date gmtCreate;
+
+    /**  */
+    @Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("gmt_update")
+    private Date gmtUpdate;
+
+    /** 删除标识 */
+    @Excel(name = "删除标识")
+    @TableField("delete_flag")
+    private Long deleteFlag;
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("circleFriendsId", getCircleFriendsId())
+            .append("commonId", getCommonId())
+            .append("head", getHead())
+            .append("nickname", getNickname())
+            .append("commentContent", getCommentContent())
+            .append("commentId", getCommentId())
+            .append("interactionFlag", getInteractionFlag())
+            .append("gmtCreate", getGmtCreate())
+            .append("gmtUpdate", getGmtUpdate())
+            .append("deleteFlag", getDeleteFlag())
+            .toString();
+    }
+}

+ 130 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/domain/CircleFriendsInfo.java

@@ -0,0 +1,130 @@
+package com.iotechn.unimall.data.domain;
+
+import com.iotechn.unimall.data.domain.SuperDO;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.iotechn.unimall.core.framework.aspectj.lang.annotaion.Excel;
+import com.iotechn.unimall.core.framework.aspectj.lang.annotaion.Excel.ColumnType;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.annotations.TableName;
+import lombok.Data;
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.enums.FieldFill;
+import com.iotechn.unimall.core.util.StringUtils;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 记录朋友圈信息对象 circle_friends_info
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+@Data
+@TableName("circle_friends_info")
+public class CircleFriendsInfo extends SuperDO {
+    private static final long serialVersionUID = 1L;
+
+    /**  */
+    @TableId("id")
+    private Long id;
+
+    /** 圈子id */
+    @Excel(name = "圈子id")
+    @TableField("circle_id")
+    private Long circleId;
+
+    /** 朋友圈发布人id */
+    @Excel(name = "朋友圈发布人id")
+    @TableField("common_id")
+    private Long commonId;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    @TableField("head")
+    private String head;
+
+    /** 昵称 */
+    @Excel(name = "昵称")
+    @TableField("nickname")
+    private String nickname;
+
+    /** 朋友圈内容 */
+    @Excel(name = "朋友圈内容")
+    @TableField("content")
+    private String content;
+
+    /** 图片 */
+    @Excel(name = "图片")
+    @TableField("image")
+    private String image;
+
+    /** 文件类型(1图片2视频) */
+    @Excel(name = "文件类型(1图片2视频)")
+    @TableField("media_type")
+    private String mediaType;
+
+    /** 位置 */
+    @Excel(name = "位置")
+    @TableField("location")
+    private String location;
+
+    /** 定位 */
+    @Excel(name = "定位")
+    @TableField("positioning")
+    private String positioning;
+
+    /** 允许评论(1允许) */
+    @Excel(name = "允许评论", readConverterExp = "1=允许")
+    @TableField("comment_flag")
+    private String commentFlag;
+
+    /**  */
+    @Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("gmt_create")
+    private Date gmtCreate;
+
+    /**  */
+    @Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("gmt_update")
+    private Date gmtUpdate;
+
+    /** 删除标识 */
+    @Excel(name = "删除标识")
+    @TableField("delete_flag")
+    private Long deleteFlag;
+    @TableField(exist = false)
+    private List<CircleFriendsDetail> circleFriendsDetailList;
+    @TableField(exist = false)
+    private List<CircleFriendsDetail> circleFriendsDetailList1;
+    //点赞数
+    @TableField(exist = false)
+    private Integer count;
+    //评论数
+    @TableField(exist = false)
+    private Integer count1;
+    //当前登录人id
+    @TableField(exist = false)
+    private Long currentCommonId;
+    //是否点赞标识
+    @TableField(exist = false)
+    private String helpFlag;
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("commonId", getCommonId())
+            .append("head", getHead())
+            .append("nickname", getNickname())
+            .append("content", getContent())
+            .append("image", getImage())
+            .append("location", getLocation())
+            .append("positioning", getPositioning())
+            .append("commentFlag", getCommentFlag())
+            .append("gmtCreate", getGmtCreate())
+            .append("gmtUpdate", getGmtUpdate())
+            .append("deleteFlag", getDeleteFlag())
+            .toString();
+    }
+}

+ 15 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/mapper/CircleFriendsDetailMapper.java

@@ -0,0 +1,15 @@
+package com.iotechn.unimall.data.mapper;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.iotechn.unimall.data.domain.CircleFriendsDetail;
+
+/**
+ * 记录朋友圈互动信息Mapper接口
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+
+public interface CircleFriendsDetailMapper extends BaseMapper<CircleFriendsDetail> {
+
+}

+ 13 - 0
unimall-data/src/main/java/com/iotechn/unimall/data/mapper/CircleFriendsInfoMapper.java

@@ -0,0 +1,13 @@
+package com.iotechn.unimall.data.mapper;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.iotechn.unimall.data.domain.CircleFriendsInfo;
+/**
+ * 记录朋友圈信息Mapper接口
+ * 
+ * @author jlb
+ * @date 2023-05-22
+ */
+public interface CircleFriendsInfoMapper extends BaseMapper<CircleFriendsInfo> {
+
+}

+ 9 - 0
unimall-data/src/main/resources/com/iotechn/unimall/data/mapper/CircleFriendsDetailMapper.xml

@@ -0,0 +1,9 @@
+<?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.iotechn.unimall.data.mapper.CircleFriendsDetailMapper">
+    
+
+
+</mapper>

+ 9 - 0
unimall-data/src/main/resources/com/iotechn/unimall/data/mapper/CircleFriendsInfoMapper.xml

@@ -0,0 +1,9 @@
+<?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.iotechn.unimall.data.mapper.CircleFriendsInfoMapper">
+    
+
+
+</mapper>

+ 9 - 0
xiaochengxu/README.md

@@ -223,3 +223,12 @@ static/styles/index.scss
 ```
 @click.native.stop="delSearchVal"
 ```
+## showToast
+
+```
+uni.showToast({
+	icon: "success",
+	title: '保存成功!',
+	duration: 2000
+});
+```

+ 52 - 0
xiaochengxu/common/util.js

@@ -0,0 +1,52 @@
+function friendlyDate(timestamp) {
+	var formats = {
+		'year': '%n% 年前',
+		'month': '%n% 月前',
+		'day': '%n% 天前',
+		'hour': '%n% 小时前',
+		'minute': '%n% 分钟前',
+		'second': '%n% 秒前',
+	};
+
+	var now = Date.now();
+	var seconds = Math.floor((now - timestamp) / 1000);
+	var minutes = Math.floor(seconds / 60);
+	var hours = Math.floor(minutes / 60);
+	var days = Math.floor(hours / 24);
+	var months = Math.floor(days / 30);
+	var years = Math.floor(months / 12);
+
+	var diffType = '';
+	var diffValue = 0;
+	if (years > 0) {
+		diffType = 'year';
+		diffValue = years;
+	} else {
+		if (months > 0) {
+			diffType = 'month';
+			diffValue = months;
+		} else {
+			if (days > 0) {
+				diffType = 'day';
+				diffValue = days;
+			} else {
+				if (hours > 0) {
+					diffType = 'hour';
+					diffValue = hours;
+				} else {
+					if (minutes > 0) {
+						diffType = 'minute';
+						diffValue = minutes;
+					} else {
+						diffType = 'second';
+						diffValue = seconds === 0 ? (seconds = 1) : seconds;
+					}
+				}
+			}
+		}
+	}
+	return formats[diffType].replace('%n%', diffValue);
+}
+export {
+	friendlyDate
+}

+ 8 - 5
xiaochengxu/components/ossutil/uploadFile.js

@@ -12,7 +12,7 @@ const Crypto = require('./crypto.js');
  *@param - successc:成功回调
  *@param - failc:失败回调
  */ 
-const uploadFile = function (filePath, dir, successc, failc) {
+const uploadFile = function (filePath, dir, successc, failc,type) {
   if (!filePath || filePath.length < 9) {
     uni.showModal({
       title: '图片错误',
@@ -21,9 +21,12 @@ const uploadFile = function (filePath, dir, successc, failc) {
     })
     return;
   }
-  //图片名字 可以自行定义,     这里是采用当前的时间戳 + 150内的随机数来给图片命名的
-  const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';
-  
+   let aliyunFileKey=''
+  if(type=="image"){
+	     aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';
+  }else{
+	    aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.mp4';
+  }  
   const aliyunServerURL = env.uploadImageUrl;//OSS地址,需要https
   const accessid = env.OSSAccessKeyId;
   const policyBase64 = getPolicyBase64();
@@ -41,7 +44,7 @@ const uploadFile = function (filePath, dir, successc, failc) {
       'success_action_status': '200',
     },
     success: function (res) {
-			console.log(res);
+			console.log("文件地址",res);
       if (res.statusCode != 200) {
         failc(new Error('上传错误:' + JSON.stringify(res)))
         return;

+ 2 - 2
xiaochengxu/config/index.js

@@ -1,8 +1,8 @@
 const dev = {
 	// baseUrlNew: 'http://192.168.110.72:8182',
-	// baseUrlNew: 'http://192.168.110.138:8182',
+	baseUrlNew: 'http://192.168.110.138:8182',
 	// baseUrlNew: 'http://192.168.110.82:8182',
-	baseUrlNew: 'https://cardapi.eliangeyun.com',
+	// baseUrlNew: 'https://cardapi.eliangeyun.com',
 	h5Appid: 'wxb66b599f7f61b46f',
 	debug: false
 }

+ 18 - 1
xiaochengxu/pages.json

@@ -211,10 +211,27 @@
             
         }
         ,{
+
             "path" : "pages/mySet/poster",
             "style" :                                                                                    
             {
-                "navigationBarTitleText": "生成海报",
+                "navigationBarTitleText": "生成海报"
+			}
+		},
+		{
+            "path" : "pages/circle/friendSCirlce",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "动态",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/circle/addFriendCirlce",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "添加动态",
                 "enablePullDownRefresh": false
             }
             

+ 92 - 178
xiaochengxu/pages/cardHolder/cardHolder.vue

@@ -216,7 +216,7 @@
 								<image src="../../static/imgs/card/home.png" mode="widthFix"
 									style="width: 32rpx;height: auto;" @click="toHome(item)"></image>
 								<text @click='switchType(item)'
-									style="color: #fff;font-size: 36rpx;font-weight: 700;">{{item.classify?item.classifyName:'默'}}</text>
+									style="color: #fff;font-size: 36rpx;font-weight: 700;">{{item.classify?item.classifyName:'默'}}</text>
 								<image v-if='item.shareCard==1' src="../../static/imgs/card/share.png" mode="widthFix"
 									style="width: 35rpx;height: auto;" @click="share(item)"></image>
 
@@ -292,21 +292,12 @@
 		<poster :data="canvasData" background-color="#FFF" :width='750' :height='420' @on-success="posterSuccess"
 			ref="poster" @on-error="posterError"></poster>
 		<!-- #ifdef MP-WEIXIN -->
-		<!-- <u-popup :show="isPhone" mode="center" :round="10">
-			<view class='sq-view'>
-				<view class="text">
-					手机登录后才能查看名片哦~
-				</view>
-				<button class="confirm" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权手机号</button>
-			</view>
-		</u-popup> -->
 		<u-modal :show="showAuthorizePhone" :showConfirmButton="false">
 			<view class="slot-content">
 				<view class="auth-card">
 					<view class="img">
 						<img class="avatar-img" src="@/static/imgs/logo.png" mode="widthFix">
 					</view>
-					<!-- <div class="title">手机登录后才能查看名片哦~</div> -->
 					<view class="content">手机登录后才能查看名片哦~</view>
 				</view>
 				<view class="auth-btncard">
@@ -323,12 +314,12 @@
 		</u-modal>
 		<u-modal :show="showAuthorizeUser" :showConfirmButton="false">
 			<view class="slot-content">
-				<div class="auth-card">
-					<div class="img">
+				<view class="auth-card">
+					<view class="img">
 						<img class="avatar-img" src="/static/imgs/logo.png" mode="widthFix">
-					</div>
-					<div class="content">邀请您补全个人信息<br></br>(昵称、头像)</div>
-					<div style="margin-left: 100rpx;margin-right: 100rpx">
+					</view>
+					<view class="content">邀请您补全个人信息<br></br>(昵称、头像)</view>
+					<view style="margin-left: 100rpx;margin-right: 100rpx">
 						<u-form :model="userInfo" ref="uForm">
 							<u-form-item label="头像">
 								<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"
@@ -344,13 +335,16 @@
 								<!-- <input type="nickname" :value="userInfo.nickname" class="weui-input" @blur="userNameInput" placeholder="请输入昵称"/> -->
 							</u-form-item>
 						</u-form>
-					</div>
-				</div>
-				<div class="auth-btncard">
-					<div class="btn-unok"><u-button :customStyle="customStyleUnOk" @click="showAuthorizeUser=false">
-							拒绝</u-button></div>
-					<div class="btn-ok"><u-button :customStyle="customStyleOk" @click="authUser"> 允许</u-button></div>
-				</div>
+					</view>
+				</view>
+				<view class="auth-btncard">
+					<view class="btn-unok"><u-button :customStyle="customStyleUnOk" @click="authUser(0)">
+							拒绝</u-button>
+					</view>
+					<view class="btn-ok">
+						<u-button :customStyle="customStyleOk" @click="authUser(1)"> 允许</u-button>
+					</view>
+				</view>
 			</view>
 		</u-modal>
 
@@ -376,7 +370,8 @@
 			return {
 				userInfo: {
 					head: '',
-					nickname: ''
+					nickname: '',
+					phone: '',
 				},
 				downOption: {
 					auto: false,
@@ -467,12 +462,13 @@
 					}
 					console.log(that.unread)
 				})
+			} else {
+				this.showAuthorizePhone = true
 			}
 
 		},
 		onLoad: function(options) {
 			that = this
-			console.log(uni.getLaunchOptionsSync().scene, 1011)
 			if (uni.getStorageSync("userInfo").phone) {
 				this.userInfo = uni.getStorageSync("userInfo")
 				this.$nextTick(function() {
@@ -483,11 +479,6 @@
 					})
 				});
 
-			} else {
-				if (uni.getLaunchOptionsSync().scene != 1154) {
-					this.login()
-
-				}
 			}
 			this.status = uni.getLaunchOptionsSync().scene
 			if (uni.getLaunchOptionsSync().scene == 1154) {
@@ -538,21 +529,24 @@
 					})
 				})
 			},
-			authUser() {
-				if (this.userInfo.nickname == '') {
-					uni.showToast({
-						icon: "none",
-						title: '请输入您的昵称',
-						duration: 2000
-					});
-					return;
+			async authUser(type) {
+				//同步信息,没有头像和昵称自动生成
+				this.userInfo = await this.$request.syncInfo(this.userInfo)
+				if (this.userInfo.openId) {
+					uni.setStorageSync("userInfo", that.userInfo)
+					that.showAuthorizeUser = false
+					that.mescroll.resetUpScroll()
 				}
-				this.getTokenAsync1()
-
 			},
 
 			downCallback() {
-				this.mescroll.resetUpScroll()
+				if (uni.getStorageSync("userInfo").phone) {
+					this.mescroll.resetUpScroll()
+				} else {
+					that.mescroll.endBySize(0, 0)
+					this.showAuthorizePhone = true
+				}
+
 			},
 			freeTell(item) {
 				uni.makePhoneCall({
@@ -565,66 +559,13 @@
 					}
 				})
 			},
-			getPhoneNumber(e) {
-				console.log(e)
-				if (e.mp.detail.errMsg === "getPhoneNumber:ok") {
-					this.isPhone = false
-					this.params.iv = e.mp.detail.iv
-					this.params.encryptedData = e.mp.detail.encryptedData
-					this.params.session_key = this.accessToken
-					console.log(this.params)
-					let appId = 'wx5d8906c2208c899f'
-					let sessionKey = this.userInfo.sessionKey
-					let encryptedData = this.params.encryptedData
-					let iv = this.params.iv
-
-					let pc = this.$WXBizDataCrypt(appId, sessionKey)
-
-					let data = this.$WXBizDataCrypt.prototype.decryptData(encryptedData, iv, appId, sessionKey)
-
-					console.log('解密后 data: ', data)
-					this.showAuthorizePhone = false
-					this.getTokenAsync(data)
-				}
+			async getPhoneNumber(e) {
+				that.userInfo = await this.$request.wxlogin()
+				that.userInfo.phone = await this.$request.getPhone(e, that.userInfo)
+				this.showAuthorizePhone = false
+				this.showAuthorizeUser = true
 
 			},
-			async getTokenAsync(val) {
-				let that = this
-				that.userInfo.phone = val.phoneNumber
-				that.$request.baseRequest('commonUserApp', 'edit', {
-					commonUserInfo: JSON.stringify(that.userInfo)
-				}, failres => {
-					uni.showToast({
-						icon: "none",
-						title: failres.errmsg,
-						duration: 3000
-					});
-					uni.hideLoading()
-				}).then(res1 => {
-					that.userInfo = res1.data
-					uni.setStorageSync("userInfo", that.userInfo)
-					that.showAuthorizeUser = true
-					that.mescroll.resetUpScroll()
-				})
-			},
-			async getTokenAsync1() {
-				let that = this
-				that.$request.baseRequest('commonUserApp', 'edit', {
-					commonUserInfo: JSON.stringify(that.userInfo)
-				}, failres => {
-					uni.showToast({
-						icon: "none",
-						title: failres.errmsg,
-						duration: 3000
-					});
-					uni.hideLoading()
-				}).then(res1 => {
-					that.userInfo = res1.data
-					uni.setStorageSync("userInfo", that.userInfo)
-					that.showAuthorizeUser = false
-					that.mescroll.resetUpScroll()
-				})
-			},
 			delVal() {
 				this.searchVal = ""
 				this.mescroll.resetUpScroll()
@@ -1028,13 +969,6 @@
 						this.checked = false
 					}
 				}
-
-				// for(var i=0;i<this.cardList.length;i++){
-				// 	console.log(this.cardList[i].checked)
-				// 	// if(this.cardList[i].checkedList.length>0){
-				// 	// 	this.checkedList.push(i)
-				// 	// }
-				// }
 				console.log(this.checkedList)
 			},
 			remarkConfirm() {
@@ -1135,7 +1069,7 @@
 							for (var i = 0; i < res.data.items.length; i++) {
 								res.data.items[i].checked = false
 								if (res.data.items[i].classify) {
-									res.data.items[i].classifyName = res.data.items[i].classify[0]
+									res.data.items[i].classifyName = res.data.items[i].classify.substring(0,2)
 								}
 							}
 							this.cardHolderList = res.data.items
@@ -1172,48 +1106,24 @@
 
 				}
 			},
-			login() {
-				let that = this
-				uni.login({
-					"provider": "weixin",
-					success: function(wxres) {
-						that.$request.baseRequest('commonUserApp', 'commonUserLogin', {
-							loginType: 1,
-							raw: JSON.stringify(wxres)
-						}, failres => {
-							uni.showToast({
-								icon: "none",
-								title: failres.errmsg,
-								duration: 3000
-							});
-							uni.hideLoading()
-						}).then(res => {
-							console.log(res.data)
-							that.isPhone = true
-							that.showAuthorizePhone = true
-							that.userInfo = res.data
-						})
-					},
-					fail: function(err) {
-						uni.showToast({
-							icon: "none",
-							title: err.code,
-							duration: 3000
-						});
-						// 登录授权失败  
-						// err.code是错误码
-					}
-				})
-			},
 			toNotice() {
-				uni.navigateTo({
-					url: "/pages/cardHolder/notice"
-				})
+				if (this.userInfo.phone) {
+					uni.navigateTo({
+						url: "/pages/cardHolder/notice"
+					})
+				} else {
+					this.showAuthorizePhone = true
+				}
 			},
 			micOpen: function() {
-				uni.navigateTo({
-					url: "/pages/cardHolder/search?mic=1"
-				})
+				if (this.userInfo.phone) {
+					uni.navigateTo({
+						url: "/pages/cardHolder/search?mic=1"
+					})
+				} else {
+					this.showAuthorizePhone = true
+				}
+
 			},
 			uploadFile: function(tempFilePath) {
 				return new Promise((resolve, reject) => {
@@ -1232,9 +1142,13 @@
 				});
 			},
 			search() {
-				uni.navigateTo({
-					url: "/pages/cardHolder/search"
-				})
+				if (this.userInfo.phone) {
+					uni.navigateTo({
+						url: "/pages/cardHolder/search"
+					})
+				} else {
+					this.showAuthorizePhone = true
+				}
 			},
 			input(res) {
 				console.log('----input:', res)
@@ -1268,36 +1182,36 @@
 				this.type = 1
 			},
 			scan() {
-				var that = this
-				// console.log(1)
-				// uni.navigateTo({
-				// 	url: "/pages/cardHolder/scancode"
-				// })
-				uni.scanCode({
-					success: function(res) {
-						console.log('条码类型:' + res.scanType);
-						console.log('条码内容:' + res.result);
-						// console.log(res.result.split("=")[1],res.result.split("=")[1].indexOf(','),res.result.split("=")[1].split(",")[0])
-						var cardId = res.result.split("=")[1].split(",")[0]
-						that.$request.baseRequest('admin.unimall.cardHolderInfo', 'getAdded', {
-							commonId: uni.getStorageSync("userInfo").id,
-							cardId: cardId
-						}, failres => {
-							console.log('res+++++', failres.errmsg)
-							uni.showToast({
-								icon: "none",
-								title: failres.errmsg,
-								duration: 3000
-							});
-						}).then(res1 => {
-							uni.navigateTo({
-								url: "/pages/cardHolder/scanCodeAddCard?id=" + res.result
-									.split("=")[1]
+				if (uni.getStorageSync("userInfo")) {
+					uni.scanCode({
+						success: function(res) {
+							console.log('条码类型:' + res.scanType);
+							console.log('条码内容:' + res.result);
+							// console.log(res.result.split("=")[1],res.result.split("=")[1].indexOf(','),res.result.split("=")[1].split(",")[0])
+							// var cardId = res.result.split("=")[1].split(",")[0]
+							var cardId = res.result.split("=")[1]
+							that.$request.baseRequest('admin.unimall.cardHolderInfo', 'getAdded', {
+								commonId: uni.getStorageSync("userInfo").id,
+								cardId: cardId
+							}, failres => {
+								console.log('res+++++', failres.errmsg)
+								uni.showToast({
+									icon: "none",
+									title: failres.errmsg,
+									duration: 3000
+								});
+							}).then(res1 => {
+								uni.navigateTo({
+									url: "/pages/cardHolder/scanCodeAddCard?id=" + res.result
+										.split("=")[1]
+								})
 							})
-						})
-
-					}
-				});
+					
+						}
+					});
+				} else {
+					this.showAuthorizePhone = true
+				}
 			},
 			toMap(item) {
 				uni.navigateTo({
@@ -1507,7 +1421,7 @@
 			border-radius: 30rpx;
 			padding: 40rpx;
 			box-sizing: border-box;
-
+			margin-bottom: 20rpx;
 			.car-bottom {
 				position: absolute;
 				bottom: 63rpx;

+ 256 - 42
xiaochengxu/pages/cardHolder/scanCodeAddCard.vue

@@ -27,10 +27,10 @@
 								width="12px" height="13px"></u--image>
 							<view class='icon-text'>{{ cardInfo.phone }}</view>
 						</view>
-						<view @click='remarkEdit(cardInfo)' class="row2 flex" style="color: #808080">
+						<view class="row2 flex" style="color: #808080">
 							<u--image :showLoading="true" :src="'/static/imgs/card/remark'+cardInfo.icon+'.png'"
 								width="10px" height="12px"></u--image>
-							<view class='icon-text' style="color: #808080;">{{cardInfo.remark?cardInfo.remark:'单击添加备注'}}
+							<view class='icon-text' style="color: #808080;">{{cardInfo.remark?cardInfo.remark:''}}
 							</view>
 						</view>
 					</view>
@@ -59,10 +59,10 @@
 								width="12px" height="13px"></u--image>
 							<view class='icon-text'>{{ cardInfo.phone }}</view>
 						</view>
-						<view @click='remarkEdit(cardInfo)' class="row2 flex" style="color: #808080">
+						<view  class="row2 flex" style="color: #808080">
 							<u--image :showLoading="true" :src="'/static/imgs/card/remark'+cardInfo.icon+'.png'"
 								width="10px" height="12px"></u--image>
-							<view class='icon-text' style="color: #808080;">{{cardInfo.remark?cardInfo.remark:'单击添加备注'}}
+							<view class='icon-text' style="color: #808080;">{{cardInfo.remark?cardInfo.remark:''}}
 							</view>
 						</view>
 					</view>
@@ -107,11 +107,11 @@
 									width="12px" height="13px"></u--image>
 								<view class='icon-text'>{{ cardInfo.phone }}</view>
 							</view>
-							<view @click='remarkEdit(cardInfo)' class="row2 flex" style="color: #808080">
+							<view class="row2 flex" style="color: #808080">
 								<u--image :showLoading="true" :src="'/static/imgs/card/remark'+cardInfo.icon+'.png'"
 									width="10px" height="12px"></u--image>
 								<view class='icon-text' style="color: #808080;">
-									{{cardInfo.remark?cardInfo.remark:'单击添加备注'}}
+									{{cardInfo.remark?cardInfo.remark:''}}
 								</view>
 							</view>
 						</view>
@@ -152,11 +152,11 @@
 									width="12px" height="13px"></u--image>
 								<view class='icon-text'>{{ cardInfo.phone }}</view>
 							</view>
-							<view @click='remarkEdit(cardInfo)' class="row2 flex" style="color: #808080">
+							<view class="row2 flex" style="color: #808080">
 								<u--image :showLoading="true" :src="'/static/imgs/card/remark'+cardInfo.icon+'.png'"
 									width="10px" height="12px"></u--image>
 								<view :style='cardInfo.remark?"color:#000;":"color:#808080;"' class='icon-text'>
-									{{cardInfo.remark?cardInfo.remark:'单击添加备注'}}
+									{{cardInfo.remark?cardInfo.remark:''}}
 								</view>
 							</view>
 						</view>
@@ -211,12 +211,69 @@
 			<u-button @click='$u.debounce(save, 500)' text="保存" type="primary" color="#18254C"
 				:customStyle="btnStyle"></u-button>
 		</view>
-
+	<u-modal :show="showAuthorizePhone" :showConfirmButton="false">
+			<view class="slot-content">
+				<view class="auth-card">
+					<view class="img">
+						<img class="avatar-img" src="@/static/imgs/logo.png" mode="widthFix">
+					</view>
+					<!-- <div class="title">手机登录后才能查看名片哦~</div> -->
+					<view class="content">手机登录后才能查看名片哦~</view>
+				</view>
+				<view class="auth-btncard">
+					<view class="btn-unok">
+						<u-button :customStyle="customStyleUnOk" @click="showAuthorizePhone=false" :plain="true">
+							拒绝</u-button>
+					</view>
+					<view class="btn-ok">
+						<u-button :customStyle="customStyleOk" open-type="getPhoneNumber"
+							@getphonenumber="getPhoneNumber"> 立即登录</u-button>
+					</view>
+				</view>
+			</view>
+		</u-modal>
+		<u-modal :show="showAuthorizeUser" :showConfirmButton="false">
+			<view class="slot-content">
+				<view class="auth-card">
+					<view class="img">
+						<img class="avatar-img" src="/static/imgs/logo.png" mode="widthFix">
+					</view>
+					<view class="content">邀请您补全个人信息<br></br>(昵称、头像)</view>
+					<view style="margin-left: 100rpx;margin-right: 100rpx">
+						<u-form :model="userInfo" ref="uForm">
+							<u-form-item label="头像">
+								<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"
+									slot="right">
+									<image class="avatar"
+										:src="userInfo.head?userInfo.head:'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'">
+									</image>
+								</button>
+							</u-form-item>
+							<u-form-item label="昵称">
+								<u-input inputAlign='right' v-model="userInfo.nickname" class="weui-input"
+									@blur="userNameInput" placeholder="请输入昵称" border="false" />
+								<!-- <input type="nickname" :value="userInfo.nickname" class="weui-input" @blur="userNameInput" placeholder="请输入昵称"/> -->
+							</u-form-item>
+						</u-form>
+					</view>
+				</view>
+				<view class="auth-btncard">
+					<view class="btn-unok"><u-button :customStyle="customStyleUnOk" @click="showAuthorizeUser=false">
+							拒绝</u-button></view>
+					<view class="btn-ok"><u-button :customStyle="customStyleOk" @click="authUser"> 允许</u-button></view>
+				</view>
+			</view>
+		</u-modal>
 		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
+	var that;
+	import {
+		pathToBase64,
+		base64ToPath
+	} from 'image-tools'
 	import Card from '../../components/Card/Card.vue'
 	export default {
 		components: {
@@ -224,6 +281,23 @@
 		},
 		data() {
 			return {
+				showAuthorizeUser: false,
+				showAuthorizePhone: false,
+				customStyleUnOk: {
+					marginTop: '20rpx',
+					color: '#18254C',
+					border: '2px solid #18254C',
+					"border-radius": "10px",
+					fontSize: "32rpx"
+				},
+				customStyleOk: {
+					marginTop: '20rpx',
+					color: '#fff',
+					border: '2px solid #18254C',
+					"border-radius": "10px",
+					fontSize: "32rpx",
+					background: "#18254C"
+				},
 				value: '',
 				btnStyle: {
 					width:'calc(50% - 80rpx)'
@@ -239,6 +313,7 @@
 				show1: false,
 				columns: [],
 				cardList: [],
+				userInfo:{},
 				rules: {
 					'userInfo.name': {
 						type: 'string',
@@ -257,45 +332,121 @@
 			}
 		},
 		onLoad(options) {
+			uni.showToast({
+				title:options,
+				duration:'10000'
+			})
+			that = this
+			console.log(options)
 			this.id = options.id.indexOf(",") ? options.id.split(",")[0] : options.id
-			this.commonId = options.id.indexOf(",") ? options.id.split(",")[1] : ''
-			this.getList()
+			if (uni.getStorageSync("userInfo").phone) {
+				this.userInfo = uni.getStorageSync("userInfo")
+				// this.commonId = options.id.indexOf(",") ? options.id.split(",")[1] : ''
+				
+				this.getList()
+				
+			} else {
+				this.showAuthorizePhone = true
+			}
 		},
 		onShow() {
-
+			
 		},
 		methods: {
-			save() {
-				uni.showLoading({
-					title: '数据加载中',
-					mask: true
-				})
-				this.$request.baseRequest('admin.unimall.cardHolderInfo', 'add', {
-					cardHolderInfo: JSON.stringify({
-						cardId: this.cardInfo.id,
-						remark: this.cardInfo.remark,
-						cardCommonId: this.commonId,
-						myCardId: this.cardInfo.myCardId,
-						commonId: uni.getStorageSync("userInfo").id,
-						classify: this.cardInfo.classify
+			//获取昵称输入内容
+			userNameInput(e) {
+				this.userInfo.nickname = e.detail.value
+			},
+			async onChooseAvatar(e) {
+				this.$set(this.userInfo, "head", await this.toBase64(e.detail.avatarUrl))
+			},
+			toBase64(url) {
+				return new Promise(resolve => {
+					pathToBase64(url).then(path => {
+						resolve(path);
+					}).catch(error => {
+						console.log(error)
 					})
-				}, failres => {
+				})
+			},
+			async authUser(type) {
+				//同步信息,没有头像和昵称自动生成
+				this.userInfo =  await this.$request.syncInfo(this.userInfo)
+				if(this.userInfo.openId) {
+					uni.setStorageSync("userInfo", that.userInfo)
+					that.showAuthorizeUser = false
+					// that.mescroll.resetUpScroll()
+					this.getList()
+				}
+			},
+			async getPhoneNumber(e) {
+				console.log("开始登录")
+				that.userInfo = await this.$request.wxlogin()
+				console.log("结束登录",that.userInfo)
+				console.log("开始获取手机号码")
+				this.$nextTick(function() {
+					that.userInfo.phone = that.$request.getPhone(e, that.userInfo)
+					that.showAuthorizePhone = false
+					that.showAuthorizeUser = true
+					console.log("结束获取手机号码",that.userInfo.phone)
+				});
+				
+			
+			},
+			save() {
+				if(this.cardInfo.length==0){
 					uni.showToast({
 						icon: "none",
-						title: failres.errmsg,
+						title: "您还未创建名片,请前往我的先创建名片!",
 						duration: 3000
 					});
-					uni.hideLoading()
-				}).then(res => {
+					return
+				}
+				this.$request.baseRequest('admin.unimall.cardHolderInfo', 'getAdded', {
+					commonId: uni.getStorageSync("userInfo").id,
+					cardId: this.cardInfo.id,
+				}, failres => {
+					console.log('res+++++', failres.errmsg)
 					uni.showToast({
-						icon: "success",
-						title: '保存成功!',
-						duration: 2000
+						icon: "none",
+						title: failres.errmsg,
+						duration: 3000
 					});
-					uni.switchTab({
-						url: "/pages/cardHolder/cardHolder"
+				}).then(res1 => {
+					uni.showLoading({
+						title: '数据加载中',
+						mask: true
+					})
+					this.$request.baseRequest('admin.unimall.cardHolderInfo', 'add', {
+						cardHolderInfo: JSON.stringify({
+							cardId: this.cardInfo.id,
+							remark: this.cardInfo.remark,
+							cardCommonId: this.commonId,
+							myCardId: this.cardInfo.myCardId,
+							commonId: uni.getStorageSync("userInfo").id,
+							classify: this.cardInfo.classify
+						})
+					}, failres => {
+						uni.showToast({
+							icon: "none",
+							title: failres.errmsg,
+							duration: 3000
+						});
+						uni.hideLoading()
+					}).then(res => {
+						uni.showToast({
+							icon: "success",
+							title: '保存成功!',
+							duration: 2000
+						});
+						 uni.setStorageSync("scanAddCardToIndex",1)
+						uni.switchTab({
+							url: "/pages/cardHolder/cardHolder"
+					
+						})
 					})
 				})
+				
 			},
 			cancel() {
 				uni.switchTab({
@@ -315,8 +466,8 @@
 				this.value = e.value[0].circleName.substring(0,1)
 				this.show = false
 			},
-			getList() {
-				this.$request.baseRequest('admin.unimall.cardManagementInfo', 'get', {
+			async getList() {
+				await this.$request.baseRequest('admin.unimall.cardManagementInfo', 'get', {
 					id: this.id
 				}, failres => {
 					console.log('res+++++', failres.errmsg)
@@ -327,14 +478,20 @@
 					});
 					uni.hideLoading()
 				}).then(res => {
-					console.log(res, "this.cardInfo")
+					console.log("this.cardInfo",res)
 					this.cardInfo = res.data
-					this.cardInfo.cardBusiness = ''
+					// if(this.cardInfo.length==0){
+					// 	uni.showToast({
+					// 		icon: "none",
+					// 		title: "您还未创建名片,请前往我的先创建名片!",
+					// 		duration: 3000
+					// 	});
+					// }
+					// this.cardInfo.cardBusiness = ''
 					// this.cardInfo.cardCommonId = res.data.commonId
 					console.log(res)
 				})
-				console.log(uni.getStorageSync("userInfo").id, 111111)
-				this.$request.baseRequest('admin.unimall.cardManagementInfo', 'list', {
+				await this.$request.baseRequest('admin.unimall.cardManagementInfo', 'list', {
 					commonId: uni.getStorageSync("userInfo").id
 				}, failres => {
 					uni.showToast({
@@ -344,9 +501,12 @@
 					});
 					uni.hideLoading()
 				}).then(res => {
-					this.cardList = [res.data.cardInfos]
+					this.cardList = [res.data.items]
+					this.cardInfo.cardBusiness = res.data.items[0].cardBusiness
+					this.cardInfo.myCardId = res.data.items[0].id
+					
 				})
-				this.$request.baseRequest('admin.unimall.cardClassifyInfo', 'list', {
+				await this.$request.baseRequest('admin.unimall.cardClassifyInfo', 'list', {
 					page: 1,
 					limit: 9999,
 					commonId: uni.getStorageSync("userInfo").id
@@ -604,4 +764,58 @@
 	.icon-text{
 		margin-left: 20rpx;
 	}
+	.slot-content {
+		width: 100%;
+	}
+	
+	.auth-btncard {
+		display: flex !important;
+		justify-content: space-between !important;
+	
+		.btn-unok {
+			width: 40%;
+		}
+	
+		.btn-ok {
+			width: 40%;
+		}
+	}
+	
+	.auth-card {
+		text-align: center;
+	
+		.avatar-img {
+			width: 250rpx;
+		}
+	
+		.title {
+			font-size: 20rpx;
+		}
+	
+		.content {
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #1A1A1A;
+			margin-bottom: 30rpx;
+		}
+	}
+	
+	.avatar-wrapper {
+		color: #333 !important;
+		border: none !important;
+		border-radius: 0 !important;
+		background-color: transparent !important;
+		padding: 0;
+	}
+	
+	.avatar-wrapper::after {
+		border: none !important;
+	}
+	
+	.avatar {
+		width: 100rpx;
+		height: 100rpx;
+		overflow: hidden;
+		border-radius: 100%;
+	}
 </style>

+ 13 - 8
xiaochengxu/pages/cardHolder/search.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<d-search-log :placeholder="'搜索名片'" :color_border="color_border" :color_text="color_border"
-			:search_list_old_man_num='15' :search_list_hot="search_list_hot" :store_key="store_key"
+			:search_list_old_man_num='15' :search_list_hot="search_list_hot" :store_key="store_key" :input_text="input_text"
 			@onClickDelAllApi="onClickDelAll" @onSearchNameApi="onSearchName" @onSearchvoiceApi='onSearchvoice'></d-search-log>
 		<u-popup :show="isRecorderManager" mode="bottom">
 			<view class="shqx" v-if="longPress == '2'">
@@ -51,7 +51,8 @@
 				store_key: 'search_list',
 				isRecorderManager: false,
 				is_clock: true,
-				startPoint: ""
+				startPoint: "",
+				input_text:""
 			};
 		},
 		onLoad(options) {
@@ -100,16 +101,21 @@
 				console.log("录音结束")
 				let that = this
 				this.longPress = '1'; 
+				that.isRecorderManager = false
 				recorderManager.onStop((res) => {
 					this.tempFilePath = res.tempFilePath
 					let _file = ''
 					if (that.is_clock) {
 						_file = uni.getFileSystemManager().readFileSync(res.tempFilePath, "base64")
 						console.log(_file)
+						uni.showLoading({
+							title:"正在识别"
+						})
 						that.$request.baseRequest('admin.unimall.certificateManagementInfo', 'speechRecognition', {
 							voiceMessage: _file,
 						}, failres => {
 							console.log('res+++++', failres.errmsg)
+							uni.hideLoading()
 							uni.showToast({
 								icon:"none",
 								title: failres.errmsg,
@@ -123,12 +129,12 @@
 							}else{
 								var text = res.data.text
 							}
-							
-							uni.setStorageSync('search_val', text);
-							uni.switchTab({
-								url: "/pages/cardHolder/cardHolder"
+							that.input_text = text
+							// uni.setStorageSync('search_val', text);
+							// uni.switchTab({
+							// 	url: "/pages/cardHolder/search"
 
-							})
+							// })
 
 						})
 					}
@@ -146,7 +152,6 @@
 				uni.setStorageSync('search_val', text);
 				uni.switchTab({
 					url: "/pages/cardHolder/cardHolder"
-
 				})
 			}
 		}

+ 155 - 0
xiaochengxu/pages/circle/addFriendCirlce.vue

@@ -0,0 +1,155 @@
+<template>
+	<view class="content">
+		<view class="row1">
+			<u-input placeholder="这一刻得想法..." focus :border="false" v-model="formData.content"></u-input>
+		</view>
+		<view class="row2">
+			<cl-upload v-model="fileList" @onSuccess="onSuccess" @showType='getShowType($event)'></cl-upload>
+		</view>
+		<view class="row3 flex flex-between" @click="selectPlace">
+			<view class="left flex">
+				<u-icon name="map-fill" color="#112253" size="18"></u-icon>
+				<text style="margin:0 20rpx;">{{formData.location?formData.location:'所在位置'}}</text>
+			</view>
+			<view class="right">
+				<u-icon name="arrow-right" color="#112253" size="20"></u-icon>
+			</view>
+		</view>
+		<view class="row4 flex flex-between">
+			<view class="left flex">
+				<u-icon name="pushpin" color="#112253" size="18"></u-icon>
+				<text style="margin:0 20rpx;">开启评论</text>
+				<u-switch v-model="switchStatus" activeColor="#112253" @change="change($event,1)" size="20"></u-switch>
+			</view>
+			<view class="right">
+				<u-icon name="arrow-right" color="#112253" size="20"></u-icon>
+			</view>
+		</view>
+		<view @click="submit" class="submit">提交</view>
+	</view>
+</template>
+
+<script>
+	var that;
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	export default {
+		data() {
+			return {
+				userInfo: {},
+				switchStatus: true,
+				fileList: [],
+				formData: {
+					commonId: '',
+					head: '',
+					nickname: '',
+					content: '',
+					image: '',
+					location: '',
+					commentFlag: '',
+					positioning:'',
+					circleId:'',
+					mediaType:''
+					
+				}
+			};
+		},
+		onShow() {
+			this.userInfo = uni.getStorageSync("userInfo")
+		},
+		onLoad(options) {
+			that = this
+			this.formData.circleId = options.id
+		},
+		methods: {
+			getShowType(type){debugger
+			console.log("文件类型",type)
+				this.mediaType = type
+			},
+			onSuccess(reslut) {
+				// 把服务端返回的图片地址添加到list中与组件数据同步
+				this.fileList.push(reslut)
+			},
+			submit() {debugger
+				this.formData.commonId = this.userInfo.id
+				this.formData.head = this.userInfo.head
+				this.formData.nickname = this.userInfo.nickname
+				this.formData.image = this.fileList.toString()
+				this.formData.mediaType = this.mediaType
+				if (this.switchStatus) {
+					this.formData.commentFlag  = 1
+				} else {
+					this.formData.commentFlag  = 0
+				}
+				if (!this.formData.content) {
+					uni.showToast({
+						icon: "none",
+						title: '内容不能为空!',
+						duration: 2000
+					});
+					return
+				}
+				this.$request.baseRequest('admin.unimall.circleFriendsInfo', 'add', {
+					circleFriendsInfo: JSON.stringify(this.formData)
+				}, failres => {
+					uni.showToast({
+						icon: "none",
+						title: failres.errmsg,
+						duration: 3000
+					});
+
+					uni.hideLoading()
+				}).then(res => {
+					debugger
+				})
+				uni.showToast({
+					icon: "success",
+					title: '保存成功!',
+					duration: 2000
+				});
+				setTimeout(() => {
+					uni.navigateBack()
+				}, 2000)
+			},
+			selectPlace() {
+				uni.chooseLocation({
+					success: function(res) {
+						that.formData.location = res.address
+						console.log('位置名称:' + res.name);
+						console.log('详细地址:' + res.address);
+						console.log('纬度:' + res.latitude);
+						console.log('经度:' + res.longitude);
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content {
+		background-color: #fff;
+		padding: 40rpx;
+
+		.row2,
+		.row3 {
+			border-bottom: 1px solid #E6E6E6;
+			padding: 30rpx 0;
+		}
+
+		.row4 {
+			padding-top: 30rpx;
+		}
+	}
+
+	.submit {
+		position: fixed;
+		bottom: 100rpx;
+		background: #112253;
+		color: #fff;
+		width: calc(100% - 80rpx);
+		padding: 20rpx;
+		box-sizing: border-box;
+		text-align: center;
+		border-radius: 20rpx;
+	}
+</style>

+ 515 - 0
xiaochengxu/pages/circle/circle-item.vue

@@ -0,0 +1,515 @@
+<template>
+	<!-- <mescroll-uni :ref="'mescrollRef' + i" @init="mescrollInit" :height="height" :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick" @scroll="scroll"> -->
+	<view class="u-demo-block">
+		<view class="u-demo-block__content" v-for="(item, index) in list" :key="index" @touchstart="click">
+			<view class="album" style="padding: 30upx;">
+					<image :src="item.head" mode="" style="width: 80upx;height: 80upx;border-radius: 10rpx;"></image>
+				<view class="album__content">
+					<view class="album__info">
+						<text class="info-name" @click="toDetail(item)">{{ item.nickname }}</text>
+						<text class="info-content" @click="toDetail(item)">{{ item.content }}</text>
+						<template v-if="item.mediaType == 1">
+							<u-album v-if="item.urlList && item.urlList.length > 0" :urls="item.urlList" multipleSize="90" space='10'></u-album>
+							<u-album v-else :urls="item.urlList"></u-album>
+						</template>
+						<view v-else class="video">
+								<video v-show="isShowVideo"
+									class="video-info"
+									:show-center-play-btn="false"
+									:src="item.image"
+									id="myVideo"
+									:autoplay="true"
+									:loop="true"
+									:controls= "true"
+								></video>
+							<view v-if="item.direction==1&&!isShowVideo" class="relative">
+								<image :src="item.image + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast,ar_auto'" mode="aspectFill" style="width: 424rpx;height:320rpx"></image>
+								<image class="cover" src="/static/play.png" @click="playVideo"></image>
+							</view>
+							<view v-if="item.direction==2&&!isShowVideo" class="relative">
+								<image :src="item.image + '?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast,ar_auto'" mode="aspectFill" style="width: 320rpx;height:424rpx"></image>
+								<image class="cover1" src="/static/play.png" @click="playVideo"></image>
+							</view>
+						</view>
+					</view>
+					<view class="location" v-if="item.location">
+						<view class="location-left">
+							<text class="location-left-name">{{ item.location }}</text>
+						</view>
+					</view>
+					<view class="time">
+							<text class="time-text">{{$u.timeFrom(new Date(item.gmtCreate).getTime(),'yyyy年mm月dd日')}}</text>
+						</view>
+					<view class="comment">
+						<text class="time-text">{{ item.dateTime }}</text>
+						<view class="comment-right">
+							<view class="comment-item" @click="doThumb(item, index)">
+								<image class="image-love" :src="item.helpFlag==1 ? '../../static/love-fill.png' : '../../static/love.png'"></image>
+								<text class="number">{{ item.count }}</text>
+							</view>
+							<view class="comment-item" @click="doComment(item, null, index)">
+								<image class="image-comment" src="../../static/comment.png"></image>
+								<text class="number">{{ item.count1 }}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="thumb-comment" v-if="item.circleFriendsDetailList&&(item.circleFriendsDetailList.length > 0 || item.comments.circleFriendsDetailList.length > 0)">
+				<view class="thumbs" v-if="item.circleFriendsDetailList&&item.circleFriendsDetailList.length > 0">
+					<image class="image-love thumbs-icon" src="../../static/love.png"></image>
+					<view class="thumbs-headers">
+						<view class="thumbs-headers-img" v-for="(item2, index2) in item.circleFriendsDetailList" :key="index2">
+							<view class="thumbs-item">
+								<text class="thumbs-name">{{ item2.nickname }}</text>
+								<text class="thumbs-name" v-if="index2 != item.circleFriendsDetailList.length - 1">,</text>
+							</view>
+						</view>
+						<text class="thumbs-headers-img thumbs-headers-more" v-if="item.circleFriendsDetailList.length > 20">等</text>
+					</view>
+				</view>
+			<!-- 	<view class="comments" v-if="item.comments.records.length > 0">
+					<image class="image-comment comments-icon" src="../../static/comment.png"></image>
+					<view class="comments-headers">
+						<view class="comments-headers-item" v-for="(item3, index3) in item.comments.records" :key="index3">
+							<view class="item-left">
+								<u-avatar :src="item3.userAvatar" shape="square" size="32" @click="onJump('/pages/friends/friendInfo?friendId=' + item3.userId)"></u-avatar>
+							</view>
+							<view class="item-right">
+								<view class="item-right-name">
+									<text class="item-right-name-top">{{ item3.userName }}</text>
+									<text class="item-right-name-bottom">{{ item3.createTime }}</text>
+								</view>
+								<view class="comment-content">
+									<view class="comment-response" v-if="item3.comUserName">
+										<text class="comment-response-txt">回复</text>
+										<text class="comment-response-name">{{ item3.comUserName }}</text>
+										<text class="comment-response-txt">:</text>
+									</view>
+									<text class="item-right-info" @click="doComment(item, item3, index)">{{ item3.comment }}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view> -->
+			</view>
+			<u-line></u-line>
+		</view>
+	</view>
+	<!-- </mescroll-uni> -->
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex';
+import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
+import MescrollMoreItemMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js';
+// import { apiGoods } from '@/api/mock.js';
+
+export default {
+	mixins: [MescrollMixin, MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
+	data() {
+		return {
+			isShowVideo:false,
+			videoContext:'',
+			downOption: {
+				auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+			},
+			upOption: {
+				onScroll: true,
+				auto: false, // 不自动加载
+				// page: {
+				// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+				// 	size: 10 // 每页数据的数量
+				// },
+				noMoreSize: 5, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
+				empty: {
+					tip: '空空如也', // 提示
+					icon: 'http://cdn.uviewui.com/uview/empty/data.png'
+				}
+			},
+			showInput: false
+		};
+	},
+	props: {
+		list: {
+			type: Array,
+			default: function(e) {
+				return [];
+			}
+		}
+	},
+
+	computed: {
+		...mapState(['locateInformation'])
+	},
+
+	created() {},
+
+	filters: {
+		formatDistance(distance) {
+			var strDistance = '';
+			if (distance < 1) {
+				//一公里以内的
+				strDistance = distance * 1000 + 'm';
+			} else {
+				distance = distance.toFixed(1);
+				strDistance = distance + 'km';
+			}
+			return strDistance;
+		}
+	},
+
+	methods: {
+		playVideo(val) {
+			this.isShowVideo = true
+			console.log('--play--');
+			// 点击显示全屏
+			this.videoContext = uni.createVideoContext('myVideo')
+			this.videoContext.requestFullScreen();
+		},
+
+		onJump(url) {
+			uni.navigateTo({
+				url: url
+			});
+		},
+
+		toDetail(item) {
+			uni.navigateTo({
+				url: '/pages/circle/circleDetail?item=' + JSON.stringify(item)
+			});
+		},
+
+		click() {
+			this.$emit('click');
+		},
+
+		doThumb(item, index) {
+			item.index = index;
+			this.$emit('doThumb', item);
+		},
+
+		doComment(item, comment, index) {
+			item.index = index;
+			this.$emit('doComment', item, comment);
+		},
+
+		doComment2Com(item, comment) {
+			this.$emit('doComment2Com', item, comment);
+		}
+	}
+};
+</script>
+<style lang="scss">
+.view {
+	flex-direction: column;
+}
+.album {
+	display: flex;
+	flex-direction: row;
+	align-items: flex-start;
+}
+.album__avatar {
+	background-color: #fff;
+	padding: 5px;
+	border-radius: 3px;
+}
+.album__content {
+	margin-left: 10px;
+	flex: 1;
+}
+.album__info {
+	margin-bottom: 15upx;
+	display: flex;
+	flex-direction: column;
+}
+.info-name {
+	color: #5786cc;
+	font-size: 30upx;
+	font-weight: bold;
+}
+.info-content {
+	color: #333;
+	font-size: 30upx;
+	padding: 5px 0 8px 0;
+}
+.video {
+	position: relative;
+	image {
+		width: 100%;
+		height: 180px;
+	}
+	.cover {
+	width: 50px;
+	    height: 50px;
+	    position: absolute;
+	    z-index: 5;
+	    left: -180rpx;
+	    right: 0;
+	    bottom: 0;
+	    top: 0;
+	    margin: auto;
+	}
+	.cover1 {
+	width: 50px;
+	    height: 50px;
+	    position: absolute;
+	    z-index: 5;
+	    left: -270rpx;
+	    right: 0;
+	    bottom: 0;
+	    top: 0;
+	    margin: auto;
+	}
+}
+.video-info {
+	width: 280px;
+	height: 200px;
+}
+.video-cover {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 270px;
+	height: 200px;
+}
+.location {
+}
+.location-left {
+	display: flex;
+	flex-direction: row;
+}
+.location-left-name {
+	font-size: 24upx;
+	color: #5786cc;
+}
+.location-left-distance {
+	margin-left: 30upx;
+	font-size: 24upx;
+	color: #5786cc;
+}
+
+.location-right {
+	color: #999;
+	font-size: 24upx;
+}
+
+.time-text {
+	color: #666;
+	font-size: 24upx;
+}
+
+.comment {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	justify-content: space-between;
+	margin-top: 15upx;
+}
+
+.comment-right {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	justify-content: center;
+}
+
+.comment-item {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	margin-left: 40upx;
+	color: #666;
+}
+
+.image-love {
+	width: 32upx;
+	height: 32upx;
+	margin-right: 6upx;
+}
+.image-comment {
+	width: 30upx;
+	height: 30upx;
+	margin-right: 8upx;
+}
+
+.number {
+	color: #666;
+	padding-left: 5upx;
+	font-size: 26upx;
+}
+.yzb {
+	margin-right: 8upx;
+}
+.yzb-pinglun1 {
+}
+.thumb-on {
+	font-size: 32upx;
+	color: red;
+}
+.thumb-off {
+	font-size: 32upx;
+}
+
+.thumb-comment {
+	padding: 20upx;
+}
+.thumbs {
+	padding: 20upx;
+	border-radius: 10upx;
+	background-color: #f8f8f8;
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+}
+.thumbs-icon {
+	margin-right: 10upx;
+	color: #666;
+	/* margin-top: 5upx; */
+}
+
+.thumbs-headers {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	overflow: hidden;
+	white-space: nowrap;
+	flex-wrap: wrap;
+	flex: 1;
+}
+.thumbs-headers-img {
+	margin-left: 10upx;
+	margin-bottom: 10upx;
+}
+
+.thumbs-headers-more {
+	font-size: 30upx;
+	color: #999;
+}
+
+.thumbs-item {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+}
+
+.thumbs-name {
+	font-size: 28upx;
+	color: #5786cc;
+}
+
+.comments {
+	margin-top: 1upx;
+	padding: 20upx;
+	border-radius: 10upx;
+	background-color: #f8f8f8;
+	display: flex;
+	flex-direction: row;
+}
+.comments-icon {
+	margin-right: 10upx;
+	color: #666;
+	margin-top: 15upx;
+	font-size: 24upx;
+}
+.comments-headers {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+}
+.comments-headers-item {
+	flex: 1;
+	display: flex;
+	flex-direction: row;
+	/* align-items: center; */
+	margin-bottom: 20upx;
+}
+.item-left {
+	margin: 0 10upx;
+	margin-top: 10upx;
+}
+.item-right {
+	margin-left: 5upx;
+	display: flex;
+	flex: 1;
+	flex-direction: column;
+}
+.item-right-name {
+	display: flex;
+	flex: 1;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+}
+.item-right-name-top {
+	color: #5786cc;
+	font-size: 26upx;
+}
+.item-right-name-bottom {
+	font-size: 24upx;
+	color: #999;
+	margin-top: 10upx;
+}
+.item-right-info {
+	font-size: 28upx;
+	color: #333;
+	flex: 1;
+}
+
+.comment-content {
+	display: flex;
+	flex-direction: row;
+	align-items: flex-start;
+	margin-top: 3upx;
+	flex: 1;
+}
+.comment-response {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	margin-right: 10upx;
+}
+.comment-response-txt {
+	font-size: 28upx;
+}
+.comment-response-name {
+	font-size: 28upx;
+	color: #5786cc;
+	padding: 0 8upx;
+}
+
+.bottom {
+	bottom: 0;
+	position: fixed;
+	height: 120rpx;
+	width: 100%;
+	padding: 0 20rpx;
+	box-sizing: border-box;
+	background-color: #f8f8f8;
+	align-items: center;
+	justify-content: center;
+	display: flex;
+
+	.bottom-bt {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		input {
+			width: 550rpx;
+			height: 70rpx;
+			padding: 0 15rpx;
+			border-radius: 10rpx;
+			background-color: #fff;
+			margin-right: 20rpx;
+		}
+		button {
+			padding: 0 20rpx;
+			height: 60rpx;
+			line-height: 60rpx;
+			background-color: #12ae85;
+			color: #fff;
+			font-size: 28rpx;
+		}
+	}
+}
+</style>

+ 363 - 22
xiaochengxu/pages/circle/detail.vue

@@ -2,8 +2,14 @@
 	<view class="content">
 		<view class="bgc">
 			<view class="content1">
-				<view class="left">
-					<image :src="dataObj.circleHead" mode="aspectFill" class="img"></image>
+				<view class="left relative">
+					<image :src="dataObj.circleHead?dataObj.circleHead:'../../static/imgs/logo.png'" mode="aspectFill" class="img"></image>
+					<view class="share">
+						<button class="shareBtn" type="default" data-name="shareBtn" open-type="share">
+							<image style='width:30rpx;height:30rpx;position: absolute;top: 2px;right: 2px;' src="@/static/imgs/share1.png" mode="aspectFill">
+							</image>
+						</button>
+					</view>
 				</view>
 				<view class="right">
 					<view  class="top flex flex-between">
@@ -32,18 +38,30 @@
 						<span @click="changeCardStatus(1)" :class="selectIndex==1?'active':'text'">已交换</span>
 						<span @click="changeCardStatus(2)" :class="selectIndex==2?'active':'text'">未交换</span>
 					</view>
-					<view class="right flex" v-if="dataObj.circleCardInfo" @click="myCardClick">
-						<image src="../../static/imgs/cirlce/account.png" mode="widthFix"
-							style="width: 36rpx;margin-right: 15rpx;height: auto;"></image>我的名片
+					<view class="right flex">
+					<!-- 	<view class="flex"  v-if="dataObj.circleCardInfo" @click="myCardClick">
+							<image src="../../static/imgs/cirlce/account.png" mode="widthFix"
+								style="width: 36rpx;margin-right: 15rpx;height: auto;"></image>我的名片
+						</view> -->
+						<view class="">
+							<image src="../../static/imgs/card/share1.png" mode="widthFix"
+								style="width: 50rpx;margin-left: 30rpx;height: 50rpx;" @click="toFriendsCirlce()"></image>
+							<image src="../../static/imgs/card/buju1.png" mode="widthFix"
+								style="width: 50rpx;margin-left: 30rpx;height: 50rpx;" @click="change()"></image>
+			<!-- 				<image src="../../static/imgs/card/buju1.png" mode="widthFix"
+								style="width: 50rpx;margin-left: 30rpx;height: 50rpx;" v-if="layout==1" @click="changeLayout(2)"></image> -->
+						<!-- 		<image src="../../static/imgs/card/buju2.png" mode="widthFix"
+									style="width: 50rpx;margin-left: 30rpx;height: 50rpx;" v-if="layout==2" @click="changeLayout(1)"></image> -->
+						</view>
 					</view>
 				</view>
 			</view>
 		</view>
 		<view  class="relative" style='top:150px;'>
-			<mescroll-uni height='1200' :up="upOption" ref="mescrollRef" @init="mescrollInit" @up="upCallback" @down="downCallback" >
+			<mescroll-uni height='1200' :up="upOption" :down="downOption" ref="mescrollRef" @init="mescrollInit" @up="upCallback" @down="downCallback" >
 			<view class="content3" v-for="(item,index) in changeCardList"
 				:style="item.currentBackground?'background:url('+item.currentBackground+');background-size:100% 100%':''"
-				:key="index">
+				:key="index" v-if="layout">
 				<view class="flex item">
 					<view class="top flex">
 						<view class="left">
@@ -72,17 +90,44 @@
 					暂无业务描述
 				</view>
 				<view class="flex btn" v-if="item.lookPage==1||item.notDisplay!=1">
-					<image @click='toHome(item)' src="../../static/imgs/cirlce/home.png" mode="widthFix" style="width: 32rpx;"
+					<image @click='toHome(item)' src="../../static/imgs/cirlce/home.png" mode="widthFix" style="width: 32rpx;height: auto;"
 						v-if="item.lookPage==1&&item.personalHomeId"></image>
-					<image src="../../static/imgs/cirlce/change.png" mode="widthFix" style="width: 32rpx;"
+					<image src="../../static/imgs/cirlce/change.png" mode="widthFix" style="width: 32rpx;;height: auto"
 						@click="changeCard(item)" v-if="item.notDisplay!=1"></image>
 				</view>
 			</view>
+			<view class="layout2" v-if="!layout">
+				<view class="list_box">
+					<view class="list-item" v-for="(item,index) in changeCardList" :key="index" @click="itemClick(item,index)">
+						<view class="left">
+							<view class="icon-box">
+								<image :src="item.headSculpture?item.headSculpture:'https://cdn.uviewui.com/uview/album/1.jpg'" style="width: 70rpx;height:70rpx;border-radius: 20rpx;"></image>
+							</view>
+							<view class="name">
+								{{item.name}}
+							</view>
+							<view class="name">
+								{{item.post}}
+							</view>
+						</view>
+						<view class="right">
+							<view class="flex btn" v-if="item.lookPage==1||item.notDisplay!=1">
+								<image @click='toHome(item)' src="../../static/imgs/cirlce/home.png" mode="widthFix" style="width: 32rpx;height: auto;"
+									v-if="item.lookPage==1&&item.personalHomeId"></image>
+								<image src="../../static/imgs/cirlce/change.png" mode="widthFix" style="width: 32rpx;;height: auto;margin-left: 20rpx;"
+									@click="changeCard(item)" v-if="item.notDisplay!=1"></image>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
 		</mescroll-uni>
 		</view>
 		
 		<u-picker :immediateChange ="true" @cancel="isShowCard=false" :show="isShowCard" :columns="cardList" keyName="cardBusiness"
 			@confirm="cardConfirm"></u-picker>
+			<u-picker :immediateChange ="true" @cancel="changeMore=false" :show="changeMore" :columns="moreList" keyName="name"
+				@confirm="changeMoreConfirm"></u-picker>
 		<u-toast ref="uToast"></u-toast>
 		<u-modal :show="show" :content='content' @confirm="$u.debounce(joinCircle, 500)" showCancelButton
 			@cancel="show=false" @close="show=false" closeOnClickOverlay></u-modal>
@@ -91,26 +136,123 @@
 		<u-modal :show="isShowChangeCard" content='确定交换名片?' @confirm="$u.debounce(confirmChangeSubmit, 500)"
 			showCancelButton @cancel="isShowChangeCard=false" @close="isShowChangeCard=false"
 			closeOnClickOverlay></u-modal>
+			<!-- #ifdef MP-WEIXIN -->
+			<u-modal :show="showAuthorizePhone" :showConfirmButton="false">
+				<view class="slot-content">
+					<view class="auth-card">
+						<view class="">
+							<img class="avatar-img" src="@/static/imgs/logo.png" mode="widthFix">
+						</view>
+						<view class="content">手机登录后才能查看名片哦~</view>
+					</view>
+					<view class="auth-btncard">
+						<view class="btn-unok">
+							<u-button :customStyle="customStyleUnOk" @click="showAuthorizePhone=false" :plain="true">
+								拒绝</u-button>
+						</view>
+						<view class="btn-ok">
+							<u-button :customStyle="customStyleOk" open-type="getPhoneNumber"
+								@getphonenumber="getPhoneNumber"> 立即登录</u-button>
+						</view>
+					</view>
+				</view>
+			</u-modal>
+			<u-modal :show="showAuthorizeUser" :showConfirmButton="false">
+				<view class="slot-content">
+					<view class="auth-card">
+						<view class="">
+							<img class="avatar-img" src="/static/imgs/logo.png" mode="widthFix">
+						</view>
+						<view class="content">邀请您补全个人信息<br></br>(昵称、头像)</view>
+						<view style="margin-left: 100rpx;margin-right: 100rpx">
+							<u-form :model="userInfo" ref="uForm">
+								<u-form-item label="头像">
+									<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"
+										slot="right">
+										<image class="avatar"
+											:src="userInfo.head?userInfo.head:'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'">
+										</image>
+									</button>
+								</u-form-item>
+								<u-form-item label="昵称">
+									<u-input inputAlign='right' v-model="userInfo.nickname" class="weui-input"
+										@blur="userNameInput" placeholder="请输入昵称" border="false" />
+									<!-- <input type="nickname" :value="userInfo.nickname" class="weui-input" @blur="userNameInput" placeholder="请输入昵称"/> -->
+								</u-form-item>
+							</u-form>
+						</view>
+					</view>
+					<view class="auth-btncard">
+						<view class="btn-unok"><u-button :customStyle="customStyleUnOk" @click="authUser(0)">
+								拒绝</u-button>
+						</view>
+						<view class="btn-ok">
+							<u-button :customStyle="customStyleOk" @click="authUser(1)"> 允许</u-button>
+						</view>
+					</view>
+				</view>
+			</u-modal>
+			<!-- #endif -->
 	</view>
 </template>
 
 <script>
+	var that;
+	import {
+		pathToBase64,
+		base64ToPath
+	} from 'image-tools'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin], // 使用mixin
 		data() {
 			return {
+				moreList:[
+					[
+						{
+							"name":'切换名片'
+						},
+						{
+							"name":'更换布局'
+						}
+					]
+				],
+				changeMore:false,
+				layout:true,
+				showAuthorizeUser: false,
+				showAuthorizePhone: false,
+				customStyleUnOk: {
+					marginTop: '20rpx',
+					color: '#18254C',
+					border: '2px solid #18254C',
+					"border-radius": "10px",
+					fontSize: "32rpx"
+				},
+				customStyleOk: {
+					marginTop: '20rpx',
+					color: '#fff',
+					border: '2px solid #18254C',
+					"border-radius": "10px",
+					fontSize: "32rpx",
+					background: "#18254C"
+				},
+				userInfo: {
+					head: '',
+					nickname: '',
+					phone: '',
+				},
+				downOption: {
+					auto: false,
+					textColor: '#bbb'
+				},
 				upOption: {
 					page: {
 						size: 10 // 每页数据的数量,默认10
 					},
 					auto: false,
 					noMoreSize: 1,
-					empty: {
-						tip: '暂无相关数据'
-					},
-					textNoMore:'没有更多了~',
-					textColor:'#bbb'
+					textNoMore: '没有更多了~',
+					textColor: '#bbb'
 				},
 				selectIndex: 0,
 				isShowChangeCard: false,
@@ -120,7 +262,6 @@
 					cardNum: '',
 					circleLabel: []
 				},
-				userInfo: {},
 				canReset: false,
 				cardList: [],
 				isShowCard: false,
@@ -137,18 +278,87 @@
 			};
 		},
 		onShow() {
-			this.$nextTick(function() {
-				this.canReset && this.mescroll.resetUpScroll() // 重置列表数据为第一页  
-				this.canReset && this.mescroll.scrollTo(0, 0) // 重置列表数据为第一页时,建议把滚动条也重置到顶部,避免无法再次翻页的问题  
-				this.canReset = true // 过滤第一次的onShow事件,避免初始化界面时重复触发upCallback, 无需配置auto:false
-			});
+			if (uni.getStorageSync("userInfo").phone) {
+				this.$nextTick(function() {
+					that.mescroll.resetUpScroll() 
+				});
+			}else {
+				this.showAuthorizePhone = true
+			}
 		},
 		onLoad(options) {
+			that = this
 			console.log(options)
+				this.id = options.val
 			this.userInfo = uni.getStorageSync("userInfo")
-			this.id = options.val
+			
+		},
+		onShareAppMessage(res) {
+			if (res.from === 'button') {
+				let path = `/pages/circle/detail?val=${that.dataObj.id}`
+				return {
+					title:`${that.userInfo.nickname}邀请您加入${that.dataObj.circleName}圈子`,
+					path: path,
+				};
+			}
 		},
 		methods: {
+			toFriendsCirlce(){
+				uni.navigateTo({
+					url:"/pages/circle/friendSCirlce?id="+this.dataObj.id
+				})
+			},
+			changeMoreConfirm(val){
+				console.log(val)
+				if(val.value[0].name=="切换名片"){
+					this.isShowCard = true
+					this.isMyCard = true
+				}else{
+					this.layout = !this.layout
+				}
+				
+				this.changeMore = false
+			},
+			change(){
+				this.changeMore = true
+			},
+			changeLayout(type){
+				
+			},
+			//获取昵称输入内容
+			userNameInput(e) {
+				this.userInfo.nickname = e.detail.value
+			},
+			async onChooseAvatar(e) {
+				this.$set(this.userInfo, "head", await this.toBase64(e.detail.avatarUrl))
+			},
+			toBase64(url) {
+				return new Promise(resolve => {
+					pathToBase64(url).then(path => {
+						resolve(path);
+					}).catch(error => {
+						console.log(error)
+					})
+				})
+			},
+			async authUser(type) {
+				//同步信息,没有头像和昵称自动生成
+				this.userInfo = await this.$request.syncInfo(this.userInfo)
+				if (this.userInfo.openId) {
+					uni.setStorageSync("userInfo", that.userInfo)
+					that.showAuthorizeUser = false
+					that.mescroll.resetUpScroll() 
+				}
+			},
+			async getPhoneNumber(e) {
+				that.userInfo = await this.$request.wxlogin()
+				this.$nextTick(function() {
+					that.userInfo.phone = that.$request.getPhone(e, that.userInfo)
+					that.showAuthorizePhone = false
+					that.showAuthorizeUser = true
+				});
+			
+			},
 			toHome(item){
 				uni.navigateTo({
 					url:'/pages/circle/lookHome?id='+item.personalHomeId
@@ -396,7 +606,7 @@
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 	.bgc {
 		background-color: #112253;
 		padding-bottom: 100rpx;
@@ -565,5 +775,136 @@
 	.line {
 		text-align: center;
 	}
+	.shareBtn{
+		background-color: #9E9E9E !important;
+		position: absolute;
+		top: 0;
+		right: 30rpx;
+		height: 40rpx;
+		padding: 0;
+		margin: 0;
+		width: 40rpx;
+		border-radius: 0 10px 0 27rpx;
+	}
+	.slot-content {
+		width: 100%;
+	}
+
+	.auth-btncard {
+		display: flex !important;
+		justify-content: space-between !important;
+
+		.btn-unok {
+			width: 40%;
+		}
+
+		.btn-ok {
+			width: 40%;
+		}
+	}
+
+	.auth-card {
+		text-align: center;
+
+		.avatar-img {
+			width: 250rpx;
+		}
+
+		.title {
+			font-size: 20rpx;
+		}
 
+		.content {
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #1A1A1A;
+			margin-bottom: 30rpx;
+		}
+	}
+
+	.avatar-wrapper {
+		color: #333 !important;
+		border: none !important;
+		border-radius: 0 !important;
+		background-color: transparent !important;
+		padding: 0;
+	}
+
+	.avatar-wrapper::after {
+		border: none !important;
+	}
+
+	.avatar {
+		width: 100rpx;
+		height: 100rpx;
+		overflow: hidden;
+		border-radius: 100%;
+	}
+
+	/deep/.u-popup__content {
+		border-radius: 20rpx !important;
+	}
+	/* 主体样式 */
+	.list_box {
+		width: 100%;
+	
+		.list-item {
+			padding: 10px 10px;
+			border-bottom: 1px solid #eee;
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			transition: all .5s;
+			&:active{
+				background-color: #EEEEEE;
+			}
+			.left {
+				display: flex;
+				align-items: center;
+	
+				.icon-box {
+					width: 70rpx;
+					height: 70rpx;
+					border-radius: 10px;
+					box-shadow: 3px 3px 7px #bebebe,
+						-3px -3px 7px #ffffff;
+					display: flex;
+					justify-content: center;
+					align-items: center;
+	
+					image {
+						width: 70%;
+						height: 70%;
+					}
+	
+					text::before {
+						font-size: 20px;
+					}
+				}
+	
+				.name {
+					margin-left: 10px;
+					font-size: 30rpx;
+					color: #FFFFFF;
+					text-shadow: 1px 1px 3px #000;
+				}
+			}
+	
+			.right {
+				display: flex;
+				align-items: center;
+	
+				.rightText {
+					margin-right: 5px;
+					color: #999;
+					font-size: 12px;
+				}
+			}
+		}
+	}
+	.layout2{
+		background: #9e9e9e94;
+		margin: 0 20rpx;
+		border-radius: 20rpx		
+	}
 </style>

+ 378 - 0
xiaochengxu/pages/circle/friendSCirlce.vue

@@ -0,0 +1,378 @@
+<template>
+	<view class="u-page">
+		<mescroll-uni :up="upOption" :down="downOption" ref="mescrollRef" @init="mescrollInit" @up="upCallback"
+			@down="downCallback">
+			<circle-item ref="mescrollItem" :list="list" @click="showInput = false" @doThumb="doThumb"
+				@doComment="doComment"></circle-item>
+		</mescroll-uni>
+		<view class="bottom" v-if="showInput">
+			<view class="bottom-bt">
+				<input class="bottom-bt-input" placeholder="请输入内容" v-model="commentValue" />
+				<text class="bottom-bt-button" @click="submitComment">发送</text>
+			</view>
+		</view>
+		<image src="../../static/imgs/cirlce/add.png" mode="widthFix" class="add" @click="addCircle"></image>
+		<u-action-sheet :show="show2" @close="show2 = false" @select="sheetSelect" :actions="actions2"
+			cancelText="取消"></u-action-sheet>
+	</view>
+</template>
+
+<script>
+	var that;
+	import circleItem from './circle-item.vue';
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
+	import {
+		friendlyDate
+	} from '@/common/util.js';
+
+	export default {
+		mixins: [MescrollMixin],
+		components: {
+			circleItem
+		},
+		data() {
+			return {
+				formData: {
+					circleFriendsId: '',
+					commonId: '',
+					head: '',
+					nickname: '',
+					interactionFlag: '',
+
+				},
+				userInfo: {},
+				circleId: '',
+				downOption: {
+					auto: false,
+					textColor: '#bbb'
+				},
+				upOption: {
+					page: {
+						size: 10 // 每页数据的数量,默认10
+					},
+					auto: false,
+					noMoreSize: 1,
+					textNoMore: '没有更多了~',
+					textColor: '#bbb'
+				},
+				list: [],
+				requestParams: {
+					searchType: 1,
+					latitude: 0,
+					longitude: 0,
+					pageSize: 10,
+					pageNo: 1
+				},
+
+				show2: false,
+				actions2: [{
+					name: '删除'
+				}],
+				showInput: false
+			};
+		},
+		onLoad(options) {
+			that = this
+			this.circleId = options.id
+			this.userInfo = uni.getStorageSync("userInfo")
+			// 需要固定swiper的高度 (需减去悬浮tabs的高度64rpx)
+			// this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(100) + 'px';
+			// this.tabHeight = uni.upx2px(100) + 'px';
+			this.loadData(true);
+		},
+		methods: {
+			addCircle() {
+				uni.navigateTo({
+					url: "/pages/circle/addFriendCirlce?id=" + this.circleId
+				})
+			},
+			/*下拉刷新的回调 */
+			downCallback() {
+				// this.loadData(true);
+				this.mescroll.resetUpScroll();
+			},
+			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
+			upCallback(page) {
+				console.log('upCallback=================', page);
+				this.requestParams.pageNo = page.num;
+				this.requestParams.pageSize = page.size;
+				this.loadData();
+			},
+
+			scroll() {},
+
+			change(index) {
+				console.log('change=========', index);
+				this.requestParams.searchType = index + 1;
+				this.loadData(true);
+			},
+			// 处理图片
+			imageInfo(url) {
+				let promise = new Promise(function(resolve, reject) {
+					uni.getImageInfo({
+						src: url,
+						success: function(image) {
+							resolve(image)
+							console.log(image.width);
+							console.log(image.height);
+						}
+					});
+				})
+				return promise
+			},
+			loadData(refresh) {
+				this.$request.baseRequest('admin.unimall.circleFriendsInfo', 'list', {
+					page: this.requestParams.pageNo,
+					limit: this.requestParams.pageSize,
+					circleId: this.circleId,
+					currentCommonId: this.userInfo.id
+				}, failres => {
+					console.log('res+++++', failres.errmsg)
+					uni.showToast({
+						icon: "none",
+						title: failres.errmsg,
+						duration: 3000
+					});
+					uni.hideLoading()
+				}).then(async res => {
+					console.log(res)
+					if (this.requestParams.pageNo.num == 1) this.list = [];
+					let curPageLen = res.data.items.length;
+					let totalPage = res.data.total;
+					this.list = res.data.items
+					for (let i = 0; i < this.list.length; i++) {
+						this.list[i].urlList = this.list[i].image.split(",")
+						if (this.list[i].mediaType == 2) {
+							let _image = await this.imageInfo(this.list[i].image +
+								'?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast,ar_auto')
+							console.log("_image", _image)
+							if (_image.width > _image.height) {
+								this.list[i].direction = 1
+							} else {
+								this.list[i].direction = 2
+							}
+						}
+					}
+					this.$nextTick(() => {
+						that.mescroll.endBySize(curPageLen, totalPage)
+					});
+					uni.hideLoading()
+				})
+			},
+
+			getCircleDetail(id, index) {
+				let param = {
+					id: id,
+					searchType: 1,
+					latitude: 0,
+					longitude: 0
+				};
+				if (this.locateInformation.location) {
+					param.latitude = this.locateInformation.location.lat;
+					param.longitude = this.locateInformation.location.lng;
+				}
+				getCircleDetail({
+						params: param
+					})
+					.then(res => {
+						console.log('getCircleDetail====', res);
+						if (res) {
+							let data = res;
+							if (data.mediaType == 1) {
+								let arr = data.url.split(',');
+								if (arr.length > 1) {
+									let list = [];
+									arr.forEach(item2 => {
+										list.push(item2);
+									});
+									data.urlList = list;
+								} else {
+									data.urlList = arr;
+								}
+							}
+							data.dateTime = friendlyDate(new Date(data.createTime.replace(/\-/g, '/')).getTime());
+							this.list[index].thumbNumber = data.thumbNumber;
+							this.list[index].commentNumber = data.commentNumber;
+							this.list[index].thumbed = data.thumbed;
+							this.list[index].thumbs = data.thumbs;
+							this.list[index].comments = data.comments;
+							console.log('data====', data);
+							console.log('index====', index);
+							console.log('this.list====', this.list);
+							this.$forceUpdate();
+						} else {}
+					})
+					.catch(err => {
+						console.log(err, 'catch');
+					});
+			},
+			//点赞
+			async doThumb(item) {
+				if (item.helpFlag == 0) {
+					this.formData = {
+						circleFriendsId: item.id,
+						commonId: this.userInfo.id,
+						head: this.userInfo.head,
+						nickname: this.userInfo.nickname
+					}
+					
+					this.formData.interactionFlag = 1
+					this.$request.baseRequest('admin.unimall.circleFriendsDetail', 'add', {
+						circleFriendsDetail: JSON.stringify(this.formData)
+					}, failres => {
+						console.log('res+++++', failres.errmsg)
+						uni.showToast({
+							icon: "none",
+							title: failres.errmsg,
+							duration: 3000
+						});
+						uni.hideLoading()
+					}).then(async res => {
+						console.log(res)
+						uni.showToast({
+							icon: "success",
+							title: '点赞成功!',
+							duration: 2000
+						});
+						this.loadData()
+					})
+				} else {
+					this.$request.baseRequest('admin.unimall.circleFriendsDetail', 'cancelLike', {
+						circleFriendsId: item.id,
+						commonId: this.userInfo.id,
+					}, failres => {
+						console.log('res+++++', failres.errmsg)
+						uni.showToast({
+							icon: "none",
+							title: failres.errmsg,
+							duration: 3000
+						});
+						uni.hideLoading()
+					}).then(async res => {
+						console.log(res)
+						uni.showToast({
+							icon: "success",
+							title: '取消成功!',
+							duration: 2000
+						});
+						this.loadData()
+					})
+				}
+			},
+
+			doComment(item, comment) {
+				this.selectedComment = comment;
+				this.selectedCircle = item;
+				if (comment != null && comment.userId == this.userInfo.id) {
+					this.show2 = true;
+					return;
+				}
+				this.showInput = !this.showInput;
+				this.commentValue = '';
+				this.$forceUpdate();
+			},
+
+			async submitComment() {
+				if (!this.commentValue) {
+					uni.$u.toast('请输入内容');
+					return;
+				}
+				let params = {
+					comment: this.commentValue,
+					circleId: this.selectedCircle.id,
+					circleUserId: this.selectedCircle.userId
+				};
+				if (this.selectedComment) {
+					let tmp = {
+						pid: this.selectedComment.id,
+						comUserId: this.selectedComment.userId
+					};
+					params = uni.$u.deepMerge(params, tmp);
+				}
+				let res = await addComment(params);
+				if (res) {
+					uni.$u.toast('评论成功');
+					this.getCircleDetail(this.selectedCircle.id, this.selectedCircle.index);
+				}
+			},
+
+			sheetSelect(val) {
+				console.log('---sheetSelect---');
+				this.doDelComment();
+			},
+
+			async doDelComment() {
+				let params = {
+					id: this.selectedComment.id,
+					circleId: this.selectedComment.circleId
+				};
+				let res = await delComment(params);
+				console.log('doDelComment', res);
+				if (res) {
+					uni.$u.toast('删除成功');
+					this.getCircleDetail(this.selectedCircle.id, this.selectedCircle.index);
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	.u-swiper {
+		position: relative;
+	}
+
+	.bottom {
+		bottom: 0;
+		position: fixed;
+		height: 120upx;
+		width: 750upx;
+		// padding: 0 20upx;
+		background-color: #eee;
+		align-items: center;
+		justify-content: center;
+		display: flex;
+		z-index: 999;
+	}
+
+	.bottom-bt {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+	}
+
+	.bottom-bt-input {
+		width: 550upx;
+		height: 70upx;
+		padding: 0 15upx;
+		border-radius: 10upx;
+		background-color: #fff;
+		margin-right: 20upx;
+		font-size: 28upx;
+		color: #333;
+	}
+
+	.bottom-bt-button {
+		padding: 0 20upx;
+		height: 55upx;
+		line-height: 55upx;
+		background-color: #344577;
+		font-size: 28upx;
+		color: #fff;
+		border-radius: 10upx;
+	}
+
+	.add {
+		width: 84rpx;
+		height: auto;
+		position: fixed;
+		bottom: 200rpx;
+		right: 30rpx;
+		height: auto;
+		z-index: 999;
+	}
+</style>

+ 18 - 25
xiaochengxu/pages/mySet/myInfo.vue

@@ -231,7 +231,7 @@
 					<view class="block">
 						<button class="shareBtn" type="default" data-name="shareBtn" open-type="share">
 							<view class="iconfont icon-weixin"></view>
-							<view  style="font-size: 26rpx;">分享微信好友</view>
+							<view style="font-size: 26rpx;">分享微信好友</view>
 						</button>
 					</view>
 				</view>
@@ -281,21 +281,20 @@
 					icon: 'none',
 					duration: 10000
 				});
-			} 
+			}
 			this.userInfo = uni.getStorageSync("userInfo")
 			if (uni.getStorageSync("userInfo").phone) {
 				this.init()
 			} else {
 				uni.switchTab({
-					url:'/pages/cardHolder/cardHolder'
+					url: '/pages/cardHolder/cardHolder'
 				})
-			
-				
+
+
 			}
 
 		},
 		onShareAppMessage(res) {
-			debugger
 			console.log(res, this.popupshow)
 			let that = this;
 			//生成名片图片
@@ -303,7 +302,7 @@
 			console.log("imageUrl", imageUrl)
 			if (res.from === 'button') {
 				let path = `/pages/cardHolder/scanCodeAddCard?id=${that.currectData.id}`
-				console.log("分享地址",path)
+				console.log("分享地址", path)
 				return {
 					title: this.popupshow ? `${that.currectData.name}分享的名片~` : '电子名片',
 					path: path,
@@ -461,20 +460,11 @@
 					},
 					{
 						type: 'image',
-						path: '../../static/imgs/card/bgc1.png',
+						path: '../../static/imgs/card/bgc6.png',
 						use: 'bg1',
 						x: 3,
 						y: 243,
-						width: 240,
-						height: 67
-					},
-					{
-						type: 'image',
-						path: '../../static/imgs/card/bgc2.png',
-						use: 'bg2',
-						x: 225,
-						y: 243,
-						width: 278,
+						width: 518,
 						height: 67
 					},
 					{
@@ -918,19 +908,22 @@
 
 		.car-bottom {
 			position: absolute;
-			bottom: 22rpx;
+			bottom: 27rpx;
 			left: 20rpx;
 			width: calc(100% - 40rpx);
+			background: url("../../static/imgs/card/bgc6.png") no-repeat center;
+			background-size: cover;
+			border-radius: 0 0 20rpx 20rpx;
 
 			.left {
 				position: absolute;
 				padding: 20rpx 0;
-				width: 305rpx;
+				width: 270rpx;
 				box-sizing: border-box;
 				display: flex;
 				justify-content: space-evenly;
-				background: url("../../static/imgs/card/bgc1.png") no-repeat center;
-				background-size: 100% 100%;
+				// background: url("../../static/imgs/card/bgc1.png") no-repeat center;
+				// background-size: 100% 100%;
 			}
 
 			.right {
@@ -942,8 +935,8 @@
 				box-sizing: border-box;
 				display: flex;
 				justify-content: space-evenly;
-				background: url("../../static/imgs/card/bgc2.png") no-repeat center;
-				background-size: 100% 100%;
+				// background: url("../../static/imgs/card/bgc2.png") no-repeat center;
+				// background-size: 100% 100%;
 
 				.text {
 					color: #fff;
@@ -1061,4 +1054,4 @@
 			color: #4977FC;
 		}
 	}
-</style>
+</style> -->

+ 5 - 3
xiaochengxu/pages/mySet/mySet.vue

@@ -270,9 +270,11 @@
 			},
 			async getPhoneNumber(e) {
 				that.userInfo = await this.$request.wxlogin()
-				that.userInfo.phone = await this.$request.getPhone(e, that.userInfo)
-				this.showAuthorizePhone = false
-				this.showAuthorizeUser = true
+				this.$nextTick(function() {
+					that.userInfo.phone = that.$request.getPhone(e, that.userInfo)
+					that.showAuthorizePhone = false
+					that.showAuthorizeUser = true
+				});
 
 			},
 			editNickName() {

二進制
xiaochengxu/static/comment.png


二進制
xiaochengxu/static/imgs/card/bgc6.png


二進制
xiaochengxu/static/imgs/card/buju1.png


二進制
xiaochengxu/static/imgs/card/buju2.png


二進制
xiaochengxu/static/imgs/card/share1.png


二進制
xiaochengxu/static/imgs/share1.png


二進制
xiaochengxu/static/love-fill.png


二進制
xiaochengxu/static/love.png


二進制
xiaochengxu/static/play.png


+ 69 - 0
xiaochengxu/uni_modules/cl-upload/changelog.md

@@ -0,0 +1,69 @@
+## 1.3.6(2023-05-22)
+添加自定义图片资源配置
+## 1.3.5(2023-05-04)
+修复小程序cloudType为other的时候获取不到视频删除按钮焦点问题
+## 1.3.4(2023-04-27)
+修复小程序unicloud自动上传不自动同步数据问题
+## 1.3.3(2023-04-27)
+修复删除按钮层级问题
+## 1.3.2(2023-04-24)
+修复安卓APP配置cloudType:other 无法显示http封面问题
+## 1.3.1(2023-04-19)
+修改版本信息
+## 1.3.0(2023-04-19)
+修复手动上传已知问题; 新增删除前,上传前钩子函数
+## 1.2.9(2023-03-22)
+修复已知问题
+## 1.2.8(2023-03-22)
+修复已知问题
+## 1.2.7(2023-03-21)
+修复部分视频封面白屏问题
+## 1.2.6(2023-03-21)
+修复部分视频封面白屏问题
+## 1.2.5(2023-03-08)
+兼容vue3中v-model数据绑定
+## 1.2.4(2023-03-06)
+1.修复低版本微信小程序video图层兼容问题;
+2.修复unicloud上传v-model不同步问题;
+## 1.2.3(2023-02-02)
+添加限制图片视频大小功能
+## 1.2.2(2023-02-01)
+兼容支付宝小程序手动上传视频
+## 1.2.1(2023-01-31)
+更新图片资源地址
+## 1.2.0(2022-12-12)
+兼容uniCloud上传
+## 1.1.9(2022-12-12)
+1. 添加最大视频限制
+2. 优化部分功能
+## 1.1.8(2022-12-09)
+修复部分设备上传视频第一帧黑屏问题
+## 1.1.7(2022-12-01)
+修复h5上传开启压缩后一直显示“正在压缩中”问题
+## 1.1.6(2022-11-24)
+兼容支付宝小程序手动上传
+## 1.1.5(2022-11-07)
+添加加载配置
+## 1.1.4(2022-11-07)
+修复图片限制数量后可以多次选择最大数量图片问题
+## 1.1.3(2022-10-28)
+添加提示弹窗配置
+## 1.1.1(2022-10-28)
+修复已知问题
+## 1.1.0(2022-08-25)
+修复base64压缩问题
+## 1.0.9(2022-08-25)
+修复服务器返回数据格式问题
+## 1.0.8(2022-08-01)
+优化代码格式、逻辑
+## 1.0.6(2022-07-30)
+修改已知问题
+## 1.0.5(2022-07-30)
+1. aspect-ratio兼容问题,添加height属性保底
+2. 添加监听上传进度变化事件
+## 1.0.3(2022-07-30)
+添加按钮控制,事件说明
+## 1.0.2(2022-07-30)
+优化服务器接口返回数据上传
+## 1.0.1(2022-07-29)
+初始化组件

+ 54 - 0
xiaochengxu/uni_modules/cl-upload/components/cl-image/cl-image.vue

@@ -0,0 +1,54 @@
+<template>
+	<image class="image" :src="imgSrc" mode="aspectFill" :disabled="false" :controls='false' @error="imgerror"></image>
+</template>
+
+<script>
+	export default {
+		props: {
+			src: {
+				type: String,
+				default: ''
+			},
+			cloudType: {
+				type: String,
+				default: 'oss'
+			},
+		},
+		data() {
+			return {
+				imgSrc: ''
+			};
+		},
+		mounted() {
+			this.setCloudFunction()
+		},
+		methods: {
+			imgerror(even) {
+				this.imgSrc =  `https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/887c60f0-27f8-46d1-8769-2c45be0f3d7d.png`
+			},
+			setCloudFunction() {
+				switch (this.cloudType){
+					case 'oss':
+						this.imgSrc = this.src + '?x-oss-process=video/snapshot,t_0,f_jpg'
+						break;
+					case 'process':
+						this.imgSrc = this.src + '?ci-process=snapshot&time=0.01'
+						break;
+					case 'vframe':
+						this.imgSrc = this.src + '?vframe/jpg/offset/0'
+						break;
+					default:
+						this.imgSrc = this.src
+						break;
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	image {
+		width: 100%;
+		height: 100%;
+	}
+</style>

+ 981 - 0
xiaochengxu/uni_modules/cl-upload/components/cl-upload/cl-upload.vue

@@ -0,0 +1,981 @@
+<template>
+	<view class="cl-updata">
+		<view class="file-list" :style="[listRowStyle]">
+
+			<view v-for="(item, index) in previewList" @tap="onClickRow(item, index)" class="file-list-row"
+				:style="[rowStyle]" :key="index">
+
+				<image v-if="fileUrlType(item) === 'image'" :src="item.path || item" :style="[imgStyle]"
+					mode="aspectFill">
+				</image>
+
+				<view v-else class="_video" :style="[imgStyle]">
+
+					<!-- #ifdef MP-WEIXIN || MP-ALIPAY -->
+					<video v-if="!autoUpload || cloudType === 'other'" class="_video" :style="[imgStyle]"
+						:src="item.url || item" :show-center-play-btn="false" :show-fullscreen-btn="false"
+						:show-play-btn="false" :show-loading="false" :enable-progress-gesture="false" :controls="false">
+						<!-- <cover-view class="video-fixed" ></cover-view> -->
+						<cover-view @tap="onPlay(item, index)" class="play">
+							<image style="width: 100%;" :src="playImg" mode="widthFix"></image>
+						</cover-view>
+					</video>
+
+					<!-- #endif -->
+
+					<!-- #ifdef APP-PLUS -->
+					<video v-if="cloudType === 'other'" class="_video" :style="[imgStyle]" :src="item" :poster="item"
+						:controls="false" :show-center-play-btn="false" :show-fullscreen-btn="false"
+						:show-play-btn="false" :show-loading="false" :enable-progress-gesture="false">
+						<cover-image class="app_play" :src="playImg" @tap="onPlay(item, index)"></cover-image>
+						<cover-view class="remove" v-if="remove" @tap="onRemove(item, index)">
+							<cover-image class="image" :src="deleteImg" mode="widthFix"
+								@tap="onRemove(item, index)"></cover-image>
+						</cover-view>
+					</video>
+					<!-- #endif -->
+
+					<!-- #ifndef MP-WEIXIN || MP-ALIPAY || APP-PLUS -->
+					<video v-if="cloudType === 'other'" class="_video" :autoplay="false" :style="[imgStyle]" :src="item"
+						:controls="false" :show-center-play-btn="false" :show-fullscreen-btn="false"
+						:show-play-btn="false" :show-loading="false" :enable-progress-gesture="false">
+						<!-- <cover-view class="video-fixed" @tap="onPlay(item, index)"></cover-view> -->
+						<cover-view @tap="onPlay(item, index)" class="play">
+							<image style="width: 100%;" :src="playImg" mode="widthFix"></image>
+						</cover-view>
+					</video>
+
+					<!-- #endif -->
+
+					<cl-image v-else class="pay" :style="[imgStyle]" :cloudType="cloudType"
+						:src="(item.path || item)"></cl-image>
+
+					<view class="play" @tap="onPlay(item, index)">
+						<image class="play-img" :src="playImg" mode="widthFix"></image>
+					</view>
+
+				</view>
+
+				<view class="remove" v-if="remove" @tap.stop="onRemove(item, index)">
+					<image class="image" :src="deleteImg" mode="widthFix"></image>
+				</view>
+			</view>
+
+			<view v-if="add && FileList.length < max" @tap="onClickAdd" :style="[rowStyle]"
+				class="file-list-row add-image">
+				<image :src="addImg" mode="widthFix"></image>
+			</view>
+		</view>
+
+
+		<view v-if="tempVideoUrl" class="mask">
+			<image @tap="tempVideoUrl = ''" class="_root" :src="closeImg" mode="widthFix"></image>
+
+			<view class="block" @tap.stop>
+				<video autoplay :src="tempVideoUrl"></video>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	import ClImage from '../cl-image/cl-image.vue'
+	export default {
+		name: "cl-upload",
+		components: {
+			ClImage
+		},
+		props: {
+			//受控图片列表
+			// #ifdef VUE2
+			value: {
+				type: Array,
+				default: () => [],
+			},
+			// #endif
+
+			// #ifdef VUE3
+			modelValue: {
+				type: Array,
+				default: () => [],
+			},
+			// #endif
+
+			// 存储云类型 oss阿里云  vframe七牛云   process腾讯云  other其他
+			cloudType: {
+				type: String,
+				default: 'oss'
+			},
+			// 标识符,即后端接口参数名
+			fileName: {
+				type: String,
+				default: 'file'
+			},
+			// // 文件类型 'image', 'video', 'all'
+			// fileType: {
+			// 	type: String,
+			// 	default: 'all'
+			// },
+			// 上传图片参数
+			imageFormData: {
+				type: Object,
+				default: () => {}
+			},
+			// 上传视频参数
+			videoFromData: {
+				type: Object,
+				default: () => {}
+			},
+
+			// 必选参数,上传的地址
+			action: {
+				type: String,
+				default: ''
+			},
+
+			// 设置上传的请求头部
+			headers: {
+				type: Object,
+				default: () => {}
+			},
+
+			// 上传时附带的额外参数
+			data: {
+				type: Object,
+				default: () => {}
+			},
+
+			// 是否开启预览图片
+			isPreviewImage: {
+				type: Boolean,
+				default: true
+			},
+
+			// 图片指示器样式,可取值:"default" - 底部圆点指示器; "number" - 顶部数字指示器; "none" - 不显示指示器。
+			indicator: {
+				type: String,
+				default: 'none'
+			},
+			// 是否在选取文件后立即进行上传	
+			autoUpload: {
+				type: Boolean,
+				default: true
+			},
+			// 是否显示删除按钮
+			remove: {
+				type: Boolean,
+				default: true
+			},
+			// 是否添加按钮
+			// add: {
+			// 	type: Boolean,
+			// 	default: true
+			// },
+			// 最多显示数量
+			max: {
+				type: Number,
+				default: 9
+			},
+			// 视频最大上传数量
+			maxVideo: {
+				type: Number,
+				default: 0
+			},
+			// 列表样式
+			listStyle: {
+				type: Object,
+				default: () => {}
+			},
+			// 删除提示弹窗标题
+			deleteTitle: {
+				type: String,
+				default: '提示'
+			},
+			// 删除提示弹窗文案
+			deleteText: {
+				type: String,
+				default: '您确认要删除吗?'
+			},
+			// 是否开启删除前钩子
+			useBeforeDelete: {
+				type: Boolean,
+				default: false
+			},
+			// 是否开启上传前钩子
+			useBeforeUpload: {
+				type: Boolean,
+				default: false
+			},
+			// 添加按钮图片
+			addImg: {
+				type: String,
+				default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/bb1550b3-e0a8-4a90-a86f-00f8c6afa9fb.png'
+			},
+			// 播放按钮图片
+			playImg: {
+				type: String,
+				default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/ae40402f-aa53-4344-b553-2322799bebd6.png'
+			},
+			// 删除按钮图片
+			deleteImg: {
+				type: String,
+				default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/d20177a5-417e-4c5d-a266-1988361c543d.png'
+			},
+			// 关闭视频按钮图片
+			closeImg: {
+				type: String,
+				default: 'https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/cde4362d-7ec7-4cac-a692-12e1f576be1e.png'
+			},
+		},
+		data() {
+			return {
+				add:true,
+				// 文件类型 'image', 'video', 'all'
+				fileType: "all",
+				// 渲染列表
+				FileList: [],
+
+				// 预览视频地址
+				tempVideoUrl: '',
+
+				// 临时文件列表
+				tempFile_paths: [],
+
+			};
+		},
+		watch: {
+			// #ifdef VUE2
+			'value': {
+				handler: function(newVal, oldVal) {
+					this.FileList = newVal;
+				},
+				deep: true,
+				immediate: true
+			},
+			// #endif
+
+			// #ifdef VUE3
+			'modelValue': {
+				handler: function(newVal, oldVal) {
+					this.FileList = newVal;
+				},
+				deep: true,
+				immediate: true
+			},
+			// #endif
+		},
+		computed: {
+			previewList() {
+				return this.FileList.map(item => item.path || item)
+			},
+			listRowStyle() {
+				const style = {
+					'grid-template-columns': `repeat(${this.listStyle?.columns || 4}, 1fr)`, // 每行数量	
+					'grid-column-gap': this.listStyle?.columnGap || '40rpx', // 行间距	
+					'grid-row-gap': this.listStyle?.rowGap || '40rpx', // 列间距
+					'padding': this.listStyle?.padding || '0rpx' // 列表内边距
+				}
+
+				return style;
+			},
+			rowStyle() {
+				const style = {
+					'aspect-ratio': this.listStyle?.height ? '' : this.listStyle?.ratio || '1/1', // 图片比例	
+					'height': this.listStyle?.height || '140rpx',
+				}
+
+				return style;
+			},
+			imgStyle() {
+				const style = {
+					'border-radius': this.listStyle?.radius || '6rpx', // 图片圆角
+				}
+
+				return style;
+			}
+		},
+		methods: {
+			/**
+			 * 删除已选择文件
+			 * @param {object} item 文件信息
+			 * @param {number} index 文件索引
+			 * */
+			onRemove(item, index) {
+				if(this.FileList.length==1){
+					this.fileType = "all"
+					this.add = true
+				}
+				const imageItem = this.FileList[index];
+
+				if (this.useBeforeDelete) {
+					this.$emit('beforeDelete', imageItem, index, () => {
+						return deleteItem()
+					})
+				}
+
+				if (!this.useBeforeDelete) {
+					uni.showModal({
+						title: this.deleteTitle,
+						content: this.deleteText,
+						success: (res) => {
+							if (res.confirm) {
+								deleteItem()
+							}
+						}
+					});
+				}
+
+				const deleteItem = () => {
+					const tempFileIndex = this.tempFile_paths.indexOf(item || item.path);
+
+					if (tempFileIndex > -1) {
+						this.tempFile_paths.splice(tempFileIndex, 1)
+					}
+
+					this.FileList.splice(index, 1)
+
+					// #ifdef VUE2 
+					this.$emit('input', this.FileList)
+					// #endif
+
+					// #ifdef VUE3
+					this.$emit("update:modelValue", this.FileList);
+					// #endif
+				}
+
+			},
+
+			/**
+			 * 点击已选择文件
+			 * @param {object} item 文件信息
+			 * @param {number} index 文件索引 
+			 * */
+			onClickRow(item, index) {
+				this.previewImage(item?.url ?? item, index);
+				this.$emit('onImage', {
+					item,
+					index
+				})
+			},
+
+			/**
+			 * 点击选择图片按钮
+			 * */
+			onClickAdd() {
+
+				switch (this.fileType) {
+					case 'image':
+						this.onChooseFile(1);
+						break;
+					case 'video':
+						this.onChooseFile(2);
+						break;
+					case 'all':
+						uni.showActionSheet({
+							itemList: ['照片', '视频'],
+							success: (res) => {
+								const tapIndex = res.tapIndex;
+								if (tapIndex === 0) {
+									this.onChooseFile(1);
+								} else {
+									this.onChooseFile(2);
+								}
+							},
+							fail: (res) => {
+								console.error(res.errMsg);
+							}
+						});
+						break;
+					default:
+						this.onChooseFile(1);
+						break;
+				}
+			},
+
+
+			/**
+			 * 从本地选择文件。
+			 * @param { number } updataType 选择类型 1:图片 2视频
+			 * */
+			async onChooseFile(updataType) {
+				const that = this;
+				if (updataType === 1) {
+					this.fileType = 'image'
+					this.$emit('showType', "1")
+					const data = Object.assign({}, {
+						// 最多可以选择的图片张数,默认9
+						count: 9,
+						// 仅对 mediaType 为 image 时有效,是否压缩所选文件
+						// #ifndef MP-TOUTIAO
+						sizeType: ['original', 'compressed'],
+						// #endif
+						// album 从相册选图,camera 使用相机,默认二者都有。
+						sourceType: ['camera', 'album'],
+
+						compress: false
+					}, this.imageFormData)
+
+					data['count'] = this.max - this.FileList.length
+
+					uni.chooseImage({
+						...data,
+						success: async (res) => {
+							let tempFiles = res.tempFiles
+							const compress = that.imageFormData?.compress || false;
+
+							// 限制图片上传尺寸
+							if (that.imageFormData?.size ?? false) {
+								tempFiles.map((imgInfo, index) => {
+									const maxSize = that.imageFormData.size * 1024 * 1024
+									if (imgInfo.size > maxSize) {
+										tempFiles.splice(index, 1)
+										that.$emit('onImageSize', imgInfo)
+										return uni.showToast({
+											title: `图片最大上传${that.imageFormData.size}MB`,
+											duration: 2000,
+											icon: 'none'
+										});
+									}
+								})
+							}
+
+							// 开启压缩图片
+							if (compress) {
+								const compressImage = tempFiles.map(imageItem => {
+									return that.compressImage(imageItem.path)
+								})
+
+								Promise.all(compressImage).then(result => {
+									upload(result);
+								})
+
+							} else {
+								upload(tempFiles);
+							}
+
+							function upload(tempImages) {
+								if (that.autoUpload) {
+									tempImages.map(item => {
+										that.onBeforeUploadFile(item, 'image')
+									})
+								} else {
+									that.FileList = [...that.FileList, ...tempImages]
+									tempImages.map(item => {
+										that.tempFile_paths.push(item)
+									})
+								}
+							}
+
+						},
+						fail(err) {
+							console.error('选择图片失败', err)
+							that.$emit('onError', err)
+						}
+
+					})
+				}
+
+				if (updataType === 2) {
+					console.log("上传视频")
+					this.fileType = "video"
+					this.$emit('showType', "2")
+					this.add = false
+					// 限制视频最大上传数量
+					const VIDEO_REGEXP = /\.(mp4|flv|avi)/i
+					const videoList = await that.FileList.filter(item => {
+						const fileUrl = item?.url ?? item
+						return VIDEO_REGEXP.test(fileUrl)
+					})
+
+					if (that.maxVideo > 0 && videoList.length >= that.maxVideo) {
+						that.$emit('onVideoMax', that.maxVideo, videoList.length)
+						return uni.showToast({
+							title: '视频数量已超出',
+							duration: 2000,
+							icon: 'none'
+						});
+					}
+
+					const data = Object.assign({}, {
+						// 	拍摄视频最长拍摄时间,单位秒。最长支持 60 秒。
+						maxDuration: 60,
+						// #ifndef MP-TOUTIAO
+						// 'front'、'back',默认'back'
+						camera: "back",
+						// #endif
+
+						// album 从相册选视频,camera 使用相机拍摄,默认二者都有。
+						sourceType: ['camera', 'album'],
+						// 是否压缩所选的视频源文件,默认值为 true,需要压缩。
+						compressed: true,
+						// 'front'、'back',默认'back'
+					}, this.videoFromData)
+
+					uni.chooseVideo({
+						...data,
+						success: (res) => {
+							let tempFilePath = {
+								...res
+							}
+							tempFilePath['path'] = res.tempFilePath
+
+							// 限制视频上传尺寸
+							if (that.videoFromData?.size ?? false) {
+								const maxSize = that.videoFromData.size * 1024 * 1024
+
+								if (tempFilePath.size > maxSize) {
+									uni.showToast({
+										title: `视频最大上传${that.videoFromData.size}MB`,
+										duration: 2000,
+										icon: 'none'
+									});
+									return false;
+								}
+
+							}
+							if (that.autoUpload) {
+								that.onBeforeUploadFile(tempFilePath, 'video')
+							} else {
+								that.FileList.push(tempFilePath)
+								that.tempFile_paths.push(tempFilePath)
+							}
+						},
+						fail(err) {
+							console.error('选择视频失败', err)
+						}
+
+					})
+				}
+			},
+
+			onBeforeUploadFile(tempFile) {
+				if (this.useBeforeUpload) {
+					return this.$emit('beforeUpload', tempFile, () => {
+						return this.updataFile(tempFile);
+					})
+				}
+				return this.updataFile(tempFile);
+			},
+
+			/**
+			 * 上传文件到服务器
+			 * @param { tempFile } 临时文件
+			 * */
+			updataFile(tempFile) {
+				const that = this;
+				const filePath = tempFile.path || tempFile;
+				const fileType = this.fileUrlType(filePath) == 'image' ? '.png' : '.mp4';
+				const fileName = tempFile.name || Date.now() + fileType;
+
+				uni.showLoading({
+					title: '正在上传中...',
+					icon: 'loading'
+				})
+
+				return new Promise((resolve, reject) => {
+					// uniCloud上传
+					if (that.action === 'uniCloud') {
+
+						uniCloud.uploadFile({
+							cloudPath: String(fileName),
+							filePath: filePath,
+							// #ifdef MP-ALIPAY 
+							fileType: fileType,
+							// #endif
+							onUploadProgress: (progressEvent) => {
+								const percentCompleted = Math.round(
+									(progressEvent.loaded * 100) / progressEvent.total
+								);
+								that.$emit('onProgress', percentCompleted)
+							},
+							success(result) {
+								if (that.autoUpload) {
+									that.FileList.push(result.fileID)
+								} else {
+									that.FileList.map((item, index) => {
+										if (item === filePath || item.path === filePath) {
+											that.FileList.splice(index, 1, result.fileID)
+										}
+									})
+								}
+
+								// #ifdef VUE2
+								that.$emit('input', that.FileList)
+								// #endif
+								// #ifdef VUE3
+								that.$emit("update:modelValue", that.FileList);
+								// #endif
+
+								resolve(result.fileID)
+								uni.hideLoading();
+								that.$emit('onProgress', {
+									...result
+								})
+							},
+							fail: (error) => {
+								uni.hideLoading();
+								console.error('error', error);
+								that.$emit('onError', error)
+								reject(error)
+							}
+						})
+						return false;
+					}
+					const uploadTask = uploadImage(filePath, 'cardImages/',
+						result => {
+							const data = result
+							uni.hideLoading();
+							that.success(data)
+
+							if (!this.autoUpload) {
+								that.FileList.map((item, index) => {
+									if (item === filePath || item.path === filePath) {
+										that.FileList.splice(index, 1)
+									}
+								})
+							}
+							resolve(data)
+						}, "", that.fileUrlType(filePath)
+					);
+					// 接口服务上传
+					// const uploadTask = uni.uploadFile({
+					// 	url: that.action,
+					// 	filePath: filePath,
+					// 	name: that.fileName,
+					// 	formData: that.data,
+					// 	header: that.headers,
+					// 	success: (uploadFileRes) => {
+					// 		const data = JSON.parse(uploadFileRes.data)
+					// 		uni.hideLoading();
+					// 		that.success(data)
+
+					// 		if (!this.autoUpload) {
+					// 			that.FileList.map((item, index) => {
+					// 				if (item === filePath || item.path === filePath) {
+					// 					that.FileList.splice(index, 1)
+					// 				}
+					// 			})
+					// 		}
+
+					// 		resolve(data)
+					// 	},
+					// 	fail: (error) => {
+					// 		uni.hideLoading();
+					// 		console.error('error', error);
+					// 		that.$emit('onError', error)
+					// 		reject(error)
+					// 	}
+					// });
+
+					// uploadTask.onProgressUpdate((res) => {
+					// 	that.$emit('onProgress', {
+					// 		...res,
+					// 		...tempFile
+					// 	})
+					// });
+				})
+			},
+
+			/**
+			 * 手动上传
+			 * */
+			submit() {
+
+				return new Promise((resolve, reject) => {
+					if (this.tempFile_paths.length <= 0) {
+						return console.error('没有可上传文件');
+					}
+
+					const result = this.tempFile_paths.map(item => {
+						return this.onBeforeUploadFile(item || item.path)
+					})
+
+					Promise.all(result).then(res => {
+						this.tempFile_paths = []
+						resolve(res)
+					}).catch(err => {
+						reject(err)
+					})
+				})
+
+			},
+
+			/**
+			 * 返回数据
+			 * */
+			success(data) {
+				this.$emit('onSuccess', data);
+
+				// 自定义数据结构-选择性开启
+				// const list = data.map(item=> {
+				// 	return JSON.parse(item).data.link;
+				// })
+				// this.$emit('input', [...this.FileList, ...list]);
+			},
+			/**
+			 * 压缩图片
+			 * @param {array} tempFilePaths 临时路径数组
+			 * @return {array} 被压缩过的路径数组
+			 * */
+			async compressImage(tempFilePaths) {
+				const that = this;
+
+				return new Promise((resolve, reject) => {
+
+					if (typeof tempFilePaths !== 'string') {
+						console.error('压缩路径错误')
+						reject([])
+					}
+
+					uni.showLoading({
+						title: '压缩中...',
+						icon: 'loading',
+					})
+
+					// #ifdef H5
+					this.canvasDataURL(tempFilePaths, {
+						quality: that.imageFormData.quality / 100
+					}, (base64Codes) => {
+						resolve(base64Codes);
+						uni.hideLoading();
+					})
+					// #endif
+
+					// #ifndef H5
+					uni.compressImage({
+						src: tempFilePaths,
+						quality: that.imageFormData.quality || 80,
+						success: res => {
+							resolve(res.tempFilePath);
+							uni.hideLoading();
+						},
+						fail(err) {
+							reject(err);
+							uni.hideLoading();
+						}
+					})
+					// #endif
+
+				})
+			},
+
+			/**
+			 * H5压缩图片质量
+			 * */
+			canvasDataURL(path, obj, callback) {
+				var img = new Image();
+				img.src = path;
+				img.onload = function() {
+					var that = this;
+					// 默认按比例压缩
+					var w = that.width,
+						h = that.height,
+						scale = w / h;
+					w = obj.width || w;
+					h = obj.height || (w / scale);
+					var quality = 0.8; // 默认图片质量为0.8
+					//生成canvas
+					var canvas = document.createElement('canvas');
+					var ctx = canvas.getContext('2d');
+					// 创建属性节点
+					var anw = document.createAttribute("width");
+					anw.nodeValue = w;
+					var anh = document.createAttribute("height");
+					anh.nodeValue = h;
+					canvas.setAttributeNode(anw);
+					canvas.setAttributeNode(anh);
+					ctx.drawImage(that, 0, 0, w, h);
+					// 图像质量
+					if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
+						quality = obj.quality;
+					}
+					// quality值越小,所绘制出的图像越模糊
+					var base64 = canvas.toDataURL('image/jpeg', quality);
+					// 回调函数返回base64的值
+					callback(base64);
+				}
+			},
+
+			/**
+			 * 预览图片
+			 * @param {string, object} item 文件信息
+			 * */
+			previewImage(item) {
+				if (this.fileUrlType(item) === 'video') return false;
+				if (!this.isPreviewImage) return false;
+
+				const imgs = this.FileList.filter(item => {
+					return this.fileUrlType(item) !== 'video'
+				}).map(item => item?.path ?? item)
+				const current = imgs.indexOf(item || item.path);
+
+				uni.previewImage({
+					current: current,
+					urls: imgs,
+					success() {},
+					fail(err) {
+						console.log(err);
+					}
+				})
+			},
+
+			/**
+			 * 预览视频
+			 * @param {string, object} item 文件信息
+			 * */
+			onPlay(item, index) {
+				this.$emit('onVideo', {
+					item,
+					index
+				})
+				this.tempVideoUrl = item.url || item;
+			},
+
+			/**
+			 * 是否img类型
+			 * @param {string, object} item 文件信息
+			 * */
+			fileUrlType(file) {
+				const filePath = file.path || file;
+
+				if (this.isBase64(filePath)) return 'image'
+
+				const fileType = filePath.split('.').pop();
+
+				const IMAGE_REGEXP = /(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg|image)/i
+				if (IMAGE_REGEXP.test(fileType)) {
+					return 'image';
+				} else {
+					return 'video';
+				}
+			},
+			isBase64(str) {
+				if (str === '' || typeof str !== 'string') return console.error('文件路径错误, base64', str);
+				return str.includes('blob:') || str.includes('data:image');
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.cl-updata {
+
+		.file-list {
+			display: grid;
+
+			&-row {
+				display: inline-flex;
+				align-items: center;
+				position: relative;
+
+				image {
+					height: 100%;
+					width: 100%;
+				}
+
+				._video {
+					position: relative;
+					width: 100%;
+					height: 100%;
+					overflow: hidden;
+				}
+
+				.video-fixed {
+					position: absolute;
+					top: 0;
+					left: 0;
+					bottom: 0;
+					width: 100%;
+					height: 100%;
+					border-radius: 10rpx;
+					z-index: 96;
+				}
+
+				.play {
+					position: absolute;
+					top: 50%;
+					left: 50%;
+					transform: translate(-50%, -50%);
+					width: 30%;
+					z-index: 95;
+				}
+
+				.app_play {
+					position: absolute;
+					top: 50%;
+					left: 50%;
+					transform: translate(-50%, -50%);
+					width: 50rpx;
+					height: 50rpx;
+				}
+
+				.remove {
+					position: absolute;
+					top: 0;
+					right: 0;
+					background-color: #373737;
+					height: 50rpx;
+					width: 50rpx;
+					border-bottom-left-radius: 200rpx;
+					z-index: 97;
+
+					.image {
+						width: 20rpx;
+						height: 20rpx;
+						position: absolute;
+						right: 12rpx;
+						top: 12rpx;
+					}
+				}
+			}
+
+			.add-image {
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				border: 2rpx dashed #ccc;
+
+				&:active {
+					opacity: 0.8;
+				}
+
+				image {
+					width: 40%;
+				}
+			}
+		}
+
+		.mask {
+			background-color: #000;
+			position: fixed;
+			top: 0;
+			right: 0;
+			bottom: 0;
+			left: 0;
+			z-index: 99;
+
+			.block {
+				padding: 0 30rpx;
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				transform: translate(-50%, -50%);
+				width: 100%;
+
+				video {
+					width: 100%;
+					height: 78vh;
+				}
+			}
+
+			._root {
+				width: 60rpx;
+				height: 60rpx;
+				position: absolute;
+				left: 40rpx;
+				top: 5vh
+			}
+		}
+	}
+</style>

+ 240 - 0
xiaochengxu/uni_modules/cl-upload/readme.md

@@ -0,0 +1,240 @@
+### cl-upload 上传组件
+
+> 支持手动自动上传,样式调整,参数配置,预览,删除等功能
+
+
+> `注意:每次上传都需要回调函数接收参数并且添加到与组件绑定的数组中以保持数据一致,这样做是因为组件不知道服务端返回的数据格式,也可以在组件中修改promise格式 一劳永逸`
+
+### 注意事项
+1. ratio 图片比例属性部分手机不支持,可选用height属性代替
+2. 自定义播放按钮部分平台有兼容性问题,可选择性关闭
+3. 开启压缩图片返回的临时路径没有尾缀,官方api的问题。真机上没问题,也可以在上传的时候手动添加尾缀
+4. **视频地址必须`https`, http可能导致无法显示封面图**
+5. 如果没条件用`https`那就配置`cloudType: other`
+
+### H5体验地址
+![image](https://mp-61599c79-d7ee-4a75-a24b-e5a288da6dd3.cdn.bspapp.com/cloudstorage/eff364bc-65f7-47e0-ae4b-7d5f19b9f094.png)
+
+#### list数据格式
+
+1. 数组格式
+```
+['地址1','地址2']
+```
+2. JSON格式
+```
+[
+    {
+        path: '地址1',
+        // 其他信息
+    },
+    {
+        path: '地址2',
+        // 其他信息
+    },
+]
+```
+
+#### 基础使用
+
+```
+<cl-upload v-model="list" action="请求地址" @onSuccess="onSuccess"></cl-upload>
+
+methods: {
+    /**
+	 * 自动上传返回的是一张图片信息
+	 * 手动上传返回的是已选中所有图片或者视频信息
+	 * */ 
+	onSuccess(reslut) {
+		// 把服务端返回的图片地址添加到list中与组件数据同步
+		this.list.push(reslut.url)
+	},
+}
+```
+### uniCloud上传
+> 一句代码实现上传,就是这么简单
+
+```
+<cl-upload v-model="list" action="uniCloud"></cl-upload>
+```
+
+### 自定义样式
+> 通过 listStyle 控制每行数量、比例、行间距、列间距等常用样式
+
+```
+<cl-upload v-model="list" :listStyle="{
+	columns: 2,
+	columnGap: '20rpx',
+	rowGap:'20rpx',
+	padding:'10rpx',
+	height:'300rpx',
+	radius:'20rpx'
+}"></cl-upload>
+```
+
+### 预览模式
+> 关闭显示添加按钮和删除按钮
+```
+<cl-upload v-model="list" :add="false" :remove="false"></cl-upload>
+```
+
+### 手动上传
+
+> 通过 autoUpload 关闭掉自动上传,提交的时候通过 refs 主动调用组件上传方法,返回本次提交成功服务器返回数据
+
+```
+<cl-upload 
+	ref="upload2" 
+	v-model="list2" 
+	:autoUpload="false"></cl-upload>
+	
+<button @tap="submit">手动提交</button>
+
+methods: {
+    submit() {
+    	/**
+    	 * 主动调用组件上传方法
+    	 * */ 
+    	this.$refs.upload2.submit().then(reslut=>{
+    		console.log(reslut); // 本次提交成功服务器返回数据
+    		
+    		// 上传第三方服务器需要手动同步数据
+    		// 上传uniCloud则不需要
+    		const imgUrls = reslut.list.map(imgInfo=> imgInfo.url);
+    		this.list2 = [...this.list2, ...imgUrls]
+    	})
+    },
+}
+```
+
+### 配置删除前和上传前钩子 `1.3.0`
+```
+/ **
+* 开启删除前钩子 useBeforeDelete
+* 开启上传前钩子 useBeforeUpload
+*/
+<cl-upload v-model="list" 
+    useBeforeDelete 
+    useBeforeUpload
+    @beforeDelete="beforeDelete"
+    @beforeUpload="beforeUpload"></cl-upload>
+    
+
+methods: {
+    /**
+	 * 删除前钩子
+	 * @param {Object} item 当前删除的图片或者视频信息
+	 * @param {Number} index 当前删除的图片或视频索引
+	 * @param {Function} next 调用此函数继续执行组件删除逻辑
+	 * */ 
+	beforeDelete(item, index, next) {
+		uni.showModal({
+			title: '提示信息',
+			content: '确定要删除这个文件嘛?',
+			success: res => {
+				if (res.confirm) {
+					// 模拟服务器接口
+					setTimeout(() => {
+						next();
+					}, 1000);
+				}
+			}
+		});
+	},
+	/**
+	 * 上传前钩子
+	 * @param {Object} tempFile 当前上传文件信息
+	 * @param {Function} next 调用此函数继续执行组件上传逻辑
+	 * */
+	beforeUpload(tempFile, next) {
+		// 自己的上传逻辑
+		// 如果不需要走组件的上传逻辑就不用调用next(), 但是上传完要同步到list
+	}
+}
+```
+
+## API 
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+| --- | --- | --- | --- | --- |
+| action | 上传地址 | String |-| uniCloud |
+| cloudType | 存储云类型(各个云服务截取封面方式不同。 other选项是video保底手段,部分平台有兼容性问题) | String |oss| 阿里云:oss  七牛云:vframe   腾讯云:process  其他:other |
+| headers | 设置上传的请求头部 | Object | - |-  |
+| data | 上传时附带的额外参数 | Object | - | - |
+| fileName| 标识符,即后端接口参数名 | String | file | - |
+| fileType | 文件类型 | String | all | 'image', 'video', 'all' |
+| imageFormData | 上传图片参数 | Object | - | - |
+| videoFromData | 上传视频参数 | Object  | - | - |
+| listStyle | 列表样式 |Object  | - | - |
+| isPreviewImage | 是否开启预览图片 | Boolean | true |false  |
+| remove | 是否显示删除按钮 | Boolean | true |false  |
+| add | 是否添加按钮 | Boolean | true |false  |
+| max | 最多显示数量 | Number | 9 | -  |
+| maxVideo | 视频最大上传数量 | Number | 不限制 |  - |
+| deleteTitle| 删除提示弹窗标题 | String | 提示 |  - |
+| deleteText| 删除提示弹窗文案 | String | 您确认要删除吗? | - |
+| loading| 是否显示加载 | Boolean | true | - |
+| loadingText| 加载文案 | String | 正在上传中... | - |
+| useBeforeDelete `1.3.0`| 是否开启删除前钩子  | Boolean | false  | true |
+| useBeforeUpload  `1.3.0`| 是否开启上传前钩子 | Boolean | false  | true |
+| addImg`1.3.6`| 添加按钮图片 | String | - |  - |
+| playImg`1.3.6`| 播放按钮图片 | String | - |  - |
+| deleteImg`1.3.6`| 删除按钮图片 | String | - |  - |
+| closeImg`1.3.6`| 关闭视频按钮图片 | String | - |  - |
+
+#### imageFormData
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+| --- | --- | --- | --- | --- |
+| count | 最多可以选择的图片张数 | number |9| - |
+| sizeType | original 原图,compressed 压缩图 | array | 默认二者都有 |-  |
+| sourceType | 相册或者相机 | array |  ['camera ', 'album'] | ['camera ', 'album']  |
+| compress | 是否开启图片压缩 | Boolean | false | true  |
+| quality | 压缩质量 | number | 80 | -  |
+| size | 图片大小 | number | - | 单位MB |
+
+#### videoFromData
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+| --- | --- | --- | --- | --- |
+| maxDuration | 拍摄视频最长拍摄时间 | number |60| 最多60秒 |
+| camera | 前摄像头后摄像头 | array | - |-  |
+| compressed | 是否压缩所选的视频源文件。 | Boolean | true |-  |
+| sourceType | 相册或者相机 | array |  ['camera ', 'album'] | ['camera ', 'album']  |
+| size | 视频大小 | number | - | 单位MB |
+
+#### listStyle
+
+| 参数 | 说明 | 类型 | 默认值 | 可选值 |
+| --- | --- | --- | --- | --- |
+| columns | 每行数量 | number |4| - |
+| columnGap | 行间距 | string | '40rpx' |-  |
+| rowGap | 列间距 | string | '40rpx' |-  |
+| padding | 列表内边距 | string | '0 0rpx' |-  |
+| ratio | 图片比例 | string | '1/1' | 低版本手机不支持,可以选择height属性  |
+| height | 图片高度 | string | '140rpx' |-  |
+| radius | 图片圆角 | string | '6rpx' |-  |
+
+#### Events
+
+| 事件名 | 说明 | 回调参数 |
+| --- | --- | --- |
+| onSuccess | 上传成功 | data: 服务器返回数据 |
+| onError | 上传失败 | error:错误信息 |
+| onImage | 点击图片 | item: 图片信息 index: 列表索引 |
+| onVideo | 点击视频 | item: 视频信息 index: 列表索引 |
+| onProgress | 上传进程 | onProgress参数说明|
+| onVideoMax | 触发视频最大数量限制 | maxVideo, fileLength|
+| onImageSize | 触发图片最大尺寸限制 | 图片信息 |
+| beforeDelete`1.3.0` | 删除前钩子 | item: 文件信息 index:文件索引 next:继续执行删除逻辑 |
+| beforeUpload `1.3.0`| 上传前钩子 | tempFile: 文件信息 next:继续执行删除逻辑 |
+
+#### onProgress参数说明
+| 事件名 | 说明 |
+| --- | --- |
+| progress | 上传进度百分比 |
+| totalBytesSent | 已经上传的数据长度 |
+| totalBytesExpectedToSend | 预期需要上传的数据总长度 |
+
+
+### [遇到问题或者讨论 uniapp 加入QQ群  553291781](https://jq.qq.com/?_wv=1027&k=5UkMN1QX)

+ 1 - 1
xiaochengxu/uni_modules/d-search-log/components/d-search-log/d-search-log.vue

@@ -125,7 +125,7 @@
 					this.search_input = newVal
 					// this.search_input = search_input.toLowerCase()
 					
-					this.saveKeyword()
+					// this.saveKeyword()
 				}
 			},
 			

+ 0 - 1
xiaochengxu/util/request.js

@@ -157,7 +157,6 @@ const getPhone = (e, userInfo) => {
 //同步信息
 const syncInfo = (userInfo) => {
 	let promise = new Promise(function(resolve, reject) {
-		debugger
 		if (!userInfo.head) userInfo.head =
 			'https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/card_head.png'
 		if (!userInfo.nickname) {