|
1 | 1 | <template>
|
2 |
| - <!-- 定义tab组件 --> |
| 2 | + <!-- 定义 tab 组件:撰写/回复等 --> |
3 | 3 | <DefineTab v-slot="{ active, text, itemClick }">
|
4 | 4 | <span
|
5 | 5 | class="inline-block w-1/2 rounded-full cursor-pointer text-center leading-[30px] relative z-1 text-[5C6370] hover:text-black"
|
|
9 | 9 | {{ text }}
|
10 | 10 | </span>
|
11 | 11 | </DefineTab>
|
12 |
| - <!-- 定义label组件 --> |
| 12 | + <!-- 定义 label 组件:长度/格式/语气/语言等 --> |
13 | 13 | <DefineLabel v-slot="{ label, hint, hintClick }">
|
14 | 14 | <h3 class="mt-5 mb-3 flex items-center justify-between text-[14px]">
|
15 | 15 | <span>{{ label }}</span>
|
|
23 | 23 | </span>
|
24 | 24 | </h3>
|
25 | 25 | </DefineLabel>
|
| 26 | + |
26 | 27 | <!-- TODO 小屏幕的时候是定位在左边的,大屏是分开的 -->
|
27 | 28 | <div class="relative" v-bind="$attrs">
|
28 | 29 | <!-- tab -->
|
|
99 | 100 | </template>
|
100 | 101 |
|
101 | 102 | <script setup lang="ts">
|
102 |
| - import { createReusableTemplate } from '@vueuse/core' |
103 |
| - import { ref } from 'vue' |
104 |
| - import Tag from './Tag.vue' |
105 |
| - import { WriteParams } from '@/api/ai/writer' |
106 |
| - import { omit } from 'lodash-es' |
107 |
| - import { getIntDictOptions } from '@/utils/dict' |
108 |
| - import dataJson from '../data.json' |
109 |
| -
|
110 |
| - type TabType = WriteParams['type'] |
111 |
| -
|
112 |
| - const message = useMessage() |
113 |
| -
|
114 |
| - defineProps<{ |
115 |
| - isWriting: boolean |
116 |
| - }>() |
117 |
| -
|
118 |
| - const emits = defineEmits<{ |
119 |
| - (e: 'submit', params: Partial<WriteParams>) |
120 |
| - (e: 'example', param: 'write' | 'reply') |
121 |
| - }>() |
122 |
| -
|
123 |
| - const example = (type: 'write' | 'reply') => { |
124 |
| - writeForm.value = { |
125 |
| - ...initData, |
126 |
| - ...omit(dataJson[type], ['data']) |
127 |
| - } |
128 |
| - emits('example', type) |
129 |
| - } |
130 |
| -
|
131 |
| - const selectedTab = ref<TabType>(1) |
132 |
| - const tabs: { |
133 |
| - text: string |
134 |
| - value: TabType |
135 |
| - }[] = [ |
136 |
| - { text: '撰写', value: 1 }, |
137 |
| - { text: '回复', value: 2 } |
138 |
| - ] |
139 |
| - const [DefineTab, ReuseTab] = createReusableTemplate<{ |
140 |
| - active?: boolean |
141 |
| - text: string |
142 |
| - itemClick: () => void |
143 |
| - }>() |
144 |
| -
|
145 |
| - const initData: WriteParams = { |
146 |
| - type: 1, |
147 |
| - prompt: '', |
148 |
| - originalContent: '', |
149 |
| - tone: 1, |
150 |
| - language: 1, |
151 |
| - length: 1, |
152 |
| - format: 1 |
153 |
| - } |
154 |
| - const writeForm = ref<WriteParams>({ ...initData }) |
155 |
| -
|
156 |
| - const writeTags = { |
157 |
| - // 长度 |
158 |
| - lenTags: getIntDictOptions('ai_write_length'), |
159 |
| - // 格式 |
160 |
| -
|
161 |
| - formatTags: getIntDictOptions('ai_write_format'), |
162 |
| - // 语气 |
163 |
| -
|
164 |
| - toneTags: getIntDictOptions('ai_write_tone'), |
165 |
| - // 语言 |
166 |
| - langTags: getIntDictOptions('ai_write_language') |
167 |
| - // |
| 103 | +import { createReusableTemplate } from '@vueuse/core' |
| 104 | +import { ref } from 'vue' |
| 105 | +import Tag from './Tag.vue' |
| 106 | +import { WriteParams } from '@/api/ai/writer' |
| 107 | +import { omit } from 'lodash-es' |
| 108 | +import { getIntDictOptions } from '@/utils/dict' |
| 109 | +import dataJson from '../data.json' |
| 110 | +
|
| 111 | +type TabType = WriteParams['type'] |
| 112 | +
|
| 113 | +const message = useMessage() |
| 114 | +
|
| 115 | +defineProps<{ |
| 116 | + isWriting: boolean |
| 117 | +}>() |
| 118 | +
|
| 119 | +const emits = defineEmits<{ |
| 120 | + (e: 'submit', params: Partial<WriteParams>) |
| 121 | + (e: 'example', param: 'write' | 'reply') |
| 122 | +}>() |
| 123 | +
|
| 124 | +const example = (type: 'write' | 'reply') => { |
| 125 | + writeForm.value = { |
| 126 | + ...initData, |
| 127 | + ...omit(dataJson[type], ['data']) |
168 | 128 | }
|
169 |
| -
|
170 |
| - const [DefineLabel, ReuseLabel] = createReusableTemplate<{ |
171 |
| - label: string |
172 |
| - class?: string |
173 |
| - hint?: string |
174 |
| - hintClick?: () => void |
175 |
| - }>() |
176 |
| -
|
177 |
| - const switchTab = (value: TabType) => { |
178 |
| - selectedTab.value = value |
179 |
| - writeForm.value = { ...initData } |
| 129 | + emits('example', type) |
| 130 | +} |
| 131 | +
|
| 132 | +const selectedTab = ref<TabType>(1) |
| 133 | +const tabs: { |
| 134 | + text: string |
| 135 | + value: TabType |
| 136 | +}[] = [ |
| 137 | + { text: '撰写', value: 1 }, // TODO @hhhero:1、2 这个枚举到 constants 里。方便后续万一要调整 |
| 138 | + { text: '回复', value: 2 } |
| 139 | +] |
| 140 | +const [DefineTab, ReuseTab] = createReusableTemplate<{ |
| 141 | + active?: boolean |
| 142 | + text: string |
| 143 | + itemClick: () => void |
| 144 | +}>() |
| 145 | +
|
| 146 | +const initData: WriteParams = { |
| 147 | + type: 1, |
| 148 | + prompt: '', |
| 149 | + originalContent: '', |
| 150 | + tone: 1, |
| 151 | + language: 1, |
| 152 | + length: 1, |
| 153 | + format: 1 |
| 154 | +} |
| 155 | +// TODO @hhhero:这个字段,要不叫 formData,和其他模块保持一致。然后 initData 和它也更好对应上 |
| 156 | +const writeForm = ref<WriteParams>({ ...initData }) |
| 157 | +
|
| 158 | +// TODO @hhhero:这种一次性的变量,要不直接 vue template 直接调用。目的是:让 ts 这块,更专注逻辑哈。 |
| 159 | +const writeTags = { |
| 160 | + // 长度 TODO @hhhero:注释放在和面哈; |
| 161 | + // TODO @hhhero:一般 length 不用缩写哈。更完整会更容易阅读; |
| 162 | + lenTags: getIntDictOptions('ai_write_length'), |
| 163 | + // 格式 |
| 164 | +
|
| 165 | + formatTags: getIntDictOptions('ai_write_format'), |
| 166 | + // 语气 |
| 167 | +
|
| 168 | + toneTags: getIntDictOptions('ai_write_tone'), |
| 169 | + // 语言 |
| 170 | + langTags: getIntDictOptions('ai_write_language') |
| 171 | + // |
| 172 | +} |
| 173 | +
|
| 174 | +// TODO @hhhero:这个写法不错。要不写个简单的注释,我怕很多人不懂哈。 |
| 175 | +const [DefineLabel, ReuseLabel] = createReusableTemplate<{ |
| 176 | + label: string |
| 177 | + class?: string |
| 178 | + hint?: string |
| 179 | + hintClick?: () => void |
| 180 | +}>() |
| 181 | +
|
| 182 | +const switchTab = (value: TabType) => { |
| 183 | + selectedTab.value = value |
| 184 | + writeForm.value = { ...initData } |
| 185 | +} |
| 186 | +
|
| 187 | +const submit = () => { |
| 188 | + if (selectedTab.value === 2 && !writeForm.value.originalContent) { |
| 189 | + message.warning('请输入原文') |
| 190 | + return |
180 | 191 | }
|
181 |
| -
|
182 |
| - const submit = () => { |
183 |
| - if (selectedTab.value === 2 && !writeForm.value.originalContent) { |
184 |
| - message.warning('请输入原文') |
185 |
| - return |
186 |
| - } else if (!writeForm.value.prompt) { |
187 |
| - message.warning(`请输入${selectedTab.value === 1 ? '写作' : '回复'}内容`) |
188 |
| - return |
189 |
| - } |
190 |
| - emits('submit', { |
191 |
| - ...(selectedTab.value === 1 ? omit(writeForm.value, ['originalContent']) : writeForm.value), |
192 |
| - type: selectedTab.value |
193 |
| - }) |
| 192 | + if (!writeForm.value.prompt) { |
| 193 | + message.warning(`请输入${selectedTab.value === 1 ? '写作' : '回复'}内容`) |
| 194 | + return |
194 | 195 | }
|
| 196 | + emits('submit', { |
| 197 | + ...(selectedTab.value === 1 ? omit(writeForm.value, ['originalContent']) : writeForm.value), |
| 198 | + type: selectedTab.value |
| 199 | + }) |
| 200 | +} |
195 | 201 | </script>
|
0 commit comments