From 2c0bc99c0397a908edfb7dd3d71fcdf9c601a060 Mon Sep 17 00:00:00 2001 From: zcxee <495141071@qq.com> Date: Sat, 7 Oct 2023 19:29:06 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=95=99=E7=BB=83=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/sch/coach.js | 51 ++++ src/api/zs/feedback.js | 51 ++++ src/views/sch/coach/components/CoachForm.vue | 135 ++++++++++ src/views/sch/coach/index.vue | 159 ++++++++++++ src/views/zs/feedback/index.vue | 253 +++++++++++++++++++ 5 files changed, 649 insertions(+) create mode 100644 src/api/sch/coach.js create mode 100644 src/api/zs/feedback.js create mode 100644 src/views/sch/coach/components/CoachForm.vue create mode 100644 src/views/sch/coach/index.vue create mode 100644 src/views/zs/feedback/index.vue diff --git a/src/api/sch/coach.js b/src/api/sch/coach.js new file mode 100644 index 0000000..ebc8c2e --- /dev/null +++ b/src/api/sch/coach.js @@ -0,0 +1,51 @@ +/* + * @Author: riverQiu + * @Date: 2023-10-07 17:14:32 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-07 18:02:01 + * @Description:教练接口 + */ +import request from '@/utils/request'; + +// 查询教练列表 +export function listCoach(query) { + return request({ + url: '/sch/coach/list', + method: 'get', + params: query + }); +} + +// 查询教练详细 +export function getCoach(coachId) { + return request({ + url: '/sch/coach/' + coachId, + method: 'get' + }); +} + +// 新增教练 +export function addCoach(data) { + return request({ + url: '/sch/coach', + method: 'post', + data: data + }); +} + +// 修改教练 +export function updateCoach(data) { + return request({ + url: '/sch/coach', + method: 'put', + data: data + }); +} + +// 删除教练 +export function delCoach(coachId) { + return request({ + url: '/sch/coach/' + coachId, + method: 'delete' + }); +} diff --git a/src/api/zs/feedback.js b/src/api/zs/feedback.js new file mode 100644 index 0000000..af7ffa7 --- /dev/null +++ b/src/api/zs/feedback.js @@ -0,0 +1,51 @@ +/* + * @Author: riverQiu + * @Date: 2023-10-07 17:14:38 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-07 17:14:44 + * @Description: 线索反馈接口 + */ +import request from '@/utils/request'; + +// 查询线索反馈列表 +export function listFeedback(query) { + return request({ + url: '/zs/feedback/list', + method: 'get', + params: query + }); +} + +// 查询线索反馈详细 +export function getFeedback(feedbackId) { + return request({ + url: '/zs/feedback/' + feedbackId, + method: 'get' + }); +} + +// 新增线索反馈 +export function addFeedback(data) { + return request({ + url: '/zs/feedback', + method: 'post', + data: data + }); +} + +// 修改线索反馈 +export function updateFeedback(data) { + return request({ + url: '/zs/feedback', + method: 'put', + data: data + }); +} + +// 删除线索反馈 +export function delFeedback(feedbackId) { + return request({ + url: '/zs/feedback/' + feedbackId, + method: 'delete' + }); +} diff --git a/src/views/sch/coach/components/CoachForm.vue b/src/views/sch/coach/components/CoachForm.vue new file mode 100644 index 0000000..c5df3b1 --- /dev/null +++ b/src/views/sch/coach/components/CoachForm.vue @@ -0,0 +1,135 @@ + +<template> + <el-dialog title="教练信息" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog"> + <div> + <el-form ref="dialogForm" :model="dialogForm" :rules="dataRule" label-position="top" @keyup.enter.native="dialogFormSubmit()"> + <el-form-item label="所属驾校" prop="schoolId"> + <el-select v-model="dialogForm.schoolId" filterable placeholder="请选择" value-key="schoolId" clearable size="small" style="width:100%"> + <el-option v-for="(dict, index) in schoolOptions" :key="index" :label="dict.schoolName" :value="dict.schoolId" /> + </el-select> + </el-form-item> + <el-form-item label="所属场地" prop="placeId"> + <el-select v-model="dialogForm.placeId" filterable placeholder="请选择" clearable value-key="placeId" size="small" style="width:100%"> + <el-option v-for="(dict, index) in placeOptions.filter(item => item.schoolId === dialogForm.schoolId)" :key="index" :label="dict.name" :value="dict.placeId" /> + </el-select> + </el-form-item> + <el-form-item label="教练名" prop="coachName"> + <el-input v-model="dialogForm.coachName" placeholder="请输入教练名" /> + </el-form-item> + <el-form-item label="联系方式" prop="phone"> + <el-input v-model="dialogForm.phone" placeholder="请输入联系方式" /> + </el-form-item> + <el-form-item label="微信openid" prop="openId"> + <el-input v-model="dialogForm.openId" placeholder="请输入微信openid" /> + </el-form-item> + </el-form> + + </div> + <span slot="footer" class="dialog-footer"> + <el-button plain @click="(visible=false)">取消</el-button> + <el-button v-jclick type="primary" :disabled="!canSubmit" @click="dialogFormSubmit()">确定</el-button> + </span> + </el-dialog> +</template> + +<script> +import { addCoach, updateCoach } from '@/api/sch/coach'; + +export default { + props: { + schoolOptions: { + type: Array, + default: [] + }, + placeOptions: { + type: Array, + default: [] + } + }, + data () { + return { + visible: false, + canSubmit: true, + dialogForm: { + coachId: null, + deptId: null, + schoolId: null, + placeId: null, + coachName: null, + phone: null, + openId: null + }, + dataRule: { + schoolId: [{ required: true, message: '所属驾校不能为空', trigger: 'blur' }], + coachName: [{ required: true, message: '教练名不能为空', trigger: 'blur' }], + phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }] + + } + }; + }, + 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 = { + coachId: null, + deptId: null, + schoolId: null, + placeId: null, + coachName: null, + phone: null, + openId: null + }; + }, + closeDialog () { + this.$emit('update:dialogVisible', false); + }, + // 表单提交 + dialogFormSubmit () { + this.$refs.dialogForm.validate((valid) => { + if (valid) { + this.canSubmit = false; + + if (this.dialogForm.coachId) { + // 校验完成,调接口 + updateCoach(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 { + addCoach(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> diff --git a/src/views/sch/coach/index.vue b/src/views/sch/coach/index.vue new file mode 100644 index 0000000..7d8d549 --- /dev/null +++ b/src/views/sch/coach/index.vue @@ -0,0 +1,159 @@ +<template> + <div class="app-container"> + <el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="68px"> + <el-form-item label="所属驾校" prop="schoolId"> + <el-select v-model="queryParams.schoolId" filterable placeholder="请选择" value-key="schoolId" clearable size="small"> + <el-option v-for="(dict, index) in schoolOptions" :key="index" :label="dict.schoolName" :value="dict.schoolId" /> + </el-select> + </el-form-item> + <el-form-item label="所属场地" prop="placeId"> + <el-select v-model="queryParams.placeId" filterable placeholder="请选择" clearable value-key="placeId" size="small"> + <el-option v-for="(dict, index) in placeOptions.filter(item => item.schoolId === queryParams.schoolId)" :key="index" :label="dict.name" :value="dict.placeId" /> + </el-select> + </el-form-item> + <el-form-item label="教练名" prop="coachName"> + <el-input v-model="queryParams.coachName" placeholder="请输入教练名" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="联系方式" prop="phone"> + <el-input v-model="queryParams.phone" placeholder="请输入联系方式" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button v-hasPermi="['sch:coach:add']" type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddAndUpdate(undefined)">新增</el-button> + </el-col> + <right-toolbar :show-search.sync="showSearch" @queryTable="getList" /> + </el-row> + + <el-table v-loading="loading" :data="coachList"> + <el-table-column type="index" width="55" align="center" /> + <el-table-column label="所属驾校" align="center" prop="schoolName" /> + <el-table-column label="所属场地" align="center" prop="placeName" /> + <el-table-column label="教练名" align="center" prop="coachName" /> + <el-table-column label="联系方式" align="center" prop="phone" /> + <el-table-column label="微信openid" align="center" prop="openId" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button v-hasPermi="['sch:coach:edit']" size="mini" type="text" icon="el-icon-edit" @click="handleAddAndUpdate(scope.row)">修改</el-button> + <el-button v-hasPermi="['sch:coach:remove']" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(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" /> + + <!-- 添加或修改教练对话框 --> + <coach-form v-if="dialogVisible" ref="dialogForm" :dialog-visible="dialogVisible" :school-options="schoolOptions" :place-options="placeOptions" @refreshDataList="getList" /> + </div> +</template> + +<script> +import { listCoach, getCoach, delCoach } from '@/api/sch/coach'; +import CoachForm from './components/CoachForm.vue'; +import schoolAPi from '@/api/sch/school'; +import { getAllPlaces } from '@/api/sch/place'; + +export default { + name: 'Coach', + components: { CoachForm }, + data () { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 教练表格数据 + coachList: [], + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + schoolId: null, + placeId: null, + coachName: null, + phone: null + }, + dialogVisible: false, + schoolOptions: [], + placeOptions: [] + }; + }, + created () { + this.getSchools(); + this.getPlaces(); + this.getList(); + }, + methods: { + /** 查询教练列表 */ + getList () { + this.loading = true; + listCoach(this.queryParams).then(response => { + this.coachList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel () { + this.open = false; + this.reset(); + }, + /** 搜索按钮操作 */ + handleQuery () { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery () { + this.resetForm('queryForm'); + this.handleQuery(); + }, + /** 新增或修改按钮操作 */ + handleAddAndUpdate (item) { + this.dialogVisible = true; + this.$nextTick(() => { + this.$refs.dialogForm.init(item); + }); + }, + /** 删除按钮操作 */ + handleDelete (row) { + const coachIds = row.coachId || this.ids; + this.$modal.confirm('是否确认删除教练编号为"' + coachIds + '"的数据项?').then(function () { + return delCoach(coachIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess('删除成功'); + }).catch(() => { }); + }, + /** 导出按钮操作 */ + handleExport () { + this.download('system/coach/export', { + ...this.queryParams + }, `coach_${new Date().getTime()}.xlsx`); + }, + getSchools () { + schoolAPi.allList().then((resp) => { + this.schoolOptions = resp.data; + }); + }, + getPlaces () { + getAllPlaces({ status: '0', showInMap: true }).then((resp) => { + this.placeOptions = resp.data; + }); + } + } +}; +</script> diff --git a/src/views/zs/feedback/index.vue b/src/views/zs/feedback/index.vue new file mode 100644 index 0000000..4a9c813 --- /dev/null +++ b/src/views/zs/feedback/index.vue @@ -0,0 +1,253 @@ +<template> + <div class="app-container"> + <el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="68px"> + <el-form-item label="线索id" prop="clueId"> + <el-input v-model="queryParams.clueId" placeholder="请输入线索id" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="教练id" prop="coachId"> + <el-input v-model="queryParams.coachId" placeholder="请输入教练id" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="反馈时间" prop="feedbackTime"> + <el-date-picker v-model="queryParams.feedbackTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择反馈时间" /> + </el-form-item> + <el-form-item label="是否联系" prop="isContact"> + <el-input v-model="queryParams.isContact" placeholder="请输入是否联系" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="到场时间" prop="arrivalTime"> + <el-date-picker v-model="queryParams.arrivalTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择到场时间" /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button v-hasPermi="['system:feedback:add']" type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button> + </el-col> + <el-col :span="1.5"> + <el-button v-hasPermi="['system:feedback:edit']" type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate">修改</el-button> + </el-col> + <el-col :span="1.5"> + <el-button v-hasPermi="['system:feedback:remove']" type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button> + </el-col> + <el-col :span="1.5"> + <el-button v-hasPermi="['system:feedback:export']" type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button> + </el-col> + <right-toolbar :show-search.sync="showSearch" @queryTable="getList" /> + </el-row> + + <el-table v-loading="loading" :data="feedbackList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="${comment}" align="center" prop="feedbackId" /> + <el-table-column label="线索id" align="center" prop="clueId" /> + <el-table-column label="反馈类型 1 跟进反馈 2 到场负反馈" align="center" prop="feedbackType" /> + <el-table-column label="教练id" align="center" prop="coachId" /> + <el-table-column label="反馈内容" align="center" prop="content" /> + <el-table-column label="反馈时间" align="center" prop="feedbackTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.feedbackTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="是否联系" align="center" prop="isContact" /> + <el-table-column label="到场时间" align="center" prop="arrivalTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.arrivalTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="到场状态" align="center" prop="arrivalStatus" /> + <el-table-column label="备注" align="center" prop="remark" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button v-hasPermi="['system:feedback:edit']" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button> + <el-button v-hasPermi="['system:feedback:remove']" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(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-dialog :title="title" :visible.sync="open" width="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="线索id" prop="clueId"> + <el-input v-model="form.clueId" placeholder="请输入线索id" /> + </el-form-item> + <el-form-item label="教练id" prop="coachId"> + <el-input v-model="form.coachId" placeholder="请输入教练id" /> + </el-form-item> + <el-form-item label="反馈内容"> + <editor v-model="form.content" :min-height="192" /> + </el-form-item> + <el-form-item label="反馈时间" prop="feedbackTime"> + <el-date-picker v-model="form.feedbackTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择反馈时间" /> + </el-form-item> + <el-form-item label="是否联系" prop="isContact"> + <el-input v-model="form.isContact" placeholder="请输入是否联系" /> + </el-form-item> + <el-form-item label="到场时间" prop="arrivalTime"> + <el-date-picker v-model="form.arrivalTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择到场时间" /> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> + </el-form-item> + </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 { listFeedback, getFeedback, delFeedback, addFeedback, updateFeedback } from '@/api/zs/feedback'; + +export default { + name: 'Feedback', + data () { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 线索反馈表格数据 + feedbackList: [], + // 弹出层标题 + title: '', + // 是否显示弹出层 + open: false, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + clueId: null, + feedbackType: null, + coachId: null, + content: null, + feedbackTime: null, + isContact: null, + arrivalTime: null, + arrivalStatus: null + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + } + }; + }, + created () { + this.getList(); + }, + methods: { + /** 查询线索反馈列表 */ + getList () { + this.loading = true; + listFeedback(this.queryParams).then(response => { + this.feedbackList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel () { + this.open = false; + this.reset(); + }, + // 表单重置 + reset () { + this.form = { + feedbackId: null, + clueId: null, + feedbackType: null, + coachId: null, + content: null, + feedbackTime: null, + isContact: null, + arrivalTime: null, + arrivalStatus: 0, + remark: null + }; + this.resetForm('form'); + }, + /** 搜索按钮操作 */ + handleQuery () { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery () { + this.resetForm('queryForm'); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange (selection) { + this.ids = selection.map(item => item.feedbackId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 新增按钮操作 */ + handleAdd () { + this.reset(); + this.open = true; + this.title = '添加线索反馈'; + }, + /** 修改按钮操作 */ + handleUpdate (row) { + this.reset(); + const feedbackId = row.feedbackId || this.ids; + getFeedback(feedbackId).then(response => { + this.form = response.data; + this.open = true; + this.title = '修改线索反馈'; + }); + }, + /** 提交按钮 */ + submitForm () { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.feedbackId != null) { + updateFeedback(this.form).then(response => { + this.$modal.msgSuccess('修改成功'); + this.open = false; + this.getList(); + }); + } else { + addFeedback(this.form).then(response => { + this.$modal.msgSuccess('新增成功'); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 删除按钮操作 */ + handleDelete (row) { + const feedbackIds = row.feedbackId || this.ids; + this.$modal.confirm('是否确认删除线索反馈编号为"' + feedbackIds + '"的数据项?').then(function () { + return delFeedback(feedbackIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess('删除成功'); + }).catch(() => { }); + }, + /** 导出按钮操作 */ + handleExport () { + this.download('system/feedback/export', { + ...this.queryParams + }, `feedback_${new Date().getTime()}.xlsx`); + } + } +}; +</script> From 6c71bccd83d95441e069a93c86d97abe9ee6fb9f Mon Sep 17 00:00:00 2001 From: zcxee <495141071@qq.com> Date: Mon, 9 Oct 2023 19:47:09 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=88=86=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/permission.js | 2 +- src/router/index.js | 5 + src/views/question/index.vue | 14 +- .../components/DistributeFormDialog copy.vue | 116 +++++++++++ .../clue/components/DistributeFormDialog.vue | 67 ++++--- src/views/zs/feedback/first.vue | 180 ++++++++++++++++++ src/views/zs/feedback/index.vue | 2 +- 7 files changed, 342 insertions(+), 44 deletions(-) create mode 100644 src/views/zs/clue/components/DistributeFormDialog copy.vue create mode 100644 src/views/zs/feedback/first.vue diff --git a/src/permission.js b/src/permission.js index 1841aea..6bfb0f6 100644 --- a/src/permission.js +++ b/src/permission.js @@ -16,7 +16,7 @@ NProgress.configure({ showSpinner: false }); -const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/question']; +const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/question', '/clue/feedback']; router.beforeEach((to, from, next) => { NProgress.start(); diff --git a/src/router/index.js b/src/router/index.js index df2777f..beb6e9f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -53,6 +53,11 @@ export const constantRoutes = [{ component: () => import('@/views/question'), hidden: true }, +{ + path: '/clue/feedback', + component: () => import('@/views/zs/feedback/first'), + hidden: true +}, { path: '/404', component: () => import('@/views/error/404'), diff --git a/src/views/question/index.vue b/src/views/question/index.vue index 1f423fb..2b141e9 100644 --- a/src/views/question/index.vue +++ b/src/views/question/index.vue @@ -81,7 +81,7 @@ export default { components: { QuestionForm, QuestionAddForm }, - data() { + data () { return { // 遮罩层 loading: false, @@ -98,12 +98,12 @@ export default { dialogAddVisible: false }; }, - created() { + created () { // this.getList(); }, methods: { /** 查询文件列表 */ - getList() { + getList () { this.loading = true; searchQuestion(this.queryParams).then(response => { this.tableList = response.data; @@ -113,7 +113,7 @@ export default { }, /** 搜索按钮操作 */ - handleQuery() { + handleQuery () { if (this.queryParams.question) { this.getList(); } else { @@ -121,17 +121,17 @@ export default { } }, /** 重置按钮操作 */ - resetQuery() { + resetQuery () { this.queryParams.question = ''; this.handleQuery(); }, - handleEdit(item) { + handleEdit (item) { this.dialogVisible = true; this.$nextTick(() => { this.$refs.dialogForm.init(item); }); }, - handleAdd(item) { + handleAdd (item) { this.dialogAddVisible = true; this.$nextTick(() => { this.$refs.dialogAddForm.init(item); diff --git a/src/views/zs/clue/components/DistributeFormDialog copy.vue b/src/views/zs/clue/components/DistributeFormDialog copy.vue new file mode 100644 index 0000000..095c588 --- /dev/null +++ b/src/views/zs/clue/components/DistributeFormDialog copy.vue @@ -0,0 +1,116 @@ +<template> + <el-dialog title="分发" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog"> + <el-form ref="dialogForm" :model="dialogForm" :rules="rules" label-width="110px"> + <el-row> + <el-col :span="24"> + <el-form-item label="场地" prop="newPlaceList"> + <span v-if="oldForm.placeNames">{{oldForm.placeNames}}</span> + + <el-select v-model="dialogForm.newPlaceList" filterable multiple placeholder="请选择" clearable style="width: 100%;"> + <el-option v-for="dict in placeOptions" :key="dict.placeId" :label="dict.name" :value="dict.placeId" /> + </el-select> + </el-form-item> + </el-col> + </el-row> + </el-form> + <span slot="footer" class="dialog-footer"> + <el-button plain @click="(visible = false)">取消</el-button> + <el-button v-jclick type="primary" :disabled="!canSubmit" @click="dialogFormSubmit()">确定</el-button> + </span> + </el-dialog> +</template> + <script> +import { getCluePlaceList, saveCluePlace } from '@/api/zs/clue'; +import { getAllPlaces } from '@/api/sch/place'; + +export default { + name: 'DistributeFormDialog', + + data() { + return { + visible: false, + canSubmit: true, + dialogForm: {}, + oldForm: {}, + rules: { + newPlaceList: { + required: true, + message: '场地不能为空不能为空', + trigger: 'blur' + } + }, + placeOptions: [] + }; + }, + methods: { + init(info = undefined) { + this.getPlaces() + this.visible = true; + this.$nextTick(() => { + this.resetDialogForm(); + this.$refs['dialogForm'].resetFields(); + if (info) { + + this.dialogForm.clueId = info; + //查询该线索的分发情况 + this.getDistributePlaces(info); + } + }); + }, + resetDialogForm() { + this.dialogForm = { + oldPlaceList: [], + newPlaceList: [], + placeIdList: [], + clueId: undefined + }; + this.oldForm = {} + }, + closeDialog() { + this.$emit('update:dialog.batchUpdateVisible', false); + }, + getDistributePlaces(clueId) { + getCluePlaceList({ clueId: clueId }).then(resp => { + if (resp.code == 200) { + this.oldForm = resp.data + this.dialogForm.oldPlaceList = this.oldForm.placeIdList; + if (this.oldForm.placeIdList && this.oldForm.placeIdList) { + this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1) + } + } + + }) + }, + // 表单提交 + dialogFormSubmit() { + this.$refs.dialogForm.validate((valid) => { + if (valid) { + this.canSubmit = false; + this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList) + // 校验完成,调接口 + saveCluePlace(this.dialogForm) + .then((resp) => { + this.canSubmit = true; + if (resp.code == 200) { + this.$message.success('分发成功'); + this.$emit('refreshDataList'); + this.visible = false; + } + }) + .catch(() => { + this.canSubmit = true; + }); + } + }); + }, + getPlaces() { + getAllPlaces({ status: '0' }).then((resp) => { + this.placeOptions = resp.data; + + }); + }, + } +}; + </script> + + \ No newline at end of file diff --git a/src/views/zs/clue/components/DistributeFormDialog.vue b/src/views/zs/clue/components/DistributeFormDialog.vue index 095c588..61781b4 100644 --- a/src/views/zs/clue/components/DistributeFormDialog.vue +++ b/src/views/zs/clue/components/DistributeFormDialog.vue @@ -3,14 +3,19 @@ <el-form ref="dialogForm" :model="dialogForm" :rules="rules" label-width="110px"> <el-row> <el-col :span="24"> - <el-form-item label="场地" prop="newPlaceList"> - <span v-if="oldForm.placeNames">{{oldForm.placeNames}}</span> - - <el-select v-model="dialogForm.newPlaceList" filterable multiple placeholder="请选择" clearable style="width: 100%;"> + <el-form-item label="场地" prop="placeId"> + <el-select v-model="dialogForm.placeId" filterable placeholder="请选择" clearable style="width: 100%;"> <el-option v-for="dict in placeOptions" :key="dict.placeId" :label="dict.name" :value="dict.placeId" /> </el-select> </el-form-item> </el-col> + <el-col :span="24"> + <el-form-item label="教练" prop="coachId"> + <el-select v-model="dialogForm.coachId" filterable placeholder="请选择" clearable style="width: 100%;"> + <el-option v-for="dict in coachOptions" :key="dict.coachId" :label="dict.coachName" :value="dict.coachId" /> + </el-select> + </el-form-item> + </el-col> </el-row> </el-form> <span slot="footer" class="dialog-footer"> @@ -19,74 +24,68 @@ </span> </el-dialog> </template> - <script> +<script> import { getCluePlaceList, saveCluePlace } from '@/api/zs/clue'; import { getAllPlaces } from '@/api/sch/place'; export default { name: 'DistributeFormDialog', - data() { + data () { return { visible: false, canSubmit: true, dialogForm: {}, oldForm: {}, rules: { - newPlaceList: { - required: true, - message: '场地不能为空不能为空', - trigger: 'blur' - } + placeId: { required: true, message: '场地不能为空', trigger: 'blur, change' }, + coachId: { required: true, message: '教练不能为空', trigger: 'blur, change' } }, placeOptions: [] }; }, methods: { - init(info = undefined) { - this.getPlaces() + init (info = undefined) { + this.getPlaces(); this.visible = true; this.$nextTick(() => { this.resetDialogForm(); this.$refs['dialogForm'].resetFields(); if (info) { - this.dialogForm.clueId = info; - //查询该线索的分发情况 + // 查询该线索的分发情况 this.getDistributePlaces(info); } }); }, - resetDialogForm() { + resetDialogForm () { this.dialogForm = { - oldPlaceList: [], - newPlaceList: [], - placeIdList: [], - clueId: undefined + placeId: undefined, + clueId: undefined, + coachId: undefined }; - this.oldForm = {} + this.oldForm = {}; }, - closeDialog() { + closeDialog () { this.$emit('update:dialog.batchUpdateVisible', false); }, - getDistributePlaces(clueId) { + getDistributePlaces (clueId) { getCluePlaceList({ clueId: clueId }).then(resp => { if (resp.code == 200) { - this.oldForm = resp.data + this.oldForm = resp.data; this.dialogForm.oldPlaceList = this.oldForm.placeIdList; if (this.oldForm.placeIdList && this.oldForm.placeIdList) { - this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1) + this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1); } } - - }) + }); }, // 表单提交 - dialogFormSubmit() { + dialogFormSubmit () { this.$refs.dialogForm.validate((valid) => { if (valid) { this.canSubmit = false; - this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList) + this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList); // 校验完成,调接口 saveCluePlace(this.dialogForm) .then((resp) => { @@ -103,14 +102,12 @@ export default { } }); }, - getPlaces() { + getPlaces () { getAllPlaces({ status: '0' }).then((resp) => { this.placeOptions = resp.data; - }); - }, + } } }; - </script> - - \ No newline at end of file +</script> + diff --git a/src/views/zs/feedback/first.vue b/src/views/zs/feedback/first.vue new file mode 100644 index 0000000..439d47b --- /dev/null +++ b/src/views/zs/feedback/first.vue @@ -0,0 +1,180 @@ +<template> + <div class="app-container" style="width:90%;margin:auto;"> + <!-- 添加或修改线索反馈对话框 --> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="学员姓名" prop="clueId"> + <el-input v-model="form.clueId" placeholder="请输入线索id" /> + </el-form-item> + <el-form-item label="联系方式" prop="clueId"> + <el-input v-model="form.clueId" placeholder="请输入线索id" /> + </el-form-item> + <el-form-item label="教练id" prop="coachId"> + <el-input v-model="form.coachId" placeholder="请输入教练id" /> + </el-form-item> + <el-form-item label="是否联系" prop="isContact"> + <el-input v-model="form.isContact" placeholder="请输入是否联系" /> + </el-form-item> + <el-form-item label="到场时间" prop="arrivalTime"> + <el-date-picker v-model="form.arrivalTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择到场时间" /> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">确 定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </div> +</template> + +<script> +import { addFeedback, updateFeedback } from '@/api/zs/feedback'; + +export default { + name: 'First', + data () { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 线索反馈表格数据 + feedbackList: [], + // 弹出层标题 + title: '', + // 是否显示弹出层 + open: false, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + clueId: null, + feedbackType: null, + coachId: null, + content: null, + feedbackTime: null, + isContact: null, + arrivalTime: null, + arrivalStatus: null + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + } + }; + }, + created () { + this.getList(); + }, + methods: { + /** 查询线索反馈列表 */ + getList () { + this.loading = true; + listFeedback(this.queryParams).then(response => { + this.feedbackList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel () { + this.open = false; + this.reset(); + }, + // 表单重置 + reset () { + this.form = { + feedbackId: null, + clueId: null, + feedbackType: null, + coachId: null, + content: null, + feedbackTime: null, + isContact: null, + arrivalTime: null, + arrivalStatus: 0, + remark: null + }; + this.resetForm('form'); + }, + /** 搜索按钮操作 */ + handleQuery () { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery () { + this.resetForm('queryForm'); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange (selection) { + this.ids = selection.map(item => item.feedbackId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 新增按钮操作 */ + handleAdd () { + this.reset(); + this.open = true; + this.title = '添加线索反馈'; + }, + /** 修改按钮操作 */ + handleUpdate (row) { + this.reset(); + const feedbackId = row.feedbackId || this.ids; + getFeedback(feedbackId).then(response => { + this.form = response.data; + this.open = true; + this.title = '修改线索反馈'; + }); + }, + /** 提交按钮 */ + submitForm () { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.feedbackId != null) { + updateFeedback(this.form).then(response => { + this.$modal.msgSuccess('修改成功'); + this.open = false; + this.getList(); + }); + } else { + addFeedback(this.form).then(response => { + this.$modal.msgSuccess('新增成功'); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 删除按钮操作 */ + handleDelete (row) { + const feedbackIds = row.feedbackId || this.ids; + this.$modal.confirm('是否确认删除线索反馈编号为"' + feedbackIds + '"的数据项?').then(function () { + return delFeedback(feedbackIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess('删除成功'); + }).catch(() => { }); + }, + /** 导出按钮操作 */ + handleExport () { + this.download('system/feedback/export', { + ...this.queryParams + }, `feedback_${new Date().getTime()}.xlsx`); + } + } +}; +</script> diff --git a/src/views/zs/feedback/index.vue b/src/views/zs/feedback/index.vue index 4a9c813..4086e65 100644 --- a/src/views/zs/feedback/index.vue +++ b/src/views/zs/feedback/index.vue @@ -48,7 +48,7 @@ <el-table-column label="反馈时间" align="center" prop="feedbackTime" width="180"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.feedbackTime, '{y}-{m}-{d}') }}</span> - </template> + </template>00000000000000000000000 </el-table-column> <el-table-column label="是否联系" align="center" prop="isContact" /> <el-table-column label="到场时间" align="center" prop="arrivalTime" width="180"> From d41a186e22761146932e7ddf66e4832fe9a29756 Mon Sep 17 00:00:00 2001 From: zcxee <495141071@qq.com> Date: Mon, 16 Oct 2023 08:58:30 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/sch/coach.js | 10 +- src/api/system/skill.js | 59 ++++ src/api/zs/feedbackDetail.js | 74 +++++ src/api/zs/feedbackOrder.js | 59 ++++ src/permission.js | 9 +- src/router/index.js | 9 +- src/views/sch/coach/components/CoachForm.vue | 5 +- src/views/sch/coach/index.vue | 6 +- src/views/system/employee/index.vue | 45 +-- src/views/system/skill/index.vue | 193 +++++++++++++ src/views/zs/clue/ClueForm/index.vue | 153 +++++----- src/views/zs/clue/columns.js | 268 +++++++++--------- .../components/DistributeFormDialog copy.vue | 42 ++- .../clue/components/DistributeFormDialog.vue | 97 +++++-- src/views/zs/clue/components/SkillDialog.vue | 70 +++++ src/views/zs/clue/index.vue | 110 ++++--- src/views/zs/feedback/arrival.vue | 122 ++++++++ src/views/zs/feedback/first.vue | 180 ------------ src/views/zs/feedback/follow.vue | 126 ++++++++ 19 files changed, 1132 insertions(+), 505 deletions(-) create mode 100644 src/api/system/skill.js create mode 100644 src/api/zs/feedbackDetail.js create mode 100644 src/api/zs/feedbackOrder.js create mode 100644 src/views/system/skill/index.vue create mode 100644 src/views/zs/clue/components/SkillDialog.vue create mode 100644 src/views/zs/feedback/arrival.vue delete mode 100644 src/views/zs/feedback/first.vue create mode 100644 src/views/zs/feedback/follow.vue diff --git a/src/api/sch/coach.js b/src/api/sch/coach.js index ebc8c2e..be32fc0 100644 --- a/src/api/sch/coach.js +++ b/src/api/sch/coach.js @@ -2,7 +2,7 @@ * @Author: riverQiu * @Date: 2023-10-07 17:14:32 * @LastEditors: riverQiu - * @LastEditTime: 2023-10-07 18:02:01 + * @LastEditTime: 2023-10-10 17:00:57 * @Description:教练接口 */ import request from '@/utils/request'; @@ -49,3 +49,11 @@ export function delCoach(coachId) { method: 'delete' }); } + +export function getAllCoaches(query){ + return request({ + url: '/sch/coach/all', + method: 'get', + params: query + }); +} diff --git a/src/api/system/skill.js b/src/api/system/skill.js new file mode 100644 index 0000000..edb38a8 --- /dev/null +++ b/src/api/system/skill.js @@ -0,0 +1,59 @@ +/* + * @Author: riverQiu + * @Date: 2023-10-14 00:31:37 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-15 00:37:52 + * @Description: + */ +import request from '@/utils/request' + +// 查询关键话术列表 +export function listSkill(query) { + return request({ + url: '/system/skill/list', + method: 'get', + params: query + }) +} + +// 查询关键话术详细 +export function getSkill(skillId) { + return request({ + url: '/system/skill/' + skillId, + method: 'get' + }) +} + + +export function getSkillKey() { + return request({ + url: '/system/skill/key', + method: 'get' + }) +} + +// 新增关键话术 +export function addSkill(data) { + return request({ + url: '/system/skill', + method: 'post', + data: data + }) +} + +// 修改关键话术 +export function updateSkill(data) { + return request({ + url: '/system/skill', + method: 'put', + data: data + }) +} + +// 删除关键话术 +export function delSkill(skillId) { + return request({ + url: '/system/skill/' + skillId, + method: 'delete' + }) +} diff --git a/src/api/zs/feedbackDetail.js b/src/api/zs/feedbackDetail.js new file mode 100644 index 0000000..1d3ac59 --- /dev/null +++ b/src/api/zs/feedbackDetail.js @@ -0,0 +1,74 @@ +/* + * @Author: riverQiu + * @Date: 2023-10-11 20:48:02 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-11 20:57:06 + * @Description: + */ +/* + * @Author: riverQiu + * @Date: 2023-10-10 16:08:39 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-10 16:10:06 + * @Description: 反馈单 + */ +import request from '@/utils/request'; + +// 查询线索反馈列表 +export function listFeedbackDetail(query) { + return request({ + url: '/zs/feedback/detail/list', + method: 'get', + params: query + }); +} + +// 查询线索反馈详细 +export function getFeedbackDetail(feedbackId) { + return request({ + url: '/zs/feedback/detail/' + feedbackId, + method: 'get' + }); +} + +export function getFeedbackDetailInfo(query){ + return request({ + url: '/zs/feedback/detail/info', + method: 'get', + params: query + }); +} + +// 查询线索反馈详细 +export function getFeedbackDetailByClueId(clueId) { + return request({ + url: '/zs/feedback/detail/' + clueId, + method: 'get' + }); +} + +// 新增线索反馈 +export function addFeedbackDetail(data) { + return request({ + url: '/zs/feedback/detail', + method: 'post', + data: data + }); +} + +// 修改线索反馈 +export function updateFeedbackDetail(data) { + return request({ + url: '/zs/feedback/detail', + method: 'put', + data: data + }); +} + +// 删除线索反馈 +export function delFeedbackDetail(feedbackId) { + return request({ + url: '/zs/feedback/detail/' + feedbackId, + method: 'delete' + }); +} diff --git a/src/api/zs/feedbackOrder.js b/src/api/zs/feedbackOrder.js new file mode 100644 index 0000000..2e2073c --- /dev/null +++ b/src/api/zs/feedbackOrder.js @@ -0,0 +1,59 @@ +/* + * @Author: riverQiu + * @Date: 2023-10-10 16:08:39 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-10 16:10:06 + * @Description: 反馈单 + */ +import request from '@/utils/request'; + +// 查询线索反馈列表 +export function listFeedbackOrder(query) { + return request({ + url: '/zs/feedback/order/list', + method: 'get', + params: query + }); +} + +// 查询线索反馈详细 +export function getFeedbackOrder(feedbackId) { + return request({ + url: '/zs/feedback/order/' + feedbackId, + method: 'get' + }); +} + +// 查询线索反馈详细 +export function getFeedbackOrderByClueId(clueId) { + return request({ + url: '/zs/feedback/order/' + clueId, + method: 'get' + }); +} + +// 新增线索反馈 +export function addFeedbackOrder(data) { + return request({ + url: '/zs/feedback/order', + method: 'post', + data: data + }); +} + +// 修改线索反馈 +export function updateFeedbackOrder(data) { + return request({ + url: '/zs/feedback/order', + method: 'put', + data: data + }); +} + +// 删除线索反馈 +export function delFeedbackOrder(feedbackId) { + return request({ + url: '/zs/feedback/order/' + feedbackId, + method: 'delete' + }); +} diff --git a/src/permission.js b/src/permission.js index 6bfb0f6..b14dc3e 100644 --- a/src/permission.js +++ b/src/permission.js @@ -1,3 +1,10 @@ +/* + * @Author: riverQiu + * @Date: 2023-08-16 22:04:23 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-11 22:17:43 + * @Description: + */ import router from './router'; import store from './store'; import { @@ -16,7 +23,7 @@ NProgress.configure({ showSpinner: false }); -const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/question', '/clue/feedback']; +const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/question', '/clue/feedback/follow', '/clue/feedback/arrival']; router.beforeEach((to, from, next) => { NProgress.start(); diff --git a/src/router/index.js b/src/router/index.js index beb6e9f..b143427 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -54,8 +54,13 @@ export const constantRoutes = [{ hidden: true }, { - path: '/clue/feedback', - component: () => import('@/views/zs/feedback/first'), + path: '/clue/feedback/follow', + component: () => import('@/views/zs/feedback/follow'), + hidden: true +}, +{ + path: '/clue/feedback/arrival', + component: () => import('@/views/zs/feedback/arrival'), hidden: true }, { diff --git a/src/views/sch/coach/components/CoachForm.vue b/src/views/sch/coach/components/CoachForm.vue index c5df3b1..cb2c854 100644 --- a/src/views/sch/coach/components/CoachForm.vue +++ b/src/views/sch/coach/components/CoachForm.vue @@ -1,6 +1,6 @@ <template> - <el-dialog title="教练信息" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog"> + <el-dialog title="接待人信息" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog"> <div> <el-form ref="dialogForm" :model="dialogForm" :rules="dataRule" label-position="top" @keyup.enter.native="dialogFormSubmit()"> <el-form-item label="所属驾校" prop="schoolId"> @@ -13,7 +13,7 @@ <el-option v-for="(dict, index) in placeOptions.filter(item => item.schoolId === dialogForm.schoolId)" :key="index" :label="dict.name" :value="dict.placeId" /> </el-select> </el-form-item> - <el-form-item label="教练名" prop="coachName"> + <el-form-item label="接待人" prop="coachName"> <el-input v-model="dialogForm.coachName" placeholder="请输入教练名" /> </el-form-item> <el-form-item label="联系方式" prop="phone"> @@ -61,6 +61,7 @@ export default { }, dataRule: { schoolId: [{ required: true, message: '所属驾校不能为空', trigger: 'blur' }], + placeId: [{ required: true, message: '场地不能为空', trigger: 'blur' }], coachName: [{ required: true, message: '教练名不能为空', trigger: 'blur' }], phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }] diff --git a/src/views/sch/coach/index.vue b/src/views/sch/coach/index.vue index 7d8d549..8d6b8e5 100644 --- a/src/views/sch/coach/index.vue +++ b/src/views/sch/coach/index.vue @@ -11,8 +11,8 @@ <el-option v-for="(dict, index) in placeOptions.filter(item => item.schoolId === queryParams.schoolId)" :key="index" :label="dict.name" :value="dict.placeId" /> </el-select> </el-form-item> - <el-form-item label="教练名" prop="coachName"> - <el-input v-model="queryParams.coachName" placeholder="请输入教练名" clearable @keyup.enter.native="handleQuery" /> + <el-form-item label="接待人" prop="coachName"> + <el-input v-model="queryParams.coachName" placeholder="请输入" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="联系方式" prop="phone"> <el-input v-model="queryParams.phone" placeholder="请输入联系方式" clearable @keyup.enter.native="handleQuery" /> @@ -34,7 +34,7 @@ <el-table-column type="index" width="55" align="center" /> <el-table-column label="所属驾校" align="center" prop="schoolName" /> <el-table-column label="所属场地" align="center" prop="placeName" /> - <el-table-column label="教练名" align="center" prop="coachName" /> + <el-table-column label="接待人" align="center" prop="coachName" /> <el-table-column label="联系方式" align="center" prop="phone" /> <el-table-column label="微信openid" align="center" prop="openId" /> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> diff --git a/src/views/system/employee/index.vue b/src/views/system/employee/index.vue index 7d17bda..fa26eff 100644 --- a/src/views/system/employee/index.vue +++ b/src/views/system/employee/index.vue @@ -158,6 +158,11 @@ </el-select> </el-form-item> </el-col> + <el-col :span="12"> + <el-form-item label="微信openId" prop="openId"> + <el-input v-model="form.openId" placeholder="请输入" /> + </el-form-item> + </el-col> </el-row> <!-- <el-col :span="12"> @@ -205,7 +210,7 @@ import editor from '@/components/Editor'; export default { name: 'Employee', components: { Treeselect, editor }, - data() { + data () { return { // 遮罩层 loading: true, @@ -287,11 +292,11 @@ export default { }, watch: { // 根据名称筛选部门树 - deptName(val) { + deptName (val) { this.$refs.tree.filter(val); } }, - created() { + created () { this.getList(); this.getDeptTree(); this._getRoleOptions(); @@ -323,7 +328,7 @@ export default { }, methods: { /** 查询用户列表 */ - getList() { + getList () { this.loading = true; empAPi.pageList(this.queryParams).then((response) => { this.userList = response.rows; @@ -331,29 +336,29 @@ export default { this.loading = false; }); }, - _getRoleOptions() { + _getRoleOptions () { getRoleOptions().then((resp) => { this.roleOptions = resp.data; }); }, /** 查询部门下拉树结构 */ - getDeptTree() { + getDeptTree () { deptTreeSelect().then((response) => { this.deptOptions = response.data; }); }, // 筛选节点 - filterNode(value, data) { + filterNode (value, data) { if (!value) return true; return data.label.indexOf(value) !== -1; }, // 节点单击事件 - handleNodeClick(data) { + handleNodeClick (data) { this.queryParams.orgId = data.id; this.getList(); }, // 用户状态修改 - handleStatusChange(row) { + handleStatusChange (row) { const text = row.status === '0' ? '启用' : '停用'; this.$confirm('确认要"' + text + '""' + row.userName + '"用户吗?', '警告', { confirmButtonText: '确定', @@ -375,12 +380,12 @@ export default { }); }, // 取消按钮 - cancel() { + cancel () { this.open = false; this.reset(); }, // 表单重置 - reset() { + reset () { this.form = { orgId: undefined, employeeName: undefined, @@ -402,24 +407,24 @@ export default { this.resetForm('form'); }, /** 搜索按钮操作 */ - handleQuery() { + handleQuery () { this.queryParams.page = 1; this.getList(); }, /** 重置按钮操作 */ - resetQuery() { + resetQuery () { this.resetForm('queryForm'); this.handleQuery(); }, /** 新增按钮操作 */ - handleAdd() { + handleAdd () { this.reset(); this.getDeptTree(); this.open = true; this.title = '添加员工'; }, /** 修改按钮操作 */ - handleUpdate(row) { + handleUpdate (row) { this.reset(); this.getDeptTree(); this.form = Object.assign({}, row); @@ -427,7 +432,7 @@ export default { this.title = '修改员工'; }, /** 重置密码按钮操作 */ - handleReset(row) { + handleReset (row) { resetUserPwd({ employeeId: row.employeeId }).then((response) => { if (response.code === 200) { this.msgSuccess('重置密码成功!'); @@ -435,7 +440,7 @@ export default { }); }, /** 提交按钮 */ - submitForm() { + submitForm () { this.$refs['form'].validate((valid) => { if (valid) { this.$set(this.form, 'deptId', this.$store.getters.schoolId); @@ -459,7 +464,7 @@ export default { } }); }, - handleLogoff(row) { + handleLogoff (row) { this.$confirm('注销后将立即释放线索,并禁用该员工,是否确认注销?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -470,7 +475,7 @@ export default { this.msgSuccess('注销成功!'); }); }, - handleRelease(row) { + handleRelease (row) { this.$confirm('是否立刻释放该员工拥有的线索?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -481,7 +486,7 @@ export default { this.msgSuccess('释放成功!'); }); }, - handleRemove(row) { + handleRemove (row) { this.$confirm('是否删除该员工,建议只在数据错误时删除?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', diff --git a/src/views/system/skill/index.vue b/src/views/system/skill/index.vue new file mode 100644 index 0000000..f154ab7 --- /dev/null +++ b/src/views/system/skill/index.vue @@ -0,0 +1,193 @@ +<template> + <div class="app-container"> + <el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="68px"> + <el-form-item label="关键词" prop="skillKey"> + <el-input v-model="queryParams.skillKey" placeholder="请输入关键词" clearable @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button v-hasPermi="['system:skill:add']" type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button> + </el-col> + + <right-toolbar :show-search.sync="showSearch" @queryTable="getList" /> + </el-row> + + <el-table v-loading="loading" :data="skillList" @selection-change="handleSelectionChange"> + <el-table-column type="index" width="55" align="center" /> + <el-table-column label="关键词" align="center" prop="skillKey" /> + <el-table-column label="话术内容" align="center" prop="content" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button v-hasPermi="['system:skill:edit']" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button> + <el-button v-hasPermi="['system:skill:remove']" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(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-dialog :title="title" :visible.sync="open" width="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="关键词" prop="skillKey"> + <el-input v-model="form.skillKey" placeholder="请输入关键词" /> + </el-form-item> + <el-form-item label="话术内容"> + <editor v-model="form.content" :min-height="192" /> + </el-form-item> + </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 { listSkill, getSkill, delSkill, addSkill, updateSkill } from '@/api/system/skill'; + +export default { + name: 'Skill', + data () { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 关键话术表格数据 + skillList: [], + // 弹出层标题 + title: '', + // 是否显示弹出层 + open: false, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + deptId: null, + skillKey: null, + content: null + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + skillKey: [{ required: true, message: '关键词不能为空', trigger: 'blur' }], + content: [{ required: true, message: '话术内容不能为空', trigger: 'blur' }] + } + }; + }, + created () { + this.getList(); + }, + methods: { + /** 查询关键话术列表 */ + getList () { + this.loading = true; + listSkill(this.queryParams).then(response => { + this.skillList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel () { + this.open = false; + this.reset(); + }, + // 表单重置 + reset () { + this.form = { + skillId: null, + deptId: null, + skillKey: null, + content: null + }; + this.resetForm('form'); + }, + /** 搜索按钮操作 */ + handleQuery () { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery () { + this.resetForm('queryForm'); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange (selection) { + this.ids = selection.map(item => item.skillId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 新增按钮操作 */ + handleAdd () { + this.reset(); + this.open = true; + this.title = '添加关键话术'; + }, + /** 修改按钮操作 */ + handleUpdate (row) { + this.reset(); + const skillId = row.skillId || this.ids; + getSkill(skillId).then(response => { + this.form = response.data; + this.open = true; + this.title = '修改关键话术'; + }); + }, + /** 提交按钮 */ + submitForm () { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.skillId != null) { + updateSkill(this.form).then(response => { + this.$modal.msgSuccess('修改成功'); + this.open = false; + this.getList(); + }); + } else { + addSkill(this.form).then(response => { + this.$modal.msgSuccess('新增成功'); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 删除按钮操作 */ + handleDelete (row) { + const skillIds = row.skillId || this.ids; + this.$modal.confirm('是否确认删除关键话术编号为"' + skillIds + '"的数据项?').then(function () { + return delSkill(skillIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess('删除成功'); + }).catch(() => { }); + }, + /** 导出按钮操作 */ + handleExport () { + this.download('system/skill/export', { + ...this.queryParams + }, `skill_${new Date().getTime()}.xlsx`); + } + } +}; +</script> diff --git a/src/views/zs/clue/ClueForm/index.vue b/src/views/zs/clue/ClueForm/index.vue index c419ced..6cbb56f 100644 --- a/src/views/zs/clue/ClueForm/index.vue +++ b/src/views/zs/clue/ClueForm/index.vue @@ -26,6 +26,8 @@ <el-checkbox v-model="saveNext" /> <span class="ml5">保存后继续创建下一条</span> </template> + <el-button type="primary" @click="handleSkill">关键话术</el-button> + </div> <!-- :disabled="!canSubmit" --> <el-button class="footer_button" :disabled="!canSubmit" type="primary" @click="clueSubmit">确 定</el-button> @@ -39,12 +41,12 @@ <el-col :span="8"> <el-col :span="24"> <el-form-item label="创建时间" prop="createTime"> - <el-date-picker style="width: 100%;" v-model="clueForm.createTime" value-format="yyyy-MM-dd HH:mm" format="yyyy-MM-dd HH:mm" type="datetime" :disabled="admin!='true'" /> + <el-date-picker v-model="clueForm.createTime" style="width: 100%;" 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="24"> <el-form-item label="线索来源" prop="source"> - <el-select style="width: 100%;" v-model="clueForm.source" placeholder="请选择" clearable> + <el-select v-model="clueForm.source" style="width: 100%;" placeholder="请选择" clearable> <el-option v-for="dict in sourceOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" /> </el-select> </el-form-item> @@ -64,57 +66,57 @@ <el-input v-model="clueForm.weChat" placeholder="请输入微信号" /> </el-form-item> </el-col> - <el-col :span="24" v-if="clueForm.source == '抖音直播'"> + <el-col v-if="clueForm.source == '抖音直播'" :span="24"> <el-form-item label="商品名称" prop="goodName"> <el-input v-model="clueForm.goodName" placeholder="请输入商品名称" /> </el-form-item> </el-col> - <el-col :span="24" v-if="clueForm.source == '抖音直播'"> + <el-col v-if="clueForm.source == '抖音直播'" :span="24"> <el-form-item label="订单实收" prop="amountReceived"> <el-input v-model="clueForm.amountReceived" placeholder="请输入订单实收" /> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="跟进人员" prop="followUser"> - <el-select style="width: 100%;" v-model="clueForm.followUser" multiple clearable :disabled="admin != 'true' && clueForm.clueId != undefined"> + <el-select v-model="clueForm.followUser" style="width: 100%;" multiple clearable :disabled="admin != 'true' && clueForm.clueId != undefined"> <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="24"> - <el-form-item label="意向状态" prop="intentionState" v-if="clueForm.source == '抖音直播'"> - <el-select style="width: 100%;" v-model="clueForm.intentionState" placeholder="请选择" clearable> + <el-form-item v-if="clueForm.source == '抖音直播'" label="意向状态" prop="intentionState"> + <el-select v-model="clueForm.intentionState" style="width: 100%;" placeholder="请选择" clearable> <el-option v-for="dict in intentionOptions.filter(item => item.remark == undefined || item.remark == '抖音')" :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 label="意向状态" prop="intentionState" v-else> - <el-select style="width: 100%;" v-model="clueForm.intentionState" placeholder="请选择" clearable> + </el-form-item> + + <el-form-item v-else label="意向状态" prop="intentionState"> + <el-select v-model="clueForm.intentionState" style="width: 100%;" placeholder="请选择" clearable> <el-option v-for="dict in intentionOptions.filter(item => item.remark == undefined || item.remark == '正常')" :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-col :span="24" v-if="clueForm.source == '抖音直播'"> + <el-col v-if="clueForm.source == '抖音直播'" :span="24"> <el-form-item label="核销时间" prop="writeOffTime"> - <el-date-picker style="width: 100%;" v-model="clueForm.writeOffTime" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" /> + <el-date-picker v-model="clueForm.writeOffTime" style="width: 100%;" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" /> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="下次跟进时间" prop="followTime"> - <el-date-picker style="width: 100%;" v-model="clueForm.followTime" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" /> + <el-date-picker v-model="clueForm.followTime" style="width: 100%;" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" /> </el-form-item> </el-col> <el-col :span="24"> @@ -131,7 +133,7 @@ <!-- 跟进记录 --> <el-col :span="24" style="margin-top: 20px;"> <el-form-item label="跟进记录" prop="clueMemo" label-position="top"> - <FollowRecord v-if="clueId" :clueId="clueId" /> + <FollowRecord v-if="clueId" :clue-id="clueId" /> </el-form-item> </el-col> @@ -139,7 +141,7 @@ <el-col :span="16"> <div> <el-col :span="24" class="mb20 plr20" style="position: relative"> - <PlaceMap ref="placeMap" :placeList="placeList" /> + <PlaceMap ref="placeMap" :place-list="placeList" /> <div class="address"> <el-form-item label="位置" prop="address" label-width="80px"> <el-input v-model="clueForm.address" placeholder="请输入位置" disabled> @@ -158,25 +160,28 @@ <!-- </el-card> --> <MapDialog v-if="mapDialogVisible" ref="mapDialog" :dialog-visible="mapDialogVisible" @handleMapDialogPoint="handleMapDialogPoint" /> + <!-- 关键话术 --> + <SkillDialog ref="SkillDialog" /> </div> </template> <script> -import { getClueInfo, getConsultRecord, addClue, updateClue, } from '@/api/zs/clue' -import empApi from '@/api/system/employee' -import { getAllPlaces } from '@/api/sch/place' +import { getClueInfo, getConsultRecord, addClue, updateClue } from '@/api/zs/clue'; +import empApi from '@/api/system/employee'; +import { getAllPlaces } from '@/api/sch/place'; import PlaceMap from './components/PlaceMap.vue'; import FollowRecord from './components/FollowRecord.vue'; import MapDialog from './components/MapDialog.vue'; +import SkillDialog from '../components/SkillDialog.vue'; export default { name: 'ClueForm', components: { - PlaceMap, FollowRecord, MapDialog + PlaceMap, FollowRecord, MapDialog, SkillDialog }, - data() { + data () { return { admin: localStorage.getItem('admin'), userId: localStorage.getItem('userId'), @@ -194,10 +199,10 @@ export default { address: { required: true, message: '位置不为空', trigger: 'blur' }, intentionState: { required: true, message: '意向状态不为空', trigger: 'blur,change' } }, - userOptions: [],//跟进人员 - sourceOptions: [],//线索来源 - intentionOptions: [],//意向状态 - placeList: [],//场地信息 + userOptions: [], // 跟进人员 + sourceOptions: [], // 线索来源 + intentionOptions: [], // 意向状态 + placeList: [], // 场地信息 mapDialogVisible: false, consultRecord: [], canSubmit: true, @@ -205,10 +210,10 @@ export default { saveNext: false }; }, - created() { - //获取clueId - this.clueId = Number(this.$route.params.clueId) - this.getAllPlaces() + created () { + // 获取clueId + this.clueId = Number(this.$route.params.clueId); + this.getAllPlaces(); this.getEmployee(); this.getClueInfo(this.clueId); @@ -223,20 +228,19 @@ export default { }, methods: { - async getClueInfo(clueId) { + async getClueInfo (clueId) { this.resetForm(); - if (clueId === 0) - return - this.saveNextShow = false - this.saveNext = false + if (clueId === 0) { return; } + this.saveNextShow = false; + this.saveNext = false; const resp = await getClueInfo(clueId); if (resp.code == 200) { - this.clueForm = { ...resp.data } + this.clueForm = { ...resp.data }; this.handleMapCenter(this.clueForm); this.getConsultRecord(this.clueForm.phone); } }, - resetForm() { + resetForm () { this.clueForm = { clueId: undefined, createTime: this.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}'), @@ -254,52 +258,52 @@ export default { licenseType: undefined, lng: undefined, lat: undefined - } + }; if (this.admin == 'false') { - this.clueForm.followUser.push(Number(this.userId)) + this.clueForm.followUser.push(Number(this.userId)); } }, // 查询咨询记录 - getConsultRecord(phone) { + getConsultRecord (phone) { getConsultRecord({ phone }).then((resp) => { if (resp && resp.code === 200 && resp.data) { - this.consultRecord = resp.data + this.consultRecord = resp.data; if (this.consultRecord && this.consultRecord.length > 0) { - this.clueForm.consultCount = this.consultRecord.length + this.clueForm.consultCount = this.consultRecord.length; } } - }) + }); }, - //地图编辑弹框 - handleMapDialog() { + // 地图编辑弹框 + handleMapDialog () { this.mapDialogVisible = true; this.$nextTick(() => { this.$refs.mapDialog.initData(this.clueForm); }); }, - //处理地图弹框返回的点 - handleMapDialogPoint(point) { - console.log("handleMapDialogPoint") - console.log(point) + // 处理地图弹框返回的点 + handleMapDialogPoint (point) { + console.log('handleMapDialogPoint'); + console.log(point); if (point) { this.handleMapCenter(point); } }, - //删除当前地址 - handleRemovePosition() { + // 删除当前地址 + handleRemovePosition () { this.clueForm.lng = undefined; this.clueForm.lat = undefined; this.clueForm.address = undefined; }, - //定位地图的中心点 - handleMapCenter(info) { + // 定位地图的中心点 + handleMapCenter (info) { this.$nextTick(() => { this.$refs.placeMap.setMapCenter(info); }); }, // 查询不能接收线索的员工 - getEmployee() { + getEmployee () { empApi.getEmployee().then((resp) => { if (resp.code === 200) { this.userOptions = resp.data; @@ -310,7 +314,7 @@ export default { }); }, // 查询场地信息 - async getAllPlaces() { + async getAllPlaces () { const resp = await getAllPlaces({ status: '0' }); if (resp.code == 200) { this.placeList = resp.data.filter((item) => item.schoolShow && item.showInMap); @@ -318,24 +322,23 @@ export default { this.$refs.placeMap.handleMarkers(this.placeList); }); } - }, - //表单提交 - clueSubmit() { + // 表单提交 + clueSubmit () { this.$refs.clueForm.validate(async (valid) => { if (valid) { - this.canSubmit = false - let resp + this.canSubmit = false; + let resp; if (this.clueForm.clueId) { - resp = await updateClue(this.clueForm) - this.canSubmit = true + resp = await updateClue(this.clueForm); + this.canSubmit = true; if (resp.code === 200) { - this.$message.success('修改成功') + this.$message.success('修改成功'); this.toBackClue(); } } else { - resp = await addClue(this.clueForm) - this.canSubmit = false + resp = await addClue(this.clueForm); + this.canSubmit = false; if (resp.code === 200) { if (resp.data && resp.data == 1) { this.$message({ @@ -343,23 +346,27 @@ export default { type: 'warning' }); } else { - this.$message.success('新增成功') - + this.$message.success('新增成功'); } if (this.saveNext) { - this.canSubmit = true - this.resetForm() + this.canSubmit = true; + this.resetForm(); } else { this.toBackClue(); } } } } - }) + }); }, - toBackClue() { - const obj = { path: "/zs/clue" }; + toBackClue () { + const obj = { path: '/zs/clue' }; this.$tab.closeOpenPage(obj); + }, + handleSkill () { + this.$nextTick(() => { + this.$refs.SkillDialog.init(); + }); } } diff --git a/src/views/zs/clue/columns.js b/src/views/zs/clue/columns.js index fb53490..413ccc4 100644 --- a/src/views/zs/clue/columns.js +++ b/src/views/zs/clue/columns.js @@ -1,136 +1,136 @@ export const defaultColumns = [{ - key: 0, - prop: 'createTime', - label: '创建时间', - width: 140, - visible: true, - overflow: false - }, - { - key: 1, - prop: 'source', - label: '线索来源', - width: 140, - visible: true, - overflow: false - }, - { - key: 2, - prop: 'name', - label: '姓名', - width: 140, - visible: true, - overflow: false - }, - { - key: 3, - prop: 'phone', - label: '联系方式', - width: 140, - visible: true, - overflow: false - }, - { - key: 4, - prop: 'weChat', - label: '微信号', - width: 140, - visible: true, - overflow: false - }, - { - key: 5, - prop: 'address', - label: '位置', - width: 140, - visible: true, - overflow: false - }, - { - key: 6, - prop: 'requirement', - label: '学员诉求', - visible: true, - overflow: false - }, - { - key: 7, - prop: 'licenseType', - label: '咨询车型', - width: 140, - visible: true, - overflow: false - }, - { - key: 8, - prop: 'followTime', - label: '下次跟进时间', - width: 120, - visible: true, - overflow: false - }, - { - key: 9, - prop: 'firstFollowUserName', - label: '首次跟进人员', - width: 120, - visible: true, - overflow: false - }, - { - key: 10, - prop: 'followUserName', - label: '跟进人员', - width: 140, - visible: true, - overflow: false - }, - { - key: 11, - prop: 'recentLook', - label: '是否近期看场地', - width: 140, - visible: true, - overflow: false - }, - { - key: 12, - prop: 'offlineReceiverName', - label: '线下接待人员', - width: 140, - visible: true, - overflow: false - }, - { - key: 13, - prop: 'clueMemo', - label: '备注', - width: 140, - visible: true, - overflow: true - }, - { - key: 14, - prop: 'goodName', - label: '商品名称', - width: 140, - visible: true, - overflow: true - }, - { - key: 15, - prop: 'amountReceived', - label: '订单实收', - width: 140, - visible: true, - overflow: true - }, - { - key: 16, - prop: 'writeOffTime', - label: '核销时间', - width: 140, - visible: true, - overflow: true - } + key: 0, + prop: 'createTime', + label: '创建时间', + width: 140, + visible: true, + overflow: false +}, +{ + key: 1, + prop: 'source', + label: '线索来源', + width: 140, + visible: true, + overflow: false +}, +{ + key: 2, + prop: 'name', + label: '姓名', + width: 140, + visible: true, + overflow: false +}, +{ + key: 3, + prop: 'phone', + label: '联系方式', + width: 140, + visible: true, + overflow: false +}, +{ + key: 4, + prop: 'weChat', + label: '微信号', + width: 140, + visible: true, + overflow: false +}, +{ + key: 5, + prop: 'address', + label: '位置', + width: 140, + visible: true, + overflow: false +}, +{ + key: 6, + prop: 'requirement', + label: '学员诉求', + visible: true, + overflow: false +}, +{ + key: 7, + prop: 'licenseType', + label: '咨询车型', + width: 140, + visible: true, + overflow: false +}, +{ + key: 8, + prop: 'followTime', + label: '下次跟进时间', + width: 120, + visible: true, + overflow: false +}, +{ + key: 9, + prop: 'firstFollowUserName', + label: '首次跟进人员', + width: 120, + visible: true, + overflow: false +}, +{ + key: 10, + prop: 'followUserName', + label: '跟进人员', + width: 140, + visible: true, + overflow: false +}, +{ + key: 11, + prop: 'recentLook', + label: '是否近期看场地', + width: 140, + visible: true, + overflow: false +}, +{ + key: 12, + prop: 'offlineReceiverName', + label: '线下接待人员', + width: 140, + visible: true, + overflow: false +}, +{ + key: 13, + prop: 'clueMemo', + label: '备注', + width: 140, + visible: true, + overflow: true +}, +{ + key: 14, + prop: 'goodName', + label: '商品名称', + width: 140, + visible: true, + overflow: true +}, +{ + key: 15, + prop: 'amountReceived', + label: '订单实收', + width: 140, + visible: true, + overflow: true +}, +{ + key: 16, + prop: 'writeOffTime', + label: '核销时间', + width: 140, + visible: true, + overflow: true +} ]; diff --git a/src/views/zs/clue/components/DistributeFormDialog copy.vue b/src/views/zs/clue/components/DistributeFormDialog copy.vue index 095c588..90bfe71 100644 --- a/src/views/zs/clue/components/DistributeFormDialog copy.vue +++ b/src/views/zs/clue/components/DistributeFormDialog copy.vue @@ -4,7 +4,7 @@ <el-row> <el-col :span="24"> <el-form-item label="场地" prop="newPlaceList"> - <span v-if="oldForm.placeNames">{{oldForm.placeNames}}</span> + <span v-if="oldForm.placeNames">{{ oldForm.placeNames }}</span> <el-select v-model="dialogForm.newPlaceList" filterable multiple placeholder="请选择" clearable style="width: 100%;"> <el-option v-for="dict in placeOptions" :key="dict.placeId" :label="dict.name" :value="dict.placeId" /> @@ -19,14 +19,14 @@ </span> </el-dialog> </template> - <script> +<script> import { getCluePlaceList, saveCluePlace } from '@/api/zs/clue'; import { getAllPlaces } from '@/api/sch/place'; export default { name: 'DistributeFormDialog', - data() { + data () { return { visible: false, canSubmit: true, @@ -43,50 +43,48 @@ export default { }; }, methods: { - init(info = undefined) { - this.getPlaces() + init (info = undefined) { + this.getPlaces(); this.visible = true; this.$nextTick(() => { this.resetDialogForm(); this.$refs['dialogForm'].resetFields(); if (info) { - this.dialogForm.clueId = info; - //查询该线索的分发情况 + // 查询该线索的分发情况 this.getDistributePlaces(info); } }); }, - resetDialogForm() { + resetDialogForm () { this.dialogForm = { oldPlaceList: [], newPlaceList: [], placeIdList: [], clueId: undefined }; - this.oldForm = {} + this.oldForm = {}; }, - closeDialog() { + closeDialog () { this.$emit('update:dialog.batchUpdateVisible', false); }, - getDistributePlaces(clueId) { + getDistributePlaces (clueId) { getCluePlaceList({ clueId: clueId }).then(resp => { if (resp.code == 200) { - this.oldForm = resp.data + this.oldForm = resp.data; this.dialogForm.oldPlaceList = this.oldForm.placeIdList; if (this.oldForm.placeIdList && this.oldForm.placeIdList) { - this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1) + this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1); } } - - }) + }); }, // 表单提交 - dialogFormSubmit() { + dialogFormSubmit () { this.$refs.dialogForm.validate((valid) => { if (valid) { this.canSubmit = false; - this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList) + this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList); // 校验完成,调接口 saveCluePlace(this.dialogForm) .then((resp) => { @@ -103,14 +101,12 @@ export default { } }); }, - getPlaces() { + getPlaces () { getAllPlaces({ status: '0' }).then((resp) => { this.placeOptions = resp.data; - }); - }, + } } }; - </script> - - \ No newline at end of file +</script> + diff --git a/src/views/zs/clue/components/DistributeFormDialog.vue b/src/views/zs/clue/components/DistributeFormDialog.vue index 61781b4..4b5808b 100644 --- a/src/views/zs/clue/components/DistributeFormDialog.vue +++ b/src/views/zs/clue/components/DistributeFormDialog.vue @@ -1,32 +1,68 @@ <template> <el-dialog title="分发" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="600px" @close="closeDialog"> - <el-form ref="dialogForm" :model="dialogForm" :rules="rules" label-width="110px"> + <el-form ref="dialogForm" :model="dialogForm" :rules="rules" label-width="110px" :disabled="dialogForm.orderId"> <el-row> <el-col :span="24"> <el-form-item label="场地" prop="placeId"> - <el-select v-model="dialogForm.placeId" filterable placeholder="请选择" clearable style="width: 100%;"> + <el-select v-model="dialogForm.placeId" filterable placeholder="请选择" clearable style="width: 100%;" @change="getCoaChes"> <el-option v-for="dict in placeOptions" :key="dict.placeId" :label="dict.name" :value="dict.placeId" /> </el-select> </el-form-item> </el-col> <el-col :span="24"> - <el-form-item label="教练" prop="coachId"> + <el-form-item label="接待人" prop="coachId"> <el-select v-model="dialogForm.coachId" filterable placeholder="请选择" clearable style="width: 100%;"> <el-option v-for="dict in coachOptions" :key="dict.coachId" :label="dict.coachName" :value="dict.coachId" /> </el-select> </el-form-item> </el-col> + <el-col :span="24"> + <el-form-item label="抄送" prop="copyUserList"> + <el-select v-model="dialogForm.copyUserList" filterable multiple placeholder="请选择" clearable style="width: 100%;"> + <el-option v-for="dict in coachOptions" :key="dict.coachId" :label="dict.coachName" :value="dict.coachId" /> + </el-select> + </el-form-item> + </el-col> + + <el-col :span="24"> + <el-form-item label="跟进信息"> + <div style="max-height: 200px; overflow-y: auto;"> + <div v-for="item in feedbackDetail" :key="item.feedbackId"> + <el-timeline-item :timestamp="item.updateTime == undefined ? item.createTime : item.updateTime" placement="top"> + <el-card> + <div v-if="item.feedbackType == 1"> + <div>是否联系:<span style="font-size: 12px;">{{ item.isContact ? '已联系' : '未联系' }}</span></div> + <div>到场时间:<span style="font-size: 12px;">{{ item.arrivalTime }}</span></div> + <div>备注:<span style="font-size: 12px;" v-html="item.remark" /></div> + </div> + <div v-if="item.feedbackType == 2"> + <div>状态: + <span v-if="item.arrivalStatus == 1">未到场</span> + <span v-if="item.arrivalStatus == 2">到场未成交</span> + <span v-if="item.arrivalStatus == 3">到场已成交</span> + </div> + <div>备注:<span style="font-size: 12px;" v-html="item.remark" /></div> + </div> + </el-card> + </el-timeline-item> + </div> + </div> + </el-form-item> + </el-col> </el-row> </el-form> - <span slot="footer" class="dialog-footer"> + <span slot="footer" class="dialog-footer" :disabled="dialogForm.orderId"> <el-button plain @click="(visible = false)">取消</el-button> - <el-button v-jclick type="primary" :disabled="!canSubmit" @click="dialogFormSubmit()">确定</el-button> + <el-button v-jclick type="primary" :disabled="!canSubmit " @click="dialogFormSubmit()">确定</el-button> </span> </el-dialog> </template> <script> -import { getCluePlaceList, saveCluePlace } from '@/api/zs/clue'; +import { listFeedbackOrder, addFeedbackOrder } from '@/api/zs/feedbackOrder'; +import { listFeedbackDetail } from '@/api/zs/feedbackDetail'; + import { getAllPlaces } from '@/api/sch/place'; +import { getAllCoaches } from '@/api/sch/coach'; export default { name: 'DistributeFormDialog', @@ -35,13 +71,19 @@ export default { return { visible: false, canSubmit: true, - dialogForm: {}, - oldForm: {}, + dialogForm: { + placeId: undefined, + clueId: undefined, + coachId: undefined, + copyUserList: [] + }, rules: { placeId: { required: true, message: '场地不能为空', trigger: 'blur, change' }, coachId: { required: true, message: '教练不能为空', trigger: 'blur, change' } }, - placeOptions: [] + placeOptions: [], + coachOptions: [], + feedbackDetail: [] }; }, methods: { @@ -54,7 +96,7 @@ export default { if (info) { this.dialogForm.clueId = info; // 查询该线索的分发情况 - this.getDistributePlaces(info); + this.getFeedbackOrder(info); } }); }, @@ -62,32 +104,39 @@ export default { this.dialogForm = { placeId: undefined, clueId: undefined, - coachId: undefined + coachId: undefined, + copyUserList: [] }; - this.oldForm = {}; }, closeDialog () { this.$emit('update:dialog.batchUpdateVisible', false); }, - getDistributePlaces (clueId) { - getCluePlaceList({ clueId: clueId }).then(resp => { - if (resp.code == 200) { - this.oldForm = resp.data; - this.dialogForm.oldPlaceList = this.oldForm.placeIdList; - if (this.oldForm.placeIdList && this.oldForm.placeIdList) { - this.placeOptions = this.placeOptions.filter(item => this.oldForm.placeIdList.indexOf(item.placeId) == -1); + getFeedbackOrder (clueId) { + listFeedbackOrder({ clueId: clueId }).then(resp => { + if (resp.code == 200 && resp.rows && resp.rows.length > 0) { + this.dialogForm = resp.rows.filter(item => item.feedbackStatus != 0)[0]; + if (this.dialogForm != undefined && this.dialogForm.placeId != undefined) { + this.getCoaChes(this.dialogForm.placeId); + } + + if (this.dialogForm.orderId) { + this.getFeedbackDetail(this.dialogForm.orderId); } } }); }, + getFeedbackDetail (orderId) { + listFeedbackDetail({ orderId: orderId }).then(resp => { + this.feedbackDetail = resp.rows; + }); + }, // 表单提交 dialogFormSubmit () { this.$refs.dialogForm.validate((valid) => { if (valid) { this.canSubmit = false; - this.dialogForm.placeIdList = this.dialogForm.oldPlaceList.concat(this.dialogForm.newPlaceList); // 校验完成,调接口 - saveCluePlace(this.dialogForm) + addFeedbackOrder(this.dialogForm) .then((resp) => { this.canSubmit = true; if (resp.code == 200) { @@ -106,6 +155,12 @@ export default { getAllPlaces({ status: '0' }).then((resp) => { this.placeOptions = resp.data; }); + }, + getCoaChes (placeId) { + console.log(placeId); + getAllCoaches({ placeId: placeId }).then(resp => { + if (resp.code == 200) { this.coachOptions = resp.data; } + }); } } }; diff --git a/src/views/zs/clue/components/SkillDialog.vue b/src/views/zs/clue/components/SkillDialog.vue new file mode 100644 index 0000000..296d123 --- /dev/null +++ b/src/views/zs/clue/components/SkillDialog.vue @@ -0,0 +1,70 @@ +<!-- + * @Author: riverQiu + * @Date: 2023-10-14 13:21:37 + * @LastEditors: riverQiu + * @LastEditTime: 2023-10-15 00:55:44 + * @Description: +--> +<template> + <el-dialog title="话术" :close-on-click-modal="false" append-to-body :visible.sync="visible" width="700px" height="700"> + <div> + <!-- 搜索框 --> + <el-select v-model="skillId" placeholder="请选择关键词" filterable style="width: 90%;" @change="selectKey"> + <el-option v-for="item in keyOptions" :key="item.skillId" :label="item.skillKey" :value="item.skillId" /> + </el-select> <!-- 常用关键词 --> + + <!-- 话术内容 --> + <el-card class="box-card"> + + <div class="text item"> + <span v-html="content" /> + </div> + </el-card> + </div> + </el-dialog> +</template> +<script> +import { getSkillKey, getSkill } from '@/api/system/skill'; +export default { + name: 'SkillDialog', + data () { + return { + visible: false, + loading: true, + keyOptions: [], + content: undefined, + skillId: undefined + }; + }, + methods: { + init () { + this.visible = true; + this.getSkillKeyOption(); + }, + getSkillKeyOption () { + getSkillKey().then((resp) => { + if (resp && resp.code === 200) { + this.keyOptions = resp.data; + } + }); + }, + selectKey (item) { + if (item) { + getSkill(item).then((resp) => { + if (resp && resp.code === 200) { + this.content = resp.data.content; + } + }); + } + } + } +}; +</script> + +<style lang="scss" scoped> +.box-card { + width: 500px; + min-height: 100px; +} +</style> + diff --git a/src/views/zs/clue/index.vue b/src/views/zs/clue/index.vue index 3eb5fdc..b90df3e 100644 --- a/src/views/zs/clue/index.vue +++ b/src/views/zs/clue/index.vue @@ -13,15 +13,22 @@ <el-button v-hasPermi="['zs:clue:export']" icon="el-icon-download" type="warning" @click="handleExport">导出</el-button> <el-button v-hasPermi="['zs:clue:edit']" icon="el-icon-edit" type="primary" :disabled="multiple" @click="handleBatChUpdate()">批量修改</el-button> <el-button type="primary" @click="handlePublicClue">公海</el-button> + <el-button type="primary" @click="handleSkill">关键话术</el-button> + </el-col> <right-toolbar :show-search.sync="showSearch" :columns="columns" @queryTable="_getTableList" /> </el-row> - <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange" border @row-dblclick="handleRowClick" @cell-click="handleCellClick"> + <el-table v-loading="loading" :data="tableList" border @selection-change="handleSelectionChange" @row-dblclick="handleRowClick" @cell-click="handleCellClick"> <el-table-column type="selection" width="50" align="center" /> <template v-for="item in columns"> <el-table-column v-if="item.visible && item.prop != 'clueMemo'" :key="item.prop" :label="item.label" align="center" :width="item.width" :prop="item.prop" :show-overflow-tooltip="item.overflow" /> <el-table-column v-if="item.visible && item.prop == 'clueMemo'" :key="item.prop" :label="item.label" align="center" :width="item.width" :prop="item.prop" :show-overflow-tooltip="item.overflow" /> </template> + <el-table-column label="反馈状态" prop="feedbackStatus" sortable fixed="right" min-width="100"> + <template slot-scope="{ row }"> + <el-tag effect="dark" style="border: none">{{ feedbackTagColorMap[row.feedbackStatus] }}</el-tag> + </template> + </el-table-column> <el-table-column label="意向状态" prop="intentionState" sortable fixed="right" min-width="100"> <template slot-scope="{ row }"> <el-tag effect="dark" style="border: none" :color="tagColorMap[row.intentionState]">{{ row.intentionState }}</el-tag> @@ -31,11 +38,11 @@ <template slot-scope="scope"> <!-- <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && scope.row.source == '抖音直播'" v-hasPermi="['zs:clue:edit']" type="text" style="color: red;" @click.native.stop="handleDYAddandUpdate(scope.row)">编辑</el-button> --> <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 )" v-hasPermi="['zs:clue:edit']" type="text" style="color: red;" @click.native.stop="handleAddandUpdate(scope.row)">编辑</el-button> - <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 )" v-hasPermi="['zs:clue:distribute']" type="text" @click.native.stop="handleDistribute(scope.row)">分发</el-button> - <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && scope.row.state" v-hasPermi="['zs:clue:sign']" type="text" style="color: #26a69a" @click.native.stop="handleSign(scope.row)">已登记</el-button> - <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && !scope.row.state" v-hasPermi="['zs:clue:sign']" type="text" @click.native.stop="handleSign(scope.row)">未登记</el-button> - <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 )" v-hasPermi="['zs:clue:remove']" type="text" @click.native.stop="handleDelete(scope.row)">删除</el-button> - <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && !scope.row.state" v-hasPermi="['zs:clue:discard']" type="text" @click.native.stop="handleDiscard(scope.row)">释放</el-button> + <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 )" v-hasPermi="['zs:clue:distribute']" type="text" @click.native.stop="handleDistribute(scope.row)">分发</el-button> + <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && scope.row.state" v-hasPermi="['zs:clue:sign']" type="text" style="color: #26a69a" @click.native.stop="handleSign(scope.row)">已登记</el-button> + <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && !scope.row.state" v-hasPermi="['zs:clue:sign']" type="text" @click.native.stop="handleSign(scope.row)">未登记</el-button> + <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 )" v-hasPermi="['zs:clue:remove']" type="text" @click.native.stop="handleDelete(scope.row)">删除</el-button> + <el-button v-if="(admin == 'true' || scope.row.followUser2.indexOf(userId) != -1 ) && !scope.row.state" v-hasPermi="['zs:clue:discard']" type="text" @click.native.stop="handleDiscard(scope.row)">释放</el-button> <el-button v-if="quickSearch == 8" type="text" @click="handleViewZhuangDan(scope.row)"> 撞单信息</el-button> <!-- <el-button v-if="searchForm.quickSearch == 8" type="text" > 撞单信息</el-button> --> </template> @@ -57,7 +64,9 @@ <!-- 备注编辑 --> <MemoFormDialog ref="memoDialog" @refreshDataList="_getTableList" /> <!-- 抖音直播弹框 --> - <DYClueFormDialog ref="DYClueFormDialog" @refreshDataList="_getTableList"/> + <DYClueFormDialog ref="DYClueFormDialog" @refreshDataList="_getTableList" /> + <!-- 关键话术 --> + <SkillDialog ref="SkillDialog" /> </div> </template> @@ -72,26 +81,27 @@ import SignFormDialog from '../sign/components/SignFormDialog.vue'; import ZhuangDanDialog from './components/ZhuangDanDialog.vue'; import MemoFormDialog from './components/MemoFormDialog.vue'; import DYClueFormDialog from './components/DYClueFormDialog.vue'; +import SkillDialog from './components/SkillDialog.vue'; import { defaultColumns } from './columns.js'; import { getClueList, deleteClue, getClueCountBadge, discardClue, getSign, getConsultRecord } from '@/api/zs/clue'; import empApi from '@/api/system/employee'; export default { name: 'Clue', - beforeRouteEnter(to, from, next) { + components: { + SearchForm, BatchUpdateDialog, PublicDialog, UploadDialog, SignFormDialog, DistributeFormDialog, ZhuangDanDialog, MemoFormDialog, + DYClueFormDialog, SkillDialog + }, + beforeRouteEnter (to, from, next) { if (from.name == 'ClueForm') { next(vm => { - vm._getTableList() - }) + vm._getTableList(); + }); } else { - next() + next(); } }, - components: { - SearchForm, BatchUpdateDialog, PublicDialog, UploadDialog, SignFormDialog, DistributeFormDialog, ZhuangDanDialog, MemoFormDialog, - DYClueFormDialog - }, - data() { + data () { return { admin: localStorage.getItem('admin'), userId: localStorage.getItem('userId'), @@ -120,13 +130,20 @@ export default { 报名他校: '#afaeb0', 无效线索: '#afaeb0' }, + feedbackTagColorMap: { + 0: '待分发', + 1: '待跟进', + 2: '已跟进', + 3: '已到场', + 4: '退单' + }, options: undefined, clueInfo: undefined, consultRecord: [], quickSearch: 0 }; }, - created() { + created () { const str = localStorage.getItem(`${this.$route.name}-table-columns`); this.columns = str ? JSON.parse(str) : defaultColumns; this._getClueCountBadge(); @@ -143,10 +160,10 @@ export default { }, methods: { // 分页查询表格数据 - _getTableList() { + _getTableList () { this.loading = true; const tempForm = this.$refs.SearchForm?.searchForm || {}; - this.quickSearch = tempForm.quickSearch + this.quickSearch = tempForm.quickSearch; const params = { ...this.searchForm, ...tempForm }; getClueList(params).then((response) => { this.tableList = response.rows; @@ -155,31 +172,36 @@ export default { }); }, // 获取已过期线索数 - async _getClueCountBadge() { + async _getClueCountBadge () { const resp = await getClueCountBadge(); if (resp.code === 200) { this.expireCount = resp.data; } }, // 新增或修改 - handleAddandUpdate(info) { + handleAddandUpdate (info) { this.$router.push('/zs/clue-form/index/' + (info ? info.clueId : 0)); }, - //抖音新增 - handleDYAddandUpdate(info){ + // 抖音新增 + handleDYAddandUpdate (info) { this.$nextTick(() => { this.$refs.DYClueFormDialog.init(info); }); }, + handleSkill () { + this.$nextTick(() => { + this.$refs.SkillDialog.init(); + }); + }, // 多选框选中数据 - handleSelectionChange(selection) { + handleSelectionChange (selection) { console.log(selection); this.ids = selection.map((item) => item.clueId); this.single = selection.length !== 1; this.multiple = !selection.length; }, // 释放线索操作 - handleDiscard(item) { + handleDiscard (item) { this.$confirm('是否确认释放该条线索(“' + item.name + '/' + item.phone + '”)到公海?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -196,7 +218,7 @@ export default { .catch(function () { }); }, // 删除 - handleDelete(item) { + handleDelete (item) { this.$confirm('是否确认删除该条线索(“' + item.name + '/' + item.phone + '”)?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -213,13 +235,13 @@ export default { .catch(function () { }); }, // 导入 - handleImport(ydtData, dYData) { + handleImport (ydtData, dYData) { this.$nextTick(() => { - this.$refs.uploadDialogForm.init({ydtData: ydtData, dYData: dYData}); + this.$refs.uploadDialogForm.init({ ydtData: ydtData, dYData: dYData }); }); }, /** 导出按钮操作 */ - handleExport() { + handleExport () { this.$confirm('是否确认导出所有学员信息项?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -230,12 +252,12 @@ export default { }); }, // 公海按钮点击时间 - handlePublicClue() { + handlePublicClue () { this.$nextTick(() => { this.$refs.publicDialogForm.init(); }); }, - getEmployee() { + getEmployee () { empApi.getEmployee().then((resp) => { if (resp.code === 200) { this.userOptions = resp.data; @@ -243,7 +265,7 @@ export default { }); }, // 批量修改 - handleBatChUpdate() { + handleBatChUpdate () { this.options = { userOptions: this.userOptions }; @@ -254,7 +276,7 @@ export default { }); }, // 登记成交 - async handleSign(item) { + async handleSign (item) { // 根据clueId查询登记信息 let signInfo = {}; this.clueInfo = item; @@ -266,39 +288,37 @@ export default { this.$refs.signDialogForm.init(signInfo); }); }, - //分发到场地 - handleDistribute(item) { - + // 分发到场地 + handleDistribute (item) { this.$nextTick(() => { this.$refs.distributeDialogForm.init(item.clueId); }); }, - //外呼 - handlePhone(item) { + // 外呼 + handlePhone (item) { }, - handleViewZhuangDan(item) { + handleViewZhuangDan (item) { this.$nextTick(() => { this.$refs.zhuangDanDialog.init(item.clueId); }); }, - handleRowClick(row) { + handleRowClick (row) { if (this.quickSearch != 8) { // if(row.source == '抖音直播'){ // this.handleDYAddandUpdate(row); // } else { - this.handleAddandUpdate(row) + this.handleAddandUpdate(row); // } } }, - handleCellClick(row, column, cell, event) { - //如果点击的是备注的话 开始备注编辑框 + handleCellClick (row, column, cell, event) { + // 如果点击的是备注的话 开始备注编辑框 if (column.property == 'clueMemo') { - console.log(row, column, cell, event) + console.log(row, column, cell, event); this.$nextTick(() => { this.$refs.memoDialog.init(row); }); - } } } diff --git a/src/views/zs/feedback/arrival.vue b/src/views/zs/feedback/arrival.vue new file mode 100644 index 0000000..1b397ae --- /dev/null +++ b/src/views/zs/feedback/arrival.vue @@ -0,0 +1,122 @@ +<template> + <div class="app-container" style="width:90%;margin:auto;"> + <!-- 添加或修改线索反馈对话框 --> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="学员姓名"> + <span>{{ order.stuName }}</span> + </el-form-item> + <el-form-item label="联系方式"> + <span>{{ order.phone }}</span> + </el-form-item> + <el-form-item label="地址"> + <span>{{ order.address }}</span> + </el-form-item> + <el-form-item label="接待人"> + <span>{{ order.coachName }}</span> + </el-form-item> + <el-form-item label="到场状态" prop="arrivalStatus"> + <el-radio-group v-model="form.arrivalStatus" size="small" :disabled="type != 'JDR'"> + <el-radio :label="1">未到场</el-radio> + <el-radio :label="2">到场未成交</el-radio> + <el-radio :label="3">到场已成交</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="type != 'JDR'" /> + </el-form-item> + </el-form> + <div v-if="type === 'JDR'" style="text-align: center;"> + <div style="text-align: center;"> + <el-button type="primary" @click="submitForm">提 交</el-button> + </div> + </div> + </div> +</template> + +<script> +import { getFeedbackDetailInfo, addFeedbackDetail, updateFeedbackDetail } from '@/api/zs/feedbackDetail'; + +import { getFeedbackOrder } from '@/api/zs/feedbackOrder'; + +export default { + name: 'Follow', + data () { + return { + // 遮罩层 + loading: true, + // 表单参数 + form: {}, + // 表单校验 + rules: { + }, + order: {}, + orderId: undefined, + type: undefined + }; + }, + created () { + console.log(this.$route.query.no); + this.type = this.$route.query.type; + this.reset(); + this.getFeedbackOrder(this.$route.query.no); + this.getFeedbackDetailInfo(this.$route.query.no); + }, + methods: { + /** 查询线索反馈表单 */ + getFeedbackOrder (orderId) { + this.loading = true; + getFeedbackOrder(orderId).then(response => { + this.order = response.data; + if (this.order.clueId) { + this.form.clueId = this.order.clueId; + } + if (this.order.coachId) { + this.form.coachId = this.order.coachId; + } + if (this.order.orderId) { + this.form.orderId = this.order.orderId; + } + this.loading = false; + }); + }, + /** 查询线索反馈表单 */ + getFeedbackDetailInfo (orderId) { + this.loading = true; + getFeedbackDetailInfo({ orderId: orderId, feedbackType: 2 }).then(response => { + if (response.data) { + this.form = response.data; + } + this.loading = false; + }); + }, + // 表单重置 + reset () { + this.form = { + feedbackId: null, + clueId: null, + feedbackType: 2, + coachId: null, + arrivalStatus: 1, + remark: null + }; + this.resetForm('form'); + }, + /** 提交按钮 */ + submitForm () { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.feedbackId != null) { + updateFeedbackDetail(this.form).then(response => { + this.$modal.msgSuccess('提交成功'); + }); + } else { + addFeedbackDetail(this.form).then(response => { + this.$modal.msgSuccess('提交成功'); + }); + } + } + }); + } + } +}; +</script> diff --git a/src/views/zs/feedback/first.vue b/src/views/zs/feedback/first.vue deleted file mode 100644 index 439d47b..0000000 --- a/src/views/zs/feedback/first.vue +++ /dev/null @@ -1,180 +0,0 @@ -<template> - <div class="app-container" style="width:90%;margin:auto;"> - <!-- 添加或修改线索反馈对话框 --> - <el-form ref="form" :model="form" :rules="rules" label-width="80px"> - <el-form-item label="学员姓名" prop="clueId"> - <el-input v-model="form.clueId" placeholder="请输入线索id" /> - </el-form-item> - <el-form-item label="联系方式" prop="clueId"> - <el-input v-model="form.clueId" placeholder="请输入线索id" /> - </el-form-item> - <el-form-item label="教练id" prop="coachId"> - <el-input v-model="form.coachId" placeholder="请输入教练id" /> - </el-form-item> - <el-form-item label="是否联系" prop="isContact"> - <el-input v-model="form.isContact" placeholder="请输入是否联系" /> - </el-form-item> - <el-form-item label="到场时间" prop="arrivalTime"> - <el-date-picker v-model="form.arrivalTime" clearable type="date" value-format="yyyy-MM-dd" placeholder="请选择到场时间" /> - </el-form-item> - <el-form-item label="备注" prop="remark"> - <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> - </el-form-item> - </el-form> - <div slot="footer" class="dialog-footer"> - <el-button type="primary" @click="submitForm">确 定</el-button> - <el-button @click="cancel">取 消</el-button> - </div> - </div> -</template> - -<script> -import { addFeedback, updateFeedback } from '@/api/zs/feedback'; - -export default { - name: 'First', - data () { - return { - // 遮罩层 - loading: true, - // 选中数组 - ids: [], - // 非单个禁用 - single: true, - // 非多个禁用 - multiple: true, - // 显示搜索条件 - showSearch: true, - // 总条数 - total: 0, - // 线索反馈表格数据 - feedbackList: [], - // 弹出层标题 - title: '', - // 是否显示弹出层 - open: false, - // 查询参数 - queryParams: { - pageNum: 1, - pageSize: 10, - clueId: null, - feedbackType: null, - coachId: null, - content: null, - feedbackTime: null, - isContact: null, - arrivalTime: null, - arrivalStatus: null - }, - // 表单参数 - form: {}, - // 表单校验 - rules: { - } - }; - }, - created () { - this.getList(); - }, - methods: { - /** 查询线索反馈列表 */ - getList () { - this.loading = true; - listFeedback(this.queryParams).then(response => { - this.feedbackList = response.rows; - this.total = response.total; - this.loading = false; - }); - }, - // 取消按钮 - cancel () { - this.open = false; - this.reset(); - }, - // 表单重置 - reset () { - this.form = { - feedbackId: null, - clueId: null, - feedbackType: null, - coachId: null, - content: null, - feedbackTime: null, - isContact: null, - arrivalTime: null, - arrivalStatus: 0, - remark: null - }; - this.resetForm('form'); - }, - /** 搜索按钮操作 */ - handleQuery () { - this.queryParams.pageNum = 1; - this.getList(); - }, - /** 重置按钮操作 */ - resetQuery () { - this.resetForm('queryForm'); - this.handleQuery(); - }, - // 多选框选中数据 - handleSelectionChange (selection) { - this.ids = selection.map(item => item.feedbackId); - this.single = selection.length !== 1; - this.multiple = !selection.length; - }, - /** 新增按钮操作 */ - handleAdd () { - this.reset(); - this.open = true; - this.title = '添加线索反馈'; - }, - /** 修改按钮操作 */ - handleUpdate (row) { - this.reset(); - const feedbackId = row.feedbackId || this.ids; - getFeedback(feedbackId).then(response => { - this.form = response.data; - this.open = true; - this.title = '修改线索反馈'; - }); - }, - /** 提交按钮 */ - submitForm () { - this.$refs['form'].validate(valid => { - if (valid) { - if (this.form.feedbackId != null) { - updateFeedback(this.form).then(response => { - this.$modal.msgSuccess('修改成功'); - this.open = false; - this.getList(); - }); - } else { - addFeedback(this.form).then(response => { - this.$modal.msgSuccess('新增成功'); - this.open = false; - this.getList(); - }); - } - } - }); - }, - /** 删除按钮操作 */ - handleDelete (row) { - const feedbackIds = row.feedbackId || this.ids; - this.$modal.confirm('是否确认删除线索反馈编号为"' + feedbackIds + '"的数据项?').then(function () { - return delFeedback(feedbackIds); - }).then(() => { - this.getList(); - this.$modal.msgSuccess('删除成功'); - }).catch(() => { }); - }, - /** 导出按钮操作 */ - handleExport () { - this.download('system/feedback/export', { - ...this.queryParams - }, `feedback_${new Date().getTime()}.xlsx`); - } - } -}; -</script> diff --git a/src/views/zs/feedback/follow.vue b/src/views/zs/feedback/follow.vue new file mode 100644 index 0000000..9c0e179 --- /dev/null +++ b/src/views/zs/feedback/follow.vue @@ -0,0 +1,126 @@ +<template> + <div class="app-container" style="width:90%;margin:auto;"> + <!-- 添加或修改线索反馈对话框 --> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="学员姓名"> + <span>{{ order.stuName }}</span> + </el-form-item> + <el-form-item label="联系方式"> + <span>{{ order.phone }}</span> + </el-form-item> + <el-form-item label="地址"> + <span>{{ order.address }}</span> + </el-form-item> + <el-form-item label="接待人" prop="coachId"> + <span>{{ order.coachName }}</span> + </el-form-item> + <el-form-item label="是否联系" prop="isContact"> + <el-radio-group v-model="form.isContact" size="small" :disabled="type != 'JDR'"> + <el-radio :label="1">是</el-radio> + <el-radio :label="0">否</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="到场时间" prop="arrivalTime"> + <el-date-picker v-model="form.arrivalTime" :disabled="type != 'JDR'" clearable type="datetime" format="yyyy-MM-dd HH:mm" value-format="yyyy-MM-dd HH:mm" placeholder="请选择到场时间" /> + </el-form-item> + <el-form-item label="备注" prop="remark"> + <el-input v-model="form.remark" :disabled="type != 'JDR'" type="textarea" placeholder="请输入内容" /> + </el-form-item> + </el-form> + <div v-if="type === 'JDR'" style="text-align: center;"> + <div style="text-align: center;"> + <el-button type="primary" @click="submitForm">提 交</el-button> + </div> + </div> + </div> +</template> + +<script> +import { getFeedbackDetailInfo, addFeedbackDetail, updateFeedbackDetail } from '@/api/zs/feedbackDetail'; + +import { getFeedbackOrder } from '@/api/zs/feedbackOrder'; + +export default { + name: 'Follow', + data () { + return { + // 遮罩层 + loading: true, + // 表单参数 + form: {}, + // 表单校验 + rules: { + }, + order: {}, + orderId: undefined, + type: undefined + }; + }, + created () { + console.log(this.$route.query.no); + this.type = this.$route.query.type; + this.reset(); + this.getFeedbackOrder(this.$route.query.no); + this.getFeedbackDetailInfo(this.$route.query.no); + }, + methods: { + /** 查询线索反馈表单 */ + getFeedbackOrder (orderId) { + this.loading = true; + getFeedbackOrder(orderId).then(response => { + this.order = response.data; + if (this.order.clueId) { + this.form.clueId = this.order.clueId; + } + if (this.order.coachId) { + this.form.coachId = this.order.coachId; + } + if (this.order.orderId) { + this.form.orderId = this.order.orderId; + } + this.loading = false; + }); + }, + /** 查询线索反馈表单 */ + getFeedbackDetailInfo (orderId) { + this.loading = true; + getFeedbackDetailInfo({ orderId: orderId, feedbackType: 1 }).then(response => { + if (response.data) { + this.form = response.data; + } + this.loading = false; + }); + }, + // 表单重置 + reset () { + this.form = { + feedbackId: null, + clueId: null, + feedbackType: 1, + coachId: null, + feedbackTime: null, + isContact: 0, + arrivalTime: null, + remark: null + }; + this.resetForm('form'); + }, + /** 提交按钮 */ + submitForm () { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.feedbackId != null) { + updateFeedbackDetail(this.form).then(response => { + this.$modal.msgSuccess('提交成功'); + }); + } else { + addFeedbackDetail(this.form).then(response => { + this.$modal.msgSuccess('提交成功'); + }); + } + } + }); + } + } +}; +</script>