Showing
7 changed files
with
509 additions
and
206 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2022-06-17 14:54:29 | 2 | * @Date: 2022-06-17 14:54:29 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-25 13:13:43 | 4 | + * @LastEditTime: 2024-07-26 11:34:18 |
| 5 | * @FilePath: /temple_material_request/src/api/material.js | 5 | * @FilePath: /temple_material_request/src/api/material.js |
| 6 | * @Description: 物资申请接口 | 6 | * @Description: 物资申请接口 |
| 7 | */ | 7 | */ |
| ... | @@ -60,6 +60,7 @@ export const addCartAPI = (params) => fn(fetch.post(Api.CART_ADD, params)); | ... | @@ -60,6 +60,7 @@ export const addCartAPI = (params) => fn(fetch.post(Api.CART_ADD, params)); |
| 60 | /** | 60 | /** |
| 61 | * @description: 编辑购物车 | 61 | * @description: 编辑购物车 |
| 62 | * @param: activity_id 活动ID | 62 | * @param: activity_id 活动ID |
| 63 | + * @param: good_list [{good_id,apply_number}] | ||
| 63 | */ | 64 | */ |
| 64 | export const editCartAPI = (params) => fn(fetch.post(Api.CART_EDIT, params)); | 65 | export const editCartAPI = (params) => fn(fetch.post(Api.CART_EDIT, params)); |
| 65 | 66 | ||
| ... | @@ -91,7 +92,7 @@ export const myUserAPI = (params) => fn(fetch.get(Api.MY_USER, params)); | ... | @@ -91,7 +92,7 @@ export const myUserAPI = (params) => fn(fetch.get(Api.MY_USER, params)); |
| 91 | * @param: contact_name 领用人姓名 | 92 | * @param: contact_name 领用人姓名 |
| 92 | * @param: contact_phone 领用人电话 | 93 | * @param: contact_phone 领用人电话 |
| 93 | * @param: use_time 使用时间 | 94 | * @param: use_time 使用时间 |
| 94 | - * @param: good_list [good_id 物资ID, apply_number 申请数量] | 95 | + * @param: good_list [good_id 物资ID, apply_number 申请数量] 如果为空,就自动查询购物车中的物资 |
| 95 | */ | 96 | */ |
| 96 | export const addUseOrderAPI = (params) => fn(fetch.post(Api.USE_ORDER_ADD, params)); | 97 | export const addUseOrderAPI = (params) => fn(fetch.post(Api.USE_ORDER_ADD, params)); |
| 97 | 98 | ||
| ... | @@ -102,10 +103,10 @@ export const addUseOrderAPI = (params) => fn(fetch.post(Api.USE_ORDER_ADD, param | ... | @@ -102,10 +103,10 @@ export const addUseOrderAPI = (params) => fn(fetch.post(Api.USE_ORDER_ADD, param |
| 102 | * @param: offset | 103 | * @param: offset |
| 103 | * @param: limit | 104 | * @param: limit |
| 104 | */ | 105 | */ |
| 105 | -export const skuListAPI = (params) => fn(fetch.get(Api.SKU_LIST, params)); | 106 | +export const getSkuListAPI = (params) => fn(fetch.get(Api.SKU_LIST, params)); |
| 106 | 107 | ||
| 107 | /** | 108 | /** |
| 108 | * @description: 规格物资详情 | 109 | * @description: 规格物资详情 |
| 109 | * @param: i 规格物资ID | 110 | * @param: i 规格物资ID |
| 110 | */ | 111 | */ |
| 111 | -export const skuInfoAPI = (params) => fn(fetch.get(Api.SKU_INFO, params)); | 112 | +export const getSkuInfoAPI = (params) => fn(fetch.get(Api.SKU_INFO, params)); | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 16:24:08 | 2 | * @Date: 2024-07-23 16:24:08 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-25 13:32:12 | 4 | + * @LastEditTime: 2024-07-26 13:57:29 |
| 5 | * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue | 5 | * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue |
| 6 | * @Description: 选择物资组件 | 6 | * @Description: 选择物资组件 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | - <div class="choose-material-page"> | 9 | + <div v-if="showBottom" class="choose-material-page"> |
| 10 | <van-popup | 10 | <van-popup |
| 11 | v-model:show="showBottom" | 11 | v-model:show="showBottom" |
| 12 | position="bottom" | 12 | position="bottom" |
| ... | @@ -20,23 +20,23 @@ | ... | @@ -20,23 +20,23 @@ |
| 20 | <van-row gutter="10" justify="center" align="center"> | 20 | <van-row gutter="10" justify="center" align="center"> |
| 21 | <van-col span="24"> | 21 | <van-col span="24"> |
| 22 | <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;"> | 22 | <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;"> |
| 23 | - <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资" style="background-color: #FBF9F1;" /> | 23 | + <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资名称/规格" style="background-color: #FBF9F1;" /> |
| 24 | </div> | 24 | </div> |
| 25 | </van-col> | 25 | </van-col> |
| 26 | </van-row> | 26 | </van-row> |
| 27 | </div> | 27 | </div> |
| 28 | </div> | 28 | </div> |
| 29 | + <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;"> | ||
| 30 | + <van-col span="8" @click="onCheckAll()"> | ||
| 31 | + <van-icon v-if="is_all_checked" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 32 | + <van-icon v-else name="passed" size="1.25rem" /> | ||
| 33 | + <span :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 34 | + </van-col> | ||
| 35 | + <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">选择物资</van-col> | ||
| 36 | + <van-col span="8"></van-col> | ||
| 37 | + </van-row> | ||
| 29 | </van-sticky> | 38 | </van-sticky> |
| 30 | <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 --> | 39 | <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 --> |
| 31 | - <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;"> | ||
| 32 | - <van-col span="8" @click="onCheckAll()"> | ||
| 33 | - <van-icon v-if="is_all_checked" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 34 | - <van-icon v-else name="passed" size="1.25rem" /> | ||
| 35 | - <span :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 36 | - </van-col> | ||
| 37 | - <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">选择物资</van-col> | ||
| 38 | - <van-col span="8"></van-col> | ||
| 39 | - </van-row> | ||
| 40 | <van-list | 40 | <van-list |
| 41 | v-model:loading="loading" | 41 | v-model:loading="loading" |
| 42 | :finished="finished" | 42 | :finished="finished" |
| ... | @@ -49,7 +49,7 @@ | ... | @@ -49,7 +49,7 @@ |
| 49 | <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | 49 | <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> |
| 50 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> | 50 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> |
| 51 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> | 51 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> |
| 52 | - {{ item.name }} | 52 | + {{ item.name }} / {{ item.spec }} |
| 53 | </div> | 53 | </div> |
| 54 | </van-col> | 54 | </van-col> |
| 55 | </van-row> | 55 | </van-row> |
| ... | @@ -68,7 +68,7 @@ | ... | @@ -68,7 +68,7 @@ |
| 68 | </van-popup> | 68 | </van-popup> |
| 69 | </div> | 69 | </div> |
| 70 | 70 | ||
| 71 | - <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail> | 71 | + <material-detail :show="show_material_detail" :good-id="material_id" @close="onCloseDetail"></material-detail> |
| 72 | 72 | ||
| 73 | </template> | 73 | </template> |
| 74 | 74 | ||
| ... | @@ -82,11 +82,14 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ | ... | @@ -82,11 +82,14 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ |
| 82 | //import { } from '@/composables' | 82 | //import { } from '@/composables' |
| 83 | import { styleColor } from "@/constant.js"; | 83 | import { styleColor } from "@/constant.js"; |
| 84 | import materialDetail from '@/components/materialDetail/index.vue'; | 84 | import materialDetail from '@/components/materialDetail/index.vue'; |
| 85 | +import { getSkuListAPI, getCartListAPI, addCartAPI } from "@/api/material"; | ||
| 85 | 86 | ||
| 86 | const $route = useRoute(); | 87 | const $route = useRoute(); |
| 87 | const $router = useRouter(); | 88 | const $router = useRouter(); |
| 88 | useTitle($route.meta.title); | 89 | useTitle($route.meta.title); |
| 89 | 90 | ||
| 91 | +const activity_id = $route.query.activity_id ? $route.query.activity_id : 800863; | ||
| 92 | + | ||
| 90 | const props = defineProps({ | 93 | const props = defineProps({ |
| 91 | show: Boolean, | 94 | show: Boolean, |
| 92 | }); | 95 | }); |
| ... | @@ -94,46 +97,84 @@ const emit = defineEmits(['close']); | ... | @@ -94,46 +97,84 @@ const emit = defineEmits(['close']); |
| 94 | 97 | ||
| 95 | const showBottom = ref(false); | 98 | const showBottom = ref(false); |
| 96 | 99 | ||
| 97 | -onMounted(() => { | 100 | +const limit = ref(20); |
| 101 | +const offset = ref(0); | ||
| 102 | + | ||
| 103 | +const list = ref([]); | ||
| 104 | +const loading = ref(false); | ||
| 105 | +const finished = ref(false); | ||
| 106 | + | ||
| 107 | + | ||
| 108 | +const getList = async () => { | ||
| 109 | + const { code, data } = await getSkuListAPI({ exclude_activity_id: activity_id, k: '', offset: offset.value, limit: limit.value }); | ||
| 110 | + if (code) { | ||
| 111 | + // 默认勾选标记 | ||
| 112 | + data.forEach(item => { | ||
| 113 | + item.checked = false; | ||
| 114 | + }); | ||
| 115 | + list.value = data; | ||
| 116 | + offset.value = list.value.length; | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +onMounted(async () => { | ||
| 121 | + // 获取物资列表 | ||
| 122 | + getList(); | ||
| 123 | + // 购物车数量 | ||
| 124 | + getCartCount(); | ||
| 98 | }); | 125 | }); |
| 99 | 126 | ||
| 127 | +const getCartCount = async () => { | ||
| 128 | + // 购物车数量 | ||
| 129 | + const cartList = await getCartListAPI({activity_id}); | ||
| 130 | + if (cartList.code) { | ||
| 131 | + cart_count.value = cartList.data.length; | ||
| 132 | + } | ||
| 133 | +} | ||
| 134 | + | ||
| 100 | // 监听字段变化 | 135 | // 监听字段变化 |
| 101 | watch( | 136 | watch( |
| 102 | () => props.show, | 137 | () => props.show, |
| 103 | (v) => { | 138 | (v) => { |
| 104 | showBottom.value = v; | 139 | showBottom.value = v; |
| 140 | + if (v) { | ||
| 141 | + } | ||
| 105 | } | 142 | } |
| 106 | ); | 143 | ); |
| 107 | 144 | ||
| 108 | const onClose = () => { | 145 | const onClose = () => { |
| 146 | + // 重置查询条件 | ||
| 147 | + offset.value = 0; | ||
| 148 | + limit.value = 20; | ||
| 149 | + finished.value = false; | ||
| 150 | + list.value = []; | ||
| 109 | emit('close'); | 151 | emit('close'); |
| 110 | } | 152 | } |
| 111 | 153 | ||
| 112 | -const list = ref([]); | 154 | +const onLoad = async () => { |
| 113 | -const loading = ref(false); | ||
| 114 | -const finished = ref(false); | ||
| 115 | - | ||
| 116 | -const onLoad = () => { | ||
| 117 | // 异步更新数据 | 155 | // 异步更新数据 |
| 118 | - // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | 156 | + const { code, data } = await getSkuListAPI({ exclude_activity_id: activity_id, k: search_value.value, offset: offset.value, limit: limit.value }); |
| 119 | - setTimeout(() => { | 157 | + if (code) { |
| 120 | - for (let i = 0; i < 5; i++) { | 158 | + // 默认勾选标记 |
| 121 | - list.value.push({ id: i, name: '物资' + i, checked: false }); | 159 | + data.forEach(item => { |
| 122 | - } | 160 | + item.checked = false; |
| 123 | - | 161 | + }); |
| 124 | - // 加载状态结束 | 162 | + list.value = _.concat(list.value, data); |
| 163 | + list.value = _.uniqBy(list.value, 'id'); | ||
| 164 | + offset.value = list.value.length; | ||
| 125 | loading.value = false; | 165 | loading.value = false; |
| 126 | - | ||
| 127 | // 数据全部加载完成 | 166 | // 数据全部加载完成 |
| 128 | - if (list.value.length >= 10) { | 167 | + if (!data.length) { |
| 168 | + // 加载状态结束 | ||
| 129 | finished.value = true; | 169 | finished.value = true; |
| 130 | } | 170 | } |
| 131 | - }, 1000); | 171 | + } |
| 132 | }; | 172 | }; |
| 133 | 173 | ||
| 174 | +const material_id = ref(''); | ||
| 134 | const onClickTitle = (item) => { // 点击物资标题回调 | 175 | const onClickTitle = (item) => { // 点击物资标题回调 |
| 135 | - console.warn(item); | ||
| 136 | show_material_detail.value = true; | 176 | show_material_detail.value = true; |
| 177 | + material_id.value = item.id; | ||
| 137 | } | 178 | } |
| 138 | 179 | ||
| 139 | const show_type = ref(false); | 180 | const show_type = ref(false); |
| ... | @@ -146,9 +187,22 @@ const onConfirm = () => { | ... | @@ -146,9 +187,22 @@ const onConfirm = () => { |
| 146 | } | 187 | } |
| 147 | 188 | ||
| 148 | const search_value = ref(''); | 189 | const search_value = ref(''); |
| 149 | -const onBlur = () => { | 190 | +const onBlur = async () => { // 搜索回调 |
| 150 | - // TODO: 输入框失去焦点,接口需要一个搜索接口,返回相应的值 | 191 | + // 重置查询条件 |
| 151 | - console.warn(search_value.value); | 192 | + offset.value = 0; |
| 193 | + limit.value = 20; | ||
| 194 | + finished.value = false; | ||
| 195 | + list.value = []; | ||
| 196 | + // 查询列表数据 | ||
| 197 | + const { code, data } = await getSkuListAPI({ exclude_activity_id: activity_id, k: search_value.value, offset: offset.value, limit: limit.value }); | ||
| 198 | + if (code) { | ||
| 199 | + // 默认勾选标记 | ||
| 200 | + data.forEach(item => { | ||
| 201 | + item.checked = false; | ||
| 202 | + }); | ||
| 203 | + list.value = data; | ||
| 204 | + offset.value = list.value.length; | ||
| 205 | + } | ||
| 152 | } | 206 | } |
| 153 | 207 | ||
| 154 | const show_material_detail = ref(false); | 208 | const show_material_detail = ref(false); |
| ... | @@ -181,27 +235,40 @@ const onCheck = (item) => { | ... | @@ -181,27 +235,40 @@ const onCheck = (item) => { |
| 181 | } | 235 | } |
| 182 | } | 236 | } |
| 183 | 237 | ||
| 184 | -const addShoppingCart = () => { // 新增购物车 | 238 | +const addShoppingCart = async () => { // 新增购物车 |
| 185 | shop_cart_list.value = []; | 239 | shop_cart_list.value = []; |
| 186 | list.value.forEach(item => { | 240 | list.value.forEach(item => { |
| 187 | - item.m_list.forEach(m => { | 241 | + if (item.checked) { |
| 188 | - if (m.checked) { | 242 | + shop_cart_list.value.push({ |
| 189 | - shop_cart_list.value.push(m); | 243 | + good_id: item.id, |
| 190 | - } | 244 | + apply_number: 0 |
| 191 | - }) | 245 | + }); |
| 246 | + } | ||
| 192 | }); | 247 | }); |
| 193 | // 购物车为空提示 | 248 | // 购物车为空提示 |
| 194 | if (!shop_cart_list.value.length) { | 249 | if (!shop_cart_list.value.length) { |
| 195 | showToast('请选择物资'); | 250 | showToast('请选择物资'); |
| 196 | return; | 251 | return; |
| 197 | } | 252 | } |
| 198 | - // TODO: 请求购物车接口,更新购物车数量 | 253 | + // 请求购物车接口,更新购物车数量 |
| 199 | - console.warn(shop_cart_list.value); | 254 | + const { code, data } = await addCartAPI({ activity_id, good_list: shop_cart_list.value }); |
| 255 | + if (code) { | ||
| 256 | + // 获取 shop_cart_list 中所有 id 的数组 | ||
| 257 | + let idsToRemove = shop_cart_list.value.map(item => item.good_id); | ||
| 258 | + | ||
| 259 | + // 过滤 arr1,排除 id 在 idsToRemove 中的元素 | ||
| 260 | + list.value = list.value.filter(item => !idsToRemove.includes(item.id)); | ||
| 261 | + | ||
| 262 | + // 购物车数量 | ||
| 263 | + getCartCount(); | ||
| 264 | + | ||
| 265 | + showToast('添加成功'); | ||
| 266 | + } | ||
| 200 | } | 267 | } |
| 201 | 268 | ||
| 202 | const goShoppingCart = () => { // 点击购物车图标 | 269 | const goShoppingCart = () => { // 点击购物车图标 |
| 203 | if ($route.path === '/material_pre_request') { // 待申领物资页面 | 270 | if ($route.path === '/material_pre_request') { // 待申领物资页面 |
| 204 | - onClose() | 271 | + onClose(); |
| 205 | } else { | 272 | } else { |
| 206 | $router.push({ path: '/material_pre_request' }); | 273 | $router.push({ path: '/material_pre_request' }); |
| 207 | } | 274 | } | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 18:31:35 | 2 | * @Date: 2024-07-23 18:31:35 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-24 11:00:42 | 4 | + * @LastEditTime: 2024-07-26 10:11:43 |
| 5 | * @FilePath: /temple_material_request/src/components/materialDetail/index.vue | 5 | * @FilePath: /temple_material_request/src/components/materialDetail/index.vue |
| 6 | * @Description: 物资详情页面 | 6 | * @Description: 物资详情页面 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | - <div class="material-detail-page"> | 9 | + <div v-if="showRight" class="material-detail-page"> |
| 10 | <van-popup | 10 | <van-popup |
| 11 | v-model:show="showRight" | 11 | v-model:show="showRight" |
| 12 | position="right" | 12 | position="right" |
| ... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
| 16 | > | 16 | > |
| 17 | <div style="margin-top: 3rem; background-color: white;"> | 17 | <div style="margin-top: 3rem; background-color: white;"> |
| 18 | <div style="display: flex; justify-content: center; align-items: center;"> | 18 | <div style="display: flex; justify-content: center; align-items: center;"> |
| 19 | - <div style="padding: 2rem 5rem; padding-bottom: 2rem; border: 1px solid #F2EDE6; background-color: #FFFDF6; text-align: center;"> | 19 | + <div v-if="!goodInfo.cover" style="padding: 2rem 5rem; padding-bottom: 2rem; border: 1px solid #F2EDE6; background-color: #FFFDF6; text-align: center;"> |
| 20 | <van-image | 20 | <van-image |
| 21 | width="6rem" | 21 | width="6rem" |
| 22 | height="6rem" | 22 | height="6rem" |
| ... | @@ -25,45 +25,71 @@ | ... | @@ -25,45 +25,71 @@ |
| 25 | /> | 25 | /> |
| 26 | <div style="color: #e0d0ba; margin-top: 1rem;">物资图正在整理中</div> | 26 | <div style="color: #e0d0ba; margin-top: 1rem;">物资图正在整理中</div> |
| 27 | </div> | 27 | </div> |
| 28 | + <div v-else> | ||
| 29 | + <van-image | ||
| 30 | + width="15rem" | ||
| 31 | + height="12rem" | ||
| 32 | + fit="contain" | ||
| 33 | + :src="goodInfo.cover" | ||
| 34 | + /> | ||
| 35 | + </div> | ||
| 28 | </div> | 36 | </div> |
| 29 | - <div style="text-align: center; font-weight: bold; color: #A67939; font-size: 1.15rem; margin: 1.5rem auto;">口袋义工服T恤(绿)</div> | 37 | + <div style="text-align: center; font-weight: bold; color: #A67939; font-size: 1.15rem; margin: 1.5rem auto;">{{ goodInfo.name }}</div> |
| 30 | <div style="color: #1C1C1C; background-color: #F2F2F2; font-size: 1rem; font-weight: bold; padding: 0.5rem 1.5rem;">基本信息</div> | 38 | <div style="color: #1C1C1C; background-color: #F2F2F2; font-size: 1rem; font-weight: bold; padding: 0.5rem 1.5rem;">基本信息</div> |
| 31 | <div style="padding: 1rem;"> | 39 | <div style="padding: 1rem;"> |
| 32 | <van-row style="margin-bottom: 0.5rem;"> | 40 | <van-row style="margin-bottom: 0.5rem;"> |
| 33 | <van-col span="8" style="color: #AFAFAF;">编码</van-col> | 41 | <van-col span="8" style="color: #AFAFAF;">编码</van-col> |
| 34 | - <van-col span="16">XFZ0021004</van-col> | 42 | + <van-col span="16">{{ goodInfo.coding }}</van-col> |
| 35 | </van-row> | 43 | </van-row> |
| 36 | <van-row style="margin-bottom: 0.5rem;"> | 44 | <van-row style="margin-bottom: 0.5rem;"> |
| 37 | <van-col span="8" style="color: #AFAFAF;">规格</van-col> | 45 | <van-col span="8" style="color: #AFAFAF;">规格</van-col> |
| 38 | - <van-col span="16">XXL</van-col> | 46 | + <van-col span="16">{{ goodInfo.spec }}</van-col> |
| 39 | </van-row> | 47 | </van-row> |
| 40 | <van-row style="margin-bottom: 0.5rem;"> | 48 | <van-row style="margin-bottom: 0.5rem;"> |
| 41 | <van-col span="8" style="color: #AFAFAF;">单位</van-col> | 49 | <van-col span="8" style="color: #AFAFAF;">单位</van-col> |
| 42 | - <van-col span="16">件</van-col> | 50 | + <van-col span="16">{{ goodInfo.specification }}</van-col> |
| 43 | </van-row> | 51 | </van-row> |
| 44 | <van-row style="margin-bottom: 0.5rem;"> | 52 | <van-row style="margin-bottom: 0.5rem;"> |
| 45 | <van-col span="8" style="color: #AFAFAF;">分类</van-col> | 53 | <van-col span="8" style="color: #AFAFAF;">分类</van-col> |
| 46 | - <van-col span="16">新服装</van-col> | 54 | + <van-col span="16"> |
| 55 | + <div v-if="goodInfo.category_name">{{ goodInfo.category_name }}</div> | ||
| 56 | + <div v-else>/</div> | ||
| 57 | + </van-col> | ||
| 47 | </van-row> | 58 | </van-row> |
| 48 | <van-row style="margin-bottom: 0.5rem;"> | 59 | <van-row style="margin-bottom: 0.5rem;"> |
| 49 | <van-col span="8" style="color: #AFAFAF;">描述</van-col> | 60 | <van-col span="8" style="color: #AFAFAF;">描述</van-col> |
| 50 | - <van-col span="16">/</van-col> | 61 | + <van-col span="16"> |
| 62 | + <div v-if="goodInfo.description" v-html="goodInfo.description"></div> | ||
| 63 | + <div v-else>/</div> | ||
| 64 | + </van-col> | ||
| 51 | </van-row> | 65 | </van-row> |
| 52 | <van-row style="margin-bottom: 0.5rem;"> | 66 | <van-row style="margin-bottom: 0.5rem;"> |
| 53 | <van-col span="8" style="color: #AFAFAF;">条码</van-col> | 67 | <van-col span="8" style="color: #AFAFAF;">条码</van-col> |
| 54 | - <van-col span="16">/</van-col> | 68 | + <van-col span="16"> |
| 69 | + <div v-if="goodInfo.bar_code">{{ goodInfo.bar_code }}</div> | ||
| 70 | + <div v-else>/</div> | ||
| 71 | + </van-col> | ||
| 55 | </van-row> | 72 | </van-row> |
| 56 | <van-row style="margin-bottom: 0.5rem;"> | 73 | <van-row style="margin-bottom: 0.5rem;"> |
| 57 | <van-col span="8" style="color: #AFAFAF;">价格</van-col> | 74 | <van-col span="8" style="color: #AFAFAF;">价格</van-col> |
| 58 | - <van-col span="16">/</van-col> | 75 | + <van-col span="16"> |
| 76 | + <div v-if="goodInfo.price">{{ goodInfo.price }}</div> | ||
| 77 | + <div v-else>/</div> | ||
| 78 | + </van-col> | ||
| 59 | </van-row> | 79 | </van-row> |
| 60 | <van-row style="margin-bottom: 0.5rem;"> | 80 | <van-row style="margin-bottom: 0.5rem;"> |
| 61 | <van-col span="8" style="color: #AFAFAF;">是否可定</van-col> | 81 | <van-col span="8" style="color: #AFAFAF;">是否可定</van-col> |
| 62 | - <van-col span="16">可定</van-col> | 82 | + <van-col span="16"> |
| 83 | + <div v-if="goodInfo.is_ordered">可定</div> | ||
| 84 | + <div v-else>不可定</div> | ||
| 85 | + </van-col> | ||
| 63 | </van-row> | 86 | </van-row> |
| 64 | <van-row style="margin-bottom: 0.5rem;"> | 87 | <van-row style="margin-bottom: 0.5rem;"> |
| 65 | <van-col span="8" style="color: #AFAFAF;">状态</van-col> | 88 | <van-col span="8" style="color: #AFAFAF;">状态</van-col> |
| 66 | - <van-col span="16">上架</van-col> | 89 | + <van-col span="16"> |
| 90 | + <div v-if="goodInfo.status === 9">上架</div> | ||
| 91 | + <div v-else>下架</div> | ||
| 92 | + </van-col> | ||
| 67 | </van-row> | 93 | </van-row> |
| 68 | </div> | 94 | </div> |
| 69 | </div> | 95 | </div> |
| ... | @@ -79,24 +105,37 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ | ... | @@ -79,24 +105,37 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ |
| 79 | //import { } from '@/utils/generateModules.js' | 105 | //import { } from '@/utils/generateModules.js' |
| 80 | //import { } from '@/utils/generateIcons.js' | 106 | //import { } from '@/utils/generateIcons.js' |
| 81 | //import { } from '@/composables' | 107 | //import { } from '@/composables' |
| 108 | +import { getSkuInfoAPI } from "@/api/material"; | ||
| 109 | + | ||
| 82 | const $route = useRoute(); | 110 | const $route = useRoute(); |
| 83 | const $router = useRouter(); | 111 | const $router = useRouter(); |
| 84 | useTitle($route.meta.title); | 112 | useTitle($route.meta.title); |
| 85 | 113 | ||
| 86 | const props = defineProps({ | 114 | const props = defineProps({ |
| 87 | show: Boolean, | 115 | show: Boolean, |
| 116 | + goodId: Number, | ||
| 88 | }); | 117 | }); |
| 118 | + | ||
| 89 | const emit = defineEmits(['close']); | 119 | const emit = defineEmits(['close']); |
| 90 | const showRight = ref(false); | 120 | const showRight = ref(false); |
| 91 | const onClose = () => { | 121 | const onClose = () => { |
| 92 | emit('close'); | 122 | emit('close'); |
| 93 | } | 123 | } |
| 94 | 124 | ||
| 125 | +const goodInfo = ref({}); | ||
| 126 | + | ||
| 95 | // 监听字段变化 | 127 | // 监听字段变化 |
| 96 | watch( | 128 | watch( |
| 97 | () => props.show, | 129 | () => props.show, |
| 98 | - (v) => { | 130 | + async (v) => { |
| 99 | showRight.value = v; | 131 | showRight.value = v; |
| 132 | + if (v) { | ||
| 133 | + const { code, data } = await getSkuInfoAPI({ i: props.goodId }); | ||
| 134 | + if (code) { | ||
| 135 | + // 物资信息 | ||
| 136 | + goodInfo.value = data; | ||
| 137 | + } | ||
| 138 | + } | ||
| 100 | } | 139 | } |
| 101 | ); | 140 | ); |
| 102 | </script> | 141 | </script> | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 10:50:38 | 2 | * @Date: 2024-07-23 10:50:38 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-25 10:00:39 | 4 | + * @LastEditTime: 2024-07-26 14:39:00 |
| 5 | * @FilePath: /temple_material_request/src/views/material_list.vue | 5 | * @FilePath: /temple_material_request/src/views/material_list.vue |
| 6 | * @Description: 物资情况页面 | 6 | * @Description: 物资情况页面 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <div class="material-list-page"> | 9 | <div class="material-list-page"> |
| 10 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> | 10 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> |
| 11 | - <van-tab v-for="index in 8" :title="'标签 ' + index"> | 11 | + <van-tab v-for="(item, index) in tabList" :title="item.dept_name" shrink> |
| 12 | <van-list | 12 | <van-list |
| 13 | v-model:loading="loading" | 13 | v-model:loading="loading" |
| 14 | :finished="finished" | 14 | :finished="finished" |
| ... | @@ -18,16 +18,20 @@ | ... | @@ -18,16 +18,20 @@ |
| 18 | <div v-for="item in list" :key="item" class="material-list-item"> | 18 | <div v-for="item in list" :key="item" class="material-list-item"> |
| 19 | <van-row> | 19 | <van-row> |
| 20 | <van-col span="14"> | 20 | <van-col span="14"> |
| 21 | - <div class="item-title van-ellipsis" :style="{ color: styleColor.baseColor }" @click="onClickTitle(item)">床垫 1.2m*2m</div> | 21 | + <div class="item-title van-ellipsis" :style="{ color: styleColor.baseColor }" @click="onClickTitle(item)">{{ item.product_name }} / {{ item.spec }}</div> |
| 22 | - <div class="item-attr">申领人:醒莲 2024/05/23使用 </div> | 22 | + <div class="item-attr"> |
| 23 | + <div v-for="(x, index) in item.order_list" :key="index"> | ||
| 24 | + 申领人: {{ x.contact_name }} {{ x.use_time }} 使用 | ||
| 25 | + </div> | ||
| 26 | + </div> | ||
| 23 | </van-col> | 27 | </van-col> |
| 24 | <van-col span="5"> | 28 | <van-col span="5"> |
| 25 | <div class="item-num-title">申请数量</div> | 29 | <div class="item-num-title">申请数量</div> |
| 26 | - <div class="item-num van-ellipsis">200个</div> | 30 | + <div class="item-num van-ellipsis">{{ item.total_apply_number }} 个</div> |
| 27 | </van-col> | 31 | </van-col> |
| 28 | <van-col span="5"> | 32 | <van-col span="5"> |
| 29 | <div class="item-num-title">实际领用</div> | 33 | <div class="item-num-title">实际领用</div> |
| 30 | - <div class="item-num van-ellipsis">200个</div> | 34 | + <div v-if="item.total_number" class="item-num van-ellipsis">{{ item.total_number }} 个</div> |
| 31 | </van-col> | 35 | </van-col> |
| 32 | </van-row> | 36 | </van-row> |
| 33 | </div> | 37 | </div> |
| ... | @@ -40,63 +44,105 @@ | ... | @@ -40,63 +44,105 @@ |
| 40 | </div> | 44 | </div> |
| 41 | </div> | 45 | </div> |
| 42 | 46 | ||
| 43 | - <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail> | 47 | + <material-detail :show="show_material_detail" :good-id="material_id" @close="onCloseDetail"></material-detail> |
| 44 | </template> | 48 | </template> |
| 45 | 49 | ||
| 46 | <script setup> | 50 | <script setup> |
| 47 | import { ref } from 'vue' | 51 | import { ref } from 'vue' |
| 48 | import { useRoute, useRouter } from 'vue-router' | 52 | import { useRoute, useRouter } from 'vue-router' |
| 49 | - | 53 | +import { showDialog } from 'vant'; |
| 50 | import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' | 54 | import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' |
| 51 | //import { } from '@/utils/generateModules.js' | 55 | //import { } from '@/utils/generateModules.js' |
| 52 | //import { } from '@/utils/generateIcons.js' | 56 | //import { } from '@/utils/generateIcons.js' |
| 53 | //import { } from '@/composables' | 57 | //import { } from '@/composables' |
| 54 | import { styleColor } from "@/constant.js"; | 58 | import { styleColor } from "@/constant.js"; |
| 55 | import materialDetail from '@/components/materialDetail/index.vue'; | 59 | import materialDetail from '@/components/materialDetail/index.vue'; |
| 56 | -import { getActivityDeptsAPI } from "@/api/material"; | 60 | +import { getActivityDeptsAPI, getGoodUseListAPI } from "@/api/material"; |
| 57 | 61 | ||
| 58 | const $route = useRoute(); | 62 | const $route = useRoute(); |
| 59 | const $router = useRouter(); | 63 | const $router = useRouter(); |
| 60 | useTitle($route.meta.title); | 64 | useTitle($route.meta.title); |
| 61 | 65 | ||
| 66 | +// form_id=799652&i=801234&c=35697 | ||
| 67 | +const activity_id = $route.query.activity_id ? $route.query.activity_id : ''; | ||
| 68 | +const form_id = $route.query.form_id ? $route.query.form_id : ''; | ||
| 69 | +const client_id = $route.query.client_id ? $route.query.client_id : ''; | ||
| 70 | + | ||
| 71 | +onMounted(async () => { | ||
| 72 | + const { data, code } = await getActivityDeptsAPI({ activity_id, is_previous: 0, only_my_dept: 0 }); | ||
| 73 | + if (code) { | ||
| 74 | + tabList.value = data; | ||
| 75 | + if (tabList.value.length) { // 默认选中组别ID | ||
| 76 | + dept_id.value = tabList.value[0]['dept_id']; | ||
| 77 | + } else { // 组别为空时跳转到购物车页面 | ||
| 78 | + showDialog({ | ||
| 79 | + title: '温馨提示', | ||
| 80 | + message: '物资列表为空,将前往添加!', | ||
| 81 | + confirmButtonColor: styleColor.baseColor | ||
| 82 | + }).then(() => { | ||
| 83 | + $router.push({ | ||
| 84 | + path: '/material_pre_request', | ||
| 85 | + query: { | ||
| 86 | + activity_id, | ||
| 87 | + form_id, | ||
| 88 | + client_id | ||
| 89 | + } | ||
| 90 | + }) | ||
| 91 | + }); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | +}); | ||
| 95 | + | ||
| 62 | const active = ref(0); | 96 | const active = ref(0); |
| 63 | -const onChange = (index) => { | 97 | +const onChange = async (index) => { |
| 64 | - console.warn(index); | 98 | + dept_id.value = tabList.value[index]['dept_id']; |
| 99 | + limit.value = 20; | ||
| 100 | + offset.value = 0; | ||
| 101 | + loading.value = false; | ||
| 102 | + finished.value = false; | ||
| 103 | + list.value = []; | ||
| 65 | } | 104 | } |
| 66 | 105 | ||
| 67 | -// TODO: getActivityDeptsAPI,is_previous=0,only_my_dept=0 | ||
| 68 | const tabList = ref([]); // 组别列表 | 106 | const tabList = ref([]); // 组别列表 |
| 107 | +const dept_id = ref(''); | ||
| 108 | + | ||
| 109 | +const limit = ref(20); | ||
| 110 | +const offset = ref(0); | ||
| 69 | 111 | ||
| 70 | const list = ref([]); | 112 | const list = ref([]); |
| 71 | const loading = ref(false); | 113 | const loading = ref(false); |
| 72 | const finished = ref(false); | 114 | const finished = ref(false); |
| 73 | 115 | ||
| 74 | -const onLoad = () => { | 116 | +const onLoad = async () => { |
| 75 | // 异步更新数据 | 117 | // 异步更新数据 |
| 76 | - // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | 118 | + const { code, data } = await getGoodUseListAPI({ activity_id, dept_id: dept_id.value, is_previous: 0, offset: offset.value, limit: limit.value }); |
| 77 | - setTimeout(() => { | 119 | + if (code) { |
| 78 | - for (let i = 0; i < 10; i++) { | 120 | + list.value = _.concat(list.value, data); |
| 79 | - list.value.push(list.value.length + 1); | 121 | + list.value = _.uniqBy(list.value, 'good_id'); |
| 80 | - } | 122 | + offset.value = list.value.length; |
| 81 | - | ||
| 82 | - // 加载状态结束 | ||
| 83 | loading.value = false; | 123 | loading.value = false; |
| 84 | - | ||
| 85 | // 数据全部加载完成 | 124 | // 数据全部加载完成 |
| 86 | - if (list.value.length >= 40) { | 125 | + if (!data.length) { |
| 126 | + // 加载状态结束 | ||
| 87 | finished.value = true; | 127 | finished.value = true; |
| 88 | } | 128 | } |
| 89 | - }, 1000); | 129 | + } |
| 90 | }; | 130 | }; |
| 91 | 131 | ||
| 132 | +const material_id = ref(''); | ||
| 92 | const onClickTitle = (item) => { // 点击物资标题回调 | 133 | const onClickTitle = (item) => { // 点击物资标题回调 |
| 93 | - console.warn(item); | ||
| 94 | show_material_detail.value = true; | 134 | show_material_detail.value = true; |
| 135 | + material_id.value = item.good_id; | ||
| 95 | } | 136 | } |
| 96 | 137 | ||
| 97 | const onClickRequest = () => { // 我要申领物资 | 138 | const onClickRequest = () => { // 我要申领物资 |
| 98 | $router.push({ | 139 | $router.push({ |
| 99 | - path: '/material_request' | 140 | + path: '/material_request', |
| 141 | + query: { | ||
| 142 | + activity_id, | ||
| 143 | + form_id, | ||
| 144 | + client_id | ||
| 145 | + } | ||
| 100 | }) | 146 | }) |
| 101 | } | 147 | } |
| 102 | 148 | ||
| ... | @@ -118,7 +164,7 @@ const onCloseDetail = () => { | ... | @@ -118,7 +164,7 @@ const onCloseDetail = () => { |
| 118 | margin-bottom: 0.5rem; | 164 | margin-bottom: 0.5rem; |
| 119 | } | 165 | } |
| 120 | .item-attr { | 166 | .item-attr { |
| 121 | - font-size: 0.85rem; | 167 | + font-size: 0.8rem; |
| 122 | color: #8F8F8F; | 168 | color: #8F8F8F; |
| 123 | } | 169 | } |
| 124 | .item-num-title { | 170 | .item-num-title { |
| ... | @@ -128,7 +174,7 @@ const onCloseDetail = () => { | ... | @@ -128,7 +174,7 @@ const onCloseDetail = () => { |
| 128 | margin-bottom: 0.5rem; | 174 | margin-bottom: 0.5rem; |
| 129 | } | 175 | } |
| 130 | .item-num { | 176 | .item-num { |
| 131 | - font-size: 1rem; | 177 | + font-size: 0.95rem; |
| 132 | text-align: center; | 178 | text-align: center; |
| 133 | } | 179 | } |
| 134 | } | 180 | } | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 12:53:15 | 2 | * @Date: 2024-07-23 12:53:15 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-25 13:21:17 | 4 | + * @LastEditTime: 2024-07-26 14:10:50 |
| 5 | * @FilePath: /temple_material_request/src/views/material_pre_request.vue | 5 | * @FilePath: /temple_material_request/src/views/material_pre_request.vue |
| 6 | * @Description: 待申领物资页面 | 6 | * @Description: 待申领物资页面 |
| 7 | --> | 7 | --> |
| ... | @@ -11,25 +11,23 @@ | ... | @@ -11,25 +11,23 @@ |
| 11 | <van-sticky> | 11 | <van-sticky> |
| 12 | <van-row justify="space-between" class="select-all-item"> | 12 | <van-row justify="space-between" class="select-all-item"> |
| 13 | <van-col span="8"> | 13 | <van-col span="8"> |
| 14 | - <!-- TODO:编辑模式下,不能确认申请 --> | ||
| 15 | <span v-if="model === 'edit'"> | 14 | <span v-if="model === 'edit'"> |
| 16 | <van-icon v-if="is_all_checked" @click="onCheckAll()" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | 15 | <van-icon v-if="is_all_checked" @click="onCheckAll()" name="checked" size="1.25rem" :color="styleColor.baseColor" /> |
| 17 | <van-icon v-else name="passed" @click="onCheckAll()" size="1.25rem" /> | 16 | <van-icon v-else name="passed" @click="onCheckAll()" size="1.25rem" /> |
| 18 | <span @click="onCheckAll()" :style="{ color: styleColor.baseColor }"> 全选</span> | 17 | <span @click="onCheckAll()" :style="{ color: styleColor.baseColor }"> 全选</span> |
| 19 | </span> | 18 | </span> |
| 20 | - <!-- TODO:非编辑模式下,显示购物车总数量 --> | ||
| 21 | <span v-else :style="{ color: styleColor.baseColor }">品项数: {{ sum_num }}</span> | 19 | <span v-else :style="{ color: styleColor.baseColor }">品项数: {{ sum_num }}</span> |
| 22 | </van-col> | 20 | </van-col> |
| 23 | <van-col span="16" :style="{ textAlign: 'right', fontSize: '0.85rem', color: styleColor.baseColor }"> | 21 | <van-col span="16" :style="{ textAlign: 'right', fontSize: '0.85rem', color: styleColor.baseColor }"> |
| 24 | <span v-if="model !== 'edit'" @click="onClickEdit"><van-icon name="records-o" /> 编辑</span> | 22 | <span v-if="model !== 'edit'" @click="onClickEdit"><van-icon name="records-o" /> 编辑</span> |
| 25 | <span v-else> | 23 | <span v-else> |
| 26 | <span @click="onClickDel"><van-icon name="delete-o" /> 删除</span> | 24 | <span @click="onClickDel"><van-icon name="delete-o" /> 删除</span> |
| 27 | - <span @click="onClickCancel"><van-icon name="close" /> 取消编辑</span> | 25 | + <span @click="onClickCancel"><van-icon name="close" /> 确认编辑</span> |
| 28 | </span> | 26 | </span> |
| 29 | </van-col> | 27 | </van-col> |
| 30 | </van-row> | 28 | </van-row> |
| 31 | </van-sticky> | 29 | </van-sticky> |
| 32 | - <div v-for="item in list" :id="item.id" :key="item" class="list-boxer"> | 30 | + <div v-for="item in list" :id="item.good_id" :key="item" class="list-boxer"> |
| 33 | <van-row align="center" justify="space-between"> | 31 | <van-row align="center" justify="space-between"> |
| 34 | <van-col span="16" style="display: flex;"> | 32 | <van-col span="16" style="display: flex;"> |
| 35 | <span v-if="item.edit"> | 33 | <span v-if="item.edit"> |
| ... | @@ -37,12 +35,12 @@ | ... | @@ -37,12 +35,12 @@ |
| 37 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> | 35 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> |
| 38 | </span> | 36 | </span> |
| 39 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> | 37 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> |
| 40 | - {{ item.name }} | 38 | + {{ item.product_name }} / {{ item.spec }} |
| 41 | </div> | 39 | </div> |
| 42 | </van-col> | 40 | </van-col> |
| 43 | <van-col span="8" style="display: flex; align-items: center;"> | 41 | <van-col span="8" style="display: flex; align-items: center;"> |
| 44 | <van-field | 42 | <van-field |
| 45 | - v-model="item.num" | 43 | + v-model="item.apply_number" |
| 46 | style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" | 44 | style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" |
| 47 | label="" | 45 | label="" |
| 48 | label-width="0" | 46 | label-width="0" |
| ... | @@ -60,7 +58,7 @@ | ... | @@ -60,7 +58,7 @@ |
| 60 | </div> | 58 | </div> |
| 61 | <div style="height: 6rem;"></div> | 59 | <div style="height: 6rem;"></div> |
| 62 | <div style="position: fixed; left: 0; right: 0; bottom:4.5rem; padding: 1rem;"> | 60 | <div style="position: fixed; left: 0; right: 0; bottom:4.5rem; padding: 1rem;"> |
| 63 | - <van-button icon="plus" type="primary" :color="styleColor.baseColor" plain block @click="addMore">添加更多</van-button> | 61 | + <van-button icon="plus" type="primary" :color="styleColor.baseColor" plain block :disabled="disabled_btn" @click="addMore">添加更多</van-button> |
| 64 | </div> | 62 | </div> |
| 65 | </div> | 63 | </div> |
| 66 | <div class="control-bar"> | 64 | <div class="control-bar"> |
| ... | @@ -68,10 +66,10 @@ | ... | @@ -68,10 +66,10 @@ |
| 68 | <div style="display: flex; justify-content: space-between; align-items: center;"> | 66 | <div style="display: flex; justify-content: space-between; align-items: center;"> |
| 69 | <div style="display: flex; align-items: center;" @click="showPicker = true"> | 67 | <div style="display: flex; align-items: center;" @click="showPicker = true"> |
| 70 | <div style="font-size: 0.85rem; color: #202020;">使用时间:</div> | 68 | <div style="font-size: 0.85rem; color: #202020;">使用时间:</div> |
| 71 | - <div style="border: 1px solid #f0f0f0; border-radius: 5px; padding: 0.5rem 0.35rem 0.5rem 1rem; min-width: 6rem; font-size: 0.85rem; display: flex; align-items: center; justify-content: space-between;">{{ use_date }} <van-icon name="notes-o" size="1rem" :color="styleColor.baseColor" /></div> | 69 | + <div style="border: 1px solid #f0f0f0; border-radius: 5px; padding: 0.5rem 0.35rem 0.5rem 1rem; min-width: 6rem; font-size: 0.85rem; display: flex; align-items: center; justify-content: space-between;">{{ use_time }} <van-icon name="notes-o" size="1rem" :color="styleColor.baseColor" /></div> |
| 72 | </div> | 70 | </div> |
| 73 | <div style="display: flex; align-items: center;"> | 71 | <div style="display: flex; align-items: center;"> |
| 74 | - <van-button type="primary" :color="styleColor.baseColor" @click="onConfirmRequest">确定申领</van-button> | 72 | + <van-button type="primary" :color="styleColor.baseColor" :disabled="disabled_btn" @click="onConfirmRequest">确定申领</van-button> |
| 75 | </div> | 73 | </div> |
| 76 | </div> | 74 | </div> |
| 77 | </div> | 75 | </div> |
| ... | @@ -95,20 +93,18 @@ | ... | @@ -95,20 +93,18 @@ |
| 95 | <!-- <div style="font-size: 0.9rem; margin-right: 1rem; width: 5rem;">申领组: </div> --> | 93 | <!-- <div style="font-size: 0.9rem; margin-right: 1rem; width: 5rem;">申领组: </div> --> |
| 96 | <div> | 94 | <div> |
| 97 | <van-radio-group v-model="type_checked" direction="horizontal" style="font-size: 0.9rem;"> | 95 | <van-radio-group v-model="type_checked" direction="horizontal" style="font-size: 0.9rem;"> |
| 98 | - <van-radio name="1" :checked-color="styleColor.baseColor" style="margin-bottom: 0.25rem;">单选框 1</van-radio> | 96 | + <van-radio :name="item.dept_id" v-for="(item, index) in my_depts" :key="index" :checked-color="styleColor.baseColor" style="margin-bottom: 0.25rem;">{{ item.dept_name }}</van-radio> |
| 99 | - <van-radio name="2" :checked-color="styleColor.baseColor" style="margin-bottom: 0.25rem;">单选框 2</van-radio> | ||
| 100 | - <van-radio name="3" :checked-color="styleColor.baseColor" style="margin-bottom: 0.25rem;">单选框 3</van-radio> | ||
| 101 | </van-radio-group> | 97 | </van-radio-group> |
| 102 | </div> | 98 | </div> |
| 103 | </div> | 99 | </div> |
| 104 | <div style="padding: 0 1rem;"> | 100 | <div style="padding: 0 1rem;"> |
| 105 | <van-row gutter="10" align="center" style="margin-bottom: 0.5rem;"> | 101 | <van-row gutter="10" align="center" style="margin-bottom: 0.5rem;"> |
| 106 | <van-col span="7" style="text-align: right;"><span style="color: red;">*</span>申领人:</van-col> | 102 | <van-col span="7" style="text-align: right;"><span style="color: red;">*</span>申领人:</van-col> |
| 107 | - <van-col span="17"><van-field v-model="request_user" label="" placeholder="请输入" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col> | 103 | + <van-col span="17"><van-field v-model="contact_name" label="" placeholder="请输入" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col> |
| 108 | </van-row> | 104 | </van-row> |
| 109 | <van-row gutter="10" align="center" style="margin-bottom: 1rem;"> | 105 | <van-row gutter="10" align="center" style="margin-bottom: 1rem;"> |
| 110 | <van-col span="7" style="text-align: right;"><span style="color: red;">*</span>联系电话:</van-col> | 106 | <van-col span="7" style="text-align: right;"><span style="color: red;">*</span>联系电话:</van-col> |
| 111 | - <van-col span="17"><van-field v-model="request_tel" label="" placeholder="请输入" type="number" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col> | 107 | + <van-col span="17"><van-field v-model="contact_phone" label="" placeholder="请输入" type="tel" maxlength="11" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col> |
| 112 | </van-row> | 108 | </van-row> |
| 113 | </div> | 109 | </div> |
| 114 | <van-row gutter="20" justify="space-around" align="center" style="padding: 1rem; border-top: 1px solid #E9E9E9; text-align: center;"> | 110 | <van-row gutter="20" justify="space-around" align="center" style="padding: 1rem; border-top: 1px solid #E9E9E9; text-align: center;"> |
| ... | @@ -122,7 +118,7 @@ | ... | @@ -122,7 +118,7 @@ |
| 122 | </van-dialog> | 118 | </van-dialog> |
| 123 | 119 | ||
| 124 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> | 120 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> |
| 125 | - <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail> | 121 | + <material-detail :show="show_material_detail" :good-id="material_id" @close="onCloseDetail"></material-detail> |
| 126 | 122 | ||
| 127 | </template> | 123 | </template> |
| 128 | 124 | ||
| ... | @@ -138,25 +134,86 @@ import { styleColor } from "@/constant.js"; | ... | @@ -138,25 +134,86 @@ import { styleColor } from "@/constant.js"; |
| 138 | import dayjs from "dayjs"; | 134 | import dayjs from "dayjs"; |
| 139 | import chooseMaterial from '@/components/chooseMaterial/index.vue'; | 135 | import chooseMaterial from '@/components/chooseMaterial/index.vue'; |
| 140 | import materialDetail from '@/components/materialDetail/index.vue'; | 136 | import materialDetail from '@/components/materialDetail/index.vue'; |
| 137 | +import { getCartListAPI, delCartAPI, myDeptsAPI, myUserAPI, editCartAPI, addUseOrderAPI } from "@/api/material"; | ||
| 141 | 138 | ||
| 142 | const $route = useRoute(); | 139 | const $route = useRoute(); |
| 143 | const $router = useRouter(); | 140 | const $router = useRouter(); |
| 144 | useTitle($route.meta.title); | 141 | useTitle($route.meta.title); |
| 145 | 142 | ||
| 143 | +const activity_id = $route.query.activity_id ? $route.query.activity_id : 800863; | ||
| 144 | +const form_id = $route.query.form_id ? $route.query.form_id : ''; | ||
| 145 | +const client_id = $route.query.client_id ? $route.query.client_id : ''; | ||
| 146 | + | ||
| 147 | +const disabled_btn = ref(false); | ||
| 148 | + | ||
| 149 | +/** | ||
| 150 | + * 获取我的组别列表 | ||
| 151 | + */ | ||
| 152 | +const my_depts = ref([]); | ||
| 153 | +const getDeptsList = async () => { | ||
| 154 | + const { data, code } = await myDeptsAPI(); | ||
| 155 | + if (code) { | ||
| 156 | + my_depts.value = data; | ||
| 157 | + if (!data.length) { | ||
| 158 | + showToast('您暂无组别无法申领物资'); | ||
| 159 | + disabled_btn.value = true; | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | +/** | ||
| 165 | + * 获取我的用户信息 | ||
| 166 | + */ | ||
| 167 | +const getUserList = async () => { | ||
| 168 | + const { data, code } = await myUserAPI(); | ||
| 169 | + if (code) { | ||
| 170 | + contact_name.value = data.name; | ||
| 171 | + contact_phone.value = data.mobile; | ||
| 172 | + } | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +/** | ||
| 176 | + * 购物车列表 | ||
| 177 | + */ | ||
| 178 | +const getCartList = async () => { | ||
| 179 | + const { data, code } = await getCartListAPI({ activity_id }); | ||
| 180 | + if (code) { | ||
| 181 | + list.value = data; | ||
| 182 | + list.value.forEach(item => { | ||
| 183 | + item.checked = false; | ||
| 184 | + }) | ||
| 185 | + if (!list.value.length) { // 购物车为空 | ||
| 186 | + addMore(); | ||
| 187 | + } else { | ||
| 188 | + sum_num.value = list.value.length; // 品项数量 | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +onMounted(async () => { | ||
| 194 | + // 获取列表 | ||
| 195 | + getCartList(); | ||
| 196 | + getDeptsList(); | ||
| 197 | + getUserList(); | ||
| 198 | + // | ||
| 199 | + minDate.value = new Date(); | ||
| 200 | +}); | ||
| 201 | + | ||
| 146 | const is_all_checked = ref(false); | 202 | const is_all_checked = ref(false); |
| 147 | 203 | ||
| 148 | -const sum_num = ref(999); // TODO: 品项的总数量,需要接口提供 | 204 | +const sum_num = ref(0); // 品项的总数量 |
| 149 | const model = ref(''); // 默认非编辑模式 | 205 | const model = ref(''); // 默认非编辑模式 |
| 150 | 206 | ||
| 151 | const onClickEdit = () => { // 点击编辑 | 207 | const onClickEdit = () => { // 点击编辑 |
| 152 | model.value = 'edit'; | 208 | model.value = 'edit'; |
| 209 | + disabled_btn.value = true; | ||
| 153 | list.value.forEach(item => { | 210 | list.value.forEach(item => { |
| 154 | item.checked = false; | 211 | item.checked = false; |
| 155 | item.error = false; | 212 | item.error = false; |
| 156 | item.edit = true; | 213 | item.edit = true; |
| 157 | }) | 214 | }) |
| 158 | } | 215 | } |
| 159 | -const onClickDel = () => { // 点击删除 | 216 | +const onClickDel = () => { // 点击删除回调 |
| 160 | let shop_cart_list = []; | 217 | let shop_cart_list = []; |
| 161 | // 把选中的值集合 | 218 | // 把选中的值集合 |
| 162 | list.value | 219 | list.value |
| ... | @@ -169,20 +226,25 @@ const onClickDel = () => { // 点击删除 | ... | @@ -169,20 +226,25 @@ const onClickDel = () => { // 点击删除 |
| 169 | showToast('删除项为空'); | 226 | showToast('删除项为空'); |
| 170 | return; | 227 | return; |
| 171 | } | 228 | } |
| 172 | - // TODO:删除选中的项,接口需要一个购物车删除指定ID的接口 | 229 | + // 把选中的值集合 |
| 173 | - let del_ids = shop_cart_list.map(item => item.id); | 230 | + let del_ids = shop_cart_list.map(item => item.good_id); |
| 174 | - console.warn(del_ids); | 231 | + // 删除接口 |
| 175 | showConfirmDialog({ | 232 | showConfirmDialog({ |
| 176 | title: '温馨提示', | 233 | title: '温馨提示', |
| 177 | message: | 234 | message: |
| 178 | `您是否需要删除这 ${del_ids.length} 项物资?`, | 235 | `您是否需要删除这 ${del_ids.length} 项物资?`, |
| 179 | confirmButtonColor: styleColor.baseColor, | 236 | confirmButtonColor: styleColor.baseColor, |
| 180 | }) | 237 | }) |
| 181 | - .then(() => { | 238 | + .then(async () => { |
| 182 | - // on confirm | 239 | + const { code, data } = await delCartAPI({ activity_id, good_ids: del_ids }); |
| 183 | - // 还原列表显示 | 240 | + if (code) { |
| 184 | - onClickCancel(); | 241 | + // 还原列表显示 |
| 185 | - // TODO: 刷新列表 | 242 | + onClickCancel(); |
| 243 | + // 获取购物车列表 | ||
| 244 | + getCartList(); | ||
| 245 | + // | ||
| 246 | + showToast('删除成功'); | ||
| 247 | + } | ||
| 186 | }) | 248 | }) |
| 187 | .catch(() => { | 249 | .catch(() => { |
| 188 | // on cancel | 250 | // on cancel |
| ... | @@ -192,11 +254,15 @@ const onClickDel = () => { // 点击删除 | ... | @@ -192,11 +254,15 @@ const onClickDel = () => { // 点击删除 |
| 192 | const onClickCancel = () => { // 点击取消 | 254 | const onClickCancel = () => { // 点击取消 |
| 193 | if (checkShoppingCart()) { | 255 | if (checkShoppingCart()) { |
| 194 | model.value = ''; | 256 | model.value = ''; |
| 257 | + disabled_btn.value = false; | ||
| 195 | is_all_checked.value = false; | 258 | is_all_checked.value = false; |
| 196 | list.value.forEach(item => { | 259 | list.value.forEach(item => { |
| 260 | + item.checked = false; | ||
| 197 | item.error = false; | 261 | item.error = false; |
| 198 | item.edit = false; | 262 | item.edit = false; |
| 199 | }); | 263 | }); |
| 264 | + } else { | ||
| 265 | + showToast('请检查输入项') | ||
| 200 | } | 266 | } |
| 201 | } | 267 | } |
| 202 | 268 | ||
| ... | @@ -229,42 +295,25 @@ const onCheck = (item) => { | ... | @@ -229,42 +295,25 @@ const onCheck = (item) => { |
| 229 | } | 295 | } |
| 230 | } | 296 | } |
| 231 | 297 | ||
| 232 | -const onBlur = (item) => { // 输入框失去焦点回调 | 298 | +const onBlur = async (item) => { // 输入框失去焦点回调 |
| 233 | - if (item.num === null || item.num === '') { | 299 | + if (item.apply_number === null || item.apply_number === '') { |
| 234 | item.error = true; | 300 | item.error = true; |
| 235 | } else { | 301 | } else { |
| 302 | + // 输入框失去焦点,购物车更新数量 | ||
| 236 | item.error = false; | 303 | item.error = false; |
| 304 | + const { code, data } = await editCartAPI({ activity_id, good_list: [{ good_id: item.good_id, apply_number: item.apply_number }] }); | ||
| 305 | + if (code) { | ||
| 306 | + | ||
| 307 | + } | ||
| 237 | } | 308 | } |
| 238 | - // TODO: 输入框失去焦点,接口需要一个购物车更新接口 | ||
| 239 | } | 309 | } |
| 240 | 310 | ||
| 241 | const list = ref([]); | 311 | const list = ref([]); |
| 242 | -const loading = ref(false); | ||
| 243 | -const finished = ref(false); | ||
| 244 | - | ||
| 245 | -const onLoad = () => { | ||
| 246 | - // 异步更新数据 | ||
| 247 | - // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | ||
| 248 | - setTimeout(() => { | ||
| 249 | - for (let i = 0; i < 10; i++) { | ||
| 250 | - list.value.push({ id: list.value.length + 1, name: '标题 床垫 1.2m*2m', num: 11, checked: false, error: false, edit: model.value === 'edit' }); | ||
| 251 | - } | ||
| 252 | - | ||
| 253 | - // 加载状态结束 | ||
| 254 | - loading.value = false; | ||
| 255 | - | ||
| 256 | - // 数据全部加载完成 | ||
| 257 | - if (list.value.length >= 40) { | ||
| 258 | - finished.value = true; | ||
| 259 | - } | ||
| 260 | - }, 1000); | ||
| 261 | - // TODO: 如果查询到的数据大于0,需要取消全选 | ||
| 262 | - is_all_checked.value = false; | ||
| 263 | -}; | ||
| 264 | 312 | ||
| 313 | +const material_id = ref(''); | ||
| 265 | const onClickTitle = (item) => { // 点击物资标题回调 | 314 | const onClickTitle = (item) => { // 点击物资标题回调 |
| 266 | - console.warn(item); | ||
| 267 | show_material_detail.value = true; | 315 | show_material_detail.value = true; |
| 316 | + material_id.value = item.good_id; | ||
| 268 | } | 317 | } |
| 269 | 318 | ||
| 270 | const showPicker = ref(false); | 319 | const showPicker = ref(false); |
| ... | @@ -272,21 +321,14 @@ const currentDate = ref([]); | ... | @@ -272,21 +321,14 @@ const currentDate = ref([]); |
| 272 | const columns_type = ref(['year', 'month', 'day']); | 321 | const columns_type = ref(['year', 'month', 'day']); |
| 273 | const minDate = ref(); | 322 | const minDate = ref(); |
| 274 | const maxDate = ref(); | 323 | const maxDate = ref(); |
| 275 | -const use_date = ref(''); | 324 | +const use_time = ref(''); |
| 276 | 325 | ||
| 277 | const onConfirm = ({ selectedValues, selectedOptions }) => { | 326 | const onConfirm = ({ selectedValues, selectedOptions }) => { |
| 278 | - use_date.value = selectedValues.join("-"); | 327 | + use_time.value = selectedValues.join("-"); |
| 279 | showPicker.value = false; | 328 | showPicker.value = false; |
| 280 | }; | 329 | }; |
| 281 | 330 | ||
| 282 | -onMounted(() => { | ||
| 283 | - minDate.value = new Date(); | ||
| 284 | - // 测试 | ||
| 285 | - onLoad() | ||
| 286 | -}) | ||
| 287 | - | ||
| 288 | const addMore = () => { // 添加更多回调 | 331 | const addMore = () => { // 添加更多回调 |
| 289 | - console.warn('addMore'); | ||
| 290 | show_choose_material.value = true; | 332 | show_choose_material.value = true; |
| 291 | } | 333 | } |
| 292 | 334 | ||
| ... | @@ -295,10 +337,10 @@ const shop_cart_list = ref([]); // 购物车列表 | ... | @@ -295,10 +337,10 @@ const shop_cart_list = ref([]); // 购物车列表 |
| 295 | const checkShoppingCart = () => { // 检查购物车有效性 | 337 | const checkShoppingCart = () => { // 检查购物车有效性 |
| 296 | let flag = true; | 338 | let flag = true; |
| 297 | // 校验购物车值 | 339 | // 校验购物车值 |
| 298 | - let error_list = list.value.filter((item) => { if (item.num === null || item.num === '') { return item;} }) | 340 | + let error_list = list.value.filter((item) => { if (item.apply_number === null || item.apply_number === '') { return item;} }) |
| 299 | if (error_list.length) { | 341 | if (error_list.length) { |
| 300 | // 跳到第一个错误框 | 342 | // 跳到第一个错误框 |
| 301 | - scrollToSection(error_list[0].id); | 343 | + scrollToSection(error_list[0].good_id); |
| 302 | // 标记所有错误 | 344 | // 标记所有错误 |
| 303 | error_list.forEach(item => { | 345 | error_list.forEach(item => { |
| 304 | item.error = true; | 346 | item.error = true; |
| ... | @@ -310,8 +352,7 @@ const checkShoppingCart = () => { // 检查购物车有效性 | ... | @@ -310,8 +352,7 @@ const checkShoppingCart = () => { // 检查购物车有效性 |
| 310 | } | 352 | } |
| 311 | 353 | ||
| 312 | const onConfirmRequest = () => { // 确定申领回调 | 354 | const onConfirmRequest = () => { // 确定申领回调 |
| 313 | - console.warn('onConfirmRequest'); | 355 | + if (!use_time.value) { |
| 314 | - if (!use_date.value) { | ||
| 315 | showToast('请选择使用日期'); | 356 | showToast('请选择使用日期'); |
| 316 | return; | 357 | return; |
| 317 | } | 358 | } |
| ... | @@ -319,11 +360,11 @@ const onConfirmRequest = () => { // 确定申领回调 | ... | @@ -319,11 +360,11 @@ const onConfirmRequest = () => { // 确定申领回调 |
| 319 | } | 360 | } |
| 320 | 361 | ||
| 321 | const scrollToSection = (id) => { // 滚动到指定位置 | 362 | const scrollToSection = (id) => { // 滚动到指定位置 |
| 322 | - const current_index = list.value.findIndex((item) => item.id === id); | 363 | + const current_index = list.value.findIndex((item) => item.good_id === id); |
| 323 | // 因为布局问题,需要滚动到上一个节点 查询上一个节点ID | 364 | // 因为布局问题,需要滚动到上一个节点 查询上一个节点ID |
| 324 | const previous_index = current_index - 2 >= 0 ? current_index - 2 : 0; | 365 | const previous_index = current_index - 2 >= 0 ? current_index - 2 : 0; |
| 325 | nextTick(() => { | 366 | nextTick(() => { |
| 326 | - let element = $('.list-wrapper').find(`#${list.value[previous_index]['id']}`); | 367 | + let element = $('.list-wrapper').find(`#${list.value[previous_index]['good_id']}`); |
| 327 | if (element[0]) { | 368 | if (element[0]) { |
| 328 | element[0].scrollIntoView({ behavior: 'smooth' }); | 369 | element[0].scrollIntoView({ behavior: 'smooth' }); |
| 329 | } else { | 370 | } else { |
| ... | @@ -334,26 +375,31 @@ const scrollToSection = (id) => { // 滚动到指定位置 | ... | @@ -334,26 +375,31 @@ const scrollToSection = (id) => { // 滚动到指定位置 |
| 334 | 375 | ||
| 335 | const showType = ref(false); | 376 | const showType = ref(false); |
| 336 | const type_checked = ref(''); // 组别 | 377 | const type_checked = ref(''); // 组别 |
| 337 | -const request_user = ref(''); // 申领人 | 378 | +const contact_name = ref(''); // 申领人 |
| 338 | -const request_tel = ref(''); // 联系电话 | 379 | +const contact_phone = ref(''); // 联系电话 |
| 339 | -const onDialogConfirm = () => { | 380 | +const onDialogConfirm = async () => { |
| 340 | if (!type_checked.value) { | 381 | if (!type_checked.value) { |
| 341 | showToast('请选择组别') | 382 | showToast('请选择组别') |
| 342 | - } | 383 | + } else if (!contact_name.value) { |
| 343 | - if (!request_user.value) { | ||
| 344 | showToast('申领人不能为空') | 384 | showToast('申领人不能为空') |
| 385 | + } else if (!contact_phone.value || !contact_phone.value.match(/^1[3456789]\d{9}$/)) { | ||
| 386 | + showToast('联系电话填写有误') | ||
| 387 | + } else { | ||
| 388 | + // 提交申领物资接口 | ||
| 389 | + const { code, data } = await addUseOrderAPI({ activity_id, dept_id: type_checked.value, use_time: use_time.value, contact_name: contact_name.value, contact_phone: contact_phone.value }); | ||
| 390 | + if (code) { | ||
| 391 | + showType.value = false; | ||
| 392 | + // 申领成功跳转 | ||
| 393 | + $router.push({ | ||
| 394 | + path: '/success', | ||
| 395 | + query: { | ||
| 396 | + activity_id, | ||
| 397 | + form_id, | ||
| 398 | + client_id | ||
| 399 | + } | ||
| 400 | + }); | ||
| 401 | + } | ||
| 345 | } | 402 | } |
| 346 | - if (!request_tel.value) { | ||
| 347 | - showToast('联系电话不能为空') | ||
| 348 | - } | ||
| 349 | - console.warn('组别', type_checked.value); | ||
| 350 | - console.warn('use_date', use_date.value); | ||
| 351 | - console.warn('request_user', request_user.value); | ||
| 352 | - console.warn('request_tel', request_tel.value); | ||
| 353 | - // TODO:购物车的值应该不用传,数量应该是单独修改 | ||
| 354 | - showType.value = false; | ||
| 355 | - // 申领成功跳转 | ||
| 356 | - $router.push({ path: '/success' }); | ||
| 357 | } | 403 | } |
| 358 | const onDialogCancel = () => { | 404 | const onDialogCancel = () => { |
| 359 | showType.value = false; | 405 | showType.value = false; |
| ... | @@ -361,8 +407,9 @@ const onDialogCancel = () => { | ... | @@ -361,8 +407,9 @@ const onDialogCancel = () => { |
| 361 | 407 | ||
| 362 | const show_choose_material = ref(false); | 408 | const show_choose_material = ref(false); |
| 363 | const onCloseChoose = () => { // 关闭选择物资弹窗回调 | 409 | const onCloseChoose = () => { // 关闭选择物资弹窗回调 |
| 364 | - // TODO: 需要刷新列表,应该可能新增的物料 | ||
| 365 | show_choose_material.value = false; | 410 | show_choose_material.value = false; |
| 411 | + // 刷新购物车列表 | ||
| 412 | + getCartList(); | ||
| 366 | } | 413 | } |
| 367 | 414 | ||
| 368 | const show_material_detail = ref(false); | 415 | const show_material_detail = ref(false); | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 12:53:15 | 2 | * @Date: 2024-07-23 12:53:15 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-25 10:01:06 | 4 | + * @LastEditTime: 2024-07-26 14:42:54 |
| 5 | * @FilePath: /temple_material_request/src/views/material_request.vue | 5 | * @FilePath: /temple_material_request/src/views/material_request.vue |
| 6 | * @Description: 申领物资页面 | 6 | * @Description: 申领物资页面 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <div class="material-request-page"> | 9 | <div class="material-request-page"> |
| 10 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> | 10 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> |
| 11 | - <van-tab v-for="index in 8" :title="'标签 ' + index"> | 11 | + <van-tab v-for="(item, index) in tabList" :title="item.dept_name" shrink> |
| 12 | <div class="list-wrapper"> | 12 | <div class="list-wrapper"> |
| 13 | <van-sticky :offset-top="44"> | 13 | <van-sticky :offset-top="44"> |
| 14 | <van-row justify="space-between" class="select-all-item"> | 14 | <van-row justify="space-between" class="select-all-item"> |
| ... | @@ -32,12 +32,12 @@ | ... | @@ -32,12 +32,12 @@ |
| 32 | <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | 32 | <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> |
| 33 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> | 33 | <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> |
| 34 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> | 34 | <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> |
| 35 | - {{ item.name }} | 35 | + {{ item.product_name }} / {{ item.spec }} |
| 36 | </div> | 36 | </div> |
| 37 | </van-col> | 37 | </van-col> |
| 38 | <van-col span="8" style="display: flex; align-items: center;"> | 38 | <van-col span="8" style="display: flex; align-items: center;"> |
| 39 | <van-field | 39 | <van-field |
| 40 | - v-model="item.num" | 40 | + v-model="item.total_apply_number" |
| 41 | style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" | 41 | style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" |
| 42 | label="" | 42 | label="" |
| 43 | label-width="0" | 43 | label-width="0" |
| ... | @@ -73,14 +73,14 @@ | ... | @@ -73,14 +73,14 @@ |
| 73 | </div> | 73 | </div> |
| 74 | 74 | ||
| 75 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> | 75 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> |
| 76 | - <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail> | 76 | + <material-detail :show="show_material_detail" :good-id="material_id" @close="onCloseDetail"></material-detail> |
| 77 | 77 | ||
| 78 | </template> | 78 | </template> |
| 79 | 79 | ||
| 80 | <script setup> | 80 | <script setup> |
| 81 | import { ref } from 'vue' | 81 | import { ref } from 'vue' |
| 82 | import { useRoute, useRouter } from 'vue-router' | 82 | import { useRoute, useRouter } from 'vue-router' |
| 83 | -import { showToast } from 'vant'; | 83 | +import { showToast, showDialog } from 'vant'; |
| 84 | import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' | 84 | import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' |
| 85 | //import { } from '@/utils/generateModules.js' | 85 | //import { } from '@/utils/generateModules.js' |
| 86 | //import { } from '@/utils/generateIcons.js' | 86 | //import { } from '@/utils/generateIcons.js' |
| ... | @@ -88,14 +88,54 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ | ... | @@ -88,14 +88,54 @@ import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@ |
| 88 | import { styleColor } from "@/constant.js"; | 88 | import { styleColor } from "@/constant.js"; |
| 89 | import chooseMaterial from '@/components/chooseMaterial/index.vue'; | 89 | import chooseMaterial from '@/components/chooseMaterial/index.vue'; |
| 90 | import materialDetail from '@/components/materialDetail/index.vue'; | 90 | import materialDetail from '@/components/materialDetail/index.vue'; |
| 91 | -import { getActivityDeptsAPI } from "@/api/material"; | 91 | +import { getActivityDeptsAPI, getGoodUseListAPI, getCartListAPI, addCartAPI } from "@/api/material"; |
| 92 | 92 | ||
| 93 | const $route = useRoute(); | 93 | const $route = useRoute(); |
| 94 | const $router = useRouter(); | 94 | const $router = useRouter(); |
| 95 | useTitle($route.meta.title); | 95 | useTitle($route.meta.title); |
| 96 | 96 | ||
| 97 | -// TODO: getActivityDeptsAPI,is_previous=1,only_my_dept=1 | 97 | +const activity_id = $route.query.activity_id ? $route.query.activity_id : 800863; |
| 98 | +const form_id = $route.query.form_id ? $route.query.form_id : ''; | ||
| 99 | +const client_id = $route.query.client_id ? $route.query.client_id : ''; | ||
| 100 | + | ||
| 101 | +const cart_count = ref(0); // 购物车数量 | ||
| 102 | +const getCartCount = async () => { | ||
| 103 | + // 购物车数量 | ||
| 104 | + const cartList = await getCartListAPI({activity_id}); | ||
| 105 | + if (cartList.code) { | ||
| 106 | + cart_count.value = cartList.data.length; | ||
| 107 | + } | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +onMounted(async () => { | ||
| 111 | + const { data, code } = await getActivityDeptsAPI({ activity_id, is_previous: 1, only_my_dept: 1 }); | ||
| 112 | + if (code) { | ||
| 113 | + tabList.value = data; | ||
| 114 | + if (tabList.value.length) { // 默认选中组别ID | ||
| 115 | + dept_id.value = tabList.value[0]['dept_id']; | ||
| 116 | + } else { // 组别为空时跳转到购物车页面 | ||
| 117 | + showDialog({ | ||
| 118 | + title: '温馨提示', | ||
| 119 | + message: '物资列表为空,将前往添加!', | ||
| 120 | + confirmButtonColor: styleColor.baseColor | ||
| 121 | + }).then(() => { | ||
| 122 | + $router.push({ | ||
| 123 | + path: '/material_pre_request', | ||
| 124 | + query: { | ||
| 125 | + activity_id, | ||
| 126 | + form_id, | ||
| 127 | + client_id | ||
| 128 | + } | ||
| 129 | + }) | ||
| 130 | + }); | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + // 购物车数量 | ||
| 134 | + getCartCount(); | ||
| 135 | +}); | ||
| 136 | + | ||
| 98 | const tabList = ref([]); // 组别列表 | 137 | const tabList = ref([]); // 组别列表 |
| 138 | +const dept_id = ref(''); | ||
| 99 | 139 | ||
| 100 | const is_all_checked = ref(false); | 140 | const is_all_checked = ref(false); |
| 101 | const num_value = ref(''); | 141 | const num_value = ref(''); |
| ... | @@ -130,8 +170,9 @@ const onCheck = (item) => { | ... | @@ -130,8 +170,9 @@ const onCheck = (item) => { |
| 130 | } | 170 | } |
| 131 | 171 | ||
| 132 | const onBlur = (item) => { // 输入框失去焦点回调 | 172 | const onBlur = (item) => { // 输入框失去焦点回调 |
| 173 | + console.warn(item); | ||
| 133 | if (item.checked) { | 174 | if (item.checked) { |
| 134 | - if (item.num === null || item.num === '') { | 175 | + if (item.total_apply_number === null || item.total_apply_number === '') { |
| 135 | item.error = true; | 176 | item.error = true; |
| 136 | } else { | 177 | } else { |
| 137 | item.error = false; | 178 | item.error = false; |
| ... | @@ -144,40 +185,48 @@ const onChange = (index) => { // 切换标签回调 | ... | @@ -144,40 +185,48 @@ const onChange = (index) => { // 切换标签回调 |
| 144 | console.warn(index); | 185 | console.warn(index); |
| 145 | // 取消全选 | 186 | // 取消全选 |
| 146 | is_all_checked.value = false; | 187 | is_all_checked.value = false; |
| 147 | - // TODO:重新查询列表数据, 取消选中 | 188 | + // |
| 148 | - list.value.forEach(item => { | 189 | + dept_id.value = tabList.value[index]['dept_id']; |
| 149 | - item.checked = false; | 190 | + limit.value = 20; |
| 150 | - item.error = false; | 191 | + offset.value = 0; |
| 151 | - }); | 192 | + loading.value = false; |
| 193 | + finished.value = false; | ||
| 194 | + list.value = []; | ||
| 152 | } | 195 | } |
| 153 | 196 | ||
| 154 | const list = ref([]); | 197 | const list = ref([]); |
| 155 | const loading = ref(false); | 198 | const loading = ref(false); |
| 156 | const finished = ref(false); | 199 | const finished = ref(false); |
| 157 | 200 | ||
| 158 | -const onLoad = () => { | 201 | +const limit = ref(20); |
| 159 | - // 异步更新数据 | 202 | +const offset = ref(0); |
| 160 | - // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | ||
| 161 | - setTimeout(() => { | ||
| 162 | - for (let i = 0; i < 10; i++) { | ||
| 163 | - list.value.push({ id: list.value.length + 1, name: '标题 床垫 1.2m*2m', num: null, checked: false, error: false }); | ||
| 164 | - } | ||
| 165 | 203 | ||
| 166 | - // 加载状态结束 | 204 | +const onLoad = async () => { |
| 205 | + // 异步更新数据 | ||
| 206 | + const { code, data } = await getGoodUseListAPI({ activity_id, dept_id: dept_id.value, is_previous: 1, offset: offset.value, limit: limit.value }); | ||
| 207 | + if (code) { | ||
| 208 | + data.forEach(item => { | ||
| 209 | + item.checked = false; | ||
| 210 | + item.error = false; | ||
| 211 | + }); | ||
| 212 | + list.value = _.concat(list.value, data); | ||
| 213 | + list.value = _.uniqBy(list.value, 'good_id'); | ||
| 214 | + offset.value = list.value.length; | ||
| 167 | loading.value = false; | 215 | loading.value = false; |
| 168 | - | ||
| 169 | // 数据全部加载完成 | 216 | // 数据全部加载完成 |
| 170 | - if (list.value.length >= 40) { | 217 | + if (!data.length) { |
| 218 | + // 加载状态结束 | ||
| 171 | finished.value = true; | 219 | finished.value = true; |
| 172 | } | 220 | } |
| 173 | - }, 1000); | 221 | + } |
| 174 | // TODO: 如果查询到的数据大于0,需要取消全选 | 222 | // TODO: 如果查询到的数据大于0,需要取消全选 |
| 175 | is_all_checked.value = false; | 223 | is_all_checked.value = false; |
| 176 | }; | 224 | }; |
| 177 | 225 | ||
| 226 | +const material_id = ref(''); | ||
| 178 | const onClickTitle = (item) => { // 点击物资标题回调 | 227 | const onClickTitle = (item) => { // 点击物资标题回调 |
| 179 | - console.warn(item); | ||
| 180 | show_material_detail.value = true; | 228 | show_material_detail.value = true; |
| 229 | + material_id.value = item.good_id; | ||
| 181 | } | 230 | } |
| 182 | 231 | ||
| 183 | const addMore = () => { // 添加更多 | 232 | const addMore = () => { // 添加更多 |
| ... | @@ -185,9 +234,8 @@ const addMore = () => { // 添加更多 | ... | @@ -185,9 +234,8 @@ const addMore = () => { // 添加更多 |
| 185 | show_choose_material.value = true; | 234 | show_choose_material.value = true; |
| 186 | } | 235 | } |
| 187 | 236 | ||
| 188 | -const cart_count = ref(0); | ||
| 189 | const shop_cart_list = ref([]); // 购物车列表 | 237 | const shop_cart_list = ref([]); // 购物车列表 |
| 190 | -const addShoppingCart = () => { // 加入购物车 | 238 | +const addShoppingCart = async () => { // 加入购物车 |
| 191 | shop_cart_list.value = []; | 239 | shop_cart_list.value = []; |
| 192 | // 把选中的值集合 | 240 | // 把选中的值集合 |
| 193 | list.value | 241 | list.value |
| ... | @@ -201,7 +249,7 @@ const addShoppingCart = () => { // 加入购物车 | ... | @@ -201,7 +249,7 @@ const addShoppingCart = () => { // 加入购物车 |
| 201 | return; | 249 | return; |
| 202 | } | 250 | } |
| 203 | // 校验购物车值 | 251 | // 校验购物车值 |
| 204 | - let error_list = shop_cart_list.value.filter((item) => { if (item.num === null || item.num === '') { return item;} }) | 252 | + let error_list = shop_cart_list.value.filter((item) => { if (item.total_apply_number === null || item.total_apply_number === '') { return item;} }) |
| 205 | if (error_list.length) { | 253 | if (error_list.length) { |
| 206 | // 跳到第一个错误框 | 254 | // 跳到第一个错误框 |
| 207 | scrollToSection(error_list[0].id); | 255 | scrollToSection(error_list[0].id); |
| ... | @@ -211,18 +259,66 @@ const addShoppingCart = () => { // 加入购物车 | ... | @@ -211,18 +259,66 @@ const addShoppingCart = () => { // 加入购物车 |
| 211 | }) | 259 | }) |
| 212 | return; | 260 | return; |
| 213 | } | 261 | } |
| 214 | - // 购物车数量 | 262 | + // |
| 215 | - cart_count.value = shop_cart_list.value.length; | 263 | + shop_cart_list.value.forEach(item => { |
| 264 | + item.apply_number = item.total_apply_number; | ||
| 265 | + }); | ||
| 266 | + // 请求购物车接口 | ||
| 267 | + const { code, data } = await addCartAPI({ activity_id, good_list: shop_cart_list.value }); | ||
| 268 | + if (code) { | ||
| 269 | + showToast('添加成功'); | ||
| 270 | + setTimeout(() => { | ||
| 271 | + $router.push({ | ||
| 272 | + path: '/material_pre_request', | ||
| 273 | + query: { | ||
| 274 | + activity_id, | ||
| 275 | + form_id, | ||
| 276 | + client_id | ||
| 277 | + } | ||
| 278 | + }); | ||
| 279 | + }, 1000); | ||
| 280 | + } | ||
| 216 | } | 281 | } |
| 217 | 282 | ||
| 218 | const goShoppingCart = () => { // 跳转购物车 | 283 | const goShoppingCart = () => { // 跳转购物车 |
| 219 | - console.warn('goShoppingCart'); | 284 | + if (!cart_count.value) { |
| 220 | - $router.push({ path: '/material_pre_request' }); | 285 | + // |
| 286 | + showDialog({ | ||
| 287 | + title: '温馨提示', | ||
| 288 | + message: | ||
| 289 | + `您的购物车为空,将前往添加!`, | ||
| 290 | + confirmButtonColor: styleColor.baseColor, | ||
| 291 | + }) | ||
| 292 | + .then(() => { | ||
| 293 | + $router.push({ | ||
| 294 | + path: '/material_pre_request', | ||
| 295 | + query: { | ||
| 296 | + activity_id, | ||
| 297 | + form_id, | ||
| 298 | + client_id | ||
| 299 | + } | ||
| 300 | + }); | ||
| 301 | + }) | ||
| 302 | + .catch(() => { | ||
| 303 | + // on cancel | ||
| 304 | + }); | ||
| 305 | + } else { | ||
| 306 | + $router.push({ | ||
| 307 | + path: '/material_pre_request', | ||
| 308 | + query: { | ||
| 309 | + activity_id, | ||
| 310 | + form_id, | ||
| 311 | + client_id | ||
| 312 | + } | ||
| 313 | + }); | ||
| 314 | + } | ||
| 221 | } | 315 | } |
| 222 | 316 | ||
| 223 | const show_choose_material = ref(false); | 317 | const show_choose_material = ref(false); |
| 224 | const onCloseChoose = () => { // 关闭选择物资弹窗回调 | 318 | const onCloseChoose = () => { // 关闭选择物资弹窗回调 |
| 225 | show_choose_material.value = false; | 319 | show_choose_material.value = false; |
| 320 | + // 购物车数量 | ||
| 321 | + getCartCount(); | ||
| 226 | } | 322 | } |
| 227 | 323 | ||
| 228 | const show_material_detail = ref(false); | 324 | const show_material_detail = ref(false); | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-06-29 18:18:02 | 2 | * @Date: 2022-06-29 18:18:02 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-24 18:25:08 | 4 | + * @LastEditTime: 2024-07-25 17:30:16 |
| 5 | * @FilePath: /temple_material_request/src/views/success.vue | 5 | * @FilePath: /temple_material_request/src/views/success.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -65,8 +65,15 @@ const goTo = (type) => { | ... | @@ -65,8 +65,15 @@ const goTo = (type) => { |
| 65 | // TODO:地址待定需要和后台沟通 | 65 | // TODO:地址待定需要和后台沟通 |
| 66 | if (type === 'home') { // 返回首页 | 66 | if (type === 'home') { // 返回首页 |
| 67 | // location.href = '/'; | 67 | // location.href = '/'; |
| 68 | + /** | ||
| 69 | + * 活动首页: | ||
| 70 | + http://oa.onwall.cn/f/main/?p=activity&form_id=799652&i=801234 | ||
| 71 | + */ | ||
| 68 | } else { // 返回活动主页 | 72 | } else { // 返回活动主页 |
| 69 | // location.href = '/'; | 73 | // location.href = '/'; |
| 74 | + /** | ||
| 75 | + * https://oa-dev.onwall.cn/?p=volunteer_home&t=volunteer&c=35697 | ||
| 76 | + */ | ||
| 70 | } | 77 | } |
| 71 | console.warn(type); | 78 | console.warn(type); |
| 72 | } | 79 | } | ... | ... |
-
Please register or login to post a comment