123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- <template>
- <div class="component-edit-indent">
- <el-dialog
- v-model="show"
- class="custom-edit-indent-dialog"
- :title="
- visible === 1
- ? $t(prefix_edit + 'title_add')
- : $t(prefix_edit + 'title_edit')
- "
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :before-close="close"
- width="960px"
- >
- <el-form
- ref="indentForm"
- :rules="rules"
- :model="form"
- label-width="130px"
- >
- <div class="edit-indent-form flex flex-wrap items-center">
- <el-form-item
- :label="$t(prefix + 'label_customer_name')"
- prop="custom_name"
- >
- <el-select
- v-model="form.custom_name"
- style="width: 100%"
- :placeholder="$t('text_please_select')"
- :remote-method="getCustomListFun"
- :loading="loading"
- allow-create
- remote
- filterable
- @change="customChange"
- >
- <el-option
- v-for="option in customList"
- :key="option.id"
- :label="option.name"
- :value="option.name"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item :label="$t(prefix + 'label_project_name')">
- <el-input v-model="form.deal_name"></el-input>
- </el-form-item>
- <el-form-item
- label="SKU"
- style="height: 40px"
- >
- <!-- <el-input
- style="display: none"
- v-model="form.product_sku"></el-input> -->
- <div
- class="el-input el-input__wrapper el-input__inner fake-sku-input"
- @click="skuSelectVisible = true"
- >
- {{ form.product_sku }}
- </div>
- </el-form-item>
- <el-form-item
- :label="$t(prefix + 'label_product_name')"
- prop="product_name"
- >
- <el-input
- v-model="form.product_name"
- disabled
- ></el-input>
- </el-form-item>
- <el-form-item
- :label="$t(prefix + 'label_require_material')"
- prop="require_material"
- >
- <div
- class="flex justify-between items-center"
- style="width: 100%"
- >
- <el-select v-model="form.require_material">
- <el-option
- v-for="item in materialOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- ></el-option>
- </el-select>
- <el-input
- v-if="form.require_material === '其它'"
- v-model.trim="form.require_material_other"
- placeholder="选其它时必填"
- style="width: 45%"
- ></el-input>
- </div>
- </el-form-item>
- <el-form-item
- :label="$t(prefix + 'label_category')"
- prop="product_category"
- >
- <div
- class="flex justify-between items-center"
- style="width: 100%"
- >
- <el-select v-model="form.product_category">
- <el-option
- v-for="item in categoryOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- ></el-option>
- </el-select>
- <el-input
- v-if="form.product_category === '其它'"
- v-model.trim="form.product_category_other"
- placeholder="选其它时必填"
- style="width: 45%"
- ></el-input>
- </div>
- </el-form-item>
- <el-form-item
- :label="$t(prefix + 'label_print_method')"
- prop="print_method"
- >
- <div
- class="flex justify-between items-center"
- style="width: 100%"
- >
- <el-select v-model="form.print_method">
- <el-option
- v-for="item in printOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- ></el-option>
- </el-select>
- <el-input
- v-if="form.print_method === '其它'"
- v-model.trim="form.print_method_other"
- placeholder="选其它时必填"
- style="width: 45%"
- ></el-input>
- </div>
- </el-form-item>
- <el-form-item :label="$t(prefix_edit + 'label_print_require')">
- <el-input v-model="form.require_print"></el-input>
- </el-form-item>
- <el-form-item
- :label="$t(prefix_edit + 'label_number')"
- prop="require_amount"
- >
- <el-input v-model="form.require_amount"></el-input>
- </el-form-item>
- <el-form-item :label="$t(prefix_edit + 'label_deliver_date')">
- <el-date-picker
- v-model="form.due_date"
- value-format="yyyy-MM-dd"
- type="date"
- placeholder="选择日期"
- ></el-date-picker>
- </el-form-item>
- <el-form-item :label="$t(prefix_edit + 'label_ref_dimension')">
- <el-input
- v-model="form.ref_size_length"
- style="width: 50px"
- placeholder="长"
- ></el-input>
- <span> * </span>
- <el-input
- v-model="form.ref_size_width"
- style="width: 50px"
- placeholder="宽"
- ></el-input>
- <span> * </span>
- <el-input
- v-model="form.ref_size_height"
- style="width: 50px"
- placeholder="高"
- ></el-input>
- <span> CM</span>
- </el-form-item>
- <el-form-item
- :label="$t(prefix_edit + 'label_ref_url')"
- style="width: 98%"
- >
- <el-input v-model="form.ref_url"></el-input>
- </el-form-item>
- <el-form-item
- :label="$t(prefix_edit + 'label_comment')"
- style="width: 98%"
- >
- <el-input
- v-model="form.other_note"
- type="textarea"
- :rows="3"
- ></el-input>
- </el-form-item>
- <el-form-item
- :label="$t(prefix_edit + 'label_ref_image')"
- style="width: 100%"
- >
- <image-upload
- v-model:list="imageList"
- :disable-preview="true"
- ></image-upload>
- </el-form-item>
- <el-form-item style="width: 100%">
- <el-table
- v-show="quoteList.length"
- :data="quoteList"
- border
- stripe
- >
- <el-table-column
- width="200"
- :label="$t(prefix_edit + 'col_product_image')"
- >
- <template #default="scope">
- <div v-if="scope.row.product_image.length">
- <img
- :src="scope.row.product_image[0]"
- style="width: 100%; height: auto"
- />
- </div>
- </template>
- </el-table-column>
- <el-table-column
- width="200"
- prop="vendor_name"
- :label="$t(prefix_edit + 'col_supplier')"
- ></el-table-column>
- <el-table-column
- prop="product_url"
- label="URL"
- ></el-table-column>
- </el-table>
- <el-button
- type="warning"
- size="small"
- @click="addInfo"
- >
- + {{ $t(prefix_edit + 'btn_add_info') }}
- </el-button>
- </el-form-item>
- </div>
- </el-form>
- <template #footer>
- <div class="flex justify-center items-center">
- <el-button
- size="small"
- type="primary"
- @click="checkForm(indentForm)"
- >
- {{ $t('btn_submit') }}
- </el-button>
- <el-button
- size="small"
- type="primary"
- @click="checkForm(indentForm, false)"
- >
- {{ $t(prefix_edit + 'btn_submit_and_next') }}
- </el-button>
- </div>
- </template>
- </el-dialog>
- <editInfo
- v-model:visible="infoVisible"
- @create="quotaCreated"
- ></editInfo>
- <sku-select
- v-model:visible="skuSelectVisible"
- @select="selectSku"
- ></sku-select>
- </div>
- </template>
- <script lang="ts" setup>
- import { defineComponent, ref, watch, nextTick, inject } from 'vue'
- import {
- ElButton,
- ElForm,
- ElFormItem,
- ElInput,
- ElTable,
- ElTableColumn,
- ElSelect,
- ElOption,
- ElDialog,
- ElNotification,
- ElDatePicker,
- } from 'element-plus'
- import type { FormInstance } from 'element-plus'
- import cloneDeep from 'lodash.clonedeep'
- import dayjs from 'dayjs'
- import ImageUpload from '@/components/ImageUpload.vue'
- import editInfo from './components/info.vue'
- import skuSelect from './components/skuSelect.vue'
- import { $t } from '@/i18n/index'
- import { getCustomList, createIndent } from '@/api/indent'
- defineComponent({
- name: 'EditIndent',
- })
- const {
- visible = 0,
- quotaData = {} as any,
- indentData = {} as any,
- categoryOptions = [],
- printOptions = [],
- materialOptions = [],
- } = defineProps<{
- visible: number
- // 引用数据. 没有拼错, 不是quote询价信息列表. 这个数据是‘引用’业务克隆出来的, 虽然最终也会赋值给quoteList
- quotaData: object
- indentData: object
- categoryOptions: any[]
- printOptions: any[]
- materialOptions: any[]
- }>()
- watch(
- () => visible,
- () => {
- show.value = visible > 0
- if (visible > 0) {
- resetData()
- }
- if (visible === 1 && quotaData?.content?.length) {
- quotaCreated(quotaData)
- }
- if (visible === 2) {
- // 编辑. 初始化传进来的数据
- const temp = cloneDeep(indentData)
- if (temp.due_date) {
- temp.due_date = dayjs(temp.due_date * 1000).format('YYYY-MM-DD')
- } else {
- temp.due_date = ''
- }
- quoteList.value = cloneDeep(temp.lists || [])
- if (Array.isArray(temp.picture) && temp.picture.length) {
- nextTick(() => {
- imageList.value = temp.picture.map((img: string) => {
- return {
- url: $mediaRegExp.test(img)
- ? img
- : import.meta.env.VITE_APP_OSS_PREFIX + img,
- }
- })
- })
- }
- temp.entity_id = temp.id
- delete temp.id
- delete temp.admin_id
- delete temp.checked
- delete temp.create_time
- delete temp.creator
- delete temp.default_quote
- delete temp.list // quoteList
- delete temp.update_time
- // delete temp.status
- form.value = Object.assign({}, cloneDeep(formDemo), temp)
- }
- },
- )
- const $emit = defineEmits(['update:visible', 'create'])
- const prefix = ref('order.indent.')
- const prefix_edit = ref('order.indent_edit.')
- const show = ref(false)
- const skuSelectVisible = ref(false)
- const form = ref({} as any)
- const formDemo = {
- custom_name: '',
- custom_id: '', // 联动custom_name
- deal_name: '',
- deal_id: '', // 永远是空
- product_sku: '',
- item_id: '', // 看旧代码是和 product_sku 有联动, 应该是商品的id
- product_name: '',
- require_material: '',
- require_material_other: '',
- product_category: '',
- product_category_other: '',
- print_method: '',
- print_method_other: '',
- require_print: '',
- require_amount: '',
- due_date: '',
- ref_size_length: '',
- ref_size_width: '',
- ref_size_height: '',
- ref_url: '',
- other_note: '',
- picture: '',
- }
- const imageList = ref([])
- const checkMaterial = (rule: any, value: any, cb: any) => {
- if (value === '') {
- return cb(new Error($t('text_please_select')))
- } else if (value === '其它') {
- if (
- !(
- form.value.require_material_other &&
- form.value.require_material_other.length
- )
- ) {
- return cb(new Error('选择其它时, 需填写具体内容!'))
- }
- }
- cb()
- }
- const checkCategory = (rule: any, value: any, cb: any) => {
- if (value === '') {
- return cb(new Error($t('text_please_select')))
- } else if (value === '其它') {
- if (
- !(
- form.value.product_category_other &&
- form.value.product_category_other.length
- )
- ) {
- return cb(new Error('选择其它时, 需填写具体内容!'))
- }
- }
- cb()
- }
- const checkPrint = (rule: any, value: any, cb: any) => {
- if (value === '') {
- return cb(new Error($t('text_please_select')))
- } else if (value === '其它') {
- if (
- !(form.value.print_method_other && form.value.print_method_other.length)
- ) {
- return cb(new Error('选择其它时, 需填写具体内容!'))
- }
- }
- cb()
- }
- const rules = {
- custom_name: [
- {
- required: true,
- message: $t('text_please_input'),
- trigger: 'change',
- },
- ],
- custom_id: [
- {
- required: true,
- message: $t('text_please_input'),
- trigger: 'change',
- },
- ],
- product_name: [
- {
- required: true,
- message: '请通过sku表单项选择一个商品',
- trigger: 'change',
- },
- ],
- require_material: [
- { required: true, validator: checkMaterial, trigger: 'change' },
- ],
- product_category: [
- { required: true, validator: checkCategory, trigger: 'change' },
- ],
- print_method: [{ required: true, validator: checkPrint, trigger: 'change' }],
- require_amount: [
- {
- required: true,
- message: $t('text_please_select'),
- trigger: 'change',
- },
- ],
- }
- // 客户下拉框候选列表
- const customList = ref([] as any[])
- const loading = ref(false)
- const quoteList = ref([])
- const selectSku = (data: any) => {
- form.value.product_name = data.product_name || ''
- form.value.product_sku = data.product_sku || ''
- form.value.item_id = data.id || ''
- }
- const customChange = (value: any) => {
- const temp = customList.value.filter((i: any) => i.name === value)
- form.value.custom_id = temp.length ? temp[0].id : ''
- }
- // 成功创建了报价, 把数据展示到界面
- const quotaCreated = (data: any) => {
- if (Array.isArray(data.content)) {
- quoteList.value = quoteList.value.concat(data.content)
- }
- }
- const resetData = () => {
- form.value = cloneDeep(formDemo)
- imageList.value = []
- customList.value = []
- quoteList.value = []
- }
- const close = (done = {} as any) => {
- $emit('update:visible', 0)
- if (typeof done === 'function') done()
- }
- const infoVisible = ref(0)
- const addInfo = () => {
- infoVisible.value = 1
- }
- const $mediaRegExp = inject('mediaRegExp') as RegExp
- const indentForm = ref<FormInstance>()
- const checkForm = (
- formEl: FormInstance | undefined,
- closeAfterCreate = true,
- ) => {
- if (!formEl) return
- formEl.validate((valid: boolean) => {
- if (valid) {
- form.value.picture = imageList.value
- .map((i: any) => {
- return i.url.replace($mediaRegExp, '/')
- })
- .join(',')
- // this$set(
- // this.form,
- // `quotes`,
- // quoteList.value.map((d: any) => d.entity_id || d.id),
- // )
- form.value.quotes = quoteList.value.map((d: any) => d.entity_id || d.id)
- createIndent(form.value)
- .then((response: any) => {
- // console.log(response, 'create indent')
- if (response.code === 1) {
- ElNotification({
- title: '创建成功',
- message: '正在刷新数据',
- duration: 3000,
- })
- // notify parent-component to refresh list data
- $emit('create')
- resetData()
- if (closeAfterCreate) {
- close()
- } else {
- formEl.clearValidate()
- }
- }
- })
- .catch(() => {
- ElNotification({
- duration: 3000,
- title: '创建出错',
- message:
- '请稍后再试. 或者按F12打开控制台, 把错误信息复制出来找管理员排查.',
- })
- })
- }
- })
- }
- const getCustomListFun = (keywords: string) => {
- loading.value = true
- customList.value = []
- getCustomList({ keywords })
- .then((response: any) => {
- if (Array.isArray(response.result) && response.result.length) {
- customList.value = response.result
- }
- })
- .finally(() => {
- loading.value = false
- })
- }
- getCustomListFun('')
- </script>
- <style lang="scss">
- .component-edit-indent {
- .custom-edit-indent-dialog {
- margin-top: 0 !important;
- margin-bottom: 0 !important;
- height: 100vh;
- .el-dialog__body {
- max-height: 87vh;
- overflow-y: scroll;
- overflow-x: auto;
- padding-top: 8px;
- }
- }
- }
- </style>
- <style lang="scss" scoped>
- .edit-indent-form {
- .el-form-item {
- width: 49%;
- }
- }
- .fake-sku-input {
- height: 30px;
- cursor: pointer;
- }
- </style>
|