Browse Source

2025-1-14

cmy 10 months ago
parent
commit
39919a47c5

+ 7 - 6
src/api/goods/index.ts

@@ -1,18 +1,19 @@
 import request from '@/axios'
 import { REQUEST_BASE } from '@/constants'
-import { designerSearch, designerData } from './types'
+import { categoryData } from './types'
 export const getProductCategory = (params: {
   page?: number
   limit?: number
+  pid: number
 }): Promise<IResponse> => {
   return request.get({ url: `${REQUEST_BASE}/productCategory/index`, params })
 }
-export const addProductCategory = (data: designerData): Promise<IResponse> => {
-  return request.post({ url: `${REQUEST_BASE}/decoration/designer`, data })
+export const addProductCategory = (data: categoryData): Promise<IResponse> => {
+  return request.post({ url: `${REQUEST_BASE}/productCategory/save`, data })
 }
 export const delProductCategory = (id: number): Promise<IResponse> => {
-  return request.delete({ url: `${REQUEST_BASE}/decoration/designer/${id}` })
+  return request.delete({ url: `${REQUEST_BASE}/productCategory/designer/${id}` })
 }
-export const putProductCategory = (data: designerData): Promise<IResponse> => {
-  return request.put({ url: `${REQUEST_BASE}/decoration/designer/${data.id}`, data })
+export const putProductCategory = (data: categoryData): Promise<IResponse> => {
+  return request.post({ url: `${REQUEST_BASE}/productCategory/update/${data.id}`, data })
 }

+ 5 - 32
src/api/goods/types.ts

@@ -1,35 +1,8 @@
-export type designerSearch = {
-  page?: number
-  limit?: number
-}
-
-export interface designerData {
+export interface categoryData {
   id?: number
-  uid: number | null
+  pid: number
   name: string //真实姓名
-  phone: number | null //手机号
-  gender: 0 | 1 | 2 //性别 0保密 1男 2女
-  avatar: string //头像
-  birth_day_time?: string | number //生日
-  province: string //省
-  city: string //市
-  area: string //区
-  tag_list: Array<string> //标签
-  longitude: string | number //经度
-  latitude: string | number //纬度
-  detail_address: string
-  start_job_year: string
-}
-export type categoryData = {
-  id?: number
-  name: string
-  is_show: 1 | 0
-  type: 1 | 2
-}
-export type jobsData = {
-  id?: number
-  name: string
-  is_show: 1 | 0
-  cate_id: number
-  default_price: number
+  image: string //图标
+  is_show: 1 | 0 //是否显示
+  sort: number //排序
 }

+ 3 - 3
src/api/staff/index.ts

@@ -1,6 +1,6 @@
 import request from '@/axios'
 import { REQUEST_BASE } from '@/constants'
-import { designerSearch, designerData, categoryData, jobsData } from './types'
+import { designerSearch, designerData, staffCategoryData, jobsData } from './types'
 export const getDesigner = (params: designerSearch): Promise<IResponse> => {
   return request.get({ url: `${REQUEST_BASE}/decoration/designer`, params })
 }
@@ -28,13 +28,13 @@ export const putWorker = (data: designerData): Promise<IResponse> => {
 export const getStaffCategory = (params: designerSearch): Promise<IResponse> => {
   return request.get({ url: `${REQUEST_BASE}/decoration/category`, params })
 }
-export const addStaffCategory = (data: categoryData): Promise<IResponse> => {
+export const addStaffCategory = (data: staffCategoryData): Promise<IResponse> => {
   return request.post({ url: `${REQUEST_BASE}/decoration/category`, data })
 }
 export const delStaffCategory = (id: number): Promise<IResponse> => {
   return request.delete({ url: `${REQUEST_BASE}/decoration/category/${id}` })
 }
-export const putStaffCategory = (data: categoryData): Promise<IResponse> => {
+export const putStaffCategory = (data: staffCategoryData): Promise<IResponse> => {
   return request.put({ url: `${REQUEST_BASE}/decoration/category/${data.id}`, data })
 }
 export const getStaffJobs = (params: { page?: number; limit?: number }): Promise<IResponse> => {

+ 1 - 1
src/api/staff/types.ts

@@ -20,7 +20,7 @@ export interface designerData {
   detail_address: string
   start_job_year: string
 }
-export type categoryData = {
+export type staffCategoryData = {
   id?: number
   name: string
   is_show: 1 | 0

+ 2 - 1
src/components/UserList/index.ts

@@ -1,3 +1,4 @@
 import UserList from './src/userList.vue'
+import UserButtom from './src/userButtom.vue'
 
-export { UserList }
+export { UserList, UserButtom }

+ 46 - 0
src/components/UserList/src/userButtom.vue

@@ -0,0 +1,46 @@
+<script setup lang="tsx">
+import { UserList } from '..'
+import { ref, watch } from 'vue'
+import { getUserDetail } from '@/api/user'
+import { ElAvatar, ElText } from 'element-plus'
+const modelValue = defineModel<number>({
+  default: 0
+})
+const userDetail = ref<any>()
+const showDrawer = ref(false)
+const emit = defineEmits(['changeUser'])
+const checkedUser = async (res: any) => {
+  userDetail.value = res
+  emit('changeUser', res)
+  showDrawer.value = false
+}
+watch(
+  () => modelValue.value,
+  async (value) => {
+    if (!value) return
+    const res = await getUserDetail(value)
+    if (res) {
+      userDetail.value = res.data
+    }
+  },
+  {
+    deep: true,
+    immediate: true
+  }
+)
+</script>
+<template>
+  <BaseButton v-if="userDetail" size="large" @click="showDrawer = true">
+    <div class="flex items-center">
+      <ElAvatar shape="circle" size="small" src="{userDetail?.value?.avatar}">
+        <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
+      </ElAvatar>
+      <div class="flex flex-col ml-5px items-start justify-start">
+        <ElText class="self-start!">{{ userDetail?.nickname }}</ElText>
+        <ElText size="small" class="self-start!"> UID:{{ userDetail?.uid }} </ElText>
+      </div>
+    </div>
+  </BaseButton>
+  <BaseButton v-else @click="showDrawer = true">选择用户</BaseButton>
+  <UserList v-model="showDrawer" @confirm="checkedUser" />
+</template>

+ 39 - 17
src/views/Authorization/User/components/Write.vue

@@ -5,7 +5,7 @@ import { PropType, watch, ref, onMounted } from 'vue'
 import { useValidator } from '@/hooks/web/useValidator'
 import { cloneDeep } from 'lodash-es'
 import { getRoleListApi } from '@/api/system/role'
-
+import type { FormRules } from 'element-plus'
 const { required, phone, lengthRange } = useValidator()
 
 const props = defineProps({
@@ -25,31 +25,32 @@ const formSchema = ref<FormSchema[]>([
     }
   },
   {
-    field: 'pwd',
-    label: '管理员密码',
+    field: 'real_name',
+    label: '管理员姓名',
     component: 'Input',
     componentProps: {
-      type: 'password',
-      placeholder: '请输入登录密码'
+      placeholder: '请输入管理员姓名'
     }
   },
   {
-    field: 'conf_pwd',
-    label: '确认密码',
-    component: 'Input',
+    field: 'pwd',
+    label: '密码',
+    component: 'InputPassword',
     componentProps: {
-      type: 'password',
-      placeholder: '请输入重复输入登录密码'
+      strength: true,
+      placeholder: '请输入登录密码'
     }
   },
   {
-    field: 'real_name',
-    label: '管理员姓名',
-    component: 'Input',
+    field: 'conf_pwd',
+    label: '确认密码',
+    component: 'InputPassword',
     componentProps: {
-      placeholder: '请输入管理员姓名'
+      strength: true,
+      placeholder: '请输入重复输入登录密码'
     }
   },
+
   {
     field: 'phone',
     label: '管理员电话',
@@ -89,8 +90,15 @@ const formSchema = ref<FormSchema[]>([
     component: 'Input'
   }
 ])
-
-const rules = ref({
+interface RuleForm {
+  account: string
+  pwd: string
+  conf_pwd: string
+  roles: string
+  phone: string
+  real_name: string
+}
+const rules = ref<FormRules<RuleForm>>({
   account: [
     {
       required: true,
@@ -102,7 +110,21 @@ const rules = ref({
     }
   ],
   pwd: [required('请填写登录密码')],
-  conf_pwd: [required('请确认密码')],
+  conf_pwd: [
+    {
+      required: true,
+      validator: (_, val, callback) => {
+        getFormData().then((formData) => {
+          if (!val) return callback()
+          if (formData.pwd !== val) {
+            callback(new Error('两次密码不一致'))
+          } else {
+            callback()
+          }
+        })
+      }
+    }
+  ],
   roles: [required('请选择管理员身份')],
   phone: [
     {

+ 31 - 8
src/views/Goods/classify/components/Write.vue

@@ -4,18 +4,14 @@ import { useForm } from '@/hooks/web/useForm'
 import { PropType, watch, ref } from 'vue'
 import { useValidator } from '@/hooks/web/useValidator'
 import { cloneDeep } from 'lodash-es'
-import { categoryData } from '@/api/staff/types'
 import { UpImgButtom } from '@/components/UpFile'
+import { getProductCategory } from '@/api/goods'
 const { required } = useValidator()
 
 const props = defineProps({
   currentRow: {
     type: Object as PropType<any>,
     default: () => null
-  },
-  category: {
-    type: Array as PropType<categoryData[]>,
-    default: () => []
   }
 })
 
@@ -27,9 +23,22 @@ const formSchema = ref<FormSchema[]>([
     colProps: {
       span: 24
     },
-    value: 1,
-    componentProps: {
-      options: props.category
+    value: 0,
+    optionApi: async () => {
+      const { data } = await getProductCategory({ pid: -1, limit: 9999, page: 1 })
+      const list = [
+        {
+          label: '顶级',
+          value: 0
+        },
+        ...data.map((data) => {
+          return {
+            value: data.id,
+            label: data.name
+          }
+        })
+      ]
+      return list
     }
   },
   {
@@ -46,6 +55,7 @@ const formSchema = ref<FormSchema[]>([
   {
     field: 'image',
     label: '图标',
+    value: [],
     component: 'CheckboxGroup',
     formItemProps: {
       slots: {
@@ -55,8 +65,21 @@ const formSchema = ref<FormSchema[]>([
       }
     }
   },
+  {
+    field: 'sort',
+    label: '排序',
+    component: 'Input',
+    colProps: {
+      span: 24
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '请输入排序'
+    }
+  },
   {
     field: 'is_show',
+    value: true,
     colProps: {
       span: 24
     },

+ 24 - 31
src/views/Goods/classify/index.vue

@@ -1,6 +1,5 @@
 <script setup lang="tsx">
-import { onMounted, reactive, ref, unref, useTemplateRef } from 'vue'
-import { getStaffJobs, delStaffJobs, addStaffJobs, putStaffJobs } from '@/api/staff'
+import { reactive, ref, unref, useTemplateRef } from 'vue'
 import { useTable } from '@/hooks/web/useTable'
 import { useI18n } from '@/hooks/web/useI18n'
 import { Table, TableColumn } from '@/components/Table'
@@ -8,36 +7,27 @@ import { ContentWrap } from '@/components/ContentWrap'
 import { Dialog } from '@/components/Dialog'
 import { BaseButton } from '@/components/Button'
 import { ElDivider, ElMessage, ElMessageBox } from 'element-plus'
-import { jobsData } from '@/api/staff/types'
 import Write from './components/Write.vue'
-import { getStaffCategory } from '@/api/staff'
+import { categoryData } from '@/api/goods/types'
 import { TableImage } from '@/components/tableImage'
-import { getProductCategory } from '@/api/goods'
-const CategoryList = ref<any[]>([])
-onMounted(() => {
-  getStaffCategory({
-    page: 1,
-    limit: 100
-  }).then((res) => {
-    CategoryList.value = res.data.list.map((res) => {
-      return {
-        label: `${res.type_chs}[${res.name}]`,
-        value: res.id
-      }
-    })
-  })
-})
+import {
+  getProductCategory,
+  putProductCategory,
+  delProductCategory,
+  addProductCategory
+} from '@/api/goods'
 const { t } = useI18n()
 
 const { tableRegister, tableState, tableMethods } = useTable({
   fetchDataApi: async () => {
     const res = await getProductCategory({
+      pid: 0,
       page: unref(currentPage) || 1,
       limit: unref(pageSize) || 10
     })
     return {
-      list: res.data.list,
-      total: res.data.count || 0
+      list: res.data,
+      total: res.data.length || 0
     }
   }
 })
@@ -53,7 +43,7 @@ const tableColumns = reactive<TableColumn[]>([
     width: 70
   },
   {
-    field: 'cate_name',
+    field: 'name',
     label: '分类名称',
     minWidth: 100
   },
@@ -128,10 +118,12 @@ const action = async (type: string, row?: any) => {
   if (type == 'edit') {
     dialogTitle.value = t('exampleDemo.edit')
     currentRow.value = {
+      pid: row.pid,
       id: row.id,
       name: row.name,
       is_show: row.is_show == 1 ? true : false,
-      default_price: row.default_price //一口价
+      image: row.image || [], //一口价
+      sort: row.sort
     }
   }
   dialogVisible.value = true
@@ -143,7 +135,7 @@ const delAction = (row: any) => {
     type: 'warning'
   })
     .then(async () => {
-      const re = await delStaffJobs(row.id)
+      const re = await delProductCategory(row.id)
       if (re) {
         ElMessage({
           showClose: true,
@@ -160,17 +152,18 @@ const save = async () => {
   const formData = await write?.submit()
   if (formData) {
     saveLoading.value = true
-    const data: jobsData = {
+    const data: categoryData = {
       id: formData.id || '',
       name: formData.name, //分类名称
-      cate_id: formData.cate_id, //类型
+      pid: formData.pid, //类型
       is_show: formData.is_show ? 1 : 0, //是否启用
-      default_price: formData.default_price //一口价
+      image: formData.image[0] || '', //一口价
+      sort: formData.sort
     }
     if (actionType.value === 'edit') {
-      await putStaffJobs(data)
+      await putProductCategory(data)
     } else if (actionType.value === 'add') {
-      await addStaffJobs(data)
+      await addProductCategory(data)
     }
     ElMessage({
       showClose: true,
@@ -205,8 +198,8 @@ const save = async () => {
     />
   </ContentWrap>
 
-  <Dialog v-model="dialogVisible" :title="dialogTitle" width="500px" maxHeight="150px">
-    <Write ref="writeRef" :category="CategoryList" :current-row="currentRow" />
+  <Dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
+    <Write ref="writeRef" :current-row="currentRow" />
     <template #footer>
       <BaseButton type="primary" :loading="saveLoading" @click="save">
         {{ t('exampleDemo.save') }}

+ 2 - 2
src/views/Staff/category/index.vue

@@ -10,7 +10,7 @@ import { ContentWrap } from '@/components/ContentWrap'
 import { Dialog } from '@/components/Dialog'
 import { BaseButton } from '@/components/Button'
 import { ElDivider, ElMessage, ElMessageBox } from 'element-plus'
-import { categoryData } from '@/api/staff/types'
+import { staffCategoryData } from '@/api/staff/types'
 import Write from './components/Write.vue'
 
 const { t } = useI18n()
@@ -163,7 +163,7 @@ const save = async () => {
   const formData = await write?.submit()
   if (formData) {
     saveLoading.value = true
-    const data: categoryData = {
+    const data: staffCategoryData = {
       id: formData.id || '',
       name: formData.name, //分类名称
       type: formData.type, //类型

+ 15 - 40
src/views/Staff/designer/components/Write.vue

@@ -4,14 +4,12 @@ import { useForm } from '@/hooks/web/useForm'
 import { PropType, watch, ref, onMounted, unref } from 'vue'
 import { useValidator } from '@/hooks/web/useValidator'
 import { cloneDeep } from 'lodash-es'
-import { ElInputTag, ElAutocomplete, ElAvatar, ElText } from 'element-plus'
-import { BaseButton } from '@/components/Button'
+import { ElInputTag, ElAutocomplete } from 'element-plus'
 import { getMapSearch } from '@/api/system/admin'
-import { UserList } from '@/components/UserList'
 import { UpImgButtom } from '@/components/UpFile'
 import { mapAddressData } from '@/api/system/admin/types'
-import { getUserDetail } from '@/api/user'
 import { getConfigKey } from '@/api/system/admin'
+import { UserButtom } from '@/components/UserList'
 const { required, phone } = useValidator()
 const mapKey = ref('')
 onMounted(async () => {
@@ -26,7 +24,6 @@ const props = defineProps({
     default: () => null
   }
 })
-const userDetail = ref<any>()
 const formSchema = ref<FormSchema[]>([
   {
     field: 'uid',
@@ -34,32 +31,17 @@ const formSchema = ref<FormSchema[]>([
     component: 'CheckboxGroup',
     formItemProps: {
       slots: {
-        default: () => {
-          if (userDetail?.value) {
-            return (
-              <>
-                <BaseButton size="large" onClick={() => (showDrawer.value = true)}>
-                  <div class={'flex items-center'}>
-                    <ElAvatar shape="circle" size="small" src={userDetail?.value?.avatar}>
-                      <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                    </ElAvatar>
-                    <div class={'flex flex-col ml-5px items-start justify-start'}>
-                      <ElText class={'self-start!'}>{userDetail?.value?.nickname}</ElText>
-                      <ElText size="small" class={'self-start!'}>
-                        UID:{userDetail?.value?.uid}
-                      </ElText>
-                    </div>
-                  </div>
-                </BaseButton>
-              </>
-            )
-          } else {
-            return (
-              <>
-                <BaseButton onClick={() => (showDrawer.value = true)}>选择用户</BaseButton>
-              </>
-            )
-          }
+        default: (data) => {
+          return (
+            <>
+              <UserButtom
+                v-model={data.uid}
+                onChangeUser={(res) => {
+                  checkedUser(res)
+                }}
+              ></UserButtom>
+            </>
+          )
         }
       }
     }
@@ -279,17 +261,15 @@ const submit = async () => {
 defineExpose({
   submit
 })
-const showDrawer = ref(false)
 const checkedUser = async (res: any) => {
-  userDetail.value = res
   setValues({
     uid: res.uid,
     name: res.real_name,
     avatar: [res.avatar],
     birth_day_time: res.birthday,
-    phone: res.phone
+    phone: res.phone,
+    gender: res.sex
   })
-  showDrawer.value = false
 }
 const actionAddress = ref<mapAddressData>()
 const searchAddress = async (queryString: string, cb: (arg: any) => void) => {
@@ -355,10 +335,6 @@ watch(
       lat: currentRow.latitude
     }
     setValues(currentRow)
-    const res = await getUserDetail(currentRow.uid)
-    if (res) {
-      userDetail.value = res.data
-    }
   },
   {
     deep: true,
@@ -394,7 +370,6 @@ watch(
         }"
       />
     </TlbsMap>
-    <UserList v-model="showDrawer" @confirm="checkedUser" />
   </div>
 </template>
 <style lang="less" scoped>

+ 2 - 2
src/views/Staff/jobs/components/Write.vue

@@ -4,7 +4,7 @@ import { useForm } from '@/hooks/web/useForm'
 import { PropType, watch, ref } from 'vue'
 import { useValidator } from '@/hooks/web/useValidator'
 import { cloneDeep } from 'lodash-es'
-import { categoryData } from '@/api/staff/types'
+import { staffCategoryData } from '@/api/staff/types'
 const { required } = useValidator()
 
 const props = defineProps({
@@ -13,7 +13,7 @@ const props = defineProps({
     default: () => null
   },
   category: {
-    type: Array as PropType<categoryData[]>,
+    type: Array as PropType<staffCategoryData[]>,
     default: () => []
   }
 })

+ 16 - 40
src/views/Staff/worker/components/Write.vue

@@ -4,14 +4,13 @@ import { useForm } from '@/hooks/web/useForm'
 import { PropType, watch, ref, onMounted, unref } from 'vue'
 import { useValidator } from '@/hooks/web/useValidator'
 import { cloneDeep } from 'lodash-es'
-import { ElInputTag, ElAutocomplete, ElAvatar, ElText } from 'element-plus'
-import { BaseButton } from '@/components/Button'
+import { ElInputTag, ElAutocomplete } from 'element-plus'
 import { getMapSearch } from '@/api/system/admin'
-import { UserList } from '@/components/UserList'
 import { UpImgButtom } from '@/components/UpFile'
 import { mapAddressData } from '@/api/system/admin/types'
-import { getUserDetail } from '@/api/user'
 import { getConfigKey } from '@/api/system/admin'
+import { UserButtom } from '@/components/UserList'
+
 const { required, phone } = useValidator()
 const mapKey = ref('')
 onMounted(async () => {
@@ -26,7 +25,6 @@ const props = defineProps({
     default: () => null
   }
 })
-const userDetail = ref<any>()
 const formSchema = ref<FormSchema[]>([
   {
     field: 'uid',
@@ -34,32 +32,17 @@ const formSchema = ref<FormSchema[]>([
     component: 'CheckboxGroup',
     formItemProps: {
       slots: {
-        default: () => {
-          if (userDetail?.value) {
-            return (
-              <>
-                <BaseButton size="large" onClick={() => (showDrawer.value = true)}>
-                  <div class={'flex items-center'}>
-                    <ElAvatar shape="circle" size="small" src={userDetail?.value?.avatar}>
-                      <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                    </ElAvatar>
-                    <div class={'flex flex-col ml-5px items-start justify-start'}>
-                      <ElText class={'self-start!'}>{userDetail?.value?.nickname}</ElText>
-                      <ElText size="small" class={'self-start!'}>
-                        UID:{userDetail?.value?.uid}
-                      </ElText>
-                    </div>
-                  </div>
-                </BaseButton>
-              </>
-            )
-          } else {
-            return (
-              <>
-                <BaseButton onClick={() => (showDrawer.value = true)}>选择用户</BaseButton>
-              </>
-            )
-          }
+        default: (data) => {
+          return (
+            <>
+              <UserButtom
+                v-model={data.uid}
+                onChangeUser={(res) => {
+                  checkedUser(res)
+                }}
+              ></UserButtom>
+            </>
+          )
         }
       }
     }
@@ -278,17 +261,15 @@ const submit = async () => {
 defineExpose({
   submit
 })
-const showDrawer = ref(false)
 const checkedUser = async (res: any) => {
-  userDetail.value = res
   setValues({
     uid: res.uid,
     name: res.real_name,
     avatar: [res.avatar],
     birth_day_time: res.birthday,
-    phone: res.phone
+    phone: res.phone,
+    gender: res.sex
   })
-  showDrawer.value = false
 }
 const actionAddress = ref<mapAddressData>()
 const searchAddress = async (queryString: string, cb: (arg: any) => void) => {
@@ -354,10 +335,6 @@ watch(
       lat: currentRow.latitude
     }
     setValues(currentRow)
-    const res = await getUserDetail(currentRow.uid)
-    if (res) {
-      userDetail.value = res.data
-    }
   },
   {
     deep: true,
@@ -393,7 +370,6 @@ watch(
         }"
       />
     </TlbsMap>
-    <UserList v-model="showDrawer" @confirm="checkedUser" />
   </div>
 </template>
 <style lang="less" scoped>

+ 1 - 1
src/views/Staff/worker/index.vue

@@ -221,7 +221,7 @@ const action = async (row: any, type: string) => {
     province: row.province,
     city: row.city,
     area: row.area,
-    tag_list: row.tag_list,
+    tag_list: row.tag_list.split(','),
     longitude: row.longitude,
     latitude: row.latitude,
     detail_address: row.detail_address,