fix: папка файлов чата называется по RequestUniqueCode, а не formKey-id
Раньше папка в библиотеке «Файлы чата» называлась «clearance-form-42» — это техническое имя ничего не говорит без открытого портала. Теперь имя папки — тот же код заявки, что показан в её заголовке («13-2608-42»), поэтому папку легко узнать прямо в библиотеке.
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
import '@pnp/sp/webs';
|
||||
import '@pnp/sp/lists';
|
||||
import '@pnp/sp/items';
|
||||
import '@pnp/sp/folders';
|
||||
import '@pnp/sp/files';
|
||||
import type { IFolder } from '@pnp/sp/folders';
|
||||
import { getSP } from '../pnp/pnpjs';
|
||||
import { resolveDataList } from '../dataList';
|
||||
import { CHAT_FILES_LIBRARY_TITLE } from '../listTitles';
|
||||
import { RequestTypeId } from '../../models/types';
|
||||
import { fileStamp, storedFileName } from './chatFileNames';
|
||||
import { fileStamp, sanitizeFileName, storedFileName } from './chatFileNames';
|
||||
|
||||
/**
|
||||
* Файлы, прикреплённые к сообщениям чата, — библиотека «Файлы чата» на сайте
|
||||
* данных, папка на каждую заявку: «Файлы чата/<тип заявки>-<id>».
|
||||
* данных, папка на каждую заявку: «Файлы чата/<RequestUniqueCode>», например
|
||||
* «Файлы чата/13-2608-42» — тот же код, что показан в заголовке заявки (см.
|
||||
* FormCard subtitle в <Форма>View.tsx). Так папку легко узнать в самой
|
||||
* библиотеке, не открывая портал.
|
||||
*
|
||||
* Почему не вложения самой заявки (shared/attachments): вложения — это
|
||||
* документы заявки, они попадают в её карточку и печать. Файл из переписки —
|
||||
@@ -57,18 +62,41 @@ function chatLibraryRoot(): Promise<string> {
|
||||
return libraryRootPromise;
|
||||
}
|
||||
|
||||
/** Имя папки заявки в библиотеке. Тип заявки в имени — чтобы id разных типов не смешивались. */
|
||||
function requestFolderName(formKey: RequestTypeId, itemId: number): string {
|
||||
return `${formKey}-${itemId}`;
|
||||
/**
|
||||
* Имя папки заявки в библиотеке — RequestUniqueCode элемента.
|
||||
*
|
||||
* Код читаем из самого элемента, а не собираем строкой (formKey+itemId), чтобы
|
||||
* папка называлась ровно тем номером, который видит пользователь на заявке.
|
||||
* Код записывается сразу после создания элемента (см. saveRequestItem в
|
||||
* shared/dataList.ts) и с этого момента не меняется, поэтому лишний раз его
|
||||
* не кешируем: запрос — это одно select-поле, а не тяжёлая операция.
|
||||
*
|
||||
* Пустой код (гипотетическая гонка на только что созданной заявке) — откат на
|
||||
* старую схему имени, чтобы папка всё равно нашлась однозначно.
|
||||
*/
|
||||
async function requestFolderName(
|
||||
formKey: RequestTypeId,
|
||||
itemId: number,
|
||||
listId: string | undefined
|
||||
): Promise<string> {
|
||||
const item = (await resolveDataList(formKey, listId)
|
||||
.items.getById(itemId)
|
||||
.select('RequestUniqueCode')()) as { RequestUniqueCode?: string };
|
||||
const code = (item.RequestUniqueCode || '').trim();
|
||||
return sanitizeFileName(code || `${formKey}-${itemId}`);
|
||||
}
|
||||
|
||||
/** Адрес папки заявки. Папки может ещё не существовать — для чтения ссылок это неважно. */
|
||||
export async function chatFilesFolderUrl(
|
||||
formKey: RequestTypeId,
|
||||
itemId: number
|
||||
itemId: number,
|
||||
listId?: string
|
||||
): Promise<string> {
|
||||
const root = await chatLibraryRoot();
|
||||
return `${root}/${requestFolderName(formKey, itemId)}`;
|
||||
const [root, name] = await Promise.all([
|
||||
chatLibraryRoot(),
|
||||
requestFolderName(formKey, itemId, listId)
|
||||
]);
|
||||
return `${root}/${name}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,9 +107,15 @@ export async function chatFilesFolderUrl(
|
||||
* addUsingPath с overwrite=true СНОСИТ содержимое — то есть все ранее
|
||||
* приложенные к заявке файлы.
|
||||
*/
|
||||
async function ensureRequestFolder(formKey: RequestTypeId, itemId: number): Promise<IFolder> {
|
||||
const root = await chatLibraryRoot();
|
||||
const name = requestFolderName(formKey, itemId);
|
||||
async function ensureRequestFolder(
|
||||
formKey: RequestTypeId,
|
||||
itemId: number,
|
||||
listId: string | undefined
|
||||
): Promise<IFolder> {
|
||||
const [root, name] = await Promise.all([
|
||||
chatLibraryRoot(),
|
||||
requestFolderName(formKey, itemId, listId)
|
||||
]);
|
||||
const folder = getSP().web.getFolderByServerRelativePath(`${root}/${name}`);
|
||||
|
||||
const exists = await folder
|
||||
@@ -106,11 +140,12 @@ async function ensureRequestFolder(formKey: RequestTypeId, itemId: number): Prom
|
||||
export async function uploadChatFiles(
|
||||
formKey: RequestTypeId,
|
||||
itemId: number,
|
||||
listId: string | undefined,
|
||||
files: File[]
|
||||
): Promise<string[]> {
|
||||
if (files.length === 0) return [];
|
||||
|
||||
const folder = await ensureRequestFolder(formKey, itemId);
|
||||
const folder = await ensureRequestFolder(formKey, itemId, listId);
|
||||
const stamp = fileStamp(new Date());
|
||||
const storedNames: string[] = [];
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ export async function getChatMessages(
|
||||
// Адрес библиотеки спрашиваем, только если в переписке ЕСТЬ файлы: у заявки
|
||||
// без вложений чат тогда вообще не зависит от библиотеки — ни лишнего
|
||||
// запроса, ни падения, если её переименуют.
|
||||
const folderUrl = hasAttachments(comments) ? await chatFilesFolderUrl(formKey, itemId) : '';
|
||||
const folderUrl = hasAttachments(comments) ? await chatFilesFolderUrl(formKey, itemId, listId) : '';
|
||||
return toChatMessages(comments, currentUserEmail, folderUrl);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,6 @@ export async function addChatMessage(
|
||||
text: string,
|
||||
files: File[] = []
|
||||
): Promise<void> {
|
||||
const storedNames = await uploadChatFiles(formKey, itemId, files);
|
||||
const storedNames = await uploadChatFiles(formKey, itemId, listId, files);
|
||||
await commentsOf(formKey, itemId, listId).add(buildCommentText(text, storedNames));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user