lalala 6 years ago
parent
commit
a24a99a526

+ 2 - 2
admin-code/package.json

@@ -24,7 +24,7 @@
 		"mockjs": "^1.0.1-beta3",
 		"mockjs": "^1.0.1-beta3",
 		"moment": "^2.24.0",
 		"moment": "^2.24.0",
 		"nprogress": "^0.2.0",
 		"nprogress": "^0.2.0",
-		"qs": "^6.7.0",
+		"qs": "^6.9.1",
 		"quill": "^1.3.7",
 		"quill": "^1.3.7",
 		"sass-loader": "^7.1.0",
 		"sass-loader": "^7.1.0",
 		"store": "^2.0.12",
 		"store": "^2.0.12",
@@ -66,4 +66,4 @@
 			"git add"
 			"git add"
 		]
 		]
 	}
 	}
-}
+}

+ 1 - 0
admin-code/src/App.vue

@@ -14,6 +14,7 @@ export default {
 			this.$store.dispatch('userInfo');
 			this.$store.dispatch('userInfo');
 		}
 		}
 		localStorage.setItem('source', 'admin');
 		localStorage.setItem('source', 'admin');
+		localStorage.setItem('account', 12358);
 	},
 	},
 
 
 	computed: {
 	computed: {

+ 4 - 0
admin-code/src/assets/css/reset.scss

@@ -29,4 +29,8 @@
 img {
 img {
     display: block;
     display: block;
     width: 100%;
     width: 100%;
+}
+
+.el-select {
+    width: 100%;
 }
 }

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

@@ -5,6 +5,7 @@ import test from './test/index';
 import order from './order/index';
 import order from './order/index';
 import member from './member/index';
 import member from './member/index';
 import goods from './goods/index';
 import goods from './goods/index';
+import level from './level/index';
 
 
 Vue.prototype.$service = {
 Vue.prototype.$service = {
 	common,
 	common,
@@ -12,7 +13,8 @@ Vue.prototype.$service = {
 	test,
 	test,
 	order,
 	order,
 	member,
 	member,
-	goods
+	goods,
+	level
 };
 };
 
 
 export default Vue.prototype.$service;
 export default Vue.prototype.$service;

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

@@ -0,0 +1,26 @@
+import { BaseService, Service } from '@/cool/index';
+
+@Service('merchant')
+export class LevelService extends BaseService {
+	/**
+	 * 会员等级 b
+	 */
+	level() {
+		return this.request({
+			url: '/member-level',
+			method: 'POST'
+		});
+	}
+
+	/**
+	 * 会员等级 b
+	 */
+	updateLevel() {
+		return this.request({
+			url: '/member-level-update',
+			method: 'POST'
+		});
+	}
+}
+
+export default new LevelService();

+ 5 - 2
admin-code/src/service/request.js

@@ -4,6 +4,7 @@ import 'nprogress/nprogress.css';
 import store from '@/store/index';
 import store from '@/store/index';
 import router from '@/router/index';
 import router from '@/router/index';
 import { href } from '@/utils/index';
 import { href } from '@/utils/index';
+import qs from 'qs';
 
 
 axios.defaults.timeout = 600000;
 axios.defaults.timeout = 600000;
 // axios.defaults.withCredentials = true;
 // axios.defaults.withCredentials = true;
@@ -23,7 +24,9 @@ axios.interceptors.request.use(
 		if (store.state.user.token) config.headers['token'] = store.state.user.token || '';
 		if (store.state.user.token) config.headers['token'] = store.state.user.token || '';
 
 
 		config.headers['source'] = localStorage.getItem('source') || '';
 		config.headers['source'] = localStorage.getItem('source') || '';
+		config.headers['account'] = localStorage.getItem('account') || '';
 
 
+		config.data = qs.stringify(config.data) || {};
 		return config;
 		return config;
 	},
 	},
 	error => {
 	error => {
@@ -72,12 +75,12 @@ axios.interceptors.response.use(
 			return onerror(500);
 			return onerror(500);
 		}
 		}
 
 
-		const { code, data, message } = res.data;
+		const { code, data, msg } = res.data;
 		switch (code) {
 		switch (code) {
 			case 1:
 			case 1:
 				return data;
 				return data;
 			default:
 			default:
-				return Promise.reject(message);
+				return Promise.reject(msg);
 		}
 		}
 	},
 	},
 	error => {
 	error => {

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

@@ -6,6 +6,8 @@ const getters = {
 	// menuCollapse: state => state.menu.collapse,
 	// menuCollapse: state => state.menu.collapse,
 	token: state => state.user.token,
 	token: state => state.user.token,
 	userInfo: state => state.user.info,
 	userInfo: state => state.user.info,
-	permission: state => state.menu.permission
+	permission: state => state.menu.permission,
+	// config
+	level: state => state.config.level
 };
 };
 export default getters;
 export default getters;

+ 3 - 1
admin-code/src/store/index.js

@@ -4,6 +4,7 @@ import getters from './getters';
 import process from './modules/process';
 import process from './modules/process';
 import menu from './modules/menu';
 import menu from './modules/menu';
 import user from './modules/user';
 import user from './modules/user';
+import config from './modules/config';
 
 
 Vue.use(Vuex);
 Vue.use(Vuex);
 
 
@@ -11,7 +12,8 @@ const store = new Vuex.Store({
 	modules: {
 	modules: {
 		process,
 		process,
 		menu,
 		menu,
-		user
+		user,
+		config
 	},
 	},
 	getters
 	getters
 });
 });

+ 31 - 0
admin-code/src/store/modules/config.js

@@ -0,0 +1,31 @@
+import store from '@/utils/store';
+import service from '@/service/index';
+
+export default {
+	state: {
+		level: store.get('level') || {}
+	},
+	actions: {
+		getLevel({ commit }) {
+			return service.level.level().then(res => {
+				commit('SET_LEVEL', res);
+				return res;
+			});
+		},
+
+		delLevel({ commit }) {
+			commit('DEL_LEVEL');
+		}
+	},
+	mutations: {
+		SET_LEVEL(state, val) {
+			state.info = val;
+			store.set('level', val);
+		},
+
+		DEL_LEVEL(state) {
+			state.info = {};
+			store.remove('level');
+		}
+	}
+};

+ 4 - 1
admin-code/src/views/goods/freight-set.vue

@@ -10,7 +10,10 @@
 			<el-form-item>
 			<el-form-item>
 				<div class="flex-center">
 				<div class="flex-center">
 					<el-input v-model="ruleForm.name" style="width: 150px"></el-input>
 					<el-input v-model="ruleForm.name" style="width: 150px"></el-input>
-					<div class="prompt-text">公里内免运费,超过 5 公里每增加1公里,运费增加</div>
+					<div class="prompt-text">
+						<i class="el-icon-warning" style="margin-right: 4px"></i>
+						<span>公里内免运费,超过 5 公里每增加1公里,运费增加</span>
+					</div>
 					<el-input v-model="ruleForm.name" style="width: 150px"></el-input>
 					<el-input v-model="ruleForm.name" style="width: 150px"></el-input>
 				</div>
 				</div>
 			</el-form-item>
 			</el-form-item>

+ 4 - 2
admin-code/src/views/goods/summary.vue

@@ -11,10 +11,12 @@
 				<cl-editor-quill v-model="ruleForm.desc" @load="editor"></cl-editor-quill>
 				<cl-editor-quill v-model="ruleForm.desc" @load="editor"></cl-editor-quill>
 			</el-form-item>
 			</el-form-item>
 			<el-form-item>
 			<el-form-item>
-				<div class="app-color-3">说明:商品介绍的后半部分,将会显示上面的内容。</div>
+				<div class="app-color-3">
+					<i class="el-icon-warning" style="margin-right: 4px"></i>
+					<span>说明:商品介绍的后半部分,将会显示上面的内容。</span>
+				</div>
 			</el-form-item>
 			</el-form-item>
 			<el-form-item>
 			<el-form-item>
-				<el-button @click="resetForm('ruleForm')">重置</el-button>
 				<el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
 				<el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
 			</el-form-item>
 			</el-form-item>
 		</el-form>
 		</el-form>

+ 295 - 34
admin-code/src/views/member/list.vue

@@ -1,49 +1,181 @@
 <template>
 <template>
-	<cl-crud class="liu-crud-wrap" @load="onLoad">
-		<template #slot-tabs="{ scope }">
-			<el-tabs class="liu-tabs" type="border-card">
-				<el-tab-pane label="全部 (152)"></el-tab-pane>
-				<el-tab-pane label="粉丝 (112)"></el-tab-pane>
-				<el-tab-pane label="会员(82)"></el-tab-pane>
-			</el-tabs>
-		</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-avatarUrl="{scope}">
-			<cl-avatar
-				shape="square"
-				:size="40"
-				:src="scope.row.avatarUrl | default_avatar"
-				:style="{ margin: 'auto' }"
-			></cl-avatar>
-		</template>
+			<template #table-column-avatarUrl="{scope}">
+				<cl-avatar
+					shape="square"
+					:size="40"
+					:src="scope.row.avatarUrl | default_avatar"
+					:style="{ margin: 'auto' }"
+				></cl-avatar>
+			</template>
 
 
-		<template #table-column-balance="{scope}">
-			<span>{{ scope.row.userAsset.balance }}</span>
-		</template>
+			<template #table-column-balance="{scope}">
+				<span>{{ scope.row.userAsset.balance }}</span>
+			</template>
 
 
-		<template #table-column-growth="{scope}">
-			<span>{{ scope.row.userAsset.growth }}</span>
-		</template>
+			<template #table-column-growth="{scope}">
+				<span>{{ scope.row.userAsset.growth }}</span>
+			</template>
 
 
+			<!-- 充值 -->
+			<template #slot-recharge="{scope}">
+				<el-button type="text" @click="rechageDialog = true">充值</el-button>
+			</template>
+			<!-- 升级 -->
+			<template #slot-upgrade="{scope}">
+				<el-button type="text" @click="upgradDialog = true">升级</el-button>
+			</template>
+			<!-- 发货 -->
+			<template #slot-ship="{scope}">
+				<el-button type="text" @click="$message('开发中...')">发货</el-button>
+			</template>
+		</cl-crud>
 		<!-- 充值 -->
 		<!-- 充值 -->
-		<template #slot-recharge="{scope}">
-			<el-button type="text">充值</el-button>
-		</template>
+		<el-dialog title="充值" :visible.sync="rechageDialog" width="400px">
+			<div class="rechage-modal-content">
+				<el-form
+					:model="rechageForm"
+					:rules="rechageRules"
+					ref="rechageForm"
+					label-width="80px"
+					class="demo-form"
+				>
+					<el-form-item label="充值金额">
+						<el-input
+							v-model="rechageForm.rechargeAmount"
+							placeholder="充值金额"
+							size="small"
+						></el-input>
+					</el-form-item>
+					<el-form-item label="确认密码">
+						<el-input
+							v-model="rechageForm.confirmPassword"
+							placeholder="确认密码"
+							size="small"
+						></el-input>
+					</el-form-item>
+				</el-form>
+			</div>
+			<div slot="footer" class="dialog-footer">
+				<el-button size="small" @click="rechageDialog = false">取 消</el-button>
+				<el-button type="primary" size="small" @click="rechageDialog = false"
+					>充值</el-button
+				>
+			</div>
+		</el-dialog>
 		<!-- 升级 -->
 		<!-- 升级 -->
-		<template #slot-upgrade="{scope}">
-			<el-button type="text">升级</el-button>
-		</template>
-		<!-- 发货 -->
-		<template #slot-ship="{scope}">
-			<el-button type="text">发货</el-button>
-		</template>
-	</cl-crud>
+		<el-dialog title="升级" :visible.sync="upgradDialog" width="400px">
+			<div class="rechage-modal-content">
+				<el-form
+					:model="upgradForm"
+					:rules="upgradRules"
+					ref="upgradForm"
+					label-width="100px"
+					class="demo-form"
+				>
+					<el-form-item label="请选择等级">
+						<el-select v-model="upgradForm.member" size="small" placeholder="请选择">
+							<el-option
+								v-for="(item, index) in levelData.list"
+								:key="index"
+								:label="`${item.level}`"
+								:value="item.level"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="确认密码">
+						<el-input
+							v-model="upgradForm.confirmPassword"
+							placeholder="确认密码"
+							size="small"
+						></el-input>
+					</el-form-item>
+				</el-form>
+			</div>
+			<div slot="footer" class="dialog-footer">
+				<el-button size="small" @click="upgradDialog = false">取 消</el-button>
+				<el-button type="primary" size="small" @click="upgradDialog = false"
+					>充值</el-button
+				>
+			</div>
+		</el-dialog>
+	</div>
 </template>
 </template>
 
 
 <script>
 <script>
+import { mapGetters } from 'vuex';
 export default {
 export default {
+	data() {
+		return {
+			// cl-crud
+			app: null,
+			tabIndex: '-1',
+			tabsData: [
+				{
+					text: '全部',
+					key: '-1',
+					val: 0
+				},
+				{
+					text: '粉丝',
+					key: '1',
+					val: 0
+				},
+				{
+					text: '会员',
+					key: '2',
+					val: 0
+				}
+			],
+			// rechage
+			rechageDialog: false,
+			rechageForm: {
+				rechargeAmount: '',
+				confirmPassword: ''
+			},
+			rechageRules: {},
+			// upgrad
+			upgradDialog: false,
+			upgradForm: {
+				member: '',
+				confirmPassword: ''
+			},
+			upgradRules: {}
+		};
+	},
+	computed: {
+		...mapGetters({ levelData: 'level' })
+	},
+	created() {
+		this.$store.dispatch('getLevel');
+	},
+	mounted() {},
 	methods: {
 	methods: {
+		handleClick(tab, e) {
+			console.log(tab, e);
+			this.app.refresh({ type: this.tabIndex });
+		},
+		// crud
 		onLoad({ ctx, app }) {
 		onLoad({ ctx, app }) {
+			this.app = app;
 			ctx.service(this.$service.member)
 			ctx.service(this.$service.member)
 				.set('table', {
 				.set('table', {
 					columns: [
 					columns: [
@@ -111,14 +243,143 @@ export default {
 						layout: ['slot-recharge', 'slot-upgrade', 'slot-ship']
 						layout: ['slot-recharge', 'slot-upgrade', 'slot-ship']
 					}
 					}
 				})
 				})
+				.set('upsert', {
+					props: {
+						width: '600px',
+						'label-width': '120px'
+					},
+
+					items: [
+						{
+							prop: 'mobile',
+							label: '手机号码',
+							span: 24,
+							component: {
+								name: 'el-input',
+								attrs: {
+									placeholder: '请填写手机号码'
+								}
+							},
+							rules: {
+								required: true,
+								message: '请填写手机号码'
+							}
+						},
+						{
+							prop: 'confirmMobile',
+							label: '确认手机号码',
+							span: 24,
+							component: {
+								name: 'el-input',
+								attrs: {
+									placeholder: '请填写确认手机号码'
+								}
+							},
+							rules: {
+								required: true,
+								message: '请填写确认手机号码'
+							}
+						},
+						{
+							prop: 'balance',
+							label: '余额',
+							span: 24,
+							component: {
+								name: 'el-input',
+								attrs: {
+									placeholder: '请填写余额'
+								}
+							},
+							rules: {
+								required: true,
+								message: '请填写余额'
+							}
+						},
+						{
+							prop: 'memberLevel',
+							label: '会员级别',
+							span: 24,
+							component: {
+								name: 'el-select',
+								attrs: {
+									placeholder: '请选择'
+								},
+								options: this.levelData.list.map(e => {
+									e.label = e.level;
+									e.value = e.level;
+									return e;
+								})
+							},
+							rules: {
+								required: true,
+								message: '级别不能为空'
+							}
+						},
+						{
+							prop: 'realName',
+							label: '姓名',
+							span: 24,
+							component: {
+								name: 'el-input',
+								attrs: {
+									placeholder: '选填'
+								}
+							}
+						},
+						{
+							prop: 'confirmPassword',
+							label: '确认密码',
+							span: 24,
+							component: {
+								name: 'el-input',
+								attrs: {
+									placeholder: '请填写确认密码'
+								},
+								props: {
+									placeholder: '请填写确认密码',
+									type: 'password'
+								}
+							},
+							rules: [
+								{
+									required: true,
+									message: '密码不能为空'
+								},
+								{
+									min: 6,
+									max: 16,
+									message: '密码长度在 6 到 16 个字符'
+								}
+							]
+						},
+						{
+							prop: 'tips',
+							component: (
+								<div>
+									<i class="el-icon-warning"></i>
+									<span style="margin-left: 6px">
+										添加后,申请会员时自动根据手机号识别客户,成长值、等级和余额会自动同步。
+									</span>
+								</div>
+							)
+						}
+					]
+				})
 				.set('layout', [
 				.set('layout', [
 					['slot-tabs'],
 					['slot-tabs'],
 					['search-key', 'flex1', 'refresh-btn', 'add-btn'],
 					['search-key', 'flex1', 'refresh-btn', 'add-btn'],
 					['data-table'],
 					['data-table'],
 					['flex1', 'pagination']
 					['flex1', 'pagination']
 				])
 				])
+				.on('refresh', async (params, { next }) => {
+					// 继续执行刷新
+					let { asset } = await next(params);
+					this.tabsData[0].val = asset.totalUser;
+					this.tabsData[1].val = asset.totalMember;
+					this.tabsData[2].val = asset.totalFans;
+				})
 				.done();
 				.done();
-			app.refresh({ status: 0 });
+			app.refresh({ type: this.tabIndex });
 		}
 		}
 	}
 	}
 };
 };