diff --git a/bash.exe.stackdump b/bash.exe.stackdump new file mode 100644 index 0000000..99f4eeb --- /dev/null +++ b/bash.exe.stackdump @@ -0,0 +1,9 @@ +Stack trace: +Frame Function Args +000FFFFA2B0 00210062B0E (00210292088, 00210270E3E, 000FFFFA2B0, 000FFFF91B0) +000FFFFA2B0 0021004846A (00000000000, 00000000000, 00000000000, 00000000000) +000FFFFA2B0 002100484A2 (00210292139, 000FFFFA168, 000FFFFA2B0, 00000000000) +000FFFFA2B0 002100CEE4E (00000000000, 00000000000, 00000000000, 00000000000) +000FFFFA2B0 002100CEF75 (000FFFFA2C0, 00000000000, 00000000000, 00000000000) +000FFFFA580 002100D0535 (000FFFFA2C0, 00000000000, 00000000000, 00000000000) +End of stack trace diff --git a/src/addon/erp/api/product.ts b/src/addon/erp/api/product.ts index b067c85..4fec049 100644 --- a/src/addon/erp/api/product.ts +++ b/src/addon/erp/api/product.ts @@ -191,4 +191,12 @@ export function deleteProduct(id : number) { showErrorMessage: true, showSuccessMessage: true, }); -} \ No newline at end of file +} +/** + * 获取食材分类tree + * @param params + * @returns + */ +export function getProductClassifyTreeList(params : Record) { + return request.get(`erp/product/tree`, params); +} diff --git a/src/addon/erp/erp.zip b/src/addon/erp/erp.zip index 605bbe4..335ee7c 100644 Binary files a/src/addon/erp/erp.zip and b/src/addon/erp/erp.zip differ diff --git a/src/addon/erp/pages/inbound/order/add.vue b/src/addon/erp/pages/inbound/order/add.vue index cf8c11a..2892e2f 100644 --- a/src/addon/erp/pages/inbound/order/add.vue +++ b/src/addon/erp/pages/inbound/order/add.vue @@ -408,7 +408,7 @@ return redirect({ url: '/addon/erp/pages/product/product/product-select', param: { - type: 'all' + warehouse_id: formData.value.warehouse_id }, }) } diff --git a/src/addon/erp/pages/inbound/stockPending/add.vue b/src/addon/erp/pages/inbound/stockPending/add.vue index 2c1deec..5c76359 100644 --- a/src/addon/erp/pages/inbound/stockPending/add.vue +++ b/src/addon/erp/pages/inbound/stockPending/add.vue @@ -443,7 +443,7 @@ return redirect({ url: '/addon/erp/pages/product/product/product-select', param: { - type: 'all' + warehouse_id: formData.value.warehouse_id }, }) } diff --git a/src/addon/erp/pages/outbound/outPending/add.vue b/src/addon/erp/pages/outbound/outPending/add.vue index d1f19a0..5d901f3 100644 --- a/src/addon/erp/pages/outbound/outPending/add.vue +++ b/src/addon/erp/pages/outbound/outPending/add.vue @@ -490,7 +490,7 @@ }); // 保存 - const handSave = async() => {s + const handSave = async() => { if (loading.value) return if (!formData.value.customer_id) { uni.showToast({ icon: 'none', title:'请选择食堂' }) diff --git a/src/addon/erp/pages/product/product/list.vue b/src/addon/erp/pages/product/product/list.vue index 63e0d21..d117325 100644 --- a/src/addon/erp/pages/product/product/list.vue +++ b/src/addon/erp/pages/product/product/list.vue @@ -1,8 +1,16 @@ @@ -75,10 +85,11 @@ import { topTabar } from '@/utils/topTabbar'; import { t } from '@/locale'; import { redirect, pxToRpx } from '@/utils/common'; + import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue" import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'; import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue'; import useMescroll from '@/components/mescroll/hooks/useMescroll.js'; - import { getProductList, deleteProduct } from '@/addon/erp/api/product'; + import { getProductList, deleteProduct, getProductClassifyTreeList } from '@/addon/erp/api/product'; import { onShow, onPageScroll, onReachBottom } from '@dcloudio/uni-app'; import usePermission from '@/utils/usePermission' const { hasPermission } = usePermission() @@ -97,10 +108,15 @@ const mescrollTop = "20rpx" const productList = ref>([]), - loading = ref(true), - listLoading = ref(true), + loading = ref(false), + listLoading = ref(false), mescrollRef = ref(null); - + const productClassifyTreeList = ref([]) + const treePicker = ref(null) + const productQuery = ref({ + type_name: '', + type_id: '', + }) interface mescrollStructure { num : number, size : number, @@ -112,7 +128,8 @@ listLoading.value = true; let data : Object = { page: mescroll.num, - limit: mescroll.size + limit: mescroll.size, + product_type_id: productQuery.value.type_id }; getProductList(data).then((res : any) => { let newArr = res.data.data; @@ -134,7 +151,27 @@ mescroll.endErr(); // 请求失败, 结束加载 }) } - + // 获取食材分类 + const getProductClassifyTree = () => { + getProductClassifyTreeList({}).then((res : any) => { + productClassifyTreeList.value = res.data + }).catch(err => { + // 如果是4001,没有绑定企业账号,强制跳转绑定 + if (err.code == 4001) { + redirect({ url: '/addon/erp/pages/member/bind' }) + } + }) + } + // 显示选择器 + const showPicker = () => { + treePicker.value._show(); + } + //监听选择(ids为数组) + const selectChange = (ids : any, names : any) => { + productQuery.value.type_id = ids.length > 0 ? ids[0] : '' + productQuery.value.type_name = names + getMescroll().resetUpScroll() + } // 删除 const del_id = ref(0); const hanldeDelete = (id : number) => { @@ -155,7 +192,13 @@ show.value = false; }).catch(() => { }); } + getProductClassifyTree() - \ No newline at end of file diff --git a/src/addon/erp/pages/product/product/out-product-select.vue b/src/addon/erp/pages/product/product/out-product-select.vue index d4cf910..6b685cf 100644 --- a/src/addon/erp/pages/product/product/out-product-select.vue +++ b/src/addon/erp/pages/product/product/out-product-select.vue @@ -1,56 +1,65 @@ @@ -71,22 +81,26 @@ import { topTabar } from '@/utils/topTabbar'; import { t } from '@/locale'; import { redirect, pxToRpx } from '@/utils/common'; + import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue" import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'; import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue'; import useMescroll from '@/components/mescroll/hooks/useMescroll.js'; - import { getProductList,getProductListByWarehouseNew} from '@/addon/erp/api/product'; + import { getProductListByWarehouseNew, getProductClassifyTreeList } from '@/addon/erp/api/product'; import { onLoad, onPageScroll, onReachBottom } from '@dcloudio/uni-app'; const { downCallback, mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom); - + const productClassifyTreeList = ref([]) const checkProductList = ref([]); - const queryType = ref('all'); // 查询方式 all 获取全部食材, warehouse 根据仓库ID ,获取对应的食材 const warehouse_id = ref(undefined); // 仓库Id - const supplier_id= ref(undefined); // 供应商Id + const supplier_id = ref(undefined); // 供应商Id + const treePicker = ref(null) + const productQuery = ref({ + type_name:'', + type_id:'', + }) // 页面加载 onLoad((option : any) => { - queryType.value = option.type ? option.type : ''; warehouse_id.value = option.warehouse_id ? option.warehouse_id : undefined supplier_id.value = option.supplier_id ? option.supplier_id : undefined }) @@ -95,8 +109,8 @@ const mescrollTop = "20rpx" const productList = ref>([]), - loading = ref(true), - listLoading = ref(true), + loading = ref(false), + listLoading = ref(false), mescrollRef = ref(null); interface mescrollStructure { @@ -106,18 +120,28 @@ [propName : string] : any } + // 获取食材分类 + const getProductClassifyTree = () => { + getProductClassifyTreeList({}).then((res : any) => { + productClassifyTreeList.value = res.data + }).catch(err => { + // 如果是4001,没有绑定企业账号,强制跳转绑定 + if (err.code == 4001) { + redirect({ url: '/addon/erp/pages/member/bind' }) + } + }) + } const getListFn = (mescroll : mescrollStructure) => { listLoading.value = true; + loading.value = true; let data : Object = { page: mescroll.num, limit: mescroll.size, warehouse_id: warehouse_id.value, - supplier_id: supplier_id.value + supplier_id: supplier_id.value, + product_type_id: productQuery.value.type_id }; - let getDataApi = - queryType.value == "all" ? getProductList : getProductListByWarehouseNew; - - getDataApi(data).then((res : any) => { + getProductListByWarehouseNew(data).then((res : any) => { let newArr = res.data.data; mescroll.endSuccess(newArr.length); //设置列表数据 @@ -137,7 +161,16 @@ mescroll.endErr(); // 请求失败, 结束加载 }) } - + // 显示选择器 + const showPicker = () => { + treePicker.value._show(); + } + //监听选择(ids为数组) + const selectChange = (ids : any, names : any) => { + productQuery.value.type_id = ids.length > 0 ? ids[0] : '' + productQuery.value.type_name = names + getMescroll().resetUpScroll() + } // 确认选择 const onConfirm = () => { uni.$emit('choose_product-out', checkProductList.value); @@ -146,7 +179,12 @@ delta: 1 }); } + getProductClassifyTree() - \ No newline at end of file diff --git a/src/addon/erp/pages/product/product/product-select.vue b/src/addon/erp/pages/product/product/product-select.vue index 36d9e7b..4ccb262 100644 --- a/src/addon/erp/pages/product/product/product-select.vue +++ b/src/addon/erp/pages/product/product/product-select.vue @@ -1,48 +1,58 @@ @@ -63,18 +74,24 @@ import { topTabar } from '@/utils/topTabbar'; import { t } from '@/locale'; import { redirect, pxToRpx } from '@/utils/common'; + import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue" import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue'; import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue'; import useMescroll from '@/components/mescroll/hooks/useMescroll.js'; - import { getProductList, getProductListByWarehouse,getProductListByWarehouseNew} from '@/addon/erp/api/product'; + import { getProductListByWarehouse, getProductClassifyTreeList } from '@/addon/erp/api/product'; import { onLoad, onPageScroll, onReachBottom } from '@dcloudio/uni-app'; const { downCallback, mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom); - + const productClassifyTreeList = ref([]); const checkProductList = ref([]); const queryType = ref('all'); // 查询方式 all 获取全部食材, warehouse 根据仓库ID ,获取对应的食材 const warehouse_id = ref(undefined); // 仓库Id + const treePicker = ref(null) + const productQuery = ref({ + type_name:'', + type_id:'', + }) // 页面加载 onLoad((option : any) => { queryType.value = option.type ? option.type : ''; @@ -83,8 +100,8 @@ const mescrollTop = "20rpx" const productList = ref>([]), - loading = ref(true), - listLoading = ref(true), + loading = ref(false), + listLoading = ref(false), mescrollRef = ref(null); interface mescrollStructure { @@ -94,17 +111,28 @@ [propName : string] : any } + // 获取食材分类 + const getProductClassifyTree = () => { + getProductClassifyTreeList({}).then((res : any) => { + productClassifyTreeList.value = res.data + }).catch(err => { + // 如果是4001,没有绑定企业账号,强制跳转绑定 + if (err.code == 4001) { + redirect({ url: '/addon/erp/pages/member/bind' }) + } + }) + } + const getListFn = (mescroll : mescrollStructure) => { listLoading.value = true; + loading.value = true; let data : Object = { page: mescroll.num, limit: mescroll.size, - warehouse_id: warehouse_id.value + warehouse_id: warehouse_id.value, + product_type_id: productQuery.value.type_id }; - let getDataApi = - queryType.value == "all" ? getProductList :queryType.value == "new" ?getProductListByWarehouseNew: getProductListByWarehouse; - - getDataApi(data).then((res : any) => { + getProductListByWarehouse(data).then((res : any) => { let newArr = res.data.data; mescroll.endSuccess(newArr.length); //设置列表数据 @@ -124,7 +152,16 @@ mescroll.endErr(); // 请求失败, 结束加载 }) } - + // 显示选择器 + const showPicker = () => { + treePicker.value._show(); + } + //监听选择(ids为数组) + const selectChange = (ids : any, names : any) => { + productQuery.value.type_id = ids.length > 0 ? ids[0] : '' + productQuery.value.type_name = names + getMescroll().resetUpScroll() + } // 确认选择 const onConfirm = () => { uni.$emit('choose_product', checkProductList.value); @@ -133,7 +170,12 @@ delta: 1 }); } + getProductClassifyTree() - \ No newline at end of file diff --git a/src/addon/erp/pages/purchase/return/add.vue b/src/addon/erp/pages/purchase/return/add.vue index 73f33e7..dcb9362 100644 --- a/src/addon/erp/pages/purchase/return/add.vue +++ b/src/addon/erp/pages/purchase/return/add.vue @@ -328,7 +328,6 @@ return redirect({ url: '/addon/erp/pages/product/product/out-product-select', param: { - type: 'warehouse', warehouse_id: formData.value.warehouse_id, supplier_id: formData.value.supplier_id, }, diff --git a/src/components/ba-tree-picker/README.md b/src/components/ba-tree-picker/README.md new file mode 100644 index 0000000..59d99f9 --- /dev/null +++ b/src/components/ba-tree-picker/README.md @@ -0,0 +1,124 @@ +## 树形层级选择器 +### 简介 +为统一样式而生,树形层级选择器,picker弹窗形式的,样式和比例参照uniapp的picker和uni-data-picker组件 +* 支持单选、多选、父级选择,当然也支持单层选择 +* 支持Object对象属性自定义映射 +* 支持显示全部选中、部分选中、未选中三种状态 +* 支持快速自定义简单样式(分割线、按钮、标题、对齐等),深入样式可复写css + +### 使用方法 +在 `script` 中引入组件 +``` javascript + import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue" + export default { + components: { + baTreePicker + } +``` +在 `template` 中使用组件 +``` javascript + +``` +在 `script` 中定义打开方法,和选择监听 +``` javascript + methods: { + // 显示选择器 + showPicker() { + this.$refs.treePicker._show(); + }, + //监听选择(ids为数组) + selectChange(ids, names) { + console.log(ids, names) + } + } +``` +在 `template` 中调用打开 +``` javascript + 调用选择器 +``` + +### 属性 +|属性名|类型|默认值|说明| +|:-|:-:|:--:|-:| +|localdata|Array|[]|源数据,目前支持tree结构,后续会考虑支持扁平化结构| +|valueKey|String|id|指定 Object 中 key 的值作为节点数据id| +|textKey|String|name|指定 Object 中 key 的值作为节点显示内容| +|childrenKey|String|children|指定 Object 中 key 的值作为节点子集| +|multiple|Boolean|false|是否多选,默认单选| +|selectParent|Boolean|true|是否可以选父级,默认可以| +|title|String| |标题| +|titleColor|String||标题颜色| +|confirmColor|String|#0055ff|确定按钮颜色| +|cancelColor|String|#757575|取消按钮颜色| +|switchColor|String|#666|节点切换图标颜色| +|border|Boolean|false|是否有分割线,默认无| + + + +### 数据格式 + +注意:必须有id、name(id可通过valueKey来配置为其它键值,如value)字段,且唯一 + +``` json +[ + { + id: 1, + name: '公司1', + children: [{ + id: 11, + name: '研发部', + children: [{ + id: 111, + name: '张三', + + },{ + id: 112, + name: '李四', + + }] + },{ + id: 12, + name: '综合部', + + } ] + }, + { + id: 2, + name: '公司2', + children: [{ + id: 21, + name: '研发部', + + },{ + id: 22, + name: '综合部', + + },{ + id: 23, + name: '财务部', + + }, ] + }, + { + id: 3, + name: '公司3' + }, + { + id: 4, + name: '公司4', + children: [{ + id: 41, + name: '研发部', + + }] + } +] +``` + + +### 方法 +|方法名|参数|默认值|说明| +|:-|:-:|:--:|-:| +|_show()| | |显示选择器| +|_hide()| | |隐藏选择器| diff --git a/src/components/ba-tree-picker/ba-tree-picker.vue b/src/components/ba-tree-picker/ba-tree-picker.vue new file mode 100644 index 0000000..5863700 --- /dev/null +++ b/src/components/ba-tree-picker/ba-tree-picker.vue @@ -0,0 +1,624 @@ + + + + + + +