17个文件已添加
15个文件已修改
3044 ■■■■■ 已修改文件
.gitignore 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build/cool/eps.d.ts 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build/cool/eps.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/base/pages/main/components/slider.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/locales/en.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/locales/zh-cn.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/locales/zh-tw.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/views/site.vue 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/views/sorter.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/ezuikit/components/ezuikit-player.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/maps/locales/en.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/maps/locales/zh-cn.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/maps/locales/zh-tw.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/maps/views/layers.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/monitor/components/site-tree.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/monitor/views/capturetask.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/monitor/views/device.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/components/item-select.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/components/order-detail.vue 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/components/order-select.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/locales/en.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/locales/zh-cn.json 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/locales/zh-tw.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/views/appointment.vue 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/views/recycleitem.vue 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/views/recycleorder.vue 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/views/recycleorderitem.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/shop/views/transaction.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/user/locales/zh-cn.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/user/views/list.vue 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
大件垃圾回收.txt 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -2,7 +2,8 @@
node_modules/
/dist/
dist-ssr/
build/
build/cool/eps.d.ts
build/cool/eps.json
# Log files
npm-debug.log*
README.md
@@ -2,3 +2,7 @@
源无忧无废校园-前端
使用组件 https://lvzhao1995.github.io/vue-tianditu/  éž vue-tianditu
pnpm add vue-tianditu2
build/cool/eps.d.ts
@@ -1071,6 +1071,73 @@
        [key: string]: any;
    }
    interface PushCaptureTaskEntity {
        /**
         * ID
         */
        id?: number;
        /**
         * è®¾å¤‡åºåˆ—号
         */
        deviceSerial?: string;
        /**
         * é€šé“号
         */
        channelNo?: number;
        /**
         * æŠ“图任务ID(萤石返回)
         */
        captureTaskId?: string;
        /**
         * äº‘空间spaceId
         */
        spaceId?: string;
        /**
         * å›¾ç‰‡åœ¨äº‘空间的URL
         */
        cloudUrl?: string;
        /**
         * å›¾ç‰‡åœ¨æœ¬åœ°çš„URL
         */
        localUrl?: string;
        /**
         * æœ¬åœ°å­˜å‚¨è·¯å¾„
         */
        localPath?: string;
        /**
         * æŠ“拍状态
         */
        status?: string;
        /**
         * ä»»åŠ¡æ‰§è¡Œæ—¥æœŸ
         */
        captureDate?: string;
        /**
         * åˆ›å»ºæ—¶é—´
         */
        createTime?: string;
        /**
         * æ›´æ–°æ—¶é—´
         */
        updateTime?: string;
        /**
         * ä»»æ„é”®å€¼
         */
        [key: string]: any;
    }
    interface OperationTradeRecordEntity {
        /**
         * ID
@@ -2973,6 +3040,15 @@
    type json = any;
    type DictKey =
        | "ratedpayload"
        | "iottype"
        | "sitetype"
        | "datachanel"
        | "vehicletype"
        | "businesstype"
        | "appointmentslot";
    interface PagePagination {
        size: number;
        page: number;
@@ -3059,6 +3135,11 @@
    interface DictTypePageResponse {
        pagination: PagePagination;
        list: DictTypeEntity[];
    }
    interface MonitorCapturetaskPageResponse {
        pagination: PagePagination;
        list: PushCaptureTaskEntity[];
    }
    interface OperationTraderecordPageResponse {
@@ -3468,6 +3549,11 @@
    interface BaseSysParam {
        /**
         * èŽ·å¾—ç½‘é¡µå†…å®¹çš„å‚æ•°å€¼
         */
        stringbykey(data?: any): Promise<any>;
        /**
         * åˆ é™¤
         */
        delete(data?: any): Promise<any>;
@@ -3501,6 +3587,7 @@
         * æƒé™æ ‡è¯†
         */
        permission: {
            stringbykey: string;
            delete: string;
            update: string;
            html: string;
@@ -3513,6 +3600,7 @@
         * æƒé™çŠ¶æ€
         */
        _permission: {
            stringbykey: boolean;
            delete: boolean;
            update: boolean;
            html: boolean;
@@ -3770,6 +3858,11 @@
        getYsDevices(data?: any): Promise<any>;
        /**
         * èŽ·å–ç«™ç‚¹åˆ—è¡¨
         */
        getSitelist(data?: any): Promise<any>;
        /**
         * åˆ é™¤
         */
        delete(data?: any): Promise<any>;
@@ -3804,6 +3897,7 @@
         */
        permission: {
            getYsDevices: string;
            getSitelist: string;
            delete: string;
            update: string;
            info: string;
@@ -3817,6 +3911,7 @@
         */
        _permission: {
            getYsDevices: boolean;
            getSitelist: boolean;
            delete: boolean;
            update: boolean;
            info: boolean;
@@ -4244,6 +4339,64 @@
         * åˆ†é¡µæŸ¥è¯¢
         */
        page(data?: any): Promise<DictTypePageResponse>;
        /**
         * æ–°å¢ž
         */
        add(data?: any): Promise<any>;
        /**
         * æƒé™æ ‡è¯†
         */
        permission: {
            delete: string;
            update: string;
            info: string;
            list: string;
            page: string;
            add: string;
        };
        /**
         * æƒé™çŠ¶æ€
         */
        _permission: {
            delete: boolean;
            update: boolean;
            info: boolean;
            list: boolean;
            page: boolean;
            add: boolean;
        };
        request: Request;
    }
    interface MonitorCapturetask {
        /**
         * åˆ é™¤
         */
        delete(data?: any): Promise<any>;
        /**
         * ä¿®æ”¹
         */
        update(data?: any): Promise<any>;
        /**
         * å•个信息
         */
        info(data?: any): Promise<PushCaptureTaskEntity>;
        /**
         * åˆ—表查询
         */
        list(data?: any): Promise<PushCaptureTaskEntity[]>;
        /**
         * åˆ†é¡µæŸ¥è¯¢
         */
        page(data?: any): Promise<MonitorCapturetaskPageResponse>;
        /**
         * æ–°å¢ž
@@ -5501,7 +5654,7 @@
        };
        demo: { goods: DemoGoods; tenant: DemoTenant };
        dict: { info: DictInfo; type: DictType };
        monitor: { ys7: MonitorYs7 };
        monitor: { capturetask: MonitorCapturetask; ys7: MonitorYs7 };
        operation: { traderecord: OperationTraderecord; wastesale: OperationWastesale };
        plugin: { info: PluginInfo };
        push: {
build/cool/eps.json
@@ -1 +1 @@
[{"prefix":"/admin/base/coding","name":"","api":[{"method":"get","path":"/getModuleTree"},{"method":"post","path":"/createCode"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/comm","name":"","api":[{"method":"post","path":"/personUpdate"},{"method":"get","path":"/uploadMode"},{"method":"get","path":"/permmenu"},{"method":"get","path":"/program"},{"method":"get","path":"/person"},{"method":"post","path":"/upload"},{"method":"post","path":"/logout"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/open","name":"","api":[{"method":"get","path":"/refreshToken"},{"method":"get","path":"/captcha"},{"method":"post","path":"/login"},{"method":"get","path":"/html"},{"method":"get","path":"/eps"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/department","name":"BaseSysDepartmentEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/order"},{"method":"post","path":"/list"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/log","name":"BaseSysLogEntity","api":[{"method":"post","path":"/setKeep"},{"method":"get","path":"/getKeep"},{"method":"post","path":"/clear"},{"method":"post","path":"/page"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"姓名","nullable":true,"source":"b.name"},{"propertyName":"action","type":"string","length":"","comment":"行为","nullable":false,"source":"a.action"},{"propertyName":"ip","type":"string","length":"","comment":"ip","nullable":true,"source":"a.ip"}]}},{"prefix":"/admin/base/sys/menu","name":"BaseSysMenuEntity","api":[{"method":"post","path":"/create"},{"method":"post","path":"/export"},{"method":"post","path":"/import"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/parse"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/param","name":"BaseSysParamEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/html"},{"method":"get","path":"/info"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"dataType","type":"number","length":"","comment":"数据类型 0-字符串 1-富文本 2-文件 ","nullable":false,"defaultValue":0,"source":"a.dataType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"keyName","type":"string","length":"","comment":"键","nullable":false,"source":"a.keyName"}]}},{"prefix":"/admin/base/sys/role","name":"BaseSysRoleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"label","type":"string","length":"50","comment":"角色标签","nullable":true,"source":"a.label"}]}},{"prefix":"/admin/base/sys/user","name":"BaseSysUserEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/move"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/basicdata/buyer","name":"BasicdataBuyerEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"部门ID","nullable":true,"source":"a.departmentId"},{"propertyName":"name","type":"string","length":"200","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"contact","type":"string","length":"50","comment":"联系人","nullable":true,"source":"a.contact"}],"fieldLike":[{"propertyName":"name","type":"string","length":"200","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"address","type":"string","length":"255","comment":"地址","nullable":true,"source":"a.address"}],"keyWordLikeFields":[]}},{"prefix":"/admin/basicdata/driver","name":"BasicdataDriverEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["激活","禁用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessId","type":"string","length":"64","comment":"身份证号","nullable":false,"source":"a.businessId"},{"propertyName":"phone","type":"string","length":"32","comment":"手机号","nullable":true,"source":"a.phone"},{"propertyName":"licenseNo","type":"string","length":"64","comment":"驾驶证号","nullable":true,"source":"a.licenseNo"}]}},{"prefix":"/admin/basicdata/iot","name":"BasicdataIotEntity","api":[{"method":"post","path":"/getYsDevices"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"iotTypeCode","type":"string","length":"","comment":"终端类型","nullable":false,"source":"a.iotTypeCode"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"iotName","type":"string","length":"","comment":"终端名称","nullable":false,"source":"a.iotName"},{"propertyName":"iotCode","type":"string","length":"","comment":"终端编码","nullable":false,"source":"a.iotCode"}]}},{"prefix":"/admin/basicdata/site","name":"BasicdataSiteEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"number","length":"","comment":"归属单位","nullable":false,"source":"a.departmentId"},{"propertyName":"siteType","type":"string","length":"","comment":"站点类型","nullable":false,"defaultValue":"收集点","dict":"sitetype","source":"a.siteType"},{"propertyName":"status","type":"number","length":"","comment":"是否启用","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"address","type":"string","length":"","comment":"地址","nullable":false,"source":"a.address"},{"propertyName":"leader","type":"string","length":"","comment":"负责人","nullable":false,"source":"a.leader"}]}},{"prefix":"/admin/basicdata/sorter","name":"BasicdataSorterEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["在职","离职","禁用"],"source":"a.status"},{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessName","type":"string","length":"64","comment":"姓名","nullable":false,"source":"a.businessName"},{"propertyName":"businessId","type":"string","length":"32","comment":"身份证号","nullable":true,"source":"a.businessId"},{"propertyName":"phone","type":"string","length":"32","comment":"手机号","nullable":true,"source":"a.phone"}]}},{"prefix":"/admin/basicdata/vehicle","name":"BasicdataVehicleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"vehicleType","type":"string","length":"","comment":"车型","nullable":false,"defaultValue":"厢式货车","dict":"vehicletype","source":"a.vehicleType"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["启用","禁用"],"source":"a.status"},{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessId","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.businessId"},{"propertyName":"defaultDriver","type":"bigint","length":"","comment":"默认司机","nullable":true,"source":"a.defaultDriver"}]}},{"prefix":"/admin/basicdata/wastetype","name":"BasicdataWastetypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"isRecyclable","type":"number","length":"","comment":"是否可回收","nullable":false,"defaultValue":0,"dict":["否","是"],"source":"a.isRecyclable"},{"propertyName":"status","type":"number","length":"","comment":"是否启用","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"code","type":"string","length":"","comment":"代码","nullable":false,"source":"a.code"}]}},{"prefix":"/admin/demo/goods","name":"DemoGoodsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[{"propertyName":"title","type":"string","length":"50","comment":"标题","nullable":false,"source":"a.title"}],"keyWordLikeFields":[{"propertyName":"description","type":"string","length":"","comment":"描述","nullable":true,"source":"a.description"}]}},{"prefix":"/admin/demo/tenant","name":"DemoGoodsEntity","api":[{"method":"post","path":"/noTenant"},{"method":"post","path":"/noUse"},{"method":"post","path":"/use"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/dict/info","name":"DictInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/types"},{"method":"post","path":"/data"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/dict/type","name":"DictTypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/monitor/ys7","name":"","api":[{"method":"post","path":"/getToken"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/operation/traderecord","name":"OperationTradeRecordEntity","api":[{"method":"post","path":"/import"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"transactionType","type":"string","length":"","comment":"交易类型","nullable":true,"source":"a.transactionType"},{"propertyName":"incomeType","type":"string","length":"","comment":"收支类型","nullable":false,"defaultValue":"收入","dict":["收入","支出","其他"],"source":"a.incomeType"},{"propertyName":"payMethod","type":"string","length":"","comment":"支付方式","nullable":true,"source":"a.payMethod"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"goodsName","type":"string","length":"","comment":"商品名称","nullable":true,"source":"a.goodsName"},{"propertyName":"opponent","type":"string","length":"","comment":"交易对方","nullable":true,"source":"a.opponent"}]}},{"prefix":"/admin/operation/wastesale","name":"OperationWastesaleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"部门ID","nullable":false,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/plugin/info","name":"PluginInfoEntity","api":[{"method":"post","path":"/install"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/push/auditlog","name":"PushAuditlogEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"客户端ID","nullable":false,"source":"a.deviceNo"},{"propertyName":"pushType","type":"string","length":"","comment":"推送类型","nullable":false,"defaultValue":"weight","dict":["weight","health_gps","vehicle_gps","driver_anomaly","others"],"source":"a.pushType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"errorMessage","type":"text","length":"","comment":"错误返回信息","nullable":true,"source":"a.errorMessage"}]}},{"prefix":"/admin/push/cameragps","name":"PushCameraGpsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"string","length":"","comment":"定位精度","nullable":false,"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"sn","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.sn"}]}},{"prefix":"/admin/push/devicealarm","name":"PushDevicealarmEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"devSerial","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.devSerial"},{"propertyName":"departmentName","type":"string","length":"","comment":"部门名称","nullable":false,"source":"c.name"}]}},{"prefix":"/admin/push/deviceonoff","name":"PushDeviceOnoffEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"deviceId","type":"string","length":"","comment":"设备ID","nullable":false,"source":"a.deviceId"},{"propertyName":"subSerial","type":"string","length":"","comment":"子序列号","nullable":true,"source":"a.subSerial"},{"propertyName":"deviceName","type":"string","length":"","comment":"设备名称","nullable":true,"source":"a.deviceName"}]}},{"prefix":"/admin/push/siteweight","name":"PushSiteweightEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"},{"propertyName":"siteType","type":"string","length":"","comment":"站点类型","nullable":false,"defaultValue":"收集点","dict":"sitetype","source":"d.siteType"}],"fieldLike":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"}],"keyWordLikeFields":[]}},{"prefix":"/admin/push/vehiclegps","name":"PushVehicleGpsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"string","length":"","comment":"定位精度","nullable":false,"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"sn","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.sn"},{"propertyName":"vehicleNo","type":"string","length":"","comment":"车牌号","nullable":true,"source":"a.vehicleNo"}]}},{"prefix":"/admin/push/weight","name":"PushWeightEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"},{"propertyName":"garbageType","type":"string","length":"","comment":"垃圾类型","nullable":false,"source":"a.garbageType"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/recycle/data","name":"RecycleDataEntity","api":[{"method":"post","path":"/restore"},{"method":"get","path":"/info"},{"method":"post","path":"/page"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"userName","type":"string","length":"","comment":"姓名","nullable":true,"source":"b.name"},{"propertyName":"url","type":"string","length":"","comment":"请求的接口","nullable":true,"source":"a.url"}]}},{"prefix":"/admin/report/dailydepartment","name":"ReportDailyDepartmentEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"departmentId","type":"number","length":"","comment":"部门ID","nullable":false,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"departmentName","type":"string","length":"","comment":"部门名称","nullable":false,"source":"a.departmentName"}]}},{"prefix":"/admin/report/dailysite","name":"ReportDailysiteEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"siteId","type":"number","length":"","comment":"站点ID","nullable":false,"source":"a.siteId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"siteName","type":"string","length":"","comment":"站点名称","nullable":false,"source":"a.siteName"}]}},{"prefix":"/admin/report/dailyvehicle","name":"ReportDailyVehicleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"vehicleNo","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.vehicleNo"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"vehicleNo","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.vehicleNo"}]}},{"prefix":"/admin/report/joblog","name":"ReportJoblogEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"dataDate","type":"date","length":"","comment":"数据目标日期","nullable":false,"source":"a.dataDate"},{"propertyName":"status","type":"enum","length":"","comment":"状态: æœªå¼€å§‹, è¿è¡Œä¸­, æˆåŠŸ, å¤±è´¥","nullable":false,"defaultValue":"INIT","source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"jobName","type":"string","length":"","comment":"任务类型: SITE_DAILY(站点日汇总), DEPT_DAILY(部门日汇总)","nullable":false,"source":"a.jobName"}]}},{"prefix":"/admin/space/info","name":"SpaceInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"type","type":"string","length":"","comment":"类型","nullable":false,"source":"a.type"},{"propertyName":"classifyId","type":"number","length":"","comment":"分类ID","nullable":true,"source":"a.classifyId"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/space/type","name":"SpaceTypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/task/info","name":"TaskInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/start"},{"method":"post","path":"/once"},{"method":"post","path":"/stop"},{"method":"get","path":"/info"},{"method":"post","path":"/page"},{"method":"get","path":"/log"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态 0-停止 1-运行","nullable":false,"defaultValue":1,"source":"a.status"},{"propertyName":"type","type":"number","length":"","comment":"状态 0-系统 1-用户","nullable":false,"defaultValue":0,"source":"a.type"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/user/address","name":"UserAddressEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/user/info","name":"UserInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","正常","已注销"],"source":"a.status"},{"propertyName":"gender","type":"number","length":"","comment":"性别","nullable":false,"defaultValue":0,"dict":["未知","男","女"],"source":"a.gender"},{"propertyName":"loginType","type":"number","length":"","comment":"登录方式","nullable":false,"defaultValue":0,"dict":["小程序","公众号","H5"],"source":"a.loginType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"nickName","type":"string","length":"","comment":"昵称","nullable":true,"source":"a.nickName"},{"propertyName":"phone","type":"string","length":"","comment":"手机号","nullable":true,"source":"a.phone"}]}}]
[{"prefix":"/admin/base/coding","name":"","api":[{"method":"get","path":"/getModuleTree"},{"method":"post","path":"/createCode"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/comm","name":"","api":[{"method":"post","path":"/personUpdate"},{"method":"get","path":"/uploadMode"},{"method":"get","path":"/permmenu"},{"method":"get","path":"/program"},{"method":"get","path":"/person"},{"method":"post","path":"/upload"},{"method":"post","path":"/logout"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/open","name":"","api":[{"method":"get","path":"/refreshToken"},{"method":"get","path":"/captcha"},{"method":"post","path":"/login"},{"method":"get","path":"/html"},{"method":"get","path":"/eps"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/department","name":"BaseSysDepartmentEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/order"},{"method":"post","path":"/list"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/log","name":"BaseSysLogEntity","api":[{"method":"post","path":"/setKeep"},{"method":"get","path":"/getKeep"},{"method":"post","path":"/clear"},{"method":"post","path":"/page"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"姓名","nullable":true,"source":"b.name"},{"propertyName":"action","type":"string","length":"","comment":"行为","nullable":false,"source":"a.action"},{"propertyName":"ip","type":"string","length":"","comment":"ip","nullable":true,"source":"a.ip"}]}},{"prefix":"/admin/base/sys/menu","name":"BaseSysMenuEntity","api":[{"method":"post","path":"/create"},{"method":"post","path":"/export"},{"method":"post","path":"/import"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/parse"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/base/sys/param","name":"BaseSysParamEntity","api":[{"method":"get","path":"/stringbykey"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/html"},{"method":"get","path":"/info"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"dataType","type":"number","length":"","comment":"数据类型 0-字符串 1-富文本 2-文件 ","nullable":false,"defaultValue":0,"source":"a.dataType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"keyName","type":"string","length":"","comment":"键","nullable":false,"source":"a.keyName"}]}},{"prefix":"/admin/base/sys/role","name":"BaseSysRoleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"label","type":"string","length":"50","comment":"角色标签","nullable":true,"source":"a.label"}]}},{"prefix":"/admin/base/sys/user","name":"BaseSysUserEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/move"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/basicdata/buyer","name":"BasicdataBuyerEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"部门ID","nullable":true,"source":"a.departmentId"},{"propertyName":"name","type":"string","length":"200","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"contact","type":"string","length":"50","comment":"联系人","nullable":true,"source":"a.contact"}],"fieldLike":[{"propertyName":"name","type":"string","length":"200","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"address","type":"string","length":"255","comment":"地址","nullable":true,"source":"a.address"}],"keyWordLikeFields":[]}},{"prefix":"/admin/basicdata/driver","name":"BasicdataDriverEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["激活","禁用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessId","type":"string","length":"64","comment":"身份证号","nullable":false,"source":"a.businessId"},{"propertyName":"phone","type":"string","length":"32","comment":"手机号","nullable":true,"source":"a.phone"},{"propertyName":"licenseNo","type":"string","length":"64","comment":"驾驶证号","nullable":true,"source":"a.licenseNo"}]}},{"prefix":"/admin/basicdata/iot","name":"BasicdataIotEntity","api":[{"method":"post","path":"/getYsDevices"},{"method":"post","path":"/getSitelist"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"iotTypeCode","type":"string","length":"","comment":"终端类型","nullable":false,"source":"a.iotTypeCode"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"iotName","type":"string","length":"","comment":"终端名称","nullable":false,"source":"a.iotName"},{"propertyName":"iotCode","type":"string","length":"","comment":"终端编码","nullable":false,"source":"a.iotCode"}]}},{"prefix":"/admin/basicdata/site","name":"BasicdataSiteEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/basicdata/sorter","name":"BasicdataSorterEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["在职","离职","禁用"],"source":"a.status"},{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessName","type":"string","length":"64","comment":"姓名","nullable":false,"source":"a.businessName"},{"propertyName":"businessId","type":"string","length":"32","comment":"身份证号","nullable":true,"source":"a.businessId"},{"propertyName":"phone","type":"string","length":"32","comment":"手机号","nullable":true,"source":"a.phone"}]}},{"prefix":"/admin/basicdata/vehicle","name":"BasicdataVehicleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"vehicleType","type":"string","length":"","comment":"车型","nullable":false,"defaultValue":"厢式货车","dict":"vehicletype","source":"a.vehicleType"},{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":0,"dict":["启用","禁用"],"source":"a.status"},{"propertyName":"departmentId","type":"bigint","length":"","comment":"所属单位","nullable":true,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"businessId","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.businessId"},{"propertyName":"defaultDriver","type":"bigint","length":"","comment":"默认司机","nullable":true,"source":"a.defaultDriver"}]}},{"prefix":"/admin/basicdata/wastetype","name":"BasicdataWastetypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"isRecyclable","type":"number","length":"","comment":"是否可回收","nullable":false,"defaultValue":0,"dict":["否","是"],"source":"a.isRecyclable"},{"propertyName":"status","type":"number","length":"","comment":"是否启用","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"name","type":"string","length":"","comment":"名称","nullable":false,"source":"a.name"},{"propertyName":"code","type":"string","length":"","comment":"代码","nullable":false,"source":"a.code"}]}},{"prefix":"/admin/demo/goods","name":"DemoGoodsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","启用"],"source":"a.status"}],"fieldLike":[{"propertyName":"title","type":"string","length":"50","comment":"标题","nullable":false,"source":"a.title"}],"keyWordLikeFields":[{"propertyName":"description","type":"string","length":"","comment":"描述","nullable":true,"source":"a.description"}]}},{"prefix":"/admin/demo/tenant","name":"DemoGoodsEntity","api":[{"method":"post","path":"/noTenant"},{"method":"post","path":"/noUse"},{"method":"post","path":"/use"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/dict/info","name":"DictInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/types"},{"method":"post","path":"/data"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/dict/type","name":"DictTypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/monitor/capturetask","name":"PushCaptureTaskEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"string","length":"","comment":"抓拍状态","nullable":false,"defaultValue":"PENDING","dict":["PENDING","SUCCESS","FAILED"],"source":"a.status"},{"propertyName":"captureDate","type":"string","length":"","comment":"任务执行日期","nullable":true,"source":"a.captureDate"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"deviceSerial","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.deviceSerial"},{"propertyName":"captureTaskId","type":"string","length":"","comment":"抓图任务ID(萤石返回)","nullable":true,"source":"a.captureTaskId"}]}},{"prefix":"/admin/monitor/ys7","name":"","api":[{"method":"post","path":"/getToken"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/operation/traderecord","name":"OperationTradeRecordEntity","api":[{"method":"post","path":"/import"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"transactionType","type":"string","length":"","comment":"交易类型","nullable":true,"source":"a.transactionType"},{"propertyName":"incomeType","type":"string","length":"","comment":"收支类型","nullable":false,"defaultValue":"收入","dict":["收入","支出","其他"],"source":"a.incomeType"},{"propertyName":"payMethod","type":"string","length":"","comment":"支付方式","nullable":true,"source":"a.payMethod"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"goodsName","type":"string","length":"","comment":"商品名称","nullable":true,"source":"a.goodsName"},{"propertyName":"opponent","type":"string","length":"","comment":"交易对方","nullable":true,"source":"a.opponent"}]}},{"prefix":"/admin/operation/wastesale","name":"OperationWastesaleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"departmentId","type":"bigint","length":"","comment":"部门ID","nullable":false,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/plugin/info","name":"PluginInfoEntity","api":[{"method":"post","path":"/install"},{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/push/auditlog","name":"PushAuditlogEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"客户端ID","nullable":false,"source":"a.deviceNo"},{"propertyName":"pushType","type":"string","length":"","comment":"推送类型","nullable":false,"defaultValue":"weight","dict":["weight","health_gps","vehicle_gps","driver_anomaly","others"],"source":"a.pushType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"errorMessage","type":"text","length":"","comment":"错误返回信息","nullable":true,"source":"a.errorMessage"}]}},{"prefix":"/admin/push/cameragps","name":"PushCameraGpsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"string","length":"","comment":"定位精度","nullable":false,"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"sn","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.sn"}]}},{"prefix":"/admin/push/devicealarm","name":"PushDevicealarmEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"devSerial","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.devSerial"},{"propertyName":"departmentName","type":"string","length":"","comment":"部门名称","nullable":false,"source":"c.name"}]}},{"prefix":"/admin/push/deviceonoff","name":"PushDeviceOnoffEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"deviceId","type":"string","length":"","comment":"设备ID","nullable":false,"source":"a.deviceId"},{"propertyName":"subSerial","type":"string","length":"","comment":"子序列号","nullable":true,"source":"a.subSerial"},{"propertyName":"deviceName","type":"string","length":"","comment":"设备名称","nullable":true,"source":"a.deviceName"}]}},{"prefix":"/admin/push/siteweight","name":"PushSiteweightEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"},{"propertyName":"siteType","type":"string","length":"","comment":"站点类型","nullable":false,"defaultValue":"收集点","dict":"sitetype","source":"d.siteType"}],"fieldLike":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"}],"keyWordLikeFields":[]}},{"prefix":"/admin/push/vehiclegps","name":"PushVehicleGpsEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"string","length":"","comment":"定位精度","nullable":false,"source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"sn","type":"string","length":"","comment":"设备序列号","nullable":false,"source":"a.sn"},{"propertyName":"vehicleNo","type":"string","length":"","comment":"车牌号","nullable":true,"source":"a.vehicleNo"}]}},{"prefix":"/admin/push/weight","name":"PushWeightEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"deviceNo","type":"string","length":"","comment":"设备号","nullable":false,"source":"a.deviceNo"},{"propertyName":"garbageType","type":"string","length":"","comment":"垃圾类型","nullable":false,"source":"a.garbageType"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/recycle/data","name":"RecycleDataEntity","api":[{"method":"post","path":"/restore"},{"method":"get","path":"/info"},{"method":"post","path":"/page"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"userName","type":"string","length":"","comment":"姓名","nullable":true,"source":"b.name"},{"propertyName":"url","type":"string","length":"","comment":"请求的接口","nullable":true,"source":"a.url"}]}},{"prefix":"/admin/report/dailydepartment","name":"ReportDailyDepartmentEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"departmentId","type":"number","length":"","comment":"部门ID","nullable":false,"source":"a.departmentId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"departmentName","type":"string","length":"","comment":"部门名称","nullable":false,"source":"a.departmentName"}]}},{"prefix":"/admin/report/dailysite","name":"ReportDailysiteEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"siteId","type":"number","length":"","comment":"站点ID","nullable":false,"source":"a.siteId"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"siteName","type":"string","length":"","comment":"站点名称","nullable":false,"source":"a.siteName"}]}},{"prefix":"/admin/report/dailyvehicle","name":"ReportDailyVehicleEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"date","type":"date","length":"","comment":"日期","nullable":false,"source":"a.date"},{"propertyName":"vehicleNo","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.vehicleNo"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"vehicleNo","type":"string","length":"32","comment":"车牌号","nullable":false,"source":"a.vehicleNo"}]}},{"prefix":"/admin/report/joblog","name":"ReportJoblogEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"dataDate","type":"date","length":"","comment":"数据目标日期","nullable":false,"source":"a.dataDate"},{"propertyName":"status","type":"enum","length":"","comment":"状态: æœªå¼€å§‹, è¿è¡Œä¸­, æˆåŠŸ, å¤±è´¥","nullable":false,"defaultValue":"INIT","source":"a.status"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"jobName","type":"string","length":"","comment":"任务类型: SITE_DAILY(站点日汇总), DEPT_DAILY(部门日汇总)","nullable":false,"source":"a.jobName"}]}},{"prefix":"/admin/space/info","name":"SpaceInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"type","type":"string","length":"","comment":"类型","nullable":false,"source":"a.type"},{"propertyName":"classifyId","type":"number","length":"","comment":"分类ID","nullable":true,"source":"a.classifyId"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/space/type","name":"SpaceTypeEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/task/info","name":"TaskInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"post","path":"/start"},{"method":"post","path":"/once"},{"method":"post","path":"/stop"},{"method":"get","path":"/info"},{"method":"post","path":"/page"},{"method":"get","path":"/log"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态 0-停止 1-运行","nullable":false,"defaultValue":1,"source":"a.status"},{"propertyName":"type","type":"number","length":"","comment":"状态 0-系统 1-用户","nullable":false,"defaultValue":0,"source":"a.type"}],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/user/address","name":"UserAddressEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[],"fieldLike":[],"keyWordLikeFields":[]}},{"prefix":"/admin/user/info","name":"UserInfoEntity","api":[{"method":"post","path":"/delete"},{"method":"post","path":"/update"},{"method":"get","path":"/info"},{"method":"post","path":"/list"},{"method":"post","path":"/page"},{"method":"post","path":"/add"}],"search":{"fieldEq":[{"propertyName":"status","type":"number","length":"","comment":"状态","nullable":false,"defaultValue":1,"dict":["禁用","正常","已注销"],"source":"a.status"},{"propertyName":"gender","type":"number","length":"","comment":"性别","nullable":false,"defaultValue":0,"dict":["未知","男","女"],"source":"a.gender"},{"propertyName":"loginType","type":"number","length":"","comment":"登录方式","nullable":false,"defaultValue":0,"dict":["小程序","公众号","H5"],"source":"a.loginType"}],"fieldLike":[],"keyWordLikeFields":[{"propertyName":"nickName","type":"string","length":"","comment":"昵称","nullable":true,"source":"a.nickName"},{"propertyName":"phone","type":"string","length":"","comment":"手机号","nullable":true,"source":"a.phone"}]}}]
src/modules/base/pages/main/components/slider.vue
@@ -65,8 +65,8 @@
        user-select: none;
        img {
            height: 24px;
            width: 24px;
            height: 40px;
            width: 48px;
        }
        span {
src/modules/basicdata/locales/en.json
@@ -45,7 +45,14 @@
"身份证号":"身份证号",
"姓名":"姓名",
"手机号":"手机号",
"密码":"密码",
"性别":"性别",
"男":"男",
"女":"女",
"未知":"未知",
"生日":"生日",
"入职日期":"入职日期",
"离职日期":"离职日期",
"工作站点":"工作站点",
"身份证正面照":"身份证正面照",
"身份证反面照":"身份证反面照",
src/modules/basicdata/locales/zh-cn.json
@@ -45,7 +45,14 @@
"身份证号":"身份证号",
"姓名":"姓名",
"手机号":"手机号",
"密码":"密码",
"性别":"性别",
"男":"男",
"女":"女",
"未知":"未知",
"生日":"生日",
"入职日期":"入职日期",
"离职日期":"离职日期",
"工作站点":"工作站点",
"身份证正面照":"身份证正面照",
"身份证反面照":"身份证反面照",
src/modules/basicdata/locales/zh-tw.json
@@ -45,7 +45,14 @@
"身份证号":"身份证号",
"姓名":"姓名",
"手机号":"手机号",
"密码":"密码",
"性别":"性别",
"男":"男",
"女":"女",
"未知":"未知",
"生日":"生日",
"入职日期":"入职日期",
"离职日期":"离职日期",
"工作站点":"工作站点",
"身份证正面照":"身份证正面照",
"身份证反面照":"身份证反面照",
src/modules/basicdata/views/site.vue
@@ -53,94 +53,104 @@
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t("站点编码"),
            prop: "businessId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true,
        },
        {
            label: t("名称"),
            prop: "businessName",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true,
        },
        {
            label: t("选择部门"),
            prop: "departmentId",
            //component: { name: "el-input", props: { clearable: true } },
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选 / true å¤šé€‰
                    placeholder: "请选择部门",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            required: true,
        },
        {
            label: t("站点类型"),
            prop: "siteType",
            component: {
                name: "cl-select",
                props: { options: dict.get("sitetype") },
            },
            value: "收集点",
            span: 12,
            required: true,
        },
        {
            label: t("地址"),
            prop: "address",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true,
        },
        {
            label: t("负责人"),
            prop: "leader",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true,
        },
        {
            label: t("经度"),
            prop: "longitude",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true,
        },
        {
            label: t("纬度"),
            prop: "latitude",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true,
        },
        { label: t("照片"), prop: "photo", component: { name: "cl-upload" } },
        {
            label: t("是否启用"),
            prop: "status",
            component: { name: "el-radio-group", options: options.status },
            value: 1,
            required: true,
        },
        {
            label: t("备注"),
            prop: "remark",
            component: {
                name: "el-input",
                props: { type: "textarea", rows: 4 },
            },
        },
    ],
  onOpen: (mode, data) => {
    if (mode === 'update' && data?.departmentId) {
      data.departmentId = Number(data.departmentId);
    }
    return data;
  },
  items: [
    {
      label: t("站点编码"),
      prop: "businessId",
      component: { name: "el-input", props: { clearable: true } },
      span: 12,
      required: true,
    },
    {
      label: t("名称"),
      prop: "businessName",
      component: { name: "el-input", props: { clearable: true } },
      span: 12,
      required: true,
    },
    {
      label: t("选择部门"),
      prop: "departmentId",
      component: {
        name: 'cl-dept-select',
        props: {
          multiple: false,
          placeholder: "请选择部门",
          checkStrictly: true,
          immediate: true,
          clearable: true,
          defaultExpandAll: true,
        },
      },
      value: undefined,
      span: 12,
      required: true,
    },
    {
      label: t("站点类型"),
      prop: "siteType",
      component: {
        name: "cl-select",
        props: { options: dict.get("sitetype") },
      },
      value: "收集点",
      span: 12,
      required: true,
    },
    {
      label: t("地址"),
      prop: "address",
      component: { name: "el-input", props: { clearable: true } },
      span: 12,
      required: true,
    },
    {
      label: t("负责人"),
      prop: "leader",
      component: { name: "el-input", props: { clearable: true } },
      span: 12,
      required: true,
    },
    {
      label: t("经度"),
      prop: "longitude",
      hook: "number",
      component: { name: "el-input-number", props: { min: 0 } },
      span: 12,
      required: true,
    },
    {
      label: t("纬度"),
      prop: "latitude",
      hook: "number",
      component: { name: "el-input-number", props: { min: 0 } },
      span: 12,
      required: true,
    },
    { label: t("照片"), prop: "photo", component: { name: "cl-upload" } },
    {
      label: t("是否启用"),
      prop: "status",
      component: { name: "el-radio-group", options: options.status },
      value: 1,
      required: true,
    },
    {
      label: t("备注"),
      prop: "remark",
      component: {
        name: "el-input",
        props: { type: "textarea", rows: 4 },
      },
    },
  ],
});
// cl-table
@@ -208,7 +218,58 @@
});
// cl-search
const Search = useSearch();
const Search = useSearch({
  items: [
    {
      label: t('归属单位'),
      prop: 'departmentId',
      component: {
        name: 'cl-dept-select',
        props: {
          placeholder: t('请选择归属单位'),
          checkStrictly: true,   // çˆ¶å­ä¸è”动
          immediate: true,       // æŒ‰å½“前用户权限加载
          clearable: true,
        },
      },
    },
    {
      label: t('站点类型'),
      prop: 'siteType',
      component: {
        name: 'cl-select',
        props: {
          options: dict.get('sitetype'),
          placeholder: t('请选择站点类型'),
          clearable: true,
        },
      },
    },
    {
      label: t('状态'),
      prop: 'status',
      component: {
        name: 'cl-select',
        props: {
          options: options.status,
          placeholder: t('请选择状态'),
          clearable: true,
        },
      },
    },
    {
      label: t('关键字'),
      prop: 'keyWord',
      component: {
        name: 'el-input',
        props: {
          placeholder: t('站点编码 / åç§° / åœ°å€ / è´Ÿè´£äºº'),
          clearable: true,
        },
      },
    },
  ],
});
// cl-crud
const Crud = useCrud(
src/modules/basicdata/views/sorter.vue
@@ -45,12 +45,18 @@
const workSiteOptions = ref<{ label: string; value: any }[]>([]);
// é€‰é¡¹
const options = reactive({
    status: [
        { label: t("在职"), value: 0 },
        { label: t("离职"), value: 1 },
        { label: t("禁用"), value: 2 },
    sex: [
        { label: t('未知'), value: '未知' },
        { label: t('男'), value: '男' },
        { label: t('女'), value: '女' }
    ],
    status: [
        { label: t('在职'), value: 0 },
        { label: t('离职'), value: 1 },
        { label: t('禁用'), value: 2 }
    ]
});
// cl-upsert
@@ -70,15 +76,50 @@
            span: 12,
            required: true,
        },
        {
            label: t("手机号"),
            label: t('手机号'),
            prop: "phone",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('密码'),
            prop: "password",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('性别'),
            prop: "sex",
            component: { name: "el-radio-group", options: options.sex },
            value: 0,
            required: true
        },
        {
            label: t('生日'),
            prop: "birthday",
            component: {
                name: "el-date-picker",
                props: { type: "date", valueFormat: "YYYY-MM-DD" }
            },
            span: 12
        },
        {
            label: t("入职日期"),
            prop: "hireDate",
            component: {
                name: "el-date-picker",
                props: { type: "date", valueFormat: "YYYY-MM-DD" },
            },
            span: 12,
        },
        {
            label: t("离职日期"),
            prop: "leaveDate",
            component: {
                name: "el-date-picker",
                props: { type: "date", valueFormat: "YYYY-MM-DD" },
@@ -149,12 +190,24 @@
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t("所属单位"), prop: "departmentName", minWidth: 120 },
        { label: t("身份证号"), prop: "businessId", minWidth: 140 },
        { label: t("姓名"), prop: "businessName", minWidth: 140 },
        { label: t("手机号"), prop: "phone", minWidth: 140 },
        { label: t("性别"), prop: "sex", minWidth: 140 },
        {
            label: t("入职日期"),
            prop: "hireDate",
            minWidth: 140,
            sortable: "custom",
            component: {
                name: "cl-date-text",
                props: { format: "YYYY-MM-DD" },
            },
        },
        {
            label: t("离职日期"),
            prop: "leaveDate",
            minWidth: 140,
            sortable: "custom",
            component: {
@@ -168,7 +221,6 @@
            minWidth: 120,
            dict: options.status,
        },
        { label: t("所属单位"), prop: "departmentName", minWidth: 120 },
        { label: t("工作站点"), prop: "workSiteName", minWidth: 120 },
        {
            label: t("身份证正面照"),
src/modules/ezuikit/components/ezuikit-player.vue
@@ -99,6 +99,7 @@
  }
};
let playedOnce = false;
const init = () => {
  if (player) {
    destroy();
@@ -109,9 +110,9 @@
    id: props.containerId,
    accessToken: props.accessToken,
    url: props.url,
    autoplay: false,
    autoplay: true,
    template: "pcLive",
    height: 400,
    height: 360,
    scaleMode: 1,
    staticPath: props.staticPath || "",
    env: {
@@ -127,6 +128,14 @@
      console.error("handleError", err);
    }
  });
  player.on(EZUIKitPlayer.EVENTS.firstFrameDisplay, () => {
    if (playedOnce) return;
    playedOnce = true;
    setTimeout(() => {
      player?.pause();
    }, 1000);
  });
  // äº‹ä»¶ç›‘听
  player.on(EZUIKitPlayer.EVENTS.videoInfo, (info: any) => {
@@ -178,6 +187,7 @@
  <div class="ez-player-card">
    <!-- ID由父组件传入,保证全局唯一 -->
    <div :id="containerId" style="height: 400px;width:100%"></div>
    <!--
    <div class="player-buttons" style="margin-top:8px;display:flex;gap:6px;flex-wrap:wrap">
      <button @click="init">init</button>
      <button @click="stop">stop</button>
@@ -187,14 +197,15 @@
      <button @click="capturePicture">截图</button>
      <button @click="fullscreen">全屏</button>
    </div>
    -->
  </div>
</template>
<style scoped>
.ez-player-card {
  border: 1px solid #e4e7ed;
  border: 0px solid #e4e7ed;
  border-radius: 6px;
  padding: 8px;
  padding: 0px;
  background: #000;
}
</style>
src/modules/maps/locales/en.json
New file
@@ -0,0 +1,71 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他"
}
src/modules/maps/locales/zh-cn.json
New file
@@ -0,0 +1,71 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他"
}
src/modules/maps/locales/zh-tw.json
New file
@@ -0,0 +1,71 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他"
}
src/modules/maps/views/layers.vue
New file
@@ -0,0 +1,84 @@
<!--App.vue-->
<template>
    <div :class="state.copyright ? '' : 'hide-copyright'" class="mapDiv">
        <tdt-map :center="state.center" :controls="state.controls" :zoom="state.zoom" :loadConfig="loadConfig">
            <tdt-control :visible="state.visible" position="topright">
            </tdt-control>
        </tdt-map>
    </div>
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import { TdtMap, type LngLat } from "vue-tianditu2";
const loadConfig = { v: "4.0", tk: "51915011aa0997aa2ddd7e38504fa8bc" };
const state = reactive({
    center: [121.280637, 32.125178] as LngLat,
    zoom: 12,
    visible: true,
    copyright: false,
    controls: [
        "Zoom",
        "Scale",
        {
            name: "MapType",
            position: "topright",
            mapTypes: [
                {
                    title: "地图", //地图控件上所要显示的图层名称
                    icon: "https://api.tianditu.gov.cn/v4.0/image/map/maptype/vector.png", //地图控件上所要显示的图层图标(默认图标大小 80x80)
                    layer: "TMAP_NORMAL_MAP" //地图类型,在原天地图api中以window.TMAP_NORMAL_MAP表示,此处为字符串
                },
                {
                    title: "卫星",
                    icon: " https://api.tianditu.gov.cn/v4.0/image/map/maptype/satellite.png",
                    layer: "TMAP_SATELLITE_MAP"
                },
                {
                    title: "卫星混合",
                    icon: "https://api.tianditu.gov.cn/v4.0/image/map/maptype/satellitepoi.png",
                    layer: "TMAP_HYBRID_MAP"
                }
                // {
                //   title: "地形",
                //   icon: "https://api.tianditu.gov.cn/v4.0/image/map/maptype/terrain.png",
                //   layer: "TMAP_TERRAIN_MAP"
                // },
                // {
                //   title: "地形混合",
                //   icon: "https://api.tianditu.gov.cn/v4.0/image/map/maptype/terrainpoi.png",
                //   layer: "TMAP_TERRAIN_HYBRID_MAP"
                // }
            ]
        },
        {
            name: "OverviewMap",
            isOpen: true,
            anchor: "bottomright"
        },
        {
            name: "Copyright",
            id: "custom",
            content: `<div style="height:40px"><button class="demo-button">自定义的版权控件</button></div>`,
            position: "bottomleft",
            bounds: [
                [113.52791, 23.21989],
                [113.03352, 23.03045]
            ]
        }
    ]
});
</script>
<style>
.mapDiv {
    width: 100%;
    height: 100%;
    padding: 0%;
}
.hide-copyright :deep(.tdt-control-copyright.tdt-control > div:not(.tdt-control-copyright)) {
    display: none;
}
</style>
src/modules/monitor/components/site-tree.vue
@@ -104,11 +104,6 @@
    selectId.value = item.a_id;
    const numReg = /^\d+$/;
    const isSite = !numReg.test(item.a_id);
    if (!isSite) {
        ElMessage.info(t('请选择站点节点查看监控'));
        emit('select', null);
        return;
    }
    emit('select', item.a_id);
}
src/modules/monitor/views/capturetask.vue
New file
@@ -0,0 +1,183 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>
<script lang="ts" setup>
    defineOptions({
        name: "monitor-capturetask"
    });
    import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
    import { useCool } from "/@/cool";
    import { useI18n } from "vue-i18n";
    import { reactive } from "vue";
    const { service } = useCool();
    const { t } = useI18n();
    // é€‰é¡¹
    const options = reactive({
        status: [
            { label: t('PENDING'), value: 0 },
            { label: t('SUCCESS'), value: 1 },
            { label: t('FAILED'), value: 2 }
        ]
    });
    // cl-upsert
    const Upsert = useUpsert({
        items: [
            {
                label: t('设备序列号'),
                prop: "deviceSerial",
                component: { name: "el-input", props: { clearable: true } },
                span: 12,
                required: true
            },
            {
                label: t('通道号'),
                prop: "channelNo",
                hook: "number",
                component: { name: "el-input-number", props: { min: 0 } },
                span: 12,
                required: true
            },
            {
                label: t('选择抓图任务'),
                prop: "captureTaskId",
                component: { name: "el-input", props: { clearable: true } },
                span: 12
            },
            {
                label: t('选择云空间'),
                prop: "spaceId",
                component: { name: "el-input", props: { clearable: true } },
                span: 12
            },
            {
                label: t('云空间图片链接'),
                prop: "cloudUrl",
                component: { name: "cl-upload" }
            },
            { label: t('本地图片链接'), prop: "localUrl", component: { name: "cl-upload" } },
            {
                label: t('本地存储路径'),
                prop: "localPath",
                component: { name: "el-input", props: { clearable: true } },
                span: 12
            },
            {
                label: t('抓拍状态'),
                prop: "status",
                component: { name: "el-radio-group", options: options.status },
                value: 0,
                required: true
            },
            {
                label: t('任务执行日期'),
                prop: "captureDate",
                component: {
                    name: "el-date-picker",
                    props: { type: "date", valueFormat: "YYYY-MM-DD" }
                },
                span: 12
            }
        ]
    });
    // cl-table
    const Table = useTable({
        columns: [
            { type: "selection" },
            { label: t('设备序列号'), prop: "deviceSerial", minWidth: 140 },
            { label: t('通道号'), prop: "channelNo", minWidth: 140, sortable: "custom" },
            { label: t('抓图任务ID'), prop: "captureTaskId", minWidth: 140 },
            { label: t('云空间ID'), prop: "spaceId", minWidth: 140 },
            {
                label: t('云空间图片链接'),
                prop: "cloudUrl",
                minWidth: 100,
                component: { name: "cl-image", props: { size: 60 } }
            },
            {
                label: t('本地图片链接'),
                prop: "localUrl",
                minWidth: 100,
                component: { name: "cl-image", props: { size: 60 } }
            },
            { label: t('本地存储路径'), prop: "localPath", minWidth: 140 },
            {
                label: t('抓拍状态'),
                prop: "status",
                minWidth: 120,
                dict: options.status
            },
            {
                label: t('任务执行日期'),
                prop: "captureDate",
                minWidth: 140,
                sortable: "custom",
                component: { name: "cl-date-text", props: { format: "YYYY-MM-DD" } }
            },
            {
                label: t('创建时间'),
                prop: "createTime",
                minWidth: 170,
                sortable: "desc",
                component: { name: "cl-date-text" }
            },
            {
                label: t('更新时间'),
                prop: "updateTime",
                minWidth: 170,
                sortable: "custom",
                component: { name: "cl-date-text" }
            },
            { type: "op", buttons: ["edit", "delete"] }
        ]
    });
    // cl-search
    const Search = useSearch();
    // cl-crud
    const Crud = useCrud(
        {
            service: service.monitor.capturetask
        },
        (app) => {
            app.refresh();
        }
    );
    // åˆ·æ–°
    function refresh(params?: any) {
        Crud.value?.refresh(params);
    }
</script>
src/modules/monitor/views/device.vue
@@ -1,27 +1,23 @@
<template>
    <div class="monitor-page" style="height:100%;display:flex;gap:12px;">
        <!-- å·¦ä¾§æ ‘å½¢ -->
        <div class="left-tree" style="width:280px;border:1px solid var(--el-border-color);border-radius:6px;">
            <site-tree @select="handleTreeSelect" />
        </div>
  <div class="monitor-page">
    <!-- å·¦ä¾§æ ‘å½¢ -->
    <div class="left-tree">
      <site-tree @select="handleTreeSelect" />
    </div>
        <!-- å³ä¾§ç›‘控区域 -->
        <div class="right-player" style="flex:1;border:1px solid var(--el-border-color);border-radius:6px;padding:12px;overflow:auto;">
            <el-empty v-if="deviceList.length === 0" description="请左侧选择站点加载监控设备" />
            <div class="player-grid" v-if="deviceList.length">
                <div v-for="dev in deviceList" :key="dev.id" class="player-card">
                    <div class="title">{{ dev.iotName }}</div>
                    <EzuikitPlayer
                    v-if="ysToken"
                    :key="'p_' + dev.id + '_' + ysToken"
                    :container-id="'player_' + dev.id"
                    :access-token="ysToken"
                    :url="`ezopen://open.ys7.com/${dev.iotCode}/1.hd.live`"
                    />
                </div>
            </div>
        </div>
    </div>
    <!-- å³ä¾§ç›‘控区域 -->
    <div class="right-player">
      <el-empty v-if="deviceList.length === 0" description="请左侧选择站点加载监控设备" />
      <div v-else class="player-grid" :style="gridStyle">
        <div v-for="dev in deviceList" :key="dev.id" class="player-card">
          <!-- <div class="title">{{ dev.iotName }}</div> -->
          <ezuikit-player v-if="ysToken" :key="'p_' + dev.id + '_' + ysToken" :container-id="'player_' + dev.id"
            :access-token="ysToken" :url="`ezopen://open.ys7.com/${dev.iotCode}/1.hd.live`"
            :pause-at-first-frame="true" />
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
@@ -29,7 +25,7 @@
  name: 'monitor-device',
});
import { ref, onMounted } from 'vue';
import { ref, computed, onMounted } from 'vue';
import { useCool } from '/@/cool';
import SiteTree from '../components/site-tree.vue';
import EzuikitPlayer from '../../ezuikit/components/ezuikit-player.vue';
@@ -37,22 +33,34 @@
const { service } = useCool();
const deviceList = ref<any[]>([]);
const ysToken = ref<string>('');
const ysToken = ref('');
// âœ… æ ¹æ®è®¾å¤‡æ•°é‡è‡ªåŠ¨è®¡ç®—ç½‘æ ¼åˆ—æ•°
const gridCols = computed(() => {
  const n = deviceList.value.length;
  if (n <= 1) return 1;
  if (n <= 4) return 2;   // 2~4 ä¸ª â†’ 2 åˆ—
  if (n <= 6) return 3;   // 5~6 ä¸ª â†’ 3 åˆ—
  if (n <= 8) return 4;   // 7~8 ä¸ª â†’ 4 åˆ—
  return 4;
});
const gridStyle = computed(() => ({
  gridTemplateColumns: `repeat(${gridCols.value}, 1fr)`,
}));
/** æ‹¿è¤çŸ³ token */
async function fetchYsToken() {
  if (ysToken.value) return; // å·²æœ‰å°±ä¸å†é‡å¤æ‹¿
  try {
    const res = await service.monitor.ys7.getToken();
    ysToken.value = res.accessToken;
  } catch (e) {
    console.error('萤石 Token èŽ·å–å¤±è´¥', e);
    const res = await service.base.sys.param.stringbykey({ key: 'ys7.accessToken' });
    ysToken.value = res as string; // âœ… ä¿®æ­£ï¼šèµ‹å€¼ç»™ .value
  } catch (e: any) {
    console.error('萤石 Token èŽ·å–å¤±è´¥', e?.response?.data?.message || e.message);
  }
}
onMounted(() => {
  fetchYsToken();
});
onMounted(fetchYsToken); // âœ… ä¿®æ­£ï¼šonMounted
/** æ ‘节点点击 */
async function handleTreeSelect(businessId: string | number | null) {
@@ -68,9 +76,8 @@
  try {
    const res = await service.basicdata.iot.getYsDevices({ businessId });
    deviceList.value = res || [];
  } catch (err) {
    console.error('获取萤石设备列表失败', err);
    deviceList.value = (res || []) as any[];
  } catch {
    deviceList.value = [];
  }
}
@@ -78,23 +85,36 @@
<style lang="scss" scoped>
.monitor-page {
    height: 100%;
  height: 100%;
  display: flex;
  gap: 12px;
}
.left-tree {
    height: 100%;
  width: 280px;
  height: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
}
.right-player {
    height: 100%;
  flex: 1;
  height: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
  padding: 12px;
  overflow: auto;
}
.player-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(440px, 1fr));
    gap: 16px;
  display: grid;
  gap: 16px;
}
.player-card {
    .title {
        padding: 6px 0;
        font-weight: 500;
    }
  .title {
    padding: 6px 0;
    font-weight: 500;
  }
}
</style>
src/modules/shop/components/item-select.vue
New file
@@ -0,0 +1,36 @@
<template>
    <cl-select-table v-model="value" :title="t('选择订单详情')" :service="service.shop.recycleitem" :columns="columns"
        :multiple="multiple" :dict='{ "text": "itemname" }' pickerType="text" />
</template>
<script setup lang="ts">
defineOptions({
    name: "recycle-item-select"
});
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { CrudProps } from "/#/crud";
import { ref, useModel } from "vue";
const props = defineProps({
    ...CrudProps,
    modelValue: null,
    multiple: Boolean
});
const { service } = useCool();
const { t } = useI18n();
const value = useModel(props, "modelValue");
const columns = ref([
    { label: t("订单编号"), prop: "orderNo", minWidth: 140 },
    { label: t("项目名称"), prop: "itemName", minWidth: 140 },
    { label: t("分类ID"), prop: "categoryId", minWidth: 120 },
    { label: t("重量"), prop: "weight", minWidth: 140, sortable: "custom" },
    { label: t("单价"), prop: "unitPrice", minWidth: 140, sortable: "custom" },
    { label: t("金额"), prop: "amount", minWidth: 140, sortable: "custom" },
    { label: t("碳积分"), prop: "carbonPoint", minWidth: 140, sortable: "custom" }
]);
</script>
src/modules/shop/components/order-detail.vue
New file
@@ -0,0 +1,303 @@
<template>
    <cl-form ref="Form">
        <template #slot-order-detail>
            <cl-crud padding="0">
                <cl-row>
                    <el-button type="success" @click="add">添加回收物</el-button>
                    <el-button :disabled="Table?.selection.length === 0" type="danger" @click="remove()">
                        åˆ é™¤
                    </el-button>
                </cl-row>
                <cl-row>
                    <cl-table ref="Table" :data="data" :auto-height="false">
                        <!-- å›žæ”¶ç‰©é€‰æ‹© -->
                        <template #column-itemName="{ scope }">
                            <el-form-item :prop="`items.${scope.$index}.itemId`"
                                :rules="{ required: true, message: '请选择回收物' }">
                                <el-select v-model="scope.row.itemId" filterable placeholder="请选择回收物"
                                    style="width: 100%" @change="onItemChange(scope.row)">
                                    <el-option v-for="item in itemOptions" :key="item.itemId" :label="item.itemName"
                                        :value="item.itemId" />
                                </el-select>
                            </el-form-item>
                        </template>
                        <!-- é‡é‡ -->
                        <template #column-weight="{ scope }">
                            <el-form-item :prop="`items.${scope.$index}.weight`"
                                :rules="{ required: true, message: '重量不能为空' }">
                                <el-input-number v-model="scope.row.weight" :min="0" :max="100000" :precision="2"
                                    :controls="false" placeholder="重量/件数" @change="calcRow(scope.row)" />
                            </el-form-item>
                        </template>
                        <!-- å•价(只读) -->
                        <template #column-unitPrice="{ scope }">
                            <el-form-item>
                                <el-input-number v-model="scope.row.unitPrice" :controls="false" :precision="2"
                                    disabled />
                            </el-form-item>
                        </template>
                        <!-- é‡‘额(只读) -->
                        <template #column-amount="{ scope }">
                            <el-form-item>
                                <el-input-number v-model="scope.row.amount" :controls="false" :precision="2" disabled />
                            </el-form-item>
                        </template>
                        <!-- ç¢³ç§¯åˆ†ï¼ˆåªè¯»ï¼‰ -->
                        <template #column-carbonPoint="{ scope }">
                            <el-form-item>
                                <el-input-number v-model="scope.row.carbonPoint" :controls="false" :precision="2"
                                    disabled />
                            </el-form-item>
                        </template>
                        <!-- ç¢³ç§¯åˆ†ï¼ˆåªè¯»ï¼‰ -->
                        <template #column-category="{ scope }">
                            <el-form-item>
                                <el-input v-model="scope.row.category" :controls="false" disabled />
                            </el-form-item>
                        </template>
                        <template #slot-btn="{ scope }">
                            <el-icon class="del-btn" @click="remove(scope.row.uid)">
                                <delete />
                            </el-icon>
                        </template>
                    </cl-table>
                </cl-row>
            </cl-crud>
        </template>
    </cl-form>
</template>
<script lang="ts" setup name="order-detail">
import { useForm, useTable } from "@cool-vue/crud";
import { computed, ref, onMounted } from "vue";
import { useCool } from "/@/cool";
import { ElMessage } from "element-plus";
import { isEmpty, find } from "lodash-es";
import { Delete } from "@element-plus/icons-vue";
import { uuid } from "/@/cool/utils";
const { service } = useCool();
const Form = useForm();
// å›žæ”¶ç‰©å­—å…¸
const itemOptions = ref<any[]>([]);
const currentOrderNo = ref<string>();
// æ˜Žç»†åˆ—表
const list = ref<any[]>([]);
// è¡¨æ ¼æ•°æ®
const data = computed(() => list.value.filter((e) => !e.isDel));
// æ‰“å¼€
async function open(orderNo: string) {
    currentOrderNo.value = orderNo;
    await refresh(orderNo);
    Form.value?.open({
        title: "回收订单明细",
        form: { items: list.value },
        width: "80%",
        items: [
            {
                prop: "items",
                component: { name: "slot-order-detail" }
            }
        ],
        on: {
            submit(_, { close, done }) {
                const delIds: number[] = [];
                const add: any[] = [];
                const update: any[] = [];
                list.value.forEach((e) => {
                    if (e.id) {
                        if (e.isDel) {
                            delIds.push(e.id);
                        } else if (e.isEdit) {
                            update.push(e);
                        }
                    } else if (!e.isDel) {
                        add.push(e);
                    }
                });
                /*
                const tasks: Promise<any>[] = [];
                if (!isEmpty(delIds)) {
                    tasks.push(service.shop.recycleorderitem.delete({ ids: delIds }));
                }
                if (!isEmpty(update)) {
                    update.forEach((e) => tasks.push(service.shop.recycleorderitem.update(e)));
                }
                if (!isEmpty(add)) {
                    tasks.push(
                        service.shop.recycleorderitem.add(
                            add.map((e) => ({
                                ...e,
                                orderNo: currentOrderNo.value!
                            }))
                        )
                    );
                }
                Promise.all(tasks)
                    .then(() => {
                        ElMessage.success("保存成功");
                        close();
                    })
                    .catch((err) => {
                        ElMessage.error(err.message);
                        refresh(orderNo);
                        done();
                    });
                    */
                const items = list.value
                    .filter(e => !e.isDel)
                    .map(e => ({
                        id: e.id,
                        itemId: e.itemId,
                        itemName: e.itemName,
                        weight: e.weight,
                        unitPrice: e.unitPrice,
                        amount: e.amount,
                        carbonPoint: e.carbonPoint,
                        category: e.category
                    }));
                service.shop.recycleorder.saveWithSummary({
                    orderNo: currentOrderNo.value!,
                    items
                })
                    .then(() => {
                        ElMessage.success("保存成功");
                        close();
                    })
                    .catch((err) => {
                        ElMessage.error(err.message);
                        refresh(currentOrderNo.value!);
                        done();
                    });
            }
        }
    });
}
// åˆ·æ–°æ˜Žç»†
async function refresh(orderNo: string) {
    const [items, details] = await Promise.all([
        service.shop.recycleitem.list({
            status: 0,
            order: "id",
            sort: "asc"
        }),
        service.shop.recycleorderitem.list({
            orderNo,
            order: "id",
            sort: "asc"
        })
    ]);
    itemOptions.value = items;
    list.value = details.map((e: any) => ({
        ...e,
        weight: Number(e.weight),
        unitPrice: Number(e.unitPrice),
        amount: Number(e.amount),
        carbonPoint: Number(e.carbonPoint),
        uid: e.id
    }));
}
// æ–°å¢ž
function add() {
    list.value.push({
        uid: uuid(),
        itemId: "",
        itemName: "",
        category: "",
        unit: "",
        weight: 0,
        unitPrice: 0,
        amount: 0,
        carbonPoint: 0,
        isDel: false,     // âœ… è¡¥ä¸Š
        isEdit: false     // âœ… è¡¥ä¸Š
    });
}
// åˆ é™¤
function remove(uid?: string) {
    const arr = uid ? [uid] : Table.value?.selection.map((e) => e.uid);
    list.value.forEach((e) => {
        if (arr?.includes(e.uid)) {
            e.isDel = true;
        }
    });
}
// é€‰æ‹©å›žæ”¶ç‰©
function onItemChange(row: any) {
    const item = find(itemOptions.value, { itemId: row.itemId });
    if (item) {
        row.itemName = item.itemName;
        row.category = item.category;
        row.unitPrice = Number(item.price);
        row.carbonPoint = Number(item.carbonPoint);
        row.unit = item.unit;
    }
    row.isEdit = true;
    calcRow(row);
}
// è®¡ç®—金额
function calcRow(row: any) {
    row.amount = Number((row.weight * row.unitPrice).toFixed(2));
    row.carbonPoint = Number((row.amount * 100).toFixed(2));
}
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: "回收物", prop: "itemName", minWidth: 180 },
        { label: "重量/件数", prop: "weight", minWidth: 120 },
        { label: "单价", prop: "unitPrice", minWidth: 120 },
        { label: "金额", prop: "amount", minWidth: 120 },
        { label: "国标分类", prop: "category", minWidth: 120 },
        { label: "碳积分", prop: "carbonPoint", minWidth: 120 },
        { type: "op", width: 80, buttons: ["slot-btn"] }
    ]
});
defineExpose({
    open
});
</script>
<style lang="scss" scoped>
.el-form-item {
    margin-bottom: 0;
}
.del-btn {
    cursor: pointer;
    &:hover {
        color: red;
    }
}
</style>
src/modules/shop/components/order-select.vue
New file
@@ -0,0 +1,66 @@
<template>
    <cl-select-table v-model="value" :title="t('选择订单管理')" :service="service.shop.recycleorder" :columns="columns"
        :multiple="multiple" :dict='{ "text": "username" }' pickerType="text" />
</template>
<script setup lang="ts">
defineOptions({
    name: "recycle-order-select"
});
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { CrudProps } from "/#/crud";
import { reactive, ref, useModel } from "vue";
const props = defineProps({
    ...CrudProps,
    modelValue: null,
    multiple: Boolean
});
const { service } = useCool();
const { t } = useI18n();
const value = useModel(props, "modelValue");
// é€‰é¡¹
const options = reactive({
    orderType: [
        { label: t("上门回收"), value: 0 },
        { label: t("站点回收"), value: 1 },
        { label: t("投递回收"), value: 2 }
    ],
    status: [
        { label: t("待处理"), value: 0 },
        { label: t("进行中"), value: 1 },
        { label: t("已完成"), value: 2 },
        { label: t("已取消"), value: 3 }
    ]
});
const columns = ref([
    { label: t("手机号"), prop: "userPhone", minWidth: 140 },
    { label: t("昵称"), prop: "userName", minWidth: 140 },
    { label: t("订单编号"), prop: "orderNo", minWidth: 140 },
    { label: t("校园用户ID"), prop: "campusUserId", minWidth: 120 },
    {
        label: t("订单类型"),
        prop: "orderType",
        minWidth: 120,
        dict: options.orderType
    },
    { label: t("站点ID"), prop: "siteId", minWidth: 120 },
    { label: t("分拣员ID"), prop: "sorterId", minWidth: 120 },
    { label: t("状态"), prop: "status", minWidth: 120, dict: options.status },
    { label: t("总重量"), prop: "totalWeight", minWidth: 140, sortable: "custom" },
    { label: t("总碳积分"), prop: "totalCarbonPoint", minWidth: 140, sortable: "custom" },
    {
        label: t("完成时间"),
        prop: "finishTime",
        minWidth: 170,
        sortable: "custom",
        component: { name: "cl-date-text" }
    }
]);
</script>
src/modules/shop/locales/en.json
New file
@@ -0,0 +1,71 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他"
}
src/modules/shop/locales/zh-cn.json
New file
@@ -0,0 +1,117 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他",
"可回收物编码":"可回收物编码",
"废品类别编码":"废品类别编码",
"计量单位":"计量单位",
"价格(元)":"价格(元)",
"碳积分":"碳积分",
"固废编码":"固废编码",
"包含品类":"包含品类",
"现场":"现场",
"预约":"预约",
"大屏":"大屏",
"活动":"活动",
"接单":"接单",
"运输":"运输",
"完成":"完成",
"待处理":"待处理",
"已完成":"已完成",
"已取消":"已取消",
"订单编号":"订单编号",
"订单类型":"订单类型",
"选择学校":"选择学校",
"选择站点":"选择站点",
"选择分拣员":"选择分拣员",
"选择预约ID":"选择预约ID",
"完成时间":"完成时间",
"机构名称":"机构名称",
"学号/工号":"学号/工号",
"分拣员ID":"分拣员ID",
"预约ID":"预约ID",
"待审核":"待审核",
"待接单":"待接单",
"已接单":"已接单",
"上门中":"上门中",
"预约编号":"预约编号",
"详细地址":"详细地址",
"预约日期":"预约日期",
"预计重量":"预计重量",
"用户姓名":"用户姓名",
"分拣员姓名":"分拣员姓名",
"回收订单":"回收订单",
"学校ID":"学校ID",
"经度":"经度",
"纬度":"纬度",
"预约时段":"预约时段",
"所属机构":"所属机构",
"分拣员":"分拣员",
"回收订单ID":"回收订单ID"
}
src/modules/shop/locales/zh-tw.json
New file
@@ -0,0 +1,71 @@
{
"设备号":"设备号",
"设备名称":"设备名称",
"上传时间":"上传时间",
"垃圾类型":"垃圾类型",
"垃圾名称":"垃圾名称",
"垃圾重量":"垃圾重量KG",
"其他数据":"其他数据",
"站点编号":"站点编号",
"站点名称":"站点名称",
"站点类型":"站点类型",
"称重设备":"称重设备",
"weight":"weight",
"health_gps":"health_gps",
"vehicle_gps":"vehicle_gps",
"driver_anomaly":"driver_anomaly",
"others":"others",
"日志时间":"日志时间",
"推送类型":"推送类型",
"客户端ID":"客户端ID",
"原始请求内容":"原始请求内容",
"错误返回信息":"错误返回信息",
"创建时间":"创建时间",
"更新时间":"更新时间",
"设备序列号":"设备序列号",
"消息序列号":"消息序列号",
"消息创建时间":"消息创建时间",
"GPS定位时间":"GPS定位时间",
"速度":"速度",
"方向角":"方向角",
"海拔高度":"海拔高度",
"定位精度":"定位精度",
"有效定位":"有效定位",
"无效定位":"无效定位",
"设备ID":"设备ID",
"通道号":"通道号",
"消息唯一ID":"消息唯一ID",
"消息时间":"消息时间",
"消息类型":"消息类型",
"设备类型":"设备类型",
"子序列号":"子序列号",
"源端ID":"源端ID",
"NAT的IP":"NAT的IP",
"事件发生时间":"事件发生时间",
"注册时间":"注册时间",
"重量":"重量",
"单价(元/Kg)":"单价(元/Kg)",
"总价(元)":"总价(元)",
"经手人ID":"经手人ID",
"经手人":"经手人",
"收购方":"收购方",
"收集点":"收集点",
"日期时间":"日期时间",
"总价":"总价",
"交易时间":"交易时间",
"交易类型":"交易类型",
"交易对方":"交易对方",
"商品名称":"商品名称",
"收支类型":"收支类型",
"金额":"金额",
"支付方式":"支付方式",
"当前状态":"当前状态",
"备注":"备注",
"文件路径":"文件路径",
"文件名":"文件名",
"交易单号":"交易单号",
"商户单号":"商户单号",
"收入":"收入",
"支出":"支出",
"其他":"其他"
}
src/modules/shop/views/appointment.vue
New file
@@ -0,0 +1,282 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>
<script lang="ts" setup>
defineOptions({
    name: "recycle-appointment"
});
import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
import { useDict } from '/$/dict';
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { reactive, computed } from "vue";
const { service } = useCool();
const { t } = useI18n();
const { dict } = useDict();
// é€‰é¡¹
const options = reactive({
    status: [
        { label: t('未知'), value: '未知' },
        { label: t('待审核'), value: '待审核' },
        { label: t('待接单'), value: '待接单' },
        { label: t('已接单'), value: '已接单' },
        { label: t('上门中'), value: '上门中' },
        { label: t('已完成'), value: '已完成' },
        { label: t('已取消'), value: '已取消' }
    ]
});
console.log(
    JSON.stringify(
        dict.get('appointmentslot').value,
        null,
        2
    )
);
const appointmentSlotOptions = computed(() =>
    dict.get('appointmentslot').value.map(item => ({
        label: item.name,
        value: String(item.value)
    }))
);
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t('预约编号'),
            prop: "appointmentNo",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('联系人'),
            prop: "contactName",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('联系电话'),
            prop: "contactPhone",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('详细地址'),
            prop: "address",
            component: { name: "el-input", props: { type: "textarea", rows: 4 } },
            required: true
        },
        {
            label: t('经度'),
            prop: "longitude",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12
        },
        {
            label: t('纬度'),
            prop: "latitude",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12
        },
        {
            label: t('预约日期'),
            prop: "appointmentDate",
            component: {
                name: "el-date-picker",
                props: { type: "date", valueFormat: "YYYY-MM-DD" }
            },
            span: 12,
            required: true
        },
        {
            label: '预约时间段',
            prop: 'appointmentSlot',
            component: {
                name: 'cl-select',
                props: {
                    options: appointmentSlotOptions
                }
            },
            required: true
        },
        {
            label: t('预计重量'),
            prop: "expectedWeight",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('状态'),
            prop: "status",
            component: { name: "cl-select", props: { options: options.status } },
            value: 0,
            span: 12,
            required: true
        },
        {
            label: t("选择学校"),
            prop: "departmentId",
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选 / true å¤šé€‰
                    placeholder: "请选择学校",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            required: true,
        },
        {
            label: t('用户ID'),
            prop: "campusUserId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('用户姓名'),
            prop: "campusUserName",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('分拣员ID'),
            prop: "sorterId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        },
        {
            label: t('分拣员姓名'),
            prop: "sorterName",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        },
        {
            label: t('回收订单'),
            prop: "recycleOrderId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        }
    ]
});
// cl-table
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t('用户ID'), prop: "campusUserId", minWidth: 120 },
        { label: t('姓名'), prop: "campusUserName", minWidth: 140 },
        { label: t('预约编号'), prop: "appointmentNo", minWidth: 140 },
        { label: t('联系人'), prop: "contactName", minWidth: 140 },
        { label: t('联系电话'), prop: "contactPhone", minWidth: 140 },
        {
            label: t('详细地址'),
            prop: "address",
            showOverflowTooltip: true,
            minWidth: 200
        },
        /*
        { label: t('经度'), prop: "longitude", minWidth: 140, sortable: "custom" },
        { label: t('纬度'), prop: "latitude", minWidth: 140, sortable: "custom" },
        */
        {
            label: t('预约日期'),
            prop: "appointmentDate",
            minWidth: 140,
            sortable: "custom",
            component: { name: "cl-date-text", props: { format: "YYYY-MM-DD" } }
        },
        { label: t('预约时间段'), prop: "appointmentSlot", minWidth: 120 },
        {
            label: t('预计重量'),
            prop: "expectedWeight",
            minWidth: 140,
            sortable: "custom"
        },
        { label: t('状态'), prop: "status", minWidth: 120, dict: options.status },
        { label: t('所属机构'), prop: "departmentName", minWidth: 120 },
        { label: t('分拣员'), prop: "sorterName", minWidth: 120 },
        {
            label: t('回收订单ID'),
            prop: "recycleOrderId",
            minWidth: 140,
            sortable: "custom"
        },
        {
            label: t('创建时间'),
            prop: "createTime",
            minWidth: 170,
            sortable: "desc",
            component: { name: "cl-date-text" }
        },
        {
            label: t('更新时间'),
            prop: "updateTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        { type: "op", buttons: ["edit", "delete"] }
    ]
});
// cl-search
const Search = useSearch();
// cl-crud
const Crud = useCrud(
    {
        service: service.shop.recycleappointment
    },
    (app) => {
        app.refresh();
    }
);
// åˆ·æ–°
function refresh(params?: any) {
    Crud.value?.refresh(params);
}
</script>
src/modules/shop/views/recycleitem.vue
New file
@@ -0,0 +1,186 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>
<script lang="ts" setup>
defineOptions({
    name: "recycle-recycleitem"
});
import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { reactive } from "vue";
const { service } = useCool();
const { t } = useI18n();
// é€‰é¡¹
const options = reactive({
    status: [
        { label: t('启用'), value: 0, type: "danger" },
        { label: t('禁用'), value: 1, type: "success" }
    ]
});
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t('可回收物编码'),
            prop: "itemId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t("选择部门"),
            prop: "departmentId",
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选
                    placeholder: "请选择部门",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            span: 12,
            required: true,
        },
        {
            label: t('名称'),
            prop: "itemName",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('包含品类'),
            prop: "including",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        },
        {
            label: t('计量单位'),
            prop: "unit",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('ä»·æ ¼(元)'),
            prop: "price",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('碳积分'),
            prop: "carbonPoint",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('固废编码'),
            prop: "category",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('状态'),
            prop: "status",
            component: { name: "el-radio-group", options: options.status },
            value: 0,
            required: true
        }
    ]
});
// cl-table
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t('可回收物编码'), prop: "itemId", minWidth: 120 },
        { label: t('名称'), prop: "itemName", minWidth: 140 },
        { label: t('包含品类'), prop: "including", minWidth: 140 },
        { label: t('所属单位'), prop: "departmentName", minWidth: 140 },
        { label: t('计量单位'), prop: "unit", minWidth: 140 },
        { label: t('ä»·æ ¼(元)'), prop: "price", minWidth: 140, sortable: "custom" },
        { label: t('碳积分'), prop: "carbonPoint", minWidth: 140, sortable: "custom" },
        { label: t('固废编码'), prop: "category", minWidth: 120 },
        {
            label: t('状态'),
            prop: "status",
            minWidth: 100,
            component: { name: "cl-switch" },
            dict: options.status
        },
        /*{
            label: t('创建时间'),
            prop: "createTime",
            minWidth: 170,
            sortable: "desc",
            component: { name: "cl-date-text" }
        },
        */
        {
            label: t('更新时间'),
            prop: "updateTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        { type: "op", buttons: ["edit", "delete"] }
    ]
});
// cl-search
const Search = useSearch();
// cl-crud
const Crud = useCrud(
    {
        service: service.shop.recycleitem
    },
    (app) => {
        app.refresh();
    }
);
// åˆ·æ–°
function refresh(params?: any) {
    Crud.value?.refresh(params);
}
</script>
src/modules/shop/views/recycleorder.vue
New file
@@ -0,0 +1,240 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
        <!-- å•†å“è§„æ ¼ -->
        <order-detail :ref="setRefs('orderDetail')" />
    </cl-crud>
</template>
<script lang="ts" setup>
defineOptions({
    name: "recycle-order"
});
import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { reactive } from "vue";
import OrderDetail from '../components/order-detail.vue';
const { service, refs, setRefs } = useCool();
const { t } = useI18n();
// é€‰é¡¹
const options = reactive({
    orderType: [
        { label: t('现场'), value: '现场' },
        { label: t('预约'), value: '预约' },
        { label: t('大屏'), value: '大屏' },
        { label: t('活动'), value: '活动' }
    ],
    status: [
        { label: t('预约'), value: '预约' },
        { label: t('接单'), value: '接单' },
        { label: t('运输'), value: '运输' },
        { label: t('完成'), value: '完成' },
        { label: t('取消'), value: '取消' },
        { label: t('未知'), value: '未知' },
    ]
});
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t('订单编号'),
            prop: "orderNo",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('订单类型'),
            prop: "orderType",
            component: { name: "el-radio-group", options: options.orderType },
            value: "现场",
            required: true
        },
        {
            label: t("选择学校"),
            prop: "departmentId",
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选 / true å¤šé€‰
                    placeholder: "请选择学校",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            required: true,
        },
        {
            label: t('选择用户'),
            prop: "campusUserId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('选择站点'),
            prop: "siteId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('选择分拣员'),
            prop: "sorterId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('选择预约ID'),
            prop: "appointmentId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        },
        {
            label: t('状态'),
            prop: "status",
            component: { name: "cl-select", props: { options: options.status } },
            value: "未知",
            span: 12,
            required: true
        },
        {
            label: t('总重量'),
            prop: "totalWeight",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('碳积分'),
            prop: "carbonPoint",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('完成时间'),
            prop: "finishTime",
            component: {
                name: "el-date-picker",
                props: { type: "datetime", valueFormat: "YYYY-MM-DD HH:mm:ss" }
            },
            span: 12
        }
    ]
});
// cl-table
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t('机构名称'), prop: "departmentName", minWidth: 140 },
        { label: t('手机号'), prop: "campusUserPhone", minWidth: 140 },
        { label: t('用户名'), prop: "campusUserName", minWidth: 140 },
        { label: t('订单编号'), prop: "orderNo", minWidth: 140 },
        {
            label: t('订单类型'),
            prop: "orderType",
            minWidth: 120,
            dict: options.orderType
        },
        { label: t('学号/工号'), prop: "campusUserId", minWidth: 120 },
        { label: t('站点ID'), prop: "siteId", minWidth: 120 },
        { label: t('分拣员ID'), prop: "sorterId", minWidth: 120 },
        { label: t('预约ID'), prop: "appointmentId", minWidth: 120 },
        { label: t('状态'), prop: "status", minWidth: 120, dict: options.status },
        { label: t('总重量'), prop: "totalWeight", minWidth: 140, sortable: "custom" },
        { label: t('碳积分'), prop: "carbonPoint", minWidth: 140, sortable: "custom" },
        {
            label: t('完成时间'),
            prop: "finishTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        {
            label: t('创建时间'),
            prop: "createTime",
            minWidth: 170,
            sortable: "desc",
            component: { name: "cl-date-text" }
        },
        /*{
            label: t('更新时间'),
            prop: "updateTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        */
        {
            type: 'op',
            width: 300,
            buttons({ scope }) {
                return [
                    'edit',
                    'delete',
                    {
                        label: '详情',
                        onClick() {
                            refs.orderDetail.open(scope.row.orderNo);
                        }
                    }
                ];
            }
        }
    ]
});
// cl-search
const Search = useSearch();
// cl-crud
const Crud = useCrud(
    {
        service: service.shop.recycleorder
    },
    (app) => {
        app.refresh();
    }
);
// åˆ·æ–°
function refresh(params?: any) {
    Crud.value?.refresh(params);
}
</script>
src/modules/shop/views/recycleorderitem.vue
New file
@@ -0,0 +1,171 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>
<script lang="ts" setup>
defineOptions({
    name: "recycle-recycleorderitem"
});
import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { reactive } from "vue";
import OrderSelect from "/$/recycle/components/order-select.vue";
import ItemSelect from "/$/recycle/components/item-select.vue";
const { service } = useCool();
const { t } = useI18n();
// é€‰é¡¹
const options = reactive({
    status: [
        { label: t('启用'), value: 0, type: "danger" },
        { label: t('禁用'), value: 1, type: "success" }
    ]
});
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t('选择订单'),
            prop: "orderId",
            component: { vm: OrderSelect },
            span: 12,
            required: true
        },
        {
            label: t('可回收物品编号'),
            prop: "typeId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('名称'),
            prop: "name",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('计量单位'),
            prop: "unit",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('ä»·æ ¼(元)'),
            prop: "price",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('碳积分'),
            prop: "carbonPoint",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('固废编码'),
            prop: "category",
            component: { name: "el-input", props: { clearable: true } },
            span: 12,
            required: true
        },
        {
            label: t('状态'),
            prop: "status",
            component: { name: "el-radio-group", options: options.status },
            value: 0,
            required: true
        }
    ]
});
// cl-table
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t('订单编号'), prop: "orderNo", minWidth: 140 },
        { label: t('可回收物编码'), prop: "typeId", minWidth: 120 },
        { label: t('名称'), prop: "name", minWidth: 140 },
        { label: t('计量单位'), prop: "unit", minWidth: 140 },
        { label: t('ä»·æ ¼(元)'), prop: "price", minWidth: 140, sortable: "custom" },
        { label: t('碳积分'), prop: "carbonPoint", minWidth: 140, sortable: "custom" },
        { label: t('固废编码'), prop: "category", minWidth: 120 },
        {
            label: t('状态'),
            prop: "status",
            minWidth: 100,
            component: { name: "cl-switch" },
            dict: options.status
        },
        {
            label: t('创建时间'),
            prop: "createTime",
            minWidth: 170,
            sortable: "desc",
            component: { name: "cl-date-text" }
        },
        {
            label: t('更新时间'),
            prop: "updateTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        { type: "op", buttons: ["edit", "delete"] }
    ]
});
// cl-search
const Search = useSearch();
// cl-crud
const Crud = useCrud(
    {
        service: service.shop.recycleorderitem
    },
    (app) => {
        app.refresh();
    }
);
// åˆ·æ–°
function refresh(params?: any) {
    Crud.value?.refresh(params);
}
</script>
src/modules/shop/views/transaction.vue
New file
@@ -0,0 +1,173 @@
<template>
    <cl-crud ref="Crud">
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
            <!-- æ¡ä»¶æœç´¢ -->
            <cl-search ref="Search" />
        </cl-row>
        <cl-row>
            <!-- æ•°æ®è¡¨æ ¼ -->
            <cl-table ref="Table" />
        </cl-row>
        <cl-row>
            <cl-flex1 />
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <cl-pagination />
        </cl-row>
        <!-- æ–°å¢žã€ç¼–辑 -->
        <cl-upsert ref="Upsert" />
    </cl-crud>
</template>
<script lang="ts" setup>
defineOptions({
    name: "finance-transaction"
});
import { useCrud, useTable, useUpsert, useSearch } from "@cool-vue/crud";
import { useCool } from "/@/cool";
import { useI18n } from "vue-i18n";
import { reactive } from "vue";
import UserSelect from "/$/user/components/user-select.vue";
const { service } = useCool();
const { t } = useI18n();
// é€‰é¡¹
const options = reactive({
    type: [
        { label: t('收入'), value: "收入", type: "danger" },
        { label: t('支出'), value: "支出", type: "success" }
    ],
    sourceType: [
        { label: t('回收'), value: '回收' },
        { label: t('商城'), value: '商城' },
        { label: t('赠送'), value: '赠送' },
        { label: t('接受'), value: '接受' },
        { label: t('捐赠'), value: '捐赠' },
        { label: t('签到'), value: '签到' },
    ]
});
// cl-upsert
const Upsert = useUpsert({
    items: [
        {
            label: t('选择用户'),
            prop: "userId",
            component: { vm: UserSelect },
            required: true
        },
        {
            label: t("选择学校"),
            prop: "departmentId",
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选 / true å¤šé€‰
                    placeholder: "请选择学校",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            required: true,
        },
        {
            label: t('流水类型'),
            prop: "type",
            component: { name: "el-radio-group", options: options.type },
            value: "收入",
            required: true
        },
        {
            label: t('金额'),
            prop: "amount",
            hook: "number",
            component: { name: "el-input-number", props: { min: 0 } },
            span: 12,
            required: true
        },
        {
            label: t('来源类型'),
            prop: "sourceType",
            component: { name: "cl-select", props: { options: options.sourceType } },
            value: "回收",
            span: 12,
            required: true
        },
        {
            label: t('备注'),
            prop: "remark",
            component: { name: "el-input", props: { type: "textarea", rows: 4 } }
        },
        {
            label: t('订单ID'),
            prop: "orderId",
            component: { name: "el-input", props: { clearable: true } },
            span: 12
        }
    ]
});
// cl-table
const Table = useTable({
    columns: [
        { type: "selection" },
        { label: t('昵称'), prop: "userName", minWidth: 140 },
        { label: t('所属机构'), prop: "departmentName", minWidth: 120 },
        { label: t('流水类型'), prop: "type", minWidth: 120, dict: options.type },
        { label: t('金额'), prop: "amount", minWidth: 140, sortable: "custom" },
        {
            label: t('来源类型'),
            prop: "sourceType",
            minWidth: 120,
            dict: options.sourceType
        },
        { label: t('备注'), prop: "remark", showOverflowTooltip: true, minWidth: 200 },
        { label: t('订单ID'), prop: "orderId", minWidth: 140 },
        {
            label: t('创建时间'),
            prop: "createTime",
            minWidth: 170,
            sortable: "desc",
            component: { name: "cl-date-text" }
        },
        /*{
            label: t('更新时间'),
            prop: "updateTime",
            minWidth: 170,
            sortable: "custom",
            component: { name: "cl-date-text" }
        },
        */
        { type: "op", buttons: ["edit", "delete"] }
    ]
});
// cl-search
const Search = useSearch();
// cl-crud
const Crud = useCrud(
    {
        service: service.shop.transaction
    },
    (app) => {
        app.refresh();
    }
);
// åˆ·æ–°
function refresh(params?: any) {
    Crud.value?.refresh(params);
}
</script>
src/modules/user/locales/zh-cn.json
@@ -16,5 +16,15 @@
  "状态": "状态",
  "创建时间": "创建时间",
  "选择用户": "选择用户",
  "姓名": "姓名"
  "姓名": "姓名",
  "学生": "学生",
  "老师": "老师",
  "学院名称": "学院名称",
  "专业名称": "专业名称",
  "班级名称": "班级名称",
  "学院ID": "学院ID",
  "专业ID": "专业ID",
  "班级ID": "班级ID",
  "碳积分总额":"碳积分总额",
  "唯一标识":"唯一标识"
}
src/modules/user/views/list.vue
@@ -3,6 +3,8 @@
        <cl-row>
            <!-- åˆ·æ–°æŒ‰é’® -->
            <cl-refresh-btn />
            <!-- æ–°å¢žæŒ‰é’® -->
            <cl-add-btn />
            <!-- åˆ é™¤æŒ‰é’® -->
            <cl-multi-delete-btn />
            <cl-flex1 />
@@ -90,6 +92,20 @@
            value: 2,
            type: 'warning'
        }
    ],
    role: [
        {
            label: t('学生'),
            value: '学生'
        },
        {
            label: t('老师'),
            value: '老师'
        },
        {
            label: t('未知'),
            value: '未知'
        }
    ]
});
@@ -101,8 +117,18 @@
            width: 60
        },
        {
            label: t('所属单位'),
            prop: 'departmentName',
            minWidth: 150
        },
        {
            label: t('昵称'),
            prop: 'nickName',
            minWidth: 150
        },
        {
            label: t('生日'),
            prop: 'birthday',
            minWidth: 150
        },
        {
@@ -119,9 +145,34 @@
            minWidth: 120
        },
        {
            label: t('角色'),
            prop: 'role',
            minWidth: 120
        },
        {
            label: t('性别'),
            prop: 'gender',
            dict: options.gender,
            minWidth: 120
        },
        {
            label: t('碳积分总额'),
            prop: 'carbonBalance',
            minWidth: 120
        },
        {
            label: t('学院名称'),
            prop: 'collegeName',
            minWidth: 120
        },
        {
            label: t('专业名称'),
            prop: 'majorName',
            minWidth: 120
        },
        {
            label: t('班级名称'),
            prop: 'className',
            minWidth: 120
        },
        {
@@ -157,11 +208,37 @@
            component: { name: 'cl-upload' }
        },
        {
            label: t("选择部门"),
            prop: "departmentId",
            component: {
                name: 'cl-dept-select',
                props: {
                    multiple: false,      // å•选 / true å¤šé€‰
                    placeholder: "请选择部门",
                    checkStrictly: true,  // çˆ¶å­èŠ‚ç‚¹ä¸è”åŠ¨
                    immediate: true       // ç«‹å³åŠ è½½éƒ¨é—¨æ ‘
                }
            },
            required: true,
        },
        {
            prop: 'unionid',
            label: t('唯一标识'),
            component: { name: 'el-input' },
            required: true
        },
        {
            prop: 'nickName',
            label: t('昵称'),
            component: { name: 'el-input' },
            required: true
        },
        {
            prop: 'birthday',
            label: t('生日'),
            component: { name: 'el-input' }
        },
        {
            prop: 'phone',
            label: t('手机号'),
@@ -182,6 +259,51 @@
            }
        },
        {
            prop: 'role',
            label: t('角色'),
            value: '学生',
            component: {
                name: 'el-radio-group',
                options: options.role
            }
        },
        {
            prop: 'carbonBalance',
            label: t('碳积分总额'),
            value: 0,
            component: { name: 'el-input' }
        },
        {
            prop: 'collegeId',
            label: t('学院ID'),
            component: { name: 'el-input' }
        },
        {
            prop: 'collegeName',
            label: t('学院名称'),
            component: { name: 'el-input' }
        },
        {
            prop: 'majorId',
            label: t('专业ID'),
            component: { name: 'el-input' }
        },
        {
            prop: 'majorName',
            label: t('专业名称'),
            component: { name: 'el-input' }
        },
        {
            prop: 'classId',
            label: t('班级ID'),
            component: { name: 'el-input' }
        },
        {
            prop: 'className',
            label: t('班级名称'),
            component: { name: 'el-input' }
        },
        {
            prop: 'status',
            label: t('状态'),
            value: 1,
´ó¼þÀ¬»ø»ØÊÕ.txt
New file
@@ -0,0 +1,90 @@
现在给一个学校的垃圾回收运营平台设计一个模块,即分拣人员管理模块。
人员以身份证号码为唯一标识,以手机号码为登录账号,密码单独设置。
业务功能包括:
登录 æ‰“卡工作,打卡下班;
gps位置附带健康数据,每间隔5分钟; å¥åº·æ•°æ®åŒ…括体温,血压,血氧... ç­‰ã€‚
实时消息,类似于告警数据,比如体温异常,血压异常,血氧异常等,这个是即时的,不受到5分钟的限制。
所有相关的表格,都包含身份证号码和departmentId(departmentId ä»Ž sorter基本信息表中获取)。
还有一类用户是学校师生,以工号/学号为唯一标识,另外其归属于一个学校院系,专业,班级。
每个师生有一个碳积分balance表,把可回收物送到收集点或者是预约上门后,把兑换成碳积分, ä»Žç¢³ç§¯åˆ†å•†åŸŽè´­ä¹°ï¼Œè½¬å¢žç»™å…¶ä»–人,或者无偿捐赠,这些是碳积分的消耗行为。
后期会行成按照班级,专业,院系,总数和人均的碳积分排名等。
预约上门回收可回收物类似于一个订单的管理,从预约开始,到最终结束。
垃圾的大类,包括:
有毒有害  \x6709\x6BD2\x6709\x5BB3
湿垃圾   \x6E7F\x5783\x573E
可回收-废纸张     \x53EF\x56DE\x6536\x002D\x5E9F\x7EB8\x5F20
可回收-废塑料   \x53EF\x56DE\x6536\x002D\x5E9F\x5851\x6599
可回收-废金属   \x53EF\x56DE\x6536\x002D\x5E9F\x91D1\x5C5E
可回收-废玻璃   \x53EF\x56DE\x6536\x002D\x5E9F\x73BB\x7483
可回收-废织物   \x53EF\x56DE\x6536\x002D\x5E9F\x7EC7\x7269\x0020
可回收-废旧电子产品   \x53EF\x56DE\x6536\x002D\x5E9F\x65E7\x7535\x5B50\x4EA7\x54C1
可回收-废旧电源电池   \x53EF\x56DE\x6536\x002D\x5E9F\x65E7\x7535\x6E90\x7535\x6C60
大件垃圾   \x5927\x4EF6\x5783\x573E
干垃圾   \x5E72\x5783\x573E
但是从师生的学校场景出发,把日常能见到的一些可回收物-物品 å¯¹åº”到这些大类,从而转换成一套基础信息表/配置表,即每种类的可回收物的售价,方便师生和分拣人员相互了解。
无论是回收可回收物-为师生发放碳积分,还是购买碳积分的学校文创小商品,都是由分拣人员来扫码(师生的唯一二维码/学校一码通),这样确认流程是ok。
最终还能按照分拣点,分拣人员来统计各类重量,价值等,上门回收订单数量,销售文创商品数量等。
垃圾分拣点还要放一个立柱式的屏幕,让学生自己打卡-就是只投递了非常少的价值的干垃圾或者可回收物,就固定发放5个碳积分,就不用分拣人员的android app æ¥æ“ä½œï¼Œï¼Œå°±ç”±å¤§å±ä¸Šçš„æ‰«ç æœºå™¨æ‰«é¢ï¼Œä¹‹åŽå¼¹å‡ºä¸€ä¸ªæ­å–œæˆ–者感谢之类的。
你先帮我分析一些这些实体关系,设计一下数据结构。