Przeglądaj źródła

调整积分商城

RuHu.Xu 10 miesięcy temu
rodzic
commit
fc90230878
100 zmienionych plików z 7313 dodań i 3464 usunięć
  1. 60 35
      App.vue
  2. 1 0
      index.html
  3. 8 3
      main.js
  4. 0 10
      manifest.json
  5. 11 5
      package.json
  6. 47 7
      pages.json
  7. 1 1
      pages/activity/groupon/detail.vue
  8. 33 24
      pages/app/sign.vue
  9. 126 134
      pages/chat/components/select-popup.vue
  10. 6 6
      pages/chat/index.vue
  11. 303 0
      pages/chat/speechtotext.vue
  12. 1 1
      pages/commission/components/commission-auth.vue
  13. 2 2
      pages/commission/components/commission-log.vue
  14. 9 9
      pages/commission/components/commission-menu.vue
  15. 75 55
      pages/commission/wallet.vue
  16. 1 1
      pages/coupon/detail.vue
  17. 4 4
      pages/goods/components/detail/detail-activity-tip.vue
  18. 17 5
      pages/goods/components/detail/detail-navbar.vue
  19. 0 7
      pages/goods/components/detail/detail-tabbar.vue
  20. 5 5
      pages/goods/groupon.vue
  21. 60 34
      pages/goods/index.vue
  22. 1 1
      pages/index/category.vue
  23. 167 41
      pages/index/login.vue
  24. 8 3
      pages/index/user.vue
  25. 117 71
      pages/order/aftersale/detail.vue
  26. 69 43
      pages/order/aftersale/return-delivery.vue
  27. 69 48
      pages/order/confirm.vue
  28. 600 612
      pages/order/detail.vue
  29. 1 1
      pages/order/express/log.vue
  30. 1 0
      pages/order/list.vue
  31. 1 1
      pages/order/otherlist.vue
  32. 5 5
      pages/pay/index.vue
  33. 269 257
      pages/pay/result.vue
  34. 3 3
      pages/public/error.vue
  35. 3 23
      pages/public/setting.vue
  36. 281 0
      pages/user/dummyAddress/edit.vue
  37. 152 0
      pages/user/dummyAddress/list.vue
  38. 12 12
      pages/user/info.vue
  39. 1 2
      pages/user/qrcode-share.vue
  40. 57 10
      pages/user/setting.vue
  41. 40 35
      pages/user/wallet/ScoreLog.vue
  42. 268 0
      pages/user/wallet/maxScoreLog.vue
  43. 149 60
      pages/user/wallet/score.vue
  44. 23 22
      pages/user/wallet/team.vue
  45. 11 1
      sheep/api/distri/score.js
  46. 8 6
      sheep/api/member/address.js
  47. 185 138
      sheep/api/member/auth.js
  48. 1 1
      sheep/api/member/signin.js
  49. 8 0
      sheep/api/pay/order.js
  50. 10 0
      sheep/api/product/favorite.js
  51. 14 0
      sheep/api/system/voice.js
  52. 19 5
      sheep/components/s-address-item/s-address-item.vue
  53. 6 31
      sheep/components/s-auth-modal/components/account-login.vue
  54. 131 0
      sheep/components/s-auth-modal/components/phone-international-input.vue
  55. 203 0
      sheep/components/s-auth-modal/components/register.vue
  56. 60 33
      sheep/components/s-auth-modal/components/sms-login.vue
  57. 58 15
      sheep/components/s-auth-modal/s-auth-modal.vue
  58. 4 4
      sheep/components/s-coupon-card/s-coupon-card.vue
  59. 1 1
      sheep/components/s-goods-card/s-goods-card.vue
  60. 718 715
      sheep/components/s-goods-column/s-goods-column.vue
  61. 229 231
      sheep/components/s-layout/s-layout.vue
  62. 3 3
      sheep/components/s-live-card/s-live-card.vue
  63. 7 7
      sheep/components/s-menu-tools/s-menu-tools.vue
  64. 13 12
      sheep/components/s-order-card/s-order-card.vue
  65. 9 9
      sheep/components/s-points-pop/s-points-pop.vue
  66. 2 2
      sheep/components/s-select-groupon-sku/s-select-groupon-sku.vue
  67. 194 48
      sheep/components/s-select-sku/s-select-sku.vue
  68. 1 1
      sheep/components/s-share-modal/canvas-poster/index.vue
  69. 1 1
      sheep/components/s-share-modal/canvas-poster/poster/index.js
  70. 1 1
      sheep/components/s-share-modal/canvas-poster/poster/user.js
  71. 3 1
      sheep/components/s-share-modal/canvas-poster/useCanvas.js
  72. 148 137
      sheep/components/s-share-modal/s-share-modal.vue
  73. 121 0
      sheep/components/s-signup-modal/s-signup-modal.vue
  74. 1 1
      sheep/components/s-uploader/s-uploader.vue
  75. 13 3
      sheep/components/s-user-card/s-user-card.vue
  76. 16 19
      sheep/components/s-wallet-card/s-wallet-card.vue
  77. 128 0
      sheep/components/s-wallet-modal/s-wallet-modal.vue
  78. 236 139
      sheep/hooks/useModal.js
  79. 1298 0
      sheep/libs/country.json
  80. 12 9
      sheep/platform/pay.js
  81. 36 2
      sheep/platform/provider/wechat/officialAccount.js
  82. 87 83
      sheep/request/index.js
  83. 1 1
      sheep/scss/_var.scss
  84. 11 1
      sheep/store/modal.js
  85. 1 0
      sheep/store/sys.js
  86. 219 205
      sheep/store/user.js
  87. 1 0
      sheep/url/index.js
  88. 17 0
      sheep/validate/form.js
  89. BIN
      static/icon/audioPaly.png
  90. BIN
      static/icon/points.png
  91. BIN
      static/icon/select-icon.png
  92. BIN
      static/icon/setting.png
  93. BIN
      static/images/WechatMiniProgram.png
  94. BIN
      static/images/WechatOfficialAccount.png
  95. BIN
      static/images/activity-btn-disabled.png
  96. BIN
      static/images/all_coupon.png
  97. BIN
      static/images/all_order.png
  98. BIN
      static/images/apple.png
  99. BIN
      static/images/browse.png
  100. BIN
      static/images/cargo.png

+ 60 - 35
App.vue

@@ -1,39 +1,64 @@
 <script setup>
-  import { onLaunch, onShow, onError } from '@dcloudio/uni-app';
-  import { ShoproInit } from './sheep';
-
-  onLaunch(() => {
-    // 隐藏原生导航栏 使用自定义底部导航
-    uni.hideTabBar();
-
-    // 加载Shopro底层依赖
-    ShoproInit();
-  });
-
-  onError((err) => {
-    console.log('AppOnError:', err);
-  });
-
-  onShow((options) => {
-    // #ifdef APP-PLUS
-    // 获取urlSchemes参数
-    const args = plus.runtime.arguments;
-    if (args) {
-    } 
-
-    // 获取剪贴板
-    uni.getClipboardData({
-      success: (res) => { },
-    });
-    // #endif
-
-    // #ifdef MP-WEIXIN
-    // 确认收货回调结果
-    console.log(options,'options');
-    // #endif
-  });
+	import {
+		onLaunch,
+		onShow,
+		onError,
+		onHide
+	} from '@dcloudio/uni-app';
+	import {
+		ShoproInit
+	} from './sheep';
+	import {
+		autoSign,
+		cancelAutoSign,
+		resetSignStatusIfNeeded
+	} from './sheep/hooks/useModal';
+
+	onShow((options) => {
+		autoSign()
+		// #ifdef APP-PLUS
+		// 获取urlSchemes参数
+		const args = plus.runtime.arguments;
+		if (args) {}
+
+		// 获取剪贴板
+		uni.getClipboardData({
+			success: (res) => {},
+		});
+		// #endif
+
+		// #ifdef MP-WEIXIN
+		// 确认收货回调结果
+		// console.log(options, 'options');
+		// #endif
+	});
+	onHide(() => {
+		// console.log("页面隐藏了,取消自动签到");
+		cancelAutoSign()
+	});
+
+	onLaunch(() => {
+
+		// 隐藏原生导航栏 使用自定义底部导航
+		uni.hideTabBar();
+
+		// 加载Shopro底层依赖
+		ShoproInit();
+		// 每天凌晨重置签到状态
+		resetSignStatusIfNeeded();
+	});
+
+	onError((err) => {
+		console.log('AppOnError:', err);
+	});
 </script>
 
 <style lang="scss">
-  @import '@/sheep/scss/index.scss';
-</style>
+	.uni-picker-container{
+		z-index:999999;
+	}
+	.uni-picker-container .uni-picker-content{
+		height:800rpx;
+	}
+	@import '@/sheep/scss/index.scss';
+</style>

+ 1 - 0
index.html

@@ -8,6 +8,7 @@
       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
     />
     <title></title>
+	
     <!--preload-links-->
     <!--app-context-->
   </head>

+ 8 - 3
main.js

@@ -1,10 +1,15 @@
 import App from './App';
 import { createSSRApp } from 'vue';
 import { setupPinia } from './sheep/store';
-
-
+function clearLinkId() {
+  // 清理 Local Storage
+  uni.removeStorageSync('linkId');
+  console.log("五分钟,清了linkId");
+}
+// 每五分钟(300000 毫秒)清理一次缓存
+setInterval(clearLinkId, 300000);
 export function createApp() {
-
+	
   const app = createSSRApp(App);
   
   setupPinia(app);

+ 0 - 10
manifest.json

@@ -220,16 +220,6 @@
             "treeShaking" : {
                 "enable" : true
             }
-        },
-        "proxy" : {
-            "/api" : {
-                "target" : "https://zxgz.newfeifan.cn/#/", //自己项目接口域名
-                "changeOrigin" : true, //是否跨域
-                "secure" : true, // 设置支持https协议的代理
-                "pathRewrite" : {
-                    "^/api" : ""
-                }
-            }
         }
     },
     "vueVersion" : "3"

+ 11 - 5
package.json

@@ -3,11 +3,14 @@
   "name": "shopro",
   "displayName": "中星",
   "version": "1.0.1",
-  "description": "芋道商城,一套代码,同时发行到iOS、Android、H5、微信小程序多个平台,请使用手机扫码快速体验强大功能",
+  "description": "广州非繁科技有限公司商城营销管理系统",
   "scripts": {
     "prettier": "prettier --write  \"{pages,sheep}/**/*.{js,json,tsx,css,less,scss,vue,html,md}\""
   },
-  "repository": "https://github.com/sheepjs/shop.git",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sheepjs/shop.git"
+  },
   "keywords": [
     "商城",
     "B2C",
@@ -90,6 +93,7 @@
   "dependencies": {
     "@hyoga/uni-socket.io": "^1.0.1",
     "dayjs": "^1.11.7",
+    "libphonenumber-js": "^1.11.2",
     "lodash": "^4.17.21",
     "luch-request": "^3.0.8",
     "pinia": "^2.0.33",
@@ -99,6 +103,8 @@
   },
   "devDependencies": {
     "prettier": "^2.8.7",
-    "vconsole": "^3.15.0"
-  }
-}
+    "vconsole": "^3.15.0",
+    "vite": "^4.0.0"
+  },
+  "main": "main.js"
+}

+ 47 - 7
pages.json

@@ -55,10 +55,7 @@
 			}
 		},
 		{
-			"path": "pages/index/login",
-			"style": {
-				"navigationBarTitleText": "登录"
-			}
+			"path": "pages/index/login"
 		},
 		{
 			"path": "pages/index/search",
@@ -320,7 +317,7 @@
 				{
 					"path": "address/list",
 					"style": {
-						"navigationBarTitleText": "收货地址"
+						"navigationBarTitleText": "实体商品收货地址"
 					},
 					"meta": {
 						"auth": true,
@@ -329,6 +326,18 @@
 						"group": "用户中心"
 					}
 				},
+				{
+					"path": "dummyAddress/list",
+					"style": {
+						"navigationBarTitleText": "虚拟商品收货地址"
+					},
+					"meta": {
+						"auth": true,
+						"sync": true,
+						"title": "虚拟商品收货地址",
+						"group": "用户中心"
+					}
+				},
 				{
 					"path": "invoice/edit",
 					"style": {
@@ -361,6 +370,16 @@
 						"title": "编辑地址"
 					}
 				},
+				{
+					"path": "dummyAddress/edit",
+					"style": {
+						"navigationBarTitleText": "编辑地址"
+					},
+					"meta": {
+						"auth": true,
+						"title": "编辑地址"
+					}
+				},
 				{
 					"path": "wallet/money",
 					"style": {
@@ -376,7 +395,7 @@
 				{
 					"path": "wallet/score",
 					"style": {
-						"navigationBarTitleText": "我的积分"
+						"navigationBarTitleText": "我的数字权益"
 					},
 					"meta": {
 						"auth": true,
@@ -397,6 +416,12 @@
 						"group": "用户中心"
 					}
 				},
+				{
+					"path": "wallet/ScoreLog"
+				},
+				{
+					"path": "wallet/maxScoreLog"
+				},
 				{
 					"path": "wallet/team",
 					"style": {
@@ -628,7 +653,22 @@
 					"title": "客服",
 					"group": "客服"
 				}
-			}]
+			},
+			{
+				"path" : "speechtotext",
+				"style" : 
+				{
+					"navigationBarTitleText" : "语音转文字",
+					"enablePullDownRefresh" : false
+				},
+				"meta": {
+					"auth": true,
+					"sync": true,
+					"title": "语音转文字",
+					"group": "语音转文字"
+				}
+			}
+			]
 		},
 		{
 			"root": "pages/pay",

+ 1 - 1
pages/activity/groupon/detail.vue

@@ -111,7 +111,7 @@
           <!-- 还有几个坑位 -->
           <view class="default-avatar ss-m-r-24 ss-m-b-20" v-for="item in state.remainNumber" :key="item">
             <image
-              :src="sheep.$url.static('/static/img/shop/avatar/unknown.png')"
+              :src="sheep.$url.static('/static/images/unknown.png')"
               class="avatar-img"
             ></image>
           </view>

+ 33 - 24
pages/app/sign.vue

@@ -43,7 +43,7 @@
 							<view v-if="item.isSign" class="is-sign ss-flex ss-row-center">
 								<view class="is-sign-num">{{ item.day < 10 ? '0' + item.day : item.day }}</view>
 								<image class="is-sign-image"
-									:src="sheep.$url.static('/static/img/shop/app/correct.png')">
+									:src="sheep.$url.static('/static/images/correct.png')">
 								</image>
 							</view>
 							<!-- 未签到日期 -->
@@ -62,7 +62,6 @@
 
 					<!-- 签到按钮 -->
 					<view class="ss-flex ss-col-center ss-row-center sign-box ss-m-y-40">
-
 						<button class="ss-reset-button sign-btn" v-if="state.isSign === 0" @tap="onSign">签到</button>
 						<button class="ss-reset-button already-btn" v-if="state.isSign === 1" disabled>已签到</button>
 					</view>
@@ -71,44 +70,43 @@
 			<view class="bg-white ss-m-t-16 ss-p-t-30 ss-p-b-60 ss-p-x-40">
 				<view class="activity-title ss-m-b-30">签到说明</view>
 				<view class="activity-des">
-					1、每日签到固定 {{ state.data.rules.everyday }} 积分
-					<text v-if="state.data.rules.is_inc == '1'">
-						,次日递增奖励 {{ state.data.rules.inc_num }} 积分,直到
+					1、每日签到固定 {{ state.data.signInSocialStatus }} 身价
+					<!-- <text v-if="state.data.rules.is_inc == '1'">
+						,次日递增奖励 {{ state.data.rules.inc_num }} 身价,直到
 						{{ state.data.rules.until_day }} 天之后不再增加
-					</text>
+					</text> -->
 				</view>
 				<view class="activity-des" v-if="state.data.rules.discounts?.length > 0">
 					2、<text class="" v-for="i in state.data.rules.discounts" :key="i">
-						连续签到 {{ i.full }} 天,奖励 {{ i.value }} 积分
+						连续签到 {{ i.full }} 天,奖励 {{ i.value }} 身价
 					</text>
 				</view>
 				<view class="activity-des" v-if="state.data.rules.is_replenish == '1'">
 					{{ state.data.rules.discounts?.length > 0 ? '3' : '2' }}、用户在
 					{{ state.data.rules.replenish_limit }} 天内,可补签
 					{{ state.data.rules.replenish_days }} 天,每次补签消耗
-					{{ state.data.rules.replenish_num }}积分
+					{{ state.data.rules.replenish_num }}身价
 				</view>
 			</view>
 		</view>
 		<s-empty v-else-if="!state.data && !state.loading" icon="/static/data-empty.png" text="签到活动还未开始">
 		</s-empty>
-		<su-popup :show="state.showModel" type="center" round="10" :isMaskClick="false" showClose>
+		<su-popup :show="state.showModel" type="center" round="10" :isMaskClick="false">
 			<view class="model-box ss-flex-col">
 				<view class="ss-m-t-56 ss-flex-col ss-col-center">
 					<text class="cicon-check-round"></text>
-					<!-- <view class="score-title">{{ state.signin.score }}积分</view> 
-					<view class="model-title ss-flex ss-col-center ss-m-t-22 ss-m-b-30">
-						已连续打卡{{ state.continue_days }}天
-					</view> -->
 					<view class="score-title">恭喜签到成功</view>
 					<view class="model-title ss-flex ss-col-center ss-m-t-22 ss-m-b-30">
-						获得每日签到10积分
-					</view> 
+						获得每日签到{{state.signin.social}}点身价
+					</view> 
+					<view class="model-title ss-flex ss-col-center ss-m-b-30" v-if="state?.upgradeOrNot ">
+						您已升级等级为{{ state?.socialStatusName }}
+					</view>
 				</view>
 				<view class="model-bg ss-flex-col ss-col-center ss-row-right">
 					<!-- <view class="title ss-m-b-64">签到成功</view> -->
 					<view class="ss-m-b-40">
-						<button class="ss-reset-button confirm-btn" >去领得更多福利</button>
+						<button class="ss-reset-button confirm-btn" @click="onConfirm()">确认</button>
 					</view>
 				</view>
 			</view>
@@ -117,7 +115,7 @@
 			<view class="model-box ss-flex-col">
 				<view class="ss-m-t-56 ss-flex-col ss-col-center">
 					<text class="cicon-check-round"></text>
-					<view class="score-title">消耗{{ state.data?.rules.replenish_num }}积分</view>
+					<view class="score-title">消耗{{ state.data?.rules.replenish_num }}身价</view>
 					<view class="model-title ss-flex ss-col-center ss-m-t-22 ss-m-b-30">
 						已连续打卡{{ state.continue_days }}天
 					</view>
@@ -142,10 +140,14 @@
 	} from '@dcloudio/uni-app';
 	import {
 		computed,
-		reactive
+		reactive,
+		watchEffect,
+		watch,
+		onMounted
 	} from 'vue';
 	import SignInApi from '@/sheep/api/member/signin';
-	const headerBg = sheep.$url.css('/static/img/shop/app/sign.png');
+
+	const headerBg = sheep.$url.css('/static/images/sign.png');
 
 	const state = reactive({
 		data: {
@@ -199,15 +201,22 @@
 		} = await SignInApi.createSignInRecord();
 		if (code === 0) {
 			state.showModel = true;
-			state.signin = data;
-			// getData();
+			state.signin = data;
+			state.isSign = 1;
+			uni.setStorageSync('isSign', true);
 		}
 	}
 
 	function onShowRetroactive(e) {
 		state.showRetroactive = true;
 		state.date = e;
-	}
+	}
+	// 监听签到成功 3s之后自动关闭
+	watch(() => state.showModel, (newValue) => {
+		if(newValue){
+			setTimeout(onConfirm,3000)
+		}
+	})
 	//签到确认刷新页面
 	function onConfirm() {
 		state.showModel = false;
@@ -311,7 +320,7 @@
 			month: formatDate(new Date()).substring(0, 7)
 		});
 	});
-
+	
 	// 切换控制年月,上一个月,下一个月
 	const handleCalendar = (type) => {
 		const cur_year = parseInt(state.cur_year);
@@ -520,7 +529,7 @@
 
 		.model-bg {
 			width: 520rpx;
-			height: 344rpx;
+			height: 6.75rem;
 			background-size: 100% 100%;
 			background-image: v-bind(headerBg);
 			background-repeat: no-repeat;

+ 126 - 134
pages/chat/components/select-popup.vue

@@ -1,152 +1,144 @@
 <template>
-  <su-popup :show="show" showClose round="10" backgroundColor="#eee" @close="emits('close')">
-    <view class="select-popup">
-      <view class="title">
-        <span>{{ mode == 'goods' ? '我的浏览' : '我的订单' }}</span>
-      </view>
-      <scroll-view
-        class="scroll-box"
-        scroll-y="true"
-        :scroll-with-animation="true"
-        :show-scrollbar="false"
-        @scrolltolower="loadmore"
-      >
-        <view
-          class="item"
-          v-for="item in state.pagination.data"
-          :key="item"
-          @tap="emits('select', { type: mode, data: item })"
-        >
-          <template v-if="mode == 'goods'">
-            <GoodsItem :goodsData="item.goods" />
-          </template>
-          <template v-if="mode == 'order'">
-            <OrderItem :orderData="item" />
-          </template>
-        </view>
-        <uni-load-more :status="state.loadStatus" :content-text="{ contentdown: '上拉加载更多' }" />
-      </scroll-view>
-    </view>
-  </su-popup>
+	<su-popup :show="show" showClose round="10" backgroundColor="#eee" @close="emits('close')">
+		<view class="select-popup">
+			<view class="title">
+				<span>{{ mode == 'goods' ? '我的浏览' : '我的订单' }}</span>
+			</view>
+			<scroll-view class="scroll-box" scroll-y="true" :scroll-with-animation="true" :show-scrollbar="false"
+				@scrolltolower="loadmore">
+				<view class="item" v-for="item in state.pagination.data" :key="item"
+					@tap="emits('select', { type: mode, data: item })">
+					<template v-if="mode == 'goods'">
+						<GoodsItem :goodsData="item.goods" />
+					</template>
+					<template v-if="mode == 'order'">
+						<OrderItem :orderData="item" />
+					</template>
+				</view>
+				<uni-load-more :status="state.loadStatus" :content-text="{ contentdown: '上拉加载更多' }" />
+			</scroll-view>
+		</view>
+	</su-popup>
 </template>
 
 <script setup>
-  import { reactive, watch } from 'vue';
-  import sheep from '@/sheep';
-  import _ from 'lodash';
-  import GoodsItem from './goods.vue';
-  import OrderItem from './order.vue';
-  import OrderApi from '@/sheep/api/trade/order';
-  import SpuHistoryApi from '@/sheep/api/product/history';
+	import {
+		reactive,
+		watch
+	} from 'vue';
+	import sheep from '@/sheep';
+	import _ from 'lodash';
+	import GoodsItem from './goods.vue';
+	import OrderItem from './order.vue';
+	import OrderApi from '@/sheep/api/trade/order';
+	import SpuHistoryApi from '@/sheep/api/product/history';
 
-  const emits = defineEmits(['select', 'close']);
-  const props = defineProps({
-    mode: {
-      type: String,
-      default: 'goods',
-    },
-    show: {
-      type: Boolean,
-      default: false,
-    },
-  });
+	const emits = defineEmits(['select', 'close']);
+	const props = defineProps({
+		mode: {
+			type: String,
+			default: 'goods',
+		},
+		show: {
+			type: Boolean,
+			default: false,
+		},
+	});
 
-  watch(
-    () => props.mode,
-    () => {
-      state.pagination.data = [];
-      if (props.mode) {
-        getList(state.pagination.page);
-      }
-    },
-  );
+	watch(() => props.mode,() => {
+			state.pagination.data = [];
+			if (props.mode) {
+				getList(state.pagination.page);
+			}
+		},
+	);
 
-  const state = reactive({
-    loadStatus: '',
-    pagination: {
-      data: [],
-      current_page: 1,
-      total: 1,
-      last_page: 1,
-    },
-  });
+	const state = reactive({
+		loadStatus: '',
+		pagination: {
+			data: [],
+			current_page: 1,
+			total: 1,
+			last_page: 1,
+		},
+	});
 
-  async function getList(page, list_rows = 5) {
-    state.loadStatus = 'loading';
-    const res =
-      props.mode == 'goods'
-        ? await SpuHistoryApi.getBrowseHistoryPage({
-            page,
-            list_rows,
-          })
-        : await OrderApi.getOrderPage({
-            page,
-            list_rows,
-          });
-    let orderList = _.concat(state.pagination.data, res.data.data);
-    state.pagination = {
-      ...res.data,
-      data: orderList,
-    };
-    if (state.pagination.current_page < state.pagination.last_page) {
-      state.loadStatus = 'more';
-    } else {
-      state.loadStatus = 'noMore';
-    }
-  }
+	async function getList(page, list_rows = 5) {
+		state.loadStatus = 'loading';
+		const res =
+			props.mode == 'goods' ?
+			await SpuHistoryApi.getBrowseHistoryPage({
+				page,
+				list_rows,
+			}) :
+			await OrderApi.getOrderPage({
+				page,
+				list_rows,
+			});
+		let orderList = _.concat(state.pagination.data, res.data.data);
+		state.pagination = {
+			...res.data,
+			data: orderList,
+		};
+		if (state.pagination.current_page < state.pagination.last_page) {
+			state.loadStatus = 'more';
+		} else {
+			state.loadStatus = 'noMore';
+		}
+	}
 
-  function loadmore() {
-    if (state.loadStatus !== 'noMore') {
-      getList(state.pagination.current_page + 1);
-    }
-  }
+	function loadmore() {
+		if (state.loadStatus !== 'noMore') {
+			getList(state.pagination.current_page + 1);
+		}
+	}
 </script>
 
 <style lang="scss" scoped>
-  .select-popup {
-    max-height: 600rpx;
+	.select-popup {
+		max-height: 600rpx;
 
-    .title {
-      height: 100rpx;
-      line-height: 100rpx;
-      padding: 0 26rpx;
-      background: #fff;
-      border-radius: 20rpx 20rpx 0 0;
+		.title {
+			height: 100rpx;
+			line-height: 100rpx;
+			padding: 0 26rpx;
+			background: #fff;
+			border-radius: 20rpx 20rpx 0 0;
 
-      span {
-        font-size: 32rpx;
-        position: relative;
+			span {
+				font-size: 32rpx;
+				position: relative;
 
-        &::after {
-          content: '';
-          display: block;
-          width: 100%;
-          height: 2px;
-          z-index: 1;
-          position: absolute;
-          left: 0;
-          bottom: -15px;
-          background: var(--ui-BG-Main);
-          pointer-events: none;
-        }
-      }
-    }
+				&::after {
+					content: '';
+					display: block;
+					width: 100%;
+					height: 2px;
+					z-index: 1;
+					position: absolute;
+					left: 0;
+					bottom: -15px;
+					background: var(--ui-BG-Main);
+					pointer-events: none;
+				}
+			}
+		}
 
-    .scroll-box {
-      height: 500rpx;
-    }
+		.scroll-box {
+			height: 500rpx;
+		}
 
-    .item {
-      background: #fff;
-      margin: 26rpx 26rpx 0;
-      border-radius: 20rpx;
+		.item {
+			background: #fff;
+			margin: 26rpx 26rpx 0;
+			border-radius: 20rpx;
 
-      :deep() {
-        .image {
-          width: 140rpx;
-          height: 140rpx;
-        }
-      }
-    }
-  }
-</style>
+			:deep() {
+				.image {
+					width: 140rpx;
+					height: 140rpx;
+				}
+			}
+		}
+	}
+</style>

+ 6 - 6
pages/chat/index.vue

@@ -71,7 +71,7 @@
               class="chat-avatar ss-m-r-24"
               :src="
                 sheep.$url.cdn(item?.sender?.avatar) ||
-                sheep.$url.static('/static/img/shop/chat/default.png')
+                sheep.$url.static('/static/images/default.png')
               "
               mode="aspectFill"
             ></image>
@@ -88,13 +88,13 @@
               <image
                 v-if="chatData.isSendSucces == -1"
                 class="loading"
-                :src="sheep.$url.static('/static/img/shop/chat/loading.png')"
+                :src="sheep.$url.static('/static/images/loading.png')"
                 mode="aspectFill"
               ></image>
               <!-- <image
                 v-if="chatData.isSendSucces == 1"
                 class="warning"
-                :src="sheep.$url.static('/static/img/shop/chat/warning.png')"
+                :src="sheep.$url.static('/static/images/warning.png')"
                 mode="aspectFill"
                 @click="onAgainSendMessage(item)"
               ></image> -->
@@ -246,7 +246,7 @@
               >
                 <image
                   class="icon"
-                  :src="sheep.$url.static('/static/img/shop/chat/image.png')"
+                  :src="sheep.$url.static('/static/images/image.png')"
                   mode="aspectFill"
                 ></image>
               </s-uploader>
@@ -255,7 +255,7 @@
             <view class="goods" @tap="onShowSelect('goods')">
               <image
                 class="icon"
-                :src="sheep.$url.static('/static/img/shop/chat/goods.png')"
+                :src="sheep.$url.static('/static/images/goods.png')"
                 mode="aspectFill"
               ></image>
               <view>商品</view>
@@ -263,7 +263,7 @@
             <view class="order" @tap="onShowSelect('order')">
               <image
                 class="icon"
-                :src="sheep.$url.static('/static/img/shop/chat/order.png')"
+                :src="sheep.$url.static('/static/images/order.png')"
                 mode="aspectFill"
               ></image>
               <view>订单</view>

+ 303 - 0
pages/chat/speechtotext.vue

@@ -0,0 +1,303 @@
+<template>
+	<s-layout class="chat-wrap" title="语音转文字">
+		<view class="chat-container">
+			<view class="messages" :style="{height:messagesHeight+'px'}" id="messages">
+				<view v-for="(message, index) in messages" :key="index" class="message" @click="playRecording(index)">
+					<view class="bubble">
+						<text class="duration">{{ message.duration }}" </text><text class="ss-m-l-10">
+							<image src="@/static/icon/audioPaly.png" class="audioPaly" />
+						</text>
+					</view>
+					<view class="text" v-if="message.transcription != null && message.transcription != ''">
+						{{message.transcription}}
+					</view>
+				</view>
+			</view>
+			<view class="input-area">
+				<button @mousedown="startRecording" @mouseup="stopRecording" @mouseleave="cancelRecording"
+					@touchstart="startRecording" @touchend="stopRecording" @touchcancel="cancelRecording"
+					@touchmove="handleTouchMove">
+					按住 说话
+				</button>
+				<view v-if="isRecording" class="recording-overlay">
+					<view>{{ recordingDuration }}</view>
+					<view>上滑至此取消</view>
+				</view>
+			</view>
+		</view>
+	</s-layout>
+</template>
+
+<script setup>
+	import {
+		ref,
+		nextTick,
+		onMounted
+	} from 'vue';
+	import sheep from '@/sheep';
+	import VoiceApi from '@/sheep/api/system/voice';
+	const {
+		safeAreaInsets,
+		safeArea
+	} = sheep.$platform.device;
+	const sysNavBar = sheep.$platform.navbar;
+	const messagesHeight = (safeArea.height) - sysNavBar - 20 - 60;
+
+	const messages = ref([]);
+	const isRecording = ref(false);
+	let startTime = ref(null);
+	const recordingDuration = ref('');
+	const minRecordingTime = 500; // 设置最小录音时间为500毫秒
+	let intervalId = null;
+	const cancelOffset = 280; // 上滑取消的距离阈值
+	const startTouchY = ref(0);
+	let mediaRecorder = null;
+	let audioChunks = [];
+	let isCancelled = ref(false);
+
+	// 初始化录音功能
+	onMounted(() => {
+		navigator.mediaDevices.getUserMedia({
+				audio: true
+			})
+			.then(stream => {
+				mediaRecorder = new MediaRecorder(stream);
+				mediaRecorder.ondataavailable = (event) => {
+					audioChunks.push(event.data);
+				};
+				mediaRecorder.onstop = () => {
+					if (!isCancelled.value) {
+						sendDuration()
+					}
+					audioChunks = [];
+				};
+			})
+			.catch(error => {
+				console.error("Error accessing media devices.", error);
+			});
+	});
+	async function sendAudioToServer(audioBlob,audioUrl,duration,messageIndex) {
+	  const formData = new FormData();
+	  formData.append('audio_file', audioBlob);
+	  try {
+	    const response = await fetch(import.meta.env.SHOPRO_BASE_URL + '/voice2text/', {
+	      method: 'POST',
+	      body: formData,
+	    });
+	    const data = await response.json();
+		if(data.success){
+			messages.value[messageIndex].transcription = data.transcription;
+		}
+	    console.log('Server response:', data);
+	  } catch (error) {
+	    console.error('Error sending audio file:', error);
+	  }
+	}
+	// 发送录音
+	const sendDuration = () => {
+		const audioBlob = new Blob(audioChunks, {
+			type: 'audio/mpeg'
+		});
+		const audioUrl = URL.createObjectURL(audioBlob);
+		const duration = Math.max(Math.floor((new Date() - startTime.value) / 1000), 1);
+		  // 先添加消息,但不包含转写文本
+		const messageIndex = messages.value.push({
+		    duration,
+		    audioUrl,
+		    transcription: '' // 初始为空
+		}) - 1;
+		sendAudioToServer(audioBlob,audioUrl,duration,messageIndex);
+		nextTick(() => {
+			let messagesElement = document.getElementById('messages');
+			messagesElement.scrollTop = messagesElement.scrollHeight;
+		});
+	}
+
+	// 更新录音
+	const updateDuration = () => {
+		const currentDuration = Math.floor((new Date() - startTime.value) / 1000);
+		recordingDuration.value = currentDuration + 's';
+		if (currentDuration >= 60) { // 如果到达60秒自动停止录音
+			stopRecording(new Event('mouseup'));
+		}
+	};
+	// 开始录音
+	const startRecording = (event) => {
+		if (!isRecording.value && (event.type === 'mousedown' || event.type === 'touchstart')) {
+			startTime.value = new Date();
+			isRecording.value = true;
+			intervalId = setInterval(updateDuration, 1000); // 每秒更新一次时间
+			recordingDuration.value = '1s'; // 开始时显示1秒
+			// console.log('开始录音...');
+			event.preventDefault();
+			startTouchY.value = event.touches ? event.touches[0].clientY : 0;
+			audioChunks = [];
+			isCancelled.value = false; // 确保开始录音时取消标志为假
+			mediaRecorder.start();
+		}
+	};
+	// 停止录音
+	const stopRecording = (event) => {
+		if (isRecording.value && (event.type === 'mouseup' || event.type === 'touchend' || event.type ===
+				'mouseleave' || event.type === 'touchcancel')) {
+			clearInterval(intervalId); // 停止定时器
+			isRecording.value = false;
+			recordingDuration.value = ''; // 清空显示的时间
+
+			if (new Date() - startTime.value >= minRecordingTime) {
+				mediaRecorder.stop();
+			} else {
+				console.log('录音时间太短,不保存');
+			}
+
+		}
+	};
+	// 取消录音
+	const cancelRecording = () => {
+		if (isRecording.value) {
+			clearInterval(intervalId);
+			console.log('录音取消');
+			isCancelled.value = true; // 设置取消标志为真
+			mediaRecorder.stop();
+			resetRecording();
+		}
+	};
+	// 重置录音
+	const resetRecording = () => {
+		isRecording.value = false;
+		recordingDuration.value = 0;
+		startTime.value = null;
+		audioChunks = [];
+	};
+	// 处理触摸移动事件
+	const handleTouchMove = (event) => {
+		// 此处应添加逻辑来检测触摸位置,如果滑动到取消区域,调用 cancelRecording
+		const currentTouchY = event.touches[0].clientY;
+		if (startTouchY.value - currentTouchY > cancelOffset) { // 检查是否上滑超过阈值
+			cancelRecording();
+		}
+	};
+	// 播放录音
+	const playRecording = (index) => {
+		const message = messages.value[index];
+		const audio = new Audio(message.audioUrl);
+		audio.play();
+	};
+</script>
+
+<style scoped>
+	.chat-container {
+		display: flex;
+		flex-direction: column;
+		overflow-y: auto;
+		background-color: #f0f0f0;
+		padding: 10px;
+	}
+
+	.messages {
+		flex-grow: 1;
+		overflow-y: auto;
+	}
+
+	.message {
+		display: flex;
+		justify-content: flex-end;
+		align-items: flex-end;
+		margin-bottom: 10px;
+		flex-direction: column;
+	}
+	.text{
+		width: 70%;
+		background: white;
+		border-radius: 5px;
+		padding: 10px;
+		margin: 5px 0 10px;
+		box-sizing: border-box;
+		font-size: 16px;
+	}
+	.bubble {
+		width:100px;
+		padding: 10px 20px 10px 20px;
+		justify-content: flex-end;
+		margin-right: 10px;
+		background-color: rgb(131 235 96);
+		border-radius: 5px;
+		display: flex;
+		align-items: right;
+		position: relative;
+	}
+
+	.bubble::after {
+		content: "";
+		width: 0px;
+		height: 0px;
+		border-top: 5px solid transparent;
+		border-bottom: 5px solid transparent;
+		border-left: 5px solid #83eb60;
+		position: absolute;
+		top: 14px;
+		right: -5px;
+	}
+
+	.duration {
+		color: #000;
+		font-size: 16px;
+	}
+
+	.audioPaly {
+		width: 12px;
+		height: 12px;
+	}
+
+	.input-area {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		background-color: rgb(245, 245, 245);
+		display: flex;
+		justify-content: center;
+		padding: 10px;
+		box-sizing: border-box;
+	}
+
+	.input-area>button {
+		display: block;
+		width: 100%;
+		background-color: #FFFFFF;
+		border: none;
+		padding: 3px 0;
+		border-radius: 5px;
+		color: #333333;
+		font-size: 16px;
+		font-weight: bold;
+		text-align: center;
+		outline: none;
+		cursor: pointer;
+
+	}
+
+	.input-area>.button-hover {
+		background-color: #f0f0f0 !important;
+	}
+
+	.input-area>button:after {
+		border: none;
+	}
+
+	.recording-overlay {
+		position: fixed;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		background-color: rgba(0, 0, 0, 0.7);
+		color: white;
+		padding: 20px;
+		border-radius: 10px;
+		text-align: center;
+	}
+
+	.recording-overlay view {
+		margin: 5px 0;
+	}
+</style>

+ 1 - 1
pages/commission/components/commission-auth.vue

@@ -12,7 +12,7 @@
       <view class="img-wrap">
         <image
           class="notice-img"
-          :src="sheep.$url.static('/static/img/shop/commission/forbidden.png')"
+          :src="sheep.$url.static('/static/images/forbidden.png')"
           mode="aspectFill"
         />
       </view>

+ 2 - 2
pages/commission/components/commission-log.vue

@@ -2,7 +2,7 @@
 <template>
 	<view class="distribution-log-wrap">
 		<view class="header-box">
-			<image class="header-bg" :src="sheep.$url.static('/static/img/shop/commission/title2.png')" />
+			<image class="header-bg" :src="sheep.$url.static('/static/images/title2.png')" />
 			<view class="ss-flex header-title">
 				<view class="title">实时动态</view>
 				<text class="cicon-forward" />
@@ -15,7 +15,7 @@
 					<view class="log-item-wrap">
 						<view class="log-item ss-flex ss-ellipsis-1 ss-col-center">
 							<view class="ss-flex ss-col-center">
-								<image class="log-img" :src="sheep.$url.static('/static/img/shop/avatar/notice.png')" mode="aspectFill" />
+								<image class="log-img" :src="sheep.$url.static('/static/images/notice.png')" mode="aspectFill" />
 							</view>
 							<view class="log-text ss-ellipsis-1">
                 {{ item.title }} {{ fen2yuan(item.price) }} 元

+ 9 - 9
pages/commission/components/commission-menu.vue

@@ -2,7 +2,7 @@
 <template>
 	<view class="menu-box ss-flex-col">
 		<view class="header-box">
-			<image class="header-bg" :src="sheep.$url.static('/static/img/shop/commission/title1.png')" />
+			<image class="header-bg" :src="sheep.$url.static('/static/images/title1.png')" />
 			<view class="ss-flex header-title">
 				<view class="title">功能专区</view>
 				<text class="cicon-forward"></text>
@@ -24,45 +24,45 @@
 
 	const state = reactive({
 		menuList: [{
-				img: '/static/img/shop/commission/commission_icon1.png',
+				img: '/static/images/commission_icon1.png',
 				title: '我的团队',
 				path: '/pages/commission/team',
 			},
 			{
-				img: '/static/img/shop/commission/commission_icon2.png',
+				img: '/static/images/commission_icon2.png',
 				title: '佣金明细',
 				path: '/pages/commission/wallet',
 			},
 			{
-				img: '/static/img/shop/commission/commission_icon3.png',
+				img: '/static/images/commission_icon3.png',
 				title: '分销订单',
 				path: '/pages/commission/order',
 			},
 			{
-				img: '/static/img/shop/commission/commission_icon4.png',
+				img: '/static/images/commission_icon4.png',
 				title: '推广商品',
 				path: '/pages/commission/goods',
 			},
 			// {
-			//   img: '/static/img/shop/commission/commission_icon5.png',
+			//   img: '/static/images/commission_icon5.png',
 			//   title: '我的资料',
 			//   path: '/pages/commission/apply',
 			//   isAgentFrom: true,
 			// },
 			// todo @非繁人:邀请海报需要登录后的个人数据
 			{
-				img: '/static/img/shop/commission/commission_icon7.png',
+				img: '/static/images/commission_icon7.png',
 				title: '邀请海报',
 				path: 'action:showShareModal',
 			},
       // TODO @非繁人:缺少 icon
       {
-				// img: '/static/img/shop/commission/commission_icon7.png',
+				// img: '/static/images/commission_icon7.png',
 				title: '推广排行',
 				path: '/pages/commission/promoter',
 			},
       {
-				// img: '/static/img/shop/commission/commission_icon7.png',
+				// img: '/static/images/commission_icon7.png',
 				title: '佣金排行',
 				path: '/pages/commission/commission-ranking',
 			}

+ 75 - 55
pages/commission/wallet.vue

@@ -10,10 +10,12 @@
 						:class="state.showMoney ? 'cicon-eye' : 'cicon-eye-off'" />
 				</view>
 				<view class="ss-flex ss-row-between ss-col-center ss-m-t-30">
-					<view class="money-num">{{ state.showMoney ? fen2yuan(state.summary.withdrawPrice || 0) : '*****' }}</view>
+					<view class="money-num">{{ state.showMoney ? fen2yuan(state.summary.withdrawPrice || 0) : '*****' }}
+					</view>
 					<view class="ss-flex">
 						<view class="ss-m-r-20">
-							<button class="ss-reset-button withdraw-btn" @tap="sheep.$router.go('/pages/commission/withdraw')">
+							<button class="ss-reset-button withdraw-btn"
+								@tap="sheep.$router.go('/pages/commission/withdraw')">
 								提现
 							</button>
 						</view>
@@ -27,14 +29,14 @@
 					<view class="loading-money">
 						<view class="loading-money-title">冻结佣金</view>
 						<view class="loading-money-num">
-              {{ state.showMoney ? fen2yuan(state.summary.frozenPrice || 0) : '*****' }}
-            </view>
+							{{ state.showMoney ? fen2yuan(state.summary.frozenPrice || 0) : '*****' }}
+						</view>
 					</view>
 					<view class="loading-money ss-m-l-100">
 						<view class="loading-money-title">可提现佣金</view>
 						<view class="loading-money-num">
-              {{ state.showMoney ? fen2yuan(state.summary.brokeragePrice || 0) : '*****' }}
-            </view>
+							{{ state.showMoney ? fen2yuan(state.summary.brokeragePrice || 0) : '*****' }}
+						</view>
 					</view>
 				</view>
 			</view>
@@ -51,7 +53,7 @@
 				</uni-datetime-picker>
 
 				<view class="total-box">
-          <!-- TODO 非繁人:这里暂时不考虑做 -->
+					<!-- TODO 非繁人:这里暂时不考虑做 -->
 					<!-- <view class="ss-m-b-10">总收入¥{{ state.pagination.income.toFixed(2) }}</view> -->
 					<!-- <view>总支出¥{{ (-state.pagination.expense).toFixed(2) }}</view> -->
 				</view>
@@ -60,7 +62,7 @@
 		</su-sticky>
 		<s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" text="暂无数据"></s-empty>
 
-    <!-- 转余额弹框 -->
+		<!-- 转余额弹框 -->
 		<su-popup :show="state.showModal" type="bottom" round="20" @close="state.showModal = false" showClose>
 			<view class="ss-p-x-20 ss-p-y-30">
 				<view class="model-title ss-m-b-30 ss-m-l-20">转余额</view>
@@ -68,7 +70,7 @@
 				<view class="input-box ss-flex ss-col-center border-bottom ss-m-b-70 ss-m-x-20">
 					<view class="unit">¥</view>
 					<uni-easyinput :inputBorder="false" class="ss-flex-1 ss-p-l-10" v-model="state.price" type="number"
-                         placeholder="请输入金额" />
+						placeholder="请输入金额" />
 				</view>
 				<button class="ss-reset-button model-btn ui-BG-Main-Gradient ui-Shadow-Main" @tap="onConfirm">
 					确定
@@ -100,33 +102,43 @@
 </template>
 
 <script setup>
-	import { computed, reactive } from 'vue';
-	import { onLoad, onReachBottom } from '@dcloudio/uni-app';
+	import {
+		computed,
+		reactive
+	} from 'vue';
+	import {
+		onLoad,
+		onReachBottom
+	} from '@dcloudio/uni-app';
 	import sheep from '@/sheep';
 	import dayjs from 'dayjs';
 	import _ from 'lodash';
-  import BrokerageApi from '@/sheep/api/trade/brokerage';
-  import { fen2yuan } from '@/sheep/hooks/useGoods';
-  import { resetPagination } from '@/sheep/util';
+	import BrokerageApi from '@/sheep/api/trade/brokerage';
+	import {
+		fen2yuan
+	} from '@/sheep/hooks/useGoods';
+	import {
+		resetPagination
+	} from '@/sheep/util';
 
 	const headerBg = sheep.$url.css('/static/img/shop/user/wallet_card_bg.png');
 
 	const state = reactive({
-    showMoney: false,
-    summary: {}, // 分销信息
+		showMoney: false,
+		summary: {}, // 分销信息
 
-    today: '',
-    date: [],
+		today: '',
+		date: [],
 		currentTab: 0,
 		pagination: {
-      list: [],
-      total: 0,
-      pageNo: 1,
-      pageSize: 1,
-    },
+			list: [],
+			total: 0,
+			pageNo: 1,
+			pageSize: 1,
+		},
 		loadStatus: '',
 
-    price: undefined,
+		price: undefined,
 		showModal: false,
 	});
 
@@ -150,19 +162,22 @@
 
 	async function getLogList() {
 		state.loadStatus = 'loading';
-		let { code, data } = await BrokerageApi.getBrokerageRecordPage({
+		let {
+			code,
+			data
+		} = await BrokerageApi.getBrokerageRecordPage({
 			pageSize: state.pagination.pageSize,
 			pageNo: state.pagination.pageNo,
-      bizType: tabMaps[state.currentTab].value,
-      'createTime[0]': state.date[0] + ' 00:00:00',
-      'createTime[1]': state.date[1] + ' 23:59:59',
+			bizType: tabMaps[state.currentTab].value,
+			'createTime[0]': state.date[0] + ' 00:00:00',
+			'createTime[1]': state.date[1] + ' 23:59:59',
 		});
 		if (code !== 0) {
-      return;
+			return;
 		}
-    state.pagination.list = _.concat(state.pagination.list, data.list);
-    state.pagination.total = data.total;
-    state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
+		state.pagination.list = _.concat(state.pagination.list, data.list);
+		state.pagination.total = data.total;
+		state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
 	}
 
 	function onChangeTab(e) {
@@ -174,7 +189,7 @@
 	function onChangeTime(e) {
 		state.date[0] = e[0];
 		state.date[1] = e[e.length - 1];
-    resetPagination(state.pagination);
+		resetPagination(state.pagination);
 		getLogList();
 	}
 
@@ -189,37 +204,42 @@
 			content: '确认把您的佣金转入到余额钱包中?',
 			success: async function(res) {
 				if (!res.confirm) {
-          return;
+					return;
+				}
+				const {
+					code
+				} = await BrokerageApi.createBrokerageWithdraw({
+					type: 1, // 钱包
+					price: state.price * 100,
+				});
+				if (code === 0) {
+					state.showModal = false;
+					await getAgentInfo();
+					onChangeTab({
+						index: 1
+					});
 				}
-        const { code } = await BrokerageApi.createBrokerageWithdraw({
-          type: 1, // 钱包
-          price: state.price * 100,
-        });
-        if (code === 0) {
-          state.showModal = false;
-          await getAgentInfo();
-          onChangeTab({
-            index: 1
-          });
-        }
 			}
 		});
 	}
 
 	async function getAgentInfo() {
-		const { code, data } = await BrokerageApi.getBrokerageUserSummary();
-    if (code !== 0) {
-      return;
-    }
-    state.summary = data;
+		const {
+			code,
+			data
+		} = await BrokerageApi.getBrokerageUserSummary();
+		if (code !== 0) {
+			return;
+		}
+		state.summary = data;
 	}
 
 	onLoad(async (options) => {
 		state.today = dayjs().format('YYYY-MM-DD');
 		state.date = [state.today, state.today];
-    if (options.type === 2) { // 切换到“提现” tab 下
-      state.currentTab = 1;
-    }
+		if (options.type === 2) { // 切换到“提现” tab 下
+			state.currentTab = 1;
+		}
 		getLogList();
 		getAgentInfo();
 	});
@@ -228,8 +248,8 @@
 		if (state.loadStatus === 'noMore') {
 			return;
 		}
-    state.pagination.pageNo++;
-    getLogList();
+		state.pagination.pageNo++;
+		getLogList();
 	});
 </script>
 

+ 1 - 1
pages/coupon/detail.vue

@@ -8,7 +8,7 @@
           <view class="tag-box ss-flex ss-col-center ss-row-center">
             <image
               class="tag-image"
-              :src="sheep.$url.static('/static/img/shop/app/coupon_icon.png')"
+              :src="sheep.$url.static('/static/images/coupon_icon.png')"
               mode="aspectFit"
             />
           </view>

+ 4 - 4
pages/goods/components/detail/detail-activity-tip.vue

@@ -11,13 +11,13 @@
             <view class="ss-m-r-16">
               <image
                 v-if="activity.type === 1"
-                :src="sheep.$url.static('/static/img/shop/goods/seckill-icon.png')"
+                :src="sheep.$url.static('/static/images/seckill-icon.png')"
                 class="activity-icon"
               />
               <!-- TODO 非繁人:拼团 -->
               <image
                 v-else-if="activity.type === 3"
-                :src="sheep.$url.static('/static/img/shop/goods/groupon-icon.png')"
+                :src="sheep.$url.static('/static/images/groupon-icon.png')"
                 class="activity-icon"
               />
             </view>
@@ -34,8 +34,8 @@
   import sheep from '@/sheep';
 
   // TODO 非繁人:这里要迁移下;
-  const seckillBg = sheep.$url.css('/static/img/shop/goods/seckill-tip-bg.png');
-  const grouponBg = sheep.$url.css('/static/img/shop/goods/groupon-tip-bg.png');
+  const seckillBg = sheep.$url.css('/static/images/seckill-tip-bg.png');
+  const grouponBg = sheep.$url.css('/static/images/groupon-tip-bg.png');
 
   const props = defineProps({
     activityList: {

+ 17 - 5
pages/goods/components/detail/detail-navbar.vue

@@ -38,18 +38,18 @@
 							@tap="onFavorite">
 							<block v-if="modelValue.favorite">
 								<image class="item-icon"
-									:src="sheep.$url.static('/static/img/shop/goods/collect_1.gif')" mode="aspectFit" />
+									:src="sheep.$url.static('/static/images/collect_1.gif')" mode="aspectFit" />
 								<!-- <view class="item-title">已收藏</view> -->
 							</block>
 							<block v-else>
 								<image class="item-icon"
-									:src="sheep.$url.static('/static/img/shop/goods/collect_0.png')" mode="aspectFit" />
+									:src="sheep.$url.static('/static/images/collect_0.png')" mode="aspectFit" />
 								<!-- <view class="item-title">收藏</view> -->
 							</block>
 						</view>
 						<view v-if="shareIcon" class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center"
-							@tap="showShareModal">
-							<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/share.png')"
+							@tap="showShareModal(modelValue.id)">
+							<image class="item-icon" :src="sheep.$url.static('/static/images/share.png')"
 								mode="aspectFit" />
 							<!-- <view class="item-title">分享</view> -->
 						</view>
@@ -65,7 +65,8 @@
 
 <script setup>
 	import {
-		reactive
+		reactive,
+		computed
 	} from 'vue';
 	import {
 		onPageScroll
@@ -79,7 +80,10 @@
 	import {
 		showShareModal
 	} from '@/sheep/hooks/useModal';
+	
+	import { showAuthModal } from '@/sheep/hooks/useModal';
 	import FavoriteApi from '@/sheep/api/product/favorite';
+	const isLogin = computed(() => sheep.$store('user').isLogin);
 	const sys_statusBar = sheep.$platform.device.statusBarHeight;
 	const sys_navBar = sheep.$platform.navbar;
 	const capsuleStyle = {
@@ -175,7 +179,12 @@
 			duration: 200,
 		});
 	}
+	// console.log(props.modelValue)
 	async function onFavorite() {
+		if(!isLogin.value){
+			showAuthModal();
+			return;
+		}
 		// 情况一:取消收藏
 		if (props.modelValue.favorite) {
 			const {
@@ -188,9 +197,12 @@
 			props.modelValue.favorite = false;
 			// 情况二:添加收藏
 		} else {
+			// 收藏
 			const {
 				code
 			} = await FavoriteApi.createFavorite(props.modelValue.id);
+			// 调用收藏加身价的接口
+			await FavoriteApi.createCollectBefore(props.modelValue.id)
 			if (code !== 0) {
 				return
 			}

+ 0 - 7
pages/goods/components/detail/detail-tabbar.vue

@@ -28,13 +28,6 @@
 						mode="aspectFit" />
 					<view class="item-title">购物车</view>
 				</view>
-				
-				<!-- <view v-if="shareIcon" class="detail-tabbar-item ss-flex ss-flex-col ss-row-center ss-col-center"
-					@tap="showShareModal">
-					<image class="item-icon" :src="sheep.$url.static('/static/img/shop/goods/share.png')"
-						mode="aspectFit" />
-					<view class="item-title">分享</view>
-				</view> -->
 				<slot></slot>
 			</view>
 		</view>

+ 5 - 5
pages/goods/groupon.vue

@@ -39,7 +39,7 @@
                   <view class="tig-icon ss-flex ss-col-center ss-row-center">
                     <view class="groupon-tag">
                       <image
-                        :src="sheep.$url.static('/static/img/shop/goods/groupon-tag.png')"
+                        :src="sheep.$url.static('/static/images/groupon-tag.png')"
                       ></image>
                     </view>
                   </view>
@@ -153,12 +153,12 @@
   import CombinationApi from "@/sheep/api/promotion/combination";
   import SpuApi from "@/sheep/api/product/spu";
 
-  const headerBg = sheep.$url.css('/static/img/shop/goods/groupon-bg.png');
-  const btnBg = sheep.$url.css('/static/img/shop/goods/groupon-btn.png');
+  const headerBg = sheep.$url.css('/static/images/groupon-bg.png');
+  const btnBg = sheep.$url.css('/static/images/groupon-btn.png');
   const disabledBtnBg = sheep.$url.css(
-    '/static/img/shop/goods/activity-btn-disabled.png',
+    '/static/images/activity-btn-disabled.png',
   );
-  const grouponBg = sheep.$url.css('/static/img/shop/goods/groupon-tip-bg.png');
+  const grouponBg = sheep.$url.css('/static/images/groupon-tip-bg.png');
 
   onPageScroll(() => {});
   const state = reactive({

+ 60 - 34
pages/goods/index.vue

@@ -3,7 +3,6 @@
 		<s-layout :onShareAppMessage="shareInfo" navbar="goods">
 			<!-- 标题栏 -->
 			<detailNavbar v-model="state.goodsInfo" />
-
 			<!-- 骨架屏 -->
 			<detailSkeleton v-if="state.skeletonLoading" />
 			<!-- 下架/售罄提醒 -->
@@ -14,20 +13,21 @@
 					<!-- 商品轮播图  -->
 					<su-swiper class="ss-m-b-14" isPreview :list="formatGoodsSwiper(state.goodsInfo.sliderPicUrls)"
 						otStyle="tag" imageMode="widthFix" dotCur="bg-mask-40" :seizeHeight="750" />
-
 					<!-- 价格+标题 -->
 					<view class="title-card detail-card ss-p-y-40 ss-p-x-20">
 						<view class="ss-flex ss-row-between ss-col-center ss-m-b-26">
-							<view class="price-box ss-flex ss-col-bottom">
+							<view class="price-box ss-flex ss-col-center">
 								<view class="price-text ss-m-r-16">
+									<image src="@/static/icon/points.png"  v-if="state.goodsInfo.spuPayType == 2" style="width:40rpx;height:40rpx"   ></image>
+									<text v-else>¥</text>
 									{{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }}
 								</view>
-								<view class="origin-price-text" v-if="state.goodsInfo.marketPrice > 0">
-									{{ fen2yuan(state.selectedSku.marketPrice || state.goodsInfo.marketPrice) }}
+								<view class="origin-price-text" v-if="state.goodsInfo.promotionFee >= 0">
+									数字权益:{{ fen2yuan(state.selectedSku.promotionFee || state.goodsInfo.promotionFee)  }}
 								</view>
 							</view>
 							<view class="sales-text">
-								{{ formatSales('exact', state.goodsInfo.salesCount) }}
+								<!-- {{ formatSales('exact', state.goodsInfo.salesCount) }} -->
 							</view>
 						</view>
 						<view class="discounts-box ss-flex ss-row-between ss-m-b-28">
@@ -40,7 +40,6 @@
 									</view>
 								</view>
 							</div>
-
 							<!-- 优惠劵 -->
 							<view class="get-coupon-box ss-flex ss-col-center ss-m-l-20" @tap="state.showModel = true"
 								v-if="state.couponInfo.length">
@@ -69,30 +68,48 @@
 				<detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" />
 
 				<!-- 活动跳转:拼团/秒杀/砍价活动 -->
-				<detail-activity-tip v-if="state.activityList.length > 0" :activity-list="state.activityList" />
+				<!-- <detail-activity-tip v-if="state.activityList.length > 0" :activity-list="state.activityList" /> -->
 
 				<!-- 详情 tabbar -->
+				
+				
 				<detail-tabbar v-model="state.goodsInfo">
-					<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0">
-						<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
+					<!-- {{state.goodsInfo.spuType }}  {{state.goodsInfo.spuPayType }} -->
+					<!-- 如果有库存并且不是积分商品和虚拟商品 可以加入购物车和购买 -->
+					<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-if="state.goodsInfo.stock > 0 && state.goodsInfo.spuType && state.goodsInfo.spuPayType == 1">
+						<button class="ss-reset-button add-btn ui-Shadow-Main"  @tap="state.showSelectSku = true">
 							加入购物车
 						</button>
 						<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="state.showSelectSku = true">
 							立即购买
 						</button>
 					</view>
+					
+					<!-- 如果有库存并且是积分商品或虚拟商品 只可以加入购物车 -->
+					<!-- 库存不为0和虚拟产品 -->
+					<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-else-if="state.goodsInfo.stock > 0 && !state.goodsInfo.spuType">
+						<button class="ss-reset-button disabled-btn buy-btn ui-Shadow-Main " @tap="state.showSelectSku = true">
+							立即购买
+						</button>
+					</view>
+					<!-- 库存不为0和非现金支付 -->
+					<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-else-if="state.goodsInfo.stock > 0 &&  state.goodsInfo.spuPayType != 1">
+						<button class="ss-reset-button disabled-btn buy-btn ui-Shadow-Main " @tap="state.showSelectSku = true">
+							立即购买
+						</button>
+					</view>
 					<view class="buy-box ss-flex ss-col-center ss-p-r-20" v-else>
-						<button class="ss-reset-button disabled-btn" disabled> 已售罄 </button>
+						<button class="ss-reset-button disabled-btn" disabled style="background: #999999;"> 已售罄 </button>
 					</view>
 				</detail-tabbar>
 
 				<!-- 优惠劵弹窗 -->
-				<s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
-					@get="onGet" />
+				<!-- <s-coupon-get v-model="state.couponInfo" :show="state.showModel" @close="state.showModel = false"
+					@get="onGet" /> -->
 
 				<!-- 满减送/限时折扣活动弹窗 -->
-				<s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel"
-					@close="state.showActivityModel = false" />
+				<!-- <s-activity-pop v-model="state.activityInfo" :show="state.showActivityModel"
+					@close="state.showActivityModel = false" /> -->
 			</block>
 		</s-layout>
 	</view>
@@ -110,6 +127,7 @@
 		onLoad,
 		onPageScroll
 	} from '@dcloudio/uni-app';
+	
 	import sheep from '@/sheep';
 	import CouponApi from '@/sheep/api/promotion/coupon';
 	import ActivityApi from '@/sheep/api/promotion/activity';
@@ -131,6 +149,7 @@
 	} from 'lodash';
 	import SpuApi from '@/sheep/api/product/spu';
 	import ShareApi from '@/sheep/api/distri/share';
+	import { showAuthModal } from '@/sheep/hooks/useModal';
 
 	onPageScroll(() => {});
 
@@ -159,6 +178,10 @@
 			sheep.$helper.toast('请选择商品规格');
 			return;
 		}
+		if(!isLogin.value){
+			showAuthModal();
+			return;
+		}
 		sheep.$store('cart').add(e);
 	}
 
@@ -174,6 +197,8 @@
 					skuId: e.id,
 					count: e.goods_num
 				}],
+				spuType:state.goodsInfo.spuType,
+				spuPayType:state.goodsInfo.spuPayType,
 				// TODO 芋艿:后续清理掉这 2 参数
 				deliveryType: 1,
 				pointStatus: false,
@@ -211,7 +236,7 @@
 			desc: state.goodsInfo.subtitle,
 			params: {
 				page: '2',
-				query: state.linkId,
+				// query: state.linkId,
 			},
 		}, {
 			type: 'goods', // 商品海报
@@ -244,7 +269,10 @@
 			// 加载到商品
 			state.skeletonLoading = false;
 			state.goodsInfo = res.data;
-		
+			console.log(state.goodsInfo )
+			if(!isLogin.value){
+				return;
+			}
 			// 加载是否收藏
 			FavoriteApi.isFavoriteExists(state.goodsId, 'goods').then((res) => {
 				if (res.code !== 0) {
@@ -264,14 +292,14 @@
 			// console.log(state.linkId)
 		});
 	}
-	const isLogin = computed(() => sheep.$store('user').isLogin);
-	watchEffect(() => {
-		if (isLogin.value) {
-			getLink()
+	const isLogin = computed(() => sheep.$store('user').isLogin)
+	watch(() => isLogin.value, (newVal) => {
+		if (newVal) {
+			getSpuDetail(state.goodsId)
 		}
 	})
 	onLoad((options) => {
-		console.log("options.id",options.id,"options.linkId",options.linkId)
+		// console.log("options.id",options.id,"options.linkId",options.linkId)
 		// 没有spuId和linkId的话 就有问题
 		if (!options.id && !options.linkId) {
 			state.goodsInfo = null;
@@ -297,7 +325,7 @@
 			getSpuDetail(state.goodsId)
 		}
 		// 2. 加载优惠劵信息
-		getCoupon();
+		// getCoupon();
 		// 3. 加载营销活动信息
 		ActivityApi.getActivityListBySpuId(state.goodsId).then((res) => {
 			if (res.code !== 0) {
@@ -313,7 +341,6 @@
 				}
 			})
 		});
-		getLink()
 	});
 </script>
 
@@ -335,22 +362,21 @@
 				line-height: 30rpx;
 				font-family: OPPOSANS;
 
-				&::before {
-					content: '¥';
-					font-size: 30rpx;
-				}
+				// &::before {
+				// 	content: '¥';
+				// 	font-size: 30rpx;
+				// }
 			}
 
 			.origin-price-text {
 				font-size: 26rpx;
 				font-weight: 400;
-				text-decoration: line-through;
 				color: $gray-c;
 				font-family: OPPOSANS;
-
-				&::before {
-					content: '¥';
-				}
+				background: #ffca3e;
+				padding: 2px 8px;
+				border-radius: 4px;
+				color: #597533;
 			}
 		}
 
@@ -438,7 +464,7 @@
 			width: 428rpx;
 			height: 72rpx;
 			border-radius: 40rpx;
-			background: #999999;
+			
 			color: $white;
 		}
 	}

+ 1 - 1
pages/index/category.vue

@@ -201,7 +201,7 @@
 
 						.menu-title {
 							font-weight: 600;
-							color: rgb(252, 65, 65);
+							color: var(--ui-BG-Main);
 
 							&::before {
 								left: 0;

+ 167 - 41
pages/index/login.vue

@@ -1,39 +1,71 @@
 <!-- 微信公众号的登录回调页 -->
 <template>
-	<!-- 空登陆页 -->
 	<view />
-	<su-popup :show="isPopup" round="10" :showClose="false" @close="closeAuthModal">
+	<!-- 积分确权 -->
+	<su-popup :show="selectSocialUsers" type="center" round="10" :isMaskClick="false">
+		<view class="head-nav">
+			<view class="head-box">
+				<view class="ss-flex ss-m-b-20">
+					<view class="isActive head-title">
+						请选择账号登录
+					</view>
+				</view>
+			</view>
+		</view>
 		<view>
-			<view class="head-box ">
+			<scroll-view class="side-menu-wrap" scroll-y style="height:600rpx">
+				<view v-for="user in state.socialUsers" :key="user.username" class="ss-flex"
+					style="padding: 20rpx;margin: 0 auto;width: 520rpx;" @click="selectUser(user.username)">
+					<image :src="user.avatar"
+						style="width:100rpx;height:100rpx;border-radius: 50%;margin-right:20rpx" />
+					<view>{{user.username}}</view>
+				</view>
+				<view v-if="!state.socialUsers.length" style="padding: 20rpx;width: 520rpx;text-align: center;margin-top: 100rpx;">
+					该微信暂绑定无账号
+					<br/>
+					请使用其他登陆方式
+				</view>
+			</scroll-view>
+		</view>
+	</su-popup>
+	<su-popup :show="isPopup" round="10" :isMaskClick="false">
+		<view>
+			<view class="head-box">
 				<view class="ss-flex ss-m-b-20">
 					<view class="isActive head-title">
-						您首次登录,请输入手机号验证
+						微信注册
 					</view>
 				</view>
 			</view>
 			<!-- 表单项 -->
-			<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind"
+			<uni-forms  v-model="state.model" :rules="state.rules" validateTrigger="bind"
 				labelWidth="140" labelAlign="center" class="loginUniForm">
-				<uni-forms-item name="mobile" label="手机号" class="loginUniFormItem">
-					<uni-easyinput placeholder="请输入手机号" v-model="state.model.mobile" :inputBorder="false" type="number">
+				<uni-forms-item name="username" label="用户名" class="loginUniFormItem" :error-message="state.usernameErrorMsg">
+					<uni-easyinput placeholder="请输入用户名" v-model="state.registerReqVO.username" :inputBorder="false"
+						:clearable="false" @blur="verifyUsername">
 						<template v-slot:right>
-							<button class="ss-reset-button code-btn code-btn-start" :disabled="state.isMobileEnd"
-								:class="{ 'code-btn-end': state.isMobileEnd }"
-								@tap="getSmsCode('smsLogin', state.model.mobile)">
-								{{ getSmsTimer('smsLogin') }}
-							</button>
+							<view v-if="!state.verifyUsername" class="icon">
+								<image style :src="sheep.$url.static('/static/images/shibai.png')" />
+							</view>
+							<view v-else class="icon">
+								<image :src="sheep.$url.static('/static/images/chenggong.png')" />
+							</view>
 						</template>
 					</uni-easyinput>
 				</uni-forms-item>
 
+				<uni-forms-item name="mobile" label="手机号" class="mobile loginUniFormItem ss-p-t-10" :error-message="state.mobileErrorMsg">
+					<phoneInternationalInput :verify-username="state.verifyUsername" @input="mobileInput"/>
+				</uni-forms-item>
 				<uni-forms-item name="code" label="验证码" class="loginUniFormItem">
 					<uni-easyinput placeholder="请输入验证码" v-model="state.model.code" :inputBorder="false" type="number"
 						maxlength="4">
 					</uni-easyinput>
 				</uni-forms-item>
 			</uni-forms>
-			<view style="display: flex;justify-content: space-between;padding: 40rpx;padding-bottom: 0rpx;">
-				<button class="ss-reset-button login-btn-start" @tap="OfficialEnterLogin"> 继续登录 </button>
+			<view
+				style="display: flex;justify-content: space-between;padding: 40rpx;padding-bottom: 0rpx;padding-bottom: 40rpx">
+				<button class="ss-reset-button login-btn-start" @tap="officialRegister"> 注册 </button>
 			</view>
 		</view>
 	</su-popup>
@@ -62,13 +94,24 @@
 		mobile
 	} from '@/sheep/validate/form';
 	import AuthUtil from '@/sheep/api/member/auth';
-	const smsLoginRef = ref(null);
+	import phoneInternationalInput from '@/sheep/components/s-auth-modal/components/phone-international-input.vue';
+	const mobileInput = (mobile,mobileError)=>{
+		state.model.mobile = mobile;
+		state.mobileErrorMsg = mobileError;
+	}
+
 	// 数据
 	const state = reactive({
-		loginReqVO: {
+		verifyUsername: false,
+		usernameErrorMsg:'',
+		mobileErrorMsg:'',
+		openid: '',
+		socialUsers: [],
+		registerReqVO: {
 			type: 31,
 			code: "",
 			state: "",
+			username: "",
 		},
 		isMobileEnd: false, // 手机号输入完毕
 		codeText: '获取验证码',
@@ -83,33 +126,77 @@
 		},
 	});
 	const isPopup = ref(false);
+	const selectSocialUsers = ref(false);
 	// 定义修改状态的方法
 	function updateIsPopup() {
-	  isPopup.value = true;
+		isPopup.value = true;
 	}
-	defineExpose({
-	  updateIsPopup
-	});
-	// 短信登录
-	async function OfficialEnterLogin() {
-		// 看缓存中有没有linkId 如果有的话 加入model传给后台 即为绑定
-		const linkId = uni.getStorageSync("linkId")
-		if(linkId){
-			state.loginReqVO.linkId = linkId
+	// 打开用户的选择列表,如果有账户并且多个的话
+	function updateSocialUsers(openid, socialUsers) {
+		selectSocialUsers.value = true;
+		state.openid = openid;
+		state.socialUsers = socialUsers;
+		console.log("updateSocialUsers条用了,这时state.socialUsers是", state.socialUsers)
+	}
+	// 选登录的用户
+	async function selectUser(username) {
+		console.log(username)
+		// 提交数据
+		const {
+			code
+		} = await AuthUtil.selectUsernameLogin({
+			openId: state.openid,
+			username
+		});
+		if (code === 0) {
+			// closeAuthModal();
+			// 检测 H5 登录回调
+			let returnUrl = uni.getStorageSync('returnUrl');
+			if (returnUrl) {
+				uni.removeStorage('returnUrl');
+				location.replace(returnUrl);
+			} else {
+				uni.switchTab({
+					url: '/',
+				});
+			}
 		}
-		// 参数校验
-		const validate = await unref(smsLoginRef)
-			.validate()
-			.catch((error) => {
-				console.log('error: ', error);
-			});
-		if (!validate) {
-			return;
+	}
+	let lastUsername = ref('')
+	async function verifyUsername(e) {
+		const username = e.detail.value;
+		if (username == '' || username == lastUsername.value) {
+			// 为空或者没改东西,不调校验
+			return false;
 		}
+		lastUsername.value = username
 		// 提交数据
+		const {
+			data
+		} = await AuthUtil.verifyUsername(username);
+		// false就是已经有这个用户名,不可以用。true是没有,可以改
+		console.log(data)
+		if(data){
+			state.usernameErrorMsg = ''
+			state.verifyUsername = data
+		}else {
+			state.usernameErrorMsg = '已存在用户名!'
+			state.verifyUsername = data
+		}
+	}
+	// 直接点微信注册,或者点微信登录,但没账号的都提示注册
+	async function officialRegister() {
+		// 没有linkId 不给注册
+		const linkId = uni.getStorageSync("linkId");
+		if (!linkId) {
+			sheep.$helper.toast('您只能通过分享注册');
+			return false;
+		}
+		state.registerReqVO.linkId = linkId
 		const {
 			code
-		} = await AuthUtil.OfficialEnterLogin(state.model, state.loginReqVO);
+		} = await AuthUtil.OfficialEnterLogin(state.model, state.registerReqVO);
+		// 提交数据
 		if (code === 0) {
 			closeAuthModal();
 			// 检测 H5 登录回调
@@ -124,16 +211,20 @@
 			}
 		}
 	}
+
 	onBeforeMount(async () => {
 		const options = {}
 		new URLSearchParams(location.search).forEach((value, key) => {
 			options[key] = value;
 		});
-		state.loginReqVO.code = options.code
-		state.loginReqVO.state = options.state
+		state.registerReqVO.code = options.code
+		state.registerReqVO.state = options.state
 	})
 	onLoad(async (options) => {
 		// #ifdef H5
+		
+		
+		
 		// 将 search 参数赋值到 options 中,方便下面解析
 		new URLSearchParams(location.search).forEach((value, key) => {
 			options[key] = value;
@@ -145,14 +236,34 @@
 
 		if (event === 'login') { // 场景一:登录
 			const res = await sheep.$platform.useProvider().login(code, state)
+			console.log("login.vue的res", res)
 			if (!res) {
-				updateIsPopup()
+				uni.showModal({
+					title: '提示',
+					content: '您的微信没有账号,请通过分享注册',
+					confirmColor: '#0e932e', //确定字体颜色
+					showCancel: false, //没有取消按钮的弹框
+					buttonText: '确定',
+					success: function(res) {
+						if (res.confirm) {
+							sheep.$router.go('/pages/index/index')
+						} 
+					}
+				});
 				return false
 			}
+			if (res.data.socialUsers != null) {
+				updateSocialUsers(res.data.openid, res.data.socialUsers)
+				return false
+			}
+		} else if (event === 'register') {
+			const res = await sheep.$platform.useProvider().register(code, state)
+			updateIsPopup()
+			return false
 		} else if (event === 'bind') { // 场景二:绑定
 			sheep.$platform.useProvider().bind(code, state);
 		}
-
+		
 		// 检测 H5 登录回调
 		let returnUrl = uni.getStorageSync('returnUrl');
 		if (returnUrl) {
@@ -169,6 +280,17 @@
 </script>
 
 <style lang="scss" scoped>
+	.icon {
+		display: flex;
+		align-items: center;
+		margin-right: 7rpx
+	}
+
+	.icon image {
+		width: 35rpx;
+		height: 35rpx;
+	}
+
 	@keyframes title-animation {
 		0% {
 			font-size: 32rpx;
@@ -340,6 +462,10 @@
 		border: 1px solid #55b774;
 	}
 
+	.disabled {
+		border: 1px solid #f7f7f7;
+	}
+
 
 
 	.agreement-box {
@@ -360,13 +486,13 @@
 		border-radius: 10rpx;
 	}
 
-	.loginUniFormItem:first-child {
+	.loginUniFormItem {
 		border-bottom: 1rpx solid #d6d6d6;
 		padding-bottom: 10rpx;
 	}
 
 	.loginUniFormItem:last-child {
-		// border-bottom: 1rpx solid #d6d6d6;
+		border-bottom: none;
 		padding-top: 10rpx;
 	}
 

+ 8 - 3
pages/index/user.vue

@@ -43,12 +43,17 @@
   onPageScroll(() => {});
   
   onLoad((options) => {
+	  // uni.setStorageSync("linkId",74)
+	  // console.log("user.vue设置了缓存",uni.getStorageSync('linkId'))
   	if (options.linkId) {
   		uni.setStorageSync("linkId",options.linkId)
+		if (!isLogin.value) {
+			showAuthModal('register','register');
+		}
   	}
-	if (!isLogin.value) {
-		showAuthModal();
-	}
+	// if (!isLogin.value) {
+	// 	showAuthModal();
+	// }
   });
 </script>
 

+ 117 - 71
pages/order/aftersale/detail.vue

@@ -13,12 +13,12 @@
 					<view class="steps-item" v-for="(item, index) in state.list" :key="index">
 						<view class="ss-flex">
 							<text class="sicon-circleclose"
-                    v-if="state.list.length - 1 === index && [61, 62, 63].includes(state.info.status)" />
+								v-if="state.list.length - 1 === index && [61, 62, 63].includes(state.info.status)" />
 							<text class="sicon-circlecheck" v-else
-                    :class="state.active >= index ? 'activity-color' : 'info-color'" />
+								:class="state.active >= index ? 'activity-color' : 'info-color'" />
 
 							<view v-if="state.list.length - 1 !== index" class="line"
-                    :class="state.active >= index ? 'activity-bg' : 'info-bg'" />
+								:class="state.active >= index ? 'activity-bg' : 'info-bg'" />
 						</view>
 						<view class="steps-item-title" :class="state.active >= index ? 'activity-color' : 'info-color'">
 							{{ item.title }}
@@ -29,14 +29,14 @@
 
 			<!-- 服务状态 -->
 			<view class="status-box ss-flex ss-col-center ss-row-between ss-m-x-20"
-            @tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.id })">
+				@tap="sheep.$router.go('/pages/order/aftersale/log', { id: state.id })">
 				<view class="">
 					<view class="status-text">
-            {{ formatAfterSaleStatusDescription(state.info) }}
-          </view>
+						{{ formatAfterSaleStatusDescription(state.info) }}
+					</view>
 					<view class="status-time">
-            {{ sheep.$helper.timeFormat(state.info.updateTime, 'yyyy-mm-dd hh:MM:ss') }}
-          </view>
+						{{ sheep.$helper.timeFormat(state.info.updateTime, 'yyyy-mm-dd hh:MM:ss') }}
+					</view>
 				</view>
 				<text class="ss-iconfont _icon-forward" style="color: #666" />
 			</view>
@@ -48,13 +48,9 @@
 			</view>
 			<!-- 服务商品 -->
 			<view class="order-shop">
-				<s-goods-item
-          :img=" state.info.picUrl"
-          :title=" state.info.spuName"
-					:titleWidth="480"
-          :skuText="state.info.properties.map((property) => property.valueName).join(' ')"
-          :num=" state.info.count"
-        />
+				<s-goods-item :img=" state.info.picUrl" :title=" state.info.spuName" :titleWidth="480"
+					:skuText="state.info.properties.map((property) => property.valueName).join(' ')"
+					:num=" state.info.count" />
 			</view>
 
 			<!-- 服务内容 -->
@@ -85,21 +81,21 @@
 			</view>
 		</view>
 
-    <!-- 操作区 -->
+		<!-- 操作区 -->
 		<s-empty v-if="isEmpty(state.info) && state.loading" icon="/static/order-empty.png" text="暂无该订单售后详情" />
 		<su-fixed bottom placeholder bg="bg-white" v-if="!isEmpty(state.info)">
 			<view class="foot_box">
-        <button class="ss-reset-button btn" v-if="state.info.buttons?.includes('cancel')"
-                @tap="onApply(state.info.id)">
-          取消申请
-        </button>
-        <button class="ss-reset-button btn" v-if="state.info.buttons?.includes('delivery')"
-                @tap="sheep.$router.go('/pages/order/aftersale/return-delivery', { id: state.info.id })">
-          填写退货
-        </button>
+				<button class="ss-reset-button btn" v-if="state.info.buttons?.includes('cancel')"
+					@tap="onApply(state.info.id)">
+					取消申请
+				</button>
+				<button class="ss-reset-button btn" v-if="state.info.buttons?.includes('delivery')"
+					@tap="sheep.$router.go('/pages/order/aftersale/return-delivery', { id: state.info.id })">
+					填写退货
+				</button>
 				<button class="ss-reset-button contcat-btn btn" @tap="sheep.$router.go('/pages/chat/index')">
-          联系客服
-        </button>
+					联系客服
+				</button>
 			</view>
 		</su-fixed>
 	</s-layout>
@@ -107,26 +103,41 @@
 
 <script setup>
 	import sheep from '@/sheep';
-	import { onLoad } from '@dcloudio/uni-app';
-	import { reactive } from 'vue';
-	import { isEmpty } from 'lodash';
-  import { fen2yuan, formatAfterSaleStatusDescription, handleAfterSaleButtons } from '@/sheep/hooks/useGoods';
-  import AfterSaleApi from '@/sheep/api/trade/afterSale';
-
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import {
+		reactive,
+		computed,
+		watch
+	} from 'vue';
+	import {
+		isEmpty
+	} from 'lodash';
+	import {
+		showAuthModal
+	} from '@/sheep/hooks/useModal';
+	import {
+		fen2yuan,
+		formatAfterSaleStatusDescription,
+		handleAfterSaleButtons
+	} from '@/sheep/hooks/useGoods';
+	import AfterSaleApi from '@/sheep/api/trade/afterSale';
+	const userInfo = sheep.$store('user').userInfo;
 	const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
 	const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png');
 	const state = reactive({
-    id: 0, // 售后编号
-    info: {}, // 收货信息
+		id: 0, // 售后编号
+		info: {}, // 收货信息
 		loading: false,
-    active: 0, // 在 list 的激活位置
-    list: [{
-      title: '提交申请',
-    }, {
-      title: '处理中',
-    }, {
-      title: '完成'
-    }], // 时间轴
+		active: 0, // 在 list 的激活位置
+		list: [{
+			title: '提交申请',
+		}, {
+			title: '处理中',
+		}, {
+			title: '完成'
+		}], // 时间轴
 	});
 
 	function onApply(id) {
@@ -137,46 +148,81 @@
 				if (!res.confirm) {
 					return;
 				}
-        const { code } = await AfterSaleApi.cancelAfterSale(id);
-        if (code === 0) {
-          await getDetail(id);
-        }
+				const {
+					code
+				} = await AfterSaleApi.cancelAfterSale(id);
+				if (code === 0) {
+					await getDetail(id);
+				}
 			},
 		});
 	}
 
-  // 复制
-  const onCopy = () => {
+	// 复制
+	const onCopy = () => {
 		sheep.$helper.copyText(state.info.no);
 	};
 
 	async function getDetail(id) {
-    state.loading = true;
-    const { code, data } = await AfterSaleApi.getAfterSale(id);
-    if (code !== 0) {
-      state.info = null;
-      return;
-    }
-    state.info = data;
-    handleAfterSaleButtons(state.info);
-
-    // 处理时间轴
-    if ([10].includes(state.info.status)) {
-      state.active = 0;
-    } else if ([20, 30].includes(state.info.status)) {
-      state.active = 1;
-    } else if ([40, 50].includes(state.info.status)) {
-      state.active = 2;
-    } else if ([61, 62, 63].includes(state.info.status)) {
-      state.active = 2;
-    }
+		state.loading = true;
+		const {
+			code,
+			data
+		} = await AfterSaleApi.getAfterSale(id);
+		if (code !== 0) {
+			state.info = null;
+			return;
+		}
+		state.info = data;
+		handleAfterSaleButtons(state.info);
+
+		// 处理时间轴
+		if ([10].includes(state.info.status)) {
+			state.active = 0;
+		} else if ([20, 30].includes(state.info.status)) {
+			state.active = 1;
+		} else if ([40, 50].includes(state.info.status)) {
+			state.active = 2;
+		} else if ([61, 62, 63].includes(state.info.status)) {
+			state.active = 2;
+		}
 	}
+	const isLogin = computed(() => sheep.$store('user').isLogin);
+	// 监听到在这个页面登陆,并刷新页面
+	watch(
+		() => isLogin.value,
+		(newVal) => {
+			if (newVal) {
+				window.location.reload()
+			}
+		}
+	);
 
 	onLoad((options) => {
-    if (!options.id) {
-      sheep.$helper.toast(`缺少订单信息,请检查`);
-      return
-    }
+		//如果没登陆就进来则有可能是在微信消息推送进来的 提示登陆
+		if (!isLogin.value) {
+			showAuthModal();
+			sheep.$helper.toast("您尚未登录,请登录:" + options.username + "后再试", 3000);
+			return false;
+		} else {
+			
+			// 如果
+			if (options.username) {
+				//  如果登陆了但不是该订单的账号,提示有问题
+				console.log(JSON.parse(uni.getStorageSync("user-store")).userInfo.username)
+				if (options.username != JSON.parse(uni.getStorageSync("user-store")).userInfo.username) {
+					sheep.$helper.toast("您当前登录的账号是" + JSON.parse(uni.getStorageSync("user-store")).userInfo.username + ",请切换到" + options.username +
+						"后再试",
+						3000);
+					return false;
+				}
+			}
+		}
+
+		if (!options.id) {
+			sheep.$helper.toast(`缺少订单信息,请检查`);
+			return
+		}
 		state.id = options.id;
 		getDetail(options.id);
 	});

+ 69 - 43
pages/order/aftersale/return-delivery.vue

@@ -7,18 +7,18 @@
 						<view class='item acea-row row-between-wrapper' style="display: flex;align-items: center;">
 							<view>物流公司</view>
 							<picker mode='selector' class='num' @change="bindPickerChange" :value="state.expressIndex"
-                      :range="state.expresses" range-key="name">
-								<view class="picker acea-row row-between-wrapper">
+								:range="state.expresses" range-key="name">
+								<view class="picker acea-row row-between-wrapper "  style="display: flex;align-items: center;">
 									<view class='reason'>{{ state.expresses[state.expressIndex].name }}</view>
-                  <!-- TODO 非繁人:这里样式有问题,少了 > 按钮 -->
-									<text class='iconfont icon-jiantou' />
+									<!-- TODO 非繁人:这里样式有问题,少了 > 按钮 -->
+									<image src="@/static/icon/select-icon.png" class="select-icon" />
 								</view>
 							</picker>
 						</view>
 						<view class='item textarea acea-row row-between' style="display: flex;align-items: center;">
 							<view>物流单号</view>
 							<input placeholder='请填写物流单号' class='num' name="logisticsNo"
-                     placeholder-class='placeholder' />
+								placeholder-class='placeholder' />
 						</view>
 						<button class='returnBnt bg-color ss-reset-button ui-BG-Main-Gradient sub-btn'
 							form-type="submit"
@@ -31,14 +31,18 @@
 </template>
 
 <script setup>
-	import { onLoad } from '@dcloudio/uni-app';
-	import { reactive } from 'vue';
-  import sheep from '@/sheep';
-  import AfterSaleApi from '@/sheep/api/trade/afterSale';
-  import DeliveryApi from '@/sheep/api/trade/delivery';
-
-  const state = reactive({
-    id: 0, // 售后编号
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import {
+		reactive
+	} from 'vue';
+	import sheep from '@/sheep';
+	import AfterSaleApi from '@/sheep/api/trade/afterSale';
+	import DeliveryApi from '@/sheep/api/trade/delivery';
+
+	const state = reactive({
+		id: 0, // 售后编号
 		expressIndex: 0, // 选中的 expresses 下标
 		expresses: [], // 可选的快递列表
 	})
@@ -48,38 +52,57 @@
 	}
 
 	async function subRefund(e) {
-    let data = {
-      id: state.id,
-      logisticsId: state.expresses[state.expressIndex].id,
-      logisticsNo: e.detail.value.logisticsNo,
-    };
-    const { code } = await AfterSaleApi.deliveryAfterSale(data);
-    if (code !== 0) {
-      return;
-    }
-    uni.showToast({
-      title: '填写退货成功',
-    });
-    sheep.$router.go('/pages/order/aftersale/detail', { id: state.id });
-	}
-
-  // 获得快递物流列表
+		if(!state.expresses[state.expressIndex].id){
+			sheep.$helper.toast(`请选择物流公司`);
+			return false
+		}
+		if(!e.detail.value.logisticsNo){
+			sheep.$helper.toast(`请填写物流单号`);
+			return false
+		}
+		let data = {
+			id: state.id,
+			logisticsId: state.expresses[state.expressIndex].id,
+			logisticsNo: e.detail.value.logisticsNo,
+		};
+		const {
+			code
+		} = await AfterSaleApi.deliveryAfterSale(data);
+		if (code !== 0) {
+			return;
+		}
+		uni.showToast({
+			title: '填写退货成功',
+		});
+		sheep.$router.go('/pages/order/aftersale/detail', {
+			id: state.id
+		});
+	}
+
+	// 获得快递物流列表
 	async function getExpressList() {
-    const { code, data } = await DeliveryApi.getDeliveryExpressList();
-    if (code !== 0) {
-      return;
-    }
-    state.expresses = data;
+		const {
+			code,
+			data
+		} = await DeliveryApi.getDeliveryExpressList();
+		if (code !== 0) {
+			return;
+		}
+		state.expresses = data;
+		state.expresses.unshift({
+            "id": 0,
+            "name": "请选择"
+        },)
 	}
 
 	onLoad(options => {
-    if (!options.id) {
-      sheep.$helper.toast(`缺少订单信息,请检查`);
-      return
-    }
-    state.id = options.id;
-    // 获得快递物流列表
-    getExpressList();
+		if (!options.id) {
+			sheep.$helper.toast(`缺少订单信息,请检查`);
+			return
+		}
+		state.id = options.id;
+		// 获得快递物流列表
+		getExpressList();
 	})
 </script>
 <style lang="scss" scoped>
@@ -108,7 +131,7 @@
 	}
 
 	.apply-return .list .item .num .picker .reason {
-		width: 385rpx;
+		width: 14rem;
 	}
 
 	.apply-return .list .item .num .picker .iconfont {
@@ -116,7 +139,10 @@
 		font-size: 30rpx;
 		margin-top: 2rpx;
 	}
-
+	.select-icon {
+		width:30rpx;
+		height:30rpx;
+	}
 	.apply-return .list .item.textarea {
 		padding: 24rpx 0;
 	}

+ 69 - 48
pages/order/confirm.vue

@@ -2,7 +2,7 @@
 	<s-layout title="确认订单">
 		<!-- TODO:这个判断先删除 v-if="state.orderInfo.need_address === 1" -->
 		<view class="bg-white address-box ss-m-b-14 ss-r-b-10" @tap="onSelectAddress">
-			<s-address-item :item="state.addressInfo" :hasBorderBottom="false">
+			<s-address-item :item="state.addressInfo" :spuType="state.orderPayload.spuType" :hasBorderBottom="false">
 				<view class="ss-rest-button">
 					<text class="_icon-forward" />
 				</view>
@@ -46,7 +46,9 @@
 			<view class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
 				<view class="item-title">总价</view>
 				<view class="ss-flex ss-col-center">
-					{{"¥"+fen2yuan(items.price.payPrice)}}
+					<image src="@/static/icon/points.png"  v-if="state.orderPayload.spuPayType == 2" style="width:30rpx;height:30rpx"   ></image>
+					<text v-else>¥</text>
+					{{fen2yuan(items.price.payPrice)}}
 				</view>
 			</view>
 		</view>
@@ -61,41 +63,30 @@
 					<view class="item-title">商品总价 共{{totalItemCount}}件商品</view>
 					<view class="ss-flex ss-col-center">
 						<text class="item-value ss-m-r-24">
-							¥{{ fen2yuan(state.orderInfo.price.totalPrice) }}
+							<image src="@/static/icon/points.png"  v-if="state.orderPayload.spuPayType == 2" style="width:30rpx;height:30rpx"   ></image>
+							<text v-else>¥</text>
+							{{ fen2yuan(state.orderInfo.price.totalPrice) }}
 						</text>
 					</view>
 				</view>
-				<!-- TODO 非繁人:接入积分 -->
-				<!-- <view
-          class="order-item ss-flex ss-col-center ss-row-between"
-          v-if="state.orderPayload.order_type === 'score'"
-        >
-          <view class="item-title">扣除积分</view>
-          <view class="ss-flex ss-col-center">
-            <image
-              :src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
-              class="score-img"
-            />
-            <text class="item-value ss-m-r-24">{{ state.orderInfo.score_amount }}</text>
-          </view>
-        </view> -->
+				<!-- TODO 非繁人:接入数字权益 -->
 				<view class="order-item ss-flex ss-col-center ss-row-between">
 					<view class="item-title">运费</view>
 					<view class="ss-flex ss-col-center">
 						<text class="item-value ss-m-r-24">
-							¥{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
+							<image src="@/static/icon/points.png"  v-if="state.orderPayload.spuPayType == 2" style="width:30rpx;height:30rpx"   ></image>
+							<text v-else>¥</text>
+							{{ fen2yuan(state.orderInfo.price.deliveryPrice) }}
 						</text>
 					</view>
 				</view>
-				<view class="order-item ss-flex ss-col-center ss-row-between">
-					<view class="item-title">积分抵扣</view>
+				<view class="order-item ss-flex ss-col-center ss-row-between" v-if="state.orderPayload.spuPayType != 2">
+					<view class="item-title">数字权益抵扣</view>
 					<view class="ss-flex ss-col-center" @tap="state.showPoints = true">
 						<!-- <text class="item-value text-red">
 		    </text> -->
 						<text class="item-value" :class="state.usedPoint > 0 ? 'text-red' : 'text-disabled'">
-							{{
-		        state.usedPoint > 0 ?  ' 可抵扣' + state.usedPoint + '元' : '不使用积分'
-		      }}
+							{{ state.usedPoint > 0 ?  ' 可抵扣' + state.usedPoint + '元' : '不使用数字权益' }}
 						</text>
 						<text class="_icon-forward item-icon" />
 					</view>
@@ -143,14 +134,18 @@
 					共{{ totalItemCount }}件
 				</view>
 				<view>合计:</view>
-				<view class="total-num text-red"> ¥{{ fen2yuan(state.orderInfo.price.payPrice) }} </view>
+				<view class="total-num text-red"> 
+				
+				<image src="@/static/icon/points.png"  v-if="state.orderPayload.spuPayType == 2" style="width:30rpx;height:30rpx"   ></image>
+				<text v-else>¥</text>
+				{{ fen2yuan(state.orderInfo.price.payPrice) - 0.01 }} </view>
 			</view>
 		</view>
 
-		<!-- 积分-->
+		<!-- 数字权益-->
 		<s-points-pop v-model="state.couponInfo" :currentMemberPoints="state.currentMemberPoints"
-			:currentTotalPrice="state.currentTotalPrice" :currentDeliveryPrice="state.currentDeliveryPrice" :show="state.showPoints" @confirm="onInputPoints"
-			@close="state.showPoints = false" />
+			:currentTotalPrice="state.currentTotalPrice" :currentDeliveryPrice="state.currentDeliveryPrice"
+			:show="state.showPoints" @confirm="onInputPoints" @close="state.showPoints = false" />
 
 		<!-- 满额折扣弹框 TODO 非繁人:后续要把优惠信息打进去 -->
 		<!-- <s-discount-list
@@ -163,7 +158,12 @@
 		<su-fixed bottom :opacity="false" bg="bg-white" placeholder :noFixed="false" :index="200">
 			<view class="footer-box border-top ss-flex ss-row-between ss-p-x-20 ss-col-center">
 				<view class="total-box-footer ss-flex ss-col-center">
-					<view class="total-num ss-font-30 text-red">
+					<view class="total-num ss-font-30 text-red " v-if="state.orderPayload.spuPayType == 2">
+						<image src="@/static/icon/points.png"  v-if="state.orderPayload.spuPayType == 2" style="width:30rpx;height:30rpx"   ></image>
+						{{ state.usedPoint }}
+						¥0.01
+					</view>
+					<view class="total-num ss-font-30 text-red" v-else>
 						¥{{ fen2yuan(state.orderInfo.price.payPrice) }}
 					</view>
 				</view>
@@ -201,13 +201,13 @@
 			price: {}, // 价格信息
 		},
 		addressInfo: {}, // 选择的收货地址
-		showPoints: false, // 是否积分抵扣
+		showPoints: false, // 是否数字权益抵扣
 		couponInfo: [], // 优惠劵列表
 		showDiscount: false, // 是否展示营销活动
-		currentMemberPoints: 0, //用户当前可用积分
-		usedPoint: 0, //用户使用的积分 
-		currentTotalPrice: 0 ,//当前的整个订单的总价格
-		currentDeliveryPrice:0 // 当前订单的总运费
+		currentMemberPoints: 0, //用户当前可用数字权益
+		usedPoint: 0, //用户使用的数字权益 
+		currentTotalPrice: 0, //当前的整个订单的总价格
+		currentDeliveryPrice: 0 // 当前订单的总运费
 	});
 
 	// 返回来的数据根据店铺名过滤 TODO
@@ -242,7 +242,14 @@
 		uni.$once('SELECT_ADDRESS', (e) => {
 			changeConsignee(e.addressInfo);
 		});
-		sheep.$router.go('/pages/user/address/list');
+		console.log(state.orderPayload.spuType)
+		// 如果是虚拟商品 进入选虚拟地址
+		if(state.orderPayload.spuType){
+			sheep.$router.go('/pages/user/address/list');
+		}else{
+			sheep.$router.go('/pages/user/dummyAddress/list');
+		}
+		
 	}
 
 	// 更改收货人地址&计算订单信息
@@ -252,8 +259,7 @@
 		}
 		await getOrderInfo();
 	}
-
-	// 使用积分
+	// 使用数字权益
 	async function onInputPoints(points) {
 
 		if (points == undefined) {
@@ -267,16 +273,23 @@
 
 	// 提交订单
 	function onConfirm() {
+
 		if (!state.addressInfo.id) {
 			sheep.$helper.toast('请选择收货地址');
 			return;
 		}
+		
+		if(state.usedPoint > state.currentMemberPoints){
+			sheep.$helper.toast('可用数字权益不足');
+			return;
+		}
 
 		submitOrder();
 	}
 
 	// 创建订单&跳转
 	async function submitOrder() {
+		
 		// 处理每个店铺的留言 以{店铺id:留言}的形式返回
 		const shops = shopsByNames.value;
 		const shopRemarks = {};
@@ -284,7 +297,7 @@
 			const shop = shops[shopName];
 			shopRemarks[shop.shopId] = shop.remark;
 		});
-
+		
 		const {
 			code,
 			data
@@ -292,8 +305,8 @@
 			items: state.orderPayload.items,
 			couponId: state.orderPayload.couponId,
 			addressId: state.addressInfo.id,
-			deliveryType: 1, // TODO 非繁人:需要支持【门店自提】
-			pointStatus: false, // TODO 非繁人:需要支持【积分选择】
+			deliveryType:  state.orderPayload.spuType == 1 ? 1 : 3, // TODO 非繁人:需要支持【门店自提】
+			pointStatus: false, // TODO 非繁人:需要支持【数字权益选择】
 			combinationActivityId: state.orderPayload.combinationActivityId,
 			combinationHeadId: state.orderPayload.combinationHeadId,
 			seckillActivityId: state.orderPayload.seckillActivityId,
@@ -318,12 +331,13 @@
 		//  每次查询设置订单之前  看有没有评论 如果有评论就存到shopRemarks
 		const shops = shopsByNames.value
 		let shopRemarks = {};
-		if(Object.keys(shops).length !== 0){
+		if (Object.keys(shops).length !== 0) {
 			Object.keys(shops).forEach(shopName => {
 				const shop = shops[shopName];
 				shopRemarks[shopName] = shop.remark;
 			});
 		}
+		
 		const {
 			data,
 			code
@@ -331,24 +345,25 @@
 			items: state.orderPayload.items,
 			couponId: state.orderPayload.couponId,
 			addressId: state.addressInfo.id,
-			deliveryType: 1, // TODO 非繁人:需要支持【门店自提】
-			pointStatus: false, // TODO 非繁人:需要支持【积分选择】
+			deliveryType:  state.orderPayload.spuType == 1 ? 1 : 3, // TODO 非繁人:需要支持【门店自提】
+			pointStatus: false, // TODO 非繁人:需要支持【数字权益选择】
 			combinationActivityId: state.orderPayload.combinationActivityId,
 			combinationHeadId: state.orderPayload.combinationHeadId,
 			seckillActivityId: state.orderPayload.seckillActivityId,
-			usedPoint: state.usedPoint
+			usedPoint: state.usedPoint,
+			addressType:state.orderPayload.spuType == 1 ? 1 : 2 //如果是虚拟产品
 		});
 		if (code !== 0) {
 			return;
 		}
 		state.orderInfo = data;
 		// 如果shopRemarks有评论的话 就放回shopsByNames
-		if(Object.keys(shopRemarks).length !== 0){
+		if (Object.keys(shopRemarks).length !== 0) {
 			Object.keys(shopRemarks).forEach(shopName => {
 				shopsByNames.value[shopName].remark = shopRemarks[shopName]
 			});
 		}
-		
+
 		// 设置收货地址
 		if (state.orderInfo.address) {
 			state.addressInfo = state.orderInfo.address;
@@ -357,7 +372,12 @@
 		state.currentTotalPrice = fen2yuan(state.orderInfo.price.payPrice)
 		state.currentDeliveryPrice = fen2yuan(state.orderInfo.price.deliveryPrice)
 		// console.log("父",state.currentTotalPrice)
-
+		
+		if(state.orderPayload.spuPayType == 2){
+			state.usedPoint = state.currentTotalPrice - 0.01
+			console.log(state.spuType)
+		}
+		
 	}
 
 
@@ -385,6 +405,7 @@
 			return;
 		}
 		state.orderPayload = JSON.parse(options.data);
+		
 		await getOrderInfo();
 
 	});
@@ -484,7 +505,7 @@
 		height: 100rpx;
 
 		.submit-btn {
-			width: 240rpx;
+			width: 230rpx;
 			height: 70rpx;
 			font-size: 28rpx;
 			font-weight: 500;
@@ -495,7 +516,7 @@
 		}
 
 		.cancel-btn {
-			width: 240rpx;
+			width: 230rpx;
 			height: 80rpx;
 			font-size: 26rpx;
 			background-color: #e5e5e5;

+ 600 - 612
pages/order/detail.vue

@@ -1,653 +1,641 @@
 <!-- 订单详情 -->
 <template>
-  <s-layout title="订单详情" class="index-wrap" navbar="inner">
-    <!-- 订单状态 TODO -->
-    <view
-      class="state-box ss-flex-col ss-col-center ss-row-right"
-      :style="[
+	<s-layout title="订单详情" class="index-wrap" navbar="inner">
+		<!-- 订单状态 TODO -->
+		<view class="state-box ss-flex-col ss-col-center ss-row-right" :style="[
         {
           marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
           paddingTop: Number(statusBarHeight + 88) + 'rpx',
         },
-      ]"
-    >
-      <view class="ss-flex ss-m-t-32 ss-m-b-20">
-        <image
-          v-if="
+      ]">
+			<view class="ss-flex ss-m-t-32 ss-m-b-20">
+				<image v-if="
             state.orderInfo.status_code == 'unpaid' ||
             state.orderInfo.status === 10 || // 待发货
             state.orderInfo.status_code == 'nocomment'
-          "
-          class="state-img"
-          :src="sheep.$url.static('/static/img/shop/order/order_loading.png')"
-        >
-        </image>
-        <image
-          v-if="
+          " class="state-img" :src="sheep.$url.static('/static/images/order_loading.png')">
+				</image>
+				<image v-if="
             state.orderInfo.status_code == 'completed' ||
             state.orderInfo.status_code == 'refund_agree'
-          "
-          class="state-img"
-          :src="sheep.$url.static('/static/img/shop/order/order_success.png')"
-        >
-        </image>
-        <image
-          v-if="state.orderInfo.status_code == 'cancel' || state.orderInfo.status_code == 'closed'"
-          class="state-img"
-          :src="sheep.$url.static('/static/img/shop/order/order_close.png')"
-        >
-        </image>
-        <image
-          v-if="state.orderInfo.status_code == 'noget'"
-          class="state-img"
-          :src="sheep.$url.static('/static/img/shop/order/order_express.png')"
-        >
-        </image>
-        <view class="ss-font-30">{{ formatOrderStatus(state.orderInfo) }}</view>
-      </view>
-      <view class="ss-font-26 ss-m-x-20 ss-m-b-70">{{
+          " class="state-img" :src="sheep.$url.static('/static/images/order_success.png')">
+				</image>
+				<image v-if="state.orderInfo.status_code == 'cancel' || state.orderInfo.status_code == 'closed'"
+					class="state-img" :src="sheep.$url.static('/static/images/order_close.png')">
+				</image>
+				<image v-if="state.orderInfo.status_code == 'noget'" class="state-img"
+					:src="sheep.$url.static('/static/images/order_express.png')">
+				</image>
+				<view class="ss-font-30">{{ formatOrderStatus(state.orderInfo) }}</view>
+			</view>
+			<view class="ss-font-26 ss-m-x-20 ss-m-b-70">{{
         formatOrderStatusDescription(state.orderInfo)
       }}</view>
-    </view>
-
-    <!-- 收货地址 -->
-    <view class="order-address-box" v-if="state.orderInfo.receiverAreaId > 0">
-      <view class="ss-flex ss-col-center">
-        <text class="address-username">
-          {{ state.orderInfo.receiverName }}
-        </text>
-        <text class="address-phone">{{ state.orderInfo.receiverMobile }}</text>
-      </view>
-      <view class="address-detail">
-        {{ state.orderInfo.receiverAreaName }} {{ state.orderInfo.receiverDetailAddress }}
-      </view>
-    </view>
-
-    <view
-      class="detail-goods"
-      :style="[{ marginTop: state.orderInfo.receiverAreaId > 0 ? '0' : '-40rpx' }]"
-    >
-      <!-- 订单信息 TODO 非繁人: -->
-      <view class="order-list" v-for="item in state.orderInfo.items" :key="item.goods_id">
-        <view class="order-card">
-          <s-goods-item
-            @tap="onGoodsDetail(item.spuId)"
-            :img="item.picUrl"
-            :title="item.spuName"
-            :skuText="item.properties.map((property) => property.valueName).join(' ')"
-            :price="item.price"
-            :num="item.count"
-          >
-            <template #tool>
-              <view class="ss-flex">
-                <button
-                  class="ss-reset-button apply-btn"
-                  v-if="[10, 20, 30].includes(state.orderInfo.status) && item.afterSaleStatus === 0"
-                  @tap.stop="
+		</view>
+
+		<!-- 收货地址 -->
+		<view class="order-address-box" v-if="state.orderInfo.receiverAreaId > 0">
+			<view class="ss-flex ss-col-center">
+				<text class="address-username">
+					{{ state.orderInfo.receiverName }}
+				</text>
+				<text class="address-phone">{{ state.orderInfo.receiverMobile }}</text>
+			</view>
+			<view class="address-detail">
+				{{ state.orderInfo.receiverAreaName }} {{ state.orderInfo.receiverDetailAddress }}
+			</view>
+		</view>
+
+		<view class="detail-goods" :style="[{ marginTop: state.orderInfo.receiverAreaId > 0 ? '0' : '-40rpx' }]">
+			<!-- 订单信息 TODO 非繁人: -->
+			<view class="order-list" v-for="item in state.orderInfo.items" :key="item.goods_id">
+				<view class="order-card">
+					<s-goods-item @tap="onGoodsDetail(item.spuId)" :img="item.picUrl" :title="item.spuName"
+						:skuText="item.properties.map((property) => property.valueName).join(' ')" :price="item.price"
+						:num="item.count">
+						<template #tool>
+							<view class="ss-flex">
+								<button class="ss-reset-button apply-btn"
+									v-if="[10, 20, 30].includes(state.orderInfo.status) && item.afterSaleStatus === 0"
+									@tap.stop="
                     sheep.$router.go('/pages/order/aftersale/apply', {
                       orderId: state.orderInfo.id,
                       itemId: item.id,
                     })
-                  "
-                >
-                  申请售后
-                </button>
-                <button
-                  class="ss-reset-button apply-btn"
-                  v-if="item.afterSaleStatus === 10"
-                  @tap.stop="
+                  ">
+									申请售后
+								</button>
+								<button class="ss-reset-button apply-btn" v-if="item.afterSaleStatus === 10" @tap.stop="
                     sheep.$router.go('/pages/order/aftersale/detail', {
                       id: item.afterSaleId,
                     })
-                  "
-                >
-                  退款中
-                </button>
-                <button
-                  class="ss-reset-button apply-btn"
-                  v-if="item.afterSaleStatus === 20"
-                  @tap.stop="
+                  ">
+									退款中
+								</button>
+								<button class="ss-reset-button apply-btn" v-if="item.afterSaleStatus === 20" @tap.stop="
                     sheep.$router.go('/pages/order/aftersale/detail', {
                       id: item.afterSaleId,
                     })
-                  "
-                >
-                  退款成功
-                </button>
-              </view>
-            </template>
-            <template #priceSuffix>
-              <button class="ss-reset-button tag-btn" v-if="item.status_text">
-                {{ item.status_text }}
-              </button>
-            </template>
-          </s-goods-item>
-        </view>
-      </view>
-    </view>
-
-    <!-- 订单信息 -->
-    <view class="notice-box">
-      <view class="notice-box__content">
-        <view class="notice-item--center">
-          <view class="ss-flex ss-flex-1">
-            <text class="title">订单编号:</text>
-            <text class="detail">{{ state.orderInfo.no }}</text>
-          </view>
-          <button class="ss-reset-button copy-btn" @tap="onCopy">复制</button>
-        </view>
-        
-		<view class="notice-item" >
-		  <text class="title">使用积分:</text>
-		  <text class="detail">
-		    {{ points2point(state.orderInfo.payIntegral) }}
-		  </text>
+                  ">
+									退款成功
+								</button>
+							</view>
+						</template>
+						<template #priceSuffix>
+							<button class="ss-reset-button tag-btn" v-if="item.status_text">
+								{{ item.status_text }}
+							</button>
+						</template>
+					</s-goods-item>
+				</view>
+			</view>
 		</view>
-		<view class="notice-item">
-		  <text class="title">用户留言:</text>
-		  <text class="detail">
-		    {{ state.orderInfo.userRemark || '无' }}
-		  </text>
+
+		<!-- 订单信息 -->
+		<view class="notice-box">
+			<view class="notice-box__content">
+				<view class="notice-item--center">
+					<view class="ss-flex ss-flex-1">
+						<text class="title">订单编号:</text>
+						<text class="detail">{{ state.orderInfo.no }}</text>
+					</view>
+					<button class="ss-reset-button copy-btn" @tap="onCopy">复制</button>
+				</view>
+
+				<view class="notice-item">
+					<text class="title">使用积分:</text>
+					<text class="detail">
+						{{ points2point(state.orderInfo.payIntegral) }}
+					</text>
+				</view>
+				<view class="notice-item">
+					<text class="title">用户留言:</text>
+					<text class="detail">
+						{{ state.orderInfo.userRemark || '无' }}
+					</text>
+				</view>
+				<view class="notice-item">
+					<text class="title">下单时间:</text>
+					<text class="detail">
+						{{ sheep.$helper.timeFormat(state.orderInfo.createTime, 'yyyy-mm-dd hh:MM:ss') }}
+					</text>
+				</view>
+				<view class="notice-item" v-if="state.orderInfo.payTime">
+					<text class="title">支付时间:</text>
+					<text class="detail">
+						{{ sheep.$helper.timeFormat(state.orderInfo.payTime, 'yyyy-mm-dd hh:MM:ss') }}
+					</text>
+				</view>
+				<view class="notice-item">
+					<text class="title">支付方式:</text>
+					<text class="detail">{{ state.orderInfo.payChannelName || '-' }}</text>
+				</view>
+			</view>
 		</view>
-		<view class="notice-item">
-		  <text class="title">下单时间:</text>
-		  <text class="detail">
-		    {{ sheep.$helper.timeFormat(state.orderInfo.createTime, 'yyyy-mm-dd hh:MM:ss') }}
-		  </text>
+
+		<!-- 价格信息 -->
+		<view class="order-price-box">
+			<view class="notice-item ss-flex ss-row-between">
+				<text class="title">商品总额</text>
+				<view class="ss-flex">
+					<text class="detail">¥{{ fen2yuan(state.orderInfo.totalPrice) }}</text>
+				</view>
+			</view>
+			<view class="notice-item ss-flex ss-row-between">
+				<text class="title">运费</text>
+				<text class="detail">¥{{ fen2yuan(state.orderInfo.deliveryPrice) }}</text>
+			</view>
+			<!-- TODO 非繁人:优惠劵抵扣、积分抵扣 -->
+			<view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.discountPrice > 0">
+				<text class="title">优惠金额</text>
+				<text class="detail">¥{{ fen2yuan(state.orderInfo.discountPrice) }}</text>
+			</view>
+			<view class="notice-item all-rpice-item ss-flex ss-m-t-20">
+				<text class="title">{{ state.orderInfo.payStatus ? '已付款' : '需付款' }}</text>
+				<text class="detail all-price">¥{{ fen2yuan(state.orderInfo.payPrice) }}</text>
+			</view>
+			<view class="notice-item all-rpice-item ss-flex ss-m-t-20" v-if="state.orderInfo.refundPrice > 0">
+				<text class="title">已退款</text>
+				<text class="detail all-price">¥{{ fen2yuan(state.orderInfo.refundPrice) }}</text>
+			</view>
 		</view>
-        <view class="notice-item" v-if="state.orderInfo.payTime">
-          <text class="title">支付时间:</text>
-          <text class="detail">
-            {{ sheep.$helper.timeFormat(state.orderInfo.payTime, 'yyyy-mm-dd hh:MM:ss') }}
-          </text>
-        </view>
-        <view class="notice-item">
-          <text class="title">支付方式:</text>
-          <text class="detail">{{ state.orderInfo.payChannelName || '-' }}</text>
-        </view>
-      </view>
-    </view>
-
-    <!-- 价格信息 -->
-    <view class="order-price-box">
-      <view class="notice-item ss-flex ss-row-between">
-        <text class="title">商品总额</text>
-        <view class="ss-flex">
-          <text class="detail">¥{{ fen2yuan(state.orderInfo.totalPrice) }}</text>
-        </view>
-      </view>
-      <view class="notice-item ss-flex ss-row-between">
-        <text class="title">运费</text>
-        <text class="detail">¥{{ fen2yuan(state.orderInfo.deliveryPrice) }}</text>
-      </view>
-      <!-- TODO 非繁人:优惠劵抵扣、积分抵扣 -->
-      <view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.discountPrice > 0">
-        <text class="title">优惠金额</text>
-        <text class="detail">¥{{ fen2yuan(state.orderInfo.discountPrice) }}</text>
-      </view>
-      <view class="notice-item all-rpice-item ss-flex ss-m-t-20">
-        <text class="title">{{ state.orderInfo.payStatus ? '已付款' : '需付款' }}</text>
-        <text class="detail all-price">¥{{ fen2yuan(state.orderInfo.payPrice) }}</text>
-      </view>
-      <view
-        class="notice-item all-rpice-item ss-flex ss-m-t-20"
-        v-if="state.orderInfo.refundPrice > 0"
-      >
-        <text class="title">已退款</text>
-        <text class="detail all-price">¥{{ fen2yuan(state.orderInfo.refundPrice) }}</text>
-      </view>
-    </view>
-
-    <!-- 底部按钮 -->
-    <!-- TODO: 查看物流、等待成团、评价完后返回页面没刷新页面 -->
-    <su-fixed bottom placeholder bg="bg-white" v-if="state.orderInfo.buttons?.length">
-		
-      <view class="footer-box ss-flex ss-col-center ss-row-right">
-        <button
-          class="ss-reset-button cancel-btn"
-          v-if="state.orderInfo.buttons?.includes('cancel')"
-          @tap="onCancel(state.orderInfo.id)"
-        >
-          取消订单
-        </button>
-        <button
-          class="ss-reset-button pay-btn ui-BG-Main-Gradient"
-          v-if="state.orderInfo.buttons?.includes('pay')"
-          @tap="onPay(state.orderInfo.id)"
-        >
-          继续支付
-        </button>
-        <!-- TODO 非繁人:拼团接入 -->
-        <button
-          class="ss-reset-button cancel-btn"
-          v-if="state.orderInfo.buttons?.includes('combination')"
-          @tap="
+
+		<!-- 底部按钮 -->
+		<!-- TODO: 查看物流、等待成团、评价完后返回页面没刷新页面 -->
+		<su-fixed bottom placeholder bg="bg-white" v-if="state.orderInfo.buttons?.length">
+
+			<view class="footer-box ss-flex ss-col-center ss-row-right">
+				<button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('cancel')"
+					@tap="onCancel(state.orderInfo.id)">
+					取消订单
+				</button>
+				<button class="ss-reset-button pay-btn ui-BG-Main-Gradient"
+					v-if="state.orderInfo.buttons?.includes('pay')" @tap="onPay(state.orderInfo.id)">
+					继续支付
+				</button>
+				<!-- TODO 非繁人:拼团接入 -->
+				<button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('combination')" @tap="
             sheep.$router.go('/pages/activity/groupon/detail', {
               id: state.orderInfo.ext.groupon_id,
             })
-          "
-        >
-          拼团详情
-        </button>
-        <button
-          class="ss-reset-button cancel-btn"
-          v-if="state.orderInfo.buttons?.includes('express')"
-          @tap="onExpress(state.orderInfo.id)"
-        >
-          查看物流
-        </button>
-        <button
-          class="ss-reset-button cancel-btn"
-          v-if="state.orderInfo.buttons?.includes('confirm')"
-          @tap="onConfirm(state.orderInfo.id)"
-        >
-          确认收货
-        </button>
-        <button
-          class="ss-reset-button cancel-btn"
-          v-if="state.orderInfo.buttons?.includes('comment')"
-          @tap="onComment(state.orderInfo.id)"
-        >
-          评价
-        </button>
-      </view>
-    </su-fixed>
-  </s-layout>
+          ">
+					拼团详情
+				</button>
+				<button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('express')"
+					@tap="onExpress(state.orderInfo.id)">
+					查看物流
+				</button>
+				<button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('confirm')"
+					@tap="onConfirm(state.orderInfo.id)">
+					确认收货
+				</button>
+				<button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('comment')"
+					@tap="onComment(state.orderInfo.id)">
+					评价
+				</button>
+			</view>
+		</su-fixed>
+	</s-layout>
 </template>
 
 <script setup>
-  import sheep from '@/sheep';
-  import { onLoad } from '@dcloudio/uni-app';
-  import { reactive } from 'vue';
-  import { isEmpty } from 'lodash';
-  import {
-    fen2yuan,
-    formatOrderStatus,
-    formatOrderStatusDescription,
-    handleOrderButtons,
-	points2point
-  } from '@/sheep/hooks/useGoods';
-  import OrderApi from '@/sheep/api/trade/order';
-
-  const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
-  const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png');
-
-  const state = reactive({
-    orderInfo: {},
-    merchantTradeNo: '', // 商户订单号
-    comeinType: '', // 进入订单详情的来源类型
-  });
-
-  // 复制
-  const onCopy = () => {
-    sheep.$helper.copyText(state.orderInfo.no);
-  };
-
-  // 去支付
-  function onPay(id) {
-    sheep.$router.go('/pages/pay/index', {
-      id: id,
-	  openType:2
-    });
-  }
-
-  // 查看商品
-  function onGoodsDetail(id) {
-	  // console.log(id)
-    sheep.$router.go('/pages/goods/index', {
-      id,
-    });
-  }
-
-  // 取消订单
-  async function onCancel(orderId) {
-    uni.showModal({
-      title: '提示',
-      content: '确定要取消订单吗?',
-      success: async function (res) {
-        if (!res.confirm) {
-          return;
-        }
-        const { code } = await OrderApi.cancelOrder(orderId);
-        if (code === 0) {
-          await getOrderDetail(orderId);
-        }
-      },
-    });
-  }
-
-  // 查看物流
-  async function onExpress(id) {
-    sheep.$router.go('/pages/order/express/log', {
-      id,
-    });
-  }
-
-  // 确认收货 TODO 非繁人:待测试
-  async function onConfirm(orderId, ignore = false) {
-    // 需开启确认收货组件
-    // todo: 非繁人:待接入微信
-    // 1.怎么检测是否开启了发货组件功能?如果没有开启的话就不能在这里return出去
-    // 2.如果开启了走mpConfirm方法,需要在App.vue的show方法中拿到确认收货结果
-	let isOpenBusinessView = true;
-	uni.showModal({
-		title: '提示',
-		content: '确认收货?',
-		success: async function(res) {
-			if (res.confirm) {
-				if (
-				  sheep.$platform.name === 'WechatMiniProgram' &&
-				  !isEmpty(state.orderInfo.wechat_extra_data) &&
-				  isOpenBusinessView &&
-				  !ignore
-				) {
-				  mpConfirm(orderId);
-				  return;
+	import sheep from '@/sheep';
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import {
+		reactive,
+		computed,
+		watch
+	} from 'vue';
+	import {
+		isEmpty
+	} from 'lodash';
+	import {
+		fen2yuan,
+		formatOrderStatus,
+		formatOrderStatusDescription,
+		handleOrderButtons,
+		points2point
+	} from '@/sheep/hooks/useGoods';
+	import OrderApi from '@/sheep/api/trade/order';
+	import {
+		showAuthModal
+	} from '@/sheep/hooks/useModal';
+	const userInfo = sheep.$store('user').userInfo;
+	const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
+	const headerBg = sheep.$url.css('/static/images/order_bg.png');
+
+	const state = reactive({
+		orderInfo: {},
+		merchantTradeNo: '', // 商户订单号
+		comeinType: '', // 进入订单详情的来源类型
+	});
+
+	// 复制
+	const onCopy = () => {
+		sheep.$helper.copyText(state.orderInfo.no);
+	};
+
+	// 去支付
+	function onPay(id) {
+		sheep.$router.go('/pages/pay/index', {
+			id: id,
+			openType: 2
+		});
+	}
+
+	// 查看商品
+	function onGoodsDetail(id) {
+		// console.log(id)
+		sheep.$router.go('/pages/goods/index', {
+			id,
+		});
+	}
+
+	// 取消订单
+	async function onCancel(orderId) {
+		uni.showModal({
+			title: '提示',
+			content: '确定要取消订单吗?',
+			success: async function(res) {
+				if (!res.confirm) {
+					return;
 				}
-				
-				// 正常的确认收货流程
-				const { code } = await OrderApi.receiveOrder(orderId);
+				const {
+					code
+				} = await OrderApi.cancelOrder(orderId);
 				if (code === 0) {
-				  await getOrderDetail(orderId);
+					await getOrderDetail(orderId);
+				}
+			},
+		});
+	}
+
+	// 查看物流
+	async function onExpress(id) {
+		sheep.$router.go('/pages/order/express/log', {
+			id,
+		});
+	}
+
+	// 确认收货 TODO 非繁人:待测试
+	async function onConfirm(orderId, ignore = false) {
+		// 需开启确认收货组件
+		// todo: 非繁人:待接入微信
+		// 1.怎么检测是否开启了发货组件功能?如果没有开启的话就不能在这里return出去
+		// 2.如果开启了走mpConfirm方法,需要在App.vue的show方法中拿到确认收货结果
+		let isOpenBusinessView = true;
+		uni.showModal({
+			title: '提示',
+			content: '确认收货?',
+			success: async function(res) {
+				if (res.confirm) {
+					if (
+						sheep.$platform.name === 'WechatMiniProgram' &&
+						!isEmpty(state.orderInfo.wechat_extra_data) &&
+						isOpenBusinessView &&
+						!ignore
+					) {
+						mpConfirm(orderId);
+						return;
+					}
+
+					// 正常的确认收货流程
+					const {
+						code
+					} = await OrderApi.receiveOrder(orderId);
+					if (code === 0) {
+						await getOrderDetail(orderId);
+					}
 				}
+			},
+		});
+
+
+	}
+
+	// #ifdef MP-WEIXIN
+	// 小程序确认收货组件
+	function mpConfirm(orderId) {
+		if (!wx.openBusinessView) {
+			sheep.$helper.toast(`请升级微信版本`);
+			return;
+		}
+		wx.openBusinessView({
+			businessType: 'weappOrderConfirm',
+			extraData: {
+				merchant_trade_no: state.orderInfo.wechat_extra_data.merchant_trade_no,
+				transaction_id: state.orderInfo.wechat_extra_data.transaction_id,
+			},
+			success(response) {
+				console.log('success:', response);
+				if (response.errMsg === 'openBusinessView:ok') {
+					if (response.extraData.status === 'success') {
+						onConfirm(orderId, true);
+					}
+				}
+			},
+			fail(error) {
+				console.log('error:', error);
+			},
+			complete(result) {
+				console.log('result:', result);
+			},
+		});
+	}
+	// #endif
+
+	// 评价
+	function onComment(id) {
+		sheep.$router.go('/pages/goods/comment/add', {
+			id
+		});
+	}
+
+	async function getOrderDetail(id) {
+		// 对详情数据进行适配
+		let res;
+		if (state.comeinType === 'wechat') {
+			// TODO 非繁人:微信场景下
+			res = await OrderApi.getOrder(id, {
+				merchant_trade_no: state.merchantTradeNo,
+			});
+		} else {
+			res = await OrderApi.getOrder(id);
+		}
+		if (res.code === 0) {
+			state.orderInfo = res.data;
+			handleOrderButtons(state.orderInfo);
+		} else {
+			sheep.$router.back();
+		}
+	}
+	const isLogin = computed(() => sheep.$store('user').isLogin);
+	// 监听到在这个页面登陆,并刷新页面
+	watch(
+		() => isLogin.value,
+		(newVal) => {
+			if (newVal) {
+				window.location.reload()
 			}
+		}, {
+			deep: true, // 深度监听
 		},
+	);
+
+	onLoad(async (options) => {
+
+		//如果没登陆就进来则有可能是在微信消息推送进来的 提示登陆
+		if (!isLogin.value) {
+			showAuthModal();
+			sheep.$helper.toast("您尚未登录,请登录:" + options.username + "后再试", 3000);
+		} else {
+			
+			// 如果
+			if (options.username) {
+				//  如果登陆了但不是该订单的账号,提示有问题
+					console.log(JSON.parse(uni.getStorageSync("user-store")).userInfo.username)
+					if (options.username != JSON.parse(uni.getStorageSync("user-store")).userInfo.username) {
+						sheep.$helper.toast("您当前登录的账号是" + JSON.parse(uni.getStorageSync("user-store")).userInfo.username + ",请切换到" + options.username + "后再试",
+							3000);
+					}
+			}
+		}
+
+		let id = 0;
+		if (options.id) {
+			id = options.id;
+		}
+		// TODO 非繁人:下面两个变量,后续接入
+		state.comeinType = options.comein_type;
+		if (state.comeinType === 'wechat') {
+			state.merchantTradeNo = options.merchant_trade_no;
+		}
+		await getOrderDetail(id);
 	});
-    
-    
-  }
-
-  // #ifdef MP-WEIXIN
-  // 小程序确认收货组件
-  function mpConfirm(orderId) {
-    if (!wx.openBusinessView) {
-      sheep.$helper.toast(`请升级微信版本`);
-      return;
-    }
-    wx.openBusinessView({
-      businessType: 'weappOrderConfirm',
-      extraData: {
-        merchant_trade_no: state.orderInfo.wechat_extra_data.merchant_trade_no,
-        transaction_id: state.orderInfo.wechat_extra_data.transaction_id,
-      },
-      success(response) {
-        console.log('success:', response);
-        if (response.errMsg === 'openBusinessView:ok') {
-          if (response.extraData.status === 'success') {
-            onConfirm(orderId, true);
-          }
-        }
-      },
-      fail(error) {
-        console.log('error:', error);
-      },
-      complete(result) {
-        console.log('result:', result);
-      },
-    });
-  }
-  // #endif
-
-  // 评价
-  function onComment(id) {
-    sheep.$router.go('/pages/goods/comment/add', {
-      id
-    });
-  }
-
-  async function getOrderDetail(id) {
-    // 对详情数据进行适配
-    let res;
-    if (state.comeinType === 'wechat') {
-      // TODO 非繁人:微信场景下
-      res = await OrderApi.getOrder(id, {
-        merchant_trade_no: state.merchantTradeNo,
-      });
-    } else {
-      res = await OrderApi.getOrder(id);
-    }
-    if (res.code === 0) {
-      state.orderInfo = res.data;
-      handleOrderButtons(state.orderInfo);
-    } else {
-      sheep.$router.back();
-    }
-  }
-
-  onLoad(async (options) => {
-    let id = 0;
-    if (options.id) {
-      id = options.id;
-    }
-    // TODO 非繁人:下面两个变量,后续接入
-    state.comeinType = options.comein_type;
-    if (state.comeinType === 'wechat') {
-      state.merchantTradeNo = options.merchant_trade_no;
-    }
-    await getOrderDetail(id);
-  });
 </script>
 
 <style lang="scss" scoped>
-  .score-img {
-    width: 36rpx;
-    height: 36rpx;
-    margin: 0 4rpx;
-  }
-
-  .apply-btn {
-    width: 140rpx;
-    height: 50rpx;
-    border-radius: 25rpx;
-    font-size: 24rpx;
-    border: 2rpx solid #dcdcdc;
-    line-height: normal;
-    margin-left: 16rpx;
-  }
-
-  .state-box {
-    color: rgba(#fff, 0.9);
-    width: 100%;
-    background: v-bind(headerBg) no-repeat,
-      linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
-    background-size: 750rpx 100%;
-    box-sizing: border-box;
-
-    .state-img {
-      width: 60rpx;
-      height: 60rpx;
-      margin-right: 20rpx;
-    }
-  }
-
-  .order-address-box {
-    background-color: #fff;
-    border-radius: 10rpx;
-    margin: -50rpx 20rpx 16rpx 20rpx;
-    padding: 44rpx 34rpx 42rpx 20rpx;
-    font-size: 30rpx;
-    box-sizing: border-box;
-    font-weight: 500;
-    color: rgba(51, 51, 51, 1);
-
-    .address-username {
-      margin-right: 20rpx;
-    }
-
-    .address-detail {
-      font-size: 26rpx;
-      font-weight: 500;
-      color: rgba(153, 153, 153, 1);
-      margin-top: 20rpx;
-    }
-  }
-
-  .detail-goods {
-    border-radius: 10rpx;
-    margin: 0 20rpx 20rpx 20rpx;
-
-    .order-list {
-      margin-bottom: 20rpx;
-      background-color: #fff;
-
-      .order-card {
-        padding: 20rpx 0;
-
-        .order-sku {
-          font-size: 24rpx;
-
-          font-weight: 400;
-          color: rgba(153, 153, 153, 1);
-          width: 450rpx;
-          margin-bottom: 20rpx;
-
-          .order-num {
-            margin-right: 10rpx;
-          }
-        }
-
-        .tag-btn {
-          margin-left: 16rpx;
-          font-size: 24rpx;
-          height: 36rpx;
-          color: var(--ui-BG-Main);
-          border: 2rpx solid var(--ui-BG-Main);
-          border-radius: 14rpx;
-          padding: 0 4rpx;
-        }
-      }
-    }
-  }
-
-  // 订单信息。
-  .notice-box {
-    background: #fff;
-    border-radius: 10rpx;
-    margin: 0 20rpx 20rpx 20rpx;
-
-    .notice-box__head {
-      font-size: 30rpx;
-
-      font-weight: 500;
-      color: rgba(51, 51, 51, 1);
-      line-height: 80rpx;
-      border-bottom: 1rpx solid #dfdfdf;
-      padding: 0 25rpx;
-    }
-
-    .notice-box__content {
-      padding: 20rpx;
-
-      .self-pickup-box {
-        width: 100%;
-
-        .self-pickup--img {
-          width: 200rpx;
-          height: 200rpx;
-          margin: 40rpx 0;
-        }
-      }
-    }
-
-    .notice-item,
-    .notice-item--center {
-      display: flex;
-      align-items: center;
-      line-height: normal;
-      margin-bottom: 24rpx;
-
-      .title {
-        font-size: 28rpx;
-        color: #999;
-      }
-
-      .detail {
-        font-size: 28rpx;
-        color: #333;
-        flex: 1;
-      }
-    }
-  }
-
-  .copy-btn {
-    width: 100rpx;
-    line-height: 50rpx;
-    border-radius: 25rpx;
-    padding: 0;
-    background: rgba(238, 238, 238, 1);
-    font-size: 22rpx;
-    font-weight: 400;
-    color: rgba(51, 51, 51, 1);
-  }
-
-  // 订单价格信息
-  .order-price-box {
-    background-color: #fff;
-    border-radius: 10rpx;
-    padding: 20rpx;
-    margin: 0 20rpx 20rpx 20rpx;
-
-    .notice-item {
-      line-height: 70rpx;
-
-      .title {
-        font-size: 28rpx;
-        color: #999;
-      }
-
-      .detail {
-        font-size: 28rpx;
-        color: #333;
-        font-family: OPPOSANS;
-      }
-    }
-
-    .all-rpice-item {
-      justify-content: flex-end;
-      align-items: center;
-
-      .title {
-        font-size: 26rpx;
-        font-weight: 500;
-        color: #333333;
-        line-height: normal;
-      }
-
-      .all-price {
-        font-size: 26rpx;
-        font-family: OPPOSANS;
-        line-height: normal;
-        color: $red;
-      }
-    }
-  }
-
-  // 底部
-  .footer-box {
-    height: 100rpx;
-    width: 100%;
-    box-sizing: border-box;
-    border-radius: 10rpx;
-    padding-right: 20rpx;
-
-    .cancel-btn {
-      width: 160rpx;
-      height: 60rpx;
-      background: #eeeeee;
-      border-radius: 30rpx;
-      margin-right: 20rpx;
-      font-size: 26rpx;
-      font-weight: 400;
-      color: #333333;
-    }
-
-    .pay-btn {
-      width: 160rpx;
-      height: 60rpx;
-      font-size: 26rpx;
-      border-radius: 30rpx;
-      font-weight: 500;
-      color: #fff;
-    }
-  }
-</style>
+	.score-img {
+		width: 36rpx;
+		height: 36rpx;
+		margin: 0 4rpx;
+	}
+
+	.apply-btn {
+		width: 140rpx;
+		height: 50rpx;
+		border-radius: 25rpx;
+		font-size: 24rpx;
+		border: 2rpx solid #dcdcdc;
+		line-height: normal;
+		margin-left: 16rpx;
+	}
+
+	.state-box {
+		color: rgba(#fff, 0.9);
+		width: 100%;
+		background: v-bind(headerBg) no-repeat,
+			linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		background-size: 750rpx 100%;
+		box-sizing: border-box;
+
+		.state-img {
+			width: 60rpx;
+			height: 60rpx;
+			margin-right: 20rpx;
+		}
+	}
+
+	.order-address-box {
+		background-color: #fff;
+		border-radius: 10rpx;
+		margin: -50rpx 20rpx 16rpx 20rpx;
+		padding: 44rpx 34rpx 42rpx 20rpx;
+		font-size: 30rpx;
+		box-sizing: border-box;
+		font-weight: 500;
+		color: rgba(51, 51, 51, 1);
+
+		.address-username {
+			margin-right: 20rpx;
+		}
+
+		.address-detail {
+			font-size: 26rpx;
+			font-weight: 500;
+			color: rgba(153, 153, 153, 1);
+			margin-top: 20rpx;
+		}
+	}
+
+	.detail-goods {
+		border-radius: 10rpx;
+		margin: 0 20rpx 20rpx 20rpx;
+
+		.order-list {
+			margin-bottom: 20rpx;
+			background-color: #fff;
+
+			.order-card {
+				padding: 20rpx 0;
+
+				.order-sku {
+					font-size: 24rpx;
+
+					font-weight: 400;
+					color: rgba(153, 153, 153, 1);
+					width: 450rpx;
+					margin-bottom: 20rpx;
+
+					.order-num {
+						margin-right: 10rpx;
+					}
+				}
+
+				.tag-btn {
+					margin-left: 16rpx;
+					font-size: 24rpx;
+					height: 36rpx;
+					color: var(--ui-BG-Main);
+					border: 2rpx solid var(--ui-BG-Main);
+					border-radius: 14rpx;
+					padding: 0 4rpx;
+				}
+			}
+		}
+	}
+
+	// 订单信息。
+	.notice-box {
+		background: #fff;
+		border-radius: 10rpx;
+		margin: 0 20rpx 20rpx 20rpx;
+
+		.notice-box__head {
+			font-size: 30rpx;
+
+			font-weight: 500;
+			color: rgba(51, 51, 51, 1);
+			line-height: 80rpx;
+			border-bottom: 1rpx solid #dfdfdf;
+			padding: 0 25rpx;
+		}
+
+		.notice-box__content {
+			padding: 20rpx;
+
+			.self-pickup-box {
+				width: 100%;
+
+				.self-pickup--img {
+					width: 200rpx;
+					height: 200rpx;
+					margin: 40rpx 0;
+				}
+			}
+		}
+
+		.notice-item,
+		.notice-item--center {
+			display: flex;
+			align-items: center;
+			line-height: normal;
+			margin-bottom: 24rpx;
+
+			.title {
+				font-size: 28rpx;
+				color: #999;
+			}
+
+			.detail {
+				font-size: 28rpx;
+				color: #333;
+				flex: 1;
+			}
+		}
+	}
+
+	.copy-btn {
+		width: 100rpx;
+		line-height: 50rpx;
+		border-radius: 25rpx;
+		padding: 0;
+		background: rgba(238, 238, 238, 1);
+		font-size: 22rpx;
+		font-weight: 400;
+		color: rgba(51, 51, 51, 1);
+	}
+
+	// 订单价格信息
+	.order-price-box {
+		background-color: #fff;
+		border-radius: 10rpx;
+		padding: 20rpx;
+		margin: 0 20rpx 20rpx 20rpx;
+
+		.notice-item {
+			line-height: 70rpx;
+
+			.title {
+				font-size: 28rpx;
+				color: #999;
+			}
+
+			.detail {
+				font-size: 28rpx;
+				color: #333;
+				font-family: OPPOSANS;
+			}
+		}
+
+		.all-rpice-item {
+			justify-content: flex-end;
+			align-items: center;
+
+			.title {
+				font-size: 26rpx;
+				font-weight: 500;
+				color: #333333;
+				line-height: normal;
+			}
+
+			.all-price {
+				font-size: 26rpx;
+				font-family: OPPOSANS;
+				line-height: normal;
+				color: $red;
+			}
+		}
+	}
+
+	// 底部
+	.footer-box {
+		height: 100rpx;
+		width: 100%;
+		box-sizing: border-box;
+		border-radius: 10rpx;
+		padding-right: 20rpx;
+
+		.cancel-btn {
+			width: 160rpx;
+			height: 60rpx;
+			background: #eeeeee;
+			border-radius: 30rpx;
+			margin-right: 20rpx;
+			font-size: 26rpx;
+			font-weight: 400;
+			color: #333333;
+		}
+
+		.pay-btn {
+			width: 160rpx;
+			height: 60rpx;
+			font-size: 26rpx;
+			border-radius: 30rpx;
+			font-weight: 500;
+			color: #fff;
+		}
+	}
+</style>

+ 1 - 1
pages/order/express/log.vue

@@ -83,7 +83,7 @@
 		const {
 			data
 		} = await OrderApi.getOrderExpressTrackList(id);
-		state.tracks = data.reverse();
+		state.tracks = data;
 	}
 
 	async function getOrderDetail(id) {

+ 1 - 0
pages/order/list.vue

@@ -351,6 +351,7 @@
 	}
 
 	onLoad(async (options) => {
+		console.log(options.type)
 		if (options.type) {
 			state.currentTab = options.type;
 		}

+ 1 - 1
pages/order/otherlist.vue

@@ -102,7 +102,7 @@
             <view v-if="order.score_amount">+</view>
             <view class="discounts-money pay-color ss-flex ss-col-center" v-if="order.score_amount">
               <image
-                :src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
+                :src="sheep.$url.static('/static/images/score1.svg')"
                 class="score-img"
               ></image>
               <view>{{ order.score_amount }}</view>

+ 5 - 5
pages/pay/index.vue

@@ -11,7 +11,7 @@
           <text>{{ payDescText }}</text>
         </view>
       </view>
-
+		
       <!-- 支付方式 -->
       <view class="modal-content ss-flex-1">
         <view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
@@ -110,6 +110,7 @@
         },
       });
     } else {
+	
       sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id);
     }
   };
@@ -191,9 +192,7 @@
     state.payMethods = getPayMethods(data)
   }
 
-  onLoad((options) => {
-	  console.log(options.openType)
-	  
+  onLoad((options) => {	  
     if (sheep.$platform.name === 'WechatOfficialAccount'
       && sheep.$platform.os === 'ios'
       && !sheep.$platform.landingPage.includes('pages/pay/index')) {
@@ -201,7 +200,7 @@
       return;
     }
     // 获得支付订单信息
-	// console.log(options)
+	console.log(options)
     let id = options.id;
     if (options.orderType) {
       state.orderType = options.orderType;
@@ -209,6 +208,7 @@
 	if(options.openType == 2){
 		setPayOrder(id)
 	}else{
+		console.log(123)
 		setOrder(id);
 	}
     

+ 269 - 257
pages/pay/result.vue

@@ -1,287 +1,299 @@
 <!-- 支付结果页面 -->
 <template>
-  <s-layout title="支付结果" :bgStyle="{ color: '#FFF' }">
-    <view class="pay-result-box ss-flex-col ss-row-center ss-col-center">
-      <!-- 信息展示 -->
-      <view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'" />
-      <image
-        class="pay-img ss-m-b-30"
-        v-if="payResult === 'success'"
-        :src="sheep.$url.static('/static/img/shop/order/order_pay_success.gif')"
-      />
-      <image
-        class="pay-img ss-m-b-30"
-        v-if="['failed', 'closed'].includes(payResult)"
-        :src="sheep.$url.static('/static/img/shop/order/order_paty_fail.gif')"
-      />
-      <view class="tip-text ss-m-b-30" v-if="payResult === 'success'">支付成功</view>
-      <view class="tip-text ss-m-b-30" v-if="payResult === 'failed'">支付失败</view>
-      <view class="tip-text ss-m-b-30" v-if="payResult === 'closed'">该订单已关闭</view>
-      <view class="tip-text ss-m-b-30" v-if="payResult === 'waiting'">检测支付结果...</view>
-      <view class="pay-total-num ss-flex" v-if="payResult === 'success'">
-        <view>¥{{ fen2yuan(state.orderInfo.price) }}</view>
-      </view>
-
-      <!-- 操作区 -->
-      <view class="btn-box ss-flex ss-row-center ss-m-t-50">
-        <button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/index/index')">
-          返回首页
-        </button>
-        <button
-          class="check-btn ss-reset-button"
-          v-if="payResult === 'failed'"
-          @tap="
+	<s-layout title="支付结果" :bgStyle="{ color: '#FFF' }">
+		<view class="pay-result-box ss-flex-col ss-row-center ss-col-center">
+			<!-- 信息展示 -->
+			<view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'" />
+			<image class="pay-img ss-m-b-30" v-if="payResult === 'success'"
+				:src="sheep.$url.static('/static/images/order_pay_success.gif')" />
+			<image class="pay-img ss-m-b-30" v-if="['failed', 'closed'].includes(payResult)"
+				:src="sheep.$url.static('/static/images/order_paty_fail.gif')" />
+			<view class="tip-text ss-m-b-30" v-if="payResult === 'success'">支付成功</view>
+			<view class="tip-text ss-m-b-30" v-if="payResult === 'failed'">支付失败</view>
+			<view class="tip-text ss-m-b-30" v-if="payResult === 'closed'">该订单已关闭</view>
+			<view class="tip-text ss-m-b-30" v-if="payResult === 'waiting'">检测支付结果...</view>
+			<view class="pay-total-num ss-flex" v-if="payResult === 'success'">
+				<view>¥{{ fen2yuan(state.orderInfo.price) }}</view>
+			</view>
+			<!-- 操作区 -->
+			<view class="btn-box ss-flex ss-row-center ss-m-t-50">
+				<button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/index/index')">
+					返回首页
+				</button>
+				<button class="check-btn ss-reset-button" v-if="payResult === 'failed'" @tap="
             sheep.$router.redirect('/pages/pay/index', { id: state.id, orderType: state.orderType })
-          "
-        >
-          重新支付
-        </button>
-        <button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder">
-          查看订单
-        </button>
-        <!-- TODO 非繁人:拼团接入 -->
-        <button
-          class="check-btn ss-reset-button"
-          v-if="payResult === 'success' && state.tradeOrder.type === 3"
-          @tap="sheep.$router.redirect('/pages/activity/groupon/order')"
-        >
-          我的拼团
-        </button>
-      </view>
-
-      <!-- TODO 非繁人:订阅 -->
-      <!-- #ifdef MP -->
-      <view class="subscribe-box ss-flex ss-m-t-44">
-        <image class="subscribe-img" :src="sheep.$url.static('/static/img/shop/order/cargo.png')" />
-        <view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
-        <view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
-      </view>
-      <!-- #endif -->
-    </view>
-  </s-layout>
+          ">
+					重新支付
+				</button>
+				<button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder">
+					查看订单
+				</button>
+				<!-- TODO 非繁人:拼团接入 -->
+				<button class="check-btn ss-reset-button" v-if="payResult === 'success' && state.tradeOrder.type === 3"
+					@tap="sheep.$router.redirect('/pages/activity/groupon/order')">
+					我的拼团
+				</button>
+			</view>
+			<!-- TODO 非繁人:订阅 -->
+			<!-- #ifdef MP -->
+			<view class="subscribe-box ss-flex ss-m-t-44">
+				<image class="subscribe-img" :src="sheep.$url.static('/static/images/cargo.png')" />
+				<view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
+				<view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
+			</view>
+			<!-- #endif -->
+		</view>
+	</s-layout>
 </template>
 
 <script setup>
-  import { onLoad, onHide, onShow } from '@dcloudio/uni-app';
-  import { reactive, computed } from 'vue';
-  import { isEmpty } from 'lodash';
-  import sheep from '@/sheep';
-  import PayOrderApi from '@/sheep/api/pay/order';
-  import { fen2yuan } from '../../sheep/hooks/useGoods';
-  import OrderApi from '@/sheep/api/trade/order';
-
-  const state = reactive({
-    id: 0, // 支付单号
-    orderType: 'goods', // 订单类型
-    result: 'unpaid', // 支付状态
-    orderInfo: {}, // 支付订单信息
-    tradeOrder: {}, // 商品订单信息,只有在 orderType 为 goods 才会请求。目的:【我的拼团】按钮的展示
-    counter: 0, // 获取结果次数
-  });
+	import {
+		onLoad,
+		onHide,
+		onShow
+	} from '@dcloudio/uni-app';
+	import {
+		reactive,
+		computed,
+		watchEffect
+	} from 'vue';
+	import {
+		isEmpty
+	} from 'lodash';
+	import sheep from '@/sheep';
+	import PayOrderApi from '@/sheep/api/pay/order';
+	import {
+		fen2yuan
+	} from '../../sheep/hooks/useGoods';
+	import OrderApi from '@/sheep/api/trade/order';
+	import {
+		showWalletModal,
+		colseWalletModal
+	} from '@/sheep/hooks/useModal';
+	const state = reactive({
+		id: 0, // 支付单号
+		orderType: 'goods', // 订单类型
+		result: 'unpaid', // 支付状态
+		orderInfo: {}, // 支付订单信息
+		tradeOrder: {}, // 商品订单信息,只有在 orderType 为 goods 才会请求。目的:【我的拼团】按钮的展示
+		counter: 0, // 获取结果次数
+	});
 
-  // 支付结果 result => payResult
-  const payResult = computed(() => {
-    if (state.result === 'unpaid') {
-      return 'waiting';
-    }
-    if (state.result === 'paid') {
-      return 'success';
-    }
-    if (state.result === 'failed') {
-      return 'failed';
-    }
-    if (state.result === 'closed') {
-      return 'closed';
-    }
-  });
+	
 
-  // 获得订单信息
-  async function getOrderInfo(id) {
-    state.counter++;
-    // 1. 加载订单信息
-    const { data, code } = await PayOrderApi.getOrder(id);
-    if (code === 0) {
-      state.orderInfo = data;
-      if (!state.orderInfo || state.orderInfo.status === 30) {
-        // 支付关闭
-        state.result = 'closed';
-        return;
-      }
-      if (state.orderInfo.status !== 0) {
-        // 非待支付,可能是已支付,可能是已退款
-        state.result = 'paid';
-        // #ifdef MP
-        subscribeMessage();
-        // #endif
-        // 特殊:获得商品订单信息
-        if (state.orderType === 'goods') {
-          const { data, code } = await OrderApi.getOrder(state.orderInfo.merchantOrderId);
-          if (code === 0) {
-            state.tradeOrder = data;
-          }
-        }
-        return;
-      }
-    }
-    // 2.1 情况三一:未支付,且轮询次数小于三次,则继续轮询
-    if (state.counter < 3 && state.result === 'unpaid') {
-      setTimeout(() => {
-        getOrderInfo(id);
-      }, 1500);
-    }
-    // 2.2 情况二:超过三次检测才判断为支付失败
-    if (state.counter >= 3) {
-      state.result = 'failed';
-    }
-  }
+	// 支付结果 result => payResult
+	const payResult = computed(() => {
+		if (state.result === 'unpaid') {
+			return 'waiting';
+		}
+		if (state.result === 'paid') {
+			return 'success';
+		}
+		if (state.result === 'failed') {
+			return 'failed';
+		}
+		if (state.result === 'closed') {
+			return 'closed';
+		}
+	});
+	watchEffect(()=>{
+		if(payResult.value == 'success'){
+			showWalletModal({points: state.orderInfo.jf,socialStatus: state.orderInfo.sj})
+		}
+	})
+	// 获得订单信息
+	async function getOrderInfo(id) {
+		state.counter++;
+		// 1. 加载订单信息
+		const {
+			data,
+			code
+		} = await PayOrderApi.getByStatus(id);
+		if (code === 0) {
+			state.orderInfo = data;
+			if (!state.orderInfo || state.orderInfo.status === 30) {
+				// 支付关闭
+				state.result = 'closed';
+				return;
+			}
+			if (state.orderInfo.status !== 0) {
+				// 非待支付,可能是已支付,可能是已退款
+				state.result = 'paid';
+				// #ifdef MP
+				subscribeMessage();
+				// #endif
+				// 特殊:获得商品订单信息
+				if (state.orderType === 'goods') {
+					const {
+						data,
+						code
+					} = await OrderApi.getByStatus(state.orderInfo.merchantOrderId);
+					if (code === 0) {
+						state.tradeOrder = data;
+					}
+				}
+				return;
+			}
+		}
+		// 2.1 情况三一:未支付,且轮询次数小于三次,则继续轮询
+		if (state.counter < 3 && state.result === 'unpaid') {
+			setTimeout(() => {
+				getOrderInfo(id);
+			}, 1500);
+		}
+		// 2.2 情况二:超过三次检测才判断为支付失败
+		if (state.counter >= 3) {
+			state.result = 'failed';
+		}
+	}
 
-  function onOrder() {
-    // TODO 非繁人:待测试
-    if (state.orderType === 'recharge') {
-      sheep.$router.redirect('/pages/pay/recharge-log');
-    } else {
-      sheep.$router.redirect('/pages/order/list');
-    }
-  }
+	function onOrder() {
+		// TODO 非繁人:待测试
+		if (state.orderType === 'recharge') {
+			sheep.$router.redirect('/pages/pay/recharge-log');
+		} else {
+			sheep.$router.redirect('/pages/order/list');
+		}
+	}
 
-  // TODO 非繁人:待测试
-  // #ifdef MP
-  function subscribeMessage() {
-    let event = ['order_dispatched'];
-    if (state.tradeOrder.type === 3) {
-      event.push('groupon_finish');
-      event.push('groupon_fail');
-    }
-    sheep.$platform.useProvider('wechat').subscribeMessage(event);
-  }
-  // #endif
+	// TODO 非繁人:待测试
+	// #ifdef MP
+	function subscribeMessage() {
+		let event = ['order_dispatched'];
+		if (state.tradeOrder.type === 3) {
+			event.push('groupon_finish');
+			event.push('groupon_fail');
+		}
+		sheep.$platform.useProvider('wechat').subscribeMessage(event);
+	}
+	// #endif
 
-  onLoad(async (options) => {
-    // 支付订单号
-    if (options.id) {
-      state.id = options.id;
-    }
-    // 订单类型
-    if (options.orderType) {
-      state.orderType = options.orderType;
-    }
+	onLoad(async (options) => {
+		// 支付订单号
+		if (options.id) {
+			state.id = options.id;
+		}
+		// 订单类型
+		if (options.orderType) {
+			state.orderType = options.orderType;
+		}
 
-    // 支付结果传值过来是失败,则直接显示失败界面
-    if (options.payState === 'fail') {
-      state.result = 'failed';
-    } else {
-      // 轮询三次检测订单支付结果
-      await getOrderInfo(state.id);
-    }
-  });
+		// 支付结果传值过来是失败,则直接显示失败界面
+		// if (options.payState === 'fail') {
+		//   state.result = 'failed';
+		// } else {
+		// 轮询三次检测订单支付结果
+		await getOrderInfo(state.id);
+		// }
+	});
 
-  onShow(() => {
-    if (isEmpty(state.orderInfo)) {
-      return;
-    }
-    getOrderInfo(state.id);
-  });
+	onShow(() => {
+		if (isEmpty(state.orderInfo)) {
+			return;
+		}
+		getOrderInfo(state.id);
+	});
 
-  onHide(() => {
-    state.result = 'unpaid';
-    state.counter = 0;
-  });
+	onHide(() => {
+		state.result = 'unpaid';
+		state.counter = 0;
+	});
 </script>
 
 <style lang="scss" scoped>
-  @keyframes rotation {
-    0% {
-      transform: rotate(0deg);
-    }
+	@keyframes rotation {
+		0% {
+			transform: rotate(0deg);
+		}
 
-    100% {
-      transform: rotate(360deg);
-    }
-  }
+		100% {
+			transform: rotate(360deg);
+		}
+	}
 
-  .score-img {
-    width: 36rpx;
-    height: 36rpx;
-    margin: 0 4rpx;
-  }
+	.score-img {
+		width: 36rpx;
+		height: 36rpx;
+		margin: 0 4rpx;
+	}
 
-  .pay-result-box {
-    padding: 60rpx 0;
+	.pay-result-box {
+		padding: 60rpx 0;
 
-    .pay-waiting {
-      margin-top: 20rpx;
-      width: 60rpx;
-      height: 60rpx;
-      border: 10rpx solid rgb(233, 231, 231);
-      border-bottom-color: rgb(204, 204, 204);
-      border-radius: 50%;
-      display: inline-block;
-      // -webkit-animation: rotation 1s linear infinite;
-      animation: rotation 1s linear infinite;
-    }
+		.pay-waiting {
+			margin-top: 20rpx;
+			width: 60rpx;
+			height: 60rpx;
+			border: 10rpx solid rgb(233, 231, 231);
+			border-bottom-color: rgb(204, 204, 204);
+			border-radius: 50%;
+			display: inline-block;
+			// -webkit-animation: rotation 1s linear infinite;
+			animation: rotation 1s linear infinite;
+		}
 
-    .pay-img {
-      width: 130rpx;
-      height: 130rpx;
-    }
+		.pay-img {
+			width: 130rpx;
+			height: 130rpx;
+		}
 
-    .tip-text {
-      font-size: 30rpx;
-      font-weight: bold;
-      color: #333333;
-    }
+		.tip-text {
+			font-size: 30rpx;
+			font-weight: bold;
+			color: #333333;
+		}
 
-    .pay-total-num {
-      font-size: 36rpx;
-      font-weight: 500;
-      color: #333333;
-      font-family: OPPOSANS;
-    }
+		.pay-total-num {
+			font-size: 36rpx;
+			font-weight: 500;
+			color: #333333;
+			font-family: OPPOSANS;
+		}
 
-    .btn-box {
-      width: 100%;
+		.btn-box {
+			width: 100%;
 
-      .back-btn {
-        width: 190rpx;
-        height: 70rpx;
-        font-size: 28rpx;
-        border: 2rpx solid #dfdfdf;
-        border-radius: 35rpx;
-        font-weight: 400;
-        color: #595959;
-      }
+			.back-btn {
+				width: 190rpx;
+				height: 70rpx;
+				font-size: 28rpx;
+				border: 2rpx solid #dfdfdf;
+				border-radius: 35rpx;
+				font-weight: 400;
+				color: #595959;
+			}
 
-      .check-btn {
-        width: 190rpx;
-        height: 70rpx;
-        font-size: 28rpx;
-        border: 2rpx solid #dfdfdf;
-        border-radius: 35rpx;
-        font-weight: 400;
-        color: #595959;
-        margin-left: 32rpx;
-      }
-    }
+			.check-btn {
+				width: 190rpx;
+				height: 70rpx;
+				font-size: 28rpx;
+				border: 2rpx solid #dfdfdf;
+				border-radius: 35rpx;
+				font-weight: 400;
+				color: #595959;
+				margin-left: 32rpx;
+			}
+		}
 
-    .subscribe-box {
-      .subscribe-img {
-        width: 44rpx;
-        height: 44rpx;
-      }
+		.subscribe-box {
+			.subscribe-img {
+				width: 44rpx;
+				height: 44rpx;
+			}
 
-      .subscribe-title {
-        font-weight: 500;
-        font-size: 32rpx;
-        line-height: 36rpx;
-        color: #434343;
-      }
+			.subscribe-title {
+				font-weight: 500;
+				font-size: 32rpx;
+				line-height: 36rpx;
+				color: #434343;
+			}
 
-      .subscribe-start {
-        color: var(--ui-BG-Main);
-        font-weight: 700;
-        font-size: 32rpx;
-        line-height: 36rpx;
-      }
-    }
-  }
-</style>
+			.subscribe-start {
+				color: var(--ui-BG-Main);
+				font-weight: 700;
+				font-size: 32rpx;
+				line-height: 36rpx;
+			}
+		}
+	}
+</style>

+ 3 - 3
pages/public/error.vue

@@ -8,7 +8,7 @@
       showAction
       actionText="重新连接"
       @clickAction="onReconnect"
-      buttonColor="#ff3000"
+      buttonColor="#132b85"
     />
     <s-empty
       v-else-if="errCode === 'TemplateError'"
@@ -17,7 +17,7 @@
       showAction
       actionText="重新加载"
       @clickAction="onReconnect"
-      buttonColor="#ff3000"
+      buttonColor="#132b85"
     />
     <s-empty
       v-else-if="errCode !== ''"
@@ -26,7 +26,7 @@
       showAction
       actionText="重新加载"
       @clickAction="onReconnect"
-      buttonColor="#ff3000"
+      buttonColor="#132b85"
     />
   </view>
 </template>

+ 3 - 23
pages/public/setting.vue

@@ -44,13 +44,13 @@
 			<!-- <view class="copyright-text ss-m-b-10">{{ appInfo.copyright }}</view> -->
 			<!-- <view class="copyright-text">{{ appInfo.copytime }}</view> -->
 		</view>
-		<su-fixed bottom placeholder>
+		<!-- <su-fixed bottom placeholder>
 			<view class="ss-p-x-20 ss-p-b-40">
 				<button class="loginout-btn ss-reset-button ui-BG-Main ui-Shadow-Main" @tap="onLogout" v-if="isLogin">
 					退出登录
 				</button>
 			</view>
-		</su-fixed>
+		</su-fixed> -->
 	</s-layout>
 </template>
 
@@ -98,27 +98,7 @@
 		});
 	}
 
-	// 退出账号
-	function onLogout() {
-		uni.showModal({
-			title: '提示',
-			content: '确认退出账号?',
-			success: async function(res) {
-				if (!res.confirm) {
-					return;
-				}
-				const {
-					code
-				} = await AuthUtil.logout();
-				if (code !== 0) {
-					return;
-				}
-				sheep.$store('user').logout();
-				uni.removeStorageSync('linkId');
-				sheep.$router.go('/pages/index/user');
-			},
-		});
-	}
+	
 </script>
 
 <style lang="scss" scoped>

+ 281 - 0
pages/user/dummyAddress/edit.vue

@@ -0,0 +1,281 @@
+<!-- 收货地址的新增/编辑 -->
+<template>
+	<!-- {{ru}} -->
+	<s-layout :title="state.model.id ? '编辑虚拟地址' : '新增虚拟地址'">
+		<uni-forms ref="addressFormRef" v-model="state.model" :rules="rules" validateTrigger="bind" labelWidth="160"
+			labelAlign="left" border :labelStyle="{ fontWeight: 'bold' }">
+			<view class="bg-white form-box ss-p-x-30">
+				<uni-forms-item name="name" label="收货人" class="form-item">
+					<uni-easyinput v-model="state.model.name" placeholder="请填写收货人姓名" :inputBorder="false"
+						placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal" />
+				</uni-forms-item>
+
+				<uni-forms-item name="mobile" label="手机号" class="form-item">
+					<uni-easyinput v-model="state.model.mobile" type="number" placeholder="请输入手机号" :inputBorder="false"
+						placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal">
+					</uni-easyinput>
+				</uni-forms-item>
+
+				<uni-forms-item name="detailAddress" label="详细地址" :formItemStyle="{ alignItems: 'flex-start' }"
+					:labelStyle="{ lineHeight: '5em' }" class="textarea-item">
+					<uni-easyinput :inputBorder="false" type="textarea" v-model="state.model.detailAddress"
+						placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
+						placeholder="请输入详细地址" clearable />
+				</uni-forms-item>
+			</view>
+			<view class="ss-m-y-20 bg-white ss-p-x-30 ss-flex ss-row-between ss-col-center default-box">
+				<view class="default-box-title"> 设为默认虚拟地址 </view>
+				<su-switch style="transform: scale(0.8)" v-model="state.model.defaultStatus" />
+			</view>
+		</uni-forms>
+		<su-fixed bottom :opacity="false" bg="" placeholder :noFixed="false" :index="10">
+			<view class="footer-box ss-flex-col ss-row-between ss-p-20">
+				<view class="ss-m-b-20">
+					<button class="ss-reset-button save-btn ui-Shadow-Main" @tap="onSave">保存</button>
+				</view>
+				<button v-if="state.model.id" class="ss-reset-button cancel-btn" @tap="onDelete">
+					删除
+				</button>
+			</view>
+		</su-fixed>
+
+		<!-- 省市区弹窗 -->
+		<su-region-picker :show="state.showRegion" @cancel="state.showRegion = false" @confirm="onRegionConfirm" />
+	</s-layout>
+</template>
+
+<script setup>
+	import {
+		ref,
+		reactive,
+		unref
+	} from 'vue';
+	import sheep from '@/sheep';
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import _ from 'lodash';
+	import {
+		mobile
+	} from '@/sheep/validate/form';
+	import AreaApi from '@/sheep/api/system/area';
+	import AddressApi from '@/sheep/api/member/address';
+	import $helper from '@/sheep/helper';
+	const addressFormRef = ref(null);
+	const state = reactive({
+		showRegion: false,
+		model: {
+			name: '',
+			mobile: '',
+			detailAddress: '',
+			defaultStatus: false,
+			areaName: '',
+			addressType:2
+		},
+		rules: {},
+	});
+	// let ru = ref({})
+	const rules = {
+		name: {
+			rules: [{
+				required: true,
+				errorMessage: '请输入收货人姓名',
+			}, ],
+		},
+		mobile,
+		detailAddress: {
+			rules: [{
+				required: true,
+				errorMessage: '请输入详细地址',
+			}]
+		},
+
+	};
+
+	// 确认选择地区
+	const onRegionConfirm = (e) => {
+		state.model.areaName = `${e.province_name} ${e.city_name} ${e.district_name}`
+		state.model.areaId = e.district_id;
+		state.showRegion = false;
+	};
+
+	// 获得地区数据
+	const getAreaData = () => {
+		if (_.isEmpty(uni.getStorageSync('areaData'))) {
+			AreaApi.getAreaTree().then((res) => {
+				if (res.code === 0) {
+					uni.setStorageSync('areaData', res.data);
+				}
+			});
+		}
+	};
+
+	// 保存收货地址
+	const onSave = async () => {
+		console.log(state)
+		// 参数校验
+		const validate = await unref(addressFormRef)
+			.validate()
+			.catch((error) => {
+				console.log('error: ', error);
+			});
+		if (!validate) {
+			return;
+		}
+
+		// 提交请求
+		const formData = {
+			...state.model
+		}
+		const {
+			code
+		} = state.model.id > 0 ? await AddressApi.updateAddress(formData) :
+			await AddressApi.createAddress(formData);
+		if (code === 0) {
+			sheep.$router.back();
+		}
+	};
+
+	// 删除收货地址
+	const onDelete = () => {
+		uni.showModal({
+			title: '提示',
+			content: '确认删除此收货地址吗?',
+			success: async function(res) {
+				if (!res.confirm) {
+					return;
+				}
+				const {
+					code
+				} = await AddressApi.deleteAddress( state.model.id , 2);
+				if (code === 0) {
+					sheep.$router.back();
+				}
+			},
+		});
+	};
+
+	onLoad(async (options) => {
+
+		// ru.value = {
+		// 	'consignee': 'aa',
+		// 	'mobile': '1595505005050',
+		// 	'province_name': '广东省',
+		// 	'city_name': '湛江市',
+		// 	'district_name': '廉江市',
+		// 	'address': 'yyyyyyyyy',
+		// 	'region': '',
+		// 	'is_default': 'false',
+		// }
+
+		// 获得地区数据
+		getAreaData();
+		// 情况一:基于 id 获得收件地址
+	
+		if (options.id) {
+			let {
+				code,
+				data
+			} = await AddressApi.getAddress(options.id,  2);
+			if (code !== 0) {
+				return;
+			}
+			// console.log(data)
+			state.model = data;
+		}
+		// 情况二:微信导入 TODO 非繁人:待接入
+		if (options.data) {
+			let data = JSON.parse(options.data);
+			// ru.value = data
+			const areaData = uni.getStorageSync('areaData');
+			let provinceArr = areaData.filter(item => item.name == data.province_name);
+			data.province_id = provinceArr[0].id;
+			let provinceArr2 = provinceArr[0].children.filter(item => item.name == data.city_name);
+			data.city_id = provinceArr2[0].id;
+			let provinceArr3 = provinceArr2[0].children.filter(item => item.name == data.district_name);
+			data.district_id = provinceArr3[0].id;
+
+			state.model = {
+				name: data.consignee,
+				mobile: data.mobile,
+				detailAddress: data.address,
+				defaultStatus: data.is_default,
+				areaName: data.province_name + ' ' + data.city_name + ' ' + data.district_name,
+				areaId: data.district_id
+			}
+
+
+
+
+			// state.model = {
+			// 	...state.model,
+			// 	...data,
+			// };
+		}
+	});
+</script>
+
+<style lang="scss" scoped>
+	:deep() {
+		.uni-forms-item__label .label-text {
+			font-size: 28rpx !important;
+			color: #333333 !important;
+			line-height: normal !important;
+		}
+
+		.uni-easyinput__content-input {
+			font-size: 28rpx !important;
+			color: #333333 !important;
+			line-height: normal !important;
+			padding-left: 0 !important;
+		}
+
+		.uni-easyinput__content-textarea {
+			font-size: 28rpx !important;
+			color: #333333 !important;
+			line-height: normal !important;
+			margin-top: 8rpx !important;
+		}
+
+		.uni-icons {
+			font-size: 40rpx !important;
+		}
+
+		.is-textarea-icon {
+			margin-top: 22rpx;
+		}
+
+		.is-disabled {
+			color: #333333;
+		}
+	}
+
+	.default-box {
+		width: 100%;
+		box-sizing: border-box;
+		height: 100rpx;
+
+		.default-box-title {
+			font-size: 28rpx;
+			color: #333333;
+			line-height: normal;
+		}
+	}
+
+	.footer-box {
+		.save-btn {
+			width: 710rpx;
+			height: 80rpx;
+			border-radius: 40rpx;
+			background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+			color: $white;
+		}
+
+		.cancel-btn {
+			width: 710rpx;
+			height: 80rpx;
+			border-radius: 40rpx;
+			background: var(--ui-BG);
+		}
+	}
+</style>

+ 152 - 0
pages/user/dummyAddress/list.vue

@@ -0,0 +1,152 @@
+<!-- 收件地址列表 -->
+<template>
+	<s-layout title="虚拟商品收货地址" :bgStyle="{ color: '#FFF' }">
+		<view v-if="state.list.length">
+			<s-address-item spuType="0" hasBorderBottom v-for="item in state.list" :key="item.id" :item="item"
+				@tap="onSelect(item)" />
+		</view>
+
+		<su-fixed bottom placeholder>
+			<view class="footer-box ss-flex ss-row-between ss-p-20">
+				<!-- 微信小程序和微信H5 -->
+				<!-- <button v-if="['WechatMiniProgram', 'WechatOfficialAccount'].includes(sheep.$platform.name)"
+					@tap="importWechatAddress"
+					class="border ss-reset-button sync-wxaddress ss-m-20 ss-flex ss-row-center ss-col-center">
+					<text class="cicon-weixin ss-p-r-10" style="color: #09bb07; font-size: 40rpx"></text>
+					导入微信地址
+				</button> -->
+				<button class="add-btn ss-reset-button ui-Shadow-Main"
+					@tap="sheep.$router.go('/pages/user/dummyAddress/edit')">
+					新增收货地址
+				</button>
+			</view>
+		</su-fixed>
+		<s-empty v-if="state.list.length === 0 && !state.loading" text="暂无收货地址" icon="/static/data-empty.png" />
+	</s-layout>
+</template>
+
+<script setup>
+	import {
+		reactive,
+		onBeforeMount
+	} from 'vue';
+	import {
+		onShow
+	} from '@dcloudio/uni-app';
+	import sheep from '@/sheep';
+	import {
+		isEmpty
+	} from 'lodash';
+	import AreaApi from '@/sheep/api/system/area';
+	import AddressApi from '@/sheep/api/member/address';
+	import $helper from '@/sheep/helper';
+	const state = reactive({
+		list: [], // 地址列表
+		loading: true,
+	});
+
+	// 选择收货地址
+	const onSelect = (addressInfo) => {
+		uni.$emit('SELECT_ADDRESS', {
+			addressInfo,
+		});
+		sheep.$router.back();
+	};
+
+	// 导入微信地址
+	// TODO 非繁人:未测试
+	function importWechatAddress() {
+		let wechatAddress = {};
+		// #ifdef MP
+		uni.chooseAddress({
+			success: (res) => {
+				wechatAddress = {
+					consignee: res.userName,
+					mobile: res.telNumber,
+					province_name: res.provinceName,
+					city_name: res.cityName,
+					district_name: res.countyName,
+					address: res.detailInfo,
+					region: '',
+					is_default: false,
+				};
+				if (!isEmpty(wechatAddress)) {
+					sheep.$router.go('/pages/user/dummyAddress/edit', {
+						data: JSON.stringify(wechatAddress),
+					});
+				}
+			},
+			fail: (err) => {
+				console.log("uni.chooseAddress调用失败,问题是:", err);
+			},
+		});
+		// #endif
+		// #ifdef H5
+		sheep.$platform.useProvider('wechat').jssdk.openAddress({
+			success: (res) => {
+				wechatAddress = {
+					consignee: res.userName,
+					mobile: res.telNumber,
+					province_name: res.provinceName,
+					city_name: res.cityName,
+					district_name: res.countryName,
+					address: res.detailInfo,
+					region: '',
+					is_default: false,
+				};
+				if (!isEmpty(wechatAddress)) {
+					sheep.$router.go('/pages/user/dummyAddress/edit', {
+						data: JSON.stringify(wechatAddress),
+					});
+				}
+			},
+		});
+		// #endif
+
+
+	}
+
+	onShow(async () => {
+		state.list = (await AddressApi.getAddressList(2)).data;
+		state.loading = false;
+	});
+
+	onBeforeMount(() => {
+		if (!!uni.getStorageSync('areaData')) {
+			return;
+		}
+		// 提前加载省市区数据
+		AreaApi.getAreaTree().then((res) => {
+			if (res.code === 0) {
+				uni.setStorageSync('areaData', res.data);
+			}
+		});
+	});
+</script>
+
+<style lang="scss" scoped>
+	.footer-box {
+		.add-btn {
+			flex: 1;
+			background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+			border-radius: 80rpx;
+			font-size: 30rpx;
+			font-weight: 500;
+			line-height: 80rpx;
+			color: $white;
+			position: relative;
+			z-index: 1;
+		}
+
+		.sync-wxaddress {
+			flex: 1;
+			line-height: 80rpx;
+			background: $white;
+			border-radius: 80rpx;
+			font-size: 30rpx;
+			font-weight: 500;
+			color: $dark-6;
+			margin-right: 18rpx;
+		}
+	}
+</style>

+ 12 - 12
pages/user/info.vue

@@ -134,21 +134,21 @@
         <view v-if="'WechatOfficialAccount' === sheep.$platform.name" class="ss-flex ss-col-center">
           <image
             class="list-img"
-            :src="sheep.$url.static('/static/img/shop/platform/WechatOfficialAccount.png')"
+            :src="sheep.$url.static('/static/images/WechatOfficialAccount.png')"
           />
           <text class="list-name">微信公众号</text>
         </view>
         <view v-if="'WechatMiniProgram' === sheep.$platform.name" class="ss-flex ss-col-center">
           <image
             class="list-img"
-            :src="sheep.$url.static('/static/img/shop/platform/WechatMiniProgram.png')"
+            :src="sheep.$url.static('/static/images/WechatMiniProgram.png')"
           />
           <text class="list-name">微信小程序</text>
         </view>
         <view v-if="'App' === sheep.$platform.name" class="ss-flex ss-col-center">
           <image
             class="list-img"
-            :src="sheep.$url.static('/static/img/shop/platform/wechat.png')"
+            :src="sheep.$url.static('/static/images/wechat.png')"
           />
           <text class="list-name">微信开放平台</text>
         </view>
@@ -176,7 +176,7 @@
 
     <su-fixed bottom placeholder bg="none">
       <view class="footer-box ss-p-20">
-        <button class="ss-rest-button logout-btn ui-Shadow-Main" @tap="onSubmit">保存</button>
+        <button class="ss-rest-button logout-btn" @tap="onSubmit">保存</button>
       </view>
     </su-fixed>
   </s-layout>
@@ -186,6 +186,9 @@
   import { computed, reactive, onBeforeMount } from 'vue';
   import sheep from '@/sheep';
   import { clone } from 'lodash';
+  import {
+  	onLoad
+  } from '@dcloudio/uni-app';
   import { showAuthModal } from '@/sheep/hooks/useModal';
   import FileApi from '@/sheep/api/infra/file';
   import UserApi from '@/sheep/api/member/user';
@@ -253,9 +256,6 @@
   // 绑定第三方账号
   async function bindThirdOauth() {
     let result = await sheep.$platform.useProvider('wechat').bind();
-    if (result) {
-      await getUserInfo();
-    }
   }
 
   // 解绑第三方账号
@@ -294,16 +294,16 @@
     // 个人信息
     const userInfo = await sheep.$store('user').getInfo();
     state.model = clone(userInfo);
-
+	
     // 获得社交用户的信息
     if (sheep.$platform.name !== 'H5') {
-      const result = await sheep.$platform.useProvider('wechat').getInfo();
+      let result = await sheep.$platform.useProvider('wechat').getInfo();
       state.thirdInfo = result || {};
     }
   };
-
-  onBeforeMount(() => {
-    getUserInfo();
+  onLoad(async (options) => {
+	getUserInfo();
+	setTimeout(getUserInfo,2000)
   });
 </script>
 

+ 1 - 2
pages/user/qrcode-share.vue

@@ -21,7 +21,7 @@
 			<button class="confirm-btn" @tap="onSavePoster">{{
 		    ['wechatOfficialAccount', 'H5'].includes(sheep.$platform.name)
 		      ? '长按图片保存'
-		      : '保存图片'
+		      : '长按图片保存'
 		  }}</button>
 			<!-- <button class="confirm-btn" @tap="showShareModal">分享</button> -->
 		</view>
@@ -74,7 +74,6 @@
 		// #ifdef APP-PLUS
 		poster.canvasId = 'canvasId-' + new Date().getTime();
 		// #endif
-		
 		const canvas = await useCanvas(poster, vm);
 		return canvas;
 	}

+ 57 - 10
pages/user/setting.vue

@@ -28,17 +28,24 @@
 					<uni-list-item
 						clickable
 						@tap="sheep.$router.go('/pages/user/address/list')"
-						title="收货地址管理"
+						title="实体收货地址管理"
 						showArrow
 						:border="false"
 					/>
 					<uni-list-item
+						clickable
+						@tap="sheep.$router.go('/pages/user/dummyAddress/list')"
+						title="虚拟收货地址管理"
+						showArrow
+						:border="false"
+					/>
+					<!-- <uni-list-item
 						clickable
 						@tap="sheep.$router.go('/pages/user/invoice/list')"
 						title="发票抬头管理"
 						showArrow
 						:border="false"
-					/>
+					/> -->
 					<uni-list-item
 						:clickable="!userInfo.mobile"
 						@tap="sheep.$router.go('/pages/user/address/list')"
@@ -47,20 +54,25 @@
 						:border="false"
 					>
 						<template v-slot:body>
-							<p style="width: 100%"
+							
+							<!-- <p style="width: 100%"
 								>实名认证&nbsp;&nbsp;&nbsp;&nbsp;{{
 									userInfo.mobile ? '已认证' : '未认证'
 								}}<span style="float: right">{{
 									userInfo.mobile ? '' : '未认证'
 								}}</span></p
-							>
+							> -->
+							<p style="width: 100%"
+								>实名认证&nbsp;&nbsp;&nbsp;&nbsp;  未认证
+								
+							</p>
 						</template>
 					</uni-list-item>
-					<uni-list-item title="推荐老师" :border="false">
+					<!-- <uni-list-item title="推荐老师" :border="false">
 						<template v-slot:body>
 							<p style="width: 100%">推荐老师&nbsp;&nbsp;&nbsp;&nbsp;xxx</p>
 						</template>
-					</uni-list-item>
+					</uni-list-item> -->
 					<uni-list-item
 						title="我的二维码"
 						clickable
@@ -86,7 +98,13 @@
 				</uni-list>
 			</view>
 		</uni-forms>
-
+		<su-fixed bottom placeholder>
+			<view class="ss-p-x-20 ss-p-b-40">
+				<button class="loginout-btn ss-reset-button" @tap="onLogout" v-if="isLogin">
+					退出登录
+				</button>
+			</view>
+		</su-fixed>
 		<!-- <su-fixed bottom placeholder bg="none">
 			<view class="footer-box ss-p-20">
 				<button class="ss-rest-button logout-btn ui-Shadow-Main" @tap="onSubmit">保存</button>
@@ -99,10 +117,11 @@
 	import { computed, reactive, onBeforeMount } from 'vue';
 	import sheep from '@/sheep';
 	import { clone } from 'lodash';
+	const isLogin = computed(() => sheep.$store('user').isLogin);
 	import { showAuthModal, showShareModal } from '@/sheep/hooks/useModal';
 	import FileApi from '@/sheep/api/infra/file';
 	import UserApi from '@/sheep/api/member/user';
-
+	import AuthUtil from '@/sheep/api/member/auth';
 	const state = reactive({
 		model: {}, // 个人信息
 		rules: {},
@@ -166,13 +185,41 @@
 			state.thirdInfo = result || {};
 		}
 	};
-
+	// 退出账号
+	function onLogout() {
+		uni.showModal({
+			title: '提示',
+			content: '确认退出账号?',
+			success: async function(res) {
+				if (!res.confirm) {
+					return;
+				}
+				const {
+					code
+				} = await AuthUtil.logout();
+				if (code !== 0) {
+					return;
+				}
+				sheep.$store('user').logout();
+				uni.removeStorageSync('linkId');
+				sheep.$router.go('/pages/index/user');
+			},
+		});
+	}
 	onBeforeMount(() => {
 		getUserInfo();
 	});
 </script>
 
 <style lang="scss" scoped>
+	.loginout-btn {
+		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		color:#fff;
+		width: 100%;
+		height: 80rpx;
+		border-radius: 40rpx;
+		font-size: 30rpx;
+	}
 	:deep() {
 		.uni-file-picker {
 			border-radius: 50%;
@@ -231,7 +278,7 @@
 	.logout-btn {
 		width: 710rpx;
 		height: 80rpx;
-		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		background: linear-gradient(90deg, #132b85, #193bb6);
 		border-radius: 40rpx;
 		font-size: 30rpx;
 		font-weight: 500;

+ 40 - 35
pages/user/wallet/ScoreLog.vue

@@ -1,42 +1,46 @@
 <template>
 	<!-- 积分确权 -->
-	<view class="model-box ss-flex-col">
-		<scroll-view class="list-box" scroll-y="true" @touchmove.stop>
-			<view v-if="state.pagination.total > 0" style="padding: 20rpx 0 0;">
-				<view class="list-item ss-flex ss-col-center ss-row-between "
-					v-for="(item,index)  in state.pagination.list" :key="item.id"
-					style="padding:0;padding: 20rpx 0;border-bottom: 1px solid #c4c4c4;">
-					<view class="ss-flex ss-col-center" style="width: 100%;">
-						<view class="ss-flex ss-m-t-10"
-							style="flex-direction: column;align-items: flex-start;width: 100%;">
-							<view class="name" style="width: 100%;"> {{ item.profitStatusName || '空' }}
-								<text style="float: right;" class="color-red"
-									:class="{'color-green':item.freezeAmount < 0}" v-if="isFreeze">{{item.freezeAmount > 0 ? '+'+points2point(item.freezeAmount):+points2point(item.freezeAmount)}}
-								</text>
-								<text style="float: right;" class="color-red"
-									:class="{'color-green':item.amount < 0}" v-else>{{item.amount > 0 ? '+'+points2point(item.amount):+points2point(item.amount)}}
-								</text>
-							</view>
-							<view class="time " style="width: 100%;">
-								{{sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM')}}
-								<!-- 冻结积分 -->
-								<text style="float: right;"
-									v-if="isFreeze">余额:{{ points2point(item.afterFreezeAmount)}}</text>
-								<!-- 已经拿到的积分 -->
-								<text style="float: right;" v-else>余额:{{points2point(item.afterAmount)}}</text>
+	<s-layout class="wallet-wrap" :bgStyle="{'backgroundColor':'#ffffff'}" title="" navbar="normal">
+
+		<view class="model-box ss-flex-col">
+			<scroll-view class="list-box" scroll-y="true" @touchmove.stop>
+				<view v-if="state.pagination.total > 0" style="padding: 20rpx;">
+					<view class="list-item ss-flex ss-col-center ss-row-between "
+						v-for="(item,index)  in state.pagination.list" :key="item.id"
+						style="padding:0;padding: 20rpx 0;border-bottom: 1px solid #c4c4c4;">
+						<view class="ss-flex ss-col-center" style="width: 100%;">
+							<view class="ss-flex ss-m-t-10"
+								style="flex-direction: column;align-items: flex-start;width: 100%;">
+								<view class="name" style="width: 100%;"> {{ item.profitStatusName || '空' }} {{item.username? "("+item.username+")" : ''}}
+								
+									<text v-if="isFreeze == 'true'" style="float: right;" class="color-red"
+										:class="{'color-green':item.freezeAmount < 0}" > 
+										{{item.freezeAmount > 0 ? '+'+points2point(item.freezeAmount):points2point(item.freezeAmount)}}
+									</text>
+									<text v-else style="float: right;" class="color-red"
+										:class="{'color-green':item.amount < 0}" >
+										{{item.amount > 0 ? '+'+points2point(item.amount): points2point(item.amount)}}
+									</text>
+								</view>
+								<view class="time " style="width: 100%;">
+									{{sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM')}}
+									<!-- 冻结积分 -->
+									<text style="float: right;"
+										v-if="isFreeze == 'true'">余额:{{ points2point(item.afterFreezeAmount)}}</text>
+									<text style="float: right;" v-else>余额:{{points2point(item.afterAmount)}}</text>
+								</view>
 							</view>
 						</view>
 					</view>
 				</view>
-			</view>
-			<s-empty v-else text="暂无数据" paddingTop="200" icon="/static/data-empty.png" />
-			<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
+				<s-empty v-else text="暂无数据" paddingTop="200" icon="/static/data-empty.png" />
+				<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
 					  contentdown: '点击加载更多',
 					}" @tap="onLoadMore(true)" @scrolltolower="onLoadMore(true)" />
-		</scroll-view>
-
-	</view>
+			</scroll-view>
 
+		</view>
+	</s-layout>
 </template>
 
 <script setup>
@@ -66,7 +70,8 @@
 	const sys_navBar = sheep.$platform.navbar;
 	const props = defineProps({
 		isFreeze: {
-			type: Boolean
+			type: String,
+			default: ''
 		}
 	})
 	const state = reactive({
@@ -112,7 +117,7 @@
 			return;
 		}
 		state.pagination.pageNo++;
-		getLogList(isFreeze);
+		getLogList(props.isFreeze);
 	}
 
 	onReachBottom(() => {
@@ -228,10 +233,10 @@
 
 
 	.list-box {
-		width: 600rpx;
-		padding: 0 30rpx;
+		// width: 600rpx;
+		// padding: 0 30rpx;
 		overflow-y: auto;
-		height: 80vh;
+		height: 100vh;
 
 		.list-item {
 

+ 268 - 0
pages/user/wallet/maxScoreLog.vue

@@ -0,0 +1,268 @@
+<template>
+	<!-- 积分确权 -->
+	<s-layout class="wallet-wrap" :bgStyle="{'backgroundColor':'#ffffff'}" title="" navbar="normal">
+
+		<view class="model-box ss-flex-col">
+			<scroll-view class="list-box" scroll-y="true" @touchmove.stop>
+				<view v-if="state.pagination.total > 0" style="padding: 20rpx;">
+					<view class="list-item ss-flex ss-col-center ss-row-between "
+						v-for="(item,index)  in state.pagination.list" :key="item.id"
+						style="padding:0;padding: 20rpx 0;border-bottom: 1px solid #c4c4c4;">
+						<view class="ss-flex ss-col-center" style="width: 100%;">
+							<view class="ss-flex ss-m-t-10"
+								style="flex-direction: column;align-items: flex-start;width: 100%;">
+								<view class="name" style="width: 100%;"> {{ item.profitStatusName || '空' }} {{item.username? "("+item.username+")" : ''}}
+									<text style="float: right;" class="color-red"
+										:class="{'color-green':item.maxAvailablePointsAmount < 0}"
+										>{{item.maxAvailablePointsAmount > 0 ? '+'+points2point(item.maxAvailablePointsAmount):+points2point(item.maxAvailablePointsAmount)}}
+									</text>
+								</view>
+								<view class="time " style="width: 100%;">
+									{{sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM')}}
+									<text style="float: right;" >余额:{{ points2point(item.afterMaxAvailablePointsAmount)}}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+				<s-empty v-else text="暂无数据" paddingTop="200" icon="/static/data-empty.png" />
+				<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
+					  contentdown: '点击加载更多',
+					}" @tap="onLoadMore(true)" @scrolltolower="onLoadMore(true)" />
+			</scroll-view>
+
+		</view>
+	</s-layout>
+</template>
+
+<script setup>
+	import sheep from '@/sheep';
+	import {
+		onLoad,
+		onReachBottom
+	} from '@dcloudio/uni-app';
+	import {
+		computed,
+		reactive
+	} from 'vue';
+	import {
+		points2point
+	} from '@/sheep/hooks/useGoods';
+	import _ from 'lodash';
+	import dayjs from 'dayjs';
+	import PointApi from '@/sheep/api/member/point';
+	import {
+		resetPagination
+	} from '@/sheep/util';
+	import ScoreApi from '@/sheep/api/distri/score';
+
+	const userWallet = computed(() => sheep.$store('user').userWallet);
+	const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
+	const userInfo = computed(() => sheep.$store('user').userInfo);
+	const sys_navBar = sheep.$platform.navbar;
+	const props = defineProps({
+		isFreeze: {
+			type: Boolean
+		}
+	})
+	const state = reactive({
+		currentTab: 0,
+		pagination: {
+			list: [],
+			total: 0,
+			pageSize: 10,
+			pageNo: 1,
+		},
+		loadStatus: '',
+		showModel: false,
+		showQueModel: false
+	});
+
+	async function getLogList(isFreeze) {
+		state.loadStatus = 'loading';
+		// isFreeze为true是冻结积分 isFreeze为false是已拿到的积分
+		let {
+			code,
+			data
+		} = await ScoreApi.getMaxScoreList({
+			pageNo: state.pagination.pageNo,
+			pageSize: state.pagination.pageSize,
+		});
+		if (code !== 0) {
+			return;
+		}
+		let list = _.concat(state.pagination.list, data.list);
+		state.pagination.list = list;
+		state.pagination.total = data.total;
+		state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
+	}
+
+	onLoad(() => {
+		getLogList(props.isFreeze);
+	});
+
+
+	function onLoadMore(isFreeze) {
+		if (state.loadStatus === 'noMore') {
+			return;
+		}
+		state.pagination.pageNo++;
+		getLogList(isFreeze);
+	}
+
+	onReachBottom(() => {
+		onLoadMore();
+	});
+</script>
+
+<style lang="scss" scoped>
+	.color-red {
+		color: red;
+	}
+
+	.color-green {
+		color: green;
+	}
+
+	.score-box {
+		margin: 20rpx;
+		border-radius: 20rpx;
+		padding-top: 100rpx;
+	}
+
+	.avatar-box {
+		width: 100rpx;
+		height: 100rpx;
+		border-radius: 50%;
+		overflow: hidden;
+
+		.avatar-img {
+			width: 100%;
+			height: 100%;
+		}
+	}
+
+	.value-box {
+		width: 100rpx;
+		height: 100rpx;
+		line-height: 100rpx;
+		text-align: center;
+		border-radius: 50%;
+		border: 2px solid #f6f6f6;
+	}
+
+	.btn {
+		width: 300rpx;
+		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		border-radius: 20rpx;
+		font-size: 30rpx;
+		font-weight: 500;
+		line-height: 80rpx;
+		color: $white;
+		position: relative;
+		z-index: 1;
+	}
+
+	.header-box {
+		width: 100%;
+		background: linear-gradient(180deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%) no-repeat;
+		background-size: 750rpx 100%;
+		padding: 0 0 120rpx 0;
+		box-sizing: border-box;
+
+		.score-box {
+			height: 100%;
+
+			.all-num {
+				font-size: 50rpx;
+				font-weight: bold;
+				color: #fff;
+				font-family: OPPOSANS;
+			}
+
+			.all-title {
+				font-size: 26rpx;
+				font-weight: 500;
+				color: #fff;
+			}
+
+			.cicon-help-o {
+				color: #fff;
+				font-size: 28rpx;
+			}
+		}
+	}
+
+	// 筛选
+	.filter-box {
+		height: 114rpx;
+		background-color: $bg-page;
+
+		.total-box {
+			font-size: 24rpx;
+			font-weight: 500;
+			color: $dark-9;
+		}
+
+		.date-btn {
+			background-color: $white;
+			line-height: 54rpx;
+			border-radius: 27rpx;
+			padding: 0 20rpx;
+			font-size: 24rpx;
+			font-weight: 500;
+			color: $dark-6;
+
+			.ss-seldate-icon {
+				font-size: 50rpx;
+				color: $dark-9;
+			}
+		}
+	}
+
+
+	.list-box {
+		// width: 600rpx;
+		// padding: 0 30rpx;
+		overflow-y: auto;
+		height: 100vh;
+
+		.list-item {
+
+			background: #fff;
+			// border-bottom: 1rpx solid #dfdfdf;
+			padding: 30rpx;
+
+			.name {
+				font-size: 28rpx;
+
+				font-weight: 500;
+				color: rgba(102, 102, 102, 1);
+				line-height: 28rpx;
+				// margin-bottom: 20rpx;
+			}
+
+			.time {
+				font-size: 24rpx;
+
+				font-weight: 500;
+				color: rgba(196, 196, 196, 1);
+				line-height: 24px;
+			}
+
+			.add {
+				font-size: 30rpx;
+
+				font-weight: 500;
+				color: #e6b873;
+			}
+
+			.minus {
+				font-size: 30rpx;
+
+				font-weight: 500;
+				color: $dark-3;
+			}
+		}
+	}
+</style>

+ 149 - 60
pages/user/wallet/score.vue

@@ -1,48 +1,66 @@
-<!-- 我的积分 -->
+<!-- 我的数字权益 -->
 <template>
-	<s-layout class="wallet-wrap" :bgStyle="{'backgroundColor':'#ffffff'}" title="我的积分" navbar="normal">
+	<s-layout class="wallet-wrap" :bgStyle="{'backgroundColor':'#ffffff'}" title="我的数字权益" navbar="normal">
 		<view class="score-box bg-white ss-flex-col ss-row-center ss-col-center">
-			<view class="ss-m-b-40 value-box " @tap="showModel()">
-				<view class="all-title ss-m-r-8">#</view>
+			<view class="ss-m-b-10  circle value-box ss-flex ss-row-center" :style="circleStyle">
+				<view >数字 <br> 权益</view>
 			</view>
-			<view class="ss-m-b-40 ss-font-40">
-				<text class="all-title ss-m-r-8">#{{ points2point(userWallet.integralDO.currentQuota) }}</text>
-			</view>
-			<view class="ss-m-b-40 ss-font-32 text-center">
-				<view class="all-title ss-m-r-8 ss-m-b-10 ">
-					当前可兑换积分:#{{ points2point(userWallet.integralDO.currentQuota) }}</view>
-				<view class="all-title ss-m-r-8" style="color: var(--ui-BG-Main)" @tap="showQueModel()">
-					待确权积分:#{{points2point(userWallet.integralDO.freezeQuota)}}</view>
-			</view>
-			<view class="ss-m-b-80">
-				<view class="all-title ss-m-r-8 ss-m-b-10">可兑换积分得计算规则</view>
-				<view class="all-title ss-m-r-8 text-center">[点击查看说明]</view>
+
+			<view class="ss-m-b-30 ss-font-40"  :style="{color:percentageColor}">
+				<text class="all-title ss-m-r-8">{{ points2point(userWallet.integralDO.currentQuota) }}</text>
 			</view>
 			<view class="ss-m-b-40">
 				<view class="all-title ss-m-r-8">
-					<button class="btn ss-reset-button ui-Shadow-Main"
-						@tap="sheep.$router.go('/pages/user/wallet/scoreToMoney')">
+					<!--  -->
+					<button class="btn ss-reset-button" @tap="sheep.$router.go('/pages/goods/list', { categoryId: 98 })">
 						兑换
 					</button>
 				</view>
 			</view>
-			<!-- <view class="ss-m-b-40">
-				<view class="all-title ss-m-r-8">
-					<button class="btn ss-reset-button ui-Shadow-Main">
-						代购NFR
-					</button>
-				</view>
-			</view> -->
+			<!-- 分割线 -->
+			<view style="width: 100%;height: 20rpx;background-color: #ececec;"></view>
+			<uni-list :border="false" class="ss-p-t-10 ss-w-100">
+				<uni-list-item clickable @tap="sheep.$router.go('/pages/user/wallet/maxScoreLog')"
+					title="当前可获得峰值" showArrow :border="false">
+					<template v-slot:body>
+						<p style="width: 100%">
+							当前可获得峰值:{{ points2point(userWallet.integralDO.currentQuota) }}/{{ points2point(userWallet.integralDO.highQuota) }}
+						</p>
+					</template>
+				</uni-list-item>
+				<uni-list-item clickable @tap="sheep.$router.go('/pages/user/wallet/ScoreLog', {isFreeze: true})"
+					title="待确权" showArrow :border="false">
+					<template v-slot:body>
+						<p style="width: 100%">待确权:{{points2point(userWallet.integralDO.freezeQuota)}}</p>
+					</template>
+				</uni-list-item>
+				<uni-list-item clickable @tap="sheep.$router.go('/pages/user/wallet/ScoreLog',{isFreeze: false})"
+					title="数字权益来源记录" showArrow :border="false">
+					<template v-slot:body>
+						<p style="width: 100%">数字权益来源记录</p>
+					</template>
+				</uni-list-item>
+				<uni-list-item clickable @tap="state.showModel = true" title="数字权益计算规则" :border="false">
+					<template v-slot:body>
+						<p style="width: 100%">数字权益计算规则</p>
+					</template>
+				</uni-list-item>
+			</uni-list>
+
 		</view>
-		<!-- 积分来源 -->
+		<!-- 数字权益计算规则 -->
 		<su-popup :show="state.showModel" type="center" round="10" :isMaskClick="false" showClose @close="close">
-			<ScoreLog :isFreeze="false"/>
-		</su-popup>
-		
-		<!-- 积分确权 -->
-		<su-popup :show="state.showQueModel" type="center" round="10" :isMaskClick="false" showClose @close="close">
-			<ScoreLog :isFreeze="true"/>
+			<view class="head-nav">
+				<view :class="state.navIndex==0?'activite':''" class="ss-m-l-20" @click="checkIndex(0)">
+					数字权益计算规则
+				</view>
+			</view>
+			<scroll-view class="scroll-view_H" scroll-y="true">
+
+				<richtext title="数字权益计算规则" type='tab' />
+			</scroll-view>
 		</su-popup>
+
 	</s-layout>
 
 </template>
@@ -67,7 +85,9 @@
 		resetPagination
 	} from '@/sheep/util';
 	import ScoreApi from '@/sheep/api/distri/score';
+	
 	import ScoreLog from './ScoreLog'
+	import richtext from '@/pages/public/richtext'
 	
 	const userWallet = computed(() => sheep.$store('user').userWallet);
 	const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
@@ -83,24 +103,42 @@
 			pageNo: 1,
 		},
 		loadStatus: '',
-		showModel:false,
-		showQueModel:false
+		showModel: false,
+
 	});
 
-	function close(){
+	function close() {
 		state.showModel = false;
-		state.showQueModel = false;
-	}
-	function showModel(){
-		state.showModel = true;
-		
-	}
-	function showQueModel(){
-		state.showQueModel = true;
 	}
+	const pointsPercentage = computed(() => {
+		const currentQuota = parseFloat(points2point(userWallet.value.integralDO.currentQuota))
+		const highQuota =parseFloat(points2point(userWallet.value.integralDO.highQuota))
+		if (currentQuota > highQuota) {
+			return 100;
+		} else {
+			const percentage = (currentQuota / highQuota) * 100;
+			
+			return Math.min(percentage, 100); // 确保百分比不会超过100
+		}
+	});
+	const percentageColor = computed(() => {
+		if (pointsPercentage.value>=90) {
+			return '#fe0000';
+		} else if(pointsPercentage.value>=75){
+			return '#d8b800';
+		} else {
+			return '#0c912f';
+		}
+	});
+	const circleStyle = computed(() => {
+	      return {
+	        // background: `conic-gradient(${percentageColor.value} ${pointsPercentage.value}%, #ddd ${pointsPercentage.value}%)`
+	        background: percentageColor.value
+	      };
+	    });
 	async function getLogList(isFreeze) {
 		state.loadStatus = 'loading';
-		// isFreeze为true是冻结积分 isFreeze为false是已拿到的积分
+		// isFreeze为true是冻结数字权益 isFreeze为false是已拿到的数字权益
 		let {
 			code,
 			data
@@ -117,12 +155,6 @@
 		state.pagination.total = data.total;
 		state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
 	}
-
-	onLoad(() => {
-
-	});
-
-
 	function onLoadMore(isFreeze) {
 
 		if (state.loadStatus === 'noMore') {
@@ -139,14 +171,71 @@
 </script>
 
 <style lang="scss" scoped>
-	.color-red{
+	.circle {
+		position: relative;
+		width: 100px;
+		height: 100px;
+		border-radius: 50%;
+		
+	}
+
+	.circle::before {
+		content: '';
+		position: absolute;
+		top: 10px;
+		left: 10px;
+		right: 10px;
+		bottom: 10px;
+		border-radius: 50%;
+		background-color: #fff;
+	}
+
+	.circle view {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		font-size: 14px;
+		font-weight: bold;
+	}
+
+
+
+	.scroll-view_H {
+		width: 600rpx;
+		height: 700rpx;
+		padding: 20rpx;
+	}
+
+	.head-nav {
+		margin: 20rpx auto;
+		display: flex;
+		align-items: center;
+		box-sizing: border-box;
+		color:  var(--ui-BG-Main);
+
+	}
+
+	.head-nav>view {
+		padding-bottom: 10rpx;
+		border-bottom: 4rpx solid  var(--ui-BG-Main);
+	}
+
+	.uni-list-item {
+		margin: 0 20rpx;
+		padding: 10rpx 0;
+		border-bottom: 1px solid #d8d8d9;
+	}
+
+	.color-red {
 		color: red;
 	}
-	.color-green{
+
+	.color-green {
 		color: green;
 	}
+
 	.score-box {
-		margin: 20rpx;
 		border-radius: 20rpx;
 		padding-top: 100rpx;
 	}
@@ -156,7 +245,6 @@
 		height: 100rpx;
 		border-radius: 50%;
 		overflow: hidden;
-
 		.avatar-img {
 			width: 100%;
 			height: 100%;
@@ -164,16 +252,15 @@
 	}
 
 	.value-box {
-		width: 100rpx;
-		height: 100rpx;
-		line-height: 100rpx;
+		width: 150rpx;
+		height: 150rpx;
 		text-align: center;
 		border-radius: 50%;
-		border: 2px solid #f6f6f6;
+		font-weight: bold;
 	}
 
 	.btn {
-		width: 300rpx;
+		width: 250rpx;
 		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
 		border-radius: 20rpx;
 		font-size: 30rpx;
@@ -240,9 +327,11 @@
 			}
 		}
 	}
-	.model-box{
+
+	.model-box {
 		height: 50vh;
 	}
+
 	.list-box {
 		width: 500rpx;
 		padding: 0 30rpx;

+ 23 - 22
pages/user/wallet/team.vue

@@ -7,12 +7,12 @@
 				<text style="float: right;">共{{state.teamCount}}人</text>
 			</view>
 
-			<view class="list-box" style="width: 100%;padding: 0;height: calc(100vh - 5.5rem) ;">
+			<view class="list-box" style="width: 100%;padding: 0;height: calc(100vh - 7.5rem) ;">
 				<!-- 推荐人 -->
 				<view>
 					<view class="list-item ss-flex ss-col-center ss-row-between "
 						style="padding-top: 30rpx; padding-bottom: 0;">
-						<view class="ss-flex ss-col-center" style="width: 100%;">
+						<view class="ss-flex ss-col-center" style="width: 100%;border-bottom: 1px solid #ededed;padding-bottom: 30rpx">
 							<view>
 								&nbsp;&nbsp;
 							</view>
@@ -23,14 +23,13 @@
 							<view class="ss-flex ss-m-t-10"
 								style="flex-direction: column;align-items: flex-start;width: calc(100% - 5.5rem);">
 								<view class="name" style="width: 100%;">
-										<text style="width:40%;display: inline-block;">{{ state.ancestor.ancNickName  }}</text> 
-										<text >推荐人</text>
-										
+										<text style="width:60%;display: inline-block;">{{ state.ancestor.username ||'昵称:'+state.ancestor.descNickName  }}</text> 											<text class="time" style="float: right;color: #666666">贡献值:{{points2point(state.ancestor.residueSocial)}}</text>
+
 								</view>
-								<view class="time " style="width: 100%;">
-									{{state.ancestor.socialStatusLevel || "等级1"}}
+								<view class="time" style="width: 100%;color: #999;">
+									<text>{{state.ancestor.socialStatusLevel || "等级1" }}</text> / <text>推荐人</text>
 									<text
-										style="float: right;">{{sheep.$helper.timeFormat(state.ancestor.createTime, 'yyyy-mm-dd')}}</text>
+										style="float: right;">团队:{{state.ancestor.descendantsCount}}人</text>
 								</view>
 							</view>
 						</view>
@@ -43,28 +42,26 @@
 							<view class="list-item ss-flex ss-col-center ss-row-between "
 								v-for="(item,index)  in state.descendants.list" :key="item.id"
 								style="padding-top: 30rpx ;padding-bottom: 0;">
-								<view class="ss-flex ss-col-center" style="width: 100%;">
+								<view class="ss-flex ss-col-center" style="width: 100%;border-bottom: 1px solid #ededed;padding-bottom: 30rpx">
 									<view>
 										{{item.sort}}
 									</view>
 									<!-- 头像 -->
 									<view class="avatar-box ss-m-x-20">
 										<image class="avatar-img" :src="
-									   item.avatar || sheep.$url.static('/static/img/shop/default_avatar.png')" mode="aspectFill"></image>
+									   item.avatar || sheep.$url.static('/static/images/default_avatar.png')" mode="aspectFill"></image>
 									</view>
 									<view class="ss-flex ss-m-t-10"
 										style="flex-direction: column;align-items: flex-start;width: calc(100% - 5.5rem);">
 										<view class="name" style="width: 100%;">
-											<text style="width:40%;display: inline-block;"> {{ item.descNickName || '空' }}</text>
-											<text >{{item.depth == 1?'直推人':''}}</text>
-											<text style="float: right;">{{item.descendantsCount}}</text>
-
+											<text style="width:60%;display: inline-block;"> {{ item.username || '昵称:'+ item.descNickName}}</text>
+											<text class="time" style="float: right;color: #666666;">贡献值:{{points2point(item.residueSocial)}}</text>
 										</view>
 										
-										<view class="time " style="width: 100%;">
-											{{item.socialStatusLevel}}
-											<text
-												style="float: right;">{{sheep.$helper.timeFormat(item.createTime, 'yyyy-mm-dd')}}</text>
+										<view class="time" style="width: 100%;color: #9992">
+											{{item.socialStatusLevel}} / <text >{{item.depth == 1?'直推人':''}}</text>
+											<text style="float: right;">团队:{{item.descendantsCount}}人</text>
+											
 										</view>
 									</view>
 								</view>
@@ -98,7 +95,9 @@
 	import {
 		resetPagination
 	} from '@/sheep/util';
-
+	import {
+		points2point
+	} from '@/sheep/hooks/useGoods';
 	const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
 	const userInfo = computed(() => sheep.$store('user').userInfo);
 	const sys_navBar = sheep.$platform.navbar;
@@ -291,11 +290,13 @@
 			padding: 30rpx;
 
 			.name {
-				font-size: 28rpx;
-
+				font-size: 30rpx;
 				font-weight: 500;
 				color: rgba(102, 102, 102, 1);
-				line-height: 28rpx;
+				line-height: 30rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
 				// margin-bottom: 20rpx;
 			}
 

+ 11 - 1
sheep/api/distri/score.js

@@ -1,7 +1,6 @@
 import request from '@/sheep/request';
 
 const ScoreApi = {
-  // 查询商品linkId
   getScoreApi: (params) => {
     return request({
       url: '/distri/pt-profit-log/page',
@@ -13,5 +12,16 @@ const ScoreApi = {
       },
     });
   },
+  getMaxScoreList: (params) => {
+    return request({
+      url: '/distri/pt-profit-log/getMaxAmountPage',
+      method: 'GET',
+      params,
+      custom: {
+        showLoading: false,
+        showError: false,
+      },
+    });
+  },
 };
 export default ScoreApi;

+ 8 - 6
sheep/api/member/address.js

@@ -2,10 +2,11 @@ import request from '@/sheep/request';
 
 const AddressApi = {
   // 获得用户收件地址列表
-  getAddressList: () => {
+  getAddressList: (addressType = 1) => {
     return request({
       url: '/member/address/list',
-      method: 'GET'
+      method: 'GET',
+	  params: { addressType }
     });
   },
   // 创建用户收件地址
@@ -33,19 +34,20 @@ const AddressApi = {
     });
   },
   // 获得用户收件地址
-  getAddress: (id) => {
+  getAddress: (id,addressType = 1) => {
+	  console.log('123123',addressType)
     return request({
       url: '/member/address/get',
       method: 'GET',
-      params: { id }
+      params: { id ,addressType}
     });
   },
   // 删除用户收件地址
-  deleteAddress: (id) => {
+  deleteAddress: (id,addressType = 1) => {
     return request({
       url: '/member/address/delete',
       method: 'DELETE',
-      params: { id }
+      params: { id,addressType }
     });
   },
 };

+ 185 - 138
sheep/api/member/auth.js

@@ -1,143 +1,190 @@
 import request from '@/sheep/request';
 
 const AuthUtil = {
-  // 使用手机 + 密码登录
-  login: (data) => {
-    return request({
-      url: '/member/auth/login',
-      method: 'POST',
-      data,
-      custom: {
-        showSuccess: true,
-        loadingMsg: '登录中',
-        successMsg: '登录成功',
-      },
-    });
-  },
-  // 使用手机 + 验证码登录
-  smsLogin: (data) => {
-    return request({
-      url: '/member/auth/sms-login',
-      method: 'POST',
-      data,
-      custom: {
-        showSuccess: true,
-        loadingMsg: '登录中',
-        successMsg: '登录成功',
-      },
-    });
-  },
-  // 发送手机验证码
-  sendSmsCode: (mobile, scene) => {
-    return request({
-      url: '/member/auth/send-sms-code',
-      method: 'POST',
-      data: {
-        mobile,
-        scene,
-      },
-      custom: {
-        loadingMsg: '发送中',
-        showSuccess: true,
-        successMsg: '发送成功',
-      },
-    });
-  },
-  // 微信公众号首次登录校验手机
-  OfficialEnterLogin: (reqVO,loginReqVO) => {
-    return request({
-      url: '/member/auth/social-login-validate-sms-code',
-      method: 'POST',
-      data: {
-		reqVO,
-        loginReqVO
-      },
-    });
-  },
-  // 登出系统
-  logout: () => {
-    return request({
-      url: '/member/auth/logout',
-      method: 'POST',
-    });
-  },
-  // 刷新令牌
-  refreshToken: (refreshToken) => {
-    return request({
-      url: '/member/auth/refresh-token',
-      method: 'POST',
-      params: {
-        refreshToken
-      },
-      custom: {
-        loading: false, // 不用加载中
-        showError: false, // 不展示错误提示
-      },
-    });
-  },
-  // 社交授权的跳转
-  socialAuthRedirect: (type, redirectUri) => {
-    return request({
-      url: '/member/auth/social-auth-redirect',
-      method: 'GET',
-      params: {
-        type,
-        redirectUri,
-      },
-      custom: {
-        showSuccess: true,
-        loadingMsg: '登陆中',
-      },
-    });
-  },
-  // 社交快捷登录
-  socialLogin: (type, code, state) => {
-    return request({
-      url: '/member/auth/social-login',
-      method: 'POST',
-      data: {
-        type,
-        code,
-        state,
-      },
-      custom: {
-        showSuccess: true,
-        loadingMsg: '登陆中',
-      },
-    });
-  },
-  // 微信小程序的一键登录
-  weixinMiniAppLogin: (phoneCode, loginCode, state) => {
-    return request({
-      url: '/member/auth/weixin-mini-app-login',
-      method: 'POST',
-      data: {
-        phoneCode,
-        loginCode,
-        state
-      },
-      custom: {
-        showSuccess: true,
-        loadingMsg: '登陆中',
-        successMsg: '登录成功',
-      },
-    });
-  },
-  // 创建微信 JS SDK 初始化所需的签名
-  createWeixinMpJsapiSignature: (url) => {
-    return request({
-      url: '/member/auth/create-weixin-jsapi-signature',
-      method: 'POST',
-      params: {
-        url
-      },
-      custom: {
-        showError: false,
-        showLoading: false,
-      },
-    })
-  },
-  //
+	// 使用手机 + 密码登录
+	login: (data) => {
+		return request({
+			url: '/member/auth/login',
+			method: 'POST',
+			data,
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登录中',
+				successMsg: '登录成功',
+			},
+		});
+	},
+	// 使用手机 + 验证码登录
+	smsLogin: (data) => {
+		return request({
+			url: '/member/auth/sms-login',
+			method: 'POST',
+			data,
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登录中',
+				successMsg: '登录成功',
+			},
+		});
+	},
+	
+	// 账号注册
+	register: (data) => {
+		return request({
+			url: '/member/auth/sms-register',
+			method: 'POST',
+			data,
+			custom: {
+				showSuccess: true,
+				loadingMsg: '注册中',
+				successMsg: '注册成功',
+			},
+		});
+	},
+	// 注册校验用户名是否重复
+	verifyUsername: (username) => {
+		return request({
+			url: '/member/user/verifyUsername?username='+username,
+			method: 'GET',
+		});
+	},
+	// 发送手机验证码
+	sendSmsCode: (mobile, scene) => {
+		return request({
+			url: '/member/auth/send-sms-code',
+			method: 'POST',
+			data: {
+				mobile,
+				scene,
+			},
+			custom: {
+				loadingMsg: '发送中',
+				showSuccess: true,
+				successMsg: '发送成功',
+			},
+		});
+	},
+	// 微信公众号登录选择账号登录
+	selectUsernameLogin: (data) => {
+		return request({
+			url: '/member/auth/select-username-login',
+			method: 'POST',
+			data,
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登录中',
+				successMsg: '登录成功',
+			},
+		});
+	},
+	// 微信公众号注册
+	officialRegister: (data) => {
+		return request({
+			url: '/member/auth/social-register',
+			method: 'POST',
+			data,
+			custom: {
+				showSuccess: true,
+				loadingMsg: '注册中',
+				successMsg: '注册成功',
+			},
+		});
+	},
+	// 微信公众号首次登录校验手机
+	OfficialEnterLogin: (reqVO, registerReqVO) => {
+		return request({
+			url: '/member/auth/social-login-validate-sms-code',
+			method: 'POST',
+			data: {
+				reqVO,
+				registerReqVO
+			},
+		});
+	},
+	// 登出系统
+	logout: () => {
+		return request({
+			url: '/member/auth/logout',
+			method: 'POST',
+		});
+	},
+	// 刷新令牌
+	refreshToken: (refreshToken) => {
+		return request({
+			url: '/member/auth/refresh-token',
+			method: 'POST',
+			params: {
+				refreshToken
+			},
+			custom: {
+				loading: false, // 不用加载中
+				showError: false, // 不展示错误提示
+			},
+		});
+	},
+	// 社交授权的跳转
+	socialAuthRedirect: (type, redirectUri) => {
+		return request({
+			url: '/member/auth/social-auth-redirect',
+			method: 'GET',
+			params: {
+				type,
+				redirectUri,
+			},
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登陆中',
+			},
+		});
+	},
+	// 社交快捷登录
+	socialLogin: (type, code, state) => {
+		return request({
+			url: '/member/auth/social-login',
+			method: 'POST',
+			data: {
+				type,
+				code,
+				state,
+			},
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登陆中',
+			},
+		});
+	},
+	// 微信小程序的一键登录
+	weixinMiniAppLogin: (phoneCode, loginCode, state) => {
+		return request({
+			url: '/member/auth/weixin-mini-app-login',
+			method: 'POST',
+			data: {
+				phoneCode,
+				loginCode,
+				state
+			},
+			custom: {
+				showSuccess: true,
+				loadingMsg: '登陆中',
+				successMsg: '登录成功',
+			},
+		});
+	},
+	// 创建微信 JS SDK 初始化所需的签名
+	createWeixinMpJsapiSignature: (url) => {
+		return request({
+			url: '/member/auth/create-weixin-jsapi-signature',
+			method: 'POST',
+			params: {
+				url
+			},
+			custom: {
+				showError: false,
+				showLoading: false,
+			},
+		})
+	},
+	//
 };
 
-export default AuthUtil;
+export default AuthUtil;

+ 1 - 1
sheep/api/member/signin.js

@@ -28,7 +28,7 @@ const SignInApi = {
 	// 签到
 	createSignInRecord: () => {
 		return request({
-			url: '/member/sign-in/record/create',
+			url: '/distri/user-sign-in-log/create',
 			method: 'POST',
 		});
 	},

+ 8 - 0
sheep/api/pay/order.js

@@ -9,6 +9,14 @@ const PayOrderApi = {
       params: { id }
     });
   },
+  // 获得支付后的订单条件
+  getByStatus: (id) => {
+    return request({
+      url: '/trade/order/getPayOrderByStatus',
+      method: 'GET',
+      params: { id }
+    });
+  },
   getPayOrder: (tradeOrderId) => {
     return request({
       url: '/trade/order/getPayOrder',

+ 10 - 0
sheep/api/product/favorite.js

@@ -34,6 +34,16 @@ const FavoriteApi = {
       },
     });
   },
+  // 添加商品收藏时调用的加身价
+  createCollectBefore: (spuId) => {
+    return request({
+      url: '/distri/user-collect-before/create',
+      method: 'POST',
+      data: {
+        productSpuId:spuId,
+      }
+    });
+  },
   // 取消商品收藏
   deleteFavorite: (spuId) => {
     return request({

+ 14 - 0
sheep/api/system/voice.js

@@ -0,0 +1,14 @@
+import request from '@/sheep/request';
+
+const VoiceApi = {
+  // 语音转文字
+  getVoiceToText: () => {
+    return request({
+      url: '/voice2text',
+      method: 'POST'
+    });
+  },
+ 
+};
+
+export default VoiceApi;

+ 19 - 5
sheep/components/s-address-item/s-address-item.vue

@@ -28,7 +28,7 @@
     <slot>
       <button class="ss-reset-button edit-btn" @tap.stop="onEdit">
         <view class="edit-icon ss-flex ss-row-center ss-col-center">
-          <image :src="sheep.$url.static('/static/img/shop/user/address/edit.png')" />
+          <image :src="sheep.$url.static('/static/images/edit.png')" />
         </view>
       </button>
     </slot>
@@ -57,12 +57,26 @@
       type: Boolean,
       defult: true,
     },
+	spuType:{
+		type:Number,
+	}
   });
-
+	
   const onEdit = () => {
-    sheep.$router.go('/pages/user/address/edit', {
-      id: props.item.id,
-    });
+	  // 虚拟商品去虚拟地址
+	  if(props.spuType == 0){
+		  sheep.$router.go('/pages/user/dummyAddress/edit', {
+		    id: props.item.id,
+			
+		  });
+	  }else{
+		sheep.$router.go('/pages/user/address/edit', {
+		  id: props.item.id,
+		});
+	  }
+    
+	
+	
   };
 </script>
 

+ 6 - 31
sheep/components/s-auth-modal/components/account-login.vue

@@ -1,36 +1,16 @@
 <!-- 账号密码登录 accountLogin  -->
 <template>
 	<view>
-		<!-- 标题栏 -->
-		<!-- <view class="head-box  ss-flex-col">
-      <view class="ss-flex ss-m-b-20">
-        
-        <view class="head-title ss-m-r-40 head-title-animation">账号登录</view>
-		<view class="head-title-active head-title-line" @tap="showAuthModal('smsLogin')">
-		  短信登录
-		</view>
-      </view>
-      <view class="head-subtitle">如果未设置过密码,请点击忘记密码</view>
-    </view> -->
-
 		<!-- 表单项 -->
 		<uni-forms ref="accountLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind"
 			labelWidth="140" labelAlign="center" class="loginUniForm">
-			<uni-forms-item name="mobile" label="账号" class="loginUniFormItem">
-				<uni-easyinput placeholder="请输入账号" v-model="state.model.mobile" :inputBorder="false">
-					<!-- <template v-slot:right>
-            <button class="ss-reset-button forgot-btn" @tap="showAuthModal('resetPassword')">
-              忘记密码
-            </button>
-          </template> -->
+			<uni-forms-item name="username" label="用户名" class="loginUniFormItem">
+				<uni-easyinput placeholder="请输入用户名" v-model="state.model.username" :inputBorder="false">
 				</uni-easyinput>
 			</uni-forms-item>
 
 			<uni-forms-item name="password" label="密码" class="loginUniFormItem">
 				<uni-easyinput type="password" placeholder="请输入密码" v-model="state.model.password" :inputBorder="false">
-					<!-- <template v-slot:right>
-            <button class="ss-reset-button login-btn-start" @tap="accountLoginSubmit">登录</button>
-          </template> -->
 				</uni-easyinput>
 			</uni-forms-item>
 		</uni-forms>
@@ -52,7 +32,7 @@
 	} from 'vue';
 	import sheep from '@/sheep';
 	import {
-		mobile,
+		username,
 		password
 	} from '@/sheep/validate/form';
 	import {
@@ -75,18 +55,17 @@
 	// 数据
 	const state = reactive({
 		model: {
-			mobile: '', // 账号
+			username: '', // 账号
 			password: '', // 密码
 		},
 		rules: {
-			mobile,
+			username,
 			password,
 		},
 	});
 
 	// 账号登录
 	async function accountLoginSubmit() {
-		
 		// 表单验证
 		const validate = await unref(accountLoginRef)
 			.validate()
@@ -94,16 +73,12 @@
 				console.log('error: ', error);
 			});
 		if (!validate) return;
-		
 		// 同意协议
 		if (!props.agreeStatus) {
 			emits('onConfirm', true)
-			// onConfirm(true)
-			// console.log("没勾选",protocol)
 			sheep.$helper.toast('请勾选同意');
 			return;
 		}
-
 		// 提交数据
 		const {
 			code,
@@ -121,7 +96,7 @@
 
 
 	.login-btn-start {
-		background: #55b774;
+		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
 		width: 60%;
 		height: 80rpx;
 		font-size: 32rpx;

+ 131 - 0
sheep/components/s-auth-modal/components/phone-international-input.vue

@@ -0,0 +1,131 @@
+<!-- 国际手机输入组件 -->
+<template>
+	<picker mode="selector" :range="country.map(item => item.chinese_name +' +'+ item.phone_code)" :value="selectedIndex"
+		@change="pickChange" style="float: left;height: 100%;width: 110rpx;display: flex;align-items: center;">
+		<view>+{{selectedCode}}
+			<image src="@/static/icon/select-icon.png" style="width: 20rpx;height: 20rpx;" />
+		</view>
+	</picker>
+	<uni-easyinput placeholder="请输入手机号" v-model="state.model.mobile"  @input="verifyMobile" :inputBorder="false" type="number" 	style="float: left;width: calc(100% - 110rpx);">
+		<template v-slot:right>
+			<button class="ss-reset-button code-btn code-btn-start" :disabled="!verifyUsername || selectedCode != 86"
+				:class="{ 'disabled': !verifyUsername || selectedCode != 86}" @tap="getSmsCode('smsLogin', state.model.mobile)">
+				{{ getSmsTimer('smsLogin') }}
+			</button>
+		</template>
+	</uni-easyinput>
+
+</template>
+
+<script setup>
+	import {
+		ref,
+		reactive,
+		unref,
+		computed
+	} from 'vue';
+	import sheep from '@/sheep';
+	import {
+		getSmsCode,
+		getSmsTimer
+	} from '@/sheep/hooks/useModal';
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import countryData from '@/sheep/libs/country.json';
+	import {parsePhoneNumberFromString,AsYouType  } from 'libphonenumber-js';
+	import parseMobile from 'libphonenumber-js/mobile'
+
+	const country = ref(countryData);
+	const selectedCode = ref('');
+	const selectedCountryCode = ref('');
+	const selectedIndex = ref(0);
+	// 查找中国在 country 数组中的索引
+	const findIndexByCode = (code) => {
+		return country.value.findIndex(item => item.phone_code == code);
+	};
+	// 更新选中的国家代码和索引
+	const pickChange = (e) => {
+		selectedIndex.value = e.detail.value;
+		selectedCode.value = country.value[selectedIndex.value].phone_code;
+		selectedCountryCode.value = country.value[selectedIndex.value].country_code;
+	};
+
+	// 设置默认选中中国
+	onLoad(() => {
+		const chinaIndex = findIndexByCode('86');
+		if (chinaIndex !== -1) {
+			selectedIndex.value = chinaIndex;
+			selectedCode.value = country.value[chinaIndex].phone_code;
+			selectedCountryCode.value = country.value[chinaIndex].country_code;
+		}
+	});
+	const props = defineProps({
+		verifyUsername: {
+			type: Boolean
+		}
+	});
+	const emits = defineEmits(['input']);
+	const verifyMobile = (e) => {
+		// console.log(e.detail.value)
+		const phone = e;
+		if(phone == ''){
+			emits('input',phone,'请输入手机号')
+		} else {
+			try{
+				const phoneParseMobile = parseMobile(phone, selectedCountryCode.value);
+				if(phoneParseMobile.isValid()){
+					emits('input',phone,'')
+				}else{
+					emits('input',phone,'手机号码格式不正确')
+				}
+			}catch(e){
+				// console.log(e)
+			}
+		}
+	}
+	// 账号注册数据
+	const state = reactive({
+		codeText: '获取验证码',
+		model: {
+			mobile: '', // 手机号
+		}
+	});
+</script>
+<style lang="scss" scoped>
+	@import '../index.scss';
+	.code-btn-start {
+		color: var(--ui-BG-Main);
+		border: 1px solid var(--ui-BG-Main);
+	}
+
+	.disabled {
+		border: 1px solid #f7f7f7;
+	}
+
+
+
+	.loginUniForm {
+		border: 1rpx solid #d6d6d6;
+		padding: 10rpx 15rpx;
+		border-radius: 10rpx;
+	}
+
+	.loginUniFormItem {
+		border-bottom: 1rpx solid #d6d6d6;
+		padding-bottom: 10rpx;
+	}
+
+	.loginUniFormItem:last-child {
+		border-bottom: none;
+		padding-top: 10rpx;
+	}
+
+	::v-deep .loginUniFormItem .uni-forms-item__inner {
+		padding-bottom: 0;
+	}
+
+	::v-deep .loginUniFormItem .uni-error-message {
+		bottom: -20rpx;
+	}
+</style>

+ 203 - 0
sheep/components/s-auth-modal/components/register.vue

@@ -0,0 +1,203 @@
+<!-- 短信注册  -->
+<template>
+	<view>
+		<!-- 表单项 -->
+		<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind" labelWidth="140"
+			labelAlign="center" class="loginUniForm">
+			<uni-forms-item name="username" label="用户名" class="loginUniFormItem" :error-message="state.usernameErrorMsg">
+				<uni-easyinput placeholder="请输入用户名" v-model="state.model.username" :inputBorder="false" :clearable="false" @blur="verifyUsername">
+				<template v-slot:right>
+					<view v-if="!state.verifyUsername" class="icon"><image style :src="sheep.$url.static('/static/images/shibai.png')" /></view>
+					<view v-else class="icon"> <image :src="sheep.$url.static('/static/images/chenggong.png')" /></view>
+				</template>
+				</uni-easyinput>
+			</uni-forms-item>
+			<uni-forms-item name="password" label="密码" class="loginUniFormItem">
+				<uni-easyinput type="password" placeholder="请输入密码" v-model="state.model.password" :inputBorder="false">
+				</uni-easyinput>
+			</uni-forms-item>
+			
+			<uni-forms-item name="mobile" label="手机号" class="mobile loginUniFormItem ss-p-t-10" :error-message="state.mobileErrorMsg">
+				<phoneInternationalInput :verify-username="state.verifyUsername" @input="mobileInput"/>
+			</uni-forms-item>
+
+			<uni-forms-item name="code" label="验证码" class="loginUniFormItem">
+				<uni-easyinput placeholder="请输入验证码" v-model="state.model.code" :inputBorder="false" type="number"
+					maxlength="4">
+				</uni-easyinput>
+			</uni-forms-item>
+		</uni-forms>
+		<view style="display: flex;justify-content: space-between;margin-top: 20rpx;">
+			<!-- <button class="ss-reset-button forgot-btn" @tap="showAuthModal('resetPassword')">
+		  忘记密码
+		</button> -->
+			<button class="ss-reset-button login-btn-start" @tap="registerSubmit"> 注册 </button>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref,
+		reactive,
+		unref,
+		computed
+	} from 'vue';
+	import sheep from '@/sheep';
+	import {
+		code,
+		mobile,
+		username,
+		password
+	} from '@/sheep/validate/form';
+	import { 
+		showAuthModal,
+		closeAuthModal,
+		getSmsCode,
+		getSmsTimer
+	} from '@/sheep/hooks/useModal';
+	import AuthUtil from '@/sheep/api/member/auth';
+	import phoneInternationalInput from './phone-international-input.vue';
+	const mobileInput = (mobile,mobileError)=>{
+		// console.log(mobile,mobileError);
+		state.model.mobile = mobile;
+		state.mobileErrorMsg = mobileError;
+	}
+	// 账号注册数据
+	const state = reactive({
+		verifyUsername: false , // 校验用户名是否可用
+		codeText: '获取验证码',
+		mobileErrorMsg:'',
+		usernameErrorMsg:'',
+		model: {
+			username:'', // 用户名
+			password:'', // 密码
+			mobile: '', // 手机号
+			code: '', // 验证码
+		},
+		rules: {
+			username,
+			password,
+			code,
+		},
+	});
+	const smsLoginRef = ref(null);
+	
+	const emits = defineEmits(['onConfirm']);
+	
+	const props = defineProps({
+		agreeStatus: {
+			type: Boolean,
+			default: false,
+		},
+	});
+	let lastUsername = ref('')
+	async function verifyUsername(e){
+		const username = e.detail.value;
+		if(username == '' || username == lastUsername.value){
+			// 为空或者没改东西,不调校验
+			return false;
+		}
+		lastUsername.value = username
+		// 提交数据
+		const { data } = await AuthUtil.verifyUsername(username);
+		// false就是已经有这个用户名,不可以用。true是没有,可以改
+		if(data){
+			state.usernameErrorMsg = ''
+			state.verifyUsername = data
+		}else {
+			state.usernameErrorMsg = '已存在用户名!'
+			state.verifyUsername = data
+		}
+	}
+	// 注册
+	async function registerSubmit() {
+		console.log(state.model)
+		// 参数校验
+		const validate = await unref(smsLoginRef)
+			.validate()
+			.catch((error) => {
+				console.log('error: ', error);
+			});
+		if (!validate) {
+			return;
+		}
+		if (!props.agreeStatus) {
+			emits('onConfirm', true)
+			//onConfirm(true)
+			sheep.$helper.toast('请勾选同意');
+			return;
+		}
+		
+		// 看缓存中有没有linkId 如果有的话 加入model传给后台 即为绑定
+		const linkId = uni.getStorageSync("linkId")
+		if (linkId) {
+			state.model.linkId = linkId
+		}else{
+			sheep.$helper.toast('您只能通过分享注册');
+			return false;
+		}
+		// 提交数据
+		const {
+			code
+		} = await AuthUtil.register(state.model);
+		if (code === 0) {
+			closeAuthModal();
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import '../index.scss';
+
+	.code-btn-start {
+		color: #55b774;
+		border: 1px solid #55b774;
+	}
+	.disabled{
+		border: 1px solid #f7f7f7;
+	}
+	.icon{
+		display:flex;
+		align-items: center;
+		margin-right:7rpx
+	}
+	.icon image{
+		width:35rpx;
+		height:35rpx;
+	}
+	.agreement-box {
+		margin: 20rpx 0;
+	}
+
+	.login-btn-start {
+		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		width: 100%;
+		height: 80rpx;
+		font-size: 32rpx;
+	}
+
+	.loginUniForm {
+		border: 1rpx solid #d6d6d6;
+		padding: 10rpx 15rpx;
+		border-radius: 10rpx;
+	}
+
+	.loginUniFormItem {
+		border-bottom: 1rpx solid #d6d6d6;
+		padding-bottom: 10rpx;
+	}
+
+	.loginUniFormItem:last-child {
+		border-bottom: none;
+		padding-top: 10rpx;
+	}
+
+	::v-deep .loginUniFormItem .uni-forms-item__inner {
+		padding-bottom: 0;
+	}
+
+	::v-deep .loginUniFormItem .uni-error-message {
+		bottom: -20rpx;
+	}
+</style>

+ 60 - 33
sheep/components/s-auth-modal/components/sms-login.vue

@@ -1,38 +1,24 @@
 <!-- 短信登录 - smsLogin  -->
 <template>
 	<view>
-		<!-- 标题栏 -->
-		<view class="head-box">
-      <view class="ss-flex ss-m-b-20">
-		 <!-- <view class="head-title-active ss-m-r-40" @tap="showAuthModal('accountLogin')">
-		    账号登录
-		  </view>
-        <view class="head-title head-title-line head-title-animation">短信登录</view> -->
-        <view class="head-subtitle">未注册的手机号,验证后自动注册账号</view>
-      </view>
-      
-    </view>
+
 		<!-- 表单项 -->
 		<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind" labelWidth="140"
 			labelAlign="center" class="loginUniForm">
-			<uni-forms-item name="mobile" label="手机号" class="loginUniFormItem">
-				<uni-easyinput placeholder="请输入手机号" v-model="state.model.mobile" :inputBorder="false" type="number">
-					<template v-slot:right>
-						<button class="ss-reset-button code-btn code-btn-start" :disabled="state.isMobileEnd"
-							:class="{ 'code-btn-end': state.isMobileEnd }"
-							@tap="getSmsCode('smsLogin', state.model.mobile)">
-							{{ getSmsTimer('smsLogin') }}
-						</button>
-					</template>
+			<uni-forms-item name="username" label="用户名" class="loginUniFormItem" :error-message="state.usernameErrorMsg">
+				<uni-easyinput placeholder="请输入用户名" v-model="state.model.username" :inputBorder="false" :clearable="false" @blur="verifyUsername">
+				<template v-slot:right>
+					<view v-if="state.verifyUsername" class="icon"><image style :src="sheep.$url.static('/static/images/shibai.png')" /></view>
+					<view v-else class="icon"> <image :src="sheep.$url.static('/static/images/chenggong.png')" /></view>
+				</template>
 				</uni-easyinput>
 			</uni-forms-item>
-
+			<uni-forms-item name="mobile" label="手机号" class="mobile loginUniFormItem ss-p-t-10" :error-message="state.mobileErrorMsg">
+				<phoneInternationalInput :verify-username="!state.verifyUsername" @input="mobileInput"/>
+			</uni-forms-item>
 			<uni-forms-item name="code" label="验证码" class="loginUniFormItem">
 				<uni-easyinput placeholder="请输入验证码" v-model="state.model.code" :inputBorder="false" type="number"
 					maxlength="4">
-					<!-- <template v-slot:right>
-            <button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit"> 登录 </button>
-          </template> -->
 				</uni-easyinput>
 			</uni-forms-item>
 		</uni-forms>
@@ -55,7 +41,8 @@
 	import sheep from '@/sheep';
 	import {
 		code,
-		mobile
+		mobile,
+		username
 	} from '@/sheep/validate/form';
 	import {
 		showAuthModal,
@@ -64,7 +51,12 @@
 		getSmsTimer
 	} from '@/sheep/hooks/useModal';
 	import AuthUtil from '@/sheep/api/member/auth';
-
+	import phoneInternationalInput from './phone-international-input.vue';
+	const mobileInput = (mobile,mobileError)=>{
+		// console.log(mobile,mobileError);
+		state.model.mobile = mobile;
+		state.mobileErrorMsg = mobileError;
+	}
 	const smsLoginRef = ref(null);
 
 	const emits = defineEmits(['onConfirm']);
@@ -78,23 +70,46 @@
 
 	// 数据
 	const state = reactive({
+		verifyUsername: true ,
+		usernameErrorMsg:'',
 		isMobileEnd: false, // 手机号输入完毕
 		codeText: '获取验证码',
+		mobileErrorMsg:'',
 		model: {
+			username:'',
 			mobile: '', // 手机号
 			code: '', // 验证码
 		},
 		rules: {
+			username,
 			code,
 			mobile,
 		},
 	});
-
+	let lastUsername = ref('')
+	async function verifyUsername(e){
+		const username = e.detail.value;
+		if(username == '' || username == lastUsername.value){
+			// 为空或者没改东西,不调校验
+			return false;
+		}
+		lastUsername.value = username
+		// 提交数据
+		const { data } = await AuthUtil.verifyUsername(username);
+		// false就是已经有这个用户名,可以登录,true是没有,不可以登录
+		if(data){
+			state.usernameErrorMsg = '请输入正确的用户名!'
+			state.verifyUsername = data
+		}else {
+			state.usernameErrorMsg = ''
+			state.verifyUsername = data
+		}
+	}
 	// 短信登录
 	async function smsLoginSubmit() {
 		// 看缓存中有没有linkId 如果有的话 加入model传给后台 即为绑定
 		const linkId = uni.getStorageSync("linkId")
-		if(linkId){
+		if (linkId) {
 			state.model.linkId = linkId
 		}
 		// 参数校验
@@ -112,7 +127,7 @@
 			sheep.$helper.toast('请勾选同意');
 			return;
 		}
-		
+
 		// 提交数据
 		const {
 			code
@@ -125,11 +140,23 @@
 
 <style lang="scss" scoped>
 	@import '../index.scss';
-
+	.disabled{
+		border: 1px solid #f7f7f7 !important;
+	}
 	.code-btn-start {
 		color: #55b774;
 		border: 1px solid #55b774;
 	}
+	
+	.icon{
+		display:flex;
+		align-items: center;
+		margin-right:7rpx
+	}
+	.icon image{
+		width:35rpx;
+		height:35rpx;
+	}
 
 
 
@@ -138,7 +165,7 @@
 	}
 
 	.login-btn-start {
-		background: rgb(14, 147, 46);
+		background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
 		width: 100%;
 		height: 80rpx;
 		font-size: 32rpx;
@@ -150,13 +177,13 @@
 		border-radius: 10rpx;
 	}
 
-	.loginUniFormItem:first-child {
+	.loginUniFormItem {
 		border-bottom: 1rpx solid #d6d6d6;
 		padding-bottom: 10rpx;
 	}
 
 	.loginUniFormItem:last-child {
-		// border-bottom: 1rpx solid #d6d6d6;
+		border-bottom: none;
 		padding-top: 10rpx;
 	}
 

+ 58 - 15
sheep/components/s-auth-modal/s-auth-modal.vue

@@ -2,27 +2,31 @@
 	<!-- 规格弹窗 -->
 	<su-popup :show="authType !== ''" round="10" :showClose="true" @close="closeAuthModal">
 		<view class="login-wrap">
-
 			<!-- 标题栏 -->
-			<view class="head-box " v-if="['smsLogin', 'accountLogin'].includes(authType)">
+			<view class="head-box " v-if="['smsLogin', 'accountLogin','register'].includes(authType)">
+				
 				<view class="ss-flex ss-m-b-20">
 					<view
-						:class="[isActive=='smsLogin'?`head-title ss-m-r-40 head-title-animation`:`head-title-active ss-m-r-40`]"
-						@tap="isActive='smsLogin';showAuthModal('smsLogin')">
+						:class="[isActive=='accountLogin' ?`head-title ss-m-r-40 head-title-animation`:`head-title-active ss-m-r-40`]"
+						@tap="isActive='accountLogin';showAuthModal('accountLogin','accountLogin')">
 						
-						短信登录
+						账号登录
 					</view>
 					<view
-						:class="[isActive=='accountLogin' ?`head-title head-title-line head-title-animation`:`head-title-active head-title-line`]"
-						@tap="isActive='accountLogin';showAuthModal('accountLogin','accountLogin')">
+						:class="[isActive=='smsLogin'?`head-title head-title-line head-title-animation ss-m-r-40`:` ss-m-r-40 head-title-active head-title-line`]"
+						@tap="isActive='smsLogin';showAuthModal('smsLogin','smsLogin')">
 						
-						账号登录
+						短信登录
+					</view>
+					<view
+						:class="[isActive=='register' ?`head-title head-title-line head-title-animation`:`head-title-active head-title-line`]"
+						@tap="isActive='register';showAuthModal('register','register')"  v-if="linkId"> 
+						注册
 					</view>
-
 				</view>
 			</view>
 			<!-- 用户协议的勾选 -->
-			<view v-if="[ 'smsLogin','accountLogin'].includes(authType)" class="agreement-box ss-flex ss-row-center"
+			<view v-if="[ 'smsLogin','accountLogin','register'].includes(authType)" class="agreement-box ss-flex ss-row-center"
 				:class="{ shake: currentProtocol }">
 				<label class="radio ss-flex ss-col-center" @tap="onChange">
 					<radio :checked="state.protocol" color="var(--ui-BG-Main)" style="transform: scale(0.8)"
@@ -39,18 +43,28 @@
 					</view>
 				</label>
 			</view>
-			<!-- 微信公众号授权登陆 -->
+			<!-- 微信公众号授权登陆  在验证码登录 账号登录中显示-->
 			<view v-if="['accountLogin', 'smsLogin'].includes(authType)"
 				class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
 				<view class="wx-login-btn " @tap="thirdLogin('wechat')" v-if=" ['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) && sheep.$platform.isWechatInstalled
 				">
 
-					<image class=" auto-login-img" :src="sheep.$url.static('/static/img/shop/platform/wechat.png')" />
+					<image class=" auto-login-img" :src="sheep.$url.static('/static/images/wechat.png')" />
 
 					<text>微信授权登录</text>
 				</view>
 			</view>
+			<!-- 微信公众号授权登陆 在账号注册中显示 -->
+			<view v-if="['register'].includes(authType)"
+				class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
+				<view class="wx-login-btn " @tap="thirdRegister('wechat')" v-if=" ['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) && sheep.$platform.isWechatInstalled
+				">
 			
+					<image class=" auto-login-img" :src="sheep.$url.static('/static/images/wechat.png')" />
+			
+					<text>微信授权注册</text>
+				</view>
+			</view>
 			<!-- 1. 微信公众号授权登录 第一次登陆时弹窗绑定手机号 accountLogin -->
 			<officialAccountFirstLogin v-if="authType === 'officialAccountFirstLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
 			
@@ -59,6 +73,9 @@
 
 			<!-- 2. 短信登录  smsLogin -->
 			<sms-login v-if="authType === 'smsLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
+			
+			<!-- 注册 -->
+			<register v-if="authType === 'register'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
 
 			<!-- 3. 忘记密码 resetPassword-->
 			<reset-password v-if="authType === 'resetPassword'" />
@@ -98,7 +115,7 @@
         >
           <image
             class="auto-login-img"
-            :src="sheep.$url.static('/static/img/shop/platform/wechat.png')"
+            :src="sheep.$url.static('/static/images/wechat.png')"
           />
         </button> -->
 
@@ -107,7 +124,7 @@
 				<!-- 7.3 iOS 登录 TODO 非繁人:等后面搞 App 再弄 -->
 				<button v-if="sheep.$platform.os === 'ios' && sheep.$platform.name === 'App'" @tap="thirdLogin('apple')"
 					class="ss-reset-button auto-login-btn">
-					<image class="auto-login-img" :src="sheep.$url.static('/static/img/shop/platform/apple.png')" />
+					<image class="auto-login-img" :src="sheep.$url.static('/static/images/apple.png')" />
 				</button>
 			</view>
 
@@ -126,6 +143,7 @@
 	import sheep from '@/sheep';
 	import accountLogin from './components/account-login.vue';
 	import smsLogin from './components/sms-login.vue';
+	import register from './components/register.vue'
 	import resetPassword from './components/reset-password.vue';
 	import changeMobile from './components/change-mobile.vue';
 	import changePassword from './components/change-password.vue';
@@ -137,7 +155,7 @@
 	} from '@/sheep/hooks/useModal';
 
 	const appInfo = computed(() => sheep.$store('app').info);
-
+	const linkId = uni.getStorageSync("linkId");
 	const modalStore = sheep.$store('modal');
 	// 授权弹窗类型
 	const authType = computed(() => modalStore.auth);
@@ -192,6 +210,31 @@
 			// #endif
 		}
 	};
+	// 第三方授权注册
+	const thirdRegister = async (provider) => {
+		if (!state.protocol) {
+			currentProtocol.value = true;
+			setTimeout(() => {
+				currentProtocol.value = false;
+			}, 1000);
+			sheep.$helper.toast('请勾选同意');
+			return;
+		}
+		const linkId = uni.getStorageSync("linkId");
+		if (!linkId) {
+			sheep.$helper.toast('您只能通过分享注册');
+			return false;
+		}
+		const loginRes = await sheep.$platform.useProvider(provider).register();
+		if (loginRes) {
+			closeAuthModal();
+			// 触发小程序授权信息弹框
+			// #ifdef MP-WEIXIN
+			showAuthModal('mpAuthorization');
+			// #endif
+		}
+	};
+	
 
 	// 微信小程序的“手机号快速验证”:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
 	const getPhoneNumber = async (e) => {

+ 4 - 4
sheep/components/s-coupon-card/s-coupon-card.vue

@@ -24,28 +24,28 @@
 				return [{
 						title: '已领取',
 						value: '0',
-						icon: '/static/img/shop/order/nouse_coupon.png',
+						icon: '/static/images/nouse_coupon.png',
 						path: '/pages/coupon/list',
 						type: 'geted',
 					},
 					{
 						title: '已使用',
 						value: '0',
-						icon: '/static/img/shop/order/useend_coupon.png',
+						icon: '/static/images/useend_coupon.png',
 						path: '/pages/coupon/list',
 						type: 'used',
 					},
 					{
 						title: '已失效',
 						value: '0',
-						icon: '/static/img/shop/order/out_coupon.png',
+						icon: '/static/images/out_coupon.png',
 						path: '/pages/coupon/list',
 						type: 'expired',
 					},
 					{
 					  title: '领券中心',
 					  value: '0',
-					  icon: '/static/img/shop/order/all_coupon.png',
+					  icon: '/static/images/all_coupon.png',
 					  path: '/pages/coupon/list',
 					  type: 'all',
 					},

+ 1 - 1
sheep/components/s-goods-card/s-goods-card.vue

@@ -174,7 +174,7 @@
     if (btnBuy.type === 'text') {
       // 文字按钮:线性渐变背景颜色
       return {
-        background: `linear-gradient(to right, ${btnBuy.bgBeginColor}, ${btnBuy.bgEndColor})`,
+        background: `linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient))`,
       };
     }
     if (btnBuy.type === 'img') {

+ 718 - 715
sheep/components/s-goods-column/s-goods-column.vue

@@ -1,723 +1,726 @@
 <!-- 页面 -->
 <template>
-  <view class="ss-goods-wrap">
-    <!-- xs卡片:横向紧凑型,一行放两个,图片左内容右边  -->
-    <view
-      v-if="size === 'xs'"
-      class="xs-goods-card ss-flex ss-col-stretch"
-      :style="[elStyles]"
-      @tap="onClick"
-    >
-      <view v-if="tagStyle.show" class="tag-icon-box">
-        <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
-      </view>
-      <image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit"></image>
-      <view
-        v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
-        class="xs-goods-content ss-flex-col ss-row-around"
-      >
-        <view
-          v-if="goodsFields.title?.show || goodsFields.name?.show"
-          class="xs-goods-title ss-line-1"
-          :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
-        >
-          {{ data.title || data.name }}
-        </view>
-        <view
-          v-if="goodsFields.price?.show"
-          class="xs-goods-price font-OPPOSANS"
-          :style="[{ color: goodsFields.price.color }]"
-        >
-          <text class="price-unit ss-font-24">{{ priceUnit }}</text>
-          {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
-        </view>
-      </view>
-    </view>
-
-    <!-- sm卡片:竖向紧凑,一行放三个,图上内容下 -->
-    <view v-if="size === 'sm'" class="sm-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
-      <view v-if="tagStyle.show" class="tag-icon-box">
-        <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
-      </view>
-      <image class="sm-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
-
-      <view
-        v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
-        class="sm-goods-content"
-        :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
-      >
-        <view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sm-goods-title ss-line-1 ss-m-b-16">
-          {{ data.title || data.name }}
-        </view>
-        <view
-          v-if="goodsFields.price?.show"
-          class="sm-goods-price font-OPPOSANS"
-          :style="[{ color: goodsFields.price.color }]"
-        >
-          <text class="price-unit ss-font-24">{{ priceUnit }}</text>
-          {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
-        </view>
-      </view>
-    </view>
-
-    <!-- md卡片:竖向,一行放两个,图上内容下 -->
-    <view v-if="size === 'md'" class="md-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
-      <view v-if="tagStyle.show" class="tag-icon-box">
-        <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
-      </view>
-      <image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix"></image>
-      <view
-        class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16"
-        :id="elId"
-      >
-        <view
-          v-if="goodsFields.title?.show || goodsFields.name?.show"
-          class="md-goods-title ss-line-1"
-          :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
-        >
-          {{ data.title || data.name }}
-        </view>
-        <view
-          v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
-          class="md-goods-subtitle ss-m-t-16 ss-line-1"
-          :style="[{ color: subTitleColor, background: subTitleBackground }]"
-        >
-          {{ data.subtitle || data.introduction }}
-        </view>
-        <slot name="activity">
-          <view v-if="data.promos?.length" class="tag-box ss-flex-wrap ss-flex ss-col-center">
-            <view
-              class="activity-tag ss-m-r-10 ss-m-t-16"
-              v-for="item in data.promos"
-              :key="item.id"
-            >
-              {{ item.title }}
-            </view>
-          </view>
-        </slot>
-        <view class="ss-flex ss-col-bottom">
-          <view
-            v-if="goodsFields.price?.show"
-            class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10"
-            :style="[{ color: goodsFields.price.color }]"
-          >
-            <text class="price-unit ss-font-24">{{ priceUnit }}</text>
-            {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
-          </view>
-
-          <view
-            v-if="(goodsFields.original_price?.show||goodsFields.marketPrice?.show) &&( data.original_price > 0|| data.marketPrice > 0)"
-            class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
-            :style="[{ color: originPriceColor }]"
-          >
-            <text class="price-unit ss-font-20">{{ priceUnit }}</text>
-            <view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
-          </view>
-        </view>
-
-        <view class="ss-m-t-16 ss-flex ss-col-center ss-flex-wrap">
-          <view class="sales-text">{{ salesAndStock }}</view>
-        </view>
-      </view>
-
-      <slot name="cart">
-        <view class="cart-box ss-flex ss-col-center ss-row-center">
-          <image class="cart-icon" src="/static/img/shop/tabbar/category2.png" mode="" />
-        </view>
-      </slot>
-    </view>
-
-    <!-- lg卡片:横向型,一行放一个,图片左内容右边  -->
-    <view
-      v-if="size === 'lg'"
-      class="lg-goods-card ss-flex ss-col-stretch"
-      :style="[elStyles]"
-      @tap="onClick"
-    >
-      <view v-if="tagStyle.show" class="tag-icon-box">
-        <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
-      </view>
-      <view v-if="seckillTag" class="seckill-tag ss-flex ss-row-center"> 秒杀 </view>
-      <view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center">
-        <view class="tag-icon">拼团</view>
-      </view>
-      <image class="lg-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
-      <view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
-        <view>
-          <view
-            v-if="goodsFields.title?.show || goodsFields.name?.show"
-            class="lg-goods-title ss-line-2"
-            :style="[{ color: titleColor }]"
-          >
-            {{ data.title || data.name }}
-          </view>
-          <view
-            v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
-            class="lg-goods-subtitle ss-m-t-10 ss-line-1"
-            :style="[{ color: subTitleColor, background: subTitleBackground }]"
-          >
-            {{ data.subtitle || data.introduction }}
-          </view>
-        </view>
-        <view>
-          <slot name="activity">
-            <view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center">
-              <view class="activity-tag ss-m-r-10" v-for="item in data.promos" :key="item.id">
-                {{ item.title }}
-              </view>
-            </view>
-          </slot>
-          <view class="ss-flex ss-col-bottom ss-m-t-10">
-            <view
-              v-if="goodsFields.price?.show"
-              class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
-              :style="[{ color: goodsFields.price.color }]"
-            >
-              <text class="ss-font-24">{{ priceUnit }}</text>
-              {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
-            </view>
-            <view
-              v-if="(goodsFields.original_price?.show||goodsFields.marketPrice?.show) &&( data.original_price > 0|| data.marketPrice > 0)"
-              class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS"
-              :style="[{ color: originPriceColor }]"
-            >
-              <text class="price-unit ss-font-20">{{ priceUnit }}</text>
-              <view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
-            </view>
-          </view>
-          <view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap">
-            <view class="sales-text">{{ salesAndStock }}</view>
-          </view>
-        </view>
-      </view>
-
-      <slot name="cart">
-        <view class="buy-box ss-flex ss-col-center ss-row-center" v-if="buttonShow">
-          去购买
-        </view>
-      </slot>
-    </view>
-
-    <!-- sl卡片:竖向型,一行放一个,图片上内容下边 -->
-    <view v-if="size === 'sl'" class="sl-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
-      <view v-if="tagStyle.show" class="tag-icon-box">
-        <image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
-      </view>
-
-      <image class="sl-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
-
-      <view class="sl-goods-content">
-        <view>
-          <view
-            v-if="goodsFields.title?.show || goodsFields.name?.show"
-            class="sl-goods-title ss-line-1"
-            :style="[{ color: titleColor }]"
-          >
-            {{ data.title || data.name }}
-          </view>
-          <view
-            v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
-            class="sl-goods-subtitle ss-m-t-16"
-            :style="[{ color: subTitleColor, background: subTitleBackground }]"
-          >
-            {{ data.subtitle || data.introduction }}
-          </view>
-        </view>
-        <view>
-          <slot name="activity">
-            <view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center ss-flex-wrap">
-              <view
-                class="activity-tag ss-m-r-10 ss-m-t-16"
-                v-for="item in data.promos"
-                :key="item.id"
-              >
-                {{ item.title }}
-              </view>
-            </view>
-          </slot>
-          <view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS">
-            <view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
-              <text class="price-unit ss-font-24">{{ priceUnit }}</text>
-              {{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
-            </view>
-			
-            <view
-              v-if="(goodsFields.original_price?.show||goodsFields.marketPrice?.show) &&( data.original_price > 0|| data.marketPrice > 0)"
-              class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
-              :style="[{ color: originPriceColor }]"
-            >
-			
-              <text class="price-unit ss-font-20">{{ priceUnit }}</text>
-              <view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
-            </view>
-          </view>
-          <view class="ss-m-t-16 ss-flex ss-flex-wrap">
-            <view class="sales-text">{{ salesAndStock }}</view>
-          </view>
-        </view>
-      </view>
-
-      <slot name="cart"
-        ><view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view></slot
-      >
-    </view>
-  </view>
+	<view class="ss-goods-wrap">
+		<!-- xs卡片:横向紧凑型,一行放两个,图片左内容右边  -->
+		<view v-if="size === 'xs'" class="xs-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick">
+			<view v-if="tagStyle.show" class="tag-icon-box">
+				<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
+			</view>
+			<image class="xs-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFit"></image>
+			<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
+				class="xs-goods-content ss-flex-col ss-row-around">
+				<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="xs-goods-title ss-line-1"
+					:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
+					{{ data.title || data.name }}
+				</view>
+				
+				<view v-if="goodsFields.price?.show" class="xs-goods-price font-OPPOSANS"
+					:style="[{ color: goodsFields.price.color }]">
+					<text class="price-unit ss-font-24">{{ priceUnit }}</text>
+					{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
+				</view>
+				<view>
+					<view class="origin-price-text" v-if="data.promotionFee >= 0">
+						数字权益:{{ fen2yuan(data.promotionFee ) }}
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- sm卡片:竖向紧凑,一行放三个,图上内容下 -->
+		<view v-if="size === 'sm'" class="sm-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
+			<view v-if="tagStyle.show" class="tag-icon-box">
+				<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
+			</view>
+			<image class="sm-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
+
+			<view v-if="goodsFields.title?.show || goodsFields.name?.show || goodsFields.price?.show"
+				class="sm-goods-content" :style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
+				<view v-if="goodsFields.title?.show || goodsFields.name?.show"
+					class="sm-goods-title ss-line-1 ss-m-b-8">
+					{{ data.title || data.name }}
+				</view>
+				
+				<view v-if="goodsFields.price?.show" class="sm-goods-price font-OPPOSANS"
+					:style="[{ color: goodsFields.price.color }]">
+					<text class="price-unit ss-font-24">{{ priceUnit }}</text>
+					{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
+				</view>
+				<view class="origin-price-text" v-if="data.promotionFee >= 0">
+					数字权益:{{ fen2yuan(data.promotionFee ) }}
+				</view>
+			</view>
+		</view>
+
+		<!-- md卡片:竖向,一行放两个,图上内容下 -->
+		<view v-if="size === 'md'" class="md-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
+			<view v-if="tagStyle.show" class="tag-icon-box">
+				<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
+			</view>
+			<image class="md-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="widthFix"></image>
+			<view class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16" :id="elId">
+				<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="md-goods-title ss-line-1"
+					:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]">
+					{{ data.title || data.name }}
+				</view>
+				<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
+					class="md-goods-subtitle ss-m-t-16 ss-line-1"
+					:style="[{ color: subTitleColor, background: subTitleBackground }]">
+					{{ data.subtitle || data.introduction }}
+				</view>
+				<slot name="activity">
+					<view v-if="data.promos?.length" class="tag-box ss-flex-wrap ss-flex ss-col-center">
+						<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id">
+							{{ item.title }}
+						</view>
+					</view>
+				</slot>
+				<view class="ss-flex ss-col-center ss-m-t-16">
+					<view v-if="goodsFields.price?.show" class="md-goods-price  font-OPPOSANS ss-m-r-10"
+						:style="[{ color: goodsFields.price.color }]">
+						<text class="price-unit ss-font-24">{{ priceUnit }}</text>
+						{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
+					</view>
+
+					<view class="origin-price-text"
+						v-if="data.promotionFee >= 0">
+						数字权益:{{ fen2yuan(data.promotionFee ) }}
+					</view>
+				</view>
+
+				<view class="ss-m-t-32 ss-flex ss-col-center ss-flex-wrap">
+					<view class="sales-text">{{ salesAndStock }}</view>
+				</view>
+			</view>
+
+			<slot name="cart">
+				<view class="cart-box ss-flex ss-col-center ss-row-center">
+					<image class="cart-icon" src="/static/img/shop/tabbar/category2.png" mode="" />
+				</view>
+			</slot>
+		</view>
+
+		<!-- lg卡片:横向型,一行放一个,图片左内容右边  -->
+		<view v-if="size === 'lg'" class="lg-goods-card ss-flex ss-col-stretch" :style="[elStyles]" @tap="onClick">
+			<view v-if="tagStyle.show" class="tag-icon-box">
+				<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
+			</view>
+			<view v-if="seckillTag" class="seckill-tag ss-flex ss-row-center"> 秒杀 </view>
+			<view v-if="grouponTag" class="groupon-tag ss-flex ss-row-center">
+				<view class="tag-icon">拼团</view>
+			</view>
+			<image class="lg-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
+			<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
+				<view>
+					<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="lg-goods-title ss-line-2"
+						:style="[{ color: titleColor }]">
+						{{ data.title || data.name }}
+					</view>
+					<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
+						class="lg-goods-subtitle ss-m-t-10 ss-line-1"
+						:style="[{ color: subTitleColor, background: subTitleBackground }]">
+						{{ data.subtitle || data.introduction }}
+					</view>
+				</view>
+				<view>
+					<slot name="activity">
+						<view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center">
+							<view class="activity-tag ss-m-r-10" v-for="item in data.promos" :key="item.id">
+								{{ item.title }}
+							</view>
+						</view>
+					</slot>
+					
+					<view class="ss-flex ss-col-bottom ss-m-b-10">
+						<view v-if="goodsFields.price?.show"
+							class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
+							:style="[{ color: goodsFields.price.color }]">
+							<text class="ss-font-24">{{ priceUnit }}</text>
+							{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
+						</view>
+					</view>
+					<view class="ss-flex ss-col-bottom ss-m-b-10">
+						<view class="origin-price-text"
+							v-if="data.promotionFee >= 0">
+							数字权益:{{ fen2yuan(data.promotionFee) }}
+						</view>
+					</view>
+					<view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap">
+						<view class="sales-text">{{ salesAndStock }}</view>
+					</view>
+				</view>
+			</view>
+
+			<slot name="cart">
+				<view class="buy-box ss-flex ss-col-center ss-row-center" v-if="buttonShow">
+					去购买
+				</view>
+			</slot>
+		</view>
+
+		<!-- sl卡片:竖向型,一行放一个,图片上内容下边 -->
+		<view v-if="size === 'sl'" class="sl-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
+			<view v-if="tagStyle.show" class="tag-icon-box">
+				<image class="tag-icon" :src="sheep.$url.cdn(tagStyle.src || tagStyle.imgUrl)"></image>
+			</view>
+
+			<image class="sl-img-box" :src="sheep.$url.cdn(data.image || data.picUrl)" mode="aspectFill"></image>
+
+			<view class="sl-goods-content">
+				<view>
+					<view v-if="goodsFields.title?.show || goodsFields.name?.show" class="sl-goods-title ss-line-1"
+						:style="[{ color: titleColor }]">
+						{{ data.title || data.name }}
+					</view>
+					<view v-if="goodsFields.subtitle?.show || goodsFields.introduction?.show"
+						class="sl-goods-subtitle ss-m-t-16"
+						:style="[{ color: subTitleColor, background: subTitleBackground }]">
+						{{ data.subtitle || data.introduction }}
+					</view>
+				</view>
+				<view>
+					<slot name="activity">
+						<view v-if="data.promos?.length" class="tag-box ss-flex ss-col-center ss-flex-wrap">
+							<view class="activity-tag ss-m-r-10 ss-m-t-16" v-for="item in data.promos" :key="item.id">
+								{{ item.title }}
+							</view>
+						</view>
+					</slot>
+					<view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS ss-m-t-10">
+						<view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
+							<text class="price-unit ss-font-24">{{ priceUnit }}</text>
+							{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
+						</view>
+						<view class="origin-price-text"
+							v-if="data.promotionFee >= 0">
+							数字权益:{{ fen2yuan(data.promotionFee) }}
+						</view>
+						
+					</view>
+					<view class="ss-m-t-16 ss-flex ss-flex-wrap">
+						<view class="sales-text">{{ salesAndStock }}</view>
+					</view>
+				</view>
+			</view>
+
+			<slot name="cart">
+				<view class="buy-box ss-flex ss-col-center ss-row-center">去购买</view>
+			</slot>
+		</view>
+	</view>
 </template>
 
 <script setup>
-  /**
-   * 商品卡片
-   *
-   * @property {Array} size = [xs | sm | md | lg | sl ] 			 	- 列表数据
-   * @property {String} tag 											- md及以上才有
-   * @property {String} img 											- 图片
-   * @property {String} background 									- 背景色
-   * @property {String} topRadius 									- 上圆角
-   * @property {String} bottomRadius 									- 下圆角
-   * @property {String} title 										- 标题
-   * @property {String} titleColor 									- 标题颜色
-   * @property {Number} titleWidth = 0								- 标题宽度,默认0,单位rpx
-   * @property {String} subTitle 										- 副标题
-   * @property {String} subTitleColor									- 副标题颜色
-   * @property {String} subTitleBackground 							- 副标题背景
-   * @property {String | Number} price 								- 价格
-   * @property {String} priceColor 									- 价格颜色
-   * @property {String | Number} originPrice 							- 原价/划线价
-   * @property {String} originPriceColor 								- 原价颜色
-   * @property {String | Number} sales 								- 销售数量
-   * @property {String} salesColor									- 销售数量颜色
-   *
-   * @slots activity												 	- 活动插槽
-   * @slots cart														- 购物车插槽,默认包含文字,背景色,文字颜色 || 图片 || 行为
-   *
-   * @event {Function()} click 										- 点击卡片
-   *
-   */
-  import { computed, reactive, getCurrentInstance, onMounted, nextTick } from 'vue';
-  import sheep from '@/sheep';
-  import { fen2yuan, formatSales } from '@/sheep/hooks/useGoods';
-  import { formatStock } from '@/sheep/hooks/useGoods';
-  import goodsCollectVue from '@/pages/user/goods-collect.vue';
-  import { isArray } from 'lodash';
-
-  // 数据
-  const state = reactive({});
-
-  // 接收参数
-  const props = defineProps({
-    goodsFields: {
-      type: [Array, Object],
-      default() {
-        return {
-          // 商品价格
-          price: { show: true },
-          // 库存
-          stock: { show: true },
-          // 商品名称
-          name: { show: true },
-          // 商品介绍
-          introduction: { show: true },
-          // 市场价
-          marketPrice: { show: true },
-          // 销量
-          salesCount: { show: true },
-        };
-      },
-    },
-    tagStyle: {
-      type: Object,
-      default: {},
-    },
-    data: {
-      type: Object,
-      default: {},
-    },
-    size: {
-      type: String,
-      default: 'sl',
-    },
-    background: {
-      type: String,
-      default: '',
-    },
-    topRadius: {
-      type: Number,
-      default: 0,
-    },
-    bottomRadius: {
-      type: Number,
-      default: 0,
-    },
-    titleWidth: {
-      type: Number,
-      default: 0,
-    },
-    titleColor: {
-      type: String,
-      default: '#333',
-    },
-    priceColor: {
-      type: String,
-      default: '',
-    },
-    originPriceColor: {
-      type: String,
-      default: '#C4C4C4',
-    },
-    priceUnit: {
-      type: String,
-      default: '¥',
-    },
-    subTitleColor: {
-      type: String,
-      default: '#999999',
-    },
-    subTitleBackground: {
-      type: String,
-      default: '',
-    },
-    buttonShow: {
-      type: Boolean,
-      default: true,
-    },
-    seckillTag: {
-      type: Boolean,
-      default: false,
-    },
-    grouponTag: {
-      type: Boolean,
-      default: false,
-    },
-  });
-
-  // 组件样式
-  const elStyles = computed(() => {
-    return {
-      background: props.background,
-      'border-top-left-radius': props.topRadius + 'px',
-      'border-top-right-radius': props.topRadius + 'px',
-      'border-bottom-left-radius': props.bottomRadius + 'px',
-      'border-bottom-right-radius': props.bottomRadius + 'px',
-    };
-  });
-
-  // 格式化销量、库存信息
-  const salesAndStock = computed(() => {
-    let text = [];
-    if (props.goodsFields.salesCount?.show) {
-      text.push(formatSales(props.data.sales_show_type, props.data.salesCount));
-    }
-    if (props.goodsFields.stock?.show) {
-      text.push(formatStock(props.data.stock_show_type, props.data.stock));
-    }
-    return text.join(' | ');
-  });
-
-  // 返回事件
-  const emits = defineEmits(['click', 'getHeight']);
-
-  const onClick = () => {
-    emits('click');
-  };
-
-  // 获取卡片实时高度
-  const { proxy } = getCurrentInstance();
-  const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`;
-  function getGoodsPriceCardWH() {
-    if (props.size === 'md') {
-      const view = uni.createSelectorQuery().in(proxy);
-      view.select(`#${elId}`).fields({ size: true, scrollOffset: true });
-      view.exec((data) => {
-        let totalHeight = 0;
-        const goodsPriceCard = data[0];
-        if (props.data.image_wh) {
-          totalHeight =
-            (goodsPriceCard.width / props.data.image_wh.w) * props.data.image_wh.h +
-            goodsPriceCard.height;
-        } else {
-          totalHeight = goodsPriceCard.width;
-        }
-        emits('getHeight', totalHeight);
-      });
-    }
-  }
-  onMounted(() => {
-    nextTick(() => {
-      getGoodsPriceCardWH();
-    });
-  });
+	/**
+	 * 商品卡片
+	 *
+	 * @property {Array} size = [xs | sm | md | lg | sl ] 			 	- 列表数据
+	 * @property {String} tag 											- md及以上才有
+	 * @property {String} img 											- 图片
+	 * @property {String} background 									- 背景色
+	 * @property {String} topRadius 									- 上圆角
+	 * @property {String} bottomRadius 									- 下圆角
+	 * @property {String} title 										- 标题
+	 * @property {String} titleColor 									- 标题颜色
+	 * @property {Number} titleWidth = 0								- 标题宽度,默认0,单位rpx
+	 * @property {String} subTitle 										- 副标题
+	 * @property {String} subTitleColor									- 副标题颜色
+	 * @property {String} subTitleBackground 							- 副标题背景
+	 * @property {String | Number} price 								- 价格
+	 * @property {String} priceColor 									- 价格颜色
+	 * @property {String | Number} originPrice 							- 原价/划线价
+	 * @property {String} originPriceColor 								- 原价颜色
+	 * @property {String | Number} sales 								- 销售数量
+	 * @property {String} salesColor									- 销售数量颜色
+	 *
+	 * @slots activity												 	- 活动插槽
+	 * @slots cart														- 购物车插槽,默认包含文字,背景色,文字颜色 || 图片 || 行为
+	 *
+	 * @event {Function()} click 										- 点击卡片
+	 *
+	 */
+	import {
+		computed,
+		reactive,
+		getCurrentInstance,
+		onMounted,
+		nextTick
+	} from 'vue';
+	import sheep from '@/sheep';
+	import {
+		fen2yuan,
+		formatSales
+	} from '@/sheep/hooks/useGoods';
+	import {
+		formatStock
+	} from '@/sheep/hooks/useGoods';
+	import goodsCollectVue from '@/pages/user/goods-collect.vue';
+	import {
+		isArray
+	} from 'lodash';
+
+	// 数据
+	const state = reactive({});
+
+	// 接收参数
+	const props = defineProps({
+		goodsFields: {
+			type: [Array, Object],
+			default () {
+				return {
+					// 商品价格
+					price: {
+						show: true
+					},
+					// 库存
+					stock: {
+						show: true
+					},
+					// 商品名称
+					name: {
+						show: true
+					},
+					// 商品介绍
+					introduction: {
+						show: true
+					},
+					// 市场价
+					promotionFee: {
+						show: true
+					},
+					// 销量
+					salesCount: {
+						show: true
+					},
+				};
+			},
+		},
+		tagStyle: {
+			type: Object,
+			default: {},
+		},
+		data: {
+			type: Object,
+			default: {},
+		},
+		size: {
+			type: String,
+			default: 'sl',
+		},
+		background: {
+			type: String,
+			default: '',
+		},
+		topRadius: {
+			type: Number,
+			default: 0,
+		},
+		bottomRadius: {
+			type: Number,
+			default: 0,
+		},
+		titleWidth: {
+			type: Number,
+			default: 0,
+		},
+		titleColor: {
+			type: String,
+			default: '#333',
+		},
+		priceColor: {
+			type: String,
+			default: '',
+		},
+		originPriceColor: {
+			type: String,
+			default: '#C4C4C4',
+		},
+		priceUnit: {
+			type: String,
+			default: '¥',
+		},
+		subTitleColor: {
+			type: String,
+			default: '#999999',
+		},
+		subTitleBackground: {
+			type: String,
+			default: '',
+		},
+		buttonShow: {
+			type: Boolean,
+			default: true,
+		},
+		seckillTag: {
+			type: Boolean,
+			default: false,
+		},
+		grouponTag: {
+			type: Boolean,
+			default: false,
+		},
+	});
+
+	// 组件样式
+	const elStyles = computed(() => {
+		return {
+			background: props.background,
+			'border-top-left-radius': props.topRadius + 'px',
+			'border-top-right-radius': props.topRadius + 'px',
+			'border-bottom-left-radius': props.bottomRadius + 'px',
+			'border-bottom-right-radius': props.bottomRadius + 'px',
+		};
+	});
+
+	// 格式化销量、库存信息
+	const salesAndStock = computed(() => {
+		let text = [];
+		if (props.goodsFields.salesCount?.show) {
+			text.push(formatSales(props.data.sales_show_type, props.data.salesCount));
+		}
+		if (props.goodsFields.stock?.show) {
+			text.push(formatStock(props.data.stock_show_type, props.data.stock));
+		}
+		return text.join(' | ');
+	});
+
+	// 返回事件
+	const emits = defineEmits(['click', 'getHeight']);
+
+	const onClick = () => {
+		emits('click');
+	};
+
+	// 获取卡片实时高度
+	const {
+		proxy
+	} = getCurrentInstance();
+	const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`;
+
+	function getGoodsPriceCardWH() {
+		if (props.size === 'md') {
+			const view = uni.createSelectorQuery().in(proxy);
+			view.select(`#${elId}`).fields({
+				size: true,
+				scrollOffset: true
+			});
+			view.exec((data) => {
+				let totalHeight = 0;
+				const goodsPriceCard = data[0];
+				if (props.data.image_wh) {
+					totalHeight =
+						(goodsPriceCard.width / props.data.image_wh.w) * props.data.image_wh.h +
+						goodsPriceCard.height;
+				} else {
+					totalHeight = goodsPriceCard.width;
+				}
+				emits('getHeight', totalHeight);
+			});
+		}
+	}
+	onMounted(() => {
+		nextTick(() => {
+			getGoodsPriceCardWH();
+		});
+	});
 </script>
 
 <style lang="scss" scoped>
-  .tag-icon-box {
-    position: absolute;
-    left: 0;
-    top: 0;
-    z-index: 2;
-    .tag-icon {
-      width: 72rpx;
-      height: 44rpx;
-    }
-  }
-  .seckill-tag {
-    position: absolute;
-    left: 0;
-    top: 0;
-    z-index: 2;
-    width: 68rpx;
-    height: 38rpx;
-    background: linear-gradient(90deg, #ff5854 0%, #ff2621 100%);
-    border-radius: 10rpx 0px 10rpx 0px;
-    font-size: 24rpx;
-    font-weight: 500;
-    color: #ffffff;
-    line-height: 32rpx;
-  }
-  .groupon-tag {
-    position: absolute;
-    left: 0;
-    top: 0;
-    z-index: 2;
-    width: 68rpx;
-    height: 38rpx;
-    background: linear-gradient(90deg, #fe832a 0%, #ff6600 100%);
-    border-radius: 10rpx 0px 10rpx 0px;
-    font-size: 24rpx;
-    font-weight: 500;
-    color: #ffffff;
-    line-height: 32rpx;
-  }
-  .goods-img {
-    width: 100%;
-    height: 100%;
-    background-color: #f5f5f5;
-  }
-  .price-unit {
-    margin-right: -4px;
-  }
-  .sales-text {
-    display: table;
-    font-size: 24rpx;
-    transform: scale(0.8);
-    margin-left: 0rpx;
-    color: #c4c4c4;
-  }
-
-  .activity-tag {
-    font-size: 20rpx;
-    color: #ff0000;
-    line-height: 30rpx;
-    padding: 0 10rpx;
-    border: 1px solid rgba(#ff0000, 0.25);
-    border-radius: 4px;
-    flex-shrink: 0;
-  }
-
-  .goods-origin-price {
-    font-size: 20rpx;
-    color: #c4c4c4;
-    line-height: 36rpx;
-    text-decoration: line-through;
-  }
-
-  // xs
-  .xs-goods-card {
-    overflow: hidden;
-    // max-width: 375rpx;
-    background-color: $white;
-    position: relative;
-
-    .xs-img-box {
-      width: 128rpx;
-      height: 128rpx;
-      margin-right: 20rpx;
-    }
-
-    .xs-goods-title {
-      font-size: 26rpx;
-      color: #333;
-      font-weight: 500;
-    }
-
-    .xs-goods-price {
-      font-size: 30rpx;
-      color: $red;
-    }
-  }
-
-  // sm
-  .sm-goods-card {
-    overflow: hidden;
-    // width: 223rpx;
-    // width: 100%;
-    background-color: $white;
-    position: relative;
-
-    .sm-img-box {
-      // width: 228rpx;
-      width: 100%;
-      height: 208rpx;
-    }
-    .sm-goods-content {
-      padding: 20rpx 16rpx;
-      box-sizing: border-box;
-    }
-    .sm-goods-title {
-      font-size: 26rpx;
-      color: #333;
-    }
-
-    .sm-goods-price {
-      font-size: 30rpx;
-      color: $red;
-    }
-  }
-
-  // md
-  .md-goods-card {
-    overflow: hidden;
-    width: 100%;
-    position: relative;
-    z-index: 1;
-    background-color: $white;
-    position: relative;
-
-    .md-img-box {
-      width: 100%;
-    }
-
-    .md-goods-title {
-      font-size: 26rpx;
-      color: #333;
-      width: 100%;
-    }
-    .md-goods-subtitle {
-      font-size: 24rpx;
-      font-weight: 400;
-      color: #999999;
-    }
-
-    .md-goods-price {
-      font-size: 30rpx;
-      color: $red;
-      line-height: 36rpx;
-    }
-
-    .cart-box {
-      width: 54rpx;
-      height: 54rpx;
-      background: linear-gradient(90deg, #fe8900, #ff5e00);
-      border-radius: 50%;
-      position: absolute;
-      bottom: 50rpx;
-      right: 20rpx;
-      z-index: 2;
-
-      .cart-icon {
-        width: 30rpx;
-        height: 30rpx;
-      }
-    }
-  }
-
-  // lg
-  .lg-goods-card {
-    overflow: hidden;
-    position: relative;
-    z-index: 1;
-    background-color: $white;
-    height: 280rpx;
-
-    .lg-img-box {
-      width: 280rpx;
-      height: 280rpx;
-      margin-right: 20rpx;
-    }
-
-    .lg-goods-title {
-      font-size: 28rpx;
-      font-weight: 500;
-      color: #333333;
-      // line-height: 36rpx;
-      // width: 410rpx;
-    }
-    .lg-goods-subtitle {
-      font-size: 24rpx;
-      font-weight: 400;
-      color: #999999;
-      // line-height: 30rpx;
-      // width: 410rpx;
-    }
-
-    .lg-goods-price {
-      font-size: 30rpx;
-      color: $red;
-      line-height: 36rpx;
-    }
-
-    .buy-box {
-      position: absolute;
-      bottom: 20rpx;
-      right: 20rpx;
-      z-index: 2;
-      width: 120rpx;
-      height: 50rpx;
-      background: linear-gradient(90deg, #fe8900, #ff5e00);
-      border-radius: 25rpx;
-      font-size: 24rpx;
-      color: #ffffff;
-    }
-    .tag-box {
-      width: 100%;
-    }
-  }
-
-  // sl
-
-  .sl-goods-card {
-    overflow: hidden;
-    position: relative;
-    z-index: 1;
-    width: 100%;
-    background-color: $white;
-    .sl-goods-content {
-      padding: 20rpx 20rpx;
-      box-sizing: border-box;
-    }
-    .sl-img-box {
-      width: 100%;
-      height: 360rpx;
-    }
-
-    .sl-goods-title {
-      font-size: 26rpx;
-      color: #333;
-      font-weight: 500;
-    }
-    .sl-goods-subtitle {
-      font-size: 24rpx;
-      font-weight: 400;
-      color: #999999;
-      line-height: 30rpx;
-    }
-
-    .sl-goods-price {
-      font-size: 30rpx;
-      color: $red;
-      line-height: 36rpx;
-    }
-
-    .buy-box {
-      position: absolute;
-      bottom: 20rpx;
-      right: 20rpx;
-      z-index: 2;
-      width: 148rpx;
-      height: 50rpx;
-      background: linear-gradient(90deg, #fe8900, #ff5e00);
-      border-radius: 25rpx;
-      font-size: 24rpx;
-      color: #ffffff;
-    }
-  }
-</style>
+	.origin-price-text {
+		font-size: 22rpx;
+		font-weight: 400;
+		color: $gray-c;
+		font-family: OPPOSANS;
+		background: #ffca3e;
+		padding: 2px 8px;
+		border-radius: 4px;
+		display:inline-block;
+		color: #597533;
+	}
+
+	.tag-icon-box {
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 2;
+
+		.tag-icon {
+			width: 72rpx;
+			height: 44rpx;
+		}
+	}
+
+	.seckill-tag {
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 2;
+		width: 68rpx;
+		height: 38rpx;
+		background: linear-gradient(90deg, #ff5854 0%, #ff2621 100%);
+		border-radius: 10rpx 0px 10rpx 0px;
+		font-size: 24rpx;
+		font-weight: 500;
+		color: #ffffff;
+		line-height: 32rpx;
+	}
+
+	.groupon-tag {
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 2;
+		width: 68rpx;
+		height: 38rpx;
+		background: linear-gradient(90deg, #fe832a 0%, #ff6600 100%);
+		border-radius: 10rpx 0px 10rpx 0px;
+		font-size: 24rpx;
+		font-weight: 500;
+		color: #ffffff;
+		line-height: 32rpx;
+	}
+
+	.goods-img {
+		width: 100%;
+		height: 100%;
+		background-color: #f5f5f5;
+	}
+
+	.price-unit {
+		margin-right: -4px;
+	}
+
+	.sales-text {
+		display: table;
+		font-size: 24rpx;
+		transform: scale(0.8);
+		margin-left: 0rpx;
+		color: #c4c4c4;
+	}
+
+	.activity-tag {
+		font-size: 20rpx;
+		color: #ff0000;
+		line-height: 30rpx;
+		padding: 0 10rpx;
+		border: 1px solid rgba(#ff0000, 0.25);
+		border-radius: 4px;
+		flex-shrink: 0;
+	}
+
+	.goods-origin-price {
+		font-size: 20rpx;
+		color: #c4c4c4;
+		line-height: 36rpx;
+		text-decoration: line-through;
+	}
+
+	// xs
+	.xs-goods-card {
+		overflow: hidden;
+		// max-width: 375rpx;
+		background-color: $white;
+		position: relative;
+
+		.xs-img-box {
+			width: 128rpx;
+			height: 128rpx;
+			margin-right: 20rpx;
+		}
+
+		.xs-goods-title {
+			font-size: 26rpx;
+			color: #333;
+			font-weight: 500;
+		}
+
+		.xs-goods-price {
+			font-size: 30rpx;
+			color: $red;
+		}
+	}
+
+	// sm
+	.sm-goods-card {
+		overflow: hidden;
+		// width: 223rpx;
+		// width: 100%;
+		background-color: $white;
+		position: relative;
+
+		.sm-img-box {
+			// width: 228rpx;
+			width: 100%;
+			height: 208rpx;
+		}
+
+		.sm-goods-content {
+			padding: 20rpx 16rpx;
+			box-sizing: border-box;
+		}
+
+		.sm-goods-title {
+			font-size: 26rpx;
+			color: #333;
+		}
+
+		.sm-goods-price {
+			font-size: 30rpx;
+			color: $red;
+		}
+	}
+
+	// md
+	.md-goods-card {
+		overflow: hidden;
+		width: 100%;
+		position: relative;
+		z-index: 1;
+		background-color: $white;
+		position: relative;
+
+		.md-img-box {
+			width: 100%;
+		}
+
+		.md-goods-title {
+			font-size: 26rpx;
+			color: #333;
+			width: 100%;
+		}
+
+		.md-goods-subtitle {
+			font-size: 24rpx;
+			font-weight: 400;
+			color: #999999;
+		}
+
+		.md-goods-price {
+			font-size: 30rpx;
+			color: $red;
+			line-height: 36rpx;
+		}
+
+		.cart-box {
+			width: 54rpx;
+			height: 54rpx;
+			background: linear-gradient(90deg, #fe8900, #ff5e00);
+			border-radius: 50%;
+			position: absolute;
+			bottom: 50rpx;
+			right: 20rpx;
+			z-index: 2;
+
+			.cart-icon {
+				width: 30rpx;
+				height: 30rpx;
+			}
+		}
+	}
+
+	// lg
+	.lg-goods-card {
+		overflow: hidden;
+		position: relative;
+		z-index: 1;
+		background-color: $white;
+		height: 280rpx;
+
+		.lg-img-box {
+			width: 280rpx;
+			height: 280rpx;
+			margin-right: 20rpx;
+		}
+
+		.lg-goods-title {
+			font-size: 28rpx;
+			font-weight: 500;
+			color: #333333;
+			// line-height: 36rpx;
+			// width: 410rpx;
+		}
+
+		.lg-goods-subtitle {
+			font-size: 24rpx;
+			font-weight: 400;
+			color: #999999;
+			// line-height: 30rpx;
+			// width: 410rpx;
+		}
+
+		.lg-goods-price {
+			font-size: 30rpx;
+			color: $red;
+			line-height: 36rpx;
+		}
+
+		.buy-box {
+			position: absolute;
+			bottom: 20rpx;
+			right: 20rpx;
+			z-index: 2;
+			width: 120rpx;
+			height: 50rpx;
+			background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+			border-radius: 25rpx;
+			font-size: 24rpx;
+			color: #ffffff;
+		}
+
+		.tag-box {
+			width: 100%;
+		}
+	}
+
+	// sl
+
+	.sl-goods-card {
+		overflow: hidden;
+		position: relative;
+		z-index: 1;
+		width: 100%;
+		background-color: $white;
+
+		.sl-goods-content {
+			padding: 20rpx 20rpx;
+			box-sizing: border-box;
+		}
+
+		.sl-img-box {
+			width: 100%;
+			height: 360rpx;
+		}
+
+		.sl-goods-title {
+			font-size: 26rpx;
+			color: #333;
+			font-weight: 500;
+		}
+
+		.sl-goods-subtitle {
+			font-size: 24rpx;
+			font-weight: 400;
+			color: #999999;
+			line-height: 30rpx;
+		}
+
+		.sl-goods-price {
+			font-size: 30rpx;
+			color: $red;
+			line-height: 36rpx;
+		}
+
+		.buy-box {
+			position: absolute;
+			bottom: 20rpx;
+			right: 20rpx;
+			z-index: 2;
+			width: 148rpx;
+			height: 50rpx;
+			background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+			border-radius: 25rpx;
+			font-size: 24rpx;
+			color: #ffffff;
+		}
+	}
+</style>

+ 229 - 231
sheep/components/s-layout/s-layout.vue

@@ -1,243 +1,241 @@
 <template>
-  <view
-    class="page-app"
-    :class="['theme-' + sys.mode, 'main-' + sys.theme, 'font-' + sys.fontSize]"
-  >
-    <view class="page-main" :style="[bgMain]">
-		
-      <!-- 默认通用顶部导航栏 -->
-      <su-navbar
-        v-if="navbar === 'normal'"
-        :title="title"
-        statusBar
-        :color="color"
-        :tools="tools"
-        :opacityBgUi="opacityBgUi"
-        @search="(e) => emits('search', e)"
-        :defaultSearch="defaultSearch"
-      />
-
-      <!-- 装修组件导航栏-普通 -->
-      <s-custom-navbar
-        v-else-if="navbar === 'custom' && navbarMode === 'normal'"
-        :data="navbarStyle"
-        :showLeftButton="showLeftButton"
-      />
-      <view class="page-body" :style="[bgBody]">
-        <!-- 沉浸式头部 -->
-        <su-inner-navbar v-if="navbar === 'inner'" :title="title" />
-        <view
-          v-if="navbar === 'inner'"
-          :style="[{ paddingTop: sheep.$platform.navbar + 'px' }]"
-        ></view>
-
-        <!-- 装修组件导航栏-沉浸式 -->
-        <!-- <s-custom-navbar v-if="navbar === 'custom' && navbarMode === 'inner'" :data="navbarStyle" :showLeftButton="showLeftButton" /> -->
-
-        <!-- 页面内容插槽 -->
-        <slot />
-
-        <!-- 底部导航 -->
-        <s-tabbar v-if="tabbar !== ''" :path="tabbar" />
-      </view>
-    </view>
-
-    <view class="page-modal">
-      <!-- 全局授权弹窗 -->
-      <s-auth-modal />
-      <!-- 全局分享弹窗 -->
-      <s-share-modal :shareInfo="shareInfo" />
-      <!-- 全局快捷入口 -->
-      <s-menu-tools />
-    </view>
-  </view>
+	<view class="page-app" :class="['theme-' + sys.mode, 'main-' + sys.theme, 'font-' + sys.fontSize]">
+		<view class="page-main" :style="[bgMain]">
+
+			<!-- 默认通用顶部导航栏 -->
+			<su-navbar v-if="navbar === 'normal'" :title="title" statusBar :color="color" :tools="tools"
+				:opacityBgUi="opacityBgUi" @search="(e) => emits('search', e)" :defaultSearch="defaultSearch" />
+
+			<!-- 装修组件导航栏-普通 -->
+			<s-custom-navbar v-else-if="navbar === 'custom' && navbarMode === 'normal'" :data="navbarStyle"
+				:showLeftButton="showLeftButton" />
+			<view class="page-body" :style="[bgBody]">
+				<!-- 沉浸式头部 -->
+				<su-inner-navbar v-if="navbar === 'inner'" :title="title" />
+				<view v-if="navbar === 'inner'" :style="[{ paddingTop: sheep.$platform.navbar + 'px' }]"></view>
+
+				<!-- 装修组件导航栏-沉浸式 -->
+				<!-- <s-custom-navbar v-if="navbar === 'custom' && navbarMode === 'inner'" :data="navbarStyle" :showLeftButton="showLeftButton" /> -->
+
+				<!-- 页面内容插槽 -->
+				<slot />
+
+				<!-- 底部导航 -->
+				<s-tabbar v-if="tabbar !== ''" :path="tabbar" />
+			</view>
+		</view>
+
+		<view class="page-modal">
+			<!-- 全局获得积分提示弹窗 -->
+			<s-wallet-modal />
+			<!-- 全局自动签到弹窗 -->
+			<s-signup-modal />
+			<!-- 全局授权弹窗 -->
+			<s-auth-modal />
+			<!-- 全局分享弹窗 -->
+			<s-share-modal :shareInfo="shareInfo" />
+			<!-- 全局快捷入口 -->
+			<s-menu-tools />
+		</view>
+	</view>
 </template>
 
 <script setup>
-  /**
-   * 模板组件 - 提供页面公共组件,属性,方法
-   */
-  import { computed, reactive, ref } from 'vue';
-  import sheep from '@/sheep';
-  import { isEmpty } from 'lodash';
-  import { onShow } from '@dcloudio/uni-app';
-  // #ifdef MP-WEIXIN
-  import { onShareAppMessage } from '@dcloudio/uni-app';
-  // #endif
-
-  const props = defineProps({
-    title: {
-      type: String,
-      default: '',
-    },
-    navbar: {
-      type: String,
-      default: 'normal',
-    },
-    opacityBgUi: {
-      type: String,
-      default: 'bg-white',
-    },
-    color: {
-      type: String,
-      default: '',
-    },
-    tools: {
-      type: String,
-      default: 'title',
-    },
-    keyword: {
-      type: String,
-      default: '',
-    },
-    navbarStyle: {
-      type: Object,
-      default: () => ({
-        mode: '',
-        type: '',
-        color: '',
-        src: '',
-        list: [],
-        alwaysShow: 0,
-      }),
-    },
-    bgStyle: {
-      type: Object,
-      default: () => ({
-        src: '',
-        color: 'var(--ui-BG-1)',
-      }),
-    },
-    tabbar: {
-      type: [String, Boolean],
-      default: '',
-    },
-    onShareAppMessage: {
-      type: [Boolean, Object],
-      default: true,
-    },
-    leftWidth: {
-      type: [Number, String],
-      default: 100,
-    },
-    rightWidth: {
-      type: [Number, String],
-      default: 100,
-    },
-    defaultSearch: {
-      type: String,
-      default: '',
-    },
-    //展示返回按钮
-    showLeftButton: {
-      type: Boolean,
-      default: false,
-    },
-  });
-  const emits = defineEmits(['search']);
-
-  const sysStore = sheep.$store('sys');
-  const userStore = sheep.$store('user');
-  const appStore = sheep.$store('app');
-  const modalStore = sheep.$store('modal');
-  const sys = computed(() => sysStore);
-
-  // 导航栏模式(因为有自定义导航栏 需要计算)
-  const navbarMode = computed(() => {
-    if (props.navbar === 'normal' || props.navbarStyle.mode === 'normal') {
-      return 'normal';
-    }
-    return 'inner';
-  });
-
-  // 背景1
-  const bgMain = computed(() => {
-    if (navbarMode.value === 'inner') {
-      return {
-        background: `${props.bgStyle.backgroundColor} url(${sheep.$url.cdn(
+	/**
+	 * 模板组件 - 提供页面公共组件,属性,方法
+	 */
+	import {
+		computed,
+		reactive,
+		ref
+	} from 'vue';
+	import sheep from '@/sheep';
+	import {
+		isEmpty
+	} from 'lodash';
+	import {
+		onShow
+	} from '@dcloudio/uni-app';
+	// #ifdef MP-WEIXIN
+	import {
+		onShareAppMessage
+	} from '@dcloudio/uni-app';
+	// #endif
+
+	const props = defineProps({
+		title: {
+			type: String,
+			default: '',
+		},
+		navbar: {
+			type: String,
+			default: 'normal',
+		},
+		opacityBgUi: {
+			type: String,
+			default: 'bg-white',
+		},
+		color: {
+			type: String,
+			default: '',
+		},
+		tools: {
+			type: String,
+			default: 'title',
+		},
+		keyword: {
+			type: String,
+			default: '',
+		},
+		navbarStyle: {
+			type: Object,
+			default: () => ({
+				mode: '',
+				type: '',
+				color: '',
+				src: '',
+				list: [],
+				alwaysShow: 0,
+			}),
+		},
+		bgStyle: {
+			type: Object,
+			default: () => ({
+				src: '',
+				color: 'var(--ui-BG-1)',
+			}),
+		},
+		tabbar: {
+			type: [String, Boolean],
+			default: '',
+		},
+		onShareAppMessage: {
+			type: [Boolean, Object],
+			default: true,
+		},
+		leftWidth: {
+			type: [Number, String],
+			default: 100,
+		},
+		rightWidth: {
+			type: [Number, String],
+			default: 100,
+		},
+		defaultSearch: {
+			type: String,
+			default: '',
+		},
+		//展示返回按钮
+		showLeftButton: {
+			type: Boolean,
+			default: false,
+		},
+	});
+	const emits = defineEmits(['search']);
+
+	const sysStore = sheep.$store('sys');
+	const userStore = sheep.$store('user');
+	const appStore = sheep.$store('app');
+	const modalStore = sheep.$store('modal');
+	const sys = computed(() => sysStore);
+
+	// 导航栏模式(因为有自定义导航栏 需要计算)
+	const navbarMode = computed(() => {
+		if (props.navbar === 'normal' || props.navbarStyle.mode === 'normal') {
+			return 'normal';
+		}
+		return 'inner';
+	});
+
+	// 背景1
+	const bgMain = computed(() => {
+		if (navbarMode.value === 'inner') {
+			return {
+				background: `${props.bgStyle.backgroundColor} url(${sheep.$url.cdn(
           props.bgStyle.backgroundImage,
         )}) no-repeat top center / 100% auto`,
-      };
-    }
-    return {};
-  });
-
-  // 背景2
-  const bgBody = computed(() => {
-    if (navbarMode.value === 'normal') {
-      return {
-        background: `${props.bgStyle.backgroundColor} url(${sheep.$url.cdn(
+			};
+		}
+		return {};
+	});
+
+	// 背景2
+	const bgBody = computed(() => {
+		if (navbarMode.value === 'normal') {
+			return {
+				background: `${props.bgStyle.backgroundColor} url(${sheep.$url.cdn(
           props.bgStyle.backgroundImage,
         )}) no-repeat top center / 100% auto`,
-      };
-    }
-    return {};
-  });
-
-  // 分享信息
-  const shareInfo = computed(() => {
-    if (props.onShareAppMessage === true) {
-      return sheep.$platform.share.getShareInfo();
-    } else {
-      if (!isEmpty(props.onShareAppMessage)) {
-        sheep.$platform.share.updateShareInfo(props.onShareAppMessage);
-        return props.onShareAppMessage;
-      }
-    }
-    return {};
-  });
-
-  // #ifdef MP-WEIXIN
-  // 微信小程序分享
-  onShareAppMessage(() => {
-    return {
-      title: shareInfo.value.title,
-      path: shareInfo.value.path,
-      imageUrl: shareInfo.value.image,
-    };
-  });
-  // #endif
-
-  onShow(() => {
-    if (!isEmpty(shareInfo.value)) {
-      sheep.$platform.share.updateShareInfo(shareInfo.value);
-    }
-  });
+			};
+		}
+		return {};
+	});
+
+	// 分享信息
+	const shareInfo = computed(() => {
+		if (props.onShareAppMessage === true) {
+			return sheep.$platform.share.getShareInfo();
+		} else {
+			if (!isEmpty(props.onShareAppMessage)) {
+				sheep.$platform.share.updateShareInfo(props.onShareAppMessage);
+				return props.onShareAppMessage;
+			}
+		}
+		return {};
+	});
+
+	// #ifdef MP-WEIXIN
+	// 微信小程序分享
+	onShareAppMessage(() => {
+		return {
+			title: shareInfo.value.title,
+			path: shareInfo.value.path,
+			imageUrl: shareInfo.value.image,
+		};
+	});
+	// #endif
+
+	onShow(() => {
+		if (!isEmpty(shareInfo.value)) {
+			sheep.$platform.share.updateShareInfo(shareInfo.value);
+		}
+	});
 </script>
 
 <style lang="scss" scoped>
-  .page-app {
-    position: relative;
-    color: var(--ui-TC);
-    background-color: var(--ui-BG-1) !important;
-    z-index: 2;
-    display: flex;
-    width: 100%;
-    height: 100vh;
-
-    .page-main {
-      position: absolute;
-      z-index: 1;
-      width: 100%;
-      min-height: 100%;
-      display: flex;
-      flex-direction: column;
+	.page-app {
+		position: relative;
+		color: var(--ui-TC);
 		background-color: var(--ui-BG-1) !important;
-      .page-body {
-        width: 100%;
-        position: relative;
-        z-index: 1;
-        flex: 1;
-      }
-
-      .page-img {
-        width: 100vw;
-        height: 100vh;
-        position: absolute;
-        top: 0;
-        left: 0;
-        z-index: 0;
-      }
-    }
-  }
-</style>
+		z-index: 2;
+		display: flex;
+		width: 100%;
+		height: 100vh;
+
+		.page-main {
+			position: absolute;
+			z-index: 1;
+			width: 100%;
+			min-height: 100%;
+			display: flex;
+			flex-direction: column;
+			background-color: var(--ui-BG-1) !important;
+
+			.page-body {
+				width: 100%;
+				position: relative;
+				z-index: 1;
+				flex: 1;
+			}
+
+			.page-img {
+				width: 100vw;
+				height: 100vh;
+				position: absolute;
+				top: 0;
+				left: 0;
+				z-index: 0;
+			}
+		}
+	}
+</style>

+ 3 - 3
sheep/components/s-live-card/s-live-card.vue

@@ -104,15 +104,15 @@
   const state = reactive({
     liveStatus: {
       101: {
-        img: sheep.$url.static('/static/img/shop/app/mplive/living.png'),
+        img: sheep.$url.static('/static/images/living.png'),
         title: '直播中',
       },
       102: {
-        img: sheep.$url.static('/static/img/shop/app/mplive/start.png'),
+        img: sheep.$url.static('/static/images/start.png'),
         title: '未开始',
       },
       103: {
-        img: sheep.$url.static('/static/img/shop/app/mplive/ended.png'),
+        img: sheep.$url.static('/static/images/ended.png'),
         title: '已结束',
       },
     },

+ 7 - 7
sheep/components/s-menu-tools/s-menu-tools.vue

@@ -36,37 +36,37 @@
   const list = [
     {
       url: '/pages/index/index',
-      icon: '/static/img/shop/tools/home.png',
+      icon: '/static/images/home.png',
       title: '首页',
     },
     {
       url: '/pages/index/search',
-      icon: '/static/img/shop/tools/search.png',
+      icon: '/static/images/search.png',
       title: '搜索',
     },
     {
       url: '/pages/index/user',
-      icon: '/static/img/shop/tools/user.png',
+      icon: '/static/images/user.png',
       title: '个人中心',
     },
     {
       url: '/pages/index/cart',
-      icon: '/static/img/shop/tools/cart.png',
+      icon: '/static/images/cart.png',
       title: '购物车',
     },
     {
       url: '/pages/user/goods-log',
-      icon: '/static/img/shop/tools/browse.png',
+      icon: '/static/images/browse.png',
       title: '浏览记录',
     },
     {
       url: '/pages/user/goods-collect',
-      icon: '/static/img/shop/tools/collect.png',
+      icon: '/static/images/collect.png',
       title: '我的收藏',
     },
     {
       url: '/pages/chat/index',
-      icon: '/static/img/shop/tools/service.png',
+      icon: '/static/images/service.png',
       title: '客服',
     },
   ];

+ 13 - 12
sheep/components/s-order-card/s-order-card.vue

@@ -31,15 +31,23 @@
     {
       title: '待付款',
       value: '1',
-      icon: '/static/img/shop/order/no_pay.png',
+      icon: '/static/images/no_pay.png',
       path: '/pages/order/list',
       type: 'unpaid',
       count: 'unpaidCount',
     },
+	{
+	  title: '待发货',
+	  value: '2',
+	  icon: '/static/images/change_order.png',
+	  path: '/pages/order/list',
+	  type: 'undelivered',
+	  count: 'undeliveredCount',
+	},
     {
       title: '待收货',
       value: '3',
-      icon: '/static/img/shop/order/no_take.png',
+      icon: '/static/images/no_take.png',
       path: '/pages/order/list',
       type: 'noget',
       count: 'deliveredCount',
@@ -47,23 +55,16 @@
     {
       title: '待评价',
       value: '4',
-      icon: '/static/img/shop/order/no_comment.png',
+      icon: '/static/images/no_comment.png',
       path: '/pages/order/list',
       type: 'nocomment',
       count: 'uncommentedCount',
     },
-    {
-      title: '售后单',
-      value: '0',
-      icon: '/static/img/shop/order/change_order.png',
-      path: '/pages/order/aftersale/list',
-      type: 'aftersale',
-      count: 'afterSaleCount',
-    },
+    
     {
       title: '全部订单',
       value: '0',
-      icon: '/static/img/shop/order/all_order.png',
+      icon: '/static/images/all_order.png',
       path: '/pages/order/list',
     },
   ];

+ 9 - 9
sheep/components/s-points-pop/s-points-pop.vue

@@ -1,14 +1,14 @@
-<!-- 订单确认的使用积分弹窗 -->
+<!-- 订单确认的使用数字权益弹窗 -->
 <template>
 	<su-popup :show="show" type="bottom" round="10" @close="emits('close')" showClose backgroundColor="#ffffff">
-		<view class="title ss-m-t-16 ss-m-l-20 ss-flex">使用积分</view>
+		<view class="title ss-m-t-16 ss-m-l-20 ss-flex">使用数字权益</view>
 		<view class="model-box ss-p-x-30">
 			<input v-model.number="state.points" class="uni-input input-points ss-m-b-10" type="number"
-				placeholder="请输入抵扣积分" oninput="this.value=this.value.replace(/\D/g);" :disabled="state.disabled"/>
+				placeholder="请输入抵扣数字权益" oninput="this.value=this.value.replace(/\D/g);" :disabled="state.disabled"/>
 		</view>
 		<view class="modal-footer text-center">
-			<view class="subtitle text-disabled">您的可用积分<text class="text-red">{{currentMemberPoints}}</text></view>
-			<view class="subtitle text-disabled">当前订单价格<text class="text-red">¥{{currentOrderTotalPrice}}</text>,可使用最高<text class="text-red"> {{canUesPoint}} </text>积分 </view>
+			<view class="subtitle text-disabled">您的可用数字权益<text class="text-red">{{currentMemberPoints}}</text></view>
+			<view class="subtitle text-disabled">当前订单价格<text class="text-red">¥{{currentOrderTotalPrice}}</text>,可使用最高<text class="text-red"> {{canUesPoint}} </text>数字权益 </view>
 			<view class="ss-flex ss-m-y-20 ss-col-center">
 				<button class="confirm-btn ss-reset-button"
 					@tap="state.points = 0;emits('confirm', state.points)">取消</button>
@@ -64,28 +64,28 @@
 		return parseFloat(props.currentDeliveryPrice)
 	})
 	
-	// 当前可使用的最高积分 = 当前的总价格 - 0.01分钱(即最低也要给1分钱) 并且积分只能是正数 且不能抵扣运费
+	// 当前可使用的最高数字权益 = 当前的总价格 - 0.01分钱(即最低也要给1分钱) 并且数字权益只能是正数 且不能抵扣运费
 	const canUesPoint = computed(()=>{
 		// console.log("state.currentTotalPrice",currentOrderTotalPrice.value - 1)
 		if(!currentOrderTotalPrice.value) return currentOrderTotalPrice.value
 		return (currentOrderTotalPrice.value - 0.01 - currentOrderDeliveryPrice.value).toFixed(2)
 	})
 	watchEffect(() => {
-		// 使用积分不能大于可用积分
+		// 使用数字权益不能大于可用数字权益
 		if (state.points > currentOrderMemberPoints.value) {
 			// 使用 nextTick 确保 DOM 更新
 			nextTick(() => {
 				state.points = currentOrderMemberPoints.value;
 			});
 		}
-		// 使用积分不能大于当前可以使用的最大积分
+		// 使用数字权益不能大于当前可以使用的最大数字权益
 		if (state.points > canUesPoint.value) {
 			nextTick(() => {
 				state.points = canUesPoint.value;
 			});
 		}
 
-		// 如果计算出来的当前可以使用的最大积分等于小于0 则不给输入
+		// 如果计算出来的当前可以使用的最大数字权益等于小于0 则不给输入
 		if(canUesPoint.value == 0 || canUesPoint.value < 0){
 			state.disabled = true
 		}

+ 2 - 2
sheep/components/s-select-groupon-sku/s-select-groupon-sku.vue

@@ -12,7 +12,7 @@
             <view class="tig ss-flex ss-col-center">
               <view class="tig-icon ss-flex ss-col-center ss-row-center">
                 <view class="groupon-tag">
-                  <image :src="sheep.$url.static('/static/img/shop/goods/groupon-tag-white.png')" />
+                  <image :src="sheep.$url.static('/static/images/groupon-tag-white.png')" />
                 </view>
               </view>
               <view class="tig-title">拼团价</view>
@@ -79,7 +79,7 @@
   import sheep from '@/sheep';
   import {convertProductPropertyList, fen2yuan} from '@/sheep/hooks/useGoods';
 
-  const headerBg = sheep.$url.css('/static/img/shop/goods/groupon-btn-long.png');
+  const headerBg = sheep.$url.css('/static/images/groupon-btn-long.png');
   const emits = defineEmits(['change', 'addCart', 'buy', 'close', 'ladder']);
   const props = defineProps({
     show: {

+ 194 - 48
sheep/components/s-select-sku/s-select-sku.vue

@@ -5,14 +5,37 @@
 		<view class="ss-modal-box bg-white ss-flex-col">
 			<view class="modal-header ss-flex ss-col-center">
 				<view class="header-left ss-m-r-30">
-					<image class="sku-image" :src="state.selectedSku.picUrl || goodsInfo.picUrl" mode="aspectFill" />
+					<image
+						class="sku-image"
+						:src="state.selectedSku.picUrl || goodsInfo.picUrl"
+						mode="aspectFill"
+					/>
 				</view>
 				<view class="header-right ss-flex-col ss-row-between ss-flex-1">
 					<view class="goods-title ss-line-2">{{ goodsInfo.name }}</view>
 					<view class="header-right-bottom ss-flex ss-col-center ss-row-between">
 						<view class="ss-flex">
 							<view class="price-text">
-								{{ fen2yuan( state.selectedSku.price || goodsInfo.price) }}
+								<image
+									src="@/static/icon/points.png"
+									v-if="goodsInfo.spuPayType == 2"
+									style="width: 30rpx; height: 30rpx"
+								></image>
+								<text v-else>¥</text>
+								{{ fen2yuan(state.selectedSku.price || goodsInfo.price) }}
+							</view>
+							<view
+								class="origin-price-text ss-m-l-10"
+								v-if="
+									state.selectedSku.promotionFee >= 0 ||
+									goodsInfo.promotionFee >= 0
+								"
+							>
+								数字权益:{{
+									fen2yuan(
+										state.selectedSku.promotionFee || goodsInfo.promotionFee,
+									)
+								}}
 							</view>
 						</view>
 						<view class="stock-text ss-m-l-20">
@@ -25,34 +48,92 @@
 			<!-- 属性选择 -->
 			<view class="modal-content ss-flex-1">
 				<scroll-view scroll-y="true" class="modal-content-scroll" @touchmove.stop>
-					<view class="sku-item ss-m-b-20" v-for="property in propertyList" :key="property.id">
+					<view
+						class="sku-item ss-m-b-20"
+						v-for="property in propertyList"
+						:key="property.id"
+					>
 						<view class="label-text ss-m-b-20">{{ property.name }}</view>
 						<view class="ss-flex ss-col-center ss-flex-wrap">
-							<button class="ss-reset-button spec-btn" v-for="value in property.values" :class="[
-                  {
-                    'ui-BG-Main-Gradient': state.currentPropertyArray[property.id] === value.id,
-                  },
-                  {
-                    'disabled-btn': value.disabled === true,
-                  },
-                ]" :key="value.id" :disabled="value.disabled === true" @tap="onSelectSku(property.id, value.id)">
+							<button
+								class="ss-reset-button spec-btn"
+								v-for="value in property.values"
+								:class="[
+									{
+										'ui-BG-Main-Gradient':
+											state.currentPropertyArray[property.id] === value.id,
+									},
+									{
+										'disabled-btn': value.disabled === true,
+									},
+								]"
+								:key="value.id"
+								:disabled="value.disabled === true"
+								@tap="onSelectSku(property.id, value.id)"
+							>
 								{{ value.name }}
 							</button>
 						</view>
 					</view>
-					<view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40">
+					<view
+						class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40"
+						v-if="goodsInfo.spuPayType == 2"
+					>
+						<view class="label-text"
+							>购买金额 (当前可用数字权益:{{
+								points2point(userWallet.integralDO.currentQuota)
+							}})</view
+						>
+						<view class="ss-flex ss-col-center">
+							<image
+								src="@/static/icon/points.png"
+								v-if="goodsInfo.spuPayType == 2"
+								style="width: 30rpx; height: 30rpx"
+							></image>
+							
+							<input
+								v-model="state.selectedSku.use_points"
+								class="uni-input input-points"
+								style="width: 100rpx; text-align: center"
+								type="number"
+								placeholder="0"
+								@input="inputPoints"
+								:disabled="!state.selectedSku.id"
+							/>
+						</view>
+					</view>
+					<view class="buy-num-box ss-flex ss-col-center ss-row-between ss-m-b-40" v-else>
 						<view class="label-text">购买数量</view>
-						<su-number-box :min="1" :max="state.selectedSku.stock" :step="1"
-							v-model="state.selectedSku.goods_num" @change="onNumberChange($event)" />
+						<su-number-box
+							:min="1"
+							:max="state.selectedSku.stock"
+							:step="1"
+							v-model="state.selectedSku.goods_num"
+							@change="onNumberChange($event)"
+						/>
 					</view>
 				</scroll-view>
 			</view>
-
 			<!-- 操作区 -->
 			<view class="modal-footer border-top">
-				<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center">
-					<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart">加入购物车</button>
-					<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy">立即购买</button>
+				<view
+					class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center"
+					v-if="goodsInfo.spuType && goodsInfo.spuPayType == 1"
+				>
+					<button class="ss-reset-button add-btn ui-Shadow-Main" @tap="onAddCart"
+						>加入购物车</button
+					>
+					<button class="ss-reset-button buy-btn ui-Shadow-Main" @tap="onBuy"
+						>立即购买</button
+					>
+				</view>
+				<view
+					class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center"
+					v-else
+				>
+					<button class="ss-reset-button one-buy-btn ui-Shadow-Main" @tap="onBuy"
+						>立即购买</button
+					>
 				</view>
 			</view>
 		</view>
@@ -60,52 +141,79 @@
 </template>
 
 <script setup>
-	import {
-		computed,
-		reactive,
-		watch,
-		onMounted
-	} from 'vue';
+	import { computed, reactive, watch, onMounted,nextTick } from 'vue';
 	import sheep from '@/sheep';
 	import {
 		formatStock,
 		convertProductPropertyList,
-		fen2yuan
+		fen2yuan,
+		points2point,
+		
 	} from '@/sheep/hooks/useGoods';
-	
+
 	const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
 	const props = defineProps({
 		goodsInfo: {
 			type: Object,
-			default () {},
+			default() {},
 		},
 		show: {
 			type: Boolean,
 			default: false,
-		}
+		},
 	});
-
+	const userWallet = computed(() => sheep.$store('user').userWallet);
 	const state = reactive({
 		selectedSku: {}, // 选中的 SKU
 		currentPropertyArray: [], // 当前选中的属性,实际是个 Map。key 是 property 编号,value 是 value 编号
 	});
 
 	const propertyList = convertProductPropertyList(props.goodsInfo.skus);
-	
+
 	// SKU 列表
 	const skuList = computed(() => {
 		let skuPrices = props.goodsInfo.skus;
 		for (let price of skuPrices) {
-			price.value_id_array = price.properties.map((item) => item.valueId)
+			price.value_id_array = price.properties.map((item) => item.valueId);
 		}
 		return skuPrices;
 	});
-
+	function inputPoints(e) {
+		const points = e.detail.value;
+		const userCanUsePoints = parseFloat(points2point(userWallet.value.integralDO.currentQuota));
+		state.selectedSku.goods_num = parseInt(state.selectedSku.use_points / fen2yuan(state.selectedSku.price));
+		
+		if (points > userCanUsePoints) {
+			sheep.$helper.toast('可用数字权益不足');
+			console.log('输入的数字权益大于可用数字权益了', points, userCanUsePoints);
+			nextTick(() => {
+				state.selectedSku.use_points = userCanUsePoints;
+				state.selectedSku.goods_num = parseInt(state.selectedSku.use_points / fen2yuan(state.selectedSku.price));
+			});
+		}
+		
+		// 如果输入的金额转换的商品数大于选中的sku的库存数,提示
+		if(state.selectedSku.use_points / fen2yuan(state.selectedSku.price) > state.selectedSku.stock){
+			sheep.$helper.toast('库存不足,已为您转换到可购买最多数量');
+			nextTick(() => {
+				state.selectedSku.use_points = (state.selectedSku.stock * fen2yuan(state.selectedSku.price) ).toFixed(2)
+				console.log(state.selectedSku.use_points )
+				// console.log(state.selectedSku.stock,fen2yuan( state.selectedSku.price))
+			});
+		}
+		
+		
+		
+		
+		console.log("购买的数量",state.selectedSku.goods_num)
+		console.log(state.selectedSku.use_points )
+	}
 	watch(
 		() => state.selectedSku,
 		(newVal) => {
 			emits('change', newVal);
-		}, {
+		},
+		{
 			immediate: true, // 立即执行
 			deep: true, // 深度监听
 		},
@@ -134,6 +242,17 @@
 
 	// 立即购买
 	function onBuy() {
+		if (props.goodsInfo.spuPayType == 2) {
+			if (state.selectedSku.goods_num < 1 || !state.selectedSku.use_points) {
+				sheep.$helper.toast('输入金额少于可购买数量');
+				return;
+			}
+			// 下单时检测如果
+			if(state.selectedSku.goods_num  > state.selectedSku.stock){
+				state.selectedSku.use_points = (state.selectedSku.stock * fen2yuan(state.selectedSku.price) ).toFixed(2)
+				state.selectedSku.goods_num = state.selectedSku.stock
+			}
+		}
 		if (state.selectedSku.id <= 0) {
 			sheep.$helper.toast('请选择规格');
 			return;
@@ -142,6 +261,7 @@
 			sheep.$helper.toast('库存不足');
 			return;
 		}
+		
 		emits('buy', state.selectedSku);
 	}
 
@@ -214,8 +334,9 @@
 			// 如果当前 property id 不存在于有库存的 SKU 中,则禁用
 			for (let valueIndex in propertyList[propertyIndex]['values']) {
 				propertyList[propertyIndex]['values'][valueIndex]['disabled'] =
-					noChooseValueIds.indexOf(propertyList[propertyIndex]['values'][valueIndex]['id']) <
-					0; // true 禁用 or false 不禁用
+					noChooseValueIds.indexOf(
+						propertyList[propertyIndex]['values'][valueIndex]['id'],
+					) < 0; // true 禁用 or false 不禁用
 			}
 		}
 	}
@@ -245,9 +366,14 @@
 	// 选择规格
 	function onSelectSku(propertyId, valueId) {
 		// console.log(propertyId,valueId)
+		// 清空已输入金额
+		state.selectedSku.use_points = 0;
 		// 清空已选择
 		let isChecked = true; // 选中 or 取消选中
-		if (state.currentPropertyArray[propertyId] !== undefined && state.currentPropertyArray[propertyId] === valueId) {
+		if (
+			state.currentPropertyArray[propertyId] !== undefined &&
+			state.currentPropertyArray[propertyId] === valueId
+		) {
 			// 点击已被选中的,删除并填充 ''
 			isChecked = false;
 			state.currentPropertyArray.splice(propertyId, 1, '');
@@ -279,21 +405,33 @@
 		// 改变 property 禁用状态
 		changeDisabled(isChecked, propertyId, valueId);
 	}
-	
+
 	changeDisabled(false);
-	
+
 	onMounted(() => {
-	  // 如果商品的属性只有一条,则默认选中
-	  if(propertyList.length == 1 && propertyList[0].values.length == 1){
-		  onSelectSku(0,0)
-	  }
-	  // 这里可以处理其他初始化逻辑,但请注意这不会接收到 onLoad 的 options 参数
+		// 如果商品的属性只有一条,则默认选中
+		if (propertyList.length == 1 && propertyList[0].values.length == 1) {
+			onSelectSku(0, 0);
+		}
+		// 这里可以处理其他初始化逻辑,但请注意这不会接收到 onLoad 的 options 参数
 	});
 
 	// TODO 非繁人:待讨论的优化点:1)单规格,要不要默认选中;2)默认要不要选中第一个规格
 </script>
 
 <style lang="scss" scoped>
+	.origin-price-text {
+		font-size: 22rpx;
+		font-weight: 400;
+		color: $gray-c;
+		font-family: OPPOSANS;
+		background: #ffca3e;
+		padding: 2px 8px;
+		border-radius: 4px;
+		display: inline-block;
+		color: #597533;
+	}
+
 	// 购买
 	.buy-box {
 		padding: 10rpx 0;
@@ -314,6 +452,14 @@
 			color: #fff;
 		}
 
+		.one-buy-btn {
+			width: 98%;
+			height: 80rpx;
+			border-radius: 40rpx;
+			background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+			color: #fff;
+		}
+
 		.score-btn {
 			width: 100%;
 			margin: 0 20rpx;
@@ -376,10 +522,10 @@
 				font-family: OPPOSANS;
 
 				&::before {
-					content: '¥';
-					font-size: 30rpx;
-					font-weight: 500;
-					color: $red;
+					// content: '¥';
+					// font-size: 30rpx;
+					// font-weight: 500;
+					// color: $red;
 				}
 			}
 
@@ -424,4 +570,4 @@
 			}
 		}
 	}
-</style>
+</style>

+ 1 - 1
sheep/components/s-share-modal/canvas-poster/index.vue

@@ -91,7 +91,7 @@
 
 
 	async function getPoster(params) {
-
+		// console.log(props.shareInfo)
 		poster.src = '';
 		poster.shareInfo = props.shareInfo;
 		// #ifdef APP-PLUS

+ 1 - 1
sheep/components/s-share-modal/canvas-poster/poster/index.js

@@ -8,13 +8,13 @@ import {
 import FileApi from '@/sheep/api/infra/file';
 let locaImage = ref("")
 async function getFileURL(file) {
-	console.log("file", file)
 	await FileApi.getFileIO(file).then((res) => {
 		locaImage.value = window.URL.createObjectURL(res);
 	})
 }
 export async function getPosterData(options) {
 	const userInfo = sheep.$store('user').userInfo;
+	console.log(JSON.parse(uni.getStorageSync("user-store")))
 	let avatar = userInfo.avatar
 	switch (options.shareInfo.poster.type) {
 		case 'user':

+ 1 - 1
sheep/components/s-share-modal/canvas-poster/poster/user.js

@@ -7,7 +7,7 @@ const user = (poster) => {
   console.log()
   return {
     background: window.location.origin + '/static/user-poster-bg.jpg',
-    // background: formatImageUrlProtocol(sheep.$url.static(sheep.$store('app').platform.share.posterInfo.user_bg)),
+    
     list: [
       {
         name: 'nickname',

+ 3 - 1
sheep/components/s-share-modal/canvas-poster/useCanvas.js

@@ -45,13 +45,14 @@ export default async function useCanvas(options, vm) {
 
 	for (let i = 0; i < list.length; i++) {
 		let item = list[i];
-		console.log(item)
+		
 		// 绘制文字
 		if (item.type === 'text') {
 			await qsc.drawText(item);
 		}
 		// 绘制图片
 		if (item.type === 'image') {
+			
 			if (item.d) {
 				qsc.setCircle({
 					x: item.x,
@@ -99,6 +100,7 @@ export default async function useCanvas(options, vm) {
 		
 		// 绘制二维码
 		if (item.type === 'qrcode') {
+			console.log(item)
 			await qsc.drawQrCode(item);
 		}
 	}

+ 148 - 137
sheep/components/s-share-modal/s-share-modal.vue

@@ -3,7 +3,7 @@
 	<view>
 		<su-popup :show="state.showShareGuide" :showClose="false" @close="onCloseGuide" />
 		<view v-if="state.showShareGuide" class="guide-wrap">
-			<image class="guide-image" :src="sheep.$url.static('/static/img/shop/share/share_guide.png')" />
+			<image class="guide-image" :src="sheep.$url.static('/static/images/share_guide.png')" />
 		</view>
 
 		<su-popup :show="show" round="10" :showClose="false" @close="closeShareModal">
@@ -14,23 +14,21 @@
 					<button v-if="shareConfig.methods.includes('forward')"
 						class="share-item share-btn ss-flex-col ss-col-center" open-type="share"
 						@tap="onShareByForward">
-						<image class="share-img" :src="sheep.$url.static('/static/img/shop/share/share_wx.png')"
-							mode="" />
+						<image class="share-img" :src="sheep.$url.static('/static/images/share_wx.png')" mode="" />
 						<text class="share-title">微信好友</text>
 					</button>
 
 					<!-- 操作 ②:生成海报图片 -->
 					<button v-if="shareConfig.methods.includes('poster')"
 						class="share-item share-btn ss-flex-col ss-col-center" @tap="onShareByPoster">
-						<image class="share-img" :src="sheep.$url.static('/static/img/shop/share/share_poster.png')"
-							mode="" />
+						<image class="share-img" :src="sheep.$url.static('/static/images/share_poster.png')" mode="" />
 						<text class="share-title">生成海报</text>
 					</button>
 
 					<!-- 操作 ③:生成链接 -->
 					<!-- <button v-if="shareConfig.methods.includes('link')"
 						class="share-item share-btn ss-flex-col ss-col-center" @tap="onShareByCopyLink">
-						<image class="share-img" :src="sheep.$url.static('/static/img/shop/share/share_link.png')"
+						<image class="share-img" :src="sheep.$url.static('/static/images/share_link.png')"
 							mode="" />
 						<text class="share-title">复制链接</text>
 					</button> -->
@@ -41,156 +39,169 @@
 			</view>
 		</su-popup>
 		<!-- 分享海报,对应操作 ② -->
-		<canvas-poster ref="SharePosterRef" :show="state.showPosterModal" :shareInfo="shareInfo"
+		<canvas-poster ref="SharePosterRef" :show="state.showPosterModal" :shareInfo="ShareInfo"
 			@close="state.showPosterModal = false" />
 	</view>
 </template>
 <script setup>
-	/**
-	 * 分享弹窗
-	 */
-	import {
-		ref,
-		unref,
-		reactive,
-		computed,
-		inject
-	} from 'vue';
-	import sheep from '@/sheep';
-	import canvasPoster from './canvas-poster/index.vue';
-	import {
-		closeShareModal,
-		showAuthModal
-	} from '@/sheep/hooks/useModal';
+/**
+ * 分享弹窗
+ */
+import {
+	ref,
+	unref,
+	reactive,
+	computed,
 	
-	const show = computed(() => sheep.$store('modal').share);
-	const shareConfig = computed(() => sheep.$store('app').platform.share);
-	const SharePosterRef = ref('');
-
-	const props = defineProps({
-		shareInfo: {
-			type: Object,
-			default () {},
+} from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import sheep from '@/sheep';
+import canvasPoster from './canvas-poster/index.vue';
+import {
+	closeShareModal,
+	showAuthModal
+} from '@/sheep/hooks/useModal';
+import ShareApi from '@/sheep/api/distri/share';
+
+const show = computed(() => sheep.$store('modal').share);
+const shareConfig = computed(() => sheep.$store('app').platform.share);
+const SharePosterRef = ref('');
+
+const props = defineProps({
+	shareInfo: {
+		type: Object,
+		default() { },
+	},
+});
+const state = reactive({
+	showShareGuide: false, // H5 的指引
+	showPosterModal: false, // 海报弹窗
+});
+let ShareInfo = computed(() =>{
+	return {
+		...props.shareInfo
+	}
+});
+
+const onShareByPoster = () => {
+	const shareId = computed(() => sheep.$store('modal').shareInfo.spuId);
+	closeShareModal();
+	if (!sheep.$store('user').isLogin) {
+		showAuthModal();
+		return;
+	}
+	if (shareId.value) {
+		ShareApi.getLinkId(3, shareId.value).then((res) => {
+			if (res.code !== 0) {
+				return;
+			}
+			ShareInfo.value.link = ShareInfo.value.link.replace('0', res.data.linkId);
+			ShareInfo.value.query = ShareInfo.value.query.replace('0', res.data.linkId);
+		});
+	}
+	unref(SharePosterRef).getPoster();
+	state.showPosterModal = true;
+};
+
+// 操作 ①:直接转发分享
+const onShareByForward = () => {
+	closeShareModal();
+
+	// #ifdef H5
+	if (['WechatOfficialAccount', 'H5'].includes(sheep.$platform.name)) {
+		state.showShareGuide = true;
+		return;
+	}
+	// #endif
+
+	// #ifdef APP-PLUS
+	uni.share({
+		provider: 'weixin',
+		scene: 'WXSceneSession',
+		type: 0,
+		href: props.shareInfo.link,
+		title: props.shareInfo.title,
+		summary: props.shareInfo.desc,
+		imageUrl: props.shareInfo.image,
+		success: (res) => {
+			console.log('success:' + JSON.stringify(res));
+		},
+		fail: (err) => {
+			console.log('fail:' + JSON.stringify(err));
 		},
-		
-	});
-	const state = reactive({
-		showShareGuide: false, // H5 的指引
-		showPosterModal: false, // 海报弹窗
 	});
-
-	// 操作 ②:生成海报分享
-	const onShareByPoster = () => {
-		
-		closeShareModal();
-		if (!sheep.$store('user').isLogin) {
-			showAuthModal();
-			return;
-		}
-		unref(SharePosterRef).getPoster();
-		state.showPosterModal = true;
-	};
-
-	// 操作 ①:直接转发分享
-	const onShareByForward = () => {
-		closeShareModal();
-
-		// #ifdef H5
-		if (['WechatOfficialAccount', 'H5'].includes(sheep.$platform.name)) {
-			state.showShareGuide = true;
-			return;
-		}
-		// #endif
-
-		// #ifdef APP-PLUS
-		uni.share({
-			provider: 'weixin',
-			scene: 'WXSceneSession',
-			type: 0,
-			href: props.shareInfo.link,
-			title: props.shareInfo.title,
-			summary: props.shareInfo.desc,
-			imageUrl: props.shareInfo.image,
-			success: (res) => {
-				console.log('success:' + JSON.stringify(res));
-			},
-			fail: (err) => {
-				console.log('fail:' + JSON.stringify(err));
-			},
-		});
-		// #endif
-	};
-
-	// 操作 ③:复制链接分享
-	const onShareByCopyLink = () => {
-		closeShareModal();
-		if (!sheep.$store('user').isLogin) {
-			showAuthModal();
-			return;
-		}
-		sheep.$helper.copyText(props.shareInfo.link);
-		// sheep.$helper.copyText('https://zxgz.newfeifan.cn/');
-		// closeShareModal();
-	};
-
-	function onCloseGuide() {
-		state.showShareGuide = false;
+	// #endif
+};
+
+// 操作 ③:复制链接分享
+const onShareByCopyLink = () => {
+	closeShareModal();
+	if (!sheep.$store('user').isLogin) {
+		showAuthModal();
+		return;
 	}
+	sheep.$helper.copyText(props.shareInfo.link);
+	// closeShareModal();
+};
+
+function onCloseGuide() {
+	state.showShareGuide = false;
+}
 </script>
 
 <style lang="scss" scoped>
-	.guide-image {
-		right: 30rpx;
-		top: 0;
-		position: fixed;
-		width: 580rpx;
-		height: 430rpx;
-		z-index: 10080;
+.guide-image {
+	right: 30rpx;
+	top: 0;
+	position: fixed;
+	width: 580rpx;
+	height: 430rpx;
+	z-index: 10080;
+}
+
+// 分享tool
+.share-box {
+	background: $white;
+	width: 750rpx;
+	border-radius: 30rpx 30rpx 0 0;
+	padding-top: 30rpx;
+
+	.share-foot {
+		font-size: 24rpx;
+		color: $gray-b;
+		height: 80rpx;
+		border-top: 1rpx solid $gray-e;
 	}
 
-	// 分享tool
-	.share-box {
-		background: $white;
-		width: 750rpx;
-		border-radius: 30rpx 30rpx 0 0;
-		padding-top: 30rpx;
-
-		.share-foot {
-			font-size: 24rpx;
-			color: $gray-b;
-			height: 80rpx;
-			border-top: 1rpx solid $gray-e;
-		}
+	.share-list-box {
+		.share-btn {
+			background: none;
+			border: none;
+			line-height: 1;
+			padding: 0;
 
-		.share-list-box {
-			.share-btn {
-				background: none;
+			&::after {
 				border: none;
-				line-height: 1;
-				padding: 0;
+			}
+		}
+
+		.share-item {
+			flex: 1;
+			padding-bottom: 20rpx;
 
-				&::after {
-					border: none;
-				}
+			.share-img {
+				width: 70rpx;
+				height: 70rpx;
+				background: $gray-f;
+				border-radius: 50%;
+				margin-bottom: 20rpx;
 			}
 
-			.share-item {
-				flex: 1;
-				padding-bottom: 20rpx;
-
-				.share-img {
-					width: 70rpx;
-					height: 70rpx;
-					background: $gray-f;
-					border-radius: 50%;
-					margin-bottom: 20rpx;
-				}
-
-				.share-title {
-					font-size: 24rpx;
-					color: $dark-6;
-				}
+			.share-title {
+				font-size: 24rpx;
+				color: $dark-6;
 			}
 		}
 	}
+}
 </style>

+ 121 - 0
sheep/components/s-signup-modal/s-signup-modal.vue

@@ -0,0 +1,121 @@
+<template>
+	<!-- 规格弹窗 -->
+	<!-- showClose -->
+	<su-popup :show="show" @close="colseSignUpModal" type="center"  round="10">
+		<view class="model-box ss-flex-col">
+			<view class="ss-m-t-56 ss-flex-col ss-col-center">
+				<text class="cicon-check-round"></text>
+				<view class="score-title">恭喜!自动签到成功!</view>
+				<view class="model-title ss-flex ss-col-center ss-m-t-22 ss-m-b-30">
+					获得每日签到{{state?.social}}点身价
+				</view>
+				<view class="model-title ss-flex ss-col-center ss-m-b-30" v-if="state?.upgradeOrNot ">
+					您已升级等级为{{ state?.socialStatusName }}
+				</view>
+			</view>
+			<view class="model-bg ss-flex-col ss-col-center ss-row-right">
+				<view class="ss-m-b-40">
+					<button class="ss-reset-button confirm-btn" @tap="colseSignUpModal();">确认</button>
+				</view>
+			</view>
+		</view>
+	</su-popup>
+</template>
+
+<script setup>
+	import {
+		computed,
+		reactive,
+		ref,
+		watch
+	} from 'vue';
+	import sheep from '@/sheep';
+
+	import {
+		colseSignUpModal,
+		showSignUpModal
+	} from '@/sheep/hooks/useModal';
+	const headerBg = sheep.$url.css('/static/images/sign.png');
+	const show = computed(() => sheep.$store('modal').signUp);
+	const state = computed(() => sheep.$store('modal').signUpInfo)
+	// 监听签到成功 3s之后自动关闭
+	watch(() => show.value, (newValue) => {
+		if(newValue){
+			setTimeout(colseSignUpModal,3000)
+		}
+	})
+</script>
+
+<style lang="scss" scoped>
+	.model-box {
+		width: 520rpx;
+		// height: 590rpx;
+		background: linear-gradient(177deg, #ff6000 0%, #fe832a 100%);
+		// background: linear-gradient(177deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		border-radius: 10rpx;
+
+		.cicon-check-round {
+			font-size: 70rpx;
+			color: #fff;
+		}
+
+		.score-title {
+			font-size: 34rpx;
+			font-family: OPPOSANS;
+			font-weight: 500;
+			color: #fcff00;
+		}
+
+		.model-title {
+			font-size: 28rpx;
+			font-weight: 500;
+			color: #ffffff;
+		}
+
+		.model-bg {
+			width: 520rpx;
+			height: 6.75rem;
+			background-size: 100% 100%;
+			background-image: v-bind(headerBg);
+			background-repeat: no-repeat;
+			border-radius: 0 0 10rpx 10rpx;
+
+			.title {
+				font-size: 34rpx;
+				font-weight: bold;
+				// color: var(--ui-BG-Main);
+				color: #ff6000;
+			}
+
+			.subtitle {
+				font-size: 26rpx;
+				font-weight: 500;
+				color: #999999;
+			}
+
+			.cancel-btn {
+				width: 220rpx;
+				height: 70rpx;
+				border: 2rpx solid #ff6000;
+				border-radius: 35rpx;
+				font-size: 28rpx;
+				font-weight: 500;
+				color: #ff6000;
+				line-height: normal;
+				margin-right: 10rpx;
+			}
+
+			.confirm-btn {
+				width: 300rpx;
+				height: 70rpx;
+				background: linear-gradient(90deg, #ff6000, #fe832a);
+				box-shadow: 0 0.2em 0.5em rgba(#ff6000, 0.4);
+				border-radius: 35rpx;
+				font-size: 28rpx;
+				font-weight: 500;
+				color: #ffffff;
+				line-height: normal;
+			}
+		}
+	}
+</style>

+ 1 - 1
sheep/components/s-uploader/s-uploader.vue

@@ -205,7 +205,7 @@
       return {
         files: [],
         localValue: [],
-        imgsrc: sheep.$url.static('/static/img/shop/upload-camera.png'),
+        imgsrc: sheep.$url.static('/static/images/upload-camera.png'),
       };
     },
     watch: {

+ 13 - 3
sheep/components/s-user-card/s-user-card.vue

@@ -4,16 +4,19 @@
 		<view class="ss-flex ss-col-center ss-row-between ss-m-b-20">
 			<view class="left-box ss-flex ss-col-center ss-m-l-36">
 				<view class="avatar-box ss-m-r-24">
+					
 					<image class="avatar-img" :src="
               isLogin
                 ? sheep.$url.cdn(userInfo.avatar)
-                : sheep.$url.static('/static/img/shop/default_avatar.png')
+                : sheep.$url.static('/static/images/default_avatar.png')
             " mode="aspectFill" @tap="sheep.$router.go('/pages/user/info')"></image>
 				</view>
 				<view>
 					<view class="nickname-box ss-flex ss-col-center">
 						<view class="nick-name ss-m-r-20">{{ userInfo?.nickname || nickname }}</view>
+						
 					</view>
+					<view class="user-name ss-m-t-5">用户名:{{ userInfo?.username || username }}</view>
 				</view>
 			</view>
 			<view class="right-box ss-m-r-30">
@@ -22,7 +25,7 @@
 					<text class="cicon-service-o"></text>
 				</button> -->
 				<button class="ss-reset-button" @tap="sheep.$router.go('/pages/user/setting')">
-					<text class="cicon-settings-o"></text>
+					<image src="@/static/icon/setting.png" class="audioPaly" style="width:40rpx;height:40rpx"/>
 				</button>
 			</view>
 		</view>
@@ -46,6 +49,7 @@
 	 * @property {Number} rightSpace 									- 容器右间距
 	 *
 	 * @property {String} avatar 					- 头像
+	 * @property {String} username 					- 昵称
 	 * @property {String} nickname 					- 昵称
 	 * @property {String} vip		  				- 等级
 	 * @property {String} collectNum 				- 收藏数
@@ -86,6 +90,10 @@
 			type: String,
 			default: '请登录',
 		},
+		username: {
+			type: String,
+			default: '无',
+		},
 		vip: {
 			type: [String, Number],
 			default: '1',
@@ -127,7 +135,9 @@
 			color: #333333;
 			line-height: normal;
 		}
-
+		.user-name{
+			color: #999999;
+		}
 		.vip-img {
 			width: 30rpx;
 			height: 30rpx;

+ 16 - 19
sheep/components/s-wallet-card/s-wallet-card.vue

@@ -52,11 +52,10 @@
 			<view class="menu-item ss-flex-1 ss-flex-col  ss-col-center ss-row-center"
 				@tap="sheep.$router.go('/pages/user/wallet/score')">
 				<view class="value-box ">
-					<view class="value-text">积分</view>
+					<view class="value-text">数字<br/>权益</view>
 				</view>
-				<view class="menu-title ss-m-t-15">#{{ points2point(userWallet.integralDO.currentQuota)  }}</view>
-				<!-- <view class=" ss-m-t-10 text-center">历史总积分:#{{ points2point(userWallet.integralDO.highQuota)  }}</view> -->
-				<!-- <view class=" ss-m-t-10 text-center">待确权积分:#{{ points2point(userWallet.integralDO.freezeQuota) }}</view> -->
+				<view class="menu-title  ss-m-t-15">可用:{{ points2point(userWallet.integralDO.currentQuota)  }}</view>
+				<view class="menu-title ss-m-t-15">待确权:{{ points2point(userWallet.integralDO.freezeQuota)  }}</view>
 			</view>
 			<view class="menu-item ss-flex-1 ss-flex-col  ss-col-center ss-row-center"
 				@tap="sheep.$router.go('/pages/user/wallet/team')">
@@ -65,8 +64,6 @@
 				</view>
 
 				<view class="menu-title ss-m-t-15">{{ userWallet.descNo  }}人</view>
-				<!-- <view class="ss-m-t-10 text-center">团队今日贡献  #{{ points2point(userWallet.descPrice) }}</view> -->
-				<!-- <view class="ss-m-t-10 text-center">团队总贡献值  #{{ points2point(userWallet.descTotalPrice) }}</view> -->
 			</view>
 
 		</view>
@@ -85,8 +82,6 @@
 				<richtext title="身价产生规则" v-if="state.navIndex==0" type='tab' />
 				<richtext title="身价权益" v-if="state.navIndex==1" type='tab' />
 			</scroll-view>
-
-
 		</su-popup>
 	</view>
 </template>
@@ -120,7 +115,7 @@
 		}
 		const progress = ((userWallet.value.socialStatusPoint / (userWallet.value.socialStatusPoint +
 		userWallet.value.socialUpNeed)) * 100) + "%"
-		console.log(progress)
+		// console.log(progress)
 		return progress
 	})
 
@@ -150,8 +145,8 @@
 
 	.activite {
 		box-sizing: border-box;
-		color: rgb(14, 147, 46);
-		border-bottom: 4rpx solid rgb(14, 147, 46);
+		color: var(--ui-BG-Main);
+		border-bottom: 4rpx solid  var(--ui-BG-Main);
 	}
 
 	.head-nav>view {
@@ -191,7 +186,7 @@
 	/* 进度条 */
 	.progress-bar {
 		height: 100%;
-		background: rgb(14, 147, 46);
+		background: var(--ui-BG-Main);
 		/* 渐变色 */
 		border-radius: 20rpx;
 		/* 圆角 */
@@ -243,8 +238,8 @@
 			/* 确保 padding 和 border 不会使元素宽度超过 50% */
 			/* 可选,为了视觉效果 */
 			.menu-title {
-				font-size: 34rpx;
-				line-height: 34rpx;
+				font-size: 32rpx;
+				line-height: 32rpx;
 				color: #333333;
 			}
 
@@ -261,17 +256,19 @@
 			}
 
 			.value-box {
-				width: 100rpx;
-				height: 100rpx;
-				line-height: 100rpx;
+				width: 120rpx;
+				height: 120rpx;
+				// line-height: 100rpx;
 				text-align: center;
 				border-radius: 50%;
 				border: 2px solid #f6f6f6;
-
+				display:flex;
+				align-items: center;
+				justify-content: center;
 				.value-text {
 					font-size: 28rpx;
 					color: #000000;
-					line-height: 100rpx;
+					// line-height: 100rpx;
 					vertical-align: text-bottom;
 					font-family: OPPOSANS;
 				}

+ 128 - 0
sheep/components/s-wallet-modal/s-wallet-modal.vue

@@ -0,0 +1,128 @@
+<template>
+	<!-- 规格弹窗 -->
+	<!-- showClose -->
+	<su-popup :show="show" @close="colseWalletModal" type="center"  round="10">
+		<view class="model-box ss-flex-col">
+			<view class="ss-m-t-56 ss-flex-col ss-col-center">
+				<text class="cicon-check-round"></text>
+				<view class="score-title">恭喜</view>
+				<view class="model-title ss-flex ss-col-center ss-m-t-15 ss-font-35" v-if="state.points && points2point(state.points) > 0"> 
+					获得数字权益:{{ points2point(state.points) }}
+				</view>
+				<view class="model-title ss-flex ss-col-center ss-m-t-15 ss-font-35" v-if="state.socialStatus">
+					获得身价:{{state.socialStatus}}
+				</view>
+				<view class="model-title ss-flex ss-col-center ss-m-y-15 ">
+					【待确权】
+				</view>
+
+			</view>
+			<view class="model-bg ss-flex-col ss-col-center ss-row-right">
+				<view class="ss-m-b-40">
+					<button class="ss-reset-button confirm-btn" @tap="colseWalletModal();">确认</button>
+				</view>
+			</view>
+		</view>
+	</su-popup>
+</template>
+
+<script setup>
+	import {
+		computed,
+		reactive,
+		ref,
+		watch
+	} from 'vue';
+	import sheep from '@/sheep';
+
+	import {
+		showWalletModal,
+		colseWalletModal
+	} from '@/sheep/hooks/useModal';
+	import {
+		points2point
+	} from '@/sheep/hooks/useGoods';
+	const headerBg = sheep.$url.css('/static/images/sign.png');
+	const show = computed(() => sheep.$store('modal').getWallet);
+	const state = computed(() => sheep.$store('modal').getWalletInfo)
+	// 监听签到成功 3s之后自动关闭
+	// watch(() => show.value, (newValue) => {
+	// 	if(newValue){
+	// 		setTimeout(colseSignUpModal,3000)
+	// 	}
+	// })
+</script>
+
+<style lang="scss" scoped>
+	.model-box {
+		width: 520rpx;
+		// height: 590rpx;
+		background: linear-gradient(177deg, #ff6000 0%, #fe832a 100%);
+		// background: linear-gradient(177deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+		border-radius: 10rpx;
+
+		.cicon-check-round {
+			// font-size: 70rpx;
+			color: #fff;
+		}
+
+		.score-title {
+			font-size: 34rpx;
+			font-family: OPPOSANS;
+			font-weight: 500;
+			color: #fcff00;
+		}
+
+		.model-title {
+			// font-size: 28rpx;
+			font-weight: 500;
+			color: #ffffff;
+		}
+
+		.model-bg {
+			width: 520rpx;
+			height: 6.75rem;
+			background-size: 100% 100%;
+			background-image: v-bind(headerBg);
+			background-repeat: no-repeat;
+			border-radius: 0 0 10rpx 10rpx;
+
+			.title {
+				font-size: 34rpx;
+				font-weight: bold;
+				// color: var(--ui-BG-Main);
+				color: #ff6000;
+			}
+
+			.subtitle {
+				font-size: 26rpx;
+				font-weight: 500;
+				color: #999999;
+			}
+
+			.cancel-btn {
+				width: 220rpx;
+				height: 70rpx;
+				border: 2rpx solid #ff6000;
+				border-radius: 35rpx;
+				font-size: 28rpx;
+				font-weight: 500;
+				color: #ff6000;
+				line-height: normal;
+				margin-right: 10rpx;
+			}
+
+			.confirm-btn {
+				width: 300rpx;
+				height: 70rpx;
+				background: linear-gradient(90deg, #ff6000, #fe832a);
+				box-shadow: 0 0.2em 0.5em rgba(#ff6000, 0.4);
+				border-radius: 35rpx;
+				font-size: 28rpx;
+				font-weight: 500;
+				color: #ffffff;
+				line-height: normal;
+			}
+		}
+	}
+</style>

+ 236 - 139
sheep/hooks/useModal.js

@@ -1,139 +1,236 @@
-import $store from '@/sheep/store';
-import $helper from '@/sheep/helper';
-import dayjs from 'dayjs';
-import { ref } from 'vue';
-import test from '@/sheep/helper/test.js';
-import AuthUtil from '@/sheep/api/member/auth';
-
-// 打开授权弹框
-export function showAuthModal(type = 'smsLogin',isActive = 'smsLogin') {
-  const modal = $store('modal');
-  if (modal.auth !== '') {
-    closeAuthModal();
-    setTimeout(() => {
-      modal.$patch((state) => {
-        state.auth = type;
-		state.isActive = isActive;
-      });
-    }, 100);
-  } else {
-    modal.$patch((state) => {
-      state.auth = type;
-	  state.isActive = isActive;
-    });
-  }
-}
-
-// 关闭授权弹框
-export function closeAuthModal() {
-  $store('modal').$patch((state) => {
-    state.auth = '';
-  });
-}
-
-// 打开分享弹框
-export function showShareModal() {
-  $store('modal').$patch((state) => {
-    state.share = true;
-  });
-}
-
-// 关闭分享弹框
-export function closeShareModal() {
-  $store('modal').$patch((state) => {
-    state.share = false;
-  });
-}
-
-// 打开快捷菜单
-export function showMenuTools() {
-  $store('modal').$patch((state) => {
-    state.menu = true;
-  });
-}
-
-// 关闭快捷菜单
-export function closeMenuTools() {
-  $store('modal').$patch((state) => {
-    state.menu = false;
-  });
-}
-
-// 发送短信验证码  60秒
-export function getSmsCode(event, mobile) {
-  const modalStore = $store('modal');
-  const lastSendTimer = modalStore.lastTimer[event];
-  if (typeof lastSendTimer === 'undefined') {
-    $helper.toast('短信发送事件错误');
-    return;
-  }
-
-  const duration = dayjs().unix() - lastSendTimer;
-  const canSend = duration >= 60;
-  if (!canSend) {
-    $helper.toast('请稍后再试');
-    return;
-  }
-  // 只有 mobile 非空时才校验。因为部分场景(修改密码),不需要输入手机
-  if (mobile && !test.mobile(mobile)) {
-    $helper.toast('手机号码格式不正确');
-    return;
-  }
-
-  // 发送验证码 + 更新上次发送验证码时间
-  let scene = -1;
-  switch (event) {
-    case 'resetPassword':
-      scene = 4;
-      break;
-    case 'changePassword':
-      scene = 3;
-      break;
-    case 'changeMobile':
-      scene = 2;
-      break;
-    case 'smsLogin':
-      scene = 1;
-      break;
-  }
-  AuthUtil.sendSmsCode(mobile, scene).then((res) => {
-    if (res.code === 0) {
-      modalStore.$patch((state) => {
-        state.lastTimer[event] = dayjs().unix();
-      });
-    }
-  });
-}
-
-// 获取短信验证码倒计时 -- 60秒
-export function getSmsTimer(event, mobile = '') {
-  const modalStore = $store('modal');
-  const lastSendTimer = modalStore.lastTimer[event];
-  if (typeof lastSendTimer === 'undefined') {
-    $helper.toast('短信发送事件错误');
-    return;
-  }
-  const duration = ref(dayjs().unix() - lastSendTimer - 60);
-  const canSend = duration.value >= 0;
-  if (canSend) {
-    return '获取验证码';
-  }
-
-  if (!canSend) {
-    setTimeout(() => {
-      duration.value++;
-    }, 1000);
-    return -duration.value.toString() + ' 秒';
-  }
-}
-
-// 记录广告弹框历史
-export function saveAdvHistory(adv) {
-  const modal = $store('modal');
-
-  modal.$patch((state) => {
-    if (!state.advHistory.includes(adv.imgUrl)) {
-      state.advHistory.push(adv.imgUrl);
-    }
-  });
-}
+import $store from '@/sheep/store';
+import $helper from '@/sheep/helper';
+import dayjs from 'dayjs';
+import {
+	ref,
+	computed
+} from 'vue';
+import test from '@/sheep/helper/test.js';
+import AuthUtil from '@/sheep/api/member/auth';
+import sheep from '@/sheep';
+import SignInApi from '@/sheep/api/member/signin';
+let time = 30;
+let timer = null;
+// 登录
+async function onSign() {
+	console.log("onSign")
+	const {
+		code,
+		data
+	} = await SignInApi.createSignInRecord();
+	if (code === 0) {
+		showSignUpModal(data)
+	}
+	if (timer) {
+		clearInterval(timer);
+	}
+	uni.setStorageSync('isRun', false);
+	uni.setStorageSync('isSign', true);
+}
+// 每日重置签到状态
+export function resetSignStatusIfNeeded() {
+	const today = new Date().toISOString().slice(0, 10); // 获取当前日期,格式为 YYYY-MM-DD
+	const lastCheckDate = uni.getStorageSync('lastCheckDate');
+	if (today !== lastCheckDate) {
+		// 如果跨天了,重置 isSign
+		uni.setStorageSync('isSign', false);
+		uni.setStorageSync('lastCheckDate', today); // 更新最后检查的日期
+	}
+}
+// 自动签到
+export function autoSign() {
+	resetSignStatusIfNeeded();
+	const isLogin = computed(() => sheep.$store('user').isLogin);
+	if (isLogin.value) {
+		// 倒计时是否在进行
+		// console.log("autoSign执行了")
+		uni.setStorageSync('isRun', true);
+		if (uni.getStorageSync('isRun') && !uni.getStorageSync('isSign')) {
+			// console.log('开始倒计时')
+			// 开始一个新的定时器
+			timer = setInterval(() => {
+				time--;
+				console.log("time", time);
+				if (uni.getStorageSync('isSign') || !isLogin.value){
+					console.log('已经签到了或者已经登出了 不可以在签到')
+					cancelAutoSign()
+					
+				}
+				if (time <= 0 && !uni.getStorageSync('isSign')) {
+					clearInterval(timer);
+					onSign();
+				}
+			}, 1000);
+		}
+	}
+}
+// 取消自动签到
+export function cancelAutoSign() {
+	// console.log("autoSign取消了")
+	if (timer) {
+		clearInterval(timer);
+	}
+	time = 30;
+	uni.setStorageSync('isRun', false);
+}
+// 打开签到弹框
+export function showSignUpModal(obj) {
+	$store('modal').$patch((state) => {
+		state.signUp = true;
+		state.signUpInfo = obj;
+	});
+}
+// 关闭签到弹框
+export function colseSignUpModal() {
+	$store('modal').$patch((state) => {
+		state.signUp = false;
+	});
+}
+
+// 打开获得积分弹窗
+export function showWalletModal(obj) {
+	$store('modal').$patch((state) => {
+		state.getWallet = true;
+		state.getWalletInfo = obj;
+	});
+}
+// 关闭获得积分弹窗
+export function colseWalletModal() {
+	$store('modal').$patch((state) => {
+		state.getWallet = false;
+	});
+}
+
+// 打开授权弹框
+export function showAuthModal(type = 'accountLogin', isActive = 'accountLogin') {
+	const modal = $store('modal');
+	if (modal.auth !== '') {
+		closeAuthModal();
+		setTimeout(() => {
+			modal.$patch((state) => {
+				state.auth = type;
+				state.isActive = isActive;
+			});
+		}, 100);
+	} else {
+		modal.$patch((state) => {
+			state.auth = type;
+			state.isActive = isActive;
+		});
+	}
+}
+
+// 关闭授权弹框
+export function closeAuthModal() {
+	$store('modal').$patch((state) => {
+		state.auth = '';
+	});
+}
+
+// 打开分享弹框
+export function showShareModal(spuId = 0) {
+	$store('modal').$patch((state) => {
+		state.share = true;
+		state.shareInfo.spuId = spuId;
+	});
+}
+
+// 关闭分享弹框
+export function closeShareModal() {
+	$store('modal').$patch((state) => {
+		state.share = false;
+	});
+}
+
+// 打开快捷菜单
+export function showMenuTools() {
+	$store('modal').$patch((state) => {
+		state.menu = true;
+	});
+}
+
+// 关闭快捷菜单
+export function closeMenuTools() {
+	$store('modal').$patch((state) => {
+		state.menu = false;
+	});
+}
+
+// 发送短信验证码  60秒
+export function getSmsCode(event, mobile) {
+	const modalStore = $store('modal');
+	const lastSendTimer = modalStore.lastTimer[event];
+	if (typeof lastSendTimer === 'undefined') {
+		$helper.toast('短信发送事件错误');
+		return;
+	}
+
+	const duration = dayjs().unix() - lastSendTimer;
+	const canSend = duration >= 60;
+	if (!canSend) {
+		$helper.toast('请稍后再试');
+		return;
+	}
+	// 只有 mobile 非空时才校验。因为部分场景(修改密码),不需要输入手机
+	if (mobile && !test.mobile(mobile)) {
+		$helper.toast('手机号码格式不正确');
+		return;
+	}
+
+	// 发送验证码 + 更新上次发送验证码时间
+	let scene = -1;
+	switch (event) {
+		case 'resetPassword':
+			scene = 4;
+			break;
+		case 'changePassword':
+			scene = 3;
+			break;
+		case 'changeMobile':
+			scene = 2;
+			break;
+		case 'smsLogin':
+			scene = 1;
+			break;
+	}
+	AuthUtil.sendSmsCode(mobile, scene).then((res) => {
+		if (res.code === 0) {
+			modalStore.$patch((state) => {
+				state.lastTimer[event] = dayjs().unix();
+			});
+		}
+	});
+}
+
+// 获取短信验证码倒计时 -- 60秒
+export function getSmsTimer(event, mobile = '') {
+	const modalStore = $store('modal');
+	const lastSendTimer = modalStore.lastTimer[event];
+	if (typeof lastSendTimer === 'undefined') {
+		$helper.toast('短信发送事件错误');
+		return;
+	}
+	const duration = ref(dayjs().unix() - lastSendTimer - 60);
+	const canSend = duration.value >= 0;
+	if (canSend) {
+		return '获取验证码';
+	}
+
+	if (!canSend) {
+		setTimeout(() => {
+			duration.value++;
+		}, 1000);
+		return -duration.value.toString() + ' 秒';
+	}
+}
+
+// 记录广告弹框历史
+export function saveAdvHistory(adv) {
+	const modal = $store('modal');
+
+	modal.$patch((state) => {
+		if (!state.advHistory.includes(adv.imgUrl)) {
+			state.advHistory.push(adv.imgUrl);
+		}
+	});
+}

+ 1298 - 0
sheep/libs/country.json

@@ -0,0 +1,1298 @@
+[
+    {
+        "english_name": "China",
+        "chinese_name": "中国",
+        "country_code": "CN",
+        "phone_code": "86"
+    },
+    {
+        "english_name": "Hong Kong",
+        "chinese_name": "中国香港",
+        "country_code": "HK",
+        "phone_code": "852"
+    },
+    {
+        "english_name": "Taiwan",
+        "chinese_name": "中国台湾",
+        "country_code": "TW",
+        "phone_code": "886"
+    },
+    {
+        "english_name": "Macau",
+        "chinese_name": "中国澳门",
+        "country_code": "MO",
+        "phone_code": "853"
+    },
+    {
+        "english_name": "Central African Republic",
+        "chinese_name": "中非共和国",
+        "country_code": "CF",
+        "phone_code": "236"
+    },
+    {
+        "english_name": "Chile",
+        "chinese_name": "智利",
+        "country_code": "CL",
+        "phone_code": "56"
+    },
+    {
+        "english_name": "Gibraltar",
+        "chinese_name": "直布罗陀",
+        "country_code": "GI",
+        "phone_code": "350"
+    },
+    {
+        "english_name": "Chad",
+        "chinese_name": "乍得",
+        "country_code": "TD",
+        "phone_code": "235"
+    },
+    {
+        "english_name": "Zambia",
+        "chinese_name": "赞比亚",
+        "country_code": "ZM",
+        "phone_code": "260"
+    },
+    {
+        "english_name": "Vietnam",
+        "chinese_name": "越南",
+        "country_code": "VN",
+        "phone_code": "84"
+    },
+    {
+        "english_name": "Jordan",
+        "chinese_name": "约旦",
+        "country_code": "JO",
+        "phone_code": "962"
+    },
+    {
+        "english_name": "Virgin Islands, British",
+        "chinese_name": "英属处女群岛",
+        "country_code": "VG",
+        "phone_code": "1340"
+    },
+    {
+        "english_name": "United Kingdom",
+        "chinese_name": "英国",
+        "country_code": "GB",
+        "phone_code": "44"
+    },
+    {
+        "english_name": "Indonesia",
+        "chinese_name": "印度尼西亚",
+        "country_code": "ID",
+        "phone_code": "62"
+    },
+    {
+        "english_name": "India",
+        "chinese_name": "印度",
+        "country_code": "IN",
+        "phone_code": "91"
+    },
+    {
+        "english_name": "Italy",
+        "chinese_name": "意大利",
+        "country_code": "IT",
+        "phone_code": "39"
+    },
+    {
+        "english_name": "Israel",
+        "chinese_name": "以色列",
+        "country_code": "IL",
+        "phone_code": "972"
+    },
+    {
+        "english_name": "Iran",
+        "chinese_name": "伊朗",
+        "country_code": "IR",
+        "phone_code": "98"
+    },
+    {
+        "english_name": "Iraq",
+        "chinese_name": "伊拉克",
+        "country_code": "IQ",
+        "phone_code": "964"
+    },
+    {
+        "english_name": "Yemen",
+        "chinese_name": "也门",
+        "country_code": "YE",
+        "phone_code": "967"
+    },
+    {
+        "english_name": "Armenia",
+        "chinese_name": "亚美尼亚",
+        "country_code": "AM",
+        "phone_code": "374"
+    },
+    {
+        "english_name": "Jamaica",
+        "chinese_name": "牙买加",
+        "country_code": "JM",
+        "phone_code": "1876"
+    },
+    {
+        "english_name": "Syria",
+        "chinese_name": "叙利亚",
+        "country_code": "SY",
+        "phone_code": "963"
+    },
+    {
+        "english_name": "Hungary",
+        "chinese_name": "匈牙利",
+        "country_code": "HU",
+        "phone_code": "36"
+    },
+    {
+        "english_name": "New Zealand",
+        "chinese_name": "新西兰",
+        "country_code": "NZ",
+        "phone_code": "64"
+    },
+    {
+        "english_name": "New Caledonia",
+        "chinese_name": "新喀里多尼亚",
+        "country_code": "NC",
+        "phone_code": "687"
+    },
+    {
+        "english_name": "Singapore",
+        "chinese_name": "新加坡",
+        "country_code": "SG",
+        "phone_code": "65"
+    },
+    {
+        "english_name": "Ivory Coast",
+        "chinese_name": "象牙海岸",
+        "country_code": "CI",
+        "phone_code": "225"
+    },
+    {
+        "english_name": "Greece",
+        "chinese_name": "希腊",
+        "country_code": "GR",
+        "phone_code": "30"
+    },
+    {
+        "english_name": "Spain",
+        "chinese_name": "西班牙",
+        "country_code": "ES",
+        "phone_code": "34"
+    },
+    {
+        "english_name": "Uzbekistan",
+        "chinese_name": "乌兹别克斯坦",
+        "country_code": "UZ",
+        "phone_code": "998"
+    },
+    {
+        "english_name": "Uruguay",
+        "chinese_name": "乌拉圭",
+        "country_code": "UY",
+        "phone_code": "598"
+    },
+    {
+        "english_name": "Ukraine",
+        "chinese_name": "乌克兰",
+        "country_code": "UA",
+        "phone_code": "380"
+    },
+    {
+        "english_name": "Uganda",
+        "chinese_name": "乌干达",
+        "country_code": "UG",
+        "phone_code": "256"
+    },
+    {
+        "english_name": "Brunei",
+        "chinese_name": "文莱",
+        "country_code": "BN",
+        "phone_code": "673"
+    },
+    {
+        "english_name": "Venezuela",
+        "chinese_name": "委内瑞拉",
+        "country_code": "VE",
+        "phone_code": "58"
+    },
+    {
+        "english_name": "Vanuatu",
+        "chinese_name": "瓦努阿图",
+        "country_code": "VU",
+        "phone_code": "678"
+    },
+    {
+        "english_name": "Turkmenistan",
+        "chinese_name": "土库曼斯坦",
+        "country_code": "TM",
+        "phone_code": "993"
+    },
+    {
+        "english_name": "Turkey",
+        "chinese_name": "土耳其",
+        "country_code": "TR",
+        "phone_code": "90"
+    },
+    {
+        "english_name": "Tunisia",
+        "chinese_name": "突尼斯",
+        "country_code": "TN",
+        "phone_code": "216"
+    },
+    {
+        "english_name": "Trinidad and Tobago",
+        "chinese_name": "特立尼达和多巴哥",
+        "country_code": "TT",
+        "phone_code": "1868"
+    },
+    {
+        "english_name": "Turks and Caicos Islands",
+        "chinese_name": "特克斯和凯科斯群岛",
+        "country_code": "TC",
+        "phone_code": "1649"
+    },
+    {
+        "english_name": "Tonga",
+        "chinese_name": "汤加",
+        "country_code": "TO",
+        "phone_code": "676"
+    },
+    {
+        "english_name": "Tanzania",
+        "chinese_name": "坦桑尼亚",
+        "country_code": "TZ",
+        "phone_code": "255"
+    },
+    {
+        "english_name": "Thailand",
+        "chinese_name": "泰国",
+        "country_code": "TH",
+        "phone_code": "66"
+    },
+    {
+        "english_name": "Tajikistan",
+        "chinese_name": "塔吉克斯坦",
+        "country_code": "TJ",
+        "phone_code": "992"
+    },
+    {
+        "english_name": "Somalia",
+        "chinese_name": "索马里",
+        "country_code": "SO",
+        "phone_code": "252"
+    },
+    {
+        "english_name": "Solomon Islands",
+        "chinese_name": "所罗门群岛",
+        "country_code": "SB",
+        "phone_code": "677"
+    },
+    {
+        "english_name": "Suriname",
+        "chinese_name": "苏里南",
+        "country_code": "SR",
+        "phone_code": "597"
+    },
+    {
+        "english_name": "Sudan",
+        "chinese_name": "苏丹",
+        "country_code": "SD",
+        "phone_code": "249"
+    },
+    {
+        "english_name": "Swaziland",
+        "chinese_name": "斯威士兰",
+        "country_code": "SZ",
+        "phone_code": "268"
+    },
+    {
+        "english_name": "Slovenia",
+        "chinese_name": "斯洛文尼亚",
+        "country_code": "SI",
+        "phone_code": "386"
+    },
+    {
+        "english_name": "Slovakia",
+        "chinese_name": "斯洛伐克",
+        "country_code": "SK",
+        "phone_code": "421"
+    },
+    {
+        "english_name": "Sri Lanka",
+        "chinese_name": "斯里兰卡",
+        "country_code": "LK",
+        "phone_code": "94"
+    },
+    {
+        "english_name": "Saint Vincent and The Grenadines",
+        "chinese_name": "圣文森特和格林纳丁斯",
+        "country_code": "VC",
+        "phone_code": "1784"
+    },
+    {
+        "english_name": "San Marino",
+        "chinese_name": "圣马力诺",
+        "country_code": "SM",
+        "phone_code": "378"
+    },
+    {
+        "english_name": "Saint Maarten (Dutch Part)",
+        "chinese_name": "圣马丁岛(荷兰部分)",
+        "country_code": "SX",
+        "phone_code": "1721"
+    },
+    {
+        "english_name": "Saint Lucia",
+        "chinese_name": "圣露西亚",
+        "country_code": "LC",
+        "phone_code": "1758"
+    },
+    {
+        "english_name": "Saint Kitts and Nevis",
+        "chinese_name": "圣基茨和尼维斯",
+        "country_code": "KN",
+        "phone_code": "1869"
+    },
+    {
+        "english_name": "Sao Tome and Principe",
+        "chinese_name": "圣多美和普林西比",
+        "country_code": "ST",
+        "phone_code": "239"
+    },
+    {
+        "english_name": "Saint Pierre and Miquelon",
+        "chinese_name": "圣彼埃尔和密克隆岛",
+        "country_code": "PM",
+        "phone_code": "508"
+    },
+    {
+        "english_name": "Saudi Arabia",
+        "chinese_name": "沙特阿拉伯",
+        "country_code": "SA",
+        "phone_code": "966"
+    },
+    {
+        "english_name": "Seychelles",
+        "chinese_name": "塞舌尔",
+        "country_code": "SC",
+        "phone_code": "248"
+    },
+    {
+        "english_name": "Cyprus",
+        "chinese_name": "塞浦路斯",
+        "country_code": "CY",
+        "phone_code": "357"
+    },
+    {
+        "english_name": "Senegal",
+        "chinese_name": "塞内加尔",
+        "country_code": "SN",
+        "phone_code": "221"
+    },
+    {
+        "english_name": "Sierra Leone",
+        "chinese_name": "塞拉利昂",
+        "country_code": "SL",
+        "phone_code": "232"
+    },
+    {
+        "english_name": "Serbia",
+        "chinese_name": "塞尔维亚",
+        "country_code": "RS",
+        "phone_code": "381"
+    },
+    {
+        "english_name": "Samoa",
+        "chinese_name": "萨摩亚",
+        "country_code": "WS",
+        "phone_code": "685"
+    },
+    {
+        "english_name": "El Salvador",
+        "chinese_name": "萨尔瓦多",
+        "country_code": "SV",
+        "phone_code": "503"
+    },
+    {
+        "english_name": "Switzerland",
+        "chinese_name": "瑞士",
+        "country_code": "CH",
+        "phone_code": "41"
+    },
+    {
+        "english_name": "Sweden",
+        "chinese_name": "瑞典",
+        "country_code": "SE",
+        "phone_code": "46"
+    },
+    {
+        "english_name": "Japan",
+        "chinese_name": "日本",
+        "country_code": "JP",
+        "phone_code": "81"
+    },
+    {
+        "english_name": "Portugal",
+        "chinese_name": "葡萄牙",
+        "country_code": "PT",
+        "phone_code": "351"
+    },
+    {
+        "english_name": "Palau",
+        "chinese_name": "帕劳",
+        "country_code": "PW",
+        "phone_code": "680"
+    },
+    {
+        "english_name": "Norway",
+        "chinese_name": "挪威",
+        "country_code": "NO",
+        "phone_code": "47"
+    },
+    {
+        "english_name": "Nigeria",
+        "chinese_name": "尼日利亚",
+        "country_code": "NG",
+        "phone_code": "234"
+    },
+    {
+        "english_name": "Niger",
+        "chinese_name": "尼日尔",
+        "country_code": "NE",
+        "phone_code": "227"
+    },
+    {
+        "english_name": "Nepal",
+        "chinese_name": "尼泊尔",
+        "country_code": "NP",
+        "phone_code": "977"
+    },
+    {
+        "english_name": "Nicaragua",
+        "chinese_name": "尼加拉瓜",
+        "country_code": "NI",
+        "phone_code": "505"
+    },
+    {
+        "english_name": "South Africa",
+        "chinese_name": "南非",
+        "country_code": "ZA",
+        "phone_code": "27"
+    },
+    {
+        "english_name": "Namibia",
+        "chinese_name": "纳米比亚",
+        "country_code": "NA",
+        "phone_code": "264"
+    },
+    {
+        "english_name": "Mexico",
+        "chinese_name": "墨西哥",
+        "country_code": "MX",
+        "phone_code": "52"
+    },
+    {
+        "english_name": "Mozambique",
+        "chinese_name": "莫桑比克",
+        "country_code": "MZ",
+        "phone_code": "258"
+    },
+    {
+        "english_name": "Monaco",
+        "chinese_name": "摩纳哥",
+        "country_code": "MC",
+        "phone_code": "377"
+    },
+    {
+        "english_name": "Morocco",
+        "chinese_name": "摩洛哥",
+        "country_code": "MA",
+        "phone_code": "212"
+    },
+    {
+        "english_name": "Moldova",
+        "chinese_name": "摩尔多瓦",
+        "country_code": "MD",
+        "phone_code": "373"
+    },
+    {
+        "english_name": "Myanmar",
+        "chinese_name": "缅甸",
+        "country_code": "MM",
+        "phone_code": "95"
+    },
+    {
+        "english_name": "Peru",
+        "chinese_name": "秘鲁",
+        "country_code": "PE",
+        "phone_code": "51"
+    },
+    {
+        "english_name": "Bangladesh",
+        "chinese_name": "孟加拉国",
+        "country_code": "BD",
+        "phone_code": "880"
+    },
+    {
+        "english_name": "Montserrat",
+        "chinese_name": "蒙特塞拉特岛",
+        "country_code": "MS",
+        "phone_code": "1664"
+    },
+    {
+        "english_name": "Mongolia",
+        "chinese_name": "蒙古",
+        "country_code": "MN",
+        "phone_code": "976"
+    },
+    {
+        "english_name": "Virgin Islands, US",
+        "chinese_name": "美属维尔京群岛",
+        "country_code": "VI",
+        "phone_code": "1284"
+    },
+    {
+        "english_name": "American Samoa",
+        "chinese_name": "美属萨摩亚",
+        "country_code": "AS",
+        "phone_code": "1684"
+    },
+    {
+        "english_name": "United States",
+        "chinese_name": "美国",
+        "country_code": "US",
+        "phone_code": "1"
+    },
+    {
+        "english_name": "Mauritania",
+        "chinese_name": "毛里塔尼亚",
+        "country_code": "MR",
+        "phone_code": "222"
+    },
+    {
+        "english_name": "Mauritius",
+        "chinese_name": "毛里求斯",
+        "country_code": "MU",
+        "phone_code": "230"
+    },
+    {
+        "english_name": "Mayotte",
+        "chinese_name": "马约特",
+        "country_code": "YT",
+        "phone_code": "269"
+    },
+    {
+        "english_name": "Martinique",
+        "chinese_name": "马提尼克",
+        "country_code": "MQ",
+        "phone_code": "596"
+    },
+    {
+        "english_name": "Macedonia",
+        "chinese_name": "马其顿",
+        "country_code": "MK",
+        "phone_code": "389"
+    },
+    {
+        "english_name": "Mali",
+        "chinese_name": "马里",
+        "country_code": "ML",
+        "phone_code": "223"
+    },
+    {
+        "english_name": "Malaysia",
+        "chinese_name": "马来西亚",
+        "country_code": "MY",
+        "phone_code": "60"
+    },
+    {
+        "english_name": "Malawi",
+        "chinese_name": "马拉维",
+        "country_code": "MW",
+        "phone_code": "265"
+    },
+    {
+        "english_name": "Malta",
+        "chinese_name": "马耳他",
+        "country_code": "MT",
+        "phone_code": "356"
+    },
+    {
+        "english_name": "Maldives",
+        "chinese_name": "马尔代夫",
+        "country_code": "MV",
+        "phone_code": "960"
+    },
+    {
+        "english_name": "Madagascar",
+        "chinese_name": "马达加斯加",
+        "country_code": "MG",
+        "phone_code": "261"
+    },
+    {
+        "english_name": "Romania",
+        "chinese_name": "罗马尼亚",
+        "country_code": "RO",
+        "phone_code": "40"
+    },
+    {
+        "english_name": "Rwanda",
+        "chinese_name": "卢旺达",
+        "country_code": "RW",
+        "phone_code": "250"
+    },
+    {
+        "english_name": "Luxembourg",
+        "chinese_name": "卢森堡",
+        "country_code": "LU",
+        "phone_code": "352"
+    },
+    {
+        "english_name": "Réunion Island",
+        "chinese_name": "留尼汪",
+        "country_code": "RE",
+        "phone_code": "262"
+    },
+    {
+        "english_name": "Liechtenstein",
+        "chinese_name": "列支敦士登",
+        "country_code": "LI",
+        "phone_code": "423"
+    },
+    {
+        "english_name": "Libya",
+        "chinese_name": "利比亚",
+        "country_code": "LY",
+        "phone_code": "218"
+    },
+    {
+        "english_name": "Liberia",
+        "chinese_name": "利比里亚",
+        "country_code": "LR",
+        "phone_code": "231"
+    },
+    {
+        "english_name": "Lithuania",
+        "chinese_name": "立陶宛",
+        "country_code": "LT",
+        "phone_code": "370"
+    },
+    {
+        "english_name": "Lebanon",
+        "chinese_name": "黎巴嫩",
+        "country_code": "LB",
+        "phone_code": "961"
+    },
+    {
+        "english_name": "Laos",
+        "chinese_name": "老挝",
+        "country_code": "LA",
+        "phone_code": "856"
+    },
+    {
+        "english_name": "Lesotho",
+        "chinese_name": "莱索托",
+        "country_code": "LS",
+        "phone_code": "266"
+    },
+    {
+        "english_name": "Latvia",
+        "chinese_name": "拉脱维亚",
+        "country_code": "LV",
+        "phone_code": "371"
+    },
+    {
+        "english_name": "Curacao",
+        "chinese_name": "库拉索",
+        "country_code": "CW",
+        "phone_code": "599"
+    },
+    {
+        "english_name": "Cook Islands",
+        "chinese_name": "库克群岛",
+        "country_code": "CK",
+        "phone_code": "682"
+    },
+    {
+        "english_name": "Kenya",
+        "chinese_name": "肯尼亚",
+        "country_code": "KE",
+        "phone_code": "254"
+    },
+    {
+        "english_name": "Croatia",
+        "chinese_name": "克罗地亚",
+        "country_code": "HR",
+        "phone_code": "385"
+    },
+    {
+        "english_name": "Kuwait",
+        "chinese_name": "科威特",
+        "country_code": "KW",
+        "phone_code": "965"
+    },
+    {
+        "english_name": "Comoros",
+        "chinese_name": "科摩罗",
+        "country_code": "KM",
+        "phone_code": "269"
+    },
+    {
+        "english_name": "Cape Verde",
+        "chinese_name": "开普",
+        "country_code": "CV",
+        "phone_code": "238"
+    },
+    {
+        "english_name": "Cayman Islands",
+        "chinese_name": "开曼群岛",
+        "country_code": "KY",
+        "phone_code": "1345"
+    },
+    {
+        "english_name": "Qatar",
+        "chinese_name": "卡塔尔",
+        "country_code": "QA",
+        "phone_code": "974"
+    },
+    {
+        "english_name": "Cameroon",
+        "chinese_name": "喀麦隆",
+        "country_code": "CM",
+        "phone_code": "237"
+    },
+    {
+        "english_name": "Zimbabwe",
+        "chinese_name": "津巴布韦",
+        "country_code": "ZW",
+        "phone_code": "263"
+    },
+    {
+        "english_name": "Czech",
+        "chinese_name": "捷克",
+        "country_code": "CZ",
+        "phone_code": "420"
+    },
+    {
+        "english_name": "Cambodia",
+        "chinese_name": "柬埔寨",
+        "country_code": "KH",
+        "phone_code": "855"
+    },
+    {
+        "english_name": "Gabon",
+        "chinese_name": "加蓬",
+        "country_code": "GA",
+        "phone_code": "241"
+    },
+    {
+        "english_name": "Ghana",
+        "chinese_name": "加纳",
+        "country_code": "GH",
+        "phone_code": "233"
+    },
+    {
+        "english_name": "Canada",
+        "chinese_name": "加拿大",
+        "country_code": "CA",
+        "phone_code": "1"
+    },
+    {
+        "english_name": "Guinea-Bissau",
+        "chinese_name": "几内亚比绍共和国",
+        "country_code": "GW",
+        "phone_code": "245"
+    },
+    {
+        "english_name": "Guinea",
+        "chinese_name": "几内亚",
+        "country_code": "GN",
+        "phone_code": "224"
+    },
+    {
+        "english_name": "Kyrgyzstan",
+        "chinese_name": "吉尔吉斯斯坦",
+        "country_code": "KG",
+        "phone_code": "996"
+    },
+    {
+        "english_name": "Djibouti",
+        "chinese_name": "吉布提",
+        "country_code": "DJ",
+        "phone_code": "253"
+    },
+    {
+        "english_name": "Kiribati",
+        "chinese_name": "基里巴斯",
+        "country_code": "KI",
+        "phone_code": "686"
+    },
+    {
+        "english_name": "Honduras",
+        "chinese_name": "洪都拉斯",
+        "country_code": "HN",
+        "phone_code": "504"
+    },
+    {
+        "english_name": "Montenegro",
+        "chinese_name": "黑山",
+        "country_code": "ME",
+        "phone_code": "382"
+    },
+    {
+        "english_name": "Netherlands",
+        "chinese_name": "荷兰",
+        "country_code": "NL",
+        "phone_code": "31"
+    },
+    {
+        "english_name": "South Korea",
+        "chinese_name": "韩国",
+        "country_code": "KR",
+        "phone_code": "82"
+    },
+    {
+        "english_name": "Haiti",
+        "chinese_name": "海地",
+        "country_code": "HT",
+        "phone_code": "509"
+    },
+    {
+        "english_name": "Kazakhstan",
+        "chinese_name": "哈萨克斯坦",
+        "country_code": "KZ",
+        "phone_code": "7"
+    },
+    {
+        "english_name": "Guyana",
+        "chinese_name": "圭亚那",
+        "country_code": "GY",
+        "phone_code": "592"
+    },
+    {
+        "english_name": "Guam",
+        "chinese_name": "关岛",
+        "country_code": "GU",
+        "phone_code": "1671"
+    },
+    {
+        "english_name": "Guatemala",
+        "chinese_name": "瓜地马拉",
+        "country_code": "GT",
+        "phone_code": "502"
+    },
+    {
+        "english_name": "Guadeloupe",
+        "chinese_name": "瓜德罗普岛",
+        "country_code": "GP",
+        "phone_code": "590"
+    },
+    {
+        "english_name": "Cuba",
+        "chinese_name": "古巴",
+        "country_code": "CU",
+        "phone_code": "53"
+    },
+    {
+        "english_name": "Georgia",
+        "chinese_name": "格鲁吉亚",
+        "country_code": "GE",
+        "phone_code": "995"
+    },
+    {
+        "english_name": "Greenland",
+        "chinese_name": "格陵兰岛",
+        "country_code": "GL",
+        "phone_code": "299"
+    },
+    {
+        "english_name": "Grenada",
+        "chinese_name": "格林纳达",
+        "country_code": "GD",
+        "phone_code": "1473"
+    },
+    {
+        "english_name": "Costa Rica",
+        "chinese_name": "哥斯达黎加",
+        "country_code": "CR",
+        "phone_code": "506"
+    },
+    {
+        "english_name": "Colombia",
+        "chinese_name": "哥伦比亚",
+        "country_code": "CO",
+        "phone_code": "57"
+    },
+    {
+        "english_name": "Democratic Republic of the Congo",
+        "chinese_name": "刚果民主共和国",
+        "country_code": "CD",
+        "phone_code": "243"
+    },
+    {
+        "english_name": "Republic Of The Congo",
+        "chinese_name": "刚果共和国",
+        "country_code": "CG",
+        "phone_code": "242"
+    },
+    {
+        "english_name": "Gambia",
+        "chinese_name": "冈比亚",
+        "country_code": "GM",
+        "phone_code": "220"
+    },
+    {
+        "english_name": "Finland",
+        "chinese_name": "芬兰",
+        "country_code": "FI",
+        "phone_code": "358"
+    },
+    {
+        "english_name": "Fiji",
+        "chinese_name": "斐济",
+        "country_code": "FJ",
+        "phone_code": "679"
+    },
+    {
+        "english_name": "Philippines",
+        "chinese_name": "菲律宾",
+        "country_code": "PH",
+        "phone_code": "63"
+    },
+    {
+        "english_name": "French Guiana",
+        "chinese_name": "法属圭亚那",
+        "country_code": "GF",
+        "phone_code": "594"
+    },
+    {
+        "english_name": "French Polynesia",
+        "chinese_name": "法属波利尼西亚",
+        "country_code": "PF",
+        "phone_code": "689"
+    },
+    {
+        "english_name": "Faroe Islands",
+        "chinese_name": "法罗群岛",
+        "country_code": "FO",
+        "phone_code": "298"
+    },
+    {
+        "english_name": "France",
+        "chinese_name": "法国",
+        "country_code": "FR",
+        "phone_code": "33"
+    },
+    {
+        "english_name": "Eritrea",
+        "chinese_name": "厄立特里亚",
+        "country_code": "ER",
+        "phone_code": "291"
+    },
+    {
+        "english_name": "Ecuador",
+        "chinese_name": "厄瓜多尔",
+        "country_code": "EC",
+        "phone_code": "593"
+    },
+    {
+        "english_name": "Russia",
+        "chinese_name": "俄罗斯",
+        "country_code": "RU",
+        "phone_code": "7"
+    },
+    {
+        "english_name": "Dominican Republic",
+        "chinese_name": "多米尼加共和国",
+        "country_code": "DO",
+        "phone_code": "1809"
+    },
+    {
+        "english_name": "Dominica",
+        "chinese_name": "多米尼加",
+        "country_code": "DM",
+        "phone_code": "1767"
+    },
+    {
+        "english_name": "Togo",
+        "chinese_name": "多哥",
+        "country_code": "TG",
+        "phone_code": "228"
+    },
+    {
+        "english_name": "Timor-Leste",
+        "chinese_name": "东帝汶",
+        "country_code": "TL",
+        "phone_code": "670"
+    },
+    {
+        "english_name": "Germany",
+        "chinese_name": "德国",
+        "country_code": "DE",
+        "phone_code": "49"
+    },
+    {
+        "english_name": "Denmark",
+        "chinese_name": "丹麦",
+        "country_code": "DK",
+        "phone_code": "45"
+    },
+    {
+        "english_name": "Equatorial Guinea",
+        "chinese_name": "赤道几内亚",
+        "country_code": "GQ",
+        "phone_code": "240"
+    },
+    {
+        "english_name": "Burundi",
+        "chinese_name": "布隆迪",
+        "country_code": "BI",
+        "phone_code": "257"
+    },
+    {
+        "english_name": "Burkina Faso",
+        "chinese_name": "布基纳法索",
+        "country_code": "BF",
+        "phone_code": "226"
+    },
+    {
+        "english_name": "Bhutan",
+        "chinese_name": "不丹",
+        "country_code": "BT",
+        "phone_code": "975"
+    },
+    {
+        "english_name": "Botswana",
+        "chinese_name": "博茨瓦纳",
+        "country_code": "BW",
+        "phone_code": "267"
+    },
+    {
+        "english_name": "Belize",
+        "chinese_name": "伯利兹",
+        "country_code": "BZ",
+        "phone_code": "501"
+    },
+    {
+        "english_name": "Bolivia",
+        "chinese_name": "玻利维亚",
+        "country_code": "BO",
+        "phone_code": "591"
+    },
+    {
+        "english_name": "Bosnia and Herzegovina",
+        "chinese_name": "波斯尼亚和黑塞哥维那",
+        "country_code": "BA",
+        "phone_code": "387"
+    },
+    {
+        "english_name": "Poland",
+        "chinese_name": "波兰",
+        "country_code": "PL",
+        "phone_code": "48"
+    },
+    {
+        "english_name": "Puerto Rico",
+        "chinese_name": "波多黎各",
+        "country_code": "PR",
+        "phone_code": "1787"
+    },
+    {
+        "english_name": "Iceland",
+        "chinese_name": "冰岛",
+        "country_code": "IS",
+        "phone_code": "354"
+    },
+    {
+        "english_name": "Belgium",
+        "chinese_name": "比利时",
+        "country_code": "BE",
+        "phone_code": "32"
+    },
+    {
+        "english_name": "Benin",
+        "chinese_name": "贝宁",
+        "country_code": "BJ",
+        "phone_code": "229"
+    },
+    {
+        "english_name": "Bulgaria",
+        "chinese_name": "保加利亚",
+        "country_code": "BG",
+        "phone_code": "359"
+    },
+    {
+        "english_name": "Bermuda",
+        "chinese_name": "百慕大群岛",
+        "country_code": "BM",
+        "phone_code": "1441"
+    },
+    {
+        "english_name": "Belarus",
+        "chinese_name": "白俄罗斯",
+        "country_code": "BY",
+        "phone_code": "375"
+    },
+    {
+        "english_name": "Brazil",
+        "chinese_name": "巴西",
+        "country_code": "BR",
+        "phone_code": "55"
+    },
+    {
+        "english_name": "Panama",
+        "chinese_name": "巴拿马",
+        "country_code": "PA",
+        "phone_code": "507"
+    },
+    {
+        "english_name": "Bahrain",
+        "chinese_name": "巴林",
+        "country_code": "BH",
+        "phone_code": "973"
+    },
+    {
+        "english_name": "Palestine",
+        "chinese_name": "巴勒斯坦",
+        "country_code": "BL",
+        "phone_code": "970"
+    },
+    {
+        "english_name": "Paraguay",
+        "chinese_name": "巴拉圭",
+        "country_code": "PY",
+        "phone_code": "595"
+    },
+    {
+        "english_name": "Pakistan",
+        "chinese_name": "巴基斯坦",
+        "country_code": "PK",
+        "phone_code": "92"
+    },
+    {
+        "english_name": "Bahamas",
+        "chinese_name": "巴哈马",
+        "country_code": "BS",
+        "phone_code": "1242"
+    },
+    {
+        "english_name": "Papua New Guinea",
+        "chinese_name": "巴布亚新几内亚",
+        "country_code": "PG",
+        "phone_code": "675"
+    },
+    {
+        "english_name": "Barbados",
+        "chinese_name": "巴巴多斯",
+        "country_code": "BB",
+        "phone_code": "1246"
+    },
+    {
+        "english_name": "Australia",
+        "chinese_name": "澳大利亚",
+        "country_code": "AU",
+        "phone_code": "61"
+    },
+    {
+        "english_name": "Austria",
+        "chinese_name": "奥地利",
+        "country_code": "AT",
+        "phone_code": "43"
+    },
+    {
+        "english_name": "Antigua and Barbuda",
+        "chinese_name": "安提瓜和巴布达",
+        "country_code": "AG",
+        "phone_code": "1268"
+    },
+    {
+        "english_name": "Anguilla",
+        "chinese_name": "安圭拉",
+        "country_code": "AI",
+        "phone_code": "1264"
+    },
+    {
+        "english_name": "Angola",
+        "chinese_name": "安哥拉",
+        "country_code": "AO",
+        "phone_code": "244"
+    },
+    {
+        "english_name": "Andorra",
+        "chinese_name": "安道尔",
+        "country_code": "AD",
+        "phone_code": "376"
+    },
+    {
+        "english_name": "Estonia",
+        "chinese_name": "爱沙尼亚",
+        "country_code": "EE",
+        "phone_code": "372"
+    },
+    {
+        "english_name": "Ireland",
+        "chinese_name": "爱尔兰",
+        "country_code": "IE",
+        "phone_code": "353"
+    },
+    {
+        "english_name": "Ethiopia",
+        "chinese_name": "埃塞俄比亚",
+        "country_code": "ET",
+        "phone_code": "251"
+    },
+    {
+        "english_name": "Egypt",
+        "chinese_name": "埃及",
+        "country_code": "EG",
+        "phone_code": "20"
+    },
+    {
+        "english_name": "Azerbaijan",
+        "chinese_name": "阿塞拜疆",
+        "country_code": "AZ",
+        "phone_code": "994"
+    },
+    {
+        "english_name": "Oman",
+        "chinese_name": "阿曼",
+        "country_code": "OM",
+        "phone_code": "968"
+    },
+    {
+        "english_name": "Aruba",
+        "chinese_name": "阿鲁巴",
+        "country_code": "AW",
+        "phone_code": "297"
+    },
+    {
+        "english_name": "United Arab Emirates",
+        "chinese_name": "阿拉伯联合酋长国",
+        "country_code": "AE",
+        "phone_code": "971"
+    },
+    {
+        "english_name": "Argentina",
+        "chinese_name": "阿根廷",
+        "country_code": "AR",
+        "phone_code": "54"
+    },
+    {
+        "english_name": "Afghanistan",
+        "chinese_name": "阿富汗",
+        "country_code": "AF",
+        "phone_code": "93"
+    },
+    {
+        "english_name": "Algeria",
+        "chinese_name": "阿尔及利亚",
+        "country_code": "DZ",
+        "phone_code": "213"
+    },
+    {
+        "english_name": "Albania",
+        "chinese_name": "阿尔巴尼亚",
+        "country_code": "AL",
+        "phone_code": "355"
+    }
+]

+ 12 - 9
sheep/platform/pay.js

@@ -91,9 +91,11 @@ export default class SheepPay {
         channelCode: channel,
         channelExtras: {}
       };
+	  
       // 特殊逻辑:微信公众号、小程序支付时,必须传入 openid
       if (['wx_pub', 'wx_lite'].includes(channel)) {
-        const openid = await sheep.$platform.useProvider('wechat').getOpenid();
+		console.log(sheep.$platform.useProvider('wechat').getOpenid)
+        const openid = await sheep.$platform.useProvider('wechat').getOpenid(true);
         // 如果获取不到 openid,微信无法发起支付,此时需要引导
         if (!openid) {
           this.bindWeixin();
@@ -275,6 +277,7 @@ export default class SheepPay {
     uni.showModal({
       title: '微信支付',
       content: '请先绑定微信再使用微信支付',
+	  confirmText:'绑定',
       success: function (res) {
         if (res.confirm) {
           sheep.$platform.useProvider('wechat').bind();
@@ -338,15 +341,15 @@ export function getPayMethods(channels) {
     alipayMethod.disabled = false;
   }
   // 3. 处理【余额支付】
-  const walletMethod = payMethods[2];
-  if (channels.includes('wallet')) {
-    walletMethod.disabled = false;
-  }
+  // const walletMethod = payMethods[2];
+  // if (channels.includes('wallet')) {
+  //   walletMethod.disabled = false;
+  // }
   // 4. 处理【苹果支付】TODO 非繁人:未来接入
   // 5. 处理【模拟支付】
-  const mockMethod = payMethods[4];
-  if (channels.includes('mock')) {
-    mockMethod.disabled = false;
-  }
+  // const mockMethod = payMethods[4];
+  // if (channels.includes('mock')) {
+  //   mockMethod.disabled = false;
+  // }
   return payMethods;
 }

+ 36 - 2
sheep/platform/provider/wechat/officialAccount.js

@@ -8,6 +8,7 @@ import {
 	closeAuthModal,
 	showAuthModal
 } from '@/sheep/hooks/useModal';
+import sheep from '@/sheep';
 const socialType = 31; // 社交类型 - 微信公众号
 
 // 加载微信公众号JSSDK
@@ -29,7 +30,7 @@ async function login(code = '', state = '') {
 	} else {
 		// 解密 code 发起登陆
 		const loginResult = await AuthUtil.socialLogin(socialType, code, state);
-		console.log("loginResult真正的登录结果:",loginResult)
+		// console.log("loginResult真正的登录结果:",loginResult.data.socialUsers)
 		if (loginResult.code === 0) {
 			// TODO 非繁人:shareLog
 			setOpenid(loginResult.data.openid);
@@ -38,6 +39,33 @@ async function login(code = '', state = '') {
 	}
 	return false;
 }
+// 微信公众号注册
+async function register(code = '', state = '') {
+	// 情况一:没有 code 时,去获取 code
+	if (!code) {
+		const loginUrl = await getLoginUrl('register');
+		
+		if (loginUrl) {
+			uni.setStorageSync('returnUrl', location.href);
+			window.location = loginUrl;
+		}
+		// 情况二:有 code 时,使用 code 去注册
+	} else {
+		// 解密 code 发起注册
+		// 从缓存中拿到linkId
+		const linkId = uni.getStorageSync("linkId");
+		console.log("official linkId",linkId)
+		// console.log("这是第二次注册了",linkId,socialType, code, state)
+		const registerResult = await AuthUtil.officialRegister({linkId,type:socialType, code, state});
+		if (registerResult.code === 0) {
+			// TODO 非繁人:shareLog
+			setOpenid(registerResult.data.openid);
+			return registerResult;
+		}
+	}
+	return false;
+}
+
 
 // 微信公众号绑定
 async function bind(code = '', state = '') {
@@ -53,6 +81,7 @@ async function bind(code = '', state = '') {
 		const loginResult = await SocialApi.socialBind(socialType, code, state);
 		if (loginResult.code === 0) {
 			setOpenid(loginResult.data);
+			sheep.$helper.toast(`已绑定`);
 			return loginResult;
 		}
 	}
@@ -70,7 +99,7 @@ const unbind = async (openid) => {
 // 获取公众号登陆地址
 async function getLoginUrl(event = 'login') {
 	const page = getRootUrl() + 'pages/index/login' +
-		'?event=' + event; // event 目的,区分是 login 还是 bind
+		'?event=' + event; // event 目的,区分是 login 还是 bind 还是 register
 
 	const {
 		code,
@@ -90,9 +119,12 @@ function setOpenid(openid) {
 
 // 获得 openid
 async function getOpenid(force = false) {
+	
 	let openid = uni.getStorageSync('openid');
+	
 	if (!openid && force) {
 		const info = await getInfo();
+		console.log(info)
 		if (info && info.openid) {
 			openid = info.openid;
 			setOpenid(openid);
@@ -107,6 +139,7 @@ async function getInfo() {
 		code,
 		data
 	} = await SocialApi.getSocialUser(socialType);
+	
 	if (code !== 0) {
 		return undefined;
 	}
@@ -116,6 +149,7 @@ async function getInfo() {
 export default {
 	load,
 	login,
+	register,
 	bind,
 	unbind,
 	getInfo,

+ 87 - 83
sheep/request/index.js

@@ -8,7 +8,7 @@ import { baseUrl, apiPath } from '@/sheep/config';
 import $store from '@/sheep/store';
 import $platform from '@/sheep/platform';
 import {
-	showAuthModal
+	showAuthModal, cancelAutoSign
 } from '@/sheep/hooks/useModal';
 import AuthUtil from '@/sheep/api/member/auth';
 
@@ -71,13 +71,13 @@ const http = new Request({
  */
 http.interceptors.request.use(
 	(config) => {
-    // 自定义处理【auth 授权】:必须登录的接口,则跳出 AuthModal 登录弹窗
+		// 自定义处理【auth 授权】:必须登录的接口,则跳出 AuthModal 登录弹窗
 		if (config.custom.auth && !$store('user').isLogin) {
 			showAuthModal();
 			return Promise.reject();
 		}
 
-    // 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading
+		// 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading
 		if (config.custom.showLoading) {
 			LoadingInstance.count++;
 			LoadingInstance.count === 1 &&
@@ -90,16 +90,16 @@ http.interceptors.request.use(
 				});
 		}
 
-    // 增加 token 令牌、terminal 终端、tenant 租户的请求头
+		// 增加 token 令牌、terminal 终端、tenant 租户的请求头
 		const token = getAccessToken();
 		if (token) {
-      config.header['Authorization'] = token;
-    }
+			config.header['Authorization'] = token;
+		}
 		// TODO 非繁人:特殊处理
-    config.header['Accept'] = '*/*'
-    config.header['tenant-id'] = '1';
-    config.header['terminal'] = '20';
-    // config.header['Authorization'] = 'Bearer test247';
+		config.header['Accept'] = '*/*'
+		config.header['tenant-id'] = '1';
+		config.header['terminal'] = '20';
+		// config.header['Authorization'] = 'Bearer test247';
 		return config;
 	},
 	(error) => {
@@ -117,40 +117,44 @@ http.interceptors.response.use(
 			$store('user').setToken(response.data.data.accessToken, response.data.data.refreshToken);
 		}
 
-    // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading
+		// 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading
 		response.config.custom.showLoading && closeLoading();
 
-    // 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示
+		// 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示
 		if (response.data.code !== 0) {
-      // 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌
-      if (response.data.code === 401) {
-        return refreshToken(response.config);
-      }
+			// 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌
+			if (response.data.code === 401) {
+				cancelAutoSign()
+				return refreshToken(response.config);
+			}
 
-      // 错误提示
+			// 错误提示
 			if (response.config.custom.showError) {
+				cancelAutoSign()
 				uni.showToast({
 					title: response.data.msg || '服务器开小差啦,请稍后再试~',
 					icon: 'none',
 					mask: true,
 				});
-      }
+			}
 		}
 
 		// 自定义处理【showSuccess 成功提示】:如果需要显示成功提示,则显示成功提示
 		if (response.config.custom.showSuccess
-      && response.config.custom.successMsg !== ''
-      &&  response.data.code === 0) {
-      uni.showToast({
+			&& response.config.custom.successMsg !== ''
+			&& response.data.code === 0) {
+			uni.showToast({
 				title: response.config.custom.successMsg,
 				icon: 'none',
 			});
 		}
 
-    // 返回结果:包括 code + data + msg
+		// 返回结果:包括 code + data + msg
 		return Promise.resolve(response.data);
 	},
 	(error) => {
+		console.log("服务器开小差")
+		cancelAutoSign()
 		const userStore = $store('user');
 		const isLogin = userStore.isLogin;
 		let errorMessage = '网络请求出错';
@@ -160,9 +164,9 @@ http.interceptors.response.use(
 					errorMessage = '请求错误';
 					break;
 				case 401:
-          errorMessage = isLogin ? '您的登陆已过期' : '请登录';
-          // 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized
-          break;
+					errorMessage = isLogin ? '您的登陆已过期' : '请登录';
+					// 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized
+					break;
 				case 403:
 					errorMessage = '拒绝访问';
 					break;
@@ -220,79 +224,79 @@ http.interceptors.response.use(
 let requestList = [] // 请求队列
 let isRefreshToken = false // 是否正在刷新中
 const refreshToken = async (config) => {
-  // 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error)
-  if (config.url.indexOf('/member/auth/refresh-token') >= 0) {
-    return Promise.reject('error')
-  }
+	// 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error)
+	if (config.url.indexOf('/member/auth/refresh-token') >= 0) {
+		return Promise.reject('error')
+	}
 
-  // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
-  if (!isRefreshToken) {
-    isRefreshToken = true
-    // 1. 如果获取不到刷新令牌,则只能执行登出操作
-    const refreshToken = getRefreshToken()
-    if (!refreshToken) {
-      return handleAuthorized()
-    }
-    // 2. 进行刷新访问令牌
-    try {
-      const refreshTokenResult = await AuthUtil.refreshToken(refreshToken);
-      if (refreshTokenResult.code !== 0) {
-        // 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑
-        // noinspection ExceptionCaughtLocallyJS
-        throw new Error('刷新令牌失败');
-      }
-      // 2.1 刷新成功,则回放队列的请求 + 当前请求
-      config.header.Authorization = 'Bearer ' + getAccessToken()
-      requestList.forEach((cb) => {
-        cb()
-      })
-      requestList = []
-      return request(config)
-    } catch (e) {
-      // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
-      // 2.2 刷新失败,只回放队列的请求
-      requestList.forEach((cb) => {
-        cb()
-      })
-      // 提示是否要登出。即不回放当前请求!不然会形成递归
-      return handleAuthorized()
-    } finally {
-      requestList = []
-      isRefreshToken = false
-    }
-  } else {
-    // 添加到队列,等待刷新获取到新的令牌
-    return new Promise((resolve) => {
-      requestList.push(() => {
-        config.header.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
-        resolve(request(config))
-      })
-    })
-  }
+	// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
+	if (!isRefreshToken) {
+		isRefreshToken = true
+		// 1. 如果获取不到刷新令牌,则只能执行登出操作
+		const refreshToken = getRefreshToken()
+		if (!refreshToken) {
+			return handleAuthorized()
+		}
+		// 2. 进行刷新访问令牌
+		try {
+			const refreshTokenResult = await AuthUtil.refreshToken(refreshToken);
+			if (refreshTokenResult.code !== 0) {
+				// 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑
+				// noinspection ExceptionCaughtLocallyJS
+				throw new Error('刷新令牌失败');
+			}
+			// 2.1 刷新成功,则回放队列的请求 + 当前请求
+			config.header.Authorization = 'Bearer ' + getAccessToken()
+			requestList.forEach((cb) => {
+				cb()
+			})
+			requestList = []
+			return request(config)
+		} catch (e) {
+			// 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
+			// 2.2 刷新失败,只回放队列的请求
+			requestList.forEach((cb) => {
+				cb()
+			})
+			// 提示是否要登出。即不回放当前请求!不然会形成递归
+			return handleAuthorized()
+		} finally {
+			requestList = []
+			isRefreshToken = false
+		}
+	} else {
+		// 添加到队列,等待刷新获取到新的令牌
+		return new Promise((resolve) => {
+			requestList.push(() => {
+				config.header.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+				resolve(request(config))
+			})
+		})
+	}
 }
 
 /**
  * 处理 401 未登录的错误
  */
 const handleAuthorized = () => {
-  const userStore = $store('user');
-  userStore.logout(true);
-  showAuthModal();
-  // 登录超时
-  return Promise.reject({
-    code: 401,
-    msg: userStore.isLogin ? '您的登陆已过期' : '请登录'
-  })
+	const userStore = $store('user');
+	userStore.logout(true);
+	showAuthModal();
+	// 登录超时
+	return Promise.reject({
+		code: 401,
+		msg: userStore.isLogin ? '您的登陆已过期' : '请登录'
+	})
 }
 
 /** 获得访问令牌 */
 const getAccessToken = () => {
-  return uni.getStorageSync('token');
+	return uni.getStorageSync('token');
 }
 
 /** 获得刷新令牌 */
 const getRefreshToken = () => {
-  return uni.getStorageSync('refresh-token');
+	return uni.getStorageSync('refresh-token');
 }
 
 const request = (config) => {

+ 1 - 1
sheep/scss/_var.scss

@@ -7,7 +7,7 @@ $red: #ff3000; //ss-红
 $pink: #e03997;
 $mauve: #b745cb;
 $purple: #652abf; //rgba(101, 42, 191, 1); // ss-紫
-$blue: #0081ff;
+$blue: #132b85;
 $cyan: #37c0fe;
 $green: #2aae67; //ss-绿
 $olive: #8dc63f;

+ 11 - 1
sheep/store/modal.js

@@ -4,8 +4,18 @@ const modal = defineStore({
   id: 'modal',
   state: () => ({
     auth: '', // 授权弹框 accountLogin|smsLogin|resetPassword|changeMobile|changePassword|changeUsername
-	isActive: '',
+	  isActive: '',
     share: false, // 分享弹框
+    shareInfo: {
+      spuId: 0,
+    }, // 分享弹框信息
+    signUp:false, // 签到弹框
+    signUpInfo:{}, // 签到弹框信息
+	getWallet:false, // 获得积分/身价弹窗
+	getWalletInfo:{
+		points:0,
+		socialStatus:0,
+	}, // 获得积分/身价弹窗信息
     menu: false, // 快捷菜单弹框
     advHistory: [], // 广告弹框记录
     lastTimer: {

+ 1 - 0
sheep/store/sys.js

@@ -12,6 +12,7 @@ const sys = defineStore({
   getters: {},
   actions: {
     setTheme(theme = '') {
+		
       if (theme === '') {
         this.theme = app().template?.basic.theme || 'orange';
       } else {

+ 219 - 205
sheep/store/user.js

@@ -1,209 +1,223 @@
-import {
-	defineStore
-} from 'pinia';
-// import userApi from '@/sheep/api/user';
-import $share from '@/sheep/platform/share';
-import {
-	isEmpty,
-	cloneDeep,
-	clone
-} from 'lodash';
-import cart from './cart';
-import app from './app';
-import {
-	showAuthModal
-} from '@/sheep/hooks/useModal';
-import UserApi from '@/sheep/api/member/user';
-import PayWalletApi from '@/sheep/api/pay/wallet';
-import OrderApi from '@/sheep/api/trade/order';
-import CouponApi from '@/sheep/api/promotion/coupon';
-
-// 默认用户信息
-const defaultUserInfo = {
-	avatar: '', // 头像
-	nickname: '', // 昵称
-	gender: 0, // 性别
-	mobile: '', // 手机号
-	point: 0, // 积分
-	socialStatusLevel: "",
-	socialStatusLevelName: "",
-	socialStatusPoint: 0,
-	socialUpNeed: 0,
-};
-
-// 默认钱包信息
-const defaultUserWallet = {
-	integralDO:{
-		currentQuota:0, // 当前积分
-		highQuota:0, //最高积分
-		freezeQuota:0 //冻结积分
+import {
+	defineStore
+} from 'pinia';
+// import userApi from '@/sheep/api/user';
+import $share from '@/sheep/platform/share';
+import {
+	isEmpty,
+	cloneDeep,
+	clone
+} from 'lodash';
+import cart from './cart';
+import app from './app';
+import {
+	showAuthModal,
+	cancelAutoSign,
+	autoSign
+} from '@/sheep/hooks/useModal';
+import UserApi from '@/sheep/api/member/user';
+import PayWalletApi from '@/sheep/api/pay/wallet';
+import OrderApi from '@/sheep/api/trade/order';
+import CouponApi from '@/sheep/api/promotion/coupon';
+
+// 默认用户信息
+const defaultUserInfo = {
+	avatar: '', // 头像
+	nickname: '', // 昵称
+	gender: 0, // 性别
+	mobile: '', // 手机号
+	point: 0, // 积分
+	username:'', //用户名
+	socialStatusLevel: "",
+	socialStatusLevelName: "",
+	socialStatusPoint: 0,
+	socialUpNeed: 0,
+};
+
+// 默认钱包信息
+const defaultUserWallet = {
+	integralDO: {
+		currentQuota: 0, // 当前积分
+		highQuota: 0, //最高积分
+		freezeQuota: 0 //冻结积分
 	},
-	descNo:0, //用户直推人人数
-	descPrice:0, //团队昨日贡献值
-	descTotalPrice:0, // 团队历史总贡献值
-}
-
-// 默认订单、优惠券等其他资产信息
-const defaultNumData = {
-	unusedCouponCount: 0,
-	orderCount: {
-		allCount: 0,
-		unpaidCount: 0,
-		undeliveredCount: 0,
-		deliveredCount: 0,
-		uncommentedCount: 0,
-		afterSaleCount: 0,
-	},
-};
-
-const user = defineStore({
-	id: 'user',
-	state: () => ({
-		userInfo: clone(defaultUserInfo), // 用户信息
-		userWallet: clone(defaultUserWallet), // 用户钱包信息
-		isLogin: !!uni.getStorageSync('token'), // 登录状态
-		numData: cloneDeep(defaultNumData), // 用户其他数据
-		lastUpdateTime: 0, // 上次更新时间
-	}),
-
-	actions: {
-		// 获取用户信息
-		async getInfo() {
-			const {
-				code,
-				data
-			} = await UserApi.getUserInfo();
-			if (code !== 0) {
-				return;
-			}
-			this.userInfo = data;
-			return Promise.resolve(data);
-		},
-
-
-		// 获得用户钱包
-		async getWallet() {
-			const {
-				code,
-				data
-			} = await PayWalletApi.getDuserInfo();
-			if (code !== 0) {
-				return;
-			}
-			this.userWallet = data;
-			// 为什么要加2 因为这里返回来的人员不包括自身
+	
+	descNo: 0, //用户直推人人数
+	descPrice: 0, //团队昨日贡献值
+	descTotalPrice: 0, // 团队历史总贡献值
+}
+
+// 默认订单、优惠券等其他资产信息
+const defaultNumData = {
+	unusedCouponCount: 0,
+	orderCount: {
+		allCount: 0,
+		unpaidCount: 0,
+		undeliveredCount: 0,
+		deliveredCount: 0,
+		uncommentedCount: 0,
+		afterSaleCount: 0,
+	},
+};
+
+const user = defineStore({
+	id: 'user',
+	state: () => ({
+		userInfo: clone(defaultUserInfo), // 用户信息
+		userWallet: clone(defaultUserWallet), // 用户钱包信息
+		isLogin: !!uni.getStorageSync('token'), // 登录状态
+		numData: cloneDeep(defaultNumData), // 用户其他数据
+		lastUpdateTime: 0, // 上次更新时间
+	}),
+
+	actions: {
+		// 获取用户信息
+		async getInfo() {
+			const {
+				code,
+				data
+			} = await UserApi.getUserInfo();
+			if (code !== 0) {
+				return;
+			}
+			// console.log("user.js data",data)
+			
+			this.userInfo = data;
+			// console.log("user.js this.userInfo",this.userInfo)
+			// console.log("获取到用户信息 开始自动签到")
+			autoSign();
+			return Promise.resolve(data);
+		},
+
+
+		// 获得用户钱包
+		async getWallet() {
+			const {
+				code,
+				data
+			} = await PayWalletApi.getDuserInfo();
+			if (code !== 0) {
+				return;
+			}
+			this.userWallet = data;
+			// 为什么要加1 因为这里返回来的人员不包括自身
 			this.userWallet.descNo = data.descNo + 1
-		},
-
-		// 获取订单、优惠券等其他资产信息
-		getNumData() {
-			OrderApi.getOrderCount().then(res => {
-				if (res.code === 0) {
-					this.numData.orderCount = res.data;
-				}
-			});
-			CouponApi.getUnusedCouponCount().then(res => {
-				if (res.code === 0) {
-					this.numData.unusedCouponCount = res.data;
-				}
-			});
-		},
-
-		// 添加分享记录
-		// TODO 非繁人:整理下;
-		async addShareLog(params) {
-			const {
-				error
-			} = await userApi.addShareLog(params);
-			if (error === 0) uni.removeStorageSync('shareLog');
-		},
-
-		// 设置 token
-		setToken(token = '', refreshToken = '') {
-			if (token === '') {
-				this.isLogin = false;
-				uni.removeStorageSync('token');
-				uni.removeStorageSync('refresh-token')
-			} else {
-				this.isLogin = true;
-				uni.setStorageSync('token', token);
-				uni.setStorageSync('refresh-token', refreshToken);
-				this.loginAfter();
-			}
-			return this.isLogin;
-		},
-
-		// 更新用户相关信息 (手动限流,5 秒之内不刷新)
-		async updateUserData() {
-			if (!this.isLogin) {
-				this.resetUserData();
-				return;
-			}
-			// 防抖,5 秒之内不刷新
-			const nowTime = new Date().getTime();
-			if (this.lastUpdateTime + 5000 > nowTime) {
-				return;
-			}
-			this.lastUpdateTime = nowTime;
-
-			// 获取最新信息
-			await this.getInfo();
-			this.getWallet();
-			this.getNumData();
-			return this.userInfo;
-		},
-
-		// 重置用户默认数据
-		resetUserData() {
-			// 清空 token
-			this.setToken();
-			// 清空用户相关的缓存
-			this.userInfo = clone(defaultUserInfo);
-			this.userWallet = clone(defaultUserWallet);
-			this.numData = cloneDeep(defaultNumData);
-			// 清空购物车的缓存
+			uni.setStorageSync('isSign', data.isSign);
+		},
+
+		// 获取订单、优惠券等其他资产信息
+		getNumData() {
+			OrderApi.getOrderCount().then(res => {
+				if (res.code === 0) {
+					this.numData.orderCount = res.data;
+				}
+			});
+			CouponApi.getUnusedCouponCount().then(res => {
+				if (res.code === 0) {
+					this.numData.unusedCouponCount = res.data;
+				}
+			});
+		},
+
+		// 添加分享记录
+		// TODO 非繁人:整理下;
+		async addShareLog(params) {
+			const {
+				error
+			} = await userApi.addShareLog(params);
+			if (error === 0) uni.removeStorageSync('shareLog');
+		},
+
+		// 设置 token
+		setToken(token = '', refreshToken = '') {
+			if (token === '') {
+				this.isLogin = false;
+				uni.removeStorageSync('token');
+				uni.removeStorageSync('refresh-token')
+			} else {
+				this.isLogin = true;
+				uni.setStorageSync('token', token);
+				uni.setStorageSync('refresh-token', refreshToken);
+				this.loginAfter();
+			}
+			return this.isLogin;
+		},
+
+		// 更新用户相关信息 (手动限流,5 秒之内不刷新)
+		async updateUserData() {
+			if (!this.isLogin) {
+				this.resetUserData();
+				return;
+			}
+			// 防抖,5 秒之内不刷新
+			const nowTime = new Date().getTime();
+			if (this.lastUpdateTime + 5000 > nowTime) {
+				return;
+			}
+			this.lastUpdateTime = nowTime;
+
+			// 获取最新信息
+			await this.getInfo();
+			this.getWallet();
+			this.getNumData();
+			return this.userInfo;
+
+		},
+
+		// 重置用户默认数据
+		resetUserData() {
+			// 清空 token
+			this.setToken();
+			// 清空用户相关的缓存
+			this.userInfo = clone(defaultUserInfo);
+			this.userWallet = clone(defaultUserWallet);
+			this.numData = cloneDeep(defaultNumData);
+			// 清空购物车的缓存
 			cart().emptyList();
-			// 清空linkId
-			
-			
-		},
-
-		// 登录后,加载各种信息
-		// TODO 非繁人:整理下;
-		async loginAfter() {
-			await this.updateUserData();
-
-			// 加载购物车
-			cart().getList();
-			// 登录后设置全局分享参数
-			$share.getShareInfo();
-
-			// 提醒绑定手机号
-			if (app().platform.bind_mobile && !this.userInfo.mobile) {
-				showAuthModal('changeMobile');
-			}
-			// 添加分享记录
-			// TODO 非繁人:整理下;
-			const shareLog = uni.getStorageSync('shareLog');
-			if (!isEmpty(shareLog)) {
-				this.addShareLog({
-					...shareLog,
-				});
-			}
-		},
-
-		// 登出系统
-		async logout() {
-			this.resetUserData();
-			return !this.isLogin;
-		}
-	},
-	persist: {
-		enabled: true,
-		strategies: [{
-			key: 'user-store',
-		}, ],
-	},
-});
-
+			// console.log("重制用户数据 取消自动签到")
+			// 取消自动签到
+			cancelAutoSign()
+			// 删掉缓存中的isSign
+			uni.removeStorageSync('isSign');
+
+		},
+
+		// 登录后,加载各种信息
+		// TODO 非繁人:整理下;
+		async loginAfter() {
+			await this.updateUserData();
+
+			// 加载购物车
+			cart().getList();
+			// 登录后设置全局分享参数
+			$share.getShareInfo();
+
+			// 提醒绑定手机号
+			// if (app().platform.bind_mobile && !this.userInfo.mobile) {
+			// 	showAuthModal('changeMobile');
+			// }
+			// 添加分享记录
+			// TODO 非繁人:整理下;
+			const shareLog = uni.getStorageSync('shareLog');
+			if (!isEmpty(shareLog)) {
+				this.addShareLog({
+					...shareLog,
+				});
+			}
+		},
+
+		// 登出系统
+		async logout() {
+			this.resetUserData();
+			return !this.isLogin;
+		}
+	},
+	persist: {
+		enabled: true,
+		strategies: [{
+			key: 'user-store',
+		}, ],
+	},
+});
+
 export default user;

+ 1 - 0
sheep/url/index.js

@@ -27,6 +27,7 @@ export default {
     if (staticurl !== 'local') {
       url = cdn(url, staticurl);
     }
+	
     return url;
   },
   // css背景图片地址

+ 17 - 0
sheep/validate/form.js

@@ -4,6 +4,23 @@
  */
 import test from '@/sheep/helper/test.js';
 
+// 用户名
+export const username = {
+  rules: [
+    {
+      required: true,
+      errorMessage: '请输入用户名',
+    },
+    {
+      validateFunction: function (rule, value, data, callback) {
+        if (!value) {
+          callback('用户名不能为空');
+        }
+        return true;
+      },
+    },
+  ],
+};
 // 手机号
 export const mobile = {
   rules: [

BIN
static/icon/audioPaly.png


BIN
static/icon/points.png


BIN
static/icon/select-icon.png


BIN
static/icon/setting.png


BIN
static/images/WechatMiniProgram.png


BIN
static/images/WechatOfficialAccount.png


BIN
static/images/activity-btn-disabled.png


BIN
static/images/all_coupon.png


BIN
static/images/all_order.png


BIN
static/images/apple.png


BIN
static/images/browse.png


BIN
static/images/cargo.png


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików