Эх сурвалжийг харах

Merge branch 'master' of http://git.huaml.com/zhh/front-end

lalala 6 жил өмнө
parent
commit
3a5d94752b
78 өөрчлөгдсөн 2193 нэмэгдсэн , 606 устгасан
  1. 1 1
      business/index.html
  2. 4 0
      business/static/css/base.scss
  3. 10 0
      business/static/css/common.scss
  4. BIN
      business/static/images/order/tag.png
  5. BIN
      business/static/img/invite.c0148d47.png
  6. 0 0
      business/static/js/index.788227f7.js
  7. 0 0
      business/static/js/index.94908fad.js
  8. 0 0
      business/static/js/pages-ad-add.ab3c9e1a.js
  9. 0 0
      business/static/js/pages-ad-add.d1047856.js
  10. 0 0
      business/static/js/pages-ad-list.07baf06b.js
  11. 0 0
      business/static/js/pages-ad-list.148ed2ee.js
  12. 0 0
      business/static/js/pages-ad-list~pages-admin-member~pages-coupon-admin-list~pages-interest-admin-invite.99cdb3ce.js
  13. 0 0
      business/static/js/pages-ad-sel-goods.e9bcdcbb.js
  14. 0 0
      business/static/js/pages-ad-sel-goods.fe4ff63a.js
  15. 0 0
      business/static/js/pages-admin-member.f128798b.js
  16. 0 0
      business/static/js/pages-admin-member.fa95dc5c.js
  17. 0 0
      business/static/js/pages-admin-order.a7ae36df.js
  18. 0 0
      business/static/js/pages-admin-order.f9ef92e4.js
  19. 0 0
      business/static/js/pages-admin-workbench.1dc7fa41.js
  20. 0 0
      business/static/js/pages-coupon-admin-list.313aee6f.js
  21. 0 0
      business/static/js/pages-coupon-admin-list.ec644c65.js
  22. 0 0
      business/static/js/pages-goodsManage-category.9e18acf1.js
  23. 0 0
      business/static/js/pages-goodsManage-category.af2805e7.js
  24. 0 0
      business/static/js/pages-goodsManage-img-store.9899553e.js
  25. 0 0
      business/static/js/pages-goodsManage-img-store.9a7774b7.js
  26. 0 0
      business/static/js/pages-interest-admin-invite.30e03b08.js
  27. 0 0
      business/static/js/pages-interest-admin-invite.900912de.js
  28. 0 0
      business/static/js/pages-interest-admin-my-invite.53a68aaa.js
  29. 0 0
      business/static/js/pages-interest-admin-my-invite.d518c6d8.js
  30. 0 0
      business/static/js/pages-interest-admin-setting.ba177ede.js
  31. 0 0
      business/static/js/pages-interest-admin-setting.fe65fee3.js
  32. 0 0
      business/static/js/pages-member-detail.9fc45a3d.js
  33. 0 0
      business/static/js/pages-member-detail.d4556472.js
  34. 0 0
      business/static/js/pages-order-admin-ship.8c0e7d44.js
  35. 0 0
      business/static/js/pages-setting-coupon.21a5b15b.js
  36. 0 0
      business/static/js/pages-setting-coupon.9640cd4a.js
  37. 0 0
      business/static/js/pages-setting-wx-menu.76612389.js
  38. 0 0
      business/static/js/pages-setting-wx-menu.efdb6f4e.js
  39. 0 0
      business/static/js/pages-staff-add.6b2a982c.js
  40. 0 0
      business/static/js/pages-staff-add.ec49d908.js
  41. 0 0
      business/static/js/pages-staff-list.bfeb14d6.js
  42. 0 0
      business/static/js/pages-staff-list.fd969a9f.js
  43. 0 0
      business/static/js/pages-staff-sel-member.5c14f668.js
  44. 0 0
      business/static/js/pages-staff-sel-member.f08ba620.js
  45. 57 0
      mobile-code/src/api/ad/index.js
  46. 1 3
      mobile-code/src/api/common/index.js
  47. 30 0
      mobile-code/src/api/coupon/index.js
  48. 28 0
      mobile-code/src/api/invite/index.js
  49. 13 0
      mobile-code/src/api/login/index.js
  50. 57 0
      mobile-code/src/api/member/index.js
  51. 71 0
      mobile-code/src/api/staff/index.js
  52. 10 9
      mobile-code/src/components/app-date-picker.vue
  53. 1 0
      mobile-code/src/components/app-wrapper-empty.vue
  54. 2 2
      mobile-code/src/components/module/app-avatar.vue
  55. 10 5
      mobile-code/src/components/module/app-search.vue
  56. 4 3
      mobile-code/src/components/plugin/modal.vue
  57. 1 1
      mobile-code/src/components/plugin/tabs.vue
  58. 35 0
      mobile-code/src/filters/constant.js
  59. 81 0
      mobile-code/src/filters/constantFilter.js
  60. 1 2
      mobile-code/src/m-pages.json
  61. 4 0
      mobile-code/src/main.js
  62. 234 83
      mobile-code/src/pages/ad/add.vue
  63. 158 41
      mobile-code/src/pages/ad/list.vue
  64. 87 4
      mobile-code/src/pages/ad/sel-goods.vue
  65. 52 39
      mobile-code/src/pages/admin/components/sel-search.vue
  66. 1 1
      mobile-code/src/pages/admin/workbench.vue
  67. 106 53
      mobile-code/src/pages/coupon/admin/list.vue
  68. 94 50
      mobile-code/src/pages/coupon/list.vue
  69. 199 125
      mobile-code/src/pages/interest/admin/invite.vue
  70. 38 7
      mobile-code/src/pages/interest/admin/setting.vue
  71. 36 6
      mobile-code/src/pages/setting/coupon.vue
  72. 181 75
      mobile-code/src/pages/staff/add.vue
  73. 227 80
      mobile-code/src/pages/staff/list.vue
  74. 60 1
      mobile-code/src/pages/staff/sel-member.vue
  75. 14 11
      mobile-code/src/plugins/luch-request_0.0.7/request.js
  76. 267 0
      mobile-code/src/utils/formValidation.js
  77. 8 1
      mobile-code/src/utils/format.js
  78. 10 3
      mobile-code/src/utils/util.js

+ 1 - 1
business/index.html

@@ -6,4 +6,4 @@
 				// window.location.href = '/h5/pcguide.html';
 			}</script><script>document.addEventListener('DOMContentLoaded', function() {
 				document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
-			})</script><link rel=stylesheet href=/static/index.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script>/*BAIDU_STAT*/</script><script src=/static/js/chunk-vendors.3186e5ea.js></script><script src=/static/js/index.788227f7.js></script></body></html>
+			})</script><link rel=stylesheet href=/static/index.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script>/*BAIDU_STAT*/</script><script src=/static/js/chunk-vendors.3186e5ea.js></script><script src=/static/js/index.94908fad.js></script></body></html>

+ 4 - 0
business/static/css/base.scss

@@ -121,6 +121,10 @@
     color: $fontColor3;
 }
 
+.app-color-4 {
+    color: $mainColor1;
+}
+
 // 金额
 .app-price {
 	color: #FF2842;

+ 10 - 0
business/static/css/common.scss

@@ -86,6 +86,11 @@ body {
         background-color: #f5f5f5;
     }
 }
+.button-com.disable {
+    color: #fff;
+    background-color: #ccc;
+    border-color: #ccc;
+}
 // ============ 后台 =============
 .admin-button-com {
     display: inline-block;
@@ -129,6 +134,11 @@ body {
     }
 }
 
+.admin-button-com.disable {
+    color: #fff;
+    background-color: #ccc;
+    border-color: #ccc;
+}
 // ======================= 输入框公共样式 - start ====================
 .input-line-wrap {
     // 是否必填

BIN
business/static/images/order/tag.png


BIN
business/static/img/invite.c0148d47.png


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/index.788227f7.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/index.94908fad.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-add.ab3c9e1a.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-add.d1047856.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-list.07baf06b.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-list.148ed2ee.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-list~pages-admin-member~pages-coupon-admin-list~pages-interest-admin-invite.99cdb3ce.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-sel-goods.e9bcdcbb.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-ad-sel-goods.fe4ff63a.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-admin-member.f128798b.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-admin-member.fa95dc5c.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-admin-order.a7ae36df.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-admin-order.f9ef92e4.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-admin-workbench.1dc7fa41.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-coupon-admin-list.313aee6f.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-coupon-admin-list.ec644c65.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-goodsManage-category.9e18acf1.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-goodsManage-category.af2805e7.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-goodsManage-img-store.9899553e.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-goodsManage-img-store.9a7774b7.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-invite.30e03b08.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-invite.900912de.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-my-invite.53a68aaa.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-my-invite.d518c6d8.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-setting.ba177ede.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-interest-admin-setting.fe65fee3.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-member-detail.9fc45a3d.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-member-detail.d4556472.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-order-admin-ship.8c0e7d44.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-setting-coupon.21a5b15b.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-setting-coupon.9640cd4a.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-setting-wx-menu.76612389.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-setting-wx-menu.efdb6f4e.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-add.6b2a982c.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-add.ec49d908.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-list.bfeb14d6.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-list.fd969a9f.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-sel-member.5c14f668.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
business/static/js/pages-staff-sel-member.f08ba620.js


+ 57 - 0
mobile-code/src/api/ad/index.js

@@ -0,0 +1,57 @@
+import https from '@/plugins/luch-request_0.0.7/request'
+
+/** *
+ * 广告列表  b
+ */
+export const getList = data => {
+	return https.get('/ad/list', data)
+}
+
+/** *
+ * 广告详情  b
+ */
+export const getDet = data => {
+	return https.get('/ad/detail', data)
+}
+
+/** *
+ * 广告添加  b
+ */
+export const add = data => {
+	return https.post('/ad/add', data)
+}
+
+/** *
+ * 广告点击  b
+ */
+export const click = data => {
+	return https.get('/ad/click', data)
+}
+
+/** *
+ * 广告更新  b
+ */
+export const update = data => {
+	return https.post('/ad/update', data)
+}
+
+/** *
+ * 广告删除  b
+ */
+export const del = data => {
+	return https.get('/ad/delete', data)
+}
+
+/** *
+ * 广告排序 b
+ */
+export const sort = data => {
+	return https.get('/ad/sort', data)
+}
+
+/** *
+ * 广告下架  b
+ */
+export const off = data => {
+	return https.get('/ad/off', data)
+}

+ 1 - 3
mobile-code/src/api/common/index.js

@@ -1,8 +1,6 @@
 import https from '@/plugins/luch-request_0.0.7/request'
 
-export const uploadPic = data => {
-	return https.post('/upload/img', data)
-}
+export const uploadPic = data => https.post('/upload/save-img', data)
 
 export const getOptions = param => https.get('/apihkds/api/option/getOptions', param)
 

+ 30 - 0
mobile-code/src/api/coupon/index.js

@@ -13,3 +13,33 @@ export const discount = data => {
 export const list = data => {
 	return https.get('/user/discount', data)
 }
+
+/** *
+ * 优惠券列表 m
+ */
+export const getList = data => {
+	return https.get('/coupon/list', data)
+}
+
+// =====================  B 端 ========================
+
+/** *
+ * 优惠券列表 b
+ */
+export const getListB = data => {
+	return https.get('/coupon/list', data)
+}
+
+/** *
+ * 新人优惠券设置的详情 b
+ */
+export const couponAssetDet = data => {
+	return https.get('/coupon-asset/detail', data)
+}
+
+/** *
+ * 奖励设置详情 b
+ */
+export const couponAssetUpdate = data => {
+	return https.post('/coupon-asset/update', data)
+}

+ 28 - 0
mobile-code/src/api/invite/index.js

@@ -6,3 +6,31 @@ import https from '@/plugins/luch-request_0.0.7/request'
 export const getList = data => {
 	return https.get('/invite/list', data)
 }
+
+/** *
+ * 详情 b
+ */
+export const getDet = data => {
+	return https.get('/invite/detail', data)
+}
+
+/** *
+ * 兑奖 b
+ */
+export const give = data => {
+	return https.get('/invite/give', data)
+}
+
+/** *
+ * 奖励设置详情 b
+ */
+export const inviteAssetDet = data => {
+	return https.get('/invite-asset/detail', data)
+}
+
+/** *
+ * 奖励设置详情 b
+ */
+export const inviteAssetUpdate = data => {
+	return https.post('/invite-asset/update', data)
+}

+ 13 - 0
mobile-code/src/api/login/index.js

@@ -1,2 +1,15 @@
 import https from '@/plugins/luch-request_0.0.7/request'
 
+/** *
+ * 员工修改密码 b
+ */
+export const updatePassword = data => {
+	return https.get('/admin/password', data)
+}
+
+/** *
+ * 员工修改确认密码 b
+ */
+export const updateConfirmPassword = data => {
+	return https.get('/admin/confirm-password', data)
+}

+ 57 - 0
mobile-code/src/api/member/index.js

@@ -1,5 +1,34 @@
 import https from '@/plugins/luch-request_0.0.7/request'
 
+/** *
+ * 只要登陆客户的优惠情况 m
+ */
+export const userDiscount = data => {
+	return https.post('/user/discount', data)
+}
+
+/** *
+ * 只要登陆客户的资产情况 m
+ */
+export const userAsset = data => {
+	return https.post('/user/asset', data)
+}
+
+/** *
+ * 我的页面 m
+ */
+export const myProfile = data => {
+	return https.post('/user/my-profile', data)
+}
+
+/** *
+ * 修改密码 m
+ */
+export const modifyPassword = data => {
+	return https.post('/user/password', data)
+}
+// =====================  B 端 ========================
+
 /** *
  * 客户列表 b
  */
@@ -7,9 +36,37 @@ export const getList = data => {
 	return https.get('/user/list', data)
 }
 
+/** *
+ * 商家端客户详情,包括资产、订单和备注 b
+ */
+export const getUserDet = data => {
+	return https.get('/user/user-detail', data)
+}
+
+/** *
+ * 获取客户详情,包括资产 b
+ */
+export const getDet = data => {
+	return https.get('/user/detail', data)
+}
+
 /** *
  * 添加客户 b
  */
 export const add = data => {
 	return https.post('/user/add', data)
 }
+
+/** *
+ * 给客户充值 b
+ */
+export const recharge = data => {
+	return https.post('/user/recharge', data)
+}
+
+/** *
+ * 给客户升级 b
+ */
+export const upgrade = data => {
+	return https.post('/user/upgrade', data)
+}

+ 71 - 0
mobile-code/src/api/staff/index.js

@@ -0,0 +1,71 @@
+import https from '@/plugins/luch-request_0.0.7/request'
+
+/** *
+ * 员工列表 b
+ */
+export const getStaffList = data => {
+	return https.get('/admin/list', data)
+}
+
+/** *
+ * 查看员工 b
+ */
+export const getStaffDet = data => {
+	return https.get('/admin/detail', data)
+}
+
+/** *
+ * 添加员工 b
+ */
+export const addStaff = data => {
+	return https.post('/admin/add', data)
+}
+
+/** *
+ * 修改员工 b
+ */
+export const updateStaff = data => {
+	return https.post('/admin/update', data)
+}
+
+/** *
+ * 删除员工 b
+ */
+export const delStaff = data => {
+	return https.get('/admin/delete', data)
+}
+
+/** *
+ * 员工角色--列表 b
+ */
+export const getRoleList = data => {
+	return https.get('/admin-role/list', data)
+}
+
+/** *
+ * 员工角色--添加 b
+ */
+export const addRole = data => {
+	return https.post('/admin-role/add', data)
+}
+
+/** *
+ * 员工角色--修改 b
+ */
+export const updateRole = data => {
+	return https.post('/admin-role/update', data)
+}
+
+/** *
+ * 员工角色--删除 b
+ */
+export const delRole = data => {
+	return https.get('/admin-role/delete', data)
+}
+
+/** *
+ * 操作记录 b
+ */
+export const getLogList = data => {
+	return https.get('/admin-log/list', data)
+}

+ 10 - 9
mobile-code/src/components/app-date-picker.vue

@@ -1,18 +1,20 @@
 <template>
-    <view>
+	<view>
 		<picker :mode="mode" :value="date" :start="startDate2" :end="endDate2" @change="bindDateChange">
-			<view class="uni-input">
-				<span v-if="placeholder&&!date">{{placeholder}}</span>
-				<span v-else>{{date}}</span>
-			<span></span>
-			</view>
+			<slot>
+				<view class="uni-input">
+					<span v-if="placeholder && !date">{{placeholder}}</span>
+					<span v-else>{{date}}</span>
+					<span></span>
+				</view>
+			</slot>
 		</picker>
 	</view>
 </template>
 
 <script>
 export default {
-	name: 'app_date_picker',
+	name: 'app-date-picker',
 	props: {
 		mode: {
 			type: String,
@@ -47,6 +49,7 @@ export default {
 	},
 	computed: {
 		startDate2() {
+			console.log(this.getDate('start'))
 			return this.getDate('start')
 		},
 		endDate2() {
@@ -78,10 +81,8 @@ export default {
 			return `${year}-${month}-${day}`
 		}
 	}
-
 }
 </script>
 
 <style scoped>
-
 </style>

+ 1 - 0
mobile-code/src/components/app-wrapper-empty.vue

@@ -118,6 +118,7 @@ export default {
 
 		& .app-empty-center {
 			width: 100%;
+			margin-bottom: 80px;
 		}
 
 		& .app-empty__img {

+ 2 - 2
mobile-code/src/components/module/app-avatar.vue

@@ -1,6 +1,6 @@
 <template>
 	<div class="avatar-img" :class="{'radius': radius}" :style="{width: width + 'upx', height: width + 'upx', borderRadius: radius}">
-        <img :style="{width: width + 'upx', height: width + 'upx', borderRadius: radius}" :src="imgUrl" alt="">
+        <img :style="{width: width + 'upx', height: width + 'upx', borderRadius: radius}" :src="imgUrl" alt="头像">
     </div>
 </template>
 
@@ -25,7 +25,7 @@ export default {
 	},
 	computed: {
 		imgUrl() {
-			return this.img || defaultImg
+			return this.src || defaultImg
 		}
 	}
 }

+ 10 - 5
mobile-code/src/components/module/app-search.vue

@@ -5,12 +5,12 @@
 				<i class="iconfont" :class="[icon]"></i>
 			</div>
 			<div class="input-wrap">
-				<input type="text" :style="{fontSize: fontSize + 'rpx'}" :placeholder="placeholder" placeholder-class="placeholder" />
+				<input type="text" v-model="search" :style="{fontSize: fontSize + 'rpx'}" :placeholder="placeholder" placeholder-class="placeholder" />
 			</div>
 		</div>
         <block v-if="isBtn">
-            <button v-if="isTextBtn" class="search-btn" :style="{fontSize: fontSize + 'rpx'}" @search="searchFn">{{ btnText }}</button>
-		    <button v-else class="search-btn admin-button-com middle blue" :style="{fontSize: fontSize + 'rpx'}" @search="searchFn">{{ btnText }}</button>
+            <button v-if="isTextBtn" class="search-btn" :style="{fontSize: fontSize + 'rpx'}" @click="searchFn">{{ btnText }}</button>
+		    <button v-else class="search-btn admin-button-com middle blue" :style="{fontSize: fontSize + 'rpx'}" @click="searchFn">{{ btnText }}</button>
         </block>
 	</div>
 </template>
@@ -64,9 +64,14 @@ export default {
 			default: '搜索'
 		}
 	},
+	data() {
+		return {
+			search: ''
+		}
+	},
 	methods: {
-		searchFn(e) {
-			this.$emit('search', e)
+		searchFn() {
+			this.$emit('search', this.search)
 		}
 	}
 }

+ 4 - 3
mobile-code/src/components/plugin/modal.vue

@@ -3,7 +3,8 @@
 		<view class="tui-modal-box" :style="{width:width,padding:padding,borderRadius:radius,background:bgcolor}" :class="[(fadein || show)?'tui-modal-normal':'tui-modal-scale',show?'tui-modal-show':'']">
 			<view v-if="!custom">
 				<view class="tui-modal-title" v-if="title">{{title}}</view>
-				<view class="tui-modal-content" :class="[title?'':'tui-mtop']">
+				<!-- <view class="tui-modal-content" :class="[title?'':'tui-mtop']"> -->
+				<view class="tui-modal-content">
 					<block v-if="content">
 						<div :style="{color:color,fontSize:size+'rpx'}">{{content}}</div>
 					</block>
@@ -134,7 +135,7 @@ export default {
 		top: 50%;
 		margin: auto;
 		background: #fff;
-		z-index: 9998;
+		z-index: 998;
 		transition: all 0.3s ease-in-out;
 		opacity: 0;
 		box-sizing: border-box;
@@ -161,7 +162,7 @@ export default {
 		right: 0;
 		bottom: 0;
 		background: rgba(0, 0, 0, 0.6);
-		z-index: 9996;
+		z-index: 996;
 		transition: all 0.3s ease-in-out;
 		opacity: 0;
 		visibility: hidden;

+ 1 - 1
mobile-code/src/components/plugin/tabs.vue

@@ -5,7 +5,7 @@
 				<view class="tui-tabs-title" :class="{'tui-tabs-active':currentTab==index,'tui-tabs-disabled':item.disabled}" :style="{fontSize:size+'rpx',lineHeight:size+'rpx',fontWeight:bold && currentTab==index?'bold':'normal'}">
 					<div class="tabs-title">{{item.name}}</div>
 					<!-- tab value -->
-					<div class="tabs-value" v-if="item.value">{{ item.value }}</div>
+					<div class="tabs-value" v-if="item.value || item.value == 0">{{ item.value }}</div>
 				</view>
 			</view>
 		</div>

+ 35 - 0
mobile-code/src/filters/constant.js

@@ -0,0 +1,35 @@
+// 全局枚举
+const _CONST_MAP = {
+	// 邀请
+	INVITE_STATUS: [
+		{
+			label: '待下单',
+			value: 0
+		},
+		{
+			label: '待兑奖',
+			value: 1
+		},
+		{
+			label: '已完成',
+			value: 2
+		}
+	],
+	// 优惠券
+	COUPON_STATUS: [
+		{
+			label: '未使用',
+			value: 0
+		},
+		{
+			label: '已使用',
+			value: 1
+		},
+		{
+			label: '过期,失效',
+			value: 2
+		}
+	]
+}
+
+export const _filter_const_map = _CONST_MAP

+ 81 - 0
mobile-code/src/filters/constantFilter.js

@@ -0,0 +1,81 @@
+import { _filter_const_map } from './constant.js'
+
+export const constFilter = (value, key) => {
+	_validateDefined(key)
+	for (let k in _filter_const_map[key]) {
+		if (_filter_const_map[key][k].value == value) return _filter_const_map[key][k].label
+	}
+}
+/**
+ * 验证配置项是否存在
+ * @param key 配置项键名
+ * @private
+ */
+const _validateDefined = key => {
+	if (!_filter_const_map.hasOwnProperty(key)) {
+		throw new Error(`constant dosen't find ${key}`)
+	}
+	return _filter_const_map[key]
+}
+
+/**
+ * 获取配置项
+ * @param key 配置项键名
+ */
+export const getDefined = key => {
+	return _validateDefined(key)
+}
+
+/**
+ * 获取配置项深拷贝(在实例修改不影响原常量值)
+ * @param key 配置项键名
+ */
+export const getDefinedCopy = key => {
+	return JSON.parse(JSON.stringify(_validateDefined(key)))
+}
+
+/**
+ * 获取配置项中的某个值 (只对数组或对象有效)
+ * @param key 配置项键名
+ * @param value 值
+ * @param by 值对应的匹配方式
+ * @returns {{}} 某个值
+ */
+export const getDefinedValue = (key, value, by = 'value') => {
+	let obj = _validateDefined(key)
+	let val = {}
+
+	if (typeof obj != 'object') {
+		return val
+	}
+
+	for (var _key of Object.keys(obj)) {
+		if (obj[_key][by] == value) {
+			return obj[_key]
+		}
+	}
+
+	return val
+}
+
+/**
+ * 输入key 值,将CONSTMAP中的key对应的Object按照value大小从小到达排序
+ * @param {*} key
+ */
+export const constMapToArray = key => {
+	_validateDefined(key)
+	let value = _filter_const_map[key]
+	if (!_.isPlainObject(value)) {
+		if (_.isArray(value)) return value
+		else throw new Error(`${value} must be Object or Array`)
+	} else {
+		let arr = []
+		for (let k in value) {
+			arr.push(value[k])
+		}
+		arr.sort((pre, next) => {
+			return pre.value - next.vaue
+		})
+		return arr
+	}
+}

+ 1 - 2
mobile-code/src/m-pages.json

@@ -111,8 +111,7 @@
 				{
 					"path": "detail",
 					"style": {
-						"navigationBarTitleText": "订单列表",
-						"enablePullDownRefresh": true
+						"navigationBarTitleText": "订单列表"
 					}
 				},
 				{

+ 4 - 0
mobile-code/src/main.js

@@ -18,6 +18,10 @@ Vue.prototype.$util = util
 import { FormatTimeFilter } from '@/filters/index'
 Vue.filter('formatTime', FormatTimeFilter)
 
+/** 一个全局变量的过滤器 value 转label */
+import { constFilter } from '@/filters/constantFilter'
+Vue.filter('constantfilter', constFilter)
+
 // import commonJS from './utils/common'
 // Vue.prototype.commonJS = commonJS
 

+ 234 - 83
mobile-code/src/pages/ad/add.vue

@@ -1,109 +1,215 @@
 <template>
 	<div class="app-content">
 		<!-- 广告信息 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell" :hover="false">
-				<div class="tui-title required">广告图名称</div>
-				<input v-model="form.receiveUserName" placeholder-class="phcolor" class="tui-input" name="name" placeholder="请输入姓名" maxlength="50" type="number" />
-			</tui-list-cell>
-			<tui-list-cell class="line-cell" :arrow="true">
-				<div class="tui-title required">开始时间</div>
-				<picker mode="date" :value="form.reachTime" @change="selTimeFn" class="tui-input">
-					<div v-if="form.reachTime">{{ form.reachTime }}</div>
-					<div class="tui-placeholder" v-else>请选择</div>
-				</picker>
-			</tui-list-cell>
-			<tui-list-cell class="line-cell" :arrow="true">
-				<div class="tui-title required">到期时间</div>
-				<picker mode="date" :value="form.reachTime" @change="selTimeFn" class="tui-input">
-					<div v-if="form.reachTime">{{ form.reachTime }}</div>
-					<div class="tui-placeholder" v-else>请选择</div>
-				</picker>
-			</tui-list-cell>
-			<tui-list-cell class="line-cell between switch" padding="14rpx 30rpx" :hover="false">
-				<div class="tui-title">马上开启</div>
-				<div>
-					<switch checked @change="switchChangeFn" />
-				</div>
-			</tui-list-cell>
-		</div>
-		<!-- 广告图片 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-img-wrap" :hover="false">
-				<div>
-					<span class="ad-name required">广告图片</span>
-					<span class="app-color-3 app-size-24">只能上传jpg/png格式</span>
-				</div>
-				<div class="line-img">
-					<app-uploader @chooseImage="chooseUploader" :multiple="false" ref="appUploader" :imgList.sync="imgList" />
-				</div>
-			</tui-list-cell>
-		</div>
-		<!-- 链接方式 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell" :hover="false">
-				<div class="tui-title required">链接方式</div>
-				<radio-group class="tui-input flex-center-between" @change="radioChange">
-					<label class="list" for="customLink">
-						<radio id="customLink" value="自定义链接" checked="checked" />
-						<span class="checkbox-text">自定义链接</span>
-					</label>
-					<label class="list" for="goodsLink">
-						<radio id="goodsLink" value="链接商品" />
-						<span class="checkbox-text">链接商品</span>
-					</label>
-				</radio-group>
-			</tui-list-cell>
-			<block v-if="false">
+		<form @submit="formSubmit">
+			<div class="module-com input-line-wrap">
 				<tui-list-cell class="line-cell" :hover="false">
-					<textarea class="tui-textarea" placeholder-class="phcolor" placeholder="请填写链接,留空点图片不跳转" auto-height />
+					<div class="tui-title required">广告图名称</div>
+					<input v-model="form.adName" placeholder-class="phcolor" class="tui-input" name="adName" placeholder="请输入名称" maxlength="50" type="text" />
 				</tui-list-cell>
-			</block>
-			<block v-else>
-				<tui-list-cell class="goods-blo" :hover="false">
-					<div class="goods-list-wrap">
-						<div class="goods-list" v-for="(item, index) in 2" :key="index">
-							<div class="list-img">
-								<img src="../../static/images/interest/invite.png" alt mode="center" />
-							</div>
-							<div class="list-right">
-								<div>花之物语 红色系</div>
-								<div class="app-price">¥389.50</div>
-							</div>
-						</div>
+				<tui-list-cell class="line-cell" :arrow="true">
+					<div class="tui-title required">开始时间</div>
+					<picker mode="date" :value="form.startTime" @change="startTimeFn"  class="tui-input">
+						<input v-model="form.startTime" name="startTime" type="text" hidden />
+						<div v-if="form.startTime">{{ form.startTime }}</div>
+						<div class="tui-placeholder" v-else>请选择</div>
+					</picker>
+				</tui-list-cell>
+				<tui-list-cell class="line-cell" :arrow="true">
+					<div class="tui-title required">到期时间</div>
+					<picker mode="date" :value="form.endTime" @change="endTimeFn" class="tui-input">
+						<input v-model="form.endTime" name="endTime" type="text" hidden />
+						<div v-if="form.endTime">{{ form.endTime }}</div>
+						<div class="tui-placeholder" v-else>请选择</div>
+					</picker>
+				</tui-list-cell>
+				<tui-list-cell class="line-cell between switch" padding="14rpx 30rpx" :hover="false">
+					<div class="tui-title">马上开启</div>
+					<div>
+						<switch :checked="form.status ? true : false" @change="switchChangeFn" />
 					</div>
-					<div class="admin-button-com blue" @click="$util.pageTo('/pages/ad/sel-goods')">选择商品</div>
 				</tui-list-cell>
-			</block>
-		</div>
-		<!-- 确认 -->
-		<div class="confirm-btn">
-			<div class="admin-button-com big blue">确认</div>
-		</div>
+			</div>
+			<!-- 广告图片 -->
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-img-wrap" :hover="false">
+					<div>
+						<span class="ad-name required">广告图片</span>
+						<span class="app-color-3 app-size-24">只能上传jpg/png格式</span>
+					</div>
+					<div class="line-img">
+						<input v-model="form.endTime" name="endTime" type="text" hidden />
+						<app-uploader @chooseImage="chooseUploader" :multiple="false" ref="appUploader" :imgList.sync="imgList" />
+					</div>
+				</tui-list-cell>
+			</div>
+			<!-- 链接方式 -->
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-cell" :hover="false">
+					<div class="tui-title required">链接方式</div>
+					<radio-group class="tui-input flex-center-between" @change="radioChange">
+						<label class="list" for="customLink">
+							<radio id="customLink" value="0" :checked="form.style == 0" />
+							<span class="checkbox-text">自定义链接</span>
+						</label>
+						<label class="list" for="goodsLink">
+							<radio id="goodsLink" value="1" :checked="form.style == 1" />
+							<span class="checkbox-text">链接商品</span>
+						</label>
+					</radio-group>
+				</tui-list-cell>
+				<block v-if="form.style == 0">
+					<tui-list-cell class="line-cell" :hover="false">
+						<textarea v-model="form.url" class="tui-textarea" placeholder-class="phcolor" placeholder="请填写链接,留空点图片不跳转" auto-height />
+					</tui-list-cell>
+				</block>
+				<block v-else>
+					<tui-list-cell class="goods-blo" :hover="false">
+						<div class="goods-list-wrap" v-if="!$util.isEmpty(goodsData)">
+							<div class="goods-list">
+								<div class="list-img">
+									<img :src="goodsData.imgSmallList[0]" alt="商品图片" mode="center" />
+								</div>
+								<div class="list-right">
+									<div>{{ goodsData.goodsName }}</div>
+									<div class="app-price">¥{{ goodsData.price }}</div>
+								</div>
+							</div>
+						</div>
+						<div class="admin-button-com blue" @click="selGoodsFn">选择商品</div>
+					</tui-list-cell>
+				</block>
+			</div>
+			<!-- 确认 -->
+			<div class="confirm-btn">
+				<button class="admin-button-com big blue" formType="submit">确认</button>
+			</div>
+		</form>
 	</div>
 </template>
 
 <script>
 import TuiListCell from '@/components/plugin/list-cell'
 import AppUploader from '@/components/app-uploader'
+import AppDatePicker from '@/components/app-date-picker'
+const form = require('@/utils/formValidation.js')
+// api
+import { getDet, add, update } from '@/api/ad'
+import { getDetailB as getGoodsDet } from '@/api/goods'
 export default {
 	name: 'ad-add',
 	components: {
 		TuiListCell,
-		AppUploader
+		AppUploader,
+		AppDatePicker
 	},
 	data() {
 		return {
-			form: {},
-			imgList: []
+			form: {
+				adName: '',
+				adImg: '',
+				status: 0,
+				inTurn: '',
+				type: 0,
+				style: 0,
+				url: '',
+				goodsId: '',
+				startTime: null,
+				endTime: null
+			},
+			imgList: [],
+			goodsData: {}
 		}
 	},
+	onLoad(option) {
+		this.setPageTitle()
+		this.init()
+	},
 	methods: {
-		selTimeFn(e) {
-			this.form.reachTime = e.detail.value
+		init() {
+			this.type = this.option.type
+
+			let data = uni.getStorageSync('addAdData')
+			if (data) {
+				uni.removeStorageSync('addAdData')
+				this.form = data.form
+				this.imgList = data.imgList
+				this.goodsData = data.goodsData
+			}
+			let goodsData = uni.getStorageSync('adSelGoods')
+			if (goodsData) {
+				uni.removeStorageSync('adSelGoods')
+				this.goodsData = goodsData
+				this.goodsId = goodsData.id
+			}
+
+			if (this.option.id && !data) {
+				this._getDet()
+			}
+		},
+		setPageTitle() {
+			if (this.option.id) {
+				uni.setNavigationBarTitle({
+      				title: this.option.type == 0 ? '修改门店轮播图' : '修改商城首页轮播图'
+				})
+			} else {
+				uni.setNavigationBarTitle({
+      				title: this.option.type == 0 ? '添加门店轮播图' : '添加商城首页轮播图'
+				})
+			}
+		},
+		// api
+		_getDet() {
+			getDet({ id: this.option.id }).then(res => {
+				if (this.$util.isEmpty(res.data)) return
+				Object.keys(this.form).forEach((i, index) => {
+					this.form[i] = res.data[i]
+				})
+				this.form.startTime = this.$util.$formatDate(this.form.startTime, 'YYYY-MM-DD')
+				this.form.endTime = this.$util.$formatDate(this.form.endTime, 'YYYY-MM-DD')
+
+				if (this.form.style) {
+					this._getGoodsDet()
+				}
+			})
+		},
+		// 获取商品详情
+		_getGoodsDet() {
+			getGoodsDet({ id: this.form.goodsId }).then(res => {
+				if (this.$util.isEmpty(res.data)) return
+				this.goodsData = res.data
+			})
+		},
+		// 操作
+		// 选择商品
+		selGoodsFn() {
+			let data = {
+				form: this.form,
+				imgList: this.imgList,
+				goodsData: this.goodsData
+			}
+			uni.setStorageSync('addAdData', data)
+			// this.form
+			this.$util.pageTo({
+				url: '/pages/ad/sel-goods',
+				query: {
+					...this.option
+				}
+			})
+		},
+		startTimeFn(e) {
+			console.log(e)
+			// this.form.startTime = e
+		},
+		endTimeFn(e) {
+			this.form.endTime = e.detail.value
+		},
+		switchChangeFn(e) {
+			this.switch = e.target.value ? 1 : 0
+		},
+		radioChange(e) {
+			this.form.style = e.detail.value
 		},
-		switchChangeFn() {},
-		radioChange() {},
 		chooseUploader() {
 			console.log('afda')
 			// modifySiteCover({
@@ -117,6 +223,51 @@ export default {
 			// 		icon: 'none'
 			// 	})
 			// })
+		},
+		confirmFn() {
+			let hostFn = this.option.id ? update : add
+			if (this.option.id) {
+				this.form.id = this.option.id
+			}
+			if (this.form.style == 0) {
+				this.form.goodsId = ''
+			} else {
+				this.form.url = ''
+			}
+			hostFn(this.form).then(res => {
+				let promptText = this.option.id ? '修改成功!' : '添加成功!'
+				this.$msg(promptText)
+			})
+		},
+		// 表单验证
+		formSubmit(e) {
+			// 表单规则
+			let rules = [
+				{
+					name: 'adName',
+					rule: ['required'],
+					msg: ['请输入姓名']
+				},
+				{
+					name: 'startTime',
+					rule: ['required'],
+					msg: ['请选择开始时间']
+				},
+				{
+					name: 'endTime',
+					rule: ['required'],
+					msg: ['请选择结束时间']
+				}
+			]
+			// 进行表单检查
+			let formData = e.detail.value
+			let checkRes = form.validation(formData, rules)
+			// 验证通过!
+			if (!checkRes) {
+				this.confirmFn()
+			} else {
+				this.$msg(checkRes)
+			}
 		}
 	}
 }
@@ -170,7 +321,7 @@ export default {
 		width: calc(100% - 60px);
 		margin: 60px 30px 20px;
 		.admin-button-com {
-			width: calc(100% - 40px);
+			width: 100%;
 		}
 	}
 </style>

+ 158 - 41
mobile-code/src/pages/ad/list.vue

@@ -2,48 +2,70 @@
 	<div class="app-content">
 		<app-tabs :tabs="tabs" :isFixed="true" :currentTab="tabIndex" @change="change" itemWidth="50%" />
 		<div class="list-wrap">
-			<div class="list" v-for="(item, index) in 1" :key="index">
-				<div class="list-img">
-					<img src="../../static/images/interest/invite.png" alt mode="center" />
-				</div>
-				<div class="list-right">
-					<div class="app-size-28 app-color-0">情人节图片</div>
-					<div>3天后到期</div>
-					<div class="list-option">
-						<div>
-							<div>点击次数:50988</div>
+			<block v-if="!$util.isEmpty(list.data)">
+				<div class="list" v-for="(item, index) in list.data" :key="index">
+					<div class="list-img">
+						<img :src="item.adImgUrl" :lazy-load="true" alt="广告图片" mode="center" />
+					</div>
+					<div class="list-right">
+						<div class="app-size-28 app-color-0">{{ item.adName }}</div>
+						<div v-if="item.endTime == '4102416000'">永久有效</div>
+						<div v-else>{{ item.endTime }}到期</div>
+						<div class="list-option">
 							<div>
-								<span>当前状态:</span>
-								<span :style="{color: true ? '#09BB07' : '#FF0000'}">启用</span>
+								<div>点击次数:{{ item.viewTimes }}</div>
+								<div>
+									<span>当前状态:</span>
+									<span :style="{color: item.status == 1 ? '#09BB07' : '#FF0000'}">{{ item.status == 1 ? '启用' : '禁用'}}</span>
+								</div>
 							</div>
-						</div>
-						<div class="operate-icon-wrap">
-							<div class="operate-icon">
-								<i class="iconfont" :class="[ operateIndex == index ? 'iconcaozuojihuo' : 	'iconcaozuo']"></i>
+							<div class="operate-icon-wrap">
+								<div class="operate-icon" @click="operateFn(item, index)">
+									<i class="iconfont" :class="[ operateIndex == index ? 'iconcaozuojihuo' : 	'iconcaozuo']"></i>
+								</div>
 							</div>
 						</div>
 					</div>
 				</div>
-			</div>
-			<!-- 操作 -->
-			<operate-module v-show="operateShow" :top="216" :right="30" :btnData="btnData" />
+				<!-- 操作 -->
+				<operate-module v-show="operateShow" :top="operateTop" :right="30" :btnData="btnData" />
+			</block>
+			<block v-else>
+				<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+			</block>
+		</div>
+		<!-- 按钮 -->
+		<div class="app-footer">
+			<div class="admin-button-com middle blue" @click="$util.pageTo({
+				url: '/pages/ad/add',
+				query: {
+					type: tabIndex
+				}
+			})">添加</div>
 		</div>
-        <!-- 按钮 -->
-        <div class="app-footer">
-            <div class="admin-button-com middle blue">添加</div>
-        </div>
+		<!-- 删除提示 -->
+		<!-- 充值弹窗 -->
+		<modal-module :show="delModal" @cancel="modalCancel" @click="delModalClick" content="确定删除该广告吗?" color="#333" :size="32" padding="30rpx 30rpx"></modal-module>
 	</div>
 </template>
 
 <script>
 import AppTabs from '@/components/plugin/tabs'
 import OperateModule from '@/pages/admin/components/module/operate'
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
+import ModalModule from '@/components/plugin/modal'
+import { list } from '@/mixins'
+// api
+import { getList, del, off } from '@/api/ad'
 export default {
 	name: 'ad-list',
 	components: {
 		AppTabs,
-		OperateModule
+		OperateModule,
+		AppWrapperEmpty,
+		ModalModule
 	},
+	mixins: [list],
 	data() {
 		return {
 			tabIndex: 0,
@@ -55,25 +77,120 @@ export default {
 					name: '商城首页轮播图'
 				}
 			],
+			// 操作菜单
+			operateData: null,
 			operateShow: false,
-			operateIndex: 0,
+			operateIndex: null,
+			operateTop: 0,
 			btnData: [
 				{
 					text: '编辑',
+					icon: 'iconbianji',
+					click: () => {
+						this.$util.pageTo({
+							url: '/pages/ad/add',
+							query: {
+								type: this.tabIndex,
+								id: this.operateData.id
+							}
+						})
+					}
+				},
+				{
+					text: '下架',
+					icon: 'iconxiajia',
+					click: () => {
+						off({ id: this.operateData.id }).then(res => {
+							this.operateCloseFn()
+							this.list.data[this.operateData.index].status = 0
+							this.$msg('下架成功!')
+						})
+					}
+				},
+				{
+					text: '删除',
 					icon: 'iconshanchu1',
 					click: () => {
-						this.operateDelFn()
+						this.delModal = true
 					}
 				}
-			]
+			],
+			// 删除弹窗
+			delModal: false
 		}
 	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
+		}
+	},
+	onLoad: function() {
+		this.init()
+	},
 	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			return getList({ status: this.tabIndex }).then(res => {
+				this.completes(res)
+			})
+		},
 		change(e) {
-			this.tabIndex = e.index
+			if (this.tabIndex == e.index) {
+				return false
+			} else {
+				this.tabIndex = e.index
+				this.operateCloseFn()
+				this.resetList()
+				this._list()
+			}
+		},
+		// 操作按钮
+		operateFn(item, index) {
+			if (this.operateShow) {
+				this.operateCloseFn()
+			} else {
+				this.operateData = item
+				this.operateData.index = index
+				this.operateIndex = index
+				this.operateTop = (index + 1) * 214
+				this.operateShow = true
+			}
+		},
+		// 关闭操作按钮
+		operateCloseFn() {
+			this.operateData = null
+			this.operateIndex = null
+			this.operateShow = false
 		},
-		operateDelFn() {
-			console.log('asdfasdfas')
+		// 删除弹窗
+		modalCancel() {
+			this.delModal = false
+		},
+		delModalClick(e) {
+			let index = e.index
+			if (index === 0) {
+				this.modalCancel()
+			} else {
+				del({ id: this.operateData.id }).then(res => {
+					this.modalCancel()
+					this.operateCloseFn()
+					this.$msg('删除成功!')
+					this.resetList()
+					this._list()
+				})
+			}
 		}
 	}
 }
@@ -82,8 +199,8 @@ export default {
 <style lang="scss" scoped>
 	.app-content {
 		min-height: calc(100vh - 200px);
-        padding-top: 100px;
-        padding-bottom: 100px;
+		padding-top: 100px;
+		padding-bottom: 100px;
 	}
 	.list-wrap {
 		width: 100%;
@@ -114,13 +231,13 @@ export default {
 				}
 			}
 		}
-    }
-    // 按钮
-    .app-footer {
-        justify-content: flex-end;
-        .admin-button-com {
-            width: 160px;
-            margin-right: 30px;
-        }
-    }
+	}
+	// 按钮
+	.app-footer {
+		justify-content: flex-end;
+		.admin-button-com {
+			width: 160px;
+			margin-right: 30px;
+		}
+	}
 </style>

+ 87 - 4
mobile-code/src/pages/ad/sel-goods.vue

@@ -1,19 +1,102 @@
 <template>
-  <div class="app-content">
-      <sel-search-module></sel-search-module>
-  </div>
+	<div class="app-content">
+		<sel-search-module :list="list.data" @search="searchFn" @change="changeFn">
+			<template v-slot:img="{ item }">
+				<div class="list-img">
+					<img :src="item.imgSmallList[0]" alt="商品图片" mode="center" />
+				</div>
+			</template>
+			<template v-slot:detail="{ item }">
+				<div class="list-right">
+					<div class="list-name">{{ item.goodsName }}</div>
+					<div class="app-price">¥{{ item.price }}</div>
+				</div>
+			</template>
+		</sel-search-module>
+	</div>
 </template>
 
 <script>
 import SelSearchModule from '@/pages/admin/components/sel-search'
+import { list } from '@/mixins'
+// api
+import { getListB } from '@/api/goods'
 export default {
 	name: 'sel-goods',
 	components: {
 		SelSearchModule
+	},
+	mixins: [list],
+	data() {
+		return {
+			search: ''
+		}
+	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
+		}
+	},
+	onLoad: function() {
+		this.init()
+	},
+	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			let params = {
+				page: this.list.page,
+				goodsName: this.search
+			}
+			return getListB(params).then(res => {
+				this.completes(res)
+			})
+		},
+		// 搜索
+		searchFn(val) {
+			if (!val) return false
+			this.search = val
+			this.resetList()
+			this._list()
+		},
+		// 选择商品
+		changeFn(e) {
+			console.log(e)
+			uni.setStorageSync('adSelGoods', e)
+			this.$util.pageTo({
+				url: '/pages/ad/add',
+				query: {
+					...this.option
+				},
+				type: 2
+			})
+		}
 	}
 }
 </script>
 
 <style lang="scss" scoped>
-
+.list-img {
+	width: 160px;
+	height: 160px;
+	margin-right: 40px;
+}
+.list-right {
+	font-size: 28px;
+	.list-name {
+		font-size: 30px;
+		margin-bottom: 20px;
+	}
+}
 </style>

+ 52 - 39
mobile-code/src/pages/admin/components/sel-search.vue

@@ -1,49 +1,49 @@
 <template>
 	<div class="sel-search-module">
 		<div class="input-wrap">
-			<app-search-module placeholder="请输入商品名称" :isBtn="true" />
+			<app-search-module placeholder="请输入名称" :isBtn="true"  @search="searchFn" />
 		</div>
         <!-- 列表 -->
 		<div class="list-wrap">
+			<!-- 多选 -->
+			<block v-if="multi">
+				<checkbox-group @change="checkboxChange">
+					<div class="list" v-for="(item, index) in list" :key="index">
+						<div class="checkbox-wrap">
+							<checkbox class="ljd-checkbox" :value="item.value" :checked="item.checked" />
+						</div>
+					</div>
+				</checkbox-group>
+			</block>
 			<!-- 单选 -->
-			<block v-if="true">
+			<block v-else>
 				<radio-group @change="radioChange">
-					<label class="list" v-for="(item, index) in selData" :key="item.value">
+					<label class="list" v-for="(item, index) in list" :key="index">
 						<div class="checkbox-wrap">
-							<radio :value="item.value" :checked="item.checked" />
+							<radio :value="index + ''" :checked="item.checked" />
 						</div>
                         <!-- 图片块 -->
-                        <slot name="img">
+                        <slot name="img" :item="item">
                             <div class="list-img">
-				                <app-avatar-module :width="120" />
+				                <app-avatar-module :src="item.avatarUrl" :width="120" />
                             </div>
                         </slot>
                         <!-- 列表详情块 -->
-                        <slot name="detail">
+                        <slot name="detail" :item="item">
                             <div class="list-right">
-                                <div class="list-name">冯宝宝</div>
-                                <div>手机号: 153928272626</div>
-                                <div>会员等级: 普通会员</div>
-                                <div>最后访问: 2019-12-09  10:10</div>
+                                <div class="list-name">{{ item.userName }}</div>
+                                <div>手机号: {{ item.mobile }}</div>
+                                <div>会员等级: {{ item.userAsset.memberLevel }}</div>
+                                <div>最后访问: {{ item.visitTimeFormat }}</div>
                             </div>
                         </slot>
 					</label>
 				</radio-group>
 			</block>
-			<!-- 多选 -->
-			<block v-else>
-				<checkbox-group @change="checkboxChange">
-					<div class="list" v-for="(item, index) in selData" :key="index">
-						<div class="checkbox-wrap">
-							<checkbox class="ljd-checkbox" :value="item.value" :checked="item.checked" />
-						</div>
-					</div>
-				</checkbox-group>
-			</block>
 		</div>
         <!-- 按钮 -->
         <div class="app-footer">
-            <div class="admin-button-com middle blue">确认</div>
+            <div class="admin-button-com middle blue" @click="confirmFn">确认</div>
         </div>
 	</div>
 </template>
@@ -57,31 +57,44 @@ export default {
 		AppSearchModule,
 		AppAvatarModule
 	},
+	props: {
+		list: {
+			type: Array,
+			default: () => []
+		},
+		multi: {
+			type: Boolean,
+			default: false
+		}
+	},
 	data() {
 		return {
-			selData: [
-				{
-					value: 'USA'
-				},
-				{
-					value: 'CHN',
-					checked: true
-				},
-				{
-					value: 'BRA'
-				},
-				{
-					value: 'JPN'
-				}
-			]
+			radioData: null,
+			checkboxArr: null
 		}
 	},
 	methods: {
+		// 单选
 		radioChange(e) {
-			// console.log(e)
+			this.radioData = this.list[e.detail.value]
 			// this.selData = []
 		},
-		checkboxChange() {}
+		// 多选
+		checkboxChange(e) {
+			console.log(e)
+		},
+		// 搜索
+		searchFn(e) {
+			this.$emit('search', e)
+		},
+		// 确认
+		confirmFn() {
+			// if (this.multi) {
+			// this.$emit('change', this.checkboxArr)
+			// } else {
+			this.$emit('change', this.radioData)
+			// }
+		}
 	}
 }
 </script>

+ 1 - 1
mobile-code/src/pages/admin/workbench.vue

@@ -153,7 +153,7 @@ export default {
 					name: '促销',
 					img: tabIcon5,
 					funtion: () => {
-						this.rechargeModal = true
+						this.$msg('该功能开发中...')
 					}
 				},
 				{

+ 106 - 53
mobile-code/src/pages/coupon/admin/list.vue

@@ -3,27 +3,32 @@
 		<app-tabs :tabs="tabs" :isFixed="true" :currentTab="tabIndex" @change="change" :height="100" itemWidth="25%" />
 		<!-- list -->
 		<div class="list-wrap">
-			<div class="list" v-for="(item, index) in 10" :key="index">
-				<div>
-					<app-avatar-module :width="110" />
+			<block v-if="!$util.isEmpty(list.data)">
+				<div class="list" v-for="(item, index) in list.data" :key="index">
+					<div>
+						<app-avatar-module :src="item.userAvatar" :width="110" />
+					</div>
+					<div class="list-right">
+						<div class="app-size-30 app-color-0">{{ item.userName }}</div>
+						<div class="list-info">
+							<div>
+								<div>
+									<span class="list-info-left">ID: {{ item.userId }}</span>
+									<span>手机号: {{ item.mobile }}</span>
+								</div>
+								<div class="list-remark">
+									<span class="list-info-left">金额: {{ item.amount }}</span>
+									<span>最低消费: {{ item.miniCost }}</span>
+								</div>
+							</div>
+							<div :class="[item.status == 1 ? 'app-color-4' : '']">{{ item.status | constantfilter('COUPON_STATUS') }}</div>
+						</div>
+					</div>
 				</div>
-				<div class="list-right">
-					<div class="app-size-30 app-color-0">清明哈</div>
-                    <div class="list-info">
-                        <div>
-                            <div>
-                                <span class="list-info-left">ID: 0927</span>
-                                <span>手机号: 13285979347</span>
-                            </div>
-                            <div class="list-remark">
-                                <span class="list-info-left">金额: 80</span>
-                                <span>最底消费: 600</span>
-                            </div>
-                        </div>
-                        <div>待下单</div>
-                    </div>
-				</div>
-			</div>
+			</block>
+			<block v-else>
+				<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+			</block>
 		</div>
 	</div>
 </template>
@@ -31,38 +36,86 @@
 <script>
 import AppTabs from '@/components/plugin/tabs'
 import AppAvatarModule from '@/components/module/app-avatar'
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
+import { list } from '@/mixins'
+// api
+import { getListB } from '@/api/coupon'
 export default {
 	name: 'admin-invite',
 	components: {
 		AppTabs,
-		AppAvatarModule
+		AppAvatarModule,
+		AppWrapperEmpty
 	},
+	mixins: [list],
 	data() {
 		return {
 			tabIndex: 0,
 			tabs: [
 				{
 					name: '全部',
-					value: 52
+					value: 0
 				},
 				{
 					name: '待使用',
-					value: 30
+					value: 0
 				},
 				{
 					name: '已使用',
-					value: 10
+					value: 0
 				},
 				{
 					name: '已失效',
-					value: 5
+					value: 0
 				}
 			]
 		}
 	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
+		}
+	},
+	onLoad: function() {
+		this.init()
+	},
 	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			let index = JSON.parse(JSON.stringify(this.tabIndex))
+			index = index - 1
+			return getListB({ status: index }).then(res => {
+				this.completes(res)
+				if (!this.$util.isEmpty(res.data)) {
+					this.tabs[0].value = res.data.asset.totalNum
+					this.tabs[1].value = res.data.asset.unUseNum
+					this.tabs[2].value = res.data.asset.useNum
+					this.tabs[3].value = res.data.asset.invalidNum
+					console.log(res.data.asset.totalNum)
+				}
+			})
+		},
 		change(e) {
-			this.tabIndex = e.index
+			if (this.tabIndex == e.index) {
+				return false
+			} else {
+				this.tabIndex = e.index
+				this.resetList()
+				this._list()
+			}
+			// this.tabIndex = e.index
 		}
 	}
 }
@@ -72,31 +125,31 @@ export default {
 	.app-content {
 		padding-top: 120px;
 	}
-    // list
-    .list-wrap {
-        width: 100%;
-        color: $fontColor3;
-        background-color: #fff;
-        .list {
-            @include disFlex(center, space-between);
-            width: calc(100% - 60px);
-            padding: 30px 0;
-            margin: 0 30px;
-            border-bottom: 1px solid $borderColor;
-            .list-right {
-                width: calc(100% - 130px);
-                .list-info {
-                    @include disFlex(center, space-between);
-                    margin-top: 10px;
-                    .list-remark {
-                        margin-top: 10px;
-                    }
-                    .list-info-left {
-                        display: inline-block;
-                        width: 160px;
-                    }
-                }
-            }
-        }
-    }
+	// list
+	.list-wrap {
+		width: 100%;
+		color: $fontColor3;
+		background-color: #fff;
+		.list {
+			@include disFlex(center, space-between);
+			width: calc(100% - 60px);
+			padding: 30px 0;
+			margin: 0 30px;
+			border-bottom: 1px solid $borderColor;
+			.list-right {
+				width: calc(100% - 130px);
+				.list-info {
+					@include disFlex(center, space-between);
+					margin-top: 10px;
+					.list-remark {
+						margin-top: 10px;
+					}
+					.list-info-left {
+						display: inline-block;
+						width: 160px;
+					}
+				}
+			}
+		}
+	}
 </style>

+ 94 - 50
mobile-code/src/pages/coupon/list.vue

@@ -1,60 +1,68 @@
 <template>
 	<div class="app-content coupon-list">
 		<!-- <div class="tabs-wrap"> -->
-			<app-tabs :tabs="tabs" :isFixed="true" :currentTab="tabIndex" @change="change" itemWidth="33.3333%" />
+		<app-tabs :tabs="tabs" :isFixed="true" :currentTab="tabIndex" @change="change" itemWidth="33.3333%" />
 		<!-- </div> -->
 		<div class="list-wrap" :class="{'expired' : tabIndex == 2}">
-			<div class="list" v-for="(item, index) in 4" :key="index">
-				<div class="list-img">
-                    <!-- 已过期 -->
-                    <template v-if="tabIndex == 2">
-					    <img src="../../static/images/coupon/expired.png" alt mode="widthFix" />
-                    </template>
-                    <template v-else>
-					    <img src="../../static/images/coupon/bg.png" alt mode="widthFix" />
-                    </template>
-				</div>
-				<!-- 列表 -->
-				<div class="list-det">
-					<div class="list-det-left">
-						<div class="price-wrap">
-							<span>¥</span>
-							<span class="price">1000</span>
-						</div>
-						<div class="full-reduc app-size-28">满100可使用</div>
-					</div>
-					<div class="list-det-right">
-						<div class="coupon-message">
-							<div class="app-color-2">优惠券</div>
-							<div>适用:全品类</div>
-							<div>有效至:2020-10-11</div>
-						</div>
-                        <!-- 未使用 -->
-						<template v-if="tabIndex == 0">
-							<button class="button-com red">去使用</button>
-						</template>
-                        <!-- 已使用 -->
-						<template v-else-if="tabIndex == 1">
-							<div class="icon-wrap">
-								<i class="iconfont iconyishiyong"></i>
-							</div>
+			<block v-if="!$util.isEmpty(list.data)">
+				<div class="list" v-for="(item, index) in list.data" :key="index">
+					<div class="list-img">
+						<!-- 已过期 -->
+						<template v-if="tabIndex == 2">
+							<img src="../../static/images/coupon/expired.png" alt mode="widthFix" />
 						</template>
-                        <!-- 已过期 -->
 						<template v-else>
-							<div class="icon-wrap">
-								<i class="iconfont iconyiguoqi"></i>
-							</div>
+							<img src="../../static/images/coupon/bg.png" alt mode="widthFix" />
 						</template>
 					</div>
+					<!-- 列表 -->
+					<div class="list-det">
+						<div class="list-det-left">
+							<div class="price-wrap">
+								<span>¥</span>
+								<span class="price">{{ item.amount }}</span>
+							</div>
+							<div class="full-reduc app-size-28">满{{ item.miniCost }}可使用</div>
+						</div>
+						<div class="list-det-right">
+							<div class="coupon-message">
+								<div class="app-color-2">优惠券</div>
+								<div>适用:全品类</div>
+								<div>有效至:{{ item.deadline | formatTime }}</div>
+							</div>
+							<!-- 未使用 -->
+							<template v-if="tabIndex == 0">
+								<button class="button-com red" @click="goUserFn">去使用</button>
+							</template>
+							<!-- 已使用 -->
+							<template v-else-if="tabIndex == 1">
+								<div class="icon-wrap">
+									<i class="iconfont iconyishiyong"></i>
+								</div>
+							</template>
+							<!-- 已过期 -->
+							<template v-else>
+								<div class="icon-wrap">
+									<i class="iconfont iconyiguoqi"></i>
+								</div>
+							</template>
+						</div>
+					</div>
 				</div>
-			</div>
+			</block>
+			<block v-else>
+				<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+			</block>
 		</div>
 	</div>
 </template>
 
 <script>
 import AppTabs from '@/components/plugin/tabs'
-import { list } from '@/api/coupon'
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
+import { list } from '@/mixins'
+// api
+import { getList } from '@/api/coupon'
 export default {
 	name: 'tabs',
 	components: {
@@ -76,9 +84,45 @@ export default {
 			]
 		}
 	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
+		}
+	},
+	onLoad: function() {
+		this.init()
+	},
 	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			return getList({ status: this.tabIndex }).then(res => {
+				this.completes(res)
+			})
+		},
 		change(e) {
-			this.tabIndex = e.index
+			if (this.tabIndex == e.index) {
+				return false
+			} else {
+				this.tabIndex = e.index
+				this.resetList()
+				this._list()
+			}
+		},
+		// 去使用
+		goUserFn() {
+			alert('跳转到哪?')
 		}
 	}
 }
@@ -103,7 +147,7 @@ export default {
 					top: 0;
 					left: 0;
 					.list-det-left {
-					    padding: 30px 0 30px 36px;
+						padding: 30px 0 30px 36px;
 						width: 210px;
 						color: #fff;
 						.price-wrap {
@@ -119,8 +163,8 @@ export default {
 					.list-det-right {
 						width: calc(100% - 280px);
 						margin-left: 22px;
-                        @include disFlex(center, space-between);
-                        padding: 30px 26px 30px 0;
+						@include disFlex(center, space-between);
+						padding: 30px 26px 30px 0;
 						.coupon-message {
 							color: $fontColor3;
 							& > div {
@@ -145,11 +189,11 @@ export default {
 			}
 			// 过期
 			&.expired {
-                .list-det-right {
-                    .iconfont {
-                        color: #E5E7EC !important;
-                    }
-                }
+				.list-det-right {
+					.iconfont {
+						color: #e5e7ec !important;
+					}
+				}
 			}
 		}
 	}

+ 199 - 125
mobile-code/src/pages/interest/admin/invite.vue

@@ -1,65 +1,99 @@
 <template>
 	<div class="app-content">
-		<app-tabs :tabs="tabs" :isFixed="true" :isAdd="true" addIcon="iconshezhi" addText="设置" @add="$util.pageTo('/pages/interest/admin/setting')" :isBoxShadow="false" :currentTab="tabIndex" @change="change" itemWidth="25%" :padding="0" />
+		<app-tabs :tabs="tabs" :isFixed="true" :isAdd="true" addIcon="iconshezhi" addText="设置" @add="$util.pageTo('/pages/interest/admin/setting')" :isBoxShadow="false" :currentTab="form.status" @change="change" itemWidth="25%" :padding="0" />
 		<div class="input-wrap">
 			<!-- <div class="map-search"> -->
-				<app-search-module placeholder="请输入商品名称" :isBtn="true"  />
+			<app-search-module placeholder="请输入商品名称" :isBtn="true" />
 			<!-- </div> -->
 			<!-- <div class="app-size-26">搜索</div> -->
 		</div>
 		<!-- list -->
 		<div class="list-wrap">
-			<div class="list" v-for="(item, index) in 10" :key="index">
-				<div>
-					<app-avatar-module :width="110" />
-				</div>
-				<div class="list-right">
-					<div class="flex-center-between">
-						<div class="app-size-30 app-color-0">清明哈</div>
-                        <div>待下单</div>
+			<block v-if="!$util.isEmpty(list.data)">
+				<div class="list" v-for="(item, index) in list.data" :key="index">
+					<div>
+						<app-avatar-module :src="item.userAvatar" :width="110" />
+					</div>
+					<div class="list-right">
+						<div class="flex-center-between">
+							<div class="app-size-30 app-color-0">{{ item.userName }}</div>
+							<div>{{ item.status | constantfilter('INVITE_STATUS') }}</div>
+						</div>
+						<div class="list-info">
+							<div class="list-info-left">
+								<div>介绍人:{{ item.introUserName }}</div>
+								<div class="list-remark" v-if="item.status == 0 && item.addTime">
+									<span>{{ item.addTime | formatTime }}</span>
+									<span class="list-remark-prompt">领券</span>
+								</div>
+								<div class="list-remark" v-if="item.status == 1 && item.orderTime">
+									<span>{{ item.orderTime | formatTime }}</span>
+									<span class="list-remark-prompt">下单{{ item.price }}</span>
+								</div>
+								<div class="list-remark" v-if="item.status == 2 && item.giveTime">
+									<span>{{ item.giveTime | formatTime }}</span>
+									<span class="list-remark-prompt">兑奖</span>
+								</div>
+							</div>
+							<div class="admin-button-com blue" v-if="item.status == 1" @click="redeemFn">兑奖</div>
+						</div>
 					</div>
-                    <div class="list-info">
-                        <div class="list-info-left">
-                            <div>介绍人:曾小小</div>
-                            <div class="list-remark">2019-11-9 16:15   领券</div>
-                        </div>
-                        <div class="admin-button-com blue" @click="redeemFn">兑奖</div>
-                    </div>
 				</div>
-			</div>
+			</block>
+			<block v-else>
+				<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+			</block>
 		</div>
 		<!-- 兑奖弹窗 -->
 		<modal-module :show="redeemModal" :custom="true" :maskClosable="false" @click="modalClick" padding="30rpx 30rpx">
 			<template>
-                <div class="redeem-wrap">
-                    <div class="redeem-list-wrap">
-                        <div class="list">
-                            <div class="list-tag">
-                                <img src="../../../static/images/interest/introducer.png" alt="" mode="widthFix" >
-                            </div>
-                            <div class="list-left">
-				                <app-avatar-module :width="100" />
-                            </div>
-                            <div class="list-right">
-                                <div class="app-color-0 app-size-30 app-blod">郑志军</div>
-                                <div>普通客户</div>
-                                <div>
-                                    <span class="list-time">2019-11-9 16:15</span>
-                                    <span>下单: ¥256</span>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <!-- 总览 -->
-                    <div class="redeem-total">
-                        <span>奖励:</span>
-                        <span class="app-price">¥30</span>
-                    </div>
-                    <div class="redeem-btn">
-                        <div class="admin-button-com default big" @click="modalCancel">取消</div>
-                        <div class="admin-button-com blue big">确认发奖</div>
-                    </div>
-                </div>
+				<div class="redeem-wrap">
+					<div class="redeem-list-wrap">
+                        <!-- 新用户 -->
+						<div class="list">
+							<div class="list-tag">
+								<img src="../../../static/images/interest/new-member.png" alt mode="widthFix" />
+							</div>
+							<div class="list-left">
+								<app-avatar-module :src="redeemData.userAvatar" :width="100" />
+							</div>
+							<div class="list-right">
+								<div class="app-color-0 app-size-30 app-blod">{{ redeemData.userName }}</div>
+								<div>普通客户</div>
+								<div>
+									<span class="list-time">{{ redeemData.orderTime | formatTime }}</span>
+									<span>下单: {{ redeemData.amount }}</span>
+								</div>
+							</div>
+						</div>
+                        <!-- 介绍人 -->
+						<div class="list">
+							<div class="list-tag">
+								<img src="../../../static/images/interest/introducer.png" alt mode="widthFix" />
+							</div>
+							<div class="list-left">
+								<app-avatar-module :src="redeemData.introUserAvatar" :width="100" />
+							</div>
+							<div class="list-right">
+								<div class="app-color-0 app-size-30 app-blod">{{ redeemData.introUserName }}</div>
+								<div>普通客户</div>
+								<div>
+									<span class="list-time">累计邀请: {{ redeemData.inviteNum }}</span>
+									<span>介绍下单数: {{ redeemData.orderNum }}</span>
+								</div>
+							</div>
+						</div>
+					</div>
+					<!-- 总览 -->
+					<div class="redeem-total">
+						<span>奖励:</span>
+						<span class="app-price">¥{{ redeemData.prize }}</span>
+					</div>
+					<div class="redeem-btn">
+						<div class="admin-button-com default big" @click="modalCancel">取消</div>
+						<div class="admin-button-com blue big" @click="confirmGive">确认发奖</div>
+					</div>
+				</div>
 			</template>
 		</modal-module>
 	</div>
@@ -70,19 +104,26 @@ import AppTabs from '@/components/plugin/tabs'
 import AppSearchModule from '@/components/module/app-search'
 import AppAvatarModule from '@/components/module/app-avatar'
 import ModalModule from '@/components/plugin/modal'
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
+import { list } from '@/mixins'
 // api
-import { getList } from '@/api/invite'
+import { getList, getDet, give } from '@/api/invite'
 export default {
 	name: 'admin-invite',
 	components: {
 		AppTabs,
 		AppSearchModule,
 		AppAvatarModule,
-		ModalModule
+		ModalModule,
+		AppWrapperEmpty
 	},
+	mixins: [list],
 	data() {
 		return {
-			tabIndex: 0,
+			form: {
+				status: 0,
+				search: ''
+			},
 			tabs: [
 				{
 					name: '全部'
@@ -97,22 +138,52 @@ export default {
 					name: '已兑奖'
 				}
 			],
-			redeemModal: false
+			// 兑奖
+			redeemModal: false,
+			// 兑奖数据
+			redeemData: {}
 		}
 	},
+	onLoad: function() {
+		this.init()
+	},
 	methods: {
-		_getList() {
-			getList().then(res => {})
+		async init() {
+			this._list()
+		},
+		_list() {
+			let params = JSON.parse(JSON.stringify(this.form))
+			params.status = params.status - 1
+			return getList(params).then(res => {
+				this.completes(res)
+			})
 		},
 		change(e) {
-			this.tabIndex = e.index
+			if (this.form.status == e.index) {
+				return false
+			} else {
+				this.form.status = e.index
+				this.resetList()
+				this._list()
+			}
 		},
 		modalCancel() {
 			this.redeemModal = false
 		},
 		modalClick() {},
-		redeemFn() {
-			this.redeemModal = true
+		// 查看详情
+		redeemFn(item) {
+			getDet({ id: item.id }).then(res => {
+			    this.redeemData = res.data
+			    this.redeemModal = true
+			})
+		},
+		// 兑奖
+		confirmGive() {
+			give({ id: this.redeemData.id }).then(res => {
+				this.$msg('兑奖成功!')
+				this.modalCancel()
+			})
 		}
 	}
 }
@@ -129,73 +200,76 @@ export default {
 		left: 0;
 		width: calc(100% - 50px);
 		background-color: #fff;
-        padding: 22px 20px 22px 30px;
-        border-top: 1px solid $borderColor;
-    }
-    // list
-    .list-wrap {
-        width: 100%;
-        color: $fontColor3;
-        background-color: #fff;
-        .list {
-            @include disFlex(center, space-between);
-            width: calc(100% - 60px);
-            padding: 30px 0;
-            margin: 0 30px;
-            border-bottom: 1px solid $borderColor;
-            .list-right {
-                width: calc(100% - 130px);
-                .list-info {
-                    @include disFlex(center, space-between);
-                    margin-top: 10px;
-                    .list-remark {
-                        margin-top: 10px;
-                    }
-                    .admin-button-com {
-                        width: 80px;
-                    }
-                }
-            }
-        }
-    }
-    // module
-    .redeem-wrap {
-        .redeem-list-wrap {
-            .list {
-                position: relative;
-                @include disFlex(center, flex-start);
-                padding: 28px 20px;
-                color: $fontColor3;
-                box-shadow: 0px 1px 16px 0px rgba(238,238,238,1);
-                border-radius: 10px;
-                .list-tag {
-                    position: absolute;
-                    top: 0;
-                    right: 0;
-                    width: 100px;
-                }
-                .list-right {
-                    margin-left: 20px;
-                    & > div:first-child {
-                        margin-top: 0;
-                    }
-                    & > div {
-                        margin-top: 14px;
-                    }
-                }
-            }
-        }
-        .redeem-total {
-            margin: 30px 0 50px;
-            text-align: center;
-            font-size: 40px;
-        }
-        .redeem-btn {
-            @include disFlex(center, space-between);
-            width: 100%;
-            .admin-button-com {
-                width: 40%;
-            }
-        }
-    }
+		padding: 22px 20px 22px 30px;
+		border-top: 1px solid $borderColor;
+	}
+	// list
+	.list-wrap {
+		width: 100%;
+		color: $fontColor3;
+		background-color: #fff;
+		.list {
+			@include disFlex(center, space-between);
+			width: calc(100% - 60px);
+			padding: 30px 0;
+			margin: 0 30px;
+			border-bottom: 1px solid $borderColor;
+			.list-right {
+				width: calc(100% - 130px);
+				.list-info {
+					@include disFlex(center, space-between);
+					margin-top: 10px;
+					.list-remark {
+						margin-top: 10px;
+						.list-remark-prompt {
+							margin-left: 20px;
+						}
+					}
+					.admin-button-com {
+						width: 80px;
+					}
+				}
+			}
+		}
+	}
+	// module
+	.redeem-wrap {
+		.redeem-list-wrap {
+			.list {
+				position: relative;
+				@include disFlex(center, flex-start);
+				padding: 28px 20px;
+				color: $fontColor3;
+				box-shadow: 0px 1px 16px 0px rgba(238, 238, 238, 1);
+				border-radius: 10px;
+				.list-tag {
+					position: absolute;
+					top: 0;
+					right: 0;
+					width: 100px;
+				}
+				.list-right {
+					margin-left: 20px;
+					& > div:first-child {
+						margin-top: 0;
+					}
+					& > div {
+						margin-top: 14px;
+					}
+				}
+			}
+		}
+		.redeem-total {
+			margin: 30px 0 50px;
+			text-align: center;
+			font-size: 40px;
+		}
+		.redeem-btn {
+			@include disFlex(center, space-between);
+			width: 100%;
+			.admin-button-com {
+				width: 40%;
+			}
+		}
+	}
 </style>

+ 38 - 7
mobile-code/src/pages/interest/admin/setting.vue

@@ -3,43 +3,74 @@
 		<div class="module-com flex-center-between switch-blo">
 			<div class="app-size-32">开启状态</div>
 			<div>
-				<switch checked @change="switchChangeFn" />
+				<switch :checked="form.switch ? true : false" @change="switchChangeFn" />
 			</div>
 		</div>
 		<div class="module-com flex-center">
             <label class="app-size-28">邀请成功下单奖励</label>
-            <input type="text" class="app-size-28 reward-inp" placeholder="请输入">
+            <input type="text" class="app-size-28 reward-inp" v-model="form.prize" placeholder="请输入">
         </div>
 		<div class="prompt-text">奖励可以是现金、绿植和散花等</div>
 		<div class="module-com new_wrap">
 			<div class="module-tit">新人可领取</div>
 			<div class="module-det">
 				<div>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.amount" />
 					<span>元优惠券,满</span>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.miniCost" />
 					<span>元可以使用,</span>
 				</div>
                 <div>
                     <span>领取后</span>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.duration" />
                     <span>天内有效。</span>
                 </div>
 			</div>
 		</div>
 		<div class="prompt-text">提示:奖励额度可以比新人领券高一此, 这样可以吸引老客户邀请 新人,新人也更愿意到店消费。</div>
-		<div class="admin-button-com blue big">确认</div>
+		<div class="admin-button-com blue big" @click="confirmFn">确认</div>
 	</div>
 </template>
 
 <script>
+import { inviteAssetDet, inviteAssetUpdate } from '@/api/invite'
 export default {
 	name: 'invite-setting',
 	data() {
-		return {}
+		return {
+			form: {
+				switch: 1,
+				prize: 0,
+				amount: 0,
+				miniCost: 0,
+				duration: 0
+			}
+		}
+	},
+	onLoad() {
+		this.init()
 	},
 	methods: {
+		init() {
+			this._getDet()
+		},
+		// 获取详情
+		_getDet() {
+			inviteAssetDet().then(res => {
+				if (this.$util.isEmpty(res.data)) return
+				Object.keys(this.form).forEach((i, index) => {
+					this.form[i] = res.data[i]
+				})
+			})
+		},
+		// 设置奖励
+		confirmFn() {
+			inviteAssetUpdate(this.form).then(res => {
+				this.$msg('修改成功!')
+			})
+		},
 		switchChangeFn(e) {
+			this.switch = e.target.value ? 1 : 0
 			console.log('switch1 发生 change 事件,携带值为', e.target.value)
 		}
 	}

+ 36 - 6
mobile-code/src/pages/setting/coupon.vue

@@ -3,37 +3,67 @@
 		<div class="module-com flex-center-between switch-blo">
 			<div class="app-size-32">开启自动涨价</div>
 			<div>
-				<switch checked @change="switchChangeFn" />
+				<switch :checked="form.switch ? true : false" @change="switchChangeFn" />
 			</div>
 		</div>
 		<div class="module-com new_wrap">
 			<div class="module-det">
 				<div>
 					<span>新人注册会员赠送</span>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.amount" />
 					<span>元优惠券,满</span>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.miniCost" />
 				</div>
                 <div>
                     <span>元可以使用,</span>
-					<input type="text" class="setting-inp" />
+					<input type="text" class="setting-inp" v-model="form.duration" />
                     <span>天内有效。</span>
                 </div>
 			</div>
 		</div>
 		<div class="prompt-text">提示:在节日的前一天和当天, 商城设置自动涨价的商品将会全部 统一涨价。过后自动恢复原价。</div>
-		<div class="admin-button-com blue big">确定</div>
+		<div class="admin-button-com blue big" @click="confirmFn">确定</div>
 	</div>
 </template>
 
 <script>
+import { couponAssetDet, couponAssetUpdate } from '@/api/coupon'
 export default {
 	name: 'setting-coupon',
 	data() {
-		return {}
+		return {
+			form: {
+				switch: 1,
+				amount: 0,
+				miniCost: 0,
+				duration: 0
+			}
+		}
+	},
+	onLoad() {
+		this.init()
 	},
 	methods: {
+		init() {
+			this._getDet()
+		},
+		// 获取详情
+		_getDet() {
+			couponAssetDet().then(res => {
+				if (this.$util.isEmpty(res.data)) return
+				Object.keys(this.form).forEach((i, index) => {
+					this.form[i] = res.data[i]
+				})
+			})
+		},
+		// 设置奖励
+		confirmFn() {
+			couponAssetUpdate(this.form).then(res => {
+				this.$msg('修改成功!')
+			})
+		},
 		switchChangeFn(e) {
+			this.switch = e.target.value ? 1 : 0
 			console.log('switch1 发生 change 事件,携带值为', e.target.value)
 		}
 	}

+ 181 - 75
mobile-code/src/pages/staff/add.vue

@@ -1,76 +1,81 @@
 <template>
 	<div class="app-content">
 		<!-- 员工信息 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell" :hover="false">
-				<div class="tui-title required">员工姓名</div>
-				<input v-model="form.receiveUserName" placeholder-class="phcolor" class="tui-input" name="name" placeholder="请输入姓名" maxlength="50" type="number" />
-			</tui-list-cell>
-			<tui-list-cell class="line-cell" :arrow="true">
-				<div class="tui-title required">角色</div>
-				<div v-if="true">老板</div>
-				<div class="tui-placeholder" v-else>请选择</div>
-			</tui-list-cell>
-			<tui-list-cell class="line-cell" :arrow="true" @click="$util.pageTo('/pages/staff/sel-member')">
-				<div class="tui-title required">关联微信</div>
-				<div v-if="true" class="member-wrap flex-center">
-                    <div class="member-img">
-				        <app-avatar-module :width="60" />
-                    </div>
-                    <div class="member-det">
-                        <div class="app-size-28">冯宝宝</div>
-                        <div>153928272822</div>
-                    </div>
-                </div>
-				<div class="tui-placeholder" v-else>请选择</div>
-			</tui-list-cell>
-		</div>
-		<div class="prompt-text">注: 关联的微信号要注册会员并关注公从号</div>
-		<!-- 收款通知 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell between" padding="14rpx 30rpx" :hover="false">
-				<div class="tui-title">收款通知</div>
-				<div>
-					<switch checked @change="switchChangeFn" />
-				</div>
-			</tui-list-cell>
-		</div>
-		<!-- 登录信息 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell" :hover="false">
-				<div class="tui-title required">登陆密码</div>
-				<input v-model="form.receiveUserName" placeholder-class="phcolor" class="tui-input" name="name" placeholder="请输入" maxlength="50" type="number" />
-			</tui-list-cell>
-			<tui-list-cell class="line-cell" :hover="false">
-				<div class="tui-title required">确认密码</div>
-				<input v-model="form.receiveUserName" placeholder-class="phcolor" class="tui-input" name="name" placeholder="请输入" maxlength="50" type="number" />
-			</tui-list-cell>
-			<tui-list-cell class="line-cell remark-wrap" :hover="false">
-				<div class="tui-title">备注信息</div>
-				<div class="tui-input">
-					<textarea class="tui-textarea remark" placeholder-class="phcolor" placeholder="请输入内容" />
-				</div>
-			</tui-list-cell>
-		</div>
-		<!-- 马上启用 -->
-		<div class="module-com input-line-wrap">
-			<tui-list-cell class="line-cell between" padding="14rpx 30rpx" :hover="false">
-				<div class="tui-title">马上启用</div>
-				<div>
-					<switch checked @change="switchChangeFn" />
-				</div>
-			</tui-list-cell>
-		</div>
-		<!-- 提交 -->
-		<div class="confirm-btn">
-			<div class="admin-button-com big blue">提交</div>
-		</div>
+		<form @submit="formSubmit" @reset="formReset">
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-cell" :hover="false">
+					<div class="tui-title required">员工姓名</div>
+					<input v-model="form.adminName" placeholder-class="phcolor" class="tui-input" name="adminName" placeholder="请输入姓名" maxlength="50" type="text" />
+				</tui-list-cell>
+				<tui-list-cell class="line-cell" :arrow="true">
+					<div class="tui-title required">角色</div>
+					<picker mode="selector" :value="form.roleId" :range="roleList" range-key="roleName" @change="changeRoleFn" class="tui-input">
+						<input v-model="form.roleId" name="roleId" type="text" hidden />
+						<div v-if="form.roleId">{{ roleSelData.roleName }}</div>
+						<div class="tui-placeholder" v-else>请选择</div>
+					</picker>
+				</tui-list-cell>
+				<tui-list-cell class="line-cell" :arrow="true" @click="$util.pageTo('/pages/staff/sel-member')">
+					<div class="tui-title required">关联微信</div>
+					<div v-if="form.userId" class="member-wrap flex-center">
+						<input v-model="form.userId" name="userId" type="text" hidden />
+						<div class="member-img">
+							<app-avatar-module :width="60" />
+						</div>
+						<div class="member-det">
+							<div class="app-size-28">冯宝宝</div>
+							<div>153928272822</div>
+						</div>
+					</div>
+					<div class="tui-placeholder" v-else>请选择</div>
+				</tui-list-cell>
+			</div>
+			<div class="prompt-text">注: 关联的微信号要注册会员并关注公从号</div>
+			<!-- 收款通知 -->
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-cell between" padding="14rpx 30rpx" :hover="false">
+					<div class="tui-title">收款通知</div>
+					<div>
+						<switch :checked="form.remind ? true : false" @change="switchChangeFn" />
+					</div>
+				</tui-list-cell>
+			</div>
+			<!-- 登录信息 -->
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-cell" :hover="false">
+					<div class="tui-title required">登陆密码</div>
+					<input v-model="form.password" placeholder-class="phcolor" class="tui-input" name="password" placeholder="请输入" maxlength="50" type="text" />
+				</tui-list-cell>
+				<tui-list-cell class="line-cell remark-wrap" :hover="false">
+					<div class="tui-title">备注信息</div>
+					<div class="tui-input">
+						<textarea v-model="form.remark" class="tui-textarea remark" placeholder-class="phcolor" placeholder="请输入内容" />
+					</div>
+				</tui-list-cell>
+			</div>
+			<!-- 马上启用 -->
+			<div class="module-com input-line-wrap">
+				<tui-list-cell class="line-cell between" padding="14rpx 30rpx" :hover="false">
+					<div class="tui-title">马上启用</div>
+					<div>
+						<switch :checked="form.status ? true : false" @change="switchChangeFn" />
+					</div>
+				</tui-list-cell>
+			</div>
+			<!-- 提交 -->
+			<div class="confirm-btn">
+				<button class="admin-button-com big blue" formType="submit">提交</button>
+			</div>
+		</form>
 	</div>
 </template>
 
 <script>
 import TuiListCell from '@/components/plugin/list-cell'
 import AppAvatarModule from '@/components/module/app-avatar'
+const form = require('@/utils/formValidation.js')
+// api
+import { getRoleList, getStaffDet as getDet, addStaff as add, updateStaff as update } from '@/api/staff'
 export default {
 	name: 'staff-add',
 	components: {
@@ -79,11 +84,112 @@ export default {
 	},
 	data() {
 		return {
-			form: {}
+			form: {
+				adminName: '',
+				roleId: '',
+				remind: 0,
+				password: '',
+				userId: '1',
+				status: 0,
+				remark: ''
+			},
+			roleList: [],
+			roleSelData: {},
+			memberData: {}
 		}
 	},
+	onLoad() {
+		this.init()
+	},
 	methods: {
-		switchChangeFn() {}
+		init() {
+		// 	this.type = this.option.type
+
+			let data = uni.getStorageSync('addStaffData')
+			if (data) {
+				uni.removeStorageSync('addStaffData')
+				this.form = data.form
+				this.imgList = data.imgList
+				this.goodsData = data.goodsData
+			}
+			let memberData = uni.getStorageSync('memberSelGoods')
+			if (memberData) {
+				uni.removeStorageSync('memberSelGoods')
+				this.memberData = memberData
+				this.userId = memberData.id
+			}
+
+			if (this.option.id && !data) {
+				this._getDet()
+			}
+			this._getRoleList()
+		},
+		// api
+		_getRoleList() {
+			getRoleList().then(res => {
+				if (this.$util.isEmpty(res.data)) return false
+				this.roleList = res.data.list
+			})
+		},
+		_getDet() {
+			getDet({ id: this.option.id }).then(res => {
+				if (this.$util.isEmpty(res.data)) return
+				Object.keys(this.form).forEach((i, index) => {
+					this.form[i] = res.data[i]
+				})
+			})
+		},
+		// option
+		changeRoleFn(e) {
+			this.roleSelData = this.roleList[e.detail.value]
+			this.form.roleId = this.roleSelData.id
+		},
+		switchChangeFn() {},
+		confirmFn() {
+			let hostFn = this.option.id ? update : add
+			if (this.option.id) {
+				this.form.id = this.option.id
+			}
+			hostFn(this.form).then(res => {
+				let promptText = this.option.id ? '修改成功!' : '添加成功!'
+				this.$msg(promptText)
+			})
+		},
+		// 表单验证
+		formSubmit(e) {
+			// 表单规则
+			let rules = [
+				{
+					name: 'adminName',
+					rule: ['required'],
+					msg: ['请输入姓名']
+				},
+				{
+					name: 'roleId',
+					rule: ['required'],
+					msg: ['请选择角色']
+				},
+				{
+					name: 'userId',
+					rule: ['required'],
+					msg: ['请选择关联微信']
+				},
+				{
+					name: 'password',
+					rule: ['required'],
+					msg: ['请输入密码']
+				}
+			]
+			// 进行表单检查
+			let formData = e.detail.value
+			let checkRes = form.validation(formData, rules)
+			// 验证通过!
+			if (!checkRes) {
+				this.confirmFn()
+			} else {
+				this.$msg(checkRes)
+			}
+		}
 	}
 }
 </script>
@@ -100,15 +206,15 @@ export default {
 	}
 	// ---
 	.module-com {
-        margin-bottom: 20px;
-        .member-wrap {
-            .member-det {
-                font-size: 24px;
-                margin-left: 20px;
-            }
-        }
+		margin-bottom: 20px;
+		.member-wrap {
+			.member-det {
+				font-size: 24px;
+				margin-left: 20px;
+			}
+		}
 		.remark-wrap {
-            align-items: flex-start;
+			align-items: flex-start;
 			.remark {
 				height: 240px;
 			}
@@ -119,7 +225,7 @@ export default {
 		width: calc(100% - 60px);
 		margin: 60px 30px 20px;
 		.admin-button-com {
-			width: calc(100% - 40px);
+			width: 100%;
 		}
 	}
 </style>

+ 227 - 80
mobile-code/src/pages/staff/list.vue

@@ -5,83 +5,119 @@
 		<block v-if="tabIndex == 0">
 			<!-- 列表 -->
 			<div class="list-wrap staff-list">
-				<div class="list" v-for="(item, index) in 4" :key="index">
-					<div>
-						<app-avatar-module :width="90" />
-					</div>
-					<div class="list-det">
-						<div class="list-det-left">
-							<div>
-								<span class="staff-name">按当地</span>
-								<span>员工</span>
-							</div>
-							<div class="flex-center">
-								<div class="status-list">
-									<i class="iconfont icondagou"></i>
-									<span>收款通知</span>
+				<block v-if="!$util.isEmpty(list.data)">
+					<div class="list" v-for="(item, index) in list.data" :key="index">
+						<div>
+							<app-avatar-module :src="item.avatarUrl" :width="90" />
+						</div>
+						<div class="list-det">
+							<div class="list-det-left">
+								<div>
+									<span class="staff-name">{{ item.adminName }}</span>
+									<span>{{ item.roleName }}</span>
 								</div>
-								<div class="status-list">
-									<i class="iconfont icondagou"></i>
-									<span>启用</span>
+								<div class="flex-center">
+									<div class="status-list">
+										<i class="iconfont icondagou" :class="[item.incomeNotice ? 'app-color-1' : '' ]"></i>
+										<span :class="[item.incomeNotice ? 'app-color-1' : 'app-color-3' ]">收款通知</span>
+									</div>
+									<div class="status-list">
+										<i class="iconfont icondagou" :class="[item.status ? 'app-color-1' : '' ]"></i>
+										<span :class="[item.status ? 'app-color-1' : 'app-color-3' ]">启用</span>
+									</div>
 								</div>
 							</div>
-						</div>
-						<div class="list-det-right">
-							<div>
-								<i class="iconfont iconbianji"></i>
-							</div>
-							<div>
-								<i class="iconfont iconshanchu1"></i>
+							<div class="list-det-right">
+								<div @click="$util.pageTo({
+								url: '/pages/staff/add',
+								query: {
+									id: item.id
+								}
+							})">
+									<i class="iconfont iconbianji"></i>
+								</div>
+								<!-- 删除 -->
+								<div @click="delModalFn(item)">
+									<i class="iconfont iconshanchu1"></i>
+								</div>
 							</div>
 						</div>
 					</div>
-				</div>
+				</block>
+				<block v-else>
+					<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+				</block>
 			</div>
 			<!-- 按钮 -->
 			<div class="app-footer">
-				<div class="admin-button-com middle blue">添加</div>
+				<div class="admin-button-com middle blue" @click="$util.pageTo('/pages/staff/add')">添加</div>
 			</div>
 		</block>
 		<!-- 角色管理 -->
 		<block v-if="tabIndex == 1">
 			<!-- 列表 -->
 			<div class="list-wrap role-list">
-				<div class="list">
-					<div class="app-size-32">销售部(10)</div>
-					<div class="role-option">
-						<div>
-							<i class="iconfont iconbianji"></i>
-						</div>
-						<div>
-							<i class="iconfont iconshanchu1"></i>
+				<block v-if="!$util.isEmpty(list.data)">
+					<div class="list" v-for="(item, index) in list.data" :key="index">
+						<div class="app-size-32">{{ item.roleName }}(10)</div>
+						<div class="role-option">
+							<div @click="modifyRoleFn(item)">
+								<i class="iconfont iconbianji"></i>
+							</div>
+							<div @click="delModalFn(item)">
+								<i class="iconfont iconshanchu1"></i>
+							</div>
 						</div>
 					</div>
-				</div>
+				</block>
+				<block v-else>
+					<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+				</block>
 			</div>
 			<!-- 按钮 -->
 			<div class="app-footer">
-				<div class="admin-button-com middle blue">添加角色</div>
+				<div class="admin-button-com middle blue" @click="addRoleFn">添加角色</div>
 			</div>
 		</block>
 		<!-- 操作记录 -->
 		<block v-if="tabIndex == 2">
 			<!-- 列表 -->
 			<div class="axis-wrap">
-				<time-axis>
-					<timeaxis-item class="axis-list" bgcolor="none" v-for="(item, index) in 4" :key="index">
-						<template v-slot:content>
-							<div class="axis-title">编辑会员账号:amdis</div>
-							<div class="axis-det">
-                                <div>ID:10087</div>
-                                <div>IP:192.168.1.1</div>
-                                <div>操作者:admin</div>
-                                <div>操作时间:2019-10-30 12:20:00</div>
-                            </div>
-						</template>
-					</timeaxis-item>
-				</time-axis>
+				<block v-if="!$util.isEmpty(list.data)">
+					<time-axis>
+						<timeaxis-item class="axis-list" bgcolor="none" v-for="(item, index) in list.data" :key="index">
+							<template v-slot:content>
+								<div class="axis-title">{{ item.content }}</div>
+								<div class="axis-det">
+									<div>ID:{{ item.id }}</div>
+									<div>IP:{{ item.ip }}</div>
+									<div>操作者:{{ item.adminName }}</div>
+									<div>操作时间:{{ item.addTime | formatTime }}</div>
+								</div>
+							</template>
+						</timeaxis-item>
+					</time-axis>
+				</block>
+				<block v-else>
+					<app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+				</block>
 			</div>
 		</block>
+		<!-- 角色操作 -->
+		<modal-module :show="roleModal" @cancel="modalCancel" @click="roleModalClick" :title="roleModalText" padding="30rpx 30rpx">
+			<template v-slot:content>
+				<div class="app-modal-input-wrap">
+					<div class="inp-list-line required">
+						<div class="line-label">角色名称</div>
+						<div class="line-input">
+							<input v-model="roleModalVal" type="text" :adjust-position="false" class="inp-input">
+						</div>
+					</div>
+				</div>
+			</template>
+		</modal-module>
+		<!-- 删除弹窗 -->
+		<modal-module :show="delModal" @cancel="modalCancel" @click="delModalClick" :content="delModalText" color="#333" :size="32" padding="30rpx 30rpx"></modal-module>
 	</div>
 </template>
 
@@ -91,14 +127,22 @@ import AppAvatarModule from '@/components/module/app-avatar'
 // 时间轴
 import TimeAxis from '@/pages/admin/components/plugin/time-axis'
 import TimeaxisItem from '@/pages/admin/components/plugin/timeaxis-item'
+import AppWrapperEmpty from '@/components/app-wrapper-empty'
+import ModalModule from '@/components/plugin/modal'
+import { list } from '@/mixins'
+// api
+import { getStaffList, delStaff, getRoleList, addRole, updateRole, delRole, getLogList } from '@/api/staff'
 export default {
 	name: 'staff-list',
 	components: {
 		AppTabs,
 		AppAvatarModule,
 		TimeAxis,
-		TimeaxisItem
+		TimeaxisItem,
+		AppWrapperEmpty,
+		ModalModule
 	},
+	mixins: [list],
 	data() {
 		return {
 			tabIndex: 0,
@@ -112,12 +156,115 @@ export default {
 				{
 					name: '操作记录'
 				}
-			]
+			],
+			// 删除弹窗操作
+			delModal: false,
+			delModalText: '确定删除该员工吗?',
+			operateData: {},
+			// 角色弹窗操作
+			roleModal: false,
+			roleModalText: '添加',
+			roleModalVal: '',
+			roleOperateData: {}
+		}
+	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
 		}
 	},
+	onLoad: function() {
+		this.init()
+	},
 	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			let hostFn = this.tabIndex == 0 ? getStaffList : this.tabIndex == 1 ? getRoleList : getLogList
+			return hostFn().then(res => {
+				this.completes(res)
+			})
+		},
 		change(e) {
-			this.tabIndex = e.index
+			if (this.tabIndex == e.index) {
+				return false
+			} else {
+				this.tabIndex = e.index
+				this.resetList()
+				this._list()
+			}
+		},
+		// 关闭弹窗
+		modalCancel() {
+			this.delModal = false
+			this.roleModal = false
+		},
+		// 删除弹窗
+		delModalFn(item) {
+			this.delModalText = this.tabIndex == 0 ? '确定删除该员工吗?' : '确定删除该角色吗?'
+			this.operateData = item
+			this.delModal = true
+		},
+		delModalClick(e) {
+			let index = e.index
+			if (index === 0) {
+				this.modalCancel()
+			} else {
+				let hostFn = this.tabIndex == 0 ? delStaff : delRole
+				hostFn({ id: this.operateData.id }).then(res => {
+					this.modalCancel()
+					this.$msg('删除成功!')
+					setTimeout(() => {
+						this.resetList()
+						this._list()
+					}, 1000)
+				})
+			}
+		},
+		// 角色操作
+		addRoleFn() {
+			this.roleModal = true
+			this.roleModalText = '添加'
+			this.roleModalVal = ''
+		},
+		modifyRoleFn(item) {
+			this.roleModal = true
+			this.roleModalText = '修改'
+			this.roleModalVal = item.roleName
+			this.roleOperateData = item
+		},
+		roleModalClick(e) {
+			let index = e.index
+			if (index === 0) {
+				this.modalCancel()
+			} else {
+				let hostFn = this.roleModalText == '添加' ? addRole : updateRole
+				let params = {
+					roleName: this.roleModalVal
+				}
+				if (this.roleModalText == '修改') {
+					params.id = this.roleOperateData.id
+				}
+				hostFn(params).then(res => {
+					this.modalCancel()
+					this.$msg(`${this.roleModalText}成功!`)
+					setTimeout(() => {
+						this.resetList()
+						this._list()
+					}, 1000)
+				})
+			}
 		}
 	}
 }
@@ -162,7 +309,7 @@ export default {
 						margin-left: 0;
 					}
 					.iconfont {
-						color: $fontColor3;
+						// color: $fontColor3;
 						font-size: 24px;
 						margin-right: 10px;
 					}
@@ -201,33 +348,33 @@ export default {
 				color: $fontColor3;
 			}
 		}
-    }
-    // 操作记录
-    .axis-wrap {
-        position: relative;
-        padding: 30px 30px 30px 40px;
-        background-color: #fff;
-        .axis-list {
-            &:last-child .axis-det{
-                margin-bottom: 0;
-            }
-        }
-        .axis-title {
-            font-size: 30px;
-            font-weight: 600;
-            margin-bottom: 14px;
-        }
-        .axis-det {
-            color: $fontColor2;
-            margin-bottom: 40px;
-            & > div {
-                margin-top: 6px;
-                &:first-child {
-                    margin-top: 0;
-                }
-            }
-        }
-    }
+	}
+	// 操作记录
+	.axis-wrap {
+		position: relative;
+		padding: 30px 30px 30px 40px;
+		background-color: #fff;
+		.axis-list {
+			&:last-child .axis-det {
+				margin-bottom: 0;
+			}
+		}
+		.axis-title {
+			font-size: 30px;
+			font-weight: 600;
+			margin-bottom: 14px;
+		}
+		.axis-det {
+			color: $fontColor2;
+			margin-bottom: 40px;
+			& > div {
+				margin-top: 6px;
+				&:first-child {
+					margin-top: 0;
+				}
+			}
+		}
+	}
 	// 按钮
 	.app-footer {
 		justify-content: flex-end;

+ 60 - 1
mobile-code/src/pages/staff/sel-member.vue

@@ -1,15 +1,74 @@
 <template>
 	<div class="app-content">
-		<sel-search-module></sel-search-module>
+		<sel-search-module :list="list.data" @search="searchFn" @change="changeFn"></sel-search-module>
 	</div>
 </template>
 
 <script>
 import SelSearchModule from '@/pages/admin/components/sel-search'
+import { list } from '@/mixins'
+// api
+import { getList } from '@/api/member'
 export default {
 	name: 'staff-sel-member',
 	components: {
 		SelSearchModule
+	},
+	mixins: [list],
+	data() {
+		return {
+			search: ''
+		}
+	},
+	onPullDownRefresh() {
+		this.resetList()
+		this._list().then(res => {
+			uni.stopPullDownRefresh()
+		})
+	},
+	onReachBottom() {
+		if (this.list.data.length < this.list.total) {
+			this._list().then(res => {
+				uni.stopPullDownRefresh()
+			})
+		} else {
+			uni.stopPullDownRefresh()
+		}
+	},
+	onLoad: function() {
+		this.init()
+	},
+	methods: {
+		async init() {
+			this._list()
+		},
+		_list() {
+			let params = {
+				page: this.list.page,
+				goodsName: this.search
+			}
+			return getList(params).then(res => {
+				this.completes(res)
+			})
+		},
+		// 搜索
+		searchFn(val) {
+			if (!val) return false
+			this.search = val
+			this.resetList()
+			this._list()
+		},
+		// 选择员工
+		changeFn(e) {
+			uni.setStorageSync('addStaffData', e)
+			this.$util.pageTo({
+				url: '/pages/staff/add',
+				query: {
+					...this.option
+				},
+				type: 2
+			})
+		}
 	}
 }
 </script>

+ 14 - 11
mobile-code/src/plugins/luch-request_0.0.7/request.js

@@ -146,18 +146,21 @@ class Request {
 						// 无权限或者登录过期
 						if (response.data.code && response.data.code == -100) {
 							uni.removeStorageSync('token')
-							uni.showToast({
-								title: '登陆过期,正在返回登录页...',
-								icon: 'none',
-								mask: true
-							})
-							setTimeout(() => {
-								uni.reLaunch({
-									url: `/pages/page/login/index`
-								})
-							}, 2000)
+							// uni.showToast({
+							// 	title: '登陆过期,正在返回登录页...',
+							// 	icon: 'none',
+							// 	mask: true
+							// })
+							// setTimeout(() => {
+							// 	uni.reLaunch({
+							// 		url: `/pages/page/login/index`
+							// 	})
+							// }, 2000)
 						} else {
+							console.log(config.hideError, 'asdfadsf')
 							if (!config.hideError) {
+								// this.$msg(response.data.msg)
+								console.log(response.data.msg, 'asdfadsf')
 								uni.showToast({
 									title: response.data.msg,
 									icon: 'none',
@@ -188,7 +191,7 @@ class Request {
 
 	get(url, data = {}, options = {}, config = {}) {
 		// options.url = url + common.queryData(data, true)
-		options.url = url + parse(data, true)
+		options.url = url + parse(data)
 		options.data = {}
 		options.method = 'GET'
 		return this.request(options, config)

+ 267 - 0
mobile-code/src/utils/formValidation.js

@@ -0,0 +1,267 @@
+/**
+ * 表单验证
+ * @author dingyong
+ * @version 1.4.0
+ **/
+
+const form = {
+	// 当出现错误时返回错误消息,否则返回空即为验证通过
+	/*
+	 formData:Object 表单对象。{key:value,key:value},key==rules.name
+	 rules: Array [{name:name,rule:[],msg:[]},{name:name,rule:[],msg:[]}]
+			name:name 属性=> 元素的名称
+			rule:字符串数组 ["required","isMobile","isEmail","isCarNo","isIdCard","isAmount","isNum","isChinese","isEnglish",isEnAndNo","isSpecial","isEmoji",""isDate","isUrl","isSame:key","range:[1,9]","minLength:9","maxLength:Number"]
+			msg:数组 []。 与数组 rule 长度相同,对应的错误提示信息
+	*/
+	validation: function(formData, rules) {
+		for (let item of rules) {
+			let key = item.name
+			let rule = item.rule
+			let msgArr = item.msg
+			if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0) {
+				continue
+			}
+			for (let i = 0, length = rule.length; i < length; i++) {
+				let ruleItem = rule[i]
+				let msg = msgArr[i]
+				if (!ruleItem || !msg) {
+					continue
+				}
+				// 数据处理
+				let value = null
+				if (~ruleItem.indexOf(':')) {
+					let temp = ruleItem.split(':')
+					ruleItem = temp[0]
+					value = temp[1]
+				}
+				let isError = false
+				switch (ruleItem) {
+					case 'required':
+						isError = form._isNullOrEmpty(formData[key])
+						break
+					case 'isMobile':
+						isError = !form._isMobile(formData[key])
+						break
+					case 'isEmail':
+						isError = !form._isEmail(formData[key])
+						break
+					case 'isCarNo':
+						isError = !form._isCarNo(formData[key])
+						break
+					case 'isIdCard':
+						isError = !form._isIdCard(formData[key])
+						break
+					case 'isAmount':
+						isError = !form._isAmount(formData[key])
+						break
+					case 'isNum':
+						isError = !form._isNum(formData[key])
+						break
+					case 'isChinese':
+						isError = !form._isChinese(formData[key])
+						break
+					case 'isEnglish':
+						isError = !form._isEnglish(formData[key])
+						break
+					case 'isEnAndNo':
+						isError = !form._isEnAndNo(formData[key])
+						break
+					case 'isEnOrNo':
+						isError = !form._isEnOrNo(formData[key])
+						break
+					case 'isSpecial':
+						isError = form._isSpecial(formData[key])
+						break
+					case 'isEmoji':
+						isError = form._isEmoji(formData[key])
+						break
+					case 'isDate':
+						isError = !form._isDate(formData[key])
+						break
+					case 'isUrl':
+						isError = !form._isUrl(formData[key])
+						break
+					case 'isSame':
+						isError = !form._isSame(formData[key], formData[value])
+						break
+					case 'range':
+						let range = null
+						try {
+							range = JSON.parse(value)
+							if (range.length <= 1) {
+								throw new Error('range值传入有误!')
+							}
+						} catch (e) {
+							return 'range值传入有误!'
+						}
+						isError = !form._isRange(formData[key], range[0], range[1])
+						break
+					case 'minLength':
+						isError = !form._minLength(formData[key], value)
+						break
+					case 'maxLength':
+						isError = !form._maxLength(formData[key], value)
+						break
+					default:
+						break
+				}
+				if (isError) {
+					return msg
+				}
+			}
+		}
+		return ''
+	},
+	_isNullOrEmpty: function(value) {
+		return !!((value === null || value === '' || value === undefined))
+	},
+	_isMobile: function(value) {
+		return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value)
+	},
+	_isEmail: function(value) {
+		return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value)
+	},
+	_isCarNo: function(value) {
+		// 新能源车牌
+		const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
+		// 旧车牌
+		const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
+		if (value.length === 7) {
+			return creg.test(value)
+		} else if (value.length === 8) {
+			return xreg.test(value)
+		} else {
+			return false
+		}
+	},
+	_isIdCard: function(value) {
+		let idCard = value
+		if (idCard.length == 15) {
+			return this.__isValidityBrithBy15IdCard
+		} else if (idCard.length == 18) {
+			let arrIdCard = idCard.split('')
+			if (this.__isValidityBrithBy18IdCard(idCard) && this.__isTrueValidateCodeBy18IdCard(arrIdCard)) {
+				return true
+			} else {
+				return false
+			}
+		} else {
+			return false
+		}
+	},
+	__isTrueValidateCodeBy18IdCard: function(arrIdCard) {
+		let sum = 0
+		let Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
+		let ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]
+		if (arrIdCard[17].toLowerCase() == 'x') {
+			arrIdCard[17] = 10
+		}
+		for (let i = 0; i < 17; i++) {
+			sum += Wi[i] * arrIdCard[i]
+		}
+		let valCodePosition = sum % 11
+		if (arrIdCard[17] == ValideCode[valCodePosition]) {
+			return true
+		} else {
+			return false
+		}
+	},
+	__isValidityBrithBy18IdCard: function(idCard18) {
+		let year = idCard18.substring(6, 10)
+		let month = idCard18.substring(10, 12)
+		let day = idCard18.substring(12, 14)
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day))
+		if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false
+		} else {
+			return true
+		}
+	},
+	__isValidityBrithBy15IdCard: function(idCard15) {
+		let year = idCard15.substring(6, 8)
+		let month = idCard15.substring(8, 10)
+		let day = idCard15.substring(10, 12)
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day))
+
+		if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false
+		} else {
+			return true
+		}
+	},
+	_isAmount: function(value) {
+		// 金额,只允许保留两位小数
+		return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value)
+	},
+	_isNum: function(value) {
+		// 只能为数字
+		return /^[0-9]+$/.test(value)
+	},
+	_isChinese: function(value) {
+		let reg = /.*[\u4e00-\u9fa5]+.*$/
+		return value !== '' && reg.test(value) && !form._isSpecial(value) && !form._isEmoji(value)
+	},
+	_isEnglish: function(value) {
+		return /^[a-zA-Z]*$/.test(value)
+	},
+	_isEnAndNo: function(value) {
+		// 8~20位数字和字母组合
+		return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(value)
+	},
+	_isEnOrNo: function(value) {
+		// 英文或者数字
+		let reg = /.*[\u4e00-\u9fa5]+.*$/
+		let result = true
+		if (reg.test(value) || form._isSpecial(value) || form._isEmoji(value)) {
+			result = false
+		}
+		return result
+	},
+	_isSpecial: function(value) {
+		// 是否包含特殊字符
+		let regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im,
+			regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im
+		if (regEn.test(value) || regCn.test(value)) {
+			return true
+		}
+		return false
+	},
+	_isEmoji: function(value) {
+		// 是否包含表情
+		return /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g.test(value)
+	},
+	_isDate: function(value) {
+		// 2019-10-12
+		const reg =
+			/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/
+		return reg.test(value)
+	},
+	_isUrl: function(value) {
+		return /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value)
+	},
+	_isSame: function(value1, value2) {
+		return value1 === value2
+	},
+	_isRange: function(value, range1, range2) {
+		if ((!range1 && range1 != 0) && (!range2 && range2 != 0)) {
+			return true
+		} else if (!range1 && range1 != 0) {
+			return value <= range2
+		} else if (!range2 && range2 != 0) {
+			return value >= range1
+		} else {
+			return value >= range1 && value <= range2
+		}
+	},
+	_minLength: function(value, min) {
+		return value.length >= Number(min)
+	},
+	_maxLength: function(value, max) {
+		return value.length <= Number(max)
+	}
+}
+module.exports = {
+	validation: form.validation
+}

+ 8 - 1
mobile-code/src/utils/format.js

@@ -1,4 +1,11 @@
-function formatTime(time) {
+/** *
+ * 全局时间转换
+ * @parmas time 时间戳默认为11位时间戳
+ * @parmas all 为true时time为13位时间戳
+ */
+function formatTime(time, all) {
+	console.log(time)
+	time = all ? time * 1000 : time
 	if (typeof time !== 'number' || time < 0) {
 		return time
 	}

+ 10 - 3
mobile-code/src/utils/util.js

@@ -82,7 +82,7 @@ export const parse = (query, isFrist = false) => {
 
 			return `${result}&${key}=${value}`
 		}, '')
-	return !isFrist ? str : str.replace(/^&/, '?')
+	return isFrist ? str : str.replace(/^&/, '?')
 }
 
 const $checkMobile = (num) => {
@@ -92,7 +92,14 @@ const $checkName = (str) => {
 	return /^[\u4E00-\u9FA5A-Za-z\s]+(·[\u4E00-\u9FA5A-Za-z]+)*$/.test(str)
 }
 
-export const $formatDate = (num, fmt = 'YYYY-MM-DD HH:mm:ss') => {
+/** *
+ * 全局时间转换
+ * @parmas num 时间戳默认为11位时间戳
+ * @parmas fmt 默认转换的时间格式
+ * @parmas all 为true时time为13位时间戳
+ */
+export const $formatDate = (num, fmt = 'YYYY-MM-DD HH:mm', all) => {
+	num = all ? num : num * 1000
 	let date = new Date()
 	date.setTime(num)
 	let o = {
@@ -146,7 +153,7 @@ export const pageTo = (item) => {
 		item.funtion()
 	}
 	if (item.url) {
-		let query = query ? parse(item.query) : ''
+		let query = item.query ? parse(item.query) : ''
 		let allUrl = `${item.url}${query}`
 		if (item.type == 2) {
 			uni.redirectTo({

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно