Prechádzať zdrojové kódy

feat: 更新用户和产品模型,添加ME值字段,优化角色设置逻辑

IlhamTahir 1 mesiac pred
rodič
commit
717c09a293

+ 1 - 1
src/api/user.ts

@@ -10,6 +10,6 @@ export const searchUsers = (userSearchFilter: UserSearchFilter) => {
   return httpClient.get<PageResult<User>>('/users', userSearchFilter)
 }
 
-export const setUserRoles = (id: number, roles: string[]) => {
+export const setUserRoles = (id: string, roles: string[]) => {
   return httpClient.put<User>(`/users/${id}/roles`, { roles })
 }

+ 1 - 1
src/layouts/components/UserArea.vue

@@ -20,7 +20,7 @@ const options: DropdownOption[] = [
       <TButton variant="text">
         <div class="flex gap-2 items-center">
           <TAvatar size="24px" image="https://tdesign.gtimg.com/site/avatar.jpg"></TAvatar>
-          {{ currentUser.username }}
+          {{ currentUser?.username }}
           <ChevronDownIcon />
         </div>
       </TButton>

+ 5 - 2
src/model/product.ts

@@ -13,10 +13,13 @@ export interface Product extends BaseModel{
   fiber: number;
   ash: number;
   moisture: number;
-  totalCalories: number; // 产品总能量(kcal),由后端基于ME算法计算
+  meValue: number | null; // ME值(kcal/g),直接配置的代谢能
+  totalCalories: number; // 产品总能量(kcal),由后端基于ME算法计算或直接配置
 }
 
-export interface CreateProductRequest extends Pick<Product, "name" | 'photo' | 'tags' | 'totalWeight' | 'category' | 'protein' | 'fat' | 'fiber' | 'ash' | 'moisture'> {}
+export interface CreateProductRequest extends Pick<Product, "name" | 'photo' | 'tags' | 'totalWeight' | 'category' | 'protein' | 'fat' | 'fiber' | 'ash' | 'moisture'> {
+  meValue?: number; // ME值(kcal/g),可选
+}
 
 export interface SearchProductFilter extends BaseFilterRequest{
 }

+ 3 - 0
src/model/user.ts

@@ -1,9 +1,12 @@
 import type { BaseFilterRequest, AuditBaseModel } from '@/model/base'
+import type { Role } from '@/model/role'
 
 export interface User extends AuditBaseModel{
   username: string
   locked: boolean
   enabled: boolean
+  name?: string
+  roles?: Role[]
 }
 
 

+ 1 - 8
src/pages/carousal/components/CarousalDialog.vue

@@ -9,7 +9,7 @@
   >
     <TForm v-if="carousalData" ref="formRef" :data="carousalData" :rules="rules" resetType="initial" label-width="100">
         <TFormItem label="轮播图:" name="imageUrl">
-          <ImageUpload @on-success="handleSuccessImg" :image-url="imgUrl"/>
+          <ImageUpload v-model="carousalData.imageUrl" />
         </TFormItem>
         <TFormItem label="跳转类型:" name="targetType" >
           <t-radio-group :default-value="carousalData.targetType" v-model="carousalData.targetType">
@@ -52,7 +52,6 @@ const carousalData = ref<UpdateCarousalsRequest>({
   targetId: '',
   targetUrl: '',
 })
-const imgUrl = ref({})
 const rules = computed(() => {
   const commonRules = {
     imageUrl: [
@@ -82,10 +81,6 @@ const rules = computed(() => {
     ? {...commonRules, targetId: [{ required: true, message: '文章 id 不能为空', type: 'error', trigger: 'blur' }, { required: true, message: '文章 id 不能为空', type: 'error', trigger: 'change' }, { whitespace: true, message: '网址路径不能为空' }] }
     : {...commonRules, targetUrl: [{ required: true, message: '网址路径不能为空', type: 'error', trigger: 'blur' }, { required: true, message: '网址路径不能为空', type: 'error', trigger: 'change' }, { whitespace: true, message: '网址路径不能为空' }] };
 });
-const handleSuccessImg = (res:string) => {
-  console.log(res,'图片地址')
-  carousalData.value.imageUrl = res
-}
 const typeOption = reactive([
   { value: 'article', label: '文章' },
   { value: 'url', label: '地址' },
@@ -102,8 +97,6 @@ watch(
   () => props.carousal,
   (newClassify: CreateCarousalsRequest) => {
     carousalData.value = Object.assign({}, newClassify)
-    const carousalObj = Object.assign({},newClassify)
-    imgUrl.value = { url: carousalObj.imageUrl || '' }
   },
   {
     deep: true,

+ 3 - 3
src/pages/pet-variety/components/PetVarietyDialog.vue

@@ -1,10 +1,10 @@
 <script setup lang="ts">
-import { type CreateProductRequest, type Product } from '@/model/product'
+import type { PetVariety } from '@/model/pet-variety'
 import { type FormInstanceFunctions, type FormRules, MessagePlugin } from 'tdesign-vue-next'
 import { createPetVariety, editPetVariety } from '@/api/petVariety'
 
 const props = defineProps<{
-  data: Product | null
+  data: PetVariety | null
 }>()
 
 
@@ -26,7 +26,7 @@ watch(
   }
 )
 
-const rules: FormRules<CreateProductRequest> = {
+const rules: FormRules<{ name: string }> = {
   name: [
     {
       required: true,

+ 15 - 1
src/pages/product/components/ProductDialog.vue

@@ -18,7 +18,8 @@ const defaultData: CreateProductRequest = {
   fat: 0,
   fiber: 0,
   ash: 0,
-  moisture: 0
+  moisture: 0,
+  meValue: undefined
 }
 
 const formData = ref<CreateProductRequest>(defaultData)
@@ -40,6 +41,7 @@ watch(
         ash: newData.ash,
         moisture: newData.moisture,
         totalWeight: newData.totalWeight,
+        meValue: newData.meValue ?? undefined,
       }
     } else {
       formData.value = defaultData
@@ -196,6 +198,18 @@ const handleSave = async () => {
           suffix="%"
         ></TInputNumber>
       </TFormItem>
+      <TFormItem label="ME值" name="meValue" help="可选项,直接配置每克产品的代谢能(kcal/g)。如果填写则优先使用此值,否则通过营养成分自动计算">
+        <TInputNumber
+          v-model="formData.meValue"
+          clearable
+          placeholder="请输入ME值(可选)"
+          theme="normal"
+          align="right"
+          suffix="kcal/g"
+          :decimalPlaces="2"
+          :min="0"
+        ></TInputNumber>
+      </TFormItem>
     </TForm>
   </TDialog>
 </template>

+ 8 - 0
src/pages/product/index.vue

@@ -34,6 +34,10 @@ const columns: BaseTableColumns = [
     title: '净重',
     colKey: 'totalWeight',
   },
+  {
+    title: 'ME值',
+    colKey: 'meValue',
+  },
   {
     title: '总能量',
     colKey: 'totalCalories',
@@ -144,6 +148,10 @@ const handleClose = () => {
       <template #totalWeight="{ row }">
         {{ row.totalWeight }}g
       </template>
+      <template #meValue="{ row }">
+        <span v-if="row.meValue">{{ row.meValue }} kcal/g</span>
+        <span v-else class="text-gray-400">自动计算</span>
+      </template>
       <template #totalCalories="{ row }">
         {{ row.totalCalories }}kcal
       </template>

+ 3 - 3
src/pages/user/components/RoleSettingDialog.vue

@@ -13,8 +13,8 @@ const props = defineProps<{
 const roles = ref<string[]>([])
 
 watch(() => props.user, (user) => {
-  if (user) {
-    roles.value = user.roles.map(role => role.name)
+  if (user && user.roles) {
+    roles.value = user.roles.map((role: Role) => role.name)
   }
 })
 
@@ -52,7 +52,7 @@ const handleConfirm = async () => {
   <TDialog>
     <TForm v-if="user">
       <TFormItem label="用户">
-        <div>{{ user.name }}</div>
+        <div>{{ user.name || user.username }}</div>
       </TFormItem>
       <TFormItem label="角色">
         <TSelect v-model="roles" :options="options" multiple></TSelect>