utils.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { Attachment, BaseSkill, Reference } from "./interface";
  2. import { strings } from './constants';
  3. export function getAttachmentType(item: Attachment | Reference) {
  4. const { type, name, fileInstance } = item ?? {};
  5. if (type) {
  6. return type;
  7. }
  8. const suffix = name?.split('.').pop();
  9. return suffix ?? fileInstance?.type?.split('/').pop() ?? 'UNKNOWN';
  10. }
  11. export function isImageType(item: Attachment | Reference) {
  12. const { name, fileInstance } = item ?? {};
  13. const suffix = name?.split('.').pop();
  14. return fileInstance?.type?.startsWith(strings.PIC_PREFIX) || strings.PIC_SUFFIX_ARRAY.includes(suffix);
  15. }
  16. export function getContentType(type: string) {
  17. const objMap = new Map([
  18. // 文档
  19. ['docx', 'word'], ['doc', 'word'], ['txt', 'word'], ['epub', 'word'], ['mobi', 'word'],
  20. // 代码
  21. ['js', 'code'], ['ts', 'code'], ['jsx', 'code'], ['tsx', 'code'], ['java', 'code'], ['py', 'code'], ['c', 'code'],
  22. ['cpp', 'code'], ['go', 'code'], ['rust', 'code'], ['php', 'code'], ['sql', 'code'], ['html', 'code'], ['css', 'code'],
  23. ['scss', 'code'], ['less', 'code'], ['md', 'code'], ['json', 'code'],
  24. // 表格
  25. ['xlsx', 'excel'], ['xls', 'excel'], ['pptx', 'ppt'], ['ppt', 'ppt'],
  26. // 视频
  27. ['mp4', 'video'], ['mkv', 'video'], ['avi', 'video'], ['mov', 'video'], ['wmv', 'video'],
  28. ['prores', 'video'], ['flv', 'video'], ['ts', 'video'], ['webm', 'video'], ['3gp', 'video'],
  29. // 音频
  30. ['flac', 'audio'], ['wav', 'audio'], ['alac', 'audio'], ['ape', 'audio'], ['mp3', 'audio'],
  31. ['aac', 'audio'], ['ogg', 'audio'], ['wma', 'audio'], ['m4a', 'audio'], ['amr', 'audio'],
  32. ['midi', 'audio'],
  33. // 图片
  34. ['png', 'image'], ['jpg', 'image'], ['jpeg', 'image'], ['gif', 'image'], ['bmp', 'image'], ['webp', 'image'],
  35. // pdf
  36. ['pdf', 'pdf'],
  37. ]);
  38. const result = objMap.get(type) ?? 'unknown';
  39. return result;
  40. }
  41. export function transformSelectSlot(obj: any) {
  42. const { attrs = {} } = obj;
  43. const { value = '' } = attrs;
  44. return {
  45. type: 'text',
  46. text: value,
  47. };
  48. }
  49. export function transformSkillSlot(obj: any) {
  50. const { type, attrs } = obj;
  51. const { value, label, hasTemplate } = attrs;
  52. return omitUndefinedFromObj({ type, value, label, hasTemplate });
  53. }
  54. export function transformInputSlot(obj: any) {
  55. const { content = [], attrs } = obj;
  56. const text = content?.[0]?.text ?? '';
  57. return {
  58. type: 'text',
  59. text: (text !== strings.ZERO_WIDTH_CHAR && text.length) ? text : attrs?.placeholder,
  60. };
  61. }
  62. export function transformText(obj: any) {
  63. const { text } = obj;
  64. return {
  65. type: 'text',
  66. text: text !== strings.ZERO_WIDTH_CHAR ? text : ''
  67. };
  68. }
  69. export const transformMap = new Map<string, any>([
  70. ['text', transformText],
  71. ['selectSlot', transformSelectSlot],
  72. ['inputSlot', transformInputSlot],
  73. ['skillSlot', transformSkillSlot],
  74. ]);
  75. export function transformJSONResult(input: any, customTransformObj: Map<string, (obj: any) => any> = new Map()) {
  76. const output: any[] = [];
  77. const traverse = (obj: any) => {
  78. const { type, content = [] } = obj;
  79. let result: any;
  80. switch (type) {
  81. case 'doc':
  82. content.forEach((item: any) => {
  83. traverse(item);
  84. });
  85. break;
  86. case 'paragraph':
  87. if (output.length > 0) {
  88. const lastItem = output[output.length - 1];
  89. if (lastItem && lastItem.type === 'text') {
  90. lastItem.text += '\n';
  91. } else {
  92. output.push({ type: 'text', text: '\n' });
  93. }
  94. }
  95. content.forEach((item: any) => {
  96. traverse(item);
  97. });
  98. break;
  99. default:
  100. const transformFn = transformMap.get(type) ?? customTransformObj.get(type);
  101. result = transformFn?.(obj);
  102. break;
  103. }
  104. if (result) {
  105. if (result.type === 'text') {
  106. const lastItem = output[output.length - 1];
  107. if (lastItem && lastItem.type === 'text') {
  108. lastItem.text += result.text;
  109. } else if (typeof result.text === 'string') {
  110. // 如果 result.text 为空字符串(比如text 节点中只有单个的零宽字符),则无需作为 output 结果
  111. // if result.text is an empty string,then it does not need to be included in output result.
  112. result.text.length && output.push(result);
  113. } else {
  114. output.push(result);
  115. }
  116. } else {
  117. output.push(result);
  118. }
  119. }
  120. };
  121. traverse(input);
  122. return output;
  123. }
  124. export function getCustomSlotAttribute() {
  125. return {
  126. default: true,
  127. parseHTML: element => true,
  128. renderHTML: attributes => ({
  129. 'data-custom-slot': attributes.isCustomSlot ? true : undefined,
  130. }),
  131. };
  132. }
  133. export function findSkillSlotInString(content: string) {
  134. const reg = /<skill-slot\s+([^>]*)><\/skill-slot>/i;
  135. const attrReg = /([\w-]+)=["']?([^"'\s>]+)["']?/g;
  136. const match = reg.exec(content);
  137. if (match) {
  138. const attrsStr = match[1];
  139. let attrMatch;
  140. let attrs = {};
  141. while ((attrMatch = attrReg.exec(attrsStr)) !== null) {
  142. attrs[attrMatch[1]] = attrMatch[2];
  143. }
  144. if (attrs['data-value']) {
  145. const obj = {
  146. label: attrs['data-label'],
  147. value: attrs['data-value'],
  148. hasTemplate: attrs['data-template'] ? attrs['data-template'] === 'true' : undefined
  149. };
  150. return omitUndefinedFromObj(obj);
  151. }
  152. }
  153. return undefined;
  154. }
  155. function omitUndefinedFromObj(obj: { [key: string]: any }) {
  156. return Object.fromEntries(
  157. Object.entries(obj).filter(([key, value]) => value !== undefined)
  158. );
  159. }
  160. export function getSkillSlotString(skill: BaseSkill) {
  161. let skillParams = '';
  162. skill.label && (skillParams += ` data-label=${skill.label}`);
  163. skill.value && (skillParams += ` data-value=${skill.value}`);
  164. (typeof skill.hasTemplate === 'boolean') && (skillParams += ` data-template=${skill.hasTemplate}`);
  165. return `<skill-slot ${skillParams}"></skill-slot>`;
  166. }