123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <template>
- <div class="pcSubmit">
- <a-form layout="vertical" :model="formData" ref="formRef" :rules="rules">
- <a-form-item name="problemDesc">
- <div class="myTitle required" slot="label"><span class="number">01</span>{{ t('feedback.title1') }}</div>
- <a-textarea
- show-count
- :maxlength="500"
- :autoSize="{ minRows: 4, maxRows: 8 }"
- v-model:value="formData.problemDesc"
- :placeholder="t('feedback.settext')"
- />
- </a-form-item>
- <a-form-item name="problemFile" style="margin-top: 2px">
- <a-upload
- v-model:file-list="formData.problemDescImgs"
- accept=".jpg,.png,.mp4"
- action="/service/manage/common/upload/files"
- list-type="picture-card"
- :maxCount="6"
- :multiple="true"
- :before-upload="beforeUpload"
- @preview="handlePreview"
- @change="fileChange"
- >
- <div>
- <PlusOutlined style="color: #d9d9d9" color="#D9D9D9" />
- <!-- <div style="margin-top: 8px">{{ t('feedback.upload') }}</div> -->
- </div>
- </a-upload>
- <div class="tips" v-html="t('feedback.fileTipsPc')"></div>
- </a-form-item>
- <a-form-item name="solution">
- <div class="myTitle required" slot="label"><span class="number">02</span>{{ t('feedback.title2') }}</div>
- <a-textarea
- show-count
- :maxlength="500"
- :autoSize="{ minRows: 4, maxRows: 8 }"
- v-model:value="formData.solution"
- :placeholder="t('feedback.settext')"
- />
- </a-form-item>
- <a-form-item name="problemFile" style="margin-top: 2px">
- <a-upload
- :maxCount="6"
- v-model:file-list="formData.solutionImgs"
- action="/service/manage/common/upload/files"
- list-type="picture-card"
- :multiple="true"
- :before-upload="beforeUpload"
- @preview="handlePreview"
- @change="fileChange"
- >
- <div>
- <PlusOutlined style="color: #d9d9d9" color="#D9D9D9" />
- <!-- <div style="margin-top: 8px">{{ t('feedback.upload') }}</div> -->
- </div>
- </a-upload>
- <div class="tips" v-html="t('feedback.fileTipsPc')"></div>
- </a-form-item>
- <a-form-item name="industryOptionId">
- <div class="myTitle required" slot="label"><span class="number">03</span>{{ t('feedback.title3') }}</div>
- <a-select
- key="industryOptionId"
- v-model:value="formData.industryOptionId"
- :placeholder="t('feedback.setselcet')"
- :options="propsOptions.industryOptionId"
- />
- </a-form-item>
- <a-form-item name="hardwareOptionId">
- <div class="myTitle required" slot="label"><span class="number">04</span>{{ t('feedback.title4') }}</div>
- <a-select
- key="hardwareOptionId"
- v-model:value="formData.hardwareOptionId"
- :placeholder="t('feedback.setselcet')"
- :options="propsOptions.hardwareOptionId"
- />
- </a-form-item>
- <a-form-item name="softwareOptionId">
- <div class="myTitle required" slot="label"><span class="number">05</span>{{ t('feedback.title5') }}</div>
- <a-select
- key="softwareOptionId"
- v-model:value="formData.softwareOptionId"
- :placeholder="t('feedback.setselcet')"
- :options="propsOptions.softwareOptionId"
- />
- </a-form-item>
- <a-form-item>
- <div class="myTitle" slot="label"><span class="number">06</span>{{ t('feedback.title6') }}</div>
- <a-input :maxlength="30" v-model:value="formData.nickName" :placeholder="t('feedback.settext')" />
- </a-form-item>
- <a-form-item>
- <div class="myTitle" slot="label"><span class="number">07</span>{{ t('feedback.title61') }}</div>
- <a-input :maxlength="30" v-model:value="formData.phone" :placeholder="t('feedback.settext')" />
- </a-form-item>
- <a-form-item>
- <div class="myTitle" slot="label"><span class="number">08</span>{{ t('feedback.title7') }}</div>
- <a-select
- v-model:value="formData.country"
- :filterOption="filterOption"
- :options="countryOption"
- showSearch
- :placeholder="t('feedback.setselcet')"
- />
- <!-- <a-cascader v-model:value="formData.countries" :options="options" placeholder="Please select" /> -->
- </a-form-item>
- <a-form-item v-if="formData.country == '中国' || formData.country == 'China'">
- <div class="myTitle" slot="label"
- ><span class="number">{{ formData.country == '中国' || formData.country == 'China' ? '09' : '08' }}</span
- >{{ t('feedback.title71') }}</div
- >
- <a-cascader v-model:value="formData.countries" :options="options" :placeholder="t('feedback.setselcet')" />
- </a-form-item>
- <a-form-item>
- <div class="myTitle" slot="label"
- ><span class="number">{{ formData.country == '中国' || formData.country == 'China' ? '10' : '09' }}</span
- >{{ t('feedback.title8') }}</div
- >
- <van-rate
- color="#FADB14"
- size="30"
- void-color="#D9D9D9"
- :allow-half="true"
- v-model="formData.score"
- :placeholder="t('feedback.setselcet')"
- />
- </a-form-item>
- <a-form-item>
- <div class="myTitle" slot="label"
- ><span class="number">{{ formData.country == '中国' || formData.country == 'China' ? '11' : '10' }}</span
- >{{ t('feedback.title9') }}</div
- >
- <a-input :maxlength="100" v-model:value="formData.scoreReason" :placeholder="t('feedback.settext')" />
- </a-form-item>
- <a-form-item style="text-align: center">
- <a-button class="w-160px" style="background-color: #00b3ec" type="primary" size="large" @click="onSubmit">{{
- t('feedback.Submit')
- }}</a-button>
- </a-form-item>
- </a-form>
- </div>
- </template>
- <script setup>
- import { ref, watch } from 'vue';
- import { PlusOutlined } from '@ant-design/icons-vue';
- import cityList from './area.json';
- import countryList from './country.json';
- // import { createImgPreview } from '/@/components/Preview/index';
- const props = defineProps(['formData', 'columns', 'addres']);
- import { message, Upload } from 'ant-design-vue';
- import { useI18n } from 'vue-i18n';
- const { t, locale } = useI18n();
- const emit = defineEmits(['submit']);
- watch(
- () => props.addres,
- (newValue, oldValue) => {
- console.log('addreswatch', newValue);
- formData.value.country = newValue.country;
- formData.value.countries = newValue.mccountries;
- },
- );
- const formData = ref({
- problemDesc: '',
- problemDescImgs: [],
- hardwareOptionId: null,
- softwareOptionId: null,
- industryOptionId: null,
- solution: '',
- solutionImgs: [],
- nickName: '',
- phone: '',
- score: 0,
- scoreReason: '',
- country: '',
- address: '',
- countries: [],
- });
- console.log('formData', formData);
- // eslint-disable-next-line vue/no-setup-props-destructure
- const propsOptions = props.columns;
- const previewImage = ref('');
- const formRef = ref(null);
- const rules = {
- problemDesc: [
- { name: 'problemDesc', validator: validatorFile, message: t('feedback.settext') + t('feedback.title1'), trigger: 'change' },
- ],
- solution: [{ name: 'solution', validator: validatorFile, message: t('feedback.settext') + t('feedback.title2'), trigger: 'change' }],
- softwareOptionId: [{ required: true, message: t('feedback.setselcet') + t('feedback.title5'), trigger: 'change' }],
- industryOptionId: [{ required: true, message: t('feedback.setselcet') + t('feedback.title3'), trigger: 'change' }],
- hardwareOptionId: [{ required: true, message: t('feedback.setselcet') + t('feedback.title4'), trigger: 'change' }],
- };
- function validatorFile(_rule, value) {
- let rule = _rule;
- let isOk = Boolean(formData.value[rule.name] || (formData.value[`${rule.name}Imgs`] && formData.value[`${rule.name}Imgs`].length > 0));
- if (isOk) {
- return Promise.resolve();
- } else {
- return Promise.reject(rule.message);
- }
- }
- function fileChange() {
- formRef.value.validateFields(['problemDesc', 'solution']);
- }
- const countryOption = countryList.map((ele) => {
- return {
- value: ele.chinese,
- label: locale.value == 'en-us' ? ele.english : ele.chinese,
- english: locale.value == 'en-us' ? ele.chinese : ele.english,
- };
- });
- function filterOption(inputValue, option) {
- return (
- option.label.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0 ||
- option.english.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0
- );
- }
- const options = cityList.map((ele) => {
- return {
- value: ele.name,
- label: ele.name,
- children: ele.city.map((element) => {
- return {
- value: element.name,
- label: element.name,
- };
- }),
- };
- });
- const beforeUpload = (file) => {
- console.log('beforeUpload', file);
- const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'video/mp4';
- if (!isJpgOrPng) {
- message.error(t('feedback.fileTips'));
- return false;
- }
- const isLt2M = file.size / 1024 / 1024 < 5;
- const isLt50M = file.size / 1024 / 1024 < 50;
- if (!isLt2M && (file.type === 'image/jpeg' || file.type === 'image/png')) {
- message.error(t('feedback.fileTips'));
- return false;
- }
- if (!isLt50M && file.type === 'video/mp4') {
- message.error(t('feedback.fileTips'));
- return Upload.LIST_IGNORE;
- }
- return file.type === 'video/mp4' ? isLt50M && isJpgOrPng : isJpgOrPng && isLt2M;
- };
- // const previewFile = (file) => {
- // console.log('file',file)
- // return file
- // }
- function getBase64(file) {
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.readAsDataURL(file);
- reader.onload = () => resolve(reader.result);
- reader.onerror = (error) => reject(error);
- });
- }
- const handlePreview = async (file) => {
- console.log('file', file);
- file.preview = file.response.data;
- window.open(file.response.data);
- return;
- // createImgPreview({ imageList: [file.response.data] });
- };
- const preview = (file) => {
- console.log('file', file);
- return file;
- };
- const onSubmit = () => {
- console.log('values', formRef.value.validate());
- formRef.value
- .validate()
- .then(() => {
- emit('submit', formData.value);
- console.log('values', formData);
- })
- .catch((error) => {
- console.log('error', error);
- });
- };
- </script>
- <style lang="scss" scoped>
- .myTitle {
- position: relative;
- margin-bottom: 14px;
- margin-top: 48px;
- .number {
- font-size: 16px;
- font-family: Microsoft YaHei, Microsoft YaHei;
- font-weight: bold;
- color: #00b3ec;
- }
- span {
- font-size: 16px;
- font-family: Microsoft YaHei, Microsoft YaHei;
- font-weight: 400;
- color: #333333;
- line-height: 19px;
- margin-right: 7px;
- }
- }
- .tips {
- font-size: 14px;
- font-family: Microsoft YaHei, Microsoft YaHei;
- font-weight: 400;
- color: #cccccc;
- line-height: 16px;
- margin-top: 8px;
- }
- .required {
- &::before {
- display: inline-block;
- margin-inline-end: 4px;
- color: #ff4d4f;
- font-size: 14px;
- font-family: SimSun, sans-serif;
- line-height: 1;
- content: '*';
- position: absolute;
- left: -11px;
- top: 4.5px;
- }
- }
- </style>
|