Commit cd11800a authored by Zhang Xiaojie's avatar Zhang Xiaojie

Merge remote-tracking branch 'origin/main' into zxj_dev

parents f3c12de3 535f295d
...@@ -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
<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: {
......
...@@ -33,5 +33,26 @@ export const clientRoutes: Array<RouteConfig> = [ ...@@ -33,5 +33,26 @@ 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: '编辑标签'
}
} }
] ]
\ 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>
...@@ -68,25 +68,21 @@ ...@@ -68,25 +68,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>
......
...@@ -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">
<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>
...@@ -39,7 +39,7 @@ export default Vue.extend({ ...@@ -39,7 +39,7 @@ export default Vue.extend({
// 'c-tag': () => import('@/components/common/c-tag.vue'), // 'c-tag': () => import('@/components/common/c-tag.vue'),
'client-card': () => import('@/views/client/components/client-card.vue') 'client-card': () => import('@/views/client/components/client-card.vue')
}, },
name: 'ClientManagement', name: 'EditClient',
data() { data() {
return { return {
tabs: [ tabs: [
......
<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.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() {
}
}
})
</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>
...@@ -24,12 +24,28 @@ module.exports = { ...@@ -24,12 +24,28 @@ module.exports = {
'linear-b': '#066BA2', 'linear-b': '#066BA2',
// 按钮 // 按钮
'button-disabled': '#C8D3DE', 'button-disabled': '#C8D3DE',
<<<<<<< HEAD
// 员工信息背景色 // 员工信息背景色
"bg-deep":'#0D73AD', "bg-deep":'#0D73AD',
// 异常字体颜色 // 异常字体颜色
"text-warning":'#CF4646', "text-warning":'#CF4646',
// 异常背景颜色 // 异常背景颜色
"bg-warning":'#FAEEEE', "bg-warning":'#FAEEEE',
=======
// 标签
'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-yellow-lighter': '#FAF5D7',
'tag-red': '#EB8282',
'tag-red-lighter': '#FAEEEE',
'tag-purple': '#9F82E5',
'tag-purple-lighter': '#F1ECFD',
>>>>>>> origin/main
}, },
spacing: { spacing: {
......
...@@ -17,6 +17,11 @@ module.exports = { ...@@ -17,6 +17,11 @@ module.exports = {
} }
} }
}, },
devServer: {
proxy: 'http://118.24.233.110', // 请求的ip或者域名:端口号
public: '192.168.0.109: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