Commit a5637e93 authored by Mac's avatar Mac

Merge branch 'master' of http://gitlab.oytour.com/xiangwei/horse

parents f76002be a51b6e3f
...@@ -10,4 +10,5 @@ export default defineComponent({ ...@@ -10,4 +10,5 @@ export default defineComponent({
</script> </script>
<style lang="sass"> <style lang="sass">
@import url('./css/font.sass') @import url('./css/font.sass')
@import url('//at.alicdn.com/t/font_2930340_slk9lu50bhg.css')
</style> </style>
/**
* 所有跟用户相关的接口(TODO:DEMO USER)
*/
import { HttpResponse } from '@/@types'
import Axios from './axios'
/**
* @interface loginParams -登录参数
* @property {string} grant_type -授权类型
* @property {string} email -邮箱
* @property {string} password -用户密码
*/
interface CutomerParams {
PageIndex: number,
PageSize: number,
rowsPerPage: number,
pageCount: number,
CorpName: string, //企业名称
CustomerName: string, //备注名
WeChatName: string, //昵称
CustomerMobile: string, //手机号码
CreateSTime: string, //创建开始时间
CreateETime: string, //创建结束时间
FriendSTime: string, //好友开始时间
FriendETime: string, //好友结束时间
Q_NotFollowUpDay: number, //几天未跟进
Q_Friends: string, //好友关系 多选逗号分隔、
Q_AddWay: string, //获取来源 多选英文逗号分隔
EmpId: number, //员工id
CustomerType: number, //类型1微信用户 2企业微信用户
SelectList: Array<any>, //自定义查询
OrderBy: number, //排序
AddCondition: number //查询条件
}
/**
* @example Axios.get(`https://xxx.com}`)
* @todo Get the exchange rate of the current currency
*/
class CustomerService {
// 登录
static async getCustomerList(data: CutomerParams): Promise<HttpResponse> {
return Axios('/QYCustomer/GetCustomerInfoPageList', {
method: 'post',
responseType: 'json',
data
})
}
}
export {CutomerParams}
export default CustomerService
...@@ -48,10 +48,8 @@ router.beforeEach((to, from, next) => { ...@@ -48,10 +48,8 @@ router.beforeEach((to, from, next) => {
//检查是否有权限访问 //检查是否有权限访问
const authMenu = allAuth.findIndex((x: AuthMenuType) => { const authMenu = allAuth.findIndex((x: AuthMenuType) => {
console.log(x.menuUrl,to.path)
return x.menuUrl == to.path return x.menuUrl == to.path
}) })
console.log(authMenu)
if (authMenu != -1) { if (authMenu != -1) {
next({ next({
...to, ...to,
......
<template> <template>
<q-list> <q-list>
<nav-item v-for="(x,i) in menus" :menu="x" :key="i"></nav-item> <div class="firstMenus">
<div v-for="(item) in menus" :key="item.MenuId">
<div class="firstMenusTitle">
<i :class="`iconfont icon-${item.MenuIcon}`" style="margin-right: 5px;"></i>
{{ item.MenuName }}
</div>
<div v-if="item.SubList" class="secondMenus">
<div v-for="_item in item.SubList" :key="_item.MenuId" class="secondMenusTitle">
<div
class="secondMenusText"
:class="{ 'menuActive': currentPath == _item.MenuUrl }"
@click="changeMenu(_item.MenuUrl)"
>{{ _item.MenuName }}</div>
</div>
</div>
</div>
</div>
</q-list> </q-list>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent, inject } from 'vue'
import navItem from './nav-item.vue' import router from '@/router'
export default defineComponent({ export default defineComponent({
components: { navItem },
name: 'navs', name: 'navs',
props: { props: {
menus: { menus: {
type: Array, type: Array,
required: true required: true
} }
},
setup(props) {
let currentPath = inject('currentPath')
let changeMenu = (url: string) => {
router.push({
path: url
})
}
return {
currentPath,
changeMenu
}
} }
}) })
</script> </script>
<style></style> <style lang="scss" scoped>
.firstMenus {
color: #fff;
.firstMenusTitle {
font-weight: 700;
height: 40px;
line-height: 40px;
padding: 0 20px;
}
}
.secondMenusTitle {
height: 30px;
line-height: 30px;
font-size: 14px;
cursor: pointer;
padding: 0 4px;
border-radius: 5px;
box-shadow: 0 30px 53px 0 rgb(0 0 0 / 12%);
position: relative;
color: #b2b4c7;
display: inline-block;
&:nth-child(odd) {
padding-left: 40px;
padding-right: 0;
min-width: 120px;
}
&:nth-child(even) {
padding-left: 14px;
padding-right: 0;
min-width: 80px;
}
.secondMenusText {
cursor: pointer;
padding: 0 4px;
display: inline-block;
line-height: 21px;
border-radius: 5px;
box-shadow: 0 30px 53px 0 rgb(0 0 0 / 12%);
position: relative;
}
.menuActive {
color: #fff;
background-color: #3470ff;
}
}
</style>
<template> <template>
<q-layout view="lhh lpR lFf"> <q-layout view="lhh lpR lFf" class="layout">
<!-- <q-header elevated> <!-- <q-header elevated>
<q-toolbar> <q-toolbar>
<q-btn flat dense round icon="menu" aria-label="Menu" @click="toggleLeftDrawer" /> <q-btn flat dense round icon="menu" aria-label="Menu" @click="toggleLeftDrawer" />
...@@ -8,26 +8,37 @@ ...@@ -8,26 +8,37 @@
<div>Quasar v{{ $q.version }}</div> <div>Quasar v{{ $q.version }}</div>
</q-toolbar> </q-toolbar>
</q-header> --> </q-header>-->
<q-drawer v-model="leftDrawerOpen" show-if-above> <q-drawer v-model="leftDrawerOpen" show-if-above :mini="miniState" :width="260">
<div class="full-height column"> <div class="full-height column">
<div class="flex q-px-md q-py-lg items-center"> <div class="flex q-px-md q-py-lg items-center header-logo">
<img src="../assets/images/md-logo.png" style="width: 40%" /> <img src="../assets/images/md-logo.png" style="width: 40%" />
<q-badge style="background: #cbcfe0; height: 18px" class="q-ml-md" transparent>Alpha</q-badge> <i class="iconfont icon-toggle-left" style="font-size:24px" v-if="!miniState"></i>
<i class="iconfont icon-toggle-right" style="font-size:24px" v-if="miniState"></i>
</div> </div>
<q-scroll-area :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height col"> <q-scroll-area
:thumb-style="scrollStyle.thumbStyle"
:bar-style="scrollStyle.barStyle"
class="full-height col"
>
<div class="q-px-md navs-list"> <div class="q-px-md navs-list">
<Navs :menus="menuList"></Navs> <Navs :menus="menuList"></Navs>
</div> </div>
</q-scroll-area> </q-scroll-area>
<div class="q-pa-md row items-center"> <!-- <div class="q-pa-md row items-center">
<q-avatar rounded size="40px"> <q-avatar rounded size="40px">
<img :src="user.userAvatar" alt=""> <img :src="user.userAvatar" alt />
</q-avatar> </q-avatar>
<div class="q-ml-md pfb col" style="font-size:20px">{{user.nickName}}</div> <div class="q-ml-md pfb col" style="font-size:20px">{{ user.nickName }}</div>
<svg-icon :size="24" color="hover-g-p svg-icon" icon="Navigation/Sign-out.svg" tips="退出账户" @click="loginOut"></svg-icon> <svg-icon
</div> :size="24"
color="hover-g-p svg-icon"
icon="Navigation/Sign-out.svg"
tips="退出账户"
@click="loginOut"
></svg-icon>
</div>-->
</div> </div>
</q-drawer> </q-drawer>
...@@ -42,18 +53,24 @@ const linksList = [ ...@@ -42,18 +53,24 @@ const linksList = [
{ {
MenuId: 1, MenuId: 1,
MenuName: '渠道管理', MenuName: '渠道管理',
MenuIcon: 'school', MenuIcon: 'target-full',
SubList: [ SubList: [
{ {
MenuId: 8, MenuId: 8,
MenuName: '我的渠道', MenuName: '我的渠道',
MenuIcon: 'school', MenuIcon: 'target-full',
MenuUrl: '/index' MenuUrl: '/index'
}, },
{ {
MenuId: 9, MenuId: 9,
MenuName: '渠道市场', MenuName: '渠道市场',
MenuIcon: 'school', MenuIcon: 'left',
MenuUrl: 'https://quasar.dev'
},
{
MenuId: 9,
MenuName: '渠道市场1',
MenuIcon: 'right',
MenuUrl: 'https://quasar.dev' MenuUrl: 'https://quasar.dev'
} }
] ]
...@@ -64,7 +81,7 @@ const linksList = [ ...@@ -64,7 +81,7 @@ const linksList = [
MenuIcon: 'school', MenuIcon: 'school',
SubList: [ SubList: [
{ {
MenuId: 10-1, MenuId: 10 - 1,
MenuName: '素材分组', MenuName: '素材分组',
MenuIcon: 'school', MenuIcon: 'school',
MenuUrl: '/groupingManage' MenuUrl: '/groupingManage'
...@@ -78,50 +95,19 @@ const linksList = [ ...@@ -78,50 +95,19 @@ const linksList = [
MenuIcon: 'school', MenuIcon: 'school',
SubList: [ SubList: [
{ {
MenuId: 11-1, MenuId: 11 - 1,
MenuName: '客户设置', MenuName: '客户设置',
MenuIcon: 'school', MenuIcon: 'school',
MenuUrl: '/customerSetup' MenuUrl: '/customerSetup'
}, },
]
},
{
MenuId: 2,
MenuName: '数据看板',
MenuIcon: 'code',
MenuUrl: 'https://github.com/quasarframework'
},
{ {
MenuId: 3, MenuId: 11-2,
MenuName: '数据分析', MenuName: '客户',
MenuIcon: 'chat', MenuIcon: 'school',
MenuUrl: 'https://chat.quasar.dev' MenuUrl: '/customer'
},
{
MenuId: 4,
MenuName: '画像洞察',
MenuIcon: 'record_voice_over',
MenuUrl: 'https://forum.quasar.dev'
},
{
MenuId: 5,
MenuName: '客户线索',
MenuIcon: 'rss_feed',
MenuUrl: 'https://twitter.quasar.dev'
},
{
MenuId: 6,
MenuName: '数据管理',
MenuIcon: 'public',
MenuUrl: 'https://facebook.quasar.dev'
},
{
MenuId: 7,
MenuName: '平台管理',
MenuIcon: 'favorite',
MenuUrl: 'https://awesome.quasar.dev'
} }
]
},
] ]
import { defineComponent, ref, reactive, provide, watch } from 'vue' import { defineComponent, ref, reactive, provide, watch } from 'vue'
...@@ -148,14 +134,16 @@ export default defineComponent({ ...@@ -148,14 +134,16 @@ export default defineComponent({
watch(useRouterCurrent, o => { watch(useRouterCurrent, o => {
currentRouterPath.value = o.currentRoute.path currentRouterPath.value = o.currentRoute.path
}) })
const user=getStoreGetter<UserGetter>('user', 'getUser') const user = getStoreGetter<UserGetter>('user', 'getUser')
const loginOut=()=>{ const loginOut = () => {
dispatchAction<UserActionsType>('user', 'setUserSignout', null) dispatchAction<UserActionsType>('user', 'setUserSignout', null)
router.push({ router.push({
path: '/login' path: '/login'
}) })
} }
let miniState = ref(false)
return { return {
miniState,
menuList: linksList, menuList: linksList,
leftDrawerOpen, leftDrawerOpen,
scrollStyle, scrollStyle,
...@@ -166,12 +154,22 @@ export default defineComponent({ ...@@ -166,12 +154,22 @@ export default defineComponent({
}) })
</script> </script>
<style> <style>
.layout .q-drawer {
background: linear-gradient(180deg, #1c2658, #0f152e);
}
.navs-list .q-item { .navs-list .q-item {
border-radius: 8px; border-radius: 8px;
font-size: 16px !important; font-size: 16px !important;
color: #788292 !important; color: #788292 !important;
} }
.navs-list .q-item i { </style>
font-size: 1.4rem !important; <style lang="scss" scoped>
.header-logo {
display: flex;
justify-content: space-between;
align-items: center;
height: 70px;
padding: 0 20px 0 20px;
color:#fff;
} }
</style> </style>
// import { ResultType } from '@/@types/enumHelper'
// import router from '@/router'
// import UserActions from '@/store/modules/user/actions'//{ UserActionsType }
// import { UserGetter } from '@/store/modules/user/getters'
// import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils'
// import message from '@/utils/message'
import { StaticConfig } from '@/config/app'
import { ref,reactive } from 'vue'
import customer2,{CutomerParams} from '@/api/customer2'
const CustomerModule = () => {
const getCustomerList =(param:CutomerParams)=>{
customer2.getCustomerList(param)
}
const title = ref(StaticConfig.appsuffix)
const data = {
columns:[{
name: 'desc',
label: '客户',
align: 'left',
},
{ name: 'calories', align: 'center', label: '客户阶段'},
{ name: 'fat', label: '客户标签', align: 'left'},
{ name: 'carbs', label: '内容标签', align: 'left' },
{ name: 'protein', label: '创建时间', align: 'left' },
{ name: 'sodium', label: '负责人', align: 'left' },
{ name: 'calcium', label: '上次跟进', align: 'left' },
{ name: 'iron', label: '渠道活码来源', align: 'left'},
{ name: 'num', label: '7日内客户回复消息数', align: 'left'},
{ name: 'num', label: '7日内员工发送消息数', align: 'left'}],
selected:[]
}
const msg = reactive({
PageIndex: 1,
PageSize: 10,
rowsPerPage: 10,
pageCount: 0,
CorpName: '', //企业名称
CustomerName: '', //备注名
WeChatName: '', //昵称
CustomerMobile: '', //手机号码
CreateSTime: '', //创建开始时间
CreateETime: '', //创建结束时间
FriendSTime: '', //好友开始时间
FriendETime: '', //好友结束时间
Q_NotFollowUpDay: 0, //几天未跟进
Q_Friends: '', //好友关系 多选逗号分隔、
Q_AddWay: '', //获取来源 多选英文逗号分隔
EmpId: 0, //员工id
CustomerType: 0, //类型1微信用户 2企业微信用户
SelectList: [], //自定义查询
OrderBy: 1, //排序
AddCondition: 0 //查询条件
})
const TypeList = reactive([{
Name:'企业',
Id:0
},{
Name:'姓名',
Id:1
},{
Name:'备注名',
Id:2
},{
Name:'电话',
Id:3
},{
Name:'昵称',
Id:4
}])
const SeletObj = reactive({
selectVal:'',
selectWay:''
})
//选择方式
const getSelectWay = () => {
console.log(SeletObj);
// if(this.SeletObj.selectWay){
// }
}
return { getCustomerList,data,msg,title,TypeList,SeletObj,getSelectWay}
}
export default CustomerModule
// import { ResultType } from '@/@types/enumHelper' // import { ResultType } from '@/@types/enumHelper'
// import router from '@/router' // import router from '@/router'
import UserActions from '@/store/modules/user/actions'//{ UserActionsType } import UserActions from '@/store/modules/user/actions' //{ UserActionsType }
// import { UserGetter } from '@/store/modules/user/getters' // import { UserGetter } from '@/store/modules/user/getters'
// import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils' // import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils'
...@@ -44,12 +44,9 @@ const userUserLoginModule = () => { ...@@ -44,12 +44,9 @@ const userUserLoginModule = () => {
Account: userModel.username, Account: userModel.username,
Password: userModel.password Password: userModel.password
} }
// dispatchAction<UserActionsType>('user', 'userLogin', param) // dispatchAction<UserActionsType>('user', 'userLogin', param)
UserActions.userLogin(param) UserActions.userLogin(param)
stateManager.subLogin = false stateManager.subLogin = false
} }
} }
} }
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, onMounted } from 'vue' import { defineComponent , onMounted } from 'vue'
import customerService from '@/api/customer' import customerService from '@/api/customer'
import draggable from "vuedraggable"; import draggable from "vuedraggable";
export default defineComponent({ export default defineComponent({
......
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
<div class="q-pa-md"> <div class="q-pa-md">
<q-page padding style="background: #FFF;border-radius: 10px;"> <q-page padding style="background: #FFF;border-radius: 10px;">
<q-tabs v-model="tab" dense class="text-grey" align="left" active-color="primary" indicator-color="primary" narrow-indicator> <q-tabs v-model="tab" dense class="text-grey" align="left" active-color="primary" indicator-color="primary"
narrow-indicator>
<q-tab name="yewumoshi" label="业务模式" /> <q-tab name="yewumoshi" label="业务模式" />
<q-tab name="field" label="客户字段" /> <q-tab name="field" label="客户字段" />
<q-tab name="label" label="标签" /> <q-tab name="label" label="标签" />
</q-tabs> </q-tabs>
<div v-if="tab=='field'" > <div v-if="tab=='field'">
 <customer-Field></customer-Field>  <customer-Field></customer-Field>
</div> </div>
...@@ -18,12 +19,17 @@ ...@@ -18,12 +19,17 @@
<script lang="ts"> <script lang="ts">
import customerField from './components/customerField.vue' import customerField from './components/customerField.vue'
import { defineComponent, ref } from 'vue' import {
defineComponent,
ref
} from 'vue'
export default defineComponent({ export default defineComponent({
components: { customerField }, components: {
customerField
},
setup() { setup() {
return{ return {
tab:ref('field') tab: ref('field')
} }
} }
......
<template>
<div class="q-pa-md customer">
<q-page padding style="background: #FFF;border-radius: 10px;">
<div class="page-search row items-center">
<div class="col row wrap q-mr-lg q-col-gutter-md">
<div class="col-3">
<q-input filled v-model="SeletObj.selectVal" label="Filled">
<template #before>
<q-select filled style="width:120px;" @input="getSelectWay" option-value="Id" option-label="Name" v-model="SeletObj.selectWay"
:options="TypeList" emit-value map-options label="选择类型" />
</template>
</q-input>
</div>
</div>
</div>
<div class="page-content">
<q-table :data="data"
:columns="columns"
row-key="name"
selection="multiple"
/>
</div>
</q-page>
</div>
</template>
<script lang='ts'>
import {defineComponent,onMounted} from 'vue'
import CustomerModule from '@/module/customer/customerModule'
export default defineComponent({
setup() {
let {
getCustomerList,data,msg,title,TypeList,SeletObj,getSelectWay
} = CustomerModule()
onMounted(()=>{
getCustomerList(msg)
})
return {
getCustomerList,data,msg,title,TypeList,SeletObj,getSelectWay
}
}
})
</script>
<style lang="scss">
.customer .q-field__before{
padding-right:0!important;
}
</style>
<style lang="scss" scoped>
</style>
...@@ -16,16 +16,19 @@ const routes: RouteRecordRaw[] = [ ...@@ -16,16 +16,19 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/layouts/MainLayout.vue'), component: () => import('@/layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('@/pages/customer/customerSetup.vue') }] children: [{ path: '', component: () => import('@/pages/customer/customerSetup.vue') }]
}, },
{ {
path:'/auth/login', path: '/customer',
component: () => import('@/layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('@/pages/customerManage/customer.vue') }]
},
{
path: '/auth/login',
component: () => import('@/pages/auth/login.vue') component: () => import('@/pages/auth/login.vue')
}, },
{ {
path:'/auth/regist', path: '/auth/regist',
component: () => import('@/pages/auth/regist.vue') component: () => import('@/pages/auth/regist.vue')
}, },
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it
{ {
......
...@@ -48,19 +48,20 @@ const userActions = { ...@@ -48,19 +48,20 @@ const userActions = {
// if (auths != ResultType.EmptyArray) { // if (auths != ResultType.EmptyArray) {
// Object.assign(menus, ...auths) // Object.assign(menus, ...auths)
// } // }
if (res.data.Code == 1) {
message.successMsg('登录成功') message.successMsg('登录成功')
setStoreState('user', 'loginUserInfo', res.data.Data)
setStoreState('user', 'menuList', res.data.Data.MenuList) setStoreState('user', 'menuList', res.data.Data.MenuList)
console.log(55, res)
const token = { const token = {
token_type: 'login_auth', token_type: 'login_auth',
access_token: res.data.Data.Token access_token: res.data.Data.Token
} }
console.log(56, token)
const expireTime = 60 * 72 * 1000 + new Date().getTime() const expireTime = 60 * 72 * 1000 + new Date().getTime()
setStoreState('user', 'token', { ...token, expireTime }) setStoreState('user', 'token', { ...token, expireTime })
router.push({ router.push({
path: '/index' path: '/index'
}) })
}
}) })
//测试伪造数据 //测试伪造数据
...@@ -77,12 +78,10 @@ const userActions = { ...@@ -77,12 +78,10 @@ const userActions = {
userAvatar: 'https://preview.keenthemes.com/metronic8/demo7/assets/media/avatars/150-26.jpg' userAvatar: 'https://preview.keenthemes.com/metronic8/demo7/assets/media/avatars/150-26.jpg'
} }
setStoreState('user', 'userDetail', loginUser) setStoreState('user', 'userDetail', loginUser)
} }
} }
type UserActionsType = typeof userActions type UserActionsType = typeof userActions
console.log(73, typeof userActions)
export { UserActionsType } export { UserActionsType }
export default userActions export default userActions
...@@ -8,13 +8,12 @@ const userGetter = { ...@@ -8,13 +8,12 @@ const userGetter = {
}, },
getUserAllAuth() { getUserAllAuth() {
const menuList: any[] = store.state.user.menuList const menuList: any[] = store.state.user.menuList
console.log((menuList.length > 0 ? menuList : ResultType.EmptyArray),menuList.length,menuList)
return menuList.length > 0 ? menuList : ResultType.EmptyArray return menuList.length > 0 ? menuList : ResultType.EmptyArray
}, },
getUser(){ getUser() {
const userInfo=store.state.user.userDetail const userInfo = store.state.user.userDetail
return userInfo return userInfo
} },
} }
type UserGetter = typeof userGetter type UserGetter = typeof userGetter
......
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