提交 #1
21
package.json
21
package.json
@@ -17,9 +17,20 @@
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,vue}": ["eslint --fix", "git add"]
|
||||
"src/**/*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"keywords": ["vue", "admin", "dashboard", "element-ui", "boilerplate", "admin-template", "management-system"],
|
||||
"keywords": [
|
||||
"vue",
|
||||
"admin",
|
||||
"dashboard",
|
||||
"element-ui",
|
||||
"boilerplate",
|
||||
"admin-template",
|
||||
"management-system"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/y_project/RuoYi-Vue.git"
|
||||
@@ -42,6 +53,7 @@
|
||||
"screenfull": "5.0.2",
|
||||
"sortablejs": "1.10.2",
|
||||
"vue": "2.6.12",
|
||||
"vue-amap": "^0.5.10",
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-cropper": "0.5.5",
|
||||
"vue-meta": "2.4.0",
|
||||
@@ -72,5 +84,8 @@
|
||||
"node": ">=8.9",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": ["> 1%", "last 2 versions"]
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
]
|
||||
}
|
||||
|
||||
43
src/api/sch/classType.js
Normal file
43
src/api/sch/classType.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询班型列表
|
||||
export function getClassTypeTableList(query) {
|
||||
return request({
|
||||
url: '/sch/classType/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增班型
|
||||
export function insertClassType(params) {
|
||||
return request({
|
||||
url: '/sch/classType',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
// 修改班型
|
||||
export function updateClassType(params) {
|
||||
return request({
|
||||
url: '/sch/classType',
|
||||
method: 'put',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
// 删除班型
|
||||
export function deleteClassType(ids) {
|
||||
return request({
|
||||
url: '/sch/classType/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
//克隆班型
|
||||
export function cloneClassType(data) {
|
||||
return request({
|
||||
url: '/sch/classType/clone',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
27
src/api/sch/place.js
Normal file
27
src/api/sch/place.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取地图数据
|
||||
export function getMapData() {
|
||||
return request({
|
||||
url: '/sch/place/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新驾校状态
|
||||
export async function updateSchoolStatus(data) {
|
||||
return await request({
|
||||
url: '/sch/place/updateSchool',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存场地状态
|
||||
export function savePlace(data) {
|
||||
return request({
|
||||
url: '/sch/place',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
36
src/api/sch/school.js
Normal file
36
src/api/sch/school.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import request from '@/utils/request'
|
||||
export default {
|
||||
pageList(data = {}) {
|
||||
return request({
|
||||
url: "/sch/school/list",
|
||||
method: "get",
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
getById(id) {
|
||||
return request({
|
||||
url: `/sch/school/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
add(data = {}) {
|
||||
return request({
|
||||
url: "/sch/school",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
},
|
||||
update(data = {}) {
|
||||
return request({
|
||||
url: "/sch/school",
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
delete(id) {
|
||||
return request({
|
||||
url: `/sch/school/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -50,3 +50,10 @@ export function delDept(deptId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
// 查询部门下拉树结构
|
||||
export function deptTreeSelect() {
|
||||
return request({
|
||||
url: '/system/dept/deptTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
42
src/api/system/employee.js
Normal file
42
src/api/system/employee.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import request from '@/utils/request'
|
||||
export default {
|
||||
pageList(data = {}) {
|
||||
return request({
|
||||
url: "/system/employee/list",
|
||||
method: "get",
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
getById(id) {
|
||||
return request({
|
||||
url: `/system/employee/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
add(data = {}) {
|
||||
return request({
|
||||
url: "/system/employee",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
},
|
||||
update(data = {}) {
|
||||
return request({
|
||||
url: "/system/employee",
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
delete(id) {
|
||||
return request({
|
||||
url: `/system/employee/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
getEmployee() {
|
||||
return request({
|
||||
url: "/system/employee/getEmployees",
|
||||
method: "get"
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -117,3 +117,12 @@ export function deptTreeSelect(roleId) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function getRoleOptions() {
|
||||
return request({
|
||||
url: '/system/role/getRoles',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import request from '@/utils/request'
|
||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||
import {
|
||||
parseStrEmpty
|
||||
} from "@/utils/ruoyi";
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
@@ -125,11 +127,3 @@ export function updateAuthRole(data) {
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询部门下拉树结构
|
||||
export function deptTreeSelect() {
|
||||
return request({
|
||||
url: '/system/user/deptTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
0
src/api/tool/common.js
Normal file
0
src/api/tool/common.js
Normal file
0
src/api/tool/map.js
Normal file
0
src/api/tool/map.js
Normal file
186
src/api/zs/clue.js
Normal file
186
src/api/zs/clue.js
Normal file
@@ -0,0 +1,186 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询线索列表
|
||||
export function getClueList(query) {
|
||||
return request({
|
||||
url: '/zs/clue/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增线索
|
||||
export function addClue(data) {
|
||||
return request({
|
||||
url: '/zs/clue',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改线索
|
||||
export function updateClue(data) {
|
||||
return request({
|
||||
url: '/zs/clue',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//删除
|
||||
export function deleteClue(data) {
|
||||
return request({
|
||||
url: '/zs/clue',
|
||||
method: 'delete',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
// 导出
|
||||
export function exportData(query) {
|
||||
return request({
|
||||
url: '/zs/clue/export',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导入模板
|
||||
export function importTemplate(param) {
|
||||
return request({
|
||||
url: '/zs/clue/importTemplate',
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
// 导入
|
||||
export function importData(data) {
|
||||
return request({
|
||||
url: '/zs/clue/importData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//查询登记getSign
|
||||
export function getSign(query) {
|
||||
return request({
|
||||
url: '/zs/clue/sign',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//保存登记
|
||||
export function saveSign(data) {
|
||||
return request({
|
||||
url: '/zs/clue/sign',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//甩单
|
||||
export function saveDistribute(data) {
|
||||
return request({
|
||||
url: '/zs/clue/distribute',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//驳回
|
||||
export function refuse(data) {
|
||||
return request({
|
||||
url: '/zs/clue/refuse',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//查询甩单记录
|
||||
export function getDistributeRecord(param) {
|
||||
return request({
|
||||
url: '/zs/clue/distributerecord',
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
|
||||
//查询跟踪记录
|
||||
export function getFollowRecord(param) {
|
||||
return request({
|
||||
url: '/zs/clue/followrecord',
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export function getConsultRecord(param) {
|
||||
return request({
|
||||
url: '/zs/clue/consultrecord',
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
// 获取已过期
|
||||
export function getClueCountBadge() {
|
||||
return request({
|
||||
url: `/zs/clue/badgeCount`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 批量更新
|
||||
export function batchUpdate(data) {
|
||||
return request({
|
||||
url: `/zs/clue/batchUpdate`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//公海线索 getPublicList
|
||||
export function getPublicList(param) {
|
||||
return request({
|
||||
url: `/zs/clue/public/list`,
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
|
||||
//拾取线索
|
||||
export function pickupClue(data) {
|
||||
return request({
|
||||
url: `/zs/clue/public/pickup`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//丢弃线索
|
||||
export function discardClue(data) {
|
||||
return request({
|
||||
url: `/zs/clue/public/discard`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//查询接收
|
||||
export function getAccept() {
|
||||
return request({
|
||||
url: `/zs/clue/accept`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//丢弃线索
|
||||
export function updateAccept(data) {
|
||||
return request({
|
||||
url: `/zs/clue/accept`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
89
src/api/zs/sign.js
Normal file
89
src/api/zs/sign.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询线索列表
|
||||
export function getSignList(query) {
|
||||
return request({
|
||||
url: '/zs/sign/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出
|
||||
export function exportData(query) {
|
||||
return request({
|
||||
url: '/zs/sign/export',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导入模板
|
||||
export function importTemplate() {
|
||||
return request({
|
||||
url: '/zs/sign/importTemplate',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 导入
|
||||
export function importData(data) {
|
||||
return request({
|
||||
url: '/zs/sign/importData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function addSign(data) {
|
||||
return request({
|
||||
url: '/zs/sign',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateSign(data) {
|
||||
return request({
|
||||
url: '/zs/sign',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getClues(param) {
|
||||
return request({
|
||||
url: '/zs/sign/clue',
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function deleteSign(data) {
|
||||
return request({
|
||||
url: '/zs/sign',
|
||||
method: 'delete',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
//审核登记
|
||||
export function checkSign(data) {
|
||||
return request({
|
||||
url: '/zs/sign/check',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//审核记录
|
||||
export function getCheckRecord(data) {
|
||||
return request({
|
||||
url: '/zs/sign/check',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
BIN
src/assets/images/place/flag_black.png
Normal file
BIN
src/assets/images/place/flag_black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 341 B |
BIN
src/assets/images/place/flag_blue.png
Normal file
BIN
src/assets/images/place/flag_blue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 357 B |
BIN
src/assets/images/place/flag_green.png
Normal file
BIN
src/assets/images/place/flag_green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 353 B |
BIN
src/assets/images/place/flag_purple.png
Normal file
BIN
src/assets/images/place/flag_purple.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 350 B |
BIN
src/assets/images/place/flag_red.png
Normal file
BIN
src/assets/images/place/flag_red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 358 B |
BIN
src/assets/images/place/flag_yellow.png
Normal file
BIN
src/assets/images/place/flag_yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 355 B |
278
src/components/CustomColumnTable/index.vue
Normal file
278
src/components/CustomColumnTable/index.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<!--
|
||||
组件方法:
|
||||
getlist: 将分页组件合并,所以需要分页查询列表的数据的方法
|
||||
selectRow:选择行时触发 【配合selectable使用】
|
||||
callFunc: 操作按钮点击时触发 【配合tableBtns使用】 会传递按钮的方法名和行数据
|
||||
clickColumn: 点击表格列时触发 【配合clickColumns使用】 传递到父级时,接受两个参数,(column,row)点击的列名,行数据
|
||||
clickRow: 点击表格行时触发 ps: 建议不要与点击表格列方法同时使用
|
||||
changeSort: 表格列排序
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="table-custom">
|
||||
<span class="custom-table-btn" @click="showCustomClick">自定义列表</span>
|
||||
<el-table v-loading="tableLoading" :data="tableList" border stripe max-height="500" @selection-change="handleSelectionChange" @sort-change="changeSort" @row-click="handleRowClick">
|
||||
<el-table-column v-if="selectable" type="selection" width="60" />
|
||||
<el-table-column type="index" :index="(index)=>((queryParams.pageNum - 1)*queryParams.pageSize + index + 1)" label="序号" width="60" />
|
||||
<el-table-column v-for="(item, index) in tableColumns" :key="index" :label="item.label" :width="item.width" :prop="item.prop" :sortable="sortableColumns.includes(item.prop)" :min-width="clickColumns.includes(item.prop)?150:100">
|
||||
<template slot-scope="{row}">
|
||||
<el-button v-if="clickColumns.includes(item.prop)" type="text" size="mini" @click="$emit('clickColumn', item.prop, row)">{{ row[item.prop] }}</el-button>
|
||||
<span v-else>{{ row[item.prop] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<slot name="appendColumn" />
|
||||
<el-table-column v-if="tableBtns.length > 0" label="操作" fixed="right" :width="getOpearateWidth()">
|
||||
<template slot-scope="{row}">
|
||||
<template v-if="tableBtns">
|
||||
<template v-for="(item, index) in tableBtns.slice(0, 2)">
|
||||
<el-button v-if="btnShow(row, item)" :key="index" type="text" @click.native.stop="call(item.buttonTrigger, row)">{{ item.buttonName }}</el-button>
|
||||
</template>
|
||||
<template v-if="tableBtns.length > 2">
|
||||
<el-dropdown class="ml0" trigger="click">
|
||||
<el-button type="primary" size="mini">
|
||||
更多
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<template v-for="(btn, idx) in tableBtns.slice(2, tableBtns.length)">
|
||||
<el-dropdown-item v-if="btnShow(row, item)" :key="idx" @click.native.stop="call(btn.buttonTrigger, row)">{{ btn.buttonName }}</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<pagination :page-sizes="[10, 20, 30, 50, 100, 200]" :total="queryParams.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="_getTableList" />
|
||||
<el-dialog title="自定义字段配置" :visible.sync="columnsetDialogShow" append-to-body class="dialog500" width="60%">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="18">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<el-checkbox v-model="columnCheckAll" @change="val => dialogSelectColumn = val ? tableAllFields.map(item=>item.prop):[] ">可选显示数据列</el-checkbox>
|
||||
</div>
|
||||
<el-checkbox-group v-model="dialogSelectColumn" style="line-height: 32px">
|
||||
<el-checkbox v-for="item in tableAllFields" :key="item.prop" :label="item.prop">{{ item.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
已选{{ dialogSelectColumn.length }}项
|
||||
<span class="ml0" style="font-size: 8px">(可拖动排序)</span>
|
||||
</div>
|
||||
<draggable :list="dialogSelectColumn" :animation="340" group="column">
|
||||
<div v-for="item in dialogSelectColumn" :key="item" class="hover-pointer">
|
||||
<div style="line-height: 24px;">{{ tableAllFields.find(column=> column.prop === item).label }}</div>
|
||||
</div>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<span slot="footer">
|
||||
<el-button @click="columnsetDialogShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleChangeColumns">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
export default {
|
||||
components: { draggable },
|
||||
props: {
|
||||
tableList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tableLoading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
queryParams: {
|
||||
required: true,
|
||||
type: Object,
|
||||
default: () => ({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
}),
|
||||
},
|
||||
// 表格操作按钮
|
||||
tableBtns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格可选
|
||||
selectable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 接口访问得到的所有表格列/或者写死的表格列格
|
||||
* 格式是: { pror: '', label: '' }
|
||||
*/
|
||||
tableAllFields: {
|
||||
required: true,
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
/**
|
||||
* 默认表格列
|
||||
* 字符串数组: prop 对应值(字段名)
|
||||
*/
|
||||
defaultColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
tablename: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// 可点击的列
|
||||
clickColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 控制按钮隐藏
|
||||
btnShowValid: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 可排序的列
|
||||
sortableColumns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columnsetDialogShow: false,
|
||||
columnCheckAll: false,
|
||||
dialogSelectColumn: [],
|
||||
name: this.tablename || this.$route.name,
|
||||
customColumns: [], // 本地缓存的表格列
|
||||
tableColumns: [], // 实际展示表格列
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tableAllFields: {
|
||||
handler(val) {
|
||||
const localStr = localStorage.getItem(this.name)
|
||||
const arr = localStr ? localStr.split(',') : []
|
||||
if (this.isNullOrEmpty(arr)) {
|
||||
this.tableColumns = val
|
||||
.filter((item) => this.defaultColumns.includes(item.prop))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
this.defaultColumns.indexOf(a.prop) -
|
||||
this.defaultColumns.indexOf(b.prop)
|
||||
)
|
||||
this.customColumns = this.defaultColumns
|
||||
} else {
|
||||
this.tableColumns = val
|
||||
.filter((item) => arr.includes(item.prop))
|
||||
.sort((a, b) => arr.indexOf(a.prop) - arr.indexOf(b.prop))
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.isNullOrEmpty(this.customColumns)) {
|
||||
const localStr = localStorage.getItem(this.name)
|
||||
this.customColumns = localStr ? localStr.split(',') : []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showCustomClick() {
|
||||
this.columnsetDialogShow = true
|
||||
this.dialogSelectColumn = [...this.customColumns]
|
||||
},
|
||||
handleChangeColumns() {
|
||||
this.customColumns = this.dialogSelectColumn
|
||||
this.tableColumns = this.tableAllFields
|
||||
.filter((item) => this.customColumns.includes(item.prop))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
this.customColumns.indexOf(a.prop) -
|
||||
this.customColumns.indexOf(b.prop)
|
||||
)
|
||||
localStorage.setItem(this.name, this.customColumns.join(','))
|
||||
this.columnsetDialogShow = false
|
||||
},
|
||||
_getTableList() {
|
||||
this.$emit('update:queryParams', this.queryParams)
|
||||
this.$emit('getlist')
|
||||
},
|
||||
handleSelectionChange(row) {
|
||||
this.selectable && this.$emit('selectRow', row)
|
||||
},
|
||||
changeSort(val) {
|
||||
this.$emit('changeSort', val)
|
||||
},
|
||||
handleRowClick(row) {
|
||||
this.$emit('clickRow', row)
|
||||
},
|
||||
call(funcName, row) {
|
||||
this.$emit('callFunc', funcName, row)
|
||||
},
|
||||
getOpearateWidth() {
|
||||
let width = 30
|
||||
for (let index = 0; index < this.tableBtns.length; index++) {
|
||||
if (index < 2) {
|
||||
const column = this.tableBtns[index]
|
||||
width += column.buttonName.length * 15
|
||||
column.buttonColor !== 'text' && (width += 30)
|
||||
} else {
|
||||
width += 70 // 更多
|
||||
break
|
||||
}
|
||||
}
|
||||
return width
|
||||
},
|
||||
btnShow(row, btn) {
|
||||
if (this.isNullOrEmpty(this.btnShowValid)) {
|
||||
return true
|
||||
} else {
|
||||
let show = true
|
||||
for (let i = 0; i < this.btnShowValid.length; i++) {
|
||||
const valid = this.btnShowValid[i]
|
||||
if (row[valid.key] === valid.value) {
|
||||
show = btn.buttonName !== valid.btnName
|
||||
}
|
||||
}
|
||||
return show
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-custom {
|
||||
width: calc(100% - 30px);
|
||||
position: relative;
|
||||
}
|
||||
.custom-table-btn {
|
||||
width: 30px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: -31px;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
color: cadetblue;
|
||||
border: 1px solid #e6ebf5;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -13,6 +13,8 @@ import ImageUpload from "@/components/ImageUpload";
|
||||
import ImagePreview from "@/components/ImagePreview";
|
||||
// 字典标签组件
|
||||
import DictTag from "@/components/DictTag";
|
||||
// 字典数据组件
|
||||
import DictData from '@/components/DictData'
|
||||
|
||||
// 全局组件挂载
|
||||
Vue.component("DictTag", DictTag);
|
||||
@@ -22,3 +24,5 @@ Vue.component("Editor", Editor);
|
||||
Vue.component("FileUpload", FileUpload);
|
||||
Vue.component("ImageUpload", ImageUpload);
|
||||
Vue.component("ImagePreview", ImagePreview);
|
||||
|
||||
DictData.install()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<section class="app-main bc-f7">
|
||||
<section class="app-main">
|
||||
<transition name="fade-transform" mode="out-in">
|
||||
<keep-alive :include="cachedViews">
|
||||
<router-view v-if="!$route.meta.link" :key="key" />
|
||||
|
||||
29
src/main.js
29
src/main.js
@@ -19,9 +19,38 @@ import './global';
|
||||
import './assets/icons'; // icon
|
||||
import './permission'; // permission control
|
||||
|
||||
import {
|
||||
download
|
||||
} from '@/utils/request'
|
||||
import {
|
||||
getDicts
|
||||
} from "@/api/system/dict/data";
|
||||
import {
|
||||
getConfigKey
|
||||
} from "@/api/system/config";
|
||||
import {
|
||||
parseTime,
|
||||
resetForm,
|
||||
addDateRange,
|
||||
selectDictLabel,
|
||||
selectDictLabels,
|
||||
handleTree
|
||||
} from "@/utils/ruoyi";
|
||||
|
||||
// 头部标签组件
|
||||
import VueMeta from 'vue-meta';
|
||||
|
||||
// 全局方法挂载
|
||||
Vue.prototype.getDicts = getDicts
|
||||
Vue.prototype.getConfigKey = getConfigKey
|
||||
Vue.prototype.parseTime = parseTime
|
||||
Vue.prototype.resetForm = resetForm
|
||||
Vue.prototype.addDateRange = addDateRange
|
||||
Vue.prototype.selectDictLabel = selectDictLabel
|
||||
Vue.prototype.selectDictLabels = selectDictLabels
|
||||
Vue.prototype.download = download
|
||||
Vue.prototype.handleTree = handleTree
|
||||
|
||||
import Mixin from './mixins/Mixin';
|
||||
Vue.mixin(Mixin);
|
||||
|
||||
|
||||
@@ -29,17 +29,14 @@ import Layout from '@/layout';
|
||||
*/
|
||||
|
||||
// 公共路由
|
||||
export const constantRoutes = [
|
||||
{
|
||||
export const constantRoutes = [{
|
||||
path: '/redirect',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
component: () => import('@/views/redirect')
|
||||
}
|
||||
]
|
||||
children: [{
|
||||
path: '/redirect/:path(.*)',
|
||||
component: () => import('@/views/redirect')
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
@@ -65,108 +62,122 @@ export const constantRoutes = [
|
||||
path: '',
|
||||
component: Layout,
|
||||
redirect: 'index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: { title: '首页', icon: 'dashboard', affix: true }
|
||||
children: [{
|
||||
path: 'index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: {
|
||||
title: '首页',
|
||||
icon: 'dashboard',
|
||||
affix: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/demo',
|
||||
component: Layout,
|
||||
redirect: 'noredirect',
|
||||
meta: { title: 'Demo', icon: 'xx' },
|
||||
children: [
|
||||
{
|
||||
path: '/base-page',
|
||||
component: () => import('@/views/demo/basePage/index'),
|
||||
name: 'BasePage',
|
||||
meta: { title: 'BasePage', icon: 'xx' }
|
||||
},
|
||||
{
|
||||
path: '/base-components',
|
||||
component: () => import('@/views/demo/baseComponents/index'),
|
||||
name: 'BaseComponents',
|
||||
meta: { title: 'BaseComponents', icon: 'xx' }
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
// {
|
||||
// path: '/demo',
|
||||
// component: Layout,
|
||||
// redirect: 'noredirect',
|
||||
// meta: {
|
||||
// title: 'Demo',
|
||||
// icon: 'xx'
|
||||
// },
|
||||
// children: [{
|
||||
// path: '/base-page',
|
||||
// component: () => import('@/views/demo/basePage/index'),
|
||||
// name: 'BasePage',
|
||||
// meta: {
|
||||
// title: 'BasePage',
|
||||
// icon: 'xx'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: '/base-components',
|
||||
// component: () => import('@/views/demo/baseComponents/index'),
|
||||
// name: 'BaseComponents',
|
||||
// meta: {
|
||||
// title: 'BaseComponents',
|
||||
// icon: 'xx'
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: '/user',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
redirect: 'noredirect',
|
||||
children: [
|
||||
{
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
children: [{
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: {
|
||||
title: '个人中心',
|
||||
icon: 'user'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
];
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes = [
|
||||
{
|
||||
export const dynamicRoutes = [{
|
||||
path: '/system/user-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:user:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||
children: [{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: {
|
||||
title: '分配角色',
|
||||
activeMenu: '/system/user'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:role:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||
children: [{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: {
|
||||
title: '分配用户',
|
||||
activeMenu: '/system/role'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:dict:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||
children: [{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: {
|
||||
title: '字典数据',
|
||||
activeMenu: '/system/dict'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/monitor/job-log',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['monitor:job:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' }
|
||||
children: [{
|
||||
path: 'index',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: {
|
||||
title: '调度日志',
|
||||
activeMenu: '/monitor/job'
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -178,6 +189,8 @@ Router.prototype.push = function push(location) {
|
||||
|
||||
export default new Router({
|
||||
mode: 'history', // 去掉url中的#
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
scrollBehavior: () => ({
|
||||
y: 0
|
||||
}),
|
||||
routes: constantRoutes
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import auth from '@/plugins/auth';
|
||||
import router, { constantRoutes, dynamicRoutes } from '@/router';
|
||||
import { getRouters } from '@/api/menu';
|
||||
import router, {
|
||||
constantRoutes,
|
||||
dynamicRoutes
|
||||
} from '@/router';
|
||||
import {
|
||||
getRouters
|
||||
} from '@/api/menu';
|
||||
import Layout from '@/layout/index';
|
||||
import ParentView from '@/components/ParentView';
|
||||
import InnerLink from '@/layout/components/InnerLink';
|
||||
@@ -30,7 +35,9 @@ const permission = {
|
||||
},
|
||||
actions: {
|
||||
// 生成路由
|
||||
GenerateRoutes({ commit }) {
|
||||
GenerateRoutes({
|
||||
commit
|
||||
}) {
|
||||
return new Promise((resolve) => {
|
||||
// 向后端请求路由数据
|
||||
getRouters().then((res) => {
|
||||
@@ -39,11 +46,15 @@ const permission = {
|
||||
const sidebarRoutes = filterAsyncRouter(sdata);
|
||||
const rewriteRoutes = filterAsyncRouter(rdata, false, true);
|
||||
const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
|
||||
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true });
|
||||
rewriteRoutes.push({
|
||||
path: '*',
|
||||
redirect: '/404',
|
||||
hidden: true
|
||||
});
|
||||
router.addRoutes(asyncRoutes);
|
||||
commit('SET_ROUTES', rewriteRoutes);
|
||||
// commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes));
|
||||
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat([]));
|
||||
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes));
|
||||
// commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat([]));
|
||||
commit('SET_DEFAULT_ROUTES', sidebarRoutes);
|
||||
commit('SET_TOPBAR_ROUTES', sidebarRoutes);
|
||||
resolve(rewriteRoutes);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const TokenKey = 'Admin-Token';
|
||||
const TokenKey = 'DM-Manage-Token';
|
||||
|
||||
export function getToken() {
|
||||
return Cookies.get(TokenKey);
|
||||
|
||||
@@ -240,3 +240,16 @@ export async function blobValidate(data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function isNullOrEmpty(val) {
|
||||
if (val === null || val === undefined) {
|
||||
return true
|
||||
} else if (val === {} || Object.keys(val).length === 0) {
|
||||
return true
|
||||
} else if (val.length === 0) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
491
src/views/sch/classType.vue
Normal file
491
src/views/sch/classType.vue
Normal file
@@ -0,0 +1,491 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<div class="head-container">
|
||||
<el-input v-model="searchName" placeholder="请输入驾校名称" clearable prefix-icon="el-icon-search" style="margin-bottom: 20px" />
|
||||
</div>
|
||||
<div class="head-container" style="max-height: 700px;overflow-y: auto">
|
||||
<el-tree ref="tree" :data="schoolOption.filter(item => item.label.includes(searchName))" accordion node-key="id" :default-expanded-keys="selectNodes.map(item => item.id)" @node-click="handleNodeClick" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-row :gutter="20">
|
||||
<el-form ref="queryForm" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-input v-model="queryParams.typeName" placeholder="请输入班型名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="queryParams.licenseType" clearable placeholder="选择驾照类型">
|
||||
<el-option v-for="item in licenseTypeOption" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="queryParams.status" placeholder="班型状态" clearable>
|
||||
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleAdd" v-hasPermi="['sch:classType:add']">新增</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" @click="handleDelete" :disabled="multiple" v-hasPermi="['sch:classType:remove']">删除</el-button>
|
||||
<el-button type="primary" icon="el-icon-copy" @click="handleClone" :disabled="multiple" v-hasPermi="['sch:classType:clone']">克隆</el-button>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading.tableLoading" :data="tableDataList" stripe border @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="驾校" prop="schoolName" />
|
||||
<el-table-column label="场地" prop="placeName" />
|
||||
<el-table-column label="班型名称" prop="typeName" />
|
||||
<el-table-column label="驾照类型" prop="licenseType" :formatter="licenseTypeFormat" width="80" />
|
||||
<!-- <el-table-column label="原价" prop="originalPrice" /> -->
|
||||
<el-table-column label="报价" prop="currentPrice" width="60" />
|
||||
<el-table-column label="底价" prop="minPrice" width="60" />
|
||||
<el-table-column label="描述" prop="description" />
|
||||
<el-table-column label="状态" prop="status" :formatter="statusFormat" width="80" />
|
||||
<el-table-column label="创建时间" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="130">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-hasPermi="['sch:classType:edit']" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||
<el-button v-hasPermi="['sch:classType:remove']" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getPageList" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-dialog title="班型设置" :visible.sync="modalVisible" width="500px" append-to-body :close-on-click-modal="false">
|
||||
<el-form ref="modalForm" :model="modalForm" :rules="modalRules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="驾校">
|
||||
<el-input v-model="modalForm.schoolName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="场地">
|
||||
<el-input v-model="modalForm.placeName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班型名称" prop="typeName">
|
||||
<el-input v-model="modalForm.typeName" placeholder="请输入班型名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="驾照类型" prop="licenseType">
|
||||
<el-select v-model="modalForm.licenseType" placeholder="选择驾照类型">
|
||||
<el-option v-for="item in licenseTypeOption" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报价" prop="currentPrice">
|
||||
<el-input v-model="modalForm.currentPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="底价" prop="minPrice">
|
||||
<el-input v-model="modalForm.minPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="甩单低价" prop="orderMinPrice">
|
||||
<el-input v-model="modalForm.orderMinPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="入账低价" prop="enterMinPrice">
|
||||
<el-input v-model="modalForm.enterMinPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司低价" prop="companyMinPrice">
|
||||
<el-input v-model="modalForm.companyMinPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="员工低价" prop="employeeMinPrice">
|
||||
<el-input v-model="modalForm.employeeMinPrice" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="排序" prop="orderNum">
|
||||
<el-input v-model="modalForm.orderNum" placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="currentPrice">
|
||||
<el-radio-group v-model="modalForm.status">
|
||||
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="是否克隆到场地" prop="currentPrice">
|
||||
<el-radio-group v-model="modalForm.clone">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<span>克隆到场地,该班型则不统一管理</span>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
<el-row>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="modalForm.description" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入描述" />
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<span slot="footer">
|
||||
<el-button @click="modalVisible = false">取 消</el-button>
|
||||
<el-button v-loading="loading.modalSaveLoading" type="primary" @click="handleSave">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="克隆班型" :visible.sync="cloneOpen" width="780px" append-to-body :v-loading="loading.cloneLoading">
|
||||
<el-form ref="clonForm" :model="clonForm" :rules="modalRules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="场地" prop="placeIdList">
|
||||
<el-select v-model="clonForm.placeIds" placeholder="请选择" size="small" multiple filterable clearable>
|
||||
<el-option v-for="dict in placeOption" :key="dict.placeId" :label="dict.name" :value="dict.placeId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer" style="padding-top:20px">
|
||||
<el-button type="primary" @click="cloneSave">确 定</el-button>
|
||||
<el-button @click="cloneOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getClassTypeTableList,
|
||||
updateClassType,
|
||||
insertClassType,
|
||||
deleteClassType,
|
||||
cloneClassType
|
||||
} from '@/api/sch/classType'
|
||||
import { validateMoney } from '@/utils/validate'
|
||||
import { getMapData } from '@/api/sch/place'
|
||||
|
||||
export default {
|
||||
name: 'Classtype',
|
||||
data() {
|
||||
return {
|
||||
searchName: '',
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
typeName: undefined,
|
||||
status: undefined,
|
||||
schoolId: this.$store.getters.schoolId,
|
||||
licenseType: undefined,
|
||||
},
|
||||
loading: {
|
||||
tableLoading: false,
|
||||
modalSaveLoading: false,
|
||||
cloneLoading: false
|
||||
},
|
||||
tableDataList: [],
|
||||
total: 0,
|
||||
statusOptions: [],
|
||||
licenseTypeOption: [],
|
||||
modalVisible: false,
|
||||
modalForm: {},
|
||||
modalRules: {
|
||||
typeName: {
|
||||
required: true,
|
||||
message: '班型名称不为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
originalPrice: {
|
||||
required: true,
|
||||
validator: validateMoney,
|
||||
trigger: 'blur',
|
||||
},
|
||||
currentPrice: {
|
||||
required: true,
|
||||
validator: validateMoney,
|
||||
trigger: 'blur',
|
||||
},
|
||||
minPrice: { required: true, validator: validateMoney, trigger: 'blur' },
|
||||
placeIds: {
|
||||
required: true,
|
||||
message: '场地不为空',
|
||||
trigger: 'change',
|
||||
},
|
||||
},
|
||||
schoolOption: [],
|
||||
placeOption: [],
|
||||
selectNodes: [],
|
||||
multiple: true,
|
||||
single: true,
|
||||
cloneOpen: false,
|
||||
clonForm: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDicts('sys_normal_disable').then((response) => {
|
||||
this.statusOptions = response.data
|
||||
})
|
||||
this.getDicts('license_type').then((response) => {
|
||||
this.licenseTypeOption = response.data
|
||||
})
|
||||
this._getSchoolTree()
|
||||
this.getPageList()
|
||||
|
||||
this.deptId = this.$store.getters.schoolId
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
handleQuery() {
|
||||
this.queryParams.page = 1
|
||||
this.getPageList()
|
||||
},
|
||||
getPageList() {
|
||||
this.loading.tableLoading = true
|
||||
const params = {
|
||||
...this.queryParams,
|
||||
schoolId:
|
||||
this.selectNodes.length > 0 ? this.selectNodes[0].id : undefined,
|
||||
placeId:
|
||||
this.selectNodes.length == 2 ? this.selectNodes[1].id : undefined,
|
||||
}
|
||||
this.tableDataList = []
|
||||
getClassTypeTableList(params).then(
|
||||
(response) => {
|
||||
this.tableDataList = response.rows
|
||||
this.total = response.total
|
||||
this.loading.tableLoading = false
|
||||
}
|
||||
)
|
||||
},
|
||||
// 重置搜索
|
||||
resetQuery() {
|
||||
this.queryParams.typeName = ''
|
||||
this.queryParams.status = undefined
|
||||
this.queryParams.schoolId = undefined
|
||||
this.queryParams.placeId = undefined
|
||||
this.queryParams.licenseType = undefined
|
||||
this.handleQuery()
|
||||
},
|
||||
// 查询驾校
|
||||
_getSchoolTree() {
|
||||
getMapData().then((resp) => {
|
||||
if (resp.code == 200) {
|
||||
let sList = resp.data.schoolList.filter((item) => item.showInMap)
|
||||
const pList = resp.data.placeList.filter((item) => item.showInMap)
|
||||
sList = sList.map((item) => ({
|
||||
id: item.schoolId,
|
||||
label: item.schoolName,
|
||||
level: 1,
|
||||
children: pList
|
||||
.filter((place) => item.schoolId === place.schoolId)
|
||||
.map((place) => ({
|
||||
id: place.placeId,
|
||||
label: place.name,
|
||||
level: 2,
|
||||
})),
|
||||
}))
|
||||
this.schoolOption = sList
|
||||
this.placeOption = resp.data.placeList
|
||||
}
|
||||
})
|
||||
},
|
||||
// 新增
|
||||
handleAdd() {
|
||||
if (this.selectNodes.length < 1) {
|
||||
this.msgError('请选择左侧驾校或场地')
|
||||
return
|
||||
}
|
||||
this.resetForm('modalForm')
|
||||
this.modalVisible = true
|
||||
this.modalForm = {
|
||||
typeName: '',
|
||||
status: '0',
|
||||
originalPrice: undefined,
|
||||
licenseType: 'C1',
|
||||
description: '',
|
||||
currentPrice: undefined,
|
||||
typeId: undefined,
|
||||
schoolId: this.selectNodes[0].id,
|
||||
schoolName: this.selectNodes[0].name,
|
||||
clone: false,
|
||||
orderMinPrice: undefined,
|
||||
enterMinPrice: undefined,
|
||||
companyMinPrice: undefined,
|
||||
employeeMinPrice: undefined
|
||||
}
|
||||
|
||||
if (this.selectNodes.length > 1) {
|
||||
this.$set(this.modalForm, "placeId", this.selectNodes[1].id);
|
||||
this.$set(this.modalForm, "placeName", this.selectNodes[1].name);
|
||||
}
|
||||
},
|
||||
// 编辑
|
||||
handleUpdate(listItem) {
|
||||
this.resetForm('modalForm')
|
||||
this.modalForm = {
|
||||
...listItem
|
||||
}
|
||||
if (listItem.placeId) {
|
||||
this.$set(
|
||||
this.modalForm,
|
||||
"placeName",
|
||||
this.placeOption.find(item => item.placeId == listItem.placeId).name
|
||||
);
|
||||
}
|
||||
this.modalVisible = true
|
||||
},
|
||||
// 模态框保存
|
||||
handleSave() {
|
||||
this.$refs.modalForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading.modalSaveLoading = true
|
||||
if (this.modalForm.typeId) {
|
||||
updateClassType(this.modalForm).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('修改成功')
|
||||
this.modalVisible = false
|
||||
this.loading.modalSaveLoading = false
|
||||
this.getPageList()
|
||||
} else {
|
||||
this.$message.error('修改失败:' + resp.message)
|
||||
this.loading.modalSaveLoading = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (!this.modalForm.schoolId) {
|
||||
this.$set(this.modalForm, 'schoolId', this.$store.getters.schoolId)
|
||||
}
|
||||
|
||||
insertClassType(this.modalForm).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('新增成功')
|
||||
this.modalVisible = false
|
||||
this.loading.modalSaveLoading = false
|
||||
this.getPageList()
|
||||
} else {
|
||||
this.$message.error('新增失败:' + resp.message)
|
||||
this.loading.modalSaveLoading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 字典状态字典翻译
|
||||
statusFormat(row, column) {
|
||||
return this.selectDictLabel(this.statusOptions, row.status)
|
||||
},
|
||||
// 字典状态字典翻译
|
||||
placeFormat(row, column) {
|
||||
if (row.placeId) {
|
||||
return this.placeOption.length > 0
|
||||
? this.placeOption.find((item) => item.placeId == row.placeId).name
|
||||
: ''
|
||||
}
|
||||
},
|
||||
// 字典状态字典翻译
|
||||
licenseTypeFormat(row, column) {
|
||||
return this.selectDictLabel(this.licenseTypeOption, row.licenseType)
|
||||
},
|
||||
handleNodeClick(data, node) {
|
||||
if (data.level === 1) {
|
||||
this.selectNodes = [{ id: data.id, name: data.label }]
|
||||
} else {
|
||||
this.selectNodes = [
|
||||
{ id: node.parent.data.id, name: node.parent.data.label },
|
||||
{ id: data.id, name: data.label },
|
||||
]
|
||||
}
|
||||
this.handleQuery()
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.typeId);
|
||||
this.nos = selection.map(item => item.productNo);
|
||||
this.single = selection.length != 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(item) {
|
||||
const typeId = item.typeId || this.ids;
|
||||
|
||||
this.$confirm(
|
||||
'是否确认删除?',
|
||||
'警告',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
deleteClassType(typeId).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('删除成功')
|
||||
this.getPageList()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(function () { })
|
||||
},
|
||||
handleClone() {
|
||||
this.cloneOpen = true;
|
||||
this.clonForm = {
|
||||
typeIds: this.ids,
|
||||
placeIds: undefined
|
||||
}
|
||||
},
|
||||
cloneSave() {
|
||||
this.$refs.clonForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading.cloneLoading = true
|
||||
cloneClassType(this.clonForm).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('克隆成功')
|
||||
this.cloneOpen = false
|
||||
this.getPageList()
|
||||
}
|
||||
this.loading.cloneLoading = false
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
130
src/views/sch/components/schoolForm.vue
Normal file
130
src/views/sch/components/schoolForm.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<el-dialog title="驾校信息" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog">
|
||||
<div>
|
||||
<el-form :model="dialogForm" :rules="dataRule" label-position="top" ref="dialogForm" @keyup.enter.native="dialogFormSubmit()">
|
||||
<el-form-item label="驾校名称" prop="schoolName">
|
||||
<el-input v-model="dialogForm.schoolName" maxlength="100" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="leader">
|
||||
<el-input v-model="dialogForm.leader" maxlength="100" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系方式" prop="phone">
|
||||
<el-input v-model="dialogForm.phone" maxlength="11" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="dialogForm.status">
|
||||
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="dialogForm.remark" maxlength="300" placeholder="请输入" clearable></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button plain @click="(visible=false)">取消</el-button>
|
||||
<el-button type="primary" v-jclick :disabled="!canSubmit" @click="dialogFormSubmit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/api/sch/school';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
dicts: ['sys_normal_disable'],
|
||||
props: {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['userInfo'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
canSubmit: true,
|
||||
dialogForm: {
|
||||
schoolId: undefined,
|
||||
schoolName: undefined,
|
||||
leader: undefined,
|
||||
phone: undefined,
|
||||
remark: undefined,
|
||||
status: '0'
|
||||
},
|
||||
dataRule: {
|
||||
schoolName: [{ required: true, message: '驾校名称不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||
}
|
||||
};
|
||||
},
|
||||
created() { },
|
||||
methods: {
|
||||
init(info = undefined) {
|
||||
// debugger
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.resetDialogForm();
|
||||
this.$refs['dialogForm'].resetFields();
|
||||
if (info) {
|
||||
this.dialogForm = this.deepClone(info);
|
||||
}
|
||||
});
|
||||
},
|
||||
resetDialogForm() {
|
||||
this.dialogForm = {
|
||||
schoolId: undefined,
|
||||
schoolName: undefined,
|
||||
leader: undefined,
|
||||
phone: undefined,
|
||||
remark: undefined
|
||||
}
|
||||
},
|
||||
closeDialog() {
|
||||
this.$emit('update:dialogVisible', false);
|
||||
},
|
||||
// 表单提交
|
||||
dialogFormSubmit() {
|
||||
this.$refs.dialogForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.canSubmit = false;
|
||||
|
||||
if (this.dialogForm.schoolId) {
|
||||
// 校验完成,调接口
|
||||
api
|
||||
.update(this.dialogForm)
|
||||
.then((resp) => {
|
||||
this.canSubmit = true;
|
||||
if (resp.code == 200) {
|
||||
this.$message.success('保存成功');
|
||||
this.$emit('refreshDataList');
|
||||
this.visible = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.canSubmit = true;
|
||||
});
|
||||
} else {
|
||||
api
|
||||
.add(this.dialogForm)
|
||||
.then((resp) => {
|
||||
this.canSubmit = true;
|
||||
if (resp.code == 200) {
|
||||
this.$message.success('保存成功');
|
||||
this.$emit('refreshDataList');
|
||||
this.visible = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.canSubmit = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
772
src/views/sch/place.vue
Normal file
772
src/views/sch/place.vue
Normal file
@@ -0,0 +1,772 @@
|
||||
<template>
|
||||
<div class="amap-page-container">
|
||||
<div id="map" class="amap-cavans" />
|
||||
<el-input id="search" v-model="searchBody" class="search-body" placeholder="请输入..." @keyup.enter.native="submitSearch">
|
||||
<el-button slot="append" icon="el-icon-search" @click="submitSearch" />
|
||||
</el-input>
|
||||
<div class="asider" :class="showSchool ? '':'hidden-school'">
|
||||
<el-card class="box-card" :body-style="{ flex: 1,'overflow-y': 'scroll', padding: 0 }">
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="map-card-title">驾校列表</div>
|
||||
</div>
|
||||
<div v-for="school in schoolList" :key="school.schoolId" style="margin:10px;" :class="currentdeptId == school.schoolId?'actived-school':''">
|
||||
<el-card :body-style="{ padding: '10px' }">
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="map-card-title">{{ school.schoolName }}</div>
|
||||
<el-switch v-model="school.showInMap" class="add-icon" active-text="展示" inactive-text="隐藏" @change="changeSchoolStatus(school)" v-hasPermi="['sch:place:edit']" />
|
||||
</div>
|
||||
<el-button @click="handleClickSchool(school)">{{ `数据管理(${getCount(school.schoolId)})` }}</el-button>
|
||||
<el-tooltip content="新增场地" placement="left" effect="dark" v-hasPermi="['sch:place:add']">
|
||||
<el-button icon="el-icon-plus" class="add-place-btn" @click="handleInsertPlace(school.schoolId)" />
|
||||
</el-tooltip>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-card>
|
||||
<div class="asider-sub">
|
||||
<el-tooltip content="放大" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-plus" class="is-circle" :disabled="zomm >= 18" @click="bigger" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="缩小" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-minus" class="is-circle" :disabled="zomm <= 8" @click="smaller" />
|
||||
</el-tooltip>
|
||||
<div class="mt10">
|
||||
<el-tooltip content="驾校" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-school" class="is-circle" @click="toggleSchool" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="定位" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-help" class="is-circle" @click="geolocation" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="测距" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-thumb" class="is-circle" @click="ranging" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="分享" placement="left" effect="dark">
|
||||
<el-button icon="el-icon-share" class="is-circle" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-card v-if="placeDialogShow" class="place-dialog" :body-style="{ padding: '10px' }">
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="map-card-title">场地设置</div>
|
||||
<el-tooltip content="取点" placement="right" effect="dark">
|
||||
<el-button icon="el-icon-location" class="add-icon" @click="getPoint" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-form ref="placeForm" :model="placeForm" label-width="70px">
|
||||
<el-form-item label="所属驾校" prop="schoolId">
|
||||
<el-select v-model="placeForm.schoolId" placeholder="请选择" clearable>
|
||||
<el-option v-for="dict in schoolList" :key="dict.schoolId" :label="dict.schoolName" :value="dict.schoolId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="placeForm.name" placeholder="输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="旗子颜色" prop="flagColor">
|
||||
<el-radio-group v-model="placeForm.flagColor">
|
||||
<el-radio v-for="(item, index) in colorOptions" :key="index" :label="item">
|
||||
<img :src="require(`@/assets/images/place/flag_${item}.png`)" width="20px" />
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input v-model="placeForm.address" placeholder="输入地址" />
|
||||
</el-form-item>
|
||||
<el-form-item label="经度" prop="lng">
|
||||
<el-input v-model="placeForm.lng" placeholder="输入经度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="lat">
|
||||
<el-input v-model="placeForm.lat" placeholder="输入纬度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属区域" prop="area">
|
||||
<el-select v-model="placeForm.area" placeholder="请选择" clearable size="small">
|
||||
<el-option v-for="dict in areaOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="placeForm.phone" placeholder="输入电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="contact">
|
||||
<el-input v-model="placeForm.contact" placeholder="输入负责人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否推荐" prop="contact">
|
||||
<el-radio v-model="placeForm.recommend" :label="true">是</el-radio>
|
||||
<el-radio v-model="placeForm.recommend" :label="false">否</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="placeForm.remark" placeholder="输入备注" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" />
|
||||
</el-form-item>
|
||||
<el-form-item style="text-align:right;">
|
||||
<el-button type="primary" @click="onSubmit" v-hasPermi="['sch:place:edit']">保存</el-button>
|
||||
<el-button @click="closePlaceDialog">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card :class="placeListDialogShow ? '':'hidden-place-list'" class="place-list-dialog" :style="{ right: showSchool ? '300px' : '0', top : fullScreenPlaceList?'0px':'420px' }" :body-style="{ padding: '10px', height: 'calc(100% - 52px)' }">
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="map-card-title">
|
||||
{{ placeListDialogTitle }}
|
||||
<el-input v-model="tableSearch" placeholder="请输入搜索的内容" clearable />
|
||||
</div>
|
||||
<el-tooltip content="全屏" placement="top" effect="dark">
|
||||
<el-button icon="el-icon-full-screen" class="add-icon" @click="fullScreenPlaceList = !fullScreenPlaceList" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="关闭" placement="top" effect="dark">
|
||||
<el-button icon="el-icon-close" class="add-icon" @click="() => { placeListDialogShow = false;fullScreenPlaceList = false }" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-table :data="placeTableData" border stripe class="place-table-list" height="100%">
|
||||
<el-table-column label="序号" type="index" fixed="left" width="50" />
|
||||
<el-table-column prop="name" label="名称" min-width="100" />
|
||||
<el-table-column prop="phone" label="电话" width="120" />
|
||||
<el-table-column prop="contact" label="负责人" width="120" />
|
||||
<el-table-column prop="address" label="地址" min-width="100" />
|
||||
<el-table-column prop="lng" label="经度" width="110" />
|
||||
<el-table-column prop="lat" label="纬度" width="110" />
|
||||
<el-table-column prop="area" label="所属区域" width="110" />
|
||||
<el-table-column label="展示" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="scope.row.showInMap" @change="changePlaceStatus(scope.row)" v-hasPermi="['sch:place:edit']" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip content="编辑" placement="top" effect="dark" v-hasPermi="['sch:place:edit']">
|
||||
<el-button icon="el-icon-edit" type="primary" style="padding: 4px 8px;" @click="handleEditPlace(scope.row)" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<div v-if="isPointing || isRanging" class="map-tip" :style="{ transform: 'translate3D(' + (tipPostion.x + 15) +'px,' + (tipPostion.y - 10) + 'px, 0)' }">{{ mapHelpText }}</div>
|
||||
<i v-if="isPointing" class="el-icon-s-flag circle" :style="{ transform: 'translate3D(' + tipPostion.x +'px,' + tipPostion.y + 'px, 0)' }" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMapData, savePlace, updateSchoolStatus } from '@/api/sch/place'
|
||||
export default {
|
||||
name: 'Place',
|
||||
data() {
|
||||
return {
|
||||
aMap: null,
|
||||
zomm: 12,
|
||||
showSchool: true,
|
||||
isRanging: false,
|
||||
aMapLocation: null,
|
||||
aMouseTool: null,
|
||||
searchBody: '',
|
||||
placeSearch: null,
|
||||
placeDialogShow: false,
|
||||
isPointing: false,
|
||||
placeForm: {
|
||||
lat: undefined,
|
||||
lng: undefined,
|
||||
name: undefined,
|
||||
address: undefined,
|
||||
remark: undefined,
|
||||
phone: undefined,
|
||||
flagColor: 'red',
|
||||
},
|
||||
colorOptions: ['red', 'yellow', 'blue', 'green', 'purple', 'black'],
|
||||
mapHelpText: '',
|
||||
tipPostion: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
geocoder: null,
|
||||
locationMarker: null,
|
||||
selectMarker: null,
|
||||
placeListDialogShow: false,
|
||||
placeListDialogTitle: '',
|
||||
fullScreenPlaceList: false,
|
||||
tableSearch: '',
|
||||
tableData: [],
|
||||
schoolList: [],
|
||||
currentdeptId: undefined,
|
||||
placeMarkerList: [],
|
||||
areaOptions: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeTableData: function () {
|
||||
if (this.tableSearch) {
|
||||
return this.tableData.filter((dataNews) => {
|
||||
return (
|
||||
dataNews.schoolId === this.currentdeptId &&
|
||||
Object.keys(dataNews).some((key) => {
|
||||
return (
|
||||
String(dataNews[key]).toLowerCase().indexOf(this.tableSearch) >
|
||||
-1
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
return this.tableData.filter(
|
||||
(dataNews) => dataNews.schoolId === this.currentdeptId
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initMap()
|
||||
this.getDicts('dm_area').then((response) => {
|
||||
this.areaOptions = response.data
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
initMap() {
|
||||
window.onLoad = () => {
|
||||
this.aMap = new AMap.Map('map', {
|
||||
zoom: this.zomm,
|
||||
zooms: [8, 18],
|
||||
})
|
||||
// 监听缩放
|
||||
this.aMap.on('zoomend', () => {
|
||||
this.zomm = this.aMap.getZoom()
|
||||
this.$message('当前缩放等级:' + this.zomm)
|
||||
})
|
||||
// 监听点击
|
||||
this.aMap.on('click', (ev) => {
|
||||
if (this.isPointing) {
|
||||
this.placeForm.lat = ev.lnglat.lat
|
||||
this.placeForm.lng = ev.lnglat.lng
|
||||
this.regeoCode()
|
||||
if (this.selectMarker) {
|
||||
this.selectMarker.setPosition([
|
||||
this.placeForm.lng,
|
||||
this.placeForm.lat,
|
||||
])
|
||||
} else {
|
||||
this.locationMarker.setPosition([
|
||||
this.placeForm.lng,
|
||||
this.placeForm.lat,
|
||||
])
|
||||
this.aMap.add(this.locationMarker)
|
||||
}
|
||||
this.isPointing = false
|
||||
}
|
||||
})
|
||||
// 监听移动
|
||||
this.aMap.on('mousemove', (ev) => {
|
||||
if (this.isRanging) {
|
||||
this.mapHelpText =
|
||||
'左键单击选点,双击/右键单击完成选点,再次点击测距按钮可退出测距模式,并清除测距结果'
|
||||
this.tipPostion = {
|
||||
x: ev.pixel.x,
|
||||
y: ev.pixel.y,
|
||||
}
|
||||
} else if (this.isPointing) {
|
||||
this.mapHelpText = '点击地图添加标注'
|
||||
this.tipPostion = {
|
||||
x: ev.pixel.x,
|
||||
y: ev.pixel.y,
|
||||
}
|
||||
}
|
||||
})
|
||||
// 添加地图插件
|
||||
AMap.plugin(
|
||||
[
|
||||
'AMap.Scale',
|
||||
'AMap.Geolocation',
|
||||
'AMap.MouseTool',
|
||||
'AMap.PlaceSearch',
|
||||
'AMap.Autocomplete',
|
||||
'AMap.Geocoder',
|
||||
],
|
||||
() => {
|
||||
this.aMap.addControl(new AMap.Scale())
|
||||
const geoLoca = new AMap.Geolocation({
|
||||
showButton: false,
|
||||
})
|
||||
this.aMapLocation = geoLoca
|
||||
this.aMap.addControl(geoLoca)
|
||||
this.aMouseTool = new AMap.MouseTool(this.aMap)
|
||||
const auto = new AMap.Autocomplete({
|
||||
input: 'search', // 前端搜索框
|
||||
})
|
||||
this.placeSearch = new AMap.PlaceSearch({
|
||||
map: this.aMap,
|
||||
})
|
||||
AMap.event.addListener(auto, 'select', this.select)
|
||||
this.geocoder = new AMap.Geocoder()
|
||||
this.locationMarker = new AMap.Marker({
|
||||
icon: require(`@/assets/images/place/flag_red.png`),
|
||||
})
|
||||
}
|
||||
)
|
||||
this.getPageData()
|
||||
}
|
||||
this.importMap()
|
||||
},
|
||||
// 导入地图
|
||||
importMap() {
|
||||
const url =
|
||||
'https://webapi.amap.com/maps?v=1.4.15&key=124646b0e6076de9d801400f833ac986&callback=onLoad'
|
||||
var jsapi = document.createElement('script')
|
||||
jsapi.charset = 'utf-8'
|
||||
jsapi.src = url
|
||||
document.head.appendChild(jsapi)
|
||||
},
|
||||
toggleSchool() {
|
||||
this.showSchool = !this.showSchool
|
||||
},
|
||||
// 经纬度 -> 地址
|
||||
regeoCode() {
|
||||
this.geocoder.getAddress(
|
||||
[this.placeForm.lng, this.placeForm.lat],
|
||||
(status, result) => {
|
||||
if (status === 'complete' && result.regeocode) {
|
||||
this.placeForm.address = result.regeocode.formattedAddress
|
||||
} else {
|
||||
console.log('根据经纬度查询地址失败')
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
// 定位
|
||||
geolocation() {
|
||||
this.aMapLocation.getCurrentPosition()
|
||||
},
|
||||
// 测距
|
||||
ranging() {
|
||||
this.isPointing = false
|
||||
this.isRanging = !this.isRanging
|
||||
if (this.isRanging) {
|
||||
this.aMap.setDefaultCursor('crosshair')
|
||||
this.drawLine()
|
||||
} else {
|
||||
this.aMap.setDefaultCursor('default')
|
||||
this.aMouseTool.close(true)
|
||||
}
|
||||
},
|
||||
// 画线
|
||||
drawLine() {
|
||||
this.aMouseTool.rule({
|
||||
startMarkerOptions: {
|
||||
// 可缺省
|
||||
icon: new AMap.Icon({
|
||||
size: new AMap.Size(19, 31), // 图标大小
|
||||
imageSize: new AMap.Size(19, 31),
|
||||
image: 'https://webapi.amap.com/theme/v1.3/markers/b/start.png',
|
||||
}),
|
||||
},
|
||||
endMarkerOptions: {
|
||||
// 可缺省
|
||||
icon: new AMap.Icon({
|
||||
size: new AMap.Size(19, 31), // 图标大小
|
||||
imageSize: new AMap.Size(19, 31),
|
||||
image: 'https://webapi.amap.com/theme/v1.3/markers/b/end.png',
|
||||
}),
|
||||
offset: new AMap.Pixel(-9, -31),
|
||||
},
|
||||
midMarkerOptions: {
|
||||
// 可缺省
|
||||
icon: new AMap.Icon({
|
||||
size: new AMap.Size(19, 31), // 图标大小
|
||||
imageSize: new AMap.Size(19, 31),
|
||||
image: 'https://webapi.amap.com/theme/v1.3/markers/b/mid.png',
|
||||
}),
|
||||
offset: new AMap.Pixel(-9, -31),
|
||||
},
|
||||
lineOptions: {
|
||||
// 可缺省
|
||||
strokeStyle: 'solid',
|
||||
strokeColor: '#FF33FF',
|
||||
strokeOpacity: 1,
|
||||
strokeWeight: 2,
|
||||
},
|
||||
tmpLineOptions: {
|
||||
strokeStyle: 'dashed',
|
||||
strokeColor: '#FF33FF',
|
||||
strokeOpacity: 1,
|
||||
strokeWeight: 2,
|
||||
},
|
||||
})
|
||||
},
|
||||
// 选择查询结果
|
||||
select(e) {
|
||||
this.placeSearch.setCity(e.poi.adcode)
|
||||
this.placeSearch.search(e.poi.name) // 关键字查询查询
|
||||
},
|
||||
// 查询按钮/回车事件
|
||||
submitSearch() {
|
||||
this.placeSearch.search(this.searchBody)
|
||||
},
|
||||
// 缩放
|
||||
bigger() {
|
||||
this.zomm++
|
||||
this.aMap.setZoom(this.zomm)
|
||||
},
|
||||
smaller() {
|
||||
this.zomm--
|
||||
this.aMap.setZoom(this.zomm)
|
||||
},
|
||||
|
||||
// 点击数据管理
|
||||
handleClickSchool(item) {
|
||||
this.placeListDialogShow = true
|
||||
this.placeListDialogTitle = `数据管理 [${item.schoolName}]`
|
||||
this.currentdeptId = item.schoolId
|
||||
},
|
||||
// 新增场地
|
||||
handleInsertPlace(schoolId) {
|
||||
if (this.selectMarker) {
|
||||
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
|
||||
this.selectMarker = null
|
||||
}
|
||||
this.placeDialogShow = true
|
||||
this.aMap.setDefaultCursor('default')
|
||||
this.isRanging = false
|
||||
this.placeForm = {
|
||||
lat: undefined,
|
||||
lng: undefined,
|
||||
name: undefined,
|
||||
address: undefined,
|
||||
remark: undefined,
|
||||
phone: undefined,
|
||||
schoolId: schoolId,
|
||||
showInMap: true,
|
||||
flagColor: 'red',
|
||||
}
|
||||
},
|
||||
// 编辑场地
|
||||
handleEditPlace(item) {
|
||||
this.placeDialogShow = true
|
||||
this.aMap.setDefaultCursor('default')
|
||||
if (this.selectMarker) {
|
||||
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
|
||||
}
|
||||
this.isRanging = false
|
||||
this.placeForm = Object.assign({}, item)
|
||||
this.selectMarker = this.placeMarkerList.filter(
|
||||
(marker) => marker.getExtData().placeId === item.placeId
|
||||
)[0]
|
||||
this.selectMarker &&
|
||||
this.selectMarker.setAnimation('AMAP_ANIMATION_BOUNCE')
|
||||
this.aMap.setCenter([item.lng, item.lat])
|
||||
},
|
||||
getPoint() {
|
||||
this.isPointing = !this.isPointing
|
||||
},
|
||||
// 保存
|
||||
async onSubmit() {
|
||||
// 保存接口
|
||||
if (this.checkPlaceFormValidate()) {
|
||||
// 先访问接口,返回id插入placeForm
|
||||
const resp = await savePlace(this.placeForm)
|
||||
if (resp.code != 200) {
|
||||
return
|
||||
} else {
|
||||
this.$message.success('操作成功');
|
||||
}
|
||||
if (!this.placeForm.placeId && resp.data) {
|
||||
this.$set(this.placeForm, 'placeId', resp.data)
|
||||
}
|
||||
// 移除选点用 的标记
|
||||
this.aMap.remove(this.locationMarker)
|
||||
// 根据form创建新marker 并添加到地图上
|
||||
const tmpMarker = new AMap.Marker({
|
||||
map: this.aMap,
|
||||
position: [this.placeForm.lng, this.placeForm.lat],
|
||||
icon: require(`@/assets/images/place/flag_${this.placeForm.flagColor}.png`),
|
||||
label: {
|
||||
content: this.placeForm.name,
|
||||
direction: 'right',
|
||||
},
|
||||
extData: this.placeForm,
|
||||
})
|
||||
// 新marker事件
|
||||
tmpMarker.on('click', this.handleClickMarker)
|
||||
// 如果当前选择的marker点存在(编辑)
|
||||
if (this.selectMarker) {
|
||||
// 地图上 移除选择的点
|
||||
this.aMap.remove(this.selectMarker)
|
||||
this.selectMarker = null
|
||||
}
|
||||
// 关闭场地弹窗
|
||||
this.placeDialogShow = false
|
||||
this.isPointing = false
|
||||
|
||||
// 场地列表 移除原列表中操作的场地数据
|
||||
const tmpArr = this.tableData.filter(
|
||||
(item) => item.placeId !== this.placeForm.placeId
|
||||
)
|
||||
// 新增新的场地
|
||||
tmpArr.push(this.placeForm)
|
||||
// 重置场地数组
|
||||
this.tableData = tmpArr
|
||||
// 地图marker列表 移除操作的原marker 添加新marker进数组
|
||||
const tmpArr1 = this.placeMarkerList.filter(
|
||||
(item) => item.getExtData().placeId !== this.placeForm.placeId
|
||||
)
|
||||
tmpArr1.push(tmpMarker)
|
||||
this.placeMarkerList = tmpArr1
|
||||
}
|
||||
},
|
||||
checkPlaceFormValidate() {
|
||||
const valid = []
|
||||
if (!this.placeForm.name) {
|
||||
valid.push('名称')
|
||||
}
|
||||
if (!this.placeForm.address) {
|
||||
valid.push('地址')
|
||||
}
|
||||
if (!this.placeForm.lng) {
|
||||
valid.push('经度')
|
||||
}
|
||||
if (!this.placeForm.lat) {
|
||||
valid.push('纬度')
|
||||
}
|
||||
if (!this.placeForm.phone) {
|
||||
valid.push('电话')
|
||||
}
|
||||
if (valid.length == 0) {
|
||||
return true
|
||||
} else {
|
||||
this.$message.error(`请将以下填写完整: ${valid.join(',')}`)
|
||||
return false
|
||||
}
|
||||
},
|
||||
// 关闭场地弹窗
|
||||
closePlaceDialog() {
|
||||
this.placeDialogShow = false
|
||||
this.isPointing = false
|
||||
this.aMap.remove(this.locationMarker)
|
||||
if (this.selectMarker) {
|
||||
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
|
||||
this.selectMarker = null
|
||||
}
|
||||
},
|
||||
handleClickMarker(ev) {
|
||||
if (this.selectMarker) {
|
||||
this.selectMarker.setAnimation('AMAP_ANIMATION_NONE')
|
||||
}
|
||||
this.placeForm = ev.target.getExtData()
|
||||
this.placeDialogShow = true
|
||||
ev.target.setAnimation('AMAP_ANIMATION_BOUNCE')
|
||||
this.selectMarker = ev.target
|
||||
},
|
||||
getPageData() {
|
||||
getMapData().then((resp) => {
|
||||
if (resp.code == 200) {
|
||||
this.schoolList = resp.data.schoolList
|
||||
this.tableData = resp.data.placeList
|
||||
this.currentdeptId = this.schoolList[0].schoolId
|
||||
this.createMarkersInMap()
|
||||
}
|
||||
})
|
||||
},
|
||||
getCount(schoolId) {
|
||||
return this.tableData.filter((item) => item.schoolId === schoolId).length
|
||||
},
|
||||
// 重置markers
|
||||
resetMarkers() {
|
||||
this.aMap.clearMap()
|
||||
this.createMarkersInMap()
|
||||
},
|
||||
// 生成markers
|
||||
createMarkersInMap() {
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
const element = this.tableData[i]
|
||||
const tempSchool = this.schoolList.filter(
|
||||
(item) => item.schoolId === element.schoolId
|
||||
)[0]
|
||||
if (!tempSchool.showInMap || !element.showInMap) {
|
||||
continue
|
||||
}
|
||||
const tmpMarker = new AMap.Marker({
|
||||
map: this.aMap,
|
||||
position: [element.lng, element.lat],
|
||||
icon: require(`@/assets/images/place/flag_${element.flagColor}.png`),
|
||||
label: {
|
||||
content: element.name,
|
||||
direction: 'right',
|
||||
},
|
||||
extData: element,
|
||||
})
|
||||
tmpMarker.on('click', this.handleClickMarker)
|
||||
this.placeMarkerList.push(tmpMarker)
|
||||
}
|
||||
},
|
||||
// 修改驾校状态
|
||||
changeSchoolStatus(item) {
|
||||
// 访问接口,成功后重置markers
|
||||
updateSchoolStatus(item).then((resp) => {
|
||||
if (resp.code == 200) {
|
||||
this.$message.success('操作成功');
|
||||
// this.aMap.clearMap()
|
||||
// this.getPageData()
|
||||
this.resetMarkers()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 修改场地状态
|
||||
async changePlaceStatus(item) {
|
||||
const resp = await savePlace(item)
|
||||
if (resp.code == 200) {
|
||||
this.resetMarkers()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.amap-page-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.amap-cavans {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.asider {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
transition: 0.3s;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/deep/ .el-card__header {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.clearfix .map-card-title {
|
||||
flex: 1;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.clearfix .add-icon {
|
||||
width: auto;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.asider-sub {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: -45px;
|
||||
padding: 10px 10px 0 0;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
.asider-sub .is-circle {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
color: #464646;
|
||||
border-radius: 0;
|
||||
font-size: 16px;
|
||||
box-shadow: 2px 2px 2px rgba(80, 80, 80, 0.67);
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.hidden-school {
|
||||
transform: translateX(300px);
|
||||
}
|
||||
|
||||
.search-body {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.add-place-btn {
|
||||
float: right;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
/deep/.place-dialog {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 60px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.map-tip {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 150px;
|
||||
padding: 5px;
|
||||
border-radius: 2px;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
opacity: 0.7;
|
||||
font-size: 12px;
|
||||
transition-duration: 1ms;
|
||||
}
|
||||
|
||||
.circle {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -25px;
|
||||
font-size: 24px;
|
||||
color: red;
|
||||
transition-duration: 1ms;
|
||||
}
|
||||
|
||||
.place-dialog .el-form .el-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.place-list-dialog {
|
||||
position: absolute;
|
||||
top: 420px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transition: 0.3s;
|
||||
z-index: 151;
|
||||
background: #e2e5ea;
|
||||
}
|
||||
|
||||
.place-list-dialog .add-icon {
|
||||
font-size: 18px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.hidden-place-list {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.place-list-dialog .clearfix .map-card-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.place-list-dialog .clearfix .map-card-title .el-input {
|
||||
margin-left: 20px;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.actived-school {
|
||||
border: 2px solid #409eff !important;
|
||||
}
|
||||
|
||||
/deep/ .el-radio__label {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
121
src/views/sch/school.vue
Normal file
121
src/views/sch/school.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
|
||||
<el-form ref="queryForm" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-input v-model="queryParams.schoolName" placeholder="请输入驾校名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle(undefined)" v-hasPermi="['sch:school:add']">新增</el-button>
|
||||
<!-- <el-button type="danger" icon="el-icon-delete" @click="handleDelete" :disabled="multiple" v-hasPermi="['sch:school:remove']">删除</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading.tableLoading" :data="tableDataList" stripe>
|
||||
<!-- <el-table-column type="selection" width="50" align="center" /> -->
|
||||
<el-table-column label="序号" type="index" width="50" />
|
||||
<el-table-column label="驾校名称" prop="schoolName" />
|
||||
<el-table-column label="负责人" prop="leader" />
|
||||
<el-table-column label="联系方式" prop="phone" />
|
||||
<el-table-column label="备注" prop="remark" />
|
||||
<el-table-column label="创建时间" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="130">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-hasPermi="['sch:school:edit']" type="text" icon="el-icon-edit" @click="addOrUpdateHandle(scope.row)">修改</el-button>
|
||||
<el-button v-hasPermi="['sch:school:remove']" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getPageList" />
|
||||
|
||||
<!-- 驾校弹框 -->
|
||||
<school-form v-if="dialogVisible" :dialogVisible="dialogVisible" ref="dialogForm" @refreshDataList="getPageList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import schoolForm from './components/schoolForm.vue'
|
||||
import schoolApi from '@/api/sch/school'
|
||||
import { appendFile } from 'fs'
|
||||
|
||||
export default {
|
||||
name: 'School',
|
||||
components: {
|
||||
schoolForm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
total: 0,
|
||||
queryParams: {
|
||||
schoolName: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
tableDataList: [],
|
||||
loading: {
|
||||
tableLoading: false
|
||||
},
|
||||
dialogVisible: false,
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
//页面初始化加载
|
||||
this.getPageList()
|
||||
},
|
||||
methods: {
|
||||
//查询列表数据
|
||||
getPageList() {
|
||||
schoolApi.pageList(this.queryParams).then(resp => {
|
||||
if (resp.code == 200) {
|
||||
this.tableDataList = resp.rows
|
||||
this.total = resp.total
|
||||
}
|
||||
})
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getPageList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.queryParams = {
|
||||
schoolName: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
this.handleQuery();
|
||||
},
|
||||
//新增和修改操作
|
||||
addOrUpdateHandle(item) {
|
||||
this.dialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dialogForm.init(item);
|
||||
});
|
||||
},
|
||||
//删除操作
|
||||
handleDelete(item) {
|
||||
this.$modal.confirm('删除驾校信息,同时会删除该驾校下的场地信息和班型信息,是否确认名称为"' + item.schoolName + '"的数据项?').then(function () {
|
||||
return schoolApi.delete(item.schoolId);
|
||||
}).then((resp) => {
|
||||
if (resp.code == 200) {
|
||||
this.getPageList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
}).catch(() => { });
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
491
src/views/system/employee/index.vue
Normal file
491
src/views/system/employee/index.vue
Normal file
@@ -0,0 +1,491 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<!--部门数据-->
|
||||
<el-col :span="4" :xs="24">
|
||||
<div class="head-container">
|
||||
<el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" default-expand-all highlight-current @node-click="handleNodeClick" />
|
||||
</div>
|
||||
</el-col>
|
||||
<!--用户数据-->
|
||||
<el-col :span="20" :xs="24">
|
||||
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
|
||||
<el-form-item prop="userOrPhone">
|
||||
<el-input v-model="queryParams.employeeName" placeholder="请输入姓名/手机号" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable>
|
||||
<el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="入职时间">
|
||||
<el-date-picker v-model="queryParams.hiredate" style="width: 240px" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button v-hasPermi="['system:employee:add']" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="userList">
|
||||
<el-table-column label="姓名" prop="employeeName" />
|
||||
<el-table-column label="手机号" prop="phone" />
|
||||
<el-table-column label="部门" prop="orgName" />
|
||||
<el-table-column label="上级领导" prop="leaderName" />
|
||||
<el-table-column label="入职时间" prop="hiredate" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.hiredate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="260">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-hasPermi="['system:employee:edit']" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||
<!-- <el-button
|
||||
v-hasPermi="['system:employee:resetPwd']"
|
||||
type="text"
|
||||
icon="el-icon-key"
|
||||
@click="handleReset(scope.row)"
|
||||
>重置密码</el-button>-->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="700px" custom-class="dialog500" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="employeeName">
|
||||
<el-input v-model="form.employeeName" placeholder="请输入员工姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="请输入手机号码" maxlength="11" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色" prop="roleIdList">
|
||||
<el-select v-model="form.roleIdList" multiple placeholder="请选择">
|
||||
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" :disabled="item.status == 1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="归属部门" prop="orgId">
|
||||
<treeselect v-model="form.orgId" :options="deptOptions" :disable-branch-nodes="true" :show-count="true" placeholder="请选择归属部门" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属区域" prop="areaList">
|
||||
<el-select v-model="form.areaList" multiple placeholder="请选择">
|
||||
<el-option v-for="dict in areaOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="权重" prop="weight">
|
||||
<el-input v-model="form.weight" placeholder="权重,1-100" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户性别">
|
||||
<el-select v-model="form.sex" placeholder="请选择">
|
||||
<el-option v-for="dict in sexOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="入职日期">
|
||||
<el-date-picker v-model="form.hiredate" :editable="false" type="date" value-format="yyyy-MM-dd" placeholder="请选择入职时间" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上级领导">
|
||||
<el-select v-model="form.leader" placeholder="请选择">
|
||||
<el-option v-for="dict in userOptions" :key="dict.id" :label="dict.name" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否释放线索">
|
||||
<el-radio-group v-model="form.discardClue">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="最大线索数">
|
||||
<el-input v-model="form.maxClueNum"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否考勤">
|
||||
<el-radio-group v-model="form.checkin">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否参与统计">
|
||||
<el-radio-group v-model="form.count">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="小程序权限">
|
||||
<el-radio-group v-model="form.hasStudent">
|
||||
<el-radio :label="true">开通</el-radio>
|
||||
<el-radio :label="false">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理系统权限">
|
||||
<el-radio-group v-model="form.hasSys">
|
||||
<el-radio :label="true">开通</el-radio>
|
||||
<el-radio :label="false">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<!-- <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> -->
|
||||
<editor v-model="form.remark" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import empAPi from '@/api/system/employee'
|
||||
import { deptTreeSelect } from "@/api/system/dept";
|
||||
import { getRoleOptions } from '@/api/system/role'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import editor from '@/components/Editor'
|
||||
|
||||
export default {
|
||||
name: 'Employee',
|
||||
components: { Treeselect, editor },
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
userId: localStorage.getItem('userId'),
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 用户表格数据
|
||||
userList: null,
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 部门树选项
|
||||
deptOptions: undefined,
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 部门名称
|
||||
deptName: undefined,
|
||||
// 默认密码
|
||||
initPassword: undefined,
|
||||
// 状态数据字典
|
||||
statusOptions: [],
|
||||
// 性别状态字典
|
||||
sexOptions: [],
|
||||
// 角色选项
|
||||
roleOptions: [],
|
||||
// 表单参数
|
||||
form: {},
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nameOrPhone: undefined,
|
||||
status: '0',
|
||||
orgId: undefined,
|
||||
roleId: undefined,
|
||||
hiredate: [],
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
employeeName: [
|
||||
{ required: true, message: '姓名不能为空', trigger: 'blur' },
|
||||
],
|
||||
roleIdList: [
|
||||
{
|
||||
required: true,
|
||||
type: 'array',
|
||||
message: '角色不能为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
],
|
||||
orgId: [
|
||||
{
|
||||
required: true,
|
||||
message: '归属部门不能为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
],
|
||||
areaList: [
|
||||
{
|
||||
required: true,
|
||||
message: '所属区域不能为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
],
|
||||
weight: [
|
||||
{
|
||||
required: true,
|
||||
message: '权重不能为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
],
|
||||
phone: [
|
||||
{ required: true, message: '手机号码不能为空', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||
message: '请输入正确的手机号码',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
userOptions: [],
|
||||
areaOptions: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 根据名称筛选部门树
|
||||
deptName(val) {
|
||||
this.$refs.tree.filter(val)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.getDeptTree();
|
||||
this._getRoleOptions()
|
||||
this.getDicts('sys_normal_disable').then((response) => {
|
||||
this.statusOptions = response.data
|
||||
})
|
||||
this.getDicts('sys_user_sex').then((response) => {
|
||||
this.sexOptions = response.data
|
||||
})
|
||||
|
||||
this.getDicts('dm_area').then((response) => {
|
||||
this.areaOptions = response.data
|
||||
})
|
||||
this.getConfigKey('sys.user.initPassword').then((response) => {
|
||||
this.initPassword = response.msg
|
||||
})
|
||||
empAPi.getEmployee().then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.userOptions = resp.data
|
||||
// this.userOptions.push({
|
||||
// id: '6ce3239c8c154f83befb9eb7441a01c7',
|
||||
// name: 'DM',
|
||||
// })
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/** 查询用户列表 */
|
||||
getList() {
|
||||
this.loading = true
|
||||
empAPi.pageList(this.queryParams).then(
|
||||
(response) => {
|
||||
this.userList = response.rows
|
||||
this.total = response.total
|
||||
this.loading = false
|
||||
}
|
||||
)
|
||||
},
|
||||
_getRoleOptions() {
|
||||
getRoleOptions().then((resp) => {
|
||||
this.roleOptions = resp.data
|
||||
})
|
||||
},
|
||||
/** 查询部门下拉树结构 */
|
||||
getDeptTree() {
|
||||
deptTreeSelect().then(response => {
|
||||
this.deptOptions = response.data;
|
||||
});
|
||||
},
|
||||
// 筛选节点
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
},
|
||||
// 节点单击事件
|
||||
handleNodeClick(data) {
|
||||
this.queryParams.orgId = data.id
|
||||
this.getList()
|
||||
},
|
||||
// 用户状态修改
|
||||
handleStatusChange(row) {
|
||||
const text = row.status === '0' ? '启用' : '停用'
|
||||
this.$confirm(
|
||||
'确认要"' + text + '""' + row.userName + '"用户吗?',
|
||||
'警告',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(function () {
|
||||
let model = {
|
||||
employeeId: row.employeeId,
|
||||
status: row.status
|
||||
}
|
||||
return empAPi.update(model)
|
||||
})
|
||||
.then(() => {
|
||||
this.msgSuccess(text + '成功')
|
||||
})
|
||||
.catch(function () {
|
||||
row.status = row.status === '0' ? '1' : '0'
|
||||
})
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false
|
||||
this.reset()
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
orgId: undefined,
|
||||
employeeName: undefined,
|
||||
phone: undefined,
|
||||
sex: '0',
|
||||
status: '0',
|
||||
remark: undefined,
|
||||
roleIdList: [],
|
||||
hiredate: undefined,
|
||||
leader: this.userId,
|
||||
discardClue: false,
|
||||
maxPublicClue: undefined,
|
||||
checkin: true,
|
||||
areaList: [],
|
||||
weight: undefined,
|
||||
count: true
|
||||
}
|
||||
this.resetForm('form')
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.page = 1
|
||||
this.getList()
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm')
|
||||
this.handleQuery()
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset()
|
||||
this.getDeptTree();
|
||||
this.open = true
|
||||
this.title = '添加员工'
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset()
|
||||
this.getDeptTree();
|
||||
this.form = Object.assign({}, row)
|
||||
this.open = true
|
||||
this.title = '修改员工'
|
||||
},
|
||||
/** 重置密码按钮操作 */
|
||||
handleReset(row) {
|
||||
resetUserPwd({ employeeId: row.employeeId }).then((response) => {
|
||||
if (response.code === 200) {
|
||||
this.msgSuccess('重置密码成功!')
|
||||
}
|
||||
})
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm: function () {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$set(this.form, 'deptId', this.$store.getters.schoolId)
|
||||
if (this.form.employeeId) {
|
||||
empAPi.update(this.form).then((response) => {
|
||||
if (response.code === 200) {
|
||||
this.$message.success('修改成功');
|
||||
this.open = false
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
empAPi.add(this.form).then((response) => {
|
||||
if (response.code === 200) {
|
||||
this.$message.success('新增成功');
|
||||
this.open = false
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
}
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -2,48 +2,18 @@
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input
|
||||
v-model="queryParams.roleName"
|
||||
placeholder="请输入角色名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.roleName" placeholder="请输入角色名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限字符" prop="roleKey">
|
||||
<el-input
|
||||
v-model="queryParams.roleKey"
|
||||
placeholder="请输入权限字符"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.roleKey" placeholder="请输入权限字符" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="角色状态"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in dict.type.sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-select v-model="queryParams.status" placeholder="角色状态" clearable style="width: 240px">
|
||||
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
@@ -53,46 +23,16 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['system:role:add']"
|
||||
>新增</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
>修改</el-button>
|
||||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:role:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
>删除</el-button>
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:role:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['system:role:export']"
|
||||
>导出</el-button>
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:role:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -105,12 +45,7 @@
|
||||
<el-table-column label="显示顺序" prop="roleSort" width="100" />
|
||||
<el-table-column label="状态" align="center" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
></el-switch>
|
||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
@@ -119,43 +54,23 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope" v-if="scope.row.roleId !== 1">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
>删除</el-button>
|
||||
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']">删除</el-button>
|
||||
<!-- <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-d-arrow-right el-icon--right"></i>更多
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="handleDataScope" icon="el-icon-circle-check"
|
||||
v-hasPermi="['system:role:edit']">数据权限</el-dropdown-item>
|
||||
<el-dropdown-item command="handleAuthUser" icon="el-icon-user"
|
||||
v-hasPermi="['system:role:edit']">分配用户</el-dropdown-item>
|
||||
<el-dropdown-item command="handleDataScope" icon="el-icon-circle-check" v-hasPermi="['system:role:edit']">数据权限</el-dropdown-item>
|
||||
<el-dropdown-item command="handleAuthUser" icon="el-icon-user" v-hasPermi="['system:role:edit']">分配用户</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-dropdown> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改角色配置对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
@@ -177,27 +92,14 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{dict.label}}</el-radio>
|
||||
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单权限">
|
||||
<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
|
||||
<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
|
||||
<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
|
||||
<el-tree
|
||||
class="tree-border"
|
||||
:data="menuOptions"
|
||||
show-checkbox
|
||||
ref="menu"
|
||||
node-key="id"
|
||||
:check-strictly="!form.menuCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="defaultProps"
|
||||
></el-tree>
|
||||
<el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menu" node-key="id" :check-strictly="!form.menuCheckStrictly" empty-text="加载中,请稍候" :props="defaultProps"></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||
@@ -220,29 +122,14 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="权限范围">
|
||||
<el-select v-model="form.dataScope" @change="dataScopeSelectChange">
|
||||
<el-option
|
||||
v-for="item in dataScopeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据权限" v-show="form.dataScope == 2">
|
||||
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
|
||||
<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
|
||||
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
|
||||
<el-tree
|
||||
class="tree-border"
|
||||
:data="deptOptions"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
ref="dept"
|
||||
node-key="id"
|
||||
:check-strictly="!form.deptCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="defaultProps"
|
||||
></el-tree>
|
||||
<el-tree class="tree-border" :data="deptOptions" show-checkbox default-expand-all ref="dept" node-key="id" :check-strictly="!form.deptCheckStrictly" empty-text="加载中,请稍候" :props="defaultProps"></el-tree>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -351,10 +238,10 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
|
||||
this.roleList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
}
|
||||
this.roleList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
/** 查询菜单树结构 */
|
||||
@@ -398,11 +285,11 @@ export default {
|
||||
// 角色状态修改
|
||||
handleStatusChange(row) {
|
||||
let text = row.status === "0" ? "启用" : "停用";
|
||||
this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function() {
|
||||
this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function () {
|
||||
return changeRoleStatus(row.roleId, row.status);
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess(text + "成功");
|
||||
}).catch(function() {
|
||||
}).catch(function () {
|
||||
row.status = row.status === "0" ? "1" : "0";
|
||||
});
|
||||
},
|
||||
@@ -422,21 +309,21 @@ export default {
|
||||
this.$refs.menu.setCheckedKeys([]);
|
||||
}
|
||||
this.menuExpand = false,
|
||||
this.menuNodeAll = false,
|
||||
this.deptExpand = true,
|
||||
this.deptNodeAll = false,
|
||||
this.form = {
|
||||
roleId: undefined,
|
||||
roleName: undefined,
|
||||
roleKey: undefined,
|
||||
roleSort: 0,
|
||||
status: "0",
|
||||
menuIds: [],
|
||||
deptIds: [],
|
||||
menuCheckStrictly: true,
|
||||
deptCheckStrictly: true,
|
||||
remark: undefined
|
||||
};
|
||||
this.menuNodeAll = false,
|
||||
this.deptExpand = true,
|
||||
this.deptNodeAll = false,
|
||||
this.form = {
|
||||
roleId: undefined,
|
||||
roleName: undefined,
|
||||
roleKey: undefined,
|
||||
roleSort: 0,
|
||||
status: "0",
|
||||
menuIds: [],
|
||||
deptIds: [],
|
||||
menuCheckStrictly: true,
|
||||
deptCheckStrictly: true,
|
||||
remark: undefined
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
@@ -453,7 +340,7 @@ export default {
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.roleId)
|
||||
this.single = selection.length!=1
|
||||
this.single = selection.length != 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
// 更多操作触发
|
||||
@@ -486,17 +373,17 @@ export default {
|
||||
// 树权限(全选/全不选)
|
||||
handleCheckedTreeNodeAll(value, type) {
|
||||
if (type == 'menu') {
|
||||
this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
|
||||
this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
|
||||
} else if (type == 'dept') {
|
||||
this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
|
||||
this.$refs.dept.setCheckedNodes(value ? this.deptOptions : []);
|
||||
}
|
||||
},
|
||||
// 树权限(父子联动)
|
||||
handleCheckedTreeConnect(value, type) {
|
||||
if (type == 'menu') {
|
||||
this.form.menuCheckStrictly = value ? true: false;
|
||||
this.form.menuCheckStrictly = value ? true : false;
|
||||
} else if (type == 'dept') {
|
||||
this.form.deptCheckStrictly = value ? true: false;
|
||||
this.form.deptCheckStrictly = value ? true : false;
|
||||
}
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
@@ -518,9 +405,9 @@ export default {
|
||||
roleMenu.then(res => {
|
||||
let checkedKeys = res.checkedKeys
|
||||
checkedKeys.forEach((v) => {
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.menu.setChecked(v, true ,false);
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.$refs.menu.setChecked(v, true, false);
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -529,7 +416,7 @@ export default {
|
||||
},
|
||||
/** 选择角色权限范围触发 */
|
||||
dataScopeSelectChange(value) {
|
||||
if(value !== '2') {
|
||||
if (value !== '2') {
|
||||
this.$refs.dept.setCheckedKeys([]);
|
||||
}
|
||||
},
|
||||
@@ -549,12 +436,12 @@ export default {
|
||||
});
|
||||
},
|
||||
/** 分配用户操作 */
|
||||
handleAuthUser: function(row) {
|
||||
handleAuthUser: function (row) {
|
||||
const roleId = row.roleId;
|
||||
this.$router.push("/system/role-auth/user/" + roleId);
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm: function() {
|
||||
submitForm: function () {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.roleId != undefined) {
|
||||
@@ -576,7 +463,7 @@ export default {
|
||||
});
|
||||
},
|
||||
/** 提交按钮(数据权限) */
|
||||
submitDataScope: function() {
|
||||
submitDataScope: function () {
|
||||
if (this.form.roleId != undefined) {
|
||||
this.form.deptIds = this.getDeptAllCheckedKeys();
|
||||
dataScope(this.form).then(response => {
|
||||
@@ -589,12 +476,12 @@ export default {
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const roleIds = row.roleId || this.ids;
|
||||
this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function() {
|
||||
this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function () {
|
||||
return delRole(roleIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
|
||||
@@ -4,74 +4,28 @@
|
||||
<!--部门数据-->
|
||||
<el-col :span="4" :xs="24">
|
||||
<div class="head-container">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
placeholder="请输入部门名称"
|
||||
clearable
|
||||
size="small"
|
||||
prefix-icon="el-icon-search"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="defaultProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="tree"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
<el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" default-expand-all highlight-current @node-click="handleNodeClick" />
|
||||
</div>
|
||||
</el-col>
|
||||
<!--用户数据-->
|
||||
<el-col :span="20" :xs="24">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input
|
||||
v-model="queryParams.userName"
|
||||
placeholder="请输入用户名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="phonenumber">
|
||||
<el-input
|
||||
v-model="queryParams.phonenumber"
|
||||
placeholder="请输入手机号码"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="用户状态"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in dict.type.sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px">
|
||||
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
@@ -81,56 +35,19 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['system:user:add']"
|
||||
>新增</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:user:edit']"
|
||||
>修改</el-button>
|
||||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:user:remove']"
|
||||
>删除</el-button>
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="info"
|
||||
plain
|
||||
icon="el-icon-upload2"
|
||||
size="mini"
|
||||
@click="handleImport"
|
||||
v-hasPermi="['system:user:import']"
|
||||
>导入</el-button>
|
||||
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['system:user:export']"
|
||||
>导出</el-button>
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -144,12 +61,7 @@
|
||||
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
|
||||
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
></el-switch>
|
||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
|
||||
@@ -157,49 +69,24 @@
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
width="160"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope" v-if="scope.row.userId !== 1">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:user:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:user:remove']"
|
||||
>删除</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">删除</el-button>
|
||||
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-d-arrow-right el-icon--right"></i>更多
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="handleResetPwd" icon="el-icon-key"
|
||||
v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item>
|
||||
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
|
||||
v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item>
|
||||
<el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item>
|
||||
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -238,7 +125,7 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
|
||||
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password/>
|
||||
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -246,51 +133,34 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户性别">
|
||||
<el-select v-model="form.sex" placeholder="请选择性别">
|
||||
<el-option
|
||||
v-for="dict in dict.type.sys_user_sex"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
></el-option>
|
||||
<el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.sys_normal_disable"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{dict.label}}</el-radio>
|
||||
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位">
|
||||
<el-select v-model="form.postIds" multiple placeholder="请选择岗位">
|
||||
<el-option
|
||||
v-for="item in postOptions"
|
||||
:key="item.postId"
|
||||
:label="item.postName"
|
||||
:value="item.postId"
|
||||
:disabled="item.status == 1"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<el-form-item label="是否管理员">
|
||||
<el-radio-group v-model="form.admin">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- <el-select v-model="form.postIds" multiple placeholder="请选择岗位">
|
||||
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option>
|
||||
</el-select> -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色">
|
||||
<el-select v-model="form.roleIds" multiple placeholder="请选择角色">
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.roleId"
|
||||
:label="item.roleName"
|
||||
:value="item.roleId"
|
||||
:disabled="item.status == 1"
|
||||
></el-option>
|
||||
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -311,18 +181,7 @@
|
||||
|
||||
<!-- 用户导入对话框 -->
|
||||
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:limit="1"
|
||||
accept=".xlsx, .xls"
|
||||
:headers="upload.headers"
|
||||
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||
:disabled="upload.isUploading"
|
||||
:on-progress="handleFileUploadProgress"
|
||||
:on-success="handleFileSuccess"
|
||||
:auto-upload="false"
|
||||
drag
|
||||
>
|
||||
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip text-center" slot="tip">
|
||||
@@ -342,7 +201,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user";
|
||||
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
|
||||
import { deptTreeSelect } from "@/api/system/dept";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import Treeselect from "@riophae/vue-treeselect";
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
@@ -471,10 +331,10 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
|
||||
this.userList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
}
|
||||
this.userList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
/** 查询部门下拉树结构 */
|
||||
@@ -496,11 +356,11 @@ export default {
|
||||
// 用户状态修改
|
||||
handleStatusChange(row) {
|
||||
let text = row.status === "0" ? "启用" : "停用";
|
||||
this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function() {
|
||||
this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function () {
|
||||
return changeUserStatus(row.userId, row.status);
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess(text + "成功");
|
||||
}).catch(function() {
|
||||
}).catch(function () {
|
||||
row.status = row.status === "0" ? "1" : "0";
|
||||
});
|
||||
},
|
||||
@@ -523,7 +383,8 @@ export default {
|
||||
status: "0",
|
||||
remark: undefined,
|
||||
postIds: [],
|
||||
roleIds: []
|
||||
roleIds: [],
|
||||
admin: false
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
@@ -592,18 +453,18 @@ export default {
|
||||
inputPattern: /^.{5,20}$/,
|
||||
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间"
|
||||
}).then(({ value }) => {
|
||||
resetUserPwd(row.userId, value).then(response => {
|
||||
this.$modal.msgSuccess("修改成功,新密码是:" + value);
|
||||
});
|
||||
}).catch(() => {});
|
||||
resetUserPwd(row.userId, value).then(response => {
|
||||
this.$modal.msgSuccess("修改成功,新密码是:" + value);
|
||||
});
|
||||
}).catch(() => { });
|
||||
},
|
||||
/** 分配角色操作 */
|
||||
handleAuthRole: function(row) {
|
||||
handleAuthRole: function (row) {
|
||||
const userId = row.userId;
|
||||
this.$router.push("/system/user-auth/role/" + userId);
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm: function() {
|
||||
submitForm: function () {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.userId != undefined) {
|
||||
@@ -625,12 +486,12 @@ export default {
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const userIds = row.userId || this.ids;
|
||||
this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function() {
|
||||
this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function () {
|
||||
return delUser(userIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
|
||||
784
src/views/zs/clue.vue
Normal file
784
src/views/zs/clue.vue
Normal file
@@ -0,0 +1,784 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row>
|
||||
<el-form ref="queryForm" :model="queryParams" inline>
|
||||
<el-row>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryParams.name" placeholder="姓名/联系方式" clearable style="width: 200px" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="queryParams.source" placeholder="选择线索来源" clearable @change="handleQuery">
|
||||
<el-option v-for="dict in sourceOptions" :key="dict.dictValue" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="queryParams.intentionState" placeholder="选择意向状态" clearable @change="handleQuery">
|
||||
<el-option v-for="dict in intentionOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue">
|
||||
<i class="el-icon-star-on" :style="dict.cssClass" />
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictValue }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="queryParams.followUser2" placeholder="选择跟进人员" filterable clearable @change="handleQuery">
|
||||
<el-option v-for="dict in userOptions" :key="dict.id" :label="dict.name" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker v-model="queryParams.createTime" style="width: 240px" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-form-item label-width="80">
|
||||
<template slot="label">
|
||||
<el-button type="text" @click="handleFilter">筛选</el-button>
|
||||
</template>
|
||||
<el-checkbox-group v-model="queryParams.etc" @change="etcChange">
|
||||
<el-checkbox v-if="filterItems.myCreate" label="myCreate">我创建的</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.myValid" label="myValid">我的有效</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.valid" label="valid">有效线索</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.todayValid" label="todayValid">今日有效线索</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.todayFollow" label="todayFollow">今日跟踪</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.outtime" label="outtime">
|
||||
<el-badge :value="expireCount" type="danger">过期线索</el-badge>
|
||||
</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.relate" label="relate">相关线索</el-checkbox>
|
||||
<el-checkbox v-if="filterItems.reSign" label="reSign">撞单线索</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item class="m20">
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="primary" @click="handlePublicClue">公海</el-button>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button type="primary">
|
||||
更多
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="handleImport(false)">导入</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="handleImport(true)">一点通导入</el-dropdown-item>
|
||||
<el-dropdown-item v-if="admin == 'true'" @click.native="handleExport">导出</el-dropdown-item>
|
||||
<el-dropdown-item v-if="admin == 'true'" @click.native="handleBatChUpdate()">批量修改</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-form-item>
|
||||
<!-- <el-button type="primary" v-if="admin != 'true' && accept" @click="handleAccept(false)">停止接收</el-button>
|
||||
<el-button type="primary" v-if="admin != 'true' && !accept" @click="handleAccept(true)">启动接收</el-button> -->
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<CustomColumnTable v-if="!queryParams.reSign" :table-list="tableDataList" :table-loading="tableLoading" :query-params.sync="queryParams" :default-columns="tableAllFields.map(item=>item.prop)" :sortable-columns="tableAllFields.map(item=>item.prop)" :table-all-fields="tableAllFields" :selectable="true" @getlist="getPageList" @changeSort="changeSort" @clickRow="handleRowClick" @selectRow="selectRow">
|
||||
<template v-slot:appendColumn>
|
||||
<!-- <el-table-column label="备注" prop="clueMemo" sortable min-width="140" show-overflow-tooltip=true v-if="!queryParams.reSign" /> -->
|
||||
<el-table-column label="意向状态" prop="intentionState" sortable fixed="right" min-width="100" v-if="!queryParams.reSign">
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag effect="dark" style="border: none" :color="tagColorMap[row.intentionState]">{{ row.intentionState }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="320" v-if="!queryParams.reSign">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" icon="el-icon-edit" @click.native.stop="handleUpdate(scope.row)" v-if="admin == 'true' || scope.row.followUser2 == userId">编辑</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) && scope.row.refuse" type="text" icon="el-icon-edit" @click.native.stop="handleRefuse(scope.row)">甩单驳回</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) &&!scope.row.refuse" type="text" icon="el-icon-edit" :style="{ color: `${scope.row.offlineReceiver?'#26A69A':'#409EFF'}` }" @click.native.stop="handleDistribute(scope.row)">甩单</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) &&scope.row.state" type="text" icon="el-icon-edit" style="color:#26A69A;" @click.native.stop="handleSign1(scope.row)">已登记</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) &&!scope.row.state" type="text" icon="el-icon-edit" @click.native.stop="handleSign1(scope.row)">未登记</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) " type="text" icon="el-icon-delete" @click.native.stop="handleDelete(scope.row)">删除</el-button>
|
||||
<el-button v-if="(admin == 'true' || scope.row.followUser2 == userId ) " type="text" icon="el-icon-delete" @click.native.stop="handleDiscard(scope.row)">释放</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</CustomColumnTable>
|
||||
|
||||
<CustomColumnTable v-else :table-list="tableDataList" :table-loading="tableLoading" :query-params.sync="queryParams" :default-columns="tableAllFields.filter(item => item.show).map(item=>item.prop)" :sortable-columns="tableAllFields.filter(item => item.show).map(item=>item.prop)" :table-all-fields="tableAllFields.filter(item => item.show)" :selectable="true" @getlist="getPageList" @changeSort="changeSort" @clickRow="handleRowClick" @selectRow="selectRow">
|
||||
</CustomColumnTable>
|
||||
|
||||
<el-drawer :visible.sync="clueVisible" size="90%" append-to-body destroy-on-close>
|
||||
<div slot="title">
|
||||
<div v-if="clueInfo.consultCount && clueInfo.consultCount < 2">
|
||||
学员信息
|
||||
<span v-if="clueInfo.name">-【{{ clueInfo.name }}】</span>
|
||||
</div>
|
||||
<el-popover v-else placement="top-start" trigger="hover">
|
||||
<el-table :data="consultRecord">
|
||||
<el-table-column width="120" prop="consultTime" label="咨询日期" />
|
||||
<el-table-column width="100" prop="consultUserName" label="咨询人" />
|
||||
</el-table>
|
||||
<el-badge slot="reference" :value="clueInfo.consultCount">
|
||||
<span>
|
||||
学员信息
|
||||
<span v-if="clueInfo.name">-【{{ clueInfo.name }}】</span>
|
||||
</span>
|
||||
</el-badge>
|
||||
</el-popover>
|
||||
</div>
|
||||
<clue-form v-if="clueVisible" ref="clueInfo" v-model="clueInfo" :options="{ userOptions: userOptions2, sourceOptions: sourceOptions, intentionOptions: intentionOptions, placeInfo: placeInfo }" />
|
||||
<div class="drawer-form__footer">
|
||||
<div style="flex: 1;text-align: right;">
|
||||
<template v-if="saveNextShow">
|
||||
<el-checkbox v-model="saveNext" />
|
||||
<span class="ml5">保存后继续创建下一条</span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="ml0" style="width: 60%; display: flex;">
|
||||
<el-button class="footer_button" @click="clueVisible = false">取 消</el-button>
|
||||
<el-button class="footer_button" type="primary" :loading="modalSaveLoading" @click="handleSaveClue">确 定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogShow" custom-class="dialog500" :width="dialogWidth">
|
||||
<component :is="componentName" v-if="dialogShow" ref="form" v-model="form" :options="dialogFormOptions" />
|
||||
<span v-if="dialogFooterShow" slot="footer">
|
||||
<el-button @click="dialogShow = false">取消</el-button>
|
||||
<el-button type="primary" :loading="dialogSaving" @click="handleDialogConfirm">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 用户导入对话框 -->
|
||||
<el-dialog title="学员信息导入" :visible.sync="upload.open" width="400px" append-to-body>
|
||||
<el-upload action="#" accept=".xlsx, .xls" :show-file-list="false" :http-request="handleUpload" :disabled="upload.isUploading" drag>
|
||||
<i class="el-icon-upload" />
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或
|
||||
<em>点击上传</em>
|
||||
</div>
|
||||
<div slot="tip" class="el-upload__tip">
|
||||
<el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
|
||||
</div>
|
||||
<div slot="tip" class="el-upload__tip" style="color:red">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
|
||||
</el-upload>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getClueList,
|
||||
exportData,
|
||||
importTemplate,
|
||||
deleteClue,
|
||||
refuse,
|
||||
getClueCountBadge,
|
||||
addClue,
|
||||
updateClue,
|
||||
getSign,
|
||||
saveSign,
|
||||
getConsultRecord,
|
||||
saveDistribute,
|
||||
batchUpdate,
|
||||
discardClue,
|
||||
updateAccept,
|
||||
getAccept
|
||||
} from '@/api/zs/clue'
|
||||
import { getEmployee, getAllPlaces, importData } from '@/api/tool/common'
|
||||
export default {
|
||||
name: 'Clue',
|
||||
components: {
|
||||
CustomColumnTable: () => ({
|
||||
component: import('@/components/CustomColumnTable'),
|
||||
}),
|
||||
ClueForm: () => ({ component: import('./components/clueForm') }),
|
||||
DistributeForm: () => ({ component: import('./components/distributeForm.vue') }),
|
||||
SignForm: () => ({ component: import('./components/signForm') }),
|
||||
BatchUpdateForm: () => ({ component: import('./components/batchUpdateForm') }),
|
||||
FilterForm: () => ({ component: import('./components/filterForm') }),
|
||||
PublicTable: () => ({ component: import('./components/publicTable') }),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
admin: localStorage.getItem('admin'),
|
||||
userId: localStorage.getItem('userId'),
|
||||
tagColorMap: {
|
||||
A高意向: '#ff7043',
|
||||
B中意向: '#26a69a',
|
||||
C无意向: '#5c6bc0',
|
||||
D未知意向: '#ef5350',
|
||||
报名成功: '#ffa726',
|
||||
报名他校: '#afaeb0',
|
||||
无效线索: '#afaeb0',
|
||||
},
|
||||
|
||||
dialogShow: false,
|
||||
dialogFooterShow: false,
|
||||
componentName: undefined,
|
||||
dialogTitle: '',
|
||||
dialogWidth: '50%',
|
||||
form: {},
|
||||
dialogSaving: false,
|
||||
dialogFormOptions: [],
|
||||
clueVisible: false,
|
||||
distributeVisible: false,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
createTime: [],
|
||||
name: undefined,
|
||||
intentionState: undefined,
|
||||
followUser2: undefined,
|
||||
source: undefined,
|
||||
etc: [],
|
||||
total: 0,
|
||||
},
|
||||
tableAllFields: [
|
||||
{ prop: 'createTime', label: '创建时间', show: true },
|
||||
{ prop: 'source', label: '线索来源', show: true },
|
||||
{ prop: 'name', label: '姓名', show: true },
|
||||
{ prop: 'phone', label: '联系方式', show: true },
|
||||
{ prop: 'address', label: '位置', show: true },
|
||||
{ prop: 'requirement', label: '学员诉求', show: true },
|
||||
{ prop: 'licenseType', label: '咨询车型', show: true },
|
||||
{ prop: 'followTime', label: '下次跟进时间', width: 140, show: true },
|
||||
{ prop: 'firstFollowUserName', label: '首次跟进人员', width: 140, show: true },
|
||||
{ prop: 'followUserName', label: '跟进人员', show: true },
|
||||
{ prop: 'recentLook', label: '是否近期看场地', width: 140 },
|
||||
{ prop: 'offlineReceiverName', label: '线下接待人员', width: 140, show: true },
|
||||
{ prop: 'clueMemo', label: '备注', show: true },
|
||||
|
||||
],
|
||||
tableLoading: false,
|
||||
tableDataList: [],
|
||||
upload: {
|
||||
open: false,
|
||||
isUploading: false,
|
||||
// 是否一点通线索
|
||||
ydtData: false,
|
||||
},
|
||||
sourceOptions: [],
|
||||
intentionOptions: [],
|
||||
userOptions: [],
|
||||
clueInfo: {},
|
||||
expireCount: undefined,
|
||||
placeInfo: [],
|
||||
consultRecord: [],
|
||||
modalSaveLoading: false,
|
||||
saveNextShow: false,
|
||||
saveNext: false,
|
||||
clueIds: [],
|
||||
filterItems: {
|
||||
myCreate: true,
|
||||
myValid: true,
|
||||
valid: true,
|
||||
todayValid: true,
|
||||
todayFollow: true,
|
||||
outtime: true,
|
||||
relate: false,
|
||||
reSign: false
|
||||
},
|
||||
accept: false,
|
||||
employeeId: undefined,
|
||||
userOptions2: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 线索来源
|
||||
this.getDicts('dm_source').then((response) => {
|
||||
this.sourceOptions = response.data
|
||||
})
|
||||
// 意向状态
|
||||
this.getDicts('dm_intention_state').then((response) => {
|
||||
this.intentionOptions = response.data
|
||||
})
|
||||
this._getClueCountBadge()
|
||||
this.getPageList()
|
||||
this.getEmployee()
|
||||
// 查询场地
|
||||
this.getAllPlace()
|
||||
if (localStorage.getItem(this.userId + '-filterItems')) {
|
||||
this.filterItems = JSON.parse(
|
||||
localStorage.getItem(this.userId + '-filterItems')
|
||||
)
|
||||
}
|
||||
this.getAccept();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getPageList()
|
||||
},
|
||||
getAccept() {
|
||||
getAccept().then(resp => {
|
||||
if (resp.code == 200) {
|
||||
this.accept = resp.data.accept;
|
||||
this.employeeId = resp.data.employeeId;
|
||||
}
|
||||
})
|
||||
},
|
||||
getPageList() {
|
||||
this.tableLoading = true
|
||||
const params = { ...this.queryParams, etc: undefined }
|
||||
getClueList(this.opearateRequestParams(params)).then((response) => {
|
||||
this.tableDataList = response.rows
|
||||
this.queryParams.total = response.total
|
||||
this.tableLoading = false
|
||||
})
|
||||
},
|
||||
// 获取已过期
|
||||
async _getClueCountBadge() {
|
||||
const resp = await getClueCountBadge()
|
||||
if (resp.code === 200) {
|
||||
this.expireCount = resp.data
|
||||
}
|
||||
},
|
||||
// 重置搜索
|
||||
resetQuery() {
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
createTime: [],
|
||||
name: undefined,
|
||||
intentionState: undefined,
|
||||
followUser2: undefined,
|
||||
source: undefined,
|
||||
etc: [],
|
||||
total: 0,
|
||||
}
|
||||
this.handleQuery()
|
||||
},
|
||||
etcChange(val) {
|
||||
this.$set(this.queryParams, 'myCreate', undefined)
|
||||
this.$set(this.queryParams, 'myValid', undefined)
|
||||
this.$set(this.queryParams, 'valid', undefined)
|
||||
this.$set(this.queryParams, 'todayValid', undefined)
|
||||
this.$set(this.queryParams, 'todayFollow', undefined)
|
||||
this.$set(this.queryParams, 'outtime', undefined)
|
||||
this.$set(this.queryParams, 'relate', undefined)
|
||||
this.$set(this.queryParams, 'reSign', undefined)
|
||||
|
||||
if (!this.isNullOrEmpty(val)) {
|
||||
val.length > 1 &&
|
||||
this.$set(this.queryParams, 'etc', [val[val.length - 1]])
|
||||
this.$set(this.queryParams, val[val.length - 1], true)
|
||||
}
|
||||
if (this.queryParams.reSign) {
|
||||
this.tableAllFields = this.tableAllFields.map(item => {
|
||||
if (item.prop == 'clueMemo') {
|
||||
item.show = false;
|
||||
}
|
||||
return item;
|
||||
})
|
||||
} else {
|
||||
this.tableAllFields = this.tableAllFields.map(item => {
|
||||
if (item.prop == 'clueMemo') {
|
||||
item.show = true;
|
||||
}
|
||||
return item;
|
||||
})
|
||||
}
|
||||
this.handleQuery()
|
||||
},
|
||||
resetForm() {
|
||||
this.clueInfo = {
|
||||
clueId: undefined,
|
||||
createTime: this.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}'),
|
||||
consultTime: undefined,
|
||||
source: undefined,
|
||||
name: undefined,
|
||||
phone: undefined,
|
||||
address: undefined,
|
||||
intentionState: undefined,
|
||||
followInfo: undefined,
|
||||
followTime: undefined,
|
||||
followUser: undefined,
|
||||
signupInfo: undefined,
|
||||
requirement: undefined,
|
||||
licenseType: undefined,
|
||||
}
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions,
|
||||
sourceOptions: this.sourceOptions,
|
||||
intentionOptions: this.intentionOptions,
|
||||
placeInfo: this.placeInfo,
|
||||
}
|
||||
},
|
||||
// 新增
|
||||
handleAdd() {
|
||||
this.resetForm()
|
||||
this.clueVisible = true
|
||||
this.saveNextShow = true
|
||||
this.saveNext = false
|
||||
this.getEmployee2();
|
||||
},
|
||||
// 编辑
|
||||
handleUpdate(listItem) {
|
||||
this.clueVisible = true
|
||||
this.clueInfo = listItem
|
||||
this.saveNextShow = false
|
||||
this.saveNext = false
|
||||
this.getEmployee2()
|
||||
// 查询咨询记录
|
||||
this.getConsultRecord(listItem.clueId)
|
||||
},
|
||||
// 查询咨询记录
|
||||
getConsultRecord(clueId) {
|
||||
getConsultRecord({ clueId }).then((resp) => {
|
||||
if (resp && resp.code === 200 && resp.data) {
|
||||
this.consultRecord = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
handleRowClick(row) {
|
||||
if (!this.queryParams.reSign) {
|
||||
this.handleUpdate(row)
|
||||
}
|
||||
},
|
||||
// 删除
|
||||
handleDelete(item) {
|
||||
this.$confirm(
|
||||
'是否确认删除该条线索(“' + item.name + '/' + item.phone + '”)?',
|
||||
'警告',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
deleteClue({ clueId: item.clueId }).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('删除成功')
|
||||
this.getPageList()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(function () { })
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.$confirm('是否确认导出所有学员信息项?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
const resp = await exportData(
|
||||
this.opearateRequestParams(this.queryParams)
|
||||
)
|
||||
this.download(resp.msg)
|
||||
})
|
||||
},
|
||||
/** 导入按钮操作 */
|
||||
handleImport(ydtData) {
|
||||
this.upload.open = true
|
||||
this.upload.ydtData = ydtData
|
||||
},
|
||||
/** 下载模板操作 */
|
||||
importTemplate() {
|
||||
importTemplate({ ydtData: this.upload.ydtData }).then((response) => {
|
||||
this.download(response.msg)
|
||||
})
|
||||
},
|
||||
async handleUpload(data) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', data.file)
|
||||
this.upload.isUploading = true
|
||||
importData(this.upload.ydtData, formData).then(resp => {
|
||||
this.upload.isUploading = false
|
||||
if (resp.code === 200) {
|
||||
this.$alert(resp.msg, '导入结果', {
|
||||
dangerouslyUseHTMLString: true
|
||||
});
|
||||
this.upload.open = false
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
getEmployee() {
|
||||
getEmployee({ coach: false }).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.userOptions = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
//查询不能接收线索的员工
|
||||
getEmployee2() {
|
||||
getEmployee({ coach: false }).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.userOptions2 = resp.data
|
||||
this.userOptions2 = this.userOptions2.filter(item => {
|
||||
return item.accept;
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
changeSort(val) {
|
||||
if (val.order) {
|
||||
this.queryParams.orderName = val.prop
|
||||
if (val.order === 'ascending') {
|
||||
this.queryParams.orderType = 'asc'
|
||||
} else {
|
||||
this.queryParams.orderType = 'desc'
|
||||
}
|
||||
} else {
|
||||
this.queryParams.orderName = undefined
|
||||
this.queryParams.orderType = undefined
|
||||
}
|
||||
this.getPageList()
|
||||
},
|
||||
handleDistribute(item) {
|
||||
this.dialogTitle = '甩单'
|
||||
this.dialogWidth = '700px'
|
||||
this.componentName = 'DistributeForm'
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions,
|
||||
offlineReceiver: item.offlineReceiver,
|
||||
}
|
||||
this.dialogFooterShow = true
|
||||
this.form = {
|
||||
clueId: item.clueId,
|
||||
offlineReceiverName: item.offlineReceiverName,
|
||||
offlineReceiver: undefined,
|
||||
memo: item.memo,
|
||||
}
|
||||
this.dialogShow = true
|
||||
},
|
||||
handleRefuse(item) {
|
||||
refuse({ clueId: item.clueId }).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('驳回成功')
|
||||
this.getPageList()
|
||||
}
|
||||
})
|
||||
},
|
||||
resetSignForm() {
|
||||
this.form = {
|
||||
dealDate: this.parseTime(new Date(), '{y}-{m}-{d}'),
|
||||
signSchool: undefined,
|
||||
schoolName: undefined,
|
||||
signPlace: undefined,
|
||||
placeName: undefined,
|
||||
signClass: undefined,
|
||||
className: undefined,
|
||||
signPrice: undefined,
|
||||
schoolPeople: undefined,
|
||||
schoolPay: undefined,
|
||||
alipay: undefined,
|
||||
profit: undefined,
|
||||
percentage: undefined,
|
||||
detail: undefined,
|
||||
dealState: undefined,
|
||||
extraPayType: undefined,
|
||||
extraPay: undefined,
|
||||
percentageState: undefined,
|
||||
memo: undefined,
|
||||
createTime: undefined,
|
||||
updateTime: undefined,
|
||||
state: true,
|
||||
commission: undefined,
|
||||
}
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions,
|
||||
sourceOptions: this.sourceOptions,
|
||||
placeInfo: this.placeInfo,
|
||||
}
|
||||
},
|
||||
async handleSign1(item) {
|
||||
this.dialogTitle = '成交登记'
|
||||
this.dialogWidth = '800px'
|
||||
this.componentName = 'SignForm'
|
||||
this.dialogFooterShow = true
|
||||
this.resetSignForm()
|
||||
const resp = await getSign({ clueId: item.clueId })
|
||||
if (resp.code === 200) {
|
||||
const {
|
||||
clueId,
|
||||
consultTime,
|
||||
name,
|
||||
phone,
|
||||
source,
|
||||
followUser,
|
||||
followUser2,
|
||||
followUserName,
|
||||
offlineReceiver,
|
||||
offlineReceiver2,
|
||||
offlineReceiverName,
|
||||
} = item
|
||||
this.form = Object.assign({}, this.form, {
|
||||
clueId,
|
||||
consultTime,
|
||||
name,
|
||||
phone,
|
||||
source,
|
||||
followUser,
|
||||
followUser2,
|
||||
followUserName,
|
||||
offlineReceiver,
|
||||
offlineReceiver2,
|
||||
offlineReceiverName,
|
||||
})
|
||||
if (resp.data) {
|
||||
this.form = { ...this.form, ...resp.data }
|
||||
this.dialogFooterShow = this.form.signEdit
|
||||
}
|
||||
this.dialogShow = true
|
||||
}
|
||||
},
|
||||
getAllPlace() {
|
||||
getAllPlaces({ status: '0' }).then((resp) => {
|
||||
this.placeInfo = resp.data.filter(
|
||||
(item) => item.schoolShow && item.showInMap
|
||||
)
|
||||
})
|
||||
},
|
||||
handleSaveClue() {
|
||||
this.$refs.clueInfo.validateForm().then(async (valid) => {
|
||||
if (valid) {
|
||||
this.modalSaveLoading = true
|
||||
let resp
|
||||
if (this.clueInfo.clueId) {
|
||||
resp = await updateClue(this.clueInfo)
|
||||
this.modalSaveLoading = false
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('修改成功')
|
||||
this.getPageList()
|
||||
this.clueVisible = false
|
||||
}
|
||||
} else {
|
||||
resp = await addClue(this.clueInfo)
|
||||
this.modalSaveLoading = false
|
||||
if (resp.code === 200) {
|
||||
this.$message.success('新增成功')
|
||||
if (this.saveNext) {
|
||||
this.resetForm()
|
||||
} else {
|
||||
this.getPageList()
|
||||
this.clueVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDialogConfirm() {
|
||||
this.$refs.form.validate().then(async (valid) => {
|
||||
if (valid) {
|
||||
let resp
|
||||
this.dialogSaving = true
|
||||
if (this.componentName === 'SignForm') {
|
||||
// 登记提交
|
||||
this.form.checkState = 1
|
||||
resp = await saveSign(this.form)
|
||||
} else if (this.componentName === 'DistributeForm') {
|
||||
resp = await saveDistribute(this.form)
|
||||
} else if (this.componentName === 'BatchUpdateForm') {
|
||||
resp = await batchUpdate(this.form)
|
||||
} else if (this.componentName === 'FilterForm') {
|
||||
this.filterItems = { ...this.form }
|
||||
localStorage.setItem(
|
||||
this.userId + '-filterItems',
|
||||
JSON.stringify(this.filterItems)
|
||||
)
|
||||
this.$message.success('操作成功')
|
||||
this.dialogShow = false
|
||||
}
|
||||
this.dialogSaving = false
|
||||
if (resp && resp.code === 200) {
|
||||
this.$message.success('操作成功')
|
||||
this.dialogShow = false
|
||||
this.getPageList()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
//表格多选
|
||||
selectRow(val) {
|
||||
console.log(val)
|
||||
this.clueIds = []
|
||||
if (val && val.length > 0) {
|
||||
this.clueIds = val.map((item) => item.clueId)
|
||||
}
|
||||
},
|
||||
//批量修改
|
||||
handleBatChUpdate() {
|
||||
this.getEmployee2()
|
||||
//判断是否选择了数据
|
||||
if (!this.clueIds || this.clueIds.length <= 0) {
|
||||
//提示选择数据
|
||||
this.$message.error('请至少选择一条数据!')
|
||||
} else {
|
||||
//打开编辑框
|
||||
this.dialogTitle = '批量修改'
|
||||
this.dialogWidth = '500px'
|
||||
this.componentName = 'BatchUpdateForm'
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions2,
|
||||
}
|
||||
this.dialogFooterShow = true
|
||||
this.form = {
|
||||
followUsers: [],
|
||||
clueIds: this.clueIds,
|
||||
}
|
||||
this.dialogShow = true
|
||||
}
|
||||
},
|
||||
//筛选点击事件
|
||||
handleFilter() {
|
||||
//打开编辑框
|
||||
this.dialogTitle = '筛选配置'
|
||||
this.dialogWidth = '500px'
|
||||
this.componentName = 'FilterForm'
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions,
|
||||
}
|
||||
this.dialogFooterShow = true
|
||||
this.form = { ...this.filterItems }
|
||||
this.dialogShow = true
|
||||
},
|
||||
handlePublicClue() {
|
||||
//打开编辑框
|
||||
this.dialogTitle = '公海线索'
|
||||
this.dialogWidth = '900px'
|
||||
this.componentName = 'PublicTable'
|
||||
this.dialogFormOptions = {
|
||||
userOptions: this.userOptions,
|
||||
}
|
||||
this.dialogFooterShow = false
|
||||
this.form = {}
|
||||
this.dialogShow = true
|
||||
},
|
||||
handleDiscard(item) {
|
||||
discardClue(item).then((resp) => {
|
||||
if (resp && resp.code == 200) {
|
||||
this.$message.success('释放成功')
|
||||
this.getPageList()
|
||||
}
|
||||
})
|
||||
},
|
||||
//停止或启动接收线索
|
||||
handleAccept(accept) {
|
||||
updateAccept({ employeeId: this.employeeId, accept: accept }).then(resp => {
|
||||
if (resp.code == 200) {
|
||||
this.$message.success(accept ? '启动成功' : '停止成功')
|
||||
this.accept = accept;
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drawer-form__footer {
|
||||
border-top: 1px solid rgba(69, 74, 91, 0.1);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
z-index: 2;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.footer_button {
|
||||
width: 49%;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
73
src/views/zs/components/batchUpdateForm.vue
Normal file
73
src/views/zs/components/batchUpdateForm.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="110px"
|
||||
:disabled="form.signId != undefined"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="跟进人员" prop="followUsers">
|
||||
<el-select v-model="form.followUsers" multiple placeholder="请选择" clearable>
|
||||
<el-option
|
||||
v-for="dict in options.userOptions"
|
||||
:key="dict.id"
|
||||
:label="dict.name"
|
||||
:value="dict.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'BatchUpdateForm',
|
||||
model: {
|
||||
prop: 'info',
|
||||
event: 'update',
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
userOptions: [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
admin: JSON.parse(localStorage.getItem('admin')),
|
||||
form: JSON.parse(JSON.stringify(this.info)),
|
||||
rules: {
|
||||
followUsers: {
|
||||
required: true,
|
||||
message: '跟进人员不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(val) {
|
||||
this.$emit('update', val)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
return this.$refs.form.validate()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
650
src/views/zs/components/clueForm.vue
Normal file
650
src/views/zs/components/clueForm.vue
Normal file
@@ -0,0 +1,650 @@
|
||||
<template>
|
||||
<div style="margin-bottom: 50px">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker v-model="form.createTime" value-format="yyyy-MM-dd HH:mm" format="yyyy-MM-dd HH:mm" type="datetime" :disabled="admin!='true'" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="线索来源" prop="source">
|
||||
<el-select v-model="form.source" placeholder="请选择" clearable>
|
||||
<el-option v-for="dict in options.sourceOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="跟进人员" prop="followUser">
|
||||
<el-select v-model="form.followUser" multiple clearable :disabled="admin != 'true' && form.clueId != undefined">
|
||||
<el-option v-for="dict in options.userOptions" :key="dict.id" :label="dict.name" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="联系方式" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="请输入联系方式" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="意向状态" prop="intentionState">
|
||||
<el-select v-model="form.intentionState" placeholder="请选择" clearable>
|
||||
<el-option v-for="dict in options.intentionOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue">
|
||||
<i class="el-icon-star-on" :style="dict.cssClass" />
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">
|
||||
{{
|
||||
dict.dictValue
|
||||
}}
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="下次跟进时间" prop="followTime">
|
||||
<el-date-picker v-model="form.followTime" value-format="yyyy-MM-dd HH:mm" format="yyyy-MM-dd HH:mm" type="datetime" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否近期看场地" prop="recentLook">
|
||||
<el-radio v-model="form.recentLook" label="是">是</el-radio>
|
||||
<el-radio v-model="form.recentLook" label="否">否</el-radio>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="显示场地">
|
||||
<el-radio-group v-model="mapPlaceType" @change="createMarkersInMap">
|
||||
<el-radio :label="0">自营场地</el-radio>
|
||||
<el-radio :label="1">全部场地</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="clueMemo">
|
||||
<el-input v-model="form.clueMemo" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20 plr20" style="position: relative">
|
||||
<div id="map" class="amap-cavans" />
|
||||
<el-collapse class="box-card">
|
||||
<el-collapse-item title="附近驾校">
|
||||
<div style="padding: 10px">
|
||||
<div slot="header">附近驾校</div>
|
||||
<div v-if="nearbySchoolSearching">正在搜索中...</div>
|
||||
<template v-else>
|
||||
<div v-for="p in nearbySchoolList" :key="p.index">
|
||||
<div class="hover-pointer" style="font-size: 14px; color: blue" @click="getClassType(p)">
|
||||
<i v-if="p.recommend" class="el-icon-star-off" />
|
||||
驾校: {{ p.deptName }}-{{ p.name }}
|
||||
</div>
|
||||
<div class="mt5">地址:{{ p.address }}</div>
|
||||
<div class="mt5">
|
||||
直线距离: {{ p.distance }} 公里;
|
||||
<span class="ml0">步行距离:{{ p.walkdistance }}</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<div class="address">
|
||||
<el-form-item label="位置" prop="address" label-width="80px">
|
||||
<el-input v-model="form.address" placeholder="请输入位置" disabled>
|
||||
<el-button slot="append" class="p10" icon="el-icon-location-information" @click="handleMapEdit" />
|
||||
<el-button slot="append" class="p10" icon="el-icon-delete-solid" @click="handleRemovePosition" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-bottom: 20px">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="跟进情况">
|
||||
<el-timeline v-if="folowInfos != undefined && folowInfos.length > 0" style="max-height: 200px; overflow-y: auto">
|
||||
<el-timeline-item v-for="item in folowInfos" :key="item.record" :timestamp="item.operateTime" placement="top" style="padding: 5px !important">
|
||||
<el-card>
|
||||
<div style="font-weight: bold">用户 {{ item.operateUserName }}</div>
|
||||
<div style="padding-left: 10px" v-html="item.centent" />
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-dialog width="800px" title="地图编辑" :visible.sync="mapDialogShow" append-to-body @opened="initDialogMap()">
|
||||
<div id="dialogMap" class="dialog-map" />
|
||||
<!-- <el-input id="search" v-model="searchBody" class="search-body" placeholder="请输入..." /> -->
|
||||
<el-autocomplete popper-class="my-autocomplete" class="search-body" placeholder="请输入..." v-model="searchBody" :trigger-on-focus="false" :fetch-suggestions="querySearch" @select="handleSelect">
|
||||
<template slot-scope="{ item }">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="addr">{{ item.district }}</span>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="mapDialogShow = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleMapSave">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog width="40%" :title="innerTitle" :visible.sync="innerVisible" append-to-body>
|
||||
<div v-if="classType == undefined || classType.length == 0">无班型数据</div>
|
||||
<el-table v-else :data="classType" style="height: 300px; overflow-y: auto">
|
||||
<el-table-column label="班型">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.licenseType }}-{{ scope.row.dictLabel }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="currentPrice" label="报价" />
|
||||
<el-table-column property="minPrice" label="底价" />
|
||||
<el-table-column property="description" label="描述" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getFollowRecord } from '@/api/zs/clue';
|
||||
import { getClassTypes } from '@/api/tool/common';
|
||||
import { inputtips, regeo, walking } from '@/api/tool/map';
|
||||
// import AMap from 'AMap';
|
||||
export default {
|
||||
model: {
|
||||
prop: 'info',
|
||||
event: 'update'
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
userOptions: [],
|
||||
sourceOptions: [],
|
||||
intentionOptions: [],
|
||||
placeInfo: []
|
||||
})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
admin: localStorage.getItem('admin'),
|
||||
userId: localStorage.getItem('userId'),
|
||||
form: JSON.parse(JSON.stringify(this.info)),
|
||||
mapDialogShow: false,
|
||||
map: null,
|
||||
locationMarker: null,
|
||||
dialogMap: null, // 弹窗地图(打点用)
|
||||
currentPoint: {}, // 地图弹窗经纬度信息
|
||||
marker: null, // 地图打点
|
||||
placeSearch: null,
|
||||
geocoder: null,
|
||||
searchBody: '',
|
||||
nearbySchoolList: [],
|
||||
folowInfos: [],
|
||||
nearbySchoolSearching: false, // 搜索附近场地
|
||||
rules: {
|
||||
name: {
|
||||
required: true,
|
||||
message: '姓名不为空',
|
||||
trigger: 'blur'
|
||||
},
|
||||
phone: {
|
||||
required: true,
|
||||
message: '联系方式不为空',
|
||||
trigger: 'blur'
|
||||
},
|
||||
createTime: {
|
||||
required: true,
|
||||
message: '创建时间不为空',
|
||||
trigger: 'blur,change'
|
||||
},
|
||||
consultTime: {
|
||||
required: true,
|
||||
message: '咨询时间不为空',
|
||||
trigger: 'blur,change'
|
||||
},
|
||||
source: {
|
||||
required: true,
|
||||
message: '线索来源不为空',
|
||||
trigger: 'blur,change'
|
||||
},
|
||||
address: {
|
||||
required: true,
|
||||
message: '位置不为空',
|
||||
trigger: 'blur'
|
||||
},
|
||||
intentionState: {
|
||||
required: true,
|
||||
message: '意向状态不为空',
|
||||
trigger: 'blur,change'
|
||||
}
|
||||
},
|
||||
innerTitle: '',
|
||||
classType: [],
|
||||
innerVisible: false,
|
||||
consultRecord: [],
|
||||
mapPlaceType: 0 // 地图上展示的场地类型 0:自营 1 全部
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(val) {
|
||||
this.$emit('update', val);
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.form.clueId) {
|
||||
this.handleUpdate();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initMap();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.geocoder = null;
|
||||
this.locationMarker = null;
|
||||
this.marker = null;
|
||||
this.placeSearch = null;
|
||||
|
||||
this.map.clearMap();
|
||||
this.map && this.map.destroy();
|
||||
this.map = null;
|
||||
|
||||
this.dialogMap && this.dialogMap.destroy();
|
||||
this.dialogMap = null;
|
||||
},
|
||||
methods: {
|
||||
// 查询该场地下的班型报价
|
||||
getClassType(item) {
|
||||
this.classType = [];
|
||||
this.innerTitle = item.deptName + '-' + item.name + '-班型报价';
|
||||
getClassTypes({
|
||||
schoolId: item.deptId,
|
||||
placeId: item.placeId,
|
||||
status: '0'
|
||||
}).then((resp) => {
|
||||
if (resp && resp.code === 200 && resp.data) {
|
||||
this.classType = resp.data;
|
||||
this.innerVisible = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 编辑
|
||||
handleUpdate() {
|
||||
// 加载跟进记录
|
||||
getFollowRecord({ clueId: this.form.clueId }).then((resp) => {
|
||||
this.folowInfos = resp.data;
|
||||
});
|
||||
},
|
||||
initMap() {
|
||||
if (!this.map) {
|
||||
this.map = new AMap.Map('map', {
|
||||
zoom: 12,
|
||||
center: [117.226095, 31.814372],
|
||||
resizeEnable: true
|
||||
});
|
||||
}
|
||||
|
||||
// 地图坐标点定位
|
||||
if (this.form.lat && this.form.lng) {
|
||||
this.locationMarker = new AMap.Marker({
|
||||
position: [this.form.lng, this.form.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.map.add(this.locationMarker);
|
||||
this.map.setCenter([this.form.lng, this.form.lat]);
|
||||
this.map.setZoom(14);
|
||||
}
|
||||
this.getNearbySchool();
|
||||
this.createMarkersInMap();
|
||||
},
|
||||
// 生成markers
|
||||
createMarkersInMap() {
|
||||
let arr = this.options.placeInfo;
|
||||
if (this.mapPlaceType === 0) {
|
||||
arr = arr.filter((item) => item.recommend);
|
||||
}
|
||||
this.map && this.map.clearMap();
|
||||
this.locationMarker && this.map.add(this.locationMarker);
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const element = arr[i];
|
||||
const tmpMarker = new AMap.Marker({
|
||||
map: this.map,
|
||||
position: [element.lng, element.lat],
|
||||
label: {
|
||||
content: element.name,
|
||||
direction: 'left'
|
||||
},
|
||||
icon: require(`@/assets/images/position_${element.flagColor}.png`),
|
||||
extData: element,
|
||||
clickable: true
|
||||
});
|
||||
tmpMarker.on('click', (ev) =>
|
||||
this.getClassType(ev.target.getExtData())
|
||||
);
|
||||
}
|
||||
},
|
||||
handleMapEdit() {
|
||||
this.searchBody = '';
|
||||
this.mapDialogShow = true;
|
||||
if (this.form.lat && this.form.lng) {
|
||||
this.currentPoint.lat = this.form.lat;
|
||||
this.currentPoint.lng = this.form.lng;
|
||||
}
|
||||
this.dialogMap && this.dialogMap.clearMap();
|
||||
},
|
||||
handleRemovePosition() {
|
||||
this.form.lng = undefined;
|
||||
this.form.lat = undefined;
|
||||
this.form.address = undefined;
|
||||
},
|
||||
initDialogMap() {
|
||||
if (!this.dialogMap) {
|
||||
this.dialogMap = new AMap.Map('dialogMap', {
|
||||
zoom: 12,
|
||||
resizeEnable: true,
|
||||
center: [117.283042, 31.86119]
|
||||
});
|
||||
this.dialogMap.on('click', (ev) => {
|
||||
this.currentPoint.lat = ev.lnglat.lat;
|
||||
this.currentPoint.lng = ev.lnglat.lng;
|
||||
this.regeoCode();
|
||||
this.marker && this.dialogMap.remove(this.marker);
|
||||
this.marker = new AMap.Marker({
|
||||
position: [this.currentPoint.lng, this.currentPoint.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.dialogMap.add(this.marker);
|
||||
});
|
||||
this.dialogMap.addControl(new AMap.Scale());
|
||||
// const auto = new AMap.Autocomplete({
|
||||
// input: 'search', // 前端搜索框
|
||||
// })
|
||||
// this.placeSearch = new AMap.PlaceSearch({
|
||||
// map: this.dialogMap,
|
||||
// pageSize: 1, // 单页显示结果条数
|
||||
// pageIndex: 1, // 页码
|
||||
// autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
|
||||
// })
|
||||
// AMap.event.addListener(auto, 'select', this.select)
|
||||
this.geocoder = new AMap.Geocoder();
|
||||
}
|
||||
// 初始化编辑地图的中心点
|
||||
if (this.form.lat && this.form.lng) {
|
||||
this.searchBody = this.form.address;
|
||||
this.marker = new AMap.Marker({
|
||||
map: this.dialogMap,
|
||||
position: [this.form.lng, this.form.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.dialogMap.setCenter([this.form.lng, this.form.lat]);
|
||||
this.dialogMap.setZoom(14);
|
||||
}
|
||||
},
|
||||
handleMapSave() {
|
||||
if (this.currentPoint.lat && this.currentPoint.lng) {
|
||||
this.form.lng = this.currentPoint.lng;
|
||||
this.form.lat = this.currentPoint.lat;
|
||||
this.$set(this.form, 'address', this.currentPoint.address);
|
||||
this.locationMarker && this.map.remove(this.locationMarker);
|
||||
this.locationMarker = new AMap.Marker({
|
||||
map: this.map,
|
||||
position: [this.currentPoint.lng, this.currentPoint.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.map.setCenter([this.currentPoint.lng, this.currentPoint.lat]);
|
||||
this.map.setZoom(14);
|
||||
this.getNearbySchool();
|
||||
this.mapDialogShow = false;
|
||||
} else {
|
||||
this.$message.error('请在地图上选择位置后保存!');
|
||||
}
|
||||
},
|
||||
// 选择查询结果
|
||||
select(e) {
|
||||
this.placeSearch.setCity(e.poi.adcode);
|
||||
this.placeSearch.search(e.poi.name, (status, result) => {
|
||||
// 搜索成功时,result即是对应的匹配数据
|
||||
if (
|
||||
result &&
|
||||
result.info &&
|
||||
result.info === 'OK' &&
|
||||
result.poiList &&
|
||||
result.poiList.pois &&
|
||||
result.poiList.pois.length > 0
|
||||
) {
|
||||
this.currentPoint.lat = result.poiList.pois[0].location.lat;
|
||||
this.currentPoint.lng = result.poiList.pois[0].location.lng;
|
||||
this.currentPoint.address = e.poi.name;
|
||||
this.dialogMap.clearMap();
|
||||
this.marker && this.dialogMap.remove(this.marker);
|
||||
this.marker = new AMap.Marker({
|
||||
map: this.dialogMap,
|
||||
position: [this.currentPoint.lng, this.currentPoint.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.dialogMap.setZoom(14);
|
||||
this.dialogMap.setCenter([
|
||||
this.currentPoint.lng,
|
||||
this.currentPoint.lat
|
||||
]);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 经纬度 -> 地址
|
||||
regeoCode() {
|
||||
// this.geocoder.getAddress(
|
||||
// [this.currentPoint.lng, this.currentPoint.lat],
|
||||
// (status, result) => {
|
||||
// if (status === 'complete' && result.regeocode) {
|
||||
// this.currentPoint.address = result.regeocode.formattedAddress;
|
||||
// this.searchBody = result.regeocode.formattedAddress;
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
if (this.currentPoint.lng && this.currentPoint.lat) {
|
||||
regeo({
|
||||
key: 'f2f35d6adc4a16bb879d303cead56237',
|
||||
location: this.currentPoint.lng + "," + this.currentPoint.lat
|
||||
}).then(resp => {
|
||||
if (resp.status == '1') {
|
||||
this.currentPoint.address = resp.regeocode.formatted_address;
|
||||
this.searchBody = resp.regeocode.formatted_address;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
// 计算各个场地到目标点的距离·
|
||||
getNearbySchool() {
|
||||
if (this.form.lng && this.form.lat) {
|
||||
this.nearbySchoolList = [];
|
||||
this.nearbySchoolSearching = true;
|
||||
// 推荐的场地
|
||||
let places1 = [];
|
||||
// 普通的场地
|
||||
let places2 = [];
|
||||
|
||||
const p2 = [this.form.lng, this.form.lat];
|
||||
for (let i = 0; i < this.options.placeInfo.length; i++) {
|
||||
const element = this.options.placeInfo[i];
|
||||
const p1 = [element.lng, element.lat];
|
||||
// 计算直线距离
|
||||
element.distance = (
|
||||
window.AMap.GeometryUtil.distance(p1, p2) / 1000
|
||||
).toFixed(2);
|
||||
element.recommend ? places1.push(element) : places2.push(element);
|
||||
}
|
||||
// 按直线距离排序
|
||||
// 排序
|
||||
if (places1.length > 1) {
|
||||
places1 = places1.sort((a, b) => a.distance - b.distance);
|
||||
}
|
||||
// 排序
|
||||
if (places2.length > 1) {
|
||||
places2 = places2.sort((a, b) => a.distance - b.distance);
|
||||
}
|
||||
// 取普通场地和推荐场地,组合, 取四个
|
||||
this.nearbySchoolList = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
places1.length > i && this.nearbySchoolList.push(places1[i]);
|
||||
places2.length > i && this.nearbySchoolList.push(places2[i]);
|
||||
if (this.nearbySchoolList.length === 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 计算步行距离
|
||||
this.nearbySchoolList.map(async (item) => {
|
||||
const p1 = [item.lng, item.lat];
|
||||
const resp = await this.getWalkingDistance(p1, p2);
|
||||
item.walkdistance = resp;
|
||||
this.$forceUpdate();
|
||||
});
|
||||
this.nearbySchoolSearching = false;
|
||||
}
|
||||
},
|
||||
// 获取两点之间的步行距离
|
||||
async getWalkingDistance(start, end) {
|
||||
if (start && end) {
|
||||
const resp = await walking({
|
||||
key: 'f2f35d6adc4a16bb879d303cead56237',
|
||||
origin: start[0] + "," + start[1],
|
||||
destination: end[0] + "," + end[1],
|
||||
});
|
||||
if (resp.status === '1') {
|
||||
let num = resp.route.paths[0].distance;
|
||||
return num > 1000 ? `${(num / 1000).toFixed(2)} 公里` : `${num} 米`
|
||||
|
||||
} else {
|
||||
return '步行数据无法确定';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
|
||||
// })
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// window.AMap.plugin('AMap.Walking', () => {
|
||||
// const walking = new AMap.Walking();
|
||||
// let num = 0;
|
||||
// walking.search(start, end, (status, result) => {
|
||||
// debugger
|
||||
// if (status === 'complete') {
|
||||
// result.routes.forEach((item) => {
|
||||
// num += item.distance;
|
||||
// });
|
||||
// resolve(
|
||||
// num > 1000 ? `${(num / 1000).toFixed(2)} 公里` : `${num} 米`
|
||||
// );
|
||||
// } else {
|
||||
// resolve('步行数据无法确定');
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
},
|
||||
validateForm() {
|
||||
return this.$refs.form.validate();
|
||||
},
|
||||
async querySearch(queryString, cb) {
|
||||
if (queryString) {
|
||||
const resp = await inputtips({
|
||||
key: 'f2f35d6adc4a16bb879d303cead56237',
|
||||
keywords: queryString
|
||||
});
|
||||
cb(resp.tips);
|
||||
}
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.currentPoint.lat = item.location.split(',')[1];
|
||||
this.currentPoint.lng = item.location.split(',')[0];
|
||||
this.currentPoint.address = item.name;
|
||||
this.searchBody = item.district + item.name;
|
||||
this.dialogMap.clearMap();
|
||||
this.marker && this.dialogMap.remove(this.marker);
|
||||
this.marker = new AMap.Marker({
|
||||
map: this.dialogMap,
|
||||
position: [this.currentPoint.lng, this.currentPoint.lat],
|
||||
icon: require(`@/assets/images/place/flag_red.png`)
|
||||
});
|
||||
this.dialogMap.setZoom(14);
|
||||
this.dialogMap.setCenter([this.currentPoint.lng, this.currentPoint.lat]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.amap-cavans {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.dialog-map {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
.address {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 10px;
|
||||
width: 400px;
|
||||
background: #fff;
|
||||
}
|
||||
.box-card {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 10px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.search-body {
|
||||
position: absolute;
|
||||
top: 90px;
|
||||
left: 25px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.el-divider--horizontal {
|
||||
margin: 6px 0;
|
||||
}
|
||||
li {
|
||||
padding: 6px;
|
||||
.name {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.addr {
|
||||
line-height: 16px;
|
||||
font-size: 10px;
|
||||
color: #b4b4b4;
|
||||
}
|
||||
|
||||
.highlighted .addr {
|
||||
color: #ddd;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
95
src/views/zs/components/distributeForm.vue
Normal file
95
src/views/zs/components/distributeForm.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="线下接待人员" prop="offlineReceiver">
|
||||
<el-input v-if="form.offlineReceiverName" v-model="form.offlineReceiverName" disabled />+
|
||||
<el-select v-model="form.offlineReceiver" multiple filterable placeholder="请选择" style="width:97%; padding-top:5px;">
|
||||
<el-option v-for="dict in options.userOptions.filter(item => !options.offlineReceiver || !options.offlineReceiver.includes(item.id))" :key="dict.id" :label="dict.name" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="memo">
|
||||
<el-input v-model="form.memo" type="textarea" :rows="4" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col v-if="distributeRecord != undefined && distributeRecord.length > 0" :span="24">
|
||||
<el-form-item label="甩单记录">
|
||||
<el-timeline style="max-height:260px;overflow-y:auto;">
|
||||
<el-timeline-item v-for="item in distributeRecord" :key="item.record" :timestamp="item.operateTime" placement="top" style="padding:5px !important;">
|
||||
<el-card>
|
||||
<span style="display:block;font-weight: bold; font-size:13px;">用户 {{ item.operateUserName }}</span>
|
||||
<span style="display:block;padding-left: 10px; font-size:13px;" v-html="item.centent" />
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDistributeRecord } from '@/api/zs/clue'
|
||||
export default {
|
||||
name: 'DistributeForm',
|
||||
model: {
|
||||
prop: 'info',
|
||||
event: 'update',
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
userOptions: [],
|
||||
offlineReceiver: [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: JSON.parse(JSON.stringify(this.info)),
|
||||
rules: {
|
||||
offlineReceiver: {
|
||||
required: true,
|
||||
message: '线下接待人员不为空',
|
||||
trigger: 'change',
|
||||
},
|
||||
},
|
||||
distributeRecord: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(val) {
|
||||
this.$emit('update', val)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.handleDistribute()
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
return this.$refs.form.validate()
|
||||
},
|
||||
handleDistribute() {
|
||||
// 甩单
|
||||
getDistributeRecord({ clueId: this.form.clueId }).then((resp) => {
|
||||
if (resp.code === 200) {
|
||||
this.distributeRecord = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
73
src/views/zs/components/filterForm.vue
Normal file
73
src/views/zs/components/filterForm.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<el-form ref="form" :model="form" :rules="rules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.myCreate" label="myCreate">我创建的</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.myValid" label="myValid">我的有效</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.valid" label="valid">有效线索</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.todayValid" label="todayValid">今日有效线索</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.todayFollow" label="todayFollow">今日跟踪</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.outtime" label="outtime">过期线索</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.relate" label="relate">相关线索</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-checkbox v-model="form.reSign" label="reSign">撞单线索</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FilterForm',
|
||||
model: {
|
||||
prop: 'info',
|
||||
event: 'update',
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
userOptions: [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: JSON.parse(JSON.stringify(this.info)),
|
||||
rules: {},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(val) {
|
||||
this.$emit('update', val)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
return this.$refs.form.validate()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
84
src/views/zs/components/publicTable.vue
Normal file
84
src/views/zs/components/publicTable.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button type="text" icon="el-icon-refresh" style="margin-bottom:10px;" @click="handleQuery">刷新</el-button>
|
||||
<el-table v-loading="loading" :data="publicList" border :row-class-name="tableRowClassName">
|
||||
<el-table-column label="创建时间" prop="consultTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.consultTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="线索来源" prop="source" width="100" />
|
||||
<el-table-column label="姓名" prop="name" width="100" />
|
||||
<el-table-column label="位置" prop="address" min-width="160" />
|
||||
<el-table-column label="意向状态" prop="intentionState" width="100" />
|
||||
<el-table-column label="备注" prop="clueMemo" min-width="150" />
|
||||
<el-table-column label="操作" fixed="right" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handlePickup(scope.row)">获取</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination :total="queryParams.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :page-sizes="[50, 100]" @pagination="getList" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getPublicList, pickupClue } from '@/api/zs/clue'
|
||||
export default {
|
||||
name: 'PublicTable',
|
||||
data() {
|
||||
return {
|
||||
publicList: [],
|
||||
loading: true,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 100,
|
||||
total: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
// this.timer = setInterval(() => {
|
||||
// this.getList()
|
||||
// }, 5000)
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true
|
||||
getPublicList(this.queryParams).then((resp) => {
|
||||
if (resp && resp.code == 200) {
|
||||
this.publicList = resp.rows
|
||||
this.loading = false
|
||||
this.queryParams.total = resp.total
|
||||
}
|
||||
})
|
||||
},
|
||||
handlePickup(item) {
|
||||
pickupClue(item).then((resp) => {
|
||||
if (resp && resp.code == 200) {
|
||||
this.$message.success('拾取成功')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
},
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
if (row.followUser2 || row.followUser) {
|
||||
return 'warning-row'
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
handleQuery() {
|
||||
this.loading = true
|
||||
this.getList()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.el-table .warning-row {
|
||||
background: oldlace;
|
||||
}
|
||||
</style>
|
||||
416
src/views/zs/components/signForm.vue
Normal file
416
src/views/zs/components/signForm.vue
Normal file
@@ -0,0 +1,416 @@
|
||||
<template>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px" :disabled="form.signId != undefined && !form.signEdit">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员姓名">
|
||||
<el-input v-model="form.name" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员联系方式">
|
||||
<el-input v-model="form.phone" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="线索来源">
|
||||
<el-select v-model="form.source" disabled>
|
||||
<el-option v-for="dict in options.sourceOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否全款" prop="state">
|
||||
<el-radio-group v-model="form.state">
|
||||
<el-radio :label="true">全款</el-radio>
|
||||
<el-radio :label="false">非全款</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="成交日期" prop="dealDate">
|
||||
<el-date-picker v-model="form.dealDate" :picker-options="dateControl" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报名价格(元)" prop="signPrice">
|
||||
<el-input v-model="form.signPrice" placeholder="学员报名时需要交纳总共的钱" @blur="priceChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报名驾校" prop="signSchool">
|
||||
<el-select v-model="form.signSchool" filterable placeholder="请选择" @change="schoolChange">
|
||||
<el-option v-for="dict in schoolOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报名场地" prop="signPlace">
|
||||
<el-select v-model="form.signPlace" filterable placeholder="请选择" @change="placeChange">
|
||||
<el-option v-for="dict in options.placeInfo.filter(item =>item.deptId === form.signSchool)" :key="dict.placeId" :label="dict.name" :value="dict.placeId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报名班型" prop="signClass">
|
||||
<el-select v-model="form.signClass" filterable placeholder="请选择" @change="priceChange">
|
||||
<el-option v-for="dict in classTypeOptions.filter(item =>((!item.placeId && item.deptId === form.signSchool) || item.placeId === form.signPlace))" :key="dict.typeId" :label="`${dict.licenseType}-${dict.typeName}`" :value="dict.typeId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="对接人" prop="schoolPeople">
|
||||
<el-input v-model="form.schoolPeople" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="驾校支付" prop="schoolPay">
|
||||
<el-input v-model="form.schoolPay" type="number" placeholder="请输入驾校支付金额" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="驾考宝典款" prop="alipay">
|
||||
<el-input v-model="form.alipay" placeholder="请输入驾考宝典款金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="额外支出" prop="extraPayType">
|
||||
<el-select v-model="form.extraPayTypes" filterable placeholder="请选择" multiple clearable>
|
||||
<el-option v-for="dict in extraPayTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="额外支出金额" prop="extraPay">
|
||||
<el-input v-model="form.extraPay" placeholder="请输入额外支出金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="归属人员" prop="followUser">
|
||||
<el-select v-model="form.followUser" multiple placeholder="请选择" clearable :disabled="true">
|
||||
<el-option v-for="dict in options.userOptions" :key="dict.id" :label="dict.name" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属区域" prop="area">
|
||||
<el-select v-model="form.area" placeholder="请选择" clearable>
|
||||
<el-option v-for="dict in areaOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="admin" :span="12">
|
||||
<el-form-item label="佣金明细" prop="commission">
|
||||
<el-select v-model="form.commission" placeholder="请选择" clearable>
|
||||
<el-option v-for="dict in commissionOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="memo">
|
||||
<el-input v-model="form.memo" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="凭据" prop="evidence">
|
||||
<el-upload action="#" class="evidence-uploader" :http-request="handleUploadFile" accept="image/*" :show-file-list="false" multiple>
|
||||
<i class="el-icon-plus evidence-uploader-icon" />
|
||||
</el-upload>
|
||||
<div v-for="(item, index) in form.fileList" :key="index" class="pr dib">
|
||||
<el-image class="image-list-item" fit="contain" :src="preUrl + item" :preview-src-list="form.fileList.map(url => preUrl + url)" lazy />
|
||||
<i class="el-icon-close btn-close" @click="handleRemoveImage(index,item)" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="checkRecord && checkRecord.length > 0">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="审核记录">
|
||||
<el-timeline style="max-height:260px;overflow-y:auto;">
|
||||
<el-timeline-item v-for="item in checkRecord" :key="item.record" :timestamp="item.operateTime" placement="top" style="padding:5px !important;">
|
||||
<el-card>
|
||||
<span style="display:block;font-weight: bold; font-size:13px;">用户 {{ item.operateUserName }}</span>
|
||||
<span style="display:block;padding-left: 10px; font-size:13px;" v-html="item.centent" />
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { validateMoney } from '@/utils/validate'
|
||||
import {
|
||||
getSchools,
|
||||
getClassTypeInfo,
|
||||
uploadEvidence,
|
||||
deleteFile,
|
||||
} from '@/api/tool/common'
|
||||
import { getCheckRecord } from '@/api/zs/sign'
|
||||
export default {
|
||||
name: 'SignForm',
|
||||
model: {
|
||||
prop: 'info',
|
||||
event: 'update',
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
userOptions: [],
|
||||
sourceOptions: [],
|
||||
placeInfo: [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
admin: JSON.parse(localStorage.getItem('admin')),
|
||||
preUrl: process.env.VUE_APP_BASE_API,
|
||||
form: JSON.parse(JSON.stringify(this.info)),
|
||||
rules: {
|
||||
area: {
|
||||
required: true,
|
||||
message: '所属区域不为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
dealDate: {
|
||||
required: true,
|
||||
message: '成交时间不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
state: {
|
||||
required: true,
|
||||
message: '是否权限必选',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
followUser: {
|
||||
required: true,
|
||||
message: '归属人员不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
signSchool: {
|
||||
required: true,
|
||||
message: '报名驾校不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
signPlace: {
|
||||
required: true,
|
||||
message: '报名场地不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
signClass: {
|
||||
required: true,
|
||||
message: '报名班型不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
dealState: {
|
||||
required: true,
|
||||
message: '结算情况不为空',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
signPrice: {
|
||||
required: true,
|
||||
validator: validateMoney,
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
schoolOptions: [],
|
||||
placeOptions: [],
|
||||
classTypeOptions: [],
|
||||
areaOptions: [],
|
||||
commissionOptions: [],
|
||||
extraPayTypeOptions: [],
|
||||
dateControl: undefined,
|
||||
checkRecord: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(val) {
|
||||
this.$emit('update', val)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.form.fileList) {
|
||||
this.$set(this.form, 'fileList', [])
|
||||
}
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
// 佣金明细
|
||||
this.getDicts('dm_commission').then((response) => {
|
||||
this.commissionOptions = response.data
|
||||
})
|
||||
// 额外支出类型
|
||||
this.getDicts('dm_extra_pay').then((response) => {
|
||||
this.extraPayTypeOptions = response.data
|
||||
})
|
||||
// 所属区域
|
||||
this.getDicts('dm_area').then((response) => {
|
||||
this.areaOptions = response.data
|
||||
})
|
||||
// 驾校
|
||||
getSchools().then((resp) => {
|
||||
this.schoolOptions = resp.data
|
||||
})
|
||||
// 班型
|
||||
getClassTypeInfo({ status: '0' }).then((resp) => {
|
||||
this.classTypeOptions = resp.data
|
||||
})
|
||||
// 审核记录
|
||||
this.form.signId &&
|
||||
getCheckRecord({
|
||||
signId: this.form.signId,
|
||||
type: 1,
|
||||
}).then((resp) => {
|
||||
this.checkRecord = resp.data
|
||||
})
|
||||
// 未登记并且非管理员,添加日期规则
|
||||
if (!this.form.signId) {
|
||||
let start = new Date()
|
||||
// 取1号
|
||||
start.setDate(1)
|
||||
// 5号之前可操作上个月,注意跨年
|
||||
if (new Date().getDate() < 5) {
|
||||
if (start.getMonth() > 0) {
|
||||
start.setMonth(start.getMonth() - 1)
|
||||
} else {
|
||||
start.setFullYear(start.getFullYear() - 1)
|
||||
start.setMonth(11)
|
||||
}
|
||||
}
|
||||
// 因为new Date()出来的时间戳,包含时分秒,判断日期时需要减一天
|
||||
start = start.getTime() - 24 * 60 * 60 * 1000
|
||||
this.dateControl = {
|
||||
disabledDate: (time) => {
|
||||
return time.getTime() < start || time.getTime() > new Date()
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
validate() {
|
||||
return this.$refs.form.validate()
|
||||
},
|
||||
// 驾校change事件
|
||||
schoolChange() {
|
||||
this.$set(this.form, 'signPlace', undefined)
|
||||
this.$set(this.form, 'signClass', undefined)
|
||||
},
|
||||
placeChange() {
|
||||
this.$set(this.form, 'signClass', undefined)
|
||||
this.$set(
|
||||
this.form,
|
||||
'schoolPeople',
|
||||
this.options.placeInfo.find(
|
||||
(item) => item.placeId === this.form.signPlace
|
||||
).contact
|
||||
)
|
||||
this.$set(
|
||||
this.form,
|
||||
'area',
|
||||
this.options.placeInfo.find(
|
||||
(item) => item.placeId === this.form.signPlace
|
||||
).area
|
||||
)
|
||||
// this.form.schoolPeople = this.options.placeInfo.find(
|
||||
// (item) => item.placeId === this.form.signPlace
|
||||
// ).contact
|
||||
},
|
||||
async handleUploadFile(data) {
|
||||
if (data.file) {
|
||||
const size = data.file.size
|
||||
const limitSize = 20 * 1024 * 1024 // 20M大小限制
|
||||
if (size < limitSize) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', data.file)
|
||||
const resp = await uploadEvidence(formData)
|
||||
if (resp.code === 200) {
|
||||
this.form.fileList.push(resp.data)
|
||||
}
|
||||
} else {
|
||||
this.msgInfo('文件过大')
|
||||
}
|
||||
}
|
||||
},
|
||||
handleRemoveImage(index, item) {
|
||||
deleteFile(item).then((resp) => {
|
||||
if (resp && resp.data)
|
||||
// 最好先通过接口删除服务器图片
|
||||
this.form.fileList.splice(index, 1)
|
||||
})
|
||||
},
|
||||
priceChange() {
|
||||
//计算驾校支付款 报名价格-班型底价
|
||||
if (this.form.signClass && this.form.signPrice) {
|
||||
let minprice
|
||||
this.classTypeOptions.some((item) => {
|
||||
if (item.typeId == this.form.signClass) {
|
||||
minprice = item.minPrice
|
||||
return item
|
||||
}
|
||||
})
|
||||
if (minprice) {
|
||||
this.$set(this.form, 'schoolPay', this.form.signPrice - minprice)
|
||||
}
|
||||
} else {
|
||||
this.$set(this.form, 'schoolPay', undefined)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.evidence-uploader {
|
||||
display: inline-block;
|
||||
.el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
.evidence-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.image-list-item {
|
||||
height: 100px;
|
||||
img {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 2px;
|
||||
font-size: 20px;
|
||||
background: #f2f6fc;
|
||||
}
|
||||
</style>
|
||||
0
src/views/zs/sign.vue
Normal file
0
src/views/zs/sign.vue
Normal file
@@ -35,20 +35,31 @@ module.exports = {
|
||||
proxy: {
|
||||
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
||||
[process.env.VUE_APP_BASE_API]: {
|
||||
// target: `http://localhost:8080`,
|
||||
target: `http://vue.ruoyi.vip/prod-api/`,
|
||||
target: `http://localhost:8086`,
|
||||
// target: `http://vue.ruoyi.vip/prod-api/`,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
},
|
||||
"/amap": {
|
||||
target: "https://restapi.amap.com",
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
pathRewrite: {
|
||||
"^/amap": ""
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
sassOptions: { outputStyle: 'expanded' }
|
||||
sassOptions: {
|
||||
outputStyle: 'expanded'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -59,6 +70,9 @@ module.exports = {
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
externals: {
|
||||
AMap: "AMap"
|
||||
},
|
||||
plugins: [
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
new CompressionPlugin({
|
||||
@@ -92,12 +106,10 @@ module.exports = {
|
||||
config
|
||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||
.after('html')
|
||||
.use('script-ext-html-webpack-plugin', [
|
||||
{
|
||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/
|
||||
}
|
||||
])
|
||||
.use('script-ext-html-webpack-plugin', [{
|
||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/
|
||||
}])
|
||||
.end();
|
||||
config.optimization.splitChunks({
|
||||
chunks: 'all',
|
||||
@@ -122,11 +134,10 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
});
|
||||
config.optimization.runtimeChunk('single'),
|
||||
{
|
||||
from: path.resolve(__dirname, './public/robots.txt'), // 防爬虫文件
|
||||
to: './' // 到根目录下
|
||||
};
|
||||
config.optimization.runtimeChunk('single'), {
|
||||
from: path.resolve(__dirname, './public/robots.txt'), // 防爬虫文件
|
||||
to: './' // 到根目录下
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user