123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 |
- <template>
- <div class="dialog-change-order">
- <el-dialog
- v-model="show"
- class="custom-change-order-dialog"
- title="报价记录"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :before-close="close"
- width="1200px"
- >
- <el-table
- v-loading="loading"
- :expand-row-keys="expandRowKeys"
- row-key="id"
- :data="list"
- >
- <el-table-column type="expand">
- <template #default="props">
- <el-form
- :ref="($el) => setFormRef($el, props.row.id_string)"
- :model="formList[props.$index]"
- label-width="140"
- >
- <div class="flex justify-between flex-wrap">
- <el-form-item
- :rules="{
- required: true,
- }"
- prop="product_sku"
- label="SKU"
- style="height: 40px"
- >
- <div
- class="el-input el-input__wrapper el-input__inner fake-sku-input"
- @click="openSkuSelect(props.$index)"
- >
- <el-input
- style="display: none"
- v-model="formList[props.$index].product_sku"
- ></el-input>
- <span class="cursor-pointer">
- {{ formList[props.$index].product_sku }}
- </span>
- </div>
- </el-form-item>
- <el-form-item
- label="产品名称"
- prop="product_name"
- >
- <el-input
- v-model="formList[props.$index].product_name"
- disabled
- ></el-input>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- }"
- label="交付日期"
- prop="Expected_Delivery_Date"
- >
- <el-date-picker
- v-model="formList[props.$index].Expected_Delivery_Date"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- type="date"
- ></el-date-picker>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- }"
- label="Brand Name"
- prop="Brand_Name"
- >
- <el-input
- v-model="formList[props.$index].Brand_Name"
- ></el-input>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- }"
- label="Client Mailbox"
- prop="Client_Mailbox"
- >
- <el-input
- v-model="formList[props.$index].Client_Mailbox"
- ></el-input>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- message: 'Job Name is required',
- }"
- label="Job Name"
- prop="Contract_Title"
- >
- <el-input
- v-model="formList[props.$index].Contract_Title"
- ></el-input>
- </el-form-item>
- <el-form-item
- label="ATTN"
- prop="Primary_Contact"
- >
- <el-input v-model="formList[props.$index].Primary_Contact">
- <template #append>
- <el-button @click="openATTNDialog(props.$index)">
- <el-icon :size="14">
- <Notebook></Notebook>
- </el-icon>
- </el-button>
- </template>
- </el-input>
- </el-form-item>
- <el-form-item
- label="Phone"
- prop="Phone"
- >
- <el-input v-model="formList[props.$index].Phone"></el-input>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- }"
- label-width="220"
- label="Shipping Unit/Building Name"
- prop="Shipping_Unit_Building_Name"
- >
- <el-input
- v-model="formList[props.$index].Shipping_Unit_Building_Name"
- ></el-input>
- <!-- <el-select
- v-model="formList[props.$index].Shipping_Unit_Building_Name"
- allow-create
- filterable
- remote
- placeholder="enter directly or select a place"
- :remote-method="($e) => remoteSearchPlace($e, props.$index)"
- :loading="loading"
- >
- <el-option
- v-for="item in remoteOption[props.$index] as any[]"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select> -->
- </el-form-item>
- <el-form-item
- label="Shipping Street"
- prop="Shipping_Street"
- >
- <el-input
- v-model="formList[props.$index].Shipping_Street"
- ></el-input>
- </el-form-item>
- <el-form-item
- label="Shipping City"
- prop="Shipping_City"
- >
- <el-input
- v-model="formList[props.$index].Shipping_City"
- ></el-input>
- </el-form-item>
- <el-form-item
- label="Shipping State"
- prop="Shipping_State"
- >
- <el-input
- v-model="formList[props.$index].Shipping_State"
- ></el-input>
- </el-form-item>
- <el-form-item
- label="Shipping Code"
- prop="Shipping_Code"
- >
- <el-input
- v-model="formList[props.$index].Shipping_Code"
- ></el-input>
- </el-form-item>
- <el-form-item
- :rules="{
- required: true,
- }"
- label="Shipping Country"
- prop="Shipping_Country"
- >
- <el-input
- v-model="formList[props.$index].Shipping_Country"
- ></el-input>
- </el-form-item>
- <el-form-item
- label="Tax Level"
- :rules="{
- required: true,
- }"
- prop="Tax_Level"
- >
- <el-select v-model="formList[props.$index].Tax_Level">
- <el-option
- v-for="item in taxList"
- :key="item"
- :label="item"
- :value="item"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item
- label="客户名称"
- prop="custom_name"
- :rules="{
- required: true,
- }"
- >
- <el-select
- v-model="formList[props.$index].custom_name"
- style="width: 100%"
- :placeholder="$t('text_please_select')"
- :remote-method="debounce(getCustomListFun, 500)"
- :loading="customLoading"
- remote
- filterable
- @change="selectCustomer"
- >
- <!-- :disabled="!!indentData.enquiry_id" -->
- <el-option
- v-for="(option, index) in customList"
- :key="option.id || index"
- :label="option.name"
- :value="option.name"
- ></el-option>
- </el-select>
- </el-form-item>
- </div>
- <div class="flex justify-end">
- <el-button
- size="small"
- @click="expandRowKeys = []"
- >
- 取消
- </el-button>
- <el-button
- size="small"
- type="primary"
- @click="submitChangeOrder(props.$index)"
- >
- 提交
- </el-button>
- <!-- <el-button @click="toApplyVendor">test</el-button> -->
- </div>
- </el-form>
- </template>
- </el-table-column>
- <el-table-column
- label="序号"
- width="65"
- type="index"
- ></el-table-column>
- <el-table-column
- min-width="180"
- max-width="300"
- label="Items"
- prop="items"
- ></el-table-column>
- <el-table-column
- label="采购数量"
- prop="number"
- ></el-table-column>
- <el-table-column
- label="售价"
- prop="unit_cost"
- ></el-table-column>
- <el-table-column
- label="setup"
- prop="setup_cost"
- ></el-table-column>
- <el-table-column
- label="运费"
- prop="freight"
- ></el-table-column>
- <el-table-column
- width="180"
- label="创建时间"
- prop="create_time"
- ></el-table-column>
- <el-table-column label="操作">
- <template #default="scope">
- <el-button
- size="small"
- type="primary"
- plain
- @click="expandRowKeys.push(scope.row.id_string)"
- >
- 转单
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <div class="my-4 flex justify-end">
- <el-pagination
- v-model:current-page="currentPage"
- v-model:page-size="pageSize"
- v-model:total="total"
- layout="prev, pager, next, jumper, sizes"
- :page-sizes="[10, 20, 50, 100]"
- @current-change="getCalcPriceRecordFunc"
- @size-change="getCalcPriceRecordFunc"
- ></el-pagination>
- </div>
- </el-dialog>
- <el-dialog
- v-model="show2"
- class="attn-dialog"
- title="选择地址"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- width="1150px"
- >
- <el-table
- v-if="currentATTNList"
- highlight-current-row
- :data="currentATTNList"
- max-height="70vh"
- @current-change="selectATTN"
- >
- <el-table-column
- type="index"
- width="50"
- ></el-table-column>
- <el-table-column
- width="150"
- label="ATTN"
- prop="Primary_Contact"
- ></el-table-column>
- <el-table-column
- width="120"
- label="Phone"
- prop="Phone"
- ></el-table-column>
- <el-table-column
- label="Shipping_Unit_Building_Name"
- prop="Shipping_Unit_Building_Name"
- ></el-table-column>
- <el-table-column
- label="Shipping_Street"
- prop="Shipping_Street"
- ></el-table-column>
- <el-table-column
- width="135"
- label="Shipping_State"
- prop="Shipping_State"
- ></el-table-column>
- </el-table>
- <div class="flex justify-center pt-2">
- <el-button
- type="primary"
- @click="onATTNSelect"
- >
- 选择该项进行填充
- </el-button>
- <el-button @click="show2 = false">关闭</el-button>
- </div>
- </el-dialog>
- <sku-select
- v-model:visible="skuSelectVisible"
- @select="selectSku"
- ></sku-select>
- </div>
- </template>
- <script lang="ts" setup>
- import { defineComponent, ref, watch } from 'vue'
- import {
- ElDialog,
- ElButton,
- ElTable,
- ElTableColumn,
- ElNotification,
- ElPagination,
- ElMessage,
- ElMessageBox,
- ElForm,
- ElFormItem,
- ElInput,
- ElDatePicker,
- ElSelect,
- ElOption,
- ElIcon,
- } from 'element-plus'
- import { Notebook } from '@element-plus/icons-vue'
- import Cookie from 'js-cookie'
- import { getCalcPriceRecord, generateOrder } from '@/api/indent'
- import debounce from 'lodash.debounce'
- import { $t } from '@/i18n/index'
- import { getCustomList } from '@/api/indent'
- import userAPI from '@/api/user'
- import skuSelect from './skuSelect.vue'
- defineComponent({
- name: 'ComponentQuoteRecord',
- })
- const {
- visible = false,
- id = '',
- indentData = {} as any,
- } = defineProps<{
- visible: boolean
- id: string | number
- indentData: object
- }>()
- const $emit = defineEmits(['update:visible', 'success'])
- let show = ref(false)
- let show2 = ref(false)
- let loading = ref(false)
- let list = ref([] as any[])
- // let remoteOption = ref([])
- let user: any = ref({} as any)
- const getUserDetailFunc = () => {
- let indentID = Cookie.get('indent-id') || ''
- let indentName = Cookie.get('indent-user') || ''
- console.log(indentID, 'indentID')
- console.log(indentName, 'indentName')
- // 由于历史原因, 早期登录时没有记录下用户id, 只有用户名称.
- if (indentID) {
- userAPI.getUserDetail({ id: indentID }).then((res: any) => {
- if (res.code === 1) {
- user.value = res.result || {}
- console.log(res.result, 'res')
- }
- })
- } else if (indentName) {
- // get user by name
- userAPI.getUserDetailByName({ username: indentName }).then((res: any) => {
- if (res.code === 1) {
- user.value = res.result || {}
- console.log(res.result, 'res')
- }
- })
- }
- }
- watch(
- () => visible,
- () => {
- show.value = visible
- if (show.value) {
- getCalcPriceRecordFunc()
- getUserDetailFunc()
- }
- },
- )
- const pageSize = ref(10)
- const currentPage = ref(1)
- const total = ref(0)
- const taxList = ref(['GST AU 10%', 'GST NZ 15%', 'No GST 0%', 'VAT 20%'])
- const getCalcPriceRecordFunc = () => {
- loading.value = true
- getCalcPriceRecord({ id: id, limit: pageSize.value, page: currentPage.value })
- .then((res: any) => {
- if (res.code === 1)
- list.value =
- res.result.data.map((i: any) => ({
- ...i,
- id_string: `${i.id}`,
- })) || []
- for (let i = 0; i < list.value.length; i++) {
- const v = list.value[i].Accounts || ({} as any)
- // remoteOption.value.push([])
- formList.value.push({
- // custom_id 不存在说明是旧系统的数据, 需要置空让用户重新选客户
- custom_name: indentData.custom_id ? indentData.custom_name : '',
- custom_id: indentData.custom_id || '', // 联动custom_name
- item_id: indentData.item_id || '',
- product_name: indentData.product_name || '',
- product_sku: indentData.product_sku || '',
- Contract_Title: '',
- Expected_Delivery_Date: '',
- Brand_Name: '',
- Client_Mailbox: '',
- Shipping_Unit_Building_Name: v.Billing_Unit_Building_Name || '',
- Shipping_Street: v.Shipping_Street || '',
- Shipping_City: v.Shipping_City || '',
- Shipping_State: v.Shipping_State || '',
- Shipping_Code: v.Shipping_Code || '',
- Shipping_Country: v.Shipping_Country || '',
- Tax_Level: 'GST AU 10%',
- Order_Source: 'Indent App',
- Contact_Name: { id: '4791186000057250001', name: '/' },
- Primary_Contact: '',
- Phone: '',
- })
- }
- total.value = res.result.total || 0
- })
- .finally(() => (loading.value = false))
- }
- const currentATTNList = ref([] as any[])
- let currentATTNIndex = ref(0) // 当前第几行表单在选attn
- const openATTNDialog = (index: number) => {
- show2.value = true
- currentATTNList.value = list.value[index].AccountEndUser || []
- currentATTN.value = {}
- console.log(index, 'index')
- currentATTNIndex.value = index || 0
- }
- let currentATTN = ref({} as any)
- const selectATTN = (value: any) => {
- currentATTN.value = value || {}
- }
- const onATTNSelect = () => {
- if (!currentATTN.value.id) {
- ElMessage.error('请先点击选择一行地址数据, 再点击按钮')
- return
- }
- const v = currentATTN.value
- const target = formList.value[currentATTNIndex.value]
- target.Shipping_Unit_Building_Name = v.Shipping_Unit_Building_Name || ''
- target.Shipping_Street = v.Shipping_Street || ''
- target.Shipping_City = v.Shipping_City || ''
- target.Shipping_State = v.Shipping_State || ''
- target.Shipping_Code = v.Shipping_Post_Code || ''
- target.Shipping_Country = v.Shipping_Country || ''
- target.Primary_Contact = v.Primary_Contact || ''
- target.Phone = v.Phone || ''
- show2.value = false
- }
- let close = (done = {} as any) => {
- $emit('update:visible', false)
- list.value = []
- formList.value = []
- // remoteOption.value = []
- if (typeof done === 'function') done()
- }
- const expandRowKeys = ref([] as string[])
- const formList = ref([] as any[])
- const formListRef = ref({} as any)
- const setFormRef = (el: any, key: string) => {
- formListRef.value[`${key}`] = el
- }
- const submitChangeOrder = (index: number) => {
- const key = list.value[index].id_string
- const target: any = formListRef.value[`${key}`]
- target.validate((valid: boolean) => {
- if (!valid) return
- const data = Object.assign({}, formList.value[index], {
- id: list.value[index].id,
- })
- if (/gi_/i.test(data.product_sku)) {
- ElNotification({
- title: '注意',
- message: '请选择正确的SKU进行转单',
- duration: 5000,
- })
- return
- }
- if (!data.product_sku || !data.product_name) {
- ElNotification({
- title: 'SKU/产品名称不能为空',
- message: '请选择正确的SKU进行转单',
- duration: 5000,
- })
- return
- }
- if (!data.custom_id || !data.custom_name) {
- ElNotification({
- title: '客户名称 数据出错',
- message: '如果界面上的客户名称有值, 请联系管理员',
- duration: 5000,
- })
- return
- }
- console.log(data, 'data')
- onChangeOrderClick(data)
- })
- }
- // 跳转到申请录入供应商的外部页面.
- const toApplyVendor = () => {
- // 找出当前转单的记录. 必定存在, 不然进不来这个组件.
- let a = indentData.lists.filter((i: any) => i.id === id)
- let tt = a[0] || {}
- console.log(tt, 'tt')
- // 为空或者不是纯数字, 说明这个id不是真的在crm的供应商id
- if ([null, 'null', ''].includes(tt.vendor_id) || !/\d+/.test(tt.vendor_id)) {
- window.open(
- `https://forms.zohopublic.com/promocollectionau/form/SupplierCreationRequirements/formperma/ArflvTSXGDW--ONLT9Wgo5t0N1XLRJ8wGErjacQZl5g?email=${user.value.email || ''}&vendor=${encodeURIComponent(tt.vendor_name)}&name=${encodeURIComponent(tt.vendor_contact)}&phone=${tt.vendor_phone}`,
- )
- }
- }
- const onChangeOrderClick = (row: any) => {
- ElMessageBox.confirm('选择该条计价记录进行转单, 是否继续?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(() => {
- loading.value = true
- generateOrder(row)
- .then((res: any) => {
- console.log(res, 'res')
- if (res.code === 1) {
- ElNotification({
- title: '转单成功',
- message: '正在刷新数据',
- duration: 5000,
- })
- $emit('success')
- let temp = res.result.data
- if (Array.isArray(temp) && temp.length) {
- let id = temp[0].details?.id
- window.open(
- import.meta.env.VITE_SO_PATH +
- `${id}` +
- import.meta.env.VITE_SO_APPEND,
- )
- toApplyVendor()
- }
- close() // 尝试处理部分浏览器(360)不会自动触发close回调的问题.
- } else {
- ElNotification({
- title: '转单失败',
- message: res.message + ', ' + row.toString(),
- })
- }
- })
- .finally(() => (loading.value = false))
- })
- }
- // const remoteSearchPlace = (str: string, index: number) => {
- // console.log(str, 'str', index)
- // if (!str.length) return
- // const target = remoteOption.value[index] as any[]
- // if (target && Array.isArray(target)) {
- // target.push({ value: 1, label: 1 })
- // }
- // }
- const skuSelectVisible = ref(false)
- const openSkuSelect = (key: any) => {
- skuSelectVisible.value = true
- }
- const selectSku = (data: any) => {
- formList.value = formList.value.map((i: any) => {
- return {
- ...i,
- product_name: data.product_name || '',
- product_sku: data.product_sku || '',
- item_id: data.id || '',
- }
- })
- }
- // 客户下拉框候选列表
- const customList = ref([] as any[])
- let customLoading = ref(false)
- const selectCustomer = (data: any) => {
- const temp = customList.value.filter((i: any) => i.name === data)
- if (temp.length === 0) {
- ElMessage.error('客户名称不存在, 请重新选择')
- return
- }
- formList.value = formList.value.map((i: any) => {
- return {
- ...i,
- custom_name: temp[0].name || '',
- custom_id: temp[0].id || '',
- }
- })
- }
- const getCustomListFun = (keyword: string) => {
- let keywords = keyword.trim()
- if (!keywords.length) return
- customLoading.value = true
- customList.value = []
- getCustomList({ keywords })
- .then((response: any) => {
- if (Array.isArray(response.result)) {
- customList.value = response.result.length ? response.result : []
- }
- })
- .finally(() => {
- customLoading.value = false
- })
- }
- </script>
- <style lang="scss">
- .dialog-change-order {
- .el-form-item {
- width: 49%;
- }
- .attn-dialog {
- margin-top: 8vh;
- }
- }
- </style>
- <style lang="scss">
- .custom-change-order-dialog {
- margin-top: 7vh;
- }
- </style>
|