add.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <!-- 添加或修改菜单对话框 -->
  3. <el-dialog
  4. title="客户添加"
  5. v-model="visible"
  6. width="680px"
  7. append-to-body
  8. draggable
  9. :close-on-click-modal = "false"
  10. >
  11. <el-form
  12. ref="companyRef"
  13. :model="form"
  14. size="small"
  15. :rules="rules"
  16. label-width="100px"
  17. >
  18. <el-row>
  19. <el-col :span="24">
  20. <el-radio-group v-model="addType">
  21. <el-radio-button :label="1">表单添加</el-radio-button>
  22. <el-radio-button :label="2">导入添加</el-radio-button>
  23. </el-radio-group>
  24. </el-col>
  25. <el-col v-if="addType === 1" :span="24">
  26. <el-form-item label="客户名称" prop="name">
  27. <el-input v-model="form.name" placeholder="请输入客户名称" />
  28. </el-form-item>
  29. </el-col>
  30. <el-col v-if="addType === 1" :span="24">
  31. <el-form-item label="客户来源" prop="sourceCategoryName">
  32. <CustomerFormCom
  33. :edit-status="true"
  34. :form-data="form"
  35. :source-categories="sourceCategories"
  36. />
  37. </el-form-item>
  38. </el-col>
  39. <el-col v-if="addType === 1" :span="24">
  40. <el-form-item label="负责人">
  41. <el-autocomplete
  42. :fetch-suggestions="querySearchAsync"
  43. style="width: 100%"
  44. v-model="form.leaderName"
  45. placeholder="请选择负责人"
  46. popper-class="my-autocomplete"
  47. @select="handleSelectEmployee"
  48. >
  49. <template #default="{ item }">
  50. <div
  51. style="
  52. display: flex;
  53. flex-direction: row;
  54. justify-content: space-between;
  55. "
  56. >
  57. <div class="name" style="font-size: 12px">
  58. {{ item.nickName }}
  59. </div>
  60. <span class="code" style="font-size: 10px; color: darkgrey">{{
  61. item.userName
  62. }}</span>
  63. </div>
  64. </template>
  65. </el-autocomplete>
  66. </el-form-item>
  67. <el-form-item label="客服">
  68. <el-autocomplete
  69. :fetch-suggestions="querySearchAsync"
  70. style="width: 100%"
  71. v-model="form.adviserName"
  72. placeholder="请选择客服"
  73. popper-class="my-autocomplete"
  74. @select="handleSelect"
  75. >
  76. <template #default="{ item }">
  77. <div
  78. style="
  79. display: flex;
  80. flex-direction: row;
  81. justify-content: space-between;
  82. "
  83. >
  84. <div class="name" style="font-size: 12px">
  85. {{ item.nickName }}
  86. </div>
  87. <span class="code" style="font-size: 10px; color: darkgrey">{{
  88. item.userName
  89. }}</span>
  90. </div>
  91. </template>
  92. </el-autocomplete>
  93. </el-form-item>
  94. </el-col>
  95. <el-col v-if="addType === 2" :span="24">
  96. <el-form-item label="上传">
  97. <el-upload
  98. ref="uploadRef"
  99. :limit="1"
  100. accept=".xlsx, .xls"
  101. :headers="upload.headers"
  102. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  103. :disabled="upload.isUploading"
  104. :on-progress="handleFileUploadProgress"
  105. :on-success="handleFileSuccess"
  106. :auto-upload="false"
  107. drag
  108. >
  109. <el-icon class="el-icon--upload">
  110. <upload-filled />
  111. </el-icon>
  112. <div class="el-upload__text">
  113. 将文件拖到此处,或<em>点击上传</em>
  114. </div>
  115. <template #tip>
  116. <div class="el-upload__tip text-center">
  117. <div class="el-upload__tip">
  118. <!-- <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据 -->
  119. </div>
  120. <span>仅允许导入xls、xlsx格式文件。</span>
  121. <el-link
  122. type="primary"
  123. :underline="false"
  124. style="font-size: 12px; vertical-align: baseline"
  125. @click="importTemplate"
  126. >下载模板</el-link
  127. >
  128. </div>
  129. </template>
  130. </el-upload>
  131. </el-form-item>
  132. </el-col>
  133. </el-row>
  134. </el-form>
  135. <template #footer>
  136. <div class="dialog-footer">
  137. <el-button
  138. type="primary"
  139. icon="Finished"
  140. size="small"
  141. @click="submitForm"
  142. >确 定</el-button
  143. >
  144. <el-button @click="cancel" icon="close" size="small">取 消</el-button>
  145. </div>
  146. </template>
  147. </el-dialog>
  148. </template>
  149. <script setup>
  150. import { getToken, getTenant } from "@/utils/auth";
  151. import {
  152. addCompany,
  153. importCompanyTemplate,
  154. listCompany,
  155. } from "@/api/business/crm/company";
  156. import CustomerFormCom from "@/components/CustomerFormCom";
  157. import { listChannel } from "@/api/business/channel";
  158. import useUserStore from "@/store/modules/user";
  159. import { listUser } from "@/api/system/user";
  160. import { listSource } from "@/api/settings/source";
  161. import { deepClone } from "@/utils";
  162. import { ref } from "vue";
  163. // import { incomeDefault, taxTypes, confirmDefault } from "@/utils/default"
  164. const { proxy } = getCurrentInstance();
  165. /** 父组件传参 */
  166. const props = defineProps({
  167. getList: {
  168. type: Function,
  169. default: () => {},
  170. },
  171. });
  172. const { getList } = toRefs(props);
  173. /** 字典数组区 */
  174. const { develop_type } = proxy.useDict("develop_type");
  175. /** 表单抽屉 页变量 */
  176. const title = ref("");
  177. const loading = ref(false);
  178. const multiple = ref(true);
  179. const visible = ref(false);
  180. const editStatus = ref(false);
  181. const sourceCategoryId = ref("");
  182. const isFullscreen = ref(false);
  183. const currentSource = ref({});
  184. const addDetailNum = ref(1);
  185. const currentMember = {};
  186. const provinces = ref(proxy.region.getProvinces());
  187. provinces.value.unshift({ code: "", name: "全部" });
  188. const cities = ref([]);
  189. const districts = ref([]);
  190. const sourceCategories = ref([]);
  191. const addType = ref(1);
  192. watch(addType, (value) => {
  193. switch (value) {
  194. case "1":
  195. break;
  196. case "2":
  197. break;
  198. default:
  199. break;
  200. }
  201. });
  202. const webHost = import.meta.env.VITE_APP_BASE_API;
  203. const setHeaders = {
  204. Authorization: getToken(),
  205. };
  206. const data = reactive({
  207. form: {},
  208. followData: {},
  209. rules: {
  210. name: [{ required: true, message: "客户名称不能为空", trigger: "blur" }],
  211. sourceCategoryName: [
  212. { validator: sourceValidator, trigger: "change" },
  213. { required: true, message: "客户来源不能为空", trigger: "change" },
  214. ],
  215. },
  216. });
  217. const addComRef = ref(null);
  218. /*** 客户导入参数 */
  219. const upload = reactive({
  220. // 是否禁用上传
  221. isUploading: false,
  222. // 设置上传的请求头部
  223. headers: { Authorization: "Bearer " + getToken(), tenantId: getTenant() },
  224. // 上传的地址
  225. url: "/ezhizao-yzbh-crm/business/company/importDataNew",
  226. });
  227. function sourceValidator(rule, value, callback) {
  228. console.log(form.value.reffererDataSource, form.value.sourceName);
  229. if (form.value.sourceCategoryName === "") {
  230. callback(new Error("来源类型不能为空"));
  231. return;
  232. }
  233. if (
  234. form.value.referrerDataSource !== "" &&
  235. form.value.referrerDataSource != null &&
  236. form.value.sourceName === ""
  237. ) {
  238. callback(new Error("来源不能为空"));
  239. return;
  240. }
  241. return callback();
  242. }
  243. //设置负责人
  244. function handleSelectEmployee(item) {
  245. form.value.leaderId = item.userId;
  246. form.value.leaderName = item.nickName;
  247. }
  248. //设置客服
  249. function handleSelect(item) {
  250. form.value.adviserId = item.userId;
  251. form.value.adviserName = item.nickName;
  252. }
  253. function handlerChangeCategory(value) {
  254. form.value.sourceId = null;
  255. form.value.sourceName = "";
  256. handlerSelectCategory();
  257. }
  258. function handlerSelectCategory() {
  259. form.value.sourceCategoryId = sourceCategoryId.value;
  260. // formData.value.referrerDataSource = currentSource.value.referrerDataSource
  261. const index = sourceCategories.value.findIndex(
  262. (l) => l.id === sourceCategoryId.value
  263. );
  264. currentSource.value = index >= 0 ? sourceCategories.value[index] : {};
  265. var item = sourceCategories.value.find(
  266. (emp) => emp.id === sourceCategoryId.value
  267. );
  268. if (item) {
  269. form.value.sourceCategoryName = item.title;
  270. form.value.referrerDataSource = item.referrerDataSource;
  271. }
  272. }
  273. /** 输入框输出建议 */
  274. function querySearchAsync(queryString, cb) {
  275. const query = { keyword: queryString };
  276. listUser(query).then((res) => {
  277. cb(res.rows);
  278. });
  279. }
  280. const contactorEmptyData = {
  281. id: null,
  282. name: "",
  283. position: "",
  284. gender: "男",
  285. phone: "",
  286. email: "",
  287. isMain: "是",
  288. remark: "",
  289. };
  290. const companyEmptyData = {
  291. id: null,
  292. code: "",
  293. name: "",
  294. oldName: "",
  295. shortName: "",
  296. ownerId: "",
  297. ownerName: "",
  298. sourceCategoryId: "",
  299. sourceCategoryName: "",
  300. sourceId: "",
  301. sourceName: "",
  302. stageId: "",
  303. stageName: "",
  304. phone: "",
  305. email: "",
  306. contactAddress: "",
  307. remark: "",
  308. socialCreditCode: "",
  309. mainBusinessId: "",
  310. mainBusinessName: "",
  311. typeId: "",
  312. typeName: "",
  313. legalRepresentative: "",
  314. foundationDate: "",
  315. licenceDate: "",
  316. businessStartDate: "",
  317. collectionMethod: "",
  318. businessEndDate: "",
  319. isPermanentlyEffective: "",
  320. registerMoney: "",
  321. registerMoneyUnitId: "",
  322. registerMoneyUnitName: "",
  323. provinceCode: "",
  324. province: "",
  325. cityCode: "",
  326. city: "",
  327. districtCode: "",
  328. district: "",
  329. address: "",
  330. businessField: "",
  331. taxTypeId: "",
  332. taxTypeName: "",
  333. taxDeclarationCategoryId: "",
  334. taxDeclarationCategoryName: "",
  335. isZero: "",
  336. taxDishId: "",
  337. taxDishName: "",
  338. competentTaxAuthority: "",
  339. annualIncome: "",
  340. taxType: "",
  341. taxCollectorName: "",
  342. taxCollectorPhone: "",
  343. taxMonth: "",
  344. openingBank: "",
  345. bankAccount: "",
  346. companyTags: [],
  347. companyTagIds: [],
  348. contactors: [],
  349. serviceTeams: [],
  350. companyFiles: [],
  351. stores: [],
  352. creatorId: useUserStore().user.id,
  353. };
  354. const followQuery = ref({});
  355. const { form, rules, followData } = toRefs(data);
  356. /*********************** 表单页方法 ****************************/
  357. /** 抽屉打开 */
  358. function open() {
  359. reset();
  360. form.value.leaderName = useUserStore().user.nickName;
  361. form.value.leaderId = useUserStore().user.userId;
  362. visible.value = true;
  363. }
  364. function init() {
  365. listSource()
  366. .then((res) => {
  367. // console.log(res)
  368. sourceCategories.value = res.rows;
  369. // console.log(sourceCategories.value)
  370. })
  371. .catch((err) => {
  372. console.log(err);
  373. });
  374. }
  375. function reset() {
  376. form.value = deepClone(companyEmptyData);
  377. // console.log(addComRef.value)
  378. if (addComRef.value != null) addComRef.value.reset();
  379. }
  380. function cancel() {
  381. visible.value = false;
  382. }
  383. function submitForm() {
  384. if (addType.value === 1) {
  385. proxy.$refs["companyRef"].validate((valid) => {
  386. if (valid) {
  387. addCompany(form.value)
  388. .then((res) => {
  389. console.log(res);
  390. visible.value = false;
  391. getList.value();
  392. // emit('success')
  393. })
  394. .catch((err) => {
  395. console.log(err);
  396. });
  397. }
  398. });
  399. } else {
  400. submitFileForm();
  401. }
  402. }
  403. const importTemplate = () => {
  404. // proxy.download('/business/company/importTemplate', {}, `company_template${new Date().getTime()}.xlsx`)
  405. importCompanyTemplate();
  406. };
  407. /**文件上传中处理 */
  408. const handleFileUploadProgress = (event, file, fileList) => {
  409. upload.isUploading = true;
  410. };
  411. /** 文件上传成功处理 */
  412. const handleFileSuccess = (response, file, fileList) => {
  413. upload.open = false;
  414. upload.isUploading = false;
  415. proxy.$refs["uploadRef"].handleRemove(file);
  416. proxy.$alert(
  417. "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
  418. response.msg +
  419. "</div>",
  420. "导入结果",
  421. { dangerouslyUseHTMLString: true }
  422. );
  423. getList.value();
  424. };
  425. /** 提交上传文件 */
  426. function submitFileForm() {
  427. proxy.$refs["uploadRef"].submit();
  428. }
  429. // 暴露给父组件的方法
  430. defineExpose({
  431. open,
  432. });
  433. init();
  434. </script>
  435. <style></style>