sign.vue 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <template>
  2. <ui-group-option class="sign" :class="{active}">
  3. <div class="content">
  4. <span class="cover" @click="fly">
  5. <img :src="getResource(getFileUrl(view.cover))" alt="">
  6. </span>
  7. <ui-input
  8. class="view-title-input"
  9. type="text"
  10. :modelValue="view.title"
  11. :maxlength="15"
  12. @update:modelValue="(title: string) => $emit('updateTitle', title.trim())"
  13. v-show="isEditTitle"
  14. ref="inputRef"
  15. height="28px"
  16. />
  17. <div class="title" v-show="!isEditTitle" @click="fly">
  18. <p>{{ view.title }}</p>
  19. <span> {{ getModelDesc(modelType as ModelType) }}</span>
  20. </div>
  21. </div>
  22. <div class="action" v-if="edit">
  23. <ui-icon type="order" ctrl />
  24. <ui-more
  25. :options="menus"
  26. style="margin-left: 20px"
  27. @click="(action: keyof typeof actions) => actions[action]()"
  28. />
  29. </div>
  30. </ui-group-option>
  31. </template>
  32. <script lang="ts" setup>
  33. import { ref, computed, watchEffect } from 'vue'
  34. import { useFocus } from 'bill/hook/useFocus'
  35. import { custom, getResource } from '@/env'
  36. import { deepIsRevise, getFileUrl } from '@/utils'
  37. import { loadModel, getModelDesc, ModelType, currentModel } from '@/model'
  38. import { viewToModelType } from '@/store'
  39. import type { View } from '@/store'
  40. import { Message } from 'bill/expose-common'
  41. import { ui18n } from '@/lang'
  42. const props = withDefaults(
  43. defineProps<{ view: View, edit?: boolean }>(),
  44. { edit: true }
  45. )
  46. const emit = defineEmits<{
  47. (e: 'updateCover', cover: string): void,
  48. (e: 'updateTitle', title: string): void,
  49. (e: 'delete'): void,
  50. }>()
  51. const menus = [
  52. { label: ui18n.t('sys.rename'), value: 'rename' },
  53. { label: ui18n.t('sys.del'), value: 'delete' },
  54. ]
  55. const inputRef = ref()
  56. const isEditTitle = useFocus(computed(() => inputRef.value?.vmRef.root))
  57. watchEffect(() => {
  58. if (!isEditTitle.value && !props.view.title.length) {
  59. isEditTitle.value = true
  60. Message.warning(ui18n.t('view.nameErr'))
  61. }
  62. })
  63. const actions = {
  64. delete: () => emit('delete'),
  65. rename: () => isEditTitle.value = true
  66. }
  67. const modelType = viewToModelType(props.view)
  68. const fly = async () => {
  69. const sdk = await loadModel(modelType)
  70. custom.currentView = props.view
  71. sdk.setView(props.view.flyData)
  72. }
  73. const active = computed(() => {
  74. return custom.currentView === props.view && !deepIsRevise(currentModel.value, modelType)
  75. })
  76. </script>
  77. <style lang="scss" src="./style.scss" scoped>
  78. </style>
  79. <style>
  80. .view-title-input.ui-input .text.suffix input {
  81. padding-right: 50px;
  82. }
  83. </style>