npm package: @partex/one-core
Description: * value 搜索的默认值 Object default: {} * defaultValue 重置的默认值 Object default: {} * data 搜索列表 ISearchBarType default: {} * loading? 加载状态 Boolean default: false * cols? 显示的栅格数量 number default: 5 * autoSubmit? 自动提交 Boolean default: true * cache? 启用缓存 boolean defau
Author: DotWho
Latest version: 2.1.31

# 公共组件
## oc-search-bar
* value 搜索的默认值 Object default: {}
* defaultValue 重置的默认值 Object default: {}
* data 搜索列表 ISearchBarType default: {}
* loading? 加载状态 Boolean default: false
* cols? 显示的栅格数量 number default: 5
* autoSubmit? 自动提交 Boolean default: true
* cache? 启用缓存 boolean default: true
* on-update:value? 值更新时执行的回调 default: undefined

* slot header
* slot left
* slot action

* ts
* ISearchBarType
```
type: 'input' | 'number' | 'select' | 'dropdown' | 'cascader' | 'treeSelect' | 'datePicker'

// base
show?: boolean // 是否显示
clearable?: boolean //是否可清除
placeholder?: string // 占位字符
updateValue?: (value: [] | string | number | null, data: any) => void // 值更新回调

// number
min?: number // 最小值
max?: number // 最大值
step?: number // 步进
showButton?: boolean // 是否显示步进按钮
suffix?: string // 前缀
validator?: (value: number) => boolean // 自定义验证

// select
multiple?: boolean // 是否多选
options: Array<SelectOption | SelectGroupOption> | any

// dropdown
options: SelectOption[] | any

// cascader
multiple?: boolean // 是否多选
checkStrategy?: 'all' | 'parent' | 'child' // 选中模式
options: CascaderOption[] | any

// treeSelect
multiple?: boolean // 是否多选
checkStrategy?: 'all' | 'parent' | 'child' // 选中模式
options: TreeSelectOption[] | any

// datePicker
dateType:
    | 'date'
    | 'datetime'
    | 'daterange'
    | 'datetimerange'
    | 'month'
    | 'monthrange'
    | 'year'
    | 'quarter'
format?: string // 格式化
isDateDisabled?: (current: number) => boolean // 禁用时间
shortcuts?:
  | Record<string, number | (() => number)>
  | Record<string, [number, number] | (() => [number, number])>

// Group
type: 'group'
options: Array<SelectOption | SelectGroupOption>
input: {
  key: string
  options: {
    [key: string]: GroupInput
  }
}
width?: number | string
```

```
<oc-search-bar
  :loading="loading"
  :value="search"
  :data="items"
  :cols="5"
  @on-update:value="submit"
>
  <template #header></template>
  <template #left></template>
  <template #action></template>
</oc-search-bar>
```

## oc-back
* 一个返回按钮
* 参数 to?: string 默认情况返回上一级历史
```
<oc-back />
<oc-back to="/home" />
```

## oc-footer
* 公共页尾
* 参数 version?: string 可显示本项目的版本信息
```
<oc-footer version="2.1.0" />
```

## oc-header
* 公共页头
* 参数 menuOptions: Array<MenuOption | MenuDividerOption | MenuGroupOption> 
* ts: IHeaderMenu
```
<oc-header :menuOptions="menu" />
const menu = ref<Array<MenuOption | MenuDividerOption | MenuGroupOption>>([
  {
    label: '首页',
    key: '/iot/home',
    icon: () => h(Tv),
    children: [
      {
        label: '大屏1',
        key: '/iot/home'
      },
      {
        label: '大屏2',
        key: '/iot/performance'
      }
    ]
  }
])
```

## oc-importer
* 公共excel导入组件
* 参数
* show: boolean 显示/隐藏
* type: string 后台需要的导入key
* file: string 模版下载地址
* steam?: boolean 是否需要下载流
* update:show? 显示/隐藏改变回调
```
<oc-importer
  v-model:show="showModal"
  type="task"
  file="https://xxx-cloud-test.oss-cn-xxx.aliyuncs.com/xxxx.xlsx"
/>
```
* 同时提供公共下载方法
* fnDownload(params)
* params
```
{
  [key: string]: any
  jobTypeName?: string
  jobParams?: string
  file?: File
  query?: Query
}
```
* 建议写法
```
<n-tooltip trigger="hover">
  <template #trigger>
    <n-popconfirm
      positive-text="导出"
      placement="bottom-end"
      @positive-click="exportData"
    >
      <template #trigger>
        <n-button :loading="downloading">
          <template #icon>
            <n-icon>
              <IconCloudArrowDown />
            </n-icon>
          </template>
        </n-button>
      </template>
      导出工序？
    </n-popconfirm>
  </template>
  导出工序
</n-tooltip>

import { fnDownload } from '@partex/one-core'
const exportData = (): void => {
  downloading.value = true
  fnDownload({
    jobTypeName: 'process',
    query: query.value
  })
    .then(() => {
      notice.success({
        content: '操作成功',
        duration: 3000
      })
      setTimeout(() => {
        downloading.value = false
      }, 2000)
    })
    .catch(() => {
      notice.error({
        content: '操作失败,请重试',
        duration: 3000
      })
      downloading.value = false
    })
}
```

## oc-logo
* 大屏顶部logo显示
* 参数 text?: string 顶部文字
```
<oc-logo text="智能刀具管理平台" />
```
## oc-my
* 个人信息页面
```
<oc-my />
```
## oc-number-roll
* 数字滚动效果
* 参数
* value: number | string
* duration?: number 持续时长
* precision?: number 精度
* format?: Fn<number, string> 格式化
```
<oc-number-roll
  :value="count ?? 0"
  :format="numFormat"
/>
```

## oc-skeleton
* 骨架屏
* 参数
* cols?: number 一排几个，最大24
* num?: [number, number][] 每行每列的数量
```
<oc-skeleton
  :cols="3"
  :num="[
    [3, 1],
    [3, 1],
    [3, 1]
  ]"
/>
```

## oc-404
* 页面未找到
```
<oc-404 />
```
## oc-500
* 发生错误
```
<oc-500 />
```

# 公共方法

## fnSetStorage
* 保存进LocalStorage
* key: string
* value: string | ObjectKey | boolean,
* expired: number | string = 30000 // 存储时间 string接受 '1 Minutes' '5 Hours' '7 Day' '1 Week'
* 0 为永久存储
```
fnSetStorage('save', {a: 1}, 0)
```

## fnGetStorage
* 取LocalStorage
* key: string
* defaultValue: any 当过期或不存在时返回默认值
```
fnGetStorage('save', false)
```

## fnDelStorage
* 删除LocalStorage
* key: string

## fnScrollTop
* 移动页面到顶部

## fnDeleteLoad
* 删除加载中状态

## fnPageModel2Naive
* 转换NUI的query到后台的query

## fnPageNaive2Model
* 转换后台的query到NUI的query

## fnFormatTime
* 格式化时间
* value: string | number | Date | null | undefined,
* fmt = 'yyyy-MM-dd'
* yyyy-MM-dd hh:mm:ss

## fnRenderAction
* 公用操作按钮方法
* buttons: IActionButton[]
* type: 'detail' | 'edit' | 'delete' | 'tips' | 'custom'
* disabled?: false
```
{
  type: 'detail',
  onClick: () => detail(row)
}
{
  type: 'edit',
  onClick: () => edit(row)
}
{
  type: 'delete',
  onClick: () => delete(row)
}
{
  type: 'tips',
  onClick: () => tips(row)
}
{
  type: 'custom',
  onClick: () => {
    exportData(row.key)
  },
  icon: IconCalendarArrowDown,
  color: 'success',
  text: '下载'
}
```

## fnEncodeCursor
* 加密到base64
* data: ObjectKey

## fnDecodeCursor
* 解密base64
* data: string

## fnThrottle
* 节流方法
```
const svgTitle = fnThrottle((e: MouseEvent): void => {
  const tmp = (e.target as HTMLBaseElement).dataset.title
  title.value = tmp || ''
}, 200)
```

## fnFullScreen
* 全屏显示
* element: any // 要全屏的元素
* callback?: Fn // 回调函数

## GET
* 全局统一fetch的GET方法
* url: string
* data: any
* responseType?: "arraybuffer" | "blob" | "document" | "json" | "stream" | "text"

## POST
* 全局统一fetch的POST方法
* url: string
* data: ObjectKey
* responseType?: "arraybuffer" | "blob" | "document" | "json" | "stream" | "text"
* timeout?: number
## FILE
* 全局统一fetch的FILE方法
* url: string
* data: any

```
import { POST } from '@partex/one-core'
GET('api/manager/prod-task/page', params)
POST('api/manager/prod-task/page', params)
FILE('api/manager/job/submit', formData)
```

# 公共Store
* commonStore
```
interface Store {
  isMobile: boolean // 是否是小屏幕
  download: boolean // 显示/隐藏下载窗口
  theme: boolean    // 主题颜色 true: light false: dark
  platformName: () => string // 平台名称
  platformType: string // 平台代码
  platformUrl: string  // 平台首页
}
```

## userStore
* 用户信息
```
factoryId?: string
userId?: string
thirdUserId?: string
email: string
password: string
name: string
realName: string
phone: string
description: string
enable: boolean
oeeStatus: 0 | 1 // OEE状态
tenantName: string // 租户名称
kind: number // -1开发者 0普通账户 1大屏账户 2虚拟账号 99管理员
roleId: 1 | 2
authorizationGroupArray: string[]
authorizationMachineArray: string[]
iot_menu_authorization: string[]
tdm_menu_authorization: string[]
qms_menu_authorization: string[]
maintain_menu_authorization: string[]
info: IUserInfo
endTime: number
tenantStatus: 0 | 1 | 2
renewalStatus: 0 | 1
ncFlg: 0 | 1 // NC代码权限
systemType: 0 | 1 | 2 // 基础版：Basic；高级版：Premium；旗舰版：Flagship
platform_tdm: boolean
```
* fnSetUser 设置用户信息
* fnGetUser 通过接口获取用户信息
* fnClearUser 清除用户信息
* fnUserLogout 退出登录

## scaleStore
* 縮放比例
```
scale: number
```
* fnComputedScale 計算縮放
* fnListenerScale 監聽縮放，返回remove
* fnSetNormalWidthAndHeight 修改NormalWidthAndHeight 默认4k 16:9

# 导出公共ts
```
export interface Query {
  page: number
  pageSize?: number
  pageCount?: number
  itemCount?: number
  pageSizes?: number[]
  isGetAll?: 0 | 1
  keyword?: string
  columnKey?: string
  order?: string
  showQuickJumper?: boolean
  showSizePicker?: boolean
  pageSlot?: number
}

export interface PageModel<T> {
  current: string
  size: string
  pages: string
  total: string
  records: T
}

export interface PageRecords<T> {
  query: Query
  records: T
}

export interface Fn<T = any, R = T> {
  (...arg: T[]): R
}

export type ObjectKey<T = any> = {
  [x in string | number]: T
}

export type Recordable<T = any> = Record<string, T>

export type Nullable<T> = T | null

export type Mapped<Type> = {
  [Properties in keyof Type as KeyType]: Type[Properties]
}

export type TimeoutHandle = ReturnType<typeof setTimeout> | undefined

export type IntervalHandle = ReturnType<typeof setInterval> | undefined
```

## ICON
* IconChevronLeft
* IconArrowSquareDown
* IconWeatherMoon
* IconWeatherSunny
* IconGridDots
* IconSearch
* IconArrowClockwise
* IconCalendarArrowDown
* IconFullScreenMaximize
* IconDelete
* IconEye
* IconDrafts
* IconDismiss
* IconMailInboxAdd
* IconCloudArrowDown

## root Colors
```
--primary: 142, 84, 200;
--white: 255, 255, 255;
--card: 255, 255, 255;
--font: 51, 51, 51;
--bg: 247, 248, 250;
--input: 255, 255, 255;
--border: 224, 224, 230;
--green: 93, 174, 87;
--yellow: 240, 151, 58;
--red: 230, 84, 68;
--blue: 32, 128, 240;
--grey: 175, 175, 175;
--cardShadow: 0 6px 10px -5px rgba(0, 0, 0, 0.1);
```

# 未加入，视情况以后加入
## useThrottleFn
* 用来处理节流函数的 Hook。
* 频繁调用 run，但只会每隔 500ms 执行一次相关函数。
```
<template>
    <div>
      <p style="marginTop: 16"> Clicked count: {{throttleFnValue}} </p>
      <button type="button" @click="run">
        useThrottleFn测试
      </button>
    </div>
</template>

<script lang="ts">
import { ref } from 'vue';
import { useThrottleFn } from 'one-core';

export default {
  setup() {
    const throttleFnValue = ref(1);
    const { run } = useThrottleFn(()=>{
      throttleFnValue.value++
    },500)

    return {
      throttleFnValue,
      run,
    }
  }
}
</script>
```

## useDebounceFn
* 用来处理防抖函数的 Hook
* 频繁调用 debounceFnRun，但只会在所有点击完成 1000ms 后执行一次相关函数
```
<template>
    <div>
      <p style="marginTop: 16"> Clicked count: {{debounceFnValue}} </p>
      <button type="button" @click="debounceFnRun">
        useDebounceFn测试
      </button>
    </div>
</template>

<script lang="ts">
import { ref } from 'vue';
import { useDebounceFn } from 'one-core';
export default {
  setup() {
    const debounceFnValue = ref<number>(1);
    const { run:debounceFnRun } = useDebounceFn(()=>{
      debounceFnValue.value++
    },500)

    return {
      debounceFnValue,
      debounceFnRun,
    }
  }
}
</script>
```

# 从v1.0.0升级到v1.1.0
### v1.0.0
![v1.0.0](./doc/code.png "before")
### v1.1.0
![v1.1.0](./doc/code_after.png "after")

### 变化
### v1.1.0之后value不支持双向绑定，提供setValues与setData方法来变更
* setValues变更value的数据
* setData变更搜索条件

### v1.1.0之后提供搜索条件记忆功能
* 注：把所有需要变动的数据都放在value的ref里面。并且在每次请求结果后调用setValues