123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- <!-- @format -->
- <script lang="ts" setup>
- import { Plus } from '@element-plus/icons-vue'
- import { getRFQsDetailApi, submitRFQsApiApi } from '@/api/model/my'
- import { ossUploadApi } from '@/api/model/common'
- import { downloadFileByA } from '@/utils/common/download'
- const props = defineProps({
- rfqId: {
- type: String,
- default: '',
- },
- })
- const emit = defineEmits(['update:data'])
- watch(() => props.rfqId, (val: any) => {
- if (val)
- getRFQsDetail(val)
- }, { immediate: true })
- const input = ref(null)
- const ruleFormRef = ref<any>()
- const loading = ref<boolean>(false)
- const ruleForm = ref<any>({
- productName: '',
- sourceQuantity: '',
- content: '',
- attachments: [],
- })
- const rules = ref<any>({
- productName: { required: true, message: 'Please input product name', trigger: 'blur' },
- sourceQuantity: { required: true, message: 'Please input sourcing quantity', trigger: 'blur' },
- content: { required: true, message: 'Please input detailed requirements', trigger: 'blur' },
- })
- const visible = defineModel('visible', { type: Boolean, required: true })
- function handleClose() {
- console.log('close')
- }
- async function getRFQsDetail(id: any) {
- try {
- const res: any = await getRFQsDetailApi({
- id,
- })
- ruleForm.value = res
- }
- catch (error) {
- console.log(error)
- }
- }
- function uploadData() {
- input.value?.click()
- }
- function inputChange(e: any) {
- const fileList = e.target.files
- const fileArr = Array.from(fileList)
- fileArr.forEach(async (file: any) => {
- const resourceUrl: any = await getResource(file)
- ruleForm.value.attachments.push({
- fileName: getFileTitle(resourceUrl),
- fileUrl: resourceUrl,
- })
- })
- }
- async function getResource(file: any) {
- try {
- if (file.size > 1024 * 1024 * 10)
- return ElMessage.error('Image size cannot exceed 10M')
- return await ossUploadApi(file)
- }
- catch (error) {
- ElMessage.error('send failed')
- }
- }
- function getFileTitle(file: string) {
- const fileArr = file.split('/')
- return fileArr[fileArr.length - 1]
- }
- function del(i: number) {
- ruleForm.value.attachments = ruleForm.value.attachments.filter((item, index) => index !== i)
- }
- async function submitForm(formEl: any | undefined) {
- if (!formEl)
- return
- await formEl.validate(async (valid, fields) => {
- if (valid) {
- loading.value = true
- await submitRFQsApiApi(ruleForm.value)
- ElMessage.success('submit success')
- visible.value = false
- loading.value = false
- emit('update:data')
- }
- else {
- console.log('error submit!', fields)
- loading.value = false
- }
- })
- }
- </script>
- <template>
- <el-dialog
- v-model="visible"
- :append-to-body="true"
- width="800"
- modal-class="custom-quotation-modal"
- @close="handleClose"
- >
- <template #header>
- <div
- class="px-40px py-25px bg-#F5F5F5 b-rd-lt-6px b-rd-rt-6px text-18px fw-500 text-#333"
- >
- Request For Quotation
- </div>
- </template>
- <div class="py-24px px-40px">
- <el-form
- ref="ruleFormRef"
- :model="ruleForm"
- :rules="rules"
- :disabled="!!rfqId"
- label-width="auto"
- class="custom-ruleForm"
- status-icon
- >
- <el-form-item label="Product Name" prop="productName">
- <el-input v-model="ruleForm.productName" placeholder="Please input product name" />
- </el-form-item>
- <el-form-item label="Sourcing quantity" prop="sourceQuantity">
- <el-input
- v-model="ruleForm.sourceQuantity"
- placeholder="Please input"
- >
- <template #append>
- Pcs
- </template>
- </el-input>
- </el-form-item>
- <el-form-item label="Detailed requirements" prop="content">
- <el-input
- v-model="ruleForm.content"
- :rows="4"
- type="textarea"
- placeholder="I 'm looking for..."
- />
- </el-form-item>
- </el-form>
- <div>
- <div v-if="!rfqId" class="flex items-center mb-16px">
- <el-button
- class="!bg-#C58C46 !text-#fff !ml-0 !w-250px !h-48px !text-14px !fw-500 !b-rd-6px"
- :icon="Plus"
- @click="uploadData"
- >
- Upload sourcing documents
- </el-button>
- <div class="ml-16px text-12px">
- Max file size: 10MB. Types supported: jpg, jpeg, png, pdf, docx, doc, xlsx, xls.
- </div>
- </div>
- <input
- ref="input"
- multiple="true"
- type="file"
- class="hidden"
- @change="inputChange"
- >
- <div>
- <div
- v-for="(items, index) in ruleForm.attachments"
- :key="index"
- class="py-14px px-16px bg-#F7F8FA flex items-center justify-between mt-8px b-solid b-1px b-#E0E0E0 b-rd-4px"
- >
- <div class="flex items-center">
- <svgo-file
- class="!w-20px cursor-pointer !h-20px text-#333 mr-16px"
- />
- 附件{{ index }}:
- <a :href="items.fileUrl"> {{ getFileTitle(items.fileUrl) }}</a>
- </div>
- <img v-if="!rfqId" src="@/assets/images/file_delete.png" class="!w-20px cursor-pointer !h-20px" alt="" srcset="" @click="del(index)">
- </div>
- </div>
- </div>
- </div>
- <template #footer>
- <el-button
- v-if="!rfqId"
- :loading="loading"
- class="!bg-#C58C46 !text-#fff !ml-0 !w-170px !h-48px !text-14px !fw-500 !b-rd-6px"
- @click="submitForm(ruleFormRef)"
- >
- Submit FRQ
- </el-button>
- <div v-if="rfqId">
- <div
- class="w-full py-24px !text-left px-16px b-dashed b-1px b-#E0E0E0 b-rd-4px "
- >
- <div v-if="ruleForm?.quotes">
- <div class="fw-700 text-#3D3D3D">
- Quotation for product
- </div>
- <div class="mt-20px mb-28px">
- <div v-for="item in ruleForm?.quotes?.attachments" :key="item.id" class="py-4px underline cursor-pointer" @click="downloadFileByA(item.fileUrl, item.fileName)">
- {{ getFileTitle(item.fileUrl) }}
- </div>
- </div>
- <div class="fw-700 my-20px text-#3D3D3D">
- Remark
- </div>
- <div class="text-#333">
- {{ ruleForm?.quotes?.remark }}
- </div>
- </div>
- <div v-else class="flex justify-center items-center">
- <svgo-quotation class="!w-28px !h-28px mr-14px" />
- No quotation yet
- </div>
- </div>
- </div>
- </template>
- </el-dialog>
- </template>
- <style lang="less">
- .custom-quotation-modal {
- .el-dialog {
- padding: unset !important;
- .el-dialog__header {
- padding: 0 !important;
- .el-dialog__headerbtn {
- right: 20px;
- top: 10px;
- }
- }
- .custom-ruleForm{
- .el-form-item{
- display: block;
- .el-form-item__label-wrap{
- margin-left: unset !important;
- margin-bottom: 5px;
- }
- .el-input__wrapper{
- .el-input__inner{
- height: 40px !important;
- }
- }
- .el-input-group--append{
- width: 480px!important;
- }
- }
- }
- .el-dialog__footer {
- padding-top: 24px !important;
- padding-bottom: 24px !important;
- padding-left: 40px !important;
- padding-right: 40px !important;
- border: 1px solid #E0E0E0;
- }
- }
- }
- </style>
|