فهرست منبع

fix( bugs ): 添加已有一些未知功能

tangning 4 سال پیش
والد
کامیت
2a3d2e0f0e

+ 1 - 1
src/api/corporation/model.ts

@@ -49,7 +49,7 @@ export interface checkUserParam {
 
 export interface SubAccountUsers {
   id: number | null;
-  subNum: string | null;
+  subNum: string | number;
   subUsers: Recordable<any>[]; //SubAccountUser[];
 }
 

+ 6 - 0
src/api/sys/model/userModel.ts

@@ -46,6 +46,12 @@ export interface LoginResultModel {
   user: RoleInfo;
 }
 export type GetUserInfoModel = UserInfo;
+
+export interface updateUserInfoPasswordParam {
+  id: string | number;
+  password?: string;
+  newPassword?: string;
+}
 /**
  * @description: Get user information return value
  */

+ 13 - 1
src/api/sys/user.ts

@@ -1,5 +1,10 @@
 import { defHttp } from '/@/utils/http/axios';
-import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userModel';
+import {
+  LoginParams,
+  LoginResultModel,
+  GetUserInfoModel,
+  updateUserInfoPasswordParam,
+} from './model/userModel';
 import { encodeStr } from '/@/utils/encodeUtil';
 import { ErrorMessageMode } from '/#/axios';
 import { ContentTypeEnum } from '/@/enums/httpEnum';
@@ -10,6 +15,7 @@ enum Api {
   // Login = '/basic-api/sys/login',
   Login = '/zfb-api/zfb/loginBackground',
   Logout = '/logout',
+  updatePassword = '/kankan-api/api/manager/user/updatePassword',
   GetUserInfo = '/zfb-api/zfb/shop/sys/user/infoAnon',
   GetPermCode = '/getPermCode',
 }
@@ -59,3 +65,9 @@ export function getPermCode() {
 export function doLogout() {
   return defHttp.get({ url: Api.Logout });
 }
+export function updatePasswordApi(params: updateUserInfoPasswordParam) {
+  return defHttp.post<GetUserInfoModel>(
+    { url: Api.updatePassword, params },
+    // { errorMessageMode: 'none' },
+  );
+}

+ 17 - 3
src/components/Cropper/src/CopperModal.vue

@@ -2,7 +2,7 @@
   <BasicModal
     v-bind="$attrs"
     @register="register"
-    :title="t('component.cropper.modalTitle')"
+    :title="title || t('component.cropper.modalTitle')"
     width="800px"
     :canFullscreen="false"
     @ok="handleOk"
@@ -22,7 +22,7 @@
         </div>
 
         <div :class="`${prefixCls}-toolbar`">
-          <Upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload">
+          <Upload :fileList="[]" accept=".jpg,.jpeg.gif,.png" :beforeUpload="handleBeforeUpload">
             <Tooltip :title="t('component.cropper.selectImage')" placement="bottom">
               <a-button size="small" preIcon="ant-design:upload-outlined" type="primary" />
             </Tooltip>
@@ -121,13 +121,15 @@
   import { dataURLtoBlob } from '/@/utils/file/base64Conver';
   import { isFunction } from '/@/utils/is';
   import { useI18n } from '/@/hooks/web/useI18n';
+  import { useMessage } from '/@/hooks/web/useMessage';
 
   type apiFunParams = { file: Blob; name: string; filename: string };
 
   const props = {
     circled: { type: Boolean, default: true },
     src: { type: String, default: '' },
-
+    title: { type: String },
+    maxSize: { type: Number, default: 5 },
     uploadApi: {
       type: Function as PropType<(params: apiFunParams) => Promise<any>>,
     },
@@ -142,6 +144,7 @@
       let filename = '';
       const src = ref('');
       const previewSource = ref('');
+      const { createMessage } = useMessage();
       const cropper = ref<Cropper>();
       let scaleX = 1;
       let scaleY = 1;
@@ -158,6 +161,12 @@
 
       // Block upload
       function handleBeforeUpload(file: File) {
+        const { size } = file;
+        const { maxSize } = props;
+        if (maxSize && size / 1024 / 1024 >= maxSize) {
+          createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
+          return false;
+        }
         const reader = new FileReader();
         reader.readAsDataURL(file);
         src.value = '';
@@ -189,6 +198,11 @@
 
       async function handleOk() {
         const uploadApi = props.uploadApi;
+
+        if (!previewSource.value) {
+          createMessage.error(t('component.upload.empty'));
+          return;
+        }
         if (uploadApi && isFunction(uploadApi)) {
           const blob = dataURLtoBlob(previewSource.value);
           try {

+ 9 - 5
src/components/Cropper/src/CropperAvatar.vue

@@ -10,7 +10,7 @@
         />
       </div>
       <img :src="sourceValue" v-if="sourceValue" alt="avatar" />
-      <img :src="logo" v-else alt="avatar" />
+      <img :src="headerImg" v-else alt="avatar" />
     </div>
     <a-button
       :class="`${prefixCls}-upload-btn`"
@@ -23,8 +23,10 @@
 
     <CopperModal
       @register="register"
-      @uploadSuccess="handleUploadSuccess"
+      @upload-success="handleUploadSuccess"
       :uploadApi="uploadApi"
+      :title="title"
+      :maxSize="5"
       :circled="circled"
       :src="sourceValue"
     />
@@ -48,11 +50,13 @@
   import { useI18n } from '/@/hooks/web/useI18n';
   import type { ButtonProps } from '/@/components/Button';
   import Icon from '/@/components/Icon';
-  import logo from '/@/assets/images/header.jpg';
+  import headerImg from '/@/assets/images/header.jpg';
 
   const props = {
     width: { type: [String, Number], default: '200px' },
     value: { type: String },
+    maxSize: { type: Number, default: 5 },
+    title: { type: String },
     showBtn: { type: Boolean, default: true },
     btnProps: { type: Object as PropType<ButtonProps> },
     btnText: { type: String, default: '' },
@@ -66,7 +70,7 @@
     props,
     emits: ['update:value', 'change'],
     setup(props, { emit, expose }) {
-      const sourceValue = ref(props.value || '');
+      const sourceValue = ref(props.value || false);
       const { prefixCls } = useDesign('cropper-avatar');
       const [register, { openModal, closeModal }] = useModal();
       const { createMessage } = useMessage();
@@ -115,7 +119,7 @@
         getStyle,
         circled: props.circled,
         handleUploadSuccess,
-        logo,
+        headerImg,
       };
     },
   });

+ 1 - 0
src/locales/lang/zh-CN/component.ts

@@ -121,6 +121,7 @@ export default {
     uploading: '上传中',
     uploadWait: '请等待文件上传结束后操作',
     reUploadFailed: '重新上传失败文件',
+    empty: '上传文件为空,请重新上传',
   },
   verify: {
     error: '验证失败!',

+ 1 - 0
src/locales/lang/zh-CN/routes/corporation.ts

@@ -43,4 +43,5 @@ export default {
   managerName: '联系人',
   optSuccess: '添加成功,默认密码为Geosign123',
   approveState: '审核状态',
+  maxlength: '输入超长',
 };

+ 1 - 0
src/locales/lang/zh-CN/routes/staff.ts

@@ -2,6 +2,7 @@ export default {
   deptName: '所属公司',
   userName: '员工名称',
   nickName: '员工昵称',
+  setpaswd: '修改密码',
   mobile: '手机',
   createTime: '创建时间',
   staffList: '员工列表',

+ 6 - 1
src/views/corporation/SubaccountModal.vue

@@ -93,7 +93,12 @@
           title: t('common.fullName'),
           dataIndex: 'nickName',
           edit: true,
-          editRule: true,
+          editRule: async (text) => {
+            if (text && text.length > 25) {
+              return t('routes.corporation.maxlength');
+            }
+            return '';
+          },
           width: 200,
         },
         {

+ 2 - 2
src/views/corporation/deviceModal.vue

@@ -106,13 +106,13 @@
           component: 'Input',
         },
         {
-          field: 'companyName',
+          field: 'name',
           label: t('routes.corporation.enterpriseName'),
           slot: 'userName',
           component: 'Input',
         },
         {
-          field: 'managerPhone',
+          field: 'userName',
           label: t('routes.corporation.enterpriseId'),
           slot: 'name',
           component: 'Input',

+ 2 - 3
src/views/corporation/index.vue

@@ -8,6 +8,7 @@
           :width="80"
           :uploadApi="uploadLogoApi"
           :value="record.sceneLogo"
+          :title="t('routes.corporation.sceneLogo')"
           @change="
             (_, data) => {
               updateSceneLogo(record, data);
@@ -21,6 +22,7 @@
           :width="80"
           :uploadApi="uploadLogoApi"
           :value="record.floorLogo"
+          :title="t('routes.corporation.floorLogo')"
           @change="
             (_, data) => {
               updateFloorLogo(record, data);
@@ -259,9 +261,6 @@
           listKey[val](true, {
             record,
           });
-        // openChargeModal(true, {
-        //   record,
-        // });
       }
       async function handleMusicUploadFetch({ file, name }) {
         const res = await uploadLogoApi({ file, name });

+ 278 - 0
src/views/devices/EditModal.vue

@@ -0,0 +1,278 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    :title="t('routes.devices.editCamera')"
+    @visible-change="handleVisibleChange"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm" />
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, onMounted } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  // allCompanyApi
+  import { editCameraApi } from '/@/api/device/list';
+  import { useI18n } from '/@/hooks/web/useI18n';
+
+  //   address: "11111"
+  // balance: "111"
+  // cameraType: "4"
+  // childName: "11111"
+  // companyId: 1146
+  // orderSn: "1111"
+  // own: "0"
+  // rnd: 0.9923218970879999
+  // snCode: "1111"
+  // wifiName: "1111"
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const modelRef = ref({});
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'cameraId',
+          component: 'Input',
+          label: 'id',
+          show: false,
+        },
+        {
+          field: 'own',
+          component: 'Select',
+          label: t('routes.devices.own'),
+          colProps: {
+            span: 24,
+          },
+          componentProps: {
+            // disabled: true,
+            options: [0, 2, 1, 3].map((ele) => {
+              return { value: ele, key: ele, label: renderOwnTypeLabel(ele) };
+            }),
+          },
+          required: true,
+        },
+        {
+          field: 'cameraType',
+          component: 'Select',
+          label: t('routes.devices.cameraType'),
+          required: true,
+          colProps: {
+            span: 24,
+          },
+          componentProps: {
+            disabled: true,
+            options: [4, 1, 9, 10, 6].map((ele) => {
+              return { value: ele, key: ele, label: rendercameraTypeLabel(ele) };
+            }),
+            // onChange: function (val) {
+            //   console.log('appendSchemaByField', val);
+            //   if (val !== 6) {
+            //     appendSchemaByField(
+            //       {
+            //         field: 'snCode',
+            //         component: 'Input',
+            //         label: t('routes.devices.snCode'),
+            //         required: true,
+            //         colProps: {
+            //           span: 24,
+            //         },
+            //       },
+            //       'address',
+            //     );
+            //   } else {
+            //     removeSchemaByFiled('snCode');
+            //   }
+            // },
+          },
+        },
+
+        {
+          field: 'childName',
+          component: 'Input',
+          label: t('routes.devices.childName'),
+          required: true,
+          colProps: {
+            span: 24,
+          },
+          componentProps: {
+            disabled: true,
+          },
+        },
+        {
+          field: 'wifiName',
+          component: 'Input',
+          label: t('routes.devices.wifiName'),
+          required: true,
+          componentProps: {
+            disabled: true,
+          },
+          colProps: {
+            span: 24,
+          },
+        },
+        {
+          field: 'address',
+          component: 'Input',
+          required: true,
+          label: t('routes.devices.address'),
+          componentProps: {
+            disabled: true,
+          },
+          colProps: {
+            span: 24,
+          },
+        },
+        {
+          field: 'snCode',
+          component: 'Input',
+          label: t('routes.devices.snCode'),
+          required: true,
+          componentProps: {
+            disabled: true,
+          },
+          ifShow: ({ model }) => {
+            console.log('record', model.cameraType);
+
+            return model.cameraType && model.cameraType !== 6;
+          },
+          colProps: {
+            span: 24,
+          },
+        },
+        // {
+        //   field: 'balance',
+        //   component: 'Input',
+        //   label: t('routes.devices.balance'),
+        //   colProps: {
+        //     span: 24,
+        //   },
+        // },
+
+        // {
+        //   field: 'companyId',
+        //   component: 'ApiSelect',
+        //   label: t('routes.devices.companyId'),
+        //   componentProps: {
+        //     api: allCompanyApi,
+        //     numberToString: true,
+        //     labelField: 'companyName',
+        //     valueField: 'id',
+        //     immediate: true,
+        //     params: {
+        //       page: 1,
+        //       limit: 1000,
+        //     },
+        //   },
+        //   colProps: {
+        //     span: 24,
+        //   },
+        // },
+      ];
+      const [
+        registerForm,
+        {
+          // getFieldsValue,
+          // validateFields,
+          // appendSchemaByField,
+          // removeSchemaByFiled,
+          setFieldsValue,
+          validate,
+          // setProps
+        },
+      ] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function renderOwnTypeLabel(type: number): string {
+        switch (type) {
+          case 0:
+            return t('routes.devices.ownName.0');
+          case 2:
+            return t('routes.devices.ownName.2');
+          case 1:
+            return t('routes.devices.ownName.1');
+          case 3:
+            return t('routes.devices.ownName.3');
+          default:
+            return '';
+        }
+      }
+      function rendercameraTypeLabel(cameraType: number): string {
+        switch (cameraType) {
+          case 4:
+            return t('routes.devices.cameraName.4');
+          case 1:
+            return t('routes.devices.cameraName.1');
+          case 9:
+            return t('routes.devices.cameraName.9');
+          case 10:
+            return t('routes.devices.cameraName.10');
+          case 6:
+            return t('routes.devices.cameraName.6');
+          default:
+            return '';
+        }
+      }
+      function onDataReceive(data) {
+        console.log('Data Received', data);
+        setFieldsValue({
+          ...data,
+          cameraId: Number(data.id),
+          cameraType: Number(data.cameraType),
+        });
+      }
+      const handleSubmit = async () => {
+        // console.log('getFieldsValue()', getFieldsValue());
+        try {
+          const values = await validate();
+          console.log('values', values);
+          if (values) {
+            const res = await editCameraApi(values);
+            emit('update');
+            console.log('res', res);
+            createMessage.success(t('common.optSuccess'));
+            closeModal();
+          }
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+
+      return {
+        register,
+        rendercameraTypeLabel,
+        renderOwnTypeLabel,
+        schemas,
+        registerForm,
+        model: modelRef,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        t,
+      };
+    },
+  });
+</script>

+ 16 - 2
src/views/devices/list.vue

@@ -18,6 +18,11 @@
         <TableAction
           :actions="[
             {
+              icon: 'clarity:note-edit-line',
+              label: t('common.edit'),
+              onClick: handleEditScenes.bind(null, record),
+            },
+            {
               icon: 'ant-design:delete-outlined',
               color: 'error',
               label: t('common.delText'),
@@ -40,7 +45,8 @@
         />
       </template>
     </BasicTable>
-    <AddModal @getList="reload" @register="registerAddModal" />
+    <AddModal @get-list="reload" @register="registerAddModal" />
+    <EditModal @register="registerEditModal" @update="reload" />
   </div>
 </template>
 <script lang="ts">
@@ -51,15 +57,17 @@
   import { useModal } from '/@/components/Modal';
   import { ListApi, unDeviceApi } from '/@/api/device/list';
   import AddModal from './AddModal.vue';
+  import EditModal from './EditModal.vue';
   import { useI18n } from '/@/hooks/web/useI18n';
   import { RoleEnum } from '/@/enums/roleEnum';
 
   // param type 0
   export default defineComponent({
-    components: { BasicTable, TableAction, Tag, AddModal },
+    components: { BasicTable, TableAction, Tag, AddModal, EditModal },
     setup() {
       const { createMessage } = useMessage();
       const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerEditModal, { openModal: openEditModal }] = useModal();
       const { t } = useI18n();
       const columns: BasicColumn[] = [
         {
@@ -182,6 +190,10 @@
           return searchData;
         },
       });
+      function handleEditScenes(record: Recordable) {
+        console.log('record', record);
+        openEditModal(true, record);
+      }
       async function handleUnbindDevice(record: Recordable) {
         await unDeviceApi({
           childName: record.childName,
@@ -228,6 +240,8 @@
         registerAddModal,
         openAddModal,
         handleUnbindDevice,
+        handleEditScenes,
+        registerEditModal,
         t,
         reload,
       };

+ 14 - 2
src/views/staff/list.vue

@@ -29,17 +29,24 @@
                 createMessage.info(t('common.notConnect'));
               },
             },
+            {
+              label: t('routes.staff.setpaswd'),
+              onClick: handleOpenModal.bind(null, record),
+            },
           ]"
         />
       </template>
     </BasicTable>
+    <SetpaswordModal @register="register" />
   </div>
 </template>
 <script lang="ts">
   import { defineComponent } from 'vue';
   import { BasicTable, useTable, BasicColumn, FormProps, TableAction } from '/@/components/Table';
   import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
   import { uploadApi } from '/@/api/sys/upload';
+  import SetpaswordModal from './setpaswordModal.vue';
   // import { Switch } from 'ant-design-vue';
   // import { h } from 'vue';
   import { ListApi } from '/@/api/staff/list';
@@ -73,9 +80,10 @@
   // userPassword: "2a22bac40f44af4d3b5fdc20ea706fc5"
 
   export default defineComponent({
-    components: { BasicTable, TableAction, Time },
+    components: { BasicTable, TableAction, Time, SetpaswordModal },
     setup() {
       const { createMessage } = useMessage();
+      const [register, { openModal }] = useModal();
       const go = useGo();
       const { t } = useI18n();
       const columns: BasicColumn[] = [
@@ -185,7 +193,9 @@
             return '';
         }
       }
-
+      function handleOpenModal(record: Recordable) {
+        openModal(true, record);
+      }
       return {
         registerTable,
         createMessage,
@@ -193,6 +203,8 @@
         go,
         renderRoleType,
         renderStatus,
+        handleOpenModal,
+        register,
         uploadApi: uploadApi as any,
       };
     },

+ 98 - 0
src/views/staff/setpaswordModal.vue

@@ -0,0 +1,98 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    @ok="handSubmit"
+    :title="t('routes.personalSetting.updateBtn')"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+  >
+    <div class="pt-3px pr-3px">
+      <BasicForm @register="registerForm" />
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { encodeStr } from '/@/utils/encodeUtil';
+  import { defineComponent, nextTick } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { updatePasswordApi } from '/@/api/sys/user';
+  import { useMessage } from '/@/hooks/web/useMessage';
+
+  const { createMessage } = useMessage();
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    setup(props) {
+      const { t } = useI18n();
+      const schemas: FormSchema[] = [
+        {
+          field: 'id',
+          component: 'Input',
+          label: 'id',
+          show: false,
+        },
+        {
+          field: 'password',
+          component: 'StrengthMeter',
+          label: t('routes.personalSetting.password'),
+          labelWidth: 120,
+          required: true,
+          colProps: { span: 18 },
+        },
+      ];
+
+      const [
+        registerForm,
+        {
+          setFieldsValue,
+          validate,
+          resetFields,
+          // setProps
+        },
+      ] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+
+      function onDataReceive(data) {
+        setFieldsValue({
+          id: data.id,
+        });
+      }
+      async function handSubmit() {
+        const { id, password } = await validate();
+        await updatePasswordApi({ id, newPassword: encodeStr(window.btoa(password)) });
+        createMessage.success(t('common.optSuccess'));
+        resetFields();
+        closeModal();
+      }
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+
+      return {
+        handSubmit,
+        register,
+        t,
+        schemas,
+        registerForm,
+        handleVisibleChange,
+        resetFields,
+      };
+    },
+  });
+</script>