Commit fc86c70c by 李宁

1

1 parent da7b0e06
Showing 43 changed files with 786 additions and 414 deletions
import request from '../../request'
/**
*
/**
* 查询账号列表
*/
export function queryAllMissionRecord() {
export function queryAccountList(data) {
return request({
url: 'hallserver/companyJob/queryAllCompanyJob',
data: {}
url: '/compass/api/system/account/page',
data,
})
}
/**
* 查询角色列表
*/
export function queryRoleList(data) {
return request({
url: '/compass/api/common/enums/account-roles',
method: 'GET'
})
}
/**
* 删除账号
*/
export function deleteRole(data) {
return request({
url: '/compass/api/system/account/delete',
data,
})
}
/**
* 添加/更新账号
*/
export function addAndUpdateRole(data) {
return request({
url: '/compass/api/system/account/create' + (data.id?'/update':''),
data,
})
}
\ No newline at end of file
......@@ -11,6 +11,76 @@ export function queryAllBusi(data) {
}
/**
* 全部商机-商机审核
*/
export function audioBusi(data) {
return request({
url: '/compass/api/opportunity/audit',
data,
})
}
/**
* 全部商机-商机详情
*/
export function queryBusiDetail(data) {
return request({
url: '/compass/api/opportunity/detail',
data,
})
}
/**
* 全部商机-商机跟进记录查询
*/
export function queryBusiFollowList(data) {
return request({
url: '/compass/api/opportunity/follow/page',
data,
})
}
/**
* 全部商机-关闭商机
*/
export function closeBusi(data) {
return request({
url: '/compass/api/opportunity/close',
data,
})
}
/**
* 全部商机-标记成单
*/
export function dealBusi(data) {
return request({
url: '/compass/api/opportunity/deal',
data,
})
}
/**
* 全部商机-分配商机
*/
export function reassignBusi(data) {
return request({
url: '/compass/api/opportunity/reassign',
data,
})
}
/**
* 全部商机-记录管理员备注
*/
export function updateRemark(data) {
return request({
url: '/compass/api/opportunity/admin-remark',
data,
})
}
/**
* 全部商机-数据统计
*/
export function queryAllBusiStatistics(data) {
......@@ -21,11 +91,81 @@ export function queryAllBusiStatistics(data) {
}
/**
* 全部商机-查询商机标签列表
* 全部商机-查询所有商机标签列表
*/
export function queryBusiLabel(data) {
export function queryBusiLabelList(data) {
return request({
url: '/compass/api/opportunity/tag/page',
data,
})
}
/**
* 商机标签的开始和关闭
*/
export function updateBusiLabelStatus(data) {
return request({
url: '/compass/api/opportunity/tag/status',
data,
})
}
/**
* 商机标签的删除
*/
export function deleteBusiLabel(data) {
return request({
url: '/compass/api/opportunity/tag/delete',
data,
})
}
/**
* 商机标签的创建和更新
*/
export function createAndUpdateTag(data) {
return request({
url: '/compass/api/opportunity/tag' + (data.id?'/update':''),
data,
})
}
/**
* 商机关闭原因列表查询
*/
export function queryBusiCloseReansonList(data) {
return request({
url: '/compass/api/opportunity/close-reason/page',
data,
})
}
/**
* 商机关闭原因添加和更新
*/
export function busiCloseReasonUpdate(data) {
return request({
url: '/compass/api/opportunity/close-reason'+(data.id?'/update':''),
data,
})
}
/**
* 商机关闭原因删除
*/
export function busiCloseReasonDel(data) {
return request({
url: '/compass/api/opportunity/close-reason/delete',
data,
})
}
/**
* 全部商机-新增商机
*/
export function createBusi(data) {
return request({
url: '/compass/api/opportunity/create',
data,
})
}
\ No newline at end of file
import request from '../../request'
/**
* 查询区域列表
* 根据级别查询区域列表
* 1-省级,2-市级,3-区级,4-网格级
*/
export function queryAllArea(data) {
export function queryLevelAllArea(data) {
return request({
url: '/compass/api/common/areas/level?areaLevel='+data.areaLevel+'&parentAreaCode='+data.parentAreaCode,
method: 'GET'
......
import request from '../../request'
/**
* 资金管理-发票管理-开票订单查询
* 网格列表查询
* @returns {AxiosPromise}
*/
export function queryTicketOrderList() {
export function queryAllGridList(data) {
return request({
url: 'hallserver/v1/invoiceApply/queryCompanyOrder',
data: {}
url: '/compass/api/grid/list',
data,
})
}
/**
* 获取该账号下可选的网格列表
*/
export function queryGridList(data) {
return request({
url: '/compass/api/grid/options',
data,
})
}
\ No newline at end of file
import request from '../../request'
/**
* 查询人员列表
*/
export function queryAllPerson(data) {
return request({
url: '/compass/api/personnel/list',
data,
})
}
/**
* 添加人员
*/
export function addNewPerson(data) {
return request({
url: '/compass/api/personnel/create',
data,
})
}
/**
*
* 删除人员
*/
export function companyInfoQuery(companyId) {
export function deletePerson(data) {
return request({
url: 'hallserver/hallCompanyInfo/getCompanyInfo',
data: {
'companyId': companyId
}
url: '/compass/api/personnel/delete',
data,
})
}
/**
* 批量导入工维人员
*/
export function importGwPerson(data) {
return request({
url: '/compass/api/personnel/import-maintenance-preview',
data,
})
}
/**
* 批量导入营销人员
*/
export function importYxPerson(data) {
return request({
url: '/compass/api/marketing/import-preview',
data,
})
}
......@@ -5,7 +5,7 @@ import request from './request'
*/
export function logout() {
return request({
url: 'hallserver/admin/logout',
url: '/compass/api/auth/logout',
data: {}
})
}
......@@ -23,24 +23,36 @@ export function login(data) {
}
/**
* 获取登录验证码
* 手机账号登录
*/
export function pohoneLogin(data) {
return request({
url: '/compass/api/auth/phone-login',
data,
})
}
/**
* 获取图形验证码
* @param loginName
* @param password
*/
export function loginCode(data) {
export function getImgCode(data) {
return request({
url: 'hallserver/admin/loginCode',
url: '/compass/api/auth/getCaptCha',
method: 'GET',
data,
})
}
/**
* 获取路由权限
* @returns {AxiosPromise}
* 获取短信验证码
* @param loginName
* @param password
*/
export function getMenus() {
export function getTelCode(data) {
return request({
url: 'hallserver/admin/function',
data: {}
url: '/compass/api/auth/send-sms',
data,
})
}
......@@ -51,7 +51,7 @@ let catchFun = function (msg) {
service.interceptors.response.use(
(response) => {
console.log(response);
if (response.status === 200) {
if (response.status == 200) {
if (response.data.code == "401") {
//登陆失效,重新登陆
catchFun("账户状态异常");
......@@ -100,9 +100,9 @@ service.interceptors.response.use(
};
}
}
} else if (response.status === 302) {
} else if (response.status == 302) {
catchFun("登陆失效,请重新登陆");
} else if (response.status === 401 || response.status == 403) {
} else if (response.status == 401 || response.status == 403) {
catchFun("账户状态异常");
} else {
if (sessionStorage.notFirstIn) {
......
......@@ -212,9 +212,9 @@ export default {
* @returns
*/
hideIdNumber: function(idCard) {
if (idCard.length === 18) {
if (idCard.length == 18) {
return idCard.substr(0, 6) + '********' + idCard.substr(-4, 4)
} else if (idCard.length === 15) {
} else if (idCard.length == 15) {
return idCard.substr(0, 6) + '******' + idCard.substr(-3, 3)
} else {
return idCard
......
......@@ -2,21 +2,21 @@
<div class="close-reason-management">
<div class="toolbar">
<p class="description">管理商机关闭时可选择的原因</p>
<el-button @click="isAddDialogOpen = true" type="primary" size="small">
<el-button @click="addReason" type="primary" size="small">
<i class="el-icon-plus"></i>
添加原因
</el-button>
</div>
<div class="reason-table">
<el-table :data="reasons" style="width: 100%">
<el-table-column prop="reason" label="关闭原因" width="300"></el-table-column>
<el-table :data="reasonsList" style="width: 100%" border>
<el-table-column prop="closeReason" label="关闭原因" width="300"></el-table-column>
<el-table-column prop="category" label="分类" width="200">
<template slot-scope="scope">
<el-tag size="mini">{{ scope.row.category }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<el-table-column label="操作" min-width="150">
<template slot-scope="scope">
<el-button
type="text"
......@@ -37,6 +37,20 @@
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageStore.currentPage"
:page-sizes="[20, 50, 100]"
:page-size="pageStore.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageStore.total"
>
</el-pagination>
</div>
<!-- 添加/编辑原因对话框 -->
<el-dialog
:title="editingReason ? '编辑关闭原因' : '添加关闭原因'"
......@@ -44,9 +58,9 @@
width="500px"
>
<el-form :model="reasonForm" :rules="reasonRules" ref="reasonForm" label-width="100px">
<el-form-item label="关闭原因" prop="reason">
<el-form-item label="关闭原因" prop="closeReason">
<el-input
v-model="reasonForm.reason"
v-model="reasonForm.closeReason"
placeholder="请输入关闭原因"
></el-input>
</el-form-item>
......@@ -68,21 +82,18 @@
</template>
<script>
// 模拟关闭原因数据
const mockCloseReasons = [
{ id: '1', reason: '客户价格不接受', category: '价格因素' },
{ id: '2', reason: '客户暂无需求', category: '需求因素' },
{ id: '3', reason: '竞品已安装', category: '竞争因素' },
{ id: '4', reason: '客户联系不上', category: '联系因素' },
{ id: '5', reason: '技术不支持', category: '技术因素' },
{ id: '6', reason: '其他原因', category: '其他' }
]
export default {
name: 'CloseReasonManagement',
data() {
return {
reasons: mockCloseReasons,
reasonsList: [],
pageStore:{
currentPage: 1,
pageSize: 20,
total: 0
},
isAddDialogOpen: false,
editingReason: null,
reasonForm: {
......@@ -90,7 +101,7 @@ export default {
category: ''
},
reasonRules: {
reason: [
closeReason: [
{ required: true, message: '请输入关闭原因', trigger: 'blur' }
],
category: [
......@@ -99,7 +110,46 @@ export default {
}
}
},
created(){
this.handleFilter()
},
methods: {
handleSizeChange(size) {
this.pageStore.pageSize = size
this.handleFilter()
},
handleCurrentChange(page) {
this.pageStore.currentPage = page
this.queryCloseList()
},
handleFilter(){
this.pageStore.currentPage = 1
this.queryCloseList()
},
queryCloseList(){
this.apiReq.queryBusiCloseReansonList({
pageNum: this.pageStore.currentPage,
pageSize: this.pageStore.pageSize
}).then(res=>{
if(res.code == 200){
this.reasonsList = res.data.records
this.pageStore.total = res.data.total
}
})
},
addReason(){
this.editingReason = null
this.reasonForm = {
category: '',
closeReason: ''
}
this.isAddDialogOpen = true
},
editReason(reason) {
this.editingReason = reason
this.reasonForm = { ...reason }
......@@ -111,44 +161,46 @@ export default {
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.reasons = this.reasons.filter(r => r.id !== id)
this.$message.success('关闭原因删除成功')
}).catch(() => {
// 用户取消删除
this.apiReq.busiCloseReasonDel({
id,
}).then(res=>{
if(res.code == 200){
let __this = this
this.$alert('删除成功', '温馨提示', {
confirmButtonText: '确定',
callback: () => {
__this.handleFilter()
}
});
}else{
this.$message.error(res.message)
}
})
})
},
submitReasonForm() {
this.$refs.reasonForm.validate((valid) => {
if (valid) {
if (this.editingReason) {
// 更新原因信息
const index = this.reasons.findIndex(r => r.id === this.editingReason.id)
if (index !== -1) {
this.$set(this.reasons, index, { ...this.editingReason, ...this.reasonForm })
this.$message.success('关闭原因更新成功')
this.apiReq.busiCloseReasonUpdate({
id: this.editingReason?this.editingReason.id: '',
category: this.reasonForm.category,
closeReason: this.reasonForm.closeReason
}).then(res=>{
if(res.code == '200'){
let __this = this
this.$alert(this.editingReason?'修改成功':'添加成功', '温馨提示', {
confirmButtonText: '确定',
callback: () => {
__this.handleFilter()
__this.isAddDialogOpen = false
}
});
}else{
this.$message.error(res.message)
}
} else {
// 添加新原因
const newReason = {
...this.reasonForm,
id: `REASON${Date.now()}`
}
this.reasons.push(newReason)
this.$message.success('关闭原因添加成功')
}
// 重置表单和状态
this.resetReasonForm()
this.isAddDialogOpen = false
this.editingReason = null
})
}
})
},
resetReasonForm() {
this.reasonForm = {
reason: '',
category: ''
}
}
}
}
......
......@@ -91,7 +91,7 @@ export default new Vuex.Store({
return new Promise((resolve, reject) => {
// 模拟登录验证
const userData = mockUsers[username]
if (userData && userData.password === password) {
if (userData && userData.password == password) {
commit('SET_USER', userData.user)
localStorage.setItem('user', JSON.stringify(userData.user))
resolve(true)
......
......@@ -35,10 +35,9 @@
<template v-for="item in menuItems">
<!-- 有子菜单的项 -->
<el-submenu
v-if="item.subItems && hasPermission(item.permissions)"
v-if="item.subItems"
:key="item.title"
:index="item.title"
>
:index="item.title" >
<template slot="title">
<i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span>
......@@ -46,8 +45,8 @@
<el-menu-item
v-for="subItem in item.subItems"
:key="subItem.url"
:index="subItem.url"
>
v-if="hasPermissionChild(subItem.url)"
:index="subItem.url">
<i :class="subItem.icon"></i>
<span slot="title">{{ subItem.title }}</span>
</el-menu-item>
......@@ -55,7 +54,7 @@
<!-- 无子菜单的项 -->
<el-menu-item
v-else-if="item.url && hasPermission(item.permissions)"
v-else-if="item.url && hasPermission(item.url)"
:key="item.title"
:index="item.url"
>
......@@ -75,17 +74,17 @@
</el-avatar>
<transition name="fade">
<div v-if="!isCollapse" class="user-details">
<span class="user-name">{{ currentUser.name }}</span>
<span class="user-region">{{ currentUser.region }}</span>
<span class="user-name">{{ acc.accountName }}</span>
<span class="user-region">{{ acc.areaName }}</span>
</div>
</transition>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="profile">
<!-- <el-dropdown-item command="profile">
<i class="el-icon-user"></i>
个人信息
</el-dropdown-item>
<el-dropdown-item divided command="logout">
</el-dropdown-item> -->
<el-dropdown-item command="logout">
<i class="el-icon-switch-button"></i>
退出登录
</el-dropdown-item>
......@@ -120,7 +119,7 @@
<div class="header-right">
<span v-if="isDemoMode" class="demo-badge">演示模式</span>
<span class="current-region">当前区域: {{ currentUser.region }}</span>
<span class="current-region">当前区域: {{ acc.areaName }}</span>
</div>
</el-header>
......@@ -201,22 +200,19 @@ export default {
return {
isCollapse: false,
menuItems: menuItems,
breadcrumbMap: breadcrumbMap
breadcrumbMap: breadcrumbMap,
acc: JSON.parse(localStorage.getItem('accountInfo'))
}
},
computed: {
...mapGetters(['user', 'isAuthenticated']),
currentUser() {
return this.user || {}
},
userInitial() {
return this.currentUser.name ? this.currentUser.name.charAt(0) : ''
return this.acc.accountName ? this.acc.accountName.charAt(0) : ''
},
userAvatar() {
return ''
},
isDemoMode() {
return sessionStorage.getItem('demoMode') === 'true'
return sessionStorage.getItem('demoMode') == 'true'
},
activeMenu() {
const { meta, path } = this.$route
......@@ -245,18 +241,43 @@ export default {
toggleCollapse() {
this.isCollapse = !this.isCollapse
},
hasPermission(permissions) {
if (!this.user || !this.user.permissions) return false
return permissions.some(permission => this.user.permissions.includes(permission))
hasPermission(url) {
if(url=='/grid-query' && this.acc.gridCode){
return false
}
return true
},
async handleUserCommand(command) {
if (command === 'logout') {
await this.logout()
this.$message.success('退出登录成功')
this.$router.push('/login')
} else if (command === 'profile') {
this.$message.info('个人信息功能开发中')
hasPermissionChild(url){
if(url == '/system/opportunity-config'){
if(this.acc.cityCode && !this.acc.countyCode){
return true
}
return false
}
return true
},
async handleUserCommand(command) {
this.apiReq.logout().then(res=>{
if(res.code == '200'){
localStorage.removeItem('accountInfo')
localStorage.removeItem('tokenInfo')
this.$router.push('/login')
}else{
this.$message.error(res.message)
}
})
// if (command == 'logout') {
// await this.logout()
// this.$message.success('退出登录成功')
// this.$router.push('/login')
// } else if (command == 'profile') {
// this.$message.info('个人信息功能开发中')
// }
}
},
created() {
......
......@@ -5,28 +5,15 @@
</div>
<el-card class="filter-card">
<div class="filter-header">
<h3 class="filter-title">查询条件</h3>
<div class="filter-actions">
<el-button size="small" @click="handleQuery">
<i class="el-icon-search"></i>
查询
</el-button>
<el-button size="small" @click="resetQuery" type="default">
<i class="el-icon-refresh-left"></i>
重置
</el-button>
</div>
</div>
<div class="filter-content">
<el-row :gutter="24">
<el-col :span="3">
<div class="search-wrapper">
<el-input
v-model="selectedGridName"
v-model="formData.gridName"
placeholder="请输入网格名称"
style="padding-left: 0;"
clearable
@keyup.enter.native="handleFilter"
/>
</div>
......@@ -35,9 +22,10 @@
<el-col :span="3">
<div class="search-wrapper">
<el-input
v-model="selectedGrid"
v-model="formData.gridCode"
placeholder="请输入网格ID"
style="padding-left: 0;"
clearable
@keyup.enter.native="handleFilter"
/>
</div>
......@@ -48,13 +36,12 @@
v-model="addressStore.city"
placeholder="选择地市"
@change="cityChange"
:disabled="getData.city!=''"
clearable>
<el-option
v-for="item in addressStore.cityArr"
:key="item.value"
:label="item.name"
:value="item.value"
:key="item.areaCode"
:label="item.areaName"
:value="item.areaCode"
></el-option>
</el-select>
</el-col>
......@@ -63,16 +50,28 @@
v-model="addressStore.county"
placeholder="选择区县"
@change="countyChange"
:disabled="getData.county!=''"
clearable>
<el-option
v-for="item in addressStore.countyArr"
:key="item.value"
:label="item.name"
:value="item.value"
:key="item.areaCode"
:label="item.areaName"
:value="item.areaCode"
></el-option>
</el-select>
</el-col>
<el-col :span="3">
<div class="filter-actions">
<el-button size="small" @click="handleQuery">
<i class="el-icon-search"></i>
查询
</el-button>
<el-button size="small" @click="resetQuery" type="default">
<i class="el-icon-refresh-left"></i>
重置
</el-button>
</div>
</el-col>
</el-row>
</div>
</el-card>
......@@ -88,9 +87,9 @@
:data="tableData"
border
>
<el-table-column prop="name" label="网格名称" width="220"></el-table-column>
<el-table-column prop="id" label="网格ID" width="220"></el-table-column>
<el-table-column prop="region" label="所属区域" min-width="250"></el-table-column>
<el-table-column prop="gridName" label="网格名称" width="220"></el-table-column>
<el-table-column prop="gridCode" label="网格ID" width="220"></el-table-column>
<el-table-column prop="areaName" label="所属区域" min-width="250"></el-table-column>
</el-table>
<!-- 分页 -->
......@@ -118,100 +117,103 @@ export default {
return {
addressStore:{
city: '',
cityName: '',
cityArr: this.addressStoreData,
cityArr: [],
county: '',
countyName: '',
countyArr: [],
},
getData:{
city: '',
cityName: '',
county: '',
countyName: ''
formData:{
gridName: '',
gridCode: '',
},
selectedRegion: [],
selectedGrid: '',
selectedGridName: '',
tableData: [],
pageStore:{
pageStore: {
currentPage: 1,
pageSize: 20,
total: 0
}
},
tableData: []
}
},
created(){
this.queryArea()
this.handleQuery()
},
methods: {
setAddressShow(){
let ad = this.addressStore
let gd = this.getData
if(gd.city){
ad.city = gd.city
ad.cityArr.forEach(item=>{
if(item.value == ad.city){
ad.countyArr = item.children
}
})
if(gd.county){
ad.county = gd.county
ad.countyArr.forEach(item=>{
if(item.value == ad.county){
ad.gridArr = item.children
}
})
if(ad.gridArr.length == 1){
gd.grid = 'moren'
}
if(gd.grid){
ad.grid = gd.grid
}
queryArea(){
this.apiReq.queryLevelAllArea({
areaLevel: 2,
parentAreaCode: '320000'
}).then(res=>{
if(res.code == 200){
this.addressStore.cityArr = res.data
}
}
})
},
cityChange(value){
let ad = this.addressStore
ad.city = value
ad.county = ''
ad.grid = ''
ad.cityArr.forEach(item=>{
if(item.value == ad.city){
ad.countyArr = item.children
this.apiReq.queryLevelAllArea({
areaLevel: 3,
parentAreaCode: value
}).then(res=>{
if(res.code == 200){
ad.countyArr = res.data
}
})
},
handleQuery() {
this.currentPage = 1
this.$message.success('查询成功')
this.pageStore.currentPage = 1
this.queryGridData()
},
queryGridData(){
if(this.addressStore.city && !this.addressStore.county){
this.$message.error('请选择区县')
return
}
this.apiReq.queryAllGridList({
areaCode: this.addressStore.county,
pageSize: this.pageStore.pageSize,
pageNum: this.pageStore.currentPage,
...this.formData
}).then(res=>{
if(res.code == 200){
this.tableData = res.data.records
this.pageStore.total = res.data.total
}
})
},
resetQuery() {
this.selectedRegion = []
this.selectedGrid = ''
this.selectedGridName = ''
this.formData.gridCode = ''
this.formData.gridName = ''
this.addressStore.city = ''
this.addressStore.county = ''
this.addressStore.countyArr = []
},
handleSizeChange(size) {
this.pageSize = size
this.currentPage = 1
this.pageStore.pageSize = size
this.handleQuery()
},
handleCurrentChange(page) {
this.currentPage = page
}
this.pageStore.currentPage = page
this.queryGridData()
},
}
}
</script>
<style lang="scss" scoped>
.grid-query {
.el-button.el-button--small{
padding: 13px 12px;
}
.page-header {
margin-bottom: 24px;
......
......@@ -16,7 +16,7 @@
智能商机管理<br>助力业务增长
</h2>
<p class="login-desc">
装维师傅上门服务时发现商机,系统自动分配给营销人员跟进,实现业务闭环管理
装维师傅上门服务时发现商机,系统自动分配给支撑人员跟进,实现业务闭环管理
</p>
</div>
......@@ -38,7 +38,7 @@
</div>
<div class="login-feature-text">
<h3 class="login-feature-title">智能分配</h3>
<p class="login-feature-desc">基于网格自动分配给合适的营销人员</p>
<p class="login-feature-desc">基于网格自动分配给合适的支撑人员</p>
</div>
</div>
......@@ -75,23 +75,21 @@
<div class="login-tabs">
<div
class="login-tab"
:class="{ active: activeTab === 'account' }"
@click="activeTab = 'account'"
>
:class="{ active: activeTab == 'account' }"
@click="activeTab = 'account'">
账号密码登录
</div>
<div
class="login-tab"
:class="{ active: activeTab === 'phone' }"
@click="activeTab = 'phone'"
>
:class="{ active: activeTab == 'phone' }"
@click="activeTab = 'phone'">
手机验证码登录
</div>
</div>
<!-- 账号密码登录表单 -->
<el-form
v-if="activeTab === 'account'"
v-if="activeTab == 'account'"
:model="loginForm"
:rules="loginRules"
ref="loginForm"
......@@ -143,7 +141,7 @@
<!-- 手机验证码登录表单 -->
<el-form
v-if="activeTab === 'phone'"
v-if="activeTab == 'phone'"
:model="phoneForm"
:rules="phoneRules"
ref="phoneForm"
......@@ -224,10 +222,6 @@
<p class="forgot-password-message">
忘记密码请联系商机管理员重置密码
</p>
<!-- <div class="forgot-password-tips">
<p><i class="el-icon-phone"></i> 联系电话:400-8888-8888</p>
<p><i class="el-icon-message"></i> 邮箱:admin@shangmensuixiao.com</p>
</div> -->
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="isForgotPasswordDialogVisible = false">确定</el-button>
......@@ -247,8 +241,8 @@ export default {
return {
activeTab: 'account', // 当前激活的登录方式
loginForm: {
username: '',
password: ''
username: 'ntadmin',
password: 'ntadmin'
},
phoneForm: {
phone: '',
......@@ -289,7 +283,7 @@ export default {
computed: {
// 是否可以发送验证码
canSendCode() {
return this.phoneForm.phone && this.phoneForm.captcha && this.phoneForm.captcha === this.captchaText
return this.phoneForm.phone && this.phoneForm.captcha
}
},
mounted() {
......@@ -310,7 +304,6 @@ export default {
try {
await this.$refs.loginForm.validate()
this.apiReq.login({
username: ld.username,
password: ld.password
......@@ -332,104 +325,59 @@ export default {
},
// 刷新图形验证码
refreshCaptcha() {
// 生成随机验证码(模拟)
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
let code = ''
for (let i = 0; i < 4; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length))
}
this.captchaText = code
// 创建canvas生成验证码图片
const canvas = document.createElement('canvas')
canvas.width = 100
canvas.height = 40
const ctx = canvas.getContext('2d')
// 背景色
ctx.fillStyle = '#f0f0f0'
ctx.fillRect(0, 0, 100, 40)
// 绘制验证码文字
ctx.font = '20px Arial'
ctx.fillStyle = '#333'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
for (let i = 0; i < code.length; i++) {
ctx.save()
ctx.translate(20 + i * 20, 20)
ctx.rotate((Math.random() - 0.5) * 0.3)
ctx.fillText(code[i], 0, 0)
ctx.restore()
}
// 添加干扰线
for (let i = 0; i < 4; i++) {
ctx.strokeStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.3)`
ctx.beginPath()
ctx.moveTo(Math.random() * 100, Math.random() * 40)
ctx.lineTo(Math.random() * 100, Math.random() * 40)
ctx.stroke()
this.apiReq.getImgCode().then(res=>{
if(res.code == 200){
this.captchaImage = 'data:image/png;base64,'+res.data.img
this.captchaId = res.data.codeId
}
this.captchaImage = canvas.toDataURL()
})
},
// 发送手机验证码
async sendPhoneCode() {
if (this.codeCountdown > 0) return
try {
await this.$refs.phoneForm.validate(['phone', 'captcha'])
// 模拟发送验证码
this.$message.success('验证码已发送到您的手机')
// 开始倒计时
this.codeCountdown = 60
this.countdownTimer = setInterval(() => {
this.codeCountdown--
if (this.codeCountdown <= 0) {
clearInterval(this.countdownTimer)
this.countdownTimer = null
}
}, 1000)
} catch (error) {
if (this.phoneForm.captcha !== this.captchaText) {
this.$message.error('图形验证码错误')
this.refreshCaptcha()
this.phoneForm.captcha = ''
this.apiReq.getTelCode({
phone: this.phoneForm.phone,
captchaCode: this.phoneForm.captcha,
captchaId: this.captchaId
}).then(res=>{
if(res.code == 200){
this.$message.success('验证码发送成功')
// 开始倒计时
this.codeCountdown = 60
this.countdownTimer = setInterval(() => {
this.codeCountdown--
if (this.codeCountdown <= 0) {
clearInterval(this.countdownTimer)
this.countdownTimer = null
}
}, 1000)
}else{
this.$message.error(res.message)
}
}
})
},
// 手机验证码登录
async handlePhoneLogin() {
try {
await this.$refs.phoneForm.validate()
this.phoneLoading = true
// 模拟手机号登录逻辑
// 这里可以添加手机号到用户名的映射逻辑
const phoneToUserMap = {
'13812345678': { username: 'grid001', password: '123456' },
'13887654321': { username: 'county001', password: '123456' },
'13765432109': { username: 'city001', password: '123456' },
'13654321098': { username: 'province001', password: '123456' }
}
this.apiReq.pohoneLogin({
phone: this.phoneForm.phone,
personnelCode: this.phoneForm.phone,
smsCode: this.phoneForm.phoneCode,
rememberMe: true
}).then(res=>{
if(res.code == 200){
localStorage.setItem('accountInfo',JSON.stringify(res.data.account))
localStorage.setItem('tokenInfo',JSON.stringify(res.data.tokenInfo))
const userInfo = phoneToUserMap[this.phoneForm.phone]
if (userInfo && this.phoneForm.phoneCode === '123456') {
await this.login({
username: userInfo.username,
password: userInfo.password
})
this.$message.success('登录成功')
this.$router.push('/')
} else {
this.$message.error('手机号或验证码错误')
}
this.$router.push('/')
}else{
this.$message.error(res.message)
}
})
} catch (error) {
console.error('Phone login error:', error)
......@@ -659,7 +607,7 @@ export default {
.captcha-image {
flex-shrink: 0;
width: 100px;
height: 40px;
height: 36px;
border: 1px solid #dcdfe6;
border-radius: 4px;
cursor: pointer;
......
......@@ -6,14 +6,14 @@
</div>
<!-- 人员管理页面特殊处理:显示业务类型Tab -->
<div v-if="activeTab === 'personnel'" class="personnel-management">
<div v-if="activeTab == 'personnel'" class="personnel-management">
<el-tabs v-model="businessTab" @tab-click="handleBusinessTabClick">
<el-tab-pane label="常规业务" name="regular"></el-tab-pane>
<el-tab-pane label="政企业务" name="enterprise" v-if="hasEnterprisePermission"></el-tab-pane>
</el-tabs>
<!-- 常规业务 -->
<div v-if="businessTab === 'regular'">
<div v-if="businessTab == 'regular'">
<el-card>
<div class="card-content">
<PersonnelManagement />
......@@ -22,7 +22,7 @@
</div>
<!-- 政企业务 -->
<div v-if="businessTab === 'enterprise' && hasEnterprisePermission">
<div v-if="businessTab == 'enterprise' && hasEnterprisePermission">
<el-card>
<div class="card-content">
<EnterprisePersonnelManagement />
......@@ -32,14 +32,14 @@
</div>
<!-- 商机管理配置 -->
<div v-else-if="activeTab === 'tags'" class="opportunity-config">
<div v-else-if="activeTab == 'tags'" class="opportunity-config">
<el-tabs v-model="configTab" @tab-click="handleConfigTabClick">
<el-tab-pane label="商机标签" name="tags"></el-tab-pane>
<el-tab-pane label="商机关闭" name="reasons"></el-tab-pane>
</el-tabs>
<!-- 商机标签 -->
<div v-if="configTab === 'tags'">
<div v-if="configTab == 'tags'">
<el-card>
<div class="card-content">
<TagManagement />
......@@ -48,7 +48,7 @@
</div>
<!-- 商机关闭原因 -->
<div v-if="configTab === 'reasons'">
<div v-if="configTab == 'reasons'">
<el-card>
<div class="card-content">
<CloseReasonManagement />
......@@ -58,7 +58,7 @@
</div>
<!-- 账号管理 -->
<div v-else-if="activeTab === 'accounts'">
<div v-else-if="activeTab == 'accounts'">
<el-card>
<div class="card-content">
<AccountManagement />
......@@ -98,9 +98,10 @@ export default {
}
},
computed: {
...mapGetters(['user']),
hasEnterprisePermission() {
return this.user?.role === 'city_admin' || this.user?.role === 'province_admin'
let accountInfo = JSON.parse(localStorage.getItem('accountInfo'))
return !accountInfo.countyCode && !accountInfo.gridCode
},
activeTabLabel() {
const tabLabels = {
......
......@@ -5,12 +5,12 @@ module.exports = {
publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
lintOnSave: process.env.NODE_ENV == 'development',
productionSourceMap: false,
devServer: {
proxy: {
'/compass': {
target: 'http://39.107.104.220:8899',
target: 'https://testznzl.lgyzpt.com/',
//target: 'https://hall.51xinpai.cn',
changeOrigin: true,
pathRewrite: {
......@@ -27,7 +27,8 @@ module.exports = {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
},
devtool: 'source-map'
},
chainWebpack: config => {
// 配置SVG图标
......
......@@ -12,6 +12,11 @@
<audio ref="audioObj" playsinline></audio>
<!-- <div class="topBut" v-if="isAlone">
<div class="left" @click="goZj">质检模拟</div>
<div class="right" @click="loginOut">退出</div>
</div> -->
<!-- 联系方式 -->
<div class="section" data-node-id="79:2566">
<div class="section-card" data-node-id="6:249">
......@@ -20,7 +25,7 @@
<span class="contact-text" data-node-id="6:259">{{ contactPhone }}</span>
<button class="edit-button" data-node-id="6:263" @click="editContact">修改</button>
</div>
<input class="phoneInput" v-else type="text" placeholder="请输入手机号">
<input class="phoneInput" v-model="contactPhone" v-else type="text" placeholder="请输入手机号">
</div>
</div>
......@@ -37,7 +42,7 @@
</div>
<div class="addressLi">
<div class="name">详细地址</div>
<input type="text" placeholder="门牌号、楼栋号">
<input type="text" placeholder="门牌号、楼栋号" v-model="detailAddress">
</div>
</div>
</div>
......@@ -51,10 +56,11 @@
v-for="type in businessTypes"
:key="type.id"
:class="['tag-button', { active: type.selected }]"
:style="{color: type.ifCho?'#33':'#CECECE'}"
:data-node-id="type.nodeId"
@click="selectBusinessType(type.id)"
>
{{ type.name }}
{{ type.tagName }}
</div>
</div>
</div>
......@@ -67,8 +73,11 @@
<div class="cordList">
<div class="cordLi" v-for="(item,index) in recordingUrlArr">
<div class="left" @click="playAudio(index)">
<img class="pause" src="images/pause.png" alt="">
<img class="voice" src="images/voice.png" alt="">
<img v-if="item.isPlay" class="pause" src="images/play.png" alt="">
<img v-else class="pause" src="images/pause.png" alt="">
<img class="voice" src="images/voice.png" alt="">
<div class="time">{{item.time}}</div>
</div>
<img class="close" src="images/close.png" @click="removeAudio(index)">
......@@ -134,14 +143,20 @@
<div v-else class="submit-button" data-node-id="6:498" @click="submitBusiness">
提交商机
</div>
<div class="loginOut" @click="loginOut">
<img src="images/loginout.png" alt="">
<div>退出</div>
</div>
<!-- 底部导航 -->
<div class="bottom-nav" v-if="isAlone">
<div class="nav-item collect-business">
<img class="nav-icon" src="images/collect-icon.svg" alt="收集商机">
<div class="nav-item collect-business active">
<img class="nav-icon" src="images/collect-icon-active.png" alt="收集商机">
<span class="nav-text" data-node-id="355:528">收集商机</span>
</div>
<div class="nav-item all-business active">
<img class="nav-icon" src="images/business-icon.svg" alt="收集商机">
<div class="nav-item all-business" @click="navigateToList">
<img class="nav-icon" src="images/business-icon.png" alt="收集商机">
<span class="nav-text" data-node-id="355:532">全部商机</span>
</div>
</div>
......@@ -197,9 +212,11 @@
</div>
<!-- 引入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/lamejs@1.2.1/lame.min.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/util.js"></script>
<script src="js/addressData.js"></script>
<script src="js/addBusi.js"></script>
<script src="js/addBusi.js?123211"></script>
</body>
</html>
\ No newline at end of file
......@@ -27,52 +27,38 @@ body {
padding-bottom: 1.2rem; /* 为底部按钮预留空间 */
}
/* 顶部标题栏 */
.header {
background-color: white;
border-bottom: 1px solid #f1f1f1;
position: sticky;
top: 0;
z-index: 100;
height: 0.88rem;
.loginOut{
display: flex;
align-items: center;
justify-content: center;
padding: 0 0.32rem;
border-radius: .08rem;
background: #EBEDF0;
width: 1.8rem;
height: .6rem;
color: #666;
font-size: .28rem;
margin: .64rem auto;
}
.loginOut img{
width: .32rem;
height: .32rem;
margin-right: .08rem;
}
.back-button {
position: absolute;
left: 0.32rem;
top: 50%;
transform: translateY(-50%);
width: 0.96rem;
height: 0.96rem;
background: none;
border: none;
cursor: pointer;
.topBut{
display: flex;
align-items: center;
justify-content: center;
}
.back-icon {
width: 0.2rem;
height: 0.36rem;
}
.back-icon img {
width: 100%;
height: 100%;
object-fit: contain;
justify-content: flex-end;
margin-bottom: .2rem;
}
.header-title {
font-family: 'Source Han Sans CN', sans-serif;
font-weight: bold;
font-size: 0.36rem;
line-height: 0.36rem;
color: #333333;
.topBut div{
border-radius: 4px;
background: #0068EE;
color: #fff;
font-size: .26rem;
font-weight: 500;
padding: .2rem .4rem;
margin-right: .1rem;
}
/* 通用卡片样式 */
......@@ -190,11 +176,6 @@ body {
user-select: none;
}
.tag-button:hover {
border-color: #0068ee;
transform: translateY(-1px);
}
.tag-button.active {
background-color: #0068ee;
border-color: #0068ee;
......
......@@ -90,6 +90,7 @@ body {
width: 100%;
border: none;
display: block;
font-size: .29rem;
}
.alertCon .ali textarea::placeholder{
color: #999;
......@@ -106,6 +107,7 @@ body {
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.alertCon .ali .imgList .addImg img.add{
width: .56rem;
......
......@@ -53,6 +53,29 @@ div{
font-size: .32rem;
}
.tabList{
display: flex;
margin: .48rem;
color: #666;
font-size: .32rem;
background: #F1F4F9;
border-radius: .16rem;
height: .96rem;
align-items: center;
padding: .08rem;
}
.tabList div{
width: 33.33%;
text-align: center;
}
.tabList div.cho{
border-radius: .12rem;
background: #FFF;
color: #0068EE;
height: .8rem;
line-height: .8rem;
}
.logo {
width: .8rem;
height: .8rem;
......
......@@ -25,7 +25,7 @@ body {
position: relative;
}
.worker-con{
padding-bottom: 1.31rem; /* 为底部导航预留空间 */
padding-bottom: 1.31rem; /* 为底部导航预留空间 */
}
/* 搜索区域 */
......@@ -117,6 +117,7 @@ body {
.filter-tags {
display: flex;
padding: 0.32rem;
padding-bottom: 0;
}
.filter-tag {
......@@ -133,14 +134,33 @@ body {
color: #0068EE;
}
.loginOut{
display: flex;
align-items: center;
justify-content: center;
border-radius: .08rem;
background: #EBEDF0;
width: 1.8rem;
height: .6rem;
color: #666;
font-size: .28rem;
margin: .64rem auto;
}
.loginOut img{
width: .32rem;
height: .32rem;
margin-right: .08rem;
}
/* 商机列表 */
.business-list {
padding: 0 0.32rem;
height: calc(100vh - 3.8rem);
height: calc(100vh - 2.8rem);
overflow: auto;
margin-top: .32rem;
}
.worker-con .business-list{
height: calc(100vh - 5.2rem);
height: calc(100vh - 3.8rem);
}
.business-card {
......
......@@ -3,16 +3,33 @@ const util = new window.publicMethod() ;
new Vue({
el: '#app',
data: {
platform: 'yx',
loginForm: {
employeeId: '',
phoneNumber: '',
verifyCode: ''
employeeId: '23123456',
phoneNumber: '13718590607',
verifyCode: '123456'
},
countdown: 0,
countdownTimer: null,
clickFlag: false
},
methods: {
tabChang(type){
this.platform = type
localStorage.setItem('platform',type)
if(type == 'gw'){
this.loginForm.employeeId = '1235456'
this.loginForm.phoneNumber = '13718596969'
}else if(type == 'yx'){
this.loginForm.employeeId = '23123456'
this.loginForm.phoneNumber = '13718590607'
}else{
this.loginForm.employeeId = '15862709858'
this.loginForm.phoneNumber = '15862709858'
}
},
getVerifyCode() {
let pa = this.loginForm
......@@ -37,10 +54,9 @@ new Vue({
this.clickFlag = true
util.httpRequest({
url: '/mobile/sendSms',
middleUrl: '/zhijian-trial/api',
url: '/send-sms',
data: {
campaignId: pa.employeeId,
personnelCode: pa.employeeId,
phone: pa.phoneNumber,
},
}).then(res=>{
......@@ -59,7 +75,7 @@ new Vue({
}, 1000);
}else{
this.clickFlag = false
util.toast(res.msg || '获取失败')
util.toast(res.message || '获取失败')
}
}).catch(()=>{
this.clickFlag = false
......@@ -98,24 +114,30 @@ new Vue({
}
util.httpRequest({
url: '/mobile/login',
middleUrl: '/zhijian-trial/api',
url: '/phone-login',
data: {
campaignId: pa.employeeId,
personnelCode: pa.employeeId,
phone: pa.phoneNumber,
smsCode: pa.verifyCode
},
}).then(res=>{
if(res.code == 200){
localStorage.setItem('userInfo',JSON.stringify(res.data.personnel))
localStorage.setItem('tokenInfo',JSON.stringify(res.data.tokenInfo))
if(this.platform == 'gw'){
window.location.href = 'addBusi.html'
}else{
window.location.href = 'myBusi.html'
}
}else{
util.toast(res.msg || '登录失败')
util.toast(res.message || '登录失败')
}
})
}
},
created(){
},
beforeDestroy() {
// 清除定时器
......
......@@ -16,6 +16,9 @@
}
},
methods: {
goAdd(){
location.href = 'addBusi.html?source=zhijian'
},
goBack(){
history.go(-1)
}
......
......@@ -72,8 +72,23 @@
*
*/
httpRequest:function(param){
let middle = param.middleUrl || '/zhijian-trial/ha'
let pa = localStorage.getItem('appLoginInfo')
let middle = '/compass/api/'
if(param.middle){
middle += param.middle
}else{
if(localStorage.getItem('platform') == 'gw'){
middle += 'personnel'
}
if(localStorage.getItem('platform') == 'yx'){
middle += 'marketing'
}
if(localStorage.getItem('platform') == 'gov'){
middle += 'gov-marketing'
}
}
let pa = localStorage.getItem('tokenInfo')
if(pa){
pa = JSON.parse(pa)
}else{
......@@ -88,7 +103,7 @@
data:param.data,
headers: {
'Content-Type': 'application/json',
'x-access-token': pa.tokenValue
'Authorization': pa.token||''
}
}).then((res) => {
resolve(res.data)
......@@ -97,6 +112,31 @@
})
})
},
detailTime: function(num,flag) {
if (num == null) {
return '';
} else {
num = Number(num);
let d = new Date(num);
let year = d.getFullYear();
let month = d.getMonth() + 1;
let date = d.getDate();
let hour = d.getHours();
let minute = d.getMinutes();
let second = d.getSeconds();
month < 10 ? month = '0' + month : month;
date < 10 ? date = '0' + date : date;
hour < 10 ? hour = '0' + hour : hour;
minute < 10 ? minute = '0' + minute : minute;
second < 10 ? second = '0' + second : second;
if(flag){
return year + "-" + month + "-" + date + " " + hour + ":" + minute
}
return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
}
},
}
window.publicMethod = utils
})()
\ No newline at end of file
......@@ -20,6 +20,12 @@
</div>
</div>
<div class="tabList">
<div :class="{cho: platform=='yx'}" @click="tabChang('yx')">C端支撑</div>
<div :class="{cho: platform=='gov'}" @click="tabChang('gov')">政企支撑</div>
<div :class="{cho: platform=='gw'}" @click="tabChang('gw')">装维师傅</div>
</div>
<div class="login-form">
<div class="input-group">
<img src="images/1.png" alt="工号图标" class="input-icon">
......@@ -58,7 +64,7 @@
<div @click="login" class="login-btn">登录</div>
<div class="loginTs">登录即表示您同意<span>《用户协议》</span><span>《隐私协议》</span></div>
<!-- <div class="loginTs">登录即表示您同意<span>《用户协议》</span>和<span>《隐私协议》</span></div> -->
</div>
</div>
</div>
......@@ -66,6 +72,6 @@
<script src="js/axios.min.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/util.js"></script>
<script src="js/login.js?444"></script>
<script src="js/login.js?441234"></script>
</body>
</html>
\ No newline at end of file
......@@ -18,25 +18,25 @@
:class="{ active: activeTab === 'all' }"
@click="switchTab('all')"
data-node-id="355:516"
>全部商机{{ totalCount }}</div>
>全部商机{{ detail.totalCount }}</div>
<div
class="tab-text"
:class="{ active: activeTab === 'pending' }"
@click="switchTab('pending')"
:class="{ active: activeTab === '1' }"
@click="switchTab('1')"
data-node-id="355:517"
>待跟进{{ pendingCount }}</div>
>待跟进{{ detail.pendingCount }}</div>
<div
class="tab-text"
:class="{ active: activeTab === 'follow-up' }"
@click="switchTab('follow-up')"
:class="{ active: activeTab === '2' }"
@click="switchTab('2')"
data-node-id="355:518"
>跟进中{{ followUpCount }}</div>
>跟进中{{ detail.followingCount }}</div>
<div
class="tab-text"
:class="{ active: activeTab === 'completed' }"
@click="switchTab('completed')"
:class="{ active: activeTab === '3,4,5' }"
@click="switchTab('3,4,5')"
data-node-id="355:519"
>已完结{{ completedCount }}</div>
>已完结{{ detail.finishedCount }}</div>
</div>
</div>
......@@ -57,11 +57,11 @@
</div>
<!-- 筛选标签 -->
<div class="filter-tags" data-node-id="355:533">
<div class="filter-tags" data-node-id="355:533" v-if="activeTab == '3,4,5'">
<div
v-for="tag in filterTags"
:key="tag.id"
:class="['filter-tag', { active: tag.selected }]"
:class="['filter-tag', { active: tag.id==tagId }]"
:data-node-id="tag.nodeId"
@click="selectFilterTag(tag.id)"
>
......@@ -72,19 +72,18 @@
<!-- 商机列表 -->
<div class="business-list">
<div
v-for="(business, index) in filteredBusinessList"
v-for="(business, index) in detail.records"
:key="business.id"
class="business-card"
:data-node-id="business.nodeId"
@click="viewBusinessDetail(business)">
<div class="card-content">
<!-- 顶部编号和状态 -->
<div class="card-header" data-node-id="355:432">
<div class="business-number" data-node-id="355:433">
<div class="number-text" data-node-id="355:434">#{{ business.orderNumber }}</div>
<div class="number-text" data-node-id="355:434">{{ business.opportunityCode }}</div>
</div>
<div :class="['status-badge', business.statusClass]" data-node-id="355:435">
<span>{{ business.statusText }}</span>
<div :class="['status-badge', getStatusCalss(business.status)]" data-node-id="355:435">
<span>{{ business.statusName }}</span>
</div>
</div>
......@@ -94,7 +93,7 @@
<div class="detail-row" data-node-id="355:437">
<img class="detail-icon" src="images/location-icon.svg" alt="地址图标">
<div class="detail-text" data-node-id="355:441">
<span>{{ business.address }}</span>
<span>{{ addressShow(business.customerAddress) }}</span>
</div>
</div>
......@@ -102,7 +101,7 @@
<div class="detail-row contact-row" data-node-id="355:443">
<img class="detail-icon" src="images/user-icon.svg" alt="地址图标">
<div class="detail-text" data-node-id="355:446">
<span>{{ business.contactPhone }}</span>
<span>{{ business.customerPhone }}</span>
</div>
</div>
......@@ -111,33 +110,37 @@
<img class="detail-icon" src="images/tag-icon.svg" alt="地址图标">
<div class="business-tags" data-node-id="355:452">
<div
v-for="tag in business.tags"
:key="tag.id"
v-for="tag in business.tagNames"
class="business-tag"
:data-node-id="tag.nodeId"
>
{{ tag.name }}
{{ tag }}
</div>
</div>
</div>
<!-- 处理人信息 -->
<div class="processor-info" data-name="Container" data-node-id="355:457">
<span>处理人:{{ business.processor }}</span>
<span>处理人:{{ business.marketingStaffName }}</span>
</div>
<!-- 时间信息 -->
<div class="time-info" data-name="Container" data-node-id="355:459">
<div class="submit-time" data-name="Container" data-node-id="355:460">
<span>提交:{{ business.submitTime }}</span>
<span>提交:{{ switchTime(business.createTime) }}</span>
</div>
<div class="update-time">
<span>更新:{{ business.updateTime }}</span>
<span>更新:{{ switchTime(business.latestFollowTime)}}</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="detail.records.length <= 0" style="text-align: center;font-size: .4rem;padding-top: 2rem;">暂无订单</div>
<div class="loginOut" @click="loginOut">
<img src="images/loginout.png" alt="">
<div>退出</div>
</div>
</div>
<!-- 底部导航 -->
......@@ -154,7 +157,7 @@
class="nav-item all-business active"
data-name="全部商机"
data-node-id="355:529">
<img class="nav-icon" src="images/business-icon.svg" alt="收集商机">
<img class="nav-icon" src="images/business-icon-active.svg" alt="收集商机">
<span class="nav-text" data-node-id="355:532">全部商机</span>
</div>
</div>
......@@ -162,6 +165,7 @@
</div>
<!-- 引入Vue.js -->
<script src="js/axios.min.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/util.js"></script>
<script src="js/myBusi.js"></script>
......
......@@ -28,7 +28,7 @@
</div>
</div>
<div class="botButt" >发现商机</div>
<div class="botButt" @click="goAdd">发现商机</div>
<div class="botButt noBusi" @click="goBack">暂无商机</div>
</div>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!