no message

This commit is contained in:
kuaifan 2025-04-18 20:26:35 +08:00
parent 7957353c3f
commit 94fd3197b3
8 changed files with 110 additions and 117 deletions

View File

@ -672,15 +672,18 @@ class DialogController extends AbstractController
}
/**
* @api {get} api/dialog/msg/search 14. 搜索消息位置
* @api {get} api/dialog/msg/search 14. 搜索消息
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__search
*
* @apiParam {Number} dialog_id 对话ID
* @apiParam {String} key 搜索关键词
* @apiParam {Number} [dialog_id] 对话ID存在则搜索消息在对话的位置
* @apiParam {Number} [take] 搜索数量
* - dialog_id > 0, 默认:200,最大:200
* - dialog_id <= 0, 默认:20,最大:50
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -688,59 +691,38 @@ class DialogController extends AbstractController
*/
public function msg__search()
{
User::auth();
$user = User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
$key = trim(Request::input('key'));
$dialogId = intval(Request::input('dialog_id'));
//
if (empty($key)) {
return Base::retError('关键词不能为空');
}
//
WebSocketDialog::checkDialog($dialog_id);
//
$data = WebSocketDialogMsg::whereDialogId($dialog_id)
->where('key', 'LIKE', "%{$key}%")
->take(200)
->pluck('id');
return Base::retSuccess('success', compact('data'));
}
/**
* @api {get} api/dialog/msg/esearch 15. 搜索消息
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__esearch
*
* @apiParam {String} key 搜索关键词
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__esearch()
{
$user = User::auth();
//
$key = trim(Request::input('key'));
$list = [];
//
$searchResults = ZincSearchDialogMsg::search($user->userid, $key, 0, Base::getPaginate(50, 20));
if ($searchResults) {
foreach ($searchResults as $item) {
if ($dialog = WebSocketDialog::find($item['id'])) {
$dialog = array_merge($dialog->toArray(), $item);
$list[] = WebSocketDialog::synthesizeData($dialog, $user->userid);
if ($dialogId > 0) {
// 搜索位置
WebSocketDialog::checkDialog($dialogId);
//
$data = WebSocketDialogMsg::whereDialogId($dialogId)
->where('key', 'LIKE', "%{$key}%")
->take(Base::getPaginate(200, 200, 'take'))
->pluck('id');
return Base::retSuccess('success', compact('data'));
} else {
// 搜索消息
$list = [];
$searchResults = ZincSearchDialogMsg::search($user->userid, $key, 0, Base::getPaginate(50, 20, 'take'));
if ($searchResults) {
foreach ($searchResults as $item) {
if ($dialog = WebSocketDialog::find($item['id'])) {
$dialog = array_merge($dialog->toArray(), $item);
$list[] = WebSocketDialog::synthesizeData($dialog, $user->userid);
}
}
}
return Base::retSuccess('success', ['data' => $list]);
}
//
return Base::retSuccess('success', [
'data' => $list,
]);
}
/**

View File

@ -37,11 +37,6 @@ use App\Module\Base;
*/
class UserDelete extends AbstractModel
{
/**
* 昵称
* @param $value
* @return string
*/
public function getCacheAttribute($value)
{
if (!is_array($value)) {
@ -65,13 +60,25 @@ class UserDelete extends AbstractModel
*/
public static function userid2basic($userid)
{
$row = self::whereUserid($userid)->first();
if (empty($row) || empty($row->cache)) {
return null;
}
$cache = $row->cache;
$cache = array_intersect_key($cache, array_flip(array_merge(User::$basicField, ['department_name'])));
$cache['delete_at'] = $row->created_at->toDateTimeString();
return $cache;
return \Cache::remember("UserDelete:{$userid}", now()->addDays(3), function () use ($userid) {
$row = self::whereUserid($userid)->first();
if (empty($row) || empty($row->cache)) {
return null;
}
$cache = $row->cache;
$cache = array_intersect_key($cache, array_flip(array_merge(User::$basicField, ['department_name'])));
$cache['delete_at'] = $row->created_at->toDateTimeString();
return $cache;
});
}
/**
* userid 获取 昵称
* @param $userid
* @return string
*/
public static function userid2nickname($userid)
{
return self::userid2basic($userid)['nickname'] ?? '';
}
}

View File

@ -298,7 +298,8 @@ class WebSocketDialog extends AbstractModel
$data['is_disable'] = $basic->isDisable(true);
$data['quick_msgs'] = UserBot::quickMsgs($basic->email);
} else {
$data['name'] = 'non-existent';
$data['name'] = UserDelete::userid2nickname($dialog_user->userid) ?: '[Delete]';
$data['is_disable'] = 1;
$data['dialog_delete'] = 1;
}
$data['dialog_user'] = $dialog_user;

View File

@ -50,7 +50,7 @@
<div v-else class="search-list">
<ul v-for="data in list" :key="data.type">
<li v-if="!action" class="item-label">{{$L(data.name)}}</li>
<li v-for="item in data.items" :key="item.id" @click="onClick(item)">
<li v-for="item in data.items" @click="onClick(item)">
<div class="item-icon">
<div v-if="item.icons[0]==='file'" :class="`no-dark-content file-icon ${item.icons[1]}`"></div>
<i v-else-if="item.icons[0]==='department'" class="taskfont icon-avatar department">&#xe75c;</i>
@ -317,9 +317,11 @@ export default {
return false
},
echoSearch(items) {
echoSearch(items, key = 'id') {
items.forEach(item => {
const index = this.searchResults.findIndex(({id, type}) => id === item.id && type === item.type)
const index = this.searchResults.findIndex(result => {
return result[key] === item[key] && result.type === item.type
})
if (index > -1) {
this.searchResults.splice(index, 1, item)
} else {
@ -432,10 +434,10 @@ export default {
searchMessage(key) {
this.loadIng++;
this.$store.dispatch("call", {
url: 'dialog/msg/esearch',
url: 'dialog/msg/search',
data: {
key,
pagesize: this.action ? 50 : 10,
take: this.action ? 50 : 10,
},
}).then(({data}) => {
const items = data.data.map(item => {
@ -469,10 +471,11 @@ export default {
desc: $A.getMsgSimpleDesc(item.last_msg),
activity: item.last_at,
searchMsgId: item.search_msg_id,
rawData: item,
};
})
this.echoSearch(items)
this.echoSearch(items, 'searchMsgId')
}).finally(_ => {
this.loadIng--;
})

View File

@ -8,8 +8,8 @@
<p>{{$L('昵称')}}: {{user.nickname}}<em v-if="user.delete_at" class="deleted no-dark-content">{{$L('已删除')}}</em><em v-else-if="user.disable_at" class="disabled no-dark-content">{{$L('已离职')}}</em></p>
<p class="department-name" :title="user.department_name || ''">{{$L('部门')}}: {{user.department_name || '-'}}</p>
<p>{{$L('职位/职称')}}: {{user.profession || '-'}}</p>
<p v-if="user.delete_at"><strong>{{$L('删除时间')}}: {{user.delete_at}}</strong></p>
<p v-else-if="user.disable_at"><strong>{{$L('离职时间')}}: {{user.disable_at}}</strong></p>
<p v-if="user.delete_at"><strong>{{$L('删除时间')}}: {{$A.newDateString(user.delete_at, 'YYYY-MM-DD HH:mm')}}</strong></p>
<p v-else-if="user.disable_at"><strong>{{$L('离职时间')}}: {{$A.newDateString(user.disable_at, 'YYYY-MM-DD HH:mm')}}</strong></p>
<slot name="end"/>
</div>
<div>

View File

@ -2249,16 +2249,16 @@ const timezone = require("dayjs/plugin/timezone");
timezoneDifference: 0,
/**
* 对象中有Date格式的转成指定格式
* @param value
* @param format 默认格式YYYY-MM-DD HH:mm:ss
* 对象中有Date格式的转成指定格式
* @param value 支持类型dayjsDatestring
* @param format 默认格式YYYY-MM-DD HH:mm:ss
* @returns {*}
*/
newDateString(value, format = "YYYY-MM-DD HH:mm:ss") {
if (value === null) {
return value;
}
if (value instanceof dayjs || value instanceof Date) {
if (value instanceof dayjs || value instanceof Date || $A.isDateString(value)) {
value = $A.dayjs(value).format(format);
} else if ($A.isJson(value)) {
value = Object.assign({}, value)
@ -2308,7 +2308,7 @@ const timezone = require("dayjs/plugin/timezone");
* @returns {boolean}
*/
isDateString(value) {
return typeof value === "string" && /^\d{4}-\d{2}-\d{2}( \d{2}(:\d{2}(:\d{2})?)?)?$/i.test(value);
return typeof value === "string" && /^\d{4}[/-]\d{2}[/-]\d{2}(\s+\d{2}(:\d{2}(:\d{2})?)?)?$/i.test(value);
},
/**

View File

@ -22,7 +22,7 @@
eeuiModulePromise(name = 'eeui') {
return new Promise((resolve, reject) => {
try {
const eeui = this.eeuiModule(name);
const eeui = $A.eeuiModule(name);
if (!eeui) {
return reject({msg: "module not found"});
}
@ -35,33 +35,33 @@
// 获取eeui版本号
eeuiAppVersion() {
return this.eeuiModule()?.getVersion();
return $A.eeuiModule()?.getVersion();
},
// 获取本地软件版本号
eeuiAppLocalVersion() {
return this.eeuiModule()?.getLocalVersion();
return $A.eeuiModule()?.getLocalVersion();
},
// Alert
eeuiAppAlert(object, callback) {
if (typeof callback !== "function") callback = _ => {};
this.eeuiModule()?.alert(object, callback);
$A.eeuiModule()?.alert(object, callback);
},
// Toast
eeuiAppToast(object) {
this.eeuiModule()?.toast(object);
$A.eeuiModule()?.toast(object);
},
// 相对地址基于当前地址补全
eeuiAppRewriteUrl(val) {
return this.eeuiModule()?.rewriteUrl(val);
return $A.eeuiModule()?.rewriteUrl(val);
},
// 获取页面信息
eeuiAppGetPageInfo(pageName) {
return this.eeuiModule()?.getPageInfo(pageName || "");
return $A.eeuiModule()?.getPageInfo(pageName || "");
},
// 打开app新页面
@ -73,55 +73,55 @@
callback = object.callback;
delete object.callback
}
this.eeuiModule()?.openPage(Object.assign({
$A.eeuiModule()?.openPage(Object.assign({
softInputMode: "resize",
}, object), callback);
},
// 使用系统浏览器打开网页
eeuiAppOpenWeb(url) {
this.eeuiModule()?.openWeb(url)
$A.eeuiModule()?.openWeb(url)
},
// 拦截返回按键事件仅支持android、iOS无效
eeuiAppSetPageBackPressed(object, callback) {
if (typeof callback !== "function") callback = _ => {};
this.eeuiModule()?.setPageBackPressed(object, callback);
$A.eeuiModule()?.setPageBackPressed(object, callback);
},
// 返回手机桌面
eeuiAppGoDesktop() {
this.eeuiModule()?.goDesktop();
$A.eeuiModule()?.goDesktop();
},
// 打开屏幕常亮
eeuiAppKeepScreenOn() {
this.eeuiModule()?.keepScreenOn();
$A.eeuiModule()?.keepScreenOn();
},
// 关闭屏幕常亮
eeuiAppKeepScreenOff() {
this.eeuiModule()?.keepScreenOff();
$A.eeuiModule()?.keepScreenOff();
},
// 隐藏软键盘
eeuiAppKeyboardHide() {
this.eeuiModule()?.keyboardHide();
$A.eeuiModule()?.keyboardHide();
},
// 给app发送消息
eeuiAppSendMessage(object) {
this.eeuiModule("webview")?.sendMessage(object);
$A.eeuiModule("webview")?.sendMessage(object);
},
// 设置浏览器地址
eeuiAppSetUrl(url) {
this.eeuiModule("webview")?.setUrl(url);
$A.eeuiModule("webview")?.setUrl(url);
},
// 扫码
eeuiAppScan(callback) {
this.eeuiModule()?.openScaner({}, (res) => {
$A.eeuiModule()?.openScaner({}, (res) => {
switch (res.status) {
case "success":
callback(res.text);
@ -132,55 +132,55 @@
// 检查更新
eeuiAppCheckUpdate() {
this.eeuiModule()?.checkUpdate();
$A.eeuiModule()?.checkUpdate();
},
// 获取主题名称 light|dark
eeuiAppGetThemeName() {
return this.eeuiModule()?.getThemeName();
return $A.eeuiModule()?.getThemeName();
},
// 判断软键盘是否可见
eeuiAppKeyboardStatus() {
return this.eeuiModule()?.keyboardStatus();
return $A.eeuiModule()?.keyboardStatus();
},
// 设置全局变量
eeuiAppSetVariate(key, value) {
this.eeuiModule()?.setVariate(key, value);
$A.eeuiModule()?.setVariate(key, value);
},
// 获取全局变量
eeuiAppGetVariate(key, defaultVal = "") {
return this.eeuiModule()?.getVariate(key, defaultVal);
return $A.eeuiModule()?.getVariate(key, defaultVal);
},
// 设置缓存数据
eeuiAppSetCachesString(key, value, expired = 0) {
this.eeuiModule()?.setCachesString(key, value, expired);
$A.eeuiModule()?.setCachesString(key, value, expired);
},
// 获取缓存数据
eeuiAppGetCachesString(key, defaultVal = "") {
return this.eeuiModule()?.getCachesString(key, defaultVal);
return $A.eeuiModule()?.getCachesString(key, defaultVal);
},
// 是否长按内容震动仅支持android、iOS无效
eeuiAppSetHapticBackEnabled(val) {
this.eeuiModule("webview").setHapticBackEnabled(val);
$A.eeuiModule("webview").setHapticBackEnabled(val);
},
// 禁止长按选择仅支持android、iOS无效
eeuiAppSetDisabledUserLongClickSelect(val) {
const webview = this.eeuiModule("webview");
this.__disabledUserLongClickSelectTimer && clearTimeout(this.__disabledUserLongClickSelectTimer);
const webview = $A.eeuiModule("webview");
$A.__disabledUserLongClickSelectTimer && clearTimeout($A.__disabledUserLongClickSelectTimer);
if (!/^\d+$/.test(val)) {
webview.setDisabledUserLongClickSelect(val);
return;
}
webview.setDisabledUserLongClickSelect(true);
this.__disabledUserLongClickSelectTimer = setTimeout(() => {
this.__disabledUserLongClickSelectTimer = null;
$A.__disabledUserLongClickSelectTimer = setTimeout(() => {
$A.__disabledUserLongClickSelectTimer = null;
webview.setDisabledUserLongClickSelect(false);
}, val);
},
@ -188,26 +188,26 @@
// 复制文本
eeuiAppCopyText(text) {
this.eeuiModule()?.copyText(text)
$A.eeuiModule()?.copyText(text)
},
// 设置是否禁止滚动
eeuiAppSetScrollDisabled(disabled) {
if (disabled) {
this.__setScrollDisabledNum++
$A.__setScrollDisabledNum++
} else {
this.__setScrollDisabledNum--
$A.__setScrollDisabledNum--
}
this.eeuiModule("webview")?.setScrollEnabled(this.__setScrollDisabledNum <= 0);
$A.eeuiModule("webview")?.setScrollEnabled($A.__setScrollDisabledNum <= 0);
},
__setScrollDisabledNum: 0,
// 设置应用程序级别的摇动撤销仅支持iOS、android无效
eeuiAppShakeToEditEnabled(enabled) {
if (enabled) {
this.eeuiModule()?.shakeToEditOn();
$A.eeuiModule()?.shakeToEditOn();
} else {
this.eeuiModule()?.shakeToEditOff();
$A.eeuiModule()?.shakeToEditOff();
}
},
@ -215,7 +215,7 @@
eeuiAppGetLatestPhoto(expiration = 60, timeout = 10) {
return new Promise(async (resolve, reject) => {
try {
const eeui = await this.eeuiModule();
const eeui = await $A.eeuiModule();
const timer = timeout > 0 ? setTimeout(() => {
reject({msg: "timeout"});
@ -233,10 +233,10 @@
if (expiration > 0 && (result.created + expiration) < $A.dayjs().unix()) {
return reject({msg: "photo expired"});
}
if (this.__latestPhotoCreated && this.__latestPhotoCreated === result.created) {
if ($A.__latestPhotoCreated && $A.__latestPhotoCreated === result.created) {
return reject({msg: "photo expired"});
}
this.__latestPhotoCreated = result.created;
$A.__latestPhotoCreated = result.created;
resolve(result);
});
} catch (e) {
@ -250,7 +250,7 @@
eeuiAppUploadPhoto(params, timeout = 30) {
return new Promise(async (resolve, reject) => {
try {
const eeui = await this.eeuiModulePromise();
const eeui = await $A.eeuiModulePromise();
const timer = timeout > 0 ? setTimeout(() => {
reject({msg: "timeout"});
@ -291,7 +291,7 @@
eeuiAppCancelUploadPhoto(id) {
return new Promise(async (resolve, reject) => {
try {
const eeui = await this.eeuiModulePromise();
const eeui = await $A.eeuiModulePromise();
eeui.cancelUploadPhoto(id, result => {
if (result.status !== 'success') {
return reject({msg: result.error || "cancel failed"});
@ -308,7 +308,7 @@
eeuiAppGetSafeAreaInsets() {
return new Promise(async (resolve, reject) => {
try {
const eeui = await this.eeuiModulePromise();
const eeui = await $A.eeuiModulePromise();
eeui.getSafeAreaInsets(result => {
if (result.status !== 'success') {
return reject({msg: result.error || "get failed"});

View File

@ -29,17 +29,17 @@
</li>
<li>
<span>{{$L('最后在线')}}: </span>
{{userData.line_at ? $A.dayjs(userData.line_at).format("YYYY-MM-DD HH:mm") : '-'}}
{{$A.newDateString(userData.line_at, 'YYYY-MM-DD HH:mm') || '-'}}
</li>
<li v-if="userData.delete_at">
<strong><span>{{$L('删除时间')}}: </span>{{userData.delete_at}}</strong>
<strong><span>{{$L('删除时间')}}: </span>{{$A.newDateString(userData.delete_at, 'YYYY-MM-DD HH:mm')}}</strong>
</li>
<li v-else-if="userData.disable_at">
<strong><span>{{$L('离职时间')}}: </span>{{userData.disable_at}}</strong>
<strong><span>{{$L('离职时间')}}: </span>{{$A.newDateString(userData.disable_at, 'YYYY-MM-DD HH:mm')}}</strong>
</li>
</template>
</ul>
<Button icon="md-chatbubbles" :disabled="userData.delete_at" @click="onOpenDialog">{{ $L('开始聊天') }}</Button>
<Button icon="md-chatbubbles" :disabled="!!userData.delete_at" @click="onOpenDialog">{{ $L('开始聊天') }}</Button>
</div>
</ModalAlive>
</template>