Commit e4ab4b3d authored by lshan's avatar lshan

lishan

parents 06076661 82c53540
...@@ -21,7 +21,7 @@ const length = Mock.mock({ ...@@ -21,7 +21,7 @@ const length = Mock.mock({
'number|1-10': 1 'number|1-10': 1
}).number }).number
let records: Array<Records> = [] const records: Array<Records> = []
for (let i = 0; i <= length; i++) { for (let i = 0; i <= length; i++) {
const obj: Records = { const obj: Records = {
...@@ -41,24 +41,6 @@ for (let i = 0; i <= length; i++) { ...@@ -41,24 +41,6 @@ for (let i = 0; i <= length; i++) {
records.push(obj) records.push(obj)
} }
// const xxx = Mock.mock({
// 'array|1-4': [
// {
// name: Mock.mock('@cname'),
// content: Mock.mock('@cparagraph(1, 4)'),
// time: Mock.mock('@datetime("yyyy-MM-dd HH:mm:ss")'),
// resource: Mock.mock({
// 'array|1-10': [
// {
// 'type': 'image',
// 'href': Random.image('200x100', Mock.mock('@color'), '#FFF', 'png', '!')
// }
// ]
// }).array
// }
// ]
// }).array
export { export {
Records, Records,
Resource, Resource,
......
interface Tag {
id: number,
label: string,
color: string,
tags: Array<string>
}
const tagList: Array<Tag> = [
{
id: 1,
label: '类型',
color: 'primary',
tags: ['客户', '渠道商', '供应商', '合作伙伴', '面试人员', '其他类型']
},
{
id: 2,
label: '级别',
color: 'yellow',
tags: ['一般', '重要', '核心']
},
{
id: 3,
label: '状态',
color: 'green',
tags: ['潜在', '意向', '洽谈', '成交', '流失']
},
{
id: 4,
label: '人事招聘状态',
color: 'purple',
tags: ['带邀约', '待面试', '初试', '复试', '入职', '最多十个字就这样换行']
}
]
// const types = [
// {
// label: '客户',
// color: 'primary'
// },
// {
// label: '渠道商',
// color: 'primary'
// },
// {
// label: '供应商',
// color: 'primary'
// },
// {
// label: '合作伙伴',
// color: 'primary'
// },
// {
// label: '面试人员',
// color: 'primary'
// },
// {
// label: '其他类型',
// color: 'primary'
// }
// ]
// const levels = [
// {
// label: '一般',
// color: 'yellow'
// },
// {
// label: '重要',
// color: 'yellow'
// },
// {
// label: '核心',
// color: 'yellow'
// }
// // '一般', '重要', '核心'
// ]
// const statusList = [
// {
// label: '潜在',
// color: 'green'
// },
// {
// label: '意向',
// color: 'green'
// },
// {
// label: '洽谈',
// color: 'green'
// },
// {
// label: '成交',
// color: 'green'
// },
// {
// label: '流失',
// color: 'green'
// }
// // '潜在', '意向', '洽谈', '成交', '流失'
// ]
// const hireStatus = [
// {
// label: '流失',
// color: 'purple'
// },
// {
// label: '待邀约',
// color: 'purple'
// },
// {
// label: '待面试',
// color: 'purple'
// },
// {
// label: '初试',
// color: 'purple'
// },
// {
// label: '复试',
// color: 'purple'
// },
// {
// label: '入职',
// color: 'purple'
// },
// {
// label: '最多十个字就这样换行',
// color: 'purple'
// }
// // '带邀约', '待面试', '初试', '复试', '入职', '最多十个字就这样换行'
// ]
export {
Tag,
tagList
}
\ No newline at end of file
...@@ -23,7 +23,7 @@ export default Vue.extend({ ...@@ -23,7 +23,7 @@ export default Vue.extend({
props: { props: {
round: { round: {
type: Boolean, type: Boolean,
default: false default: true
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<div class="flex py-3 items-center justify-between"> <div class="flex py-3 items-center justify-between">
<slot name="prefix" /> <slot name="prefix" />
<div class="flex justify-between flex-1" :class="contentAlign"> <div class="flex justify-between flex-1" :class="contentAlign">
<div class="title flex-shrink-0 mr-4" :class="titleColor">{{ title }}</div> <div v-if="checkIfEmpty(title)" class="title flex-shrink-0 mr-4" :class="titleColor">{{ title }}</div>
<!-- 输入框 --> <!-- 输入框 -->
<template v-if="type === 'input'"> <template v-if="type === 'input'">
<input <input
......
<template> <template>
<div class="text-xs px-1 py-0.5 rounded" :class="getTagClass"> <div class="text-xs px-1 py-0.5 rounded inline-block" :class="getTagClass">
{{ label }} {{ label }}
</div> </div>
</template> </template>
...@@ -10,13 +10,12 @@ import Vue from 'vue' ...@@ -10,13 +10,12 @@ import Vue from 'vue'
export default Vue.extend({ export default Vue.extend({
name: 'CTag', name: 'CTag',
props: { props: {
bgColor: { color: {
type: String, type: String,
default: 'bg-tag-blue-lighter' default: 'primary',
}, validator(val) {
textColor: { return ['primary', 'red', 'green', 'purple', 'yellow', 'orange'].indexOf(val) > -1
type: String, }
default: 'text-color-primary'
}, },
label: { label: {
type: String, type: String,
...@@ -25,7 +24,16 @@ export default Vue.extend({ ...@@ -25,7 +24,16 @@ export default Vue.extend({
}, },
computed: { computed: {
getTagClass() { getTagClass() {
return `${this.bgColor} ${this.textColor}` // 'tag-primary': '#32B2F7'
// 'tag-primary-lighter': '#EAF6FF',
// 'tag-orange': '#FD8800',
// 'tag-orange-lighter': '#FAF2D8',
// 'tag-green': '#4CD15F',
// 'tag-green-lighter': '#E5F7F0',
// 'tag-yellow': '#F3B200',
// 'tag-red': '#EB8282',
// 'tag-purple': '#9F82E5',
return `bg-tag-${this.color}-lighter text-tag-${this.color}`
} }
}, },
methods: { methods: {
......
<template> <template>
<div class="mb-px rounded"> <div class="mb-px rounded">
<div class="px-4 bg-white mb-px text-sm text-text-secondary py-2 h-9 flex items-center" @click="clickItem"> <div class="px-4 bg-white mb-px text-sm text-text-secondary py-2 h-9 flex items-center" @click="clickItem">
<div class="title">{{ title }}</div> <div class="title flex items-center">
<slot name="prefix" />
<div class="">{{ title }}</div>
</div>
<app-icon <app-icon
v-if="dot" v-if="dot"
type="png" type="png"
......
...@@ -2,12 +2,18 @@ ...@@ -2,12 +2,18 @@
<div <div
class="mb-px bg-white px-4 rounded" class="mb-px bg-white px-4 rounded"
> >
<div v-if="checkIfEmpty(label)" class="py-2 flex items-center justify-between text-sm text-text-secondary"> <div v-if="checkIfEmpty(label)" class="py-2 flex items-center justify-between text-sm text-text-secondary relative">
<div class=""> <div class="">
<span v-if="required" class="text-color-primary mr-0.5">*</span> <span v-if="required" class="text-color-primary mr-0.5">*</span>
<span>{{ label }}</span> <span>{{ label }}</span>
</div> </div>
<div v-if="limit > 0" class="limit">{{ length }}/{{ limit }}</div> <div v-if="limit > 0" class="limit">{{ length }}/{{ limit }}</div>
<app-icon
v-if="dot"
type="png"
:path="require('@/assets/icons/dot.png')"
class-name="h-5 w-1 ml-auto absolute right-0"
/>
</div> </div>
<div class="py-3"> <div class="py-3">
<div class="flex-1"> <div class="flex-1">
...@@ -38,12 +44,6 @@ ...@@ -38,12 +44,6 @@
</div> </div>
<div v-if="showError" class="error text-xs text-warn-color mt-2">{{ errorMsg }}</div> <div v-if="showError" class="error text-xs text-warn-color mt-2">{{ errorMsg }}</div>
</div> </div>
<!-- <app-icon
v-if="dot"
type="png"
:path="require('@/assets/icons/dot.png')"
class-name="h-5 w-1 ml-auto flex-shrink-0"
/> -->
</div> </div>
</div> </div>
</template> </template>
...@@ -53,12 +53,16 @@ import Vue from 'vue' ...@@ -53,12 +53,16 @@ import Vue from 'vue'
export default Vue.extend({ export default Vue.extend({
components:{ components:{
// 'app-icon':()=>import('@/components/common/Icon.vue') 'app-icon':()=>import('@/components/common/Icon.vue')
// 'main-page': () => import('@/layout/main-page.vue') // 'main-page': () => import('@/layout/main-page.vue')
}, },
props: { props: {
// title: String, // title: String,
<<<<<<< HEAD
add: { add: {
=======
dot: {
>>>>>>> origin/main
type: Boolean, type: Boolean,
default: false default: false
}, },
......
...@@ -47,7 +47,7 @@ export const clientRoutes: Array<RouteConfig> = [ ...@@ -47,7 +47,7 @@ export const clientRoutes: Array<RouteConfig> = [
path: '/edit-client', path: '/edit-client',
component: () => import('@/views/client/edit-client.vue'), component: () => import('@/views/client/edit-client.vue'),
meta: { meta: {
title: '客户信息' title: '编辑客户信息'
} }
}, },
{ {
...@@ -57,5 +57,40 @@ export const clientRoutes: Array<RouteConfig> = [ ...@@ -57,5 +57,40 @@ export const clientRoutes: Array<RouteConfig> = [
{ {
path: '/search-result', path: '/search-result',
component: () => import('@/views/client/search-result.vue') component: () => import('@/views/client/search-result.vue')
},
{
path: '/tag',
component: () => import('@/views/client/tag-management.vue'),
meta: {
title: '标签管理'
}
},
{
path: '/add-tag',
component: () => import('@/views/client/add-tag.vue'),
meta: {
title: '添加标签'
}
},
{
path: '/edit-tag/:id',
component: () => import('@/views/client/edit-tag.vue'),
meta: {
title: '编辑标签'
}
},
{
path: '/filter',
component: () => import('@/views/client/filter-client.vue'),
meta: {
title: '筛选'
}
},
{
path: '/follows',
component: () => import('@/views/client/follows.vue'),
meta: {
title: '跟进成员'
}
} }
] ]
\ No newline at end of file
import Vue from 'vue' import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router' import VueRouter, { RawLocation, RouteConfig, Route } from 'vue-router'
// import App from '../App.vue' // import App from '../App.vue'
import { teamRoutes } from './team' import { teamRoutes } from './team'
import { attendanceRoutes } from './attendance' import { attendanceRoutes } from './attendance'
...@@ -8,6 +8,17 @@ import { okrRoutes } from './okr' ...@@ -8,6 +8,17 @@ import { okrRoutes } from './okr'
Vue.use(VueRouter) Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push as unknown as Promise<Route>
const originalReplace = VueRouter.prototype.replace as unknown as Promise<Route>
// push
VueRouter.prototype.push = function push (location: RawLocation) {
return (originalPush as any).call(this, location).catch((err: Error) => err)
}
// replace
VueRouter.prototype.replace = function (location: RawLocation) {
return (originalReplace as any).call(this, location).catch((err: Error) => err)
}
const routes: Array<RouteConfig> = [ const routes: Array<RouteConfig> = [
{ {
path: '/', path: '/',
......
<template>
<!-- 添加标签 -->
<main-page
left-arrow
@click-left="$router.go(-1)"
>
<div class="pt-14 px-4 pb-4">
<input-cell
v-model="tagName"
label="标签组名称"
:limit="20"
placeholder="请输入标签组名称"
>
<app-icon
slot="prefix"
icon-name="plus-round"
class-name="h-6.5 w-6.5 mr-4"
/>
</input-cell>
<input-cell
v-model="tag"
:limit="10"
label="标签列表"
placeholder="输入标签"
class="mt-4"
/>
<group-cell
title="标签列表"
class="mt-4"
>
<div class="list grid grid-cols-6 bg-white rounded">
<!-- <div class="flex items-center justify-center py-3">
<div class="h-6 w-6 border border-color-primary rounded-full flex items-center justify-center">
<div class="h-5 w-5 bg-color-primary rounded-full" />
</div>
</div> -->
<div
v-for="color in colors"
:key="color"
class="flex items-center justify-center py-3"
>
<div
class="w-6 h-6 relative flex items-center justify-center"
@click="currentColor = color"
>
<div
v-if="currentColor === color"
class="absolute w-full h-full rounded-full top-0 left-0 border"
:class="`border-tag-${color}`"
/>
<div class="w-5 h-5 rounded-full" :class="`bg-tag-${color}`" />
</div>
</div>
</div>
</group-cell>
<div class="mt-7">
<c-tag
v-for="tag in examples"
:key="tag.color"
:label="tag.label"
:color="tag.color"
class="mr-1.5"
/>
</div>
<div class="fixed bottom-0 left-0 w-full px-4 py-1.5">
<c-button round>保存</c-button>
</div>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import * as Tags from '@/DTO/tags'
export default Vue.extend({
name: 'AddTag',
components:{
'main-page': () => import('@/layout/main-page.vue'),
'input-cell': () => import('@/components/common/input-cell.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'group-cell': () => import('@/components/common/group-cell.vue'),
'c-tag': () => import('@/components/common/c-tag.vue'),
'c-button': () => import('@/components/common/c-button.vue')
},
data() {
const { tagList } = Tags
return {
tagList,
tagName: '',
tag: '',
currentColor: 'primary',
colors: ['primary', 'orange', 'yellow', 'green', 'red', 'purple'],
examples: [
{
label: '待邀约',
color: 'primary'
},
{
label: '核心',
color: 'orange'
},
{
label: '意向',
color: 'green'
},
{
label: '初试',
color: 'yellow'
},
{
label: '复试',
color: 'red'
},
{
label: '入职',
color: 'purple'
}
]
}
}
})
</script>
<style lang="less">
</style>
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
title-color="text-text-secondary" title-color="text-text-secondary"
title="跟进" title="跟进"
content="2" content="2"
@click="$router.push('/follows')"
> >
<div slot="content" class="w-full flex items-center mr-4 overflow-hidden"> <div slot="content" class="w-full flex items-center mr-4 overflow-hidden">
<app-icon <app-icon
...@@ -68,25 +69,21 @@ ...@@ -68,25 +69,21 @@
<c-tag <c-tag
class="mr-1.5 mb-1.5" class="mr-1.5 mb-1.5"
label="重要" label="重要"
bg-color="bg-tag-orange-lighter" color="red"
text-color="text-tag-orange"
/> />
<c-tag <c-tag
class="mr-1.5 mb-1.5" class="mr-1.5 mb-1.5"
label="洽谈" label="洽谈"
bg-color="bg-tag-green-lighter" color="green"
text-color="text-tag-green"
/> />
<c-tag <c-tag
class="mr-1.5 mb-1.5" class="mr-1.5 mb-1.5"
label="洽谈" label="洽谈"
bg-color="bg-tag-green-lighter" color="purple"
text-color="text-tag-green"
/> />
<c-tag <c-tag
label="这里是标签最多十个字" label="这里是标签最多十个字"
bg-color="bg-tag-green-lighter" color="green"
text-color="text-tag-green"
/> />
</div> </div>
</c-cell> </c-cell>
...@@ -220,6 +217,9 @@ export default Vue.extend({ ...@@ -220,6 +217,9 @@ export default Vue.extend({
onSelect(item: {name: string, type: string}) { onSelect(item: {name: string, type: string}) {
this.show = false this.show = false
console.log(item.type, 'item') console.log(item.type, 'item')
if (item.type === 'edit') {
this.$router.push('/edit-client')
}
} }
} }
}) })
......
...@@ -80,6 +80,8 @@ export default Vue.extend({ ...@@ -80,6 +80,8 @@ export default Vue.extend({
clickTab(action: string) { clickTab(action: string) {
if (action === 'search') { if (action === 'search') {
this.$router.push('/search-client') this.$router.push('/search-client')
} else if (action === 'filter') {
this.$router.push('/filter')
} }
}, },
addClient() { addClient() {
......
...@@ -31,13 +31,11 @@ ...@@ -31,13 +31,11 @@
<c-tag <c-tag
class="mr-1.5" class="mr-1.5"
label="重要" label="重要"
bg-color="bg-tag-orange-lighter" color="orange"
text-color="text-tag-orange"
/> />
<c-tag <c-tag
label="洽谈" label="洽谈"
bg-color="bg-tag-green-lighter" color="green"
text-color="text-tag-green"
/> />
</div> </div>
</div> </div>
......
<template>
<div class="tab-card px-4 py-2.5 bg-white rounded flex items-center" @click="$emit('click')">
<div class="flex-1 overflow-hidden">
<div class="">{{ tag.label }}</div>
<div class="mt-1.5 whitespace-nowrap">
<div v-if="tag.tags.length < 1" class="text-text-secondary text-sm">
暂无标签
</div>
<template v-if="tag.tags.length > 3">
<c-tag
v-for="(item, index) in tag.tags.slice(0,3)"
:key="index"
:label="item"
:color="tag.color"
class="mr-1.5"
/>
<span class="text-text-secondary">...</span>
</template>
<template v-else>
<c-tag
v-for="(item, index) in tag.tags"
:key="index"
:label="item"
:color="tag.color"
class="mr-1.5"
/>
</template>
</div>
</div>
<app-icon
icon-name="dot"
class-name="w-1 h-5 flex-shrink-0 ml-2"
/>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'TagCard',
components: {
'app-icon': () => import('@/components/common/Icon.vue'),
'c-tag': () => import('@/components/common/c-tag.vue')
},
props: {
tag: Object,
default() {
return {}
}
},
data() {
return {}
},
})
</script>
<style lang="less">
</style>
...@@ -4,27 +4,113 @@ ...@@ -4,27 +4,113 @@
left-arrow left-arrow
@click-left="$router.go(-1)" @click-left="$router.go(-1)"
> >
<div class="pt-12 px-4"> <div class="pt-14 px-4 pb-16">
<div class="grid grid-cols-2 text-text-secondary font-medium text-sm bg-common-bg sticky top-12"> <input-cell
<div class="flex items-center justify-center py-3" @click="clickTab('search')"> v-model="name"
required
label="姓名"
placeholder="请输入姓名(必填)"
:limit="20"
/>
<group-cell
dot
title="标签"
class="mt-4"
@click="$router.push('/filter')"
>
<span slot="prefix" class="text-color-primary mr-0.5">*</span>
<div class="bg-white px-4 py-2">
<div v-if="tags.length > 0" class="">
<c-tag
v-for="(tag, index) in tags"
:key="index"
:label="tag.label"
:color="tag.color"
class="mr-1.5 mb-1"
/>
</div>
<div v-else class="text-sm text-red-400">请选择标签</div>
</div>
</group-cell>
<input-cell
v-model="phone"
label="电话"
placeholder="请输入电话号码"
>
<app-icon
slot="prefix"
icon-name="plus-round"
class-name="w-6.5 h-6.5 mr-4"
/>
</input-cell>
<input-cell
v-model="address"
label="地址"
type="textarea"
class="mt-4"
:limit="50"
/>
<c-cell dot>
<div
slot="content"
class="w-full flex items-center"
>
<app-icon
icon-name="location"
class-name="w-4"
/>
<span class="ml-2 text-sm text-text-secondary">显示定位</span>
</div>
</c-cell>
<input-cell
v-model="company"
label="公司"
class="mt-4"
/>
<input-cell
v-model="position"
label="职位"
class="mt-4"
/>
<div class="mt-4">
<div
class="px-4 py-2 bg-white mb-px rounded flex items-center justify-between"
@click="$router.push({
path: '/team-frame',
query: {
transfer: 1
}
})"
>
<div class="title">跟进人</div>
<div class="flex items-center">
<div class="text-sm text-text-secondary mr-1.5">{{ follows.length }}</div>
<app-icon <app-icon
icon-name="search-blue" icon-name="dot"
class-name="w-6.5 h-6.5" class-name="w-1 h-5"
/> />
<div class="ml-1.5">搜索</div>
</div> </div>
<div class="flex items-center justify-center py-3" @click="clickTab('filter')"> </div>
<div class="bg-white rounded px-4 py-2.5">
<div v-if="follows.length < 1" class="text-sm text-text-secondary">暂无跟进人</div>
<div v-else class="flex">
<div
v-for="follow in follows"
:key="follow.id"
class="flex flex-col items-center mt-2 mr-4"
>
<app-icon <app-icon
icon-name="tag" icon-name="avator"
class-name="w-5 h-5" class-name="h-12 w-12"
/> />
<div class="ml-2.5">筛选</div> <div class="text-xs text-text-secondary mt-1">{{ follow.name }}</div>
</div>
</div> </div>
</div> </div>
<client-card class="mt-2" /> </div>
<client-card class="mt-4" /> </div>
<client-card class="mt-4" /> <div class="fixed bottom-0 left-0 bg-common-bg w-full px-4 py-1.5">
<client-card class="mt-4" /> <c-button>完成</c-button>
</div> </div>
</main-page> </main-page>
</template> </template>
...@@ -36,23 +122,42 @@ export default Vue.extend({ ...@@ -36,23 +122,42 @@ export default Vue.extend({
components:{ components:{
'app-icon':()=>import('@/components/common/Icon.vue'), 'app-icon':()=>import('@/components/common/Icon.vue'),
'main-page': () => import('@/layout/main-page.vue'), 'main-page': () => import('@/layout/main-page.vue'),
// 'c-tag': () => import('@/components/common/c-tag.vue'), 'input-cell': () => import('@/components/common/input-cell.vue'),
'client-card': () => import('@/views/client/components/client-card.vue') 'c-button': () => import('@/components/common/c-button.vue'),
'group-cell': () => import('@/components/common/group-cell.vue'),
'c-tag': () => import('@/components/common/c-tag.vue'),
'c-cell': () => import('@/components/common/c-cell.vue')
}, },
name: 'ClientManagement', name: 'EditClient',
data() { data() {
return { return {
tabs: [ name: '刘强',
phone: '13112345678',
address: '单行高度100,这里是输入的客户地址,没有地址不用显示',
company: '杭州复杂美科技有限公司',
position: '市场经理',
tags: [
{
color: 'primary',
label: '合作伙伴'
},
{
color: 'orange',
label: '核心'
},
{ {
label: '我跟进的', color: 'green',
key: 'mine' label: '洽谈'
}, },
{ {
label: '公共资源', color: 'primary',
key: 'public' label: '这里是标签最多十个字'
} }
], ],
currentKey: 'public' follows: [
{ name: '跟进人', id: 1 },
{ name: '真实姓名', id: 2 },
]
} }
}, },
methods: { methods: {
......
<template>
<!-- 编辑标签 -->
<main-page
left-arrow
@click-left="$router.go(-1)"
>
<div class="pt-14 px-4 pb-16">
<input-cell
v-model="tagName"
label="标签组名称"
:limit="20"
placeholder="请输入标签组名称"
>
<app-icon
slot="prefix"
icon-name="plus-round"
class-name="h-6.5 w-6.5 mr-4"
/>
</input-cell>
<group-cell
title="标签列表"
class="mt-4"
>
<c-cell
v-for="(tag, index) in currentTag.tags"
:key="index"
>
<app-icon
slot="prefix"
icon-name="minus-red"
@click="deleteTag(tag)"
/>
<div slot="content" class="w-full">{{ tag }}</div>
</c-cell>
<input-cell v-model="tag">
<app-icon
slot="prefix"
icon-name="plus-round"
class-name="h-6.5 w-6.5 mr-4"
/>
</input-cell>
</group-cell>
<group-cell
title="标签列表"
class="mt-4"
>
<div class="list grid grid-cols-6 bg-white rounded">
<div
v-for="color in colors"
:key="color"
class="flex items-center justify-center py-3"
>
<div
class="w-6 h-6 relative flex items-center justify-center"
@click="currentColor = color"
>
<div
v-if="currentColor === color"
class="absolute w-full h-full rounded-full top-0 left-0 border"
:class="`border-tag-${color}`"
/>
<div class="w-5 h-5 rounded-full" :class="`bg-tag-${color}`" />
</div>
</div>
</div>
</group-cell>
<c-button
round
type="secondary"
class="mt-4"
>
删除标签
</c-button>
<div class="fixed bg-common-bg bottom-0 left-0 w-full px-4 py-1.5">
<c-button round @click="saveTag">保存</c-button>
</div>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import * as Tags from '@/DTO/tags'
export default Vue.extend({
name: 'EditTag',
components:{
'main-page': () => import('@/layout/main-page.vue'),
'input-cell': () => import('@/components/common/input-cell.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'group-cell': () => import('@/components/common/group-cell.vue'),
// 'c-tag': () => import('@/components/common/c-tag.vue'),
'c-button': () => import('@/components/common/c-button.vue'),
'c-cell': () => import('@/components/common/c-cell.vue')
},
data() {
const { tagList } = Tags
const currentTag: Tags.Tag = {
id: 0,
label: 'tag',
color: 'primary',
tags: ['primary']
}
return {
tagList,
currentTag,
tagName: '',
tag: '',
currentColor: 'primary',
colors: ['primary', 'orange', 'yellow', 'green', 'red', 'purple'],
}
},
created() {
const id = Number(this.$route.params.id)
this.currentTag = this.tagList.find(tag => tag.id === id) as Tags.Tag
// this.tags = JSON.parse(JSON.stringify(this.currentTag.tags))
this.tagName = this.currentTag.label
this.currentColor = this.currentTag.color
},
methods: {
deleteTag(tag: string) {
const index = this.currentTag.tags.findIndex(item => item === tag)
this.currentTag.tags.splice(index, 1)
},
saveTag() {
if (this.tag.replace(/(^\s*)|(\s*$)/g, '') !== '') {
this.currentTag.tags.push(this.tag)
}
this.currentTag.color = this.currentColor
// this.currentTag.tags = this.tags
this.$router.push('/tag')
}
}
})
</script>
<style lang="less">
</style>
<template>
<!-- 筛选 -->
<main-page>
<div
slot="left"
class="text-sm font-medium"
@click="$router.go(-1)"
>
取消
</div>
<app-icon
slot="right"
icon-name="menu"
class-name="w-4 h-4"
@click="$router.push('/tag')"
/>
<div class="pt-14 px-4 pb-16">
<div
v-for="tag in tagList"
:key="tag.id"
>
<div class="title py-1 flex items-center">
<div class="dot w-2 h-2 rounded-full mr-1.5" :class="`bg-tag-${tag.color}`" />
<div class="title" :class="`text-tag-${tag.color}`">{{ tag.label }}</div>
</div>
<div class="wrapper mt-1.5 grid grid-cols-3 gap-x-6 gap-y-2.5">
<div
v-for="(item, index) in tag.tags"
:key="index"
class="rounded px-3 h-10 text-sm flex items-center justify-center leading-4"
:class="selected[tag.id].indexOf(item) > -1 ? `bg-tag-${tag.color}-lighter text-tag-${tag.color}` : 'bg-white'"
@click="selectTag(tag.id, item)"
>
{{ item }}
</div>
</div>
</div>
</div>
<div class="px-4 py-1.5 bg-common-bg fixed bottom-0 left-0 w-full grid grid-cols-2 gap-x-4">
<c-button @click="reset">重置</c-button>
<c-button @click="$router.push('/client-management')">确定</c-button>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import * as Tags from '@/DTO/tags'
interface Select {
[key: string]: Array<string>
}
export default Vue.extend({
name: 'FilterClient',
components:{
'main-page': () => import('@/layout/main-page.vue'),
'c-button': () => import('@/components/common/c-button.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
},
data() {
const { tagList } = Tags
const selected: Select = {}
return {
tagList,
selected
}
},
created() {
this.tagList.forEach(tag => {
this.$set(this.selected, tag.id, [] )
})
},
methods: {
selectTag(id: number, tag: string) {
const index = this.selected[id].findIndex(item => item === tag)
if (index < 0) {
this.selected[id].push(tag)
} else {
this.selected[id].splice(index, 1)
}
},
reset() {
for(const key in this.selected) {
this.selected[key] = []
}
}
}
})
</script>
<style lang="less">
</style>
<template>
<!-- 跟进成员 -->
<main-page
left-arrow
@click-left="$router.go(-1)"
>
<app-icon
slot="right"
icon-name="plus-black"
class-name="w-6.5 h-6.5"
@click="show=true"
/>
<van-action-sheet
v-model="show"
:actions="actions"
cancel-text="取消"
close-on-click-action
@select="onSelect"
/>
<div class="pt-12 px-4 pb-4">
<div v-if="follows.length < 1" class="text-center text-sm text-text-secondary mt-20">暂无跟进人员</div>
<div
v-else
v-for="follow in follows"
:key="follow.id"
@click="selectFollow(follow)"
>
<div class="flex items-center">
<div v-if="showRadio" class="h-6 w-6 flex items-center justify-center flex-shrink-0 mr-3">
<app-icon
v-if="selected.indexOf(follow.id) < 0"
icon-name="radio"
class-name="w-4 h-4"
/>
<app-icon
v-else
icon-name="radio-checked"
class-name="w-4 h-4"
/>
</div>
<div class="title flex-1 py-2 flex items-center overflow-hidden">
<app-icon
icon-name="avator"
class-name="w-9 h-9 flex-shrink-0"
/>
<div class="ml-2 flex-1 truncate">{{ follow.name }}</div>
</div>
</div>
</div>
</div>
<div v-if="showRadio && follows.length > 0" class="fixed bg-common-bg w-full bottom-0 left-0 px-4 py-1.5">
<c-button type="secondary" @click="deleteFollow">删除</c-button>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import { ActionSheet, Toast } from 'vant'
Vue.use(ActionSheet).use(Toast)
interface Follow {
name: string,
id: string
}
export default Vue.extend({
name: 'Follows',
components:{
'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'c-button': () => import('@/components/common/c-button.vue')
},
created() {
const arr: Array<Follow> = []
for(let i = 0; i <= 6; i++) {
const name = i === 3 ? '有一只鱼名字很长很长很长很长很长的话后面就省略' : '真实姓名'
arr.push({
name,
id: i+name
})
}
this.follows = arr
},
data() {
const selected: Array<string> = []
const follows: Array<Follow> = []
return {
follows,
show: false,
showRadio: false,
selected,
actions: [
{ name: '添加新成员', type: 'add' },
{ name: '删除成员', type: 'delete'}
]
}
},
methods: {
onSelect(item: {name: string, type: string}) {
console.log(item.type, 'type')
if (item.type === 'add') {
this.$router.push({
path: '/team-frame',
query: {
transfer: '1'
}
})
} else if (item.type === 'delete') {
this.showRadio = true
}
},
selectFollow(follow: Follow) {
const index = this.selected.findIndex(i => i === follow.id)
if (index < 0) {
this.selected.push(follow.id)
} else {
this.selected.splice(index, 1)
}
},
deleteFollow() {
if (this.selected.length < 1) {
Toast('请选择需要删除的成员')
return
}
this.$dialog.confirm({
title: '提示',
message: '确定要删除选中的成员吗?',
// confirmButtonText: '解散'
}).then(() => {
this.selected.forEach(id => {
const index = this.follows.findIndex(follow => follow.id === id)
this.follows.splice(index, 1)
})
this.selected = []
}).catch(() => {
console.log('取消解散')
})
}
}
})
</script>
<style lang="less">
</style>
...@@ -25,25 +25,45 @@ ...@@ -25,25 +25,45 @@
<div <div
slot="action" slot="action"
class="text-color-primary font-medium" class="text-color-primary font-medium"
@click="$router.go(-1)" @click="$router.replace('/search-client')"
> >
取消 取消
</div> </div>
</search-bar> </search-bar>
<div class="mt-2"> <div class="mt-2">
<div class="result"> <div class="result">
<!-- 客户 -->
<div class="text-sm text-text-secondary py-1.5">客户姓名</div> <div class="text-sm text-text-secondary py-1.5">客户姓名</div>
</div>
<div class="list"> <div class="list">
<div <div
v-for="(client, index) in result.client" v-for="(client, index) in matchedResult.client"
:key="index" :key="index"
class="flex items-center py-2"> class="flex items-center py-2"
@click="$router.push('/client-info')"
>
<app-icon <app-icon
icon-name="avator" icon-name="avator"
class-name="h-9 w-9" class-name="h-9 w-9"
/> />
<div class="ml-2.5 flex-1 truncate">{{ client.name }}</div> <div class="ml-2.5 flex-1 truncate" v-html="client.name" />
</div>
</div>
<!-- 公司 -->
<div class="text-sm text-text-secondary py-1.5">公司名称</div>
<div class="list">
<div
v-for="(client, index) in matchedResult.company"
:key="index"
class="flex items-center py-2"
>
<div class="h-9 w-9 flex items-center justify-center">
<app-icon
icon-name="location"
class-name="h-4 w-4"
/>
</div>
<div class="ml-2.5 flex-1 truncate" v-html="client.name" />
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -54,15 +74,26 @@ ...@@ -54,15 +74,26 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
interface Result {
[key: string]: Array<{name: string}>
}
export default Vue.extend({ export default Vue.extend({
components:{ components:{
'search-bar':()=>import('@/components/common/search-bar.vue'), 'search-bar':()=>import('@/components/common/search-bar.vue'),
'main-page': () => import('@/layout/main-page.vue'), 'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'), 'app-icon': () => import('@/components/common/Icon.vue'),
'search-history': () => import('@/views/client/components/search-history.vue') // 'search-history': () => import('@/views/client/components/search-history.vue')
// 'client-card': () => import('@/views/client/components/client-card.vue') // 'client-card': () => import('@/views/client/components/client-card.vue')
}, },
name: 'SearchResult', name: 'SearchResult',
beforeRouteLeave(to, from, next) {
if (to.fullPath !== this.$route.fullPath) {
next()
} else {
next(false)
}
},
data() { data() {
return { return {
tabs: [ tabs: [
...@@ -79,7 +110,7 @@ export default Vue.extend({ ...@@ -79,7 +110,7 @@ export default Vue.extend({
result: { result: {
client: [ client: [
{ name: '客户姓名' }, { name: '客户姓名' },
{ name: '刘强' }, { name: '刘强' },
{ name: '刘一只鱼' } { name: '刘一只鱼' }
], ],
company: [ company: [
...@@ -87,19 +118,51 @@ export default Vue.extend({ ...@@ -87,19 +118,51 @@ export default Vue.extend({
{ name: '刘阿姨煎饼摊' } { name: '刘阿姨煎饼摊' }
] ]
}, },
search: '' search: ''
} }
}, },
created() {
console.log('reas')
},
mounted() { mounted() {
this.search = this.$route.query.keyword as string // this.search = this.$route.query.keyword as string
// this.changeResult(this.result)
},
computed: {
matchedResult() {
const obj: Result = JSON.parse(JSON.stringify(this.result))
for (const key in obj) {
const reg = new RegExp(this.search, 'g')
obj[key].forEach(item => {
item.name = item.name.replace(reg, result => {
return `<span class="text-color-primary">${result}</span>`
})
return item
})
}
return obj
}
}, },
methods: { methods: {
handleSearch() { handleSearch() {
console.log(this.search, 'val') this.$router.replace({
path: '/search-result',
query: {
keyword: this.search
}
})
// this.changeResult(this.result)
}, },
goBack() { goBack() {
this.$router.go(-1) this.$router.go(-1)
} }
},
watch: {
search(newVal) {
if (newVal.length < 1) {
this.$router.replace('/search-client')
}
}
} }
}) })
</script> </script>
......
...@@ -54,7 +54,7 @@ export default Vue.extend({ ...@@ -54,7 +54,7 @@ export default Vue.extend({
components:{ components:{
'search-bar':()=>import('@/components/common/search-bar.vue'), 'search-bar':()=>import('@/components/common/search-bar.vue'),
'main-page': () => import('@/layout/main-page.vue'), 'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'), // 'app-icon': () => import('@/components/common/Icon.vue'),
'search-history': () => import('@/views/client/components/search-history.vue') 'search-history': () => import('@/views/client/components/search-history.vue')
// 'client-card': () => import('@/views/client/components/client-card.vue') // 'client-card': () => import('@/views/client/components/client-card.vue')
}, },
......
<template>
<!-- 标签管理 -->
<main-page
left-arrow
@click-left="$router.go(-1)"
>
<app-icon
slot="right"
icon-name="plus-black"
@click="addTag"
/>
<div class="pt-12 px-4 pb-4">
<template v-for="tag in tagList">
<tag-card
:key="tag.id"
:tag="tag"
class="mb-4"
@click="clickCard(tag)"
/>
</template>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import * as Tags from '@/DTO/tags'
export default Vue.extend({
components:{
// 'search-bar':()=>import('@/components/common/search-bar.vue'),
'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'tag-card': () => import('@/views/client/components/tag-card.vue')
},
name: 'TagManagement',
data() {
const { tagList } = Tags
return {
tagList
}
},
methods: {
addTag() {
this.$router.push('/add-tag')
},
clickCard(tag: Tags.Tag) {
console.log(tag)
this.$router.push(`/edit-tag/${tag.id}`)
}
}
})
</script>
<style lang="less">
</style>
...@@ -25,14 +25,18 @@ module.exports = { ...@@ -25,14 +25,18 @@ module.exports = {
// 按钮 // 按钮
'button-disabled': '#C8D3DE', 'button-disabled': '#C8D3DE',
// 标签 // 标签
'tag-blue-lighter': '#EAF6FF', 'tag-primary': '#32B2F7',
'tag-primary-lighter': '#EAF6FF',
'tag-orange': '#FD8800', 'tag-orange': '#FD8800',
'tag-orange-lighter': '#FAF2D8', 'tag-orange-lighter': '#FAF2D8',
'tag-green': '#4CD15F', 'tag-green': '#4CD15F',
'tag-green-lighter': '#E5F7F0', 'tag-green-lighter': '#E5F7F0',
'tag-yellow': '#F3B200', 'tag-yellow': '#F3B200',
'tag-yellow-lighter': '#FAF5D7',
'tag-red': '#EB8282', 'tag-red': '#EB8282',
'tag-red-lighter': '#FAEEEE',
'tag-purple': '#9F82E5', 'tag-purple': '#9F82E5',
'tag-purple-lighter': '#F1ECFD',
}, },
spacing: { spacing: {
......
...@@ -17,6 +17,11 @@ module.exports = { ...@@ -17,6 +17,11 @@ module.exports = {
} }
} }
}, },
devServer: {
proxy: 'http://localhost:8080', // 请求的ip或者域名:端口号
public: '127.0.0.1:8080', // 本地的ip:端口号
port: '8080'
}
// pwa: { // pwa: {
// name: 'My App', // name: 'My App',
// themeColor: '#4DBA87', // themeColor: '#4DBA87',
......
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