UNPKG

jobsys-explore

Version:

Enhanced component based on vant

1 lines 427 kB
{"version":3,"file":"jobsys-explore.cjs","sources":["../components/button/ExButton.jsx","../utils/withInstall.js","../components/button/index.js","../components/theme/ExTheme.jsx","../components/theme/index.js","../components/utils.js","../components/form/ExField.jsx","../components/form/PickerWrapper.jsx","../components/provider/ExProvider.jsx","../components/form/ExAddress.jsx","../components/form/ExCascader.jsx","../components/form/ExCheckbox.jsx","../../../node_modules/.pnpm/vant@4.6.6_vue@3.5.13_typescript@4.9.5_/node_modules/vant/es/utils/format.mjs","../components/form/ExDate.jsx","../components/form/ExDatetime.jsx","../components/form/ExTime.jsx","../components/form/ExNumber.jsx","../components/form/ExRadio.jsx","../components/form/ExSelect.jsx","../components/form/ExSwitch.jsx","../components/form/ExRate.jsx","../components/form/ExSlider.jsx","../components/uploader/ExUploader.jsx","../components/form/ExFieldUploader.jsx","../components/form/ExMatrixRadio.jsx","../components/form/utils.js","../components/form/ExMatrixScale.jsx","../components/form/ExMatrixCheckbox.jsx","../components/form/FormItem.jsx","../components/form/ExForm.jsx","../components/form/index.js","../components/provider/index.js","../components/result/ExResult.jsx","../components/result/index.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/can-promise.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/utils.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/error-correction-level.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/bit-buffer.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/bit-matrix.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/alignment-pattern.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/finder-pattern.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/mask-pattern.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/error-correction-code.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/galois-field.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/polynomial.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/reed-solomon-encoder.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/version-check.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/regex.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/mode.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/version.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/format-info.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/numeric-data.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/alphanumeric-data.js","../../../node_modules/.pnpm/encode-utf8@1.0.3/node_modules/encode-utf8/index.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/byte-data.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/kanji-data.js","../../../node_modules/.pnpm/dijkstrajs@1.0.3/node_modules/dijkstrajs/dijkstra.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/segments.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/core/qrcode.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/renderer/utils.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/renderer/canvas.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/renderer/svg-tag.js","../../../node_modules/.pnpm/qrcode@1.5.3/node_modules/qrcode/lib/browser.js","../components/qrcode/ExQrcode.jsx","../components/qrcode/index.js","../utils/style.js","../components/grid/ExGrid.jsx","../components/search/components/Expand.jsx","../components/search/components/Quick.jsx","../components/search/components/Field.jsx","../components/search/ExSearch.jsx","../components/pagination/ExPagination.jsx","../components/pagination/index.js","../components/search/index.js","../components/uploader/index.js","../components/grid/index.js","../components/decorator/ExDecorator.jsx","../components/decorator/index.js","../components/sector/ExSector.jsx","../components/sector/index.js","../../../node_modules/.pnpm/signature_pad@5.0.7/node_modules/signature_pad/dist/signature_pad.js","../components/signature-pad/ExSignaturePad.jsx","../components/signature-pad/index.js","../business-components/survey/ExSurvey.jsx","../business-components/survey/index.js","../index.js"],"sourcesContent":["import { defineComponent } from \"vue\"\nimport { Button } from \"vant\"\nimport \"./index.less\"\n\n/**\n * 主题组件\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExButton\",\n\tprops: {\n\t\t/**\n\t\t * 按钮类型\n\t\t * @values primary, success, warning, danger\n\t\t */\n\t\ttype: { type: String, default: \"default\" },\n\n\t\t/**\n\t\t * 按钮大小\n\t\t * @values large, normal, small, mini\n\t\t */\n\t\tsize: { type: String, default: \"normal\" },\n\n\t\t/**\n\t\t * 失效状态\n\t\t */\n\t\tdisabled: { type: Boolean, default: false },\n\n\t\t/**\n\t\t * 是否圆形按钮\n\t\t */\n\t\tround: { type: Boolean, default: true },\n\n\t\t/**\n\t\t * 是否块状按钮\n\t\t */\n\t\tblock: { type: Boolean, default: true },\n\n\t\t/**\n\t\t * 按钮标签\n\t\t */\n\t\ttext: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 按钮图标,需要使用\n\t\t *\n\t\t */\n\t\ticon: { type: Object, default: null },\n\n\t\t/**\n\t\t * 按钮图标位置\n\t\t * @values left, right\n\t\t */\n\t\ticonPosition: { type: String, default: \"left\" },\n\n\t\t/**\n\t\t * 请求状态控制器\n\t\t * @param {boolean} fetcher.loading 是否加载中\n\t\t */\n\t\tfetcher: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ loading: false }),\n\t\t},\n\n\t\t/**\n\t\t * [原生配置](https://vant-contrib.gitee.io/vant/#/zh-CN/button)\n\t\t */\n\t\tbuttonProps: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\t},\n\temits: [\n\t\t/**\n\t\t * @event click\n\t\t * @param {Event} event 点击事件\n\t\t */\n\t\t\"click\",\n\t],\n\n\tsetup(props, { emit, slots }) {\n\t\tconst onClick = (e) => {\n\t\t\t/**\n\t\t\t * @event click 点击事件\n\t\t\t */\n\t\t\temit(\"click\", e)\n\t\t}\n\n\t\tconst defaultLabel = () => {\n\t\t\treturn props.text || slots.default?.()\n\t\t}\n\n\t\tconst defaultSlot = () => {\n\t\t\tif (props.icon && props.iconPosition === \"left\") {\n\t\t\t\treturn [props.icon, defaultLabel()]\n\t\t\t} else if (props.icon && props.iconPosition === \"right\") {\n\t\t\t\treturn [defaultLabel(), props.icon]\n\t\t\t}\n\t\t\treturn [defaultLabel()]\n\t\t}\n\n\t\treturn () => (\n\t\t\t<Button\n\t\t\t\tclass={\"ex-button\"}\n\t\t\t\tloading={props.fetcher.loading}\n\t\t\t\ttype={props.type}\n\t\t\t\tsize={props.size}\n\t\t\t\tdisabled={props.disabled}\n\t\t\t\tround={props.round}\n\t\t\t\tblock={props.block}\n\t\t\t\tonClick={onClick}\n\t\t\t\t{...props.buttonProps}\n\t\t\t>\n\t\t\t\t{{\n\t\t\t\t\tdefault: () => defaultSlot(),\n\t\t\t\t}}\n\t\t\t</Button>\n\t\t)\n\t},\n})\n","export default (component) => {\n\tcomponent.install = (app) => {\n\t\tconst name = component.name || component.__name\n\t\tapp.component(name, component)\n\t}\n\treturn component\n}\n","import _ExButton from \"./ExButton.jsx\"\nimport withInstall from \"../../utils/withInstall\"\nexport const ExButton = withInstall(_ExButton)\nexport default ExButton\n","import { defineComponent } from \"vue\"\nimport \"./index.less\"\n\n/**\n * 主题组件\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExTheme\",\n})\n","import _ExTheme from \"./ExTheme.jsx\"\nimport withInstall from \"../../utils/withInstall\"\nexport const ExTheme = withInstall(_ExTheme)\nexport default ExTheme\n","import { cloneDeep, isFunction, isNumber, isString } from \"lodash-es\"\nimport { watch } from \"vue\"\nimport { useCache, useFetch } from \"../hooks\"\n\n/**\n * 通用 field props\n */\nexport const defaultFieldProps = {\n\t/**\n\t * 输入框左侧文本\n\t */\n\tlabel: { type: String, default: \"\" },\n\n\t/**\n\t * 名称,作为提交表单时的标识符\n\t */\n\tname: { type: String, default: \"\" },\n\n\t/**\n\t * 输入框占位提示文字\n\t */\n\tplaceholder: { type: String, default: \"请填写\" },\n\n\t/**\n\t * 提示文案\n\t */\n\thelp: { type: [String, Function], default: \"\" },\n\n\t/**\n\t * 元素的append slot\n\t */\n\tappend: { type: [String, Function], default: \"\" },\n\n\t/**\n\t * 是否禁用输入框\n\t */\n\tdisabled: { type: Boolean, default: false },\n\n\t/**\n\t * 是否显示表单必填星号\n\t */\n\trequired: { type: Boolean, default: false },\n\n\t/**\n\t * 是否展示右侧箭头并开启点击反馈\n\t */\n\tisLink: { type: Boolean, default: false },\n\n\t/**\n\t * 是否为只读状态,只读状态下无法输入内容\n\t */\n\treadonly: { type: Boolean, default: false },\n\n\t/**\n\t * 表单校验规则\n\t */\n\trules: { type: Array, default: null },\n\n\t/**\n\t * 原生 [Field 配置](https://vant-contrib.gitee.io/vant/#/zh-CN/field)\n\t */\n\tfieldProps: { type: Object, default: () => ({}) },\n\n\t/**\n\t * 原生输入组件的 props\n\t */\n\tdefaultProps: { type: Object, default: () => ({}) },\n}\n\n/**\n * 原生 Field 的 slots\n * 用于从组合组件中挑选\n */\nexport const defaultFieldSlots = {\n\tlabel: () => null,\n\tinput: () => null,\n\t\"left-icon\": () => null,\n\t\"right-icon\": () => null,\n\tbutton: () => null,\n\t\"error-message\": () => null,\n\textra: () => null,\n}\n\n/**\n * 通用的 options props\n */\nexport const defaultOptionsProps = {\n\t/**\n\t * 选项\n\t */\n\toptions: { type: [Array, Function], default: () => [] },\n\n\t/**\n\t * 选项 url\n\t */\n\turl: { type: String, default: null },\n\n\t/**\n\t * 缓存url返回的数据\n\t */\n\turlCache: { type: Boolean, default: true },\n\n\t/**\n\t * 选项获取后的回调\n\t */\n\tafterFetched: { type: Function, default: null },\n}\n\n/**\n * Prepare options for select\n *\n * @param options\n * @return {Array}\n */\nexport const prepareOptions = (options) => {\n\toptions = isFunction(options) ? options() : options\n\toptions = cloneDeep(options).map((op) => {\n\t\tif (op.children?.length) {\n\t\t\top.children = prepareOptions(op.children)\n\t\t}\n\t\treturn isString(op) || isNumber(op) ? { value: op, label: op, text: op } : { text: op.label, ...op }\n\t})\n\treturn options\n}\n\n//内部方法,为了useOptionTrait实现单次请求,避免重复请求\nconst recordOptionsUrl = {}\nconst optionsFetcher = (props) => {\n\treturn new Promise((resolve) => {\n\t\tuseFetch()\n\t\t\t.get(props.url)\n\t\t\t.then((items) => {\n\t\t\t\tif (props.afterFetched) {\n\t\t\t\t\titems = props.afterFetched(items)\n\t\t\t\t}\n\t\t\t\tresolve(items)\n\t\t\t})\n\t})\n}\n/**\n * 初始化选项\n * @param options\n * @param props\n * @param {Array|Function} [defaultOptions]\n *\n * @return void\n */\nexport const useOptionTrait = async (options, props, defaultOptions) => {\n\toptions.value = prepareOptions(props.options)\n\n\tconst fetchData = async (props) => {\n\t\tif (recordOptionsUrl[props.url]) {\n\t\t\treturn recordOptionsUrl[props.url]\n\t\t}\n\t\trecordOptionsUrl[props.url] = optionsFetcher(props)\n\n\t\tconst result = await recordOptionsUrl[props.url]\n\t\trecordOptionsUrl[props.url] = null\n\t\treturn new Promise((resolve) => {\n\t\t\tresolve(result)\n\t\t})\n\t}\n\n\twatch(\n\t\t() => props.options,\n\t\t() => {\n\t\t\toptions.value = prepareOptions(props.options)\n\t\t},\n\t)\n\n\tif (!options.value.length) {\n\t\tif (props.url) {\n\t\t\tif (props.urlCache && useCache(props.url).get()) {\n\t\t\t\toptions.value = useCache(props.url).get()\n\t\t\t} else {\n\t\t\t\tfetchData(props).then((items) => {\n\t\t\t\t\toptions.value = items\n\t\t\t\t\tif (props.urlCache) {\n\t\t\t\t\t\tuseCache(props.url).set(items)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t} else if (defaultOptions) {\n\t\t\toptions.value = defaultOptions\n\t\t}\n\t}\n}\n","import { computed, defineComponent, getCurrentInstance, reactive, watch } from \"vue\"\nimport { Field, Icon, Popover } from \"vant\"\nimport { defaultFieldProps, defaultFieldSlots } from \"../utils\"\nimport { omit, pick, isString } from \"lodash-es\"\n\n/**\n * ExField 输入框\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExField\",\n\tprops: {\n\t\t...defaultFieldProps,\n\n\t\t/**\n\t\t * 输入框内容\n\t\t */\n\t\tmodelValue: { type: [String, Number, Array, Object, Boolean], default: () => \"\" },\n\n\t\t/**\n\t\t * 输入框类型, 支持原生 input 标签的所有\n\t\t */\n\t\ttype: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 是否作为 Picker 的 Trigger\n\t\t */\n\t\tmask: { type: Boolean, default: false },\n\t},\n\temits: [\"update:modelValue\", \"click\"],\n\tsetup(props, { slots, emit }) {\n\t\tconst instance = getCurrentInstance()\n\t\tconst displayText = instance.parent?.parent?.exposed?.displayText\n\n\t\tconst state = reactive({\n\t\t\tvalue: props.mask ? displayText : props.modelValue,\n\t\t\tshowHelp: false,\n\t\t})\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => {\n\t\t\t\tstate.value = props.modelValue\n\t\t\t},\n\t\t)\n\n\t\tconst isLink = computed(() => (props.mask && !props.disabled && !props.readonly ? true : props.isLink))\n\t\tconst isReadonly = computed(() => (props.mask ? true : props.readonly))\n\n\t\tconst onUpdateValue = (value) => {\n\t\t\temit(\"update:modelValue\", value)\n\t\t}\n\n\t\t/****************** render **********************/\n\n\t\tconst helpElem = () => {\n\t\t\tif (props.help) {\n\t\t\t\treturn (\n\t\t\t\t\t<Popover v-model:show={state.showHelp} theme={\"dark\"} placement={\"bottom-start\"}>\n\t\t\t\t\t\t{{\n\t\t\t\t\t\t\tdefault: () => <div class={\"ex-field__help\"}>{isString(props.help) ? props.help : props.help()}</div>,\n\t\t\t\t\t\t\treference: () =>\n\t\t\t\t\t\t\t\tprops.help ? (\n\t\t\t\t\t\t\t\t\t<span class={\"ex-field__help-handler\"}>\n\t\t\t\t\t\t\t\t\t\t<Icon name={\"warning-o\"}></Icon>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t) : null,\n\t\t\t\t\t\t}}\n\t\t\t\t\t</Popover>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t\tconst labelElem = () => (\n\t\t\t<div class={\"ex-field__label\"}>\n\t\t\t\t<span>{props.label || slots.label?.()}</span>\n\n\t\t\t\t{helpElem()}\n\t\t\t</div>\n\t\t)\n\n\t\tconst inputElem = () => {\n\t\t\tlet inputSlots = omit(slots, Object.keys(defaultFieldSlots))\n\t\t\tlet InputElem = slots.input ? slots.input() : null\n\n\t\t\tif (Object.keys(inputSlots).length) {\n\t\t\t\tif (InputElem.length > 1) {\n\t\t\t\t\tconsole.warn(\"More than one root element wrapped in ExField with input slots!\")\n\t\t\t\t}\n\t\t\t\tInputElem = InputElem[0]\n\t\t\t\treturn <InputElem>{inputSlots}</InputElem>\n\t\t\t}\n\t\t\treturn InputElem\n\t\t}\n\n\t\tconst appendElem = () => {\n\t\t\tif (props.append) {\n\t\t\t\tconst appendResult = isString(props.append) ? props.append : props.append()\n\t\t\t\treturn appendResult ? <div class={\"ex-field__append\"}>{appendResult}</div> : null\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\n\t\treturn () => {\n\t\t\tlet fieldSlots = pick(slots, Object.keys(defaultFieldSlots))\n\t\t\tif (!fieldSlots.label) {\n\t\t\t\tfieldSlots.label = labelElem\n\t\t\t}\n\n\t\t\tif (fieldSlots.input) {\n\t\t\t\tfieldSlots.input = inputElem\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<div class={`ex-field`}>\n\t\t\t\t\t<Field\n\t\t\t\t\t\tv-model={state.value}\n\t\t\t\t\t\ttype={props.type}\n\t\t\t\t\t\tname={props.name}\n\t\t\t\t\t\tplaceholder={props.placeholder}\n\t\t\t\t\t\treadonly={isReadonly.value}\n\t\t\t\t\t\tdisabled={props.disabled}\n\t\t\t\t\t\trequired={props.required}\n\t\t\t\t\t\tisLink={isLink.value}\n\t\t\t\t\t\trules={props.rules}\n\t\t\t\t\t\tonClickInput={() => emit(\"click\")}\n\t\t\t\t\t\tonUpdate:modelValue={onUpdateValue}\n\t\t\t\t\t\t{...props.fieldProps}\n\t\t\t\t\t\tshowWordLimit={isReadonly.value ? false : props.fieldProps?.showWordLimit}\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ ...fieldSlots }}\n\t\t\t\t\t</Field>\n\t\t\t\t\t{appendElem()}\n\t\t\t\t</div>\n\t\t\t)\n\t\t}\n\t},\n})\n","import { defineComponent, ref } from \"vue\"\nimport { Popup } from \"vant\"\nimport ExField from \"./ExField.jsx\"\nimport { omit, pick } from \"lodash-es\"\nimport { defaultFieldProps } from \"../utils\"\n\nexport default defineComponent({\n\tname: \"PickerWrapper\",\n\n\tprops: {\n\t\t/**\n\t\t * Picker 标题\n\t\t */\n\t\ttitle: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 是否启用卡片模式\n\t\t */\n\t\tinset: { type: Boolean, default: false },\n\n\t\t/**\n\t\t * 是否会弹窗\n\t\t */\n\t\tdisabled: { type: Boolean, default: false },\n\n\t\t/**\n\t\t * 是否显示关闭\n\t\t */\n\t\tcloseable: { type: Boolean, default: true },\n\t},\n\temits: [\"close\", \"open\"],\n\tsetup: (props, { emit, slots, expose }) => {\n\t\tconst showPopup = ref(false)\n\n\t\tconst onClickWrapper = () => {\n\t\t\tif (props.disabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tshowPopup.value = true\n\t\t\temit(\"open\")\n\t\t}\n\n\t\tconst close = () => {\n\t\t\tshowPopup.value = false\n\t\t\temit(\"close\")\n\t\t}\n\n\t\texpose({ close })\n\n\t\treturn () => {\n\t\t\t// 为了让 ExField 的 onClickInput 事件才触发 Popup\n\t\t\t// 所以会手动获取 trigger slot 的第一个组件来手动监听 onClick 事件\n\t\t\t// 如果以后有需要多个组件的情况,再做调整\n\n\t\t\tlet TriggerElem = slots.trigger ? slots.trigger() : null\n\n\t\t\tif (TriggerElem && TriggerElem.length) {\n\t\t\t\tTriggerElem = TriggerElem[0]\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t<span class={\"ex-field-popup-wrapper\"}>\n\t\t\t\t\t<TriggerElem onClick={onClickWrapper}></TriggerElem>\n\t\t\t\t</span>,\n\n\t\t\t\t<Popup\n\t\t\t\t\tv-model:show={showPopup.value}\n\t\t\t\t\tcloseable={props.closeable}\n\t\t\t\t\tposition={\"bottom\"}\n\t\t\t\t\tround={true}\n\t\t\t\t\tteleport={\"body\"}\n\t\t\t\t\tcloseOnPopstate={true}\n\t\t\t\t\tclass={`ex-field-popup ${props.inset ? \"ex-field-popup-inset\" : \"\"}`}\n\t\t\t\t\tsafeAreaInsetBottom={true}\n\t\t\t\t\tsafeAreaInsetTop={true}\n\t\t\t\t\tonClickOverlay={close}\n\t\t\t\t\tonClickCloseIcon={close}\n\t\t\t\t>\n\t\t\t\t\t{{\n\t\t\t\t\t\tdefault: () => [\n\t\t\t\t\t\t\tprops.closeable ? (\n\t\t\t\t\t\t\t\t<div class={\"ex-field-popup__header\"}>\n\t\t\t\t\t\t\t\t\t<h2 class={\"ex-field-popup__title\"}>{props.title}</h2>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null,\n\t\t\t\t\t\t\tslots.default?.(),\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t</Popup>,\n\t\t\t]\n\t\t}\n\t},\n})\n\nexport const pickerProps = (props) => {\n\treturn {\n\t\ttitle: props.title || `请选择${props.label}`,\n\t\tdisabled: props.readonly || props.disabled,\n\t}\n}\n\nexport const pickerSlots = (slots, props) => {\n\tlet triggerElem = slots.default ? slots.default() : null\n\n\tif (!triggerElem) {\n\t\tconst fieldProps = pick(props, Object.keys(defaultFieldProps))\n\t\t// default slot 是 trigger, 其它的 slots 全部传给 ExField\n\t\tconst fieldSlots = omit(slots, \"default\")\n\n\t\ttriggerElem = (\n\t\t\t<ExField {...fieldProps} mask={true}>\n\t\t\t\t{fieldSlots}\n\t\t\t</ExField>\n\t\t)\n\t}\n\n\treturn {\n\t\ttrigger: () => triggerElem,\n\t}\n}\n","import { defineComponent, provide } from \"vue\"\n\nexport const EX_UPLOADER = Symbol(\"EX_UPLOADER\")\nexport const EX_ADDRESS = Symbol(\"EX_ADDRESS\")\nexport const EX_FORM = Symbol(\"EX_FORM\")\nexport const EX_SEARCH = Symbol(\"EX_SEARCH\")\nexport const EX_PAGINATION = Symbol(\"EX_PAGINATION\")\n\n/**\n * Explore 配置组件\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExProvider\",\n\t/**\n\t * @typedef {Object} ProviderProps\n\t * @property {UploaderProviderProps} [uploader] `ExUploader` 配置\n\t * @property {AddressProviderProps} [address] `ExAddress` 配置\n\t * @property {FormProviderProps} [form] `ExForm` 配置\n\t * @property {SearchProviderProps} [search] `ExSearch` 配置\n\t * @property {PaginationProviderProps} [pagination] `ExPagination` 配置\n\t *\n\t */\n\tprops: {\n\t\t/**\n\t\t * @typedef {Object} UploaderProviderProps `ExUploader` 配置\n\t\t * @property {string} uploadUrl 上传地址\n\t\t * @property {UploadFileItem} defaultFileItem 默认文件项\n\t\t *\n\t\t * @typedef {Object} UploadFileItem 文件项\n\t\t * @property {string} [id] 文件 ID\n\t\t * @property {string} [name] 文件名\n\t\t * @property {string} defaultFileItem.url 文件地址\n\t\t * @property {string} defaultFileItem.path 文件路径\n\t\t * @property {string} [thumbUrl] 缩略图地址\n\t\t */\n\t\tuploader: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tuploadUrl: \"\",\n\t\t\t\tdefaultFileItem: {\n\t\t\t\t\tid: \"id\",\n\t\t\t\t\tname: \"name\",\n\t\t\t\t\turl: \"url\",\n\t\t\t\t\tpath: \"path\",\n\t\t\t\t\tthumbUrl: \"thumbUrl\",\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\n\t\t/**\n\t\t * @typedef {Object} AddressProviderProps `ExAddress` 配置\n\t\t * @property {string} addressUrl 选项请求地址\n\t\t * @property {string} displayTextType 显示值的类型。\"all\": 所有, last:最后选中的值\n\t\t * @property {Function} [afterFetched] 处理接口返回数据的函数\n\t\t * @property {AddressOptionKeys} optionKeys 地址选项键名\n\t\t *\n\t\t * @typedef {Object} AddressOptionKeys 地址选项键名\n\t\t * @property {string} optionKeys.value 选项对应的值\n\t\t * @property {string} optionKeys.text 选项文字\n\t\t * @property {string} optionKeys.children 子选项列表\n\t\t */\n\t\taddress: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\taddressUrl: \"\",\n\t\t\t\tdisplayTextType: \"\",\n\t\t\t\tafterFetched: null,\n\t\t\t\toptionKeys: {\n\t\t\t\t\tvalue: \"code\",\n\t\t\t\t\ttext: \"name\",\n\t\t\t\t\tchildren: \"children\",\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\n\t\t/**\n\t\t * @typedef {Object} FormProviderProps `ExForm` 配置\n\t\t * @property {Object} [format] 格式化配置, 如 {date: true} 表示在提交表单时使用 `useFormFormat` 格式所有日期字段\n\t\t * @property {Function} [afterFetched] 处理接口返回数据的函数\n\t\t */\n\t\tform: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tformat: {},\n\t\t\t\tafterFetched: null,\n\t\t\t}),\n\t\t},\n\n\t\t/**\n\t\t * @typedef {Object} SearchProviderProps `ExSearch` 配置\n\t\t * @property {Object} [maskClass] 定制伪 Input 样式\n\t\t * @property {Object} [inputClass] 弹层中 Input 的样式\n\t\t */\n\t\tsearch: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tmaskClass: \"\",\n\t\t\t\tinputClass: \"\",\n\t\t\t}),\n\t\t},\n\n\t\t/**\n\t\t * @typedef {Object} PaginationRes\n\t\t * @property {Array} items 数据\n\t\t * @property {number} currentPage 当前页码\n\t\t * @property {number} totalSize 总条数\n\t\t * @property {String} [errorMessage] 错误信息\n\t\t */\n\n\t\t/**\n * @typedef {Object} PaginationProviderProps `ExPagination` 配置\n * @property {function():PaginationRes} [afterFetched] 处理接口返回数据的函数\n * @property {PaginationRequestKeys} [requestKeys] 请求参数键名\n * /\n\n /**\n * @typedef {Object} PaginationRequestKeys 请求参数键名\n * @property {string} [currentPage] 当前页码\n * @property {string} [pageSize] 每页条数\n */\n\t\tpagination: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tafterFetched: null,\n\t\t\t\trequestKeys: {\n\t\t\t\t\tcurrentPage: \"currentPage\",\n\t\t\t\t\tpageSize: \"pageSize\",\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\tprovide(EX_UPLOADER, {\n\t\t\tuploadUrl: props.uploader?.uploadUrl || \"\",\n\t\t\tdefaultFileItem: {\n\t\t\t\tid: \"id\",\n\t\t\t\tname: \"name\",\n\t\t\t\turl: \"url\",\n\t\t\t\tpath: \"path\",\n\t\t\t\tthumbUrl: \"thumbUrl\",\n\t\t\t\t...props.uploader?.defaultFileItem,\n\t\t\t},\n\t\t})\n\t\tprovide(EX_ADDRESS, {\n\t\t\taddressUrl: props.address?.addressUrl || \"\",\n\t\t\tdisplayTextType: props.address?.displayTextType || \"\",\n\t\t\tafterFetched: props.address?.afterFetched,\n\t\t\toptionKeys: {\n\t\t\t\tvalue: \"code\",\n\t\t\t\ttext: \"name\",\n\t\t\t\tchildren: \"children\",\n\t\t\t\t...props.address?.optionKeys,\n\t\t\t},\n\t\t})\n\t\tprovide(EX_FORM, { format: {}, ...props.form })\n\t\tprovide(EX_SEARCH, {\n\t\t\tmaskClass: \"\",\n\t\t\tinputClass: \"\",\n\t\t\t...props.search,\n\t\t})\n\t\tprovide(EX_PAGINATION, {\n\t\t\tafterFetched: props.pagination?.afterFetched,\n\t\t\trequestKeys: {\n\t\t\t\tcurrentPage: \"currentPage\",\n\t\t\t\tpageSize: \"pageSize\",\n\t\t\t\t...props.pagination?.requestKeys,\n\t\t\t},\n\t\t})\n\n\t\treturn () => <div>{slots.default?.()}</div>\n\t},\n})\n","import { computed, defineComponent, inject, ref, watch } from \"vue\"\nimport { Cascader } from \"vant\"\nimport localData from \"./addressData.json\"\nimport PickerWrapper, { pickerProps, pickerSlots } from \"./PickerWrapper.jsx\"\nimport { defaultFieldProps, defaultOptionsProps, useOptionTrait } from \"../utils\"\nimport { cloneDeep, isArray, last } from \"lodash-es\"\nimport { useFindTextsFromPath } from \"../../hooks\"\nimport { EX_ADDRESS } from \"../provider/ExProvider.jsx\"\n\n/**\n * 地址组件\n *\n * 数据优先级:`dataSource` > `url` > `本地数据`\n *\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExAddress\",\n\tprops: {\n\t\t...defaultOptionsProps,\n\t\t...defaultFieldProps,\n\n\t\tmodelValue: { type: [String, Number, Array], default: () => [] },\n\n\t\t/**\n\t\t * 标题\n\t\t */\n\t\ttitle: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 生成哪个级别的数据\n\t\t * 1: 省, 2: 省市, 3: 省市区\n\t\t */\n\t\tlevel: { type: Number, default: 3 },\n\n\t\t/**\n\t\t * 显示值的类型\n\t\t * 空值或all: 所有, last:最后\n\t\t */\n\t\tdisplayTextType: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 是否把选项的值返回到modelValue\n\t\t */\n\t\ttextInValue: { type: Boolean, default: false },\n\t},\n\temits: [\"update:modelValue\"],\n\tsetup(props, { emit, slots, expose }) {\n\t\tconst addressProvider = inject(EX_ADDRESS, () => ({}))\n\t\tconst defaultAddressUrl = addressProvider.addressUrl || \"\"\n\t\tconst defaultDisplayTextType = addressProvider.displayTextType || \"\"\n\t\tconst defaultAfterFetched = addressProvider.afterFetched || \"\"\n\t\tconst optionKeys = addressProvider.optionKeys || {}\n\n\t\tconst { text: textKey, value: valueKey, children: childrenKey } = optionKeys\n\n\t\tconst componentValue = ref(\"\")\n\n\t\tconst setModelValue = () => {\n\t\t\tlet value = isArray(props.modelValue) ? last(props.modelValue) : props.modelValue\n\t\t\tif (props.textInValue && value) {\n\t\t\t\tvalue = value[valueKey]\n\t\t\t}\n\t\t\tcomponentValue.value = value\n\t\t}\n\t\tsetModelValue()\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => setModelValue(),\n\t\t)\n\n\t\tconst pickerRef = ref(null)\n\t\tconst options = ref([])\n\n\t\tconst displayText = computed(() => {\n\t\t\tif (props.modelValue.length === 0) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\tconst displayTextType = props.displayTextType || defaultDisplayTextType\n\n\t\t\t//textInValue状态下的初始值\n\t\t\tif (props.textInValue && props.modelValue && props.modelValue.length === 1) {\n\t\t\t\treturn last(props.modelValue)[textKey]\n\t\t\t}\n\n\t\t\t//反向赋值\n\t\t\tconst mValue = props.textInValue ? props.modelValue.map((item) => item[valueKey]) : props.modelValue\n\t\t\tconst optionsTexts = useFindTextsFromPath(options.value, mValue, {\n\t\t\t\tvalue: valueKey,\n\t\t\t\tchildren: childrenKey,\n\t\t\t\tlabel: textKey,\n\t\t\t})\n\n\t\t\treturn displayTextType === \"last\" ? last(optionsTexts) : optionsTexts.join(\"/\")\n\t\t})\n\n\t\t//把默认值赋值给props\n\t\tconst cloneProps = cloneDeep(props)\n\t\tif (!cloneProps.url && defaultAddressUrl) {\n\t\t\tcloneProps.url = defaultAddressUrl\n\t\t}\n\t\tif (!cloneProps.afterFetched && defaultAfterFetched) {\n\t\t\tcloneProps.afterFetched = defaultAfterFetched\n\t\t}\n\t\t//先处理好 options\n\t\tconst dealOptions = () => {\n\t\t\tuseOptionTrait(options, cloneProps, localData)\n\t\t}\n\t\tdealOptions()\n\n\t\twatch(\n\t\t\t() => props.options,\n\t\t\t() => {\n\t\t\t\tdealOptions()\n\t\t\t},\n\t\t)\n\n\t\tconst onFinish = ({ selectedOptions }) => {\n\t\t\tpickerRef.value.close()\n\t\t\temit(\"update:modelValue\", props.textInValue ? selectedOptions : selectedOptions.map((item) => item[valueKey]))\n\t\t}\n\n\t\texpose({ displayText })\n\n\t\t/********** render **********/\n\n\t\treturn () => (\n\t\t\t<PickerWrapper ref={pickerRef} {...pickerProps(props)}>\n\t\t\t\t{{\n\t\t\t\t\t...pickerSlots(slots, props),\n\t\t\t\t\tdefault: () => (\n\t\t\t\t\t\t<Cascader\n\t\t\t\t\t\t\tv-model={componentValue.value}\n\t\t\t\t\t\t\tfieldNames={{ text: textKey, value: valueKey, children: childrenKey }}\n\t\t\t\t\t\t\tcloseable={false}\n\t\t\t\t\t\t\tshowHeader={false}\n\t\t\t\t\t\t\toptions={options.value}\n\t\t\t\t\t\t\tonFinish={onFinish}\n\t\t\t\t\t\t\t{...props.defaultProps}\n\t\t\t\t\t\t/>\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t</PickerWrapper>\n\t\t)\n\t},\n})\n\n/**\n *\n * 根据地址编码获取完整的地址编码\n *\n * @param code\n * @param {number} [level] 地址级别: 1: 省, 2: 省市, 3: 省市区\n * @return {string[]|(string|*)[]|*[]}\n */\nexport function useAddressFullCode(code, level) {\n\tcode += \"\"\n\tif (code && code.length === 6) {\n\t\tif (!level) {\n\t\t\tif (/0000$/.test(code)) {\n\t\t\t\tlevel = 1\n\t\t\t} else if (/00$/.test(code)) {\n\t\t\t\tlevel = 2\n\t\t\t} else {\n\t\t\t\tlevel = 3\n\t\t\t}\n\t\t}\n\t\tif (level === 1) {\n\t\t\treturn [`${code.substr(0, 2)}0000`]\n\t\t}\n\t\tif (level === 2) {\n\t\t\treturn [`${code.substr(0, 2)}0000`, `${code.substr(0, 4)}00`]\n\t\t}\n\t\tif (level === 3) {\n\t\t\treturn [`${code.substr(0, 2)}0000`, `${code.substr(0, 4)}00`, code]\n\t\t}\n\t}\n\treturn []\n}\n\n/**\n * 根据地址编码获取完整的地址名称\n * @param code\n * @param {number} [level] 地址级别: 1: 省, 2: 省市, 3: 省市区\n * @return {*[]}\n */\nexport function useAddressNameFormCode(code, level) {\n\tif (!isArray(code)) {\n\t\tcode = useAddressFullCode(code, level)\n\t}\n\treturn useFindTextsFromPath(localData, code, { value: \"code\", label: \"name\", children: \"children\" })\n}\n\nexport const addressData = localData\n","import { computed, defineComponent, ref, watch } from \"vue\"\nimport PickerWrapper, { pickerProps, pickerSlots } from \"./PickerWrapper.jsx\"\nimport { Button, Cascader, Search } from \"vant\"\nimport { defaultFieldProps, defaultOptionsProps, useOptionTrait } from \"../utils\"\nimport { useFindParentLabels } from \"../../hooks\"\nimport { cloneDeep, isArray, last } from \"lodash-es\"\n\n/**\n * ExCascader 级联选择\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExCascader\",\n\tprops: {\n\t\t...defaultOptionsProps,\n\t\t...defaultFieldProps,\n\n\t\tmodelValue: { type: [Array, String], default: () => [] },\n\n\t\t/**\n\t\t * 标题\n\t\t */\n\t\ttitle: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 是否显示清除按钮\n\t\t */\n\t\tclearable: { type: Boolean, default: false },\n\n\t\t/**\n\t\t * 显示值的类型\n\t\t * 空值或all: 所有, last:最后\n\t\t */\n\t\tdisplayTextType: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 是否把选项的值返回到modelValue\n\t\t */\n\t\ttextInValue: { type: Boolean, default: false },\n\t},\n\temits: [\"update:modelValue\", \"change\"],\n\tsetup(props, { emit, slots, expose }) {\n\t\tconst componentValue = ref(\"\")\n\n\t\tconst setModelValue = () => {\n\t\t\tlet value = isArray(props.modelValue) ? last(props.modelValue) : props.modelValue\n\t\t\tif (props.textInValue && value) {\n\t\t\t\tvalue = value.value\n\t\t\t}\n\t\t\tcomponentValue.value = value\n\t\t}\n\t\tsetModelValue()\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => setModelValue(),\n\t\t)\n\n\t\tconst pickerRef = ref(null)\n\n\t\tconst options = ref([]) //整理后的原始 Options\n\t\tconst shownOptions = ref([]) //根据 keyword 过滤后的 Options\n\t\tconst keyword = ref(\"\")\n\n\t\t//先处理好 options\n\t\tconst dealOptions = () => {\n\t\t\tuseOptionTrait(options, props)\n\t\t\tshownOptions.value = options.value\n\t\t}\n\t\tdealOptions()\n\n\t\twatch(\n\t\t\t() => props.options,\n\t\t\t() => {\n\t\t\t\tdealOptions()\n\t\t\t},\n\t\t)\n\n\t\twatch(\n\t\t\t() => keyword.value,\n\t\t\t(keyword) => {\n\t\t\t\tcomponentValue.value = \"\"\n\t\t\t\tif (keyword) {\n\t\t\t\t\tshownOptions.value = filterByText(cloneDeep(options.value), keyword)\n\t\t\t\t} else {\n\t\t\t\t\tshownOptions.value = options.value\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\n\t\tconst filterByText = (data, keyword) => {\n\t\t\t// 递归函数,用于过滤每一层级的数据\n\t\t\tfunction filterRecursively(items) {\n\t\t\t\treturn items.filter((item) => {\n\t\t\t\t\t// 判断是否包含关键字\n\t\t\t\t\tlet hasKeyword = item.text.toLowerCase().includes(keyword.toLowerCase())\n\t\t\t\t\tif (item.children && item.children.length) {\n\t\t\t\t\t\titem.children = filterRecursively(item.children)\n\t\t\t\t\t\tif (item.children.length) {\n\t\t\t\t\t\t\thasKeyword = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 如果包含关键字,或者有子级包含关键字,则保留该项\n\t\t\t\t\treturn hasKeyword\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// 调用递归函数开始过滤\n\t\t\treturn filterRecursively(data)\n\t\t}\n\n\t\tconst displayText = computed(() => {\n\t\t\tif (!componentValue.value) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\n\t\t\tconst labels = useFindParentLabels(options.value, componentValue.value, props.defaultProps?.fieldNames)\n\n\t\t\treturn labels ? (props.displayTextType === \"last\" ? last(labels) : labels.join(\"/\")) : \"\"\n\t\t})\n\n\t\tconst onFinish = ({ selectedOptions }) => {\n\t\t\tconst value = props.textInValue ? selectedOptions : selectedOptions.map((item) => item.value)\n\t\t\temit(\"change\", value)\n\t\t\temit(\"update:modelValue\", value)\n\t\t\tpickerRef.value.close()\n\t\t}\n\n\t\tconst onClear = () => {\n\t\t\temit(\"change\", [])\n\t\t\temit(\"update:modelValue\", [])\n\t\t\tpickerRef.value.close()\n\t\t}\n\n\t\texpose({ displayText })\n\n\t\treturn () => (\n\t\t\t<PickerWrapper ref={pickerRef} {...pickerProps(props)}>\n\t\t\t\t{{\n\t\t\t\t\t...pickerSlots(slots, props),\n\t\t\t\t\tdefault: () => [\n\t\t\t\t\t\t<Cascader\n\t\t\t\t\t\t\tclass={\"ex-cascader\"}\n\t\t\t\t\t\t\tv-model={componentValue.value}\n\t\t\t\t\t\t\tcloseable={false}\n\t\t\t\t\t\t\tshowHeader={true}\n\t\t\t\t\t\t\toptions={shownOptions.value}\n\t\t\t\t\t\t\tonFinish={onFinish}\n\t\t\t\t\t\t\t{...props.defaultProps}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{\n\t\t\t\t\t\t\t\ttitle: () => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<Search shape={\"round\"} placeholder={\"选项搜索\"} v-model={keyword.value} style={{ width: \"100%\" }}></Search>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t</Cascader>,\n\t\t\t\t\t\tprops.clearable ? (\n\t\t\t\t\t\t\t<div class={\"ex-field-popup__clear-btn\"}>\n\t\t\t\t\t\t\t\t<Button block type={\"primary\"} plain={true} round={true} onClick={onClear}>\n\t\t\t\t\t\t\t\t\t清除\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null,\n\t\t\t\t\t],\n\t\t\t\t}}\n\t\t\t</PickerWrapper>\n\t\t)\n\t},\n})\n","import { defineComponent, ref, watch } from \"vue\"\nimport { defaultFieldProps, defaultOptionsProps, useOptionTrait } from \"../utils\"\nimport { Checkbox, CheckboxGroup } from \"vant\"\nimport ExField from \"./ExField.jsx\"\nimport { pick } from \"lodash-es\"\n\n/**\n * ExCheckbox 多选\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExCheckbox\",\n\tprops: {\n\t\t...defaultFieldProps,\n\t\t...defaultOptionsProps,\n\n\t\tmodelValue: { type: Array, default: () => [] },\n\t},\n\temits: [\"update:modelValue\"],\n\tsetup(props, { emit, slots }) {\n\t\tconst componentValue = ref(props.modelValue)\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => (componentValue.value = props.modelValue),\n\t\t)\n\n\t\tconst options = ref([])\n\n\t\tuseOptionTrait(options, props)\n\n\t\tconst onChange = (value) => {\n\t\t\temit(\"update:modelValue\", value)\n\t\t}\n\n\t\tconst fieldProps = pick(props, Object.keys(defaultFieldProps))\n\n\t\treturn () => (\n\t\t\t<ExField {...fieldProps}>\n\t\t\t\t{{\n\t\t\t\t\t...slots,\n\t\t\t\t\tinput: () => (\n\t\t\t\t\t\t<CheckboxGroup\n\t\t\t\t\t\t\tv-model={componentValue.value}\n\t\t\t\t\t\t\tdisabled={props.disabled || props.readonly}\n\t\t\t\t\t\t\t{...props.defaultProps}\n\t\t\t\t\t\t\tonChange={onChange}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{\n\t\t\t\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\t\t\t\toptions.value.map((option) => <Checkbox name={option.value}>{{ default: () => option.text }}</Checkbox>),\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t</CheckboxGroup>\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t</ExField>\n\t\t)\n\t},\n})\n","import { inBrowser } from \"./basic.mjs\";\nimport { windowWidth, windowHeight } from \"./dom.mjs\";\nimport { isDef, isNumeric } from \"./basic.mjs\";\nfunction addUnit(value) {\n if (isDef(value)) {\n return isNumeric(value) ? `${value}px` : String(value);\n }\n return void 0;\n}\nfunction getSizeStyle(originSize) {\n if (isDef(originSize)) {\n if (Array.isArray(originSize)) {\n return {\n width: addUnit(originSize[0]),\n height: addUnit(originSize[1])\n };\n }\n const size = addUnit(originSize);\n return {\n width: size,\n height: size\n };\n }\n}\nfunction getZIndexStyle(zIndex) {\n const style = {};\n if (zIndex !== void 0) {\n style.zIndex = +zIndex;\n }\n return style;\n}\nlet rootFontSize;\nfunction getRootFontSize() {\n if (!rootFontSize) {\n const doc = document.documentElement;\n const fontSize = doc.style.fontSize || window.getComputedStyle(doc).fontSize;\n rootFontSize = parseFloat(fontSize);\n }\n return rootFontSize;\n}\nfunction convertRem(value) {\n value = value.replace(/rem/g, \"\");\n return +value * getRootFontSize();\n}\nfunction convertVw(value) {\n value = value.replace(/vw/g, \"\");\n return +value * windowWidth.value / 100;\n}\nfunction convertVh(value) {\n value = value.replace(/vh/g, \"\");\n return +value * windowHeight.value / 100;\n}\nfunction unitToPx(value) {\n if (typeof value === \"number\") {\n return value;\n }\n if (inBrowser) {\n if (value.includes(\"rem\")) {\n return convertRem(value);\n }\n if (value.includes(\"vw\")) {\n return convertVw(value);\n }\n if (value.includes(\"vh\")) {\n return convertVh(value);\n }\n }\n return parseFloat(value);\n}\nconst camelizeRE = /-(\\w)/g;\nconst camelize = (str) => str.replace(camelizeRE, (_, c) => c.toUpperCase());\nconst kebabCase = (str) => str.replace(/([A-Z])/g, \"-$1\").toLowerCase().replace(/^-/, \"\");\nfunction padZero(num, targetLength = 2) {\n let str = num + \"\";\n while (str.length < targetLength) {\n str = \"0\" + str;\n }\n return str;\n}\nconst clamp = (num, min, max) => Math.min(Math.max(num, min), max);\nfunction trimExtraChar(value, char, regExp) {\n const index = value.indexOf(char);\n if (index === -1) {\n return value;\n }\n if (char === \"-\" && index !== 0) {\n return value.slice(0, index);\n }\n return value.slice(0, index + 1) + value.slice(index).replace(regExp, \"\");\n}\nfunction formatNumber(value, allowDot = true, allowMinus = true) {\n if (allowDot) {\n value = trimExtraChar(value, \".\", /\\./g);\n } else {\n value = value.split(\".\")[0];\n }\n if (allowMinus) {\n value = trimExtraChar(value, \"-\", /-/g);\n } else {\n value = value.replace(/-/, \"\");\n }\n const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;\n return value.replace(regExp, \"\");\n}\nfunction addNumber(num1, num2) {\n const cardinal = 10 ** 10;\n return Math.round((num1 + num2) * cardinal) / cardinal;\n}\nexport {\n addNumber,\n addUnit,\n camelize,\n clamp,\n formatNumber,\n getSizeStyle,\n getZIndexStyle,\n kebabCase,\n padZero,\n unitToPx\n};\n","import { computed, defineComponent, ref, watch } from \"vue\"\nimport PickerWrapper, { pickerSlots } from \"./PickerWrapper.jsx\"\nimport { DatePicker } from \"vant\"\nimport { padZero } from \"vant/es/utils\"\nimport { defaultFieldProps } from \"../utils\"\nimport { isUndefined } from \"lodash-es\"\nimport { isDayjs } from \"dayjs\"\n\n/**\n * ExDate 日期选择\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExDate\",\n\tprops: {\n\t\t...defaultFieldProps,\n\n\t\tmodelValue: { type: [Date, String, Object], default: () => null },\n\n\t\t/**\n\t\t * 标题\n\t\t */\n\t\ttitle: { type: String, default: \"选择日期\" },\n\t},\n\temits: [\"update:modelValue\"],\n\tsetup(props, { emit, slots, expose }) {\n\t\tconst columnsType = props.defaultProps?.columnsType || [\"year\", \"month\", \"day\"]\n\n\t\tconst getYear = (value) => {\n\t\t\treturn isDayjs(value) ? value.year() : value.getFullYear()\n\t\t}\n\t\tconst getMonth = (value) => {\n\t\t\treturn isDayjs(value) ? value.month() + 1 : value.getMonth() + 1\n\t\t}\n\t\tconst getDate = (value) => {\n\t\t\treturn isDayjs(value) ? value.date() : value.getDate()\n\t\t}\n\n\t\tconst _setValueByColumns = (columnsType, value, date) => {\n\t\t\tcolumnsType.forEach((column) => {\n\t\t\t\tif (column === \"year\") {\n\t\t\t\t\tvalue.push(getYear(date))\n\t\t\t\t} else if (column === \"month\") {\n\t\t\t\t\tvalue.push(getMonth(date))\n\t\t\t\t} else if (column === \"day\") {\n\t\t\t\t\tvalue.push(getDate(date))\n\t\t\t\t}\n\t\t\t})\n\t\t\treturn value\n\t\t}\n\t\tconst prepareDate = (date) => {\n\t\t\tconst value = []\n\n\t\t\tif (!date) {\n\t\t\t\treturn value\n\t\t\t}\n\n\t\t\treturn _setValueByColumns(columnsType, value, date)\n\t\t}\n\n\t\tlet defaultValue = prepareDate(props.modelValue)\n\n\t\tif (!defaultValue.length) {\n\t\t\tconst now = new Date()\n\t\t\tdefaultValue = _setValueByColumns(columnsType, defaultValue, now)\n\t\t}\n\n\t\tconst componentValue = ref(defaultValue)\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => {\n\t\t\t\tcomponentValue.value = prepareDate(props.modelValue)\n\t\t\t},\n\t\t)\n\n\t\tconst pickerRef = ref(null)\n\n\t\tconst displayText = computed(() => {\n\t\t\tif (props.modelValue) {\n\t\t\t\tlet text = \"\"\n\t\t\t\tcolumnsType.forEach((column) => {\n\t\t\t\t\tif (column === \"year\") {\n\t\t\t\t\t\ttext += getYear(props.modelValue)\n\t\t\t\t\t} else if (column === \"month\") {\n\t\t\t\t\t\tif (text) {\n\t\t\t\t\t\t\ttext += \"/\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttext += padZero(getMonth(props.modelValue), 2)\n\t\t\t\t\t} else if (column === \"day\") {\n\t\t\t\t\t\tif (text) {\n\t\t\t\t\t\t\ttext += \"/\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttext += padZero(getDate(props.modelValue), 2)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\treturn text\n\t\t\t}\n\n\t\t\treturn \"\"\n\t\t})\n\n\t\texpose({ displayText })\n\n\t\tconst onConfirm = ({ selectedValues }) => {\n\t\t\tpickerRef.value.close()\n\n\t\t\tconst now = new Date()\n\t\t\tlet date = {}\n\t\t\tcolumnsType.forEach((column, index) => {\n\t\t\t\tif (column === \"year\") {\n\t\t\t\t\tdate.year = selectedValues[index]\n\t\t\t\t} else if (column === \"month\") {\n\t\t\t\t\tdate.month = selectedValues[index] - 1\n\t\t\t\t} else if (column === \"day\") {\n\t\t\t\t\tdate.date = selectedValues[index]\n\t\t\t\t}\n\t\t\t})\n\n\t\t\temit(\n\t\t\t\t\"update:modelValue\",\n\t\t\t\tnew Date(date.year || now.getFullYear(), isUndefined(date.month) ? now.getMonth() : date.month, date.date || now.getDate()),\n\t\t\t)\n\t\t}\n\n\t\treturn () => (\n\t\t\t<PickerWrapper ref={pickerRef} closeable={false} disabled={props.disabled || props.readonly}>\n\t\t\t\t{{\n\t\t\t\t\t...pickerSlots(slots, props),\n\t\t\t\t\tdefault: () => (\n\t\t\t\t\t\t<DatePicker\n\t\t\t\t\t\t\tv-model={componentValue.value}\n\t\t\t\t\t\t\tonConfirm={onConfirm}\n\t\t\t\t\t\t\tonCancel={() => pickerRef.value.close()}\n\t\t\t\t\t\t\ttitle={props.title}\n\t\t\t\t\t\t\t{...props.defaultProps}\n\t\t\t\t\t\t/>\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t</PickerWrapper>\n\t\t)\n\t},\n})\n","import PickerWrapper, { pickerSlots } from \"./PickerWrapper.jsx\"\nimport { ref, defineComponent, computed, watch } from \"vue\"\nimport { Calendar, Collapse, CollapseItem, TimePicker } from \"vant\"\nimport ExButton from \"../button/ExButton.jsx\"\nimport { padZero } from \"vant/es/utils\"\nimport { defaultFieldProps } from \"../utils\"\nimport { cloneDeep } from \"lodash-es\"\n\n/**\n * ExDatetime 日期时间选择器\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExDatetime\",\n\tprops: {\n\t\t...defaultFieldProps,\n\n\t\tmodelValue: { type: Date, default: () => null },\n\t},\n\temits: [\"update:modelValue\"],\n\tsetup(props, { slots, emit, expose }) {\n\t\tconst dateValue = ref(null)\n\t\tconst timeValue = ref(null)\n\t\tconst displayText = ref(null)\n\t\tconst pickerRef = ref()\n\n\t\tconst activeName = ref(\"date\")\n\n\t\tconst minDate = new Date(2010, 0, 1)\n\t\tconst maxDate = new Date(2045, 11, 31)\n\n\t\tconst weekdays = [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\"]\n\n\t\tconst dateText = computed(() => {\n\t\t\tif (dateValue.value) {\n\t\t\t\treturn `${dateValue.value.getFullYear()}/${dateValue.value.getMonth() + 1}/${dateValue.value.getDate()} 星期${\n\t\t\t\t\tweekdays[dateValue.value.getDay()]\n\t\t\t\t}`\n\t\t\t}\n\t\t\treturn \"请选择日期\"\n\t\t})\n\t\tconst timeText = computed(() => {\n\t\t\tif (timeValue.value) {\n\t\t\t\treturn timeValue.value\n\t\t\t}\n\t\t\treturn \"请选择时间\"\n\t\t})\n\t\tconst timeModel = computed(() => {\n\t\t\tif (timeValue.value) {\n\t\t\t\tconst [hours, minutes] = timeValue.value.split(\":\")\n\t\t\t\treturn [hours, minutes]\n\t\t\t}\n\t\t\treturn []\n\t\t})\n\n\t\tconst defaultDate = ref(props.modelValue || new Date())\n\n\t\tconst setDisplayText = () => {\n\t\t\tdisplayText.value = dateValue.value && timeValue.value ? `${dateText.value} ${timeText.value}` : \"\"\n\t\t}\n\t\t/**\n\t\t *\n\t\t * @param {Date|null} date\n\t\t */\n\t\tconst prepareDate = (date) => {\n\t\t\tif (date) {\n\t\t\t\tdateValue.value = cloneDeep(date)\n\t\t\t\ttimeValue.value = `${padZero(date.getHours(), 2)}:${padZero(date.getMinutes(), 2)}`\n\t\t\t}\n\t\t\tsetDisplayText()\n\t\t}\n\n\t\tprepareDate(props.modelValue)\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => prepareDate(props.modelValue),\n\t\t)\n\n\t\texpose({ displayText })\n\n\t\tconst onSelectDate = (date) => {\n\t\t\tdateValue.value = date\n\t\t}\n\n\t\tconst onTimeChange = ({ selectedValues }) => {\n\t\t\ttimeValue.value = selectedValues.join(\":\")\n\t\t}\n\n\t\tconst onConfirm = () => {\n\t\t\tif (!dateValue.value) {\n\t\t\t\tdateValue.value = new Date()\n\t\t\t}\n\t\t\tlet dateString = `${dateValue.value.getFullYear()}/${dateValue.value.getMonth() + 1}/${dateValue.value.getDate()}`\n\n\t\t\tif (!timeValue.value) {\n\t\t\t\tdateString += ` 00:00:00`\n\t\t\t} else {\n\t\t\t\tdateString += ` ${timeValue.value}`\n\t\t\t}\n\n\t\t\tpickerRef.value.close()\n\t\t\tsetDisplayText()\n\n\t\t\temit(\"update:modelValue\", new Date(dateString))\n\t\t}\n\n\t\treturn () => {\n\t\t\treturn (\n\t\t\t\t<PickerWrapper ref={pickerRef} inset={true} disabled={props.disabled || props.readonly}>\n\t\t\t\t\t{{\n\t\t\t\t\t\t...pickerSlots(slots, props),\n\t\t\t\t\t\tdefault: () => [\n\t\t\t\t\t\t\t<Collapse accordion={true} v-model={activeName.value} border={false} class={\"ex-datetime_collapse\"}>\n\t\t\t\t\t\t\t\t{{\n\t\t\t\t\t\t\t\t\tdefault: () => [\n\t\t\t\t\t\t\t\t\t\t<CollapseItem name={\"date\"} icon={\"calendar-o\"} value={dateText.value} isLink={false}>\n\t\t\t\t\t\t\t\t\t\t\t{{\n\t\t\t\t\t\t\t\t\t\t\t\ttitle: () => <span style={{ fontWeight: \"bold\" }}>日期</span>,\n\t\t\t\t\t\t\t\t\t\t\t\tdefault: () => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div style={{ height: \"300px\" }}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Calendar\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tminDate={minDate}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmaxDate={maxDate}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tshowSubtitle={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tshowConfirm={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdefaultDate={defaultDate.value}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpoppable={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tshowTitle={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tlazyRender={true}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trowHeight={36}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonSelect={onSelectDate}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{...props.defaultProps.calendarProps}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t></Calendar>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t</CollapseItem>,\n\t\t\t\t\t\t\t\t\t\t<CollapseItem name={\"time\"} icon={\"clock-o\"} isLink={false} value={timeText.value}>\n\t\t\t\t\t\t\t\t\t\t\t{{\n\t\t\t\t\t\t\t\t\t\t\t\ttitle: () => <span style={{ fontWeight: \"bold\" }}>时间</span>,\n\t\t\t\t\t\t\t\t\t\t\t\tdefault: () => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TimePicker\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmodelValue={timeModel.value}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tshowToolbar={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={onTimeChange}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{...props.defaultProps.timeProps}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t></TimePicker>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t</CollapseItem>,\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t</Collapse>,\n\t\t\t\t\t\t\t<ExButton type={\"primary\"} style={{ margin: \"20px 0\" }} onClick={onConfirm}>\n\t\t\t\t\t\t\t\t确定\n\t\t\t\t\t\t\t</ExButton>,\n\t\t\t\t\t\t],\n\t\t\t\t\t}}\n\t\t\t\t</PickerWrapper>\n\t\t\t)\n\t\t}\n\t},\n})\n","import { computed, defineComponent, ref, watch } from \"vue\"\nimport PickerWrapper, { pickerSlots } from \"./PickerWrapper.jsx\"\nimport { TimePicker } from \"vant\"\nimport { defaultFieldProps } from \"../utils\"\n\n/**\n * ExTime 日期选择\n * @version 1.0.0\n */\nexport default defineComponent({\n\tname: \"ExTime\",\n\tprops: {\n\t\t...defaultFieldProps,\n\n\t\tmodelValue: { type: String, default: \"\" },\n\n\t\t/**\n\t\t * 标题\n\t\t */\n\t\ttitle: { type: String, default: \"选择时间\" },\n\t},\n\temits: [\"update:modelValue\"],\n\tsetup(props, { emit, slots, expose }) {\n\t\tconst columnsType = props.defaultProps?.columnsType || [\"hour\", \"minute\"]\n\t\tconst prepareDate = (time) => {\n\t\t\tconst value = []\n\n\t\t\tif (time) {\n\t\t\t\ttime = time.split(\":\")\n\t\t\t} else {\n\t\t\t\treturn value\n\t\t\t}\n\n\t\t\tcolumnsType.forEach((column, index) => {\n\t\t\t\tvalue.push(time[index])\n\t\t\t})\n\n\t\t\treturn value\n\t\t}\n\n\t\tconst defaultValue = prepareDate(props.modelValue)\n\n\t\tconst componentValue = ref(defaultValue)\n\n\t\twatch(\n\t\t\t() => props.modelValue,\n\t\t\t() => {\n\t\t\t\tcomponentValue.value = prepareDate(props.modelValue)\n\t\t\t},\n\t\t)\n\n\t\tconst pickerRef = ref(null)\n\n\t\tconst displayText = computed(() => {\n\t\t\tif (props.modelValue) {\n\t\t\t\tlet text = \"\"\n\t\t\t\tcolumnsType.forEach((column, index) => {\n\t\t\t\t\tlet times = prepareDate(props.modelValue)\n\n\t\t\t\t\tif (column === \"hour\") {\n\t\t\t\t\t\ttext += `${times[index]}`\n\t\t\t\t\t} else if (column === \"minute\") {\n\t\t\t\t\t\ttext += `:${times[index]}`\n\t\t\t\t\t} else if (column === \"second\") {\n\t\t\t\t\t\ttext += `:${times[index]}`\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\treturn text\n\t\t\t}\n\n\t\t\treturn \"\"\