This commit is contained in:
Tsanie Lily 2023-04-06 23:17:44 +08:00
parent 6157f994a9
commit 449196b491
6 changed files with 244 additions and 59 deletions

View File

@ -1,7 +1,7 @@
import "./style.scss";
import { createElement, createElementInit } from "../../functions";
import { r } from "../../utility/lgres";
import { isEmail, isPhone } from "../../utility";
import { formatUrl, isEmail, isPhone } from "../../utility";
import { setTooltip } from "../../ui/tooltip";
import { createIcon } from "../../ui/icon";
import { createCheckbox } from "../../ui/checkbox";
@ -195,32 +195,153 @@ class CustomerCommunication {
)
);
const message = createElement('div');
const message = createElement('div', 'list-bar');
this.#message = message;
container.appendChild(message);
return this.#container = container;
}
load(data, contacts) {
load(data, contacts, followers) {
const children = [];
if (data?.length > 0) {
for (let comm of data) {
const div = document.createElement('div', 'txtdiv');
const div = createElement('div', 'item-div');
let name;
if (comm.IsReply) {
const email = isEmail(comm.Sender);
const c = contacts.find(c => email ?
c.Email === comm.Sender :
c.MobilePhone === comm.Sender);
if (c != null) {
name = c.Name;
const c = isEmail(comm.Sender) ?
contacts.find(c => c.Email === comm.Sender) :
contacts.find(c => c.MobilePhone === comm.Sender);
name = c?.Name;
}
name ??= comm.IsReply && String(comm.FormatSender) !== '' ? comm.FormatSender : comm.Sender;
let sendto = '';
if (!comm.IsReply && comm.OriPhoneNumbers?.length > 0) {
for (let oriph of comm.OriPhoneNumbers) {
let cname;
const email = isEmail(oriph);
if (contacts?.length > 0) {
let c = email ?
contacts.find(c => c.Email === oriph) :
contacts.find(c => c.MobilePhone === oriph);
if (c != null) {
cname = `${email ? c.Email : c.MobilePhone} - ${c.Name}`;
} else if (followers?.length > 0) {
c = email ?
followers.find(f => f.Email === oriph) :
followers.find(f => f.MobilePhone === oriph);
if (c != null) {
cname = `${email ? c.Email : c.MobilePhone} - ${c.Name}`;
}
}
}
sendto += (cname ?? oriph) + '\n';
}
}
if (sendto !== '') {
sendto = r('sendToColon', 'Send To :') + `\n${sendto}`;
}
div.appendChild(createElementInit('div', div => {
div.className = 'item-poster';
div.innerText = name;
if (!comm.IsReply && sendto?.length > 0) {
setTooltip(div, sendto);
}
}));
const content = createElement('div', 'item-content');
if (/https?:\/\//i.test(comm.Message)) {
content.innerHTML = formatUrl(comm.Message);
} else {
content.innerText = comm.Message;
}
if (comm.IsReply) {
div.classList.add('item-other');
} else {
const [status, statusmsg] = this.#getMessageStatus(comm);
if (status !== -100) {
let statustext;
switch (status) {
case 0:
statustext = r('pending', 'Pending');
content.style.backgroundColor = '#ffc107';
break;
case 1:
statustext = r('sent', 'Sent');
break;
case 9:
statustext = r('failed', 'Failed');
content.style.backgroundColor = '#ffc107';
break;
case 10:
statustext = r('optOut', 'Opt-Out');
content.style.backgroundColor = '#ffc107';
break;
case 412:
statustext = r('landline', 'Landline');
content.style.backgroundColor = '#ffc107';
break;
default:
statustext = r('undelivered', 'Undelivered');
content.style.backgroundColor = '#ffc107';
break;
}
const divstatus = createElementInit('div', div => {
div.className = 'item-status';
div.innerText = statustext;
if (status == -10) {
setTooltip(div, statusmsg);
}
});
content.appendChild(divstatus);
}
}
div.append(
content,
createElementInit('div', div => {
div.className = 'item-time';
div.innerText = comm.TimeStr;
})
);
children.push(div);
}
children[0].style.marginTop = '0';
this.#message.append(...children);
this.#message.scrollTop = this.#message.scrollHeight
// setTimeout(() => this.#message.scrollTop = this.#message.scrollHeight, 0);
}
}
#getMessageStatus(comm) {
let status = -100; // 没有状态,页面上不显示
const ls = [];
let statusmsg = '';
if (!comm.StatusIncorrect && comm.Participator?.length > 0) {
for (let p of comm.Participator) {
if (!isEmail(p.CustomerNumber)) {
if (ls.indexOf(p.Status) < 0) {
ls.push(p.Status);
}
if (statusmsg.length > 0) {
statusmsg += '\n';
}
statusmsg += `${p.CustomerNumber}: `;
const st = ({
0: r('undelivered', 'Undelivered'),
1: r('sent', 'Sent'),
9: r('failed', 'Failed')
})[p.Status];
if (st != null) {
statusmsg += st;
}
}
}
}
if (ls.length === 1) {
status = ls[0];
} else if (ls.length > 1) {
status = -10; // 多种状态
}
return [status, statusmsg];
}
}
export default CustomerCommunication;

View File

@ -183,59 +183,87 @@
>div {
padding: 0 10px 10px;
}
}
&+div {
flex: 1 1 auto;
overflow: auto;
margin-top: 8px;
.list-bar {
flex: 1 1 auto;
overflow: auto;
margin-top: 8px;
.msgdiv {
margin-top: 5px;
border-bottom: solid 1px lightgray;
padding: 3px 10px 5px;
line-height: 1.5rem;
white-space: normal;
word-break: break-word;
overflow: hidden;
font-size: .8125rem;
color: #333;
.item-div {
margin-top: 5px;
border-bottom: solid 1px lightgray;
padding: 3px 10px 5px;
line-height: 1.5rem;
white-space: normal;
word-break: break-word;
overflow: hidden;
font-size: .8125rem;
color: #333;
display: flex;
flex-direction: column;
&:last-child {
border-bottom: none;
&:last-child {
border-bottom: none;
}
}
.item-poster {
font-weight: bold;
align-self: flex-end;
.tooltip-wrapper>.tooltip-content {
font-weight: normal;
}
}
.item-content {
line-height: 1.2rem;
padding: 8px 20px;
border-radius: 5px;
white-space: pre-wrap;
word-break: break-word;
max-width: 240px;
margin-right: 10px;
background-color: #9eea6a;
align-self: flex-end;
a>svg {
width: 13px;
height: 13px;
fill: #2140fb;
&:hover {
border-bottom: 1px solid;
}
}
.msgposter {
font-weight: bold;
&+div {
line-height: 1.2rem;
padding: 8px 20px;
background-color: rgb(244, 244, 244);
border-radius: 5px;
white-space: pre-wrap;
text-align: left;
word-break: break-word;
&.txtself {
max-width: 240px;
margin-right: 10px;
background-color: #9eea6a;
display: inline-block;
}
&.txtother {
max-width: 240px;
margin-left: 10px;
display: inline-block;
}
}
}
.msgtime {
.item-status {
text-align: right;
color: #aaa;
font-size: .7rem;
margin-top: 3px;
font-weight: bold;
margin-right: -12px;
font-size: 10px;
}
}
.item-time {
align-self: flex-end;
color: #aaa;
font-size: .7rem;
}
&.item-other {
.item-poster,
.item-content {
align-self: flex-start;
}
.item-content {
background-color: rgb(244, 244, 244);
margin-right: unset;
margin-left: 10px;
}
}
}

View File

@ -1,7 +1,7 @@
import { getCookie, setCookie, deleteCookie } from "./utility/cookie";
import { init, r, lang } from "./utility/lgres";
import { get, post, upload } from "./utility/request";
import { nullOrEmpty, contains, endsWith, padStart } from "./utility/strings";
import { nullOrEmpty, contains, endsWith, padStart, formatUrl } from "./utility/strings";
let g = typeof globalThis !== 'undefined' ? globalThis : self;
@ -57,6 +57,7 @@ export {
contains,
endsWith,
padStart,
formatUrl,
// variables
g as global,
isPositive,

View File

@ -1,4 +1,5 @@
export function nullOrEmpty(s?: string | any | null): boolean
export function contains(s: string, key: string | any, ignoreCase?: boolean): boolean
export function endsWith(s: string, suffix: string): boolean
export function padStart(s: string, num: Number, char: string): boolean
export function padStart(s: string, num: Number, char: string): boolean
export function formatUrl(msg: string): string

View File

@ -48,6 +48,12 @@
<p>
用此字符串填充,使得字符串对齐,默认为 ' '
</p>
<h2>formatUrl</h2>
<code>function formatUrl(msg: string): string</code>
<h3>msg: string</h3>
<p>
把超链接解析替换为图标
</p>
<hr />
<h2>用法</h2>
<pre>const util = window["lib-utility"];

View File

@ -29,9 +29,37 @@ function padStart(s, num, char) {
return (char ?? ' ').repeat(num - s.length);
}
function formatUrl(msg) {
//const urlReg = /(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/ig;
//const urlArrray = str.match(urlReg);
const p = /(http|ftp|https):\/\/.+?(\s|\r\n|\r|\n|\"|\'|\*|$)/g;
const r = msg.match(p);
msg = htmlencode(msg);
if (r?.length > 0) {
const rs = [];
for (let t of r) {
t = t.replace(/["'\r\n ]/g, '');
if (rs.indexOf(t) < 0) {
rs.push(t);
}
}
for (let r of rs) {
msg = msg.replaceAll(r, '<a target="_blank" href="' + r + '"><svg><use xlink:href="' + ((typeof consts !== 'undefined' && consts.path) ?? '') + 'fonts/fa-regular.svg#link"></use></svg></a>');
}
}
return msg
.replaceAll('\r\n', '<br/>')
.replaceAll('\n', '<br/>')
.replaceAll(' ', '&nbsp;');
}
export {
nullOrEmpty,
contains,
endsWith,
padStart
padStart,
formatUrl
}