lalala 6 лет назад
Родитель
Сommit
625da3c517

+ 8 - 0
admin-code/src/assets/css/base.scss

@@ -84,6 +84,10 @@ $backColor: #f5f5f5;
     margin-left: 10px !important;
 }
 
+.app-center {
+    text-align: center;
+}
+
 .flex {
     display: flex;
 }
@@ -139,6 +143,10 @@ $backColor: #f5f5f5;
     justify-content: flex-end;
 }
 
+.flex-wrap {
+    flex-wrap: wrap;
+}
+
 // ===================    定义的全局字体普通样式 ========================
 
 .app-padding {

BIN
admin-code/src/assets/images/interest/introducer.png


BIN
admin-code/src/assets/images/interest/new-member.png


+ 12 - 2
admin-code/src/components/module/operate.vue

@@ -5,6 +5,7 @@
 		placement="bottom-end"
 		width="200"
 		trigger="hover"
+		@show="showFn"
 	>
 		<div class="operate-wrap">
 			<div
@@ -37,9 +38,18 @@ export default {
 		btnData: {
 			type: Array,
 			default: () => []
+		},
+		// 触发后传入的数据
+		item: {
+			type: Object,
+			default: () => []
 		}
 	},
-	methods: {}
+	methods: {
+		showFn() {
+			this.$emit('show', this.item);
+		}
+	}
 };
 </script>
 
@@ -85,7 +95,7 @@ export default {
 }
 .operate-module {
 	.operate-btn {
-		color: #fff;
+		color: #666;
 		font-size: 24px;
 		&:hover {
 			color: $mainColor;

+ 85 - 0
admin-code/src/constant/constant.js

@@ -0,0 +1,85 @@
+// 全局枚举
+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
+		}
+	],
+	// 代理状态
+	PROXY_STATUS: [
+		{
+			label: '审核中',
+			value: 0
+		},
+		{
+			label: '试用中',
+			value: 1
+		},
+		{
+			label: '审核未通过',
+			value: 2
+		},
+		{
+			label: '已付费',
+			value: 3
+		},
+		{
+			label: '已到期',
+			value: 4
+		}
+	],
+	// 订单状态
+	ORDER_STATUS: [
+		{
+			label: '待付款',
+			value: 0
+		},
+		{
+			label: '待配送',
+			value: 1
+		},
+		{
+			label: '配送中',
+			value: 2
+		},
+		{
+			label: '待通知',
+			value: 3
+		},
+		{
+			label: '已取消',
+			value: 4
+		},
+		{
+			label: '已完成',
+			value: 4
+		}
+	]
+}
+
+export const _filter_const_map = _CONST_MAP

+ 81 - 0
admin-code/src/constant/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
+	}
+}

+ 3 - 3
admin-code/src/cool/components/upload/index.vue

@@ -139,16 +139,16 @@ export default {
 
 				if (multiple) {
 					if (item.url) {
-						item.url = data;
+						item.url = data.url;
 					} else {
 						this.list.push({
-							url: data
+							url: data.url
 						});
 					}
 				} else {
 					this.list = [
 						{
-							url: data
+							url: data.url
 						}
 					];
 				}

+ 9 - 0
admin-code/src/filter/index.js

@@ -1,4 +1,6 @@
 import Vue from 'vue';
+import { $formatDate } from '@/utils/util';
+let FormatTimeFilter = $formatDate;
 
 Vue.filter('default_avatar', function(url) {
 	if (!url) {
@@ -15,3 +17,10 @@ Vue.filter('default_name', function(name) {
 
 	return name;
 });
+
+// 时间
+Vue.filter('formatTime', FormatTimeFilter);
+
+/** 一个全局变量的过滤器 value 转label */
+import { constFilter } from '@/constant/constantFilter';
+Vue.filter('constantfilter', constFilter);

+ 13 - 3
admin-code/src/main.js

@@ -24,11 +24,21 @@ Vue.use(ElementUI);
 
 Vue.use(crud, {
 	crud: {
-		dict: {},
+		dict: {
+			// 搜索
+			search: {
+				keyWord: 'search' // 模糊查询的关键字
+			}
+		},
+		search: {
+			key: {
+				placeholder: '昵称 / 手机号'
+			}
+		},
 		fn: {
 			permission(that) {
-				const { permission } = that.$store.state.menu;
-				const { add, delete: del, update } = that.service.permission;
+				// const { permission } = that.$store.state.menu;
+				// const { add, delete: del, update } = that.service.permission;
 
 				that.permission = {
 					// add: permission.includes(add),

+ 18 - 22
admin-code/src/mixins/list.js

@@ -1,15 +1,15 @@
 export default {
 	watch: {
-		// 'list.loading'(val) {
-		// 	if (val) {
-		// 		uni.showLoading({
-		// 			title: '加载中...',
-		// 			mask: true
-		// 		});
-		// 	} else {
-		// 		uni.hideLoading();
-		// 	}
-		// }
+		'list.loading'(val) {
+			if (val) {
+				// uni.showLoading({
+				// 	title: '加载中...',
+				// 	mask: true
+				// });
+			} else {
+				// uni.hideLoading();
+			}
+		}
 	},
 	computed: {
 		totalPages() {
@@ -36,7 +36,7 @@ export default {
 			this.list = {
 				data: [],
 				page: 1,
-				limit: 10,
+				pageSize: 10,
 				loading: true,
 				finished: false,
 				total: null
@@ -44,19 +44,15 @@ export default {
 		},
 		completes(res, listKey) {
 			this.list.loading = false;
-			if (res.code !== 1) {
-				this.list.finished = true;
-			}
+			// if (res.code !== 1) {
+			// 	this.list.finished = true;
+			// }
 			this.list.data =
 				this.list.page === 1
-					? res.data.list || res.data.data || res.data[listKey]
-					: this.list.data.concat(res.data.list || res.data.data || res.data[listKey]);
-			this.list.total = res.data.total;
-			if (
-				this.totalPages <= this.list.page ||
-				(!this.$util.isEmpty(res.data.current_page) &&
-					res.data.current_page == res.data.last_page)
-			) {
+					? res.list || res.data || res[listKey]
+					: this.list.data.concat(res.list || res.data || res[listKey]);
+			this.list.total = res.totalPage * this.list.pageSize;
+			if (res.moreData == 0) {
 				this.list.finished = true;
 			} else {
 				++this.list.page;

+ 32 - 43
admin-code/src/mock/userInfo.js

@@ -187,7 +187,7 @@ let menu = {
 			id: '2',
 			parentId: null,
 			name: '客户管理',
-			type: 0,
+			type: 1,
 			icon: 'iconkehuguanli',
 			orderNum: 2,
 			router: '/member/list',
@@ -199,7 +199,7 @@ let menu = {
 			id: '3',
 			parentId: null,
 			name: '订单管理',
-			type: 0,
+			type: 1,
 			icon: 'iconkehuguanli',
 			orderNum: 2,
 			router: '/order/list',
@@ -303,8 +303,30 @@ let menu = {
 			type: 0,
 			icon: 'iconkehuguanli',
 			orderNum: 2,
-			router: '/goods/list',
-			viewPath: 'views/goods/goods-list.vue',
+			router: '/invite/list',
+			viewPath: 'views/invite/list.vue',
+			keepAlive: 1
+		},
+		{
+			id: '501',
+			parentId: '5',
+			name: '邀请有礼',
+			type: 1,
+			icon: 'iconkehuguanli',
+			orderNum: 2,
+			router: '/invite/list',
+			viewPath: 'views/invite/list.vue',
+			keepAlive: 1
+		},
+		{
+			id: '502',
+			parentId: '5',
+			name: '奖励设置',
+			type: 1,
+			icon: 'iconkehuguanli',
+			orderNum: 2,
+			router: '/invite/reward-set',
+			viewPath: 'views/invite/reward-set.vue',
 			keepAlive: 1
 		},
 		// 优惠券
@@ -312,11 +334,11 @@ let menu = {
 			id: '6',
 			parentId: null,
 			name: '优惠券',
-			type: 0,
+			type: 1,
 			icon: 'iconkehuguanli',
 			orderNum: 2,
-			router: '/goods/list',
-			viewPath: 'views/goods/goods-list.vue',
+			router: '/coupon/list',
+			viewPath: 'views/coupon/list.vue',
 			keepAlive: 1
 		},
 		// 促销
@@ -336,11 +358,11 @@ let menu = {
 			id: '8',
 			parentId: null,
 			name: '广告管理',
-			type: 0,
+			type: 1,
 			icon: 'iconkehuguanli',
 			orderNum: 2,
-			router: '/goods/list',
-			viewPath: 'views/goods/goods-list.vue',
+			router: '/ad/list',
+			viewPath: 'views/ad/list.vue',
 			keepAlive: 1
 		},
 		// 员工管理
@@ -379,39 +401,6 @@ let menu = {
 			viewPath: null,
 			keepAlive: 0
 		},
-		{
-			id: '203',
-			parentId: '27',
-			name: '商品列表',
-			type: 1,
-			icon: 'icon-user',
-			orderNum: 1,
-			router: '/goods/list',
-			viewPath: 'views/goods/goods-list.vue',
-			keepAlive: 1
-		},
-		{
-			id: '200',
-			parentId: '27',
-			name: '订单列表',
-			type: 1,
-			icon: 'icon-user',
-			orderNum: 1,
-			router: '/goods/list',
-			viewPath: 'views/goods/list.vue',
-			keepAlive: 1
-		},
-		{
-			id: '201',
-			parentId: '27',
-			name: '客户列表',
-			type: 1,
-			icon: 'icon-user',
-			orderNum: 1,
-			router: '/member/list',
-			viewPath: 'views/member/list.vue',
-			keepAlive: 1
-		},
 		{
 			id: '17',
 			parentId: '27',

+ 1 - 0
admin-code/src/pages/layout/slider/index.vue

@@ -64,6 +64,7 @@ export default {
 			}
 		},
 		pageSubTo(item, index) {
+			console.log(item);
 			this.subIndex = index;
 			this.$router.push(item.path);
 		}

+ 20 - 0
admin-code/src/service/ad/index.js

@@ -0,0 +1,20 @@
+import { BaseService, Service } from '@/cool/index';
+
+@Service('ad')
+export class AdService extends BaseService {
+	updateStatus(data) {
+		return this.request({
+			url: '/update-status',
+			params: data
+		});
+	}
+
+	sort(data) {
+		return this.request({
+			url: '/sort',
+			params: data
+		});
+	}
+}
+
+export default new AdService();

+ 13 - 1
admin-code/src/service/common/index.js

@@ -10,7 +10,7 @@ export class CommonService extends BaseService {
 	 */
 	upload() {
 		return {
-			url: baseUrl + '/comm/upload'
+			url: baseUrl + '/upload/save-img'
 		};
 	}
 
@@ -100,6 +100,18 @@ export class CommonService extends BaseService {
 			}
 		});
 	}
+
+	/**
+	 * 用户信息
+	 *
+	 * @returns
+	 * @memberof CommonService
+	 */
+	fest() {
+		return this.request({
+			url: '/fest/list'
+		});
+	}
 }
 
 export default new CommonService();

+ 26 - 0
admin-code/src/service/coupon/index.js

@@ -0,0 +1,26 @@
+import { BaseService, Service } from '@/cool/index';
+
+export class CouponService extends BaseService {
+	page(data) {
+		return this.request({
+			url: '/coupon/list',
+			params: data
+		});
+	}
+
+	assetDet() {
+		return this.request({
+			url: '/coupon-asset/detail'
+		});
+	}
+
+	assetUpdate(data) {
+		return this.request({
+			url: '/coupon-asset/update',
+			method: 'POST',
+			data: data
+		});
+	}
+}
+
+export default new CouponService();

+ 30 - 0
admin-code/src/service/img-store/index.js

@@ -0,0 +1,30 @@
+import { BaseService, Service } from '@/cool/index';
+
+@Service('pic')
+export class GoodsService extends BaseService {
+	changeStatus(data) {
+		return this.request({
+			url: '/change-status',
+			method: 'POST',
+			data: data
+		});
+	}
+
+	remark(data) {
+		return this.request({
+			url: '/remark',
+			method: 'POST',
+			data: data
+		});
+	}
+
+	top(data) {
+		return this.request({
+			url: '/top',
+			method: 'POST',
+			data: data
+		});
+	}
+}
+
+export default new GoodsService();

+ 9 - 1
admin-code/src/service/index.js

@@ -7,6 +7,10 @@ import member from './member/index';
 import goods from './goods/index';
 import level from './level/index';
 import category from './category/index';
+import imgStore from './img-store/index';
+import invite from './invite/index';
+import coupon from './coupon/index';
+import ad from './ad/index';
 
 Vue.prototype.$service = {
 	common,
@@ -16,7 +20,11 @@ Vue.prototype.$service = {
 	member,
 	goods,
 	level,
-	category
+	category,
+	imgStore,
+	invite,
+	coupon,
+	ad
 };
 
 export default Vue.prototype.$service;

+ 55 - 0
admin-code/src/service/invite/index.js

@@ -0,0 +1,55 @@
+import { BaseService, Service } from '@/cool/index';
+
+export class InviteService extends BaseService {
+	/**
+	 * 列表 b
+	 */
+	page(data) {
+		return this.request({
+			url: '/invite/list',
+			params: data
+		});
+	}
+
+	/**
+	 * 明细 b
+	 */
+	info(data) {
+		return this.request({
+			url: '/invite/list',
+			params: data
+		});
+	}
+
+	/**
+	 * 兑奖 b
+	 */
+	give(data) {
+		return this.request({
+			url: '/invite/give',
+			params: data
+		});
+	}
+
+	/**
+	 * 奖励设置详情 b
+	 */
+	assetDetail() {
+		return this.request({
+			url: '/invite-asset/detail'
+		});
+	}
+
+	/**
+	 * 奖励设置详情 b
+	 */
+	assetUpdate(data) {
+		return this.request({
+			url: '/invite-asset/update',
+			method: 'POST',
+			data: data
+		});
+	}
+}
+
+export default new InviteService();

+ 2 - 1
admin-code/src/store/getters.js

@@ -9,6 +9,7 @@ const getters = {
 	permission: state => state.menu.permission,
 	// config
 	level: state => state.config.level,
-	category: state => state.config.category
+	category: state => state.config.category,
+	festival: state => state.config.festival
 };
 export default getters;

+ 26 - 2
admin-code/src/store/modules/config.js

@@ -4,9 +4,11 @@ import service from '@/service/index';
 export default {
 	state: {
 		level: store.get('level') || {},
-		category: store.get('category') || {}
+		category: store.get('category') || [],
+		festival: store.get('festival') || []
 	},
 	actions: {
+		// 等级
 		getLevel({ commit }) {
 			return service.level.level().then(res => {
 				commit('SET_LEVEL', res);
@@ -17,6 +19,7 @@ export default {
 			commit('DEL_LEVEL');
 		},
 
+		// 分类
 		getCategory({ commit }) {
 			return service.category.list().then(res => {
 				commit('SET_CATEGORY', res);
@@ -25,6 +28,17 @@ export default {
 		},
 		delCategory({ commit }) {
 			commit('DEL_CATEGORY');
+		},
+
+		// 节日
+		getFestival({ commit }) {
+			return service.common.fest().then(res => {
+				commit('SET_FESTIVAL', res);
+				return res;
+			});
+		},
+		delFestival({ commit }) {
+			commit('DEL_FESTIVAL');
 		}
 	},
 	mutations: {
@@ -43,8 +57,18 @@ export default {
 		},
 
 		DEL_CATEGORY(state) {
-			state.info = {};
+			state.info = [];
 			store.remove('category');
+		},
+
+		SET_FESTIVAL(state, val) {
+			state.info = val;
+			store.set('festival', val);
+		},
+
+		DEL_FESTIVAL(state) {
+			state.info = [];
+			store.remove('festival');
 		}
 	}
 };

+ 270 - 0
admin-code/src/views/ad/list.vue

@@ -0,0 +1,270 @@
+<template>
+	<div class="app-list-content">
+		<cl-crud class="liu-crud-wrap" @load="onLoad">
+			<template #slot-tabs="{ scope }">
+				<el-tabs
+					class="liu-tabs"
+					type="border-card"
+					v-model="tabIndex"
+					@tab-click="handleClick"
+				>
+					<el-tab-pane
+						v-for="(item, index) in tabsData"
+						:key="index"
+						:label="item.text"
+						:name="item.key"
+					></el-tab-pane>
+				</el-tabs>
+			</template>
+
+			<template #table-column-adImgUrl="{scope}">
+				<div>
+					<cl-avatar
+						shape="square"
+						:size="40"
+						:src="scope.row.adImgUrl | default_avatar"
+						:style="{ margin: 'auto' }"
+					></cl-avatar>
+				</div>
+			</template>
+
+			<template #table-column-endTime="{scope}">
+				<div v-if="scope.row.endTime == '4102416000'">永久有效</div>
+				<div v-else-if="scope.row.endTime">{{ scope.row.endTime | formatTime }}</div>
+				<div v-else>-</div>
+			</template>
+
+			<template #table-column-status="{scope}"
+				><el-switch
+					v-model="scope.row.status"
+					active-value="1"
+					inactive-value="0"
+					@change="changeStatus(scope.row)"
+				></el-switch>
+			</template>
+
+			<!-- 添加 -->
+			<template #slot-add-ad-btn="{scope}">
+				<el-button type="primary" size="mini" @click="changeStatus">添加</el-button>
+			</template>
+		</cl-crud>
+		<!-- 新增弹窗 -->
+		<el-dialog
+			:title="`添加广告图`"
+			:visible.sync="addDialog"
+			:close-on-click-modal="false"
+			width="600px"
+		>
+			<div class="ad-modal-content">
+				<el-form
+					:model="adForm"
+					:rules="adForm"
+					ref="adForm"
+					label-width="100px"
+					class="demo-form"
+				>
+					<el-form-item label="广告图名称" prop="delivery">
+						<el-input
+							v-model="adForm.adName"
+							placeholder="请输入名称"
+							size="small"
+						></el-input>
+					</el-form-item>
+					<el-form-item label="请选择时间" prop="delivery">
+						<el-col :span="11">
+							<el-date-picker
+								type="date"
+								placeholder="选择日期"
+								v-model="adForm.startTime"
+								value-format="yyyy-MM-dd"
+								style="width: 100%;"
+							></el-date-picker>
+						</el-col>
+						<el-col class="app-center" :span="2">-</el-col>
+						<el-col :span="11">
+							<el-date-picker
+								type="date"
+								placeholder="选择日期"
+								v-model="adForm.endTime"
+								value-format="yyyy-MM-dd"
+								style="width: 100%;"
+							></el-date-picker>
+						</el-col>
+					</el-form-item>
+					<el-form-item label="广告图片" prop="adImg">
+						<cl-upload v-model="adForm.adImg"></cl-upload>
+					</el-form-item>
+					<el-form-item label="马上启用" prop="status">
+						<el-switch
+							v-model="adForm.status"
+							active-value="1"
+							inactive-value="0"
+						></el-switch>
+					</el-form-item>
+					<el-form-item label="链接方式" prop="type">
+						<el-radio-group v-model="adForm.style">
+							<el-radio label="0">自定义链接</el-radio>
+							<el-radio label="1">链接商品</el-radio>
+						</el-radio-group>
+						<template v-if="adForm.style == 0">
+							<div>
+								<el-input
+									v-model="appendForm.url"
+									placeholder="请填写链接,留空点图片不跳转"
+									size="small"
+								></el-input>
+							</div>
+						</template>
+						<template v-else>
+							<div>
+								<el-button type="primary" size="small" @click="selGoods"
+									>选择商品</el-button
+								>
+							</div>
+						</template>
+					</el-form-item>
+				</el-form>
+			</div>
+			<div slot="footer" class="dialog-footer">
+				<el-button size="small" @click="resetForm">取 消</el-button>
+				<el-button type="primary" size="small" @click="addFn">确认</el-button>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			app: null,
+			tabIndex: '1',
+			tabsData: [
+				{
+					text: '门店轮播图',
+					key: '1'
+				},
+				{
+					text: '商城首页轮播图',
+					key: '0'
+				}
+			],
+			// 新增弹窗
+			addDialog: true,
+			adForm: {
+				adName: '',
+				adImg: '',
+				status: 1,
+				inTurn: 0,
+				type: '1',
+				style: '0',
+				startTime: '',
+				endTime: ''
+			},
+			appendForm: {
+				url: '',
+				goodsId: ''
+			}
+		};
+	},
+	methods: {
+		handleClick(tab, e) {
+			this.app.refresh({ type: this.tabIndex });
+		},
+		changeStatus(item) {
+			this.$service.ad.updateStatus({ id: item.id, status: item.status }).then(res => {
+				this.$message.success('操作成功!');
+			});
+		},
+		resetForm() {
+			this.$refs['adForm'].resetFields();
+			this.addDialog = false;
+		},
+		addFn() {
+			let form = JSON.parse(JSON.stringify(this.adForm));
+			form.type = this.tabIndex;
+			if (form.style == '0') {
+				form.url = this.appendForm.url;
+			} else {
+				form.goodsId = this.appendForm.goodsId;
+			}
+			this.$service.ad.add(form).then(res => {
+				this.$message.success('操作成功!');
+				this.resetForm();
+				this.app.refresh({ type: this.tabIndex });
+			});
+		},
+		selGoods() {},
+		// cl-crud 组件ad
+		onLoad({ ctx, app }) {
+			this.app = app;
+			ctx.service(this.$service.ad)
+				.set('table', {
+					columns: [
+						{
+							prop: 'id',
+							label: 'id',
+							align: 'center',
+							'min-width': 100
+						},
+						{
+							prop: 'adName',
+							label: '广告名称',
+							align: 'center'
+						},
+						{
+							prop: 'adImgUrl',
+							label: '广告图片',
+							align: 'center'
+						},
+						{
+							prop: 'endTime',
+							label: '到期时间',
+							align: 'center'
+						},
+						{
+							prop: 'status',
+							label: '启用状态',
+							align: 'center'
+						},
+						{
+							prop: 'viewTimes',
+							label: '点击次数',
+							align: 'center'
+						},
+						{
+							prop: 'inTurn',
+							label: '排序',
+							align: 'center'
+						}
+					],
+					// 操作列
+					op: {
+						visible: true, // 是否显示
+						// 同 element-ui Table-column Attributes
+						props: {
+							width: 100,
+							align: 'center',
+							fixed: 'right',
+							label: '操作'
+						},
+						// 布局,请移步 `layout`
+						layout: ['slot-column-redeem']
+					}
+				})
+				.set('layout', [
+					['slot-tabs'],
+					['flex1', 'refresh-btn', 'slot-add-ad-btn'],
+					['data-table'],
+					['flex1', 'pagination']
+				])
+				.done();
+			app.refresh({ type: this.tabIndex });
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+// module
+</style>

+ 162 - 0
admin-code/src/views/coupon/list.vue

@@ -0,0 +1,162 @@
+<template>
+	<div class="app-list-content">
+		<cl-crud class="liu-crud-wrap" @load="onLoad">
+			<template #slot-tabs="{ scope }">
+				<el-tabs
+					class="liu-tabs"
+					type="border-card"
+					v-model="tabIndex"
+					@tab-click="handleClick"
+				>
+					<el-tab-pane
+						v-for="(item, index) in tabsData"
+						:key="index"
+						:label="`${item.text}(${item.val})`"
+						:name="item.key"
+					></el-tab-pane>
+				</el-tabs>
+			</template>
+
+			<template #table-column-addTime="{scope}">
+				<span>{{ scope.row.addTime | formatTime }}</span>
+			</template>
+
+			<template #table-column-deadline="{scope}">
+				<span>{{ scope.row.deadline | formatTime }}</span>
+			</template>
+
+			<template #table-column-status="{scope}">
+				<span v-if="scope.row.status == 1">
+					<i class="iconfont icondagou"></i>
+				</span>
+				<span v-else>{{ scope.row.status | constantfilter('COUPON_STATUS') }}</span>
+			</template>
+		</cl-crud>
+	</div>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			// cl-crud
+			app: null,
+			tabIndex: '-1',
+			tabsData: [
+				{
+					text: '全部',
+					key: '-1',
+					val: 0
+				},
+				{
+					text: '待使用',
+					key: '0',
+					val: 0
+				},
+				{
+					text: '已使用',
+					key: '1',
+					val: 0
+				},
+				{
+					text: '已失效',
+					key: '2',
+					val: 0
+				}
+			]
+		};
+	},
+	mounted() {},
+	methods: {
+		handleClick() {
+			this.app.refresh({ status: this.tabIndex });
+		},
+		// crud
+		onLoad({ ctx, app }) {
+			this.app = app;
+			ctx.service(this.$service.coupon)
+				.set('table', {
+					columns: [
+						{
+							prop: 'userId',
+							label: 'ID',
+							align: 'center'
+						},
+						{
+							prop: 'userName',
+							label: '持有人',
+							align: 'center'
+						},
+						{
+							prop: 'mobile',
+							label: '手机号',
+							align: 'center'
+						},
+						{
+							prop: 'amount',
+							label: '金额',
+							align: 'center'
+						},
+						{
+							prop: 'miniCost',
+							label: '最低消费',
+							align: 'center',
+							emptyText: '无'
+						},
+						{
+							prop: 'addTime',
+							label: '领取时间',
+							align: 'center',
+							width: 150
+						},
+						{
+							prop: 'deadline',
+							label: '到期时间',
+							align: 'center',
+							width: 150
+						},
+						{
+							prop: 'source',
+							label: '来源',
+							align: 'center'
+						},
+						{
+							prop: 'status',
+							label: '状态',
+							align: 'center'
+						}
+					],
+					// 操作列
+					op: {
+						visible: false, // 是否显示
+						// 同 element-ui Table-column Attributes
+						props: {
+							width: 150,
+							align: 'center',
+							fixed: 'right',
+							label: '操作'
+						},
+						// 布局,请移步 `layout`
+						layout: ['slot-recharge', 'slot-upgrade', 'slot-ship']
+					}
+				})
+				.set('layout', [
+					['slot-tabs'],
+					['flex1', 'refresh-btn'],
+					['data-table'],
+					['flex1', 'pagination']
+				])
+				.on('refresh', async (params, { next }) => {
+					// 继续执行刷新
+					let { asset } = await next(params);
+					this.tabsData[0].val = asset.totalNum;
+					this.tabsData[1].val = asset.unUseNum;
+					this.tabsData[2].val = asset.useNum;
+					this.tabsData[3].val = asset.invalidNum;
+				})
+				.done();
+			app.refresh({ status: this.tabIndex });
+		}
+	}
+};
+</script>

+ 45 - 7
admin-code/src/views/goods/goods-list.vue

@@ -2,10 +2,19 @@
 	<div class="app-list-content">
 		<cl-crud class="liu-crud-wrap" @load="onLoad">
 			<template #slot-tabs="{ scope }">
-				<el-tabs class="liu-tabs" type="border-card">
-					<el-tab-pane label="全部"></el-tab-pane>
-					<el-tab-pane label="上架"></el-tab-pane>
-					<el-tab-pane label="下架"></el-tab-pane>
+				<el-tabs
+					class="liu-tabs"
+					type="border-card"
+					v-model="tabIndex"
+					@tab-click="handleClick"
+				>
+					<el-tab-pane
+						v-for="(item, index) in tabsData"
+						:key="index"
+						:label="item.text"
+						:name="item.key"
+					>
+					</el-tab-pane>
 				</el-tabs>
 			</template>
 
@@ -18,7 +27,7 @@
 			<template #table-column-goodsName="{scope}">
 				<span>{{ scope.row.goodsName }}</span>
 				<!-- <span>二维码</span> -->
-				<span @click="openLinkFn(scope.row.shortUrl)">链接</span>
+				<span class="short-link" @click="openLinkFn(scope.row.shortUrl)">链接</span>
 			</template>
 
 			<!-- 添加商品 -->
@@ -58,11 +67,31 @@
 export default {
 	data() {
 		return {
+			app: null,
 			dialogFormVisible: false,
-			sortLink: ''
+			sortLink: '',
+			tabIndex: '-1',
+			tabsData: [
+				{
+					text: '全部',
+					key: '-1'
+				},
+				{
+					text: '上架',
+					key: '1'
+				},
+				{
+					text: '下架',
+					key: '0'
+				}
+			]
 		};
 	},
 	methods: {
+		handleClick(tab, e) {
+			console.log(tab, e);
+			this.app.refresh({ type: this.tabIndex });
+		},
 		// 打开链接
 		openLinkFn(link) {
 			this.sortLink = link || '';
@@ -98,6 +127,7 @@ export default {
 		},
 		// cl-crud 组件
 		onLoad({ ctx, app }) {
+			this.app = app;
 			ctx.service(this.$service.goods)
 				.set('table', {
 					columns: [
@@ -170,8 +200,16 @@ export default {
 					['flex1', 'pagination']
 				])
 				.done();
-			app.refresh({ status: 0 });
+			app.refresh({ status: this.tabIndex });
 		}
 	}
 };
 </script>
+
+<style lang="scss" scoped>
+.short-link {
+	color: $mainColor;
+	margin-left: 10px;
+	cursor: pointer;
+}
+</style>

+ 133 - 54
admin-code/src/views/goods/img-store.vue

@@ -3,73 +3,94 @@
 		<!-- operate -->
 		<div class="flex-center-between">
 			<div class="operate-left flex-center">
-				<el-select v-model="form.region" placeholder="选择分类" size="mini">
-					<el-option label="花束" value="shanghai"></el-option>
-					<el-option label="区域二" value="beijing"></el-option>
+				<el-select
+					v-model="form.categoryId"
+					placeholder="选择分类"
+					size="mini"
+					:clearable="true"
+					@change="selChangeFn"
+				>
+					<el-option
+						v-for="(item, index) in categoryData"
+						:key="index"
+						:label="item.categoryName"
+						:value="item.id"
+					></el-option>
 				</el-select>
-				<el-button type="primary" @click="onSubmit" size="mini" class="app-margin-left-10"
+				<el-button
+					type="primary"
+					@click="selSubmitFn"
+					size="mini"
+					class="app-margin-left-10"
 					>查询</el-button
 				>
 			</div>
 			<div class="operate-right">
-				<el-button @click="onSubmit" size="mini">查看分类</el-button>
-				<el-button type="primary" @click="onSubmit" size="mini">新增</el-button>
+				<el-button size="mini" @click="$router.push('/goods/category')">查看分类</el-button>
+				<el-button type="primary" @click="addImgFn" size="mini">新增</el-button>
 			</div>
 		</div>
 		<!-- list -->
 		<div class="list-wrap">
-			<div class="list" v-for="(item, index) in 10" :key="index">
+			<div class="list" v-for="(item, index) in list.data" :key="index">
 				<div class="list-img">
-					<img src="https://pic.qqtn.com/up/2019-11/2019110209212070747.jpg" alt="" />
+					<img :src="item.imgUrl" alt="商品图片" />
 				</div>
 				<div class="flex-center-between">
-					<div>天使美人</div>
-					<div class="app-price">¥389.50</div>
+					<div>{{ item.name }}</div>
+					<div class="app-price">¥{{ item.price }}</div>
 				</div>
 				<!--  -->
 				<div class="operate-btn-wrap">
-					<operate-module :btnData="btnData" />
+					<operate-module :btnData="btnData" :item="item" @show="operateChangeFn" />
 				</div>
 			</div>
 		</div>
 		<!-- module -->
-		<el-dialog title="图片上传成功!" :visible.sync="addImageModal" width="600px">
+		<el-dialog
+			title="图片上传成功!"
+			:visible.sync="addImageModal"
+			width="600px"
+			:close-on-click-modal="false"
+		>
 			<div class="add-image-modal-content">
 				<el-form :model="addForm" :rules="rules" ref="addForm" label-width="120px">
 					<el-form-item label="选择分类(可多选)">
-						<el-checkbox
-							v-model="addForm.status"
-							label="花束/花盒"
-							border
-							v-for="(item, index) in 4"
-							:key="index"
-							size="small"
-						></el-checkbox>
+						<el-checkbox-group v-model="addForm.categoryIdList" size="small">
+							<el-checkbox
+								border
+								v-for="(item, index) in categoryData"
+								:label="item.id"
+								:key="index"
+								size="small"
+								@change="selChangeDialogFn($event, item)"
+								>{{ item.categoryName }}</el-checkbox
+							>
+						</el-checkbox-group>
 					</el-form-item>
 					<el-form-item label="售价">
 						<el-input
-							v-model="addForm.styleName"
+							v-model="addForm.price"
 							placeholder="填价格,图片可当商品卖(选填)"
 						>
-							<i slot="suffix" class="iconfont iconqian"></i
-						></el-input>
+							<i slot="suffix" class="iconfont iconqian"></i>
+						</el-input>
 					</el-form-item>
 					<el-form-item label="名称">
-						<el-input v-model="addForm.price" placeholder="选填"></el-input>
+						<el-input v-model="addForm.name" placeholder="选填"></el-input>
 					</el-form-item>
 				</el-form>
 			</div>
 			<div slot="footer" class="dialog-footer">
-				<el-button size="small" @click="addImageModal = false">取 消</el-button>
-				<el-button type="primary" size="small" @click="addImageModal = false"
-					>确 定</el-button
-				>
+				<el-button size="small" @click="resetForm">取 消</el-button>
+				<el-button type="primary" size="small" @click="addOrModifyFn">确 定</el-button>
 			</div>
 		</el-dialog>
 	</div>
 </template>
 
 <script>
+import { mapGetters } from 'vuex';
 import operateModule from '@/components/module/operate';
 import { list } from '@/mixins';
 export default {
@@ -81,31 +102,26 @@ export default {
 	data() {
 		return {
 			form: {
-				user: '',
-				region: ''
+				categoryId: ''
 			},
+			// operate
+			operateData: {},
 			btnData: [
 				{
 					text: '编辑',
 					icon: 'iconbianji',
 					click: () => {
-						this.$util.pageTo({
-							url: '/pages/ad/add',
-							query: {
-								type: this.tabIndex,
-								id: this.operateData.id
-							}
-						});
+						this.addForm.picIdList = [this.operateData.id];
+						this.addImageModal = true;
 					}
 				},
 				{
-					text: '下架',
+					text: '置顶',
 					icon: 'iconxiajia',
 					click: () => {
-						off({ id: this.operateData.id }).then(res => {
-							this.operateCloseFn();
-							this.list.data[this.operateData.index].status = 0;
-							this.$msg('下架成功!');
+						this.$service.imgStore.top({ id: this.operateData.id }).then(res => {
+							this.resetList();
+							this._list();
 						});
 					}
 				},
@@ -113,26 +129,88 @@ export default {
 					text: '删除',
 					icon: 'iconshanchu1',
 					click: () => {
-						this.delModal = true;
+						this.$confirm('是否删除该图库?', '提示', {
+							confirmButtonText: '确定',
+							cancelButtonText: '取消',
+							type: 'warning'
+						})
+							.then(() => {
+								this.$service.imgStore
+									.delete({ id: this.operateData.id })
+									.then(res => {
+										this.resetList();
+										this._list();
+										this.$message({
+											type: 'success',
+											message: '删除成功!'
+										});
+									});
+							})
+							.catch(() => {});
 					}
 				}
 			],
 			// 图片上传成功
-			addImageModal: true,
+			addImageModal: false,
 			addForm: {
-				status: false
+				picIdList: [],
+				price: 0,
+				name: '',
+				categoryIdList: []
 			},
 			rules: {}
 		};
 	},
+	computed: {
+		...mapGetters({ categoryData: 'category' }),
+		...mapGetters({ festData: 'getFestival' })
+	},
+	created() {
+		this._list();
+	},
+	mounted() {},
 	methods: {
-		_getList() {
-			return list().then(res => {
-				this.completes(res);
-			});
+		_list() {
+			return this.$service.imgStore
+				.list({
+					page: this.list.page,
+					...this.form
+				})
+				.then(res => {
+					this.completes(res);
+				});
+		},
+		selChangeFn(e) {
+			this.form.categoryId = e;
 		},
-		onSubmit() {
+		selSubmitFn() {
+			this.resetList();
+			this._list();
+		},
+		// 新增图片
+		addImgFn() {
+			this.addImageModal = true;
+		},
+		selChangeDialogFn(status, item) {
+			console.log(status, item);
+		},
+		// type == 1 新增,type == 2 修改
+		addOrModifyFn(type) {
+			this.$service.imgStore.remark(this.addForm).then(res => {
+				this.$message.success('操作成功!');
+				this.resetForm();
+				this.resetList();
+				this._list();
+			});
 			console.log('submit!');
+		},
+		resetForm() {
+			this.$refs['addForm'].resetFields();
+			this.addImageModal = false;
+		},
+		// operate
+		operateChangeFn(item) {
+			this.operateData = item;
 		}
 	}
 };
@@ -147,9 +225,10 @@ export default {
 		position: relative;
 		margin-right: 20px;
 		margin-bottom: 20px;
-		box-shadow: 2px 2px 3px 0 #f5f5f5;
+		box-shadow: 0 0 10px #eee;
 		.list-img {
 			width: 200px;
+			height: 200px;
 			margin-bottom: 6px;
 		}
 		.flex-center-between {
@@ -168,9 +247,9 @@ export default {
 	.el-checkbox.is-bordered.el-checkbox--small {
 		margin-left: 0;
 		margin-right: 10px;
-		&:nth-child(4n + 4) {
-			margin-right: 0;
-		}
+		// &:nth-child(4n + 4) {
+		// 	margin-right: 0;
+		// }
 	}
 }
 </style>

+ 277 - 0
admin-code/src/views/invite/list.vue

@@ -0,0 +1,277 @@
+<template>
+	<div class="app-list-content">
+		<cl-crud class="liu-crud-wrap" @load="onLoad">
+			<template #slot-tabs="{ scope }">
+				<el-tabs
+					class="liu-tabs"
+					type="border-card"
+					v-model="tabIndex"
+					@tab-click="handleClick"
+				>
+					<el-tab-pane
+						v-for="(item, index) in tabsData"
+						:key="index"
+						:label="item.text"
+						:name="item.key"
+					></el-tab-pane>
+				</el-tabs>
+			</template>
+
+			<template #table-column-avatarUrl="{scope}">
+				<div class="flex-center">
+					<cl-avatar
+						shape="square"
+						:size="40"
+						:src="scope.row.userAvatar | default_avatar"
+						:style="{ margin: 'auto' }"
+					></cl-avatar>
+					<div>{{ scope.row.userName }}</div>
+				</div>
+			</template>
+
+			<template #table-column-addTime="{scope}">
+				<div>{{ scope.row.addTime | formatTime }}</div>
+			</template>
+
+			<template #table-column-status="{scope}">
+				<div>{{ scope.row.status | constantfilter('INVITE_STATUS') }}</div>
+			</template>
+
+			<template #table-column-orderTime="{scope}">
+				<div v-if="scope.row.status == 1">{{ item.orderTime | formatTime }}</div>
+				<div v-else-if="scope.row.status == 1">{{ item.giveTime | formatTime }}</div>
+				<div v-else>-</div>
+			</template>
+
+			<!-- 兑奖 -->
+			<template #slot-column-redeem="{scope}">
+				<el-button v-if="scope.row.status == 1" type="text" @click="redeemFn(scope.row)"
+					>兑奖</el-button
+				>
+				<div v-else>-</div>
+			</template>
+		</cl-crud>
+		<!-- 添加商品 -->
+		<el-dialog title="兑奖" :visible.sync="redeemVisible" width="40%">
+			<template>
+				<div class="redeem-wrap">
+					<div class="redeem-list-wrap">
+						<!-- 新用户 -->
+						<div class="list">
+							<div class="list-tag">
+								<img src="../../assets/images/interest/new-member.png" alt />
+							</div>
+							<div class="list-left">
+								<cl-avatar
+									shape="square"
+									:size="80"
+									:src="redeemData.introUserAvatar | default_avatar"
+									:style="{ margin: 'auto' }"
+								></cl-avatar>
+							</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="../../assets/images/interest/introducer.png" alt />
+							</div>
+							<div class="list-left">
+								<cl-avatar
+									shape="square"
+									:size="80"
+									:src="redeemData.introUserAvatar | default_avatar"
+									:style="{ margin: 'auto' }"
+								></cl-avatar>
+							</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>
+			</template>
+			<div slot="footer" class="dialog-footer">
+				<el-button @click="redeemVisible = false">取 消</el-button>
+				<el-button type="primary" @click="confirmRedeemFn">确认发奖</el-button>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			app: null,
+			tabIndex: '-1',
+			tabsData: [
+				{
+					text: '全部',
+					key: '-1'
+				},
+				{
+					text: '待下单',
+					key: '0'
+				},
+				{
+					text: '待兑奖',
+					key: '1'
+				},
+				{
+					text: '已兑奖',
+					key: '2'
+				}
+			],
+			// 兑奖弹窗
+			redeemVisible: false,
+			redeemData: {}
+		};
+	},
+	methods: {
+		handleClick(tab, e) {
+			this.app.refresh({ status: this.tabIndex });
+		},
+		redeemFn(item) {
+			this.redeemData = item;
+			this.redeemVisible = true;
+		},
+		confirmRedeemFn() {
+			this.$service.invite.give({ id: this.redeemData.is }).then(res => {
+				this.$message.success('兑奖成功!');
+				this.redeemVisible = true;
+				this.app.refresh({ type: this.tabIndex });
+			});
+		},
+		// cl-crud 组件
+		onLoad({ ctx, app }) {
+			this.app = app;
+			ctx.service(this.$service.invite)
+				.set('table', {
+					columns: [
+						{
+							prop: 'introUserName',
+							label: '邀请人',
+							align: 'center',
+							'min-width': 100
+						},
+						{
+							prop: 'mobile',
+							label: '邀请人手机',
+							align: 'center'
+						},
+						{
+							prop: 'addTime',
+							label: '邀请时间',
+							align: 'center'
+						},
+						{
+							prop: 'userName',
+							label: '新客户',
+							align: 'center'
+						},
+						{
+							prop: 'orderTime',
+							label: '下单时间',
+							align: 'center'
+						},
+						{
+							prop: 'status',
+							label: '状态',
+							align: 'center'
+						}
+					],
+					// 操作列
+					op: {
+						visible: true, // 是否显示
+						// 同 element-ui Table-column Attributes
+						props: {
+							width: 100,
+							align: 'center',
+							fixed: 'right',
+							label: '操作'
+						},
+						// 布局,请移步 `layout`
+						layout: ['slot-column-redeem']
+					}
+				})
+				.set('layout', [
+					['slot-tabs'],
+					['search-key', 'flex1', 'refresh-btn'],
+					['data-table'],
+					['flex1', 'pagination']
+				])
+				.done();
+			app.refresh({ status: this.tabIndex });
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+// 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>

+ 101 - 0
admin-code/src/views/invite/reward-set.vue

@@ -0,0 +1,101 @@
+<template>
+	<div class="app-content reward-set-wrap">
+		<el-form
+			:model="ruleForm"
+			:rules="rules"
+			ref="ruleForm"
+			label-width="150px"
+			class="demo-ruleForm"
+		>
+			<el-form-item label="开启状态" prop="name">
+				<el-switch
+					v-model="ruleForm.switch"
+					active-value="1"
+					inactive-value="0"
+				></el-switch>
+			</el-form-item>
+			<el-form-item label="邀请成功下单奖励" prop="resource">
+				<el-input v-model="ruleForm.prize"></el-input>
+			</el-form-item>
+			<el-form-item label="新人可领取" prop="name">
+				<div class="flex-center flex-wrap">
+					<el-input v-model="ruleForm.amount" style="width: 150px"></el-input>
+					<div class="prompt-text">元优惠券,满</div>
+					<el-input v-model="ruleForm.miniCost" style="width: 150px"></el-input>
+					<div class="prompt-text">元可以使用,领取后</div>
+					<el-input v-model="ruleForm.duration" style="width: 150px"></el-input>
+					<div class="prompt-text">天内有效。</div>
+				</div>
+			</el-form-item>
+			<el-form-item>
+				<div class="app-color-3">
+					提示:奖励额度可以比新人领券高一此,这样可以吸引老客户邀请新人,新人也更愿意到店消费。
+				</div>
+			</el-form-item>
+			<el-form-item>
+				<!-- <el-button @click="resetForm('ruleForm')">重置</el-button> -->
+				<el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
+			</el-form-item>
+		</el-form>
+	</div>
+</template>
+
+<script>
+export default {
+	name: 'reward-set',
+	data() {
+		return {
+			ruleForm: {
+				switch: '0',
+				prize: '',
+				amount: '',
+				miniCost: '',
+				duration: ''
+			},
+			rules: {}
+		};
+	},
+	created() {
+		this._getDet();
+	},
+	methods: {
+		_getDet() {
+			this.$service.invite.assetDetail().then(res => {
+				if (this.$util.isEmpty(res)) return;
+				Object.keys(this.ruleForm).forEach((i, index) => {
+					this.ruleForm[i] = res[i];
+				});
+			});
+		},
+		submitForm(formName) {
+			this.$refs[formName].validate(valid => {
+				if (valid) {
+					this.$service.invite.assetDetail(this.ruleForm).then(res => {
+						this.$message.success('设置成功!');
+					});
+				} else {
+					console.log('error submit!!');
+					return false;
+				}
+			});
+		},
+		resetForm(formName) {
+			this.$refs[formName].resetFields();
+		}
+	}
+};
+</script>
+<style lang="scss">
+.reward-set-wrap {
+	.prompt-text {
+		margin: 0 10px;
+	}
+	.el-checkbox.is-bordered.el-checkbox--small {
+		margin-left: 0;
+		margin-right: 10px;
+		&:nth-child(4n + 4) {
+			margin-right: 0;
+		}
+	}
+}
+</style>

+ 20 - 8
admin-code/src/views/member/list.vue

@@ -48,7 +48,12 @@
 			</template>
 		</cl-crud>
 		<!-- 充值 -->
-		<el-dialog title="充值" :visible.sync="rechargeDialog" width="400px">
+		<el-dialog
+			title="充值"
+			:visible.sync="rechargeDialog"
+			:close-on-click-modal="false"
+			width="400px"
+		>
 			<div class="recharge-modal-content">
 				<el-form
 					:model="rechargeForm"
@@ -80,7 +85,12 @@
 			</div>
 		</el-dialog>
 		<!-- 升级 -->
-		<el-dialog title="升级" :visible.sync="upgradeDialog" width="400px">
+		<el-dialog
+			title="升级"
+			:visible.sync="upgradeDialog"
+			:close-on-click-modal="false"
+			width="400px"
+		>
 			<div class="recharge-modal-content">
 				<el-form
 					:model="upgradeForm"
@@ -163,7 +173,7 @@ export default {
 		...mapGetters({ levelData: 'level' })
 	},
 	created() {
-		this.$store.dispatch('getLevel');
+		// this.$store.dispatch('getLevel');
 	},
 	mounted() {},
 	methods: {
@@ -327,11 +337,13 @@ export default {
 								attrs: {
 									placeholder: '请选择'
 								},
-								options: this.levelData.list.map(e => {
-									e.label = e.level;
-									e.value = e.level;
-									return e;
-								})
+								options: this.$util.isEmpty(this.levelData)
+									? []
+									: this.levelData.list.map(e => {
+											e.label = e.level;
+											e.value = e.level;
+											return e;
+									  })
 							},
 							rules: {
 								required: true,