Commit 184dfba1 authored by xinla's avatar xinla
Browse files

Merge branch 'front_end_dev_1.5'

parents 25389524 6e368308
Showing with 980 additions and 761 deletions
+980 -761
# 开发环境配置
ENV = 'development'
# 仟微管理系统/开发环境
VUE_APP_BASE_API = 'http://demo.linkwechat.cn/api'
# VUE_APP_BASE_API = 'http://n3rpzt.natappfree.cc'
# 基础api(根据实际情况,自行配置,下为示例)
VUE_APP_BASE_API = 'http://demo.linkwechat.cn'
# 开发环境IP
VUE_APP_BASE_URL = 'http://119.45.28.29:8090'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 生产环境配置
ENV = 'production'
# 仟微管理系统/生产环境api
VUE_APP_BASE_API = 'http://119.45.28.29:8090'
# 基础api
VUE_APP_BASE_API = 'http://demo.linkwechat.cn'
# 生产环境IP
VUE_APP_BASE_URL = 'http://119.45.28.29:8090'
# 路由基础路径
VUE_APP_BASE_URL = '/'
\ No newline at end of file
# 测试环境配置
ENV = 'test'
# 基础api
VUE_APP_BASE_API = 'http://demo.linkwechat.cn'
# 路由基础路径
VUE_APP_BASE_URL = '/test/'
# Do not edit. File was generated by node-gyp's "configure" step
{
"target_defaults": {
"cflags": [],
"default_configuration": "Release",
"defines": [],
"include_dirs": [],
"libraries": [],
"msbuild_toolset": "v141",
"msvs_windows_target_platform_version": "10.0.17763.0"
},
"variables": {
"asan": 0,
"build_v8_with_gn": "false",
"coverage": "false",
"dcheck_always_on": 0,
"debug_nghttp2": "false",
"debug_node": "false",
"enable_lto": "false",
"enable_pgo_generate": "false",
"enable_pgo_use": "false",
"error_on_warn": "false",
"force_dynamic_crt": 0,
"host_arch": "x64",
"icu_data_in": "..\\..\\deps\\icu-tmp\\icudt67l.dat",
"icu_endianness": "l",
"icu_gyp_path": "tools/icu/icu-generic.gyp",
"icu_path": "deps/icu-small",
"icu_small": "false",
"icu_ver_major": "67",
"is_debug": 0,
"napi_build_version": "7",
"nasm_version": "2.14",
"node_byteorder": "little",
"node_debug_lib": "false",
"node_enable_d8": "false",
"node_install_npm": "true",
"node_module_version": 83,
"node_no_browser_globals": "false",
"node_prefix": "/usr/local",
"node_release_urlbase": "https://nodejs.org/download/release/",
"node_shared": "false",
"node_shared_brotli": "false",
"node_shared_cares": "false",
"node_shared_http_parser": "false",
"node_shared_libuv": "false",
"node_shared_nghttp2": "false",
"node_shared_openssl": "false",
"node_shared_zlib": "false",
"node_tag": "",
"node_target_type": "executable",
"node_use_bundled_v8": "true",
"node_use_dtrace": "false",
"node_use_etw": "true",
"node_use_node_code_cache": "true",
"node_use_node_snapshot": "true",
"node_use_openssl": "true",
"node_use_v8_platform": "true",
"node_with_ltcg": "true",
"node_without_node_options": "false",
"openssl_fips": "",
"openssl_is_fips": "false",
"ossfuzz": "false",
"shlib_suffix": "so.83",
"target_arch": "x64",
"v8_enable_31bit_smis_on_64bit_arch": 0,
"v8_enable_gdbjit": 0,
"v8_enable_i18n_support": 1,
"v8_enable_inspector": 1,
"v8_enable_lite_mode": 0,
"v8_enable_object_print": 1,
"v8_enable_pointer_compression": 0,
"v8_no_strict_aliasing": 1,
"v8_optimized_debug": 1,
"v8_promise_internal_field_count": 1,
"v8_random_seed": 0,
"v8_trace_maps": 0,
"v8_use_siphash": 1,
"want_separate_host_toolset": 0,
"nodedir": "C:\\Users\\77514\\AppData\\Local\\node-gyp\\Cache\\14.15.0",
"standalone_static_library": 1,
"msbuild_path": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\MSBuild\\15.0\\Bin\\MSBuild.exe"
}
}
......@@ -6,6 +6,7 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build:test": "vue-cli-service build --mode test",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
......
......@@ -7,7 +7,7 @@ const service = window.CONFIG.services.wecom + '/weapp'
*/
export function getList() {
return request({
url: service + '/list',
url: service + '/list'
})
}
......@@ -30,6 +30,15 @@ export function update(data) {
return request({
url: service + '/updateWeApp',
method: 'put',
data,
data
})
}
// 添加
export function add(data) {
return request({
url: service + '/addWeApp',
method: 'post',
data
})
}
import request from '@/utils/request'
const getTree = (params) => {
const getExternalChatList = (params) => {
return request({
url: '/chat/mapping/list',
url: '/chat/msg/selectExternalChatList/'+ params.fromId,
method: 'get'
})
}
const selectAloneChatList = (params) => {
return request({
url: '/chat/msg/selectAloneChatList\n/',
method: 'get',
params,
params
})
}
const getInternalChatList = (params) => {
return request({
url: '/chat/msg/selectInternalChatList/'+ params.fromId,
method: 'get'
})
}
const getGroupChatList = (params) => {
return request({
url: '/chat/msg/selectGroupChatList/'+ params.fromId,
method: 'get'
})
}
const chatList = (params) => {
return request({
url: '/wecom/finance/getChatContactList',
url: '/chat/msg/list',
method: 'get',
params,
})
......@@ -26,14 +48,7 @@ const indexEchart = () => {
method: 'get'
})
}
//
const chatGrounpList = (params) => {
return request({
url: '/wecom/finance/getChatRoomContactList',
method: 'get',
params,
})
}
const listByCustomer = (params) => {
return request({
url: '/wecom/customer/list',
......@@ -41,9 +56,9 @@ const listByCustomer = (params) => {
params,
})
}
const getChatAllList = (params) => {
const getFullSearchChatList = (params) => {
return request({
url: '/wecom/finance/getChatAllList',
url: '/chat/msg/selectFullSearchChatList',
method: 'get',
params,
})
......@@ -52,9 +67,11 @@ const getChatAllList = (params) => {
export const content = {
indexEchart,
indexTable,
getTree,
getExternalChatList,
selectAloneChatList,
getInternalChatList,
getGroupChatList,
chatList,
listByCustomer,
getChatAllList,
chatGrounpList
getFullSearchChatList
}
......@@ -113,6 +113,9 @@ export default {
this.$emit('update:fileName', res.data.fileName)
this.$emit('update:file', file)
// this.fileUrl = URL.createObjectURL(file.raw)
} else {
this.loading = false
this.$message.error(res.msg)
}
},
onError(err, file, fileList) {
......
......@@ -6,129 +6,138 @@ const baseURL = process.env.VUE_APP_BASE_API
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['', '', '', '', '', '', ''][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/')
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['', '', '', '', '', '', ''][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
if (this.$refs[refName]) {
this.$refs[refName].resetFields()
}
}
//年月日格式
export function yearMouthDay(data) {
var time = new Date(data);
var year = time.getFullYear();
var month = time.getMonth()+1;
var date = time.getDate();
console.log(year+'-'+add0(month)+'-'+add0(date))
return year+'-'+add0(month)+'-'+add0(date)
var time = new Date(data)
var year = time.getFullYear()
var month = time.getMonth() + 1
var date = time.getDate()
console.log(year + '-' + add0(month) + '-' + add0(date))
return year + '-' + add0(month) + '-' + add0(date)
}
function add0(m) {
return m < 10 ? '0' + m : m
}
function add0(m){return m<10?'0'+m:m }
// 添加日期范围
export function addDateRange(params, dateRange) {
var search = params;
search.beginTime = "";
search.endTime = "";
if (null != dateRange && '' != dateRange) {
search.beginTime = this.dateRange[0];
search.endTime = this.dateRange[1];
}
return search;
var search = params
search.beginTime = ''
search.endTime = ''
if (null != dateRange && '' != dateRange) {
search.beginTime = this.dateRange[0]
search.endTime = this.dateRange[1]
}
return search
}
// 回显数据字典
export function selectDictLabel(datas, value) {
var actions = [];
Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + value)) {
actions.push(datas[key].dictLabel);
return true;
}
})
return actions.join('');
var actions = []
Object.keys(datas).some((key) => {
if (datas[key].dictValue == '' + value) {
actions.push(datas[key].dictLabel)
return true
}
})
return actions.join('')
}
// 回显数据字典(字符串数组)
export function selectDictLabels(datas, value, separator) {
var actions = [];
var currentSeparator = undefined === separator ? "," : separator;
var temp = value.split(currentSeparator);
Object.keys(value.split(currentSeparator)).some((val) => {
Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + temp[val])) {
actions.push(datas[key].dictLabel + currentSeparator);
}
})
})
return actions.join('').substring(0, actions.join('').length - 1);
var actions = []
var currentSeparator = undefined === separator ? ',' : separator
var temp = value.split(currentSeparator)
Object.keys(value.split(currentSeparator)).some((val) => {
Object.keys(datas).some((key) => {
if (datas[key].dictValue == '' + temp[val]) {
actions.push(datas[key].dictLabel + currentSeparator)
}
})
})
return actions.join('').substring(0, actions.join('').length - 1)
}
// 通用下载方法
export function download(fileName) {
window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
window.location.href =
baseURL +
'/common/download?fileName=' +
encodeURI(fileName) +
'&delete=' +
true
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
if (typeof arg === 'undefined') {
flag = false;
return '';
}
return arg;
});
return flag ? str : '';
var args = arguments,
flag = true,
i = 1
str = str.replace(/%s/g, function() {
var arg = args[i++]
if (typeof arg === 'undefined') {
flag = false
return ''
}
return arg
})
return flag ? str : ''
}
// 转换字符串,undefined,null等转化为""
export function praseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return "";
}
return str;
if (!str || str == 'undefined' || str == 'null') {
return ''
}
return str
}
/**
......@@ -139,70 +148,46 @@ export function praseStrEmpty(str) {
* @param {*} children 孩子节点字段 默认 'children'
*/
export function handleTree(data, id, parentId, children) {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
let result = [];
data = JSON.parse(JSON.stringify(data))
if (!Array.isArray(data)) {
return result
}
data.forEach(item => {
delete item[children];
});
let map = {};
data.forEach(item => {
map[item[id]] = item;
});
data.forEach(item => {
let parent = map[item[parentId]];
if (parent) {
parent[children] || (parent[children] = [])
parent[children].push(item);
} else {
result.push(item);
}
});
return result;
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
let result = []
data = JSON.parse(JSON.stringify(data))
if (!Array.isArray(data)) {
return result
}
data.forEach((item) => {
delete item[children]
})
let map = {}
data.forEach((item) => {
map[item[id]] = item
})
data.forEach((item) => {
let parent = map[item[parentId]]
if (parent) {
parent[children] || (parent[children] = [])
parent[children].push(item)
} else {
result.push(item)
}
})
return result
}
/**
* dataURL转化为File对象
* @param {*} dataURL 本地数据 base64
*/
export function dataURLtoFile (dataURL) {
const arr = dataURL.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n) {
u8arr[n - 1] = bstr.charCodeAt(n - 1)
n -= 1 // to make eslint happy
}
return new File([u8arr], '', { type: mime })
}
/**
* 整理echat 数据
* @param {*} arrData 数据
*/
export function arrData (data) {
let obj={
arr1:[],
arr2:[],
arr3:[],
arr4:[],
btm1:[],
}
data.forEach((a,b)=>{
obj.arr1.push(a.newApplyCnt)
obj.btm1.push(a.xtime)
obj.arr3.push(a.newMemberCnt)
obj.arr2.push(a.newContactCnt)
obj.arr4.push(a.negativeFeedbackCnt)
})
console.log(obj)
return obj
export function dataURLtoFile(dataURL) {
const arr = dataURL.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n) {
u8arr[n - 1] = bstr.charCodeAt(n - 1)
n -= 1 // to make eslint happy
}
return new File([u8arr], '', { type: mime })
}
<script>
import { getList, update } from '@/api/appTool/selfApp'
import { getList, update, add } from '@/api/appTool/selfApp'
// import clipboard from "clipboard";
export default {
......@@ -73,7 +73,7 @@ export default {
submit() {
this.$refs['form'].validate((valid) => {
if (valid) {
update(this.form)
;(this.form.id ? update : add)(this.form)
.then(() => {
this.msgSuccess('操作成功')
this.dialogVisible = false
......@@ -262,6 +262,8 @@ export default {
display: flex;
border: 1px solid #eee;
margin: 0 20px 20px 0;
background: #fff;
border-radius: 6px;
.el-image {
margin-right: 10px;
width: 50px;
......
......@@ -98,7 +98,7 @@ export default {
>
</el-form-item>
</el-form>
<el-table :data="tableData" border style="width: 100%">
<el-table :data="tableData">
<el-table-column prop="taskName" label="群裂变名称"> </el-table-column>
<el-table-column prop="fissNum" label="裂变客户数量"> </el-table-column>
<el-table-column prop="fissStatus" label="活动状态">
......
......@@ -218,7 +218,11 @@ export default {
components: { PhoneDialog, SelectMaterial, SelectCustomerGroup },
data() {
const checkContent = (rule, value, callback) => {
if (!this.form.content && this.form.picList.length === 0 && this.form.materialIdList.length === 0) {
if (
!this.form.content &&
this.form.picList.length === 0 &&
this.form.materialIdList.length === 0
) {
callback(new Error('该项为必填项'))
} else {
callback()
......@@ -246,7 +250,10 @@ export default {
pickerOptions: {
disabledDate(time) {
// return time.getTime() < Date.now()
return time.getTime() < new Date(new Date(new Date().toLocaleDateString()).getTime())
return (
time.getTime() <
new Date(new Date(new Date().toLocaleDateString()).getTime())
)
}
},
uploadImageUrl: '',
......@@ -256,9 +263,7 @@ export default {
ruleName: [
{ required: true, message: '该项为必填项', trigger: 'blur' }
],
title: [
{ required: true, message: '该项为必填项', trigger: 'blur' }
],
title: [{ required: true, message: '该项为必填项', trigger: 'blur' }],
chatIdList: [
{ required: true, message: '该项为必填项', trigger: 'change' }
],
......@@ -268,8 +273,8 @@ export default {
content: [
// { required: true, message: '该项为必填项', trigger: 'change' },
{ validator: checkContent, trigger: 'change' }
],
}),
]
})
}
},
watch: {
......@@ -279,7 +284,7 @@ export default {
this.form.startExeTime = ''
this.form.stopExeTime = ''
} else {
[ this.form.startExeTime, this.form.stopExeTime ] = dateRange
;[this.form.startExeTime, this.form.stopExeTime] = dateRange
}
},
customerGroups(groups) {
......@@ -293,11 +298,11 @@ export default {
},
computed: {
imageMaterialUrls() {
const urls = this.imageMaterialList.map(m => m.materialUrl)
const urls = this.imageMaterialList.map((m) => m.materialUrl)
return urls
},
messageList() {
const texts = this.textMaterialList.map(t => t.content)
const texts = this.textMaterialList.map((t) => t.content)
return texts
},
imageList() {
......@@ -313,37 +318,44 @@ export default {
/** 获取详情 */
getDetail(id) {
this.loading = true
getDetail(id)
.then(({ data }) => {
this.dateRange = [data.startExeTime || '', data.stopExeTime || '']
this.customerGroups = data.groupList || []
this.form.ruleName = data.ruleName || ''
this.form.title = data.title || ''
this.form.content = data.content || ''
this.form.picList = data.picList || []
getDetail(id).then(({ data }) => {
this.dateRange = [data.startExeTime || '', data.stopExeTime || '']
this.customerGroups = data.groupList || []
this.form.materialIdList = []
this.form.ruleName = data.ruleName || ''
this.form.title = data.title || ''
this.form.content = data.content || ''
this.form.picList = data.picList || []
const materialList = data.materialList || []
this.form.materialIdList = []
for (let material of materialList) {
if (material.materialUrl) {
this.imageMaterialList.push(material)
} else {
this.textMaterialList.push(material)
}
const materialList = data.materialList || []
this.form.materialIdList.push(material.id)
for (let material of materialList) {
if (material.materialUrl) {
this.imageMaterialList.push(material)
} else {
this.textMaterialList.push(material)
}
this.loading = false
})
this.form.materialIdList.push(material.id)
}
this.loading = false
})
},
// 选择素材确认按钮
submitSelectMaterial(text, image, file) {
text && text.id && !this.form.materialIdList.includes(text.id) && this.form.materialIdList.push(text.id) && this.textMaterialList.push(text)
image && image.id && !this.form.materialIdList.includes(image.id) && this.form.materialIdList.push(image.id) && this.imageMaterialList.push(image)
text &&
text.id &&
!this.form.materialIdList.includes(text.id) &&
this.form.materialIdList.push(text.id) &&
this.textMaterialList.push(text)
image &&
image.id &&
!this.form.materialIdList.includes(image.id) &&
this.form.materialIdList.push(image.id) &&
this.imageMaterialList.push(image)
this.$refs.form.validateField('content')
},
// 选择客户群聊确认
......@@ -379,22 +391,25 @@ export default {
})
},
goRoute() {
const pathName = this.activeName === '0' ? 'Text' : 'Image'
this.$router.push({
name: pathName,
})
let contentType = ['text', 'image', 'file']
window.open('#/customerMaintain/material/' + contentType[this.activeName])
},
removeImage(url) {
this.form.picList.splice(this.form.picList.indexOf(url), 1)
},
removeImageMaterial(image) {
this.imageMaterialList.splice(this.imageMaterialList.indexOf(image), 1)
this.form.materialIdList.splice(this.form.materialIdList.indexOf(image.id), 1)
this.form.materialIdList.splice(
this.form.materialIdList.indexOf(image.id),
1
)
},
removeTextMaterial(text) {
this.textMaterialList.splice(this.textMaterialList.indexOf(text), 1)
this.form.materialIdList.splice(this.form.materialIdList.indexOf(text.id), 1)
this.form.materialIdList.splice(
this.form.materialIdList.indexOf(text.id),
1
)
}
}
}
......@@ -402,12 +417,7 @@ export default {
<template>
<div class="wrap" v-loading="loading">
<el-form
:model="form"
ref="form"
:rules="rules"
label-width="100px"
>
<el-form :model="form" ref="form" :rules="rules" label-width="100px">
<el-form-item label="规则名称" prop="ruleName">
<el-input
v-model="form.ruleName"
......@@ -444,10 +454,7 @@ export default {
clearable
></el-input>
</el-form-item>
<el-form-item
label="执行时间"
prop="startExeTime"
>
<el-form-item label="执行时间" prop="startExeTime">
<el-date-picker
v-model="dateRange"
value-format="yyyy-MM-dd HH:mm:ss"
......@@ -505,11 +512,7 @@ export default {
@click="removeImageMaterial(image)"
></el-button>
</div>
<div
v-for="url in form.picList"
:key="url"
class="image-wrapper"
>
<div v-for="url in form.picList" :key="url" class="image-wrapper">
<el-image :src="url" fit="fit"></el-image>
<el-button
icon="el-icon-close"
......@@ -519,10 +522,7 @@ export default {
></el-button>
</div>
<upload
:fileUrl.sync="uploadImageUrl"
class="image-uploader"
>
<upload :fileUrl.sync="uploadImageUrl" class="image-uploader">
<i class="el-icon-plus uploader-icon"></i>
</upload>
</el-tab-pane>
......@@ -655,7 +655,8 @@ export default {
top: 5px;
}
}
.text-wrapper, .image-wrapper {
.text-wrapper,
.image-wrapper {
margin: 5px;
.remove-btn {
......
......@@ -4,40 +4,40 @@
<li v-for="(item, index) in allChat" :key="index">
<!-- <span v-if="item.fromInfo.name">{{item.fromInfo.name}}</span> -->
<div :style="{ color: item.action == 'send' ? '#199ed8' : '#999' }">
<span v-if="item.fromInfo">{{ item.fromInfo.name }}</span>
<span v-if="item">{{ item.name }}</span>
<span
:style="{ color: item.action == 'send' ? '#199ed8' : '#999' }"
>{{ parseTime(item.msgTime) }}</span
>{{ item.msgTime }}</span
>
</div>
<div v-if="item.msgType == 'text'" class="msgtypetext">
{{ item.text.content }}
{{ JSON.parse(item.contact).content }}
</div>
<div v-else-if="item.msgType == 'image'" class="msgtypeimg">
<img :src="item.image.attachment" @click="showImg(item)" />
<img :src="JSON.parse(item.contact).attachment" @click="showImg(JSON.parse(item.contact))" />
</div>
<div
v-else-if="item.msgType == 'file'"
class="msgtypefile"
@click="down(item.file)"
@click="down(JSON.parse(item.contact))"
>
{{ item.file.fileName }}
{{ JSON.parse(item.contact).fileName }}
</div>
<div v-else-if="item.msgType == 'voice'" class="msgtypevoice">
<i
class="el-icon-microphone"
style=" font-size: 40px; color: #199ed8;"
@click="playVideo(item)"
@click="playVideo(JSON.parse(item.contact))"
></i>
</div>
<div v-else-if="item.msgType == 'emotion'" class="msgtypeimg">
<img :src="item.emotion.attachment" @click="showImg(item)" />
<img :src="JSON.parse(item.contact).attachment" @click="showImg(item)" />
</div>
<div v-else-if="item.msgType == 'video'" class="msgtypevideo">
<i
class="el-icon-video-play"
style=" font-size: 40px; color: #199ed8;"
@click="play(item, 'video')"
@click="play(JSON.parse(item.contact), 'video')"
></i>
</div>
<div v-else-if="item.msgType == 'location'" class="msgtypecard">
......@@ -45,24 +45,24 @@
<el-amap
ref="map"
vid="amapDemo"
:center="[item.location.longitude, item.location.latitude]"
:center="[JSON.parse(item.contact).longitude, JSON.parse(item.contact).latitude]"
:zoom="zoom"
class="amap-demo"
style="pointer-events: none;"
>
<el-amap-marker
:position="[item.location.longitude, item.location.latitude]"
:position="[JSON.parse(item.contact).longitude, iJSON.parse(item.contact).latitude]"
></el-amap-marker>
</el-amap>
</div>
<div class="card_foot">{{ item.location.address }}</div>
<div class="card_foot">{{ JSON.parse(item.contact).address }}</div>
</div>
<div v-else-if="item.msgType == 'weapp'" class="msgtypecard">
<div class="card_name">{{ item.weApp.title }}</div>
<div class="card_name">{{ JSON.parse(item.contact).title }}</div>
<div class="card_foot">小程序</div>
</div>
<div v-else-if="item.msgType == 'card'" class="msgtypecard ">
<div class="card_name">{{ item.card.corpName }}</div>
<div class="card_name">{{ JSON.parse(item.contact).corpName }}</div>
<div class="card_foot">个人名片</div>
</div>
</li>
......@@ -165,20 +165,20 @@ export default {
mp3.pause()
},
playVideo(e) {
this.vioceSrc = [e.voice.attachment]
this.vioceSrc = [e.attachment]
this.diavioce = true
},
onBeforePlay(next) {
next() // 开始播放
},
showImg(e) {
this.imgSrc = e.image.attachment
this.imgSrc = e.attachment
this.dialogVisible = true
},
play(e) {
this.dia = true
const player = this.$refs.videoPlayer.player
this.playerOptions['sources'][0]['src'] = e.video.attachment
this.playerOptions['sources'][0]['src'] = e.attachment
player.play()
},
down(e) {
......
......@@ -8,18 +8,14 @@
@click="liClick(item)"
>
<el-row style="padding:10px">
<el-col :span="3"
><img :src="item.receiveWeUser.avatarMediaid"
/></el-col>
<el-col :span="3"><img :src="item.avatar"/></el-col>
<el-col :span="21">
<p>
{{ item.receiveWeUser.name }}
<span class="fr gray">{{
parseTime(item.finalChatContext.msgtime)
}}</span>
{{ item.name }}
<span class="fr gray">{{ item.msgTime }}</span>
</p>
<p class="gray padt10" v-if="item.finalChatContext.text">
{{ item.finalChatContext.text.content }}
<p class="gray padt10" v-if="item.contact">
{{ JSON.parse(item.contact).content }}
</p>
</el-col>
</el-row>
......@@ -58,7 +54,7 @@ export default {
<style lang="scss" scoped>
.list {
overflow-y: scroll;
height: 651px;
height: calc(100vh - 328px);
::-webkit-scrollbar {
display: none;
}
......
<template>
<div class="list" v-loading="loading">
<div v-if="personList">
<div v-if="personList.length">
<ul>
<li
v-for="(item, index) in personList"
:key="index"
@click="liClick(item)"
>
<el-row
style="padding:10px"
v-if="item.finalChatContext.msgtype == 'text'"
>
<span class="fl">
<div class="ninebox">
<ul v-if="item.roomInfo">
<li
v-for="(a, i) in item.roomInfo.avatar.split(',')"
:key="i"
>
<img :src="a" />
</li>
</ul>
</div>
</span>
<span class="fl" style="margin-left:8px;line-height:60px">
<el-row type="flex" v-if="item.msgType == 'text'">
<div class="ninebox">
<ul v-if="item.avatar">
<li v-for="(a, i) in item.avatar.split(',')" :key="i">
<img :src="a" />
</li>
</ul>
</div>
<div class="fl" style="margin-left:8px;line-height:60px">
<p>
{{ item.finalChatContext.roomInfo.name }}
<span class="fr gray">{{
parseTime(item.finalChatContext.fromInfo.updateTime)
}}</span>
{{ item.name }}
<!-- <span class="fr gray">{{ item.msgTime }}</span> -->
</p>
<p class="gray" v-if="item.finalChatContext.fromInfo">
{{ item.finalChatContext.fromInfo.name }}:{{
item.finalChatContext.text.content
}}
</p>
</span>
<!-- <p class="gray" v-if="item">
{{ item.name }}:
{{ item.content }}
</p> -->
</div>
</el-row>
<!-- <el-row style="padding:10px" v-if="item.finalChatContext.msgtype=='file'">
<el-col :span="3">&nbsp;</el-col>
......@@ -43,13 +32,15 @@
<p><span class="fr gray">{{parseTime(item.finalChatContext.msgtime)}}</span></p>
<p class="gray padt10" >{{item.finalChatContext.from}}:
<span v-if="item.finalChatContext.file.fileext=='mp4'">[视频]</span>
</p>
</p>
</el-col>
</el-row> -->
</li>
</ul>
</div>
<div v-else></div>
<div class="ac" v-else>
暂无数据
</div>
</div>
</template>
<script>
......@@ -80,6 +71,7 @@ export default {
</script>
<style lang="scss" scoped>
.ninebox {
flex: none;
width: 54px;
height: 52px;
border: 1px solid #199ed8;
......@@ -93,6 +85,7 @@ export default {
}
.list {
overflow-y: scroll;
height: calc(100vh - 328px);
::-webkit-scrollbar {
display: none;
......
<template>
<div class="list" v-loading="loading">
<div v-if="personList.length >= 1">
<div v-if="personList.length">
<ul>
<li
v-for="(item, index) in personList"
......@@ -8,17 +8,17 @@
@click="liClick(item)"
>
<el-row style="padding:10px">
<span class="fl">
<img :src="item.finalChatContext.fromInfo.avatarMediaid"
/></span>
<span class="fl"> <img :src="item.avatar"/></span>
<span class="fl" style="margin-left:8px">
<p>{{ item.finalChatContext.fromInfo.name }}</p>
<p>{{ item.name }}</p>
</span>
</el-row>
</li>
</ul>
</div>
<div v-else></div>
<div class="ac" v-else>
暂无数据
</div>
</div>
</template>
<script>
......@@ -51,7 +51,8 @@ export default {
<style lang="scss" scoped>
.list {
overflow-y: scroll;
height: 708px;
height: calc(100vh - 328px);
::-webkit-scrollbar {
display: none;
}
......
<template>
<div class="list" v-loading="loading">
<div v-if="personList.length >= 1">
<div v-if="personList.length">
<ul>
<li
v-for="(item, index) in personList"
:key="index"
@click="liClick(item)"
>
<el-row style="padding:10px">
<span class="fl"> <img :src="item.receiveWeCustomer.avatar"/></span>
<el-row>
<span class="fl"> <img :src="item.avatar"/></span>
<span class="fl" style="margin-left:8px">
<p>{{ item.receiveWeCustomer.name }}</p>
<p>{{ item.name }}</p>
</span>
<!-- <span class="fl">
<p>{{ item.contact }}</p>
</span> -->
</el-row>
</li>
</ul>
</div>
<div v-else></div>
<div class="ac" v-else>
暂无数据
</div>
</div>
</template>
<script>
......@@ -32,7 +37,6 @@ export default {
defluat: false
}
},
data() {
return {
loadings: true
......@@ -42,6 +46,14 @@ export default {
liClick(e) {
console.log(e, 'liClick')
this.$emit('chatFn', e)
},
msgContentType(type, msg) {
console.log(type, msg, 'msgContentType')
//消息获取
/*case msg = JSON.parse(msg);
switch (type){
case "text":
}*/
}
}
}
......@@ -49,7 +61,7 @@ export default {
<style lang="scss" scoped>
.list {
overflow-y: scroll;
height: 708px;
height: calc(100vh - 328px);
::-webkit-scrollbar {
display: none;
}
......
This diff is collapsed.
<template>
<div>
<el-form :inline="true" :model="form" class="demo-form-inline">
<el-row>
<el-form-item label="员工名称">
<el-input v-model="form.Ename" placeholder="客户名称" style="width:300px"></el-input>
</el-form-item>
<el-form-item label="客户名称">
<el-input v-model="form.Cname" placeholder="客户名称" style="width:300px"></el-input>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="查找内容">
<el-input v-model="form.Scontent" placeholder="查找内容" style="width:300px"></el-input>
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker v-model="form.Stime" type="datetimerange" format='yyyy-MM-dd' range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期" align="right">
</el-date-picker>
</el-form-item>
</el-row>
<el-row>
<el-form-item>
<el-button type="primary" @click="init">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>导出列表</el-button>
</el-form-item>
</el-row>
<el-form :inline="true" :model="form" class="top-serach">
<el-form-item label="员工名称">
<el-input v-model="form.Ename" placeholder="客户名称"></el-input>
</el-form-item>
<el-form-item label="客户名称">
<el-input v-model="form.Cname" placeholder="客户名称"></el-input>
</el-form-item>
<el-form-item label="查找内容">
<el-input v-model="form.Scontent" placeholder="查找内容"></el-input>
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker
v-model="form.Stime"
type="datetimerange"
format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right"
>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="init">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>导出列表</el-button>
</el-form-item>
</el-form>
<div class="content">
<el-table :data="fileData" stripe style="width: 100%" :header-cell-style="{background:'#fff'}">
<div>
<el-table
:data="fileData"
stripe
style="width: 100%"
:header-cell-style="{ background: '#fff' }"
>
<el-table-column prop="date" label="发送者" width="180">
<template slot-scope="scope">
<p v-if="scope.row.fromInfo">{{scope.row.fromInfo.name}}</p>
<p v-if="scope.row">{{ scope.row.name }}</p>
</template>
</el-table-column>
<el-table-column prop="name" label=" 内容">
<template slot-scope="scope">
<p v-if="!!scope.row.content" class="emcode" v-html="scope.row.content"></p>
<p v-else-if="!!!scope.row.content&&scope.row.text">{{scope.row.text.content}}</p>
<p
v-if="!!scope.row.contact"
class="emcode"
v-html="scope.row.contact"
></p>
<p v-else-if="!!!scope.row.contact && scope.row.text">
{{ JSON.parse(scope.row.contact).content }}
</p>
</template>
</el-table-column>
<el-table-column label="消息状态" width="200">
<template slot="header">
{{floorRange}}
<el-select size="mini" v-model="floorRange" class="noborder" @change="chechName(floorRange)">
<el-option v-for="item in displayOptions" :key="item.value" :label="item.label" :value="item.value">
{{ floorRange }}
<el-select
size="mini"
v-model="floorRange"
class="noborder"
@change="chechName(floorRange)"
>
<el-option
v-for="item in displayOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</template>
<template slot-scope="scope">
<div class="pers">
<span v-if="scope.row.action==''">
</span>
<span v-else-if="scope.row.action=='send'">
<span v-if="scope.row.action == ''"> </span>
<span v-else-if="scope.row.action == 'send'">
<span class="green"></span>
已发送
</span>
<span v-else-if="scope.row.action=='recall'">
<span v-else-if="scope.row.action == 'recall'">
<span class="red"></span>
已撤回
</span>
<span v-else-if="scope.row.action=='switch'">
<span v-else-if="scope.row.action == 'switch'">
<span class="gay"></span>
企业日志
</span>
......@@ -69,161 +91,161 @@
</template>
</el-table-column>
<el-table-column prop="address" label="发送时间" width="200">
<template slot-scope="scope" v-if="scope.row.text">
{{parseTime(scope.row.msgtime)}}
<template slot-scope="scope">
{{ scope.row.msgTime }}
</template>
</el-table-column>
</el-table>
<el-pagination background class="pagination" layout="prev, pager, next" :total="total"
@current-change="currentChange" :current-page="currentPage">
<el-pagination
background
class="pagination"
layout="prev, pager, next"
:total="total"
@current-change="currentChange"
:current-page="currentPage"
>
</el-pagination>
</div>
</div>
</template>
<script>
import {
content
} from '@/api/content.js'
import {
yearMouthDay,
parseTime
} from '@/utils/common.js'
export default {
data() {
return {
form: {
Ename: "",
Cname: '',
Scontent: '',
Stime: ''
import { content } from '@/api/conversation/content.js'
import { yearMouthDay, parseTime } from '@/utils/common.js'
export default {
data() {
return {
form: {
Ename: '',
Cname: '',
Scontent: '',
Stime: ''
},
currentPage: 1,
total: 0,
ac: '',
fileData: [],
floorRange: '全部',
displayOptions: [
{
value: '',
label: '全部'
},
currentPage: 1,
total: 0,
ac: '',
fileData: [],
floorRange: '全部',
displayOptions: [{
value: "",
label: "全部"
},
{
value: "send",
label: "已发送"
},
{
value: "recall",
label: "已撤回"
},
{
value: "switch",
label: "切回企业日志"
}
]
}
{
value: 'send',
label: '已发送'
},
{
value: 'recall',
label: '已撤回'
},
{
value: 'switch',
label: '切回企业日志'
}
]
}
},
mounted() {
this.init()
},
methods: {
currentChange(e) {
this.currentPage = e
this.init(true)
},
mounted() {
this.init()
init(flag) {
if (!!!flag) {
this.currentPage = 1
}
let query = {
name: this.form.Ename,
customerName: this.form.Cname,
contact: this.form.Scontent,
beginTime: this.form.Stime ? yearMouthDay(this.form.Stime[0]) : '',
endTime: this.form.Stime ? yearMouthDay(this.form.Stime[1]) : '',
pageNum: this.currentPage,
action: this.ac,
orderByColumn: 'msg_time',
isAsc: 'desc'
}
content.getFullSearchChatList(query).then((res) => {
this.fileData = res.rows
this.total = Number(res.total)
})
},
methods: {
currentChange(e) {
this.currentPage = e
this.init(true)
},
init(flag) {
if (!!!flag) {
this.currentPage = 1
}
let query = {
userName: this.form.Ename,
customerName: this.form.Cname,
keyWord: this.form.Scontent,
beginTime: this.form.Stime ? yearMouthDay(this.form.Stime[0]) : "",
endTime: this.form.Stime ? yearMouthDay(this.form.Stime[1]) : "",
pageNum: this.currentPage,
action: this.ac
}
content.getChatAllList(query).then(res => {
console.log(res)
this.fileData = res.rows;
this.total = Number(res.total)
})
},
chechName(e) {
if (e == '') {
this.floorRange = '全部'
this.ac = ''
} else if (e == 'send') {
this.floorRange = '已发送'
this.ac = 'send'
} else if (e == 'recall') {
this.floorRange = '已撤回'
this.ac = 'recall'
} else {
this.floorRange = '切回企业日志'
this.ac = 'switch'
}
console.log(e,this.ac)
this.init()
chechName(e) {
if (e == '') {
this.floorRange = '全部'
this.ac = ''
} else if (e == 'send') {
this.floorRange = '已发送'
this.ac = 'send'
} else if (e == 'recall') {
this.floorRange = '已撤回'
this.ac = 'recall'
} else {
this.floorRange = '切回企业日志'
this.ac = 'switch'
}
console.log(e, this.ac)
this.init()
}
}
}
</script>
<style lang="scss" scoped>
.demo-form-inline {
background: #f1f1f1;
padding: 18px 10px 0 10px;
}
.content {
margin-top: 15px;
padding: 10px;
}
.pers {
position: relative;
.demo-form-inline {
background: #f1f1f1;
padding: 18px 10px 0 10px;
}
.green {
background: greenyellow;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
.content {
margin-top: 15px;
padding: 10px;
}
.red {
background: red;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
.pers {
position: relative;
.gay {
background: gray;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
.green {
background: greenyellow;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
.red {
background: red;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
.noborder {
/deep/ .el-input--mini .el-input__inner {
width: 2px;
border: none
}
.gay {
background: gray;
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
top: 10px;
left: -8px;
}
}
.emcode /deep/ em {
color: #ff0000;
.noborder {
/deep/ .el-input--mini .el-input__inner {
width: 2px;
border: none;
}
}
.emcode /deep/ em {
color: #ff0000;
}
</style>
......@@ -14,7 +14,7 @@
</el-input>
</div>
</div>
<div class="ct_box ct_boxFirst">
<div class="ct_box ct_boxFirst" style="height: calc(100vh - 288px)">
<ul>
<li
v-for="(i, t) in CList"
......@@ -42,6 +42,7 @@
placeholder="搜索聊天记录"
prefix-icon="el-icon-search"
v-model="chatContent"
@keyup.enter.native="chatMsgList"
>
</el-input>
</div>
......@@ -249,7 +250,7 @@ import list from '../component/customerList.vue'
import chats from '../component/chat.vue'
import grouplist from '../component/groupList.vue'
import { content } from '@/api/content.js'
import { content } from '@/api/conversation/content.js'
import { yearMouthDay } from '@/utils/common.js'
export default {
components: {
......@@ -271,7 +272,7 @@ export default {
CList: [],
personList: [],
loading: false,
employId: '',
fromId: '',
chatData: {},
allChat: [],
......@@ -288,7 +289,7 @@ export default {
methods: {
chatFn(data) {
this.chatData = data
console.log(data)
console.log(data, '<><><><>><')
this.activeNameThreeClick()
},
groupFn(data) {
......@@ -305,29 +306,43 @@ export default {
personCheck(data, e) {
this.personIndex = e
this.talkName = data.name
this.employId = data.externalUserid
this.fromId = data.externalUserid
this.getChatList()
},
getChatList(flag) {
if (!this.employId) {
if (!this.fromId) {
return
}
if (flag) {
this.loading = true
}
this.personList = []
content
.getTree({
fromId: this.employId,
searchType: this.activeName
})
.then(({ rows }) => {
this.loading = false
this.personList = rows
})
.catch((err) => {
this.loading = false
})
if (this.activeName == '0') {
content
.selectAloneChatList({
fromId: this.fromId,
contact: this.chatContent
})
.then(({ data }) => {
this.loading = false
this.personList = data
})
.catch((err) => {
this.loading = false
})
} else {
content
.getGroupChatList({
fromId: this.fromId
})
.then(({ data }) => {
this.loading = false
this.personList = data
})
.catch((err) => {
this.loading = false
})
}
},
activeNameThreeClick(page, group) {
if (!!!page) {
......@@ -345,8 +360,8 @@ export default {
} else if (this.activeNameThree == 4) {
msgType = 'voice'
}
let query = {
fromId: this.chatData.fromId,
msgType,
pageSize: '10',
pageNum: this.currentPage,
......@@ -354,12 +369,13 @@ export default {
endTime: this.takeTime ? yearMouthDay(this.takeTime[1]) : ''
}
if (group) {
query.roomId = this.chatData.roomId
query.roomId = this.chatData.receiver
} else {
query.receiveId = this.chatData.receiveId
query.fromId = this.fromId
query.toList = this.chatData.receiver
}
if (group) {
content.chatGrounpList(query).then((res) => {
content.chatList(query).then((res) => {
this.total = Number(res.total)
this.resortData(res)
})
......@@ -392,11 +408,6 @@ export default {
pageNum: 1,
pageSize: 999,
name: this.employName,
userId: '',
tagIds: '',
beginTime: '',
endTime: '',
status: '',
isOpenChat: '1'
}
content.listByCustomer(querys).then((res) => {
......@@ -404,6 +415,9 @@ export default {
this.CList = res.rows
this.employAmount = res.total
})
},
chatMsgList() {
this.getChatList()
}
},
mounted() {
......@@ -426,7 +440,6 @@ export default {
.employ {
background: #f6f6f9;
min-height: 800px;
.hd_tabs {
background: #fff;
......@@ -446,7 +459,6 @@ export default {
.hd_tabs_content {
width: 100%;
min-height: 653px;
border-bottom: 1px solid #efefef;
}
......@@ -458,13 +470,11 @@ export default {
}
.ct_boxFirst {
height: 700px;
}
.ct_box {
background: white;
border-bottom: 1px solid #efefef;
min-height: 709px;
padding: 10px;
overflow-y: scroll;
color: #999;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment