liukang 2 سال پیش
والد
کامیت
605880d81d
100فایلهای تغییر یافته به همراه9343 افزوده شده و 1274 حذف شده
  1. 23 0
      .hbuilderx/launch.json
  2. 484 1
      App.vue
  3. 4 0
      components/chat/chat.css
  4. 271 0
      components/chat/chat.vue
  5. 394 0
      components/chat/emediaInvite/emediaInvite.css
  6. 240 0
      components/chat/emediaInvite/emediaInvite.vue
  7. 65 0
      components/chat/inputbar/inputbar.css
  8. 227 0
      components/chat/inputbar/inputbar.vue
  9. 73 0
      components/chat/inputbar/suit/audio/audio.css
  10. 347 0
      components/chat/inputbar/suit/audio/audio.vue
  11. 14 0
      components/chat/inputbar/suit/audio/record_status.js
  12. 39 0
      components/chat/inputbar/suit/emoji/emoji.css
  13. 82 0
      components/chat/inputbar/suit/emoji/emoji.vue
  14. 169 0
      components/chat/inputbar/suit/image/image.vue
  15. 95 0
      components/chat/inputbar/suit/location/location.vue
  16. 65 0
      components/chat/inputbar/suit/main/main.css
  17. 189 0
      components/chat/inputbar/suit/main/main.vue
  18. 65 0
      components/chat/inputbar/suit/ptopcall/ptopcall.vue
  19. 110 0
      components/chat/inputbar/suit/videoComp/videoComp.vue
  20. 148 0
      components/chat/msglist/msglist.css
  21. 323 0
      components/chat/msglist/msglist.vue
  22. 25 0
      components/chat/msglist/type/audio/audio.css
  23. 178 0
      components/chat/msglist/type/audio/audio.vue
  24. 62 0
      components/chat/msglist/type/audio/audioCtxFactory.js
  25. 5 0
      components/chat/msglist/type/audio/playStatus.js
  26. 56 0
      components/chat/msgpackager.js
  27. 195 0
      components/chat/msgstorage.js
  28. 14 0
      components/chat/msgtype.js
  29. 0 0
      components/chat/multiemedia/index.css
  30. 484 0
      components/chat/multiemedia/index.nvue
  31. 3 3
      components/custom-tab-bar/custom-tab-bar.vue
  32. 110 0
      components/longPressModal/index.vue
  33. 29 0
      components/swipedelete/swipedelete.css
  34. 68 0
      components/swipedelete/swipedelete.vue
  35. 90 7
      manifest.json
  36. 0 0
      newSDK/uni_sdk3.6.3.js
  37. 0 0
      newSDK/uni_sdk4.0.1.js
  38. 0 0
      newSDK/uni_sdk4.0.3.js
  39. 0 0
      newSDK/uni_sdk4.0.4.js
  40. 0 0
      newSDK/uni_sdk4.0.5.js
  41. 0 0
      newSDK/uni_sdk4.0.7.js
  42. 119 84
      node_modules/uview-ui/package.json
  43. 6 17
      package-lock.json
  44. 1 0
      package.json
  45. 48 15
      pages.json
  46. 4 0
      pages/chatroom/chatroom.css
  47. 99 0
      pages/chatroom/chatroom.vue
  48. 825 610
      pages/good/add.vue
  49. 15 5
      pages/good/manager.vue
  50. 6 0
      pages/good/options.vue
  51. 62 9
      pages/good/setting.vue
  52. 23 37
      pages/good/spec.vue
  53. 24 32
      pages/login/codeLogin/codeLogin.vue
  54. 15 7
      pages/login/forgot/forgot.vue
  55. 6 17
      pages/login/login/login.vue
  56. 49 0
      pages/login/xieyi.vue
  57. 236 0
      pages/mine/message/chat.css
  58. 57 1
      pages/mine/message/detail.vue
  59. 791 1
      pages/mine/message/index.vue
  60. 164 1
      pages/mine/message/list.vue
  61. 46 10
      pages/mine/service/address/add.vue
  62. 175 31
      pages/mine/service/detail.vue
  63. 2 2
      pages/mine/service/feed/detail.vue
  64. 25 13
      pages/mine/service/feed/feed.vue
  65. 15 2
      pages/mine/service/feed/history.vue
  66. 218 87
      pages/mine/service/purOrder/detail.vue
  67. 55 8
      pages/mine/service/purOrder/list.vue
  68. 27 13
      pages/mine/service/purOrder/msg.vue
  69. 2 2
      pages/mine/service/rule.vue
  70. 54 0
      pages/mine/service/setting/about.vue
  71. 2 2
      pages/mine/service/setting/account_info.vue
  72. 12 7
      pages/mine/service/setting/bind_eMail.vue
  73. 1 0
      pages/mine/service/setting/edit_pwd.vue
  74. 7 7
      pages/mine/service/setting/personal.vue
  75. 3 3
      pages/mine/service/setting/setting.vue
  76. 4 4
      pages/mine/wallet/add.vue
  77. 4 4
      pages/mine/wallet/bankList.vue
  78. 12 8
      pages/mine/wallet/wallet.vue
  79. 21 7
      pages/mine/wallet/withdraw.vue
  80. 57 13
      pages/order/list.vue
  81. 42 17
      pages/order/orderDetail.vue
  82. 148 12
      pages/order/refund.vue
  83. 137 48
      pages/order/refundDetail.vue
  84. 5 4
      pages/order/send.vue
  85. 179 6
      pages/release/ocean/ocean.vue
  86. 232 47
      pages/release/production/production.vue
  87. 204 6
      pages/release/purchase/purchase.vue
  88. 228 44
      pages/release/waixie/waixie.vue
  89. 94 17
      pages/tabbar/index/index.vue
  90. 36 3
      pages/tabbar/mine/mine.vue
  91. BIN
      static/images/Camera.png
  92. BIN
      static/images/Emoji.png
  93. BIN
      static/images/ad.png
  94. BIN
      static/images/camora.png
  95. BIN
      static/images/ctbg.png
  96. BIN
      static/images/faces/btn_del.png
  97. BIN
      static/images/faces/del.png
  98. BIN
      static/images/faces/ee_1.png
  99. BIN
      static/images/faces/ee_10.png
  100. BIN
      static/images/faces/ee_11.png

+ 23 - 0
.hbuilderx/launch.json

@@ -0,0 +1,23 @@
+{
+    // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+    // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version" : "0.0",
+    "configurations" : [
+        {
+            "app-plus" : {
+                "launchtype" : "local"
+            },
+            "default" : {
+                "launchtype" : "local"
+            },
+            "mp-weixin" : {
+                "launchtype" : "local"
+            },
+            "type" : "uniCloud"
+        },
+        {
+            "playground" : "custom",
+            "type" : "uni-app:app-ios"
+        }
+    ]
+}

+ 484 - 1
App.vue

@@ -1,17 +1,500 @@
 <script>
+	let WebIM = (wx.WebIM = require("./utils/WebIM")["default"]);
+	let msgStorage = require("./components/chat/msgstorage");
+	let msgType = require("./components/chat/msgtype");
+	let disp = require("./utils/broadcast");
+	let logout = false;
+	// let emedia = uni.emedia = require("./emediaSDK/webrtc/src/entry")
+	// let emedia = (uni.emedia = require("./emediaSDK/emedia_for_miniProgram"));
+	// emedia.config({ useUniappPlugin: true });
+	function ack(receiveMsg) {
+	  // 处理未读消息回执
+	  var bodyId = receiveMsg.id; // 需要发送已读回执的消息id
+	
+	  var ackMsg = new WebIM.message("read", WebIM.conn.getUniqueId());
+	  ackMsg.set({
+	    id: bodyId,
+	    to: receiveMsg.from,
+	  });
+	  WebIM.conn.send(ackMsg.body);
+	}
+	function onMessageError(err) {
+	  if (err.type === "error") {
+	    uni.showToast({
+	      title: err.errorText,
+	    });
+	    return false;
+	  }
+	
+	  return true;
+	}
+	function getCurrentRoute() {
+	  let pages = getCurrentPages();
+	  if (pages.length > 0) {
+	    let currentPage = pages[pages.length - 1];
+	    return currentPage.route;
+	  }
+	  return "/";
+	}
+	
+	
+	// 包含陌生人版本
+	function calcUnReadSpot(message) {
+	  let myName = uni.getStorageSync("myUsername");
+	  uni.getStorageInfo({
+	    success: function (res) {
+	      let storageKeys = res.keys;
+	      let newChatMsgKeys = [];
+	      let historyChatMsgKeys = [];
+	      storageKeys.forEach((item) => {
+	        if (item.indexOf(myName) > -1 && item.indexOf("rendered_") == -1) {
+	          newChatMsgKeys.push(item);
+	        }
+	      });
+	      let count = newChatMsgKeys.reduce(function (result, curMember, idx) {
+	        let chatMsgs;
+	        chatMsgs = uni.getStorageSync(curMember) || [];
+	        return result + chatMsgs.length;
+	      }, 0);
+	
+	      getApp().globalData.unReadMessageNum = count;
+	      disp.fire("em.unreadspot", message);
+	    },
+	  });
+	}
+	
+	function saveGroups() {
+	  var me = this;
+	  return WebIM.conn.getGroup({
+	    limit: 50,
+	    success: function (res) {
+	      uni.setStorage({
+	        key: "listGroup",
+	        data: res.data,
+	      });
+	    },
+	    error: function (err) {
+	      console.log(err);
+	    },
+	  });
+	}
+	
+	// var jpushModule = uni.requireNativePlugin("JG-JPush");
+	import webIM from './utils/WebIM.js'
+	var that = ''
 	export default {
+		globalData: {
+			unReadMessageNum: 0,
+			userInfo: null,
+			saveFriendList: [],
+			saveGroupInvitedList: [],
+			isIPX: false, //是否为iphone X
+			conn: {
+				closed: false,
+				curOpenOpt: {},
+		
+				open(opt) {
+					uni.showLoading({
+						title: "正在初始化客户端..",
+						mask: true,
+					});
+					this.curOpenOpt = opt;
+					WebIM.conn.open(opt);
+					this.closed = false;
+				},
+		
+				reopen() {
+					if (this.closed) {
+						//this.open(this.curOpenOpt);
+						WebIM.conn.open(this.curOpenOpt);
+						this.closed = false;
+					}
+				},
+			},
+			onLoginSuccess: function(myName) {
+				uni.hideLoading();
+				uni.redirectTo({
+					url: "../chat/chat?myName=" + myName,
+				});
+			},
+		
+			getUserInfo(cb) {
+				var me = this;
+		
+				if (this.userInfo) {
+					typeof cb == "function" && cb(this.userInfo);
+				} else {
+					// 调用登录接口
+					uni.login({
+						success() {
+							uni.getUserInfo({
+								success(res) {
+									me.userInfo = res.userInfo;
+									typeof cb == "function" && cb(me.userInfo);
+								},
+							});
+						},
+					});
+				}
+			},
+		
+			checkIsIPhoneX: function() {
+				const me = this;
+				uni.getSystemInfo({
+					success: function(res) {
+						// 根据 model 进行判断
+						if (res.model && res.model.search("iPhone X") != -1) {
+							me.isIPX = true;
+						}
+					},
+				});
+			},
+		},
+		
 		onLaunch: function() {
+			this.HXlogin()
 			console.log('App Launch')
+			var me = this;
+			var logs = uni.getStorageSync("logs") || [];
+			logs.unshift(Date.now());
+			uni.setStorageSync("logs", logs); //
+			
+			disp.on("em.main.ready", function() {
+				calcUnReadSpot();
+			});
+			disp.on("em.chatroom.leave", function() {
+				calcUnReadSpot();
+			});
+			disp.on("em.chat.session.remove", function() {
+				calcUnReadSpot();
+			});
+			disp.on("em.chat.audio.fileLoaded", function() {
+				calcUnReadSpot();
+			});
+			disp.on("em.main.deleteFriend", function() {
+				calcUnReadSpot();
+			});
+			disp.on("em.chat.audio.fileLoaded", function() {
+				calcUnReadSpot();
+			}); //
+			
+			WebIM.conn.listen({
+				onOpened(message) {
+					console.log('>>>>>>环信登录成功啦')
+				},
+			
+				onReconnect() {
+					uni.showToast({
+						title: "重连中...",
+						duration: 2000,
+					});
+				},
+			
+				onSocketConnected() {
+					uni.showToast({
+						title: "socket连接成功",
+						duration: 2000,
+					});
+				},
+			
+				onClosed() {
+					uni.showToast({
+						title: "网络已断开",
+						icon: "none",
+						duration: 2000,
+					});
+					uni.redirectTo({
+						url: "/pages/login/codeLogin/codeLogin",
+					});
+					me.globalData.conn.closed = true;
+					WebIM.conn.close();
+				},
+			
+				onInviteMessage(message) {
+					me.globalData.saveGroupInvitedList.push(message);
+					disp.fire("em.invite.joingroup", message); // uni.showModal({
+					// 	title: message.from + " 已邀你入群 " + message.roomid,
+					// 	success(){
+					// 		disp.fire("em.invite.joingroup", message);
+					// 	},
+					// 	error(){
+					// 		disp.fire("em.invite.joingroup", message);
+					// 	}
+					// });
+				},
+			
+				onReadMessage(message) {
+					//console.log('已读', message)
+				},
+			
+				//onPresence为旧版 ,建议参考最新增删好友api文档 :http://docs-im.easemob.com/im/web/basics/buddy
+				onPresence(message) {
+			
+					switch (message.type) {
+						case "unsubscribe":
+							break;
+							// 好友邀请列表
+						case "subscribe":
+							for (let i = 0; i < me.globalData.saveFriendList.length; i++) {
+								if (me.globalData.saveFriendList[i].from === message.from) {
+									me.globalData.saveFriendList[i] = message;
+									disp.fire("em.subscribe");
+									return;
+								}
+							}
+							msgStorage.saveReceiveMsg(message, 'INFORM'); //存添加好友消息,方便展示通知
+							me.globalData.saveFriendList.push(message);
+							disp.fire("em.subscribe");
+			
+							break;
+			
+						case "subscribed":
+							uni.showToast({
+								title: "添加成功",
+								duration: 1000,
+							});
+							disp.fire("em.subscribed");
+							break;
+			
+						case "unsubscribed":
+							disp.fire("em.unsubscribed");
+							break;
+						case "direct_joined":
+							saveGroups();
+							uni.showToast({
+								title: "已进群",
+								duration: 1000,
+							});
+							break;
+						case "memberJoinPublicGroupSuccess":
+							saveGroups();
+							uni.showToast({
+								title: "已进群",
+								duration: 1000,
+							});
+							break;
+						case "invite":
+							// 防止重复添加
+							for (let i = 0; i < me.globalData.saveGroupInvitedList.length; i++) {
+								if (me.globalData.saveGroupInvitedList[i].from === message.from) {
+									me.globalData.saveGroupInvitedList[i] = message;
+									disp.fire("em.invite.joingroup")
+									return;
+								}
+							}
+							me.globalData.saveGroupInvitedList.push(message);
+							disp.fire("em.invite.joingroup");
+							msgStorage.saveReceiveMsg(message, 'INFORM'); //存添加好友消息,方便展示通知
+							break;
+						case "unavailable":
+							disp.fire("em.contacts.remove");
+							disp.fire("em.group.leaveGroup", message);
+							break;
+			
+						case "deleteGroupChat":
+							disp.fire("em.invite.deleteGroup", message);
+							break;
+			
+						case "leaveGroup":
+							disp.fire("em.group.leaveGroup", message);
+							break;
+			
+						case "removedFromGroup":
+							disp.fire("em.group.leaveGroup", message);
+							break;
+			
+						default:
+							break;
+					}
+				},
+			
+				onRoster(message) {
+					// let pages = getCurrentPages();
+					// if(pages[0]){
+					// 	pages[0].onShow();
+					// }
+				},
+			
+				onVideoMessage(message) {
+					console.log("onVideoMessage: ", message);
+			
+					if (message) {
+						msgStorage.saveReceiveMsg(message, msgType.VIDEO);
+					}
+			
+					calcUnReadSpot(message);
+					ack(message);
+				},
+			
+				onAudioMessage(message) {
+					console.log("onAudioMessage", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.AUDIO);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				onCmdMessage(message) {
+					console.log("onCmdMessage", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.CMD);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				// onLocationMessage(message){
+				// 	console.log("Location message: ", message);
+				// 	if(message){
+				// 		msgStorage.saveReceiveMsg(message, msgType.LOCATION);
+				// 	}
+				// },
+				onTextMessage(message) {
+					console.log("收到消息", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.TEXT);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				onEmojiMessage(message) {
+					console.log("onEmojiMessage", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.EMOJI);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				onPictureMessage(message) {
+					console.log("onPictureMessage", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.IMAGE);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				onFileMessage(message) {
+					console.log("onFileMessage", message);
+			
+					if (message) {
+						if (onMessageError(message)) {
+							msgStorage.saveReceiveMsg(message, msgType.FILE);
+						}
+			
+						calcUnReadSpot(message);
+						ack(message);
+					}
+				},
+			
+				// 各种异常
+				onError(error) {
+					console.log(error); // 16: server-side close the websocket connection
+					// if (error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED) {
+					//   // if(error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED && !logout){
+					//   // if(WebIM.conn.autoReconnectNumTotal < WebIM.conn.autoReconnectNumMax){
+					//   // 	return;
+					//   // }
+					//   uni.showToast({
+					//     title: "websocket 断开",
+					//     duration: 1000
+					//   });
+					//   uni.redirectTo({
+					//     url: "../login/login"
+					//   });
+					//   logout = true;
+					//   return;
+					// } // 8: offline by multi login
+			
+					// if (error.type == WebIM.statusCode.WEBIM_CONNCTION_SERVER_ERROR) {
+					//   uni.showToast({
+					//     title: "offline by multi login",
+					//     duration: 1000
+					//   });
+					//   uni.redirectTo({
+					//     url: "../login/login"
+					//   });
+					// }
+			
+					if (error.type == WebIM.statusCode.WEBIM_CONNCTION_OPEN_ERROR) {
+						uni.hideLoading();
+						disp.fire("em.error.passwordErr"); // uni.showModal({
+						// 	title: "用户名或密码错误",
+						// 	confirmText: "OK",
+						// 	showCancel: false
+						// });
+					}
+			
+					if (error.type == WebIM.statusCode.WEBIM_CONNCTION_AUTH_ERROR) {
+						uni.hideLoading();
+						disp.fire("em.error.tokenErr");
+					}
+			
+					if (error.type == "socket_error") {
+						///sendMsgError
+						console.log("socket_errorsocket_error", error);
+						uni.showToast({
+							title: "网络已断开",
+							icon: "none",
+							duration: 2000,
+						});
+						disp.fire("em.error.sendMsgErr", error);
+					}
+				},
+			});
+			this.globalData.checkIsIPhoneX();
 		},
 		onShow: function() {
 			console.log('App Show')
 		},
 		onHide: function() {
 			console.log('App Hide')
+		},
+		methods: {
+			HXlogin() {
+				var userId = uni.getStorageSync('myUsername')
+				var options = {
+					user: userId,
+					pwd	: '12345678',
+					appKey: uni.WebIM.config.appkey,
+					success: function() {
+						// var lianjie = uni.WebIM.conn.isOpened()
+						var my = uni.getStorageSync("myUsername");
+						console.log('登录成功');
+						// uni.setStorageSync('myUsername',my)
+					},
+					error: function() {
+						
+					}
+				}
+				uni.WebIM.conn.open(options);
+			}
 		}
 	}
 </script>
-
 <style lang="scss">
 	/*每个页面公共css */
 	@import "colorui/main.css";

+ 4 - 0
components/chat/chat.css

@@ -0,0 +1,4 @@
+.main {
+	width: 100%;
+	height: 100%;
+}

+ 271 - 0
components/chat/chat.vue

@@ -0,0 +1,271 @@
+<template>
+  <view class="main">
+    <view class="main">
+      <chatSuitAudio
+        ref="chatSuitAudio"
+        :username="username"
+        :chatType="chatType"
+        @newAudioMsg="saveSendMsg"
+      ></chatSuitAudio>
+
+      <chatMsglist
+        ref="chatMsglist"
+        :username="username"
+        @msglistTap="normalScroll"
+		@clickMsg="clickMsg"
+        id="chat-msglist"
+      ></chatMsglist>
+    </view>
+    <chatInputbar
+      ref="chatInputbar"
+      :username="username"
+      :chatType="chatType"
+      @newTextMsg="saveSendMsg"
+      @newImageMsg="saveSendMsg"
+      @newLocationMsg="saveSendMsg"
+      @newVideoMsg="saveSendMsg"
+      @tapSendAudio="toggleRecordModal"
+      @inputFocused="shortScroll"
+      @inputBlured="normalScroll"
+	  @makeVideoCall="onMakeVideoCall"
+	  @makeAudioCall="onMakeAudioCall"
+	  v-show="!showEmediaInvite"
+    ></chatInputbar>
+	
+	<chatEmediaInvite 
+		:username="username" 
+		:action="action"
+		@onStartConfr="onStartConfr"
+		@goBack="onGoBack"
+		v-if="showEmediaInvite"/>
+		
+	<!-- <chatMultiEmedia
+		style="{display: multiEmediaVisible}"
+		:username="username" 
+		:groupId="groupId"
+		:action="emediaAction"
+		@inviteMember="onInviteMember"
+		@createConfrSuccess="onCreateConfrSuccess"
+		@hangup="onHangup"
+		v-if="showmultiEmedia"/> -->
+  </view>
+  
+</template>
+
+<script>
+let msgStorage = require("./msgstorage");
+let msgType = require("./msgtype");
+import chatMsglist from "./msglist/msglist";
+import chatInputbar from "./inputbar/inputbar";
+import chatSuitAudio from "./inputbar/suit/audio/audio";
+import chatEmediaInvite from "./emediaInvite/emediaInvite.vue"
+import chatMultiEmedia from "./multiemedia/index.nvue"
+export default {
+  data() {
+    return {
+    __comps__: {
+        msglist: null,
+        inputbar: null,
+        audio: null,
+    },
+	inputbarVisible: 'block',
+	action: null,
+	pubUrl: '',
+	subUrl: '',
+	showEmedia: false,
+	showmultiEmedia: false,
+	showEmediaInvite: false,
+	emediaAction: null,
+	multiEmediaVisible: 'block',
+	confrId: '',
+	groupId: '',
+	confrMember: []
+    };
+  },
+
+  components: {
+    chatMsglist,
+    chatInputbar,
+    chatSuitAudio,
+	chatEmediaInvite,
+	chatMultiEmedia
+  },
+  props: {
+    username: {
+      type: Object,
+      default: () => ({}),
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT,
+    },
+  },
+  computed: {
+	computedUserName(){
+	  return this.username
+	}
+  },
+
+  mounted() {
+	this.username = uni.username;
+	uni.$on('createConfrSuccess', this.onCreateConfrSuccess)
+  },
+
+  moved() {},
+
+  destroyed() {},
+
+  methods: {
+    toggleRecordModal() {
+      this.$refs.chatSuitAudio.toggleRecordModal();
+    },
+
+    normalScroll() {
+      this.$refs.chatMsglist.normalScroll();
+	  this.$refs.chatInputbar.cancelEmoji();
+	  this.$refs.chatInputbar.closeFunModal();
+    },
+	clickMsg(msg){
+		this.$emit('onClickInviteMsg', msg)
+		console.log('点击消息上一级', msg)
+		
+	},
+    shortScroll() {
+      this.$refs.chatMsglist.shortScroll();
+    },
+
+    saveSendMsg(evt) {
+      msgStorage.saveMsg(evt.msg, evt.type);
+	  this.$refs.chatInputbar.cancelEmoji();
+	  this.$refs.chatInputbar.closeFunModal()
+    },
+
+    getMore() {
+      this.$refs.chatMsglist.getHistoryMsg();
+    },
+	onMakeVideoCall(){
+		this.showEmediaInvite= true
+		this.inputbarVisible= 'none'
+		this.action= 'create'
+		console.log(this.showEmediaInvite)
+	},
+	onStartConfr(data){
+		console.log('发起邀请的回调', data)
+		this.showEmediaInvite= false
+		this.showmultiEmedia= true
+		this.multiEmediaVisible= 'block'
+		this.inputbarVisible= 'none'
+		this.confrMember= data.confrMember
+		this.emediaAction={
+			action: 'create'
+		}
+		
+		this.$emit('onMakeVideoCall', {
+			confrMember: data.confrMember,
+			groupId: this.username.groupId
+		})
+	},
+	onCreateConfrSuccess(data){
+		console.log('创建会成功议回调', data)
+		this.sconfrId= data.confrId
+		getApp().globalData.confrId = data.confrId
+		this.sendInviteMsg(this.confrMember, data.confrId, data)
+	},
+	onGoBack(){
+		this.showEmediaInvite= false
+		this.showmultiEmedia= true
+		this.multiEmediaVisible= 'block'
+		this.inputbarVisible= 'none'
+		this.confrMember= []
+	},
+
+	onInviteMember(e){
+		let username = this.username;
+		if(!this.username.groupId){
+			username.groupId = e.detail
+		}
+		
+		this.action= 'invite'
+		this.showEmediaInvite= true
+		this.inputbarVisible= 'none'
+		//showmultiEmedia: false
+		this.multiEmediaVisible= 'none'
+	},
+	onMakeAudioCall(){
+		this.showEmediaInvite= true
+		this.showmultiEmedia= false
+		this.inputbarVisible= 'none'
+	},
+	onClickInviteMsg(data){
+		console.log('收到邀请消息')
+		console.log(data)
+		let confrId = data.conferenceId
+		let msg_extension = typeof(data.msg_extension) == 'string'?JSON.parse(data.msg_extension):data.msg_extension
+		let password = data.password || ''
+		this.emediaAction= {
+			action: 'join',
+			confrId: confrId,
+			password: password,
+			roomName: data.roomName || ''
+		},
+		this.showEmediaInvite= false,
+		this.showmultiEmedia= true,
+		this.inputbarVisible= 'none',
+		this.groupId= msg_extension.group_id
+	},
+	onHangup(){
+		this.showEmediaInvite= false,
+		this.showmultiEmedia= false,
+		this.inputbarVisible= 'block'
+		getApp().globalData.confrId = ''
+	},
+	sendInviteMsg(members, confrId, data){
+		console.log("%c members","background: green")
+		console.log(members)
+		console.log('进入发邀请的函数', members)
+		console.log('this.username.groupId----', this.username.groupId)
+		
+		console.log('confrId', confrId)
+		console.log('data', data)
+		members&&members.forEach((value) => {
+			let id = uni.WebIM.conn.getUniqueId();
+			let msg = new uni.WebIM.message('txt', id);
+
+			msg.set({
+				msg: wx.WebIM.conn.context.userId + ' invite you to video call',
+				from: wx.WebIM.conn.context.userId,
+				to: value,
+				roomType: false,
+				chatType: 'singleChat',
+				ext: {
+					msg_extension: JSON.stringify({
+						inviter: wx.WebIM.conn.context.userId,
+						group_id: this.username.groupId
+					}),
+					// roomName: data&&data.roomName || '',
+					password: '123456',
+					conferenceId: getApp().globalData.confrId
+				},
+				success(id, serverMsgId){
+					console.log('发送邀请消息成功 to: '+value)
+					//disp.fire('em.chat.sendSuccess', id, me.data.userMessage);
+				},
+				fail(id, serverMsgId){
+					console.log('发送邀请消息失败了')
+				}
+			});
+			
+			// if(this.chatType == msgType.chatType.CHAT_ROOM){
+			// 	msg.setGroup("groupchat");
+			// }
+			console.log('发送邀请', msg.body)
+			uni.WebIM.conn.send(msg.body);
+
+		})
+	},
+  },
+};
+</script>
+<style>
+@import "./chat.css";
+</style>

+ 394 - 0
components/chat/emediaInvite/emediaInvite.css

@@ -0,0 +1,394 @@
+page{
+	height: 100%;
+	width: 100%;
+}
+.wraper{ 
+	height: 100%;
+	position: fixed;
+	z-index: 999;
+	width: 100%;
+	top: 0;
+	left: 0;
+	background: #fff;
+}
+.main_title{
+	background-color: #fff;
+	width: 100%;
+	height: 128rpx;
+	position: fixed;
+	top: 0;
+	z-index: 9;
+}
+.main_title text{
+	line-height: 96rpx;
+	font-size: 64rpx;
+	font-weight: 400;
+	margin-left: 32rpx;
+}
+.main_title_hide{
+	top: -128rpx;
+	transition: top 0.5s;
+}
+.main_title_show{
+	top: 0;
+	transition: top 0.5s;
+}
+.search,.search_input {
+	width: 100%;
+	height: 88rpx;
+	background-color: #fff;
+	display: flex;
+	align-items: center;
+	top: 0;
+	left: 0;
+}
+.search {
+	justify-content: space-around;
+}
+.search_input {
+	justify-content: space-around;
+}
+.search view, .search_input view {
+	height: 64rpx;
+	line-height: 64rpx;
+	background-color: #F5F5F5;
+	border-radius: 16rpx;
+	text-align: center;
+	display: flex;
+	align-items: center;
+	margin: 0 32rpx;
+}
+.search view {
+	width: 100%;
+	justify-content: center;
+	align-items: center;
+}
+.search image {
+	display: block;
+	width: 6%;
+	height: 53%;
+	margin-right: 10rpx;
+}
+.search_input view {
+	padding-left: 24rpx;
+	text-align: left;
+	flex: 1;
+	margin: 0 28rpx 0 32rpx;
+}
+.search icon,.search_input icon {
+	display: inline-block;
+	margin: 8rpx 12rpx 0;
+	font-size: 24rpx;
+}
+.search text {
+	font-size: 30rpx;
+	color: #9B9B9B;
+}
+
+.search_input text {
+	display: inline-block;
+	height: 60rpx;
+	line-height: 60rpx;
+	font-size: 30rpx;
+	color: #0873DE;
+	margin-right: 32rpx;
+}
+.search_input input {
+	font-size: 28rpx;
+	width: 90%;
+}
+
+.scrollWraper{
+	flex: 1;
+	position: relative;
+}
+
+/*.contain {
+	margin-top: 40px;
+}*/
+.chat,.chat_groups,.chat_lists{
+	position: relative;
+	width: 100%;
+	height: 90rpx;
+	display: flex;
+	align-items: center;
+}
+.chat,.chat_groups {
+	border-bottom: 0.5px solid #E5E5E5;
+}
+.chat image {
+	width: 6%;
+	height: 50%;
+	margin:0 26rpx 0 20rpx;
+}
+.chat .em-msgNum {
+	position: absolute;
+	right: 20rpx;
+	height: 34rpx;
+	border-radius: 20rpx;
+	min-width: 30rpx;
+	background: #f04134;
+	color: #fff;
+	line-height: 40rpx;
+	text-align: center;
+	padding: 0px 4rpx 4rpx 4rpx;
+}
+.chat_groups image {
+	width: 8%;
+	height: 54%;
+	margin:0 20rpx 0 16rpx;
+}
+.chat_lists image {
+	width: 12%;
+	height: 100%;
+	margin-right: 4rpx;
+}
+.chat text,.chat_groups text,.chat_lists text {
+	font-size: 28rpx;
+}
+.numbers {
+	width: 100%;
+	height: 100rpx;
+}
+.nbr_header {
+	height: 2rpx;
+	background-color: #D4D4D4;
+	line-height: 40rpx;
+	padding-left: 32rpx;
+}
+.nbr_body {
+	width: 70%;
+	height: 100rpx;
+	display: inline-block;
+	font-size: 32rpx;
+	line-height: 100rpx;
+	margin-right: 0;
+	float: left;
+}
+.mask {
+	background-color: black;
+	opacity: 0.4;
+	position: absolute;
+	top: 40rpx;
+	left: 0;
+	right: 0;
+	bottom: 0;
+}
+.delete {
+	width: 60rpx;
+	height: 70rpx;
+	float: right;
+	margin-top: 12rpx;
+}
+.delete image {
+	width: 32rpx;
+	height: 4rpx;
+}
+.info {
+	margin-top: 10rpx;
+	width: 12%;
+	height: 80rpx;
+	display: inline-block;
+	float: left;
+}
+.info image {
+	width: 68%;
+	height: 70%;
+	display: inline-block;
+	margin: 12rpx auto auto 12rpx;
+}
+
+.otherItem{
+	height: 108rpx;
+	display: flex;
+  	align-items: center;
+  	border-bottom: 0.5px solid #E5E5E5;
+  	margin:0 32rpx;
+  	position: relative;
+}
+.otherItem image{
+	width: 72rpx;
+	height: 72rpx;
+	margin: 0 22rpx 0 0;
+}
+.otherItem text{
+	font-size: 34rpx;
+	color: #000;
+}
+.otherItem .line{
+	position: absolute;
+	bottom: 0;
+	width: 100%;
+	height:.5px;
+}
+
+.content{
+	box-sizing: border-box; 
+} 
+
+.location{
+	width: 100%;
+} 
+.location_top{
+	height: 76rpx;
+	line-height: 76rpx;
+	background: #f4f4f4;
+	color: #606660;
+	font-size: 28rpx;
+	padding: 0 20rpx;
+} 
+.location_bottom{
+	height: 140rpx;
+	line-height: 140rpx;
+	color: #d91f16;
+	font-size: 28rpx;
+	border-top: 0.5px #E5E5E5 solid;
+	border-bottom: 0.5px #E5E5E5 solid;
+	padding: 0 20rpx;
+	align-items: center;
+	display: -webkit-flex;
+} 
+.address_top{
+	height: 80rpx;
+    line-height: 70rpx;
+    background: #FAFAFA;
+    color: #9B9B9B;
+    font-size: 17px;
+    padding: 10rpx 32rpx;
+} 
+.address_bottom{
+	height: 108rpx;
+	line-height: 108rpx;
+	background: #fff;
+	color: #000000;
+	font-size: 34rpx;
+	border-bottom: 0.5px #E5E5E5 solid;
+	margin: 0 32rpx;
+	display: flex;
+	align-items: center;
+} 
+.address_bottom image{
+	width: 72rpx;
+	height: 72rpx;
+	margin-right: 24rpx;
+}
+.address_bottom text{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	flex: 1;
+}
+.location_img{
+	width: 48rpx;
+	height: 48rpx;
+	position: absolute;
+	right: 20rpx;
+	top: 125rpx;
+} 
+.add_city{
+	width: 228rpx;
+	height: 60rpx;
+	line-height: 60rpx;
+	text-align: center;
+	border: 0.5px solid #E5E5E5;
+	color: #000000;
+	margin-right: 20rpx;
+} 
+.add_citying{
+	width: 228rpx;
+	height: 60rpx;
+	line-height: 60rpx;
+	text-align: center;
+	border: 2rpx solid #09bb07;
+	color: #09bb07;
+	margin-right: 20rpx;
+} 
+.orientation{
+	white-space:normal;
+	display: inline-block;
+ 	width: 45rpx;
+ 	height:50rpx;
+	font-size: 28rpx;
+	font-weight: bold;
+ 	color: rgb(88, 87, 87);
+ 	text-align: center;
+} 
+.orientation_region{
+	padding: 10rpx 0px; 
+	width: 28rpx;
+	font-size: 20rpx;
+	position: fixed;
+	top: 50%;
+	right: 0;
+	transform:translate(0,-50%);
+	border-radius: 10px
+} 
+.orientation_city{
+	height: 24rpx;
+	width: 24rpx;
+	line-height: 24rpx;
+	font-size: 18rpx;
+	color: #000;
+	text-align: center;
+} 
+.active{
+	color: #fff;
+	background-color: #0873DE;
+	border-radius: 50%;
+}
+.list-fixed{
+	position: fixed;
+	width: 100%;
+	z-index: 999; 
+	height: 56rpx;
+	line-height: 56rpx; 
+	background: #EBEBEB;
+	color: #999999;
+	font-size: 28rpx;
+	padding: 0 20rpx;
+	top: 128rpx;
+}
+.fixed-title{
+	color:#2cc1d1;
+}
+
+.goTop{
+	top: 0;
+	transition: top 0.5s;
+	padding-bottom: 104rpx!important;
+}
+.goTopX{
+	top: 0rpx;
+	transition: top 0.5s;
+	padding-bottom: 140rpx!important;
+}
+.goback{
+	top: 128rpx;
+	transition: top 0.5s;
+}
+.fixedTitleTop{
+	top: 0;
+}
+.tap_mask{
+	width: 100%;
+	overflow: hidden;
+}
+.btnWraper{
+	align-items: center;
+	justify-content: center;
+	display: flex;
+	flex-direction: column;
+}
+.button{
+	width: 80%;
+	height: 80rpx;
+	background: green;
+	border-radius: 40rpx;
+	right: 0;
+	left: 0;
+	color: #fff;
+	font-size: 16px;
+	margin: 10rpx;
+}
+.red{
+	background: red;
+}

+ 240 - 0
components/chat/emediaInvite/emediaInvite.vue

@@ -0,0 +1,240 @@
+<template>
+	<view class="wraper">
+		<view class="search" v-if="search_btn">
+			<view bindtap="openSearch">
+				<icon type="search" size="13"></icon>
+				<text>搜索</text>
+			</view>
+		</view>
+	
+		<view class="search_input" v-if="search_friend">
+			<view>
+				<icon type="search" size="13"></icon>
+				<input placeholder="搜索" 
+					placeholder-style="color:#CFCFCF;line-height:20px;font-size:12px;" 
+					auto-focus
+					confirm-type="search"
+					type='text'
+					bindconfirm="onSearch"
+					bindinput="onInput"
+					:value="input_code"
+					></input>
+					<icon type="clear" size="13" catchtap='clearInput' v-if="show_clear"></icon>
+			</view>
+			<text bindtap="cancel">取消</text>
+		</view>
+		
+		<scroll-view
+			class="content" 
+			enable-back-to-top
+			scroll-y="true"
+			scroll-with-animation="true" 
+			:style="{height: second_height + 'px'}"
+		> 
+	
+		<checkbox-group v-for="(item,index) in renderList" :data-item="item" :key="index"  :id="item.id" :data-id='item.id' @change="checkboxChange"> 
+	
+			<view class="tap_mask" @tap="into_room" :data-username="item.member||item.owner">
+	          	<view class="address_bottom" :data-username="item.member||item.owner" @tap="into_room">
+					<image src="../../../static/images/theme2x.png" @tap="into_room" :data-username="item.member||item.owner"></image>
+		          	<text @tap="into_room" :data-username="item.member||item.owner">{{item.member||item.owner}}</text>
+		          	<checkbox :value="item.member||item.owner" :checked="item.checked" :disabled="item.disabled"/>
+	      		</view>
+	  		</view>
+	
+		</checkbox-group>
+		</scroll-view>
+	
+		<view class="btnWraper">
+			<button class="button" @tap="startConfr">{{buttonText}}</button>
+			<button class="button red" @tap="goBack">返回</button>
+		</view>
+	
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				search_btn: true,
+				search_friend: false,
+				groupMember: [],
+				serchList: [],
+		
+				checkedValue: [],
+				renderList: [],
+				buttonText: '发起会议',
+				second_height: 450,
+				show_clear: false,
+			}
+		},
+		props: {
+		  username: {
+		    type: Object,
+		    default: () => ({})
+		  },
+		  action: {
+		    type: String,
+		    default: ''
+		  }
+		},
+		mounted() {
+			console.log('邀请页面的参数', this)
+			console.log(this.properties)
+			var that = this
+			// 获取系统信息
+			wx.getSystemInfo({
+				success: function (res) {
+					console.log('height=' + res.windowHeight);
+					console.log('width=' + res.windowWidth);
+					// 计算主体部分高度,单位为px
+					that.second_height= res.windowHeight - res.windowWidth / 750 * 300
+				}
+			})
+
+			if(this.action == 'invite'){
+				this.buttonText= '邀请'
+			}
+
+			var roomId = this.username&&this.username.groupId
+			console.log('roomId', this.username)
+			roomId&&this.getGroupMember(roomId)
+		},
+		methods: {
+			getGroupMember: function(roomId){
+				var me = this;
+				// 获取群成员
+				var pageNum = 1,
+					pageSize = 1000;
+				var options = {
+					pageNum: pageNum,
+					pageSize: pageSize,
+					groupId: roomId,
+					success: function(resp){
+						console.log('获取群成员', resp)
+						if(resp && resp.data){
+							me.groupMember= resp.data
+							me.getRenderList(resp.data)
+						}
+					},
+					error: function(err){
+	
+					}
+				};
+				uni.WebIM.conn.listGroupMember(options);
+			},
+	
+			getRenderList(list){
+				console.log('this.checkedValue', this.checkedValue)
+				let serchList = list.map((item) => {
+					for (var i = 0; i < this.checkedValue.length; i++) {
+						if((item.member&&item.member.indexOf(this.checkedValue[i]) != -1) || (item.owner&&item.owner.indexOf(this.checkedValue[i]) != -1)){
+							item.checked = true
+							return item
+							break;
+						}else{
+							item.checked = false
+						}
+					}
+					return item
+				})
+	
+				serchList.forEach((item) => {
+					if(item.member == wx.WebIM.conn.context.userId || item.owner == wx.WebIM.conn.context.userId){
+						item.disabled = true
+					}
+					
+				})
+				this.renderList= serchList
+				console.log('serchList >>>>', serchList)
+	
+			},
+	
+	
+			checkboxChange: function (e) {
+				console.log('checkbox发生change事件,携带value值为:', e)
+				if(this.checkedValue.indexOf(e.detail.value) == -1 && e.detail.value[0]){
+					this.checkedValue.push(e.detail.value[0])
+					console.log(this.checkedValue)
+				}else{
+					let value = e.target.dataset.item.name
+					this.checkedValue.splice(this.checkedValue.indexOf(value), 1)
+					console.log(this.checkedValue)
+				}
+			},
+	
+			openSearch: function(){
+				this.search_btn= false,
+				this.search_friend= true,
+				this.show_mask= true,
+				this.gotop= true
+			},
+	
+			cancel: function(){
+				this.search_btn= true,
+				this.search_friend= false,
+				this.gotop= false
+				//this.getBrands(this.member)
+			},
+	
+			
+	
+			onInput(e){
+	
+				let inputValue = e.detail.value
+				if (inputValue) {
+					this.show_clear= true
+				} else {
+					this.show_clear= false
+				}
+			},
+	
+			clearInput: function(){
+				this.input_code= ''
+				this.show_clear= false
+			},
+	
+			cancel: function(){
+				this.search_btn= true
+				this.search_friend= false
+				let original = this.groupMember||[]
+				this.getRenderList(original)
+			},
+	
+			onSearch: function(val){
+				let searchValue = val.detail.value
+				let member = this.groupMember;
+				let serchList = [];
+				member.forEach((item, index)=>{
+					if(String(item.member).indexOf(searchValue) != -1 || String(item.owner).indexOf(searchValue) != -1){
+						serchList.push(item)
+					}
+				})
+				// this.setData({
+				// 	groupMember: serchList
+				// })
+	
+				this.getRenderList(serchList)
+			},
+	
+			startConfr(){
+				this.$emit('onStartConfr', {confrMember: this.checkedValue, action: this.action, groupId: this.username.groupId})
+				this.checkedValue= []
+			},
+	
+			goBack(){
+				this.checkedValue=[]
+				this.$emit('goBack')
+			},
+			
+			into_room(){
+				
+			}
+		}
+	}
+</script>
+<style>
+@import "./emediaInvite.css";
+</style>
+

+ 65 - 0
components/chat/inputbar/inputbar.css

@@ -0,0 +1,65 @@
+.room_bar {
+	width: 100%;
+	height: auto;
+	border-top: 1px solid rgba(0 0 0 0.5);
+	position: fixed;
+	bottom: 0;
+	right: 0;
+	z-index: 999;
+	background-color: #FFFFFF;
+	transform: translateZ(1000px);
+}
+
+.other_func {
+	width: 100%;
+	/* height: 60rpx; */
+	display: flex;
+}
+.other_func_X{
+	/* height: 128rpx; */
+}
+
+.other_func image {
+	width: 54px;
+	height: 54px;
+	display: block;
+	margin-bottom: 5px;
+}
+
+.open_emoji,
+.send_image,
+.open_camera,
+.v-record {
+	margin-left: 48rpx;
+	text-align: center;
+	color: #b7b7b7;
+    font-size: 13px;
+}
+
+
+.v-record .icon-record {
+	width: 18rpx;
+	height: 40rpx;
+}
+.v-record{
+	margin-left: 48rpx;
+}
+
+.fun_list {
+	margin-top: 30px;
+	width: 100%;
+	height: 145px;
+	background-color: #dddddd;
+	padding-top: 10px;
+	padding-left: 3%;
+	display: none;
+}
+.showFunModal {
+	width: 100%;
+	height: 145px;
+	padding-top: 10px;
+	display: block;
+	background-color: #f2f2f2;
+}
+
+

+ 227 - 0
components/chat/inputbar/inputbar.vue

@@ -0,0 +1,227 @@
+<template>
+  <view class="room_bar">
+    <chatSuitEmoji
+      ref="chatSuitEmoji"
+      @newEmojiStr="emojiAction"
+    ></chatSuitEmoji>
+    <chatSuitMain
+      ref="chatSuitMain"
+      :username="username"
+      :chatType="chatType"
+      @inputFocused="closeAllModal"
+      @openEmoji="openEmoji"
+      @openRecordModal="toggleRecordModal"
+      @openFunModal="openFunModal"
+    ></chatSuitMain>
+    <chatSuitImage
+      ref="chatSuitImage"
+      :username="username"
+      :chatType="chatType"
+    ></chatSuitImage>
+    <!-- <chat-suit-location id="chat-suit-location" username="{{ username }}"></chat-suit-location> -->
+    <!-- <chat-suit-video ref="chatSuitVideo" :username="username"></chat-suit-video> -->
+    <chatSuitPtopcall
+      ref="chatSuitPtopcall"
+      :chatType="chatType"
+      @makeVideoCall="onMakeVideoCall"
+    >
+    </chatSuitPtopcall>
+
+    <swiper
+      :class="showFunModal"
+      :indicator-dots="true"
+      :autoplay="false"
+      :interval="5000"
+      :duration="1000"
+    >
+      <swiper-item>
+        <view :class="'other_func ' + (isIPX ? 'other_func_X' : '')">
+          <view class="open_camera" @tap="openCamera">
+            <image src="/static/images/camora.png"></image>
+            相机
+          </view>
+          <view class="send_image" @tap="sendImage">
+            <image src="/static/images/pic.png"></image>
+            相册
+          </view>
+
+          <view
+            class="send_image"
+            @tap="edit_group"
+            v-show="chatType === 'chatRoom'"
+          >
+            <image src="/static/images/pic.png"></image>
+            群信息
+          </view>
+
+          <!-- <view class="send_image" @tap="sendVideo">
+            <image
+              src="/static/images/video.png"
+              style="height: 20px; width: 20px"
+            ></image>
+          </view>
+          <view class="send_image" bind:tap="sendLocation">
+            <image
+              src="../../../static/images/iconLocation2x.png"
+              style="height: 18px"
+            />
+          </view>
+
+          <view class="v-record" @tap="callVideo" v-if="username.groupId">
+            <image
+              src="/static/images/call2x.png"
+              style="height: 24px; width: 15px"
+            />
+          </view> -->
+        </view>
+      </swiper-item>
+    </swiper>
+  </view>
+</template>
+
+<script>
+let RecordStatus = require("./suit/audio/record_status").RecordStatus;
+let msgType = require("../msgtype");
+import chatSuitEmoji from "./suit/emoji/emoji";
+import chatSuitImage from "./suit/image/image";
+import chatSuitLocation from "./suit/location/location";
+import chatSuitMain from "./suit/main/main";
+import chatSuitPtopcall from "./suit/ptopcall/ptopcall.vue";
+
+// import chatSuitVideo from "./suit/videoComp/videoComp"
+
+let FUNMODAL_STATUS = {
+  OPENED: "showFunModal",
+  CLOSED: "fun_list",
+};
+
+export default {
+  data() {
+    return {
+      recordStatus: RecordStatus.HIDE,
+      RecordStatus,
+      __comps__: {
+        main: null,
+        emoji: null,
+        image: null,
+        location: null,
+        video: null,
+      },
+      isIPX: "",
+      showFunModal: FUNMODAL_STATUS.CLOSED,
+    };
+  },
+
+  components: {
+    chatSuitEmoji,
+    chatSuitImage,
+    chatSuitLocation,
+    chatSuitMain,
+    chatSuitPtopcall,
+    // chatSuitVideo
+  },
+  props: {
+    username: {
+      type: Object,
+      default: () => ({}),
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT,
+    },
+  },
+
+  // lifetimes
+  created() {},
+
+  beforeMount() {},
+
+  moved() {},
+
+  destroyed() {},
+
+  onLoad() {
+    this.isIPX= false
+    // let comps = this.$data.__comps__;
+    // comps.main = this.selectComponent("#chatSuitMain");
+    // comps.emoji = this.selectComponent("#chatSuitEmoji");
+    // comps.image = this.selectComponent("#chatSuitImage");
+  },
+
+  methods: {
+    // 事件有长度限制:仅限 26 字符
+    toggleRecordModal() {
+      this.$emit("tapSendAudio", null, {
+        bubbles: true,
+        composed: true,
+      });
+    },
+
+    // sendVideo(){
+    // 	this.$refs.chatSuitVideo.sendVideo();
+    // },
+    openCamera() {
+      this.$refs.chatSuitImage.openCamera();
+    },
+
+    openEmoji() {
+        setTimeout(() => {
+        this.showFunModal= FUNMODAL_STATUS.CLOSED
+      }, 100);
+      this.$refs.chatSuitEmoji.openEmoji();
+    },
+
+    cancelEmoji() {
+      this.$refs.chatSuitEmoji.cancelEmoji();
+    },
+
+    sendImage() {
+      this.$refs.chatSuitImage.sendImage();
+    },
+
+    sendLocation() {
+      // this.data.__comps__.location.sendLocation();
+    },
+
+    emojiAction(evt) {
+      this.$refs.chatSuitMain.emojiAction(evt.msg);
+    },
+
+    callVideo() {
+      this.$refs.chatSuitPtopcall.show();
+    },
+
+    onMakeVideoCall() {
+      console.log("onMakeVideoCall -> inputbar");
+      this.$emit("makeVideoCall", null, "single");
+    },
+
+    openFunModal() {
+      this.showFunModal= FUNMODAL_STATUS.OPENED
+      this.cancelEmoji()
+    },
+    closeFunModal() {
+      this.showFunModal= FUNMODAL_STATUS.CLOSED
+      this.cancelEmoji()
+    },
+    closeAllModal(){
+      this.cancelEmoji()
+      this.closeFunModal()
+    },
+    edit_group() {
+      var nameList = {
+        myName: this.username.myName,
+        groupName: this.username.your,
+        roomId: this.username.groupId,
+      };
+      uni.navigateTo({ 
+        url:
+          "../groupSetting/groupSetting?groupInfo=" + JSON.stringify(nameList),
+      });
+    },
+  },
+};
+</script>
+<style>
+@import "./inputbar.css";
+</style>

+ 73 - 0
components/chat/inputbar/suit/audio/audio.css

@@ -0,0 +1,73 @@
+.modal {
+	position: absolute;
+	top: 0;
+	right: 0;
+	left: 0;
+	bottom: 0;
+	width: 100%;
+	height: 100%;
+	z-index: 999;
+	/*display: flex;
+	justify-content: center;
+	align-items: center;*/
+}
+
+.modal-record .modal-body {
+	width: 480rpx;
+	height: 440rpx;
+	background-color: #fff;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+	border-radius: 3px;
+	box-shadow: 0 0 32rpx rgba(0, 0, 0, 0.15);
+	position: fixed;
+	bottom: 480rpx;
+	left: 50%;
+	margin-left: -240rpx;
+}
+
+.modal-record .desc {
+	color: rgb(112, 126, 137);
+	font-size: 13px;
+	margin-bottom: 40rpx;
+	display: block;
+	height: 30rpx;
+	width: 100%;
+	text-align: center;
+}
+
+.modal-record .dot {
+	width: 128rpx;
+	height: 128rpx;
+	border-radius: 50%;
+	background-color: #0873DE;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+
+.dot image {
+	width: 44rpx;
+	height: 64rpx;
+}
+
+.sound-waves {
+  width: 100%;
+  box-sizing: border-box;
+  padding-left:10%;
+  margin-top: 80rpx;
+  height: 80rpx;
+  text-align: center;
+}
+ 
+.sound-waves view {
+  transition: all 0.5s;
+  width: 1%;
+  margin-left: 1.5%;
+  margin-right: 1.5%;
+  height: 160rpx;
+  background-color: #aaa;
+  float: left;
+}

+ 347 - 0
components/chat/inputbar/suit/audio/audio.vue

@@ -0,0 +1,347 @@
+<template>
+  <view
+    v-if="recordStatus != RecordStatus.HIDE"
+    class="modal modal-record"
+    @tap="toggleRecordModal"
+  >
+    <view class="modal-body" @tap.stop="toggleWithoutAction">
+      <view class="sound-waves">
+        <view
+          v-for="(item, index) in radomheight"
+          :key="index"
+          :style="'height:' + item + 'rpx;margin-top:-' + item / 2 + 'rpx'"
+        ></view>
+        <view style="clear: both; width: 0; height: 0"></view>
+      </view>
+      <text class="desc">{{ RecordDesc[recordStatus] }}</text>
+      <view
+        class="dot"
+        @touchstart="handleRecording"
+        @touchmove="handleRecordingMove"
+        @touchend="handleRecordingCancel"
+      >
+        <image class="icon-mic" src="/static/images/send.png"></image>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+let WebIM = require("../../../../../utils/WebIM")["default"];
+let msgType = require("../../../msgtype");
+let RECORD_CONST = require("./record_status");
+let RecordStatus = RECORD_CONST.RecordStatus;
+let RecordDesc = RECORD_CONST.RecordDesc;
+let disp = require("../../../../../utils/broadcast");
+let msgStorage = require("../../../msgstorage");
+let RunAnimation = false;
+let recordTimeInterval = null;
+const InitHeight = [50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50];
+
+export default {
+  data() {
+    return {
+      changedTouches: null,
+      recordStatus: RecordStatus.HIDE,
+      RecordStatus,
+      RecordDesc,
+      // 模板中有引用
+      radomheight: InitHeight,
+      recorderManager: uni.getRecorderManager(),
+      recordClicked: false,
+      isLongPress: false,
+      recordTime: 0
+    };
+  },
+
+  components: {},
+  props: {
+    username: {
+      type: Object,
+      default: () => ({})
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT
+    }
+  },
+
+  // lifetimes
+  created() {},
+
+  beforeMount() {},
+
+  moved() {},
+
+  destroyed() {
+    clearInterval(recordTimeInterval)
+    this.recordTime = 0
+  },
+
+  mounted() {},
+
+  methods: {
+    toggleWithoutAction(e) {// 阻止 tap 冒泡
+    },
+
+    toggleRecordModal() {
+      this.recordStatus = this.recordStatus == RecordStatus.HIDE ? RecordStatus.SHOW : RecordStatus.HIDE
+      this.radomheight = InitHeight
+    },
+
+    handleRecordingMove(e) {
+      var touches = e.touches[0];
+      var changedTouches = this.changedTouches;
+
+      if (!changedTouches) {
+        return;
+      }
+
+      if (this.recordStatus == RecordStatus.SWIPE) {
+        if (changedTouches.pageY - touches.pageY < 20) {
+          this.recordStatus = RecordStatus.HOLD
+        }
+      }
+
+      if (this.recordStatus == RecordStatus.HOLD) {
+        if (changedTouches.pageY - touches.pageY > 20) {
+          this.recordStatus = RecordStatus.SWIPE
+        }
+      }
+    },
+
+    handleRecording(e) {
+		console.log('开始点击',uni.getSystemInfoSync())
+		if(uni.getSystemInfoSync().app === "alipay"){
+			// https://forum.alipay.com/mini-app/post/7301031?ant_source=opendoc_recommend
+			uni.showModal({
+				content: '支付宝小程序不支持语音消息,请查看支付宝相关api了解详情'
+			})
+			return
+		}
+      let me = this;
+	  
+      me.recordClicked = true
+      setTimeout(() => {
+        if (me.recordClicked == true) {
+          executeRecord();
+        }
+      }, 350);
+
+      function executeRecord() {
+        if (uni.getSetting) {
+        uni.getSetting({
+          success: res => {
+            clearInterval(recordTimeInterval);
+            me.recordTime = 0
+            let recordAuth = res.authSetting['scope.record'];
+
+            if (recordAuth == false) {
+              //已申请过授权,但是用户拒绝
+              uni.openSetting({
+                success: function (res) {
+                  let recordAuth = res.authSetting['scope.record'];
+
+                  if (recordAuth == true) {
+                    uni.showToast({
+                      title: "授权成功",
+                      icon: "success"
+                    });
+                  } else {
+                    uni.showToast({
+                      title: "请授权录音",
+                      icon: "none"
+                    });
+                  }
+
+                  me.isLongPress = false
+                }
+              });
+            } else if (recordAuth == true) {
+              // 用户已经同意授权
+              startRecord();
+            } else {
+              // 第一次进来,未发起授权
+              uni.authorize({
+                scope: 'scope.record',
+                success: () => {
+                  //授权成功
+                  uni.showToast({
+                    title: "授权成功",
+                    icon: "success"
+                  });
+                }
+              });
+            }
+          },
+          fail: function () {
+            uni.showToast({
+              title: "鉴权失败,请重试",
+              icon: "none"
+            });
+          }
+        })
+        return
+         }else{
+          startRecord()
+          return
+        }
+      }
+
+      function startRecord() {
+        clearInterval(recordTimeInterval);
+        me.recordTime = 0
+        me.changedTouches = e.touches[0];
+        me.recordStatus = RecordStatus.HOLD
+        RunAnimation = true;
+        me.myradom();
+        let recorderManager = me.recorderManager || uni.getRecorderManager();
+        recorderManager.onStart(() => {
+          // console.log("开始录音...");
+          recordTimeInterval = setInterval(()=>{
+            me.recordTime ++
+          },1000)
+          
+        });
+        recorderManager.start({
+          format: "mp3"
+        }); // 超时
+
+        setTimeout(function () {
+          me.handleRecordingCancel();
+          RunAnimation = false;
+        }, 100000);
+      }
+    },
+
+    handleRecordingCancel() {
+      RunAnimation = false;
+      let recorderManager = this.recorderManager; // 向上滑动状态停止:取消录音发放
+
+      if (this.recordStatus == RecordStatus.SWIPE) {
+        this.recordStatus = RecordStatus.RELEASE
+      } else {
+        this.recordStatus = RecordStatus.HIDE
+        this.recordClicked = false
+      }
+
+      recorderManager.onStop(res => {
+        // console.log("结束录音...", res);
+        clearInterval(recordTimeInterval);
+        let duration = this.recordTime * 1000;
+        if (this.recordStatus == RecordStatus.RELEASE) {
+          console.log("user canceled");
+          this.recordStatus = RecordStatus.HIDE
+          return;
+        }
+
+        if (duration <= 1000) {
+          uni.showToast({
+            title: "录音时间太短",
+            icon: "none"
+          });
+        } else {
+          // 上传
+          this.uploadRecord(res.tempFilePath, duration);
+        }
+        	clearInterval(recordTimeInterval);
+					this.recordStatus = RecordStatus.HIDE
+					this.recordTime = 0;
+      }); // 停止录音
+
+      recorderManager.stop();
+    },
+
+    isGroupChat() {
+      return this.chatType == msgType.chatType.CHAT_ROOM;
+    },
+
+    getSendToParam() {
+      return this.isGroupChat() ? this.username.groupId : this.username.your;
+    },
+
+    uploadRecord(tempFilePath, dur) {
+      var str = WebIM.config.appkey.split("#");
+      var me = this;
+      var token = WebIM.conn.context.accessToken;
+      uni.uploadFile({
+        url: "https://a1.easemob.com/" + str[0] + "/" + str[1] + "/chatfiles",
+        filePath: tempFilePath,
+		fileType: 'audio',
+        name: "file",
+        header: {
+          "Content-Type": "multipart/form-data",
+          Authorization: "Bearer " + token
+        },
+
+        success(res) {
+          var id = WebIM.conn.getUniqueId();
+          var msg = new WebIM.message(msgType.AUDIO, id);
+          var dataObj = JSON.parse(res.data); // 接收消息对象
+
+          msg.set({
+            apiUrl: WebIM.config.apiURL,
+            accessToken: token,
+            body: {
+              type: msgType.AUDIO,
+              url: dataObj.uri + "/" + dataObj.entities[0].uuid,
+              filetype: "",
+              filename: tempFilePath,
+              accessToken: token,
+              length: Math.ceil(dur / 1000)
+            },
+            from: me.username.myName,
+            to: me.getSendToParam(),
+            roomType: false,
+            chatType: me.chatType,
+            success: function (argument) {
+              disp.fire('em.chat.sendSuccess', id);
+            }
+          });
+
+          if (me.isGroupChat()) {
+            msg.setGroup("groupchat");
+          }
+
+          msg.body.length = Math.ceil(dur / 1000); //console.log('发送的语音消息', msg.body)
+
+          WebIM.conn.send(msg.body);
+                let obj = {
+                  msg: msg,
+                  type: msgType.AUDIO
+                }
+                me.saveSendMsg(obj);
+        }
+
+      });
+    },
+    saveSendMsg(evt) {
+      msgStorage.saveMsg(evt.msg, evt.type);
+    },
+
+    myradom() {
+      const that = this;
+      var _radomheight = that.radomheight;
+
+      for (var i = 0; i < that.radomheight.length; i++) {
+        //+1是为了避免为0
+        _radomheight[i] = 100 * Math.random().toFixed(2) + 10;
+      }
+
+      that.radomheight = _radomheight
+
+      if (RunAnimation) {
+        setTimeout(function () {
+          that.myradom();
+        }, 500);
+      } else {
+        return;
+      }
+    }
+
+  }
+};
+</script>
+<style>
+@import "./audio.css";
+</style>

+ 14 - 0
components/chat/inputbar/suit/audio/record_status.js

@@ -0,0 +1,14 @@
+module.exports = {
+  RecordDesc: {
+    0: "长按开始录音",
+    2: "向上滑动取消",
+    3: "松开手取消"
+  },
+  RecordStatus: {
+    SHOW: 0,
+    HIDE: 1,
+    HOLD: 2,
+    SWIPE: 3,
+    RELEASE: 4
+  }
+};

+ 39 - 0
components/chat/inputbar/suit/emoji/emoji.css

@@ -0,0 +1,39 @@
+.emoji_list {
+	margin-top: 30px;
+	width: 100%;
+	height: 145px;
+	background-color: #dddddd;
+	padding-top: 10px;
+	padding-left: 3%;
+	display: none;
+}
+
+.showEmoji {
+	width: 100%;
+	height: 145px;
+	padding-top: 10px;
+	padding-left: 3%;
+	display: block;
+}
+
+.emoji_list image,
+.showEmoji image {
+	width: 26px;
+	height: 26px;
+	margin: 5px 2%;
+}
+
+.emoji {
+	width: 26px;
+	height: 26px;
+	margin: 0 0;
+}
+
+.emoji_item {
+	display: flex;
+	justify-content: space-around;
+	margin-right: 20px;
+}
+.last_item{
+	justify-content:flex-end !important
+}

+ 82 - 0
components/chat/inputbar/suit/emoji/emoji.vue

@@ -0,0 +1,82 @@
+<template>
+<swiper :class="show" :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration">
+	<block>
+		<swiper-item>
+			<view class="emoji_item">
+				<image v-for="(item, index) in emojiObj.map1" :key="index" :src="'../../../../' + emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+			<view class="emoji_item">
+				<image v-for="(item, index) in emojiObj.map2" :key="index" :src="'../../../../' +emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+			<view class="emoji_item">
+				<image v-for="(item, index) in emojiObj.map3" :key="index" :src="'../../../../' +emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+		</swiper-item>
+	</block>
+	<block class="second">
+		<swiper-item>
+			<view class="emoji_item">
+				<image v-for="(item, index) in emojiObj.map4" :key="index" :src="'../../../../' +emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+			<view class="emoji_item">
+				<image v-for="(item, index) in emojiObj.map5" :key="index" :src="'../../../../' +emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+			<view class="emoji_item last_item">
+				<image v-for="(item, index) in emojiObj.map6" :key="index" :src="'../../../../' +emojiObj.path + item" @tap="sendEmoji" :data-emoji="index"></image>
+			</view>
+		</swiper-item>
+	</block>
+</swiper>
+</template>
+
+<script>
+let WebIM = require("../../../../../utils/WebIM")["default"];
+let msgType = require("../../../msgtype");
+let EMOJI_STATUS = {
+  OPENED: "showEmoji",
+  CLOSED: "emoji_list"
+};
+
+export default {
+  data() {
+    return {
+      show: EMOJI_STATUS.CLOSED,
+      emoji: WebIM.Emoji,
+      emojiObj: WebIM.EmojiObj,
+      interval: 5000,
+      duration: 1000,
+      autoplay: false,
+      indicatorDots: true // 显示面板指示点
+
+    };
+  },
+
+  components: {},
+  props: {},
+  methods: {
+    openEmoji() {
+      this.show=EMOJI_STATUS.OPENED
+    },
+
+    cancelEmoji() {
+      this.show= EMOJI_STATUS.CLOSED
+    },
+
+    // 输出 emoji
+    sendEmoji(event) {
+      var emoji = event.target.dataset.emoji;
+      this.$emit("newEmojiStr", {
+        msg: emoji,
+        type: msgType.EMOJI
+      }, {
+        bubbles: true,
+        composed: true
+      });
+    }
+
+  }
+};
+</script>
+<style>
+@import "./emoji.css";
+</style>

+ 169 - 0
components/chat/inputbar/suit/image/image.vue

@@ -0,0 +1,169 @@
+<template>
+	<view></view>
+</template>
+<script>
+	let WebIM = require("../../../../../utils/WebIM")["default"];
+	let msgType = require("../../../msgtype");
+	let disp = require("../../../../../utils/broadcast");
+	let msgStorage = require("../../../msgstorage");
+	export default {
+		data() {
+			return {};
+		},
+
+		components: {},
+		props: {
+			username: {
+				type: Object,
+				default: () => ({})
+			},
+			chatType: {
+				type: String,
+				default: msgType.chatType.SINGLE_CHAT
+			}
+		},
+		methods: {
+			openCamera() {
+				var me = this;
+				uni.chooseImage({
+					count: 1,
+					sizeType: ["original", "compressed"],
+					sourceType: ["camera"],
+
+					success(res) {
+						me.upLoadImage(res);
+					}
+
+				});
+			},
+
+			sendImage() {
+				var me = this;
+				uni.chooseImage({
+					count: 1,
+					sizeType: ["original", "compressed"],
+					sourceType: ["album"],
+
+					success(res) {
+						console.log('选择的图片', res)
+						me.upLoadImage(res);
+					}
+
+				});
+			},
+
+			isGroupChat() {
+				return this.chatType == msgType.chatType.CHAT_ROOM;
+			},
+
+			getSendToParam() {
+				return this.isGroupChat() ? this.username.groupId : this.username.your;
+			},
+
+			upLoadImage(res) {
+				var me = this;
+				var tempFilePaths = res.tempFilePaths;
+				var token = WebIM.conn.context.accessToken;
+				uni.getImageInfo({
+					src: res.tempFilePaths[0],
+
+					success(res) {
+						var allowType = {
+							jpg: true,
+							jpeg: true,
+							gif: true,
+							png: true,
+							bmp: true
+						};
+						var str = WebIM.config.appkey.split("#");
+						var width = res.width;
+						var height = res.height;
+						var index = res.path.lastIndexOf(".");
+						console.log('index>>',index);
+						var filetype = ~index && res.path.slice(index + 1) || "";
+						if (!res.type) {
+							uni.showToast({
+								title: "H5端,uni-app暂未支持",
+                      			icon: "none"
+							})
+						}
+						if (filetype.toLowerCase() in allowType || res.type in allowType) {
+							uni.uploadFile({
+								url: "https://a1.easemob.com/" + str[0] + "/" + str[1] + "/chatfiles",
+								filePath: tempFilePaths[0],
+								fileType: 'image',
+								name: "file",
+								header: {
+									// "Content-Type": "multipart/form-data",
+									'Content-Type': 'application/x-www-form-urlencoded',
+									Authorization: "Bearer " + token
+								},
+								success: (res)=>{
+									console.log('上传图片成功', res)
+									if (res.statusCode == 400) {
+										// 图片上传阿里云检验不合法
+										// var errData = JSON.parse(res.data);
+										// if (errData.error === 'content improper') {
+										uni.showToast({
+											title: "图片检测不合法",
+											duration: 1000
+										});
+										return false
+										// }
+									}
+									var data = res.data;
+									var dataObj = JSON.parse(data);
+									var id = WebIM.conn.getUniqueId(); // 生成本地消息 id
+
+									var msg = new WebIM.message(msgType.IMAGE, id);
+									var file = {
+										type: msgType.IMAGE,
+										size: {
+											width: width,
+											height: height
+										},
+										url: dataObj.uri + "/" + dataObj.entities[0].uuid,
+										filetype: filetype,
+										filename: tempFilePaths[0]
+									};
+									msg.set({
+										apiUrl: WebIM.config.apiURL,
+										body: file,
+										from: me.username.myName,
+										to: me.getSendToParam(),
+										roomType: false,
+										chatType: me.chatType,
+										success: function(argument) {
+											disp.fire('em.chat.sendSuccess', id);
+										}
+									});
+
+									if (me.chatType == msgType.chatType.CHAT_ROOM) {
+										msg.setGroup("groupchat");
+									}
+
+									WebIM.conn.send(msg.body);
+									let obj = {
+										msg: msg,
+										type: msgType.IMAGE
+									}
+									me.saveSendMsg(obj);
+								},
+								fail: (err) => {
+									console.log('上传失败', err)
+								},
+								complete: (err) => {
+									console.log('上传完成', err)
+								}
+							});
+						}
+					}
+				});
+			},
+			saveSendMsg(evt) {
+				msgStorage.saveMsg(evt.msg, evt.type);
+			}
+
+		}
+	};
+</script>

+ 95 - 0
components/chat/inputbar/suit/location/location.vue

@@ -0,0 +1,95 @@
+<template>
+<view></view>
+</template>
+<script>
+let WebIM = require("../../../../../utils/WebIM")["default"];
+let msgType = require("../../../msgtype");
+let msgStorage = require("../../../msgstorage");
+export default {
+  data() {
+    return {};
+  },
+
+  components: {},
+  props: {
+    username: {
+      type: Object,
+      default: () => ({})
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT
+    }
+  },
+  methods: {
+    isGroupChat() {
+      return this.chatType == msgType.chatType.CHAT_ROOM;
+    },
+
+    getSendToParam() {
+      return this.isGroupChat() ? this.username.groupId : this.username.your;
+    },
+
+    sendLocation() {
+      var me = this;
+      uni.authorize({
+        scope: "scope.userLocation",
+
+        fail() {
+          uni.showToast({
+            title: "已拒绝",
+            icon: "none"
+          });
+        },
+
+        success() {
+          uni.chooseLocation({
+            fail() {
+              console.log(arguments);
+            },
+
+            complete() {
+              console.log(arguments);
+            },
+
+            success(respData) {
+              var id = WebIM.conn.getUniqueId();
+              var msg = new WebIM.message(msgType.LOCATION, id);
+              msg.set({
+                msg: "",
+                from: me.username.myName,
+                to: me.getSendToParam(),
+                roomType: false,
+                lng: respData.longitude,
+                lat: respData.latitude,
+                addr: respData.address,
+                chatType: me.chatType,
+
+                success(id, serverMsgId) {}
+
+              });
+
+              if (me.chatType == msgType.chatType.CHAT_ROOM) {
+                msg.setGroup("groupchat");
+              }
+
+              WebIM.conn.send(msg.body);
+                let obj = {
+                  msg: msg,
+                  type: msgType.IMAGE
+                }
+              me.saveSendMsg(obj);
+            }
+
+          });
+        }
+
+      });
+    },
+    saveSendMsg(evt) {
+      msgStorage.saveMsg(evt.msg, evt.type);
+    }
+
+  }
+};
+</script>

+ 65 - 0
components/chat/inputbar/suit/main/main.css

@@ -0,0 +1,65 @@
+
+.text-input {
+	width: 100%;
+	/* height: 100rpx; */
+	padding: 0;
+	display: block;
+}
+
+.news {
+	width: 100%;
+	font-size: 14px;
+	padding: 0 10px;
+	display: inline-block;
+	margin: 10rpx;
+	line-height: 48rpx;
+	position:relative;
+	top: 0;
+	background-color: #fff;
+	border-radius: 16px;
+	flex: 1;
+	max-height: 200rpx;
+	min-height: 60rpx;
+}
+
+.send_btn {
+	width: 80rpx;
+	height: 60rpx;
+	line-height: 60rpx;
+	font-size: 17px;
+	color: #000;
+	padding: 0;
+	display: inline-block;
+	float: right;
+	margin: 8rpx 16rpx auto auto;
+	background-color: #fff;
+}
+
+.f-row{
+	/* height:100rpx; */
+	display:flex;
+	align-items:center;
+	background-color: #f2f2f2;
+}
+.send-btn-style{
+	font-size: 10px;
+	background-color: #2196F3;
+	color: #fff;
+    margin-right: 10px;
+}
+.hover{
+	background-color:#075ca1
+}
+.icon-mic{
+	width: 22px;
+    height: 22px;
+	margin: 5px 10px;
+	position: relative;
+	top: 2px;
+}
+.f-row-x{
+	padding-bottom: 30px;
+	display:flex;
+	align-items:center;
+	background-color: #f2f2f2;
+}

+ 189 - 0
components/chat/inputbar/suit/main/main.vue

@@ -0,0 +1,189 @@
+<template>
+  <!-- <chat-suit-emoji id="chat-suit-emoji" bind:newEmojiStr="emojiAction"></chat-suit-emoji> -->
+  <form class="text-input">
+    <view :class="isIPX ?'f-row-x' :'f-row'">
+      <!-- 发送语音 -->
+      <view>
+        <image class="icon-mic" src="@/static/images/voice.png" @tap="openRecordModal"></image>
+      </view>
+      <!-- 输入框 -->
+      <textarea
+        class="f news"
+        type="text"
+        cursor-spacing="65"
+        confirm-type='done'
+        v-model="inputMessage"
+        @confirm="sendMessage"
+        @input="bindMessage"
+        @tap="focus"
+        @focus="focus"
+        @blur="blur"
+        :confirm-hold="isIPX ? true : false"
+        auto-height
+        :show-confirm-bar='false'
+        maxlength="300"
+      />
+      <view>
+        <image class="icon-mic" src="@/static/images/Emoji.png" @tap="openEmoji"></image>
+      </view>
+      <view v-show="!inputMessage" @tap="openFunModal">
+        <image class="icon-mic" src="@/static/images/ad.png"></image>
+      </view>
+       <button 
+        class="send-btn-style" 
+        hover-class='hover'
+        @tap="sendMessage"
+        v-show="inputMessage" 
+      >发送</button>
+    </view>
+  </form>
+</template>
+
+<script>
+let WebIM = require("../../../../../utils/WebIM")["default"];
+let msgType = require("../../../msgtype");
+let disp = require("../../../../../utils/broadcast");
+let msgStorage = require("../../../msgstorage");
+
+export default {
+  data() {
+    return {
+      inputMessage: "",
+      // render input 的值
+      userMessage: "", // input 的实时值
+      isIPX: false,
+    };
+  },
+
+  components: {},
+  props: {
+    username: {
+      type: Object,
+      default: () => ({}),
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT,
+    },
+  },
+
+  // lifetimes
+  created() {
+    this.isIPX= getApp().globalData.isIPX
+  },
+
+  beforeMount() {},
+
+  moved() {},
+
+  destroyed() {},
+
+  mounted() {},
+
+  methods: {
+    focus() {
+      this.$emit("inputFocused", null, {
+        bubbles: true,
+      });
+    },
+    blur() {
+      this.$emit("inputBlured", null, {
+        bubbles: true,
+      });
+    },
+
+    isGroupChat() {
+      return this.chatType == msgType.chatType.CHAT_ROOM;
+    },
+
+    getSendToParam() {
+      return this.isGroupChat() ? this.username.groupId : this.username.your;
+    },
+
+    bindMessage(e) {
+      this.userMessage= e.detail.value
+    },
+
+    emojiAction(emoji) {
+      var str;
+      var msglen = this.userMessage.length - 1;
+
+      if (emoji && emoji != "[del]") {
+        str = this.userMessage + emoji;
+      } else if (emoji == "[del]") {
+        let start = this.userMessage.lastIndexOf("[");
+        let end = this.userMessage.lastIndexOf("]");
+        let len = end - start;
+
+        if (end != -1 && end == msglen && len >= 3 && len <= 4) {
+          str = this.userMessage.slice(0, start);
+        } else {
+          str = this.userMessage.slice(0, msglen);
+        }
+      }
+      this.userMessage = str;
+      this.inputMessage = str;
+    },
+
+    sendMessage() {
+      let me = this;
+      String.prototype.trim = function () {
+        return this.replace(/(^\s*)|(\s*$)/g, "");
+      };
+      if (!this.userMessage.trim()) {
+        return;
+      }
+      let id = WebIM.conn.getUniqueId();
+      let msg = new WebIM.message(msgType.TEXT, id);
+      msg.set({
+        msg: this.userMessage,
+        from: this.username.myName,
+        to: this.getSendToParam(),
+        // roomType: false,
+        chatType: this.chatType,
+        success(id, serverMsgId) {
+          console.log("成功了");
+          // 关闭表情弹窗
+          me.$parent.cancelEmoji()
+          me.$parent.closeFunModal()
+          disp.fire("em.chat.sendSuccess", id, me.userMessage);
+        },
+        fail(id, serverMsgId) {
+          console.log("失败了");
+        },
+      });
+	  
+      if (this.chatType == msgType.chatType.CHAT_ROOM) {
+        // msg.setGroup("groupchat");
+		msg.setChatType("groupchat");
+      }
+        WebIM.conn.send(msg.body);
+        let obj = {
+          msg: msg,
+          type: msgType.TEXT,
+        };
+        this.saveSendMsg(obj);
+      this.userMessage = "";
+      this.inputMessage = "";
+      uni.hideKeyboard();
+    },
+
+    saveSendMsg(evt) {
+      msgStorage.saveMsg(evt.msg, evt.type);
+    },
+
+    openEmoji(){
+      this.$emit('openEmoji')
+    },
+    openRecordModal(){
+      this.$emit('openRecordModal')
+    },
+    openFunModal(){
+      this.$emit('openFunModal')
+    }
+  },
+};
+</script>
+<style>
+@import "./main.css";
+</style>

+ 65 - 0
components/chat/inputbar/suit/ptopcall/ptopcall.vue

@@ -0,0 +1,65 @@
+<template>
+	<view v-if="visible" class="wraper">
+		<view>
+			<button type="default" @tap="callVideo">会议模式</button>
+			<button
+				type="default"
+				@tap="cancel"
+			> 取消 </button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				visible: false
+			}
+		},
+		methods: {
+			show(){
+				this.visible= true
+			},
+			cancel(){
+				console.log('取消')
+				this.visible= false
+				/* this.setData({
+					visible: false
+				}) */
+			},
+	
+			callAudio(){
+				//this.triggerEvent('makeAudioCall', 'single')
+				this.$emit("makeAudioCall", null, 'single');
+				this.cancel()
+			},
+	
+			callVideo(){
+				console.log('callVideo')
+				this.$emit("makeVideoCall", null, 'single');
+				//this.triggerEvent('makeVideoCall', 'single')
+				this.cancel()
+			}
+		}
+	}
+</script>
+
+<style>
+.wraper{
+	position: fixed;
+	bottom: 0;
+	height: 200rpx;
+	width: 100%;
+	z-index: 9;
+	background: #FFFFFF;
+}
+.other-button-hover {
+  background-color: blue;
+}
+.button-cancel {
+	position: absolute;
+	width: 100%;
+	bottom: 0;
+}
+</style>

+ 110 - 0
components/chat/inputbar/suit/videoComp/videoComp.vue

@@ -0,0 +1,110 @@
+<template>
+  <div></div>
+</template>
+
+<script>
+let WebIM = require("../../../../../utils/WebIM")["default"];
+let msgType = require("../../../msgtype");
+let msgStorage = require("../../../msgstorage");
+let disp = require("../../../../../utils/broadcast");
+
+export default {
+  data() {
+    return {};
+  },
+
+  components: {},
+  props: {
+    username: {
+      type: Object,
+      default: () => ({}),
+    },
+    chatType: {
+      type: String,
+      default: msgType.chatType.SINGLE_CHAT,
+    },
+  },
+  methods: {
+    isGroupChat() {
+      return this.chatType == msgType.chatType.CHAT_ROOM;
+    },
+
+    getSendToParam() {
+      return this.isGroupChat() ? this.username.groupId : this.username.your;
+    },
+
+    // 未启用
+    sendVideo() {
+      var me = this;
+      var token = WebIM.conn.context.accessToken;
+      uni.chooseVideo({
+        sourceType: ["album", "camera"],
+        maxDuration: 60,
+        camera: "back",
+        success(res) {
+          var tempFilePaths = res.tempFilePath;
+          var str = WebIM.config.appkey.split("#");
+          uni.uploadFile({
+            url:
+              "https://a1.easemob.com/" + str[0] + "/" + str[1] + "/chatfiles",
+            filePath: tempFilePaths,
+            name: "file",
+            header: {
+              "Content-Type": "multipart/form-data",
+              Authorization: "Bearer " + token,
+            },
+            success(res) {
+              var data = res.data;
+              var dataObj = JSON.parse(data);
+              var id = WebIM.conn.getUniqueId(); // 生成本地消息id
+              var msg = new WebIM.message(msgType.VIDEO, id);
+              msg.set({
+                apiUrl: WebIM.config.apiURL,
+                accessToken: token,
+                body: {
+                  type: msgType.VIDEO,
+                  url: dataObj.uri + "/" + dataObj.entities[0].uuid,
+                  filetype: "mp4",
+                  filename: tempFilePaths,
+									accessToken: token,
+                },
+                from: me.username.myName,
+                to: me.getSendToParam(),
+                roomType: false,
+                chatType: me.chatType,
+                success: function (argument) {
+									disp.fire('em.chat.sendSuccess', id);
+								}
+              });
+              if (me.isGroupChat()) {
+                msg.setGroup("groupchat");
+              }
+              WebIM.conn.send(msg.body);
+              let obj = {
+                msg: msg,
+                type: msgType.VIDEO,
+              };
+              me.saveSendMsg(obj);
+            },
+          });
+        },
+      });
+    },
+    saveSendMsg(evt) {
+      msgStorage.saveMsg(evt.msg, evt.type);
+    },
+  },
+
+  // lifetimes
+  created() {},
+
+  beforeMount() {},
+
+  moved() {},
+
+  destroyed() {},
+
+  mounted() {},
+};
+</script>
+

+ 148 - 0
components/chat/msglist/msglist.css

@@ -0,0 +1,148 @@
+/*.chat-bg{
+	position:fixed;
+	width: 100%;
+	height: 100%;
+	z-index: 0;
+	top: 50px;
+}*/
+.scroll_view,.scroll_view_change {
+	/* width: 100%;
+	position: absolute;
+	left: 0;
+	right: 0;
+	bottom: 170rpx; */
+	background-color: #FAFAFA;
+	padding-bottom: 100rpx;
+}
+
+.scroll_view_X,
+.scroll_view_change_X{
+	padding-bottom: 230rpx;
+}
+
+
+.message {
+	width: 100%;
+	height: auto;
+	padding: 0 30rpx;
+	position: relative;
+	box-sizing: border-box;
+}
+
+.time {
+	margin: 14rpx 0;
+	text-align: center;
+}
+
+.time .time-text {
+	display: inline-block;
+	padding: 6rpx 20rpx 0 20rpx;
+	font-size: 24rpx;
+	color: #fff;
+	line-height: 28rpx;
+	border-radius: 4rpx;
+	background-color: #dcdcdc;
+}
+
+.user .user-text {
+	margin: auto 100rpx 8rpx;
+	font-size: 20rpx;
+	color: #dcdcdc;
+	display: block;
+}
+
+.avatar {
+	width: 72rpx;
+	height: 72rpx;
+	margin: 0 20rpx 0 0;
+	border-radius: 50%;
+	float: left;
+}
+
+.msg {
+	display: inline-block;
+	padding: 20rpx;
+	max-width: calc(85% - 80rpx);
+	min-height: 40rpx; 
+	font-size: 24rpx;
+	/*overflow: hidden;*/
+	text-align: left;
+	word-break: break-all;
+	background-color: #fff;
+	border-radius: 26rpx;
+	position: relative;
+	margin-top: 24rpx;
+}
+
+.msg .msg_poprightarrow {
+	position: absolute;
+	right: -10rpx;
+	height: 18rpx;
+	width: 18rpx;
+	margin-top: -10rpx;
+}
+
+.msg .msg_popleftarrow{
+	position:absolute;
+	left: -14rpx;
+	height: 18rpx;
+	width: 18rpx;
+	margin-top: -10rpx;
+}
+
+.msg .msg-text {
+	line-height: 40rpx;
+	font-size: 32rpx;
+	margin: 0;
+}
+
+/*.msg:before {
+	content: " ";
+	position: absolute;
+	top: 9px;
+	right: 100%;
+	border: 6px solid transparent;
+	border-right-color: #EDEDED;
+}*/
+
+.self {
+	text-align: right;
+}
+
+.self .avatar {
+	float: right;
+	margin: 0 0 0 20rpx;
+}
+
+.user {
+	position: relative;
+	bottom: -30rpx;
+}
+
+.self .msg {
+	background-color: #0873DE;
+	color: #fff;
+}
+
+.self .msg:before {
+	right: inherit;
+	left: 100%;
+	border-right-color: transparent;
+	border-left-color: #b2e281;
+}
+
+.template {
+	display: inline;
+}
+.err{
+	width: 32rpx;
+	height: 32rpx;
+	position: absolute;
+	left: -40rpx;
+}
+.hide{
+	display: none;
+}
+.show{
+	display: block;
+}

+ 323 - 0
components/chat/msglist/msglist.vue

@@ -0,0 +1,323 @@
+<template>
+  <view
+    scroll-y="true"
+    :class="view + ' wrap ' + (isIPX?'scroll_view_X': '')"
+    @tap="onTap"
+    upper-threshold="-50"
+    :scroll-into-view="toView"
+  >
+    <view class="message" v-for="item in chatMsg" :key="item.mid" :id="item.mid">
+      <!-- <view class="time">
+				<text class="time-text">{{ item.time }}</text>
+      </view>-->
+      <view class="main" :class="item.style">
+        <view class="user">
+          <!-- yourname:就是消息的 from -->
+          <text class="user-text">{{ item.time}}</text>
+        </view>
+        <image class="avatar" v-if="item.style=='self'" :src="item.user.avatarurl" />
+		<image class="avatar" v-else :src="item.your.avatarurl" />
+        <view class="msg">
+          <image
+            class="err"
+            :class="(item.style == 'self' && item.isFail) ?  'show' : 'hide'"
+            src="/static/images/msgerr.png"
+          />
+
+          <image
+            v-if="item.style == 'self'"
+            src="/static/images/poprightarrow2x.png"
+            class="msg_poprightarrow"
+          />
+          <image
+            v-if="item.style == ''"
+            src="/static/images/popleftarrow2x.png"
+            class="msg_popleftarrow"
+          />
+          <view v-if="item.msg.type == 'img' || item.msg.type == 'video'">
+            <image
+              v-if="item.msg.type == 'img'"
+              class="avatar"
+              :src="item.msg.data"
+              style="width:90px; height:120px; margin:2px auto;"
+              mode="aspectFit"
+              @tap="previewImage"
+              :data-url="item.msg.data"
+            />
+            <!-- <video v-if="item.msg.type == 'video'" :src="item.msg.data" controls style="width:300rpx;"/> -->
+          </view>
+          <audio-msg v-if="item.msg.type == 'audio'" :msg="item"></audio-msg>
+          <view v-else-if="item.msg.type == 'txt' || item.msg.type == 'emoji'">
+            <view class="template" v-for="(d_item, d_index) in item.msg.data" :key="d_index">
+              <text
+				        :data-msg="item"
+				        @tap="clickMsg"
+                v-if="d_item.type == 'txt'"
+                class="msg-text"
+                style="float:left;"
+                selectable="true"
+              >{{ d_item.data }}</text>
+
+              <image
+                v-if="d_item.type == 'emoji'"
+                class="avatar"
+                :src="'/static/images/faces/' + d_item.data"
+                style="width:25px; height:25px; margin:0 0 2px 0; float:left;"
+              />
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+  <!-- <view style="height: 1px;"></view> -->
+</template>
+
+
+<script>
+let msgStorage = require("../msgstorage");
+let disp = require("../../../utils/broadcast");
+let LIST_STATUS = {
+  SHORT: "scroll_view_change",
+  NORMAL: "scroll_view"
+};
+let page = 0;
+let Index = 0;
+let curMsgMid = '';
+let isFail = false;
+import audioMsg from "./type/audio/audio";
+
+export default {
+  data() {
+    return {
+      view: LIST_STATUS.NORMAL,
+      toView: "",
+      chatMsg: [],
+      __visibility__: false,
+      isIPX: false
+    };
+  },
+
+  components: {
+    audioMsg
+  },
+  props: {
+    username: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+
+  // lifetimes
+  created() {},
+
+  beforeMount() {
+    this.__visibility__ = true;
+    page = 0;
+    Index = 0;
+  },
+
+  moved() {},
+
+  destroyed() {
+    this.__visibility__ = false;
+	msgStorage.off("newChatMsg", this.dispMsg)
+  },
+
+  mounted(event) {
+    let me = this;
+    if (getApp().globalData.isIPX) {
+      this.isIPX= true
+    }
+	
+	  this.username = uni.username;
+    let username = this.username;
+    let myUsername = uni.getStorageSync("myUsername");
+    let sessionKey = username.groupId ? username.groupId + myUsername : username.your + myUsername;
+    let chatMsg = uni.getStorageSync(sessionKey) || [];
+    this.renderMsg(null, null, chatMsg, sessionKey);
+    uni.setStorageSync(sessionKey, null);
+    disp.on('em.error.sendMsgErr', function (err) {
+      // curMsgMid = err.data.mid;
+      isFail = true;
+      // return;
+      console.log('发送失败了');
+	  return;
+      let msgList = me.chatMsg;
+      msgList.map(item => {
+        if (item.mid.substring(item.mid.length - 10) == curMsgMid.substring(curMsgMid.length - 10)) {
+          item.msg.data[0].isFail = true;
+          item.isFail = true;
+          me.chatMsg= msgList
+        }
+      });
+
+      // if (me.curChatMsg[0].mid == curMsgMid) {
+      //   me.curChatMsg[0].msg.data[0].isShow = false;
+      //   me.curChatMsg[0].isShow = false;
+      // }
+
+      uni.setStorageSync("rendered_" + sessionKey, msgList);
+    });
+    msgStorage.on("newChatMsg", this.dispMsg);
+  },
+
+  methods: {
+    normalScroll() {
+      this.view= LIST_STATUS.NORMAL
+    },
+	dispMsg(renderableMsg, type, curChatMsg, sesskey) {
+	  let me = this;
+	  let username = this.username;
+	  let myUsername = uni.getStorageSync("myUsername");
+	  let sessionKey = username.groupId ? username.groupId + myUsername : username.your + myUsername;
+	  me.curChatMsg = curChatMsg;
+	  
+	  if (!me.__visibility__) return; // 判断是否属于当前会话
+	
+	  if (username.groupId) {
+	    // 群消息的 to 是 id,from 是 name
+	    if (renderableMsg.info.from == username.groupId || renderableMsg.info.to == username.groupId) {
+	      if (sesskey == sessionKey) {
+	        me.renderMsg(renderableMsg, type, curChatMsg, sessionKey, 'newMsg');
+	      }
+	    }
+	  } else if (renderableMsg.info.from == username.your || renderableMsg.info.to == username.your) {
+	    if (sesskey == sessionKey) {
+	      me.renderMsg(renderableMsg, type, curChatMsg, sessionKey, 'newMsg');
+	    }
+	  }
+	},
+    shortScroll() {
+      this.view= LIST_STATUS.SHORT
+    },
+
+    onTap() {
+      this.$emit("msglistTap", null, {
+        bubbles: true
+      });
+    },
+
+    previewImage(event) {
+      var url = event.target.dataset.url;
+      uni.previewImage({
+        urls: [url] // 需要预览的图片 http 链接列表
+
+      });
+    },
+
+    getHistoryMsg() {
+      let me = this;
+      let username = this.username;
+      let myUsername = uni.getStorageSync("myUsername");
+      let sessionKey = username.groupId ? username.groupId + myUsername : username.your + myUsername;
+      let historyChatMsgs = uni.getStorageSync("rendered_" + sessionKey) || [];
+
+      if (Index < historyChatMsgs.length) {
+        let timesMsgList = historyChatMsgs.slice(-Index - 10, -Index);
+        this.chatMsg= timesMsgList.concat(me.chatMsg),
+        this.toView= timesMsgList[timesMsgList.length - 1].mid
+        Index += timesMsgList.length;
+
+        if (timesMsgList.length == 10) {
+          page++;
+        }
+
+        uni.stopPullDownRefresh();
+      }
+    },
+
+    renderMsg(renderableMsg, type, curChatMsg, sessionKey, isnew) {
+      let me = this;
+
+      var historyChatMsgs = uni.getStorageSync("rendered_" + sessionKey) || []; 
+
+      historyChatMsgs = historyChatMsgs.concat(curChatMsg); 
+		
+      if (!historyChatMsgs.length) return;
+	  let user = {}
+	  let your = {}
+	  let myUsername = uni.getStorageSync('myUsername')
+	  uni.WebIM.conn.fetchUserInfoById([myUsername,me.username.your], ['avatarurl','nickname']).then((res) => {
+		  user = res.data[myUsername]
+		  your = res.data[me.username.your]
+		  console.log('用户信息',res);
+		  historyChatMsgs.map(function(item,index) {
+		  	item.user = user
+			item.your = your
+		  })
+		  if (isnew == 'newMsg') {
+		    this.chatMsg= this.chatMsg.concat(curChatMsg)
+		      // 跳到最后一条
+		    this.toView= historyChatMsgs[historyChatMsgs.length - 1].mid
+		  } else {
+		  		  this.chatMsg= historyChatMsgs.slice(-10)
+		  		    // 跳到最后一条
+		  		  this.toView= historyChatMsgs[historyChatMsgs.length - 1].mid
+		  }
+		  
+		  uni.setStorageSync("rendered_" + sessionKey, historyChatMsgs);
+		  let chatMsg = uni.getStorageSync(sessionKey) || [];
+		  chatMsg.map(function (item, index) {
+		    curChatMsg.map(function (item2, index2) {
+		      if (item2.mid == item.mid) {
+		        chatMsg.splice(index, 1);
+		      }
+		    });
+		  });
+		  uni.setStorageSync(sessionKey, chatMsg);
+		  Index = historyChatMsgs.slice(-10).length;
+		  // setTimeout 兼容支付宝小程序
+		  setTimeout(() => {
+		  		  uni.pageScrollTo({
+		  		    scrollTop: 5000,
+		  		    duration: 300,
+		  		  		fail: (e) => {
+		  		  			//console.log('滚失败了', e)
+		  		  		}
+		  		  });
+		  }, 100)
+		  
+		  if (isFail) {
+		    this.renderFail(sessionKey);
+		  }
+	  })
+		
+		
+     
+    },
+
+    renderFail(sessionKey) {
+      let me = this;
+      let msgList = me.chatMsg;
+      msgList.map(item => {
+        if (item.mid.substring(item.mid.length - 10) == curMsgMid.substring(curMsgMid.length - 10)) {
+          item.msg.data[0].isFail = true;
+          item.isFail = true;
+          me.chatMsg= msgList
+        }
+      });
+
+      if (me.curChatMsg[0].mid == curMsgMid) {
+        me.curChatMsg[0].msg.data[0].isShow = false;
+        me.curChatMsg[0].isShow = false;
+      }
+
+      uni.setStorageSync("rendered_" + sessionKey, msgList);
+      isFail = false;
+    },
+	
+	clickMsg(event){
+		if(typeof(event.target.dataset.msg) == 'object' && 
+			event.target.dataset.msg.msg.ext && 
+			event.target.dataset.msg.msg.ext.msg_extension){
+			this.$emit("clickMsg", event.target.dataset.msg.msg.ext)
+		}
+	}
+
+  }
+};
+</script>
+<style>
+@import "./msglist.css";
+</style>

+ 25 - 0
components/chat/msglist/type/audio/audio.css

@@ -0,0 +1,25 @@
+.audio-player {
+	position: relative;
+	overflow: hidden;
+	display: flex;
+	transition: opacity .5s;
+}
+
+.audio-player .controls {
+	height:40rpx;
+	align-items:center;
+	display:flex;
+}
+
+.audio-player .controls image {
+	height: 48rpx;
+	width: 30rpx;
+	margin: 0 8rpx 0 100rpx;
+}
+
+.audio-player .time {
+	font-size: 34rpx;
+	line-height: 40rpx;
+	flex: 1;
+	text-align: left;
+}

+ 178 - 0
components/chat/msglist/type/audio/audio.vue

@@ -0,0 +1,178 @@
+<template>
+<view class="audio-player" @tap="audioPlay" :style="'opacity: ' + opcity">
+	<text class="time">语音消息 {{ time }}</text>
+	<view class="controls play-btn" @tap="audioPlay">
+		<image :src="style == 'self'? '../../../../../static/images/voicemsgmy.png' : '../../../../../static/images/voicemsg.png'"></image>
+	</view>
+</view>
+</template>
+
+<script>
+let audioCtxFc = require("./audioCtxFactory");
+let playStatus = require("./playStatus");
+
+export default {
+  data() {
+    return {
+      playStatus: playStatus,
+      curStatus: playStatus.STOP,
+      time: "0'",
+      opcity: 1,
+      __comps__: {
+        audioCtx: null
+      },
+      style: ""
+    };
+  },
+
+  components: {},
+  props: {
+    msg: {
+      type: Object,
+      val: {}
+    }
+  },
+  obeyMuteSwitch: false,
+  autoplay: true,
+
+  // lifetimes
+  created() {},
+
+  beforeMount() {
+    this.time=this.msg.msg.length + "''"
+	this.style = this.msg.style
+  },
+
+  moved() {},
+
+  destroyed() {
+    let audioCtx = this.$data.__comps__.audioCtx = audioCtxFc.getCtx(this.msg.mid);
+    this.audioPause(audioCtx);
+    this.delEvent(); //audioCtx.destroy();
+  },
+
+  mounted() {
+    let self = this;
+    let curl = '';
+    let audioCtx = this.$data.__comps__.audioCtx = audioCtxFc.getCtx(this.msg.mid);
+    audioCtx.autoplay = false;
+    audioCtx.loop = false; //
+
+    this.onPlaying = () => {
+      //console.log("onPlaying", JSON.stringify(this.data));
+      this.curStatus= playStatus.PLAYING
+      uni.inter && clearInterval(uni.inter);
+      uni.inter = setInterval(() => {
+        let opcity = this.opcity;
+        this.opcity= opcity == 1 ? 0.4 : 1
+      }, 500);
+    };
+
+    this.onPause = () => {
+      // console.log("onPause", JSON.stringify(this.data));
+      // 第二次播放会立即抛出一个异常的 onPause
+      if (parseInt(this.time, 10) < 1) {
+        return;
+      }
+
+      this.curStatus= playStatus.PAUSE
+      this.opcity= 1 //time:
+    };
+
+    this.onDone = () => {
+      // console.log("onDone", JSON.stringify(this.data));
+	  this.curStatus= playStatus.STOP
+	  this.opcity= 1 //time:
+      clearInterval(uni.inter);
+    }; // 多次播放会丢失这个回调
+
+
+    this.onTimeUpdate = () => {
+      this.time= (audioCtx.currentTime >> 0) + "'"
+    };
+
+    this.onWait = () => {
+      uni.showToast({
+        title: "下载中...",
+        duration: 1000
+      });
+    };
+
+    this.addEvent();
+  },
+
+  methods: {
+    audioPlay() {
+	if(uni.getSystemInfo().app === 'alipay'){
+		// https://forum.alipay.com/mini-app/post/7301031?ant_source=opendoc_recommend
+		uni.showToast({
+			duration: 2000,
+			title: '支付宝小程序不支持音频消息'
+		})
+		return 
+	}
+      uni.inter && clearInterval(uni.inter);
+      let audioCtx = this.$data.__comps__.audioCtx;
+      var curl = '';
+      uni.downloadFile({
+        url: this.msg.msg.data,
+        header: {
+          "X-Requested-With": "XMLHttpRequest",
+          Accept: "audio/mp3",
+          Authorization: "Bearer " + this.msg.msg.token
+        },
+
+        success(res) {
+          curl = res.tempFilePath;
+          console.log('音频本地', audioCtx); //renderableMsg.msg.url = res.tempFilePath;
+
+          audioCtx.src = curl;
+          audioCtx.play();
+        },
+
+        fail(e) {
+          console.log("downloadFile failed", e);
+          uni.showToast({
+            title: "下载失败",
+            duration: 1000
+          });
+        }
+
+      });
+    },
+
+    audioPause(auCtx) {
+      //let audioCtx = this.data.__comps__.audioCtx;
+      let audioCtx = this.$data.__comps__.audioCtx = audioCtxFc.getCtx(this.msg.mid) || auCtx;
+      audioCtx && audioCtx.pause();
+    },
+
+    addEvent() {
+      let audioCtx = this.$data.__comps__.audioCtx;
+      audioCtx.onPlay(this.onPlaying);
+      audioCtx.onPause(this.onPause);
+      audioCtx.onWaiting(this.onPause);
+      audioCtx.onStop(this.onDone);
+      audioCtx.onEnded(this.onDone);
+      audioCtx.onError(this.onDone);
+      audioCtx.onWaiting(this.onWait); //audioCtx.onTimeUpdate(this.onTimeUpdate);
+    },
+
+    delEvent() {
+      let audioCtx = this.$data.__comps__.audioCtx;
+      audioCtx.offPlay(this.onPlaying);
+      audioCtx.offPause(this.onPause);
+      audioCtx.offWaiting(this.onPause);
+      audioCtx.offStop(this.onDone);
+      audioCtx.offEnded(this.onDone);
+      audioCtx.offError(this.onDone);
+      audioCtx.offWaiting(this.onWait); // 多次播放会丢失这个回调,所以不用卸载
+      // audioCtx.offTimeUpdate(this.onTimeUpdate);
+    }
+
+  }
+};
+</script>
+<style>
+@import "./audio.css";
+</style>

+ 62 - 0
components/chat/msglist/type/audio/audioCtxFactory.js

@@ -0,0 +1,62 @@
+// 每一个音频消息都有自己的 ctx。
+// 可以有多个 ctx,每次播放都能知道是哪个 ctx 在调用,从而让其他的 ctx pause。
+// 消息销毁,记得处理 ctx。
+// 主要是同步跨 ctx 的操作,保证只有一个 ctx 播放
+let allCtx = {};
+let inUseCtx = null;
+let allComm = {};
+
+function proxier(ctx) {
+  let __play__ = ctx.play;
+  let __pause__ = ctx.pause;
+  ctx.play = playProxier;
+  ctx.pause = pauseProxier;
+
+  function playProxier() {
+    // 如果正在播放的不是自己,暂停
+    if (inUseCtx && inUseCtx != this) {
+      inUseCtx.pause();
+    }
+
+    __play__.call(this);
+
+    inUseCtx = this;
+  }
+
+  function pauseProxier() {
+    // 只有是自己才 pause
+    if (inUseCtx == this) {
+      __pause__.call(this);
+    }
+  }
+}
+
+module.exports = {
+  getCtx(mid) {
+    let returnCtx = allCtx[mid];
+
+    if (!returnCtx) {
+      returnCtx = uni.createInnerAudioContext();
+      allCtx[mid] = returnCtx;
+      proxier(returnCtx);
+    }
+
+    return returnCtx;
+  },
+
+  getAllCtx() {
+    uni.setStorageSync("allCtx", JSON.stringify(Object.keys(allCtx)));
+    return allCtx;
+  },
+
+  getCommponet(mid, comm) {
+    let curComm = allComm[mid];
+
+    if (!curComm) {
+      allComm[mid] = comm;
+    }
+
+    return allComm;
+  }
+
+};

+ 5 - 0
components/chat/msglist/type/audio/playStatus.js

@@ -0,0 +1,5 @@
+module.exports = {
+  PLAYING: "playing",
+  PAUSE: "pause",
+  STOP: "stop"
+};

+ 56 - 0
components/chat/msgpackager.js

@@ -0,0 +1,56 @@
+let WebIM = require("../../utils/WebIM.js")["default"];
+
+let msgType = require("./msgtype.js");
+
+module.exports = function (sendableMsg, type, myName) {
+  var time = WebIM.time();
+  var renderableMsg = {
+    info: {
+      from: sendableMsg.body.from,
+      to: sendableMsg.body.to
+    },
+    username: sendableMsg.body.from == myName ? sendableMsg.body.to : sendableMsg.body.from,
+    yourname: sendableMsg.body.from,
+    msg: {
+      type: type,
+      url: sendableMsg.body.url ? sendableMsg.body.url : '',
+      data: getMsgData(sendableMsg, type),
+	  ext: sendableMsg.body.ext
+    },
+    style: sendableMsg.body.from == myName ? "self" : "",
+    time: time,
+    mid: sendableMsg.type + sendableMsg.id,
+    chatType: sendableMsg.body.chatType
+  };
+
+  if (type == msgType.IMAGE) {
+    renderableMsg.msg.size = {
+      width: sendableMsg.body.body.size.width,
+      height: sendableMsg.body.body.size.height
+    };
+  } else if (type == msgType.AUDIO) {
+    renderableMsg.msg.length = sendableMsg.body.length;
+  } else if (type == msgType.FILE) {
+    renderableMsg.msg.data = [{
+      data: "[当前不支持此格式消息展示]",
+      type: "txt"
+    }];
+    renderableMsg.msg.type = 'txt';
+  }
+
+  return renderableMsg;
+
+  function getMsgData(sendableMsg, type) {
+    if (type == msgType.TEXT) {
+      return WebIM.parseEmoji(sendableMsg.value.replace(/\n/mg, ""));
+    } else if (type == msgType.EMOJI) {
+      return sendableMsg.value;
+    } else if (type == msgType.IMAGE || type == msgType.VIDEO || type == msgType.AUDIO) {
+      return sendableMsg.body.body.url;
+    } else if (type == msgType.FILE) {
+      return sendableMsg.body.body.msg;
+    }
+
+    return "";
+  }
+};

+ 195 - 0
components/chat/msgstorage.js

@@ -0,0 +1,195 @@
+let Disp = require("../../utils/Dispatcher.js");
+
+let msgPackager = require("./msgpackager.js");
+
+let msgType = require("./msgtype.js");
+
+let msgStorage = new Disp();
+
+let disp = require("../../utils/broadcast.js");
+
+msgStorage.saveReceiveMsg = function (receiveMsg, type) {
+  let sendableMsg;
+
+  if (type == msgType.IMAGE) {
+    sendableMsg = {
+      id: receiveMsg.id,
+      type: type,
+      body: {
+        id: receiveMsg.id,
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        type: receiveMsg.type,
+        ext: receiveMsg.ext,
+        chatType: receiveMsg.type,
+        toJid: "",
+        body: {
+          type: type,
+          url: receiveMsg.url,
+          filename: receiveMsg.filename,
+          filetype: receiveMsg.filetype,
+          size: {
+            width: receiveMsg.width,
+            height: receiveMsg.height
+          }
+        }
+      }
+    };
+  } else if (type == msgType.TEXT || type == msgType.EMOJI) {
+    sendableMsg = {
+      id: receiveMsg.id,
+      type: type,
+      body: {
+        id: receiveMsg.id,
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        type: receiveMsg.type,
+        ext: receiveMsg.ext,
+        chatType: receiveMsg.type,
+        toJid: "",
+        body: {
+          type: type,
+          msg: receiveMsg.data
+        }
+      },
+      value: receiveMsg.data
+    };
+  } 
+  else if (type == 'INFORM') { // 通知消息
+    sendableMsg = {
+      body: {
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        chatType: 'INFORM',
+        gid:receiveMsg.gid ? receiveMsg.gid:'',
+        type:receiveMsg.type
+      },
+    };
+  } else if (type == msgType.FILE) {
+    sendableMsg = {
+      id: receiveMsg.id,
+      type: type,
+      body: {
+        id: receiveMsg.id,
+        length: receiveMsg.file_length,
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        type: receiveMsg.type,
+        ext: receiveMsg.ext,
+        chatType: receiveMsg.type,
+        toJid: "",
+        body: {
+          type: type,
+          url: receiveMsg.url,
+          filename: receiveMsg.filename,
+          msg: "当前不支持此格式消息展示"
+        }
+      },
+      value: receiveMsg.data
+    };
+  } else if (type == msgType.AUDIO) {
+    sendableMsg = {
+      id: receiveMsg.id,
+      type: type,
+      accessToken: receiveMsg.token || receiveMsg.accessToken,
+      body: {
+        id: receiveMsg.id,
+        length: receiveMsg.length,
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        type: receiveMsg.type,
+        ext: receiveMsg.ext,
+        chatType: receiveMsg.type,
+        toJid: "",
+        body: {
+          type: type,
+          url: receiveMsg.url,
+          filename: receiveMsg.filename,
+          filetype: receiveMsg.filetype,
+          from: receiveMsg.from,
+          to: receiveMsg.to
+        }
+      }
+    };
+  } else if (type == msgType.VIDEO) {
+    sendableMsg = {
+      id: receiveMsg.id,
+      type: type,
+      accessToken: receiveMsg.token || receiveMsg.accessToken,
+      body: {
+        id: receiveMsg.id,
+        length: receiveMsg.length,
+        from: receiveMsg.from,
+        to: receiveMsg.to,
+        type: receiveMsg.type,
+        ext: receiveMsg.ext,
+        chatType: receiveMsg.type,
+        toJid: "",
+        body: {
+          type: type,
+          url: receiveMsg.url,
+          filename: receiveMsg.filename,
+          filetype: receiveMsg.filetype,
+          from: receiveMsg.from,
+          to: receiveMsg.to
+        },
+      },
+    };
+  } else {
+    return;
+  }
+
+  this.saveMsg(sendableMsg, type, receiveMsg);
+};
+
+msgStorage.saveMsg = function (sendableMsg, type, receiveMsg) {
+  let me = this;
+  let myName = uni.getStorageSync("myUsername");
+  let sessionKey; // 仅用作群聊收消息,发消息没有 receiveMsg
+
+  if (receiveMsg && receiveMsg.type == "groupchat") {
+    sessionKey = receiveMsg.to + myName;
+  } else if (sendableMsg.body.chatType === 'INFORM'){
+    sessionKey = 'INFORM'
+  }
+  
+  // 群聊发 & 单发 & 单收
+  else {
+    sessionKey = sendableMsg.body.from == myName ? sendableMsg.body.to + myName : sendableMsg.body.from + myName;
+  }
+
+  let curChatMsg = uni.getStorageSync(sessionKey) || [];
+  let renderableMsg = msgPackager(sendableMsg, type, myName);
+
+  if (type == msgType.AUDIO) {
+    renderableMsg.msg.length = sendableMsg.body.length;
+    renderableMsg.msg.token = sendableMsg.accessToken;
+  }
+
+  curChatMsg.push(renderableMsg); //console.log('renderableMsgrenderableMsg', renderableMsg)
+
+  if (type == msgType.VIDEO) {
+    renderableMsg.msg.token = sendableMsg.accessToken; //如果是音频则请求服务器转码
+  }
+
+
+  save();
+
+  function save() {
+    uni.setStorage({
+      key: sessionKey,
+      data: curChatMsg,
+
+      success() {
+        if (type == msgType.AUDIO || type == msgType.VIDEO) {
+          disp.fire('em.chat.audio.fileLoaded');
+        }
+
+        me.fire("newChatMsg", renderableMsg, type, curChatMsg, sessionKey);
+      }
+
+    });
+  }
+};
+
+module.exports = msgStorage;

+ 14 - 0
components/chat/msgtype.js

@@ -0,0 +1,14 @@
+module.exports = {
+  IMAGE: "img",
+  TEXT: "txt",
+  LOCATION: "location",
+  VIDEO: "video",
+  AUDIO: "audio",
+  EMOJI: "emoji",
+  FILE: "chat",
+  //
+  chatType: {
+    SINGLE_CHAT: "singleChat",
+    CHAT_ROOM: "chatRoom"
+  }
+};

+ 0 - 0
components/chat/multiemedia/index.css


+ 484 - 0
components/chat/multiemedia/index.nvue

@@ -0,0 +1,484 @@
+<template>
+	<view class="wraper">
+		<view class="infoConnecting">
+			11多人会议
+		</view>
+		<live-pusher class="live-pusher" :url="pubUrl" @netstatus="netstatusChange" :muted="false" :enable-camera="true" id="livePusher"
+		 ref="livePusher" @statechange="statechange" mode="HD" @error="error"></live-pusher>
+		</live-pusher>
+	
+			<view  
+				v-if="subUrls.length > 0"
+				v-for="item in subUrls">
+	
+				<video
+					:id="item.streamId"
+					:src="item.subUrl" 
+					object-fit="contain"
+					autoplay 
+				>
+					<view class="userName">{{item.memName}}</view>
+				</video>
+	
+			</view>
+		<!-- </scroll-view> -->
+	
+	
+		<!-- <view class="controlContent">
+			<view class="emediaContrContent">
+				<view class="controlItem" @tap="toggleCamera" style="{color: devicePositionColor}">
+					<image
+						class="icon-record"
+						:src="'../../../static/images/'+devicePositionIcon+'2x.png'" style="{width:'22px'; height: '24px'}"/>
+					切换摄像头
+				</view>
+				<view class="controlItem" @tap="toggleMuted" style="{color: micphoneColor}">
+					<image
+						class="icon-record"
+						:src="'../../../static/images/'+micphoneIcon+'2x.png'" style="{width:'22px'; height: '24px'}"/>
+					麦克风</view>
+				<view class="controlItem" @tap="togglePlay" style="{color: videoColor}">
+					<image
+						class="icon-record"
+						:src="'../../../static/images/'+videoIcon+'2x.png'" style="{width:'22px'; height: '24px'}"/>
+					视频</view>
+				<view class="controlItem" @tap="toggleBeauty" style="{color: beautyColor}">
+					<image
+						class="icon-record"
+						:src="'../../../static/images/'+beautyIcon+'.png'" style="{width:'16px'; height: '24px'}"/>
+					美颜</view>
+				<view class="controlItem" @tap="inviteMember">
+					<image
+						class="icon-record"
+						src='../../../static/images/invite_white2x.png' style="{width:'22px'; height: '24px'"/>
+					邀请</view>
+			</view>
+	
+			<view class="hangup" @tap="hangup">
+				<image
+					class="icon-record"
+					src='../../../static/images/hangup2x.png'/>
+			</view>
+		</view>
+	 -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				pubUrl: "",
+				subUrls: [],
+				showInvite: true,
+				devicePosition: "front",
+				muted: false,
+				playVideoMuted: false,
+		
+				devicePositionIcon: 'switchCamera_white',
+				devicePositionColor: '#fff',
+				micphoneIcon: 'micphone_white',
+				beautyIcon: 'beauty',
+				micphoneColor: '#fff',
+				videoIcon: 'video_white',
+				videoColor: '#fff',
+				beauty: 9,
+				beautyColor: '#fff',
+				myName: '',
+				confrId: '',
+				enableCamera: true,
+				time: '',
+				context: {}
+			}
+		},
+		props: {
+		  username: {
+		    type: Object,
+		    default: () => ({}),
+		  },
+		  action: {
+		    type: Object,
+		    default: {},
+		  },
+		  groupId:{
+		    type: String,
+		    default: '',
+		  },
+		},
+		methods: {
+			joinRoom(data){
+				let me = this;
+				console.log('joinRoom', data)
+				me.context = uni.createLivePusherContext("livePusher", me);
+				console.log('我的播放组件', me.context)
+				var context = this.context
+				if (context && context.ctx && context.ctx.attr && context.ctx.attr.url) {
+					context.stop()
+				}
+				let id = wx.WebIM.conn.getUniqueId();
+				let roomName = 'wxConfr' + id //随机的房间名,防止和别人的房间名冲突
+				let rec = wx.getStorageSync("rec") || false;
+				let recMerge = wx.getStorageSync("recMerge") || false;
+				let params = {
+					roomName,
+					password: '',
+					role: 7,
+					config: {
+						rec,
+						recMerge
+					}
+				}
+				if (data) {
+					params.roomName = data.roomName
+					params.password = data.password
+				}
+				
+				wx.emedia.mgr.joinRoom(params).then((res) => {
+					console.log('res', res)
+					let confrId = res.confrId
+					me.confrId= confrId
+					me.$emit('createConfrSuccess', {confrId: confrId, groupId: me.username.groupId, roomName: params.roomName, password: params.password})
+					
+					console.log('--------+--+----+---+--------')
+					let rtcId = wx.emedia.util.getRtcId()
+					console.log(11111111111111, confrId)
+					wx.emedia.mgr.pubStream(rtcId).then(function(res){
+						console.log('pubUrl-------------', res.data.rtmp)
+						console.log(2222222222222)
+						me.pubUrl= res.data.rtmp
+						setTimeout(() => {
+							console.log('55555555555', me)
+							console.log(me.context)
+							me.context.start()
+						}, 500)
+					}).catch(e => {
+					    console.log(4444444, e)   //404
+					    return f(false);  //即便返回了一个成功的promise,下面的finally也会执行,如果返回的是失败的promise,控制台最后一行会报错uncaught (in promise) 404
+					})
+					.finally( (e) => {
+					    console.log(100,e)  //100
+					})
+					console.log(33333333333333, me.pubUrl)
+				})
+				
+				
+			},
+			createConf(){
+				console.log('>>> createConf');
+				
+				var me = this
+				let rec = wx.getStorageSync("rec") || false;
+				let recMerge = wx.getStorageSync("recMerge") || false;
+				//参数:会议类型 密码 是否录制 是否合并
+				wx.emedia.mgr.createConference(10, '', rec, recMerge).then(function(data){
+					console.log('成功', data)
+					let ticket = data.data.ticket
+					let ticketJosn = JSON.parse(ticket)
+					let confrId = ticketJosn.confrId
+	
+					wx.emedia.mgr.joinConferenceWithTicket(confrId, ticket).then(function(res){
+						console.log('加入会议成功', res)
+					})
+					// wx.emedia.mgr.joinConference(confrId, '').then(function(res){
+					// 	console.log('加入会议成功', res)
+					// })
+					
+					me.confrId = confrId
+					me.$emit('createConfrSuccess', {confrId: confrId, groupId: me.username.groupId})
+				})
+			},
+	
+			joinConf(data){
+				console.log('加入会议 ————-------————')
+				console.log(data)
+				let me = this
+				wx.emedia.mgr.getConferenceTkt(data.confrId, data.password).then(function(res){
+					console.log('申请reqTkt成功', res.data)
+					let ticket = res.data.ticket || ''
+					let tktObj = JSON.parse(ticket)
+					wx.emedia.mgr.joinConferenceWithTicket(data.confrId, ticket).then(function(res){
+						console.log('加入会议成功', res)
+					})
+					me.confrId= tktObj.confrId
+					me.$emit('createConfrSuccess', {confrId: tktObj.confrId, groupId: me.username.groupId})
+				})
+			},
+			
+			togglePlay(){
+				let me = this
+				console.log("%c togglePlay", "color:green")
+	
+				// this.LivePusherContext.stop()
+				this.enableCamera= !me.enableCamera
+				this.pubUrl= me.pubUrl
+				this.videoIcon= this.videoIcon == 'video_white'?'video_gray': 'video_white'
+				this.videoColor= this.videoColor == '#fff'? '#aaa': '#fff'
+				this.LivePusherContext.start()
+				/* this.setData({
+					
+				}, () => {
+					
+				}) */
+			},
+	
+			toggleCamera(){
+				console.log("%c toggleCamera", "color:green")
+				let me = this
+				// me.LivePusherContext.stop()
+				me.LivePusherContext.switchCamera({
+					success: function(){
+						me.devicePosition= me.devicePosition == 'fron' ? 'back' : 'front',
+						me.devicePositionIcon= me.devicePositionIcon =='switchCamera_white'?'switchCamera_gray': 'switchCamera_white',
+						me.devicePositionColor= me.devicePositionColor == '#fff'? '#aaa':'#fff'
+					}
+				})
+
+			},
+	
+			toggleMuted(){
+				console.log("%c toggleMuted", "color:green")
+				this.muted= !this.muted
+				this.micphoneIcon= this.micphoneIcon == 'micphone_white'? 'micphone_gray': 'micphone_white'
+				this.micphoneColor= this.micphoneColor == '#fff'? '#aaa': '#fff'
+			},
+	
+			toggleBeauty(){
+				this.beauty= this.beauty == 0 ? 9 : 0
+				this.beautyColor= this.beautyColor == '#fff'? '#aaa': '#fff'
+				this.beautyIcon= this.beautyIcon == 'beauty' ? 'beauty_gray': 'beauty'
+			},
+	
+			hangup(){
+				console.log('挂断', this.confrId)
+				wx.emedia.mgr.exitConference(this.confrId)
+				this.$emit('hangup')
+				this.stopTimer()
+			},
+			inviteMember(){
+				this.$emit('inviteMember', this.groupId)
+			},
+			// statechange(e){
+			// 	console.log('>>>>>>>>>live-pusher code:', e.detail)
+			// 	if (e.detail.code === 5001) {
+			// 		// 部分安卓手机在接电话时会停止推拉流报错,状态码5001,此时退出会议。 https://developers.weixin.qq.com/community/develop/doc/0006ac6d7a4968fa675a49fef53c00
+			// 		this.hangup()
+			// 		console.error('由于有电话接入,已退出会议')
+			// 	}
+			// },
+			netstatusChange(e){
+				console.log('>>>>>>>>>>net status:', e.detail)
+			},
+	
+			getTimer(){
+				let count = 0;
+				let time = '00:00:00'
+				this.timer = setInterval(() => {
+					count++;
+					let s = showNum(count % 60);
+					let m = showNum(parseInt((count / 60)) % 60)
+					let h = showNum(parseInt(count / 60 / 60))
+					time = `${h}:${m}:${s}`
+					this.time = time
+				}, 1000)
+	
+				function showNum(num) {
+					if (num < 10) {
+						return '0' + num
+					}
+					return num
+				}
+	
+			},
+			stopTimer(){
+				clearInterval(this.timer)
+			},
+			error(err){
+				console.log('EEEEEEEEEEEEE', err)
+			},
+			statechange(state){
+				console.log("SSSSSSSSSSS", state)
+			}
+		},
+		
+		mounted() {
+			console.log('进入')
+			wx.setKeepScreenOn({
+			  keepScreenOn: true
+			})
+			console.log('进入111')
+			this.myName= wx.WebIM.conn.context.userId
+			console.log('进入222')
+			this.getTimer()
+			var me = this
+			let subUrls = []
+			let obj = {};
+			console.log('进入333')
+			this.LivePusherContext = uni.createLivePusherContext('livePusher',this)
+			console.log('this.LivePusherContext ..', this.LivePusherContext)
+			if(this.action&&this.action.action == 'join'){
+				console.log('join')
+				// 音视频sdk提供两种创建、加入会议的api 使用任意一种都可以:(1) 一种是通过会议id ticket 或者 会议id 密码加入会议 如使用下面 joinConf
+				// (2)另一种是通过房间名 密码加入 如使用下面joinRoom
+
+				//this.joinConf(this.action) // (1)
+				//this.joinRoom(this.action) // (2)
+				if (this.action.roomName) {
+					console.log('使用joinroom')
+					this.joinRoom(this.action)
+				}else{
+					console.log('使用joinConf')
+					this.joinConf(this.action)
+				}
+			}else{
+				// 创建会议同样是两种api (1)一种是使用createConf 单纯创建一个会议,需要再申请ticket 或者用密码加入会议 如使用下面的createConf
+				// (2)也可以使用joinRoom,通过房间名、密码创建房间并直接加入 不需再进行加入会议的操作
+				this.joinRoom() // (1)
+				//this.createConf() // (2)
+			}
+			wx.emedia.mgr.onMediaChanaged = function(e){
+				console.log('onMediaChanaged', e)
+			}
+			wx.emedia.mgr.onConferenceExit = function(e){
+				console.log('onConferenceExit', e)
+			}
+			wx.emedia.mgr.onMemberExited = function(reason){
+				console.log('onMemberExited', reason)
+			};
+ 
+			wx.emedia.mgr.onStreamControl = function(mem){
+				console.log('onStreamControl', mem)
+			}
+
+			wx.emedia.mgr.onStreamControl.onSoundChanage = function(a, b, c, d){
+				console.log('onSoundChanage')
+			}
+
+			wx.emedia.mgr.onReconnect = function (res, ent){
+				// 发生断网重连,相当于重新加入会议
+
+				// 清空live-player 否则在原来的后面追加,导致原来的黑屏显示
+				subUrls = []
+
+				// 重新加入恢复到初始状态,防止和控制按钮状态不符
+
+				// 重连后摄像头方向不会改变
+				me.subUrls= []
+				me.showInvite= true
+				me.devicePosition= "front"
+				me.muted= false
+				me.playVideoMuted= false
+				
+				
+				me.micphoneIcon= 'micphone_white'
+				me.micphoneColor= '#fff'
+				me.videoIcon= 'video_white'
+				me.beautyIcon= 'beauty'
+				me.videoColor= '#fff'
+				me.beauty= 9
+				me.beautyColor= '#fff'
+				me.enableCamera= true
+			}
+
+			wx.emedia.mgr.onMemberJoined = function(mem){
+				console.log("++++++++++ member", mem)
+				var jid = wx.WebIM.conn.context.jid
+				let identityName = jid.appKey + '_' + jid.name+ '@' + jid.domain
+				// let identityName = wx.WebIM.conn.context.jid.split("/")[0]
+				// 如果是自己进入会议了,开始发布流
+				if(mem.name == identityName){
+					let rtcId = wx.emedia.util.getRtcId()
+					wx.emedia.mgr.pubStream(rtcId).then(function(res){
+						me.pubUrl= res.data.rtmp
+					})
+
+					var enableCamera = me.enableCamera;
+					console.warn("begin enable camera", me.enableCamera);
+
+					//默认enableCamera为false  关闭摄像头时声音不会有延迟,否则有延迟
+					//所以最好别用autopush
+					me.enableCamera= false
+					me.pubUrl= me.url + 'record_type=audio' || 'https://domain/push_stream'
+					// enableCamera && me.enableCamera= enableCamera
+					/* me.setData({
+						enableCamera: false,
+						pubUrl: me.url + 'record_type=audio' || 'https://domain/push_stream',
+					}, () => {
+						// var enableCameraDefault = true
+						//if(!enableCameraDefault){ //治疗不推流的毛病
+							// console.log('关闭摄像头推流')
+							// setTimeout(() => {
+							// 	me.LivePusherContext.start({
+							// 		success: function () {
+										// console.log('关闭摄像头推流', enableCamera)
+							// 		}
+							// 	})
+							// }, 1500)
+						// }else{
+						// 	me.LivePusherContext.start({
+						   //  	success: function () {
+						   //  		console.log('开始推流了', enableCamera)
+						   //    		enableCamera && me.setData({enableCamera: enableCamera})
+						   //  	}
+						   //  })
+						// }
+					}) */
+				}
+			}
+			wx.emedia.mgr.onStreamAdded = function(stream){
+				console.log('%c onAddStream', 'color: green', stream)
+				let streamId = stream.id
+				// setTimeout(() => {
+					if(subUrls.length > 8){
+						return
+					}
+					wx.emedia.mgr.subStream(streamId).then(function(data){
+						console.log('%c 订阅流成功', 'color:green', data)
+						// let playContext = wx.createLivePlayerContext(streamId, me)
+						let subUrl = {
+							streamId: streamId,
+							subUrl: data.data.rtmp,
+							memName: stream.memName.split("_")[1].split("@")[0],
+							// playContext: playContext
+						}
+						subUrls.push(subUrl)
+						console.log('%c subUrls 11 ....', "background:yellow")
+						console.log(subUrls)
+	
+						me.subUrls= subUrls
+						me.showInvite= false
+					})
+				// }, 2000)
+
+			}
+			wx.emedia.mgr.onStreamRemoved = function(stream){
+				console.log('%c onRemoveStream', 'color: red', stream)
+				subUrls = subUrls.filter((item) => {
+					if(item.streamId != stream.id){
+						return item
+					}else{
+						console.log('%c ------', 'backgroukd:yellow')
+						console.log(item)
+						// item.playContext.stop({
+						// 	success: function(){
+						// 		console.log('关闭成功')
+						// 	},
+						// 	complete: function(){
+						// 		console.log('关闭成功')
+						// 	}
+						// })
+					}
+				})
+				obj[stream.id] = false
+				me.subUrls= subUrls
+				console.log('subUrls', subUrls)
+			},
+			wx.emedia.mgr.onConfrAttrsUpdated = function(e){
+				console.log('onConfrAttrsUpdated: ', e)
+			}
+			
+		},
+	
+	}
+</script>
+
+

+ 3 - 3
components/custom-tab-bar/custom-tab-bar.vue

@@ -14,7 +14,7 @@
 			<image src="/static/images/tabbar/tab3.png" v-else class="icon"></image>
 			<view class="tab_text" :class="current == 3?'tab_text2': ''">我的</view>	
 		</view>
-		<u-popup :show="show" @close="close" :round="10" mode="bottom">
+		<u-popup :show="show" @close="close" round="10" mode="bottom" :safeAreaInsetBottom="false">
 			<view class="popu">
 				<view class="hflex">
 					<block v-for="(item,index) in orderList" :key="index">
@@ -83,9 +83,9 @@
 			},
 			toTab(index) {
 				if(index == 1) {
-					$api.jump('/pages/tabbar/index/index',3)
+					$api.jump('/pages/tabbar/index/index',2)
 				} else {
-					$api.jump('/pages/tabbar/mine/mine',3)
+					$api.jump('/pages/tabbar/mine/mine',2)
 				}
 			}
 		}

+ 110 - 0
components/longPressModal/index.vue

@@ -0,0 +1,110 @@
+<template>
+  <view v-if="showPop" class="shade" @tap="hidePop">
+    <view class="pop" :style="popStyle" :class="{ show: showPop }">
+      <view
+        v-for="(item, index) in popButton"
+        :key="index"
+        @tap="pickerMenu"
+        :data-index="index"
+        >{{ item }}</view
+      >
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: "long-press-modal",
+  props: {
+    /* 窗口尺寸 */
+    winSize: {
+      type: Object,
+      default() {
+        return {
+          witdh: 375,
+          height: 603,
+        };
+      },
+    },
+    /* 显示操作弹窗 */
+    showPop: {
+      type: Boolean,
+      default: false,
+    },
+    /* 弹窗按钮列表 */
+    popButton: {
+      type: Array,
+      default() {
+        // 如下
+        // return ["标为关注", "置顶聊天", "删除该聊天"]
+        return [];
+      },
+    },
+    /* 弹窗定位样式 */
+    popStyle: {
+      type: String,
+      default: "",
+    },
+    change:{
+      type:Function,
+    }
+  },
+  methods: {
+    /* 隐藏弹窗 */
+    hidePop() {
+      this.$emit('hidePop')
+    },
+    /* 选择菜单 */
+    pickerMenu() {
+      this.$emit('change')
+      this.hidePop();
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+/* 遮罩 */
+.shade {
+  position: fixed;
+  z-index: 100;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  -webkit-touch-callout: none;
+
+  .pop {
+    position: fixed;
+    z-index: 101;
+    width: 200upx;
+    box-sizing: border-box;
+    font-size: 28upx;
+    text-align: left;
+    color: #333;
+    background-color: #fff;
+    box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
+    line-height: 80upx;
+    transition: transform 0.15s ease-in-out 0s;
+    user-select: none;
+    -webkit-touch-callout: none;
+    transform: scale(0, 0);
+
+    &.show {
+      transform: scale(1, 1);
+    }
+
+    & > view {
+      padding: 0 20upx;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      user-select: none;
+      -webkit-touch-callout: none;
+
+      &:active {
+        background-color: #f3f3f3;
+      }
+    }
+  }
+}
+</style>

+ 29 - 0
components/swipedelete/swipedelete.css

@@ -0,0 +1,29 @@
+
+.swipedelete-wrapper {
+  transition: all .4s ease;
+  position: relative;
+}
+.swipedelete-btn {
+/*  position:absolute;
+  top:0;
+  right:-180rpx;
+  text-align:center;
+  background: #f00;
+  color:#fff;
+  width:160rpx;
+  height:100%;
+  display:flex;
+  justify-content:center;
+  align-items:center;*/
+  position:absolute;
+	right: -160rpx; 
+	top:0;
+	background-color:#D0021B;
+	width:160rpx;
+	height:100%;
+	text-align:center;
+	color: #fff;
+  display:flex;
+  align-items:center;
+  justify-content:center;
+}

+ 68 - 0
components/swipedelete/swipedelete.vue

@@ -0,0 +1,68 @@
+<template>
+<view class="swipedelete-wrapper" @touchmove="touchMoveHandler" @touchstart="touchStartHandler" :style="'transform:translateX(' + translateX + 'rpx)'">
+	<slot></slot>
+  <view class="swipedelete-btn" @tap="deleteItem">删除</view>
+</view>
+</template>
+
+<script>
+let startX = 0;
+
+export default {
+  data() {
+    return {
+      translateX: 0
+    };
+  },
+
+  components: {},
+  props: {},
+  methods: {
+    deleteItem: function (e) {
+      this.translateX=0
+      this.$emit('deleteChatItem', {}, {
+        bubbles: true
+      });
+    },
+
+    /**
+     * 滑动删除事件-滑动开始
+     */
+    touchStartHandler: function (e) {
+      startX = e.touches[0].pageX;
+    },
+
+    /**
+     * 滑动删除事件-滑动
+     */
+    touchMoveHandler: function (e) {
+      let pageX = e.touches[0].pageX;
+      let moveX = pageX - startX;
+
+      if (Math.abs(moveX) < 80) {
+        return;
+      } // e.target.style.WebkitTransform = `translateX(${moveX}px)`
+
+
+      if (moveX > 0) {
+        // 右滑 隐藏删除
+        if (Math.abs(this.translateX) == 0) {
+          return;
+        } else {
+          this.translateX= 0
+        }
+      } else {
+        // 左滑 显示删除
+        if (Math.abs(this.translateX) >= 160) {
+          return;
+        } else {
+          this.translateX= -160
+        }
+      }
+    }
+  }
+};
+</script>
+<style>
+@import "./swipedelete.css";
+</style>

+ 90 - 7
manifest.json

@@ -1,9 +1,9 @@
 {
-    "name" : "cbz-sj",
+    "name" : "船百知商家端",
     "appid" : "__UNI__82416DD",
     "description" : "",
-    "versionName" : "1.0.0",
-    "versionCode" : "100",
+    "versionName" : "1.0.1",
+    "versionCode" : 100030900,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {
@@ -17,7 +17,12 @@
             "delay" : 0
         },
         /* 模块配置 */
-        "modules" : {},
+        "modules" : {
+            "VideoPlayer" : {},
+            "Camera" : {},
+            "Barcode" : {},
+            "Maps" : {}
+        },
         /* 应用发布信息 */
         "distribute" : {
             /* android打包配置 */
@@ -25,23 +30,44 @@
                 "permissions" : [
                     "<uses-feature android:name=\"android.hardware.camera\"/>",
                     "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                     "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                     "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                     "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                     "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                 ]
             },
             /* ios打包配置 */
-            "ios" : {},
+            "ios" : {
+                "dSYMs" : false,
+                "idfa" : false,
+                "privacyDescription" : {
+                    "NSPhotoLibraryUsageDescription" : "注册时选择图片作为头像",
+                    "NSCameraUsageDescription" : "拍照反馈问题"
+                },
+                "urlschemewhitelist" : [ "baidumap", "iosamap", "qqmap" ]
+            },
             /* SDK配置 */
             "sdkConfigs" : {
-                "maps" : {},
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "1a8fc823e599e46cd1a3451b8eed5fc1",
+                        "appkey_android" : ""
+                    }
+                },
                 "payment" : {
                     "alipay" : {
                         "__platform__" : [ "ios" ]
@@ -51,6 +77,58 @@
                         "appid" : "",
                         "UniversalLinks" : ""
                     }
+                },
+                "push" : {
+                    "unipush" : {}
+                },
+                "ad" : {}
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            }
+        },
+        "nativePlugins" : {
+            "YangChuan-YCiOSFileSelect" : {
+                "__plugin_info__" : {
+                    "name" : "ios-uniapp 文件选取word,pdf,xls等文件",
+                    "description" : "uniapp iOS文件选取 iOS选取text,pdf,word,doc,xls,ppt",
+                    "platforms" : "iOS",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=1311",
+                    "android_package_name" : "",
+                    "ios_bundle_id" : "com.ShipKnown.Business",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "1311",
+                    "parameters" : {}
                 }
             }
         }
@@ -77,5 +155,10 @@
     "uniStatistics" : {
         "enable" : false
     },
-    "vueVersion" : "2"
+    "vueVersion" : "2",
+    "h5" : {
+        "sdkConfigs" : {
+            "maps" : {}
+        }
+    }
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk3.6.3.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk4.0.1.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk4.0.3.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk4.0.4.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk4.0.5.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
newSDK/uni_sdk4.0.7.js


+ 119 - 84
node_modules/uview-ui/package.json

@@ -1,87 +1,122 @@
 {
-	"id": "uview-ui",
-	"name": "uview-ui",
-	"displayName": "uView2.0重磅发布,利剑出鞘,一统江湖",
-	"version": "2.0.31",
-	"description": "uView UI已完美兼容nvue,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
-	"keywords": [
-        "uview",
-        "uview",
-        "ui",
-        "ui",
-        "uni-app",
-        "uni-app",
-        "ui"
+  "_args": [
+    [
+      "uview-ui@2.0.31",
+      "D:\\代码\\cbz\\cbz-sj"
+    ]
+  ],
+  "_from": "uview-ui@2.0.31",
+  "_id": "uview-ui@2.0.31",
+  "_inBundle": false,
+  "_integrity": "sha512-I/0fGuvtiKHH/mBb864SGYk+SJ7WaF32tsBgYgeBOsxlUp+Th+Ac2tgz2cTvsQJl6eZYWsKZ3ixiSXCAcxZ8Sw==",
+  "_location": "/uview-ui",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "uview-ui@2.0.31",
+    "name": "uview-ui",
+    "escapedName": "uview-ui",
+    "rawSpec": "2.0.31",
+    "saveSpec": null,
+    "fetchSpec": "2.0.31"
+  },
+  "_requiredBy": [
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.31.tgz",
+  "_spec": "2.0.31",
+  "_where": "D:\\代码\\cbz\\cbz-sj",
+  "bugs": {
+    "url": "https://github.com/umicro/uView2.0/issues"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
     ],
-	"repository": "https://github.com/umicro/uView2.0",
-	"engines": {
-		"HBuilderX": "^3.1.0"
-	},
-	"dcloudext": {
-		"category": [
-			"前端组件",
-			"通用组件"
-		],
-		"sale": {
-			"regular": {
-				"price": "0.00"
-			},
-			"sourcecode": {
-				"price": "0.00"
-			}
-		},
-		"contact": {
-			"qq": "1416956117"
-		},
-		"declaration": {
-			"ads": "无",
-			"data": "无",
-			"permissions": "无"
-		},
-		"npmurl": "https://www.npmjs.com/package/uview-ui"
-	},
-	"uni_modules": {
-		"dependencies": [],
-		"encrypt": [],
-		"platforms": {
-			"cloud": {
-				"tcb": "y",
-				"aliyun": "y"
-			},
-			"client": {
-				"Vue": {
-					"vue2": "y",
-					"vue3": "n"
-				},
-				"App": {
-					"app-vue": "y",
-					"app-nvue": "y"
-				},
-				"H5-mobile": {
-					"Safari": "y",
-					"Android Browser": "y",
-					"微信浏览器(Android)": "y",
-					"QQ浏览器(Android)": "y"
-				},
-				"H5-pc": {
-					"Chrome": "y",
-					"IE": "y",
-					"Edge": "y",
-					"Firefox": "y",
-					"Safari": "y"
-				},
-				"小程序": {
-					"微信": "y",
-					"阿里": "y",
-					"百度": "y",
-					"字节跳动": "y",
-					"QQ": "y"
-				},
-				"快应用": {
-					"华为": "y",
-					"联盟": "y"
-				}
-			}
-		}
-	}
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "1416956117"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/uview-ui"
+  },
+  "description": "uView UI已完美兼容nvue,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
+  "displayName": "uView2.0重磅发布,利剑出鞘,一统江湖",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "homepage": "https://github.com/umicro/uView2.0#readme",
+  "id": "uview-ui",
+  "keywords": [
+    "uview",
+    "uview",
+    "ui",
+    "ui",
+    "uni-app",
+    "uni-app",
+    "ui"
+  ],
+  "name": "uview-ui",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/umicro/uView2.0.git"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "n"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        }
+      }
+    }
+  },
+  "version": "2.0.31"
 }

+ 6 - 17
package-lock.json

@@ -1,23 +1,12 @@
 {
-  "name": "cbz-sj",
-  "lockfileVersion": 2,
   "requires": true,
-  "packages": {
-    "": {
-      "dependencies": {
-        "uview-ui": "^2.0.31"
-      }
-    },
-    "node_modules/uview-ui": {
-      "version": "2.0.31",
-      "resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.31.tgz",
-      "integrity": "sha512-I/0fGuvtiKHH/mBb864SGYk+SJ7WaF32tsBgYgeBOsxlUp+Th+Ac2tgz2cTvsQJl6eZYWsKZ3ixiSXCAcxZ8Sw==",
-      "engines": {
-        "HBuilderX": "^3.1.0"
-      }
-    }
-  },
+  "lockfileVersion": 1,
   "dependencies": {
+    "@amap/amap-jsapi-loader": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
+      "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
+    },
     "uview-ui": {
       "version": "2.0.31",
       "resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.31.tgz",

+ 1 - 0
package.json

@@ -1,5 +1,6 @@
 {
   "dependencies": {
+    "@amap/amap-jsapi-loader": "^1.0.1",
     "uview-ui": "^2.0.31"
   }
 }

+ 48 - 15
pages.json

@@ -7,7 +7,8 @@
 			"path": "pages/tabbar/index/index",
 			"style": {
 				"navigationBarTitleText": "商城",
-				"navigationStyle": "custom"
+				"navigationStyle": "custom",
+				"enablePullDownRefresh": true
 			}
 		},
 		{
@@ -28,6 +29,16 @@
             
         }
 		,{
+		    "path" : "pages/login/xieyi",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": "",
+				"navigationBarBackgroundColor": "#fff"
+				// "navigationStyle": "custom"
+		    }
+		    
+		}
+		,{
 		    "path" : "pages/login/codeLogin/codeLogin",
 		    "style" :                                                                                    
 		    {
@@ -137,9 +148,10 @@
 		    "style" :                                                                                    
 		    {
 		        "navigationBarTitleText": "",
-		        "enablePullDownRefresh": false,
+		        // "enablePullDownRefresh": false,
 				"navigationBarBackgroundColor": "#fff",
-				"navigationStyle": "custom"
+				"navigationStyle": "custom",
+				"enablePullDownRefresh": true
 		    }
 		},
 		{
@@ -165,7 +177,7 @@
 		    "style" :                                                                                    
 		    {
 		        "navigationBarTitleText": "退款/售后",
-		        "enablePullDownRefresh": false,
+		        "enablePullDownRefresh": true,
 				"navigationBarBackgroundColor": "#fff"
 		    }
 		},
@@ -193,6 +205,7 @@
 		    {
 		        "navigationBarTitleText": "订单详情",
 				"navigationBarBackgroundColor": "#fff",
+				"navigationBarTextStyle": "white",
 				"navigationStyle": "custom"
 		    }
 		},
@@ -244,6 +257,16 @@
 		    
 		},
 		{
+		    "path" : "pages/mine/service/setting/about",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": "关于我们",
+				// "navigationStyle": "custom" 
+				"navigationBarBackgroundColor": "#fff"
+		    }
+		    
+		},
+		{
 		    "path" : "pages/mine/service/setting/account_info",
 		    "style" :                                                                                    
 		    {
@@ -392,19 +415,29 @@
 				"navigationBarBackgroundColor": "#fff"
 		    }
 		    
+		},
+		{
+		    "path" : "pages/chatroom/chatroom",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": "",
+				// "navigationStyle": "custom" 
+				"navigationBarBackgroundColor": "#fff"
+		    }
+		    
 		}
     ],
-	"tabBar": {
-		"custom": true,
-		"list": [
-			{
-				"pagePath": "pages/tabbar/index/index"
-			},
-			{
-				"pagePath": "pages/tabbar/mine/mine"
-			}
-		]
-	},
+	// "tabBar": {
+	// 	"custom": true,
+	// 	"list": [
+	// 		{
+	// 			"pagePath": "pages/tabbar/index/index"
+	// 		},
+	// 		{
+	// 			"pagePath": "pages/tabbar/mine/mine"
+	// 		}
+	// 	]
+	// },
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
 		"navigationBarTitleText": "uni-app",

+ 4 - 0
pages/chatroom/chatroom.css

@@ -0,0 +1,4 @@
+page{
+	background-color: #FAFAFA;
+	height: 100%;
+}

+ 99 - 0
pages/chatroom/chatroom.vue

@@ -0,0 +1,99 @@
+<template>
+<chat id="chat" :username="username" ref="chat" chatType="singleChat" @onClickInviteMsg="onClickMsg"></chat>
+</template>
+
+<script>
+let disp = require("@/utils/broadcast");
+import chat from "@/components/chat/chat.vue";
+
+export default {
+  data() {
+    return {
+      username: {
+        your: ""
+      }
+    };
+  },
+
+  components: {
+    chat
+  },
+  props: {},
+  // options = 系统传入的 url 参数
+  onLoad(options) {
+	  // console.log(JSON.parse(options.username));
+    let username = JSON.parse(options.username);
+    /* this.setData({
+      username: username
+    }); */
+	this.username = username
+	// 生成的支付宝小程序在onLoad里获取不到,这里放到全局变量下
+	uni.username = username;
+	let title = ''
+	uni.WebIM.conn.fetchUserInfoById(username.your, 'nickname').then((res) => {
+	    title = res.data[username.your].nickname
+		uni.setNavigationBarTitle({
+		  title: title
+		});
+	})
+	console.log(title);
+
+	this.getList()
+	this.getUser()
+  },
+
+  onUnload() {
+    disp.fire("em.chatroom.leave");
+  },
+
+  onPullDownRefresh: function () {
+    uni.showNavigationBarLoading();
+    this.$refs.chat.getMore();
+    // 停止下拉动作
+    uni.hideNavigationBarLoading();
+    uni.stopPullDownRefresh();
+  },
+  methods: {
+	  getList() {
+		  var that = this
+		  let options = {
+		    // 对方的用户 ID 或者群组 ID 或聊天室 ID。
+		    targetId: that.username.your,
+		    // 每页期望获取的消息条数。取值范围为 [1,50],默认值为 20。
+		    pageSize: 20,
+		    // 查询的起始消息 ID。若该参数设置为 `-1`、`null` 或空字符串,从最新消息开始。
+		    cursor: -1,
+		    // 会话类型:(默认) `singleChat`:单聊;`groupChat`:群聊。
+		    chatType: "singleChat",
+		    // 消息搜索方向:(默认)`up`:按服务器收到消息的时间的逆序获取;`down`:按服务器收到消息的时间的正序获取。
+		    searchDirection: "up",
+		  };
+		  uni.WebIM.conn
+		    .getHistoryMessages(options)
+		    .then((res) => {
+		      
+		      // console.log(res);
+		    })
+		    .catch((e) => {
+		      // 获取失败。
+		    });
+	  },
+	  getUser() {
+		  let myUsername = uni.getStorageSync('myUsername')
+		  let users = [this.username.your, myUsername]
+		  uni.WebIM.conn.fetchUserInfoById(users).then((res) => {
+		      // console.log('用户信息',res)
+		  })
+	  },
+	  onClickMsg(msg){
+		msg.action = 'join'
+		// uni.navigateTo({
+		// 	url: "../emedia/index?srcData="+JSON.stringify(msg)
+		// });
+	  }
+  }
+};
+</script>
+<style>
+@import "./chatroom.css";
+</style>

+ 825 - 610
pages/good/add.vue

@@ -1,611 +1,826 @@
-<template>
-	<view class="content">
-		<view class="box">
-			<view class="title requ">图片和标题</view>
-			<view class="upload">
-				<u-upload :fileList="fileList1" :accept='accept' @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="166rpx" height="166rpx">
-					<image src="/static/images/common/upload_img.png" class="upload_img1"></image>
-				</u-upload>
-			</view>
-			<u-textarea v-model="name" border="none" placeholder="标题示例:【现货】夏季新款 韩版碎花雪纺连衣裙" count maxlength="100"></u-textarea>
-		</view>
-		<view class="box">
-			<view class="box_item hflex acenter jbetween">
-				<view class="box_left requ">规格</view>
-				<view class="hflex acenter" @click="addSpec">
-					<view class="box_right text_blue" v-if="items == ''">+新增规格</view>
-					<view class="box_right text_blue" v-else>共{{items.length}}个规格</view>
-					<u-icon name="arrow-right" size="12" color="#617BFE"></u-icon>
-				</view>
-			</view>
-			<view class="box_item hflex acenter jbetween">
-				<view class="box_left requ">价格和库存</view>
-				<view class="hflex acenter">
-					<view class="box_right" v-if="items == ''">未设置</view>
-					<view class="box_right" v-else>已设置</view>
-					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
-				</view>
-			</view>
-			<view class="box_item hflex acenter jbetween">
-				<view class="box_left requ">类目</view>
-				<view class="hflex acenter" @click="open">
-					<view class="box_right" v-if="cateids == ''">请选择商品类目</view>
-					<view class="box_right" v-else>{{cate}}</view>
-					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
-				</view>
-			</view>
-		</view>
-		<view class="box">
-			<view class="box_item hflex acenter jbetween">
-				<view class="box_left">物流配送</view>
-				<view class="hflex acenter">
-					<view class="box_right">快递发货</view>
-					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
-				</view>
-			</view>
-		</view>
-		<view class="box">
-			<view class="title">商品详情</view>
-			<u-textarea v-model="content" border="none" placeholder="描述一下商品特色吧~" ></u-textarea>
-			<view class="title">图片/视频</view>
-			<view class="upload">
-				<u-upload :fileList="fileList2" :accept='accept' @afterRead="afterRead" @delete="deletePic" name="2" multiple :maxCount="9" width="200rpx" height="200rpx">
-					<image src="/static/images/common/upload_img.png" class="upload_img2"></image>
-				</u-upload>
-			</view>
-		</view>
-		<view class="box" style="margin-bottom: 186rpx;">
-			<view class="box_item hflex acenter jbetween">
-				<view class="box_left">商品状态</view>
-				<view class="hflex acenter">
-					<block v-for="(item,index) in radioList" :key="index">
-						<view class="hflex acenter" style="padding-left: 32rpx;" @click="changeRadio(index)">
-							<image src="/static/images/common/select1.png" style="width: 36rpx;height: 36rpx;" v-if="active !== index"></image>
-							<image src="/static/images/common/select2.png" style="width: 36rpx;height: 36rpx;" v-else></image>
-							<view class="radio_text">{{item.name}}</view>
-						</view>
-					</block>
-				</view>
-			</view>
-		</view>
-		<view class="bottom">
-			<view class="btn hflex acenter jcenter" @click="create" v-if="id == ''">创建商品</view>
-			<view class="btn_group hflex acenter jbetween" v-else>
-				<view class="btn1 hflex acenter jcenter" @click="dele">删除</view>
-				<view class="btn2 hflex acenter jcenter" @click="save">保存</view>
-			</view>
-		</view>
-		<u-popup :show="cate_show" :round="10" mode="bottom" @close="close">
-			<view class="popu">
-				<view class="popu_top hflex acenter jbetween">
-					<view></view>
-					<view class="popu_title">选择类目</view>
-					<image src="/static/images/common/close_icon.png" style="width: 28rpx;height: 28rpx;" @click="close"></image>
-				</view>
-				<view class="center">
-					<view class="menuList hflex acenter jbetween">
-						<scroll-view scroll-y="true" class="menu_left">
-							<view class="vflex">
-								<block v-for="(item,index) in cateList" :key="index">
-									<view class="left_item hflex acenter jcenter" :class="index == left_active? 'left_active':''">{{item.name}}</view>
-								</block>
-							</view>
-						</scroll-view>
-						<scroll-view scroll-y="true" class="menu_right">
-							<view class="vflex">
-								<block v-for="(item,index) in cateList[left_active].sub" :key="index">
-									<view class="right_item hflex acenter jbetween" @click="selectItem(index)">
-										<view class="item_text hflex acenter jcenter" :class="index == right_active? 'right_active':''">{{item.name}}</view>
-										<image src="/static/images/common/check.png" style="width: 36rpx;height: 36rpx;" v-if="index == right_active"></image>
-									</view>
-								</block>
-							</view>
-						</scroll-view>
-					</view>
-				</view>
-				<view class="popu_bottom">
-					<view class="btn hflex acenter jcenter"@click="sure">确定</view>
-					
-				</view>
-			</view>
-		</u-popup>
-	</view>
-</template>
-
-<script>
-	import $api, { info } from '@/static/js/api.js'
-	var that = ''
-	export default {
-		data() {
-			return {
-				fileList1: [],
-				fileList2: [],
-				cateList: [],
-				left_active: 0,
-				right_active: -1,
-				name: '',
-				accept: ['image','video'],
-				content: '',
-				radioList: [
-					{
-						name: '上架售卖'
-					},
-					{
-						name: '暂不上架'
-					}
-				],
-				active: 0,
-				items: '',
-				cover: '',
-				slider: '',
-				content: '',
-				status: 1,
-				cateids: '',
-				cate: '',
-				spec: '',
-				stock_total: 0,
-				price_selling: '',
-				cate_show: false,
-				id: '',
-				data: [],
-				spect: '',
-			}
-		},
-		onLoad(options) {
-			that = this
-			if(options.id) {
-				that.id = options.id
-				that.getData()
-			}
-			if(options.data) {
-				that.data = JSON.parse(options.data)
-				that.spect = options.spec
-				that.items = that.data
-				that.spec = that.spect
-				for(var i=0;i<that.items.length;i++) {
-					that.stock_total += Number(that.items[i].stock_total)
-				}
-				that.price_selling = that.items[0].price_selling
-			}
-			
-			that.getCate()
-		},
-		methods: {
-			getData() {
-				$api.req({
-					url: '/data/api.business.Goods/goods_details',
-					method: 'POST',
-					data: {
-						goods_id: that.id
-					}
-				}, function(res) {
-					if(res.code == 1) {
-						console.log(res);
-						that.cover = res.data.cover
-						var imgList = res.data.cover.split('|')
-						for(var i=0;i<imgList.length;i++) {
-							var data = {
-								url: imgList[i]
-							}
-							that.fileList1.push(data)
-						}
-						that.name = res.data.name
-						that.items = res.data.item
-						that.cateids = res.data.cateids
-						for(var i=0;i<that.cateList.length;i++) {
-							for(var j=0;j<that.cateList[i].sub.length;j++) {
-								if(that.cateList[i].sub[j].id == that.cateids) {
-									that.cate = that.cateList[i].name + '-' + that.cateList[i].sub[j].name
-								}
-							}
-						}
-						that.content = res.data.content
-						that.slider = res.data.slider
-						imgList = res.data.slider.split('|')
-						for(var i=0;i<imgList.length;i++) {
-							var data = {
-								url: imgList[i]
-							}
-							that.fileList2.push(data)
-						}
-						that.status = res.data.status
-						that.stock_total = res.data.stock_total
-						that.price_selling = res.data.price_selling
-						if(that.status == 1) {
-							that.active = 0
-						} else {
-							that.active = 1
-						}
-						if(that.data.length!==0) {
-							that.items = that.data
-							that.spec = that.spect
-							for(var i=0;i<that.items.length;i++) {
-								that.stock_total += Number(that.items[i].stock_total)
-							}
-							that.price_selling = that.items[0].price_selling
-						}
					}
-				})
-			},
-			getCate() {
-				$api.req({
-					url: '/data/api.business.Goods/getCate'
-				}, function(res) {
-					if(res.code == 1) {
-						that.cateList = res.data
-					}
-				})
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						// status: 'uploading',
-						// message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						// status: 'success',
-						type: result.type,
-						url: result.url
-					}))
-					fileListLen++
-				}
-				console.log(that.fileList1);
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						header: {
-							'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
-							'api-name': 'iosapp'
-						},
-						formData: {
-							user: 'test'
-						},
-						success: (res) => {
-							setTimeout(() => {
-								var data = JSON.parse(res.data)
-								console.log('data:',data);
-								var type = data.data.key.split('.')
-								if(type[1] == 'mp4') {
-									that.$set(data.data,'type','video')
-								} else {
-									that.$set(data.data,'type','image')
-								}
-								resolve(data.data)
-							}, 1000)
-						}
-					});
-				})
-			},
-			changeRadio(index) {
-				that.active = index
-				if(that.active == 0) {
-					that.status = 1
-				} else {
-					that.status = 0
-				}
-			},
-			addSpec() {
-				if(that.id !== "") {
-					$api.jump('/pages/good/spec?items=' + JSON.stringify(that.items)+'&good_id=' + that.id)
-				} else {
-					$api.jump('/pages/good/spec?items=' + JSON.stringify(that.items))
-				}
-			},
-			open() {
-				that.cate_show = true
-			},
-			selectItem(index) {
-				that.right_active = index
-			},
-			sure() {
-				that.cateids = that.cateList[that.left_active].sub[that.right_active].id
-				that.cate = that.cateList[that.left_active].name + '-' + that.cateList[that.left_active].sub[that.right_active].name
-				that.close()
-			},
-			close() {
-				that.cate_show = false
-			},
-			create() {
-				console.log('总库存',that.stock_total);
-				for(var i=0;i<that.fileList1.length;i++) {
-					that.cover += that.fileList1[i].url + '|'
-				}
-				for(var i=0;i<that.fileList2.length;i++) {
-					that.slider += that.fileList2[i].url + '|'
-				}
-				that.cover = that.cover.substr(0,that.cover.length - 1)
-				that.slider = that.slider.substr(0,that.slider.length - 1)
-				$api.req({
-					url: '/data/api.business.Goods/goods_add',
-					method: 'POST',
-					data: {
-						name: that.name,
-						cateids: that.cateids,
-						cover: that.cover,
-						slider: that.slider,
-						content: that.content,
-						stock_total: that.stock_total,
-						price_selling: that.price_selling,
-						status: that.status,
-						spec: that.spec,
-						items: JSON.stringify(that.items)
-					}
-				}, function(res) {
-					if(res.code == 1) {
-						$api,info(res.info)
-						$api.jump('/pages/tabbar/index/index',3)
-					}
-				})
-			},
-			save() {
-				that.cover = ""
-				that.slider = ""
-				console.log('总库存',that.stock_total);
-				for(var i=0;i<that.fileList1.length;i++) {
-					that.cover += that.fileList1[i].url + '|'
-				}
-				for(var i=0;i<that.fileList2.length;i++) {
-					that.slider += that.fileList2[i].url + '|'
-				}
-				that.cover = that.cover.substr(0,that.cover.length - 1)
-				that.slider = that.slider.substr(0,that.slider.length - 1)
-				$api.req({
-					url: '/data/api.business.Goods/goods_edit',
-					method: 'POST',
-					data: {
-						goods_id: that.id,
-						name: that.name,
-						cateids: that.cateids,
-						cover: that.cover,
-						slider: that.slider,
-						content: that.content,
-						stock_total: that.stock_total,
-						price_selling: that.price_selling,
-						status: that.status,
-						items: JSON.stringify(that.items)
-					}
-				}, function(res) {
-					if(res.code == 1) {
-						$api,info(res.info)
-						$api.jump('/pages/tabbar/index/index',3)
-					}
-				})
-			},
-			dele() {
-				$api.req({
-					url: '/data/api.business.Goods/del_goods',
-					method: 'POST',
-					data: {
-						goods_id: that.id
-					}
-				}, function(res) {
-					if(res.code == 1) {
-						$api.info(res.info) 
-						$api.jump('/pages/tabbar/index/index',3)
-					}
-				})
-			}
-		},
-	}
-</script>
-
-<style lang="scss" scoped>
-	.content::v-deep {
-		background: #F5F5F5;
-		.box {
-			width: 100%;
-			background: #FFFFFF;
-			box-sizing: border-box;
-			padding: 0 30rpx;
-			margin-top: 20rpx;
-			.title {
-				font-size: 30rpx;
-				font-weight: 400;
-				color: #222222;
-				line-height: 42rpx;
-				margin: 28rpx 0 20rpx;
-			}
-			.requ {
-				position: relative;
-			}
-			.requ:before {
-				content: '*';
-				top: 0;
-				left: -15rpx;
-				position: absolute;
-				font-size: 30rpx;
-				font-weight: 400;
-				color: #FF3636;
-				
-			}
-			.upload {
-				margin-bottom: 20px;
-				.upload_img1 {
-					width: 166rpx;
-					height: 166rpx;
-				}
-				
-				.upload_img2 {
-					width: 200rpx;
-					height: 200rpx;
-				}
-				
-			}
-			.u-textarea {
-				padding: 0 !important;
-			}
-			.box_item {
-				padding: 28rpx 0;
-				border-bottom: 1rpx solid #F5F5F5;
-				.box_left {
-					font-size: 30rpx;
-					font-weight: 400;
-					color: #222222;
-					line-height: 42rpx;
-				}
-				.box_right {
-					font-size: 30rpx;
-					font-weight: 400;
-					color: #ACACAC;
-					line-height: 42rpx;
-					padding-right: 10rpx;
-				}
-				.text_blue {
-					color: #617BFE;
-				}
-				.radio_text {
-					font-size: 30rpx;
-					font-weight: 400;
-					color: #222222;
-					line-height: 42rpx;
-					padding-left: 12rpx;
-				}
-			}
-		}
-		.bottom {
-			width: 100%;
-			height: 166rpx;
-			background: #FFFFFF;
-			position: fixed;
-			bottom: 0;
-			z-index: 99;
-			.btn {
-				width: 690rpx;
-				height: 84rpx;
-				background: #5471FF;
-				border-radius: 46rpx;
-				margin: 8rpx auto 0;
-				font-size: 36rpx;
-				font-weight: 500;
-				color: #FFFFFF;
-				line-height: 50rpx;
-			}
-			.btn_group {
-				width: 100%;
-				box-sizing: border-box;
-				padding: 8rpx 30rpx 0;
-				.btn1 {
-					width: 330rpx;
-					height: 84rpx;
-					border-radius: 46rpx;
-					border: 1rpx solid #5471FF;
-					font-size: 32rpx;
-					font-weight: 500;
-					color: #5471FF;
-					line-height: 50rpx;
-				}
-				.btn2 {
-					width: 330rpx;
-					height: 84rpx;
-					background: #5471FF;
-					border-radius: 46rpx;
-					font-size: 32rpx;
-					font-weight: 500;
-					color: #FFFFFF;
-					line-height: 50rpx;
-				}
-			}
-		}
-		.popu {
-			background: #FFFFFF;
-			border-radius: 40rpx 40rpx 0px 0px;
-			// border: 2rpx solid #979797;
-			.popu_top {
-				width: 690rpx;
-				margin: 0 auto;
-				padding: 44rpx 0 28rpx;
-				border-bottom: 1px solid #F7F7F7;
-				.popu_title {
-					font-size: 36rpx;
-					font-weight: 500;
-					color: #222222;
-					line-height: 50rpx;
-				}
-			}
-			.center {
-				margin: 0 0 188rpx;
-				.menuList {
-					width: 100%;
-					.menu_left {
-						width: 180rpx;
-						height: 850rpx;
-						background: #F5F5F5;
-						border-radius: 0px 28rpx 0px 0px;
-						.left_item {
-							font-size: 28rpx;
-							font-weight: 400;
-							color: #222222;
-							line-height: 40rpx;
-							padding: 30rpx 0;
-						}
-						.left_active {
-							color: #506DFF;
-							background: #fff;
-						}
-					}
-					.menu_right {
-						width: 570rpx;
-						height: 850rpx;
-						background: #FFFFFF;
-						.right_item {
-							padding: 30rpx 30rpx 30rpx 64rpx;
-							.item_text {
-								font-size: 30rpx;
-								font-weight: 400;
-								color: #393939;
-								line-height: 42rpx;
-							}
-							.right_active {
-								color: #5B77FF;
-							}
-						}
-						.tabs_text {
-							width: 80rpx;
-							height: 56rpx;
-							background: #FFFFFF;
-							font-size: 20rpx;
-							font-weight: 400;
-							color: #393939;
-							line-height: 28rpx;
-						}
-					}
-				}
-			}
-			.popu_bottom {
-				width: 100%;
-				height: 166rpx;
-				background: #FFFFFF;
-				position: fixed;
-				bottom: 0;
-				z-index: 99;
-				.btn {
-					width: 690rpx;
-					height: 84rpx;
-					background: #5471FF;
-					border-radius: 46rpx;
-					margin: 8rpx auto 0;
-					font-size: 36rpx;
-					font-weight: 500;
-					color: #FFFFFF;
-					line-height: 50rpx;
-				}
-				
-			}
-		}
-	}
+<template>
+	<view class="content">
+		<view class="box">
+			<view class="title requ">图片和标题</view>
+			<view class="upload">
+				<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="1" width="166rpx" height="166rpx">
+				</u-upload>
+			</view>
+			<u-textarea v-model="name" border="none" confirmType="done" placeholder="标题示例:【现货】夏季新款 韩版碎花雪纺连衣裙" count maxlength="100"></u-textarea>
+		</view>
+		<view class="box">
+			<view class="box_item hflex acenter jbetween">
+				<view class="box_left requ">规格</view>
+				<view class="hflex acenter" @click="addSpec">
+					<view class="box_right text_blue" v-if="items == ''">+新增规格</view>
+					<view class="box_right text_blue" v-else>共{{items.length}}个规格</view>
+					<u-icon name="arrow-right" size="12" color="#617BFE"></u-icon>
+				</view>
+			</view>
+			<view class="box_item hflex acenter jbetween">
+				<view class="box_left requ">价格和库存</view>
+				<view class="hflex acenter" @click="toSetting">
+					<view class="box_right" v-if="items == ''">未设置</view>
+					<view class="box_right" v-else>已设置</view>
+					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
+				</view>
+			</view>
+			<view class="box_item hflex acenter jbetween" @click="open">
+				<view class="box_left requ">类目</view>
+				<view class="hflex acenter">
+					<view class="box_right" v-if="cateids == ''">请选择商品类目</view>
+					<view class="box_right" style="max-width: 500rpx;" v-else>{{cate}}</view>
+					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
+				</view>
+			</view>
+		</view>
+		<view class="box">
+			<view class="box_item hflex acenter jbetween">
+				<view class="box_left">物流配送</view>
+				<view class="hflex acenter">
+					<view class="box_right">快递发货</view>
+					<u-icon name="arrow-right" size="12" color="#ACACAC"></u-icon>
+				</view>
+			</view>
+		</view>
+		<view class="box">
+			<view class="title">商品详情</view>
+			<u-textarea v-model="content" border="none" confirmType="done" placeholder="描述一下商品特色吧~" ></u-textarea>
+			<view class="title">图片/视频</view>
+			<view class="upload hflex acenter fwrap">
+				<block v-for="(item,index) in fileList2" :key="index">
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<!-- <image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+					<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video> -->
+				</block>
+				<!-- <u-upload :fileList="fileList2" @afterRead="afterRead" @delete="deletePic" name="2" multiple :maxCount="9" width="200rpx" height="200rpx">
+					<image src="/static/images/common/upload_img.png" class="upload_img2"></image>
+				</u-upload> -->
+				<image src="/static/images/common/upload_img.png" class="img"  @click="choose"></image>
+			</view>
+		</view>
+		<view class="box" style="margin-bottom: 186rpx;">
+			<view class="box_item hflex acenter jbetween">
+				<view class="box_left">商品状态</view>
+				<view class="hflex acenter">
+					<block v-for="(item,index) in radioList" :key="index">
+						<view class="hflex acenter" style="padding-left: 32rpx;" @click="changeRadio(index)">
+							<image src="/static/images/common/select1.png" style="width: 36rpx;height: 36rpx;" v-if="active !== index"></image>
+							<image src="/static/images/common/select2.png" style="width: 36rpx;height: 36rpx;" v-else></image>
+							<view class="radio_text">{{item.name}}</view>
+						</view>
+					</block>
+				</view>
+			</view>
+		</view>
+		<view class="bottom">
+			<view class="btn hflex acenter jcenter" @click="create" v-if="id == ''">创建商品</view>
+			<view class="btn_group hflex acenter jbetween" v-else>
+				<view class="btn1 hflex acenter jcenter" @click="dele">删除</view>
+				<view class="btn2 hflex acenter jcenter" @click="save">保存</view>
+			</view>
+		</view>
+		<u-popup :show="cate_show" round="10" mode="bottom" @close="close" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_top hflex acenter jbetween">
+					<view></view>
+					<view class="popu_title">选择类目</view>
+					<image src="/static/images/common/close_icon.png" style="width: 28rpx;height: 28rpx;" @click="close"></image>
+				</view>
+				<view class="center">
+					<view class="menuList hflex acenter jbetween">
+						<scroll-view scroll-y="true" class="menu_left">
+							<view class="vflex">
+								<block v-for="(item,index) in cateList" :key="index">
+									<view class="left_item text_hide hflex acenter" :class="index == left_active? 'left_active':''" @click="clickTab1(index)">
+										<text class="text_hide" style="width: 100%;text-align: center;">{{item.name}}</text>
+									</view>
+								</block>
+							</view>
+						</scroll-view>
+						<scroll-view scroll-y="true" class="menu_right">
+							<view class="vflex" v-if="cateList[left_active]">
+								<block v-for="(item,index) in cateList[left_active].sub" :key="index">
+									<view class="right_item hflex acenter jbetween" @click="selectItem(index)">
+										<view class="item_text hflex acenter jcenter" :class="index == right_active? 'right_active':''">{{item.name}}</view>
+										<image src="/static/images/common/check.png" style="width: 36rpx;height: 36rpx;" v-if="index == right_active"></image>
+									</view>
+								</block>
+							</view>
+						</scroll-view>
+					</view>
+				</view>
+				<view class="popu_bottom">
+					<view class="btn hflex acenter jcenter"@click="sure">确定</view>
+					
+				</view>
+			</view>
+		</u-popup>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+	import $api, { info } from '@/static/js/api.js'
+	var that = ''
+	export default {
+		data() {
+			return {
+				fileList1: [],
+				fileList2: [],
+				cateList: [],
+				left_active: 0,
+				right_active: -1,
+				name: '',
+				content: '',
+				radioList: [
+					{
+						name: '上架售卖'
+					},
+					{
+						name: '暂不上架'
+					}
+				],
+				active: 0,
+				items: '',
+				cover: '',
+				slider: '',
+				content: '',
+				status: 1,
+				cateids: '',
+				cate: '',
+				spec: '',
+				stock_total: 0,
+				price_selling: '',
+				cate_show: false,
+				id: '',
+				data: [],
+				spect: '',
+				data_specs: '',
+				show_choose: false
+			}
+		},
+		onLoad(options) {
+			that = this
+			if(options.id) {
+				that.id = options.id
+				that.getData()
+			}
+			if(options.data) {
+				that.data = JSON.parse(options.data)
+				that.spect = options.spec
+				that.items = that.data
+				that.spec = that.spect
+				for(var i=0;i<that.items.length;i++) {
+					that.stock_total += Number(that.items[i].stock_total)
+					if(that.items[i].status) {
+						that.items[i].status = 1
+					} else {
+						that.items[i].status = 2
+					}
+				}
+				that.price_selling = that.items[0].price_selling
+			}
+			
+			that.getCate()
+		},
+		onShow() {
+			var data = uni.getStorageSync('specData')
+			var spec = uni.getStorageSync('spectitle')
+			if(data) {
+				that.data = JSON.parse(data)
+				that.spect = JSON.parse(spec)
+				that.items = that.data
+				that.spec = that.spect
+				for(var i=0;i<that.items.length;i++) {
+					that.stock_total += Number(that.items[i].stock_total)
+					if(that.items[i].status) {
+						that.items[i].status = 1
+					} else {
+						that.items[i].status = 2
+					}
+				}
+				that.price_selling = that.items[0].price_selling
+			}
+		},
+		methods: {
+			getData() {
+				$api.req({
+					url: '/data/api.business.Goods/goods_details',
+					method: 'POST',
+					data: {
+						goods_id: that.id
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						console.log(res);
+						that.data_specs = res.data.data_specs
+						that.cover = res.data.cover
+						var imgList = res.data.cover.split('|')
+						for(var i=0;i<imgList.length;i++) {
+							var data = {
+								url: imgList[i]
+							}
+							that.fileList1.push(data)
+						}
+						that.name = res.data.name
+						that.items = res.data.item
+						that.cateids = res.data.cateids
+						that.cate = res.data.cate_name[0].name
+						that.content = res.data.content
+						that.slider = res.data.slider
+						imgList = res.data.slider.split('|')
+						for(var i=0;i<imgList.length;i++) {
+							var data = {
+								url: imgList[i]
+							}
+							that.fileList2.push(data)
+						}
+						that.status = res.data.status
+						that.stock_total = res.data.stock_total
+						that.price_selling = res.data.price_selling
+						if(that.status == 1) {
+							that.active = 0
+						} else {
+							that.active = 1
+						}
+						if(that.data.length!==0) {
+							that.items = that.data
+							that.spec = that.spect
+							for(var i=0;i<that.items.length;i++) {
+								that.stock_total += Number(that.items[i].stock_total)
+							}
+							that.price_selling = that.items[0].price_selling
+						}
+					}
+				})
+			},
+			getCate() {
+				$api.req({
+					url: '/data/api.business.Goods/getCate'
+				}, function(res) {
+					if(res.code == 1) {
+						that.cateList = res.data
+					}
+				})
+			},
+			// 删除图片
+			deletePic(event) {
+				this[`fileList${event.name}`].splice(event.index, 1)
+			},
+			deletePic2(index) {
+				that.fileList2.splice(index,1)
+			},
+			// 新增图片
+			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
+				let lists = [].concat(event.file)
+				let fileListLen = this[`fileList${event.name}`].length
+				lists.map((item) => {
+					this[`fileList${event.name}`].push({
+						...item,
+						// status: 'uploading',
+						// message: '上传中'
+					})
+				})
+				for (let i = 0; i < lists.length; i++) {
+					const result = await this.uploadFilePromise(lists[i].url)
+					let item = this[`fileList${event.name}`][fileListLen]
+					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
+						// status: 'success',
+						type: result.type,
+						url: result.url
+					}))
+					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
+				}
+				console.log(that.fileList1);
+			},
+			uploadFilePromise(url) {
+				return new Promise((resolve, reject) => {
+					let a = uni.uploadFile({
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+						filePath: url,
+						name: 'file',
+						header: {
+							'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+							'api-name': 'iosapp'
+						},
+						formData: {
+							user: 'test'
+						},
+						success: (res) => {
+							setTimeout(() => {
+								var data = JSON.parse(res.data)
+								console.log('data:',data);
+								var type = data.data.key.split('.')
+								if(type[1] == 'mp4') {
+									that.$set(data.data,'type','video')
+								} else {
+									that.$set(data.data,'type','image')
+								}
+								resolve(data.data)
+							}, 1000)
+						}
+					});
+				})
+			},
+			changeRadio(index) {
+				that.active = index
+				if(that.active == 0) {
+					that.status = 1
+				} else {
+					that.status = 0
+				}
+			},
+			addSpec() {
+				if(that.id) {
+					return
+				}
+				$api.jump('/pages/good/spec?items=' + that.data_specs+'&good_id=' + that.id)
+			},
+			toSetting() {
+				var data = uni.getStorageSync('specData')
+				var list = uni.getStorageSync('spectitle')
+				if(that.id) {
+					$api.jump('/pages/good/setting?good_id=' + that.id + '&list=' + JSON.stringify(that.items) + '&data=' +that.data_specs)
+				} else {
+					$api.jump('/pages/good/setting?list=' + data + '&data=' +list)
+				}
+			},
+			open() {
+				that.cate_show = true
+			},
+			clickTab1(e) {
+				that.left_active = e
+				that.right_active = -1
+			},
+			selectItem(index) {
+				that.right_active = index
+			},
+			sure() {
+				if(that.left_active == -1 && that.right_active == -1) {
+					$api.info("请先选择类目")
+					return
+				}
+				if(that.right_active == -1) {
+					that.cateids = that.cateList[that.left_active].id
+					that.cate = that.cateList[that.left_active].name
+				} else {
+					that.cateids = that.cateList[that.left_active].sub[that.right_active].id
+					that.cate = that.cateList[that.left_active].sub[that.right_active].name
+				}
+				that.close()
+			},
+			close() {
+				that.cate_show = false
+				that.show_choose = false
+			},
+			create() {
+				uni.removeStorageSync("specData")
+				uni.removeStorageSync("spectitle")
+				console.log('总库存',that.stock_total);
+				for(var i=0;i<that.fileList1.length;i++) {
+					that.cover += that.fileList1[i].url + '|'
+				}
+				for(var i=0;i<that.fileList2.length;i++) {
+					that.slider += that.fileList2[i].url + '|'
+				}
+				that.cover = that.cover.substr(0,that.cover.length - 1)
+				that.slider = that.slider.substr(0,that.slider.length - 1)
+				console.log(that.spec);
+				$api.req({
+					url: '/data/api.business.Goods/goods_add',
+					method: 'POST',
+					data: {
+						name: that.name,
+						cateids: that.cateids,
+						cover: that.cover,
+						slider: that.slider,
+						content: that.content,
+						stock_total: that.stock_total,
+						price_selling: that.price_selling,
+						status: that.status,
+						spec: JSON.stringify(that.spec),
+						items: JSON.stringify(that.items)
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						$api,info(res.info)
+						
+						$api.jump('/pages/tabbar/index/index',2)
+					}
+				})
+			},
+			save() {
+				that.cover = ""
+				that.slider = ""
+				uni.removeStorageSync("specData")
+				uni.removeStorageSync("spectitle")
+				console.log('总库存',that.stock_total);
+				for(var i=0;i<that.fileList1.length;i++) {
+					that.cover += that.fileList1[i].url + '|'
+				}
+				for(var i=0;i<that.fileList2.length;i++) {
+					that.slider += that.fileList2[i].url + '|'
+				}
+				var items = []
+				for(var i=0;i<that.items.length;i++) {
+					var temp = {
+						id: that.items[i].id,
+						goods_spec: that.items[i].goods_spec,
+						stock_total: that.items[i].stock_total,
+						price_selling: that.items[i].price_selling,
+						sku_image: that.items[i].show_image?that.items[i].show_image: that.items[i].sku_image,
+						status: that.items[i].status
+					}
+					items.push(temp)
+				}
+				that.cover = that.cover.substr(0,that.cover.length - 1)
+				that.slider = that.slider.substr(0,that.slider.length - 1)
+				$api.req({
+					url: '/data/api.business.Goods/goods_edit',
+					method: 'POST',
+					data: {
+						goods_id: that.id,
+						name: that.name,
+						cateids: that.cateids,
+						cover: that.cover,
+						slider: that.slider,
+						content: that.content,
+						stock_total: that.stock_total,
+						price_selling: that.price_selling,
+						status: that.status,
+						items: JSON.stringify(items)
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						$api,info(res.info)
+						
+						$api.jump('/pages/tabbar/index/index',2)
+					}
+				})
+			},
+			dele() {
+				$api.req({
+					url: '/data/api.business.Goods/del_goods',
+					method: 'POST',
+					data: {
+						goods_id: that.id
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						$api.info(res.info) 
+						$api.jump('/pages/tabbar/index/index',2)
+					}
+				})
+			},
+			choose() {
+				that.show_choose = true
+			},
+			choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList2.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.fileList2.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList2.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.fileList2.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	.content::v-deep {
+		background: #F5F5F5;
+		.box {
+			width: 100%;
+			background: #FFFFFF;
+			box-sizing: border-box;
+			padding: 0 30rpx;
+			margin-top: 20rpx;
+			.title {
+				font-size: 30rpx;
+				font-weight: 400;
+				color: #222222;
+				line-height: 42rpx;
+				margin: 28rpx 0 20rpx;
+			}
+			.requ {
+				position: relative;
+			}
+			.requ:before {
+				content: '*';
+				top: 0;
+				left: -15rpx;
+				position: absolute;
+				font-size: 30rpx;
+				font-weight: 400;
+				color: #FF3636;
+				
+			}
+			.upload {
+				margin-bottom: 20px;
+				.upload_img1 {
+					width: 166rpx;
+					height: 166rpx;
+				}
+				
+				.upload_img2 {
+					width: 200rpx;
+					height: 200rpx;
+				}
+				.img {
+					width: 200rpx;
+					height: 200rpx;
+					margin: 0 20rpx 20rpx 0;
+					border-radius: 16rpx;
+				}
+				video {
+					width: 200rpx;
+					height: 200rpx;
+					margin: 0 20rpx 20rpx 0;
+				}
+				.close_icon {
+					position: absolute;
+					top: 0;
+					right: 15rpx;
+					width: 30rpx;
+					height: 30rpx;
+					z-index: 99;
+				}
+			}
+			.u-textarea {
+				padding: 0 !important;
+			}
+			.box_item {
+				padding: 28rpx 0;
+				border-bottom: 1rpx solid #F5F5F5;
+				.box_left {
+					font-size: 30rpx;
+					font-weight: 400;
+					color: #222222;
+					line-height: 42rpx;
+				}
+				.box_right {
+					font-size: 30rpx;
+					font-weight: 400;
+					color: #ACACAC;
+					line-height: 42rpx;
+					padding-right: 10rpx;
+					text-overflow: ellipsis;
+					overflow: hidden;
+					display: -webkit-box;
+					-webkit-box-orient: vertical;
+					box-orient: vertical;
+					line-clamp: 2;
+					-webkit-line-clamp: 2;
+				}
+				.text_blue {
+					color: #617BFE;
+				}
+				.radio_text {
+					font-size: 30rpx;
+					font-weight: 400;
+					color: #222222;
+					line-height: 42rpx;
+					padding-left: 12rpx;
+				}
+			}
+		}
+		.bottom {
+			width: 100%;
+			height: 166rpx;
+			background: #FFFFFF;
+			position: fixed;
+			bottom: 0;
+			z-index: 99;
+			.btn {
+				width: 690rpx;
+				height: 84rpx;
+				background: #5471FF;
+				border-radius: 46rpx;
+				margin: 8rpx auto 0;
+				font-size: 36rpx;
+				font-weight: 500;
+				color: #FFFFFF;
+				line-height: 50rpx;
+			}
+			.btn_group {
+				width: 100%;
+				box-sizing: border-box;
+				padding: 8rpx 30rpx 0;
+				.btn1 {
+					width: 330rpx;
+					height: 84rpx;
+					border-radius: 46rpx;
+					border: 1rpx solid #5471FF;
+					font-size: 32rpx;
+					font-weight: 500;
+					color: #5471FF;
+					line-height: 50rpx;
+				}
+				.btn2 {
+					width: 330rpx;
+					height: 84rpx;
+					background: #5471FF;
+					border-radius: 46rpx;
+					font-size: 32rpx;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 50rpx;
+				}
+			}
+		}
+		.popu {
+			background: #FFFFFF;
+			border-radius: 40rpx 40rpx 0px 0px;
+			// border: 2rpx solid #979797;
+			.popu_top {
+				width: 690rpx;
+				margin: 0 auto;
+				padding: 44rpx 0 28rpx;
+				border-bottom: 1px solid #F7F7F7;
+				.popu_title {
+					font-size: 36rpx;
+					font-weight: 500;
+					color: #222222;
+					line-height: 50rpx;
+				}
+			}
+			.center {
+				margin: 0 0 188rpx;
+				.menuList {
+					width: 100%;
+					.menu_left {
+						width: 200rpx;
+						height: 850rpx;
+						background: #F5F5F5;
+						border-radius: 0px 28rpx 0px 0px;
+						.left_item {
+							max-width: 200rpx;
+							font-size: 28rpx;
+							font-weight: 400;
+							color: #222222;
+							line-height: 40rpx;
+							padding: 30rpx 20rpx;
+						}
+						.left_active {
+							color: #506DFF;
+							background: #fff;
+						}
+					}
+					.menu_right {
+						width: 550rpx;
+						height: 850rpx;
+						background: #FFFFFF;
+						.right_item {
+							padding: 30rpx 30rpx 30rpx 64rpx;
+							.item_text {
+								font-size: 30rpx;
+								font-weight: 400;
+								color: #393939;
+								line-height: 42rpx;
+							}
+							.right_active {
+								color: #5B77FF;
+							}
+						}
+						.tabs_text {
+							width: 80rpx;
+							height: 56rpx;
+							background: #FFFFFF;
+							font-size: 20rpx;
+							font-weight: 400;
+							color: #393939;
+							line-height: 28rpx;
+						}
+					}
+				}
+			}
+			.popu_bottom {
+				width: 100%;
+				height: 166rpx;
+				background: #FFFFFF;
+				position: fixed;
+				bottom: 0;
+				z-index: 99;
+				.btn {
+					width: 690rpx;
+					height: 84rpx;
+					background: #5471FF;
+					border-radius: 46rpx;
+					margin: 8rpx auto 0;
+					font-size: 36rpx;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 50rpx;
+				}
+				
+			}
+		}
+		.choose {
+			padding: 20rpx 0;
+		}
+	}
 </style>

+ 15 - 5
pages/good/manager.vue

@@ -12,7 +12,7 @@
 					</u-checkbox-group>
 					<image :src="item.cover" class="img"></image>
 					<view class="right">
-						<view class="item_name">{{item.name}}</view>
+						<view class="item_name text_hide">{{item.name}}</view>
 						<view class="item_price">¥<span style="font-size: 32rpx;">{{item.price_selling}}</span></view>
 						<view class="item_stock">库存{{item.stock_total}}</view>
 					</view>
@@ -22,7 +22,7 @@
 		<view class="bottom hflex jbetween">
 			<view class="hflex">
 				<u-checkbox-group @change="checkboxChange2" placement="column">
-					<u-checkbox shape="circle"></u-checkbox>
+					<u-checkbox shape="circle" :checked="checkAll"></u-checkbox>
 				</u-checkbox-group>
 				<view class="left_text">全选</view>
 			</view>
@@ -48,7 +48,7 @@
 						name: '售卖中',
 						badge: {
 							value: 0,
-							bgColor: '#393939',
+							bgColor: '#FF383F',
 							color: '#FFFFFF'
 						}
 					},
@@ -58,7 +58,7 @@
 						name: '已下架',
 						badge: {
 							value: 0,
-							bgColor: '#393939',
+							bgColor: '#FF383F',
 							color: '#FFFFFF'
 						}
 					},
@@ -68,7 +68,7 @@
 						name: '已售罄',
 						badge: {
 							value: 0,
-							bgColor: '#393939',
+							bgColor: '#FF383F',
 							color: '#FFFFFF'
 						}
 					}
@@ -98,6 +98,10 @@
 					}
 				}, function(res) {
 					if(res.code == 1) {
+						for(var i=0;i<res.data.list.list.length;i++) {
+							var temp = res.data.list.list[i].cover.split('|')
+							res.data.list.list[i].cover = temp[0]
+						}
 						for (var i=0;i<that.tabs.length;i++) {
 							that.$set(that.tabs[i].badge,'value',res.data.count[i+1])
 						}
@@ -122,6 +126,11 @@
 						that.$set(that.tabs[i].badge,"color",'#888888')
 					}
 				}
+				for(var i=0;i<that.pageList.length;i++) {
+					that.$set(that.pageList[i],'check',false)
+				}
+				that.checkAll = false
+				that.count = 0
 				that.tab_active = e.index
 				that.page = 1
 				that.pageList = []
@@ -230,6 +239,7 @@
 				}
 				.right {
 					.item_name {
+						width: 400rpx;
 						font-size: 30rpx;
 						font-weight: 400;
 						color: #222222;

+ 6 - 0
pages/good/options.vue

@@ -57,6 +57,12 @@
 				that.options.push(data)
 			},
 			save() {
+				for(var i=0;i<that.options.length;i++) {
+					if(that.options[i].name == '') {
+						$api.info('型号不能为空')
+						return
+					}
+				}
 				let pages = getCurrentPages();
 				let prevPage = pages[pages.length - 2];
 				that.$set(prevPage.$vm._data.specList[that.index],'list',that.options)

+ 62 - 9
pages/good/setting.vue

@@ -4,14 +4,14 @@
 			<view class="title">共{{pageList.length}}个型号:{{title}}</view>
 			<block v-for="(item,index) in pageList" :key="index">
 				<view class="box">
-					<view class="box_title cell">{{item.goods_spec}}</view>
+					<view class="box_title cell">{{titleList[index].title}}</view>
 					<view class="hflex acenter jbetween cell">
 						<view class="left">价格</view>
-						<u-input v-model="item.price_selling" border="none" placeholder="请填写商品价格"></u-input>
+						<u-input v-model="item.price_selling" type="digit" border="none" placeholder="请填写商品价格" @blur="moneyinput(index)"></u-input>
 					</view>
 					<view class="hflex acenter jbetween cell">
 						<view class="left">库存</view>
-						<u-input v-model="item.stock_total " border="none" placeholder="请填写商品库存"></u-input>
+						<u-input v-model="item.stock_total" type="number" border="none" placeholder="请填写商品库存"></u-input>
 					</view>
 					<view class="hflex acenter cell">
 						<view class="left">图片</view>
@@ -42,6 +42,7 @@
 	export default {
 		data() {
 			return {
+				titleList: [],
 				specList: [],
 				pageList: [],
 				title: '',
@@ -50,7 +51,14 @@
 		},
 		onLoad(options) {
 			that = this
-			that.specList = JSON.parse(options.data)
+			if(options.data) {
+				that.specList = JSON.parse(options.data)
+				console.log('that.specList',that.specList);
+			}
+			if(options.list) {
+				that.pageList = JSON.parse(options.list)
+				console.log('that.pageList',that.pageList);
+			}
 			if(options.good_id) {
 				that.good_id = options.good_id
 			}
@@ -60,6 +68,7 @@
 			getList() {
 				var list = []
 				var list2 = []
+				console.log(that.pageList);
 				for(var i=0;i<that.specList.length;i++) {
 					that.title += that.specList[i].name + '、'
 					for(var j=0;j<that.specList[i].list.length;j++) {
@@ -76,6 +85,10 @@
 					for(var i=0;i<list.length;i++) {
 						for(var j=i+1;j<list.length;j++) {
 							if(list[i].type !== list[j].type) {
+								var temp = {
+									title: list[i].name+'|' + list[j].name
+								}
+								that.titleList.push(temp)
 								var data = {
 									goods_spec: list[i].group + '::' + list[i].name+';;' + list[j].group + '::' + list[j].name,
 									stock_total : '',
@@ -90,6 +103,10 @@
 				} 
 				if(that.specList.length == 1) {
 					for(var i=0;i<list.length;i++) {
+						var temp = {
+							title : list[i].name
+						}
+						that.titleList.push(temp)
 						var data = {
 							goods_spec: list[i].group+ '::' + list[i].name,
 							stock_total : '',
@@ -101,10 +118,13 @@
 					}
 				}
 				if(that.specList.length == 3) {
-					console.log(that.specList);
 					for(var i=0;i<that.specList[0].list.length;i++) {
 						for(var j=0;j<that.specList[1].list.length;j++) {
 							for(var k=0;k<that.specList[2].list.length;k++) {
+								var temp = {
+									title: that.specList[0].list[i].name+'|' +  that.specList[1].list[j].name + '|' +  that.specList[2].list[k].name
+								}
+								that.titleList.push(temp)
 								var data = {
 									goods_spec: that.specList[0].list[i].group+ '::' + that.specList[0].list[i].name+';;'+ that.specList[1].list[j].group+ '::' +  that.specList[1].list[j].name + ';;' + that.specList[2].list[k].group+ '::' +  that.specList[2].list[k].name,
 									stock_total : '',
@@ -117,7 +137,24 @@
 						}
 					}
 				}
-				that.pageList = list2
+				var plist = []
+				console.log(that.pageList);
+				if(that.pageList.length == 0) {
+					that.pageList = list2
+				} else {
+					for(var i=0;i<that.pageList.length;i++) {
+						var data = {
+							id: that.pageList[i].id,
+							goods_spec: that.pageList[i].goods_spec,
+							stock_total : that.pageList[i].stock_total,
+							price_selling : that.pageList[i].price_selling,
+							sku_image : that.pageList[i].show_image?that.pageList[i].show_image:that.pageList[i].sku_image,
+							status : that.pageList[i].status == 1 ? true : false,
+						}
+						plist.push(data)
+					}
+					that.pageList = plist
+				}
 			},
 			uploadImg(index) {
 				uni.chooseImage({
@@ -151,15 +188,31 @@
 			closeImg(index) {
 				that.pageList[index].sku_image = ""
 			},
+			moneyinput(index) {
+				console.log(index);
+				if(that.pageList[index].price_selling<=0) {
+					$api.info('请输入>0的数字')
+					that.pageList[index].price_selling = ''
+				}
+				
+			},
 			save() {
+				console.log(that.pageList);
 				for(var i=0;i<that.pageList.length;i++) {
-					if(that.pageList[i].status) {
+					if(!that.pageList[i].price_selling || !that.pageList[i].stock_total || !that.pageList[i].sku_image) {
+						$api.info("必填项不能为空")
+						return
+					}
+					/* if(that.pageList[i].status) {
 						that.pageList[i].status = 1
 					} else {
 						that.pageList[i].status = 2
-					}
+					} */
 				}
-				$api.jump('/pages/good/add?data=' + JSON.stringify(that.pageList) + '&spec=' + JSON.stringify(that.specList) + '&id=' + that.good_id)
+				
+				uni.setStorageSync('specData',JSON.stringify(that.pageList))
+				uni.setStorageSync('spectitle',JSON.stringify(that.specList))
+				$api.jump(-1)
 			}
 		},
 	}

+ 23 - 37
pages/good/spec.vue

@@ -8,7 +8,7 @@
 				<view class="box">
 					<view class="hflex acenter jbetween box-top">
 						<view class="hflex acenter">
-							<view class="name">{{item.name}}</view>
+							<view class="name text_hide">{{item.name}}</view>
 							<image src="/static/images/common/edit_icon.png" style="width: 28rpx;height: 28rpx;" @click="open(index)"></image>
 						</view>
 						<view class="hflex acenter" @click="delSpec(index)">
@@ -19,8 +19,8 @@
 					<view class="hflex acenter fwrap" style="padding: 32rpx 0;">
 						<block v-for="(item2,index2) in item.list" :key="index2">
 							<view class="options hflex acenter">
-								<view class="text">{{item2.name}} | </view>
-								<image src="/static/images/common/close_icon.png" style="width: 28rpx;height: 28rpx;" @click="delOptions(index,index2)"></image>
+								<view class="text text-right">{{item2.name}}</view>
+								<image src="/static/images/common/close_icon.png" style="margin-left: 16rpx;width: 28rpx;height: 28rpx;" @click="delOptions(index,index2)"></image>
 							</view>
 						</block>
 						<view class="options hflex acenter">
@@ -36,10 +36,10 @@
 				下一步
 			</view>	
 		</view>	
-		<u-popup :show="show" :round="10" mode="center" @close="close">
+		<u-popup :show="show" round="10" mode="center" @close="close" :safeAreaInsetBottom="false">
 			<view class="popu">
 				<view class="popu_title">添加规格分类</view>	
-				<u-input v-model="name" border="none" shape="circle" placeholder="请输入"></u-input>
+				<u-input v-model="name" border="none" maxlength="15" shape="circle" placeholder="请输入"></u-input>
 				<view class="hflex acenter jcenter btn_group">
 					<view class="left_btn" @click="close">取消</view>	
 					<view class="right_btn" @click="save">保存</view>
@@ -70,39 +70,15 @@
 				that.good_id = options.good_id
 			}
 			if(options.items) {
-				// that.getData(options.items)
+				that.getData(options.items)
 			}
 		},
 		methods: {
 			getData(data) {
 				var data = JSON.parse(data)
-				var spec = data[0].goods_spec.split(';;')
-				var list = []
-				for(var i=0;i<spec.length;i++) {
-					var name = spec[i].split('::')
-					var data2 = {
-						name: name[0]
-					}
-					that.specList.push(data2)
-				}
-				var temp = []
-				for(var i=0;i<data.length;i++) {
-					var a = data[i].goods_spec.split(';;')
-					temp.push(a)
-				}
-				for(var i=0;i<that.specList.length;i++) {
-					var list2 = []
-					for(var j=0;j<temp.length;j++) {
-						var temp2 = temp[j][i].split('::')
-						var b = {
-							name: temp2[1]
-						}
-						list2.push(b)
-					}
-					console.log(list2);
-					list2 = $api.duplicate(list2,'name')
-					that.$set(that.specList[i],'list',list2)
-				}
+				console.log(data);
+				
+				that.specList = data
 			},
 			open(index) {
 				if(index == -1) {
@@ -117,6 +93,10 @@
 				that.show = false
 			},
 			save() {
+				if(that.name == '') {
+					$api.info('请输入规格分类')
+					return
+				}
 				var data = {
 					name: that.name
 				}
@@ -132,19 +112,20 @@
 				that.specList.splice(index,1)
 			},
 			delOptions(index,index2) {
-				that.specList[index].options.splice(index2,1)
+				console.log(that.specList);
+				that.specList[index].list.splice(index2,1)
 			},
 			add(index,name) {
 				var url = ''
-				if(that.specList[index].options) {
-					url = '/pages/good/options?index='+index+'&data='+JSON.stringify(that.specList[index].options) + '&group=' + name
+				if(that.specList[index].list) {
+					url = '/pages/good/options?index='+index+'&data='+JSON.stringify(that.specList[index].list) + '&group=' + name
 				} else {
 					url = '/pages/good/options?index='+index + '&group=' + name
 				}
 				$api.jump(url)
 			},
 			next() {
-				$api.jump('/pages/good/setting?data=' + JSON.stringify(that.specList) + '&good_id=' + that.good_id)
+				$api.jump('/pages/good/setting?data=' + JSON.stringify(that.specList) + '&good_id=' + that.good_id,1)
 			}
 		},
 	}
@@ -172,6 +153,7 @@
 					padding: 24rpx 0;
 					border-bottom: 1rpx solid #F5F5F5;
 					.name {
+						width: 500rpx;
 						font-size: 30rpx;
 						font-weight: 500;
 						color: #222222;
@@ -197,6 +179,10 @@
 						color: #333333;
 						line-height: 36rpx;
 					}
+					.text-right {
+						padding-right: 16rpx;
+						border-right: 1rpx solid #D8D8D8;
+					}
 					.text_blue {
 						color: #5471FF;
 					}

+ 24 - 32
pages/login/codeLogin/codeLogin.vue

@@ -64,9 +64,10 @@
 					})
 					$api.req({
 						url: '/data/api.Login/sendsms',
+						method: 'POST',
 						data: {
-							phone: that.userInfo.phone,
-							type: 1
+							phone: that.userInfo.name,
+							type: 5
 						}
 					}, function(res) {
 						uni.hideLoading();
@@ -87,26 +88,29 @@
 			},
 			// 打开弹出层
 			open(index) {
+				
 				const that = this
-				// if(index == 0) {
-				// 	$api.req({
-				// 		url: '/api/Publics/config_info'
-				// 	}, function(res) {
-				// 		if (res.code == 1) {
-				// 			that.protocolTitle = '用户协议'
-				// 			that.protocolContent = res.data.xieyi
-				// 		}
-				// 	})
-					
-				// } else {
-				// 	that.protocolTitle = '隐私政策'
-				// 	that.protocolContent = ''
-				// }
-				// that.showProtocol = true
+				$api.jump('/pages/login/xieyi?title=用户服务协议&data=' + index)
+				/* $api.req({
+					url: '/data/api.business.Login/getconfigset'
+				}, function(res) {
+					if (res.code == 1) {
+						if(index == 0) {
+							$api.jump('/pages/login/xieyi?title=用户服务协议&data=0')
+						} else {
+							$api.jump('/pages/login/xieyi?title=个人隐私保护政策&data=1')
+						}
+					}
+				}) */
+			},
+			// 已阅读
+			isRead() {
+				that.showProtocol = false
+				that.agree = true
 			},
 			// 登录
 			login() {
-				if ($api.formCheck(that.userInfo.name,"phone") && $api.formCheck(that.code, "code4")) {
+				if ($api.formCheck(that.userInfo.name,"phone")) {
 					if (!that.agree) {
 						$api.info('请先阅读并同意用户协议和隐私协议')
 					} else {
@@ -122,20 +126,8 @@
 							console.log(res)
 							if(res.code == 1) {
 								wx.setStorageSync("token",res.data)
-								wx.setStorageSync("id",res.data.id)
-								var options = {
-								  user: res.data.id.toString(),
-								  pwd: '123456',
-								  appKey: uni.WebIM.config.appkey,
-								  success: function (res2) {
-									wx.setStorageSync("HXtoken",res2.access_token)
-									$api.jump('/pages/tabbar/mine/mine',3)
-								  },
-								  error: function(error){
-									  console.log(error);
-								  }
-								};
-								uni.WebIM.conn.open(options);
+								$api.jump('/pages/tabbar/mine/mine',2)
+								
 							}
 						})
 					}

+ 15 - 7
pages/login/forgot/forgot.vue

@@ -8,7 +8,7 @@
 					<view class="code" @tap="getCode" >{{tips}}</view>
 				</template>
 			</u-input>
-			<u-input :type="pwd_type" v-model="userInfo.password" placeholder="请输入密码">
+			<u-input :type="pwd_type" v-model="userInfo.password" placeholder="请输入密码">
 				<template slot="suffix">
 					<view @click="show_pwd" v-if="pwd_type == 'password'">
 						<image src="/static/images/login/biyanjing.png" class="pwd_icon"></image>
@@ -49,6 +49,13 @@
 			}
 		},
 		methods: {
+			show_pwd() {
+				if(that.pwd_type == 'password') {
+					that.pwd_type = 'text'
+				} else {
+					that.pwd_type = 'password'
+				}
+			},
 			// 验证码文字
 			codeChange(text) {
 				that.tips = text
@@ -61,9 +68,10 @@
 					})
 					$api.req({
 						url: '/data/api.Login/sendsms',
+						method: 'POST',
 						data: {
-							phone: that.userInfo.phone,
-							type: 3
+							phone: that.userInfo.name,
+							type: 6
 						}
 					}, function(res) {
 						uni.hideLoading();
@@ -80,13 +88,13 @@
 			},
 			// 提交
 			submit() {
-				if ($api.formCheck(that.userInfo.name,"require") && $api.formCheck(that.userInfo.password, "require") && $api.formCheck(that.code, "code4")) {
+				if ($api.formCheck(that.userInfo.name,"require") && $api.formCheck(that.userInfo.password, "require") && $api.formCheck(that.code, "code6")) {
 					$api.req({
-						url: '/data/api.Login/findpwd',
+						url: '/data/api.business.Login/findpwd',
 						method: 'POST',
 						data: {
-							phone: that.userInfo.name,
-							verify: that.code,
+							mobile: that.userInfo.name,
+							code: that.code,
 							password: that.userInfo.password,
 						}
 					}, function(res) {

+ 6 - 17
pages/login/login/login.vue

@@ -73,21 +73,11 @@
 			// 打开弹出层
 			open(index) {
 				const that = this
-				// if(index == 0) {
-				// 	$api.req({
-				// 		url: '/api/Publics/config_info'
-				// 	}, function(res) {
-				// 		if (res.code == 1) {
-				// 			that.protocolTitle = '用户协议'
-				// 			that.protocolContent = res.data.xieyi
-				// 		}
-				// 	})
-					
-				// } else {
-				// 	that.protocolTitle = '隐私政策'
-				// 	that.protocolContent = ''
-				// }
-				// that.showProtocol = true
+				$api.jump('/pages/login/xieyi?title=用户服务协议&data=' + index)
+			},
+			isRead() {
+				that.showProtocol = false
+				that.agree = true
 			},
 			// 登录
 			login() {
@@ -106,7 +96,6 @@
 						}, function(res) {
 							if(res.code == 1) {
 								wx.setStorageSync("token",res.data)
-								wx.setStorageSync("id",res.data.id)
 								/* var options = { 
 								  user: res.data.id.toString(),
 								  pwd: '123456',
@@ -119,7 +108,7 @@
 								  }
 								};
 								uni.WebIM.conn.open(options); */
-								$api.jump('/pages/tabbar/mine/mine',3)
+								$api.jump('/pages/tabbar/mine/mine',2)
 							} else {
 								$api.info(res.info)
 							}

+ 49 - 0
pages/login/xieyi.vue

@@ -0,0 +1,49 @@
+<template>
+	<view class="content">
+		<u-parse :content="data"></u-parse>
+	</view>
+</template>
+
+<script>
+	import $api from '@/static/js/api.js'
+	var that = ''
+	export default {
+		data() {
+			return {
+				data: '',
+				index: ''
+			}
+		},
+		onLoad(options) {
+			that = this
+			if(options.title) {
+				uni.setNavigationBarTitle({
+					title: options.title
+				})
+			}
+			that.index = options.data
+			that.getData()
+		},
+		methods: {
+			getData() {
+				$api.req({
+					url: '/data/api.business.Login/getconfigset'
+				}, function(res) {
+					if (res.code == 1) {
+						if(that.index == 0) {
+							that.data = res.data.shop_service_agreement
+						} else {
+							that.data = res.data.shop_protection_policy
+						}
+					}
+				})
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	.content {
+		padding: 20rpx;
+	}
+</style>

+ 236 - 0
pages/mine/message/chat.css

@@ -0,0 +1,236 @@
+page{
+	width: 100%;
+	overflow: hidden;
+}
+.chat_title{
+	position: fixed;
+	background-color: #fff;
+	width: 100%;
+	z-index: 9;
+	top: 0;
+	height: 128rpx;
+}
+.chat_title text{
+	line-height: 96rpx;
+	font-size: 64rpx;
+	font-weight: 400;
+	margin-left: 32rpx;
+}
+
+.search,.search_input {
+	width: 100%;
+	height: 88rpx;
+	background-color: #f2f2f2;
+	display: flex;
+	align-items: center;
+	top: 0;
+	left: 0;
+}
+
+
+.search {
+	justify-content: space-around;
+}
+.search_input {
+	justify-content: space-around;	
+}
+.search view, .search_input view {
+	height: 64rpx;
+	line-height: 64rpx;
+	background-color: #fff;
+	border-radius: 17px;
+	text-align: center;
+	display: flex;
+	align-items: center;
+	margin: 0 32rpx;
+}
+.search view {
+	width: 100%;
+	justify-content: center;
+	align-items: center;
+	background-color: #fff;
+}
+.search image {
+	display: block;
+	width: 5%;
+	height: 50%;
+}
+.search_input view {
+	padding-left: 24rpx;
+	text-align: left;
+	flex: 1;
+	margin: 0 28rpx 0 32rpx;
+}
+.search icon,.search_input icon {
+	display: inline-block;
+	margin: 8rpx 12rpx 0;
+	font-size: 24rpx;
+}
+.search text {
+	font-size: 30rpx;
+	color: #9B9B9B;
+}
+
+.search_input text {
+	display: inline-block;
+	height: 60rpx;
+	line-height: 60rpx;
+	font-size: 30rpx;
+	color: #0873DE;
+	margin-right: 32rpx;
+}
+.search_input input {
+	font-size: 28rpx;
+	width: 90%;
+}
+.mask {
+	background-color: black;
+	opacity: 0.4;
+	position: fixed;
+	top: 80rpx;
+	left: 0;
+	right: 0;
+	bottom: 0;
+}
+.chat_list_wraper{
+	/* padding: 270rpx 0; */
+	box-sizing: border-box; 
+	height: 100%;
+	/* position: fixed; */
+	overflow: hidden;
+}
+
+.chat_list {
+	width: 100%;
+	height: 128rpx;
+	overflow: hidden;
+}
+.tap_mask{
+	width: 100%;
+	overflow: hidden;
+}
+.list_box{
+	/* margin: 0 32rpx; */
+	height: 126rpx;
+	border-bottom: 0.5px #E5E5E5 solid;
+	display: flex;
+}
+.list_left {
+	width: 63%;
+	height: 100%;
+	float: left;
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	flex: 1;
+}
+.list_text {
+	width: 60%;
+	height: 100%;
+	float: left;
+	font-size: 28rpx;
+}
+.list_pic {
+	margin-right: 20rpx;
+}
+.list_pic image {
+	display: block;
+	width: 88rpx;
+	height: 88rpx;
+	border-radius: 50%;
+}
+.list_user,.list_user2{
+	font-size: 34rpx;
+	color: #000;
+	position: relative;
+	top: 22rpx;
+	overflow: hidden;
+	max-width: 350rpx;
+	display: inline-block;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+.list_user2{
+	top: 40rpx !important;
+}
+.em-msgNum {
+	position: absolute;
+	left: 64rpx;
+	top: 20rpx;
+	min-width: 28rpx;
+	border-radius: 14rpx;
+	background: #f04134;
+	color: #fff;
+	line-height: 28rpx;
+	font-size: 25rpx;
+	text-align: center;
+	padding: 3rpx;
+	z-index: 999;
+}
+.list_word {
+	height: 40rpx;
+	display: block;
+	margin-top: 0;
+	overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    position: absolute;
+    width: 70%;
+    font-size: 24rpx;
+    color: #9B9B9B;
+    top: 66rpx;
+}
+.list_right {
+	width: 240rpx;
+	height: 100%;
+	float: right;
+	font-size: 24rpx;
+	text-align: right;
+}
+.list_right text:first-child {
+	display: block;
+	line-height: 60rpx;
+	margin: 12rpx auto auto auto;
+}
+.list_right text:last-child {
+	height: 40rpx; 
+	font-size: 26rpx;
+	color: #CFCFCF;
+	display: block;
+	margin-top: 4rpx;
+}
+
+.chat_noChat{
+	text-align: center;
+	font-size: 30rpx;
+	color: #9B9B9B;
+	margin-top: 400rpx;
+}
+.ctbg{
+	width: 138px;
+    height: 106px;
+    display: block;
+    margin: 20rpx auto;
+}
+/* .main_title_hide{
+	top: -128rpx;
+	transition: top 0.5s;
+}
+.main_title_show{
+	top: 0;
+	transition: top 0.5s;
+} */
+/* .goTop{
+	top: 0rpx;
+	transition: top 0.5s;
+	padding-bottom: 104rpx!important;
+}
+.goTopX{
+	top: 0rpx;
+	transition: top 0.5s;
+	padding-bottom: 140rpx!important;
+}
+.goback{
+	top: 128rpx;
+	transition: top 0.5s;
+} */

+ 57 - 1
pages/mine/message/detail.vue

@@ -1,8 +1,64 @@
 <template>
+	<view class="content">
+		<view class="title">{{pageData.title}}</view>
+		<view class="container">
+			<u-parse :content="pageData.content"></u-parse>
+		</view>
+	</view>
 </template>
 
 <script>
+	var that = ""
+	import $api from '@/static/js/api.js'
+	export default {
+		data() {
+			return{
+				pageData: {
+				},
+				id: '',
+			}
+		},
+		onLoad(options) {
+			that = this
+			that.id = options.id
+			that.getData()
+		},
+		methods: {
+			getData() {
+				$api.req({
+					url: '/data/api.business.User/message_details',
+					method: 'POST',
+					data: {
+						id: that.id
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						console.log(res);
+						that.pageData = res.data
+					}
+				})
+			}
+		}
+	}
 </script>
 
-<style>
+<style scoped lang="scss"> 
+	.content {
+		background-color: #fff;
+		padding: 0 30rpx;
+		.title {
+			width: 100%;
+			margin: 40rpx 0 24rpx;
+			font-size: 40rpx;
+			line-height: 56rpx;
+			color: #222;
+			font-weight: 600;
+		}
+		.container {
+			font-size: 36rpx;
+			color: #444;
+			line-height: 50rpx;
+			padding-top: 20rpx;
+		}
+	}
 </style>

+ 791 - 1
pages/mine/message/index.vue

@@ -1,8 +1,798 @@
 <template>
+	<view class="content">
+		<view class="list">
+			<view class="list_item hflex acenter" @click="toList(1)">
+				<image class="item_img" src="/static/images/mine/notice.png" mode="aspectFill"></image>
+				<view class="number" v-if="notice_num > 0">{{notice_num}}</view>
+				<view class="item_right">
+					<view class="hflex acenter jbetween">
+						<view class="hflex acenter">
+							<view class="name">系统通知</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="list_item hflex acenter" @click="toList(2)">
+				<image class="item_img" src="/static/images/mine/order_msg.png" mode="aspectFill"></image>
+				<!-- <view class="number" v-if="message_num > 0">{{message_num}}</view> -->
+				<view class="item_right">
+					<view class="hflex acenter jbetween">
+						<view class="hflex acenter">
+							<view class="name">订单消息</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			
+		</view>
+		<view class="chat_list_wraper">
+			<scroll-view scroll-y="true"
+				:class="'chat_list_wraper ' + (gotop ? (isIPX ? 'goTopX' : 'goTop') : 'goback')"
+				:style="'padding-bottom: ' + (isIPX ? '270rpx' : '226rpx')">
+				<view class="search_input" v-if="search_chats">
+					<view>
+						<icon type="search" size="12"></icon>
+						<input placeholder="搜索" placeholder-style="color:#9B9B9B;line-height:21px;font-size:15px;"
+							auto-focus confirm-type="search" type="text" @confirm="onSearch" @input="onInput"
+							:value="input_code" />
+						<icon type="clear" size="12" @tap.stop="clearInput" v-if="show_clear"></icon>
+					</view>
+					<text @tap="cancel">取消</text>
+				</view>
+		
+				<view v-for="(item, index) in arr" :key="index" class="chat_list" :data-item="item" @tap.stop="del_chat"
+					@longpress="longpress">
+					<swipe-delete>
+						<!-- 通知模块 -->
+						<!-- <view class="tap_mask" @tap.stop="into_inform" :data-item="item"
+							v-if="item.chatType == 'INFORM'">
+							<view class="list_box">
+								<view class="list_left">
+									<view class="list_pic">
+										<view v-if="unReadTotalNotNum > 0" class="em-unread-spot2">{{
+								unReadTotalNotNum
+							  }}</view>
+										<image :class="unReadTotalNotNum > 0 ? 'haveSpot' : ''"
+											src="/static/images/inform.png"></image>
+									</view>
+									<view class="list_text">
+										<text class="list_user"> 系统通知 </text>
+										<text class="list_word"
+											v-if="item.chatType == 'INFORM'">申请通知来自:{{ item.info.from }}</text>
+									</view>
+								</view>
+								<view class="list_right">
+									<text :data-username="item.username">{{ item.time }}</text>
+								</view>
+							</view>
+						</view> -->
+		
+						<view class="tap_mask" @tap.stop="into_chatRoom" :data-item="item">
+							<!-- 消息列表 -->
+							<view class="list_box">
+								<view class="list_left" :data-username="item.your?item.your.nickname:item.username">
+									<view class="list_pic">
+										<view class="em-msgNum"
+											v-if="item.unReadCount > 0 || item.unReadCount == '99+'">
+											{{ item.unReadCount }}</view>
+		
+										<image :src="item.your?item.your.avatarurl:'/static/images/theme2x.png'"></image>
+									</view>
+									<view class="list_text">
+										<text class="list_user text_hide">{{item.your?item.your.nickname:item.username}}</text>
+										<text class="list_word" v-if="item.msg.data[0].data">{{
+								item.msg.data[0].data
+							  }}</text>
+										<text class="list_word" v-if="item.msg.type == 'img'">[图片]</text>
+										<text class="list_word" v-if="item.msg.type == 'audio'">[语音]</text>
+										<!-- <text class="list_word" v-if="item.msg.type == 'video'"
+								>[视频]</text
+							  > -->
+									</view>
+								</view>
+								<view class="list_right">
+									<text :data-username="item.username">{{ item.time }}</text>
+								</view>
+							</view>
+						</view>
+					</swipe-delete>
+				</view>
+		
+				<long-press-modal :winSize="winSize" :popButton="popButton" @change="pickerMenuChange"
+					:showPop="showPop" @hidePop="hidePop" :popStyle="popStyle" />
+				<!-- <view v-if="arr.length" class="chat_noChat">
+					<image class="ctbg" src="/static/images/ctbg.png"></image>
+					暂无聊天消息
+				</view> -->
+				<!-- </view> -->
+			</scroll-view>
+			<!-- bug: margin-bottom 不生效 需要加一个空标签-->
+			<view style="height: 1px"></view>
+		
+			<view class="mask" @tap="close_mask" v-if="show_mask"></view>
+		
+			<!-- <view :class="isIPX ? 'chatRoom_tab_X' : 'chatRoom_tab'"> -->
+				<!-- <view class="tableBar">
+					<view v-if="unReadSpotNum > 0 || unReadSpotNum == '99+'"
+						:class="'em-unread-spot ' +(unReadSpotNum == '99+' ? 'em-unread-spot-litleFont' : '')">
+						{{ unReadSpotNum == '99+'?unReadSpotNum:unReadSpotNum+ unReadTotalNotNum }}</view>
+					<image :class="unReadSpotNum > 0 || unReadSpotNum == '99+' ? 'haveSpot' : ''"
+						src="@/static/images/sessionhighlight2x.png"></image>
+					<text class="activeText">消息</text>
+				</view>
+		
+				<view class="tableBar" @tap="tab_contacts">
+					<image src="/static/images/comtacts2x.png"></image>
+					<text>联系人</text>
+				</view> -->
+		
+				<!-- <view class="tableBar" @tap="tab_notification">
+			<view v-if="unReadTotalNotNum > 0" class="em-unread-spot">{{
+			  unReadTotalNotNum
+			}}</view>
+			<image
+			  :class="unReadTotalNotNum > 0 ? 'haveSpot' : ''"
+			  src="/static/images/notice.png"
+			></image>
+			<text>通知</text>
+		  </view> -->
+		
+				<!-- <view class="tableBar" @tap="tab_setting">
+				<image src="/static/images/setting2x.png"></image>
+				<text>我的</text>
+			</view> -->
+			<!-- </view> -->
+		</view>
+	</view>
 </template>
 
 <script>
+	import $api from '@/static/js/api.js'
+	let disp = require("@/utils/broadcast");
+	var WebIM = require("@/utils/WebIM")["default"];
+	let isfirstTime = true;
+	import swipeDelete from "@/components/swipedelete/swipedelete";
+	import longPressModal from "@/components/longPressModal/index";
+	
+	var that = ''
+	export default {
+		data() {
+			return {
+				pageList1:[],
+				search_btn: true,
+				search_chats: false,
+				show_mask: false,
+				yourname: "",
+				unReadSpotNum: 0,
+				unReadNoticeNum: 0,
+				messageNum: 0,
+				unReadTotalNotNum: 0,
+				arr: [],
+				show_clear: false,
+				member: "",
+				isIPX: false,
+				gotop: false,
+				input_code: "",
+				
+				groupName: {},
+				winSize: {},
+				popButton: ["删除该聊天"],
+				showPop: false,
+				popStyle: "",
+				currentVal: '',
+				notice_num: 0,
+				message_num: 0
+			}
+		},
+		components: {
+			swipeDelete,
+			longPressModal,
+		},
+		props: {},
+		
+		onLoad() {
+			that = this
+			this.getWindowSize();
+			that.getNum()
+			let me = this;
+			//监听加好友申请
+			disp.on("em.subscribe", function() {
+				me.getChatList();
+				/* me.setData({
+					messageNum: getApp().globalData.saveFriendList.length,
+					unReadTotalNotNum: getApp().globalData.saveFriendList.length +
+						getApp().globalData.saveGroupInvitedList.length,
+				}); */
+			});
+			
+			//监听解散群
+			disp.on("em.invite.deleteGroup", function() {
+				me.listGroups();
+				me.getRoster();
+				me.getChatList();
+				me.messageNum= getApp().globalData.saveFriendList.length
+			});
+			
+			//监听未读消息数
+			disp.on("em.unreadspot", function(message) {
+				me.getChatList();
+				me.unReadSpotNum= getApp().globalData.unReadMessageNum > 99 ?
+						"99+" :
+						getApp().globalData.unReadMessageNum
+			});
+			
+			//监听未读加群“通知”
+			disp.on("em.invite.joingroup", function() {
+				me.unReadNoticeNum= getApp().globalData.saveGroupInvitedList.length
+				me.unReadTotalNotNum= getApp().globalData.saveFriendList.length +
+					getApp().globalData.saveGroupInvitedList.length
+			});
+			
+			disp.on("em.contacts.remove", function() {
+				me.getChatList();
+				me.getRoster();
+			});
+			
+			this.getRoster();
+		},
+		onShow: function() {
+			// uni.hideHomeButton();
+			this.getChatList();
+			console.log(uni.getStorageSync('rendered_cbz_46admin-10010'))
+			console.log('111111111',this.arr)
+			this.unReadSpotNum =
+				getApp().globalData.unReadMessageNum > 99 ?
+				"99+" :
+				getApp().globalData.unReadMessageNum
+			try{
+				this.messageNum = getApp().globalData.saveFriendList.length
+				this.unReadNoticeNum = getApp().globalData.saveGroupInvitedList.length
+				this.unReadTotalNotNum =
+					getApp().globalData.saveFriendList.length +
+					getApp().globalData.saveGroupInvitedList.length
+						
+			}catch(e){
+				//TODO handle the exception
+			}
+			if (getApp().globalData.isIPX) {
+				this.isIPX = true
+			}
+		},
+		methods: {
+			getNum() {
+				$api.req({
+					url: '/data/api.business.User/messagenoread',
+					method: 'POST',
+				}, function(res) {
+					if(res.code == 1) {
+						console.log(res)
+						that.notice_num = res.data.message_count
+						that.message_num = res.data.order_count
+					}
+				})
+			},
+			listGroups() {
+				var me = this;
+				return WebIM.conn.getGroup({
+					limit: 50,
+					success: function(res) {
+						let groupName = {};
+						let listGroup = res.data || [];
+						listGroup.forEach((item) => {
+							groupName[item.groupid] = item.groupname;
+						});
+			
+						me.groupName= groupName,
+						uni.setStorage({
+							key: "listGroup",
+							data: res.data,
+						});
+						me.getChatList();
+					},
+					error: function(err) {
+						console.log(err);
+					},
+				});
+			},
+			
+			getRoster() {
+				let me = this;
+				let rosters = {
+					success(roster) {
+						var member = [];
+						for (let i = 0; i < roster.length; i++) {
+							if (roster[i].subscription == "both") {
+								member.push(roster[i]);
+							}
+						}
+						uni.setStorage({
+							key: "member",
+							data: member,
+						});
+						me.member= member
+						me.listGroups();
+						//if(!systemReady){
+						disp.fire("em.main.ready");
+						//systemReady = true;
+						//}
+						me.arr= me.getChatList(),
+						console.log('消息列表:',me.arr);
+						me.unReadSpotNum= getApp().globalData.unReadMessageNum > 99 ?
+							"99+" :
+							getApp().globalData.unReadMessageNum
+					},
+					error(err) {
+						console.log(err);
+					},
+				};
+				WebIM.conn.getRoster(rosters);
+			},
+			
+			/* // // 不包含陌生人版本
+			// getChatList() {
+			//   var array = [];
+			//   var member = uni.getStorageSync("member");
+			//   var myName = uni.getStorageSync("myUsername");
+			//   var listGroups = uni.getStorageSync('listGroup') || [];
+			
+			//   for (let i = 0; i < member.length; i++) {
+			//     let newChatMsgs = uni.getStorageSync(member[i].name + myName) || [];
+			//     let historyChatMsgs = uni.getStorageSync("rendered_" + member[i].name + myName) || [];
+			//     let curChatMsgs = historyChatMsgs.concat(newChatMsgs);
+			
+			//     if (curChatMsgs.length) {
+			//       let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];
+			//       lastChatMsg.unReadCount = newChatMsgs.length;
+			
+			//       if (lastChatMsg.unReadCount > 99) {
+			//         lastChatMsg.unReadCount = "99+";
+			//       }
+			
+			//       let dateArr = lastChatMsg.time.split(' ')[0].split('-');
+			//       let timeArr = lastChatMsg.time.split(' ')[1].split(':');
+			//       let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2];
+			//       lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+			//       lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+			//       array.push(lastChatMsg);
+			//     }
+			//   }
+			
+			//   for(let i = 0; i < listGroups.length; i++){
+			//  let newChatMsgs = uni.getStorageSync(listGroups[i].groupid + myName) || [];
+			//  let historyChatMsgs = uni.getStorageSync("rendered_" + listGroups[i].groupid + myName) || [];
+			//  let curChatMsgs = historyChatMsgs.concat(newChatMsgs);
+			//  if(curChatMsgs.length){
+			//    let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];
+			//    lastChatMsg.unReadCount = newChatMsgs.length;
+			//    if(lastChatMsg.unReadCount > 99) {
+			//      lastChatMsg.unReadCount = "99+";
+			//    }
+			//    let dateArr = lastChatMsg.time.split(' ')[0].split('-')
+			//    let timeArr = lastChatMsg.time.split(' ')[1].split(':')
+			//    let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2]
+			//    lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`
+			//    lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`
+			//    lastChatMsg.groupName = listGroups[i].groupname
+			//    array.push(lastChatMsg);
+			//  }
+			// }
+			
+			//   array.sort((a, b) => {
+			//     return b.dateTimeNum - a.dateTimeNum;
+			//   });
+			//   return array;
+			// }, */
+			
+			// 包含陌生人版本
+			getChatList() {
+				var myName = uni.getStorageSync("myUsername");
+				var array = [];
+				const me = this;
+				uni.getStorageInfo({
+					success: function(res) {
+						let storageKeys = res.keys;
+						let newChatMsgKeys = [];
+						let historyChatMsgKeys = [];
+						let len = myName.length;
+						storageKeys.forEach((item) => {
+							if (item.slice(-len) == myName && item.indexOf("rendered_") == -1) {
+								newChatMsgKeys.push(item);
+							} else if (
+								item.slice(-len) == myName &&
+								item.indexOf("rendered_") > -1
+							) {
+								historyChatMsgKeys.push(item);
+							} else if (item === "INFORM") {
+								newChatMsgKeys.push(item);
+							}
+						});
+			
+						cul.call(me, newChatMsgKeys, historyChatMsgKeys);
+					},
+				});
+			
+				function cul(newChatMsgKeys, historyChatMsgKeys) {
+					let array = [];
+					let lastChatMsg;
+			
+					for (let i = historyChatMsgKeys.length; i > 0, i--;) {
+						let index = newChatMsgKeys.indexOf(historyChatMsgKeys[i].slice(9));
+						if (index > -1) {
+							let newChatMsgs = uni.getStorageSync(newChatMsgKeys[index]) || [];
+							if (newChatMsgKeys.includes()) {}
+							if (newChatMsgs.length) {
+								lastChatMsg = newChatMsgs[newChatMsgs.length - 1];
+								lastChatMsg.unReadCount = newChatMsgs.length;
+								if (lastChatMsg.unReadCount > 99) {
+									lastChatMsg.unReadCount = "99+";
+								}
+								let dateArr = lastChatMsg.time.split(" ")[0].split("-");
+								let timeArr = lastChatMsg.time.split(" ")[1].split(":");
+								let month = dateArr[2] < 10 ? "0" + dateArr[2] : dateArr[2];
+								lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+								lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+								newChatMsgKeys.splice(index, 1);
+							} else {
+								let historyChatMsgs = uni.getStorageSync(historyChatMsgKeys[i]);
+								if (historyChatMsgs.length) {
+									lastChatMsg = historyChatMsgs[historyChatMsgs.length - 1];
+									let dateArr = lastChatMsg.time.split(" ")[0].split("-");
+									let timeArr = lastChatMsg.time.split(" ")[1].split(":");
+									let month = dateArr[2] < 10 ? "0" + dateArr[2] : dateArr[2];
+									lastChatMsg.dateTimeNum =
+										`${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+									lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+								}
+							}
+						} else {
+							let historyChatMsgs = uni.getStorageSync(historyChatMsgKeys[i]);
+							if (historyChatMsgs.length) {
+								lastChatMsg = historyChatMsgs[historyChatMsgs.length - 1];
+								let dateArr = lastChatMsg.time.split(" ")[0].split("-");
+								let timeArr = lastChatMsg.time.split(" ")[1].split(":");
+								let month = dateArr[2] < 10 ? "0" + dateArr[2] : dateArr[2];
+								lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+								lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+							}
+						}
+						if (
+							lastChatMsg &&
+							(lastChatMsg.chatType == "groupchat" ||
+								lastChatMsg.chatType == "chatRoom")
+						) {
+							lastChatMsg.groupName = me.groupName[lastChatMsg.info.to];
+						}
+						lastChatMsg && lastChatMsg.username != myName &&
+							array.push(lastChatMsg);
+					}
+			
+					for (let i = newChatMsgKeys.length; i > 0, i--;) {
+						let newChatMsgs = uni.getStorageSync(newChatMsgKeys[i]) || [];
+						if (newChatMsgs.length) {
+							lastChatMsg = newChatMsgs[newChatMsgs.length - 1];
+							lastChatMsg.unReadCount = newChatMsgs.length;
+							if (lastChatMsg.unReadCount > 99) {
+								lastChatMsg.unReadCount = "99+";
+							}
+							let dateArr = lastChatMsg.time.split(" ")[0].split("-");
+							let timeArr = lastChatMsg.time.split(" ")[1].split(":");
+							let month = dateArr[2] < 10 ? "0" + dateArr[2] : dateArr[2];
+							lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+							lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+							if (
+								lastChatMsg.chatType == "groupchat" ||
+								lastChatMsg.chatType == "chatRoom"
+							) {
+								lastChatMsg.groupName = me.groupName[lastChatMsg.info.to];
+							}
+							lastChatMsg.username != myName && array.push(lastChatMsg);
+						}
+					}
+			
+					array.sort((a, b) => {
+						return b.dateTimeNum - a.dateTimeNum;
+					});
+					this.arr= array
+					console.log('this.arr',this.arr)
+				}
+			},
+			
+			openSearch: function() {
+				this.search_btn= false
+				this.search_chats= true
+				this.gotop= true
+			},
+			
+			onSearch: function(val) {
+				let searchValue = val.detail.value;
+				var myName = uni.getStorageSync("myUsername");
+				const me = this;
+				let serchList = [];
+				let arr = [];
+				uni.getStorageInfo({
+					success: function(res) {
+						let storageKeys = res.keys;
+						let chatKeys = [];
+						let len = myName.length;
+						storageKeys.forEach((item) => {
+							if (item.slice(-len) == myName) {
+								chatKeys.push(item);
+							}
+						});
+						chatKeys.forEach((item, index) => {
+							if (item.indexOf(searchValue) != -1) {
+								serchList.push(item);
+							}
+						});
+						let lastChatMsg = "";
+						serchList.forEach((item, index) => {
+							let chatMsgs = uni.getStorageSync(item) || [];
+							if (chatMsgs.length) {
+								lastChatMsg = chatMsgs[chatMsgs.length - 1];
+			
+								let dateArr = lastChatMsg.time.split(" ")[0].split("-");
+								let timeArr = lastChatMsg.time.split(" ")[1].split(":");
+								let month = dateArr[2] < 10 ? "0" + dateArr[2] : dateArr[2];
+								lastChatMsg.dateTimeNum =
+									`${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;
+								lastChatMsg.time =
+									`${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}:${timeArr[1]}`;
+								arr.push(lastChatMsg);
+							}
+						});
+						me.arr = arr
+					},
+				});
+			},
+			leftClick() {},
+			cancel: function() {
+				this.getChatList();
+				this.search_btn= true
+				this.search_chats= false
+				//arr: this.getChatList(),
+				this.unReadSpotNum= getApp().globalData.unReadMessageNum > 99 ? "99+" : getApp().globalData.unReadMessageNum
+				this.gotop= false
+			},
+			clearInput: function() {
+				this.input_code= ""
+				this.show_clear= false
+			},
+			onInput: function(e) {
+				let inputValue = e.detail.value;
+				if (inputValue) {
+					this.show_clear= true
+				} else {
+					this.show_clear= false
+				}
+			},
+			tab_contacts: function() {
+				uni.redirectTo({
+					url: "../main/main?myName=" + uni.getStorageSync("myUsername"),
+				});
+			},
+			close_mask: function() {
+				this.search_btn= true
+				this.search_chats= false
+				this.show_mask= false
+			},
+			tab_setting: function() {
+				uni.redirectTo({
+					url: "../setting/setting",
+				});
+			},
+			tab_notification: function() {
+				uni.redirectTo({
+					url: "../notification/notification",
+				});
+			},
+			into_chatRoom: function(event) {
+				let detail = event.currentTarget.dataset.item;
+				if (
+					detail.chatType == "groupchat" ||
+					detail.chatType == "chatRoom" ||
+					detail.groupName
+				) {
+					this.into_groupChatRoom(detail);
+				} else {
+					this.into_singleChatRoom(detail);
+				}
+			},
+			// 单聊
+			into_singleChatRoom: function(detail) {
+				console.log('detail',detail);
+				var my = uni.getStorageSync("myUsername");
+				var nameList = {
+					myName: my,
+					your: detail.username,
+				};
+				uni.navigateTo({
+					url: "/pages/chatroom/chatroom?username=" + JSON.stringify(nameList),
+				});
+			},
+			// 群聊 和 聊天室 (两个概念)
+			into_groupChatRoom: function(detail) {
+				var my = uni.getStorageSync("myUsername");
+				var nameList = {
+					myName: my,
+					your: detail.groupName,
+					groupId: detail.info.to,
+				};
+				uni.navigateTo({
+					url: "../groupChatRoom/groupChatRoom?username=" + JSON.stringify(nameList),
+				});
+			},
+			
+			into_inform: function() {
+				uni.redirectTo({
+					url: "../notification/notification",
+				});
+			},
+			
+			removeAndRefresh: function(event) {
+				let removeId = event.currentTarget.dataset.item.info.from
+				let ary = getApp().globalData.saveFriendList
+				let idx
+				if (ary.length > 0) {
+					ary.forEach((v, k) => {
+						if (v.from == removeId) {
+							idx = k
+						}
+					})
+					getApp().globalData.saveFriendList.splice(idx, 1);
+				}
+				uni.removeStorageSync('INFORM')
+			},
+			
+			del_chat: function(event) {
+				let detail = event.currentTarget.dataset.item;
+				let nameList = {};
+				let me = this;
+				// 删除当前选中群组聊天列表
+				if (detail.chatType == "groupchat" || detail.chatType == "chatRoom") {
+					nameList = {
+						your: detail.info.to,
+					};
+					//删除当前选中通知列表
+				} else if (detail.chatType === "INFORM") {
+					nameList = {
+						your: "INFORM",
+					};
+				}
+				//删除当前选中好友聊天列表
+				else {
+					nameList = {
+						your: detail.username,
+					};
+				}
+				var myName = uni.getStorageSync("myUsername");
+				var currentPage = getCurrentPages();
+			
+				uni.showModal({
+					title: "确认删除?",
+					confirmText: "删除",
+					success: function(res) {
+						if (res.confirm) {
+							uni.removeStorageSync(nameList.your + myName);
+							uni.removeStorageSync("rendered_" + nameList.your + myName);
+							nameList.your === 'INFORM' && me.removeAndRefresh(event);
+							// if (Object.keys(currentPage[0]).length>0) {
+							//   currentPage[0].onShow();
+							// }
+							disp.fire("em.chat.session.remove");
+							me.getChatList();
+						}
+					},
+					fail: function(err) {
+						console.log('删除列表', err);
+					},
+				});
+			},
+			longpress: function(e) {
+				//将当前选中的值存在data中方便后续操作
+				this.currentVal = e
+				let [touches, style, index] = [e.touches[0], "", e.currentTarget.dataset.index, ];
+			
+				/* 因 非H5端不兼容 style 属性绑定 Object ,所以拼接字符 */
+				if (touches.clientY > this.winSize.height / 2) {
+					style = `bottom:${this.winSize.height - touches.clientY}px;`;
+				} else {
+					style = `top:${touches.clientY}px;`;
+				}
+				if (touches.clientX > this.winSize.witdh / 2) {
+					style += `right:${this.winSize.witdh - touches.clientX}px`;
+				} else {
+					style += `left:${touches.clientX}px`;
+				}
+			
+				this.popStyle = style;
+				// this.pickerUserIndex = Number(index);
+				this.showShade = true;
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.showPop = true;
+					}, 10);
+				});
+			},
+			/* 获取窗口尺寸 */
+			getWindowSize() {
+				uni.getSystemInfo({
+					success: (res) => {
+						this.winSize = {
+							witdh: res.windowWidth,
+							height: res.windowHeight,
+						};
+					},
+				});
+			},
+			hidePop() {
+				this.showPop = false;
+			},
+			pickerMenuChange() {
+				console.log("当前选中>>", this.currentVal);
+				this.del_chat(this.currentVal)
+			},
+			toList(index) {
+				$api.jump('/pages/mine/message/list?index=' + index)
+			}
+		},
+	}
 </script>
 
-<style>
+<style lang="scss" scoped>
+	@import "./chat.css";
+	.content {
+		padding: 0 30rpx;
+		background-color: #fff;
+		.list {
+			width: 100%;
+			.list_item {
+				width: 100%;
+				margin: 48rpx 0 36rpx;
+				position: relative;
+				.item_img {
+					width: 88rpx;
+					height: 88rpx;
+					border-radius: 50%;
+					
+				}
+				.number {
+					position: absolute;
+					top: 5rpx;
+					left: 70rpx;
+					width: 32rpx;
+					height: 32rpx;
+					background-color: #ff4b4b;
+					border: 1rpx solid #fff;
+					border-radius: 50%;
+					font-size: 24rpx;
+					color: #fff;
+					text-align: center;
+					line-height: 32rpx;
+				}
+				.item_right {
+					width: calc(100% - 108rpx);
+					padding-left: 20rpx;
+					.name {
+						font-size: 28rpx;
+						color: #222;
+					}
+					.text_style1 {
+						font-size: 24rpx;
+						color: #999;
+					}
+					.text_style2 {
+						margin-left: 10rpx;
+						width: 56rpx;
+						height: 28rpx;
+						border-radius: 8rpx;
+						border: 1rpx solid #506dff;
+						font-size: 20rpx;
+						color: #506dff;
+						text-align: center;
+						line-height: 28rpx;
+					}
+				}
+			}
+		}
+	}
 </style>

+ 164 - 1
pages/mine/message/list.vue

@@ -1,8 +1,171 @@
 <template>
+	<view class="content">
+		<view class="list" v-if="type=='1'">
+			<block v-for="(item,index) in pageList" :key="index">
+				<view class="box" @click="toDetail(index)">
+					<view class="hflex acenter">
+						<view class="dian" v-if="item.is_read == 0"></view>
+						<view class="title">{{item.title}}</view>
+					</view>
+					<u-parse :content="item.content"></u-parse>
+				</view>
+			</block>
+		</view>
+		<view class="list vflex acenter" v-if="type == '2'">
+			<block v-for="(item,index) in pageList" :key="index">
+				<view class="time">{{item.create_time}}</view>
+				<view class="box">
+					<view class="status" v-if="item.title == '买家拍下商品'">{{item.title}}</view>
+					<view class="status" v-if="item.title == '买家已经付款'" style="color: #4D6DFF;">{{item.title}}</view>
+					<view class="status" v-if="item.title == '订单被取消了'" style="color: #FF4D4D;">{{item.title}}</view>
+					<view class="hflex acenter">
+						<image :src="item.image" class="image" mode="aspectFill"></image>
+						<view class="vflex jcenter">
+							<view class="name">{{item.content}}</view>
+							<view class="text">{{item.remark}}</view>
+						</view>
+					</view>
+				</view>
+			</block>
+		</view>
+	</view>
 </template>
 
 <script>
+	import $api from '@/static/js/api.js'
+	var that = ''
+	export default {
+		data() {
+			return {
+				id: '',
+				pageList: [],
+				page: 1,
+				total: 1,
+				type: '',
+			}
+		},
+		onLoad(options) {
+			that = this
+			that.type = options.index
+			// that.getList()
+		},
+		onShow() {
+			that.getList()
+		},
+		methods: {
+			getList() {
+				console.log('type=' +that.type);
+				$api.req({
+					url: '/data/api.business.User/message_list',
+					method: 'POST',
+					data: {
+						page:that.page,
+						type: that.type
+					}
+				}, function(res) {
+					console.log(res)
+					if(res.code == 1) {
+						
+						if(that.page == 1) {
+							that.pageList = res.data.data
+						} else {
+							that.pageList = that.pageList.concat(res.data.data)
+						}
+						that.total = res.data.length
+					}
+				})
+			},
+			// 查看详情
+			toDetail(index) {
+				$api.jump('/pages/mine/message/detail?id=' + that.pageList[index].id)
+			},
+			onReachBottom() {
+				if (Number(that.page) * 15 >= Number(that.total)) {
+					$api.info("没有更多了")
+				} else {
+					that.page++
+					that.getList()
+				}
+				
+			}
+		},
+	}
 </script>
 
-<style>
+<style lang="scss" scoped>
+	.content {
+		background-color: #F4F4F4;
+		padding: 0 30rpx;
+		.list {
+			width: 100%;
+			.time {
+				margin-top: 20rpx;
+				max-width: 100%;
+				width: max-content;
+				text-align: center;
+				font-size: 20rpx;
+				font-weight: 400;
+				color: #FFFFFF;
+				line-height: 28rpx;
+				padding: 6rpx 24rpx;
+				background: #CECECE;
+				border-radius: 20rpx;
+			}
+			.box {
+				width: 100%;
+				box-sizing: border-box;
+				padding: 20rpx 20rpx ;
+				background-color: #fff;
+				border-radius: 24rpx;
+				margin-top: 20rpx;
+				.dian {
+					width: 12rpx;
+					height: 12rpx;
+					border-radius: 50%;
+					background-color: #ff4646;
+					margin-right: 8rpx;
+				}
+				.title {
+					font-size: 32rpx;
+					color: #222;
+					font-weight: 600;
+					margin-bottom: 20rpx;
+				}
+				.status {
+					font-size: 26rpx;
+					font-weight: 500;
+					color: #FF874D;
+					line-height: 36rpx;
+					padding-bottom: 16rpx;
+				}
+				.image {
+					width: 156rpx;
+					height: 156rpx;
+					border-radius: 16rpx;
+					margin-right: 18rpx;
+				}
+				.name {
+					font-size: 28rpx;
+					font-weight: 400;
+					color: #222222;
+					line-height: 40rpx;
+					max-width: 470rpx;
+					text-overflow: ellipsis;
+					overflow: hidden;
+					display: -webkit-box;
+					-webkit-box-orient: vertical;
+					box-orient: vertical;
+					line-clamp: 2;
+					-webkit-line-clamp: 2;
+				}
+				.text {
+					font-size: 24rpx;
+					font-weight: 400;
+					color: #929292;
+					line-height: 34rpx;
+					padding-top: 22rpx;
+				}
+			}
+		}
+	}
 </style>

+ 46 - 10
pages/mine/service/address/add.vue

@@ -9,18 +9,18 @@
 				<view class="left">手机号码</view>
 				<u-input v-model="phone" border="none" placeholder="请填写收货人手机号码"></u-input>
 			</view>
-			<view class="hflex acenter jbetween item">
+			<view class="hflex acenter jbetween item" @click="selectmap">
 				<view class="left">所在地区</view>
-				<comp-select-address :addressStr="areas" class="address" @selectAddress="selectAddress">
+				<!-- <comp-select-address :addressStr="areas" class="address" @selectAddress="selectAddress">
 					
-				</comp-select-address>
-				<!-- <u-input v-model="areas" border="none" disabled disabledColor="#fff" placeholder="请选择所在地区"></u-input> -->
+				</comp-select-address> -->
+				<u-input v-model="areas" border="none" disabled disabledColor="#fff" placeholder="请选择所在地区"></u-input>
 				<u-icon name="map-fill" color="#506DFF" size="13"></u-icon>
 			</view>
 			
-			<view class="hflex acenter jbetween item">
+			<view class="hflex jbetween item">
 				<view class="left">详细地址</view>
-				<u-input v-model="address" border="none" placeholder="请输入街道、楼牌号"></u-input>
+				<u-textarea v-model="address" border="none" placeholder="请输入街道、楼牌号"></u-textarea>
 			</view>
 			<!-- <view class="hflex acenter jbetween item">
 				<view class="left">设为默认地址</view>
@@ -45,12 +45,15 @@
 				phone: '',
 				province: '',
 				city: '',
-				area: '',
+				// area: '',
 				areas: '',
 				address: '',
 				is_active: false,
 				is_edit: 0,
-				id: ''
+				id: '',
+				latitude: 0,
+				longitude: 0,
+				mapKey: '24f36a47991198151dae0d0168c154fe'
 			}
 		},
 		onLoad(options) {
@@ -71,7 +74,7 @@
 				that.province = data.province
 				that.city = data.city
 				that.area = data.area
-				that.areas = data.province + that.city + that.area
+				that.areas = that.province + that.city + that.area
 				that.address = data.address
 				
 				that.id = data.id
@@ -170,18 +173,51 @@
 						$api.jump(-1)
 					}
 				})
+			},
+			selectmap() {
+				uni.chooseLocation({
+					success: function (res) {
+						console.log(res);
+						// that.areas = res.name
+						that.address = res.address
+						that.longitude = res.longitude
+						that.latitude = res.latitude
+						uni.request({
+							url:'https://restapi.amap.com/v3/geocode/regeo?output=JSON&location='+res.longitude+','+ res.latitude +'&key=' + that.mapKey + '&radius=1000&extensions=all',
+							method: 'GET',
+							success(res) {
+								console.log(res)
+								let data = res.data.regeocode.addressComponent
+								console.log(data);
+								// this_.city=data.city
+								that.province = data.province
+								that.city = data.city
+								that.area = data.district
+								that.areas = that.province + that.city + that.area
+							},
+							fail(error) {
+								console.log(error);
+							}
+						});
+					},
+					fail: (err) => {
+					}
+				});
 			}
 		},
 	}
 </script>
 
 <style lang="scss" scoped>
-	.content {
+	.content::v-deep {
 		padding: 0 30rpx;
 		.form {
 			margin-top: 22rpx;
 			.item {
 				padding: 26rpx 0;
+				.u-textarea {
+					padding: 0 !important;
+				}
 			}
 			.left {
 				width: 200rpx;

+ 175 - 31
pages/mine/service/detail.vue

@@ -1,15 +1,15 @@
 <template>
 	<view class="content">
 		<view class="box hflex acenter">
-			<view class="img_box">
+			<view class="img_box" @click="replace">
 				<image :src="pageData.head_img" class="img"></image>
-				<view class="img_bottom hflex acenter jcenter" @click="replace">点击替换</view>
+				<view class="img_bottom hflex acenter jcenter">点击替换</view>
 			</view>
 			<view class="vflex img_right">
 				<view class="top_title">{{pageData.company}}</view>
 				<view class="hflex acenter jbetween">
 					<view class="addr">{{pageData.address}}</view>
-					<image src="/static/images/mine/address_icon.png" style="width: 44rpx;height: 44rpx;"></image>
+					<image src="/static/images/mine/address_icon.png" style="width: 44rpx;height: 44rpx;" @click="openMap"></image>
 				</view>
 			</view>
 		</view>
@@ -31,21 +31,23 @@
 			</view>
 			<view class="cell">
 				<view class="left">商家简介</view>
-				<u-textarea v-model="pageData.intro" :disabled="!is_edit"></u-textarea >
+				<u-textarea v-model="pageData.intro" confirmType="done" :disabled="!is_edit"></u-textarea >
 			</view>
 			<view class="cell">
 				<view class="left">图片及视频</view>
 			</view>
-			<view class="imgs" v-if="!is_edit">
+			<view class="imgs hflex acenter fwrap">
 				<block v-for="(item,index) in pageData.imgs_videos" :key="index">
-					<image :src="item.url" class="img" v-if="item.type == 'image'"></image>
-					<video :src="item.url" class="img" v-if="item.type == 'video'"></video>
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image v-if="is_edit" src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image v-if="is_edit" src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic(index)"></image>
+					</view>
 				</block>
-			</view>
-			<view class="imgs" v-else>
-				<u-upload :fileList="pageData.imgs_videos" :accept='accept' @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx">
-					<image src="/static/images/common/upload_img.png" style="width: 200rpx;height: 200rpx;"></image>
-				</u-upload>
+				<image  src="/static/images/common/upload_img.png" class="img" @click="choose"></image>
 			</view>
 		</view>
 		<view class="box">
@@ -57,6 +59,19 @@
 		<view class="btn hflex acenter jcenter" @click="save">
 			保存
 		</view>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -68,7 +83,7 @@
 			return {
 				pageData: {},
 				is_edit: false,
-				accept: ['image','video'],
+				show_choose: false
 			}
 		},
 		onLoad() {
@@ -80,24 +95,21 @@
 				var pages = getCurrentPages()
 				var prePage = pages[pages.length - 2]
 				that.pageData = prePage.$vm.user.merchant
+				// that.pageData.imgs_videos = that.pageData.imgs_videos[0].split(',')
+				console.log(that.pageData.imgs_videos);
 				for(var i=0;i<that.pageData.imgs_videos.length;i++) {
-					if(!that.pageData.imgs_videos[i].type) {
-						var img = that.pageData.imgs_videos[i].split('.')
-						var type = ''
-						console.log(img);
-						if(img[img.length - 1] == 'mp4') {
-							type = 'video'
-						} else if(img[img.length - 1] == 'jpg' || img[img.length - 1] == 'png' || img[img.length - 1] == 'jpeg' || img[img.length - 1] == 'gif') {
-							type = 'image'
+					if(that.pageData.imgs_videos[i].substr(-3) == 'mp4' || that.pageData.imgs_videos[i].substr(-3) == 'flv') {
+						that.pageData.imgs_videos[i] = {
+							url: that.pageData.imgs_videos[i],
+							type: 'video'
 						}
-						var data = {
-							type: type,
-							url: that.pageData.imgs_videos[i]
+					} else {
+						that.pageData.imgs_videos[i] = {
+							url: that.pageData.imgs_videos[i],
+							type: 'image'
 						}
-						that.pageData.imgs_videos.splice(i,1,data)
 					}
 				}
-				console.log(that.pageData);
 			},
 			replace() {
 				uni.chooseImage({
@@ -128,15 +140,35 @@
 					}
 				});
 			},
+			openMap() {
+				console.log(typeof(that.pageData.latitude));
+				uni.openLocation({
+					latitude: Number(that.pageData.latitude),
+					longitude: Number(that.pageData.longitude),
+					success: function (res) {
+						console.log('success',res);
+					},
+					fail: function (err) {
+						console.log('err',err);
+					}
+				});
+			},
 			edit() {
 				that.is_edit = true
 			},
+			close() {
+				that.show_choose = false
+			},
 			// 删除图片
 			deletePic(event) {
-				that.pageData.imgs_videos.splice(event.index, 1)
+				that.pageData.imgs_videos.splice(event, 1)
 			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				let lists = [].concat(event.file)
 				let fileListLen = that.pageData.imgs_videos.length
 				lists.map((item) => {
@@ -155,12 +187,15 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 			},
 			uploadFilePromise(url) {
 				return new Promise((resolve, reject) => {
 					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
 						filePath: url,
 						name: 'file',
 						header: {
@@ -187,11 +222,14 @@
 				})
 			},
 			save() {
+				console.log(that.pageData.imgs_videos);
+				
 				var imgs_videos = ""
 				for(var i=0;i<that.pageData.imgs_videos.length;i++) {
-					imgs_videos+=that.pageData.imgs_videos[i].url + ''
+					imgs_videos+=that.pageData.imgs_videos[i].url + ','
 				}
 				imgs_videos = imgs_videos.substr(0,imgs_videos.length - 1)
+				// that.pageData.imgs_videos = JSON.stringify(that.pageData.imgs_videos)
 				$api.req({
 					url: '/data/api.business.User/edit',
 					method: 'POST',
@@ -209,6 +247,97 @@
 					}
 				})
 			},
+			choose() {
+				that.show_choose = true
+			},
+			async choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.pageData.imgs_videos.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.pageData.imgs_videos.push(item)
+								console.log('上传完图片内容',that.pageData.imgs_videos);
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						console.log('选择视频',res);
+						let fileListLen = that.pageData.imgs_videos.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.pageData.imgs_videos.push(item)
+								uni.hideLoading()
+								console.log('上传完图片内容',that.pageData.imgs_videos);
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			}
 		},
 	}
 </script>
@@ -232,8 +361,12 @@
 				margin-right: 20rpx;
 				position: relative;
 				.img {
-					width: 100%;
-					height: 100%;
+					width: 200rpx;
+					height: 200rpx;
+				}
+				video {
+					width: 200rpx;
+					height: 200rpx;
 				}
 				.img_bottom {
 					position: absolute;
@@ -315,6 +448,14 @@
 				.img:nth-child(3n+3) {
 					margin: 0 0 20rpx;
 				}
+				.close_icon {
+					position: absolute;
+					top: 0;
+					right: 15rpx;
+					width: 30rpx;
+					height: 30rpx;
+					z-index: 99;
+				}
 			}
 		}
 		.btn {
@@ -328,5 +469,8 @@
 			color: #FFFFFF;
 			line-height: 50rpx;
 		}
+		.choose {
+			padding: 20rpx 0;
+		}
 	}
 </style>

+ 2 - 2
pages/mine/service/feed/detail.vue

@@ -14,10 +14,10 @@
 		</view>
 		<view class="box" v-if="detail.reply">
 			<view class="hflex acenter jbetween box_top">
-				<view class="title">回复</view>
+				<view class="title" style="color: #506DFF;">回复</view>
 				<view class="text_style1">{{detail.reply_time}}</view>
 			</view>
-			<view class="text">{{detail.repaly}}</view>
+			<view class="text">{{detail.reply}}</view>
 		</view>
 	</view>
 </template>

+ 25 - 13
pages/mine/service/feed/feed.vue

@@ -9,15 +9,15 @@
 			</u-navbar>
 			<view class="box">
 				<view class="top">
-					<u-input v-model="title" border="bottom" placeholder="请填写标题(最多18个字)"></u-input>
-					<u--textarea v-model="problem" placeholder="请填写具体描述" ></u--textarea>
+					<u-input v-model="title" maxlength="18" border="bottom" placeholder="请填写标题(最多18个字)"></u-input>
+					<u-textarea v-model="problem" confirmType="done" placeholder="请填写具体描述" ></u-textarea>
 				</view>
 				
 			</view>
 			<view class="box">
 				<view class="left">请提供问题截图或者照片(选题)</view>
 				<view class="upload">
-					<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" :maxCount="9" name="1" multiple :previewFullImage="true" width="204rpx" height="204rpx">
+					<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" :maxCount="9" name="1" multiple :previewFullImage="true" width="200rpx" height="200rpx">
 						<image src="/static/images/common/image_add.png" style="width: 204rpx; height: 204rpx	;"></image>
 					</u-upload>
 				</view>
@@ -69,15 +69,20 @@
 					if(list[i].id == id) {
 						that.title = list[i].title
 						that.problem = list[i].content
-						var imgs = list[i].image.split(',')
-						let obj = {}
-						for(let key in imgs) {
-							obj[key] = imgs[key]
+						if(list[i].image) {
+							var imgs = list[i].image.split(',')
+							let obj = {}
+							for(let key in imgs) {
+								obj[key] = imgs[key]
+							}
+							var fileList1 = Object.keys(obj).map(item => ({
+								url: obj[item]
+							}))
+							that.fileList1 = fileList1
+						} else {
+							that.fileList1 = []
 						}
-						var fileList1 = Object.keys(obj).map(item => ({
-							url: obj[item]
-						}))
-						that.fileList1 = fileList1
+						
 						that.phone = list[i].phone
 					}
 				}
@@ -90,6 +95,10 @@
 			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				console.log(`fileList${event.name}`);
 				console.log(this[`fileList${event.name}`]);
 				let lists = [].concat(event.file)
@@ -110,6 +119,9 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 			},
 			// 上传图片
@@ -163,7 +175,7 @@
 							if(res.code == 1) {
 								console.log(res);
 								$api.info(res.info)
-								$api.jump('/pages/tabbar/mine/mine',3)
+								$api.jump('/pages/tabbar/mine/mine',2)
 							}
 						})
 					} else {
@@ -219,7 +231,7 @@
 			}
 			.top {
 				.u-input {
-					padding: 28rpx 0 !important;
+					padding: 0 0 28rpx !important;
 				}
 				.u-textarea {
 					// margin: 28rpx auto 0;

+ 15 - 2
pages/mine/service/feed/history.vue

@@ -9,7 +9,7 @@
 					<view class="date">{{item.create_time}}</view>
 					<view class="hflex acenter">
 						<view class="btn" @click.stop="detele(item.id)">删除</view>
-						<view class="btn1" @click.stop="toEdit(item.id)" v-if="!item.reply">编辑</view>
+						<view class="btn1" v-if="!item.reply" @click.stop="toEdit(item.id)">编辑</view>
 					</view>
 				</view>
 			</view>
@@ -32,6 +32,8 @@
 		},
 		onLoad() {
 			that = this
+		},
+		onShow() {
 			that.getList()
 		},
 		methods: {
@@ -123,7 +125,18 @@
 				white-space: nowrap;
 				margin-bottom: 24rpx;
 				box-sizing: border-box;
-				padding: 0 8rpx 0 16rpx;
+				padding: 0 8rpx 0 36rpx;
+				position: relative;
+			}
+			.reply::before {
+				content: "";
+				position: absolute;
+				top: 34rpx;
+				left: 12rpx;
+				width: 12rpx;
+				height: 12rpx;
+				background: #506DFF;
+				border-radius: 50%;
 			}
 			.bottom {
 				width: 100%;

+ 218 - 87
pages/mine/service/purOrder/detail.vue

@@ -5,27 +5,27 @@
 			<view class="title" v-if="pageData.status == 1">暂无报价</view>
 			<view class="title" v-if="pageData.status == 2">已有报价</view>
 			<view class="title" v-if="pageData.status == 3 && pageData.tab !== 1">已匹配</view>
-			<view class="hflex acenter jbetween" v-if="pageData.status == 3 && pageData.tab == 1">
+			<!-- <view class="hflex acenter jbetween" v-if="pageData.status == 3 && pageData.tab == 1">
 				<view class="title">已匹配</view>
 				<view class="top_down hflex acenter jcenter" @click="select">
 					<image src="/static/images/common/down2.png" style="width: 36rpx;height: 36rpx;"></image>
 					<view class="">下载附件</view>
 				</view>
-			</view>
+			</view> -->
 		</view>
 		<view class="center">
 			<view class="box">
 				<view class="title">商品明细</view>
-				<block v-for="(item,index) in pageData.items">
+				<block v-for="(item,index) in pageData.items" :key="index">
 					<view class="item_bg">
 						<view class="item_name">{{item.name}}</view>
-						<view class="text_style1" v-if="tab !== '4'">规格:{{item.spec}}  数量:{{item.number}}</view>
+						<view class="text_style1" v-if="tab !== '4'">规格:{{item.spec}}  数量:{{item.number}}</view>
 						<view class="text_style1" v-else>数量/吨位:{{item.weight}}</view>
 						<view v-if="item.enclosure">
 							<block v-for="(item2,index2) in item.enclosure" :key="index2">
 								<view class="hflex acenter jbetween enclo">
 									<view class="enclo_name">{{item2.filename}}</view>
-									<view class="enclo_down hflex acenter jcenter" @click="open(index,index2)">
+									<view class="enclo_down hflex acenter jcenter" @click="open(item2.fileurl)">
 										<image src="/static/images/common/down_icon.png" style="width: 20rpx;height: 20rpx;"></image>
 										<view>下载附件</view>
 									</view>
@@ -34,10 +34,10 @@
 						</view>
 						<view class="text_style1" v-if="item.price">原采购价:<span class="price">¥{{item.price}}</span></view>
 						<view class="text_style1" v-if="item.standard">质量标准:{{item.standard}}</view>
-						<view class="hflex acenter jcenter" v-if="pageData.status == 1 && tab == '1'">
+						<view class="hflex acenter jcenter" v-if="!item.is_matched && tab == '1' && item.offers.length == 0">
 							<view class="item_btn hflex acenter jcenter">暂无报价</view>
 						</view>
-						<view class="hflex acenter jbetween offer_bg" v-if="pageData.status == 2 && tab == '1'">
+						<view class="hflex acenter jbetween offer_bg" v-if="!item.is_matched && tab == '1' && item.offers.length != 0">
 							<view class="bg_left">已有报价•{{item.offers.length}}条</view>
 							<view class="hflex acenter" @click="showOffer(index)">
 								<view class="top_text">{{!item.show?'展开':'隐藏'}}</view>
@@ -51,11 +51,12 @@
 									<view class="hflex acenter jbetween">
 										<view class="offer-user hflex acenter">
 											<image :src="item2.user.headimg" class="offer_avatar"></image>
-											<view class="user_name">{{item2.user.nickname}}</view>
+											<view class="user_name text_hide">{{item2.user.nickname}}</view>
 											<view class="renz hflex acenter jcenter">已认证</view>
 										</view>
 										<view class="offer_price">
-											报价:<span style="font-size: 36rpx;">¥{{item2.amount}}</span>
+											报价:<span style="font-size: 36rpx;" v-if="item2.amount">¥{{item2.amount}}</span>
+												<span style="font-size: 36rpx;" v-else>暂无报价</span>
 										</view>
 									</view>
 									<view class="hflex acenter jbetween offer_center">
@@ -63,32 +64,40 @@
 										<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(item2.user.phone)"></image>
 									</view>
 									<view class="hflex acenter jend offer_bottom">
-										<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(item2.user.id)">查看详情</view>
-										<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="match(item2.id)">匹配订单</view>
+										<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(index,index2)">查看详情</view>
+										<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(index,index2)">联系报价人</view>
+										<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="match(index,index2)">匹配订单</view>
 									</view>
 								</view>
 							</block>
 						</view>
-						<view class="offer_bg" v-if="tab == '1' && pageData.status == 3">
-							<view class="hflex acenter jbetween">
-								<view class="offer-user hflex acenter">
-									<image :src="pageData.offers[0].user.headimg" class="offer_avatar"></image>
-									<view class="user_name">{{pageData.offers[0].user.nickname}}</view>
-									<view class="renz hflex acenter jcenter">已认证</view>
-								</view>
-								<view class="offer_price">
-									报价:<span style="font-size: 36rpx;">¥{{pageData.offers[0].amount}}</span>
+						<view class="offer_bg" v-if="item.is_matched && tab == '1'">
+							<block v-for="(item1,index1) in item.offers" :key="index1">
+								<view class="">
+									<view class="hflex acenter jbetween">
+										<view class="offer-user hflex acenter">
+											<image :src="item1.user.headimg" class="offer_avatar"></image>
+											<view class="user_name text_hide">{{item1.user.nickname}}</view>
+											<view class="renz hflex acenter jcenter">已认证</view>
+										</view>
+										<view class="offer_price">
+											报价:<span style="font-size: 36rpx;" v-if="item1.amount">¥{{item1.amount}}</span>
+												<span style="font-size: 36rpx;" v-else>暂无报价</span>
+										</view>
+									</view>
+									<view class="hflex acenter jbetween offer_center">
+										<view class="tele">联系电话:{{item1.user.phone}}</view>
+										<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(item1.user.phone)"></image>
+									</view>
+									<view class="hflex acenter jend offer_bottom" v-if="item.offer_id == item1.id">
+										<view class="bottom_btn1 hflex acenter jcenter" @click="open(item.down_word)">下载文件</view>
+										<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(index,index1)">查看详情</view>
+										<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(index,index1)">联系接单人</view>
+										<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="remind(item1.user_id)">提醒完成</view>
+									</view>
 								</view>
-							</view>
-							<view class="hflex acenter jbetween offer_center">
-								<view class="tele">联系电话:{{pageData.offers[0].user.phone}}</view>
-								<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(pageData.offers[0].user.phone)"></image>
-							</view>
-							<view class="hflex acenter jend offer_bottom">
-								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(pageData.offers[0].user.id)">查看详情</view>
-								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(pageData.offers[0].user.id)">联系接单人</view>
-								<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter">提醒完成</view>
-							</view>
+							</block>
+							
 						</view>
 					</view>
 				</block>
@@ -98,31 +107,43 @@
 				<view class="cell">
 					<view class="right" v-if="pageData.standard_check">生产验收标准:<span class="left">{{pageData.standard_check}}</span></view>
 				</view>
-				<view class="title">图片/视频</view>
-				<view class="hflex acenter fwrap" v-if="tab == '1'">
+				<view class="title">上传图片</view>
+				<view class="hflex acenter fwrap" v-if="pageData.tab == 1">
 					<block v-for="(item,index) in pageData.images" :key="index">
 						<image v-if="item.type == 'image'" :src="item.src" class="img"></image>
-						<video v-else :src="item.src"  class="img"></video>
+						<video v-else direction="0" :src="item.src"  class="img"></video>
 					</block>
 				</view>
 				<view class="hflex acenter fwrap" v-else>
 					<block v-for="(item,index) in pageData.file" :key="index">
 						<image v-if="item.type == 'image'" :src="item.src" class="img"></image>
-						<video v-else :src="item.src"  class="img"></video>
+						<video v-else direction="0" :src="item.src"  class="img"></video>
 					</block>
 				</view>
-				<view class="hflex acenter cell">
+				<view class="hflex acenter cell" v-if="pageData.post_address">
 					<view class="left">交货地址:</view>
 					<view class="right">{{pageData.post_address}}</view>
 				</view>
-				<view class="hflex acenter cell">
+				<view class="hflex acenter cell" v-if="pageData.post_time">
 					<view class="left">交货日期:</view>
 					<view class="right">{{pageData.post_time}}</view>
 				</view>
-				<view class="hflex acenter cell">
+				<view class="hflex acenter cell" v-if="pageData.create_time">
 					<view class="left">发布时间:</view>
 					<view class="right">{{pageData.create_time}}</view>
 				</view>
+				<view class="hflex acenter cell" v-if="pageData.form">
+					<view class="left">包装形式:</view>
+					<view class="right">{{pageData.form}}</view>
+				</view>
+				<view class="hflex acenter cell" v-if="pageData.wharf_to">
+					<view class="left">装货码头:</view>
+					<view class="right">{{pageData.wharf_to}}</view>
+				</view>
+				<view class="hflex acenter cell" v-if="pageData.wharf_for">
+					<view class="left">到港码头:</view>
+					<view class="right">{{pageData.wharf_for}}</view>
+				</view>
 			</view>
 			<view class="box" v-if="pageData.status == 2 && tab !== '1'">
 				<view class="hflex acenter jbetween cell2">
@@ -139,11 +160,12 @@
 							<view class="hflex acenter jbetween">
 								<view class="offer-user hflex acenter">
 									<image :src="item2.user.headimg" class="offer_avatar"></image>
-									<view class="user_name">{{item2.user.nickname}}</view>
+									<view class="user_name text_hide">{{item2.user.nickname}}</view>
 									<view class="renz hflex acenter jcenter">已认证</view>
 								</view>
 								<view class="offer_price">
-									报价:<span style="font-size: 36rpx;">¥{{item2.amount}}</span>
+									报价:<span style="font-size: 36rpx;" v-if="item2.amount">¥{{item2.amount}}</span>
+												<span style="font-size: 36rpx;" v-else>暂无报价</span>
 								</view>
 							</view>
 							<view class="hflex acenter jbetween offer_center">
@@ -151,8 +173,9 @@
 								<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(item2.user.phone)"></image>
 							</view>
 							<view class="hflex acenter jend offer_bottom">
-								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(item2.user.id)">查看详情</view>
-								<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="match(item2.id)">匹配订单</view>
+								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail1(index2)">查看详情</view>
+								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail1(index2)">联系报价人</view>
+								<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="match(index,index2)">匹配订单</view>
 							</view>
 						</view>
 					</block>
@@ -161,37 +184,43 @@
 			</view>
 			<view class="box" v-if="tab !== '1' && pageData.status == 3">
 				<view class="bg_left cell2">接单人详情</view>
-				<view class="box_bg">
-					<view class="offer_bg">
-						<view class="hflex acenter jbetween">
-							<view class="offer-user hflex acenter">
-								<image :src="pageData.offers[0].user.headimg" class="offer_avatar"></image>
-								<view class="user_name">{{pageData.offers[0].user.nickname}}</view>
-								<view class="renz hflex acenter jcenter">已认证</view>
+				<block v-for="(item1,index1) in pageData.offers" :key="index1">
+					<view class="box_bg">
+						<view class="offer_bg">
+							<view class="hflex acenter jbetween">
+								<view class="offer-user hflex acenter">
+									<image :src="item1.user.headimg" class="offer_avatar"></image>
+									<view class="user_name text_hide">{{item1.user.nickname}}</view>
+									<view class="renz hflex acenter jcenter">已认证</view>
+								</view>
+								<view class="offer_price">
+									报价:<span style="font-size: 36rpx;" v-if="item1.amount">¥{{item1.amount}}</span>
+												<span style="font-size: 36rpx;" v-else>暂无报价</span>
+								</view>
 							</view>
-							<view class="offer_price">
-								报价:<span style="font-size: 36rpx;">¥{{pageData.offers[0].amount}}</span>
+							<view class="hflex acenter jbetween offer_center">
+								<view class="tele">联系电话:{{item1.user.phone}}</view>
+								<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(item1.user.phone)"></image>
+							</view>
+							<view class="hflex acenter jend offer_bottom" v-if="item1.id == pageData.offer_id">
+								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail1(index1)">查看详情</view>
+								<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail1(index1)">联系接单人</view>
+								<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter" @click="remind(item1.user_id)">提醒完成</view>
 							</view>
-						</view>
-						<view class="hflex acenter jbetween offer_center">
-							<view class="tele">联系电话:{{pageData.offers[0].user.phone}}</view>
-							<image src="/static/images/common/tele.png" style="width: 32rpx; height: 32rpx;" @click="tele(pageData.offers[0].user.phone)"></image>
-						</view>
-						<view class="hflex acenter jend offer_bottom">
-							<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(pageData.offers[0].user.id)">查看详情</view>
-							<view class="bottom_btn1 hflex acenter jcenter" @click="toDetail(pageData.offers[0].user.id)">联系接单人</view>
-							<view class="bottom_btn1 bottom_btn2 hflex acenter jcenter">提醒完成</view>
 						</view>
 					</view>
-				</view>
+				</block>
 			</view>
 		</view>
 		
-		<view class="bottom hflex jend" v-if="pageData.status !== 3">
+		<view class="bottom hflex jend" v-if="pageData.status == 1">
 			<view class="btn1 hflex acenter jcenter" @click="cancel(pageData.id)">取消订单</view>
-			<view class="btn1 btn2 hflex acenter jcenter" @click="edit(pageData.id)">编辑订单</view>
+			<view class="btn1 btn2 hflex acenter jcenter" v-if="pageData.status == 1" @click="edit(pageData.id)">编辑订单</view>
 		</view>
-		<u-popup :show="down_show" mode="center" @close="close">
+		<view class="bottom hflex jend" v-if="pageData.status == 3 && pageData.tab != 1">
+			<view class="btn1 btn2 hflex acenter jcenter" v-if="pageData.status == 3 && pageData.tab != 1" @click="open(pageData.down_word)">下载文件</view>
+		</view>
+		<u-popup :show="down_show" mode="center" round="10" @close="close" :safeAreaInsetBottom="false">
 			<view class="popu">
 				<view class="popu_top hflex acenter jbetween">
 					<view></view>
@@ -199,17 +228,39 @@
 					<image src="/static/images/common/close_icon.png" style="width: 32rpx;height: 32rpx;" @click="close"></image>
 				</view>
 				<view class="file_bg hflex acenter">
-					<image :src="pageData.items[index1].enclosure?pageData.items[index1].enclosure[index2].icon:''" class="file_icon"></image>
-					<view class="file_name">{{pageData.items[index1].enclosure?pageData.items[index1].enclosure[index2].filename:''}}</view>
+					<view class="file_name text_hide">{{down_word}}</view>
 				</view>
 				<view class="btn_group hflex acenter jbetween">
-					<view class="left_btn hflex acenter jcenter" @click="copy(pageData.items[index1].enclosure?pageData.items[index1].enclosure[index2].fileurl:'')">复制链接</view>
-					<view class="right_btn hflex acenter jcenter" @click="down(pageData.items[index1].enclosure?pageData.items[index1].enclosure[index2].fileurl:'')">下载文件</view>
+					<view class="left_btn hflex acenter jcenter" @click="copy(down_word)">复制链接</view>
+					<view class="right_btn hflex acenter jcenter" @click="see(down_word)">预览文件</view>
+				</view>
+				<!-- <view class="hflex acenter jcenter text_blue" @click="see(pageData.items[index1].enclosure[index2].fileurl)">预览文件></view> -->
+			</view>
+		</u-popup>
+		<u-popup :show="select_show" mode="center" round="10" @close="close" v-if="pageData.staus==1" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_top hflex acenter jbetween">
+					<view></view>
+					<view class="popu_title">选择接单人</view>
+					<image src="/static/images/common/close_icon.png" style="width: 32rpx;height: 32rpx;" @click="close"></image>
 				</view>
-				<view class="hflex acenter jcenter text_blue" @click="see(pageData.items[index1].enclosure?pageData.items[index1].enclosure[index2].fileurl:'')">预览文件></view>
+				<scroll-view scroll-y="true" style="height: 360rpx;">
+					<view class="" v-for="(item,index) in pageData.items" :key="index">
+						<u-radio-group iconPlacement="right">
+							<view class="hflex acenter jbetween"  v-for="(item2,index2) in item.offers" :key="index2">
+								<view class="hflex acenter ">
+									<image :src="item2.user.headimg" class="offer_avatar"></image>
+									<view class="user_name text_hide">{{item2.user.nickname}}</view>
+								</view>
+								<u-radio shape="circle" activeColor="#506dff" @change="changge(index,index2)"></u-radio>
+							</view>
+						</u-radio-group>
+					</view>	
+					
+				</scroll-view>
+				<view class="btn_next hflex acenter jcenter" @click="next">下一步</view>
 			</view>
 		</u-popup>
-		<u-popup :show="select_show" mode="center" @close="close" v-if="pageData.staus==1"></u-popup>
 	</view>
 </template>
 
@@ -231,6 +282,7 @@
 				index1: 0,
 				index2: 0,
 				select_show: false,
+				down_word: '',
 			}
 		},
 		onLoad(options) {
@@ -253,6 +305,9 @@
 				}, function(res) {
 					if(res.code == 1) {
 						that.pageData = res.data
+						// console.log(that.pageData);
+					} else {
+						$api.info(res.info)
 					}
 				})
 			},
@@ -266,17 +321,24 @@
 			showOffer2() {
 				that.show = !that.show
 			},
-			open(index1,index2) {
-				that.index1 = index1
-				that.index2 = index2
+			open(url) {
+				that.down_word = url
 				that.down_show = true
 			},
 			close() {
 				that.down_show = false
 				that.select_show = false
 			},
-			select() {
+			/* select() {
 				that.select_show = true
+			}, */
+			next() {
+				that.select_show = false
+				that.down_show = true
+			},
+			changge(index1,index2) {
+				that.index1 = index1
+				that.index2 = index2
 			},
 			down(url) {
 				uni.downloadFile({
@@ -288,7 +350,7 @@
 						uni.saveFile({
 							tempFilePath: filePath,
 							success: function(res) {
-								console.log(res);
+								// console.log(res);
 								that.close()
 								that.see(res.savedFilePath)
 							}
@@ -326,25 +388,63 @@
 					phoneNumber: value
 				});
 			},
-			toDetail(id) {
-				$api.jump('/pages/mine/service/purOrder/msg?id=' + that.id + '&userid=' + id + '&tab=' + that.tab) 
+			toDetail(index1,index2) {
+				$api.jump('/pages/mine/service/purOrder/msg?id=' + that.pageData.id + '&userid=' + that.pageData.items[index1].offers[index2].user_id + '&tab=' + that.pageData.tab + '&offer=' + JSON.stringify(that.pageData.items[index1].offers[index2])) 
 			},
-			match(id) {
+			toDetail1(index1) {
+				$api.jump('/pages/mine/service/purOrder/msg?id=' + that.pageData.id + '&userid=' + that.pageData.offers[index1].user_id + '&tab=' + that.pageData.tab + '&offer=' + JSON.stringify(that.pageData.offers[index1])) 
+			},
+			remind(id) {
 				$api.req({
-					url: '/data/api.business.Purchase/match',
-					method: 'POST',
+					url: '/data/api.business.Purchase/reminder',
 					data: {
-						tab: that.tab,
-						id: that.id,
-						offer_id: id
+						user_id: id
 					}
 				}, function(res) {
 					if(res.code == 1) {
-						$api.info(res.info)
-						that.getData()
+						// $api.info(res.info)
+						$api.info('已发送提醒')
 					}
 				})
 			},
+			match(index,index2) {
+				console.log('匹配');
+				if(that.pageData.tab == 1) {
+					$api.req({
+						url: '/data/api.business.Purchase/match',
+						method: 'POST',
+						data: {
+							tab: that.tab,
+							id: that.pageData.items[index].id,
+							offer_id: that.pageData.items[index].offers[index2].id
+						}
+					}, function(res) {
+						console.log('匹配',res);
+						if(res.code == 1) {
+							console.log(res);
+							$api.info(res.info)
+							that.getData()
+						}
+					})
+				} else {
+					$api.req({
+						url: '/data/api.business.Purchase/match',
+						method: 'POST',
+						data: {
+							tab: that.tab,
+							id: that.pageData.id,
+							offer_id: that.pageData.offers[index2].id
+						}
+					}, function(res) {
+						console.log('匹配',res);
+						if(res.code == 1) {
+							console.log(res);
+							$api.info(res.info)
+							that.getData()
+						}
+					})
+				}
+			},
 			cancel(id) {
 				$api.req({
 					url: '/data/api.business.Purchase/cancel',
@@ -413,7 +513,7 @@
 		.center {
 			position: absolute;
 			left: 0;
-			top: 196rpx;
+			top: 250rpx;
 			width: 100%;
 			box-sizing: border-box;
 			padding: 0 30rpx;
@@ -496,6 +596,8 @@
 								border-radius: 50%;
 							}
 							.user_name {
+								max-width: 150rpx;
+								width: max-content;
 								font-size: 28rpx;
 								font-weight: 400;
 								color: #222222;
@@ -532,7 +634,7 @@
 						.offer_bottom {
 							padding: 20rpx 0 0;
 							.bottom_btn1 {
-								margin-left: 20rpx;
+								margin-left: 10rpx;
 								// width: 132rpx;
 								height: 48rpx;
 								border-radius: 26rpx;
@@ -541,7 +643,7 @@
 								font-weight: 400;
 								color: #506DFF;
 								line-height: 32rpx;
-								padding: 0 22rpx;
+								padding: 0 15rpx;
 							}
 							.bottom_btn2 {
 								background: #506DFF;
@@ -629,6 +731,8 @@
 							border-radius: 50%;
 						}
 						.user_name {
+							max-width: 150rpx;
+							width: max-content;
 							font-size: 28rpx;
 							font-weight: 400;
 							color: #222222;
@@ -728,6 +832,18 @@
 					line-height: 50rpx;
 				}
 			}
+			
+			.btn_next {
+				width: 310rpx;
+				height: 88rpx;
+				background: #506DFF;
+				border-radius: 44rpx;
+				font-size: 32rpx;
+				font-weight: 500;
+				color: #FFFFFF;
+				line-height: 44rpx;
+				margin: 42rpx auto;
+			}
 			.file_bg {
 				width: 550rpx;
 				height: 100rpx;
@@ -748,6 +864,7 @@
 			}
 			.btn_group {
 				width: 100%;
+				padding: 0 0 20rpx;
 				.left_btn {
 					width: 260rpx;
 					height: 76rpx;
@@ -776,6 +893,20 @@
 				line-height: 42rpx;
 				padding: 28rpx 0 46rpx;
 			}
+			.offer_avatar {
+				width: 72rpx;
+				height: 72rpx;
+				border-radius: 50%;
+			}
+			.user_name {
+				max-width: 150rpx;
+				width: max-content;
+				font-size: 28rpx;
+				font-weight: 400;
+				color: #222222;
+				line-height: 40rpx;
+				padding: 0 16rpx;
+			}
 		}
 	}
 </style>

+ 55 - 8
pages/mine/service/purOrder/list.vue

@@ -6,7 +6,7 @@
 		<view class="tabs2">
 			<u-tabs :list="tabList" @click="changeTabs2" :activeStyle="activeStyle2" :inactiveStyle="inactiveStyle2"lineWidth="0" lineHeight='0' :scrollable="false"></u-tabs>
 		</view>
-		<view class="vflex">
+		<view class="vflex" style="box-sizing: border-box;padding: 0 30rpx;">
 			<block v-for="(item,index) in pageList" :key="index">
 				<view class="box" @click="toDetail(item.id)">
 					<view class="top hflex acenter jbetween">
@@ -32,12 +32,12 @@
 						<view class="top_right1 top_right3 hflex acenter jcenter" v-if="item.status == 3">已匹配</view>
 					</view>
 					<view class="center">
-						<block v-for="(item2,index2) in item.items">
+						<block v-for="(item2,index2) in item.items" :key="index2">
 							<view class="items">
 								<view class="items_name">{{item2.name}}</view>
 								<view class="hflex acenter items_spec" v-if="item.tab != 4">
 									<view>规格:{{item2.spec}} </view>
-									<view style="padding-left: 20rpx;">采购数量:{{item2.number}}</view>
+									<view style="padding-left: 20rpx;">采购数量:{{item2.number}}</view>
 								</view>
 								<view class="hflex acenter items_spec" v-else>
 									<view>数量/吨位:{{item2.weight}} </view>
@@ -52,7 +52,7 @@
 							<view class="btn1 btn2 hflex acenter jcenter" @click.stop="edit(item.id)">编辑订单</view>
 						</view>
 						<view class="hflex" v-else>
-							<view class="btn1 btn2 hflex acenter jcenter">提醒完成</view>
+							<view class="btn1 btn2 hflex acenter jcenter" @click.stop="remind(index)">提醒完成</view>
 						</view>
 					</view>
 				</view>
@@ -131,6 +131,8 @@
 		},
 		onLoad() {
 			that = this
+		},
+		onShow() {
 			that.getList()
 		},
 		methods: {
@@ -177,7 +179,9 @@
 				}, function(res) {
 					if(res.code == 1) {
 						$api.info(res.info)
-						that.getList()
+						setTimeout(()=>{
+							that.getList()
+						},1000)
 					}
 				})
 			},
@@ -197,7 +201,49 @@
 						url = '/pages/release/ocean/ocean?id=' +id;
 						break;
 				}
-				$api.jump(url)
+				$api.jump(url + '&back=true')
+			},
+			remind(index) {
+				var user_id = ""
+				if(that.tab == 1) {
+					for(var i=0;i<that.pageList[index].items.length;i++) {
+						if (that.pageList[index].items[i].is_matched) {
+							for(var j=0;j<that.pageList[index].items[i].offers.length;j++) {
+								if (that.pageList[index].items[i].offer_id == that.pageList[index].items[i].offers[j].id) {
+									user_id = that.pageList[index].items[i].offers[j].user_id
+									$api.req({
+										url: '/data/api.business.Purchase/reminder',
+										data: {
+											user_id: user_id
+										}
+									}, function(res) {
+										if(res.code == 1) {
+											$api.info('已发送提醒')
+										}
+									})
+								}
+							}
+						}
+					}
+				} else {
+					if (that.pageList[index].is_matched) {
+						for(var j=0;j<that.pageList[index].offers.length;j++) {
+							if (that.pageList[index].offer_id == that.pageList[index].offers[j].id) {
+								user_id = that.pageList[index].offers[j].user_id
+								$api.req({
+									url: '/data/api.business.Purchase/reminder',
+									data: {
+										user_id: user_id
+									}
+								}, function(res) {
+									if(res.code == 1) {
+										$api.info('已发送提醒')
+									}
+								})
+							}
+						}
+					}
+				}
 			},
 			toDetail(id) {
 				$api.jump('/pages/mine/service/purOrder/detail?id=' + id + '&tab=' + that.tab)
@@ -216,7 +262,7 @@
 </script>
 
 <style lang="scss" scoped>
-	.content {
+	.content::v-deep {
 		background: #F4F4F4;
 		.tabs {
 			width: 100%;
@@ -265,6 +311,7 @@
 			}
 			.center {
 				width: 100%;
+				
 				.items {
 					padding: 24rpx 0;
 					border-bottom: 1rpx solid #F4F4F4;
@@ -276,7 +323,7 @@
 						padding-bottom: 16rpx;
 					}
 					.items_spec {
-						width: auto;
+						width: max-content;
 						font-size: 24rpx;
 						font-weight: 400;
 						color: #999999;

+ 27 - 13
pages/mine/service/purOrder/msg.vue

@@ -1,22 +1,28 @@
 <template>
 	<view class="content">
-		<!-- <view class="top">
+		<view class="top">
 			<view class="top_title">当前报价</view>
-			<view class="vflex">
-				<block v-for="(item,index) in offer.list" :key="index">
+			<view class="vflex" v-if="offer.amounts">
+				<block v-for="(item,index) in offer.amounts" :key="index">
 					<view class="top_item hflex acenter">
 						<view class="item_label">第{{index + 1}}次报价</view>
-						<view class="text_red">{{item.price}}</view>
+						<view class="text_red">{{item.amount}}</view>
 					</view>
 				</block>
 			</view>
+			<view class="vflex" v-if="offer.amount && !offer.amounts">
+				<view class="top_item hflex acenter">
+					<!-- <view class="item_label">第{{index + 1}}次报价</view> -->
+					<view class="text_red">{{offer.amount}}</view>
+				</view>
+			</view>
 			<view class="top_title">图片及资质证明图片</view>
-			<block v-for="(item,index) in offer.imgs" :key="index">
-				<view class="hflex acenter">
+			<view class="hflex acenter fwrap">
+				<block v-for="(item,index) in offer.images" :key="index">
 					<image :src="item" class="img"></image>
-				</view>
-			</block>
-		</view> -->
+				</block>
+			</view>
+		</view>
 		<view class="list" id="list">
 			<block v-for="(item,index) in pageList" :key="index">
 				<view class="hflex acenter jend item" v-if="item.uuid2 == userId">
@@ -24,7 +30,7 @@
 					<image :src="item.user?item.user.headimg:''" class="headimg"></image>
 				</view>
 				<view class="hflex acenter item" v-else>
-					<image :src="item.user.headimg" class="headimg"></image>
+					<image :src="item.user?item.user.headimg:''" class="headimg"></image>
 					<view class="message message_left">{{item.content}}</view>
 				</view>
 			</block>
@@ -59,7 +65,12 @@
 			that.id = options.id
 			that.tab = options.tab
 			that.userId = options.userid
+			if(options.offer) {
+				that.offer = JSON.parse(options.offer)
+			}
 			that.getList()
+		},
+		onReady() {
 			that.scrollToBottom()
 		},
 		methods: {
@@ -74,6 +85,7 @@
 				}, function(res) {
 					if(res.code == 1) {
 						that.pageList = res.data
+						console.log(that.pageList);
 					}
 				})
 			},
@@ -101,7 +113,6 @@
 			scrollToBottom() {
 				uni.createSelectorQuery().select('#list').boundingClientRect(function(rect){
 				  // 使页面滚动到底部
-				  console.log("页面的高度",rect)
 				  uni.pageScrollTo({
 					scrollTop: rect.bottom
 				  })
@@ -122,6 +133,9 @@
 			border-radius: 0px 0px 28rpx 28rpx;
 			box-sizing: border-box;
 			padding: 24rpx 30rpx 0;
+			/* position: absolute;
+			top: 0;
+			left: 0; */
 			.top_title {
 				font-size: 28rpx;
 				font-weight: 500;
@@ -152,8 +166,8 @@
 				}
 			}
 			.img {
-				width: 220rpx;
-				height: 220rpx;
+				width: 200rpx;
+				height: 200rpx;
 				border-radius: 16rpx;
 				margin: 0 16rpx 24rpx 0;
 			}

+ 2 - 2
pages/mine/service/rule.vue

@@ -22,11 +22,11 @@
 		methods: {
 			getData() {
 				$api.req({
-					url: '/data/api.auth.Center/getplatformrules',
+					url: '/data/api.business.Login/getconfigset',
 					method: 'POST',
 				}, function(res) {
 					if(res.code ==1) {
-						that.text = res.data.platform_rules
+						that.text = res.data.shop_platform_rules
 					}
 				})
 			}

+ 54 - 0
pages/mine/service/setting/about.vue

@@ -0,0 +1,54 @@
+<template>
+	<view class="content">
+		<view class="box vflex acenter jcenter">
+			<image src="/static/images/mine/logo.png" class="logo"></image>
+			<view class="text_style1">船百知-商家端</view>
+			<view class="text_style2">1.0.0</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import $api from '@/static/js/api.js'
+	var that = ''
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		onLoad() {
+			that = this
+		},
+		methods: {
+			
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	.content {
+		background-color: #f4f4f4;
+		padding: 24rpx 30rpx 0;
+		.box {
+			width: 100%;
+			height: 416rpx;
+			background: #fff;
+			border-radius: 24rpx;
+			.logo {
+				width: 156rpx;
+				height: 156rpx;
+				border-radius: 40rpx;
+			}
+			.text_style1 {
+				font-size: 32rpx;
+				color: #222;
+				margin: 28rpx 0 10rpx;
+			}
+			.text_style2 {
+				font-size: 32rpx;
+				color: #b2b2b2;
+			}
+		}
+	}
+</style>

+ 2 - 2
pages/mine/service/setting/account_info.vue

@@ -4,14 +4,14 @@
 			<view class="hflex acenter jbetween cell">
 				<view class="left">手机号码</view>
 				<view class="hflex acenter">
-					<view class="right">{{user.phone}}</view>
+					<view class="right">{{user.contact_phone}}</view>
 					<u-icon name="arrow-right" color="#000" size="10"></u-icon>
 				</view>
 			</view>
 			<view class="hflex acenter jbetween cell" @click="bindEmail">
 				<view class="left">邮箱</view>
 				<view class="hflex acenter">
-					<view class="right">{{user.contact_mail?user.contact_mail:''}}</view>
+					<view class="right">{{user.contact_mail?user.contact_mail:'去绑定'}}</view>
 					<u-icon name="arrow-right" color="#000" size="10"></u-icon>
 				</view>
 			</view>

+ 12 - 7
pages/mine/service/setting/bind_eMail.vue

@@ -33,6 +33,9 @@
 			that = this
 			console.log(options);
 			that.type = options.type
+			
+		},
+		onReady() {
 			var title = ""
 			switch(that.type) {
 				case 'username': 
@@ -75,13 +78,15 @@
 				}, function(res) {
 					if(res.code == 1) {
 						$api.info(res.info)
-						// let options = {
-						// 	nickname: that.username,
-						// }
-						// uni.WebIM.conn.updateOwnUserInfo(options).then((res) => {
-						//     console.log(res)
-						// 	$api.jump(1,-1)
-						// })
+						if(that.type == 'username') {
+							let options = {
+								nickname: that.username,
+							}
+							uni.WebIM.conn.updateOwnUserInfo(options).then((res) => {
+							    console.log(res)
+							})
+						}
+						$api.jump(1,-1)
 						
 					}
 				})

+ 1 - 0
pages/mine/service/setting/edit_pwd.vue

@@ -36,6 +36,7 @@
 						}, function(res) {
 							if(res.code == 1) {
 								console.log(res);
+								$api.info('修改成功')
 							}
 						})
 					} else {

+ 7 - 7
pages/mine/service/setting/personal.vue

@@ -96,13 +96,13 @@
 										}
 									},function(res) {
 										console.log(res);
-										// let options = {
-										// 	avatarurl: that.user.headimg,
-										// }
-										// uni.WebIM.conn.updateOwnUserInfo(options).then((res) => {
-										//     console.log(res)
-										// })
-										// $api.info(res.info)
+										let options = {
+											avatarurl: that.user.headimg,
+										}
+										uni.WebIM.conn.updateOwnUserInfo(options).then((res) => {
+										    console.log(res)
+										})
+										$api.info(res.info)
 									})
 								}
 							}

+ 3 - 3
pages/mine/service/setting/setting.vue

@@ -59,7 +59,7 @@
 			},
 			// 关于我们
 			about() {
-				$api.jump('/pages/mine/setting/about')
+				$api.jump('/pages/mine/service/setting/about')
 			},
 			// 平台规则
 			rules() {
@@ -68,10 +68,10 @@
 			// 退出登录
 			quit() {
 				uni.removeStorageSync("token")
-				// uni.removeStorageSync("HXtoken")
+				uni.removeStorageSync("myUsername")
 				uni.removeStorageSync("id")
 				uni.WebIM.conn.close();
-				$api.jump('/pages/tabbar/mine/mine')
+				$api.jump('/pages/tabbar/mine/mine',2)
 			}
 		},
 	}

+ 4 - 4
pages/mine/wallet/add.vue

@@ -45,10 +45,10 @@
 		},
 		methods: {
 			inputCard(e) {
-				var l = e.replace(/\s*/g, '')
-				if (l.length % 4 == 0) {
-					e = e + ' '
-				}
+				// var l = e.replace(/\s*/g, '')
+				// if (l.length % 4 == 0) {
+				// 	e = e + ' '
+				// }
 				that.card_no = e
 				// that.card_no = e.replace(/\s/g, ' ').replace(/[^\d]/g, ' ').replace(/(\d{4})(?=\d)/g, '$1')
 			},

+ 4 - 4
pages/mine/wallet/bankList.vue

@@ -21,7 +21,7 @@
 			<u-icon name="plus-circle" color="#506DFF" size="19"></u-icon>
 			<view class="add_text">去添加</view>
 		</view>
-		<u-popup :show="show" :round="10" mode="bottom" @close="close">
+		<u-popup :show="show" round="10" mode="bottom" @close="close" :safeAreaInsetBottom="false">
 			<view class="popu">
 				<view class="popu_text hflex acenter jcenter" @click="delbank">解除绑定</view>
 				<view class="popu_btn hflex acenter jcenter" @click="close">取消</view>
@@ -56,12 +56,12 @@
 					// method: 'POST'
 				}, function(res) {
 					if(res.code == 1) {
-						console.log(res);
 						that.pageList = res.data.list
 						for(var i=0;i<res.data.list.length;i++) {
-							that.pageList[i].number = res.data.list[i].number.replace(/(?<=\d{0})\d+(?=\d{4})/,"**** **** **** ")
+							that.pageList[i].number = res.data.list[i].number.substr(-4)
+							that.pageList[i].number = "**** **** **** " + that.pageList[i].number
 						}
-						console.log(that.pageList);
+						// console.log(that.pageList);
 					}
 				})
 			},

+ 12 - 8
pages/mine/wallet/wallet.vue

@@ -6,20 +6,20 @@
 				<view class="money">{{money}}</view>
 				<view class="money_btn" @click="toWithdraw">提现</view>
 			</view>
-			<view class="bottom hflex acenter jbetween" @click="toBank">
+			<!-- <view class="bottom hflex acenter jbetween" @click="toBank">
 				<view class="bottom_left">银行卡(张)<span class="bottom_num">{{bankNum?bankNum:''}} </span></view>
 				<u-icon name="arrow-right" color="#fff" size="16"></u-icon>
-			</view>
+			</view> -->
 		</view>
 		<view class="list">
 			<view class="list_title">收支明细</view>
 			<block v-for="(item,index) in pageList" :key="index">
 				<view class="list_item hflex acenter jbetween">
 					<view class="vflex">
-						<view class="text_style1">{{item.title}}</view>
-						<view class="text_style2">{{item.create_at}}</view>
+						<view class="text_style1">{{item.form}}</view>
+						<view class="text_style2">{{item.create_time}}</view>
 					</view>
-					<view class="text_style3">-{{item.change}}</view>
+					<view class="text_style3">-{{item.amount}}</view>
 				</view>
 			</block>
 		</view>
@@ -36,11 +36,14 @@
 				pageList: [],
 				bankNum:'',
 				page: 1,
-				total: 1
+				total: 1,
+				service: ''
 			}
 		},
 		onLoad() {
 			that = this
+		},
+		onShow() {
 			that.getList()
 		},
 		methods: {
@@ -57,12 +60,13 @@
 						that.pageList = res.data.list
 						that.total = res.data.page.total
 						that.bankNum = res.data.bank_nunm
+						that.service = res.data.service
 					}
 				}) 
 			},
 			// 去提现
 			toWithdraw() {
-				$api.jump('/pages/mine/wallet/withdraw')
+				$api.jump('/pages/mine/wallet/withdraw?money=' + that.money + '&service=' + that.service)
 			},
 			toBank() {
 				$api.jump('/pages/mine/wallet/bankList')
@@ -76,7 +80,7 @@
 		padding: 20rpx 30rpx 0;
 		.top {
 			width: 100%;
-			height: 284rpx;
+			// height: 284rpx;
 			box-sizing: border-box;
 			padding: 25rpx 0;
 			background: url('/static/images/mine/amount_bg.png') no-repeat;

+ 21 - 7
pages/mine/wallet/withdraw.vue

@@ -34,7 +34,7 @@
 				<view class="btn" @click="withdraw">立即提现</view>
 			</view>
 		</view>
-		<u-popup :show="show" :round="20" bgColor="#F4F4F4" :closeable="true" closeIconPos="top-left" mode="bottom" @close="close">
+		<u-popup :show="show" round="20" bgColor="#F4F4F4" :closeable="true" closeIconPos="top-left" mode="bottom" @close="close" :safeAreaInsetBottom="false">
 			<view class="popup_bg">
 				<view class="title">选择银行卡</view>
 				<view class="add hflex acenter jbetween" @click="add">
@@ -69,19 +69,24 @@
 			return {
 				money: '0.00',
 				value: '',
-				service: 0.01,
+				service: 0,
 				service_money: 0,
 				amount: 0,
 				bank: [
 				],
-				active: 0,
+				active: -1,
 				max_money: 10000,
 				min_money: 1,
 				show: false
 			}
 		},
-		onLoad() {
+		onLoad(options) {
 			that = this 
+			that.money = options.money
+			var ser = Number(options.service)
+			console.log('ser',ser);
+			that.service = ser / 100
+			console.log('service',that.service);
 			that.getList()
 			// that.getData()
 		},
@@ -93,13 +98,13 @@
 				}, function(res) {
 					if(res.code == 1) {
 						that.bank = res.data.list
-						var c = ''
+						/* var c = ''
 						if(that.bank.length > 0) {
 							for(var i=0;i<that.bank.length;i++) {
 								c = that.bank[i].number.substr(-4)
 								that.$set(that.bank[i],'number',c)
 							}
-						}
+						} */
 					}
 				})
 			},
@@ -126,13 +131,21 @@
 			},
 			// 输入框发生改变
 			change(e) {
-				console.log(typeof(e));
 				that.value = e
+				console.log('1',Number(that.value));
+				console.log('2',that.service);
+				console.log((Number(that.value) * that.service));
 				that.service_money = (Number(that.value) * that.service).toFixed(2)
 				that.amount = (that.value - that.service_money).toFixed(2)
+				console.log(that.service_money);
+				console.log(that.amount);
 			},
 			// 立即提现
 			withdraw() {
+				if(that.active == -1) {
+					$api.info("请先选择银行卡")
+					return
+				}
 				if(that.value > 0) {
 					if(Number(that.value) > Number(that.max_money) || Number(that.value) < Number(that.min_money)) {
 						$api.info('请选择在'+that.min_money+'与'+that.max_money+'之间')
@@ -147,6 +160,7 @@
 						},function(res) {
 							if(res.code == 1) {
 								$api.info(res.info)
+								$api.jump(-1)
 							}
 						})
 					}

+ 57 - 13
pages/order/list.vue

@@ -2,7 +2,7 @@
 	<view class="content">
 		<u-navbar title="" @leftClick="leftClick" :autoBack="true" :placeholder="true" >
 			<view slot="center">
-				<u-search placeholder="商品名、单号、下单人" :showAction="false" v-model="order_name"></u-search>
+				<u-search placeholder="商品名、单号、下单人" :showAction="false" v-model="order_name" @search="search"></u-search>
 			</view>
 		</u-navbar>
 		<view class="tabs">
@@ -16,7 +16,7 @@
 			<block v-for="(item,index) in pageList" :key="index">
 				<view class="box" @click="toDetail(item.id)">
 					<view class="top hflex acenter jbetween">
-						<view class="order-no">订单号<span style="color: #333">{{item.order_no}}</span></view>
+						<view class="order-no">订单号<span style="color: #333;font-weight: 600;00">{{item.order_no}}</span></view>
 						<view class="text_blue" v-if="item.status == 0">已取消</view>
 						<view class="text_blue" v-if="item.status == 1">等待买家付款</view>
 						<view class="text_blue" v-if="item.status == 2">等待买家付款</view>
@@ -32,7 +32,7 @@
 								<image :src="item2.goods_cover" class="img"></image>
 								<view class="good_center">
 									<view class="name text_hide">{{item2.goods_name}}</view>
-									<view class="spec">{{item2.goods_spec}}</view>
+									<view class="spec text_hide">{{item2.goods_spec}}</view>
 								</view>
 								<view class="vflex jend">
 									<view class="price">¥<span style="font-size: 30rpx;">{{item2.price_selling}}</span></view>
@@ -45,7 +45,7 @@
 						</view>
 					</view>
 					<view class="box_bottom hflex jend">
-						<view class="btn1 hflex acenter jcenter" @click.stop="chat">联系买家</view>
+						<view class="btn1 hflex acenter jcenter" @click.stop="chat(index)">联系买家</view>
 						<view class="btn1 btn2 hflex acenter jcenter" v-if="item.status==4" @click.stop="send(item.id)">立即发货</view>
 					</view>
 				</view>
@@ -66,7 +66,10 @@
 					{
 						name: '全部',
 						status: 1,
-						
+						badge: {
+							value: 0,
+							shape: 'horn',
+						}
 					},
 					{
 						name: '待支付',
@@ -102,19 +105,33 @@
 		onLoad(options) {
 			that = this
 			that.status = Number(options.status)
-			that.getList()
 			that.getNum()
+			uni.startPullDownRefresh();
+		},
+		onShow() {
+			that.getList()
+		},
+		onPullDownRefresh() {
+			that.page = 1
+			that.pageList = []
+			that.getList()
 		},
 		methods: {
 			leftClick() {
 			},
+			search(e) {
+				that.order_name = e
+				that.page = 1
+				that.pageList = []
+				that.getList()
+			},
 			getNum() {
 				$api.req({
-					url: '/data/api.business.Order/order_statistics'
+					url: '/data/api.business.Order/order_count'
 				}, function(res) {
 					if(res.code == 1) {
-						for(var i=1;i<that.tabList.length;i++) {
-							that.tabList[i].badge.value = res.data[i - 1]
+						for(var i=0;i<that.tabList.length;i++) {
+							that.tabList[i].badge.value = res.data[i]
 						}
 					}
 				})
@@ -130,6 +147,20 @@
 					}
 				}, function(res) {
 					if(res.code == 1) {
+						for(var i=0;i<res.data.list.length;i++) {
+							for(var j=0;j<res.data.list[i].goods_item.length;j++) {
+								if( res.data.list[i].goods_item[j].goods_cover) {
+									var temp = res.data.list[i].goods_item[j].goods_cover.split('|')
+									res.data.list[i].goods_item[j].goods_cover = temp[0]
+								}
+								
+							}
+						}
+						for(var i=0;i<res.data.list.length;i++) {
+							for(var j=0;j<res.data.list[i].goods_item.length;j++) {
+								res.data.list[i].goods_item[j].goods_spec = $api.resetspec(res.data.list[i].goods_item[j].goods_spec)
+							}
+						}
 						if(that.page == 1) {
 							that.pageList = res.data.list
 						} else {
@@ -137,6 +168,7 @@
 						}
 						that.total = res.data.page.total
 						that.limit = res.data.page.limit
+						uni.stopPullDownRefresh();
 					}
 				})
 			},
@@ -149,8 +181,15 @@
 			toDetail(id) {
 				$api.jump('/pages/order/orderDetail?id=' + id)
 			},
-			chat() {
-				
+			chat(index) {
+				var my = uni.getStorageSync("myUsername");
+				var nameList = {
+				  myName: my,
+				  your: that.pageList[index].huanxinID,
+				};
+				uni.navigateTo({
+				  url: "/pages/chatroom/chatroom?username=" + JSON.stringify(nameList),
+				});
 			},
 			send(id) {
 				$api.jump('/pages/order/send?id=' + id)
@@ -169,6 +208,9 @@
 
 <style lang="scss" scoped>
 	.content::v-deep {
+		.u-search {
+			width: 500rpx;
+		}
 		.tabs {
 			.u-tabs__wrapper__nav__item[data-v-0de61367] {
 				position: relative;
@@ -186,7 +228,7 @@
 			width: 100%;
 			box-sizing: border-box;
 			padding: 0 30rpx;
-			min-height: calc(100vh - 176rpx);
+			min-height: calc(100vh - 160rpx);
 			background: #F4F4F4;
 			.box {
 				background: #FFFFFF;
@@ -225,6 +267,7 @@
 					.img {
 						width: 180rpx;
 						height: 180rpx;
+						border-radius: 16rpx;
 					}
 					.good_center {
 						margin: 0 20rpx;
@@ -237,7 +280,8 @@
 							padding-bottom: 20rpx;
 						}
 						.spec {
-							width: 288rpx;
+							width: max-content;
+							max-width: 288rpx;
 							background: #F5F5F5;
 							border-radius: 12rpx;
 							font-size: 20rpx;

+ 42 - 17
pages/order/orderDetail.vue

@@ -33,23 +33,23 @@
 		<view class="center">
 			<view class="box">
 				<view class="box_title">发货信息</view>
-				<view class="hflex jbetween cell" >
+				<view class="hflex jbetween cell" v-if="pageData.user_address">
 					<view class="left">收货信息</view>
 					<view class="right">{{pageData.user_address.address_name}} , {{pageData.user_address.address_phone}} , {{pageData.user_address.address_province}}{{pageData.user_address.address_city}}{{pageData.user_address.address_area}}{{pageData.user_address.address_content}}</view>
 				</view>
 				<view class="hflex jbetween cell" v-if="pageData.status == 5">
 					<view class="left">物流单号</view>
 					<view class="right hflex acenter">
-						<view> {{pageData.express_no}}</view>
+						<view> {{pageData.user_address.send_number}}</view>
 						<image src="/static/images/common/copy.png" style="width: 28rpx;height: 28rpx;" @click="copy(pageData.express_no)"></image>
 					</view>
 				</view>
 			</view>
-			<view class="box">
+			<view class="box" v-if="pageData.user">
 				<view class="box_title">买家信息</view>
 				<view class="hflex jbetween cell">
 					<view class="left">买家昵称</view>
-					<view class="right">{{pageData.user.nickname}}</view>
+					<view class="right text_hide">{{pageData.user.nickname}}</view>
 				</view>
 				<view class="hflex jbetween cell">
 					<view class="left">联系电话</view>
@@ -68,7 +68,7 @@
 									<view class="item_price">¥<span style="font-size: 30rpx;">{{item.price_selling}}</span></view>
 								</view>
 								<view class="hflex jbetween" style="padding: 20rpx 0 0;">
-									<view class="norm">{{item.goods_spec}}</view>
+									<view class="norm text_hide">{{item.goods_spec}}</view>
 									<view class="left_text">X{{item.stock_sales}}</view>
 								</view>
 							</view>
@@ -79,7 +79,7 @@
 					<view class="left" style="color: #888888;">运费</view>
 					<view class="right" style="color: #888888;">¥0.00</view>
 				</view>
-				<view class="hflex jend cell">
+				<view class="hflex jend cell" v-if="pageData.goods_item">
 					<view class="right">
 						共{{pageData.goods_item.length}}件商品 实付款¥<span style="font-size: 32rpx;color: #222;">{{pageData.payment_amount}}</span>
 					</view>
@@ -95,6 +95,10 @@
 					</view>
 				</view>
 				<view class="hflex jbetween cell">
+					<view class="left">备注</view>
+					<view class="right">{{pageData.order_remark}}</view>
+				</view>
+				<view class="hflex jbetween cell">
 					<view class="left">下单时间</view>
 					<view class="right">{{pageData.create_at}}</view>
 				</view>
@@ -113,12 +117,12 @@
 			</view>
 		</view>
 		<view class="bottom hflex acenter jend">
-			<view class="btn1 btn2 hflex acenter jcenter" v-if="pageData.status == 0 ||pageData.status == 2 || pageData.status == 3">联系买家</view>
+			<view class="btn1 btn2 hflex acenter jcenter" v-if="pageData.status == 0 ||pageData.status == 2 || pageData.status == 3"@click="chat">联系买家</view>
 			<view class="hflex acenter jend" v-if="pageData.status == 4">
-				<view class="btn1 hflex acenter jcenter">联系买家</view>
+				<view class="btn1 hflex acenter jcenter" @click="chat">联系买家</view>
 				<view class="btn1 btn2 hflex acenter jcenter" @click="send(pageData.id)">立即发货</view>
 			</view>
-			<view class="btn1 hflex acenter jcenter" v-if="pageData.status == 5 ||pageData.status == 6">联系买家</view>
+			<view class="btn1 hflex acenter jcenter" v-if="pageData.status == 5 ||pageData.status == 6"@click="chat">联系买家</view>
 		</view>
 	</view>
 </template>
@@ -149,13 +153,22 @@
 						order_id: that.id
 					}
 				}, function(res) {
+					console.log(that.id);
 					if(res.code == 1) {
+						for(var i=0;i<res.data.goods_item.length;i++) {
+							if(res.data.goods_item[i].goods_cover) {
+								var temp = res.data.goods_item[i].goods_cover.split('|')
+								res.data.goods_item[i].goods_cover = temp[0]
+							}
+						}
 						that.pageData = res.data
-						that.pageData.user_address.address_name = that.pageData.user_address.address_name.slice(0,1)+ '**'
-						that.pageData.user_address.address_phone = '***********'
-						that.pageData.user_address.address_content = that.pageData.user_address.address_content.slice(0,5) + '******'
-						that.pageData.user.phone = that.pageData.user.phone.substring(0,3)+"****"+that.pageData.user.phone.substring(7);
+						for(var i=0;i<that.pageData.goods_item.length;i++) {
+							that.pageData.goods_item[i].goods_spec = $api.resetspec(that.pageData.goods_item[0].goods_spec)
+						}
+						console.log("商品数据",that.pageData);
 						that.computTime()
+					} else {
+						$api.info(res.info)
 					}
 				})
 			},
@@ -165,7 +178,7 @@
 			},
 			// 计算倒计时
 			computTime() {
-				var date = new Date(that.pageData.create_at).getTime() + ( 30 * 60 * 1000);
+				var date = new Date(that.pageData.create_at).getTime() + ( that.pageData.time * 60 * 1000);
 				var nowDate = new Date().getTime()
 				that.time = date - nowDate
 			},
@@ -177,6 +190,16 @@
 					}
 				});
 			},
+			chat() {
+				var my = uni.getStorageSync("myUsername");
+				var nameList = {
+				  myName: my,
+				  your: that.pageData.huanxinID,
+				};
+				uni.navigateTo({
+				  url: "/pages/chatroom/chatroom?username=" + JSON.stringify(nameList),
+				});
+			},
 			send(id) {
 				$api.jump('/pages/order/send?id=' + id)
 			},
@@ -258,6 +281,7 @@
 						line-height: 36rpx;
 					}
 					.right {
+						max-width: 400rpx;
 						font-size: 26rpx;
 						font-weight: 400;
 						color: #555555;
@@ -294,7 +318,8 @@
 							line-height: 24rpx;
 						}
 						.norm {
-							width: 288rpx;
+							max-width: 300rpx;
+							width: max-content;
 							// height: 42px;
 							background: #F5F5F5;
 							border-radius: 12rpx;
@@ -332,13 +357,13 @@
 			bottom: 0;
 			.btn1 {
 				width: 208rpx;
-				height: 76rpx;
+				height: 86rpx;
 				border-radius: 38rpx;
 				border: 1rpx solid #787878;
 				font-size: 30rpx;
 				font-weight: 400;
 				color: #222222;
-				line-height: 42rpx;
+				line-height: 76rpx;
 				margin-left: 20rpx;
 			}
 			.btn2 {

+ 148 - 12
pages/order/refund.vue

@@ -5,8 +5,9 @@
 				<view class="box" @click="toDetail(item.id)">
 					<view class="top hflex acenter jbetween">
 						<view class="order-no">订单号<span style="color: #333">{{item.order_no}}</span></view>
-						<view class="text_red" v-if="item.status == 7">未退款</view>
-						<view class="text_blue" v-if="item.status == 8">已退款</view>
+						<view class="text_red" v-if="item.refund_status == 1">等待审核</view>
+						<view class="text_blue" v-if="item.refund_status == 2">同意退款</view>
+						<view class="text_blue" v-if="item.refund_status == 3">拒绝退款</view>
 					</view>
 					<view class="time">下单时间:{{item.create_at}}</view>
 					<view class="good">
@@ -15,7 +16,7 @@
 								<image :src="item2.goods_cover" class="img"></image>
 								<view class="good_center">
 									<view class="name text_hide">{{item2.goods_name}}</view>
-									<view class="spec">{{item2.goods_spec}}</view>
+									<view class="spec text_hide">{{item2.goods_spec}}</view>
 								</view>
 								<view class="vflex jend">
 									<view class="price">¥<span style="font-size: 30rpx;">{{item2.price_selling}}</span></view>
@@ -27,17 +28,40 @@
 							<view class="good_bottom">共{{item.goods_item.length}}件商品 实付款¥<span class="bottom_price">{{item.payment_amount}}</span></view>
 						</view>
 					</view>
-					<view class="box_bottom hflex jend" v-if="item.status == 7">
-						<view class="btn1 hflex acenter jcenter" @click.stop="refuse(item.id,2)">拒绝申请</view>
-						<view class="btn1 btn2 hflex acenter jcenter" @click.stop="refuse(item.id,2)">同意退款</view>
+					<view class="box_bottom hflex jend" v-if="item.refund_status == 1">
+						<view class="btn1 hflex acenter jcenter" @click.stop="apply1(item.id,2)">拒绝申请</view>
+						<view class="btn1 btn2 hflex acenter jcenter" @click.stop="apply1(item.id,1)">同意退款</view>
 					</view>
-					<view class="box_bottom hflex jend" v-if="item.status == 8">>
+					<view class="box_bottom hflex jend" v-if="item.refund_status == 2">
 						<view class="btn1 hflex acenter jcenter" @click.stop="dele(item.id)">删除记录</view>
 						<view class="btn1 btn2 hflex acenter jcenter" @click.stop="toDetail(item.id)">查看详情</view>
 					</view>
+					<view class="box_bottom hflex jend" v-if="item.refund_status == 3">
+						<view class="btn1 hflex acenter jcenter" style="color: #9A9A9A;">已拒绝申请</view>
+					</view>
 				</view>
+				
 			</block>
 		</view>
+		<u-popup :show="show_refuse" mode="center" round="10" @close="close" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_title hflex acenter jcenter">拒绝原因</view>
+				<u-textarea v-model="reason" confirmType="done" placeholder="请填写拒绝原因" border="none" ></u-textarea>
+				<view class="popu_bottom hflex acenter jcenter">
+					<view class="btn1 hflex acenter jcenter" @click="close">取消</view>
+					<view class="btn1 btn2 hflex acenter jcenter" @click="refuse">提交</view>
+				</view>
+			</view>
+		</u-popup>
+		<u-popup :show="show_agree" mode="center" round="10" @close="close" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_title hflex acenter jcenter">确认退款</view>
+				<view class="popu_bottom hflex acenter jcenter">
+					<view class="btn1 hflex acenter jcenter" @click="close">取消</view>
+					<view class="btn1 btn2 hflex acenter jcenter" @click="agree">确认</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -51,10 +75,22 @@
 				page: 1,
 				limit: 10,
 				total: 1,
+				show_refuse: false,
+				reason: '',
+				show_agree: false,
+				id: '',
 			}
 		},
 		onLoad() {
 			that = this
+			uni.startPullDownRefresh();
+		},
+		onShow() {
+			that.getList()
+		},
+		onPullDownRefresh() {
+			that.page = 1
+			that.pageList = []
 			that.getList()
 		},
 		methods: {
@@ -66,23 +102,83 @@
 					}
 				}, function(res) {
 					if(res.code == 1) {
+						for(var i=0;i<res.data.list.length;i++) {
+							for(var j=0;j<res.data.list[i].goods_item.length;j++) {
+								var temp = res.data.list[i].goods_item[j].goods_cover.split('|')
+								res.data.list[i].goods_item[j].goods_cover = temp[0]
+							}
+						}
+						for(var i=0;i<res.data.list.length;i++) {
+							for(var j=0;j<res.data.list[i].goods_item.length;j++) {
+								res.data.list[i].goods_item[j].goods_spec = $api.resetspec(res.data.list[i].goods_item[j].goods_spec)
+							}
+						}
+						
 						if(that.page == 1) {
 							that.pageList = res.data.list
 						} else {
 							that.pageList = that.pageList.concat(res.data.list)
 						}
+						// console.log(that.pageList);
 						that.total = res.data.page.total
 						that.limit = res.data.page.limit
+						uni.stopPullDownRefresh();
+					}
+				})
+			},
+			apply1(id,type) {
+				
+				that.id = id
+				// console.log(type);
+				if(type == 1) {
+					that.show_agree = true
+				} else {
+					that.show_refuse = true
+				}
+			},
+			close() {
+				that.show_refuse = false
+				that.show_agree = false
+			},
+			refuse() {
+				$api.req({
+					url: '/data/api.business.Order/examine_refund',
+					method: 'POST',
+					data: {
+						order_id: that.id,
+						type: 2,
+						reason: that.reason
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						that.page = 1
+						that.getList()
+						that.close()
 					}
 				})
 			},
-			refuse(id,type) {
+			agree() {
 				$api.req({
 					url: '/data/api.business.Order/examine_refund',
 					method: 'POST',
 					data: {
-						order_id: id,
-						type: type
+						order_id: that.id,
+						type: 1
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						that.page = 1
+						that.getList()
+						that.close()
+					}
+				})
+			},
+			dele(id) {
+				$api.req({
+					url: '/data/api.business.Order/del_refund',
+					method: 'POST',
+					data: {
+						order_id: id
 					}
 				}, function(res) {
 					if(res.code == 1) {
@@ -113,7 +209,7 @@
 			width: 100%;
 			box-sizing: border-box;
 			padding: 0 30rpx;
-			min-height: calc(100vh - 176rpx);
+			min-height:100vh;
 			background: #F4F4F4;
 			.box {
 				background: #FFFFFF;
@@ -176,7 +272,8 @@
 							padding-bottom: 20rpx;
 						}
 						.spec {
-							width: 288rpx;
+							width: max-content;
+							max-width: 300rpx;
 							background: #F5F5F5;
 							border-radius: 12rpx;
 							font-size: 20rpx;
@@ -236,5 +333,44 @@
 				}
 			}
 		}
+		.popu {
+			width: 570rpx;
+			margin: 0 auto;
+			background: #FFFFFF;
+			border-radius: 20rpx;
+			box-sizing: border-box;
+			padding: 0 30rpx;
+			.popu_title {
+				font-size: 36rpx;
+				font-weight: 500;
+				color: #222222;
+				line-height: 50rpx;
+				padding: 44rpx 0 36rpx;
+			}
+			.u-textarea {
+				background: #F2F2F2 !important;
+				border-radius: 20rpx !important;
+				margin-bottom: 54rpx;
+			}
+			.popu_bottom {
+				padding-bottom: 52rpx;
+				.btn1 {
+					width: 220rpx;
+					height: 76rpx;
+					border-radius: 38rpx;
+					border: 2rpx solid #506DFF;
+					font-size: 32rpx;
+					font-weight: 400;
+					color: #506DFF;
+					line-height: 44rpx;
+				}
+				.btn2 {
+					background: #506DFF;
+					color: #FFFFFF;
+					margin-left: 50rpx;
+				}
+			}
+			
+		}
 	}
 </style>

+ 137 - 48
pages/order/refundDetail.vue

@@ -1,34 +1,23 @@
 <template>
 	<view class="content">
 		<view class="top">
-			<view class="hflex acenter">
-				<!-- <view class="state">{{pageData.status}}</view> -->
-				<view class="state" v-if="pageData.refund_status == 1">请处理退货退款申请</view>
-				<view class="state" v-if="pageData.refund_status == 2 || pageData.refund_statue == 3">等待买家寄回商品</view>
-				<view class="state" v-if="pageData.refund_status == 4">买家已寄回商品</view>
+			<view v-if="pageData.refund_status == 1">
+				<view class="state">请处理退款申请</view>
+				<view class="subTitle">如果您同意,请点击“同意退款”</view>
 			</view>
-			<view class="subTitle" v-if="pageData.refund_status == 1">如果您同意,请点击"同意退货",将正确地址给买家</view>
-			<view class="subTitle" v-if="pageData.refund_status == 2 || pageData.refund_statue == 3">您已同意退货退款申请,等待买家寄回商品</view>
-			<view class="top_bg" v-if="pageData.refund_status == 4">
-				<view class="hflex acenter jbetween top_cell">
-					<view class="left">快递公司</view>
-					<view class="left">{{pagedata.express_name}}</view>
-				</view>
-				<view class="hflex acenter jbetween top_cell">
-					<view class="left">快递单号</view>
-					<view class="hflex acenter">
-						<view class="left">{{pagedata.express_no}} | </view>
-						<view class="left" @click="copy(pagedata.express_no)">复制</view>
-					</view>
-				</view>
+			<view v-if="pageData.refund_status == 3">
+				<view class="state">您拒绝了退款申请</view>
+			</view>
+			<view v-if="pageData.refund_status == 2">
+				<view class="state">您同意了退款申请</view>
 			</view>
 		</view>
 		<view class="center">
-			<view class="box">
+			<view class="box" v-if="pageData.user">
 				<view class="box_title">买家信息</view>
 				<view class="hflex jbetween cell">
 					<view class="left">买家昵称</view>
-					<view class="right">{{pageData.user.nickname}}</view>
+					<view class="right text_hide" style="max-width: 500rpx;">{{pageData.user.nickname}}</view>
 				</view>
 				<view class="hflex jbetween cell">
 					<view class="left">联系电话</view>
@@ -47,7 +36,7 @@
 									<view class="item_price">¥<span style="font-size: 30rpx;">{{item.price_selling}}</span></view>
 								</view>
 								<view class="hflex jbetween" style="padding: 20rpx 0 0;">
-									<view class="norm">{{item.goods_spec}}</view>
+									<view class="norm text_hide">{{item.goods_spec}}</view>
 									<view class="left_text">X{{item.stock_sales}}</view>
 								</view>
 							</view>
@@ -57,7 +46,8 @@
 				<view class="hflex acenter jbetween cell">
 					<view class="left">退款状态</view>
 					<view class="right text-red" v-if="pageData.refund_status == 1">待商家处理</view>
-					<view class="right text-red" v-else>已同意退款</view>
+					<view class="right text-red" v-if="pageData.refund_status == 2">同意退款</view>
+					<view class="right text-red" v-if="pageData.refund_status == 3">拒绝退款</view>
 				</view>
 				<view class="hflex acenter jbetween cell">
 					<view class="left">退款原因</view>
@@ -83,19 +73,19 @@
 				<view class="box_title">申请信息</view>
 				<view class="hflex jbetween cell">
 					<view class="left">是否收货</view>
-					<view class="right">{{pageData.goods_status}}</view>
+					<view class="right">未收到货</view>
 				</view>
-				<view class="hflex jbetween cell">
+			<!-- 	<view class="hflex jbetween cell">
 					<view class="left">售后类型</view>
 					<view class="right">{{pageData.refund_type}}</view>
-				</view>
+				</view> -->
 				<view class="hflex jbetween cell">
 					<view class="left">售后说明</view>
 					<view class="right">{{pageData.refund_desc}}</view>
 				</view>
 				<view class="hflex cell">
 					<view class="left">图片凭证</view>
-					<view class="hflex acenter img_list">
+					<view class="hflex acenter fwrap img_list">
 						<block v-for="(item,index) in pageData.refund_nr" :key="index">
 							<image :src="item" class="refund_img"></image>
 						</block>
@@ -103,13 +93,32 @@
 				</view>
 			</view>
 		</view>
-		<view class="bottom hflex acenter jend" v-if="pageData.refund_status == 1 || pageData.refund_statue == 4">
-			<view class="btn1 btn2 hflex acenter jcenter" v-if="pageData.refund_status == 4">确认收货</view>
-			<view class="hflex acenter jend" v-if="pageData.refund_status == 1">
-				<view class="btn1 hflex acenter jcenter" @click="apply(2)">拒绝申请</view>
-				<view class="btn1 btn2 hflex acenter jcenter" @click="apply(1)">同意退款</view>
+		<view class="bottom hflex acenter jend" v-if="pageData.refund_status == 1 || pageData.refund_status == 3">
+			<view class="btn1 hflex acenter jcenter" style="color: #9A9A9A;" v-if="pageData.refund_status == 3">已拒绝申请</view>
+			<view class="hflex acenter jend" style="height: 100%;" v-if="pageData.refund_status == 1">
+				<view class="btn1 hflex acenter jcenter" @click="apply1(2)">拒绝申请</view>
+				<view class="btn1 btn2 hflex acenter jcenter" @click="apply1(1)">同意退款</view>
 			</view>
 		</view>
+		<u-popup :show="show_refuse" round="10" mode="center" @close="close" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_title hflex acenter jcenter">拒绝原因</view>
+				<u-textarea v-model="reason" confirmType="done" placeholder="请填写拒绝原因" border="none" ></u-textarea>
+				<view class="popu_bottom hflex acenter jcenter">
+					<view class="btn1 hflex acenter jcenter" @click="close">取消</view>
+					<view class="btn1 btn2 hflex acenter jcenter" @click="refuse">提交</view>
+				</view>
+			</view>
+		</u-popup>
+		<u-popup :show="show_agree" round="10" mode="center" @close="close" :safeAreaInsetBottom="false">
+			<view class="popu">
+				<view class="popu_title hflex acenter jcenter">确认退款</view>
+				<view class="popu_bottom hflex acenter jcenter">
+					<view class="btn1 hflex acenter jcenter" @click="close">取消</view>
+					<view class="btn1 btn2 hflex acenter jcenter" @click="agree">确认</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -123,6 +132,9 @@
 				pageData: {},
 				time: 0,
 				timeData: {},
+				show_refuse: false,
+				reason: '',
+				show_agree: false,
 			}
 		},
 		onLoad(options) {
@@ -140,11 +152,16 @@
 					}
 				}, function(res) {
 					if(res.code == 1) {
+						for(var i=0;i<res.data.goods_item.length;i++) {
+							var temp = res.data.goods_item[i].goods_cover.split('|')
+							res.data.goods_item[i].goods_cover = temp[0]
+						}
 						that.pageData = res.data
-						that.pageData.user_address.address_name = that.pageData.user_address.address_name.slice(0,1)+ '**'
-						that.pageData.user_address.address_phone = '***********'
-						that.pageData.user_address.address_content = that.pageData.user_address.address_content.slice(0,5) + '******'
-						that.pageData.user.phone = that.pageData.user.phone.substring(0,3)+"****"+that.pageData.user.phone.substring(7);
+						for(var i=0;i<that.pageData.goods_item.length;i++) {
+							that.pageData.goods_item[i].goods_spec = $api.resetspec(that.pageData.goods_item[i].goods_spec)
+						}
+						// console.log(that.pageData);
+						that.pageData.refund_nr = that.pageData.refund_nr.split('|')
 					}
 				})
 			},
@@ -156,17 +173,45 @@
 					}
 				});
 			},
-			apply(type) {
+			apply1(type) {
+				if(type == 1) {
+					that.show_agree = true
+				} else {
+					that.show_refuse = true
+				}
+			},
+			close() {
+				that.show_refuse = false
+				that.show_agree = false
+			},
+			refuse() {
+				$api.req({
+					url: '/data/api.business.Order/examine_refund',
+					method: 'POST',
+					data: {
+						order_id: that.id,
+						type: 2
+					}
+				}, function(res) {
+					if(res.code == 1) {
+						that.getData()
+						that.close()
+					}
+				})
+			},
+			agree() {
 				$api.req({
 					url: '/data/api.business.Order/examine_refund',
 					method: 'POST',
 					data: {
 						order_id: that.id,
-						type: type
+						type: 1,
+						reason: that.reason
 					}
 				}, function(res) {
 					if(res.code == 1) {
 						that.getData()
+						that.close()
 					}
 				})
 			}
@@ -175,11 +220,14 @@
 </script>
 
 <style lang="scss" scoped>
-	.content {
+	.content::v-deep {
 		background: #F4F4F4;
 		.top {
-			width: 100%;
+			width: 690rpx;
+			margin: 20rpx auto 0;
 			padding: 20rpx 30rpx 24rpx;
+			background: #FFFFFF;
+			border-radius: 20rpx;
 			.state {
 				font-size: 36rpx;
 				font-weight: bold;
@@ -279,9 +327,10 @@
 						line-height: 36rpx;
 					}
 					.img_list {
+						// max-width: 280rpx;
 						.refund_img {
-							width: 156rpx;
-							height: 156rpx;
+							width: 146rpx;
+							height: 146rpx;
 							border-radius: 16rpx;
 							margin: 0 18rpx 20rpx 0;
 						}
@@ -315,7 +364,8 @@
 							line-height: 24rpx;
 						}
 						.norm {
-							width: 288rpx;
+							width: max-content;
+							max-width: 300rpx;
 							// height: 42px;
 							background: #F5F5F5;
 							border-radius: 12rpx;
@@ -353,14 +403,15 @@
 			bottom: 0;
 			.btn1 {
 				width: 208rpx;
-				height: 76rpx;
+				height: 86rpx;
 				border-radius: 38rpx;
-				border: 1rpx solid #787878;
+				// border: 1rpx solid #787878;
 				font-size: 30rpx;
 				font-weight: 400;
-				color: #222222;
-				line-height: 42rpx;
+				color: #506DFF;
+				line-height: 76rpx;
 				margin-left: 20rpx;
+				border: 1rpx solid #506DFF;
 			}
 			.btn2 {
 				background: #506DFF;
@@ -368,6 +419,44 @@
 				color: #FFFFFF;
 			}
 		}
-	
+		.popu {
+			width: 570rpx;
+			margin: 0 auto;
+			background: #FFFFFF;
+			border-radius: 20rpx;
+			box-sizing: border-box;
+			padding: 0 30rpx;
+			.popu_title {
+				font-size: 36rpx;
+				font-weight: 500;
+				color: #222222;
+				line-height: 50rpx;
+				padding: 44rpx 0 36rpx;
+			}
+			.u-textarea {
+				background: #F2F2F2 !important;
+				border-radius: 20rpx !important;
+				margin-bottom: 54rpx;
+			}
+			.popu_bottom {
+				padding-bottom: 52rpx;
+				.btn1 {
+					width: 220rpx;
+					height: 76rpx;
+					border-radius: 38rpx;
+					border: 2rpx solid #506DFF;
+					font-size: 32rpx;
+					font-weight: 400;
+					color: #506DFF;
+					line-height: 44rpx;
+				}
+				.btn2 {
+					background: #506DFF;
+					color: #FFFFFF;
+					margin-left: 50rpx;
+				}
+			}
+			
+		}
 	}
 </style>

+ 5 - 4
pages/order/send.vue

@@ -13,7 +13,7 @@
 									<view class="item_price">¥<span style="font-size: 30rpx;">{{item.price_selling}}</span></view>
 								</view>
 								<view class="hflex jbetween" style="padding: 20rpx 0 0;">
-									<view class="norm">{{item.goods_spec}}</view>
+									<view class="norm text_hide">{{item.goods_spec}}</view>
 									<view class="left_text">X{{item.stock_sales}}</view>
 								</view>
 							</view>
@@ -46,13 +46,13 @@
 						<u-icon name="arrow-right" size="12" color="#888"></u-icon>
 					</view>
 				</view> 
-				<view class="hflex jbetween cell3" @click="selectAddr('send')">
+				<!-- <view class="hflex jbetween cell3" @click="selectAddr('send')">
 					<view class="label">退货地址</view>
 					<view class="hflex acenter">
 						<view class="text">{{send_addr}}</view>
 						<u-icon name="arrow-right" size="12" color="#888"></u-icon>
 					</view>
-				</view> 
+				</view> -->
 			</view>
 		</view>
 		<view class="bottom">
@@ -214,7 +214,8 @@
 							line-height: 24rpx;
 						}
 						.norm {
-							width: 288rpx;
+							max-width: 300rpx;
+							width: max-content;
 							// height: 42px;
 							background: #F5F5F5;
 							border-radius: 12rpx;

+ 179 - 6
pages/release/ocean/ocean.vue

@@ -18,7 +18,7 @@
 				<view class="add_text">添加</view>
 			</view>
 		</view>
-		<block v-for="(item,index) in items">
+		<block v-for="(item,index) in items" :key="index">
 			<view class="box">
 				<view class="box_item hflex acenter">
 					<view class="left">商品{{index + 1}}</view>
@@ -51,10 +51,25 @@
 		</view>
 		<view class="box">
 			<view class="box_title">图片/视频</view>
-			<u-upload :fileList="fileList1" :accept='accept' @beforeRead="open" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload>
+			<view class="hflex acenter fwrap" style="padding-bottom: 20rpx;">
+				<block v-for="(item,index) in fileList1" :key="index">
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<!-- <image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+					<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video> -->
+				</block>
+				<!-- <u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload> -->
+				<image src="/static/images/common/upload_img.png" class="img" @click="choose"></image>
+			</view>
 		</view>
 		<view class="btn hflex acenter jcenter" @click="release">立即发布</view>
-		<u-popup :show="show_time" :round="10" mode="bottom" @close="close">
+		<u-popup :show="show_time" round="10" mode="bottom" @close="close" :safeAreaInsetBottom="false">
 			<view class="popu">
 				<image src="/static/images/common/popu_close.png" class="close" @click="close"></image>
 				<view class="popu_title">选择包装形式(可多选)</view>
@@ -66,6 +81,19 @@
 				<view class="btn hflex acenter jcenter" @click="sure">确定</view>
 			</view>
 		</u-popup>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -89,15 +117,16 @@
 					weight: '',
 					
 				},
-				accept: ['image','video'],
 				fileList1: [],
 				form: '',
-				formList: ['散装','货柜','整船'],
+				formList: [],
 				active: [],
 				wharf_to: '',
 				wharf_for: '',
 				show_time: false,
 				id: '',
+				back: false,
+				show_choose: false
 			}
 		},
 		onLoad(options) {
@@ -106,6 +135,10 @@
 				that.id = options.id
 				that.getData()
 			}
+			if(options.back) {
+				that.back = options.back
+			}
+			that.getformList()
 		},
 		methods: {
 			getData() {
@@ -127,11 +160,21 @@
 					}
 				})
 			},
+			getformList() {
+				$api.req({
+					url: '/data/api.business.Purchase/config'
+				}, function(res) {
+					if(res.code == 1) {
+						that.formList = res.data.packing
+					}
+				})
+			},
 			showTime() {
 				that.show_time = true
 			},
 			close() {
 				that.show_time = false
+				that.show_choose = false
 			},
 			select(index) {
 				for(var i=0;i<that.active.length;i++) {
@@ -153,8 +196,15 @@
 			deletePic(event) {
 				this[`fileList${event.name}`].splice(event.index, 1)
 			},
+			deletePic2(index) {
+				that.fileList1.splice(index,1)
+			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				let lists = [].concat(event.file)
 				let fileListLen = this[`fileList${event.name}`].length
 				lists.map((item) => {
@@ -173,13 +223,16 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 				console.log(that.fileList1);
 			},
 			uploadFilePromise(url) {
 				return new Promise((resolve, reject) => {
 					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
 						filePath: url,
 						name: 'file',
 						header: {
@@ -222,6 +275,16 @@
 					}
 					images.push(image)
 				}
+				for(var i=0;i<that.items.length;i++) {
+					if(!that.items[i].name || !that.items[i].weight) {
+						$api.info('商品不能为空')
+						return
+					}
+				}
+				if(images.length <=0) {
+					$api.info('请选择图片')
+					return
+				}
 				$api.req({
 					url: '/data/api.business.Purchase/ocean_order',
 					method: 'POST',
@@ -238,8 +301,100 @@
 				}, function(res) {
 					if(res.code == 1) {
 						$api.info(res.info)
+						if(that.back) {
+							$api.jump(-1)
+						} else {
+							$api.jump('/pages/tabbar/index/index',2)
+						}
 					}
 				})
+			},
+			choose() {
+				that.show_choose = true
+			},
+			choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
 			}
 		},
 	}
@@ -275,6 +430,24 @@
 				line-height: 40rpx;
 				padding: 24rpx 0 20rpx;
 			}
+			.img {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+				border-radius: 16rpx;
+			}
+			video {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+			}
+			.close_icon {
+				position: absolute;
+				top: 0;
+				right: 15rpx;
+				width: 30rpx;
+				height: 30rpx;
+			}
 			.box_item {
 				padding: 28rpx 0;
 				border-bottom: 1rpx solid #F5F5F5;

+ 232 - 47
pages/release/production/production.vue

@@ -18,7 +18,7 @@
 				<view class="add_text">添加</view>
 			</view>
 		</view>
-		<block v-for="(item,index) in items">
+		<block v-for="(item,index) in items" :key="index">
 			<view class="box">
 				<view class="box_item hflex acenter">
 					<view class="left">商品{{index + 1}}</view>
@@ -32,11 +32,11 @@
 					<view class="left">数量</view>
 					<u-input v-model="item.number" border="none" placeholder="请输入数量"></u-input>
 				</view>
-				<view class="box_item hflex acenter jbetween">
+				<view class="box_item hflex">
 					<view class="left">附件</view>
-					<view class="center hflex">
+					<view class="center vflex">
 						<block v-for="(item2,index2) in item.enclosure" :key="index2">
-							<view>{{item2.filename}}</view>
+							<view class="text_hide" style="max-width: 300rpx;">{{item2.filename}}</view>
 						</block>
 					</view>
 					<view class="right" @click="upload(index)">上传附件</view>
@@ -50,11 +50,11 @@
 		<view class="box">
 			<view class="box_item1">
 				<view class="left">生产技术标准</view>
-				<u-textarea v-model="standard_tech" placeholder="请填写生产技术的标准"></u-textarea>
+				<u-textarea v-model="standard_tech" confirmType="done" placeholder="请填写生产技术的标准"></u-textarea>
 			</view>
 			<view class="box_item1">
 				<view class="left">生产验收标准</view>
-				<u-textarea v-model="standard_check" placeholder="请填写生产验收的标准"></u-textarea>
+				<u-textarea v-model="standard_check" confirmType="done" placeholder="请填写生产验收的标准"></u-textarea>
 			</view>
 			<view class="box_item hflex acenter">
 				<view class="left">交货地址</view>
@@ -64,13 +64,41 @@
 				<view class="left">交货时间</view>
 				<u-input v-model="post_time" border="none" disabled disabledColor="#fff" placeholder="请选择交货时间" suffixIcon="arrow-right"></u-input>
 			</view>
-			<u-datetime-picker :show="show_time" :formatter="formatter" :minDate="Number(new Date())" mode="datetime" @close="close" @confirm="selectTime"></u-datetime-picker>
+			<u-datetime-picker :show="show_time"  :minDate="Number(new Date())"  mode="date" @cancel="close" @confirm="selectTime"></u-datetime-picker>
 		</view>
 		<view class="box">
 			<view class="box_title">图片/视频</view>
-			<u-upload :fileList="fileList1" :accept='accept' @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload>
+			<view class="hflex acenter fwrap" style="padding-bottom: 20rpx;">
+				<block v-for="(item,index) in fileList1" :key="index">
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<!-- <image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+					<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video> -->
+				</block>
+				<!-- <u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload> -->
+				<image src="/static/images/common/upload_img.png" class="img" @click="choose"></image>
+			</view>
 		</view>
 		<view class="btn hflex acenter jcenter" @click="release">立即发布</view>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -106,8 +134,8 @@
 						}
 					]
 				},
+				back: false,
 				show: false,
-				accept: ['image','video'],
 				fileList1: [],
 				post_address: '',
 				post_time: '',
@@ -115,6 +143,7 @@
 				standard_tech: '',
 				standard_check: '',
 				id: '',
+				show_choose: false
 			}
 		},
 		onLoad(options) {
@@ -123,6 +152,9 @@
 				that.id = options.id
 				that.getData()
 			}
+			if(options.back) {
+				that.back = options.back
+			}
 		},
 		methods: {
 			getData() {
@@ -150,47 +182,63 @@
 			},
 			close() {
 				that.show_time = false
+				that.show_choose = false
 			},
 			selectTime(e) {
 				that.post_time = $api.formatDate(e)
 				that.close()
 			},
 			upload(index) {
-				uni.chooseFile({
-					count: 9, //默认100
-					type:'all',
-					success: function (res) {
-						const tempFilePaths = res.tempFilePaths;
-						uni.uploadFile({
-							url: $api.config.baseUrl + '/data/api.auth.Center/upload', //仅为示例,非真实的接口地址
-							filePath: tempFilePaths[0],
-							name: 'file',
-							header: {
-								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
-								'api-name': 'iosapp'
-							},
-							formData: {
-								'user': 'test'
-							},
-							success: (uploadFileRes) => {
-								var data = JSON.parse(uploadFileRes.data)
-								var enclosure = {
-									filename: res.tempFiles[0].name,
-									fileurl: data.data.url
-								}
-								if(that.items[index].enclosure[0].filename == '') {
-									that.items[index].enclosure.splice(0,1,enclosure)
-								} else {
-									that.items[index].enclosure.push(enclosure)
-								}
-								console.log('items',that.items);
-							}
-						});
-					},
-					fail: function(res) {
-						console.log('fail',res);
-					}
-				});
+				let platform = '';
+				uni.getSystemInfo({ 
+				    success:function(res){ platform = res.platform; } 
+				}) 
+				if(platform == 'ios'){ 
+				    const iOSFileSelect = uni.requireNativePlugin('YangChuan-YCiOSFileSelect'); 
+				    // apple document-types 文件类型参数 https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html 
+				    // 文件类型参数
+				    let params = { "document-types":["public.text","public.zip","public.data","com.adobe.pdf", "com.microsoft.word.doc","com.adobe.postscript", "com.microsoft.excel.xls","com.adobe.encapsulated- postscript", "com.microsoft.powerpoint.ppt","com.adobe.photoshop- image", "com.microsoft.word.rtf","com.microsoft.advanced- systems-format", "com.microsoft.advanced- stream-redirector"], "isBase64":0 } 
+				    iOSFileSelect.show(params, result => { 
+				        let status = parseInt(result.status); 
+				        // 状态200选取成功
+				        if(status == 200){ 
+							console.log(result);
+				            let url = result.url; 
+				            uni.downloadFile({ url:url, success:function(res){ 
+				                if(res.statusCode == 200){ 
+				                    // filePath 可用于 uni.uploadFile 上传的路径
+				                    let filePath = res.tempFilePath; 
+										uni.uploadFile({
+											url: $api.config.baseUrl + '/data/api.auth.Center/upload', //仅为示例,非真实的接口地址
+											filePath: filePath,
+											name: 'file',
+											header: {
+												'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+												'api-name': 'iosapp'
+											},
+											formData: {
+												'user': 'test'
+											},
+											success: (uploadFileRes) => {
+												var data = JSON.parse(uploadFileRes.data)
+												var enclosure = {
+													filename: result.lastName,
+													fileurl: data.data.url
+												}
+												if(that.items[index].enclosure[0].filename == '') {
+													that.items[index].enclosure.splice(0,1,enclosure)
+												} else {
+													that.items[index].enclosure.push(enclosure)
+												}
+												console.log('items',that.items);
+											}
+										});
+				                    } 
+				                } 
+				            }); 
+				        }
+					}); 
+				}
 			},
 			// 删除图片
 			deletePic(event) {
@@ -198,6 +246,10 @@
 			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				let lists = [].concat(event.file)
 				let fileListLen = this[`fileList${event.name}`].length
 				lists.map((item) => {
@@ -216,13 +268,16 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 				console.log(that.fileList1);
 			},
 			uploadFilePromise(url) {
 				return new Promise((resolve, reject) => {
 					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
 						filePath: url,
 						name: 'file',
 						header: {
@@ -255,7 +310,18 @@
 				that.items.splice(index,1)
 			},
 			release() {
-				console.log(that.fileList1);
+				for(var i=0;i<that.items.length;i++) {
+					if(!that.items[i].name || !that.items[i].spec || !that.items[i].number) {
+						$api.info('商品不能为空')
+						return
+					}
+					if(!that.items[i].enclosure) {
+						that.items[i].enclosure = {
+							filename: '',
+							fileurl: ''
+						}
+					}
+				}
 				var images = []
 				var image = {}
 				for(var i=0;i<that.fileList1.length;i++) {
@@ -266,6 +332,10 @@
 					}
 					images.push(image)
 				}
+				if(images.length <=0) {
+					$api.info('请选择图片')
+					return
+				}
 				$api.req({
 					url: '/data/api.business.Purchase/production_order',
 					method: 'POST',
@@ -281,11 +351,107 @@
 						item: JSON.stringify(that.items)
 					}
 				}, function(res) {
+					console.log(res);
 					if(res.code == 1) {
 						$api.info(res.info)
+						if(that.back) {
+							$api.jump(-1)
+						} else {
+							$api.jump('/pages/tabbar/index/index',2)
+						}
 					}
 				})
-			}
+			},
+			choose() {
+				that.show_choose = true
+			},
+			choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+			deletePic2(index) {
+				that.fileList1.splice(index,1)
+			},
 		},
 	}
 </script>
@@ -320,6 +486,24 @@
 				line-height: 40rpx;
 				padding: 24rpx 0 20rpx;
 			}
+			.img {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+				border-radius: 16rpx;
+			}
+			video {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+			}
+			.close_icon {
+				position: absolute;
+				top: 0;
+				right: 15rpx;
+				width: 30rpx;
+				height: 30rpx;
+			}
 			.box_item {
 				padding: 28rpx 0;
 				border-bottom: 1rpx solid #F5F5F5;
@@ -334,6 +518,7 @@
 					width: calc(100% - 276rpx);
 				}
 				.right {
+					text-align: right;
 					font-size: 30rpx;
 					font-weight: 400;
 					color: #5471FF;

+ 204 - 6
pages/release/purchase/purchase.vue

@@ -18,7 +18,7 @@
 				<view class="add_text">添加</view>
 			</view>
 		</view>
-		<block v-for="(item,index) in items">
+		<block v-for="(item,index) in items" :key="index">
 			<view class="box">
 				<view class="box_item hflex acenter">
 					<view class="left">商品{{index + 1}}</view>
@@ -34,7 +34,7 @@
 				</view>
 				<view class="box_item1">
 					<view class="left">质量标准</view>
-					<u-textarea v-model="item.standard" placeholder="请填写质量标准要求"></u-textarea>
+					<u-textarea v-model="item.standard" confirmType="done" placeholder="请填写质量标准要求"></u-textarea>
 				</view>
 				<view class="box_item hflex acenter">
 					<view class="left">原采购价</view>
@@ -47,7 +47,22 @@
 		</block>
 		<view class="box">
 			<view class="box_title">图片/视频</view>
-			<u-upload :fileList="fileList1" :accept='accept' @beforeRead="open" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload>
+			<view class="hflex acenter fwrap" style="padding-bottom: 20rpx;">
+				<block v-for="(item,index) in fileList1" :key="index">
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<!-- <image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+					<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video> -->
+				</block>
+				<!-- <u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload> -->
+				<image src="/static/images/common/upload_img.png" class="img" @click="choose"></image>
+			</view>
 		</view>
 		<view class="box">
 			<view class="box_item hflex acenter">
@@ -58,9 +73,22 @@
 				<view class="left">交货时间</view>
 				<u-input v-model="post_time" border="none" disabled disabledColor="#fff" placeholder="请选择交货时间" suffixIcon="arrow-right"></u-input>
 			</view>
-			<u-datetime-picker :show="show_time" :formatter="formatter" :minDate="Number(new Date())" mode="datetime" @close="close" @confirm="selectTime"></u-datetime-picker>
+			<u-datetime-picker :show="show_time" :minDate="Number(new Date())" mode="date" @cancel="close" @confirm="selectTime"></u-datetime-picker>
 		</view>
 		<view class="btn hflex acenter jcenter" @click="release">立即发布</view>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -89,12 +117,13 @@
 					price: ''
 				},
 				show: false,
-				accept: ['image','video'],
 				fileList1: [],
 				post_address: '',
 				post_time: '',
 				show_time: false,
 				id: '',
+				back: false,
+				show_choose: false
 			}
 		},
 		onLoad(options) {
@@ -103,6 +132,9 @@
 				that.id = options.id
 				that.getData()
 			}
+			if(options.back) {
+				that.back = options.back
+			}
 		},
 		methods: {
 			getData() {
@@ -126,8 +158,21 @@
 			showTime() {
 				that.show_time = true
 			},
+			formatter(type, value) {
+                if (type === 'year') {
+                    return `${value}年`
+                }
+                if (type === 'month') {
+                    return `${value}月`
+                }
+                if (type === 'day') {
+                    return `${value}日`
+                }
+                return value
+            },
 			close() {
 				that.show_time = false
+				that.show_choose = false
 			},
 			selectTime(e) {
 				that.post_time = $api.formatDate(e)
@@ -137,8 +182,15 @@
 			deletePic(event) {
 				this[`fileList${event.name}`].splice(event.index, 1)
 			},
+			deletePic2(index) {
+				that.fileList1.splice(index,1)
+			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				let lists = [].concat(event.file)
 				let fileListLen = this[`fileList${event.name}`].length
 				lists.map((item) => {
@@ -157,13 +209,16 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 				console.log(that.fileList1);
 			},
 			uploadFilePromise(url) {
 				return new Promise((resolve, reject) => {
 					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
 						filePath: url,
 						name: 'file',
 						header: {
@@ -190,6 +245,13 @@
 				})
 			},
 			addGood() {
+				that.good = {
+					name: '',
+					spec: '',
+					number: '',
+					standard: '',
+					price: ''
+				},
 				that.items.push(that.good)
 			},
 			delGood(index) {
@@ -207,6 +269,16 @@
 					images.push(image)
 				}
 				console.log(images);
+				for(var i=0;i<that.items.length;i++) {
+					if(!that.items[i].name || !that.items[i].spec || !that.items[i].number) {
+						$api.info('商品不能为空')
+						return
+					}
+				}
+				if(images.length <=0) {
+					$api.info('请选择图片')
+					return
+				}
 				$api.req({
 					url: '/data/api.business.Purchase/purchase_order',
 					method: 'POST',
@@ -222,8 +294,100 @@
 				}, function(res) {
 					if(res.code == 1) {
 						$api.info(res.info)
+						if(that.back) {
+							$api.jump(-1)
+						} else {
+							$api.jump('/pages/tabbar/index/index',2)
+						}
 					}
 				})
+			},
+			choose() {
+				that.show_choose = true
+			},
+			choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
 			}
 		},
 	}
@@ -259,6 +423,37 @@
 				line-height: 40rpx;
 				padding: 24rpx 0 20rpx;
 			}
+			.img {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+				border-radius: 16rpx;
+			}
+			video {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+			}
+			.close_icon {
+				position: absolute;
+				top: 0;
+				right: 15rpx;
+				width: 30rpx;
+				height: 30rpx;
+			}
+			.img_bottom {
+				position: absolute;
+				bottom: 0;
+				left: 0;
+				width: 100%;
+				height: 36rpx;
+				background: rgba(0,0,0,0.5);
+				border-radius: 0px 0px 16rpx 16rpx;
+				font-size: 20rpx;
+				font-weight: 400;
+				color: #FFFFFF;
+				line-height: 28rpx;
+			}
 			.box_item {
 				padding: 28rpx 0;
 				border-bottom: 1rpx solid #F5F5F5;
@@ -315,5 +510,8 @@
 			color: #222222;
 			line-height: 50rpx;
 		}
+		.choose {
+			padding: 20rpx 0;
+		}
 	}
 </style>

+ 228 - 44
pages/release/waixie/waixie.vue

@@ -18,7 +18,7 @@
 				<view class="add_text">添加</view>
 			</view>
 		</view>
-		<block v-for="(item,index) in items">
+		<block v-for="(item,index) in items" :key="index">
 			<view class="box">
 				<view class="box_item hflex acenter">
 					<view class="left">商品{{index + 1}}</view>
@@ -34,7 +34,7 @@
 				</view>
 				<view class="box_item hflex acenter jbetween">
 					<view class="left">附件</view>
-					<view class="center hflex">
+					<view class="center vflex">
 						<block v-for="(item2,index2) in item.enclosure" :key="index2">
 							<view>{{item2.filename}}</view>
 						</block>
@@ -50,11 +50,11 @@
 		<view class="box">
 			<view class="box_item1">
 				<view class="left">生产技术标准</view>
-				<u-textarea v-model="standard_tech" placeholder="请填写生产技术的标准"></u-textarea>
+				<u-textarea v-model="standard_tech" confirmType="done" placeholder="请填写生产技术的标准"></u-textarea>
 			</view>
 			<view class="box_item1">
 				<view class="left">生产验收标准</view>
-				<u-textarea v-model="standard_check" placeholder="请填写生产验收的标准"></u-textarea>
+				<u-textarea v-model="standard_check" confirmType="done" placeholder="请填写生产验收的标准"></u-textarea>
 			</view>
 			<view class="box_item hflex acenter">
 				<view class="left">交货地址</view>
@@ -64,13 +64,41 @@
 				<view class="left">交货时间</view>
 				<u-input v-model="post_time" border="none" disabled disabledColor="#fff" placeholder="请选择交货时间" suffixIcon="arrow-right"></u-input>
 			</view>
-			<u-datetime-picker :show="show_time" :formatter="formatter" :minDate="Number(new Date())" mode="datetime" @close="close" @confirm="selectTime"></u-datetime-picker>
+			<u-datetime-picker :show="show_time"  :minDate="Number(new Date())"  mode="date" @cancel="close" @confirm="selectTime"></u-datetime-picker>
 		</view>
 		<view class="box">
 			<view class="box_title">图片/视频</view>
-			<u-upload :fileList="fileList1" :accept='accept'  @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload>
+			<view class="hflex acenter fwrap" style="padding-bottom: 20rpx;">
+				<block v-for="(item,index) in fileList1" :key="index">
+					<view v-if="item.type == 'image'" style="position: relative;">
+						<image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<view v-if="item.type == 'video'" style="position: relative;">
+						<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video>
+						<image src="/static/images/common/popu_close.png" class="close_icon" @click="deletePic2(index)"></image>
+					</view>
+					<!-- <image :src="item.url" class="img" mode="aspectFill" v-if="item.type == 'image'"></image>
+					<video :src="item.url" direction="0" class="img" v-if="item.type == 'video'"></video> -->
+				</block>
+				<!-- <u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="9" width="200rpx" height="200rpx"></u-upload> -->
+				<image src="/static/images/common/upload_img.png" class="img" @click="choose"></image>
+			</view>
 		</view>
 		<view class="btn hflex acenter jcenter" @click="release">立即发布</view>
+		<u-popup :show="show_choose" @close="close">
+			<view class="vflex acenter">
+				<view class="hflex acenter jcenter choose" @click="choose_img">
+					<view>图片</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="choose_video">
+					<view>视频</view>
+				</view>
+				<view class="hflex acenter jcenter choose" @click="close">
+					<view>取消</view>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
@@ -106,8 +134,8 @@
 						}
 					]
 				},
+				back: false,
 				show: false,
-				accept: ['image','video'],
 				fileList1: [],
 				post_address: '',
 				post_time: '',
@@ -115,6 +143,7 @@
 				standard_tech: '',
 				standard_check: '',
 				id: '',
+				show_choose: false
 			}
 		},
 		onLoad(options) {
@@ -123,6 +152,9 @@
 				that.id = options.id
 				that.getData()
 			}
+			if(options.back) {
+				that.back = options.back
+			}
 		},
 		methods: {
 			getData() {
@@ -150,47 +182,63 @@
 			},
 			close() {
 				that.show_time = false
+				that.show_choose = false
 			},
 			selectTime(e) {
 				that.post_time = $api.formatDate(e)
 				that.close()
 			},
 			upload(index) {
-				uni.chooseFile({
-					count: 9, //默认100
-					type:'all',
-					success: function (res) {
-						const tempFilePaths = res.tempFilePaths;
-						uni.uploadFile({
-							url: $api.config.baseUrl + '/data/api.auth.Center/upload', //仅为示例,非真实的接口地址
-							filePath: tempFilePaths[0],
-							name: 'file',
-							header: {
-								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
-								'api-name': 'iosapp'
-							},
-							formData: {
-								'user': 'test'
-							},
-							success: (uploadFileRes) => {
-								var data = JSON.parse(uploadFileRes.data)
-								var enclosure = {
-									filename: res.tempFiles[0].name,
-									fileurl: data.data.url
-								}
-								if(that.items[index].enclosure[0].filename == '') {
-									that.items[index].enclosure.splice(0,1,enclosure)
-								} else {
-									that.items[index].enclosure.push(enclosure)
-								}
-								console.log('items',that.items);
-							}
-						});
-					},
-					fail: function(res) {
-						console.log('fail',res);
-					}
-				});
+				let platform = '';
+				uni.getSystemInfo({ 
+				    success:function(res){ platform = res.platform; } 
+				}) 
+				if(platform == 'ios'){ 
+				    const iOSFileSelect = uni.requireNativePlugin('YangChuan-YCiOSFileSelect'); 
+				    // apple document-types 文件类型参数 https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html 
+				    // 文件类型参数
+				    let params = { "document-types":["public.text","public.zip","public.data","com.adobe.pdf", "com.microsoft.word.doc","com.adobe.postscript", "com.microsoft.excel.xls","com.adobe.encapsulated- postscript", "com.microsoft.powerpoint.ppt","com.adobe.photoshop- image", "com.microsoft.word.rtf","com.microsoft.advanced- systems-format", "com.microsoft.advanced- stream-redirector"], "isBase64":0 } 
+				    iOSFileSelect.show(params, result => { 
+				        let status = parseInt(result.status); 
+				        // 状态200选取成功
+				        if(status == 200){ 
+							console.log(result);
+				            let url = result.url; 
+				            uni.downloadFile({ url:url, success:function(res){ 
+				                if(res.statusCode == 200){ 
+				                    // filePath 可用于 uni.uploadFile 上传的路径
+				                    let filePath = res.tempFilePath; 
+										uni.uploadFile({
+											url: $api.config.baseUrl + '/data/api.auth.Center/upload', //仅为示例,非真实的接口地址
+											filePath: filePath,
+											name: 'file',
+											header: {
+												'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+												'api-name': 'iosapp'
+											},
+											formData: {
+												'user': 'test'
+											},
+											success: (uploadFileRes) => {
+												var data = JSON.parse(uploadFileRes.data)
+												var enclosure = {
+													filename: result.lastName,
+													fileurl: data.data.url
+												}
+												if(that.items[index].enclosure[0].filename == '') {
+													that.items[index].enclosure.splice(0,1,enclosure)
+												} else {
+													that.items[index].enclosure.push(enclosure)
+												}
+												console.log('items',that.items);
+											}
+										});
+				                    } 
+				                } 
+				            }); 
+				        }
+					}); 
+				}
 			},
 			// 删除图片
 			deletePic(event) {
@@ -198,6 +246,10 @@
 			},
 			// 新增图片
 			async afterRead(event) {
+				uni.showLoading({
+					title: '上传中',
+					mask: true
+				})
 				let lists = [].concat(event.file)
 				let fileListLen = this[`fileList${event.name}`].length
 				lists.map((item) => {
@@ -216,13 +268,16 @@
 						url: result.url
 					}))
 					fileListLen++
+					if(lists.length - 1 == i) {
+						uni.hideLoading()
+					}
 				}
 				console.log(that.fileList1);
 			},
 			uploadFilePromise(url) {
 				return new Promise((resolve, reject) => {
 					let a = uni.uploadFile({
-						url: $api.config.baseUrl + '/data/api.auth.Center/upload', // 仅为示例,非真实的接口地址
+						url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
 						filePath: url,
 						name: 'file',
 						header: {
@@ -266,6 +321,22 @@
 					}
 					images.push(image)
 				}
+				for(var i=0;i<that.items.length;i++) {
+					if(!that.items[i].name || !that.items[i].spec || !that.items[i].number) {
+						$api.info('商品不能为空')
+						return
+					}
+					if(!that.items[i].enclosure) {
+						that.items[i].enclosure = {
+							filename: '',
+							fileurl: ''
+						}
+					}
+				}
+				if(images.length <=0) {
+					$api.info('请选择图片')
+					return
+				}
 				$api.req({
 					url: '/data/api.business.Purchase/coordination_order',
 					method: 'POST',
@@ -283,9 +354,104 @@
 				}, function(res) {
 					if(res.code == 1) {
 						$api.info(res.info)
+						if(that.back) {
+							$api.jump(-1)
+						} else {
+							$api.jump('/pages/tabbar/index/index',2)
+						}
 					}
 				})
-			}
+			},
+			choose() {
+				that.show_choose = true
+			},
+			choose_img() {
+				that.close()
+				
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album','camera'], //从相册选择
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFiles[0].path
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								console.log('data:',data);
+								let item = {
+									type: 'image',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						
+					}
+				});
+			},
+			choose_video() {
+				that.close()
+				
+				uni.chooseVideo({
+					sourceType: ['camera', 'album'],
+					success: function (res) {
+						uni.showLoading({
+							title: '上传中',
+							mask: true
+						})
+						let fileListLen = that.fileList1.length
+						let file = res.tempFilePath
+						console.log(file);
+						uni.uploadFile({
+							url: $api.config.baseUrl + '/data/api.auth.Center/upload',  
+							filePath: file,
+							name: 'file',
+							header: {
+								'token': uni.getStorageSync('token')?uni.getStorageSync('token'):'',
+								'api-name': 'iosapp'
+							},
+							formData: {
+								user: 'test'
+							},
+							success: (res2) => {
+								var data = JSON.parse(res2.data)
+								let item = {
+									type: 'video',
+									url: data.data.url
+								}
+								that.fileList1.push(item)
+								uni.hideLoading()
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+			deletePic2(index) {
+				that.fileList1.splice(index,1)
+			},
 		},
 	}
 </script>
@@ -320,6 +486,24 @@
 				line-height: 40rpx;
 				padding: 24rpx 0 20rpx;
 			}
+			.img {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+				border-radius: 16rpx;
+			}
+			video {
+				width: 200rpx;
+				height: 200rpx;
+				margin: 0 20rpx 20rpx 0;
+			}
+			.close_icon {
+				position: absolute;
+				top: 0;
+				right: 15rpx;
+				width: 30rpx;
+				height: 30rpx;
+			}
 			.box_item {
 				padding: 28rpx 0;
 				border-bottom: 1rpx solid #F5F5F5;

+ 94 - 17
pages/tabbar/index/index.vue

@@ -6,7 +6,7 @@
 					<image src="/static/images/common/logo.png" class="logo"></image>
 				</view>
 				<view class="u-nav-slot" slot="right">
-					<u-search placeholder="请输入搜索内容" :showAction="false" v-model="search"></u-search>
+					<u-search placeholder="请输入搜索内容" :showAction="false" v-model="search" @search="openSearch"></u-search>
 				</view>
 			</u-navbar>
 		</view>
@@ -18,26 +18,34 @@
 			<scroll-view scroll-y="true" class="menu_left">
 				<view class="vflex">
 					<block v-for="(item,index) in cateList" :key="index">
-						<view class="left_item hflex acenter jcenter" :class="index == left_active? 'left_active':''">{{item.name}}</view>
+						<view class="left_item text_hide hflex acenter" :class="index == left_active? 'left_active':''" @click="clickTab1(index)">
+							<text class="text_hide" style="width:100%; text-align: center;">{{item.name}}</text>
+						</view>
 					</block>
 				</view>
 			</scroll-view>
 			<scroll-view scroll-y="true" class="menu_right">
-				<u-tabs :list="cateList[left_active].sub" @click="clickTab2" lineWidth="0" :activeStyle="{
+				<!-- <u-tabs :list="cateList[left_active].sub" @click="clickTab2" lineWidth="0" :activeStyle="{
 					background: '#E7EBFF',borderRadius: '24rpx',border: '1rpx solid #5471FF',color: '#5B77FF',padding: '0 24rpx'
 				}" :inactiveStyle="{
-					color: '#393939',background: '#F3F3F7',borderRadius: '24rpx'}" v-if="!cate_show">
+					color: '#393939',background: '#F3F3F7',borderRadius: '24rpx',padding: '0 24rpx'}"  :current="right_active">
 					<view slot="right" style="padding-left: 4rpx;" @tap="open">
 						<view class="tabs_text hflex acenter jcenter">全部</view>
 					</view>
-				</u-tabs>
+				</u-tabs> -->
+				<scroll-view scroll-x="true" style="white-space: nowrap;position: relative;margin-bottom: 20rpx;width: 470rpx; height: 48rpx;">
+					<view class="hflex acenter" v-if="cateList[left_active] && !cate_show">
+						<view v-for="(item,index) in cateList[left_active].sub" :key="index" class="right_tab" :class="index == right_active? 'right_tab_active' : ''" @click="clickTab2(index)">{{item.name}}</view>
+					</view>
+				</scroll-view>
+				<view class="tabs_text hflex jcenter" @tap="open" v-if="!cate_show && left_active != -1">全部</view>
 				<view class="cate_bg" v-if="cate_show" @click="open">
 					<view class="cate_top" @click.stop="">
 						<view class="hflex acenter jbetween">
 							<view class="top_left">选择分类</view>
 							<view class="top_text" @click="open">收起</view>
 						</view>
-						<view class="hflex acenter fwrap">
+						<view class="hflex acenter fwrap" v-if="cateList[left_active]">
 							<block v-for="(item2,index2) in cateList[left_active].sub" :key="index2">
 								<view class="cate hflex acenter jcenter" :class="right_active == index2?'cate_active':''" @click="clickcate(index2)">{{item2.name}}</view>
 							</block>
@@ -135,24 +143,34 @@
 				tab_active: 0,
 				current: 0,
 				cateList: [],
-				left_active: 0,
+				left_active: -1,
 				right_active: 0,
 				pageList: [],
 				cate_show: false,
 				page: 1,
 				limit: 10,
-				total: 10
+				total: 10,
+				triggered: false,
 			}
 		},
 		onLoad() {
 			that = this
-			
+			that.isLogin()
+			// uni.startPullDownRefresh();
 		},
 		onShow() {
 			that.getCate()
-			
+		},
+		onPullDownRefresh() {
+			that.getCate()
 		},
 		methods: {
+			isLogin() {
+				var token = uni.getStorageSync('token')
+				if(!token) {
+					$api.jump('/pages/login/codeLogin/codeLogin')
+				}
+			},
 			getCate() {
 				$api.req({
 					url: '/data/api.business.Goods/getCate'
@@ -164,16 +182,28 @@
 				})
 			},
 			getList() {
+				var cateids = ''
+				if(that.left_active == -1) {
+					cateids = ''
+				} else if(that.cateList[that.left_active].sub.length>0) {
+					cateids = that.cateList[that.left_active].sub[that.right_active].id
+				} else {
+					cateids = that.cateList[that.left_active].id
+				}
 				$api.req({
 					url: '/data/api.business.Goods/goods_list',
 					data: {
 						name: that.search,
 						status: that.tabs[that.tab_active].status,
-						cateids: that.cateList[that.left_active].sub[that.right_active].id,
+						cateids: cateids,
 						page: that.page
 					}
 				}, function(res) {
 					if(res.code == 1) {
+						for(var i=0;i<res.data.list.list.length;i++) {
+							var temp = res.data.list.list[i].cover.split('|')
+							res.data.list.list[i].cover = temp[0]
+						}
 						for (var i=0;i<that.tabs.length;i++) {
 							that.$set(that.tabs[i].badge,'value',res.data.count[i])
 						}
@@ -185,7 +215,9 @@
 						that.total = res.data.list.page.total
 						that.limit = res.data.list.page.limit
 					}
+					uni.stopPullDownRefresh();
 				})
+				
 			},
 			clickTab(e) {
 				var index = e.index
@@ -198,24 +230,40 @@
 						that.$set(that.tabs[i].badge,"color",'#888888')
 					}
 				}
+				that.left_active = -1
+				that.right_active = 0
 				that.tab_active = e.index
 				that.page = 1
 				that.pageList = []
 				that.getList()
 			},
+			clickTab1(e) {
+				that.left_active = e
+				that.right_active = 0
+				that.page = 1
+				that.pageList = []
+				that.getList()
+			},
 			clickTab2(e) {
-				that.right_active = e.index
+				that.right_active = e
 				that.page = 1
 				that.pageList = []
 				that.getList()
 			},
 			clickcate(index) {
 				that.right_active = index
+				console.log(that.right_active);
 				that.page = 1
 				that.pageList = []
 				that.getList()
 				that.open()
 			},
+			openSearch(e) {
+				that.search = e
+				that.page = 1
+				that.pageList = []
+				that.getList()
+			},
 			open() {
 				that.cate_show = !that.cate_show
 			},
@@ -264,7 +312,7 @@
 					that.getList()
 				}
 				
-			}
+			},
 		},
 	}
 </script>
@@ -273,6 +321,7 @@
 	.content::v-deep {
 		position: relative;
 		.top {
+			
 			.logo {
 				width: 160rpx;
 				height: 60rpx;
@@ -283,20 +332,23 @@
 			}
 		}
 		.tabs {
+			
 		}
 		.menuList {
 			width: 100%;
+			margin-bottom: 328rpx;
 			.menu_left {
-				width: 180rpx;
+				width: 200rpx;
 				height: 1078rpx;
 				background: #F5F5F5;
 				border-radius: 0px 28rpx 0px 0px;
 				.left_item {
+					width: 200rpx;
 					font-size: 28rpx;
 					font-weight: 400;
 					color: #222222;
 					line-height: 40rpx;
-					padding: 30rpx 0;
+					padding: 30rpx 20rpx;
 				}
 				.left_active {
 					color: #506DFF;
@@ -304,10 +356,30 @@
 				}
 			}
 			.menu_right {
-				width: 570rpx;
+				width: 550rpx;
 				height: 1078rpx;
 				background: #FFFFFF;
 				position: relative;
+				.right_tab {
+					background: #F3F3F7;
+					border-radius: 24rpx;
+					font-size: 22rpx;
+					font-weight: 400;
+					color: #393939;
+					line-height: 48rpx;
+					padding: 0 24rpx;
+					height: 48rpx;
+					margin-right: 20rpx;
+					
+				}
+				.right_tab:nth-last-child(1) {
+					margin-right: 80rpx;
+				}
+				.right_tab_active {
+					background: #E7EBFF;
+					border: 1rpx solid #5471FF;
+					color: #5B77FF;
+				}
 				.cate_bg {
 					position: absolute;
 					top: 0;
@@ -352,13 +424,17 @@
 					}
 				}
 				.tabs_text {
+					position: absolute;
+					z-index: 99;
+					right: 0;
+					top: 0;
 					width: 80rpx;
 					height: 56rpx;
 					background: #FFFFFF;
 					font-size: 20rpx;
 					font-weight: 400;
 					color: #393939;
-					line-height: 28rpx;
+					line-height: 48rpx;
 				}
 				.right_item {
 					width: 100%;
@@ -381,6 +457,7 @@
 						}
 					}
 					.item_title {
+						max-width: 100%;
 						font-size: 28rpx;
 						font-weight: 500;
 						color: #222222;

+ 36 - 3
pages/tabbar/mine/mine.vue

@@ -79,9 +79,9 @@
 		data() {
 			return {
 				user: {
-					message_num: 12
+					message_num: 0
 				},
-				login: true,
+				login: false,
 				orderList: [
 					{
 						id: 2,
@@ -125,7 +125,29 @@
 				}, function(res) {
 					if(res.code == 1) {
 						that.user = res.data
-					} else if(res.code == 0) {
+						uni.setStorageSync('id',res.data.id)
+						var options = {
+						  user: res.data.huanxinID,
+						  pwd: '12345678',
+						  appKey: uni.WebIM.config.appkey,
+						  success: function (res2) {
+							wx.setStorageSync("myUsername",res.data.huanxinID)
+							
+						  },
+						  error: function(error){
+							  console.log(error);
+						  }
+						};
+						uni.WebIM.conn.open(options);
+						setTimeout(()=> {
+							let option = {
+							    nickname: res.data.nickname,
+							    avatarurl: res.data.headimg,
+							}
+							uni.WebIM.conn.updateOwnUserInfo(option);
+						},3000)
+						
+					} else {
 						uni.removeStorageSync('token')
 						that.login = false
 						that.user = {}
@@ -161,6 +183,7 @@
 					$api.jump('/pages/mine/message/index')
 				} else {
 					$api.info('请先登录')
+					$api.jump('/pages/login/login/login')
 				}
 			},
 			toMoney() {
@@ -168,14 +191,22 @@
 					$api.jump('/pages/mine/wallet/wallet')
 				} else {
 					$api.info('请先登录')
+					$api.jump('/pages/login/login/login')
 				}
 			},
 			toOrder(id) {
+				if(!that.login) {
+					$api.info('请先登录')
+					$api.jump('/pages/login/login/login')
+					return
+				}
 				if(id != 5) {
 					$api.jump('/pages/order/list?status=' + id)
 				} else {
 					$api.jump('/pages/order/refund')
+					
 				}
+				
 			},
 			toService(index) {
 				var url = ''
@@ -200,6 +231,7 @@
 					$api.jump(url)
 				} else {
 					$api.info('请先登录')
+					$api.jump('/pages/login/login/login')
 				}
 			},
 		},
@@ -233,6 +265,7 @@
 			width: 100%;
 			box-sizing: border-box;
 			padding: 0 30rpx;
+			margin-bottom: 80rpx;
 			.amount {
 				width: 100%;
 				height: 144rpx;

BIN
static/images/Camera.png


BIN
static/images/Emoji.png


BIN
static/images/ad.png


BIN
static/images/camora.png


BIN
static/images/ctbg.png


BIN
static/images/faces/btn_del.png


BIN
static/images/faces/del.png


BIN
static/images/faces/ee_1.png


BIN
static/images/faces/ee_10.png


BIN
static/images/faces/ee_11.png


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است