ваше сообщение коммита
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
<el-button v-if="canEditData" type="primary" @click="showImportModal = true" style="margin-right: 1em;">Импорт</el-button>
|
<el-button v-if="canEditData" type="primary" @click="showImportModal = true" style="margin-right: 1em;">Импорт</el-button>
|
||||||
<button class="close-btn" @click="$emit('close')">×</button>
|
<button class="close-btn" @click="$emit('close')">×</button>
|
||||||
</div>
|
</div>
|
||||||
<el-form :inline="true" class="filters-form" label-position="top">
|
<el-form v-if="isEditorRole" :inline="true" class="filters-form" label-position="top">
|
||||||
<el-form-item label="Поиск">
|
<el-form-item label="Поиск">
|
||||||
<el-input v-model="filterSearch" placeholder="Поиск по имени, email, telegram, кошельку" clearable @input="onAnyFilterChange" />
|
<el-input v-model="filterSearch" placeholder="Поиск по имени, email, telegram, кошельку" clearable @input="onAnyFilterChange" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -204,29 +204,64 @@ const hasSelectedEditor = computed(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Фильтрация контактов для USER - видит только editor админов и себя
|
// Фильтры формы доступны только для роли editor
|
||||||
const filteredContacts = computed(() => {
|
const isEditorRole = computed(() => userAccessLevel.value?.level === 'editor');
|
||||||
console.log('[ContactTable] 🔍 Фильтрация контактов:');
|
|
||||||
console.log('[ContactTable] userAccessLevel:', userAccessLevel.value);
|
|
||||||
console.log('[ContactTable] userId:', userId.value);
|
|
||||||
console.log('[ContactTable] Все контакты:', contactsArray.value);
|
|
||||||
|
|
||||||
|
// Фильтрация контактов: по роли (user/readonly/editor), для editor — дополнительно по форме фильтров
|
||||||
|
const filteredContacts = computed(() => {
|
||||||
|
let list;
|
||||||
if (userAccessLevel.value?.level === 'user') {
|
if (userAccessLevel.value?.level === 'user') {
|
||||||
// USER видит только editor админов и себя
|
// USER видит только editor админов и себя
|
||||||
const filtered = contactsArray.value.filter(contact => {
|
list = contactsArray.value.filter(contact => {
|
||||||
const isEditor = contact.role === 'editor'; // Используем role вместо contact_type
|
const isEditor = contact.role === 'editor';
|
||||||
const isSelf = contact.id === userId.value;
|
const isSelf = contact.id === userId.value;
|
||||||
console.log(`[ContactTable] Контакт ${contact.id}: role=${contact.role}, contact_type=${contact.contact_type}, isEditor=${isEditor}, isSelf=${isSelf}`);
|
|
||||||
console.log(`[ContactTable] Полный объект контакта:`, contact);
|
|
||||||
return isEditor || isSelf;
|
return isEditor || isSelf;
|
||||||
});
|
});
|
||||||
console.log('[ContactTable] Отфильтрованные контакты:', filtered);
|
} else {
|
||||||
return filtered;
|
// READONLY и EDITOR видят всех
|
||||||
|
list = [...contactsArray.value];
|
||||||
}
|
}
|
||||||
|
|
||||||
// READONLY и EDITOR видят всех
|
// Фильтры формы применяем только для роли editor
|
||||||
console.log('[ContactTable] Показываем всех (не user роль)');
|
if (!isEditorRole.value) return list;
|
||||||
return contactsArray.value;
|
|
||||||
|
return list.filter(contact => {
|
||||||
|
if (filterSearch.value) {
|
||||||
|
const q = filterSearch.value.toLowerCase();
|
||||||
|
const name = (contact.name || '').toLowerCase();
|
||||||
|
const email = (contact.email || '').toLowerCase();
|
||||||
|
const telegram = (contact.telegram || '').toLowerCase();
|
||||||
|
const wallet = (contact.wallet || '').toLowerCase();
|
||||||
|
if (!name.includes(q) && !email.includes(q) && !telegram.includes(q) && !wallet.includes(q)) return false;
|
||||||
|
}
|
||||||
|
if (filterContactType.value && filterContactType.value !== 'all') {
|
||||||
|
const ct = (contact.contact_type || '').toLowerCase();
|
||||||
|
if (ct !== filterContactType.value) return false;
|
||||||
|
}
|
||||||
|
if (filterDateFrom.value) {
|
||||||
|
const created = contact.created_at ? new Date(contact.created_at) : null;
|
||||||
|
const from = new Date(filterDateFrom.value);
|
||||||
|
from.setHours(0, 0, 0, 0);
|
||||||
|
if (!created || created < from) return false;
|
||||||
|
}
|
||||||
|
if (filterDateTo.value) {
|
||||||
|
const created = contact.created_at ? new Date(contact.created_at) : null;
|
||||||
|
const to = new Date(filterDateTo.value);
|
||||||
|
to.setHours(23, 59, 59, 999);
|
||||||
|
if (!created || created > to) return false;
|
||||||
|
}
|
||||||
|
if (filterNewMessages.value === 'yes') {
|
||||||
|
if (!newMsgUserIds.value.includes(String(contact.id))) return false;
|
||||||
|
}
|
||||||
|
if (filterBlocked.value === 'blocked' && !contact.is_blocked) return false;
|
||||||
|
if (filterBlocked.value === 'unblocked' && contact.is_blocked) return false;
|
||||||
|
if (selectedTagIds.value.length > 0) {
|
||||||
|
const contactTagIds = contact.tag_ids || (contact.tags || []).map(t => t.id || t);
|
||||||
|
const hasMatch = selectedTagIds.value.some(tid => contactTagIds.includes(tid));
|
||||||
|
if (!hasMatch) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// WebSocket для тегов - ОТКЛЮЧАЕМ из-за циклических запросов
|
// WebSocket для тегов - ОТКЛЮЧАЕМ из-за циклических запросов
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ services:
|
|||||||
- OLLAMA_NUM_GPU=0
|
- OLLAMA_NUM_GPU=0
|
||||||
- OLLAMA_KEEP_ALIVE=86400
|
- OLLAMA_KEEP_ALIVE=86400
|
||||||
- OLLAMA_MODEL_TIMEOUT=0
|
- OLLAMA_MODEL_TIMEOUT=0
|
||||||
- OLLAMA_MAX_LOADED_MODELS=2
|
# 1 модель в RAM: при 2 моделях free≈4.1 GiB, qwen2.5:7b нужно 4.5 GiB → Load failed
|
||||||
|
- OLLAMA_MAX_LOADED_MODELS=1
|
||||||
- OLLAMA_FLASH_ATTENTION=0
|
- OLLAMA_FLASH_ATTENTION=0
|
||||||
- OLLAMA_LLM_LIBRARY=auto
|
- OLLAMA_LLM_LIBRARY=auto
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -108,6 +109,9 @@ services:
|
|||||||
|
|
||||||
backend:
|
backend:
|
||||||
image: digital_legal_entitydle-backend:latest
|
image: digital_legal_entitydle-backend:latest
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
container_name: dapp-backend
|
container_name: dapp-backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -174,6 +178,9 @@ services:
|
|||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: digital_legal_entitydle-frontend:latest
|
image: digital_legal_entitydle-frontend:latest
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
container_name: dapp-frontend
|
container_name: dapp-frontend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
@@ -229,6 +236,9 @@ services:
|
|||||||
# Nginx с автоматическим SSL и поддержкой WebSocket
|
# Nginx с автоматическим SSL и поддержкой WebSocket
|
||||||
frontend-nginx:
|
frontend-nginx:
|
||||||
image: digital_legal_entitydle-frontend-nginx:latest
|
image: digital_legal_entitydle-frontend-nginx:latest
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: nginx.Dockerfile
|
||||||
container_name: dapp-frontend-nginx
|
container_name: dapp-frontend-nginx
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
Reference in New Issue
Block a user