Commit 49c872f6 by 姜雷

添加部分用户组件

parent 2b8df781
VUE_APP_LIB_MANAGER=http://ex-dev-dcxy-static.168cad.top
VUE_APP_BASE_URL=/systemManageShell/ VUE_APP_BASE_URL=/systemManageShell/
VUE_APP_CUSTOMER_MENU_CODE=0001 VUE_APP_CUSTOMER_MENU_CODE=0001
VUE_APP_BASE_MENU_CODE=0002 VUE_APP_BASE_MENU_CODE=0002
VUE_APP_SYSTEM_MENU_CODE=0003 VUE_APP_SYSTEM_MENU_CODE=0003
VUE_APP_WHITE_LIST=/login,/404,/401 VUE_APP_WHITE_LIST=/login,/404,/401
VUE_APP_LIB_MANAGER=http://ex-dev-dcxy-static.168cad.top
VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top
VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top
VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top
......
NODE_ENV = production NODE_ENV = production
VUE_APP_LIB_MANAGER=http://ex-dev-dcxy-static.168cad.top
VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top
VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top
VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top
VUE_APP_BASE_SERVER_URL_APP=http://ex-dev-dcxy-base-app.168cad.top VUE_APP_BASE_SERVER_URL_APP=http://ex-dev-dcxy-base-app.168cad.top
...@@ -13,6 +13,7 @@ npm run build:master # 生成环境 ...@@ -13,6 +13,7 @@ npm run build:master # 生成环境
根目录下`.env.dev`,`.env.test`,`.env.master`,分别替换服务地址 根目录下`.env.dev`,`.env.test`,`.env.master`,分别替换服务地址
```bash ```bash
VUE_APP_LIB_MANAGER=http://ex-dev-dcxy-static.168cad.top # 静态项目部署地址
VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top #系统管理接口 VUE_APP_SYSTEM_SERVER_URL=http://ex-dev-dcxy-system-manage.168cad.top #系统管理接口
VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top #会员系统接口 VUE_APP_CUSTOMER_SERVER_URL=http://ex-dev-customer-manage.168cad.top #会员系统接口
VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top #基础服务接口 VUE_APP_BASE_SERVER_URL=http://ex-dev-dcxy-base-manage.168cad.top #基础服务接口
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
"start": "npm run dev", "start": "npm run dev",
"lint": "eslint --ext .js,.vue src", "lint": "eslint --ext .js,.vue src",
"build": "vue-cli-service build --modern", "build": "vue-cli-service build --modern",
"build:dev": "vue-cli-service build --modern --mode dev", "build:dev": "cross-env npm run buildapp:dev && npm run buildlib:dev",
"build:test": "vue-cli-service build --modern --mode test", "build:test": "vue-cli-service build --modern --mode test",
"build:master": "vue-cli-service build --modern --mode master", "build:master": "vue-cli-service build --modern --mode master",
"build:prod": "vue-cli-service build --modern", "build:prod": "vue-cli-service build --modern",
"buildapp:dev": "vue-cli-service build --modern --mode dev", "buildapp:dev": "vue-cli-service build --modern --mode dev",
"buildlib:dev": "vue-cli-service build --target lib --name manageShell ./src/lib-main.js --modern --mode dev", "buildlib:dev": "vue-cli-service build --target lib --name manageShell ./src/lib/main.js --modern --mode dev",
"analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build" "analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build"
}, },
"dependencies": { "dependencies": {
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"popmotion": "^8.1.22", "popmotion": "^8.1.22",
"qiniu-js": "^2.2.0", "qiniu-js": "^2.2.0",
"rym-element-ui": "^0.1.43", "rym-element-ui": "^0.1.46",
"vue": "^2.5.2", "vue": "^2.5.2",
"vue-qr": "^1.2.8", "vue-qr": "^1.2.8",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<meta charset="utf-8">
<title>baseManage demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./baseManage.umd.js"></script>
<link rel="stylesheet" href="./baseManage.css">
<script>
console.log(baseManage)
</script>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511504199105" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1815" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M817.968553 215.897142l-169.357176 0 0-58.869782c0-25.391297-20.657482-46.048779-46.048779-46.048779l-181.125197 0c-25.391297 0-46.048779 20.657482-46.048779 46.048779l0 58.869782-169.357176 0c-25.391297 0-46.048779 20.657482-46.048779 46.048779l0 71.631434c0 25.391297 20.657482 46.048779 46.048779 46.048779l28.321022 0 0 425.947112c0 59.246359 48.200792 107.447151 107.447151 107.447151l340.40076 0c59.246359 0 107.447151-48.200792 107.447151-107.447151L789.647531 379.626133l28.321022 0c25.391297 0 46.048779-20.657482 46.048779-46.048779l0-71.631434C864.017332 236.554624 843.35985 215.897142 817.968553 215.897142zM426.553932 162.14389l170.892135 0 0 53.753251-170.892135 0L426.553932 162.14389zM738.482221 805.574269c0 31.033807-25.248034 56.281841-56.281841 56.281841L341.79962 861.85611c-31.033807 0-56.281841-25.248034-56.281841-56.281841L285.517779 379.626133l452.964442 0L738.482221 805.574269zM812.852022 328.460824l-601.704045 0 0-61.398372 203.227588 0c2.302439 0.356111 4.66116 0.542352 7.061836 0.542352l181.125197 0c2.400676 0 4.759397-0.186242 7.062859-0.542352l203.226564 0L812.852022 328.460824zM513.023306 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655-14.128789 0-25.582655 11.453866-25.582655 25.582655l0 288.572348C487.440651 771.866562 498.894518 783.320429 513.023306 783.320429zM645.541459 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655s-25.582655 11.453866-25.582655 25.582655l0 288.572348C619.958804 771.866562 631.41267 783.320429 645.541459 783.320429zM380.505154 783.320429c14.128789 0 25.582655-11.453866 25.582655-25.582655l0-288.572348c0-14.128789-11.453866-25.582655-25.582655-25.582655s-25.582655 11.453866-25.582655 25.582655l0 288.572348C354.922499 771.866562 366.376365 783.320429 380.505154 783.320429z" p-id="3757"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511504199105" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1815" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M185.89696 532.2752h286.72v286.72a20.48 20.48 0 1 0 40.96 0v-286.72h286.72a20.48 20.48 0 1 0 0-40.96h-286.72v-286.72a20.48 20.48 0 1 0-40.96 0v286.72h-286.72a20.48 20.48 0 1 0 0 40.96z" fill="" p-id="3098"></path></svg>
\ No newline at end of file
import fetch from '../fetch';
const path = process.env.VUE_APP_CUSTOMER_SERVER_URL;
export const fetchUserBaseInfo = entity =>
fetch({
url: path + '/dcxy/customerInfo/baseInfo',
params: entity,
});
export const fetchUserBaseInfoByPhone = entity =>
fetch({
url: path + '/dcxy/customerInfo/baseCustomer',
params: entity,
});
<template>
<transition
name="dialog-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
>
<div
class="el-dialog__wrapper user-dialog"
v-show="visible"
@click.self="handleWrapperClick"
>
<div
role="dialog"
aria-modal="true"
:aria-label="title || 'dialog'"
class="el-dialog"
:class="[{ 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
ref="dialog"
:style="style"
>
<user-with-content
:customerId="customerId"
:visible='visible'
ref="userContent"
>
<button
type="button"
class="el-dialog__headerbtn"
aria-label="Close"
v-if="showClose"
@click="handleClose"
slot="closeBtn"
>
<img
src="@/assets/images/dialog/close_icon.png"
alt=""
>
</button>
<slot
name="title"
slot="title"
></slot>
<slot></slot>
<slot
name="footer"
slot="footer"
></slot>
</user-with-content>
</div>
</div>
</transition>
</template>
<script>
import { Dialog } from 'element-ui';
export default {
name: 'user-dialog-inner',
extends: Dialog,
props: {
customerId: Number,
},
// mounted() {
// let dialogWidth = 0;
// console.log(this.$refs.userContent.$el.offsetWidth);
// let rightDom = document.querySelector(
// '.SigleUserWithContent-inner .right-part'
// );
// dialogWidth += rightDom.offsetWidth;
// dialogWidth += rightDom.offsetLeft;
// console.log(dialogWidth);
// console.log(this.style);
// this.width = dialogWidth + 'px';
// },
};
</script>
<style lang="scss">
.user-dialog {
.el-dialog {
background: transparent;
box-shadow: none;
}
}
</style>
import UserDialogInner from './UserDialog';
export default {
name: 'user-dialog',
components: {
UserDialogInner,
},
props: {
customerId: Number,
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
width: String,
fullscreen: Boolean,
top: {
type: String,
default: '15vh',
},
modal: {
type: Boolean,
default: true,
},
modalAppendToBody: {
type: Boolean,
default: true,
},
appendToBody: {
type: Boolean,
default: false,
},
lockScroll: {
type: Boolean,
default: true,
},
customClass: {
type: String,
default: '',
},
closeOnClickModal: {
type: Boolean,
default: true,
},
closeOnPressEscape: {
type: Boolean,
default: true,
},
showClose: {
type: Boolean,
default: true,
},
beforeClose: Function,
center: {
type: Boolean,
default: false,
},
},
data() {
return {
wrapWidth: '50vw',
};
},
mounted() {
let dialogWidth = 0;
let rightDom = document.querySelector(
'.SigleUserWithContent-inner .right-part'
);
dialogWidth += rightDom.offsetWidth;
dialogWidth += rightDom.offsetLeft;
if (dialogWidth) {
this.wrapWidth = dialogWidth + 'px';
}
},
watch: {
visible(newVal) {
if (newVal && this.wrapWidth === '50vw') {
this.$nextTick(() => {
let dialogWidth = 0;
let rightDom = this.$el.querySelector(
'.SigleUserWithContent-inner .right-part'
);
dialogWidth += rightDom.offsetWidth;
dialogWidth += rightDom.offsetLeft;
this.wrapWidth = dialogWidth + 'px';
});
}
},
},
methods: {
updateVisible(val) {
this.$emit('update:visible', val);
},
},
render(h) {
const { width, wrapWidth } = this;
const updateVisible = {
on: {
'update:visible': this.updateVisible,
},
};
return width ? (
<UserDialogInner
{...updateVisible}
customerId={this.customerId}
visible={this.visible}
title={this.title}
fullscreen={this.fullscreen}
top={this.top}
modal={this.modal}
modalAppendToBody={this.modalAppendToBody}
appendToBody={this.appendToBody}
lockScroll={this.lockScroll}
customClass={this.customClass}
closeOnClickModal={this.closeOnClickModal}
closeOnPressEscape={this.closeOnPressEscape}
showClose={this.showClose}
beforeClose={this.beforeClose}
center={this.center}
width={this.width}>
<template slot="title">{this.$slots.title}</template>
{this.$slots.default}
<template slot="footer">{this.$slots.footer}</template>
</UserDialogInner>
) : (
<UserDialogInner
{...updateVisible}
customerId={this.customerId}
visible={this.visible}
title={this.title}
fullscreen={this.fullscreen}
top={this.top}
modal={this.modal}
modalAppendToBody={this.modalAppendToBody}
appendToBody={this.appendToBody}
lockScroll={this.lockScroll}
customClass={this.customClass}
closeOnClickModal={this.closeOnClickModal}
closeOnPressEscape={this.closeOnPressEscape}
showClose={this.showClose}
beforeClose={this.beforeClose}
center={this.center}
width={wrapWidth}>
<template slot="title">{this.$slots.title}</template>
{this.$slots.default}
<template slot="footer">{this.$slots.footer}</template>
</UserDialogInner>
);
},
};
<template>
<div class="HeaderImgBox">
<img
v-if="imgUrl"
:src="imgUrl"
/>
<img
v-else
src="@/assets/images/user/defaultHeaderImg.png"
/>
</div>
</template>
<script>
export default {
name: 'header-img-box',
props: {
imgUrl: String,
},
};
</script>
<style lang="scss">
.HeaderImgBox {
width: 40px;
height: 40px;
}
</style>
<template>
<div
class="UserInfo-Card-Wrap"
ref="CardWrap"
@mouseleave="offEditBar"
>
<div :class="['UserInfo-Card-EditBar',{'editBarVisible':editBarVisible},{'layoutRight':layoutType}]">
<div
v-if="$route.meta.btns && $route.meta.btns['0003']"
class="EditBar-item"
@click="showDetail"
>
<div class="EditBar-item-inner">
<img src="../../assets/images/user/detail_icon.png" />
</div>
<span class="EditBar-item-inner-text">详情</span>
</div>
<div
v-if="$route.meta.btns && $route.meta.btns['0004']"
class="EditBar-item"
@click="showEdit"
>
<div class="EditBar-item-inner">
<img src="../../assets/images/user/edit_icon.png" />
</div>
<span class="EditBar-item-inner-text">编辑</span>
</div>
<div
v-if="$route.meta.btns && $route.meta.btns['0005']"
class="EditBar-item"
@click="showAccount"
>
<div class="EditBar-item-inner">
<img src="../../assets/images/user/account_icon.png" />
</div>
<span class="EditBar-item-inner-text">账户</span>
</div>
<div
v-if="$route.meta.btns && $route.meta.btns['0006']"
class="EditBar-item"
@click="toggleLock"
>
<div class="EditBar-item-inner">
<img
v-if="state === '1'"
src="../../assets/images/user/lock_icon.png"
/>
<img
v-else-if="state === '2'"
src="../../assets/images/user/unlock_icon.png"
/>
</div>
<span class="EditBar-item-inner-text">{{state === '1'?'锁定':'解锁'}}</span>
</div>
<div class="EditBar-trans"></div>
</div>
<div :class="['UserInfo-Box', 'UserInfo-Card',{'hover':cardZIndex}]">
<div class="UserInfo-Title-Wrap">
<div class="UserInfo-Title">
<div class="UserInfo-IdTitle">ID:{{id}}</div>
<div
ref="HeaderImg"
@mouseenter="showEditBar"
>
<header-img-box
:class="['UserInfo-HeaderImg', {'hover':editBarVisible}]"
:imgUrl="customerHead"
></header-img-box>
</div>
<div class="UserInfo-Name-Box">
<div class="UserInfo-Name-Col">
<span>{{customerName}}</span>
<span>{{getTypeLabel(customerType)}}</span>
</div>
<div class="UserInfo-Name-Col">
<span>{{$formatePhone(customerPhone)}}</span>
<span>{{getSexLabel(customerSex)}}</span>
</div>
</div>
</div>
</div>
<div class="UserInfo-Content">
<div class="UserInfo-Content-Col UserInfo-State-Box">
<div
v-if="state === '1'"
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/normal_icon.png" />
</div>
正常使用
</div>
<div
v-else
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/locked_icon.png" />
</div>
已锁定
</div>
<div
v-if="isFirstRecharge"
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/normal_icon.png" />
</div>
已充值
</div>
<div
v-else
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/locked_icon.png" />
</div>
未充值
</div>
</div>
<div class="UserInfo-Content-Col">注册时间:{{$formatDate(new Date(createAt),'yyyy-MM-dd')}}</div>
<div class="UserInfo-Content-Col UserInfo-CampusName">{{areaName}}</div>
</div>
</div>
</div>
</template>
<script>
import getUserInfoLabelMixin from '@/mixins/user/getUserInfoLabel.js';
export default {
props: {
areaName: String,
createAt: String,
customerHead: String,
customerName: String,
customerPhone: String,
customerSex: String,
customerType: String,
id: Number,
isFirstRecharge: Number,
state: String,
showDetail: { type: Function, default: () => {} },
showEdit: { type: Function, default: () => {} },
showAccount: { type: Function, default: () => {} },
toggleLock: { type: Function, default: () => {} },
},
mixins: [getUserInfoLabelMixin],
data() {
return {
editBarVisible: false,
cardZIndex: false,
layoutType: 0, // 0 为默认左边弹出 1 为右边弹出
wrapOffsetLeft: 0,
};
},
mounted() {
let sideBarDom = document.querySelector('.scroll-container'); // 导航部分
let sideBarWidth = sideBarDom ? sideBarDom.offsetWidth : 0;
let el = this.$refs.CardWrap;
let wrapOffsetLeft = el.offsetLeft;
while ((el = el.offsetParent)) {
wrapOffsetLeft += el.offsetLeft;
}
this.wrapOffsetLeft = wrapOffsetLeft;
if (this.wrapOffsetLeft < sideBarWidth + 60) {
this.layoutType = 1;
}
// this.offsetLeft = this.wrapOffsetLeft + 60;
},
methods: {
showEditBar() {
this.editBarVisible = true;
},
offEditBar() {
this.editBarVisible = false;
},
},
};
</script>
<style lang="scss">
@import '../../assets/styles/variables.scss';
.UserInfo-Card-Wrap {
width: 170px;
height: 174px;
display: flex;
align-items: flex-end;
margin-right: 14px;
margin-bottom: 14px;
position: relative;
.UserInfo-Card-EditBar {
position: absolute;
left: 0;
z-index: 2001;
width: 0px;
height: 158px;
background-color: #00c2ff;
box-shadow: 2px 2px 10px #333;
border-radius: 8px 0 0 8px;
transition: all 0.28s;
&.editBarVisible {
left: -36px;
width: 36px;
.EditBar-trans {
opacity: 1;
}
}
.EditBar-item {
height: 39px;
position: relative;
overflow: hidden;
cursor: pointer;
&:first-child {
border-radius: 8px 0 0 0;
}
&:hover {
background-color: #11a6e8;
}
.EditBar-item-inner {
width: 14px;
height: 14px;
position: absolute;
top: 6px;
left: 10px;
}
.EditBar-item-inner-text {
position: absolute;
font-size: 12px;
color: #fff;
width: 36px;
height: 14px;
bottom: 0;
text-align: center;
overflow: hidden;
}
}
.EditBar-trans {
opacity: 0;
position: absolute;
right: -13px;
top: 26px;
border-left: 13px solid #00c2ff;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
transition: all 0.28s;
}
}
.UserInfo-Card-EditBar.layoutRight {
left: 66px;
border-radius: 0 8px 8px 0;
&.editBarVisible {
.EditBar-trans {
right: 36px;
}
}
.EditBar-item {
&:first-child {
border-radius: 0 8px 0 0;
}
}
.EditBar-trans {
right: 0px;
transform: rotate(180deg);
}
}
.UserInfo-Card {
height: 158px;
border-radius: 0 8px 8px 8px;
box-shadow: 2px 2px 5px #bbbec2;
z-index: 1000;
&:hover {
box-shadow: 2px 2px 5px #999;
}
// &.hover {
// z-index: 2002;
// }
// .UserInfo-Title-Wrap {
// height: 150px;
// padding-top: 30px;
// }
.UserInfo-Title {
// margin-top: 30px;
border-radius: 0 8px 0 0;
}
.UserInfo-IdTitle {
position: absolute;
left: 0;
top: -16px;
width: 88px;
height: 16px;
line-height: 16px;
background-color: #4e82fb;
color: #fff;
text-indent: 10px;
border-radius: 20px 20px 0 0 / 40px 40px 0 0;
}
.UserInfo-Content {
height: 90px;
border-radius: 0 0 8px 8px;
}
.UserInfo-HeaderImg {
transition: all 0.28s;
}
.UserInfo-HeaderImg.hover {
border-color: #00c2ff;
}
}
}
@media screen and (min-width: $bigScreenWidth) {
.UserInfo-Card-Wrap {
width: 300px;
height: 310px;
margin-right: 20px;
margin-bottom: 20px;
.UserInfo-Card-EditBar {
height: 280px;
&.editBarVisible {
left: -60px;
width: 60px;
}
.EditBar-item {
height: 60px;
.EditBar-item-inner {
width: 26px;
height: 26px;
top: 12px;
left: 17px;
}
.EditBar-item-inner-text {
width: 60px;
bottom: 3px;
}
}
.EditBar-trans {
right: -25px;
top: 44px;
border-left: 25px solid #00c2ff;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
}
}
.UserInfo-Card-EditBar.layoutRight {
left: 120px;
&.editBarVisible {
.EditBar-trans {
right: 60px;
}
}
.EditBar-trans {
right: 0px;
}
}
.UserInfo-Card {
height: 280px;
.UserInfo-IdTitle {
top: -30px;
width: 155px;
height: 30px;
line-height: 30px;
text-indent: 24px;
border-radius: 20px 20px 0 0 / 40px 40px 0 0;
}
.UserInfo-Content {
height: 160px;
}
}
}
}
</style>
<template>
<div
class="UserInfo-Box"
v-if="customerId || customerPhone"
>
<div class="UserInfo-Title">
<div class="UserInfo-IdTag">ID:{{customerBaseInfo.id}}</div>
<header-img-box
class="UserInfo-HeaderImg"
:imgUrl="customerBaseInfo.customerHead"
/>
<div class="UserInfo-Name-Box">
<div class="UserInfo-Name-Col">
<span>{{customerBaseInfo.customerName}}</span>
<span>{{getTypeLabel(customerBaseInfo.customerType)}}</span>
</div>
<div class="UserInfo-Name-Col">
<span>{{$formatePhone(customerBaseInfo.customerPhone)}}</span>
<span>{{getSexLabel(customerBaseInfo.customerSex)}}</span>
</div>
</div>
</div>
<div class="UserInfo-Content">
<div class="UserInfo-Content-Col UserInfo-State-Box">
<div
v-if="customerBaseInfo.state === '1'"
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/normal_icon.png" />
</div>
正常使用
</div>
<div
v-else
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/locked_icon.png" />
</div>
已锁定
</div>
<div
v-if="customerBaseInfo.isFirstRecharge"
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/normal_icon.png" />
</div>
已充值
</div>
<div
v-else
class="UserInfo-State"
>
<div class="UserInfo-State-Icon">
<img src="@/assets/images/user/locked_icon.png" />
</div>
未充值
</div>
</div>
<div class="UserInfo-Content-Col">注册时间:{{$formatDate(customerBaseInfo.createAt,'yyyy-MM-dd')}}</div>
<div class="UserInfo-Content-Col UserInfo-CampusName">{{customerBaseInfo.areaName}}</div>
</div>
</div>
</template>
<script>
import headImg from '@/assets/images/demo/head_icon.png';
import UserBaseInfoMixin from '../../mixins/user/userBaseInfo.js';
import getUserInfoLabelMixin from '@/mixins/user/getUserInfoLabel.js';
export default {
props: {
customerId: Number,
customerPhone: String,
},
mixins: [UserBaseInfoMixin, getUserInfoLabelMixin],
};
</script>
<style lang="scss">
@import '../../assets/styles/variables.scss';
.UserInfo-Box {
width: 170px;
min-width: 170px;
height: 157px;
font-family: 'Microsoft YaHei';
font-size: 12px;
border-radius: 8px;
.UserInfo-Title {
height: 68px;
background-color: #4e82fb;
position: relative;
padding: 10px;
box-sizing: border-box;
display: flex;
.UserInfo-Name-Box {
align-self: center;
flex: 1;
color: #fff;
font-size: 12px;
line-height: 24px;
.UserInfo-Name-Col {
display: flex;
justify-content: space-between;
}
}
.UserInfo-HeaderImg {
width: 46px;
height: 46px;
border: 3px solid #a7c0fd;
border-radius: 50%;
margin-right: 8px;
overflow: hidden;
}
.UserInfo-IdTag {
border-radius: 0 8px 8px 0;
box-shadow: 0 0 10px #666;
position: absolute;
width: 70px;
height: 18px;
line-height: 18px;
text-indent: 5px;
left: 0;
bottom: -9px;
background-color: #ffd737;
font-size: 12px;
font-weight: bold;
color: #084e8a;
}
}
.UserInfo-Content {
height: 90px;
background-color: #fff;
padding: 10px;
.UserInfo-Content-Col {
line-height: 25px;
}
.UserInfo-State-Box {
margin-top: 2px;
display: flex;
.UserInfo-State {
display: flex;
margin-right: 10px;
align-items: center;
.UserInfo-State-Icon {
width: 12px;
height: 12px;
margin-right: 4px;
}
}
}
.UserInfo-CampusName {
line-height: 1;
margin-top: 0px;
}
}
}
@media screen and (min-width: $bigScreenWidth) {
.UserInfo-Box {
width: 300px;
min-width: 300px;
height: 300px;
font-size: 16px;
.UserInfo-Title {
height: 120px;
padding: 20px;
.UserInfo-Name-Box {
font-size: 18px;
line-height: 38px;
}
.UserInfo-HeaderImg {
width: 80px;
height: 80px;
border-width: 5px;
margin-right: 10px;
}
.UserInfo-IdTag {
width: 128px;
height: 30px;
line-height: 30px;
text-indent: 5px;
bottom: -20px;
font-size: 16px;
}
}
.UserInfo-Content {
height: 180px;
padding: 20px;
.UserInfo-Content-Col {
line-height: 38px;
}
.UserInfo-State-Box {
margin-top: 6px;
.UserInfo-State {
margin-right: 20px;
.UserInfo-State-Icon {
width: 20px;
height: 20px;
margin-right: 10px;
}
}
}
.UserInfo-CampusName {
line-height: 1;
margin-top: 10px;
}
}
}
}
</style>
<template>
<div class="SigleUserWithContent">
<div class="SigleUserWithContent-inner">
<UserInfo
class="left-part"
:customerId="customerId"
:customerPhone="customerPhone"
:visible="visible"
/>
<div class="right-part">
<div class="el-dialog__header">
<div class="connect-line"></div>
<div class="el-dialog__title">
<slot name="title"></slot>
</div>
<slot name="closeBtn"></slot>
</div>
<div class="el-dialog__body clearfix">
<slot></slot>
</div>
<div
class="el-dialog__footer"
v-if="$slots.footer"
>
<slot name="footer"></slot>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'user-with-content',
props: {
customerId: Number,
visible: {
type: Boolean,
default: true,
},
customerPhone: String,
},
};
</script>
<style lang="scss">
@import '../../assets/styles/variables.scss';
.SigleUserWithContent {
.SigleUserWithContent-inner {
display: flex;
background: transparent;
box-shadow: none;
.UserInfo-Box {
border-radius: 8px;
.UserInfo-Title {
border-radius: 8px 8px 0 0;
}
.UserInfo-Content {
border-radius: 0 0 8px 8px;
}
}
.left-part {
z-index: 2;
border-radius: 8px;
box-shadow: 2px 2px 10px #333;
}
.right-part {
flex: 1;
margin-left: 20px;
background-color: #fff;
border-radius: 0 8px 8px 8px;
.el-dialog__header {
border-radius: 0 8px 0 0;
}
}
}
.sigle-user__body {
display: flex;
padding: 0;
}
.el-dialog__header {
position: relative;
height: 38px;
background-color: #4e82fb;
padding: 10px;
.el-dialog__headerbtn {
position: absolute;
top: -20px;
right: -20px;
width: 39px;
height: 39px;
}
.connect-line {
position: absolute;
left: -50px;
top: 0;
border-top: 19px solid transparent;
border-right: 50px solid #4e82fb;
border-bottom: 19px solid transparent;
}
.el-dialog__title {
margin: 0px auto 0;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
line-height: 18px;
vertical-align: top;
font-size: 14px;
img {
width: 14px;
height: 14px;
margin-right: 20px;
}
}
}
.el-dialog__footer {
box-sizing: content-box;
text-align: center;
}
}
@media screen and (min-width: $bigScreenWidth) {
.SigleUserWithContent {
.SigleUserWithContent-inner {
.right-part {
margin-left: 25px;
}
}
.el-dialog__header {
height: 96px;
.el-dialog__headerbtn {
top: -30px;
right: -30px;
width: 65px;
height: 65px;
}
.connect-line {
left: -70px;
border-top-width: 48px;
border-right-width: 70px;
border-bottom-width: 48px;
}
.el-dialog__title {
margin: 14px auto 0;
font-size: 22px;
img {
width: 28px;
height: 28px;
margin-right: 20px;
}
}
}
.el-dialog__footer {
padding: 50px 20px 40px;
}
}
}
</style>
...@@ -34,6 +34,17 @@ export const customerIsFirstRechargeOptions = [ ...@@ -34,6 +34,17 @@ export const customerIsFirstRechargeOptions = [
{ label: '已充值', value: '1' }, { label: '已充值', value: '1' },
]; ];
export const areaTypes = [
{ label: '正常运营', value: '1' },
{ label: '测试使用', value: '2' },
];
export const properties = [
{ label: '学校', value: '1' },
{ label: '单位', value: '2' },
{ label: '社区', value: '3' },
];
export const operClassifyList = [ export const operClassifyList = [
{ label: '新增', value: '01' }, { label: '新增', value: '01' },
{ label: '修改', value: '02' }, { label: '修改', value: '02' },
...@@ -66,6 +77,8 @@ export default { ...@@ -66,6 +77,8 @@ export default {
customerTypesOptions, customerTypesOptions,
customerSexOptions, customerSexOptions,
customerIsFirstRechargeOptions, customerIsFirstRechargeOptions,
areaTypes,
properties,
operClassifyList, operClassifyList,
operClassifyName4role, operClassifyName4role,
operClassifyName4User, operClassifyName4User,
......
import 'normalize.css/normalize.css'; import 'normalize.css/normalize.css';
import App from './App'; import App from './App';
import router, { constantRouterMap, routeStore } from './router'; import router, { constantRouterMap, routeStore } from '../router';
import store from './store'; import store from '../store';
import { formatRouteLink } from './utils/route';
routeStore.install(store); routeStore.install(store);
...@@ -12,7 +11,7 @@ import '@/permission'; // 用户登录认证 ...@@ -12,7 +11,7 @@ import '@/permission'; // 用户登录认证
// import './mock' // mockjs // import './mock' // mockjs
import extendCom from '@/utils/extends'; import extendCom from '@/utils/extends';
const createSystem = () => { const createSystem = ({ routers, routeConfig }) => {
extendCom(Vue); extendCom(Vue);
Vue.config.productionTip = false; Vue.config.productionTip = false;
...@@ -25,18 +24,8 @@ const createSystem = () => { ...@@ -25,18 +24,8 @@ const createSystem = () => {
render: h => { render: h => {
let routes = [...constantRouterMap]; let routes = [...constantRouterMap];
let allRoute = store.getters.asyncRoutes; let allRoute = store.getters.asyncRoutes;
if (allRoute && allRoute.length) { routeConfig && routeConfig(routes, allRoute);
let addRoute = allRoute.find( return <App route={routes} allRoutes={allRoute} />;
menu => menu.menuCode === process.env.VUE_APP_MENU_CODE
);
if (addRoute) {
addRoute = addRoute.childs;
} else {
addRoute = [];
}
routes = [...routes, ...formatRouteLink(addRoute)];
}
return <App route={routes} />;
}, },
}); });
}; };
......
...@@ -27,8 +27,6 @@ new Vue({ ...@@ -27,8 +27,6 @@ new Vue({
let allRoute = store.getters.asyncRoutes; let allRoute = store.getters.asyncRoutes;
if (allRoute && allRoute.length) { if (allRoute && allRoute.length) {
let addRoute = formatRouteLink(allRoute); let addRoute = formatRouteLink(allRoute);
console.log(addRoute);
for (let index = 0; index < addRoute.length; index++) { for (let index = 0; index < addRoute.length; index++) {
const element = addRoute[index]; const element = addRoute[index];
if (element.children) { if (element.children) {
......
...@@ -4,6 +4,7 @@ import createLogger from 'vuex/dist/logger'; ...@@ -4,6 +4,7 @@ import createLogger from 'vuex/dist/logger';
import app from './modules/app/index'; import app from './modules/app/index';
import user from './modules/user/index'; import user from './modules/user/index';
import base from './modules/base/index'; import base from './modules/base/index';
import customer from './modules/customer/index';
Vue.use(Vuex); Vue.use(Vuex);
...@@ -14,6 +15,7 @@ const store = new Vuex.Store({ ...@@ -14,6 +15,7 @@ const store = new Vuex.Store({
app, app,
user, user,
base, base,
customerBase: customer,
}, },
strict: debug, strict: debug,
plugins: debug ? [createLogger()] : [], plugins: debug ? [createLogger()] : [],
......
import {
fetchUserBaseInfo,
fetchUserBaseInfoByPhone,
} from '@/api/base/customer';
import { GET_CUSTOMER_BASEINFO } from './mutation-types';
const state = () => ({
areaName: '',
createAt: '',
customerHead: '',
customerName: '',
customerPhone: '',
customerSex: '',
customerType: '',
id: null,
isFirstRecharge: null,
state: '',
});
const getters = {
customerBaseInfo: state => state,
};
const actions = {
fetchUserBaseInfo({ commit }, entity) {
fetchUserBaseInfo(entity)
.then(res => {
const userInfo = res.data;
if (userInfo) {
commit(GET_CUSTOMER_BASEINFO, userInfo);
} else {
commit(GET_CUSTOMER_BASEINFO, state());
}
})
.catch(err => {
console.log(err);
commit(GET_CUSTOMER_BASEINFO, state());
});
},
fetchUserBaseInfoByPhone({ commit }, entity) {
fetchUserBaseInfoByPhone(entity)
.then(res => {
const userInfo = res.data;
if (userInfo) {
commit(GET_CUSTOMER_BASEINFO, userInfo);
} else {
commit(GET_CUSTOMER_BASEINFO, state());
}
})
.catch(err => {
console.log(err);
commit(GET_CUSTOMER_BASEINFO, state());
});
},
};
const mutations = {
[GET_CUSTOMER_BASEINFO](state, userInfo) {
Object.keys(userInfo).map(key => {
state[key] = userInfo[key];
});
},
};
export default {
state,
getters,
actions,
mutations,
};
export const GET_CUSTOMER_BASEINFO = 'GET_CUSTOMER_BASEINFO';
\ No newline at end of file
...@@ -4,9 +4,17 @@ import { ...@@ -4,9 +4,17 @@ import {
getFilters, getFilters,
formatePhone, formatePhone,
allowLetterNumber, allowLetterNumber,
formatterMoneyToDouble,
} from '@/utils/index'; } from '@/utils/index';
import rymUi from 'rym-element-ui'; import rymUi from 'rym-element-ui';
import 'rym-element-ui/lib/rymUi.css'; import 'rym-element-ui/lib/rymUi.css';
import HeaderImg from '../components/HeaderImg/HeaderImg.vue';
import UserWithContent from '../components/UserCard/UserWithContent.vue';
import UserCard from '../components/UserCard/UserCard.vue';
import UserInfo from '../components/UserCard/UserInfo.vue';
import UserDialog from '../components/Dialog/UserDialogWrap';
import AreaSelect from '../components/input/AreaSelect/index'; import AreaSelect from '../components/input/AreaSelect/index';
import ServiceTypeSelect from '../components/input/ServiceTypeSelect/index'; import ServiceTypeSelect from '../components/input/ServiceTypeSelect/index';
import GiveTypeSelect from '../components/input/GiveTypeSelect.vue'; import GiveTypeSelect from '../components/input/GiveTypeSelect.vue';
...@@ -21,6 +29,14 @@ const extendVue = Vue => { ...@@ -21,6 +29,14 @@ const extendVue = Vue => {
Vue.prototype.$formatePhone = formatePhone; Vue.prototype.$formatePhone = formatePhone;
Vue.prototype.$getFilters = getFilters; Vue.prototype.$getFilters = getFilters;
Vue.prototype.$allowLetterNumber = allowLetterNumber; Vue.prototype.$allowLetterNumber = allowLetterNumber;
Vue.prototype.$formatterMoneyToDouble = formatterMoneyToDouble;
Vue.component('UserCard', UserCard);
Vue.component('UserInfo', UserInfo);
Vue.component(UserWithContent.name, UserWithContent);
Vue.component(UserDialog.name, UserDialog);
Vue.component(HeaderImg.name, HeaderImg);
// input // input
Vue.component(AreaSelect.name, AreaSelect); Vue.component(AreaSelect.name, AreaSelect);
Vue.component(BaseDataSelect.name, BaseDataSelect); Vue.component(BaseDataSelect.name, BaseDataSelect);
......
...@@ -351,3 +351,7 @@ export const allowLetterNumber = value => { ...@@ -351,3 +351,7 @@ export const allowLetterNumber = value => {
let newVal = value.replace(/[^a-zA-Z0-9]/g, ''); let newVal = value.replace(/[^a-zA-Z0-9]/g, '');
return newVal; return newVal;
}; };
export const formatterMoneyToDouble = val => {
return val ? Number(val).toFixed(2) : Number(0).toFixed(2);
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment