diff --git a/api/contract.js b/api/contract.js index da2bcae..cdfa1c8 100644 --- a/api/contract.js +++ b/api/contract.js @@ -73,4 +73,10 @@ export function getListByDeptId(data) { return api.get('/bpm/oa/contract/getListByDeptId', data, { login: false }) -} \ No newline at end of file +} +// 获取部门类型为公司的部门信息 +export function getCompanyDept(data) { + return api.get('/system/dept/getCompanyDept', data, { + login: false + }) +} diff --git a/api/user.js b/api/user.js index 58ac754..95f9b43 100644 --- a/api/user.js +++ b/api/user.js @@ -1,32 +1,107 @@ import api from './api' +import { + VUE_APP_API_URL +} from '@/config' +import cookie from '@/utils/cookie' export function userGetUserInfo(data) { - return api.get('/system/user/profile/get', data, { login: true }) + return api.get('/system/user/profile/get', data, { + login: true + }) } export function getSimpleUserList(data) { - return api.get('/system/user/page', data, { login: true }) + return api.get('/system/user/page', data, { + login: true + }) } export function getSimpleUserList2(data) { - return api.get('/system/user/simple-list', data, { login: true }) + return api.get('/system/user/simple-list', data, { + login: true + }) } export function getFlowUsers(data) { - return api.get('/crm/flow/flow-users', data, { login: true }) + return api.get('/crm/flow/flow-users', data, { + login: true + }) } export function updateUser(data) { - return api.put('/system/user/profile/update', data, { login: true }) + return api.put('/system/user/profile/update', data, { + login: true + }) } export function updateUserProfilePassword(data) { - return api.put('/system/user/profile/update-password', data, { login: true }) + return api.put('/system/user/profile/update-password', data, { + login: true + }) +} + +export function getAllUserList(data) { + return api.get('/system/user/list-all', data, { + login: true + }) +} + +export function deleteBpmFile(data) { + return api.delete(`/infra/file/deleteBpmFile?url=${data.url}`, data, { + login: true + }) } - - +//上传文件 流程的 +export function uploadFile(filePath, cancelLoading) { + return new Promise((resolve, reject) => { + if (!cancelLoading) { + uni.showLoading({ + title: '上传中' + }) + } + let url = VUE_APP_API_URL + '/infra/file/bpmUpload' + uni.showLoading({ + title: '正在上传' + }) + uni.uploadFile({ + url, + name: 'uploadFiles', + filePath: filePath, + header: { + 'Authorization': 'Bearer ' + cookie.get('accessToken'), + 'tenant-id': '1' + }, + success: res => { + console.log(res) + uni.hideLoading() + if (JSON.parse(res.data).code == 200 || JSON.parse(res.data).code == 0) { + resolve(JSON.parse(res.data).data) + } else if (JSON.parse(res.data).code == 401) { + uni.showToast({ + title: '登录过期,请重新登录', + }); + setTimeout(() => { + uni.reLaunch({ + url: '/pages/components/pages/login/login' + }) + }, 1000) + reject(res) + } else { + uni.showToast({ + title: JSON.parse(res.data).msg + }); + reject(res) + } + }, + fail: err => { + uni.hideLoading() + reject(err) + } + }) + }) +} \ No newline at end of file diff --git a/components/xtx-treeNode/README.md b/components/xtx-treeNode/README.md new file mode 100644 index 0000000..cab6fbe --- /dev/null +++ b/components/xtx-treeNode/README.md @@ -0,0 +1,81 @@ +## 适用于组织架构的基础展示 + +使用 +``` + +``` +list数据结构 +``` +list: [{ + id: '1', + name: '机构一', + children: [ + { + id: '101', + name: '人事部', + children: [] + },{ + id: '102', + name: '总部', + children: [ + { + id: '1021', + name: '选项一', + children: [] + },{ + id: '1022', + name: '选项二', + children: [] + },{ + id: '1023', + name: '选项三', + children: [] + } + ] + },{ + id: '103', + name: '后勤部', + children: [] + } + ] +},{ + id: '12', + name: '机构二', + children: [ + { + id: '10121', + name: '选项一', + children: [] + },{ + id: '10122', + name: '选项二', + children: [] + },{ + id: '10123', + name: '选项三', + children: [] + } + ] +},{ + id: '13', + name: '机构三', + children: [{ + id: '10131', + name: '选项一', + children: [] + },{ + id: '10132', + name: '选项二', + children: [] + },{ + id: '10133', + name: '选项三', + children: [] + }] +}] +``` +## 事件说明 + +| 事件名 | 说明 | 回调 | +| ------- | ------- | ------- | +| change | 点击node节点触发 | ({ id: '10131', name: '选项一', children: []})=>{} | \ No newline at end of file diff --git a/components/xtx-treeNode/xtx-treeNode.vue b/components/xtx-treeNode/xtx-treeNode.vue new file mode 100644 index 0000000..74602b7 --- /dev/null +++ b/components/xtx-treeNode/xtx-treeNode.vue @@ -0,0 +1,70 @@ + + + + + \ No newline at end of file diff --git a/pages.json b/pages.json index 8bbdb2b..49e0d76 100644 --- a/pages.json +++ b/pages.json @@ -362,12 +362,14 @@ "text": "客户", "iconPath": "static/images/tabBar/customer.png", "selectedIconPath": "static/images/tabBar/customer-selected.png" - }, { - "pagePath": "pages/msg/index", - "text": "消息", - "iconPath": "static/images/tabBar/msg.png", - "selectedIconPath": "static/images/tabBar/msg-select.png" - }, { + }, + //{ + // "pagePath": "pages/msg/index", + // "text": "消息", + // "iconPath": "static/images/tabBar/msg.png", + // "selectedIconPath": "static/images/tabBar/msg-select.png" + // }, + { "pagePath": "pages/mine/mine", "text": "我的", "iconPath": "static/images/tabBar/mine.png", diff --git a/pages/components/pages/contract/add.vue b/pages/components/pages/contract/add.vue index 23cc07c..5be90cf 100644 --- a/pages/components/pages/contract/add.vue +++ b/pages/components/pages/contract/add.vue @@ -9,16 +9,16 @@ --> - + - - + + - + @@ -283,8 +353,7 @@ } from '@dcloudio/uni-app' import { getCustomerListPage, - getContactsPage, - createOAContract + getContactsPage } from '@/api/customer' import { getBusinessProductListByBusinessId, @@ -296,17 +365,24 @@ getContract, getContractProductListByContractId, updateContract, - check + check, + getCompanyDept, + createOAContract, + getOAContract } from '@/api/contract' import { getSimpleUserList, getFlowUsers, - getSimpleUserList2 + getSimpleUserList2, + getAllUserList, + uploadFile, + deleteBpmFile } from '@/api/user' import AddressSelect from '@/components/AddressSelect/index.vue' import { - formatDateTime, - prePage + timestampToDate, + prePage, + getFileType } from '@/utils/util' import { useMainStore @@ -314,6 +390,9 @@ import { storeToRefs } from 'pinia' + import { + deepClone + } from '../../../../uni_modules/uv-ui-tools/libs/function' const main = useMainStore() const { selectProductList @@ -327,7 +406,7 @@ const goodsName = ref('') const page = ref(1) const page3 = ref(1) - const pageSize = ref(10) + const pageSize = ref(15) const lastPage = ref(false) const lastPage3 = ref(false) const selectList = ref([]) @@ -335,33 +414,30 @@ const type = ref('add') const contractId = ref(0) const customerId = ref(0) - const nextTime = ref('') - const orderTime = ref(formatDateTime(new Date())) - const startTime = ref(formatDateTime(new Date())) - const endTime = ref(formatDateTime(new Date())) const content = ref('') const customerName = ref('') const form = ref({ + fileItems: [], //附件 contractType: 1, // 合同类型 contractNo: '', //合同编号 contractName: '', //合同名称 customerId: '', //客户ID customerName: '', //客户名称 - nextTime: '', //下次联系时间 - startDate: new Date(), //开始时间 - orderTime: new Date(), //下单时间 - endDate: new Date(), //结束时间 + startDate: timestampToDate(new Date()), //开始时间 + signingDate: timestampToDate(new Date()), //签约日期 + endDate: timestampToDate(new Date()), //结束时间 remark: '', //备注 - discountRate: '', //整单折扣 - totalPrice: '', //产品总金额 + discountRate: 0, //整单折扣 + totalPrice: 0, //产品总金额 contactsName: '', //客户签约人 contactsId: '', //签约人id - orderAdminName: '', //签约人名称 companyId: '', //签约公司编号 + companyName: '', //签约公司名称 businessId: '', //商机ID invoiceMoney: '', // 已开票金额 - returnMoney: '', // 已收/已付金额 contractMoney: '', // 合同金额 + signatoryId: '', // 签约人编号 + signatoryName: '', // 签约人名称 }) const timeText = ref('') const errorType = ref('message') @@ -381,55 +457,147 @@ }) onLoad((e) => { - if (e.type) { - type.value = e.type - } - if (type.value == 'check') { + type.value = e.type + if (type.value == 'detail') { isCheck.value = true - title.value = '审核合同' + title.value = '合同详情' contractId.value = e.id getContractInfo() } - if (type.value == "edit") { - title.value = '编辑合同' - contractId.value = e.id - getContractInfo() - } else { - // getNumber() - } + getUserList() //获取签约人 getCustomerList() - getUserList() - // getFlowUsersList() 获取审批人的 + getCompanyList() //获取公司列表 }) onShow(() => { - selectList.value = selectProductList.value + selectList.value = selectProductList.value || [] count_price() }) - const getFlowUsersList = async () => { - let data = await getFlowUsers({ - flowType: 'contract' + // 附件上传相关 + const imgFiles = ref([]) //图片列表 + const pdfList = ref([]) //pdf列表 + //删除文件 + const deleteFiles = (val, i) => { + deleteBpmFile({ + url: val.url + }).then(res => { + pdfList.value.splice(i, 1) }) - let users = await getSimpleUserList2() - let userIdArr = [] - let userArr = [] - for (var i = 0; i <= data.length; i++) { - users.forEach((item, index) => { - if (data[i] == item.id) { - userIdArr.push(item.id) - userArr.push(item.nickname) + } + //上传 + const uploadFileApi = (url) => { + return new Promise((reslove, reject) => { + uploadFile(url, true) + .then((res) => { + console.log(res, 'success') + reslove(res); + }) + .catch((err) => { + console.log(err, 'err') + reject(err); + }); + }); + } + //获取文件后缀名 + const getExtension = (fileName) => { + let arr = fileName.split('.'); + return arr[arr.length - 1]; + } + //选择图片 + const chooseImage = () => { + uni.chooseImage({ + count: 9 - imgFiles.value.length, //默认9 + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 + sourceType: ['album', 'camera'], //从相册选择 + success: (res) => { + let promise = Promise.resolve(); + let arr = []; + uni.showLoading({ + title: '上传中' + }) + + res.tempFilePaths.forEach((item) => { + promise = promise.then(() => uploadFileApi(item)); + promise + .then((ress) => { + arr.push(1) + imgFiles.value.push({ + name: ress.name, + url: ress.url + }) + if (arr.length >= res.tempFilePaths.length) { + uni.hideLoading() + } + }) + .catch((err) => { + uni.hideLoading() + }); + }); + } + }); + } + //上传文件 pdf + const chooseFiles = () => { + wx.chooseMessageFile({ + count: 9 - pdfList.value.length, //默认100 + extension: ['pdf', '.pdf'], + success: (res) => { + let isUploadFile = true + res.tempFiles.forEach(item => { + if (getExtension(item.name) != 'pdf') { + isUploadFile = false + } + }) + if (!isUploadFile) { + uni.showToast({ + title: '请您上传pdf格式文件', + }); + return + } + let promise = Promise.resolve(); + let arr = []; + uni.showLoading({ + title: '上传中' + }) + + res.tempFiles.forEach((item) => { + promise = promise.then(() => uploadFileApi(item.path)); + promise + .then((ress) => { + arr.push(1) + pdfList.value.push({ + name: ress.name, + url: ress.url + }) + if (arr.length >= res.tempFilePaths.length) { + uni.hideLoading() + } + }) + .catch((err) => { + uni.hideLoading() + }); + }); + } + }); + } + + + //获取公司列表 + const companyList = ref([]) + const getCompanyList = async () => { + companyList.value = await getCompanyDept() + if (form.value.companyId) { + companyList.value.forEach((item, index) => { + if (form.value.companyId == item.id) { + item.checked = true + } else { + item.checked = false } }) } - form.value.flowAdminIdName = userArr.join(',') - form.value.flowAdminId = userIdArr } - //合同编号 - const getNumber = async () => { - form.value.contractNo = await getContractNo() - } const selectShowRef = ref() const selectShow = () => { @@ -446,8 +614,7 @@ // 选择时间 const createTimeChange = (e) => { - form.value.orderTime = e.value - orderTime.value = formatDateTime(e.value) + form.value.signingDate = timestampToDate(e.value) } const datetimePicker2 = ref() @@ -457,8 +624,19 @@ // 选择时间 const createTimeChange2 = (e) => { - form.value.startDate = e.value - startTime.value = formatDateTime(e.value) + form.value.startDate = timestampToDate(e.value) + if (form.value.endDate) { + //比较开始时间和结束时间大小 + let startDate = new Date(form.value.startDate); + let endDate = new Date(form.value.endDate); + if (endDate < startDate) { + form.value.endDate = '' + uni.showToast({ + icon: 'none', + title: '结束时间不能大于开始时间' + }) + } + } } const datetimePicker3 = ref() @@ -468,15 +646,36 @@ // 选择时间 const createTimeChange3 = (e) => { - form.value.endDate = e.value - endTime.value = formatDateTime(e.value) + form.value.endDate = timestampToDate(e.value) + if (form.value.startDate) { + //比较开始时间和结束时间大小 + let startDate = new Date(form.value.startDate); + let endDate = new Date(form.value.endDate); + if (endDate < startDate) { + form.value.endDate = '' + uni.showToast({ + icon: 'none', + title: '结束时间不能大于开始时间' + }) + } + } } // 获取商机数据详情 const getContractInfo = async () => { - form.value = await getContract({ + form.value = await getOAContract({ id: contractId.value }) - form.value.flowAdminId = form.value.flowAdminId2 + if (form.value.fileItems.length) { + form.value.fileItems.forEach(item => { + if (getFileType(item.name) == 'image') { + imgFiles.value.push(item) + } + if (getFileType(item.name) == 'pdf') { + pdfList.value.push(item) + } + }) + } + selectList.value = await getContractProductListByContractId({ contractId: contractId.value }) @@ -493,7 +692,6 @@ uni.navigateTo({ url: '/pages/components/pages/business/selectProduct' }); - } const getCustomerList = async (isNextPage, pages) => { @@ -505,7 +703,7 @@ }).then(res => { if (res) { // 不够一页 - if (res.list.length < 10) { + if (res.list.length < pageSize.value) { listStatus.value = 'nomore' } // 最后一页 @@ -534,37 +732,20 @@ } const getUserList = async (isNextPage, pages) => { - await getSimpleUserList({ - pageNo: page.value, - pageSize: pageSize.value, + await getAllUserList({ username: keyword3.value, + deptId: form.value.companyId }).then(res => { - if (res) { - // 不够一页 - if (res.list.length < 10) { - listStatus3.value = 'nomore' - } - // 最后一页 - if (res.list.length == 0) { - lastPage3.value = true - } - // 第二页开始 - if (isNextPage) { - userList.value = userList.value.concat(res.list) - return - } - userList.value = res.list - - if (form.value.orderAdminId) { - userList.value.forEach((item, index) => { - if (form.value.orderAdminId == item.id) { - item.checked = true - username.value = item.username - } else { - item.checked = false - } - }) - } + userList.value = res + if (form.value.signatoryId) { + userList.value.forEach((item, index) => { + if (form.value.signatoryId == item.id) { + item.checked = true + username.value = item.nickname + } else { + item.checked = false + } + }) } }) } @@ -574,28 +755,16 @@ const reachBottom = () => { if (lastPage.value || listStatus.value == 'loading') return listStatus.value = 'loading' - setTimeout(() => { - getCustomerList(true, ++page.value) - if (customerList.value.length >= 10) { - listStatus.value = 'loadmore'; - } else { - listStatus.values = 'loading'; - } - }, 1200) + page.value++ + getCustomerList(true, page.value) + if (customerList.value.length >= pageSize.value) { + listStatus.value = 'loadmore'; + } else { + listStatus.values = 'loading'; + } } - const reachBottom3 = () => { - if (lastPage3.value || listStatus3.value == 'loading') return - listStatus3.value = 'loading' - setTimeout(() => { - getUserList(true, ++page3.value) - if (userList.value.length >= 10) { - listStatus3.value = 'loadmore'; - } else { - listStatus3.values = 'loading'; - } - }, 1200) - } + // 选择客户 const onItem = async (val, i) => { customerList.value.forEach((item, index) => { @@ -607,7 +776,6 @@ } }) form.value.customerId = val.id - form.value.customerName = val.name ? val.name : '' //选择了客户 返回客户联系人 let data = await getContactsPage({ @@ -640,7 +808,6 @@ } }) form.value.contactsId = val.id - form.value.contactsName = val.name ? val.name : '' selectShowClose2() } @@ -658,13 +825,12 @@ userList.value.forEach((item, index) => { if (val.id == item.id) { item.checked = true - val.username = val.username ? val.username : item.username; } else { item.checked = false } }) - form.value.orderAdminId = val.id - form.value.orderAdminName = val.username ? val.username : '' + form.value.signatoryId = val.id + form.value.signatoryName = val.nickname ? val.nickname : '' selectShowClose3() } @@ -690,7 +856,6 @@ selectList.value = await getBusinessProductListByBusinessId({ businessId: val.id }) - selectShowClose4() } @@ -702,12 +867,52 @@ unref(selectShowRef5).close() } + //公司 + const selectShowRef6 = ref() + const selectShow6 = async () => { + unref(selectShowRef6).open() + } + const selectShowClose6 = () => { + unref(selectShowRef6).close() + } + const onItem6 = (val, i) => { + companyList.value.forEach((item, index) => { + if (val.id == item.id) { + item.checked = true + } else { + item.checked = false + } + }) + form.value.companyId = val.id + form.value.companyName = val.name + userList.value = [] + page3.value = 1 + getUserList() + selectShowClose6() + } + // 产品数量增加 - const valChange = () => { + const valChange = (e) => { count_price() } // 优惠率改变 - const inputChang = () => { + const inputChang = (e) => { + if (e.detail.value > form.value.totalPrice) { + form.value.discountRate = 0 + uni.showToast({ + icon: 'none', + title: '折扣金额不能大于总金额' + }) + } + + if (e.detail.value < 0) { + form.value.discountRate = 0 + uni.showToast({ + icon: 'none', + title: '折扣金额不能小于0' + }) + } + count_price() } // 移除已选产品 @@ -717,16 +922,18 @@ } // 计算价格 const count_price = () => { - let total = 0; - setTimeout(() => { - for (let i = 0; i < selectList.value.length; i++) { - total += selectList.value[i].nums * selectList.value[i].price - } - if (form.value.discountRate > 0) { - total = total - (form.value.discountRate / 100) * total + let list = deepClone(selectList.value) + + if (list.length > 0) { + let total = 0; + for (let i = 0; i < list.length; i++) { + total = total + (list[i].nums * list[i].price) } + total = total - Number(form.value.discountRate || 0) form.value.totalPrice = total.toFixed(2) - }, 500) + } else { + form.value.totalPrice = 0 + } } const submitCheck = async (type) => { @@ -785,7 +992,7 @@ }) return } - if (form.value.orderAdminIdName == '') { + if (form.value.signatoryId == '') { uni.showToast({ icon: 'error', title: '请选择公司签约人' @@ -819,11 +1026,10 @@ obj.subtotal = item.nums * item.price newArr[index] = obj }) - if (type.value == 'add') { - + if (type.value !== 'detail') { form.value.contractProducts = newArr - await createContract(form.value) - + form.value.fileItems = [...imgFiles.value, ...pdfList.value] + await createOAContract(form.value) uni.showToast({ title: '添加成功', icon: 'success', @@ -834,9 +1040,6 @@ uni.navigateBack(); }, 1000); } else { - // selectList.value.forEach((item,index)=>{ - // item.subtotal = item.nums * item.price - // }) form.value.contractProducts = newArr await updateContract(form.value) uni.showToast({ @@ -855,7 +1058,7 @@ \ No newline at end of file diff --git a/pages/components/pages/contract/index.vue b/pages/components/pages/contract/index.vue index beb1952..6fe5810 100644 --- a/pages/components/pages/contract/index.vue +++ b/pages/components/pages/contract/index.vue @@ -19,35 +19,30 @@ @scrolltolower="reachBottom"> - + - {{items.name}} + {{items.contractName}} - - - - - - + + {{fillterStatus(items.result)}} + - ¥{{items.money}} 回款:¥{{items.returnMoney}} + ¥{{items.contractMoney}} 回款:¥{{items.returnMoney}} - {{items.orderAdminName ? items.orderAdminName : '--'}} + {{items.signatoryName ? items.signatoryName : '暂无'}} - 到期:{{timeFormats(items.endTime)}} + 到期:{{timestampToDate(items.endDate)}} - - 审核 - - - 详情 - + 详情 @@ -76,10 +71,13 @@ } from '@dcloudio/uni-app' import { getContractPage, - getOAContractPage + getOAContractPage, } from '@/api/contract' import { - formatDateTime + getDictData, + } from '@/api/customer.js' + import { + timestampToDate } from '@/utils/util' const title = ref('合同') const keyword = ref('') @@ -131,8 +129,30 @@ scrollTop.value = 0 dataList.value = [] getList() + getStatusList() }) + const statusList = ref([]) + const getStatusList = () => { + getDictData({ + type: 'bpm_process_instance_result' + }).then(res => { + statusList.value = res + }) + } + + //格式化状态 + const fillterStatus = (status) => { + if (statusList.value.length) { + let obj = statusList.value.find(item => { + return item.value == status + }) + return obj == undefined ? '' : obj.name + } else { + return status + } + } + const timeFormats = (val) => { if (val) { return formatDateTime(val) @@ -140,24 +160,12 @@ return '--' } } - + const handleSelect = (key) => { relation.value = key.value getList() } - // 审核 - const onCheck = (id, type) => { - if (type == 'look') { - uni.navigateTo({ - url: '/pages/components/pages/contract/add?id=' + id + '&type=edit' - }); - } else { - uni.navigateTo({ - url: '/pages/components/pages/contract/add?id=' + id + '&type=check' - }); - } - } const getList = async (isNextPage, pages) => { await getOAContractPage({ @@ -205,9 +213,10 @@ getList() } - const onItem = (val) => { + // 详情 + const onCheck = (id, type) => { uni.navigateTo({ - url: '/pages/components/pages/contract/add?id=' + val + '&type=edit' + url: '/pages/components/pages/contract/add?id=' + id + '&type=detail' }); } diff --git a/pages/components/pages/mine/index.vue b/pages/components/pages/mine/index.vue index 0aabcdf..13f141e 100644 --- a/pages/components/pages/mine/index.vue +++ b/pages/components/pages/mine/index.vue @@ -1,133 +1,146 @@ - - - - - + + + + + \ No newline at end of file diff --git a/pages/components/pages/msg/wait.vue b/pages/components/pages/msg/wait.vue index 877eb63..006a2b8 100644 --- a/pages/components/pages/msg/wait.vue +++ b/pages/components/pages/msg/wait.vue @@ -8,7 +8,6 @@ - 2024-10-07 diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue index 16d65a9..27204ad 100644 --- a/pages/mine/mine.vue +++ b/pages/mine/mine.vue @@ -12,9 +12,9 @@ {{roleName}} - + diff --git a/static/greyguanbi.png b/static/greyguanbi.png new file mode 100644 index 0000000..237f659 Binary files /dev/null and b/static/greyguanbi.png differ diff --git a/uni_modules/uni-easyinput/changelog.md b/uni_modules/uni-easyinput/changelog.md new file mode 100644 index 0000000..84c72eb --- /dev/null +++ b/uni_modules/uni-easyinput/changelog.md @@ -0,0 +1,115 @@ +## 1.1.19(2024-07-18) +- 修复 初始值传入 null 导致input报错的bug +## 1.1.18(2024-04-11) +- 修复 easyinput组件双向绑定问题 +## 1.1.17(2024-03-28) +- 修复 在头条小程序下丢失事件绑定的问题 +## 1.1.16(2024-03-20) +- 修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug +## 1.1.15(2024-02-21) +- 新增 左侧插槽:left +## 1.1.14(2024-02-19) +- 修复 onBlur的emit传值错误 +## 1.1.12(2024-01-29) +- 补充 adjust-position文档属性补充 +## 1.1.11(2024-01-29) +- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面 +## 1.1.10(2024-01-22) +- 去除 移除无用的log输出 +## 1.1.9(2023-04-11) +- 修复 vue3 下 keyboardheightchange 事件报错的bug +## 1.1.8(2023-03-29) +- 优化 trim 属性默认值 +## 1.1.7(2023-03-29) +- 新增 cursor-spacing 属性 +## 1.1.6(2023-01-28) +- 新增 keyboardheightchange 事件,可监听键盘高度变化 +## 1.1.5(2022-11-29) +- 优化 主题样式 +## 1.1.4(2022-10-27) +- 修复 props 中背景颜色无默认值的bug +## 1.1.0(2022-06-30) + +- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容 +- 新增 clear 事件,点击右侧叉号图标触发 +- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发 +- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等 + +## 1.0.5(2022-06-07) + +- 优化 clearable 显示策略 + +## 1.0.4(2022-06-07) + +- 优化 clearable 显示策略 + +## 1.0.3(2022-05-20) + +- 修复 关闭图标某些情况下无法取消的 bug + +## 1.0.2(2022-04-12) + +- 修复 默认值不生效的 bug + +## 1.0.1(2022-04-02) + +- 修复 value 不能为 0 的 bug + +## 1.0.0(2021-11-19) + +- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput) + +## 0.1.4(2021-08-20) + +- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug + +## 0.1.3(2021-08-11) + +- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题 + +## 0.1.2(2021-07-30) + +- 优化 vue3 下事件警告的问题 + +## 0.1.1 + +- 优化 errorMessage 属性支持 Boolean 类型 + +## 0.1.0(2021-07-13) + +- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) + +## 0.0.16(2021-06-29) + +- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug + +## 0.0.15(2021-06-21) + +- 修复 passwordIcon 属性拼写错误的 bug + +## 0.0.14(2021-06-18) + +- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标 +- 修复 confirmType 属性不生效的问题 + +## 0.0.13(2021-06-04) + +- 修复 disabled 状态可清出内容的 bug + +## 0.0.12(2021-05-12) + +- 新增 组件示例地址 + +## 0.0.11(2021-05-07) + +- 修复 input-border 属性不生效的问题 + +## 0.0.10(2021-04-30) + +- 修复 ios 遮挡文字、显示一半的问题 + +## 0.0.9(2021-02-05) + +- 调整为 uni_modules 目录规范 +- 优化 兼容 nvue 页面 diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/common.js b/uni_modules/uni-easyinput/components/uni-easyinput/common.js new file mode 100644 index 0000000..fde8d3c --- /dev/null +++ b/uni_modules/uni-easyinput/components/uni-easyinput/common.js @@ -0,0 +1,54 @@ +/** + * @desc 函数防抖 + * @param func 目标函数 + * @param wait 延迟执行毫秒数 + * @param immediate true - 立即执行, false - 延迟执行 + */ +export const debounce = function(func, wait = 1000, immediate = true) { + let timer; + return function() { + let context = this, + args = arguments; + if (timer) clearTimeout(timer); + if (immediate) { + let callNow = !timer; + timer = setTimeout(() => { + timer = null; + }, wait); + if (callNow) func.apply(context, args); + } else { + timer = setTimeout(() => { + func.apply(context, args); + }, wait) + } + } +} +/** + * @desc 函数节流 + * @param func 函数 + * @param wait 延迟执行毫秒数 + * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发 + */ +export const throttle = (func, wait = 1000, type = 1) => { + let previous = 0; + let timeout; + return function() { + let context = this; + let args = arguments; + if (type === 1) { + let now = Date.now(); + + if (now - previous > wait) { + func.apply(context, args); + previous = now; + } + } else if (type === 2) { + if (!timeout) { + timeout = setTimeout(() => { + timeout = null; + func.apply(context, args) + }, wait) + } + } + } +} diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue new file mode 100644 index 0000000..93506d6 --- /dev/null +++ b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue @@ -0,0 +1,676 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uni-easyinput/package.json b/uni_modules/uni-easyinput/package.json new file mode 100644 index 0000000..2939256 --- /dev/null +++ b/uni_modules/uni-easyinput/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-easyinput", + "displayName": "uni-easyinput 增强输入框", + "version": "1.1.19", + "description": "Easyinput 组件是对原生input组件的增强", + "keywords": [ + "uni-ui", + "uniui", + "input", + "uni-easyinput", + "输入框" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "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", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-easyinput/readme.md b/uni_modules/uni-easyinput/readme.md new file mode 100644 index 0000000..f1faf8f --- /dev/null +++ b/uni_modules/uni-easyinput/readme.md @@ -0,0 +1,11 @@ + + +### Easyinput 增强输入框 +> **组件名:uni-easyinput** +> 代码块: `uEasyinput` + + +easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-number-box/changelog.md b/uni_modules/uni-number-box/changelog.md new file mode 100644 index 0000000..adf9221 --- /dev/null +++ b/uni_modules/uni-number-box/changelog.md @@ -0,0 +1,39 @@ +## 1.2.8(2024-04-26) +- 修复 在vue2下H5黑边的bug +## 1.2.7(2024-04-26) +- 修复 在vue2手动输入后失焦导致清空数值的严重bug +## 1.2.6(2024-02-22) +- 新增 设置宽度属性width(单位:px) +## 1.2.5(2024-02-21) +- 修复 step步长小于1时,键盘类型为number的bug +## 1.2.4(2024-02-02) +- 修复 加减号垂直位置偏移样式问题 +## 1.2.3(2023-05-23) +- 更新示例工程 +## 1.2.2(2023-05-08) +- 修复 change 事件执行顺序错误的问题 +## 1.2.1(2021-11-22) +- 修复 vue3中某些scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box) +## 1.1.2(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-04-20) +- 修复 uni-number-box 浮点数运算不精确的 bug +- 修复 uni-number-box change 事件触发不正确的 bug +- 新增 uni-number-box v-model 双向绑定 +## 1.0.5(2021-02-05) +- 调整为uni_modules目录规范 + +## 1.0.7(2021-02-05) +- 调整为uni_modules目录规范 +- 新增 支持 v-model +- 新增 支持 focus、blur 事件 +- 新增 支持 PC 端 diff --git a/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue b/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue new file mode 100644 index 0000000..4e203cc --- /dev/null +++ b/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue @@ -0,0 +1,232 @@ + + + diff --git a/uni_modules/uni-number-box/package.json b/uni_modules/uni-number-box/package.json new file mode 100644 index 0000000..4ac9047 --- /dev/null +++ b/uni_modules/uni-number-box/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-number-box", + "displayName": "uni-number-box 数字输入框", + "version": "1.2.8", + "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。", + "keywords": [ + "uni-ui", + "uniui", + "数字输入框" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "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", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-number-box/readme.md b/uni_modules/uni-number-box/readme.md new file mode 100644 index 0000000..affc56f --- /dev/null +++ b/uni_modules/uni-number-box/readme.md @@ -0,0 +1,13 @@ + + +## NumberBox 数字输入框 +> **组件名:uni-number-box** +> 代码块: `uNumberBox` + + +带加减按钮的数字输入框。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/utils/util.js b/utils/util.js index 57e62c9..d15355e 100644 --- a/utils/util.js +++ b/utils/util.js @@ -1,191 +1,216 @@ -// 验证手机号码 - export function validatePhoneNumber(data) { - var reg = /^1[3-9]\d{9}$/ - return reg.test(data) - } - - export function lastfour(num) { - // 截取后4位 - let lastFourDigits = num.slice(-4); - return lastFourDigits - } - -export function isValidBankCard(cardNumber) { - const reg = /^(\d{16}|\d{19})$/ - // 使用正则表达式测试银行卡号 - return reg.test(cardNumber) - } - -export function formatTime(time) { - if (typeof time !== 'number' || time < 0) { - return time - } - - var hour = parseInt(time / 3600) - time = time % 3600 - var minute = parseInt(time / 60) - time = time % 60 - var second = time - - return ([hour, minute, second]).map(function(n) { - n = n.toString() - return n[1] ? n : '0' + n - }).join(':') -} - -export function formatDateTime(date, fmt = 'yyyy-MM-dd hh:mm:ss') { - if(!date) { - return '' - } - if (typeof (date) === 'number') { - date = new Date(date) - } - var o = { - "M+": date.getMonth() + 1, //月份 - "d+": date.getDate(), //日 - "h+": date.getHours(), //小时 - "m+": date.getMinutes(), //分 - "s+": date.getSeconds(), //秒 - "q+": Math.floor((date.getMonth() + 3) / 3), //季度 - "S": date.getMilliseconds() //毫秒 - } - if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)) - for (var k in o) - if (new RegExp("(" + k + ")").test(fmt)) - fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))) - return fmt -} - -export function formatLocation(longitude, latitude) { - if (typeof longitude === 'string' && typeof latitude === 'string') { - longitude = parseFloat(longitude) - latitude = parseFloat(latitude) - } - - longitude = longitude.toFixed(2) - latitude = latitude.toFixed(2) - - return { - longitude: longitude.toString().split('.'), - latitude: latitude.toString().split('.') - } -} - -var dateUtils = { - UNITS: { - '年': 31557600000, - '月': 2629800000, - '天': 86400000, - '小时': 3600000, - '分钟': 60000, - '秒': 1000 - }, - humanize: function(milliseconds) { - var humanize = ''; - for (var key in this.UNITS) { - if (milliseconds >= this.UNITS[key]) { - humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前'; - break; - } - } - return humanize || '刚刚'; - }, - format: function(dateStr) { - var date = this.parse(dateStr) - var diff = Date.now() - date.getTime(); - if (diff < this.UNITS['天']) { - return this.humanize(diff); - } - var _format = function(number) { - return (number < 10 ? ('0' + number) : number); - }; - return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' + - _format(date.getHours()) + ':' + _format(date.getMinutes()); - }, - parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象 - var a = str.split(/[^0-9]/); - return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]); - } -}; - -// 返回上一页 -export function prePage(page = null){ - let pages = getCurrentPages(); - //console.log('pages:',pages); - let prePage = pages[pages.length - 2]; - if (page !== null) { - prePage = pages[page]; - } - // #ifdef H5 - //return prePage; - // #endif - return prePage; -} - -export function kmUnit(m){ - var v; - if(typeof m === 'number' && !isNaN(m)){ - if (m >= 1000) { - v = (m / 1000).toFixed(2) + 'km' - } else { - v = m + 'm' - } - }else{ - v = '0m' - } - return v; -} - -export function isWeixin() { - if (navigator && navigator.userAgent && navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1) { - return true - } - return false - } - +// 验证手机号码 +export function validatePhoneNumber(data) { + var reg = /^1[3-9]\d{9}$/ + return reg.test(data) +} + +export function lastfour(num) { + // 截取后4位 + let lastFourDigits = num.slice(-4); + return lastFourDigits +} + +export function isValidBankCard(cardNumber) { + const reg = /^(\d{16}|\d{19})$/ + // 使用正则表达式测试银行卡号 + return reg.test(cardNumber) +} + +export function formatTime(time) { + if (typeof time !== 'number' || time < 0) { + return time + } + + var hour = parseInt(time / 3600) + time = time % 3600 + var minute = parseInt(time / 60) + time = time % 60 + var second = time + + return ([hour, minute, second]).map(function(n) { + n = n.toString() + return n[1] ? n : '0' + n + }).join(':') +} + +export function formatDateTime(date, fmt = 'yyyy-MM-dd hh:mm:ss') { + if (!date) { + return '' + } + if (typeof(date) === 'number') { + date = new Date(date) + } + var o = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "h+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + } + if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)) + for (var k in o) + if (new RegExp("(" + k + ")").test(fmt)) + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))) + return fmt +} + +export function timestampToDate(timestamp) { + let date = new Date(timestamp); + let year = date.getFullYear(); + let month = ("0" + (date.getMonth() + 1)).slice(-2); + let day = ("0" + date.getDate()).slice(-2); + + return `${year}-${month}-${day}`; +} + +export function formatLocation(longitude, latitude) { + if (typeof longitude === 'string' && typeof latitude === 'string') { + longitude = parseFloat(longitude) + latitude = parseFloat(latitude) + } + + longitude = longitude.toFixed(2) + latitude = latitude.toFixed(2) + + return { + longitude: longitude.toString().split('.'), + latitude: latitude.toString().split('.') + } +} + +var dateUtils = { + UNITS: { + '年': 31557600000, + '月': 2629800000, + '天': 86400000, + '小时': 3600000, + '分钟': 60000, + '秒': 1000 + }, + humanize: function(milliseconds) { + var humanize = ''; + for (var key in this.UNITS) { + if (milliseconds >= this.UNITS[key]) { + humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前'; + break; + } + } + return humanize || '刚刚'; + }, + format: function(dateStr) { + var date = this.parse(dateStr) + var diff = Date.now() - date.getTime(); + if (diff < this.UNITS['天']) { + return this.humanize(diff); + } + var _format = function(number) { + return (number < 10 ? ('0' + number) : number); + }; + return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' + + _format(date.getHours()) + ':' + _format(date.getMinutes()); + }, + parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象 + var a = str.split(/[^0-9]/); + return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]); + } +}; + +// 返回上一页 +export function prePage(page = null) { + let pages = getCurrentPages(); + //console.log('pages:',pages); + let prePage = pages[pages.length - 2]; + if (page !== null) { + prePage = pages[page]; + } + // #ifdef H5 + //return prePage; + // #endif + return prePage; +} + +export function kmUnit(m) { + var v; + if (typeof m === 'number' && !isNaN(m)) { + if (m >= 1000) { + v = (m / 1000).toFixed(2) + 'km' + } else { + v = m + 'm' + } + } else { + v = '0m' + } + return v; +} + +export function isWeixin() { + if (navigator && navigator.userAgent && navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1) { + return true + } + return false +} + export function parseQuery() { - let res = {} - - // #ifdef H5 - const query = (location.href.split('?')[1] || '').trim().replace(/^(\?|#|&)/, '') - - if (!query) { - return res - } - - query.split('&').forEach(param => { - const parts = param.replace(/\+/g, ' ').split('=') - const key = decodeURIComponent(parts.shift()) - const val = parts.length > 0 ? decodeURIComponent(parts.join('=')) : null - - if (res[key] === undefined) { - res[key] = val - } else if (Array.isArray(res[key])) { - res[key].push(val) - } else { - res[key] = [res[key], val] - } - }) - // #endif - // #ifndef H5 - var pages = getCurrentPages() //获取加载的页面 - var currentPage = pages[pages.length - 1] //获取当前页面的对象 - var url = currentPage.route //当前页面url - res = currentPage.options //如果要获取url中所带的参数可以查看options - // #endif - - return res - } - - -export function urlDecode(query) { - if (!query) return null - let hash, object = {} - const hashes = query.slice(query.indexOf('?') + 1).split('&') - for (let i = 0; i < hashes.length; i++) { - hash = hashes[i].split('=') - object[hash[0]] = hash[1] - } - - return object; + let res = {} + + // #ifdef H5 + const query = (location.href.split('?')[1] || '').trim().replace(/^(\?|#|&)/, '') + + if (!query) { + return res + } + + query.split('&').forEach(param => { + const parts = param.replace(/\+/g, ' ').split('=') + const key = decodeURIComponent(parts.shift()) + const val = parts.length > 0 ? decodeURIComponent(parts.join('=')) : null + + if (res[key] === undefined) { + res[key] = val + } else if (Array.isArray(res[key])) { + res[key].push(val) + } else { + res[key] = [res[key], val] + } + }) + // #endif + // #ifndef H5 + var pages = getCurrentPages() //获取加载的页面 + var currentPage = pages[pages.length - 1] //获取当前页面的对象 + var url = currentPage.route //当前页面url + res = currentPage.options //如果要获取url中所带的参数可以查看options + // #endif + + return res +} + + +export function urlDecode(query) { + if (!query) return null + let hash, object = {} + const hashes = query.slice(query.indexOf('?') + 1).split('&') + for (let i = 0; i < hashes.length; i++) { + hash = hashes[i].split('=') + object[hash[0]] = hash[1] + } + + return object; +} + +//根据名称返回是图片还是pdf +export function getFileType(filename) { + const lowercaseFilename = filename.toLowerCase(); + + if (lowercaseFilename.endsWith('.jpg') || lowercaseFilename.endsWith('.jpeg') || lowercaseFilename.endsWith( + '.png') || lowercaseFilename.endsWith('.gif')) { + return 'image'; + } else if (lowercaseFilename.endsWith('.pdf')) { + return 'pdf'; + } else if (lowercaseFilename.endsWith('.xls') || lowercaseFilename.endsWith('.xlsx')) { + return 'excel'; + } else { + return 'other'; + } } \ No newline at end of file