From 54d8eb1bd2ae36b8ed5589bf5730284f11434625 Mon Sep 17 00:00:00 2001 From: xhc <15171145581@163.com> Date: Fri, 6 Jun 2025 17:50:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=B8=8A=E4=BC=A0=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=B0=B4=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 36 +- src/api/api.js | 7 +- src/components/da-dropdown/changelog.md | 164 ++++ .../da-dropdown/components/cell.vue | 172 ++++ .../da-dropdown/components/daterange.vue | 209 ++++ .../da-dropdown/components/filter.vue | 220 +++++ .../components/part-dropdown-footer.vue | 75 ++ .../da-dropdown/components/picker.vue | 220 +++++ src/components/da-dropdown/index.vue | 898 ++++++++++++++++++ src/components/da-dropdown/readme.md | 443 +++++++++ src/components/da-dropdown/typing.ts | 151 +++ src/components/da-dropdown/utils.ts | 207 ++++ src/components/hpy-watermark.vue | 344 +++++++ src/components/image-watermark-picker.vue | 275 ++++++ src/components/waterMarker.vue | 147 +++ src/package.json | 20 + src/pages/feedback/feedback.vue | 2 +- src/pages/index/index.vue | 115 ++- src/pages/knowledgeBase/knowledgeBase.vue | 104 +- src/pages/message/message.vue | 49 +- src/pages/my/my.vue | 8 +- src/pages/points/points.vue | 220 ++++- src/pages/startInspection/startInspection.vue | 6 +- src/uni_modules/hpy-watermark/changelog.md | 5 + .../hpy-watermark/hpy-watermark.vue | 198 ++++ src/uni_modules/hpy-watermark/package.json | 83 ++ src/uni_modules/hpy-watermark/readme.md | 201 ++++ 27 files changed, 4474 insertions(+), 105 deletions(-) create mode 100644 src/components/da-dropdown/changelog.md create mode 100644 src/components/da-dropdown/components/cell.vue create mode 100644 src/components/da-dropdown/components/daterange.vue create mode 100644 src/components/da-dropdown/components/filter.vue create mode 100644 src/components/da-dropdown/components/part-dropdown-footer.vue create mode 100644 src/components/da-dropdown/components/picker.vue create mode 100644 src/components/da-dropdown/index.vue create mode 100644 src/components/da-dropdown/readme.md create mode 100644 src/components/da-dropdown/typing.ts create mode 100644 src/components/da-dropdown/utils.ts create mode 100644 src/components/hpy-watermark.vue create mode 100644 src/components/image-watermark-picker.vue create mode 100644 src/components/waterMarker.vue create mode 100644 src/package.json create mode 100644 src/uni_modules/hpy-watermark/changelog.md create mode 100644 src/uni_modules/hpy-watermark/components/hpy-watermark/hpy-watermark.vue create mode 100644 src/uni_modules/hpy-watermark/package.json create mode 100644 src/uni_modules/hpy-watermark/readme.md diff --git a/src/App.vue b/src/App.vue index de2b297..b8b914e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,7 @@ * @Author: XHC * @Date: 2025-05-19 10:21:48 * @LastEditors: XHC - * @LastEditTime: 2025-05-30 10:44:11 + * @LastEditTime: 2025-06-06 17:37:54 * @Description: --> + + diff --git a/src/components/da-dropdown/components/daterange.vue b/src/components/da-dropdown/components/daterange.vue new file mode 100644 index 0000000..57c7415 --- /dev/null +++ b/src/components/da-dropdown/components/daterange.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/src/components/da-dropdown/components/filter.vue b/src/components/da-dropdown/components/filter.vue new file mode 100644 index 0000000..4a39be3 --- /dev/null +++ b/src/components/da-dropdown/components/filter.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/src/components/da-dropdown/components/part-dropdown-footer.vue b/src/components/da-dropdown/components/part-dropdown-footer.vue new file mode 100644 index 0000000..efd18c3 --- /dev/null +++ b/src/components/da-dropdown/components/part-dropdown-footer.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/components/da-dropdown/components/picker.vue b/src/components/da-dropdown/components/picker.vue new file mode 100644 index 0000000..23e1966 --- /dev/null +++ b/src/components/da-dropdown/components/picker.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/src/components/da-dropdown/index.vue b/src/components/da-dropdown/index.vue new file mode 100644 index 0000000..aebaba8 --- /dev/null +++ b/src/components/da-dropdown/index.vue @@ -0,0 +1,898 @@ + + + + + diff --git a/src/components/da-dropdown/readme.md b/src/components/da-dropdown/readme.md new file mode 100644 index 0000000..9384942 --- /dev/null +++ b/src/components/da-dropdown/readme.md @@ -0,0 +1,443 @@ +# da-dropdown + +一个基于 Vue3 的头部导航栏下拉弹窗组件,多平台兼容。 + +组件一直在更新,遇到问题可在下方讨论。 + +`同时更新 Vue2 版本,在此查看 ===>` **[Vue2 版](https://ext.dcloud.net.cn/plugin?id=13062)** + +### 关于使用 + +可在右侧的`使用 HBuilderX 导入插件`或`下载示例项目ZIP`,示例项目已添加多个示例,方便快速上手。 + +可通过下方的示例及文档说明,进一步了解使用组件相关细节参数。 + +插件地址:https://ext.dcloud.net.cn/plugin?id=11840 + +### 功能一览 + +1. 下拉列表(单选) +2. 点击常亮 +3. 点击排序 +4. 下拉筛选(单选按钮、多选按钮、滑动选择器) +5. 级联筛选(单选) +6. 日期筛选(日期快选、日期区间选择) +7. 顶部搜索 +8. 自定插槽 + +### 组件示例 + +```jsx + +``` + +```js +import { defineComponent, ref } from 'vue' + +import DaDropdown from '@/components/da-dropdown/index.vue' + +export default defineComponent({ + components: { DaDropdown }, + setup() { + const dropdownMenuList = ref([ + // 演示数据请看下方各模块说明或下载示例项目查看 + // ... + ]) + function handleConfirm(v) { + console.log('handleConfirm ==>', v) + } + function handleClose(v) { + console.log('handleClose ==>', v) + } + function handleOpen(v) { + console.log('handleOpen ==>', v) + } + return { + dropdownMenuList, + handleConfirm, + handleClose, + handleOpen, + } + }, +}) +``` + +### 组件参数 + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :------------------- | :-------- | :-------- | :--- | :--------------------------------- | +| v-model:dropdownMenu | `Array` | `[]` | 是 | 导航菜单数据 | +| themeColor | `String` | `#007aff` | 否 | 主题颜色 | +| textColor | `String` | `#333333` | 否 | 导航文字颜色 | +| bgColor | `String` | `#ffffff` | 否 | 背景颜色,当固定在顶部时,此为必填 | +| fixedTop | `Boolean` | `false` | 否 | 是否固定在顶部 | +| fixedTopValue | `Number` | `0` | 否 | 固定在头部时的位置,单位 px | +| duration | `Number` | `300` | 否 | 弹窗动画的过渡时间 | + +> 温馨提示:如果页面定义了 "navigationStyle": "custom" ,因此固定头部时需要额外获取状态栏高度,以免被异形屏头部覆盖,此时的 fixedTopValue 的作用就出来了,通过 fixedTopValue 自定义加减固定头部所处的位置。 + + +### 组件事件 + +| 事件名称 | 回调参数 | 说明 | +| :------- | :------------------------- | :----------------------------------------------------------------- | +| open | `(index) => void` | 打开弹窗时回调 | +| close | `(index,menuList) => void` | 关闭弹窗时回调 | +| confirm | `(value,data) => void` | 确定选择内容时回调,返回选择的数据,格式`{'菜单项prop值': '内容'}` | + + +### 组件方法 + +| 事件名称 | 回调参数 | 说明 | +| :---------------- | :------------------------- | :-------------------------------------- | +| openMenuItemPopup | `(index) => void` | 打开指定位置的菜单项弹窗 | +| closeMenuPopup | `() => void` | 关闭菜单项弹窗 | +| getMenuValue | `() => object` | 获取菜单存在的值 | +| updateMenu | `(prop,value,key) => void` | 更新菜单项内容【参考示例7】 | +| setMenuLoading | `(prop,state) => void` | 操作指定菜单项为加载中状态【参考示例7】 | +| getMenuIndex | `(prop) => number` | 获取菜单项所在索引位置 | +| getMenuList | `() => array` | 获取当前菜单列表数据【参考示例6】 | + + +### 组件菜单项 + +#### dropdownMenu 基础参数 + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---------- | :--------- | :----- | :--- | :--------------------------------------------------------------- | +| title | `String` | - | 是 | 菜单名称 | +| prop | `String` | - | 是 | 菜单 prop 值,**菜单项的 prop 是唯一的** | +| type | `String` | - | 是 | 菜单类型,参考下方类型说明 | +| syncDataFn | `Function` | - | 否 | 异步函数返回子项数据,优先级大于 options | +| syncDataKey | `String` | - | 否 | 异步数据不是根数据时需要。支持嵌套,如:`data.list`【参考示例7】 | + +除上方基础参数以外,不同的菜单项(type)会有额外的配置参数 + +**type 说明** +**cell** 下拉列表 +**click** 点击 +**sort** 排序 +**filter** 复杂筛选 +**picker** 级联 +**daterange** 日期范围 +**search** 搜索框(菜单项 type 唯一) +**slot** 弹窗插槽 + +#### 菜单项 - 下拉列表(cell) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :------- | :----------------- | :----------------------------------------------------- | :--- | :----------------------------------------- | +| value | `Number`\|`String` | - | 否 | 默认值,和`options`的 value 必须保持同类型 | +| showAll | `Boolean` | `false` | 否 | 是否显示 “不限” 项 | +| showIcon | `Boolean` | `false` | 否 | 是否在选中时显示勾选图标 | +| field | `Object` | `{ label: 'label', value: 'value', suffix: 'suffix' }` | 否 | 列表子项数据对应内容字段 | +| options | `Array` | `[]` | 否 | 下拉列表子项数据 | + + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '下拉', + type: 'cell', + prop: 'god1', + showAll: true, + showIcon: true, + // value: '2', // 默认内容2 + options: [ + { label: '下拉列表项1', value: '1', suffix: '副标题' }, + { label: '下拉列表项2', value: '2' }, + { label: '下拉列表项3', value: '3' }, + ], + }, +] +``` + +#### 菜单项 - 高亮(click) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---- | :-------- | :----- | :--- | :-------------------------------- | +| value | `Boolean` | - | 否 | 默认值,true 选中、false 取消选中 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '点击', + type: 'click', + prop: 'god2', + // value: true, // 默认选中 + }, +] +``` + +#### 菜单项 - 排序(sort) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---- | :------------ | :----- | :--- | :-------------------------- | +| value | `asc`\|`desc` | - | 否 | 默认值,asc 升序、desc 倒序 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '排序', + type: 'sort', + prop: 'god3', + // value: 'asc', // 默认升序 + }, +] +``` + +#### 菜单项 - 筛选(filter) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :------ | :------- | :----- | :--- | :------------------------------------------- | +| value | `Object` | - | 否 | 默认值,格式`{ prop1: '值1', prop2: '值2' }` | +| options | `Array` | `[]` | 否 | 筛选子项数据,**说明见下** | + +##### filter -> options 参数说明 + +| 属性 | 类型 | 必填 | 说明 | +| :------------- | :---------------------------- | :--- | :-------------------------------------------------------------------------------------------- | +| title | `String` | 是 | 筛选项的子项标题 | +| type | `radio`\|`checkbox`\|`slider` | 是 | 筛选项的子项类型,可选 radio 单选按钮、checkbox 多选按钮、slider 滑动选择器 | +| prop | `String` | 是 | 筛选项的子项 prop,**注意保持子项 prop 唯一** | +| componentProps | `Object` | 否 | 筛选项的对应的组件配置,[slider 组件配置](https://uniapp.dcloud.net.cn/component/slider.html) | +| options | `Array` | 否 | 筛选子项的类型对应的数据 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '筛选', + type: 'filter', + prop: 'god4', + // 默认选中单选2、多选2、3、滑动30 + // value: { ft1: '2', ft2: ['2', '3'], ft3: 30 }, + options: [ + { + title: '单选', + type: 'radio', + prop: 'ft1', + options: [ + { label: '单选1', value: '1' }, + { label: '单选2', value: '2' } + ], + }, + { + title: '多选', + type: 'checkbox', + prop: 'ft2', + options: [ + { label: '多选1', value: '1' }, + { label: '多选2', value: '2' } + ], + }, + { + title: '滑块', + type: 'slider', + prop: 'ft3', + componentProps: { + min: 0, + max: 100, + step: 1, + showValue: true, + }, + }, + ], + }, +] +``` + +#### 菜单项 - 级联(picker) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---------- | :--------- | :--------------------------------------------------------- | :--- | :--------------------------------------------------------------- | +| value | `Array` | - | 否 | 默认值,格式`['一级value', '二级value']` | +| showAll | `Boolean` | `false` | 否 | 是否显示 “不限” 项 | +| showIcon | `Boolean` | `false` | 否 | 是否在选中末级时显示勾选图标 | +| field | `Object` | `{ label: 'label', value: 'value', children: 'children' }` | 否 | 级联子项数据对应内容字段 | +| options | `Array` | `[]` | 否 | 级联子项数据 | +| syncDataFn | `Function` | - | 否 | 异步函数返回级联子项数据,优先级大于 options | +| syncDataKey | `String` | - | 否 | 异步数据不是根数据时需要。支持嵌套,如:`data.list`【参考示例7】 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '级联选择', + type: 'picker', + prop: 'god5', + showAll: true, + showIcon: true, + // showAll 为true时相当于在options第一的位置插入“不限”项 + // { label: '不限', value: '-9999' }, + field: { + label: 'label', + value: 'value', + children: 'children', + }, + // value: ['2', '22'], // 默认选中 级联X22 + options: [ + { + label: '级联X1', + value: '1', + children: [ + { label: '级联X11', value: '11' }, + { label: '级联X12', value: '12' }, + ], + }, + { + label: '级联X2', + value: '2', + children: [ + { label: '级联X21', value: '21' }, + { label: '级联X22', value: '22' }, + ], + }, + ], + }, +] +``` + +#### 菜单项 - 日期(daterange) + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :-------- | :-------- | :----- | :--- | :--------------------------------------------------- | +| value | `Object` | - | 否 | 默认值,格式`{ start: '开始日期', end: '结束日期' }` | +| showQuick | `Boolean` | `true` | 否 | 是否显示日期快选 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '日期范围', + type: 'daterange', + prop: 'god6', + // 默认选中 2022-01-01到2022-02-01 + // value: { start: '2022-01-01', end: '2022-02-01' }, + }, +] +``` + +#### 菜单项 - 顶部搜索框(search) + + +当存在此类型时,头部将会展示搜索框,**注意:此类型唯一** + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---- | :------- | :----- | :--- | :----- | +| value | `String` | - | 否 | 默认值 | + +```js +// 简单示例 +const dropdownMenuList = [ + { + title: '搜索', + type: 'search', + prop: 'god0', + }, +] +``` + +#### 菜单项 - 拓展插槽(slot1、slot2、slot3、slot4、slot5) + +拓展插槽有 5 个,足以应付业务需求了,类型名称为`slot1`、`slot2`、`slot3`、`slot4`、`slot5`,这是固定的类型值 + +| 属性 | 类型 | 默认值 | 必填 | 说明 | +| :---- | :------- | :----- | :--- | :----- | +| value | `String` | - | 否 | 默认值 | + +```jsx +// 简单示例 + +``` + +```js +const dropdownMenuList = [ + { + title: '插槽1', + type: 'slot1', + prop: 'god1', + }, + { + title: '插槽2', + type: 'slot2', + prop: 'god2', + }, + { + title: '插槽3', + type: 'slot3', + prop: 'god3', + }, + { + title: '插槽4', + type: 'slot4', + prop: 'god4', + }, + { + title: '插槽5', + type: 'slot5', + prop: 'god5', + }, +] +``` + +### 组件版本 + +v2.2.2 + +### 差异化 + +已通过测试 + +> - H5 页面 +> - 微信小程序 +> - 支付宝、钉钉小程序 +> - 字节跳动、抖音、今日头条小程序 +> - 百度小程序 +> - 飞书小程序 +> - QQ 小程序 +> - 京东小程序 + +未测试 + +> - 快手小程序由于非企业用户暂无演示 +> - 快应用、360 小程序因 Vue3 支持的原因暂无演示 + +### 开发组 + +[@CRLANG](https://crlang.com) diff --git a/src/components/da-dropdown/typing.ts b/src/components/da-dropdown/typing.ts new file mode 100644 index 0000000..4bf6d6c --- /dev/null +++ b/src/components/da-dropdown/typing.ts @@ -0,0 +1,151 @@ +/** + * 菜单项-下拉配置 + */ +export interface DaCellOption { + /** + * 是否显示“不限”选项 + */ + showAll?: boolean + /** + * 是否显示勾选图标 + */ + showIcon?: boolean +} +/** + * 菜单项-点击配置 + */ +export interface DaClickOption {} +/** + * 菜单项-排序配置 + */ +export interface DaSortOption {} +/** + * 菜单项-筛选配置 + */ +export interface DaFilterOption {} +/** + * 菜单项-级联配置 + */ +export interface DaPickerOption { + /** + * 是否显示“不限”选项 + */ + showAll?: boolean + /** + * 是否显示勾选图标 + */ + showIcon?: boolean + field?: { + label: string + value: string + children: string + } +} +/** + * 菜单项-日期范围配置 + */ +export interface DaDaterangeOption { + value?: { + start: string + end: string + } +} +/** + * 下拉列表-项内容 + */ +export interface DaCellItemOption extends DaDropdownMenuListOption { + /** + * 右侧子标题 + */ + suffix?: string +} +/** + * 筛选-项内容 + */ +export interface DaFilterItemOption { + /** + * 筛选标题 + */ + title: string + /** + * 筛选类型,可选 radio 单选按钮、checkbox 多选按钮、slider 滑动选择器 + */ + type: 'radio' | 'checkbox' | 'slider' + /** + * 筛选项prop + */ + prop: string + /** + * 已选内容 + */ + value?: string | number | string[] | number[] + /** + * 筛选项-slider子项组件prop,具体参考 https://uniapp.dcloud.net.cn/component/slider.html + */ + componentProp?: object + /** + * 筛选项-子项 + */ + options?: DaDropdownMenuListOption[] +} + +/** + * 级联-项内容 + */ +export interface DaPickerItem extends DaDropdownMenuListOption { + isActived: boolean + /** + * 子项 + */ + children?: DaPickerItem[] +} + +/** + * 菜单列表选择项 + */ +export interface DaDropdownMenuListOption { + /** + * 选择项标题 + */ + label: string + /** + * 选择项内容 + */ + value: string +} + +/** + * 菜单项 + */ +export interface DaDropdownMenuListItem extends DaCellOption, DaClickOption, DaSortOption, DaFilterOption, DaPickerOption { + /** + * 菜单标题 + */ + title: string + /** + * 菜单类型 + * 可选:cell 下拉选择、click 点击、sort 排序、filter 复杂筛选、picker 级联、daterange 日期范围 + */ + type: 'cell' |'click' | 'sort' | 'filter' | 'picker'| 'daterange' + /** + * 菜单项prop + */ + prop: string + /** + * 菜单值 + */ + value?: string + /** + * 菜单选项函数,优先级大于 options + */ + syncDataFn?: Function + /** + * 菜单选项 + */ + options?: DaDropdownMenuListOption[] | DaFilterItemOption[] +} + +/** + * 菜单列表 + */ +export type DaDropdownMenuList = DaDropdownMenuListItem[] diff --git a/src/components/da-dropdown/utils.ts b/src/components/da-dropdown/utils.ts new file mode 100644 index 0000000..9207fda --- /dev/null +++ b/src/components/da-dropdown/utils.ts @@ -0,0 +1,207 @@ +/** + * 深拷贝内容 + * @param originData 拷贝对象 + * @author crlang(https://crlang.com) + */ +export function deepClone(originData) { + const type = Object.prototype.toString.call(originData) + let data + if (type === '[object Array]') { + data = [] + for (let i = 0; i < originData.length; i++) { + data.push(deepClone(originData[i])) + } + } else if (type === '[object Object]') { + data = {} + for (const prop in originData) { + // eslint-disable-next-line no-prototype-builtins + if (originData.hasOwnProperty(prop)) { // 非继承属性 + data[prop] = deepClone(originData[prop]) + } + } + } else { + data = originData + } + return data +} + +export function getValueByKey(object, path, defaultVal = undefined) { + console.log('object, path', object, path) + // 先将path处理成统一格式 + let newPath = [] + if (Array.isArray(path)) { + newPath = path + } else { + // 先将字符串中的'['、']'去除替换为'.',split分割成数组形式 + newPath = path.replace(/\[/g, '.').replace(/\]/g, '').split('.') + } + + // 递归处理,返回最后结果 + return newPath.reduce((o, k) => { + console.log(o, k) // 此处o初始值为下边传入的 object,后续值为每次取的内部值 + return (o || {})[k] + }, object) || defaultVal +} + +/** + * 处理部分初始数据 + * @param data + */ +export function checkDataField(options, fields) { + if (!fields || !options || options.length === 0) { + return options + } + + for (let i = 0; i < options.length; i++) { + const k = options[i] + k.label = k[fields.label || 'label'] || null + k.value = k[fields.value || 'value'] || null + k.suffix = k[fields.suffix || 'suffix'] || null + k.children = k[fields.children || 'children'] || null + if (k.children?.length) { + k.options = checkDataField(k.options) + } + } + return options +} + +/** + * 格式化数值-个位数补零 + * @param n 数值 + * @author crlang(https://crlang.com) + */ +export function formatNumber(n) { + let s = parseInt(n) + if (isNaN(s)) { + s = '0' + } else { + s = s.toString() + } + return s[1] ? s : `0${s}` +} + +/** + * 格式化时间 + * @param date 时间对象 + * @param format 格式 + * @author crlang(https://crlang.com) + */ +export function formatTime(date, format) { + const daDate = new Date(date.toString().length < 11 ? date * 1000 : date) + const fromatsRule = ['y', 'm', 'd', 'h', 'i', 's'] + let tmp = [] + const year = daDate.getFullYear() + const month = daDate.getMonth() + 1 + const day = daDate.getDate() + const hour = daDate.getHours() + const minute = daDate.getMinutes() + const second = daDate.getSeconds() + + if (format) { + tmp.push(year, month, day, hour, minute, second) + tmp = tmp.map(formatNumber) + for (let i = 0; i < tmp.length; i++) { + format = format.toLowerCase().replace(fromatsRule[i], tmp[i]) + } + return format + } + + return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}` +} + +/** + * 获取某个时间范围 + * + * @param v -1、-7、-14、-30、-60 + * @returns object {start: y-m-d,end: y-m-d} + * @author crlang(https://crlang.com) + */ +export function getRangeDate(v) { + const now = new Date() + const nowTime = now.getTime() + const oneDay = 24 * 60 * 60 * 1000 + const dateRange = { start: '', end: '' } + const nowWeekDay = now.getDay() // 今天本周的第几天 + const nowDay = now.getDate() // 当前日 + const nowMonth = now.getMonth() // 当前月 + const nowYear = now.getFullYear() // 当前年 + + /** + * 获得某个月的天数 + * @param month 当前月份 + */ + const getMonthDays = function(month) { + const monthStartDate = new Date(nowYear, month, 1) + const monthEndDate = new Date(nowYear, month + 1, 1) + const days = (monthEndDate - monthStartDate) / oneDay + return days + } + + // 昨日 + if (v === '-1') { + dateRange.start = formatTime(new Date(nowTime - oneDay), 'y-m-d') + dateRange.end = dateRange.start + // 本周 + } else if (v === '-7') { + const weekStart = new Date(nowYear, nowMonth, nowDay - nowWeekDay + 1) + const weekEnd = new Date(nowTime + oneDay) // 今日 + dateRange.start = formatTime(weekStart, 'y-m-d') + dateRange.end = formatTime(weekEnd, 'y-m-d') + // 上周 + } else if (v === '-14') { + const weekStart = new Date(nowYear, nowMonth, nowDay - nowWeekDay - 6) + const weekEnd = new Date(nowYear, nowMonth, nowDay - nowWeekDay) + dateRange.start = formatTime(weekStart, 'y-m-d') + dateRange.end = formatTime(weekEnd, 'y-m-d') + // 本月 + } else if (v === '-30') { + const monthStart = new Date(nowYear, nowMonth, 1) + const monthEnd = new Date(nowTime + oneDay) + dateRange.start = formatTime(monthStart, 'y-m-d') + dateRange.end = formatTime(monthEnd, 'y-m-d') + // 上月 + } else if (v === '-60') { + const lastMonthDate = new Date() // 上月日期 + lastMonthDate.setDate(1) + lastMonthDate.setMonth(lastMonthDate.getMonth() - 1) + const lastMonth = lastMonthDate.getMonth() + const lastMonthStart = new Date(nowMonth === 0 ? nowYear - 1 : nowYear, lastMonth, 1) + const lastMonthEnd = new Date(nowMonth === 0 ? nowYear - 1 : nowYear, lastMonth, getMonthDays(lastMonth)) + dateRange.start = formatTime(lastMonthStart, 'y-m-d') + dateRange.end = formatTime(lastMonthEnd, 'y-m-d') + } else { + // 传入 v 为整数是即为近 xx 天 + if (v > 0) { + dateRange.start = formatTime(new Date(nowTime - oneDay * parseInt(v)), 'y-m-d') + dateRange.end = formatTime(new Date(nowTime - oneDay), 'y-m-d') // 不含今天 + } + } + return dateRange +} + +export const menuInitOpts = { + cell: { + showArrow: true, + }, + click: { + }, + sort: { + showSort: true, + }, + filter: { + showArrow: true, + }, + picker: { + showArrow: true, + }, + daterange: { + showQuick: true, + showArrow: true, + }, + slot: { + showArrow: true, + }, + search: { + showSearch: true, + }, +} diff --git a/src/components/hpy-watermark.vue b/src/components/hpy-watermark.vue new file mode 100644 index 0000000..e7f91c5 --- /dev/null +++ b/src/components/hpy-watermark.vue @@ -0,0 +1,344 @@ + + + + + \ No newline at end of file diff --git a/src/components/image-watermark-picker.vue b/src/components/image-watermark-picker.vue new file mode 100644 index 0000000..461b58b --- /dev/null +++ b/src/components/image-watermark-picker.vue @@ -0,0 +1,275 @@ + + + + + + diff --git a/src/components/waterMarker.vue b/src/components/waterMarker.vue new file mode 100644 index 0000000..7cdef7f --- /dev/null +++ b/src/components/waterMarker.vue @@ -0,0 +1,147 @@ + + + \ No newline at end of file diff --git a/src/package.json b/src/package.json new file mode 100644 index 0000000..1edf91b --- /dev/null +++ b/src/package.json @@ -0,0 +1,20 @@ +{ + "id": "da-dropdown", + "name": "da-dropdown 下拉筛选菜单(支持主题色、功能丰富,Vue3版)", + "displayName": "da-dropdown 下拉筛选菜单(支持主题色、功能丰富,Vue3版)", + "version": "2.2.2", + "description": "一个基于 Vue3 的头部导航栏下拉筛选菜单组件,兼容App、H5、微信小程序、支付宝小程序、抖音小程序等。。。", + "keywords": [ + "dropdown", + "导航栏", + "筛选", + "下拉菜单", + "da系列" + ], + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ] + } +} \ No newline at end of file diff --git a/src/pages/feedback/feedback.vue b/src/pages/feedback/feedback.vue index 3f187b2..7a57027 100644 --- a/src/pages/feedback/feedback.vue +++ b/src/pages/feedback/feedback.vue @@ -92,7 +92,7 @@ const submit = (ref) => { .tips { border-radius: 10rpx; background: #ffffff3f; - margin: 30rpx; + margin: 0 30rpx 30rpx; padding: 10rpx; display: flex; align-items: center; diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index e043e21..6b3a5ab 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -2,7 +2,7 @@ * @Author: XHC * @Date: 2025-05-19 11:07:37 * @LastEditors: XHC - * @LastEditTime: 2025-05-29 16:55:28 + * @LastEditTime: 2025-06-06 17:40:38 * @Description: 首页 --> \ No newline at end of file diff --git a/src/pages/message/message.vue b/src/pages/message/message.vue index 1154e95..ec00f91 100644 --- a/src/pages/message/message.vue +++ b/src/pages/message/message.vue @@ -2,7 +2,7 @@ * @Author: XHC * @Date: 2025-05-19 15:19:14 * @LastEditors: XHC - * @LastEditTime: 2025-05-23 15:30:08 + * @LastEditTime: 2025-06-05 17:46:03 * @Description: 消息 --> diff --git a/src/uni_modules/hpy-watermark/package.json b/src/uni_modules/hpy-watermark/package.json new file mode 100644 index 0000000..c427e8e --- /dev/null +++ b/src/uni_modules/hpy-watermark/package.json @@ -0,0 +1,83 @@ +{ + "id": "hpy-watermark", + "displayName": "文字水印", + "version": "1.0.6", + "description": "图片增加文字水印,支持拍照和相册选取多张", + "keywords": [ + "水印", + "图片水印", + "文字水印", + "watermark" +], + "repository": "", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/hpy-watermark/readme.md b/src/uni_modules/hpy-watermark/readme.md new file mode 100644 index 0000000..ad8315d --- /dev/null +++ b/src/uni_modules/hpy-watermark/readme.md @@ -0,0 +1,201 @@ + +## 图片增加文字水印 + +> **组件名:hpy-watermark +> 图片增加文字水印,支持拍照和相册选取多张 + +## API + +## Props + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性名类型默认值说明
markAlignString左下角文字文字位置(默认:左下角)可选值:左上角:topLeft、右上角:topRight、左下角:bottomLeft、右下角:bottomRight
fontSizeNumber40文字大小,默认:40
fontColorString白色文字颜色,默认:#FFFFFF
qualityNumber1图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理
fileTypeStringjpg目标文件的类型,只支持 'jpg' 或 'png'。默认为 'jpg'
shadowColorString黑色阴影颜色,默认:rgba(0, 0, 0, 1.0)
shadowWidthNumber2阴影边框大小,默认:2
textAlignStringstart设置文本的水平对齐方式,默认:start,文本在指定的位置开始。 start、end、center、left、right
textBaselineStringalphabetic设置文本的垂直对齐方式,默认:alphabetic文本基线是普通的字母基线。top、hanging、middle、ideographic、bottom
+ + +## methods + + + + + + + + + + + +
参数名类型说明
addWaterMarkObject{filePaths:['图片地址1', '图片地址2'], fillTexts:['水印文字1', '水印文字2']}
+ +## 使用示例 + +```html + +``` + +```javascript + + +``` + +```style + +``` \ No newline at end of file