addEditor.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <template>
  2. <div class="w-full h-full flex flex-col">
  3. <div class="flex-1 overflow-y-auto">
  4. <van-form ref="vanFormRef" show-error :show-error-message="false" label-align="left" input-align="right"
  5. class="bg-white" @submit="onSubmit">
  6. <van-field v-model.trim="vantFormVal.taskName" name="taskName" rows="2" label="任务名称" maxlength="100" required
  7. show-word-limit type="textarea" placeholder="请输入" />
  8. <van-field v-model="vantFormVal.priority" name="priority" label="优先级" placeholder="请选择" is-link readonly
  9. required @click="showSelectionBox('priority', fixedFieldPriority)">
  10. <template #input v-if="vantFormVal.priority || vantFormVal.priority == 0">
  11. {{ vantFormVal.priorityName }}
  12. </template>
  13. </van-field>
  14. <van-field v-model="vantFormVal.taskType" name="taskType" label="任务类型" placeholder="请选择" is-link readonly
  15. @click="showSelectionBox('taskType', fixedFieldTaskType)" class="resetStyles">
  16. <template #input v-if="vantFormVal.taskType || vantFormVal.taskType == 0">
  17. {{ vantFormVal.taskTypeName }}
  18. </template>
  19. </van-field>
  20. <!-- 客户选择 -->
  21. <template v-if="vantFormVal.taskType == 0">
  22. <van-field v-model="vantFormVal.customId" name="customId" label="客户" placeholder="请选择" is-link readonly
  23. @click="showSelectionBox('customId', allCustomersList)" class="resetStyles">
  24. <template #input v-if="vantFormVal.customId">
  25. {{ vantFormVal.customIdName }}
  26. </template>
  27. </van-field>
  28. </template>
  29. <!-- 商机选择 -->
  30. <template v-if="vantFormVal.taskType == 1">
  31. <van-field v-model="vantFormVal.businessOpportunityId" name="businessOpportunityId" :label="`${businessLabel}`"
  32. placeholder="请选择" is-link readonly class="resetStyles"
  33. @click="showSelectionBox('businessOpportunityId', allBusinessOpportunities)">
  34. <template #input v-if="vantFormVal.businessOpportunityId">
  35. {{ vantFormVal.businessOpportunityIdName }}
  36. </template>
  37. </van-field>
  38. </template>
  39. <!-- 销售订单选择 -->
  40. <template v-if="vantFormVal.taskType == 2">
  41. <van-field v-model="vantFormVal.orderId" name="orderId" label="销售订单" placeholder="请选择" is-link readonly
  42. class="resetStyles" @click="showSelectionBox('orderId', allSalesOrdersList)">
  43. <template #input v-if="vantFormVal.orderId">
  44. {{ vantFormVal.orderIdName }}
  45. </template>
  46. </van-field>
  47. </template>
  48. <!-- 线索选择 -->
  49. <template v-if="vantFormVal.taskType == 3">
  50. <van-field v-model="vantFormVal.clueId" name="clueId" label="线索" placeholder="请选择" is-link readonly
  51. class="resetStyles" @click="showSelectionBox('clueId', allCluesList)">
  52. <template #input v-if="vantFormVal.clueId">
  53. {{ vantFormVal.clueIdName }}
  54. </template>
  55. </van-field>
  56. </template>
  57. <van-field v-model="vantFormVal.contactsId" name="contactsId" label="联系人" placeholder="请选择" is-link readonly
  58. :disabled="contactDisabled"
  59. v-if="fixedFieldTaskType.find(v => v.value == (vantFormVal.taskType || '1'))?.show" class="resetStyles"
  60. @click="showSelectionBox('contactsId', allContactsList)">
  61. <template #input v-if="vantFormVal.contactsId">
  62. {{ vantFormVal.contactsIdName }}
  63. </template>
  64. </van-field>
  65. <van-field v-model="vantFormVal.executorId" name="executorId" label="执行人" placeholder="请选择" is-link readonly
  66. class="resetStyles" @click="showSelectionToBox('executorId')">
  67. <template #input v-if="vantFormVal.executorIdName && vantFormVal.executorIdName.length > 0">
  68. <TranslationComponent :openId="vantFormVal.executorIdName" />
  69. </template>
  70. </van-field>
  71. <van-field name="isRepeat" label="重复提醒" class="resetStyles">
  72. <template #input>
  73. <van-switch v-model="vantFormVal.isRepeat" size="small" />
  74. </template>
  75. </van-field>
  76. <!-- 重复提醒 -->
  77. <template v-if="vantFormVal.isRepeat">
  78. <van-field v-model="vantFormVal.repeatType" name="repeatType" label="重复类型" placeholder="请选择" is-link readonly
  79. class="resetStyles" @click="showSelectionBox('repeatType', fixedFieldRepetitiveType)">
  80. <template #input v-if="vantFormVal.repeatType">
  81. {{ vantFormVal.repeatTypeName }}
  82. </template>
  83. </van-field>
  84. <template v-if="[0, 1, 2, 3, '0', '1', '2', '3'].includes(vantFormVal.repeatType)">
  85. <van-field v-model="vantFormVal.repeatDesignSameday" type="digit" name="repeatDesignSameday" label="每"
  86. class="resetStyles" v-if="vantFormVal.repeatType == 3">
  87. <template #input>
  88. <van-stepper v-model="vantFormVal.repeatDesignSameday" :min="0" button-size="1.2rem" theme="round"
  89. integer class="mr-2" />
  90. </template>
  91. <template #extra> 天 </template>
  92. </van-field>
  93. <van-field name="endType" label="结束" class="resetStyles">
  94. <template #input>
  95. <van-radio-group v-model="vantFormVal.endType" direction="horizontal" class="flex flex-col"
  96. @change="radiogroupChange">
  97. <van-radio name="1"><span
  98. :class="vantFormVal.endType == 1 ? 'themeTextColor' : ''">永不</span></van-radio>
  99. <van-radio name="2" class="mt-3">
  100. <van-stepper v-model="vantFormVal.repeatEndCount" :disabled="vantFormVal.endType != 2" :min="0"
  101. button-size="1.2rem" theme="round" integer class="mr-2" />
  102. 次数以后
  103. </van-radio>
  104. <van-radio name="3" class="mt-3">
  105. <div class="flex items-center">
  106. <van-field label="日期" is-link readonly :disabled="vantFormVal.endType != 3" class="selectField"
  107. placeholder="请选择" @click="vantFormVal.endType == 3 && showDatePickerBox('repeatEndDate')">
  108. <template #input v-if="vantFormVal.repeatEndDate">
  109. {{ vantFormVal.repeatEndDate }}
  110. </template>
  111. </van-field>
  112. 以后
  113. </div>
  114. </van-radio>
  115. </van-radio-group>
  116. </template>
  117. </van-field>
  118. </template>
  119. <template v-if="[4, '4'].includes(vantFormVal.repeatType)">
  120. <div class="flex items-center justify-between px-8 pt-3">
  121. <div>自定义日期</div>
  122. <div><van-icon name="add-o" class="ml-2 themeTextColor" size="1.3rem" @click="addCustomeDateItem()" />
  123. </div>
  124. </div>
  125. <van-cell-group inset class="additionalCoAuthorship">
  126. <template v-for="(item, index) in customeDate">
  127. <van-cell :title="`第${index + 1}次重复在`">
  128. <template #default>
  129. <div class="flex items-center justify-end">
  130. <van-stepper v-model="item.value" :min="0" button-size="1.2rem" theme="round" integer
  131. class="mr-2" />
  132. 天后
  133. <van-icon name="delete-o" class="ml-2 text-[red]" size="1.3rem"
  134. @click="deleteCustomeDateItem(index)" />
  135. </div>
  136. </template>
  137. </van-cell>
  138. </template>
  139. </van-cell-group>
  140. </template>
  141. </template>
  142. <van-field label="开始时间" name="startDate" is-link readonly class="resetStyles" placeholder="请选择"
  143. @click="showDatePickerBox('startDate')">
  144. <template #input v-if="vantFormVal.startDate">
  145. {{ vantFormVal.startDate }}
  146. </template>
  147. </van-field>
  148. <van-field label="结束时间" name="endDate" is-link readonly class="resetStyles" placeholder="请选择"
  149. @click="showDatePickerBox('endDate')">
  150. <template #input v-if="vantFormVal.endDate">
  151. {{ vantFormVal.endDate }}
  152. </template>
  153. </van-field>
  154. <div></div>
  155. </van-form>
  156. <CustomerForm ref="formFormRef" :formJson="formJson" :formValue="formVal"></CustomerForm>
  157. </div>
  158. <div class="mar-20px ">
  159. <van-button type="primary" @click="onSubmit" class="w-full">
  160. {{ Object.keys(formVal).length > 0 ? '确定修改' : '确定添加' }}
  161. </van-button>
  162. </div>
  163. <!-- 选择器 -->
  164. <div>
  165. <!-- 下拉框选择 -->
  166. <van-popup v-model:show="showSelectionFlag" destroy-on-close position="bottom" :style="{ height: '80%' }">
  167. <PullDownSelector :show-element="showSelectionFlag" :options="showSelectionArray" :doYouNeedTranslation="false" @change="selectChange" />
  168. </van-popup>
  169. <van-popup v-model:show="showSelectionToFlag" destroy-on-close position="bottom" :style="{ height: '80%' }">
  170. <PullDownSelector :show-element="showSelectionToFlag" :value="showSelectionToValue" @change="selectChange" :multiple-choice="true" />
  171. </van-popup>
  172. <!-- 选择日期 -->
  173. <van-popup v-model:show="showDatePicker" destroy-on-close position="bottom" :style="{ height: '50%' }">
  174. <van-date-picker v-model="showDatePickerVal" @confirm="showPickerConfirm" @cancel="showDatePicker = false" />
  175. </van-popup>
  176. <!-- 选择时间 -->
  177. <van-popup v-model:show="showDateTimePicker" destroy-on-close position="bottom" :style="{ height: '50%' }">
  178. <van-time-picker v-model="showDatePickerTimeVal" @confirm="showPickerTimeConfirm" @cancel="showDateTimePicker = false" />
  179. </van-popup>
  180. </div>
  181. </div>
  182. </template>
  183. <script setup>
  184. import { ref, onActivated, computed } from 'vue';
  185. import { useLifecycle } from '@hooks/useCommon.js';
  186. import { fixedFieldTaskType, fixedFieldPriority, fixedFieldRepetitiveType } from '@utility/defaultData.js';
  187. import { GET_ALL_CUSTOMERSLIST, GET_ALL_BUSINESS_OPPORTUNITIES, GET_SALES_ORDER_LIST, GET_OBTAIN_ALL_CLUES, GET_CONTACTS_WITH_MORE_I_DS, TASK_ADD_EDIT, MODIFY_TASK } from "@hooks/useApi";
  188. import requests from "@common/requests";
  189. import useToast from "@hooks/useToast"
  190. import dayjs from 'dayjs';
  191. import PullDownSelector from '@components/common/pullDownSelector.vue'
  192. import CustomerForm from '@components/common/formForm/formView.vue'
  193. import TranslationComponent from '@components/common/translationComponent.vue';
  194. import useRouterStore from "@store/useRouterStore.js";
  195. import commonUtil from "@utility/commonUtil"
  196. const router = useRouterStore()
  197. const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
  198. const props = defineProps({
  199. formJson: { required: true },
  200. formValue: { required: true },
  201. });
  202. const formFormRef = ref(null)
  203. const vantFormVal = ref({
  204. taskType: 0,
  205. taskTypeName: '客户',
  206. endType: '1',
  207. repeatEndCount: 0,
  208. repeatType: 0,
  209. repeatTypeName: '每天'
  210. })
  211. const formVal = ref({})
  212. const allBusinessOpportunities = ref([])
  213. const allCustomersList = ref([])
  214. const allCluesList = ref([])
  215. const allSalesOrdersList = ref([])
  216. const allContactsList = ref([])
  217. const showSelectionFlag = ref(false)
  218. const showSelectionFiled = ref([])
  219. const showSelectionArray = ref([])
  220. const showDatePicker = ref(false)
  221. const showDateTimePicker = ref(false)
  222. const showDatePickerVal = ref(dayjs().format("YYYY-MM-DD").split("-"))
  223. const showDatePickerTimeVal = ref(dayjs().format("HH:mm").split(":"))
  224. const showDatePickerFiled = ref('')
  225. const customeDate = ref([])
  226. const showSelectionToFlag = ref(false)
  227. const showSelectionToValue = ref([])
  228. const taskTypeFiled = ['customId', 'businessOpportunityId', 'orderId', 'clueId']
  229. const isExistBusiness = sessionStorage.getItem("isExistBusiness");
  230. const businessLabel = isExistBusiness === "1" ? "商机" : "项目";
  231. const contactDisabled = computed(() => {
  232. const taskType = vantFormVal.value?.taskType
  233. if (!taskType && taskType != 0) {
  234. return true
  235. }
  236. if (taskType == 0 && !vantFormVal.value.customId) {
  237. return true
  238. }
  239. if (taskType == 1 && !vantFormVal.value.businessOpportunityId) {
  240. return true
  241. }
  242. if (taskType == 2 && !vantFormVal.value.orderId) {
  243. return true
  244. }
  245. return false
  246. })
  247. function onSubmit() {
  248. formFormRef.value.getJsonData().then((res) => {
  249. let formValue = {
  250. ...formVal.value,
  251. ...vantFormVal.value,
  252. ...res.data,
  253. repeatDesignDay: customeDate.value.map(item => item.value).join(','),
  254. executorId: vantFormVal.value.executorId,
  255. isRepeat: vantFormVal.value.isRepeat ? 1 : 0,
  256. }
  257. delete formValue.taskLogs
  258. delete formValue.contactsName
  259. delete formValue.orderIdName
  260. delete formValue.priorityName
  261. delete formValue.taskTypeName
  262. delete formValue.repeatTypeName
  263. delete formValue.executorIdName
  264. delete formValue.taskExecutors
  265. console.log('formValue', formValue)
  266. toastLoading('保存中')
  267. const url = formValue.id ? MODIFY_TASK : TASK_ADD_EDIT
  268. requests.post(url, { ...commonUtil.getFromValue({ ...formValue }) }).then(() => {
  269. toastSuccess('保存成功')
  270. setTimeout(() => {
  271. router.navigateBack({
  272. success: () => {
  273. router.eventEmit('moduleListRefreshData', {})
  274. }
  275. })
  276. }, 2000)
  277. }).finally(() => {
  278. })
  279. })
  280. }
  281. function showPickerConfirm({ selectedValues }) {
  282. // vantFormVal.value[showDatePickerFiled.value] = selectedValues.join('-')
  283. // showDatePicker.value = false
  284. showDatePicker.value = false
  285. showDateTimePicker.value = true
  286. }
  287. function showPickerTimeConfirm({ selectedValues }) {
  288. vantFormVal.value[showDatePickerFiled.value] = `${showDatePickerVal.value.join('-')} ${selectedValues.join(':')}`
  289. showDateTimePicker.value = false
  290. }
  291. function showDatePickerBox(filed) {
  292. console.log(vantFormVal.value[filed], '<==== 123321')
  293. const dateVal = vantFormVal.value[filed] ? vantFormVal.value[filed].split(' ')[0] : dayjs().format("YYYY-MM-DD")
  294. const timeVal = vantFormVal.value[filed] ? vantFormVal.value[filed].split(' ')[1] : dayjs().format("HH:mm")
  295. showDatePickerFiled.value = filed
  296. showDatePickerVal.value = dateVal.split("-")
  297. showDatePickerTimeVal.value = timeVal.split(":")
  298. showDatePicker.value = true
  299. }
  300. function selectChange(value, label) {
  301. console.log(value, label)
  302. if (taskTypeFiled.includes(showSelectionFiled.value)) {
  303. const item = fixedFieldTaskType.find(item => item.value == vantFormVal.value.taskType)
  304. console.log(item, value,)
  305. if (item && item.show) {
  306. getContactData(showSelectionFiled.value, value)
  307. }
  308. }
  309. if (showSelectionFiled.value == 'repeatType') {
  310. vantFormVal.value = {
  311. ...vantFormVal.value,
  312. endType: 0,
  313. repeatEndCount: 0,
  314. repeatEndDate: null
  315. }
  316. customeDate.value = []
  317. }
  318. vantFormVal.value[showSelectionFiled.value] = Array.isArray(value) ? value.join(',') : value
  319. vantFormVal.value[`${showSelectionFiled.value}Name`] = label
  320. showSelectionFlag.value = false
  321. showSelectionToFlag.value = false
  322. }
  323. function showSelectionToBox(filed) {
  324. showSelectionFiled.value = filed
  325. showSelectionToValue.value = vantFormVal.value[filed] || []
  326. showSelectionToFlag.value = true
  327. }
  328. function showSelectionBox(filed, list = [], event) {
  329. if (taskTypeFiled.includes(filed)) {
  330. const fileds = taskTypeFiled.filter(item => item !== filed)
  331. fileds.forEach(item => {
  332. vantFormVal.value[item] = ''
  333. vantFormVal.value[`${item}Name`] = ''
  334. })
  335. vantFormVal.value.contactsId = ''
  336. vantFormVal.value[`contactsIdName`] = ''
  337. }
  338. showSelectionFiled.value = filed
  339. showSelectionArray.value = filed == 'executorId' ? [] : list
  340. showSelectionFlag.value = true
  341. }
  342. function addCustomeDateItem() {
  343. customeDate.value.push({ value: null })
  344. }
  345. function deleteCustomeDateItem(index) {
  346. customeDate.value.splice(index, 1)
  347. }
  348. function radiogroupChange(val) {
  349. switch (val) {
  350. case 1:
  351. vantFormVal.value.repeatEndDate = ''
  352. vantFormVal.value.repeatEndCount = null
  353. break;
  354. case 2:
  355. vantFormVal.value.repeatEndDate = ''
  356. break;
  357. case 3:
  358. vantFormVal.value.repeatEndCount = null
  359. break;
  360. default:
  361. break;
  362. }
  363. }
  364. function getContactData(filed, value) {
  365. const urlType = {
  366. 'customId': 'customerId',
  367. 'businessOpportunityId': 'businessId',
  368. 'orderId': 'salesId',
  369. }
  370. const url = `${GET_CONTACTS_WITH_MORE_I_DS}?${urlType[filed]}=${value}`
  371. requests.get(url).then(({ data = [] }) => {
  372. let list = data.map(item => {
  373. return {
  374. label: item.name,
  375. value: item.id,
  376. }
  377. })
  378. if (!list.length) {
  379. list = [{}]
  380. }
  381. allContactsList.value = list
  382. })
  383. }
  384. function getAllListData() {
  385. requests.post(GET_ALL_CUSTOMERSLIST, {}).then(res => {
  386. allCustomersList.value = res.data.map(item => {
  387. return {
  388. label: item.customName,
  389. value: item.id,
  390. }
  391. })
  392. })
  393. requests.post(GET_ALL_BUSINESS_OPPORTUNITIES, {}).then(res => {
  394. allBusinessOpportunities.value = res.data.map(item => {
  395. return {
  396. label: item.name,
  397. value: item.id,
  398. }
  399. })
  400. })
  401. requests.post(GET_SALES_ORDER_LIST, { pageIndex: -1, pageSize: -1 }).then(({ data }) => {
  402. allSalesOrdersList.value = (data.record || []).map(item => {
  403. return {
  404. label: item.orderName,
  405. value: item.id,
  406. }
  407. })
  408. })
  409. requests.post(GET_OBTAIN_ALL_CLUES, {}).then(res => {
  410. allCluesList.value = res.data.map(item => {
  411. return {
  412. label: item.clueName,
  413. value: item.id,
  414. }
  415. })
  416. })
  417. }
  418. function initializeData() {
  419. const row = props.formValue
  420. if (!row.id) {
  421. vantFormVal.value = {
  422. taskType: 0,
  423. taskTypeName: '客户',
  424. endType: '1',
  425. repeatEndCount: 0,
  426. repeatType: 0,
  427. repeatTypeName: '每天'
  428. }
  429. formVal.value = props.formValue
  430. customeDate.value = []
  431. return
  432. }
  433. const { id, taskName, priority, taskType, customId, customName, businessOpportunityId, businessOpportunityName, orderId, orderName, clueId, clueNme, contactsId, contactsName
  434. , taskExecutors, isRepeat, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, repeatDesignDay, executorId, startDate, endDate } = row
  435. vantFormVal.value = {
  436. id, taskName, priority, taskType, customId, businessOpportunityId, orderId, clueId, contactsId, executorId, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, startDate, endDate,
  437. isRepeat: isRepeat == 1 ? true : false,
  438. executorIdName: taskExecutors || [],
  439. contactsIdName: contactsName,
  440. clueIdNme: clueNme,
  441. orderIdName: orderName,
  442. customIdName: customName,
  443. businessOpportunityIdName: businessOpportunityName,
  444. priorityName: fixedFieldPriority.find(item => item.value == priority)?.label || '',
  445. taskTypeName: fixedFieldTaskType.find(item => item.value == taskType)?.label || '',
  446. repeatTypeName: fixedFieldRepetitiveType.find(item => item.value == repeatType)?.label || ''
  447. }
  448. const list = repeatDesignDay && repeatDesignDay.split(',') || []
  449. customeDate.value = (list || []).map(item => {
  450. return {
  451. value: item
  452. }
  453. })
  454. formVal.value = props.formValue
  455. if ((taskType || taskType == 0) && taskType != 3) {
  456. const filed = taskType == 0 ? 'customId' : taskType == 1 ? 'businessOpportunityId' : taskType == 2 ? 'orderId' : 'clueId'
  457. const value = taskType == 0 ? customId : taskType == 1 ? businessOpportunityId : taskType == 2 ? orderId : clueId
  458. if (value) {
  459. getContactData(filed, value)
  460. }
  461. }
  462. }
  463. useLifecycle({
  464. load: () => {
  465. initializeData()
  466. getAllListData()
  467. },
  468. init: () => {
  469. initializeData()
  470. getAllListData()
  471. }
  472. });
  473. onActivated(() => {
  474. })
  475. </script>
  476. <style lang='scss' scoped>
  477. .selectField {
  478. padding: 0;
  479. width: 12rem;
  480. margin-right: 4px;
  481. }
  482. .selectField :deep(.van-cell__title) {
  483. width: 4rem;
  484. }
  485. .additionalCoAuthorship {
  486. border-bottom: 1px solid #EBEDF0
  487. }
  488. </style>