Pārlūkot izejas kodu

引入 uview 组件

YunaiV 3 gadi atpakaļ
vecāks
revīzija
002aea34ae

+ 1 - 1
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java

@@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
 public class MbrUserInfoRespVO {
 
     @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
-    private String nickName;
+    private String nickname;
 
     @ApiModelProperty(value = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952")
     private String avatar;

+ 15 - 0
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java

@@ -0,0 +1,15 @@
+package cn.iocoder.yudao.userserver.modules.member.convert.user;
+
+import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO;
+import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserProfileConvert {
+
+    UserProfileConvert INSTANCE = Mappers.getMapper(UserProfileConvert.class);
+
+    MbrUserInfoRespVO convert(MbrUserDO bean);
+
+}

+ 2 - 4
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO
 import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO;
+import cn.iocoder.yudao.userserver.modules.member.convert.user.UserProfileConvert;
 import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper;
 import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService;
 import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService;
@@ -115,10 +116,7 @@ public class MbrUserServiceImpl implements MbrUserService {
     public MbrUserInfoRespVO getUserInfo(Long userId) {
         MbrUserDO user = this.checkUserExists(userId);
         // 拼接返回结果
-        MbrUserInfoRespVO userResp = new MbrUserInfoRespVO();
-        userResp.setNickName(user.getNickname());
-        userResp.setAvatar(user.getAvatar());
-        return userResp;
+        return UserProfileConvert.INSTANCE.convert(user);
     }
 
     @Override

+ 1 - 0
yudao-vue-ui/App.vue

@@ -75,6 +75,7 @@
 	/*每个页面公共css */
 	@import url("./common/css/common.css");
 	@import url("./common/css/icon.css");
+	@import "@/uni_modules/uview-ui/index.scss";
 	
 	.lazyload{
 		position: relative;

+ 3 - 1
yudao-vue-ui/common/js/request.js

@@ -1,6 +1,8 @@
-const BASE_URL = 'http://127.0.0.1:28080/api/';
+import store from '@/store'
 import { msg, getAuthToken } from './util'
 
+const BASE_URL = 'http://127.0.0.1:28080/api/';
+
 export const request = (options) => {
 	return new Promise((resolve, reject) => {
 		// 发起请求

+ 1 - 1
yudao-vue-ui/common/js/util.js

@@ -61,7 +61,7 @@ export const msg = (title = '', param={}) => {
  * @return {Boolean} 是否登陆
  */
 export const isLogin = (options = {}) => {
-	const token = this.getAuthToken();
+	const token = getAuthToken();
 	if (token) {
 		return true;
 	}

+ 3 - 0
yudao-vue-ui/main.js

@@ -1,5 +1,8 @@
 import App from './App'
 
+import uView from '@/uni_modules/uview-ui'
+Vue.use(uView)
+
 // 全局 Mixin
 import mixin from './common/mixin/mixin'
 Vue.mixin(mixin) 

+ 3 - 0
yudao-vue-ui/pages.json

@@ -1,4 +1,7 @@
 {
+	"easycom": {
+		"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
+	},
 	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
 		{
 			"path": "pages/index/index",

+ 633 - 0
yudao-vue-ui/pages/set/cutImage/cut.js

@@ -0,0 +1,633 @@
+(function(global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+		typeof define === 'function' && define.amd ? define(factory) :
+		(global.weCropper = factory());
+}(this, (function() {
+	'use strict';
+	var device = void 0;
+	var TOUCH_STATE = ['touchstarted', 'touchmoved', 'touchended'];
+
+	function firstLetterUpper(str) {
+		return str.charAt(0).toUpperCase() + str.slice(1);
+	}
+
+	function setTouchState(instance) {
+		for (var _len = arguments.length, arg = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+			arg[_key - 1] = arguments[_key];
+		}
+
+		TOUCH_STATE.forEach(function(key, i) {
+			if (arg[i] !== undefined) {
+				instance[key] = arg[i];
+			}
+		});
+	}
+
+	function validator(instance, o) {
+		Object.defineProperties(instance, o);
+	}
+
+	function getDevice() {
+		if (!device) {
+			device = wx.getSystemInfoSync();
+		}
+		return device;
+	}
+
+	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
+		return typeof obj;
+	} : function(obj) {
+		return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" :
+			typeof obj;
+	};
+
+
+
+
+	var classCallCheck = function(instance, Constructor) {
+		if (!(instance instanceof Constructor)) {
+			throw new TypeError("Cannot call a class as a function");
+		}
+	};
+
+	var createClass = function() {
+		function defineProperties(target, props) {
+			for (var i = 0; i < props.length; i++) {
+				var descriptor = props[i];
+				descriptor.enumerable = descriptor.enumerable || false;
+				descriptor.configurable = true;
+				if ("value" in descriptor) descriptor.writable = true;
+				Object.defineProperty(target, descriptor.key, descriptor);
+			}
+		}
+
+		return function(Constructor, protoProps, staticProps) {
+			if (protoProps) defineProperties(Constructor.prototype, protoProps);
+			if (staticProps) defineProperties(Constructor, staticProps);
+			return Constructor;
+		};
+	}();
+
+
+
+
+	var slicedToArray = function() {
+		function sliceIterator(arr, i) {
+			var _arr = [];
+			var _n = true;
+			var _d = false;
+			var _e = undefined;
+
+			try {
+				for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
+					_arr.push(_s.value);
+
+					if (i && _arr.length === i) break;
+				}
+			} catch (err) {
+				_d = true;
+				_e = err;
+			} finally {
+				try {
+					if (!_n && _i["return"]) _i["return"]();
+				} finally {
+					if (_d) throw _e;
+				}
+			}
+
+			return _arr;
+		}
+
+		return function(arr, i) {
+			if (Array.isArray(arr)) {
+				return arr;
+			} else if (Symbol.iterator in Object(arr)) {
+				return sliceIterator(arr, i);
+			} else {
+				throw new TypeError("Invalid attempt to destructure non-iterable instance");
+			}
+		};
+	}();
+
+	var tmp = {};
+
+	var DEFAULT = {
+		id: {
+			default: 'cropper',
+			get: function get$$1() {
+				return tmp.id;
+			},
+			set: function set$$1(value) {
+				if (typeof value !== 'string') {}
+				tmp.id = value;
+			}
+		},
+		width: {
+			default: 750,
+			get: function get$$1() {
+				return tmp.width;
+			},
+			set: function set$$1(value) {
+				tmp.width = value;
+			}
+		},
+		height: {
+			default: 750,
+			get: function get$$1() {
+				return tmp.height;
+			},
+			set: function set$$1(value) {
+				tmp.height = value;
+			}
+		},
+		scale: {
+			default: 2.5,
+			get: function get$$1() {
+				return tmp.scale;
+			},
+			set: function set$$1(value) {
+				tmp.scale = value;
+			}
+		},
+		zoom: {
+			default: 5,
+			get: function get$$1() {
+				return tmp.zoom;
+			},
+			set: function set$$1(value) {
+				tmp.zoom = value;
+			}
+		},
+		src: {
+			default: 'cropper',
+			get: function get$$1() {
+				return tmp.src;
+			},
+			set: function set$$1(value) {
+				tmp.src = value;
+			}
+		},
+		cut: {
+			default: {},
+			get: function get$$1() {
+				return tmp.cut;
+			},
+			set: function set$$1(value) {
+				tmp.cut = value;
+			}
+		},
+		onReady: {
+			default: null,
+			get: function get$$1() {
+				return tmp.ready;
+			},
+			set: function set$$1(value) {
+				tmp.ready = value;
+			}
+		},
+		onBeforeImageLoad: {
+			default: null,
+			get: function get$$1() {
+				return tmp.beforeImageLoad;
+			},
+			set: function set$$1(value) {
+				tmp.beforeImageLoad = value;
+			}
+		},
+		onImageLoad: {
+			default: null,
+			get: function get$$1() {
+				return tmp.imageLoad;
+			},
+			set: function set$$1(value) {
+				tmp.imageLoad = value;
+			}
+		},
+		onBeforeDraw: {
+			default: null,
+			get: function get$$1() {
+				return tmp.beforeDraw;
+			},
+			set: function set$$1(value) {
+				tmp.beforeDraw = value;
+			}
+		}
+	};
+	function prepare() {
+		var self = this;
+
+		var _getDevice = getDevice(),
+			windowWidth = _getDevice.windowWidth;
+
+		self.attachPage = function() {
+			var pages = getCurrentPages();
+			var pageContext = pages[pages.length - 1];
+			pageContext.wecropper = self;
+		};
+
+		self.createCtx = function() {
+			var id = self.id;
+
+			if (id) {
+				self.ctx = wx.createCanvasContext(id);
+			}
+		};
+
+		self.deviceRadio = windowWidth / 750;
+		self.deviceRadio = self.deviceRadio.toFixed(2)
+	}
+	function observer() {
+		var self = this;
+
+		var EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];
+
+		self.on = function(event, fn) {
+			if (EVENT_TYPE.indexOf(event) > -1) {
+				if (typeof fn === 'function') {
+					event === 'ready' ? fn(self) : self['on' + firstLetterUpper(event)] = fn;
+				}
+			}
+			return self;
+		};
+	}
+	function methods() {
+		var self = this;
+
+		var deviceRadio = self.deviceRadio;
+
+		var boundWidth = self.width; 
+		var boundHeight = self.height; 
+		var _self$cut = self.cut,
+			_self$cut$x = _self$cut.x,
+			x = _self$cut$x === undefined ? 0 : _self$cut$x,
+			_self$cut$y = _self$cut.y,
+			y = _self$cut$y === undefined ? 0 : _self$cut$y,
+			_self$cut$width = _self$cut.width,
+			width = _self$cut$width === undefined ? boundWidth : _self$cut$width,
+			_self$cut$height = _self$cut.height,
+			height = _self$cut$height === undefined ? boundHeight : _self$cut$height;
+
+
+		self.updateCanvas = function() {
+			if (self.croperTarget) {
+
+
+				self.ctx.drawImage(self.croperTarget, self.imgLeft, self.imgTop, self.scaleWidth, self.scaleHeight);
+			}
+			typeof self.onBeforeDraw === 'function' && self.onBeforeDraw(self.ctx, self);
+
+			self.setBoundStyle();
+			self.ctx.draw();
+			return self;
+		};
+
+		self.pushOrign = function(src) {
+			self.src = src;
+
+			typeof self.onBeforeImageLoad === 'function' && self.onBeforeImageLoad(self.ctx, self);
+
+			uni.getImageInfo({
+				src: src,
+				success: function success(res) {
+					var innerAspectRadio = res.width / res.height;
+					self.croperTarget = res.path || src;
+					if (innerAspectRadio < width / height) {
+						self.rectX = x;
+						self.baseWidth = width;
+						self.baseHeight = width / innerAspectRadio;
+						self.rectY = y - Math.abs((height - self.baseHeight) / 2);
+					} else {
+						self.rectY = y;
+						self.baseWidth = height * innerAspectRadio;
+						self.baseHeight = height;
+						self.rectX = x - Math.abs((width - self.baseWidth) / 2);
+					}
+
+					self.imgLeft = self.rectX;
+					self.imgTop = self.rectY;
+					self.scaleWidth = self.baseWidth;
+					self.scaleHeight = self.baseHeight;
+
+					self.updateCanvas();
+
+					typeof self.onImageLoad === 'function' && self.onImageLoad(self.ctx, self);
+				}
+			});
+
+			self.update();
+			return self;
+		};
+
+		self.getCropperImage = function() {
+			for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+				args[_key] = arguments[_key];
+			}
+
+			var id = self.id;
+
+			var ARG_TYPE = toString.call(args[0]);
+			switch (ARG_TYPE) {
+				case '[object Object]':
+					var _args$0$quality = args[0].quality,
+						quality = _args$0$quality === undefined ? 10 : _args$0$quality;
+
+					uni.canvasToTempFilePath({
+						canvasId: id,
+						x: x,
+						y: y,
+						fileType: "jpg",
+						width: width,
+						height: height,
+						destWidth: width * quality / (deviceRadio * 10),
+						destHeight: height * quality / (deviceRadio * 10),
+						success: function success(res) {
+							typeof args[args.length - 1] === 'function' && args[args.length - 1](res.tempFilePath);
+						}
+					});
+					break;
+				case '[object Function]':
+					uni.canvasToTempFilePath({
+						canvasId: id,
+						x: x,
+						y: y,
+						fileType: "jpg",
+						width: width,
+						height: height,
+						destWidth: width,
+						destHeight: height,
+						success: function success(res) {
+
+							typeof args[args.length - 1] === 'function' && args[args.length - 1](res.tempFilePath);
+						}
+					});
+					break;
+			}
+
+			return self;
+		};
+	}
+
+	function update() {
+		var self = this;
+		if (!self.src) return;
+
+		self.__oneTouchStart = function(touch) {
+			self.touchX0 = touch.x;
+			self.touchY0 = touch.y;
+		};
+
+		self.__oneTouchMove = function(touch) {
+			var xMove = void 0,
+				yMove = void 0;
+			if (self.touchended) {
+				return self.updateCanvas();
+			}
+			xMove = touch.x - self.touchX0;
+			yMove = touch.y - self.touchY0;
+
+			var imgLeft = self.rectX + xMove;
+			var imgTop = self.rectY + yMove;
+
+			self.outsideBound(imgLeft, imgTop);
+
+			self.updateCanvas();
+		};
+
+		self.__twoTouchStart = function(touch0, touch1) {
+			var xMove = void 0,
+				yMove = void 0,
+				oldDistance = void 0;
+
+			self.touchX1 = self.rectX + self.scaleWidth / 2;
+			self.touchY1 = self.rectY + self.scaleHeight / 2;
+
+			xMove = touch1.x - touch0.x;
+			yMove = touch1.y - touch0.y;
+			oldDistance = Math.sqrt(xMove * xMove + yMove * yMove);
+
+			self.oldDistance = oldDistance;
+		};
+
+		self.__twoTouchMove = function(touch0, touch1) {
+			var xMove = void 0,
+				yMove = void 0,
+				newDistance = void 0;
+			var scale = self.scale,
+				zoom = self.zoom;
+
+			xMove = touch1.x - touch0.x;
+			yMove = touch1.y - touch0.y;
+			newDistance = Math.sqrt(xMove * xMove + yMove * yMove
+
+				//  使用0.005的缩放倍数具有良好的缩放体验
+			);
+			self.newScale = self.oldScale + 0.001 * zoom * (newDistance - self.oldDistance);
+
+			//  设定缩放范围
+			self.newScale <= 1 && (self.newScale = 1);
+			self.newScale >= scale && (self.newScale = scale);
+
+			self.scaleWidth = self.newScale * self.baseWidth;
+			self.scaleHeight = self.newScale * self.baseHeight;
+			var imgLeft = self.touchX1 - self.scaleWidth / 2;
+			var imgTop = self.touchY1 - self.scaleHeight / 2;
+
+			self.outsideBound(imgLeft, imgTop);
+
+			self.updateCanvas();
+		};
+
+		self.__xtouchEnd = function() {
+			self.oldScale = self.newScale;
+			self.rectX = self.imgLeft;
+			self.rectY = self.imgTop;
+		};
+	}
+	var handle = {
+		touchStart: function touchStart(e) {
+			var self = this;
+			var _e$touches = slicedToArray(e.touches, 2),
+				touch0 = _e$touches[0],
+				touch1 = _e$touches[1];
+
+			if (!touch0.x) {
+				touch0.x = touch0.clientX;
+				touch0.y = touch0.clientY;
+				if (touch1) {
+					touch1.x = touch1.clientX;
+					touch1.y = touch1.clientY;
+				}
+			}
+
+			setTouchState(self, true, null, null);
+			self.__oneTouchStart(touch0);
+			if (e.touches.length >= 2) {
+				self.__twoTouchStart(touch0, touch1);
+			}
+		},
+
+
+		touchMove: function touchMove(e) {
+			var self = this;
+
+			var _e$touches2 = slicedToArray(e.touches, 2),
+				touch0 = _e$touches2[0],
+				touch1 = _e$touches2[1];
+			if (!touch0.x) {
+				touch0.x = touch0.clientX;
+				touch0.y = touch0.clientY;
+				if (touch1) {
+					touch1.x = touch1.clientX;
+					touch1.y = touch1.clientY;
+				}
+			}
+			setTouchState(self, null, true);
+			if (e.touches.length === 1) {
+				self.__oneTouchMove(touch0);
+			}
+			if (e.touches.length >= 2) {
+				self.__twoTouchMove(touch0, touch1);
+			}
+		},
+		touchEnd: function touchEnd(e) {
+			var self = this;
+
+			setTouchState(self, false, false, true);
+			self.__xtouchEnd();
+		}
+	};
+	function cut() {
+		var self = this;
+		var deviceRadio = self.deviceRadio;
+
+		var boundWidth = self.width;
+		var boundHeight = self.height;
+		var _self$cut = self.cut,
+			_self$cut$x = _self$cut.x,
+			x = _self$cut$x === undefined ? 0 : _self$cut$x,
+			_self$cut$y = _self$cut.y,
+			y = _self$cut$y === undefined ? 0 : _self$cut$y,
+			_self$cut$width = _self$cut.width,
+			width = _self$cut$width === undefined ? boundWidth : _self$cut$width,
+			_self$cut$height = _self$cut.height,
+			height = _self$cut$height === undefined ? boundHeight : _self$cut$height;
+
+
+		self.outsideBound = function(imgLeft, imgTop) {
+			self.imgLeft = imgLeft >= x ? x : self.scaleWidth + imgLeft - x <= width ? x + width - self.scaleWidth : imgLeft;
+
+			self.imgTop = imgTop >= y ? y : self.scaleHeight + imgTop - y <= height ? y + height - self.scaleHeight : imgTop;
+		};
+
+		self.setBoundStyle = function() {
+			var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+				_ref$color = _ref.color,
+				color = _ref$color === undefined ? '#04b00f' : _ref$color,
+				_ref$mask = _ref.mask,
+				mask = _ref$mask === undefined ? 'rgba(0, 0, 0, 0.5)' : _ref$mask,
+				_ref$lineWidth = _ref.lineWidth,
+				lineWidth = _ref$lineWidth === undefined ? 1 : _ref$lineWidth;
+
+			self.ctx.beginPath();
+			self.ctx.setFillStyle(mask);
+			self.ctx.fillRect(0, 0, x, boundHeight);
+			self.ctx.fillRect(x, 0, width, y);
+			self.ctx.fillRect(x, y + height, width, boundHeight - y - height);
+			self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);
+			self.ctx.fill();
+			self.ctx.beginPath();
+			self.ctx.setStrokeStyle(color);
+			self.ctx.setLineWidth(lineWidth);
+			self.ctx.moveTo(x - lineWidth, y + 10 - lineWidth);
+			self.ctx.lineTo(x - lineWidth, y - lineWidth);
+			self.ctx.lineTo(x + 10 - lineWidth, y - lineWidth);
+			self.ctx.stroke();
+			self.ctx.beginPath();
+			self.ctx.setStrokeStyle(color);
+			self.ctx.setLineWidth(lineWidth);
+			self.ctx.moveTo(x - lineWidth, y + height - 10 + lineWidth);
+			self.ctx.lineTo(x - lineWidth, y + height + lineWidth);
+			self.ctx.lineTo(x + 10 - lineWidth, y + height + lineWidth);
+			self.ctx.stroke();
+			self.ctx.beginPath();
+			self.ctx.setStrokeStyle(color);
+			self.ctx.setLineWidth(lineWidth);
+			self.ctx.moveTo(x + width - 10 + lineWidth, y - lineWidth);
+			self.ctx.lineTo(x + width + lineWidth, y - lineWidth);
+			self.ctx.lineTo(x + width + lineWidth, y + 10 - lineWidth);
+			self.ctx.stroke();
+			self.ctx.beginPath();
+			self.ctx.setStrokeStyle(color);
+			self.ctx.setLineWidth(lineWidth);
+			self.ctx.moveTo(x + width + lineWidth, y + height - 10 + lineWidth);
+			self.ctx.lineTo(x + width + lineWidth, y + height + lineWidth);
+			self.ctx.lineTo(x + width - 10 + lineWidth, y + height + lineWidth);
+			self.ctx.stroke();
+		};
+	}
+
+	var __version__ = '1.1.4';
+
+	var weCropper = function() {
+		function weCropper(params) {
+			classCallCheck(this, weCropper);
+
+			var self = this;
+			var _default = {};
+
+			validator(self, DEFAULT);
+
+			Object.keys(DEFAULT).forEach(function(key) {
+				_default[key] = DEFAULT[key].default;
+			});
+			Object.assign(self, _default, params);
+
+			self.prepare();
+			self.attachPage();
+			self.createCtx();
+			self.observer();
+			self.cutt();
+			self.methods();
+			self.init();
+			self.update();
+
+			return self;
+		}
+
+		createClass(weCropper, [{
+			key: 'init',
+			value: function init() {
+				var self = this;
+				var src = self.src;
+
+
+				self.version = __version__;
+
+				typeof self.onReady === 'function' && self.onReady(self.ctx, self);
+
+				if (src) {
+					self.pushOrign(src);
+				}
+				setTouchState(self, false, false, false);
+
+				self.oldScale = 1;
+				self.newScale = 1;
+
+				return self;
+			}
+		}]);
+		return weCropper;
+	}();
+
+	Object.assign(weCropper.prototype, handle);
+
+
+	weCropper.prototype.prepare = prepare;
+	weCropper.prototype.observer = observer;
+	weCropper.prototype.methods = methods;
+	weCropper.prototype.cutt = cut;
+	weCropper.prototype.update = update;
+
+	return weCropper;
+
+})));

+ 223 - 0
yudao-vue-ui/pages/set/cutImage/cut.vue

@@ -0,0 +1,223 @@
+<template>
+	<view class="content">
+		<view class="title-view" :style="{height: navigationBarHeight + 'px'}">
+			<navigator open-type="navigateBack" class="back-btn mix-icon icon-xiangzuo"></navigator>
+			<text class="title">裁剪</text>
+			<text class="empty"></text>
+		</view>
+
+		<view class="cropper-wrapper">
+			<canvas 
+				class="cropper"
+				disable-scroll="true"
+				@touchstart="touchStart"
+				@touchmove="touchMove"
+				@touchend="touchEnd"
+				:style="{ width: cropperOpt.width, height: cropperOpt.height }"
+				canvas-id="cropper"
+			 ></canvas>
+		</view>
+		<view class="cropper-buttons">
+			<view class="btn upload" @tap="uploadTap">重选</view>
+			<view class="btn getCropperImage" @tap="getCropperImage">确定</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import weCropper from './cut.js';
+	const device = uni.getSystemInfoSync();
+	const width = device.windowWidth;
+	const height = device.windowHeight;
+
+	export default {
+		data() {
+			return {
+				cropperOpt: {
+					id: 'cropper',
+					width: width,
+					height: height,
+					scale: 2.5,
+					zoom: 8,
+					cut: {
+						x: (width - 200) / 2,
+						y: (height - this.systemInfo.navigationBarHeight - this.systemInfo.statusBarHeight - 200) / 2,
+						width: 200,
+						height: 200
+					}
+				},
+				weCropper: ''
+			};
+		},
+		computed: {
+			navigationBarHeight(){
+				console.log(this.systemInfo.navigationBarHeight);
+				return this.systemInfo.navigationBarHeight;
+			}
+		},
+		onLoad(option) {
+			// do something
+			const cropperOpt = this.cropperOpt;
+			const src = option.src;
+			console.log(src);
+			if (src) {
+				Object.assign(cropperOpt, {
+					src
+				});
+
+				this.weCropper = new weCropper(cropperOpt)
+					.on('ready', function(ctx) {})
+					.on('beforeImageLoad', ctx => {
+						/* uni.showToast({
+							title: '上传中',
+							icon: 'loading',
+							duration: 3000
+						}); */
+					})
+					.on('imageLoad', ctx => {
+						uni.hideToast();
+					});
+			}
+		},
+		methods: {
+			touchStart(e) {
+				this.weCropper.touchStart(e);
+			},
+			touchMove(e) {
+				this.weCropper.touchMove(e);
+			},
+			touchEnd(e) {
+				this.weCropper.touchEnd(e);
+			},
+			convertBase64UrlToBlob(dataURI, type) {
+				var binary = atob(dataURI.split(',')[1]);
+				var array = [];
+				for (var i = 0; i < binary.length; i++) {
+					array.push(binary.charCodeAt(i));
+				}
+				return new Blob([new Uint8Array(array)], {
+					type: type
+				}, {
+					filename: '1111.jpg'
+				});
+			},
+			blobToDataURL(blob) {
+				var a = new FileReader();
+				a.readAsDataURL(blob); //读取文件保存在result中
+				a.onload = function(e) {
+					var getRes = e.target.result; //读取的结果在result中
+					console.log(getRes);
+				};
+			},
+			getCropperImage() {
+				let _this = this;
+				this.weCropper.getCropperImage(avatar => {
+					if (avatar) {
+						this.$util.prePage().setAvatar(avatar);
+						uni.navigateBack();
+
+					} else {
+						console.log('获取图片失败,请稍后重试');
+					}
+				});
+			},
+			uploadTap() {
+				const self = this;
+
+				uni.chooseImage({
+					count: 1, // 默认9
+					sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
+					success(res) {
+						let src = res.tempFilePaths[0];
+						//  获取裁剪图片资源后,给data添加src属性及其值
+						self.weCropper.pushOrign(src);
+					}
+				});
+			}
+		},
+	};
+</script>
+
+<style lang="scss">
+	page, .content{
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+	}
+	.content {
+		display: flex;
+		flex-direction: column;
+		background-color: #000;
+		padding-top: var(--status-bar-height);
+	}
+
+	.title-view{
+		flex-shrink: 0;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		width: 100%;
+		background: transparent;
+		
+		.back-btn{
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			width: 42px;
+			height: 40px;
+			font-size: 18px;
+			color: #fff;
+		}
+		.title{
+			font-size: 17px;
+			color: #fff;
+		}
+		.empty{
+			width: 42px;
+		}
+	}
+
+	.cropper {
+		width: 100%;
+		flex: 1;
+	}
+
+	.cropper-wrapper {
+		flex: 1;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		background-color: #000;
+	}
+
+	.cropper-buttons {
+		flex-shrink: 0;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		height: 50px;
+		background-color: rgba(0, 0, 0, 0.4);
+		
+		.btn{
+			width: 100px;
+			height: 50px;
+			line-height: 50px;
+			font-size: 15px;
+			color: #fff;
+			
+			&.upload{
+				padding-left: 20px;
+			}
+			
+			&.getCropperImage{
+				padding-right: 20px;
+				text-align: right;
+			}
+		}
+	}
+</style>

+ 8 - 31
yudao-vue-ui/pages/set/userInfo.vue

@@ -5,8 +5,7 @@
 			<view class="avatar-wrap" @click="chooseImage">
 				<image class="avatar" :src="tempAvatar || userInfo.avatar || '/static/icon/default-avatar.png'" mode="aspectFill"></image>
 				<!-- 进度遮盖 -->
-				<view 
-					class="progress center"
+				<view class="progress center"
 					:class="{
 						'no-transtion': uploadProgress === 0,
 						show: uploadProgress != 100
@@ -14,27 +13,13 @@
 					:style="{
 						width: uploadProgress + '%',
 						height: uploadProgress + '%',
-					}"
-				></view>
+					}"></view>
 			</view>
 		</view>
 		<view class="cell b-b">
 			<text class="tit fill">昵称</text>
 			<input class="input" v-model="userInfo.nickname" type="text" maxlength="8" placeholder="请输入昵称" placeholder-class="placeholder">
 		</view>
-		<view class="cell b-b">
-			<text class="tit fill">性别</text>
-			<view class="checkbox center" @click="changeGender(1)">
-				<text v-if="userInfo.gender == 1" class="mix-icon icon-xuanzhong"></text>
-				<text v-else class="mix-icon icon-yk_yuanquan"></text>
-				<text>男</text>
-			</view>
-			<view class="checkbox center" @click="changeGender(2)">
-				<text v-if="userInfo.gender == 2" class="mix-icon icon-xuanzhong"></text>
-				<text v-else class="mix-icon icon-yk_yuanquan"></text>
-				<text>女</text>
-			</view>
-		</view>
 		
 		<mix-button ref="confirmBtn" text="保存资料" marginTop="80rpx" @onConfirm="confirm"></mix-button>
 	</view>
@@ -65,11 +50,12 @@
 			this.userInfo = {avatar, nickname, gender};
 		},
 		methods: {
-			//提交修改
-			async confirm(){
+			// 提交修改
+			async confirm() {
+				// 校验信息是否变化
 				const {uploadProgress, userInfo, curUserInfo} = this;
 				let isUpdate = false;
-				for(let key in userInfo){
+				for (let key in userInfo) {
 					if(userInfo[key] !== curUserInfo[key]){
 						isUpdate = true;
 						break;
@@ -95,11 +81,6 @@
 					this.$refs.confirmBtn.stop();
 					return;
 				}
-				if (!userInfo.gender) {
-					this.$util.msg('请选择您的性别');
-					this.$refs.confirmBtn.stop();
-					return;
-				}
 				const res = await this.$request('user', 'update', userInfo);
 				this.$refs.confirmBtn.stop();
 				this.$util.msg(res.msg);
@@ -110,7 +91,7 @@
 					}, 1000)
 				}
 			},
-			//选择头像
+			// 选择头像
 			chooseImage(){
 				uni.chooseImage({
 					count: 1,
@@ -121,7 +102,7 @@
 					}
 				});
 			}, 
-			//裁剪回调
+			// 裁剪回调
 			async setAvatar(filePath){
 				this.tempAvatar = filePath;
 				this.uploadProgress = 0;
@@ -151,10 +132,6 @@
 						this.$util.msg('头像上传失败');
 					}
 				}
-			},
-			//修改性别
-			changeGender(gender){
-				this.$set(this.userInfo, 'gender', gender)
 			}
 		}
 	}

+ 15 - 24
yudao-vue-ui/pages/tabbar/user.vue

@@ -52,27 +52,20 @@
 		</view>
 
 		<!-- 功能入口 -->
-		<view class="option-wrap">
-			<!-- <mix-list-cell icon="icon-iconfontweixin" iconColor="#fa436a" title="我的钱包" @onClick="navTo('/pages/wallet/index', {login: true})"></mix-list-cell> -->
-			<!-- <mix-list-cell icon="icon-dizhi" iconColor="#5fcda2" title="地址管理" @onClick="navTo('/pages/address/list', {login: true})"></mix-list-cell> -->
-			<!-- <mix-list-cell icon="icon-share" iconColor="#9789f7" title="分享" tips="呼朋唤友赢好礼"></mix-list-cell> -->
-			<!-- <mix-list-cell icon="icon-shoucang_xuanzhongzhuangtai" iconColor="#54b4ef" title="我的收藏" @onClick="navTo('/pages/favorite/favorite', {login: true})"></mix-list-cell> -->
-			<!-- <mix-list-cell icon="icon-pinglun-copy" iconColor="#ee883b" title="意见反馈" @onClick="navTo('/pages/feedback/feedback', {login: true})"></mix-list-cell> -->
-			<!-- <mix-list-cell icon="icon-shezhi1" iconColor="#37b0fb" title="设置" border="" @onClick="navTo('/pages/set/set', {login: true})"></mix-list-cell> -->
-			<mix-list-cell icon="icon-bianji" iconColor="#5fcda2" title="个人信息" border="" @onClick="navTo('/pages/set/userInfo', {login: true})"></mix-list-cell>
-			<mix-list-cell icon="icon-shezhi1" iconColor="#37b0fb" title="账号安全" border="" @onClick="navTo('/pages/set/set', {login: true})"></mix-list-cell>
-		</view>
+		<u-cell-group class="option1-wrap">
+			<u-cell icon="edit-pen" title="个人信息" isLink @click="navTo('/pages/set/userInfo', {login: true})"></u-cell>
+			<u-cell icon="setting" title="账号安全" isLink @click="navTo('/pages/set/set', {login: true})"></u-cell>
+		</u-cell-group>
 	</view>
 </template>
 
 <script>
+	import { mapState, mapGetters } from 'vuex'
+	import { isLogin } from '@/common/js/util.js'
+	
 	export default {
 		data() {
 			return {
-				userInfo: { // TODO 芋艿:读取
-					nickname: '芋艿'
-				},
-				hasLogin: true, // TODO 芋艿:读取
 				orderCount: { // TODO 芋艿:读取
 					c0: 1,
 					c1: 2,
@@ -81,9 +74,15 @@
 				}
 			};
 		},
+		computed: {
+			...mapState(['userInfo']),
+			...mapGetters(['hasLogin']),
+		},
 		onShow() {
-			// 获得用户信息
-			this.$store.dispatch('obtainUserInfo');
+			// 获得用户信息 TODO 芋艿:
+			// if (isLogin()) {
+			// 	this.$store.dispatch('obtainUserInfo');
+			// }
 			// TODO 芋艿:获得订单数量
 		}
 	}
@@ -211,12 +210,4 @@
 			}
 		}
 	}
-
-	.option-wrap {
-		width: 700rpx;
-		margin: 20rpx auto 0;
-		margin-top: 20rpx;
-		background: #fff;
-		border-radius: 10rpx;
-	}
 </style>

+ 3 - 1
yudao-vue-ui/uni.scss

@@ -37,4 +37,6 @@ $black : #000 ;
 $gray : #777 ;
 $grey : #82939c ;
 	
-$borderColor:#e0e0e0;
+$borderColor:#e0e0e0;
+
+@import '@/uni_modules/uview-ui/theme.scss';