bill il y a 3 ans
Parent
commit
42ccbc516a

+ 1 - 1
package.json

@@ -13,7 +13,7 @@
     "axios": "^0.27.2",
     "mitt": "^3.0.0",
     "vue": "^3.2.37",
-    "vue-cropper": "^0.5.8",
+    "vue-cropper": "1.0.2",
     "vue-router": "^4.1.3"
   },
   "devDependencies": {

+ 4 - 4
pnpm-lock.yaml

@@ -10,7 +10,7 @@ specifiers:
   typescript: ^4.6.4
   vite: ^3.0.0
   vue: ^3.2.37
-  vue-cropper: ^0.5.8
+  vue-cropper: 1.0.2
   vue-router: ^4.1.3
   vue-tsc: ^0.38.4
 
@@ -19,7 +19,7 @@ dependencies:
   axios: 0.27.2
   mitt: 3.0.0
   vue: 3.2.37
-  vue-cropper: 0.5.8
+  vue-cropper: 1.0.2
   vue-router: 4.1.3_vue@3.2.37
 
 devDependencies:
@@ -817,8 +817,8 @@ packages:
       fsevents: 2.3.2
     dev: true
 
-  /vue-cropper/0.5.8:
-    resolution: {integrity: sha512-Xgi/aLQCcNCiBTUdovy/i4LWx0G7fQnAENBpDWA3J4i87Zlk9DJRksXrClsQ6nnaFRfQVkMimij5GEvAMaXdYw==}
+  /vue-cropper/1.0.2:
+    resolution: {integrity: sha512-ZD1kl8OMMrDXJOS1ZRdnohh2BFfYjTeq+r7+yAahydQvrVOKbzXixx6f8LCoMjB+AgAf5BXnlWsZxmu964wJYA==}
     dev: false
 
   /vue-router/4.1.3_vue@3.2.37:

+ 3 - 8
public/lib/potree/potree.js

@@ -115162,15 +115162,10 @@ ENDSEC
             
             
             viewer.addEventListener('global_single_click',(e)=>{
-<<<<<<< HEAD
-                if(viewer.inputHandler.selection[0] ||//正在平移和旋转,不允许更换
-                    viewer.scene.cameraAnimations.length  //正在播放
-=======
-                if( viewer.scene.cameraAnimations.length  //正在播放
-                    || e.drag && e.drag.notPressMouse   //在加测量线
-                    || viewer.mainViewport.view.isFlying() //有其他校准
+                if(/* viewer.inputHandler.selection[0] ||//正在平移和旋转,不允许更换 */
+                    viewer.scene.cameraAnimations.length ||  //正在播放
+                    e.drag && e.drag.notPressMouse   //在加测量线
                     //e.clickElement && e.clickElement != e.intersect.object
->>>>>>> local
                 ){
                     return
                 }

+ 44 - 12
src/api/tagging-style.ts

@@ -1,6 +1,12 @@
 import axios from './instance'
-import { TAGGING_LIST } from './constant'
-import { fetchTaggings } from './tagging'
+import { TAGGING_STYLE_LIST, INSERT_TAGGING_STYLE, DELETE_TAGGING_STYLE, UPLOAD_HEADS } from './constant'
+import { jsonToForm } from '@/utils'
+interface ServiceStyle {
+  iconId: number,
+  iconTitle: string,
+  iconUrl: string,
+  isSystem: number
+}
 
 export interface TaggingStyle {
   id: string
@@ -9,16 +15,42 @@ export interface TaggingStyle {
   default: boolean
 }
 
+const toLocal = (serviceStyle: ServiceStyle) : TaggingStyle => ({
+  id: serviceStyle.iconId.toString(),
+  name: serviceStyle.iconTitle,
+  icon: serviceStyle.iconUrl,
+  default: Boolean(serviceStyle.isSystem)
+})
+
+const toService = (style: TaggingStyle): ServiceStyle => ({
+  iconId: Number(style.id),
+  iconTitle: style.name,
+  iconUrl: style.icon,
+  isSystem: Number(style.default)
+
+})
+
 export type TaggingStyles = TaggingStyle[]
 
-export const getTaggingStyles = async () => {
-  // axios.post<TaggingStyles>(TAGGING_LIST)
-  return [
-    {
-      id: '1', 
-      icon: 'static/img_default/lQLPDhrvVzvNvTswMLAOU-UNqYnnZQG1YPJUwLwA_48_48.png',
-      name: '111',
-      default: true
-    }
-  ]
+export const fetchTaggingStyles = async () => {
+  const data = await axios.get<ServiceStyle[]>(TAGGING_STYLE_LIST)
+  return data.map(toLocal)
+}
+
+export const postAddTaggingStyle = async (props: {file: Blob, iconTitle: string}) => {
+  
+  const data = await axios<ServiceStyle>({
+    method: 'POST',
+    headers: UPLOAD_HEADS,
+    url: INSERT_TAGGING_STYLE, 
+    data: jsonToForm({
+      file: new File([props.file], `${props.iconTitle}.png`),
+      iconTitle: props.iconTitle
+    })
+  })
+  return toLocal(data)
+}
+
+export const postDeleteTaggingStyle = async (id: TaggingStyle['id']) => {
+  await axios.post(DELETE_TAGGING_STYLE, { iconId: Number(id) })
 }

+ 15 - 15
src/api/tagging.ts

@@ -16,9 +16,9 @@ interface ServerTagging {
   "hotIconUrl": string,
   "getMethod": string,
   "getUser": string,
-  "id": number,
-  "meta": { "name": string, "url": string } [],
-  "remark": string,
+  "tagId": number,
+  "tagImgUrl": string,
+  "leaveBehind": string,
   "tagDescribe": string,
   "tagTitle": string,
 }
@@ -39,47 +39,47 @@ export type Taggings = Tagging[]
 
 
 const serviceToLocal = (serviceTagging: ServerTagging): Tagging => ({
-  id: serviceTagging.id.toString(),
+  id: serviceTagging.tagId.toString(),
   styleId: serviceTagging.hotIconId.toString(),
   title: serviceTagging.tagTitle,
   desc: serviceTagging.tagDescribe,
-  part: serviceTagging.remark,
+  part: serviceTagging.leaveBehind,
   method: serviceTagging.getMethod,
   principal: serviceTagging.getUser,
-  images: serviceTagging.meta.map(({url}) => url),
+  images: JSON.parse(serviceTagging.tagImgUrl)
 })
 
-const localToService = (tagging: Tagging, update = false): PartialProps<ServerTagging, 'id' | 'hotIconUrl'> & { fusionId: number } => ({
+const localToService = (tagging: Tagging, update = false): PartialProps<ServerTagging, 'tagId' | 'hotIconUrl'> & { fusionId: number } => ({
   "hotIconId": Number(tagging.styleId),
   "fusionId": params.caseId,
   "getMethod": tagging.method,
   "getUser": tagging.principal,
   "hotIconUrl": "static/img_default/lQLPDhrvVzvNvTswMLAOU-UNqYnnZQG1YPJUwLwA_48_48.png",
-  "id": update ? Number(tagging.id) : undefined,
-  "meta": tagging.images.map(((item, i) => ({ "name": item, "url": item }))),
-  "remark": tagging.part,
+  "tagId": update ? Number(tagging.id) : undefined,
+  "tagImgUrl": JSON.stringify(tagging.images),
+  "leaveBehind": tagging.part,
   "tagDescribe": tagging.desc,
   "tagTitle": tagging.title,
 })
 
 
 export const fetchTaggings = async () => {
-  const staggings = await axios.post<ServerTagging[]>(TAGGING_LIST, {})
+  const staggings = await axios.get<ServerTagging[]>(TAGGING_LIST, { params: { caseId: params.caseId } })
   return staggings.map(serviceToLocal)
 }
 
 export const postAddTagging = async (tagging: Tagging) => {
-  const stagging = await axios.post<ServerTagging>(INSERT_TAGGING, localToService(tagging))
-  return serviceToLocal(stagging)
+  const stagging = await axios.post<ServerTagging>(INSERT_TAGGING, { ...localToService(tagging), caseId: params.caseId })
+  return serviceToLocal(stagging, )
 }
 
 export const postUpdateTagging = (tagging: Tagging) => {
-  return axios.post<undefined>(UPDATE_TAGGING, localToService(tagging, true))
+  return axios.post<undefined>(UPDATE_TAGGING, { ...localToService(tagging, true), caseId: params.caseId })
 }
   
 
 export const postDeleteTagging = (id: Tagging['id']) => {
-  return axios.post<undefined>(DELETE_TAGGING, { ids: [id] })
+  return axios.post<undefined>(DELETE_TAGGING, { tagId: id })
 }
 
   

+ 3 - 1
src/components/bill-ui/components/cropper/cropper.vue

@@ -15,7 +15,7 @@
 import { VueCropper } from 'vue-cropper'
 import Confirm from '../dialog/Confirm.vue'
 import { computed, defineProps, ref } from 'vue'
-// import 'vue-cropper/dist/index.css'
+import 'vue-cropper/dist/index.css'
 
 const layerWidth = 500
 const props = defineProps({
@@ -66,11 +66,13 @@ const on = {
 }
 
 const clickHandler = async (status) => {
+  console.log(status)
   if (status === 'ok') {
     const data = await Promise.all([
       new Promise(resolve => vmRef.value.getCropBlob(resolve)),
       new Promise(resolve => vmRef.value.getCropData(resolve)),
     ])
+    console.log('emmm', data)
     props.cb(null, data)
   } else {
     props.cb()

+ 3 - 1
src/components/bill-ui/utils/index.js

@@ -16,7 +16,9 @@ export const toRawType = value => toTypeString(value).slice(8, -1)
  * 判断是否函数
  * @param {any} target 参数对象
  */
-export const isFunction = target => toRawType(target) === 'Function'
+export const isFunction = target => {
+    return toRawType(target) === 'Function' || toRawType(target) === 'AsyncFunction'
+}
 
 /**
  * 判断是否普通对象

+ 8 - 1
src/components/tagging/list.vue

@@ -14,8 +14,15 @@
 <script lang="ts" setup>
 import { computed } from 'vue'
 import Sign from './sign.vue'
-import { Tagging, getFuseModelShowVariable, getFuseModel, getTaggingPositions, TaggingPosition, taggingPositions } from '@/store';
 import { custom } from '@/env'
+import { 
+  getFuseModelShowVariable, 
+  getFuseModel, 
+  getTaggingPositions, 
+  taggingPositions 
+} from '@/store';
+
+import type { Tagging, TaggingPosition } from '@/store';
 
 const props = defineProps<{ tagging: Tagging }>()
 

+ 1 - 1
src/env/index.ts

@@ -39,7 +39,7 @@ export type Params = {
   token?: string
 }
 
-export const baseURL = params.baseURL ? params.baseURL : import.meta.env.DEV ? '/api' : ''
+export const baseURL = params.baseURL ? params.baseURL : import.meta.env.DEV ? '/local' : ''
 
 
 export const getResource = (uri: string) => {

+ 1 - 2
src/layout/model-list/sign.vue

@@ -4,11 +4,10 @@
     <div class="model-action" @click.stop>
         <ui-input type="checkbox" v-model="show" />
       <ui-icon 
-        v-if="custom.modelsChangeStore && model.type !== SceneType.SWSS"
+        v-if="model.type !== SceneType.SWSS && custom.modelsChangeStore" 
         type="del" 
         ctrl 
         @click="$emit('delete')" 
-        v-if="model.type !== SceneType.SWSS && custom.modelsChangeStore" 
       />
     </div>
   </div>

+ 4 - 4
src/store/index.ts

@@ -1,5 +1,5 @@
 import { ref } from 'vue'
-import { initialModels } from './scene'
+import { initialScenes } from './scene'
 import { initialFuseModels } from './fuse-model'
 import { initialTaggings } from './tagging'
 import { initialTaggingStyles } from './tagging-style'
@@ -10,10 +10,10 @@ export const error = ref(false)
 
 export const initialStore = async () => {
   await Promise.all([
-    initialModels(),
+    initialScenes(),
     initialFuseModels(),
-    // initialTaggingStyles(),
-    // initialTaggings(),
+    initialTaggingStyles(),
+    initialTaggings(),
     // initialGuides()
   ])
   try {

+ 2 - 2
src/store/scene.ts

@@ -8,9 +8,9 @@ export type { Scene, Scenes } from '@/api'
 
 export const scenes = ref<Scenes>([])
 
-export const getModel = (modelId: Scene['id']) => scenes.value.find(scene => scene.id === modelId)
+export const getScene = (sceneId: Scene['id']) => scenes.value.find(scene => scene.id === sceneId)
 
-export const initialModels = fetchStoreItems(
+export const initialScenes = fetchStoreItems(
   scenes, 
   fetchScenes, 
 )

+ 57 - 7
src/store/tagging-style.ts

@@ -1,17 +1,67 @@
 import { ref, computed } from 'vue'
-import { getTaggingStyles } from '@/api'
+import { autoSetModeCallback, createTemploraryID } from './sys'
+import { 
+  fetchTaggingStyles,
+  postAddTaggingStyle,
+  postDeleteTaggingStyle
+} from '@/api'
+import { 
+  addStoreItem, 
+  deleteStoreItem, 
+  fetchStoreItems, 
+  recoverStoreItems, 
+  saveStoreItems 
+} from '@/utils'
+
+import type { TaggingStyle as STaggingStyle } from '@/api'
+
+export type TaggingStyle = LocalMode<STaggingStyle, 'icon'>
+export type TaggingStyles = TaggingStyle[]
 
-import type { TaggingStyles, TaggingStyle } from '@/api'
 
 export const taggingStyles = ref<TaggingStyles>([])
 export const defaultStyle = computed(() => taggingStyles.value.find(style => style.default))
 
-export const getTaggingStyle = (id: TaggingStyle['id']) => 
-  taggingStyles.value.find(style => style.id === id)
+export const createTaggingStyle = (style: Partial<TaggingStyle> = {}): TaggingStyle => ({
+  id: createTemploraryID(),
+  icon: '',
+  default: false,
+  name: '',
+  ...style
+})
+
+export const getTaggingStyle = (id: TaggingStyle['id']) => {
+  return taggingStyles.value.find(style => style.id === id)
+}
+
 
-export const initialTaggingStyles = async () => {
-  taggingStyles.value = await getTaggingStyles()
+let bcStyles: TaggingStyles = []
+export const getBackupTaggingStyles = () => bcStyles
+export const backupTaggingStyles = () => {
+  bcStyles = taggingStyles.value.map(style => ({...style}))
 }
+export const recoverTaggingStyles = recoverStoreItems(taggingStyles, getBackupTaggingStyles)
 
 
-export type { TaggingStyle, TaggingStyles } from '@/api'
+export const initialTaggingStyles = fetchStoreItems(taggingStyles, fetchTaggingStyles, backupTaggingStyles)
+export const addTaggingStyle = addStoreItem(taggingStyles, async (tagging) => {
+  if (typeof tagging.icon === 'string') {
+    return tagging
+  } else {
+    return postAddTaggingStyle({ file: tagging.icon.blob, iconTitle: tagging.name })
+  }
+})
+export const deleteTaggingStyle = deleteStoreItem(taggingStyles, style => postDeleteTaggingStyle(style.id))
+export const saveTaggingStyles = saveStoreItems(
+  taggingStyles, 
+  getBackupTaggingStyles,
+  {
+    add: addTaggingStyle,
+    delete: deleteTaggingStyle,
+  }
+)
+export const autoSaveTaggingStyles = autoSetModeCallback(taggingStyles, {
+  backup: backupTaggingStyles,
+  recovery: recoverTaggingStyles,
+  save: saveTaggingStyles,
+})

+ 20 - 5
src/store/tagging.ts

@@ -1,7 +1,7 @@
 import { ref } from 'vue'
 import { togetherCallback } from '@/utils'
 import { autoSetModeCallback, createTemploraryID } from './sys'
-import { defaultStyle } from './tagging-style'
+import { defaultStyle, getTaggingStyle } from './tagging-style'
 import { 
   initTaggingPositionsByTagging, 
   saveTaggingPositions,
@@ -11,6 +11,12 @@ import {
   getTaggingPositions
 } from './tagging-positions'
 import { 
+  saveTaggingStyles,
+  recoverTaggingStyles,
+  backupTaggingStyles,
+  taggingStyles
+} from './tagging-style'
+import { 
   fetchTaggings, 
   postAddTagging,
   postDeleteTagging,
@@ -28,6 +34,7 @@ import {
 
 
 import type { Tagging as STagging } from '@/api'
+import type { TaggingStyle } from './tagging-style'
 
 export type Tagging = LocalMode<STagging, 'images'>
 export type Taggings = Tagging[]
@@ -79,7 +86,7 @@ export const updateTagging = updateStoreItem(taggings, postUpdateTagging, transf
 export const deleteTagging = deleteStoreItem(taggings, tagging => postDeleteTagging(tagging.id))
 export const initialTaggings = fetchStoreItems(taggings, async () => {
   const taggings = await fetchTaggings()
-  await Promise.all(taggings.map(initTaggingPositionsByTagging))
+  // await Promise.all(taggings.map(initTaggingPositionsByTagging))
   return taggings
 }, backupTaggings)
 export const saveTaggings = saveStoreItems(
@@ -92,10 +99,18 @@ export const saveTaggings = saveStoreItems(
   }
 )
 
-export const autoSaveTaggings = autoSetModeCallback([taggings, taggingPositions], {
-  backup: togetherCallback([backupTaggings, backupTaggingPositions]),
-  recovery: togetherCallback([recoverTaggings, recoverTaggingPositions]),
+
+export const autoSaveTaggings = autoSetModeCallback([taggings, taggingPositions, taggingStyles], {
+  backup: togetherCallback([backupTaggings, backupTaggingPositions, backupTaggingStyles]),
+  recovery: togetherCallback([recoverTaggings, recoverTaggingPositions, recoverTaggingStyles]),
   save: async () => {
+    const styles = taggings.value.map(tagging => getTaggingStyle(tagging.styleId))
+    await saveTaggingStyles()
+    for (let i = 0; i < styles.length; i++) {
+      if (styles[i]) {
+        taggings.value[i].styleId = (styles[i] as TaggingStyle).id
+      }
+    }
     await saveTaggings()
     await saveTaggingPositions()
   },

+ 3 - 1
src/style.scss

@@ -28,7 +28,9 @@ body {
   --left-pano-width: 340px;
 }
 
-
+h1, h2, h3, h4, h5, h6 {
+  color: inherit;
+}
 a {
   color: var(--color-main-normal);
 }

+ 36 - 57
src/views/tagging/edit.vue

@@ -5,13 +5,13 @@
           标注
           <ui-icon type="close" ctrl @click.stop="$emit('quit')" class="edit-close" />
         </h3>
-        <!-- <StylesManage 
+        <StylesManage 
           :styles="styles" 
           :active="(getTaggingStyle(tagging.styleId) as TaggingStyle)" 
           @change="style => tagging.styleId = style.id" 
           @delete="deleteStyle"
-          @uploadStyles="uploadStyles" 
-        /> -->
+          @uploadStyle="uploadStyle" 
+        />
         <ui-input 
           require 
           class="input" 
@@ -94,24 +94,20 @@
 </template>
 
 <script lang="ts" setup>
-// import StylesManage from './styles.vue'
+import StylesManage from './styles.vue'
 import Images from './images.vue'
-// import { LocalTaggingStyle } from './styles.vue'
 import { computed, ref } from 'vue';
 import { Dialog, Message } from 'bill/index';
 import { 
-  // taggingStyles,
+  taggingStyles,
   Tagging, 
-  Taggings,
-  // TemploraryID, 
-  // getTaggingStyle, 
-  // TaggingStyle,
-  // taggings
+  getTaggingStyle, 
+  TaggingStyle,
+  taggings,
+  isTemploraryID
 } from '@/store'
 
 export type EditProps = {
-  // taggingFiles: WeakMap<Tagging, Array<File>>
-  // styleFile: WeakMap<TaggingStyle, File>
   data: Tagging
 }
 
@@ -129,48 +125,31 @@ const submitHandler = () => {
   }
 }
 
-// const styles = computed(() => 
-//   [...taggingStyles.value].sort((a, b) => 
-//     a.default ? -1 : b.default ? 1 : a.id === TemploraryID ? -1 : b.id === TemploraryID ? 1 : 0
-//   )
-// )
-
-// const deleteStyle = (style: TaggingStyle) => {
-//     const index = taggingStyles.value.indexOf(style)
-//     if (~index) {
-//       taggingStyles.value.splice(index, 1)
-//       for (const item of taggings.value) {
-//         if (item.styleId === style.id) {
-//           const defaultIcon = taggingStyles.value.find(({ default: isDefault }) => isDefault)?.id
-//           if (defaultIcon) {
-//             item.styleId = defaultIcon
-//           }
-//         }
-//       }
-//     }
-// }
-
-// const normalizeIcon = (icon: LocalTaggingStyle['icon'] | string): string => {
-//   if (typeof icon === 'string') {
-//     return icon
-//   } else {
-//     return icon.preview
-//   }
-// }
-
-// const uploadStyles = (unStyles: Array<LocalTaggingStyle>) => {
-//   const addStyles = unStyles.map(item => {
-//     const style = {
-//       ...item,
-//       icon: normalizeIcon(item.icon),
-//     }
+const styles = computed(() => 
+  [...taggingStyles.value].sort((a, b) => 
+    a.default ? -1 : b.default ? 1 : isTemploraryID(a.id) ? -1 : isTemploraryID(b.id) ? 1 : 0
+  )
+)
+
+const deleteStyle = (style: TaggingStyle) => {
+    const index = taggingStyles.value.indexOf(style)
+    if (~index) {
+      taggingStyles.value.splice(index, 1)
+      for (const item of taggings.value) {
+        if (item.styleId === style.id) {
+          const defaultIcon = taggingStyles.value.find(({ default: isDefault }) => isDefault)?.id
+          if (defaultIcon) {
+            item.styleId = defaultIcon
+          }
+        }
+      }
+    }
+}
 
-//     props.styleFile.set(style, item.icon.file)
-//     return style
-//   })
-//   styles.value.push(...addStyles)
-//   tagging.value.styleId = addStyles[0].id
-// }
+const uploadStyle = (style: TaggingStyle) => {
+  taggingStyles.value.push(style)
+  tagging.value.styleId = style.id
+}
 
 type LocalImageFile = { file: File; preview: string } | Tagging['images'][number]
 const fileChange = (file: LocalImageFile | LocalImageFile[]) => {
@@ -180,7 +159,6 @@ const fileChange = (file: LocalImageFile | LocalImageFile[]) => {
     if (typeof atom === 'string' || 'blob' in atom) {
       return atom
     } else {
-      console.log(atom)
       return {
         blob: atom.file,
         url: atom.preview
@@ -207,11 +185,12 @@ const delImageHandler = async (file: Tagging['images'][number]) => {
   z-index: 2000;
   padding: 20px;
   overflow-y: auto;
-  display: flex;
-  justify-content: center;
+  text-align: center;
 }
 
 .edit-hot-item {
+  display: inline-block;
+  text-align: left;
   margin-top: 100px;
   margin-bottom: 20px;
   width: 400px;

+ 5 - 5
src/views/tagging/index.vue

@@ -60,12 +60,12 @@ import {
   autoSaveTaggings, 
   createTagging,
   enterEdit, 
-  Model,
-  getModel,
+  getFuseModel,
   getFuseModelShowVariable,
   getTaggingPositions,
   taggingPositions,
-  createTaggingPosition
+  createTaggingPosition,
+  FuseModel
 } from '@/store'
 import { 
   custom, 
@@ -108,7 +108,7 @@ const flyTaggingPositions = (tagging: Tagging) => {
       return;
     }
     const position = positions[i]
-    const model = getModel(position.modelId)
+    const model = getFuseModel(position.modelId)
     if (!model || !getFuseModelShowVariable(model).value) {
       flyIndex(i + 1)
       return;
@@ -146,7 +146,7 @@ watch(selectTagging, (a, b, onCleanup) => {
   if (selectTagging.value) {
     const leave = () => selectTagging.value = null
 
-    let currentModel: Model | null = custom.currentModel
+    let currentModel: FuseModel | null = custom.currentModel
     if (!currentModel) {
       for (const [model, show] of custom.showModelsMap.entries()) {
         show && (currentModel = model)

+ 12 - 21
src/views/tagging/styles.vue

@@ -22,7 +22,7 @@
       @click="clickHandler(hotStyle)"
     >
       <span>
-        <img :src="hotStyle.icon" />
+        <img :src="getFileUrl(hotStyle.icon)" />
         <ui-icon 
           v-if="!hotStyle.default"
           class="delete" 
@@ -32,7 +32,7 @@
       </span>
     </div>
     <div 
-      v-if="!props.all && props.styles.length > 5"
+      v-if="!props.all && props.styles.length > 6"
       class="add item style-more" 
       @click="showAll = !showAll"
     >
@@ -49,7 +49,8 @@
             :active="active" 
             all
             @quitMore="showAll = false" 
-            @uploadStyles="addStyles" @change="clickHandler"
+            @uploadStyles="style => emit('uploadStyle', style)" 
+            @change="clickHandler"
             @delete="style => emit('delete', style)"
           />
         </ui-bubble>
@@ -64,13 +65,10 @@
 
 <script setup lang="ts">
 import { TaggingStyle, TaggingStyles } from '@/store'
-import { createTemploraryID } from '@/store'
+import { createTaggingStyle } from '@/store'
 import { ref, computed, defineEmits } from 'vue'
 import { Cropper } from 'bill/index'
-
-export type LocalTaggingStyle = Omit<TaggingStyle, 'icon'> & {
-  icon: { file: File; preview: string }
-}
+import { getFileUrl } from '@/utils'
 
 const props = defineProps<{
   styles: TaggingStyles
@@ -81,7 +79,7 @@ const props = defineProps<{
 const emit = defineEmits<{
   (e: 'change', style: TaggingStyle): void
   (e: 'delete', style: TaggingStyle): void
-  (e: 'uploadStyles', styles: Array<LocalTaggingStyle>): void
+  (e: 'uploadStyle', styles: TaggingStyle): void
   (e: 'quitMore'): void
 }>()
 
@@ -90,7 +88,7 @@ const styleAll = computed(() => {
   if (props.all) {
     return props.styles
   } else {
-    const styles = props.styles.slice(0, props.styles.length > 5 ? 4 : 5)
+    const styles = props.styles.slice(0, props.styles.length > 6 ? 5 : 6)
     if (!styles.includes(props.active)) {
       styles[3] = props.active
     }
@@ -98,16 +96,13 @@ const styleAll = computed(() => {
   }
 })
 
-const iconUpload = async ({ file, preview }: LocalTaggingStyle['icon']) => {
+const iconUpload = async ({ file, preview }: { file: File, preview: string }) => {
   const data = await Cropper.open(preview)
   if (data) {
-    const item = {
-      id: createTemploraryID(),
-      icon: { file: data[0], preview: data[1] },
+    emit('uploadStyle', createTaggingStyle({ 
       name: file.name,
-      default: false,
-    }
-    emit('uploadStyles', [item])
+      icon: { url: data[1], blob: data[0] }
+    }))
   }
 }
 
@@ -117,10 +112,6 @@ const clickHandler = (hotStyle: TaggingStyle) => {
   }
   emit('change', hotStyle)
 }
-
-const addStyles = (newStyles: Array<LocalTaggingStyle>) => {
-  emit('uploadStyles', newStyles)
-}
 </script>
 
 <style lang="scss" scoped>

+ 5 - 0
vite.config.ts

@@ -26,6 +26,11 @@ export default defineConfig({
     port: 5173,
     open: true,
     proxy: {
+      '/local': {
+        target: 'http://192.168.0.38:8808',
+        changeOrigin: true,
+        rewrite: path => path.replace(/^\/local/, '')
+      },
       '/api': {
         target: 'http://192.168.0.47:8808',
         changeOrigin: true,