【招生小程序】 新增# 1、对接电销的添加跟进、跟进记录列表;2、对接招生的添加进展;3、修复:刷新页面时底部导航栏显示首页路径错误;4、修复:点击底部导航栏中的总结模板后,再点击首页后,页面无反应的问题
parent
2de7edf2d4
commit
30d61360fa
|
@ -6,7 +6,7 @@
|
||||||
# @FilePath: \chargingpile-uniapp\.env.development
|
# @FilePath: \chargingpile-uniapp\.env.development
|
||||||
###
|
###
|
||||||
# 请求域名
|
# 请求域名
|
||||||
# VITE_APP_BASE_URL= 'http://120.77.216.5:8084'
|
# VITE_APP_BASE_URL= 'http://192.168.111.5:8086'
|
||||||
VITE_APP_BASE_URL="http://192.168.111.98:8084"
|
VITE_APP_BASE_URL="http://192.168.111.98:8086"
|
||||||
# VITE_APP_BASE_URL="https://wechat.szcxj2024.com"
|
# VITE_APP_BASE_URL="https://124.220.209.120:8086"
|
||||||
# VITE_APP_SOCKET_URL = 'wss://front.yuegoodlife.com'
|
# VITE_APP_SOCKET_URL = 'wss://front.yuegoodlife.com'
|
23
src/App.vue
23
src/App.vue
|
@ -13,7 +13,7 @@ import { getAllDict } from '@/hooks/useDictOptions'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
// getAllDict()
|
getAllDict()
|
||||||
|
|
||||||
onLaunch(async () => {
|
onLaunch(async () => {
|
||||||
appStore.getSystemInfoFn()
|
appStore.getSystemInfoFn()
|
||||||
|
@ -24,28 +24,9 @@ onLaunch(async () => {
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
const token = userStore.token
|
const token = userStore.token
|
||||||
if (token) {
|
if (token) {
|
||||||
await appStore.getConfig()
|
// await appStore.getConfig()
|
||||||
appStore.updateLocation()
|
appStore.updateLocation()
|
||||||
} else appStore.closeTimer()
|
} else appStore.closeTimer()
|
||||||
})
|
})
|
||||||
|
|
||||||
// function genDates() {
|
|
||||||
// const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
|
||||||
// const currentDate = new Date()
|
|
||||||
// const currentDayOfWeek = currentDate.getDay()
|
|
||||||
// let preDateOfWeek = currentDate.getDate() - 1
|
|
||||||
// const daysInRange = []
|
|
||||||
// for (let i = currentDayOfWeek; i <= weekdays.length - 1; i++) {
|
|
||||||
// preDateOfWeek = preDateOfWeek + 1
|
|
||||||
// daysInRange.push(preDateOfWeek)
|
|
||||||
// }
|
|
||||||
// let currentDateOfWeek = currentDate.getDate()
|
|
||||||
// for (let i = 0; i <= weekdays.length - daysInRange.length; i++) {
|
|
||||||
// currentDateOfWeek = currentDateOfWeek - 1
|
|
||||||
// daysInRange.unshift(currentDateOfWeek)
|
|
||||||
// }
|
|
||||||
// console.log(daysInRange)
|
|
||||||
// }
|
|
||||||
// genDates()
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 新增线索
|
||||||
|
export function apiAddCluse(params: any) {
|
||||||
|
return request.post({ url: '/clue/add', data: params })
|
||||||
|
}
|
||||||
|
// 线索列表
|
||||||
|
export function apiCluseList(params: any) {
|
||||||
|
return request.get({ url: '/clue/list', data: params })
|
||||||
|
}
|
||||||
|
// 领取线索
|
||||||
|
export function apiGetCluse(params: any) {
|
||||||
|
return request.post({ url: '/clue/grabTheOrder', data: params })
|
||||||
|
}
|
||||||
|
// 线索详情
|
||||||
|
export function apiCluseDetail(params: any) {
|
||||||
|
return request.get({ url: '/clue/detail', data: params })
|
||||||
|
}
|
||||||
|
// 添加进展
|
||||||
|
export function apiAddCluseProgress(params: any) {
|
||||||
|
return request.post({ url: '/clue/addProgress', data: params })
|
||||||
|
}
|
||||||
|
// 转化完成
|
||||||
|
export function apiCompleteCluse(params: any) {
|
||||||
|
return request.post({ url: '/clue/conversionCompleted', data: params })
|
||||||
|
}
|
||||||
|
// 修改备注
|
||||||
|
export function apiEditRemark(params: any) {
|
||||||
|
return request.post({ url: '/clue/modifyRemarks', data: params })
|
||||||
|
}
|
||||||
|
// 修改跟进
|
||||||
|
export function apiEditClue(params: any) {
|
||||||
|
return request.post({ url: '/clue/edit', data: params })
|
||||||
|
}
|
|
@ -2,10 +2,13 @@ import request from '@/utils/request'
|
||||||
|
|
||||||
// 所有字典以及字典下的所有数据
|
// 所有字典以及字典下的所有数据
|
||||||
export function dictAllDataList() {
|
export function dictAllDataList() {
|
||||||
return request.get({
|
return request.get(
|
||||||
url: '/setting/dict/type/allDataList',
|
{
|
||||||
data: {
|
url: '/setting/dict/type/allDataList',
|
||||||
pageSize: 60
|
data: {
|
||||||
}
|
pageSize: 60
|
||||||
})
|
}
|
||||||
|
},
|
||||||
|
{ isAuth: true }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ async function handleLogin(e) {
|
||||||
scene: LoginTypeEnum.MNP,
|
scene: LoginTypeEnum.MNP,
|
||||||
iv: e.detail.iv,
|
iv: e.detail.iv,
|
||||||
encryptedData: e.detail.encryptedData,
|
encryptedData: e.detail.encryptedData,
|
||||||
channel: ChannelEnum.STAFF_PLATFORM
|
channel: ChannelEnum.USER_PLATFORM
|
||||||
})
|
})
|
||||||
// 保存登录数据
|
// 保存登录数据
|
||||||
loginData.value = data
|
loginData.value = data
|
||||||
|
@ -228,14 +228,14 @@ async function loginHandle(data: any) {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
await userStore.getUser()
|
await userStore.getUser()
|
||||||
// 获取系统配置
|
// 获取系统配置
|
||||||
await appStore.getConfig()
|
// await appStore.getConfig()
|
||||||
|
|
||||||
// 显示登录成功提示
|
// 显示登录成功提示
|
||||||
uni.$u.toast('登录成功')
|
uni.$u.toast('登录成功')
|
||||||
|
|
||||||
// 隐藏登录加载框
|
// 隐藏登录加载框
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
appStore.setFirstLogin(true)
|
// appStore.setFirstLogin(true)
|
||||||
const { userInfo } = userStore
|
const { userInfo } = userStore
|
||||||
if (userInfo.roles?.length > 1) {
|
if (userInfo.roles?.length > 1) {
|
||||||
uni.redirectTo({
|
uni.redirectTo({
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
<view class="bg-[#FAFAFE]">
|
<view class="bg-[#FAFAFE]">
|
||||||
<view class="bg-white px-[32rpx]">
|
<view class="bg-white px-[32rpx]">
|
||||||
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||||
<TFormItem prop="publishName">
|
<TFormItem prop="recruitTeacherName">
|
||||||
<TInputField
|
<TInputField
|
||||||
v-model="form.publishName"
|
v-model="form.recruitTeacherName"
|
||||||
label="发布人"
|
label="发布人"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
inputAlign="left"
|
inputAlign="left"
|
||||||
|
@ -13,9 +13,9 @@
|
||||||
:labelWidth="100"
|
:labelWidth="100"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="clientName">
|
<TFormItem prop="studentName">
|
||||||
<TInputField
|
<TInputField
|
||||||
v-model="form.clientName"
|
v-model="form.studentName"
|
||||||
label="客户姓名"
|
label="客户姓名"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
inputAlign="left"
|
inputAlign="left"
|
||||||
|
@ -24,9 +24,9 @@
|
||||||
:labelWidth="100"
|
:labelWidth="100"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="mobile">
|
<TFormItem prop="phone">
|
||||||
<TInputField
|
<TInputField
|
||||||
v-model="form.mobile"
|
v-model="form.phone"
|
||||||
label="电话"
|
label="电话"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
inputAlign="left"
|
inputAlign="left"
|
||||||
|
@ -35,8 +35,9 @@
|
||||||
:labelWidth="100"
|
:labelWidth="100"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="desc">
|
<TFormItem prop="basicInformation">
|
||||||
<TTextareaField
|
<TTextareaField
|
||||||
|
v-model="form.basicInformation"
|
||||||
label="基本情况"
|
label="基本情况"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
autoHeight
|
autoHeight
|
||||||
|
@ -45,9 +46,9 @@
|
||||||
:labelWidth="100"
|
:labelWidth="100"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="status">
|
<TFormItem prop="state">
|
||||||
<TMultiSelect
|
<TMultiSelect
|
||||||
v-model="form.status"
|
v-model="form.state"
|
||||||
label="状态"
|
label="状态"
|
||||||
:groupList="statusList"
|
:groupList="statusList"
|
||||||
:labelWidth="100"
|
:labelWidth="100"
|
||||||
|
@ -56,50 +57,84 @@
|
||||||
</TForm>
|
</TForm>
|
||||||
</view>
|
</view>
|
||||||
<view class="px-[60rpx]">
|
<view class="px-[60rpx]">
|
||||||
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleSubmit">
|
<u-button
|
||||||
提交
|
class="btn"
|
||||||
|
color="#0E66FB"
|
||||||
|
shape="circle"
|
||||||
|
:loading="loading"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
提交{{ form.state }}
|
||||||
</u-button>
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { apiAddCluseProgress, apiCluseEdit } from '@/api/clue'
|
||||||
|
import { stateEnum } from '@/enums'
|
||||||
|
import { useClueDetail } from '@/hooks/useCommon'
|
||||||
|
import { toast } from '@/utils/util'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { shallowRef } from 'vue'
|
import { shallowRef } from 'vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const { fetchClueDetail, clueDetailInfo } = useClueDetail()
|
||||||
|
|
||||||
const id = ref('')
|
const id = ref('')
|
||||||
|
|
||||||
const tForm = ref()
|
const tForm = ref()
|
||||||
const form = ref({
|
const form = ref({
|
||||||
publishName: '',
|
id: '',
|
||||||
clientName: '张三',
|
recruitTeacherName: '',
|
||||||
mobile: '',
|
studentName: '',
|
||||||
desc: '',
|
phone: '',
|
||||||
status: ''
|
basicInformation: '',
|
||||||
|
state: null
|
||||||
})
|
})
|
||||||
const rules = {
|
const rules = {
|
||||||
status: [{ required: true, message: '请选择状态' }]
|
state: [{ required: true, message: '请选择状态' }]
|
||||||
}
|
}
|
||||||
const statusList = shallowRef([
|
const statusList = shallowRef([
|
||||||
{ label: '账号已添加', value: 1 },
|
{ label: '账号已添加', value: stateEnum.ADD_RELATION },
|
||||||
{ label: '账号不存在', value: 2 },
|
{ label: '账号不存在', value: stateEnum.NO_EXIST },
|
||||||
{ label: '账号未通过', value: 3 }
|
{ label: '账号未通过', value: stateEnum.UN_PASS }
|
||||||
])
|
])
|
||||||
onLoad(option => {
|
onLoad(async option => {
|
||||||
if (option?.id) {
|
if (option?.id) {
|
||||||
id.value = option.id
|
id.value = option.id
|
||||||
|
await fetchClueDetail(id.value)
|
||||||
|
setFormData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const loading = ref(false)
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
tForm.value
|
tForm.value
|
||||||
.validate()
|
.validate()
|
||||||
.then(valid => {
|
.then(async valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
console.log('校验通过')
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
id: form.value.id,
|
||||||
|
state: form.value.state
|
||||||
|
}
|
||||||
|
await apiAddCluseProgress(data)
|
||||||
|
toast('添加进展成功')
|
||||||
|
uni.navigateBack()
|
||||||
|
uni.$emit('refreshPage')
|
||||||
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
const setFormData = () => {
|
||||||
|
for (const key in clueDetailInfo.value) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(form.value, key)) {
|
||||||
|
form.value[key] = clueDetailInfo.value[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
.wrapper {
|
.wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: #fafafe;
|
|
||||||
@apply flex flex-col;
|
@apply flex flex-col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,13 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const resetFields = () => {
|
||||||
|
instance.proxy.children.map(child => {
|
||||||
|
const prop = child.prop
|
||||||
|
const value = uni.$u.getProperty(originalModel.value, prop)
|
||||||
|
uni.$u.setProperty(props.model, prop, value)
|
||||||
|
})
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => props.rules,
|
() => props.rules,
|
||||||
newVal => {
|
newVal => {
|
||||||
|
@ -139,7 +146,8 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
children: [],
|
children: [],
|
||||||
validate
|
validate,
|
||||||
|
resetFields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
:inputAlign="inputAlign"
|
:inputAlign="inputAlign"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:maxlength="maxlength"
|
:maxlength="maxlength"
|
||||||
|
placeholderStyle="color: '#7c7e82'"
|
||||||
></u-input>
|
></u-input>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -58,7 +58,6 @@ const innerValue = ref(props.modelValue)
|
||||||
const handleSelectedItem = (val: number) => {
|
const handleSelectedItem = (val: number) => {
|
||||||
emit('update:modelValue', val)
|
emit('update:modelValue', val)
|
||||||
innerValue.value = val
|
innerValue.value = val
|
||||||
console.log(val)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ const props = defineProps({
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue', 'onInput'])
|
||||||
|
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ const isShowClear = computed(() => {
|
||||||
const onInput = e => {
|
const onInput = e => {
|
||||||
innerValue.value = e.detail.value
|
innerValue.value = e.detail.value
|
||||||
emit('update:modelValue', innerValue.value)
|
emit('update:modelValue', innerValue.value)
|
||||||
|
emit('onInput')
|
||||||
}
|
}
|
||||||
const onClear = () => {
|
const onClear = () => {
|
||||||
innerValue.value = ''
|
innerValue.value = ''
|
||||||
|
|
|
@ -47,8 +47,8 @@ const { roles } = useRoleData()
|
||||||
const emit = defineEmits(['update:modelValue', 'close'])
|
const emit = defineEmits(['update:modelValue', 'close'])
|
||||||
const activeRole = ref(props.modelValue)
|
const activeRole = ref(props.modelValue)
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
let currentRoutes = getCurrentPages() // 获取当前打开过的页面路由数组
|
const currentRoutes = getCurrentPages() // 获取当前打开过的页面路由数组
|
||||||
let currentRoute = currentRoutes[currentRoutes.length - 1].route //获取当前页面路由
|
const currentRoute = currentRoutes[currentRoutes.length - 1].route //获取当前页面路由
|
||||||
const handleActiveRole = (val: number) => {
|
const handleActiveRole = (val: number) => {
|
||||||
activeRole.value = val
|
activeRole.value = val
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ const props = withDefaults(defineProps<TabBarProps>(), {
|
||||||
|
|
||||||
const tabBarStore = useTabBarStore()
|
const tabBarStore = useTabBarStore()
|
||||||
const { tabBarList, activeTabBar } = storeToRefs(tabBarStore)
|
const { tabBarList, activeTabBar } = storeToRefs(tabBarStore)
|
||||||
|
|
||||||
const handleTabbar = (index: number) => {
|
const handleTabbar = (index: number) => {
|
||||||
tabBarStore.setActiveTabBar(index)
|
tabBarStore.setActiveTabBar(index)
|
||||||
navigateTo(unref(tabBarList)[index], 'reLaunch')
|
navigateTo(unref(tabBarList)[index], 'reLaunch')
|
||||||
|
|
|
@ -8,12 +8,7 @@
|
||||||
<view class="px-[24rpx] py-[16rpx] flex flex-col gap-[16rpx]">
|
<view class="px-[24rpx] py-[16rpx] flex flex-col gap-[16rpx]">
|
||||||
<slot name="content" />
|
<slot name="content" />
|
||||||
</view>
|
</view>
|
||||||
<view
|
<slot name="action" v-if="isSlotAction" />
|
||||||
class="px-[32rpx] border-t border-solid border-[#F3F3F3] flex justify-end py-[12rpx]"
|
|
||||||
v-if="isSlotAction"
|
|
||||||
>
|
|
||||||
<slot name="action" />
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
curDate: {
|
curDate: {
|
||||||
type: String,
|
type: Number,
|
||||||
default: new Date().getTime()
|
default: new Date().getTime()
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<template #title>
|
<template #title>
|
||||||
<view class="flex justify-between w-full py-[10rpx]">
|
<view class="flex justify-between w-full py-[10rpx]">
|
||||||
<view class="flex">
|
<view class="flex">
|
||||||
<text>韩梅梅</text>
|
<text>{{ item.studentName }}</text>
|
||||||
<view class="flex ml-[48rpx] gap-[4rpx] items-center">
|
<view class="flex ml-[48rpx] gap-[4rpx] items-center">
|
||||||
<text class="text-primary">18138952909</text>
|
<text class="text-primary">{{ item.phone }}</text>
|
||||||
<u-copy content="uview-plus is great !">
|
<u-copy content="uview-plus is great !">
|
||||||
<TIcon name="icon-copy" color="#0E66FB" />
|
<TIcon name="icon-copy" color="#0E66FB" />
|
||||||
</u-copy>
|
</u-copy>
|
||||||
|
@ -15,7 +15,10 @@
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<view class="flex flex-col gap-[16rpx]">
|
<view class="flex flex-col gap-[16rpx]">
|
||||||
<view class="flex gap-[8rpx] items-center">
|
<view
|
||||||
|
class="flex gap-[8rpx] items-center"
|
||||||
|
v-if="item.situation == converStatusEnum.EXCEPTION"
|
||||||
|
>
|
||||||
<TIcon name="icon-warning" color="#F5222D" />
|
<TIcon name="icon-warning" color="#F5222D" />
|
||||||
<text class="text-error">待电销老师重新跟进</text>
|
<text class="text-error">待电销老师重新跟进</text>
|
||||||
</view>
|
</view>
|
||||||
|
@ -23,22 +26,33 @@
|
||||||
<text class="text-muted w-[128rpx]">基本情况</text>
|
<text class="text-muted w-[128rpx]">基本情况</text>
|
||||||
<view class="flex gap-[4rpx] flex-1 items-end">
|
<view class="flex gap-[4rpx] flex-1 items-end">
|
||||||
<text>
|
<text>
|
||||||
学生爸爸接电话,学生高三毕业,300多分,家长不清楚学生收到录取通知,家长说学生不读书了,我让家长先问问学生对未来的规划先和学生沟通一下,家长同意我们加他微信发专业资料给他看看,可以在微信上问问学生具体情况。推荐3+2,给家长发一下学校简介和专业资料。
|
{{ item.basicInformation }}
|
||||||
</text>
|
</text>
|
||||||
<u-copy content="uview-plus is great !">
|
<u-copy content="uview-plus is great !">
|
||||||
<TIcon name="icon-copy" color="#0E66FB" />
|
<TIcon name="icon-copy" color="#0E66FB" />
|
||||||
</u-copy>
|
</u-copy>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx]">
|
<view class="flex gap-[20rpx]" v-if="item.telemarketingTeacherId !== null">
|
||||||
<text class="text-muted w-[128rpx]">电销老师</text>
|
<text class="text-muted w-[128rpx]">电销老师</text>
|
||||||
<text class="flex-1">王五</text>
|
<text class="flex-1">{{ item.telemarketingTeacherName }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx]">
|
<view
|
||||||
|
class="flex gap-[20rpx]"
|
||||||
|
v-if="
|
||||||
|
item.situation == converStatusEnum.CONVERTED_PROCESS && item.state !== null
|
||||||
|
"
|
||||||
|
>
|
||||||
<text class="text-muted w-[128rpx]">状态</text>
|
<text class="text-muted w-[128rpx]">状态</text>
|
||||||
<text class="flex-1 text-error">账号不存在</text>
|
<text class="flex-1 text-error">{{ parseStateText }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx]">
|
<view
|
||||||
|
class="flex gap-[20rpx]"
|
||||||
|
v-if="
|
||||||
|
item.situation == converStatusEnum.CONVERTED ||
|
||||||
|
item.situation == converStatusEnum.FAILED
|
||||||
|
"
|
||||||
|
>
|
||||||
<text class="text-muted w-[128rpx]">备注</text>
|
<text class="text-muted w-[128rpx]">备注</text>
|
||||||
<view class="flex gap-[12rpx]">
|
<view class="flex gap-[12rpx]">
|
||||||
<text class="flex-1 text-error">已交一部分定位金</text>
|
<text class="flex-1 text-error">已交一部分定位金</text>
|
||||||
|
@ -51,19 +65,42 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx]">
|
<view class="flex gap-[20rpx]" v-if="item.situation == converStatusEnum.CONVERTED">
|
||||||
<text class="text-muted w-[128rpx]">成交时间</text>
|
<text class="text-muted w-[128rpx]">成交时间</text>
|
||||||
<text class="flex-1">2025-02-10 16:04:00</text>
|
<text class="flex-1">2025-02-10 16:04:00</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template #action>
|
<template #action>
|
||||||
<view class="flex justify-end gap-[16rpx]">
|
<view
|
||||||
<u-button color="#0E66FB" shape="circle" @click="handleGet">领取</u-button>
|
class="px-[32rpx] border-t border-solid border-[#F3F3F3] flex justify-end py-[12rpx]"
|
||||||
<u-button color="#0E66FB" shape="circle" @click="handleAddProgress">
|
>
|
||||||
添加进展
|
<view class="flex justify-end gap-[16rpx]">
|
||||||
</u-button>
|
<u-button
|
||||||
<u-button color="#0E66FB" shape="circle" @click="handleComplete">转化完成</u-button>
|
color="#0E66FB"
|
||||||
|
shape="circle"
|
||||||
|
v-if="item.situation == converStatusEnum.UN_RECEIVED"
|
||||||
|
@click="handleGet"
|
||||||
|
>
|
||||||
|
领取
|
||||||
|
</u-button>
|
||||||
|
<u-button
|
||||||
|
color="#0E66FB"
|
||||||
|
shape="circle"
|
||||||
|
v-if="item.situation == converStatusEnum.CONVERTED_PROCESS"
|
||||||
|
@click="handleAddProgress"
|
||||||
|
>
|
||||||
|
添加进展
|
||||||
|
</u-button>
|
||||||
|
<u-button
|
||||||
|
color="#0E66FB"
|
||||||
|
shape="circle"
|
||||||
|
v-if="item.situation == converStatusEnum.ADD_RELATION"
|
||||||
|
@click="handleComplete"
|
||||||
|
>
|
||||||
|
转化完成
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</w-card>
|
</w-card>
|
||||||
|
@ -71,18 +108,36 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { toast } from '@/utils/util'
|
import { toast } from '@/utils/util'
|
||||||
|
import { PropType } from 'vue'
|
||||||
|
import { IClue } from '../telesale/clue-card.vue'
|
||||||
|
import { converStatusEnum, stateEnum } from '@/enums'
|
||||||
|
import { apiGetCluse } from '@/api/clue'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object as PropType<IClue>,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['handleUpdateRemark'])
|
const emit = defineEmits(['handleUpdateRemark', 'refreshPage'])
|
||||||
|
|
||||||
|
const stateMap: Record<stateEnum, string> = {
|
||||||
|
[stateEnum.ADD_RELATION]: '账号已添加',
|
||||||
|
[stateEnum.NO_EXIST]: '账号不存在',
|
||||||
|
[stateEnum.UN_PASS]: '账号未通过'
|
||||||
|
}
|
||||||
|
const parseStateText = computed(() => stateMap[props.item.state])
|
||||||
// 领取
|
// 领取
|
||||||
const handleGet = () => {
|
const handleGet = async () => {
|
||||||
const { item } = props
|
const {
|
||||||
toast('领取成功')
|
item: { id }
|
||||||
|
} = props
|
||||||
|
try {
|
||||||
|
await apiGetCluse({ id })
|
||||||
|
toast('领取成功')
|
||||||
|
emit('refreshPage')
|
||||||
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
// 添加进展
|
// 添加进展
|
||||||
const handleAddProgress = () => {
|
const handleAddProgress = () => {
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
<template #title>
|
<template #title>
|
||||||
<view class="flex justify-between w-full py-[10rpx]">
|
<view class="flex justify-between w-full py-[10rpx]">
|
||||||
<view class="flex">
|
<view class="flex">
|
||||||
<text>韩梅梅</text>
|
<text>{{ item.studentName }}</text>
|
||||||
<view class="flex ml-[48rpx] gap-[4rpx] items-center">
|
<view class="flex ml-[48rpx] gap-[4rpx] items-center">
|
||||||
<text class="text-primary">18138952909</text>
|
<text class="text-primary">{{ item.phone }}</text>
|
||||||
<u-copy content="uview-plus is great !">
|
<u-copy content="uview-plus is great !">
|
||||||
<TIcon name="icon-copy" color="#0E66FB" />
|
<TIcon name="icon-copy" color="#0E66FB" />
|
||||||
</u-copy>
|
</u-copy>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<text>待领取</text>
|
<text v-if="item.situation == converStatusEnum.UN_RECEIVED" class="text-[#ED6D41]">
|
||||||
|
待领取
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
|
@ -23,34 +25,62 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx] mb-[16rpx]">
|
<view class="flex gap-[20rpx] mb-[16rpx]">
|
||||||
<text class="text-muted w-[128rpx]">跟进时间</text>
|
<text class="text-muted w-[128rpx]">跟进时间</text>
|
||||||
<text class="flex-1">2025-02-08 11:11:30</text>
|
<text class="flex-1">{{ item.createTime }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx] mb-[16rpx]">
|
<view class="flex gap-[20rpx] mb-[16rpx]" v-if="item.recruitTeacherId !== null">
|
||||||
<text class="text-muted w-[128rpx]">招生老师</text>
|
<text class="text-muted w-[128rpx]">招生老师</text>
|
||||||
<text class="flex-1">王五</text>
|
<text class="flex-1">{{ item.recruitTeacherName }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex gap-[20rpx]">
|
<view class="flex gap-[20rpx]" v-if="item.state !== null">
|
||||||
<text class="text-muted w-[128rpx]">状态</text>
|
<text class="text-muted w-[128rpx]">状态</text>
|
||||||
<text class="flex-1">账号不存在</text>
|
<text class="flex-1">账号不存在</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template #action>
|
<template #action>
|
||||||
<u-button color="#0E66FB" shape="circle" @click="handleEditFollow">修改跟进</u-button>
|
<view
|
||||||
|
class="px-[32rpx] border-t border-solid border-[#F3F3F3] flex justify-end py-[12rpx]"
|
||||||
|
v-if="item.situation == converStatusEnum.EXCEPTION"
|
||||||
|
>
|
||||||
|
<u-button color="#0E66FB" shape="circle" @click="handleEditFollow">
|
||||||
|
修改跟进
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</w-card>
|
</w-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { PropType } from 'vue'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
import { converStatusEnum, stateEnum } from '@/enums'
|
||||||
|
|
||||||
|
export interface IClue {
|
||||||
|
studentName: string
|
||||||
|
phone: string
|
||||||
|
id: number
|
||||||
|
basicInformation: string
|
||||||
|
remark: string
|
||||||
|
isConversion: number
|
||||||
|
listSource: number //线索来源
|
||||||
|
state: stateEnum //状态
|
||||||
|
situation: number // 转化情况
|
||||||
|
createTime: string // 跟进时间
|
||||||
|
telemarketingTeacherName: string // 电销老师
|
||||||
|
recruitTeacherName: string // 招生老师
|
||||||
|
recruitTeacherId: number
|
||||||
|
telemarketingTeacherId: number
|
||||||
|
}
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object as PropType<IClue>,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const ellipsisDesc = computed(
|
const ellipsisDesc = computed(
|
||||||
() => item => item.desc?.length >= 14 ? item.desc?.slice(0, 14) + '...' : item.desc
|
() => (item: IClue) =>
|
||||||
|
item.basicInformation?.length >= 14
|
||||||
|
? item.basicInformation?.slice(0, 14) + '...'
|
||||||
|
: item.basicInformation
|
||||||
)
|
)
|
||||||
const handleEditFollow = () => {
|
const handleEditFollow = () => {
|
||||||
const { item } = props
|
const { item } = props
|
||||||
|
|
|
@ -2,57 +2,86 @@
|
||||||
<view class="mt-[32rpx] p-[32rpx] bg-white">
|
<view class="mt-[32rpx] p-[32rpx] bg-white">
|
||||||
<view class="flex justify-between items-center mb-[20rpx]">
|
<view class="flex justify-between items-center mb-[20rpx]">
|
||||||
<text class="text-[44rpx] font-bold">跟进信息</text>
|
<text class="text-[44rpx] font-bold">跟进信息</text>
|
||||||
<text class="text-[28rpx]">全部清空</text>
|
<text class="text-[28rpx]" @click="handleClear">全部清空</text>
|
||||||
</view>
|
</view>
|
||||||
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||||
<TFormItem prop="clientName">
|
<TFormItem prop="studentName">
|
||||||
<TInputField
|
<TInputField
|
||||||
v-model="form.clientName"
|
v-model="form.studentName"
|
||||||
label="客户姓名"
|
label="客户姓名"
|
||||||
placeholder="请填写客户姓名(必填)"
|
placeholder="请填写客户姓名(必填)"
|
||||||
inputAlign="left"
|
inputAlign="left"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="mobile">
|
<TFormItem prop="phone">
|
||||||
<TInputField
|
<TInputField
|
||||||
v-model="form.mobile"
|
v-model="form.phone"
|
||||||
label="电话"
|
label="电话"
|
||||||
placeholder="请填写电话(必填)"
|
placeholder="请填写电话(必填)"
|
||||||
inputAlign="left"
|
inputAlign="left"
|
||||||
/>
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
<TFormItem prop="desc">
|
<TFormItem prop="basicInformation">
|
||||||
<TTextareaField label="基本情况" placeholder="请填写基本情况(必填)" autoHeight />
|
<TTextareaField
|
||||||
|
v-model="form.basicInformation"
|
||||||
|
label="基本情况"
|
||||||
|
placeholder="请填写基本情况(必填)"
|
||||||
|
autoHeight
|
||||||
|
/>
|
||||||
</TFormItem>
|
</TFormItem>
|
||||||
</TForm>
|
</TForm>
|
||||||
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleConfirm">确认</u-button>
|
<u-button
|
||||||
|
class="btn"
|
||||||
|
color="#0E66FB"
|
||||||
|
shape="circle"
|
||||||
|
:loading="loading"
|
||||||
|
@click="handleConfirm"
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</u-button>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { apiAddCluse } from '@/api/clue'
|
||||||
|
import { toast, validate } from '@/utils/util'
|
||||||
|
import { validateContact } from '@/utils/validate'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const tForm = ref()
|
const tForm = ref()
|
||||||
const form = ref({
|
const form = ref({
|
||||||
clientName: '',
|
studentName: '',
|
||||||
mobile: '',
|
phone: '',
|
||||||
desc: ''
|
basicInformation: ''
|
||||||
})
|
})
|
||||||
|
const loading = ref(false)
|
||||||
const rules = {
|
const rules = {
|
||||||
clientName: [{ required: true, message: '请填写客户姓名', trigger: 'blur' }],
|
studentName: [{ required: true, message: '请填写客户姓名', trigger: 'blur' }],
|
||||||
mobile: [{ required: true, message: '请填写电话', trigger: 'blur' }],
|
phone: [
|
||||||
desc: [{ required: true, message: '请填写基本情况', trigger: 'blur' }]
|
{ required: true, message: '请填写电话', trigger: 'blur' },
|
||||||
|
{ validator: validateContact, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
basicInformation: [{ required: true, message: '请填写基本情况', trigger: 'blur' }]
|
||||||
}
|
}
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
tForm.value
|
tForm.value
|
||||||
.validate()
|
.validate()
|
||||||
.then(valid => {
|
.then(async valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
console.log('校验通过')
|
loading.value = true
|
||||||
|
try {
|
||||||
|
await apiAddCluse(form.value)
|
||||||
|
toast('添加成功')
|
||||||
|
handleClear()
|
||||||
|
} catch (error) {}
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
}
|
}
|
||||||
|
const handleClear = () => {
|
||||||
|
tForm.value.resetFields()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
@ -1,46 +1,47 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="flex-1 h-full flex flex-col">
|
<view class="flex-1 h-full flex flex-col">
|
||||||
<TSearch
|
<TSearch
|
||||||
v-model="searchValue"
|
v-model="queryParams.likeWork"
|
||||||
placeholder="搜索客户姓名/手机号码"
|
placeholder="搜索客户姓名/手机号码"
|
||||||
backgroundColor="#F5F5F5"
|
backgroundColor="#F5F5F5"
|
||||||
|
@on-input="searchChange"
|
||||||
/>
|
/>
|
||||||
<view class="flex-1 mt-3 px-2 overflow-auto bg-[#FAFAFE]">
|
<view class="flex-1 mt-3 px-2 overflow-auto bg-[#FAFAFE]">
|
||||||
<!-- <z-paging
|
<z-paging
|
||||||
ref="paging"
|
ref="paging"
|
||||||
v-model="dataList"
|
v-model="dataList"
|
||||||
@query="queryList"
|
@query="queryList"
|
||||||
:fixed="false"
|
:fixed="false"
|
||||||
height="100%"
|
height="100%"
|
||||||
> -->
|
>
|
||||||
|
<clue-card
|
||||||
<clue-card
|
v-for="(item, index) in dataList"
|
||||||
v-for="(item, index) in dataList"
|
:key="`${index} + 'unique'`"
|
||||||
:key="`${index} + 'unique'`"
|
:item="item"
|
||||||
:item="item"
|
/>
|
||||||
/>
|
</z-paging>
|
||||||
<!-- </z-paging> -->
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiOverhaulPagelist } from '@/api/overhaul'
|
|
||||||
import { useZPaging } from '@/hooks/useZPaging'
|
import { useZPaging } from '@/hooks/useZPaging'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import clueCard from './clue-card.vue'
|
import clueCard from './clue-card.vue'
|
||||||
|
import { apiCluseList } from '@/api/clue'
|
||||||
|
import { debounce } from 'lodash-es'
|
||||||
|
|
||||||
const searchValue = ref('')
|
const queryParams = ref({
|
||||||
const queryParams = ref({})
|
likeWork: ''
|
||||||
const dataList = ref([
|
})
|
||||||
{
|
const dataList = ref([])
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
])
|
|
||||||
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
||||||
queryParams.value,
|
queryParams.value,
|
||||||
apiOverhaulPagelist,
|
apiCluseList,
|
||||||
() => {}
|
() => {}
|
||||||
)
|
)
|
||||||
|
const searchChange = debounce(() => {
|
||||||
|
refresh()
|
||||||
|
}, 300)
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -6,8 +6,8 @@ export enum ThemeEnum {
|
||||||
DARK = 'dark'
|
DARK = 'dark'
|
||||||
}
|
}
|
||||||
export enum ChannelEnum {
|
export enum ChannelEnum {
|
||||||
USER_PLATFORM = 0,
|
USER_PLATFORM = 0, // 用户端
|
||||||
STAFF_PLATFORM = 1
|
STAFF_PLATFORM = 1 //师傅端
|
||||||
}
|
}
|
||||||
// 客户端
|
// 客户端
|
||||||
export enum ClientEnum {
|
export enum ClientEnum {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
export enum teleSaleEnum {
|
||||||
|
ADD_FOLLOW = 0,
|
||||||
|
FOLLOW_RECORD = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum converStatusEnum {
|
||||||
|
INTENTION = 0, //有意向
|
||||||
|
UN_RECEIVED = 1, //待领取
|
||||||
|
CONVERTED_PROCESS = 2, //转化中
|
||||||
|
ADD_RELATION = 3, //已添加
|
||||||
|
EXCEPTION = 4, //异常待处理
|
||||||
|
CONVERTED = 5, //已成交
|
||||||
|
FAILED = 6 //已战败
|
||||||
|
}
|
||||||
|
export enum stateEnum {
|
||||||
|
ADD_RELATION = 0, //账号已添加
|
||||||
|
NO_EXIST = 1, //账号不存在
|
||||||
|
UN_PASS = 2 //账号未通过
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { apiCluseDetail } from '@/api/clue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// 获取线索详情
|
||||||
|
export function useClueDetail() {
|
||||||
|
const clueDetailInfo = ref()
|
||||||
|
const fetchClueDetail = async (id: number | string) => {
|
||||||
|
uni.showLoading({
|
||||||
|
title: '加载中'
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
const result = await apiCluseDetail({ id })
|
||||||
|
clueDetailInfo.value = result
|
||||||
|
} catch (error) {}
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
clueDetailInfo,
|
||||||
|
fetchClueDetail
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,110 +23,50 @@ export interface RoleItem {
|
||||||
export function useRoleData() {
|
export function useRoleData() {
|
||||||
const roles: RoleItem[] = [
|
const roles: RoleItem[] = [
|
||||||
{
|
{
|
||||||
name: '业务员',
|
name: '电销老师',
|
||||||
ids: [8, 9],
|
ids: [5],
|
||||||
tabBarList: [
|
tabBarList: [
|
||||||
{
|
{
|
||||||
text: '客户库',
|
text: '首页',
|
||||||
|
path: '/pages/telesale/home/index',
|
||||||
inactiveIcon: clientInActive,
|
inactiveIcon: clientInActive,
|
||||||
activeIcon: clientActive,
|
activeIcon: clientActive
|
||||||
path: '/pages/salesman/client/index'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '合同管理',
|
text: '总结模板',
|
||||||
path: '/pages/salesman/contract/index',
|
path: '/pages/telesale/summary/index',
|
||||||
inactiveIcon: contractInActive,
|
inactiveIcon: contractInActive,
|
||||||
activeIcon: contractActive
|
activeIcon: contractActive
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '个人中心',
|
text: '个人中心',
|
||||||
path: '/pages/salesman/profile/index',
|
path: '/pages/telesale/my/index',
|
||||||
inactiveIcon: profileInActive,
|
inactiveIcon: profileInActive,
|
||||||
activeIcon: profileActive
|
activeIcon: profileActive
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '检修员',
|
name: '招生老师',
|
||||||
ids: [6],
|
ids: [6],
|
||||||
tabBarList: [
|
tabBarList: [
|
||||||
{
|
{
|
||||||
text: '工单池',
|
text: '首页',
|
||||||
inactiveIcon: order,
|
inactiveIcon: order,
|
||||||
activeIcon: orderActive,
|
activeIcon: orderActive,
|
||||||
path: '/pages/overhaul/pool/index'
|
path: '/pages/recruitsale/home/index'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '我的任务',
|
text: '总结模板',
|
||||||
|
path: '/pages/recruitsale/summary/index',
|
||||||
inactiveIcon: task,
|
inactiveIcon: task,
|
||||||
activeIcon: taskActive,
|
activeIcon: taskActive
|
||||||
path: '/pages/overhaul/task/index'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '个人中心',
|
text: '个人中心',
|
||||||
|
path: '/pages/recruitsale/my/index',
|
||||||
inactiveIcon: profileInActive,
|
inactiveIcon: profileInActive,
|
||||||
activeIcon: profileActive,
|
activeIcon: profileActive
|
||||||
path: '/pages/overhaul/my/index'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '客户',
|
|
||||||
ids: [1, 2, 11],
|
|
||||||
tabBarList: [
|
|
||||||
{
|
|
||||||
text: '工单记录',
|
|
||||||
inactiveIcon: order,
|
|
||||||
activeIcon: orderActive,
|
|
||||||
path: '/pages/client/workOrder/index'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '个人中心',
|
|
||||||
inactiveIcon: profileInActive,
|
|
||||||
activeIcon: profileActive,
|
|
||||||
path: '/pages/client/my/index'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '维修员',
|
|
||||||
ids: [7],
|
|
||||||
tabBarList: [
|
|
||||||
// {
|
|
||||||
// text: '工单池',
|
|
||||||
// inactiveIcon: order,
|
|
||||||
// activeIcon: orderActive,
|
|
||||||
// path: '/pages/repair/pool/index'
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
text: '工单列表',
|
|
||||||
inactiveIcon: task,
|
|
||||||
activeIcon: taskActive,
|
|
||||||
path: '/pages/repair/task/index'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '个人中心',
|
|
||||||
inactiveIcon: profileInActive,
|
|
||||||
activeIcon: profileActive,
|
|
||||||
path: '/pages/repair/my/index'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '维修主管',
|
|
||||||
ids: [10],
|
|
||||||
tabBarList: [
|
|
||||||
{
|
|
||||||
text: '工单列表',
|
|
||||||
inactiveIcon: task,
|
|
||||||
activeIcon: taskActive,
|
|
||||||
path: '/pages/charge/order/index'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '个人中心',
|
|
||||||
inactiveIcon: profileInActive,
|
|
||||||
activeIcon: profileActive,
|
|
||||||
path: '/pages/charge/my/index'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,56 @@
|
||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/recruitsale/home/index",
|
"path": "pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": "首页",
|
||||||
}
|
"navigationStyle": "custom"
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/recruitsale/summary/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/telesale/summary/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": ""
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/telesale/home/index",
|
"path": "pages/telesale/home/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
|
},
|
||||||
|
"auth": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/recruitsale/home/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
},
|
||||||
|
"auth": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/telesale/summary/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
},
|
||||||
|
"auth": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/recruitsale/summary/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
},
|
||||||
|
"auth": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/recruitsale/my/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "个人中心",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
},
|
||||||
|
"auth": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/telesale/my/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "个人中心",
|
||||||
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"path": "pages/salesman/contract/index",
|
"path": "pages/salesman/contract/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
@ -44,21 +71,6 @@
|
||||||
},
|
},
|
||||||
"auth": true
|
"auth": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/client/my/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "个人中心",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
},
|
|
||||||
"auth": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/salesman/profile/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "个人中心",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/overhaul/pool/index",
|
"path": "pages/overhaul/pool/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
@ -1,86 +1,19 @@
|
||||||
<!--
|
|
||||||
* @Author: micky
|
|
||||||
* @Date: 2024-08-10 15:24:06
|
|
||||||
* @LastEditors: micky
|
|
||||||
* @LastEditTime: 2024-08-28 18:39:12
|
|
||||||
* @FilePath: \chargingpile-uniapp\src\pages\index\index.vue
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<view class="wrapper">
|
<view></view>
|
||||||
<swiper class="swiper" @change="swiperChange">
|
|
||||||
<swiper-item v-for="(item, index) in list" :key="index" class="item">
|
|
||||||
<image :src="item.image"></image>
|
|
||||||
<view class="title">{{ item.title }}</view>
|
|
||||||
<view class="desc">{{ item.desc }}</view>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
<view class="rowDot">
|
|
||||||
<view v-for="(item, index) in list" :key="index" class="dots">
|
|
||||||
<view :class="['dot', index === swiperCurrent ? 'active' : '']"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<u-button
|
|
||||||
type="primary"
|
|
||||||
class="login-btn"
|
|
||||||
shape="circle"
|
|
||||||
v-if="swiperCurrent == 3"
|
|
||||||
@click="toPage"
|
|
||||||
>
|
|
||||||
立即登录
|
|
||||||
</u-button>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue'
|
import { ROLEINDEX } from '@/enums/cacheEnums'
|
||||||
import Step1 from '@/static/images/step_1.png'
|
|
||||||
import Step2 from '@/static/images/step_2.png'
|
|
||||||
import Step3 from '@/static/images/step_3.png'
|
|
||||||
import Step4 from '@/static/images/step_4.png'
|
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
|
||||||
import { useUserStore } from '@/stores/user'
|
|
||||||
import { useRoleData } from '@/hooks/useRoleData'
|
import { useRoleData } from '@/hooks/useRoleData'
|
||||||
import { useTabBarStore } from '@/stores/tabbar'
|
import { useTabBarStore } from '@/stores/tabbar'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
import cache from '@/utils/cache'
|
import cache from '@/utils/cache'
|
||||||
import { ROLEINDEX } from '@/enums/cacheEnums'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const { roles } = useRoleData()
|
const { roles } = useRoleData()
|
||||||
const tabBarStore = useTabBarStore()
|
const tabBarStore = useTabBarStore()
|
||||||
|
|
||||||
const swiperCurrent = ref(0)
|
|
||||||
const list = reactive([
|
|
||||||
{
|
|
||||||
image: Step1,
|
|
||||||
title: '用户报修',
|
|
||||||
desc: '用户可以通过在线报修、电话报修或扫码报修等多种方式提交维修请求。'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: Step2,
|
|
||||||
title: '桩点检修',
|
|
||||||
desc: '检修员接单后将上门对客户上报的桩点进行现场维修。'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: Step3,
|
|
||||||
title: '上门巡检',
|
|
||||||
desc: '检修员在巡检过程中发现设备异常时需提交检修单。'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: Step4,
|
|
||||||
title: '模块维修',
|
|
||||||
desc: '维修员通过扫描模块条形码来创建维修工单。'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const swiperChange = e => {
|
|
||||||
swiperCurrent.value = e.detail.current
|
|
||||||
}
|
|
||||||
const toPage = () => {
|
|
||||||
uni.redirectTo({
|
|
||||||
url: '/bundle/pages/login/login'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const setNextRoute = () => {
|
const setNextRoute = () => {
|
||||||
const ind = cache.get(ROLEINDEX) || 0
|
const ind = cache.get(ROLEINDEX) || 0
|
||||||
const { userInfo } = userStore
|
const { userInfo } = userStore
|
||||||
|
@ -100,51 +33,4 @@ onLoad(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped></style>
|
||||||
<style lang="scss" scoped>
|
|
||||||
.wrapper {
|
|
||||||
@apply h-full relative z-10;
|
|
||||||
.swiper {
|
|
||||||
@apply px-[30px] h-[400px] pt-[150px];
|
|
||||||
.item {
|
|
||||||
@apply flex flex-col items-center;
|
|
||||||
}
|
|
||||||
image {
|
|
||||||
@apply w-[100vw] h-[310px] mb-[48rpx];
|
|
||||||
line-height: 90rpx;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
@apply text-[24px] text-[#2F2F52] mb-[15px];
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
@apply text-[#334155];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.rowDot {
|
|
||||||
@apply flex justify-center mt-[66px];
|
|
||||||
.dots {
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
.dot {
|
|
||||||
margin-right: 8rpx;
|
|
||||||
width: 20rpx;
|
|
||||||
height: 8rpx;
|
|
||||||
opacity: 1;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
background: #efefef;
|
|
||||||
}
|
|
||||||
.dot.active {
|
|
||||||
width: 48rpx;
|
|
||||||
background: #1a66ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.login-btn) {
|
|
||||||
button {
|
|
||||||
@apply w-[200px] h-[40px] -mt-[20px];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="flex-1 h-screen flex flex-col">
|
<TContainer>
|
||||||
<TSearch
|
<TSearch
|
||||||
v-model="queryParams.searchValue"
|
v-model="queryParams.likeWork"
|
||||||
placeholder="搜索客户姓名/手机号码"
|
placeholder="搜索客户姓名/手机号码"
|
||||||
backgroundColor="#F5F5F5"
|
backgroundColor="#F5F5F5"
|
||||||
showBorder
|
showBorder
|
||||||
|
@ -13,27 +13,26 @@
|
||||||
:activeStyle="{ color: '#0E66FB' }"
|
:activeStyle="{ color: '#0E66FB' }"
|
||||||
lineWidth="49"
|
lineWidth="49"
|
||||||
lineColor="#0E66FB"
|
lineColor="#0E66FB"
|
||||||
:current="activeTab"
|
|
||||||
@change="handleChangeTab"
|
@change="handleChangeTab"
|
||||||
></u-tabs>
|
></u-tabs>
|
||||||
<view class="flex-1 pt-[24rpx] px-[24rpx] overflow-auto bg-[#F8F8F8]">
|
<view class="flex-1 pt-[24rpx] px-[24rpx] overflow-auto bg-[#F8F8F8]">
|
||||||
<!-- <z-paging
|
<z-paging
|
||||||
ref="paging"
|
ref="paging"
|
||||||
v-model="dataList"
|
v-model="dataList"
|
||||||
@query="queryList"
|
@query="queryList"
|
||||||
:fixed="false"
|
:fixed="false"
|
||||||
height="100%"
|
height="100%"
|
||||||
> -->
|
>
|
||||||
|
<clue-card
|
||||||
<clue-card
|
v-for="(item, index) in dataList"
|
||||||
v-for="(item, index) in dataList"
|
:key="`${index} + 'unique'`"
|
||||||
:key="`${index} + 'unique'`"
|
:item="item"
|
||||||
:item="item"
|
@handle-update-remark="handleUpdateRemark"
|
||||||
@handle-update-remark="handleUpdateRemark"
|
@refresh-page="refresh"
|
||||||
/>
|
/>
|
||||||
<!-- </z-paging> -->
|
</z-paging>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</TContainer>
|
||||||
<w-confirm-popup v-model="popupShow" @confirm="handleConfirm">
|
<w-confirm-popup v-model="popupShow" @confirm="handleConfirm">
|
||||||
<template #content>
|
<template #content>
|
||||||
<TTextareaField v-model="contentText" border="surround" :required="false" />
|
<TTextareaField v-model="contentText" border="surround" :required="false" />
|
||||||
|
@ -48,40 +47,33 @@ import { ref } from 'vue'
|
||||||
import clueCard from '@/components/widgets/recruitsale/clue-card.vue'
|
import clueCard from '@/components/widgets/recruitsale/clue-card.vue'
|
||||||
import { shallowRef } from 'vue'
|
import { shallowRef } from 'vue'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
import { apiCluseList } from '@/api/clue'
|
||||||
|
import { converStatusEnum } from '@/enums'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
const tabs = shallowRef([
|
const tabs = shallowRef([
|
||||||
{ name: '待领取', value: 0 },
|
{ name: '待领取', value: converStatusEnum.UN_RECEIVED },
|
||||||
{ name: '转化中', value: 1 },
|
{ name: '转化中', value: converStatusEnum.CONVERTED_PROCESS },
|
||||||
{ name: '已成交', value: 2 },
|
{ name: '已成交', value: converStatusEnum.CONVERTED },
|
||||||
{ name: '已战败', value: 3 }
|
{ name: '已战败', value: converStatusEnum.FAILED }
|
||||||
])
|
])
|
||||||
const activeTab = ref(0)
|
const activeTab = ref(converStatusEnum.UN_RECEIVED)
|
||||||
const queryParams = computed(() => {
|
const queryParams = computed(() => {
|
||||||
const payload = {
|
const payload = {
|
||||||
status: activeTab.value,
|
situation: activeTab.value,
|
||||||
searchValue: ''
|
likeWork: ''
|
||||||
}
|
}
|
||||||
return payload
|
return payload
|
||||||
})
|
})
|
||||||
const dataList = ref([
|
const dataList = ref([])
|
||||||
{
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3
|
|
||||||
}
|
|
||||||
])
|
|
||||||
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
||||||
queryParams.value,
|
queryParams.value,
|
||||||
apiOverhaulPagelist,
|
apiCluseList,
|
||||||
() => {}
|
() => {}
|
||||||
)
|
)
|
||||||
const handleChangeTab = item => {
|
const handleChangeTab = item => {
|
||||||
activeTab.value = item.value
|
activeTab.value = item.value
|
||||||
// refresh(queryParams.value)
|
refresh(queryParams.value)
|
||||||
}
|
}
|
||||||
const popupShow = ref(false)
|
const popupShow = ref(false)
|
||||||
const contentText = ref('')
|
const contentText = ref('')
|
||||||
|
@ -91,5 +83,10 @@ const handleUpdateRemark = item => {
|
||||||
contentText.value = remark
|
contentText.value = remark
|
||||||
}
|
}
|
||||||
const handleConfirm = () => {}
|
const handleConfirm = () => {}
|
||||||
|
onLoad(() => {
|
||||||
|
uni.$on('refreshPage', () => {
|
||||||
|
refresh(queryParams.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<TProfile :isShow="false"></TProfile>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
|
@ -1,9 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="pb-[24rpx]">
|
<TContainer>
|
||||||
<w-date-more :curDate="curDate" type="recruitsale" />
|
<view class="pb-[24rpx]">
|
||||||
<date-strip v-model="curDate" @change="handleDateChange" height="160rpx" />
|
<w-date-more :curDate="curDate" type="recruitsale" />
|
||||||
<w-summary-form v-model="templateItems" @handle-confirm="handleConfirm" :readonly="type" />
|
<date-strip v-model="curDate" @change="handleDateChange" height="160rpx" />
|
||||||
</view>
|
<w-summary-form
|
||||||
|
v-model="templateItems"
|
||||||
|
@handle-confirm="handleConfirm"
|
||||||
|
:readonly="type"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</TContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="flex flex-col h-screen">
|
<TContainer>
|
||||||
<u-tabs
|
<u-tabs
|
||||||
:list="tabs"
|
:list="tabs"
|
||||||
:scrollable="false"
|
:scrollable="false"
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
@change="handleChangeTab"
|
@change="handleChangeTab"
|
||||||
></u-tabs>
|
></u-tabs>
|
||||||
<view class="flex-1 bg-gray3">
|
<view class="flex-1 bg-gray3">
|
||||||
<follow-form v-if="activeTab === 0" />
|
<follow-form v-if="activeTab === teleSaleEnum.ADD_FOLLOW" />
|
||||||
<follow-record v-else-if="activeTab === 1" />
|
<follow-record v-else-if="activeTab === teleSaleEnum.FOLLOW_RECORD" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</TContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -22,11 +22,12 @@ import { shallowRef } from 'vue'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import followForm from '@/components/widgets/telesale/follow-form.vue'
|
import followForm from '@/components/widgets/telesale/follow-form.vue'
|
||||||
import followRecord from '@/components/widgets/telesale/follow-record.vue'
|
import followRecord from '@/components/widgets/telesale/follow-record.vue'
|
||||||
|
import { teleSaleEnum } from '@/enums'
|
||||||
|
|
||||||
const activeTab = ref(1)
|
const activeTab = ref(teleSaleEnum.ADD_FOLLOW)
|
||||||
const tabs = shallowRef([
|
const tabs = shallowRef([
|
||||||
{ name: '新增跟进', value: 0 },
|
{ name: '新增跟进', value: teleSaleEnum.ADD_FOLLOW },
|
||||||
{ name: '跟进动态', value: 1 }
|
{ name: '跟进动态', value: teleSaleEnum.FOLLOW_RECORD }
|
||||||
])
|
])
|
||||||
const handleChangeTab = item => {
|
const handleChangeTab = item => {
|
||||||
activeTab.value = item.value
|
activeTab.value = item.value
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<TProfile :isShow="false"></TProfile>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
|
@ -3,6 +3,7 @@
|
||||||
<w-date-more :curDate="curDate" type="telesale" />
|
<w-date-more :curDate="curDate" type="telesale" />
|
||||||
<date-strip v-model="value" @change="handleDateChange" height="160rpx" />
|
<date-strip v-model="value" @change="handleDateChange" height="160rpx" />
|
||||||
<w-summary-form v-model="templateItems" @handle-confirm="handleConfirm" />
|
<w-summary-form v-model="templateItems" @handle-confirm="handleConfirm" />
|
||||||
|
<tabbar />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'iconfont'; /* Project id 4837700 */
|
font-family: 'iconfont'; /* Project id 4837700 */
|
||||||
src: url('//at.alicdn.com/t/c/font_4837700_wjnzp8mer6o.woff2?t=1740542409608') format('woff2'),
|
src: url('//at.alicdn.com/t/c/font_4837700_mvrnof6x61s.woff2?t=1740644911077') format('woff2'),
|
||||||
url('//at.alicdn.com/t/c/font_4837700_wjnzp8mer6o.woff?t=1740542409608') format('woff'),
|
url('//at.alicdn.com/t/c/font_4837700_mvrnof6x61s.woff?t=1740644911077') format('woff'),
|
||||||
url('//at.alicdn.com/t/c/font_4837700_wjnzp8mer6o.ttf?t=1740542409608') format('truetype');
|
url('//at.alicdn.com/t/c/font_4837700_mvrnof6x61s.ttf?t=1740644911077') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
|
@ -13,6 +13,14 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-clear:before {
|
||||||
|
content: '\e601';
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search:before {
|
||||||
|
content: '\e67d';
|
||||||
|
}
|
||||||
|
|
||||||
.icon-left:before {
|
.icon-left:before {
|
||||||
content: '\e83d';
|
content: '\e83d';
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,11 +60,11 @@ export const useAppStore = defineStore({
|
||||||
return url ? `${this.config.domain}${url}` : ''
|
return url ? `${this.config.domain}${url}` : ''
|
||||||
// return url || ''
|
// return url || ''
|
||||||
},
|
},
|
||||||
async getConfig() {
|
// async getConfig() {
|
||||||
const data = await apiConfig()
|
// const data = await apiConfig()
|
||||||
this.config = data
|
// this.config = data
|
||||||
cache.set(CONFIG, data)
|
// cache.set(CONFIG, data)
|
||||||
},
|
// },
|
||||||
|
|
||||||
// setCityInfo(city: City) {
|
// setCityInfo(city: City) {
|
||||||
// this.cityInfo = city
|
// this.cityInfo = city
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* @LastEditTime: 2024-10-27 18:19:43
|
* @LastEditTime: 2024-10-27 18:19:43
|
||||||
* @FilePath: \chargingpile-uniapp\src\stores\user.ts
|
* @FilePath: \chargingpile-uniapp\src\stores\user.ts
|
||||||
*/
|
*/
|
||||||
import { apiUserInfo, getUserCenter } from '@/api/user'
|
import { apiUserInfo } from '@/api/user'
|
||||||
import { TOKEN_KEY, USER_INFO, CONFIG, ROLEINDEX } from '@/enums/cacheEnums'
|
import { TOKEN_KEY, USER_INFO, CONFIG, ROLEINDEX } from '@/enums/cacheEnums'
|
||||||
import cache from '@/utils/cache'
|
import cache from '@/utils/cache'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
@ -48,14 +48,6 @@ export const useUserStore = defineStore({
|
||||||
const data = await apiUserInfo({
|
const data = await apiUserInfo({
|
||||||
token: this.token || this.temToken
|
token: this.token || this.temToken
|
||||||
})
|
})
|
||||||
let roleArr = []
|
|
||||||
for (const key in data.roleMap) {
|
|
||||||
roleArr.push({
|
|
||||||
name: data.roleMap[key],
|
|
||||||
id: Number(key)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
data.roles = roleArr
|
|
||||||
this.userInfo = data
|
this.userInfo = data
|
||||||
cache.set(USER_INFO, data)
|
cache.set(USER_INFO, data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,3 +288,8 @@ page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.u-tabbar {
|
||||||
|
.u-tabbar__content {
|
||||||
|
z-index: 99999 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
const mobileReg =
|
||||||
|
/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/
|
||||||
|
|
||||||
|
/**手机号码 */
|
||||||
|
export function validateContact(rule: any, value: any, callback: any) {
|
||||||
|
if (value) {
|
||||||
|
if (!mobileReg.test(value)) {
|
||||||
|
callback(new Error('请输入正确的电话'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,8 @@ module.exports = {
|
||||||
lightblack: '#3D3D3D',
|
lightblack: '#3D3D3D',
|
||||||
border: '#F1F1F1',
|
border: '#F1F1F1',
|
||||||
border2: '#F3F3F3',
|
border2: '#F3F3F3',
|
||||||
blue2: '#EEF6FF'
|
blue2: '#EEF6FF',
|
||||||
|
orage: '#ED6D41'
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: '24rpx',
|
xs: '24rpx',
|
||||||
|
|
Loading…
Reference in New Issue